From 55f51733177372bd79c2be661791dacecdee81a2 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Fri, 10 Mar 2006 22:15:37 -0600 Subject: Make pvrusb2 aware of alternative hardware types From: Mike Isely 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 --- .../drivers/media/video/pvrusb2/pvrusb2-context.c | 6 ++- .../drivers/media/video/pvrusb2/pvrusb2-context.h | 1 + .../media/video/pvrusb2/pvrusb2-hdw-internal.h | 7 +++ linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c | 51 +++++++++++++++++++--- linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h | 5 ++- linux/drivers/media/video/pvrusb2/pvrusb2-main.c | 11 ++--- 6 files changed, 64 insertions(+), 17 deletions(-) (limited to 'linux/drivers/media/video/pvrusb2') 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"); -- cgit v1.2.3