diff options
author | Antti Palosaari | 2012-06-04 16:36:09 -0300 |
---|---|---|
committer | Mauro Carvalho Chehab | 2012-08-04 07:56:25 -0300 |
commit | a0d72d246d124096cad0b4bbce8a893e913f08a1 (patch) | |
tree | 0c92826430bee2f8ebb1845d1a706aace27b1437 /drivers | |
parent | 21f5a32e1f0a4ae086e4985d4a949e7289440c3a (diff) |
[media] dvb_usb_v2: clean firmware downloading routines
Remove Cypress USB-interface firmware downloading routines.
That is common module and having single vendor chip routines
in common module is wrong. Just move those elsewhere.
Move single function out from the dvb_usb_firmware.c and
remove that file.
Signed-off-by: Antti Palosaari <crope@iki.fi>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/dvb/dvb-usb/dvb_usb.h | 19 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/dvb_usb_firmware.c | 176 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/dvb_usb_init.c | 42 |
3 files changed, 42 insertions, 195 deletions
diff --git a/drivers/media/dvb/dvb-usb/dvb_usb.h b/drivers/media/dvb/dvb-usb/dvb_usb.h index c6144bb9b82d..4aa5bd190aec 100644 --- a/drivers/media/dvb/dvb-usb/dvb_usb.h +++ b/drivers/media/dvb/dvb-usb/dvb_usb.h @@ -204,12 +204,6 @@ struct dvb_usb_device_properties { #define DVB_USB_IS_AN_I2C_ADAPTER 0x01 int caps; -#define DEVICE_SPECIFIC 0 -#define CYPRESS_AN2135 1 -#define CYPRESS_AN2235 2 -#define CYPRESS_FX2 3 - int usb_ctrl; - int size_of_priv; const char *firmware; @@ -398,17 +392,4 @@ extern int dvb_usbv2_generic_rw(struct dvb_usb_device *, u8 *, u16, u8 *, u16, int); extern int dvb_usbv2_generic_write(struct dvb_usb_device *, u8 *, u16); -/* commonly used firmware download types and function */ -struct hexline { - u8 len; - u32 addr; - u8 type; - u8 data[255]; - u8 chk; -}; -extern int usbv2_cypress_load_firmware(struct usb_device *udev, - const struct firmware *fw, int type); -extern int dvb_usbv2_get_hexline(const struct firmware *fw, struct hexline *hx, - int *pos); - #endif diff --git a/drivers/media/dvb/dvb-usb/dvb_usb_firmware.c b/drivers/media/dvb/dvb-usb/dvb_usb_firmware.c deleted file mode 100644 index e0b43139c0c4..000000000000 --- a/drivers/media/dvb/dvb-usb/dvb_usb_firmware.c +++ /dev/null @@ -1,176 +0,0 @@ -/* dvb-usb-firmware.c is part of the DVB USB library. - * - * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de) - * see dvb-usb-init.c for copyright information. - * - * This file contains functions for downloading the firmware to Cypress FX 1 - * and 2 based devices. - * - * FIXME: This part does actually not belong to dvb-usb, but to the - * usb-subsystem. - */ -#include "dvb_usb_common.h" - -#include <linux/usb.h> - -struct usb_cypress_controller { - int id; - /* name of the usb controller */ - const char *name; - /* needs to be restarted, when the firmware has been downloaded. */ - u16 cpu_cs_register; -}; - -static struct usb_cypress_controller cypress[] = { - { .id = DEVICE_SPECIFIC, .name = "Device specific", - .cpu_cs_register = 0 }, - { .id = CYPRESS_AN2135, .name = "Cypress AN2135", - .cpu_cs_register = 0x7f92 }, - { .id = CYPRESS_AN2235, .name = "Cypress AN2235", - .cpu_cs_register = 0x7f92 }, - { .id = CYPRESS_FX2, .name = "Cypress FX2", - .cpu_cs_register = 0xe600 }, -}; - -/* - * load a firmware packet to the device - */ -static int usb_cypress_writemem(struct usb_device *udev, u16 addr, u8 *data, - u8 len) -{ - return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - 0xa0, USB_TYPE_VENDOR, addr, 0x00, data, len, 5000); -} - -int usbv2_cypress_load_firmware(struct usb_device *udev, - const struct firmware *fw, int type) -{ - struct hexline hx; - u8 reset; - int ret, pos = 0; - - /* stop the CPU */ - reset = 1; - ret = usb_cypress_writemem(udev, cypress[type].cpu_cs_register, - &reset, 1); - if (ret != 1) - err("could not stop the USB controller CPU."); - - while ((ret = dvb_usbv2_get_hexline(fw, &hx, &pos)) > 0) { - deb_fw("writing to address 0x%04x (buffer: 0x%02x %02x)\n", - hx.addr, hx.len, hx.chk); - ret = usb_cypress_writemem(udev, hx.addr, hx.data, hx.len); - - if (ret != hx.len) { - err("error while transferring firmware " \ - "(transferred size: %d, block size: %d)", - ret, hx.len); - ret = -EINVAL; - break; - } - } - if (ret < 0) { - err("firmware download failed at %d with %d", pos, ret); - return ret; - } - - if (ret == 0) { - /* restart the CPU */ - reset = 0; - if (ret || usb_cypress_writemem(udev, - cypress[type].cpu_cs_register, - &reset, 1) != 1) { - err("could not restart the USB controller CPU."); - ret = -EINVAL; - } - } else - ret = -EIO; - - return ret; -} -EXPORT_SYMBOL(usbv2_cypress_load_firmware); - -int dvb_usb_download_firmware(struct dvb_usb_device *d) -{ - int ret; - const struct firmware *fw = NULL; - const char *name; - - /* resolve firmware name */ - name = d->props.firmware; - if (d->props.get_firmware_name) { - ret = d->props.get_firmware_name(d, &name); - if (ret < 0) - return ret; - } - - ret = request_firmware(&fw, name, &d->udev->dev); - if (ret != 0) { - err("did not find the firmware file. (%s) " \ - "Please see linux/Documentation/dvb/ for more" \ - " details on firmware-problems. (%d)", - name, ret); - return ret; - } - - info("downloading firmware from file '%s'", name); - - switch (d->props.usb_ctrl) { - case CYPRESS_AN2135: - case CYPRESS_AN2235: - case CYPRESS_FX2: - ret = usbv2_cypress_load_firmware(d->udev, fw, - d->props.usb_ctrl); - break; - case DEVICE_SPECIFIC: - if (d->props.download_firmware) - ret = d->props.download_firmware(d, fw); - else { - err("BUG: driver didn't specified a download_firmware" \ - "-callback, although it claims to have a" \ - " DEVICE_SPECIFIC one."); - ret = -EINVAL; - } - break; - default: - ret = -EINVAL; - break; - } - - release_firmware(fw); - return ret; -} - -int dvb_usbv2_get_hexline(const struct firmware *fw, struct hexline *hx, - int *pos) -{ - u8 *b = (u8 *) &fw->data[*pos]; - int data_offs = 4; - if (*pos >= fw->size) - return 0; - - memset(hx, 0, sizeof(struct hexline)); - - hx->len = b[0]; - - if ((*pos + hx->len + 4) >= fw->size) - return -EINVAL; - - hx->addr = b[1] | (b[2] << 8); - hx->type = b[3]; - - if (hx->type == 0x04) { - /* b[4] and b[5] are the Extended linear address record data - * field */ - hx->addr |= (b[4] << 24) | (b[5] << 16); -/* hx->len -= 2; - data_offs += 2; */ - } - memcpy(hx->data, &b[data_offs], hx->len); - hx->chk = b[hx->len + data_offs]; - - *pos += hx->len + 5; - - return *pos; -} -EXPORT_SYMBOL(dvb_usbv2_get_hexline); diff --git a/drivers/media/dvb/dvb-usb/dvb_usb_init.c b/drivers/media/dvb/dvb-usb/dvb_usb_init.c index 561ceb69144f..6e0903989484 100644 --- a/drivers/media/dvb/dvb-usb/dvb_usb_init.c +++ b/drivers/media/dvb/dvb-usb/dvb_usb_init.c @@ -31,6 +31,48 @@ module_param_named(force_pid_filter_usage, dvb_usb_force_pid_filter_usage, MODULE_PARM_DESC(force_pid_filter_usage, "force all dvb-usb-devices to use a" \ " PID filter, if any (default: 0)."); +int dvb_usb_download_firmware(struct dvb_usb_device *d) +{ + int ret; + const struct firmware *fw = NULL; + const char *name; + + /* resolve firmware name */ + name = d->props.firmware; + if (d->props.get_firmware_name) { + ret = d->props.get_firmware_name(d, &name); + if (ret < 0) + return ret; + } + + if (!d->props.download_firmware) { + ret = -EINVAL; + goto err; + } + + ret = request_firmware(&fw, name, &d->udev->dev); + if (ret < 0) { + err("did not find the firmware file. (%s) " \ + "Please see linux/Documentation/dvb/ for more" \ + " details on firmware-problems. (%d)", name, ret); + goto err; + } + + info("downloading firmware from file '%s'", name); + + ret = d->props.download_firmware(d, fw); + + release_firmware(fw); + + if (ret < 0) + goto err; + + return 0; +err: + pr_debug("%s: failed=%d\n", __func__, ret); + return ret; +} + static int dvb_usb_adapter_init(struct dvb_usb_device *d) { struct dvb_usb_adapter *adap; |