aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/frontends/dibx000_common.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/dvb/frontends/dibx000_common.c')
-rw-r--r--drivers/media/dvb/frontends/dibx000_common.c109
1 files changed, 65 insertions, 44 deletions
diff --git a/drivers/media/dvb/frontends/dibx000_common.c b/drivers/media/dvb/frontends/dibx000_common.c
index f6938f97feb4..dc5d17a67579 100644
--- a/drivers/media/dvb/frontends/dibx000_common.c
+++ b/drivers/media/dvb/frontends/dibx000_common.c
@@ -10,30 +10,39 @@ MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
10 10
11static int dibx000_write_word(struct dibx000_i2c_master *mst, u16 reg, u16 val) 11static int dibx000_write_word(struct dibx000_i2c_master *mst, u16 reg, u16 val)
12{ 12{
13 u8 b[4] = { 13 mst->i2c_write_buffer[0] = (reg >> 8) & 0xff;
14 (reg >> 8) & 0xff, reg & 0xff, 14 mst->i2c_write_buffer[1] = reg & 0xff;
15 (val >> 8) & 0xff, val & 0xff, 15 mst->i2c_write_buffer[2] = (val >> 8) & 0xff;
16 }; 16 mst->i2c_write_buffer[3] = val & 0xff;
17 struct i2c_msg msg = { 17
18 .addr = mst->i2c_addr,.flags = 0,.buf = b,.len = 4 18 memset(mst->msg, 0, sizeof(struct i2c_msg));
19 }; 19 mst->msg[0].addr = mst->i2c_addr;
20 20 mst->msg[0].flags = 0;
21 return i2c_transfer(mst->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0; 21 mst->msg[0].buf = mst->i2c_write_buffer;
22 mst->msg[0].len = 4;
23
24 return i2c_transfer(mst->i2c_adap, mst->msg, 1) != 1 ? -EREMOTEIO : 0;
22} 25}
23 26
24static u16 dibx000_read_word(struct dibx000_i2c_master *mst, u16 reg) 27static u16 dibx000_read_word(struct dibx000_i2c_master *mst, u16 reg)
25{ 28{
26 u8 wb[2] = { reg >> 8, reg & 0xff }; 29 mst->i2c_write_buffer[0] = reg >> 8;
27 u8 rb[2]; 30 mst->i2c_write_buffer[1] = reg & 0xff;
28 struct i2c_msg msg[2] = { 31
29 {.addr = mst->i2c_addr, .flags = 0, .buf = wb, .len = 2}, 32 memset(mst->msg, 0, 2 * sizeof(struct i2c_msg));
30 {.addr = mst->i2c_addr, .flags = I2C_M_RD, .buf = rb, .len = 2}, 33 mst->msg[0].addr = mst->i2c_addr;
31 }; 34 mst->msg[0].flags = 0;
32 35 mst->msg[0].buf = mst->i2c_write_buffer;
33 if (i2c_transfer(mst->i2c_adap, msg, 2) != 2) 36 mst->msg[0].len = 2;
37 mst->msg[1].addr = mst->i2c_addr;
38 mst->msg[1].flags = I2C_M_RD;
39 mst->msg[1].buf = mst->i2c_read_buffer;
40 mst->msg[1].len = 2;
41
42 if (i2c_transfer(mst->i2c_adap, mst->msg, 2) != 2)
34 dprintk("i2c read error on %d", reg); 43 dprintk("i2c read error on %d", reg);
35 44
36 return (rb[0] << 8) | rb[1]; 45 return (mst->i2c_read_buffer[0] << 8) | mst->i2c_read_buffer[1];
37} 46}
38 47
39static int dibx000_is_i2c_done(struct dibx000_i2c_master *mst) 48static int dibx000_is_i2c_done(struct dibx000_i2c_master *mst)
@@ -248,26 +257,32 @@ static int dibx000_i2c_gated_gpio67_xfer(struct i2c_adapter *i2c_adap,
248 struct i2c_msg msg[], int num) 257 struct i2c_msg msg[], int num)
249{ 258{
250 struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap); 259 struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
251 struct i2c_msg m[2 + num];
252 u8 tx_open[4], tx_close[4];
253 260
254 memset(m, 0, sizeof(struct i2c_msg) * (2 + num)); 261 if (num > 32) {
262 dprintk("%s: too much I2C message to be transmitted (%i).\
263 Maximum is 32", __func__, num);
264 return -ENOMEM;
265 }
266
267 memset(mst->msg, 0, sizeof(struct i2c_msg) * (2 + num));
255 268
256 dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_GPIO_6_7); 269 dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_GPIO_6_7);
257 270
258 dibx000_i2c_gate_ctrl(mst, tx_open, msg[0].addr, 1); 271 /* open the gate */
259 m[0].addr = mst->i2c_addr; 272 dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[0], msg[0].addr, 1);
260 m[0].buf = tx_open; 273 mst->msg[0].addr = mst->i2c_addr;
261 m[0].len = 4; 274 mst->msg[0].buf = &mst->i2c_write_buffer[0];
275 mst->msg[0].len = 4;
262 276
263 memcpy(&m[1], msg, sizeof(struct i2c_msg) * num); 277 memcpy(&mst->msg[1], msg, sizeof(struct i2c_msg) * num);
264 278
265 dibx000_i2c_gate_ctrl(mst, tx_close, 0, 0); 279 /* close the gate */
266 m[num + 1].addr = mst->i2c_addr; 280 dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[4], 0, 0);
267 m[num + 1].buf = tx_close; 281 mst->msg[num + 1].addr = mst->i2c_addr;
268 m[num + 1].len = 4; 282 mst->msg[num + 1].buf = &mst->i2c_write_buffer[4];
283 mst->msg[num + 1].len = 4;
269 284
270 return i2c_transfer(mst->i2c_adap, m, 2 + num) == 2 + num ? num : -EIO; 285 return i2c_transfer(mst->i2c_adap, mst->msg, 2 + num) == 2 + num ? num : -EIO;
271} 286}
272 287
273static struct i2c_algorithm dibx000_i2c_gated_gpio67_algo = { 288static struct i2c_algorithm dibx000_i2c_gated_gpio67_algo = {
@@ -279,26 +294,32 @@ static int dibx000_i2c_gated_tuner_xfer(struct i2c_adapter *i2c_adap,
279 struct i2c_msg msg[], int num) 294 struct i2c_msg msg[], int num)
280{ 295{
281 struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap); 296 struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
282 struct i2c_msg m[2 + num];
283 u8 tx_open[4], tx_close[4];
284 297
285 memset(m, 0, sizeof(struct i2c_msg) * (2 + num)); 298 if (num > 32) {
299 dprintk("%s: too much I2C message to be transmitted (%i).\
300 Maximum is 32", __func__, num);
301 return -ENOMEM;
302 }
303
304 memset(mst->msg, 0, sizeof(struct i2c_msg) * (2 + num));
286 305
287 dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_TUNER); 306 dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_TUNER);
288 307
289 dibx000_i2c_gate_ctrl(mst, tx_open, msg[0].addr, 1); 308 /* open the gate */
290 m[0].addr = mst->i2c_addr; 309 dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[0], msg[0].addr, 1);
291 m[0].buf = tx_open; 310 mst->msg[0].addr = mst->i2c_addr;
292 m[0].len = 4; 311 mst->msg[0].buf = &mst->i2c_write_buffer[0];
312 mst->msg[0].len = 4;
293 313
294 memcpy(&m[1], msg, sizeof(struct i2c_msg) * num); 314 memcpy(&mst->msg[1], msg, sizeof(struct i2c_msg) * num);
295 315
296 dibx000_i2c_gate_ctrl(mst, tx_close, 0, 0); 316 /* close the gate */
297 m[num + 1].addr = mst->i2c_addr; 317 dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[4], 0, 0);
298 m[num + 1].buf = tx_close; 318 mst->msg[num + 1].addr = mst->i2c_addr;
299 m[num + 1].len = 4; 319 mst->msg[num + 1].buf = &mst->i2c_write_buffer[4];
320 mst->msg[num + 1].len = 4;
300 321
301 return i2c_transfer(mst->i2c_adap, m, 2 + num) == 2 + num ? num : -EIO; 322 return i2c_transfer(mst->i2c_adap, mst->msg, 2 + num) == 2 + num ? num : -EIO;
302} 323}
303 324
304static struct i2c_algorithm dibx000_i2c_gated_tuner_algo = { 325static struct i2c_algorithm dibx000_i2c_gated_tuner_algo = {