diff options
author | Chris Adams <cmadams@hiwaay.net> | 2009-01-11 14:48:53 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-01-12 19:37:01 -0500 |
commit | 05a3d9050ad7bb791b9ba306165ea98e6d9e9da2 (patch) | |
tree | e07816d365aa05914a92cb7eed05cb20462779e7 /drivers/usb | |
parent | bf0672db79c18ce38d1783be982051a718a0bc22 (diff) |
ti_usb_3410_5052: support alternate firmware
The TI USB serial driver supports specifying alternate vendor and
product IDs (since the chips can and are used in devices under other
vendor/product IDs). However, the alternate IDs were not loaded in the
combined product table. This patch also adds support for loading
alternate firmware for alternate vendor/product IDs.
Signed-off-by: Chris Adams <cmadams@hiwaay.net>
Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/serial/ti_usb_3410_5052.c | 44 |
1 files changed, 29 insertions, 15 deletions
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index 01d0c70d60e9..1cdb1515253d 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c | |||
@@ -145,7 +145,7 @@ static int ti_command_in_sync(struct ti_device *tdev, __u8 command, | |||
145 | static int ti_write_byte(struct ti_device *tdev, unsigned long addr, | 145 | static int ti_write_byte(struct ti_device *tdev, unsigned long addr, |
146 | __u8 mask, __u8 byte); | 146 | __u8 mask, __u8 byte); |
147 | 147 | ||
148 | static int ti_download_firmware(struct ti_device *tdev, int type); | 148 | static int ti_download_firmware(struct ti_device *tdev); |
149 | 149 | ||
150 | /* circular buffer */ | 150 | /* circular buffer */ |
151 | static struct circ_buf *ti_buf_alloc(void); | 151 | static struct circ_buf *ti_buf_alloc(void); |
@@ -176,7 +176,7 @@ static unsigned int product_5052_count; | |||
176 | /* the array dimension is the number of default entries plus */ | 176 | /* the array dimension is the number of default entries plus */ |
177 | /* TI_EXTRA_VID_PID_COUNT user defined entries plus 1 terminating */ | 177 | /* TI_EXTRA_VID_PID_COUNT user defined entries plus 1 terminating */ |
178 | /* null entry */ | 178 | /* null entry */ |
179 | static struct usb_device_id ti_id_table_3410[1+TI_EXTRA_VID_PID_COUNT+1] = { | 179 | static struct usb_device_id ti_id_table_3410[2+TI_EXTRA_VID_PID_COUNT+1] = { |
180 | { USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) }, | 180 | { USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) }, |
181 | { USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) }, | 181 | { USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) }, |
182 | }; | 182 | }; |
@@ -188,7 +188,7 @@ static struct usb_device_id ti_id_table_5052[4+TI_EXTRA_VID_PID_COUNT+1] = { | |||
188 | { USB_DEVICE(TI_VENDOR_ID, TI_5052_FIRMWARE_PRODUCT_ID) }, | 188 | { USB_DEVICE(TI_VENDOR_ID, TI_5052_FIRMWARE_PRODUCT_ID) }, |
189 | }; | 189 | }; |
190 | 190 | ||
191 | static struct usb_device_id ti_id_table_combined[] = { | 191 | static struct usb_device_id ti_id_table_combined[6+2*TI_EXTRA_VID_PID_COUNT+1] = { |
192 | { USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) }, | 192 | { USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) }, |
193 | { USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) }, | 193 | { USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) }, |
194 | { USB_DEVICE(TI_VENDOR_ID, TI_5052_BOOT_PRODUCT_ID) }, | 194 | { USB_DEVICE(TI_VENDOR_ID, TI_5052_BOOT_PRODUCT_ID) }, |
@@ -304,21 +304,28 @@ MODULE_DEVICE_TABLE(usb, ti_id_table_combined); | |||
304 | 304 | ||
305 | static int __init ti_init(void) | 305 | static int __init ti_init(void) |
306 | { | 306 | { |
307 | int i, j; | 307 | int i, j, c; |
308 | int ret; | 308 | int ret; |
309 | 309 | ||
310 | /* insert extra vendor and product ids */ | 310 | /* insert extra vendor and product ids */ |
311 | c = ARRAY_SIZE(ti_id_table_combined) - 2 * TI_EXTRA_VID_PID_COUNT - 1; | ||
311 | j = ARRAY_SIZE(ti_id_table_3410) - TI_EXTRA_VID_PID_COUNT - 1; | 312 | j = ARRAY_SIZE(ti_id_table_3410) - TI_EXTRA_VID_PID_COUNT - 1; |
312 | for (i = 0; i < min(vendor_3410_count, product_3410_count); i++, j++) { | 313 | for (i = 0; i < min(vendor_3410_count, product_3410_count); i++, j++, c++) { |
313 | ti_id_table_3410[j].idVendor = vendor_3410[i]; | 314 | ti_id_table_3410[j].idVendor = vendor_3410[i]; |
314 | ti_id_table_3410[j].idProduct = product_3410[i]; | 315 | ti_id_table_3410[j].idProduct = product_3410[i]; |
315 | ti_id_table_3410[j].match_flags = USB_DEVICE_ID_MATCH_DEVICE; | 316 | ti_id_table_3410[j].match_flags = USB_DEVICE_ID_MATCH_DEVICE; |
317 | ti_id_table_combined[c].idVendor = vendor_3410[i]; | ||
318 | ti_id_table_combined[c].idProduct = product_3410[i]; | ||
319 | ti_id_table_combined[c].match_flags = USB_DEVICE_ID_MATCH_DEVICE; | ||
316 | } | 320 | } |
317 | j = ARRAY_SIZE(ti_id_table_5052) - TI_EXTRA_VID_PID_COUNT - 1; | 321 | j = ARRAY_SIZE(ti_id_table_5052) - TI_EXTRA_VID_PID_COUNT - 1; |
318 | for (i = 0; i < min(vendor_5052_count, product_5052_count); i++, j++) { | 322 | for (i = 0; i < min(vendor_5052_count, product_5052_count); i++, j++, c++) { |
319 | ti_id_table_5052[j].idVendor = vendor_5052[i]; | 323 | ti_id_table_5052[j].idVendor = vendor_5052[i]; |
320 | ti_id_table_5052[j].idProduct = product_5052[i]; | 324 | ti_id_table_5052[j].idProduct = product_5052[i]; |
321 | ti_id_table_5052[j].match_flags = USB_DEVICE_ID_MATCH_DEVICE; | 325 | ti_id_table_5052[j].match_flags = USB_DEVICE_ID_MATCH_DEVICE; |
326 | ti_id_table_combined[c].idVendor = vendor_5052[i]; | ||
327 | ti_id_table_combined[c].idProduct = product_5052[i]; | ||
328 | ti_id_table_combined[c].match_flags = USB_DEVICE_ID_MATCH_DEVICE; | ||
322 | } | 329 | } |
323 | 330 | ||
324 | ret = usb_serial_register(&ti_1port_device); | 331 | ret = usb_serial_register(&ti_1port_device); |
@@ -390,11 +397,7 @@ static int ti_startup(struct usb_serial *serial) | |||
390 | 397 | ||
391 | /* if we have only 1 configuration, download firmware */ | 398 | /* if we have only 1 configuration, download firmware */ |
392 | if (dev->descriptor.bNumConfigurations == 1) { | 399 | if (dev->descriptor.bNumConfigurations == 1) { |
393 | if (tdev->td_is_3410) | 400 | if ((status = ti_download_firmware(tdev)) != 0) |
394 | status = ti_download_firmware(tdev, 3410); | ||
395 | else | ||
396 | status = ti_download_firmware(tdev, 5052); | ||
397 | if (status) | ||
398 | goto free_tdev; | 401 | goto free_tdev; |
399 | 402 | ||
400 | /* 3410 must be reset, 5052 resets itself */ | 403 | /* 3410 must be reset, 5052 resets itself */ |
@@ -1671,9 +1674,9 @@ static int ti_do_download(struct usb_device *dev, int pipe, | |||
1671 | return status; | 1674 | return status; |
1672 | } | 1675 | } |
1673 | 1676 | ||
1674 | static int ti_download_firmware(struct ti_device *tdev, int type) | 1677 | static int ti_download_firmware(struct ti_device *tdev) |
1675 | { | 1678 | { |
1676 | int status = -ENOMEM; | 1679 | int status; |
1677 | int buffer_size; | 1680 | int buffer_size; |
1678 | __u8 *buffer; | 1681 | __u8 *buffer; |
1679 | struct usb_device *dev = tdev->td_serial->dev; | 1682 | struct usb_device *dev = tdev->td_serial->dev; |
@@ -1681,9 +1684,18 @@ static int ti_download_firmware(struct ti_device *tdev, int type) | |||
1681 | tdev->td_serial->port[0]->bulk_out_endpointAddress); | 1684 | tdev->td_serial->port[0]->bulk_out_endpointAddress); |
1682 | const struct firmware *fw_p; | 1685 | const struct firmware *fw_p; |
1683 | char buf[32]; | 1686 | char buf[32]; |
1684 | sprintf(buf, "ti_usb-%d.bin", type); | ||
1685 | 1687 | ||
1686 | if (request_firmware(&fw_p, buf, &dev->dev)) { | 1688 | /* try ID specific firmware first, then try generic firmware */ |
1689 | sprintf(buf, "ti_usb-v%04x-p%04x.fw", dev->descriptor.idVendor, | ||
1690 | dev->descriptor.idProduct); | ||
1691 | if ((status = request_firmware(&fw_p, buf, &dev->dev)) != 0) { | ||
1692 | if (tdev->td_is_3410) | ||
1693 | strcpy(buf, "ti_3410.fw"); | ||
1694 | else | ||
1695 | strcpy(buf, "ti_5052.fw"); | ||
1696 | status = request_firmware(&fw_p, buf, &dev->dev); | ||
1697 | } | ||
1698 | if (status) { | ||
1687 | dev_err(&dev->dev, "%s - firmware not found\n", __func__); | 1699 | dev_err(&dev->dev, "%s - firmware not found\n", __func__); |
1688 | return -ENOENT; | 1700 | return -ENOENT; |
1689 | } | 1701 | } |
@@ -1699,6 +1711,8 @@ static int ti_download_firmware(struct ti_device *tdev, int type) | |||
1699 | memset(buffer + fw_p->size, 0xff, buffer_size - fw_p->size); | 1711 | memset(buffer + fw_p->size, 0xff, buffer_size - fw_p->size); |
1700 | status = ti_do_download(dev, pipe, buffer, fw_p->size); | 1712 | status = ti_do_download(dev, pipe, buffer, fw_p->size); |
1701 | kfree(buffer); | 1713 | kfree(buffer); |
1714 | } else { | ||
1715 | status = -ENOMEM; | ||
1702 | } | 1716 | } |
1703 | release_firmware(fw_p); | 1717 | release_firmware(fw_p); |
1704 | if (status) { | 1718 | if (status) { |