diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2014-09-11 14:46:53 +0200 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2014-09-11 14:46:53 +0200 |
commit | 336879b1da97fffc097f77c6d6f818660f2826f0 (patch) | |
tree | 4ddb4d1c5d2b67fb096c72e41d2a03b01a605041 /drivers/media/usb/go7007/go7007-loader.c | |
parent | 3d3cbd84300e7be1e53083cac0f6f9c12978ecb4 (diff) | |
parent | fdcaa1dbb7c6ed419b10fb8cdb5001ab0a00538f (diff) |
Merge remote-tracking branch 'airlied/drm-next' into topic/vblank-rework
Dave asked me to do the backmerge before sending him the revised pull
request, so here we go. Nothing fancy in the conflicts, just a few
things changed right next to each another.
Conflicts:
drivers/gpu/drm/drm_irq.c
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Diffstat (limited to 'drivers/media/usb/go7007/go7007-loader.c')
-rw-r--r-- | drivers/media/usb/go7007/go7007-loader.c | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/drivers/media/usb/go7007/go7007-loader.c b/drivers/media/usb/go7007/go7007-loader.c new file mode 100644 index 00000000000..042f78a3128 --- /dev/null +++ b/drivers/media/usb/go7007/go7007-loader.c @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2008 Sensoray Company Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/module.h> +#include <linux/slab.h> +#include <linux/usb.h> +#include <linux/firmware.h> +#include <cypress_firmware.h> + +struct fw_config { + u16 vendor; + u16 product; + const char * const fw_name1; + const char * const fw_name2; +}; + +static struct fw_config fw_configs[] = { + { 0x1943, 0xa250, "go7007/s2250-1.fw", "go7007/s2250-2.fw" }, + { 0x093b, 0xa002, "go7007/px-m402u.fw", NULL }, + { 0x093b, 0xa004, "go7007/px-tv402u.fw", NULL }, + { 0x0eb1, 0x6666, "go7007/lr192.fw", NULL }, + { 0x0eb1, 0x6668, "go7007/wis-startrek.fw", NULL }, + { 0, 0, NULL, NULL } +}; +MODULE_FIRMWARE("go7007/s2250-1.fw"); +MODULE_FIRMWARE("go7007/s2250-2.fw"); +MODULE_FIRMWARE("go7007/px-m402u.fw"); +MODULE_FIRMWARE("go7007/px-tv402u.fw"); +MODULE_FIRMWARE("go7007/lr192.fw"); +MODULE_FIRMWARE("go7007/wis-startrek.fw"); + +static int go7007_loader_probe(struct usb_interface *interface, + const struct usb_device_id *id) +{ + struct usb_device *usbdev; + const struct firmware *fw; + u16 vendor, product; + const char *fw1, *fw2; + int ret; + int i; + + usbdev = usb_get_dev(interface_to_usbdev(interface)); + if (!usbdev) + goto failed2; + + if (usbdev->descriptor.bNumConfigurations != 1) { + dev_err(&interface->dev, "can't handle multiple config\n"); + goto failed2; + } + + vendor = le16_to_cpu(usbdev->descriptor.idVendor); + product = le16_to_cpu(usbdev->descriptor.idProduct); + + for (i = 0; fw_configs[i].fw_name1; i++) + if (fw_configs[i].vendor == vendor && + fw_configs[i].product == product) + break; + + /* Should never happen */ + if (fw_configs[i].fw_name1 == NULL) + goto failed2; + + fw1 = fw_configs[i].fw_name1; + fw2 = fw_configs[i].fw_name2; + + dev_info(&interface->dev, "loading firmware %s\n", fw1); + + if (request_firmware(&fw, fw1, &usbdev->dev)) { + dev_err(&interface->dev, + "unable to load firmware from file \"%s\"\n", fw1); + goto failed2; + } + ret = cypress_load_firmware(usbdev, fw, CYPRESS_FX2); + release_firmware(fw); + if (0 != ret) { + dev_err(&interface->dev, "loader download failed\n"); + goto failed2; + } + + if (fw2 == NULL) + return 0; + + if (request_firmware(&fw, fw2, &usbdev->dev)) { + dev_err(&interface->dev, + "unable to load firmware from file \"%s\"\n", fw2); + goto failed2; + } + ret = cypress_load_firmware(usbdev, fw, CYPRESS_FX2); + release_firmware(fw); + if (0 != ret) { + dev_err(&interface->dev, "firmware download failed\n"); + goto failed2; + } + return 0; + +failed2: + usb_put_dev(usbdev); + dev_err(&interface->dev, "probe failed\n"); + return -ENODEV; +} + +static void go7007_loader_disconnect(struct usb_interface *interface) +{ + dev_info(&interface->dev, "disconnect\n"); + usb_put_dev(interface_to_usbdev(interface)); + usb_set_intfdata(interface, NULL); +} + +static const struct usb_device_id go7007_loader_ids[] = { + { USB_DEVICE(0x1943, 0xa250) }, + { USB_DEVICE(0x093b, 0xa002) }, + { USB_DEVICE(0x093b, 0xa004) }, + { USB_DEVICE(0x0eb1, 0x6666) }, + { USB_DEVICE(0x0eb1, 0x6668) }, + {} /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE(usb, go7007_loader_ids); + +static struct usb_driver go7007_loader_driver = { + .name = "go7007-loader", + .probe = go7007_loader_probe, + .disconnect = go7007_loader_disconnect, + .id_table = go7007_loader_ids, +}; + +module_usb_driver(go7007_loader_driver); + +MODULE_AUTHOR(""); +MODULE_DESCRIPTION("firmware loader for go7007-usb"); +MODULE_LICENSE("GPL v2"); |