diff options
Diffstat (limited to 'drivers/media/dvb/frontends/dibx000_common.c')
-rw-r--r-- | drivers/media/dvb/frontends/dibx000_common.c | 109 |
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 | ||
11 | static int dibx000_write_word(struct dibx000_i2c_master *mst, u16 reg, u16 val) | 11 | static 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 | ||
24 | static u16 dibx000_read_word(struct dibx000_i2c_master *mst, u16 reg) | 27 | static 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 | ||
39 | static int dibx000_is_i2c_done(struct dibx000_i2c_master *mst) | 48 | static 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 | ||
273 | static struct i2c_algorithm dibx000_i2c_gated_gpio67_algo = { | 288 | static 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 | ||
304 | static struct i2c_algorithm dibx000_i2c_gated_tuner_algo = { | 325 | static struct i2c_algorithm dibx000_i2c_gated_tuner_algo = { |