diff options
Diffstat (limited to 'linux/drivers/media/video/cx25840/cx25840-firmware.c')
-rw-r--r-- | linux/drivers/media/video/cx25840/cx25840-firmware.c | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/linux/drivers/media/video/cx25840/cx25840-firmware.c b/linux/drivers/media/video/cx25840/cx25840-firmware.c index 01fbe174e..bdc630f0f 100644 --- a/linux/drivers/media/video/cx25840/cx25840-firmware.c +++ b/linux/drivers/media/video/cx25840/cx25840-firmware.c @@ -26,6 +26,7 @@ #define FWFILE "v4l-cx25840.fw" #define FWFILE_CX23885 "v4l-cx23885-avcore-01.fw" +#define FWFILE_CX231XX "v4l-cx231xx-avcore-01.fw" /* * Mike Isely <isely@pobox.com> - The FWSEND parameter controls the @@ -97,9 +98,22 @@ int cx25840_loadfw(struct i2c_client *client) u8 buffer[FWSEND]; const u8 *ptr; int size, retval; + int MAX_BUF_SIZE = FWSEND; + u32 gpio_oe = 0, gpio_da = 0; - if (state->is_cx23885) + if (state->is_cx23885) { firmware = FWFILE_CX23885; + /* Preserve the GPIO OE and output bits */ + gpio_oe = cx25840_read(client, 0x160); + gpio_da = cx25840_read(client, 0x164); + } + else if (state->is_cx231xx) + firmware = FWFILE_CX231XX; + + if ((state->is_cx231xx) && MAX_BUF_SIZE > 16) { + v4l_err(client, " Firmware download size changed to 16 bytes max length\n"); + MAX_BUF_SIZE = 16; /* cx231xx cannot accept more than 16 bytes at a time */ + } if (request_firmware(&fw, firmware, FWDEV(client)) != 0) { v4l_err(client, "unable to open firmware %s\n", firmware); @@ -114,7 +128,7 @@ int cx25840_loadfw(struct i2c_client *client) size = fw->size; ptr = fw->data; while (size > 0) { - int len = min(FWSEND - 2, size); + int len = min(MAX_BUF_SIZE - 2, size); memcpy(buffer + 2, ptr, len); @@ -134,5 +148,11 @@ int cx25840_loadfw(struct i2c_client *client) size = fw->size; release_firmware(fw); + if (state->is_cx23885) { + /* Restore GPIO configuration after f/w load */ + cx25840_write(client, 0x160, gpio_oe); + cx25840_write(client, 0x164, gpio_da); + } + return check_fw_load(client, size); } |