From e568b608a89f187c88cbbff8149047e16754aec7 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Thu, 23 Jul 2009 11:18:54 -0400 Subject: cx25840: Bugfix for no DVB-T on the Hauppauge HVR-1700 From: Steven Toth After the i2c subdev changes the ordering of initialization changed, causing a total loss of previous GPIO settings and a loss of DTV. The generic firmware loading routine has now changed to preserve GPIO values if the device is cx23885 based (safety) and I've moved the GPIO configuration from probe() into the cx23885 init func which is a little clearer and fixes the bug. Priority: normal Tested-By: Sohail Syyed Reviewed-by: Michael Krufky Signed-off-by: Steven Toth --- linux/drivers/media/video/cx25840/cx25840-core.c | 15 +++++++++------ linux/drivers/media/video/cx25840/cx25840-firmware.c | 13 ++++++++++++- 2 files changed, 21 insertions(+), 7 deletions(-) (limited to 'linux/drivers/media/video/cx25840') diff --git a/linux/drivers/media/video/cx25840/cx25840-core.c b/linux/drivers/media/video/cx25840/cx25840-core.c index 2929bf3b7..557a3eaa1 100644 --- a/linux/drivers/media/video/cx25840/cx25840-core.c +++ b/linux/drivers/media/video/cx25840/cx25840-core.c @@ -341,6 +341,15 @@ static void cx23885_initialize(struct i2c_client *client) /* Select AFE clock pad output source */ cx25840_write(client, 0x144, 0x05); + /* Drive GPIO2 direction and values for HVR1700 + * where an onboard mux selects the output of demodulator + * vs the 417. Failure to set this results in no DTV. + * It's safe to set this across all Hauppauge boards + * currently, regardless of the board type. + */ + cx25840_write(client, 0x160, 0x1d); + cx25840_write(client, 0x164, 0x00); + /* Do the firmware load in a work handler to prevent. Otherwise the kernel is blocked waiting for the bit-banging i2c interface to finish uploading the @@ -1610,12 +1619,6 @@ static int cx25840_probe(struct i2c_client *client, state->id = id; state->rev = device_id; - if (state->is_cx23885) { - /* Drive GPIO2 direction and values */ - cx25840_write(client, 0x160, 0x1d); - cx25840_write(client, 0x164, 0x00); - } - return 0; } diff --git a/linux/drivers/media/video/cx25840/cx25840-firmware.c b/linux/drivers/media/video/cx25840/cx25840-firmware.c index f01456ec4..bdc630f0f 100644 --- a/linux/drivers/media/video/cx25840/cx25840-firmware.c +++ b/linux/drivers/media/video/cx25840/cx25840-firmware.c @@ -99,9 +99,14 @@ int cx25840_loadfw(struct i2c_client *client) 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; @@ -143,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); } -- cgit v1.2.3 From 158fd570dbf7a826c6578d5b5a9036dc58059371 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 31 Aug 2009 22:57:52 +0200 Subject: cx25840: fix determining the firmware name From: Hans Verkuil Depending on the model there are three different firmwares to choose from. Unfortunately if a cx23885 is loaded first, then the global firmware name is overwritten with that firmware and if ivtv is loaded next, then it tries to load the wrong firmware. In addition, the original approach would also overwrite any firmware that the user specified explicitly. Priority: normal Signed-off-by: Hans Verkuil CC: Jarod Wilson --- .../drivers/media/video/cx25840/cx25840-firmware.c | 35 ++++++++++++++-------- 1 file changed, 22 insertions(+), 13 deletions(-) (limited to 'linux/drivers/media/video/cx25840') diff --git a/linux/drivers/media/video/cx25840/cx25840-firmware.c b/linux/drivers/media/video/cx25840/cx25840-firmware.c index bdc630f0f..a19ab8644 100644 --- a/linux/drivers/media/video/cx25840/cx25840-firmware.c +++ b/linux/drivers/media/video/cx25840/cx25840-firmware.c @@ -24,10 +24,6 @@ #include "cx25840-core.h" -#define FWFILE "v4l-cx25840.fw" -#define FWFILE_CX23885 "v4l-cx23885-avcore-01.fw" -#define FWFILE_CX231XX "v4l-cx231xx-avcore-01.fw" - /* * Mike Isely - The FWSEND parameter controls the * size of the firmware chunks sent down the I2C bus to the chip. @@ -41,11 +37,11 @@ #define FWDEV(x) &((x)->dev) -static char *firmware = FWFILE; +static char *firmware = ""; module_param(firmware, charp, 0444); -MODULE_PARM_DESC(firmware, "Firmware image [default: " FWFILE "]"); +MODULE_PARM_DESC(firmware, "Firmware image to load"); static void start_fw_load(struct i2c_client *client) { @@ -66,6 +62,19 @@ static void end_fw_load(struct i2c_client *client) cx25840_write(client, 0x803, 0x03); } +static const char *get_fw_name(struct i2c_client *client) +{ + struct cx25840_state *state = to_state(i2c_get_clientdata(client)); + + if (firmware[0]) + return firmware; + if (state->is_cx23885) + return "v4l-cx23885-avcore-01.fw"; + if (state->is_cx231xx) + return "v4l-cx231xx-avcore-01.fw"; + return "v4l-cx25840.fw"; +} + static int check_fw_load(struct i2c_client *client, int size) { /* DL_ADDR_HB DL_ADDR_LB */ @@ -73,11 +82,13 @@ static int check_fw_load(struct i2c_client *client, int size) s |= cx25840_read(client, 0x800); if (size != s) { - v4l_err(client, "firmware %s load failed\n", firmware); + v4l_err(client, "firmware %s load failed\n", + get_fw_name(client)); return -EINVAL; } - v4l_info(client, "loaded %s firmware (%d bytes)\n", firmware, size); + v4l_info(client, "loaded %s firmware (%d bytes)\n", + get_fw_name(client), size); return 0; } @@ -97,26 +108,24 @@ int cx25840_loadfw(struct i2c_client *client) const struct firmware *fw = NULL; u8 buffer[FWSEND]; const u8 *ptr; + const char *fwname = get_fw_name(client); int size, retval; int MAX_BUF_SIZE = FWSEND; u32 gpio_oe = 0, gpio_da = 0; 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); + if (request_firmware(&fw, fwname, FWDEV(client)) != 0) { + v4l_err(client, "unable to open firmware %s\n", fwname); return -EINVAL; } -- cgit v1.2.3