diff options
author | Mike Isely <isely@pobox.com> | 2006-03-10 22:15:37 -0600 |
---|---|---|
committer | Mike Isely <isely@pobox.com> | 2006-03-10 22:15:37 -0600 |
commit | 55f51733177372bd79c2be661791dacecdee81a2 (patch) | |
tree | 0d6ea010ba7f103bae5e2c894e556e1f01be7af2 /linux | |
parent | 0bf24997cc63766b78264dd717524e7721f75446 (diff) | |
download | mediapointer-dvb-s2-55f51733177372bd79c2be661791dacecdee81a2.tar.gz mediapointer-dvb-s2-55f51733177372bd79c2be661791dacecdee81a2.tar.bz2 |
Make pvrusb2 aware of alternative hardware types
From: Mike Isely <isely@pobox.com>
Notice and track actual hardware type of device. This information is
also used now to select the correct FX2 firmware file to load (because
they can be different, unfortunately).
Signed-off-by: Mike Isely <isely@pobox.com>
Diffstat (limited to 'linux')
6 files changed, 64 insertions, 17 deletions
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-context.c b/linux/drivers/media/video/pvrusb2/pvrusb2-context.c index b8f7fb043..0f0e14d01 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-context.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-context.c @@ -74,7 +74,9 @@ static void pvr2_context_setup(struct pvr2_context *mp) struct pvr2_context *pvr2_context_create( - struct usb_interface *intf,void (*setup_func)(struct pvr2_context *)) + struct usb_interface *intf, + const struct usb_device_id *devid, + void (*setup_func)(struct pvr2_context *)) { struct pvr2_context *mp = 0; mp = kmalloc(sizeof(*mp),GFP_KERNEL); @@ -83,7 +85,7 @@ struct pvr2_context *pvr2_context_create( pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr_main id=%p",mp); mp->setup_func = setup_func; mutex_init(&mp->mutex); - mp->hdw = pvr2_hdw_create(intf); + mp->hdw = pvr2_hdw_create(intf,devid); if (!mp->hdw) { pvr2_context_destroy(mp); mp = 0; diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-context.h b/linux/drivers/media/video/pvrusb2/pvrusb2-context.h index e721cc559..873622a0f 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-context.h +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-context.h @@ -77,6 +77,7 @@ void pvr2_context_enter(struct pvr2_context *); void pvr2_context_exit(struct pvr2_context *); struct pvr2_context *pvr2_context_create(struct usb_interface *intf, + const struct usb_device_id *devid, void (*setup_func)(struct pvr2_context *)); void pvr2_context_disconnect(struct pvr2_context *); diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h index b18906ea6..1b161773b 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h @@ -93,6 +93,10 @@ struct pvr2_decoder_ctrl { #define FW1_STATE_RELOAD 3 #define FW1_STATE_OK 4 +/* Known major hardware variants, keyed from device ID */ +#define PVR2_HDW_TYPE_29XXX 0 +#define PVR2_HDW_TYPE_24XXX 1 + /* This structure contains all state data directly needed to manipulate the hardware (as opposed to complying with a kernel interface) */ @@ -101,6 +105,9 @@ struct pvr2_hdw { struct usb_device *usb_dev; struct usb_interface *usb_intf; + /* Device type, one of PVR2_HDW_TYPE_xxxxx */ + unsigned int hdw_type; + /* Video spigot */ struct pvr2_stream *vid_stream; diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c index 1b0181ee9..dcd5e40c8 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -35,6 +35,17 @@ #include "pvrusb2-encoder.h" #include "pvrusb2-debug.h" +struct usb_device_id pvr2_device_table[] = { + [PVR2_HDW_TYPE_29XXX] = { USB_DEVICE(0x2040, 0x2900) }, + [PVR2_HDW_TYPE_24XXX] = { USB_DEVICE(0x2040, 0x2400) }, + { } +}; + +static const char *pvr2_device_names[] = { + [PVR2_HDW_TYPE_29XXX] = "WinTV PVR USB2 Model Category 29xxxx", + [PVR2_HDW_TYPE_24XXX] = "WinTV PVR USB2 Model Category 24xxxx", +}; + static struct pvr2_hdw *unit_pointers[PVR_NUM] = {[ 0 ... PVR_NUM-1 ] = 0}; DECLARE_MUTEX(pvr2_unit_sem); @@ -494,17 +505,32 @@ int pvr2_upload_firmware1(struct pvr2_hdw *hdw) unsigned int pipe; int ret; u16 address; - static const char *fw_files[] = { + static const char *fw_files_29xxx[] = { "v4l-pvrusb2-29xxx-01.fw", }; - + static const char *fw_files_24xxx[] = { + "v4l-pvrusb2-24xxx-01.fw", + }; + static const struct { + const char **lst; + unsigned int cnt; + } fw_file_defs[] = { + [PVR2_HDW_TYPE_29XXX] = { + fw_files_29xxx, + sizeof(fw_files_29xxx)/sizeof(fw_files_29xxx[0]), + }, + [PVR2_HDW_TYPE_24XXX] = { + fw_files_24xxx, + sizeof(fw_files_24xxx)/sizeof(fw_files_24xxx[0]), + }, + }; hdw->fw1_state = FW1_STATE_FAILED; // default result trace_firmware("pvr2_upload_firmware1"); ret = pvr2_locate_firmware(hdw,&fw_entry,"fx2 controller", - sizeof(fw_files)/sizeof(fw_files[0]), - fw_files); + fw_file_defs[hdw->hdw_type].cnt, + fw_file_defs[hdw->hdw_type].lst); if (ret < 0) { if (ret == -ENOENT) hdw->fw1_state = FW1_STATE_MISSING; return ret; @@ -1206,16 +1232,29 @@ int pvr2_hdw_setup(struct pvr2_hdw *hdw) /* Create and return a structure for interacting with the underlying hardware */ -struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf) +struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, + struct usb_device_id *devid) { unsigned int idx,cnt1,cnt2; struct pvr2_hdw *hdw; + unsigned int hdw_type; __u8 ifnum; + hdw_type = devid - pvr2_device_table; + if (hdw_type >= + sizeof(pvr2_device_names)/sizeof(pvr2_device_names[0])) { + pvr2_trace(PVR2_TRACE_ERROR_LEGS, + "Bogus device type of %u reported",hdw_type); + return 0; + } + hdw = kmalloc(sizeof(*hdw),GFP_KERNEL); - pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_create: hdw=%p",hdw); + pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_create: hdw=%p, type \"%s\"", + hdw,pvr2_device_names[hdw_type]); if (!hdw) goto fail; memset(hdw,0,sizeof(*hdw)); + hdw->hdw_type = hdw_type; + hdw->eeprom_addr = -1; hdw->unit_number = -1; hdw->v4l_minor_number = -1; diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h index cfde4a0c5..4f1844629 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h @@ -168,7 +168,8 @@ struct pvr2_hdw; /* Create and return a structure for interacting with the underlying hardware */ -struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf); +struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, + struct usb_device_id *devid); /* Poll for background activity (if any) */ void pvr2_hdw_poll(struct pvr2_hdw *); @@ -407,6 +408,8 @@ void pvr2_hdw_trigger_module_log(struct pvr2_hdw *hdw); a debugging aid. */ int pvr2_upload_firmware2(struct pvr2_hdw *hdw); +/* List of device types that we can match */ +extern struct usb_device_id pvr2_device_table[]; #endif /* __PVRUSB2_HDW_H */ diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-main.c b/linux/drivers/media/video/pvrusb2/pvrusb2-main.c index 0003c7a07..8e22c93e0 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-main.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-main.c @@ -62,11 +62,6 @@ MODULE_PARM_DESC(debug, "Debug trace mask"); static struct pvr2_sysfs_class *class_ptr = 0; -static struct usb_device_id pvr_table[] = { - { USB_DEVICE(0x2040, 0x2900) }, - { } -}; - static void pvr_setup_attach(struct pvr2_context *pvr) { /* Create association with v4l layer */ @@ -80,7 +75,7 @@ static int pvr_probe(struct usb_interface *intf, struct pvr2_context *pvr; /* Create underlying hardware interface */ - pvr = pvr2_context_create(intf,pvr_setup_attach); + pvr = pvr2_context_create(intf,devid,pvr_setup_attach); if (!pvr) { pvr2_trace(PVR2_TRACE_ERROR_LEGS, "Failed to create hdw handler"); @@ -116,7 +111,7 @@ static struct usb_driver pvr_driver = { owner: THIS_MODULE, #endif name: "pvrusb2", - id_table: pvr_table, + id_table: pvr2_device_table, probe: pvr_probe, disconnect: pvr_disconnect }; @@ -166,7 +161,7 @@ static void __exit pvr_exit(void) module_init(pvr_init); module_exit(pvr_exit); -MODULE_DEVICE_TABLE (usb, pvr_table); +MODULE_DEVICE_TABLE (usb, pvr2_device_table); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); |