From 7cac2bd195ef658e25808a8762c6b44ad11aa7fd Mon Sep 17 00:00:00 2001 From: Alex Woods Date: Sat, 10 Jan 2004 01:11:17 +0000 Subject: Handle the new firmwares that change the devices' USB IDs. Tidy up the STB initialisation process a little. --- linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c | 99 +++++++++++++++++++-------- 1 file changed, 72 insertions(+), 27 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c index 5c0e469c5..fd94d1e89 100644 --- a/linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c +++ b/linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c @@ -64,6 +64,7 @@ static int debug = 0; enum ttusb_dec_model { TTUSB_DEC2000T, + TTUSB_DEC2540T, TTUSB_DEC3000S }; @@ -170,6 +171,9 @@ static struct dvb_frontend_info dec3000s_frontend_info = { FE_CAN_HIERARCHY_AUTO, }; +static void ttusb_dec_set_model(struct ttusb_dec *dec, + enum ttusb_dec_model model); + static u16 crc16(u16 crc, const u8 *buf, size_t len) { u16 tmp; @@ -251,8 +255,7 @@ static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command, } static int ttusb_dec_get_stb_state (struct ttusb_dec *dec, unsigned int *mode, - unsigned int *product, - unsigned int *version) + unsigned int *model, unsigned int *version) { u8 c[COMMAND_PACKET_SIZE]; int c_length; @@ -270,9 +273,9 @@ static int ttusb_dec_get_stb_state (struct ttusb_dec *dec, unsigned int *mode, memcpy(&tmp, c, 4); *mode = ntohl(tmp); } - if (product != NULL) { + if (model != NULL) { memcpy(&tmp, &c[4], 4); - *product = ntohl(tmp); + *model = ntohl(tmp); } if (version != NULL) { memcpy(&tmp, &c[8], 4); @@ -1118,6 +1121,7 @@ static int ttusb_dec_boot_dsp(struct ttusb_dec *dec) #else switch (dec->model) { case TTUSB_DEC2000T: + case TTUSB_DEC2540T: firmware = &dsp_dec2000t[0]; firmware_size = sizeof(dsp_dec2000t); break; @@ -1198,11 +1202,11 @@ static int ttusb_dec_boot_dsp(struct ttusb_dec *dec) static int ttusb_dec_init_stb(struct ttusb_dec *dec) { int result; - unsigned int mode, product, version; + unsigned int mode, model, version; dprintk("%s\n", __FUNCTION__); - result = ttusb_dec_get_stb_state(dec, &mode, &product, &version); + result = ttusb_dec_get_stb_state(dec, &mode, &model, &version); if (!result) { if (!mode) { @@ -1214,9 +1218,32 @@ static int ttusb_dec_init_stb(struct ttusb_dec *dec) "%x.%02x%c%c\n", version >> 24, (version >> 16) & 0xff, (version >> 8) & 0xff, version & 0xff); - return ttusb_dec_boot_dsp(dec); - } else + + result = ttusb_dec_boot_dsp(dec); + if (result) + return result; + else + return 1; + } else { + /* We can't trust the USB IDs that some firmwares + give the box */ + switch (model) { + case 0x00070008: + ttusb_dec_set_model(dec, TTUSB_DEC3000S); + break; + case 0x00070009: + ttusb_dec_set_model(dec, TTUSB_DEC2000T); + break; + default: + printk(KERN_ERR "%s: unknown model returned " + "by firmware (%04x) - please report\n", + __FUNCTION__, model); + return -1; + break; + } + return 0; + } } else return result; @@ -1573,18 +1600,6 @@ static void ttusb_dec_init_frontend(struct ttusb_dec *dec) { dec->i2c_bus.adapter = dec->adapter; - switch (dec->model) { - case TTUSB_DEC2000T: - dec->frontend_info = &dec2000t_frontend_info; - dec->frontend_ioctl = ttusb_dec_2000t_frontend_ioctl; - break; - - case TTUSB_DEC3000S: - dec->frontend_info = &dec3000s_frontend_info; - dec->frontend_ioctl = ttusb_dec_3000s_frontend_ioctl; - break; - } - dvb_register_frontend(dec->frontend_ioctl, &dec->i2c_bus, (void *)dec, dec->frontend_info); } @@ -1650,15 +1665,15 @@ static int ttusb_dec_probe(struct usb_interface *intf, switch (id->idProduct) { case 0x1006: - dec->model = TTUSB_DEC3000S; - dec->model_name = "DEC3000-s"; - dec->firmware_name = "dvb-ttusb-dec-3000s.fw"; + ttusb_dec_set_model(dec, TTUSB_DEC3000S); break; case 0x1008: - dec->model = TTUSB_DEC2000T; - dec->model_name = "DEC2000-t"; - dec->firmware_name = "dvb-ttusb-dec-2000t.fw"; + ttusb_dec_set_model(dec, TTUSB_DEC2000T); + break; + + case 0x1009: + ttusb_dec_set_model(dec, TTUSB_DEC2540T); break; } @@ -1711,15 +1726,45 @@ static void ttusb_dec_disconnect(struct usb_interface *intf) kfree(dec); } +static void ttusb_dec_set_model(struct ttusb_dec *dec, + enum ttusb_dec_model model) +{ + dec->model = model; + + switch (model) { + case TTUSB_DEC2000T: + dec->model_name = "DEC2000-t"; + dec->firmware_name = "dvb-ttusb-dec-2000t.fw"; + dec->frontend_info = &dec2000t_frontend_info; + dec->frontend_ioctl = ttusb_dec_2000t_frontend_ioctl; + break; + + case TTUSB_DEC2540T: + dec->model_name = "DEC2540-t"; + dec->firmware_name = "dvb-ttusb-dec-2540t.fw"; + dec->frontend_info = &dec2000t_frontend_info; + dec->frontend_ioctl = ttusb_dec_2000t_frontend_ioctl; + break; + + case TTUSB_DEC3000S: + dec->model_name = "DEC3000-s"; + dec->firmware_name = "dvb-ttusb-dec-3000s.fw"; + dec->frontend_info = &dec3000s_frontend_info; + dec->frontend_ioctl = ttusb_dec_3000s_frontend_ioctl; + break; + } +} + static struct usb_device_id ttusb_dec_table[] = { {USB_DEVICE(0x0b48, 0x1006)}, /* DEC3000-s */ /*{USB_DEVICE(0x0b48, 0x1007)}, Unconfirmed */ {USB_DEVICE(0x0b48, 0x1008)}, /* DEC2000-t */ + {USB_DEVICE(0x0b48, 0x1009)}, /* DEC2540-t */ {} }; static struct usb_driver ttusb_dec_driver = { - .name = DRIVER_NAME, + .name = "ttusb-dec", .probe = ttusb_dec_probe, .disconnect = ttusb_dec_disconnect, .id_table = ttusb_dec_table, -- cgit v1.2.3