aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx25840
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2009-08-31 16:57:52 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-09-12 11:19:52 -0400
commit8d81ae243158b0ac8b2c1646d5adcbdf26a260bc (patch)
tree9205ec200ec17a4a32c2a6f5dc043dd43446afb5 /drivers/media/video/cx25840
parenta65f3159244f27ce6ff84dd1bb641079acdbd396 (diff)
V4L/DVB (12613): cx25840: fix determining the firmware name
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. Cc: Jarod Wilson <jarod@wilsonet.com> Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/cx25840')
-rw-r--r--drivers/media/video/cx25840/cx25840-firmware.c35
1 files changed, 22 insertions, 13 deletions
diff --git a/drivers/media/video/cx25840/cx25840-firmware.c b/drivers/media/video/cx25840/cx25840-firmware.c
index 2a535d0403ed..1f483c1d0dbe 100644
--- a/drivers/media/video/cx25840/cx25840-firmware.c
+++ b/drivers/media/video/cx25840/cx25840-firmware.c
@@ -23,10 +23,6 @@
23 23
24#include "cx25840-core.h" 24#include "cx25840-core.h"
25 25
26#define FWFILE "v4l-cx25840.fw"
27#define FWFILE_CX23885 "v4l-cx23885-avcore-01.fw"
28#define FWFILE_CX231XX "v4l-cx231xx-avcore-01.fw"
29
30/* 26/*
31 * Mike Isely <isely@pobox.com> - The FWSEND parameter controls the 27 * Mike Isely <isely@pobox.com> - The FWSEND parameter controls the
32 * size of the firmware chunks sent down the I2C bus to the chip. 28 * size of the firmware chunks sent down the I2C bus to the chip.
@@ -40,11 +36,11 @@
40 36
41#define FWDEV(x) &((x)->dev) 37#define FWDEV(x) &((x)->dev)
42 38
43static char *firmware = FWFILE; 39static char *firmware = "";
44 40
45module_param(firmware, charp, 0444); 41module_param(firmware, charp, 0444);
46 42
47MODULE_PARM_DESC(firmware, "Firmware image [default: " FWFILE "]"); 43MODULE_PARM_DESC(firmware, "Firmware image to load");
48 44
49static void start_fw_load(struct i2c_client *client) 45static void start_fw_load(struct i2c_client *client)
50{ 46{
@@ -65,6 +61,19 @@ static void end_fw_load(struct i2c_client *client)
65 cx25840_write(client, 0x803, 0x03); 61 cx25840_write(client, 0x803, 0x03);
66} 62}
67 63
64static const char *get_fw_name(struct i2c_client *client)
65{
66 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
67
68 if (firmware[0])
69 return firmware;
70 if (state->is_cx23885)
71 return "v4l-cx23885-avcore-01.fw";
72 if (state->is_cx231xx)
73 return "v4l-cx231xx-avcore-01.fw";
74 return "v4l-cx25840.fw";
75}
76
68static int check_fw_load(struct i2c_client *client, int size) 77static int check_fw_load(struct i2c_client *client, int size)
69{ 78{
70 /* DL_ADDR_HB DL_ADDR_LB */ 79 /* DL_ADDR_HB DL_ADDR_LB */
@@ -72,11 +81,13 @@ static int check_fw_load(struct i2c_client *client, int size)
72 s |= cx25840_read(client, 0x800); 81 s |= cx25840_read(client, 0x800);
73 82
74 if (size != s) { 83 if (size != s) {
75 v4l_err(client, "firmware %s load failed\n", firmware); 84 v4l_err(client, "firmware %s load failed\n",
85 get_fw_name(client));
76 return -EINVAL; 86 return -EINVAL;
77 } 87 }
78 88
79 v4l_info(client, "loaded %s firmware (%d bytes)\n", firmware, size); 89 v4l_info(client, "loaded %s firmware (%d bytes)\n",
90 get_fw_name(client), size);
80 return 0; 91 return 0;
81} 92}
82 93
@@ -96,26 +107,24 @@ int cx25840_loadfw(struct i2c_client *client)
96 const struct firmware *fw = NULL; 107 const struct firmware *fw = NULL;
97 u8 buffer[FWSEND]; 108 u8 buffer[FWSEND];
98 const u8 *ptr; 109 const u8 *ptr;
110 const char *fwname = get_fw_name(client);
99 int size, retval; 111 int size, retval;
100 int MAX_BUF_SIZE = FWSEND; 112 int MAX_BUF_SIZE = FWSEND;
101 u32 gpio_oe = 0, gpio_da = 0; 113 u32 gpio_oe = 0, gpio_da = 0;
102 114
103 if (state->is_cx23885) { 115 if (state->is_cx23885) {
104 firmware = FWFILE_CX23885;
105 /* Preserve the GPIO OE and output bits */ 116 /* Preserve the GPIO OE and output bits */
106 gpio_oe = cx25840_read(client, 0x160); 117 gpio_oe = cx25840_read(client, 0x160);
107 gpio_da = cx25840_read(client, 0x164); 118 gpio_da = cx25840_read(client, 0x164);
108 } 119 }
109 else if (state->is_cx231xx)
110 firmware = FWFILE_CX231XX;
111 120
112 if ((state->is_cx231xx) && MAX_BUF_SIZE > 16) { 121 if ((state->is_cx231xx) && MAX_BUF_SIZE > 16) {
113 v4l_err(client, " Firmware download size changed to 16 bytes max length\n"); 122 v4l_err(client, " Firmware download size changed to 16 bytes max length\n");
114 MAX_BUF_SIZE = 16; /* cx231xx cannot accept more than 16 bytes at a time */ 123 MAX_BUF_SIZE = 16; /* cx231xx cannot accept more than 16 bytes at a time */
115 } 124 }
116 125
117 if (request_firmware(&fw, firmware, FWDEV(client)) != 0) { 126 if (request_firmware(&fw, fwname, FWDEV(client)) != 0) {
118 v4l_err(client, "unable to open firmware %s\n", firmware); 127 v4l_err(client, "unable to open firmware %s\n", fwname);
119 return -EINVAL; 128 return -EINVAL;
120 } 129 }
121 130