Skip to content

Commit 05a3d90

Browse files
Chris Adamstorvalds
authored andcommitted
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 <[email protected]> Signed-off-by: Alan Cox <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent bf0672d commit 05a3d90

File tree

1 file changed

+29
-15
lines changed

1 file changed

+29
-15
lines changed

drivers/usb/serial/ti_usb_3410_5052.c

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ static int ti_command_in_sync(struct ti_device *tdev, __u8 command,
145145
static int ti_write_byte(struct ti_device *tdev, unsigned long addr,
146146
__u8 mask, __u8 byte);
147147

148-
static int ti_download_firmware(struct ti_device *tdev, int type);
148+
static int ti_download_firmware(struct ti_device *tdev);
149149

150150
/* circular buffer */
151151
static struct circ_buf *ti_buf_alloc(void);
@@ -176,7 +176,7 @@ static unsigned int product_5052_count;
176176
/* the array dimension is the number of default entries plus */
177177
/* TI_EXTRA_VID_PID_COUNT user defined entries plus 1 terminating */
178178
/* 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] = {
180180
{ USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) },
181181
{ USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) },
182182
};
@@ -188,7 +188,7 @@ static struct usb_device_id ti_id_table_5052[4+TI_EXTRA_VID_PID_COUNT+1] = {
188188
{ USB_DEVICE(TI_VENDOR_ID, TI_5052_FIRMWARE_PRODUCT_ID) },
189189
};
190190

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] = {
192192
{ USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) },
193193
{ USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) },
194194
{ USB_DEVICE(TI_VENDOR_ID, TI_5052_BOOT_PRODUCT_ID) },
@@ -304,21 +304,28 @@ MODULE_DEVICE_TABLE(usb, ti_id_table_combined);
304304

305305
static int __init ti_init(void)
306306
{
307-
int i, j;
307+
int i, j, c;
308308
int ret;
309309

310310
/* insert extra vendor and product ids */
311+
c = ARRAY_SIZE(ti_id_table_combined) - 2 * TI_EXTRA_VID_PID_COUNT - 1;
311312
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++) {
313314
ti_id_table_3410[j].idVendor = vendor_3410[i];
314315
ti_id_table_3410[j].idProduct = product_3410[i];
315316
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;
316320
}
317321
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++) {
319323
ti_id_table_5052[j].idVendor = vendor_5052[i];
320324
ti_id_table_5052[j].idProduct = product_5052[i];
321325
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;
322329
}
323330

324331
ret = usb_serial_register(&ti_1port_device);
@@ -390,11 +397,7 @@ static int ti_startup(struct usb_serial *serial)
390397

391398
/* if we have only 1 configuration, download firmware */
392399
if (dev->descriptor.bNumConfigurations == 1) {
393-
if (tdev->td_is_3410)
394-
status = ti_download_firmware(tdev, 3410);
395-
else
396-
status = ti_download_firmware(tdev, 5052);
397-
if (status)
400+
if ((status = ti_download_firmware(tdev)) != 0)
398401
goto free_tdev;
399402

400403
/* 3410 must be reset, 5052 resets itself */
@@ -1671,19 +1674,28 @@ static int ti_do_download(struct usb_device *dev, int pipe,
16711674
return status;
16721675
}
16731676

1674-
static int ti_download_firmware(struct ti_device *tdev, int type)
1677+
static int ti_download_firmware(struct ti_device *tdev)
16751678
{
1676-
int status = -ENOMEM;
1679+
int status;
16771680
int buffer_size;
16781681
__u8 *buffer;
16791682
struct usb_device *dev = tdev->td_serial->dev;
16801683
unsigned int pipe = usb_sndbulkpipe(dev,
16811684
tdev->td_serial->port[0]->bulk_out_endpointAddress);
16821685
const struct firmware *fw_p;
16831686
char buf[32];
1684-
sprintf(buf, "ti_usb-%d.bin", type);
16851687

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) {
16871699
dev_err(&dev->dev, "%s - firmware not found\n", __func__);
16881700
return -ENOENT;
16891701
}
@@ -1699,6 +1711,8 @@ static int ti_download_firmware(struct ti_device *tdev, int type)
16991711
memset(buffer + fw_p->size, 0xff, buffer_size - fw_p->size);
17001712
status = ti_do_download(dev, pipe, buffer, fw_p->size);
17011713
kfree(buffer);
1714+
} else {
1715+
status = -ENOMEM;
17021716
}
17031717
release_firmware(fw_p);
17041718
if (status) {

0 commit comments

Comments
 (0)