diff options
Diffstat (limited to 'drivers/media/usb/cx231xx/cx231xx-i2c.c')
-rw-r--r-- | drivers/media/usb/cx231xx/cx231xx-i2c.c | 532 |
1 files changed, 532 insertions, 0 deletions
diff --git a/drivers/media/usb/cx231xx/cx231xx-i2c.c b/drivers/media/usb/cx231xx/cx231xx-i2c.c new file mode 100644 index 000000000000..781feed406f7 --- /dev/null +++ b/drivers/media/usb/cx231xx/cx231xx-i2c.c | |||
@@ -0,0 +1,532 @@ | |||
1 | /* | ||
2 | cx231xx-i2c.c - driver for Conexant Cx23100/101/102 USB video capture devices | ||
3 | |||
4 | Copyright (C) 2008 <srinivasa.deevi at conexant dot com> | ||
5 | Based on em28xx driver | ||
6 | Based on Cx23885 driver | ||
7 | |||
8 | This program is free software; you can redistribute it and/or modify | ||
9 | it under the terms of the GNU General Public License as published by | ||
10 | the Free Software Foundation; either version 2 of the License, or | ||
11 | (at your option) any later version. | ||
12 | |||
13 | This program is distributed in the hope that it will be useful, | ||
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | GNU General Public License for more details. | ||
17 | |||
18 | You should have received a copy of the GNU General Public License | ||
19 | along with this program; if not, write to the Free Software | ||
20 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
21 | */ | ||
22 | |||
23 | #include <linux/module.h> | ||
24 | #include <linux/kernel.h> | ||
25 | #include <linux/usb.h> | ||
26 | #include <linux/i2c.h> | ||
27 | #include <media/v4l2-common.h> | ||
28 | #include <media/tuner.h> | ||
29 | |||
30 | #include "cx231xx.h" | ||
31 | |||
32 | /* ----------------------------------------------------------- */ | ||
33 | |||
34 | static unsigned int i2c_scan; | ||
35 | module_param(i2c_scan, int, 0444); | ||
36 | MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time"); | ||
37 | |||
38 | static unsigned int i2c_debug; | ||
39 | module_param(i2c_debug, int, 0644); | ||
40 | MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]"); | ||
41 | |||
42 | #define dprintk1(lvl, fmt, args...) \ | ||
43 | do { \ | ||
44 | if (i2c_debug >= lvl) { \ | ||
45 | printk(fmt, ##args); \ | ||
46 | } \ | ||
47 | } while (0) | ||
48 | |||
49 | #define dprintk2(lvl, fmt, args...) \ | ||
50 | do { \ | ||
51 | if (i2c_debug >= lvl) { \ | ||
52 | printk(KERN_DEBUG "%s at %s: " fmt, \ | ||
53 | dev->name, __func__ , ##args); \ | ||
54 | } \ | ||
55 | } while (0) | ||
56 | |||
57 | static inline bool is_tuner(struct cx231xx *dev, struct cx231xx_i2c *bus, | ||
58 | const struct i2c_msg *msg, int tuner_type) | ||
59 | { | ||
60 | if (bus->nr != dev->board.tuner_i2c_master) | ||
61 | return false; | ||
62 | |||
63 | if (msg->addr != dev->board.tuner_addr) | ||
64 | return false; | ||
65 | |||
66 | if (dev->tuner_type != tuner_type) | ||
67 | return false; | ||
68 | |||
69 | return true; | ||
70 | } | ||
71 | |||
72 | /* | ||
73 | * cx231xx_i2c_send_bytes() | ||
74 | */ | ||
75 | int cx231xx_i2c_send_bytes(struct i2c_adapter *i2c_adap, | ||
76 | const struct i2c_msg *msg) | ||
77 | { | ||
78 | struct cx231xx_i2c *bus = i2c_adap->algo_data; | ||
79 | struct cx231xx *dev = bus->dev; | ||
80 | struct cx231xx_i2c_xfer_data req_data; | ||
81 | int status = 0; | ||
82 | u16 size = 0; | ||
83 | u8 loop = 0; | ||
84 | u8 saddr_len = 1; | ||
85 | u8 *buf_ptr = NULL; | ||
86 | u16 saddr = 0; | ||
87 | u8 need_gpio = 0; | ||
88 | |||
89 | if (is_tuner(dev, bus, msg, TUNER_XC5000)) { | ||
90 | size = msg->len; | ||
91 | |||
92 | if (size == 2) { /* register write sub addr */ | ||
93 | /* Just writing sub address will cause problem | ||
94 | * to XC5000. So ignore the request */ | ||
95 | return 0; | ||
96 | } else if (size == 4) { /* register write with sub addr */ | ||
97 | if (msg->len >= 2) | ||
98 | saddr = msg->buf[0] << 8 | msg->buf[1]; | ||
99 | else if (msg->len == 1) | ||
100 | saddr = msg->buf[0]; | ||
101 | |||
102 | switch (saddr) { | ||
103 | case 0x0000: /* start tuner calibration mode */ | ||
104 | need_gpio = 1; | ||
105 | /* FW Loading is done */ | ||
106 | dev->xc_fw_load_done = 1; | ||
107 | break; | ||
108 | case 0x000D: /* Set signal source */ | ||
109 | case 0x0001: /* Set TV standard - Video */ | ||
110 | case 0x0002: /* Set TV standard - Audio */ | ||
111 | case 0x0003: /* Set RF Frequency */ | ||
112 | need_gpio = 1; | ||
113 | break; | ||
114 | default: | ||
115 | if (dev->xc_fw_load_done) | ||
116 | need_gpio = 1; | ||
117 | break; | ||
118 | } | ||
119 | |||
120 | if (need_gpio) { | ||
121 | dprintk1(1, | ||
122 | "GPIO WRITE: addr 0x%x, len %d, saddr 0x%x\n", | ||
123 | msg->addr, msg->len, saddr); | ||
124 | |||
125 | return dev->cx231xx_gpio_i2c_write(dev, | ||
126 | msg->addr, | ||
127 | msg->buf, | ||
128 | msg->len); | ||
129 | } | ||
130 | } | ||
131 | |||
132 | /* special case for Xc5000 tuner case */ | ||
133 | saddr_len = 1; | ||
134 | |||
135 | /* adjust the length to correct length */ | ||
136 | size -= saddr_len; | ||
137 | buf_ptr = (u8 *) (msg->buf + 1); | ||
138 | |||
139 | do { | ||
140 | /* prepare xfer_data struct */ | ||
141 | req_data.dev_addr = msg->addr; | ||
142 | req_data.direction = msg->flags; | ||
143 | req_data.saddr_len = saddr_len; | ||
144 | req_data.saddr_dat = msg->buf[0]; | ||
145 | req_data.buf_size = size > 16 ? 16 : size; | ||
146 | req_data.p_buffer = (u8 *) (buf_ptr + loop * 16); | ||
147 | |||
148 | bus->i2c_nostop = (size > 16) ? 1 : 0; | ||
149 | bus->i2c_reserve = (loop == 0) ? 0 : 1; | ||
150 | |||
151 | /* usb send command */ | ||
152 | status = dev->cx231xx_send_usb_command(bus, &req_data); | ||
153 | loop++; | ||
154 | |||
155 | if (size >= 16) | ||
156 | size -= 16; | ||
157 | else | ||
158 | size = 0; | ||
159 | |||
160 | } while (size > 0); | ||
161 | |||
162 | bus->i2c_nostop = 0; | ||
163 | bus->i2c_reserve = 0; | ||
164 | |||
165 | } else { /* regular case */ | ||
166 | |||
167 | /* prepare xfer_data struct */ | ||
168 | req_data.dev_addr = msg->addr; | ||
169 | req_data.direction = msg->flags; | ||
170 | req_data.saddr_len = 0; | ||
171 | req_data.saddr_dat = 0; | ||
172 | req_data.buf_size = msg->len; | ||
173 | req_data.p_buffer = msg->buf; | ||
174 | |||
175 | /* usb send command */ | ||
176 | status = dev->cx231xx_send_usb_command(bus, &req_data); | ||
177 | } | ||
178 | |||
179 | return status < 0 ? status : 0; | ||
180 | } | ||
181 | |||
182 | /* | ||
183 | * cx231xx_i2c_recv_bytes() | ||
184 | * read a byte from the i2c device | ||
185 | */ | ||
186 | static int cx231xx_i2c_recv_bytes(struct i2c_adapter *i2c_adap, | ||
187 | const struct i2c_msg *msg) | ||
188 | { | ||
189 | struct cx231xx_i2c *bus = i2c_adap->algo_data; | ||
190 | struct cx231xx *dev = bus->dev; | ||
191 | struct cx231xx_i2c_xfer_data req_data; | ||
192 | int status = 0; | ||
193 | u16 saddr = 0; | ||
194 | u8 need_gpio = 0; | ||
195 | |||
196 | if (is_tuner(dev, bus, msg, TUNER_XC5000)) { | ||
197 | if (msg->len == 2) | ||
198 | saddr = msg->buf[0] << 8 | msg->buf[1]; | ||
199 | else if (msg->len == 1) | ||
200 | saddr = msg->buf[0]; | ||
201 | |||
202 | if (dev->xc_fw_load_done) { | ||
203 | |||
204 | switch (saddr) { | ||
205 | case 0x0009: /* BUSY check */ | ||
206 | dprintk1(1, | ||
207 | "GPIO R E A D: Special case BUSY check \n"); | ||
208 | /*Try read BUSY register, just set it to zero*/ | ||
209 | msg->buf[0] = 0; | ||
210 | if (msg->len == 2) | ||
211 | msg->buf[1] = 0; | ||
212 | return 0; | ||
213 | case 0x0004: /* read Lock status */ | ||
214 | need_gpio = 1; | ||
215 | break; | ||
216 | |||
217 | } | ||
218 | |||
219 | if (need_gpio) { | ||
220 | /* this is a special case to handle Xceive tuner | ||
221 | clock stretch issue with gpio based I2C */ | ||
222 | |||
223 | dprintk1(1, | ||
224 | "GPIO R E A D: addr 0x%x, len %d, saddr 0x%x\n", | ||
225 | msg->addr, msg->len, | ||
226 | msg->buf[0] << 8 | msg->buf[1]); | ||
227 | |||
228 | status = | ||
229 | dev->cx231xx_gpio_i2c_write(dev, msg->addr, | ||
230 | msg->buf, | ||
231 | msg->len); | ||
232 | status = | ||
233 | dev->cx231xx_gpio_i2c_read(dev, msg->addr, | ||
234 | msg->buf, | ||
235 | msg->len); | ||
236 | return status; | ||
237 | } | ||
238 | } | ||
239 | |||
240 | /* prepare xfer_data struct */ | ||
241 | req_data.dev_addr = msg->addr; | ||
242 | req_data.direction = msg->flags; | ||
243 | req_data.saddr_len = msg->len; | ||
244 | req_data.saddr_dat = msg->buf[0] << 8 | msg->buf[1]; | ||
245 | req_data.buf_size = msg->len; | ||
246 | req_data.p_buffer = msg->buf; | ||
247 | |||
248 | /* usb send command */ | ||
249 | status = dev->cx231xx_send_usb_command(bus, &req_data); | ||
250 | |||
251 | } else { | ||
252 | |||
253 | /* prepare xfer_data struct */ | ||
254 | req_data.dev_addr = msg->addr; | ||
255 | req_data.direction = msg->flags; | ||
256 | req_data.saddr_len = 0; | ||
257 | req_data.saddr_dat = 0; | ||
258 | req_data.buf_size = msg->len; | ||
259 | req_data.p_buffer = msg->buf; | ||
260 | |||
261 | /* usb send command */ | ||
262 | status = dev->cx231xx_send_usb_command(bus, &req_data); | ||
263 | } | ||
264 | |||
265 | return status < 0 ? status : 0; | ||
266 | } | ||
267 | |||
268 | /* | ||
269 | * cx231xx_i2c_recv_bytes_with_saddr() | ||
270 | * read a byte from the i2c device | ||
271 | */ | ||
272 | static int cx231xx_i2c_recv_bytes_with_saddr(struct i2c_adapter *i2c_adap, | ||
273 | const struct i2c_msg *msg1, | ||
274 | const struct i2c_msg *msg2) | ||
275 | { | ||
276 | struct cx231xx_i2c *bus = i2c_adap->algo_data; | ||
277 | struct cx231xx *dev = bus->dev; | ||
278 | struct cx231xx_i2c_xfer_data req_data; | ||
279 | int status = 0; | ||
280 | u16 saddr = 0; | ||
281 | u8 need_gpio = 0; | ||
282 | |||
283 | if (msg1->len == 2) | ||
284 | saddr = msg1->buf[0] << 8 | msg1->buf[1]; | ||
285 | else if (msg1->len == 1) | ||
286 | saddr = msg1->buf[0]; | ||
287 | |||
288 | if (is_tuner(dev, bus, msg2, TUNER_XC5000)) { | ||
289 | if ((msg2->len < 16)) { | ||
290 | |||
291 | dprintk1(1, | ||
292 | "i2c_read: addr 0x%x, len %d, saddr 0x%x, len %d\n", | ||
293 | msg2->addr, msg2->len, saddr, msg1->len); | ||
294 | |||
295 | switch (saddr) { | ||
296 | case 0x0008: /* read FW load status */ | ||
297 | need_gpio = 1; | ||
298 | break; | ||
299 | case 0x0004: /* read Lock status */ | ||
300 | need_gpio = 1; | ||
301 | break; | ||
302 | } | ||
303 | |||
304 | if (need_gpio) { | ||
305 | status = | ||
306 | dev->cx231xx_gpio_i2c_write(dev, msg1->addr, | ||
307 | msg1->buf, | ||
308 | msg1->len); | ||
309 | status = | ||
310 | dev->cx231xx_gpio_i2c_read(dev, msg2->addr, | ||
311 | msg2->buf, | ||
312 | msg2->len); | ||
313 | return status; | ||
314 | } | ||
315 | } | ||
316 | } | ||
317 | |||
318 | /* prepare xfer_data struct */ | ||
319 | req_data.dev_addr = msg2->addr; | ||
320 | req_data.direction = msg2->flags; | ||
321 | req_data.saddr_len = msg1->len; | ||
322 | req_data.saddr_dat = saddr; | ||
323 | req_data.buf_size = msg2->len; | ||
324 | req_data.p_buffer = msg2->buf; | ||
325 | |||
326 | /* usb send command */ | ||
327 | status = dev->cx231xx_send_usb_command(bus, &req_data); | ||
328 | |||
329 | return status < 0 ? status : 0; | ||
330 | } | ||
331 | |||
332 | /* | ||
333 | * cx231xx_i2c_check_for_device() | ||
334 | * check if there is a i2c_device at the supplied address | ||
335 | */ | ||
336 | static int cx231xx_i2c_check_for_device(struct i2c_adapter *i2c_adap, | ||
337 | const struct i2c_msg *msg) | ||
338 | { | ||
339 | struct cx231xx_i2c *bus = i2c_adap->algo_data; | ||
340 | struct cx231xx *dev = bus->dev; | ||
341 | struct cx231xx_i2c_xfer_data req_data; | ||
342 | int status = 0; | ||
343 | |||
344 | /* prepare xfer_data struct */ | ||
345 | req_data.dev_addr = msg->addr; | ||
346 | req_data.direction = msg->flags; | ||
347 | req_data.saddr_len = 0; | ||
348 | req_data.saddr_dat = 0; | ||
349 | req_data.buf_size = 0; | ||
350 | req_data.p_buffer = NULL; | ||
351 | |||
352 | /* usb send command */ | ||
353 | status = dev->cx231xx_send_usb_command(bus, &req_data); | ||
354 | |||
355 | return status < 0 ? status : 0; | ||
356 | } | ||
357 | |||
358 | /* | ||
359 | * cx231xx_i2c_xfer() | ||
360 | * the main i2c transfer function | ||
361 | */ | ||
362 | static int cx231xx_i2c_xfer(struct i2c_adapter *i2c_adap, | ||
363 | struct i2c_msg msgs[], int num) | ||
364 | { | ||
365 | struct cx231xx_i2c *bus = i2c_adap->algo_data; | ||
366 | struct cx231xx *dev = bus->dev; | ||
367 | int addr, rc, i, byte; | ||
368 | |||
369 | if (num <= 0) | ||
370 | return 0; | ||
371 | mutex_lock(&dev->i2c_lock); | ||
372 | for (i = 0; i < num; i++) { | ||
373 | |||
374 | addr = msgs[i].addr >> 1; | ||
375 | |||
376 | dprintk2(2, "%s %s addr=%x len=%d:", | ||
377 | (msgs[i].flags & I2C_M_RD) ? "read" : "write", | ||
378 | i == num - 1 ? "stop" : "nonstop", addr, msgs[i].len); | ||
379 | if (!msgs[i].len) { | ||
380 | /* no len: check only for device presence */ | ||
381 | rc = cx231xx_i2c_check_for_device(i2c_adap, &msgs[i]); | ||
382 | if (rc < 0) { | ||
383 | dprintk2(2, " no device\n"); | ||
384 | mutex_unlock(&dev->i2c_lock); | ||
385 | return rc; | ||
386 | } | ||
387 | |||
388 | } else if (msgs[i].flags & I2C_M_RD) { | ||
389 | /* read bytes */ | ||
390 | rc = cx231xx_i2c_recv_bytes(i2c_adap, &msgs[i]); | ||
391 | if (i2c_debug >= 2) { | ||
392 | for (byte = 0; byte < msgs[i].len; byte++) | ||
393 | printk(" %02x", msgs[i].buf[byte]); | ||
394 | } | ||
395 | } else if (i + 1 < num && (msgs[i + 1].flags & I2C_M_RD) && | ||
396 | msgs[i].addr == msgs[i + 1].addr | ||
397 | && (msgs[i].len <= 2) && (bus->nr < 3)) { | ||
398 | /* read bytes */ | ||
399 | rc = cx231xx_i2c_recv_bytes_with_saddr(i2c_adap, | ||
400 | &msgs[i], | ||
401 | &msgs[i + 1]); | ||
402 | if (i2c_debug >= 2) { | ||
403 | for (byte = 0; byte < msgs[i].len; byte++) | ||
404 | printk(" %02x", msgs[i].buf[byte]); | ||
405 | } | ||
406 | i++; | ||
407 | } else { | ||
408 | /* write bytes */ | ||
409 | if (i2c_debug >= 2) { | ||
410 | for (byte = 0; byte < msgs[i].len; byte++) | ||
411 | printk(" %02x", msgs[i].buf[byte]); | ||
412 | } | ||
413 | rc = cx231xx_i2c_send_bytes(i2c_adap, &msgs[i]); | ||
414 | } | ||
415 | if (rc < 0) | ||
416 | goto err; | ||
417 | if (i2c_debug >= 2) | ||
418 | printk("\n"); | ||
419 | } | ||
420 | mutex_unlock(&dev->i2c_lock); | ||
421 | return num; | ||
422 | err: | ||
423 | dprintk2(2, " ERROR: %i\n", rc); | ||
424 | mutex_unlock(&dev->i2c_lock); | ||
425 | return rc; | ||
426 | } | ||
427 | |||
428 | /* ----------------------------------------------------------- */ | ||
429 | |||
430 | /* | ||
431 | * functionality() | ||
432 | */ | ||
433 | static u32 functionality(struct i2c_adapter *adap) | ||
434 | { | ||
435 | return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C; | ||
436 | } | ||
437 | |||
438 | static struct i2c_algorithm cx231xx_algo = { | ||
439 | .master_xfer = cx231xx_i2c_xfer, | ||
440 | .functionality = functionality, | ||
441 | }; | ||
442 | |||
443 | static struct i2c_adapter cx231xx_adap_template = { | ||
444 | .owner = THIS_MODULE, | ||
445 | .name = "cx231xx", | ||
446 | .algo = &cx231xx_algo, | ||
447 | }; | ||
448 | |||
449 | static struct i2c_client cx231xx_client_template = { | ||
450 | .name = "cx231xx internal", | ||
451 | }; | ||
452 | |||
453 | /* ----------------------------------------------------------- */ | ||
454 | |||
455 | /* | ||
456 | * i2c_devs | ||
457 | * incomplete list of known devices | ||
458 | */ | ||
459 | static char *i2c_devs[128] = { | ||
460 | [0x60 >> 1] = "colibri", | ||
461 | [0x88 >> 1] = "hammerhead", | ||
462 | [0x8e >> 1] = "CIR", | ||
463 | [0x32 >> 1] = "GeminiIII", | ||
464 | [0x02 >> 1] = "Aquarius", | ||
465 | [0xa0 >> 1] = "eeprom", | ||
466 | [0xc0 >> 1] = "tuner", | ||
467 | [0xc2 >> 1] = "tuner", | ||
468 | }; | ||
469 | |||
470 | /* | ||
471 | * cx231xx_do_i2c_scan() | ||
472 | * check i2c address range for devices | ||
473 | */ | ||
474 | void cx231xx_do_i2c_scan(struct cx231xx *dev, struct i2c_client *c) | ||
475 | { | ||
476 | unsigned char buf; | ||
477 | int i, rc; | ||
478 | |||
479 | cx231xx_info(": Checking for I2C devices ..\n"); | ||
480 | for (i = 0; i < 128; i++) { | ||
481 | c->addr = i; | ||
482 | rc = i2c_master_recv(c, &buf, 0); | ||
483 | if (rc < 0) | ||
484 | continue; | ||
485 | cx231xx_info("%s: i2c scan: found device @ 0x%x [%s]\n", | ||
486 | dev->name, i << 1, | ||
487 | i2c_devs[i] ? i2c_devs[i] : "???"); | ||
488 | } | ||
489 | cx231xx_info(": Completed Checking for I2C devices.\n"); | ||
490 | } | ||
491 | |||
492 | /* | ||
493 | * cx231xx_i2c_register() | ||
494 | * register i2c bus | ||
495 | */ | ||
496 | int cx231xx_i2c_register(struct cx231xx_i2c *bus) | ||
497 | { | ||
498 | struct cx231xx *dev = bus->dev; | ||
499 | |||
500 | BUG_ON(!dev->cx231xx_send_usb_command); | ||
501 | |||
502 | bus->i2c_adap = cx231xx_adap_template; | ||
503 | bus->i2c_client = cx231xx_client_template; | ||
504 | bus->i2c_adap.dev.parent = &dev->udev->dev; | ||
505 | |||
506 | strlcpy(bus->i2c_adap.name, bus->dev->name, sizeof(bus->i2c_adap.name)); | ||
507 | |||
508 | bus->i2c_adap.algo_data = bus; | ||
509 | i2c_set_adapdata(&bus->i2c_adap, &dev->v4l2_dev); | ||
510 | i2c_add_adapter(&bus->i2c_adap); | ||
511 | |||
512 | bus->i2c_client.adapter = &bus->i2c_adap; | ||
513 | |||
514 | if (0 == bus->i2c_rc) { | ||
515 | if (i2c_scan) | ||
516 | cx231xx_do_i2c_scan(dev, &bus->i2c_client); | ||
517 | } else | ||
518 | cx231xx_warn("%s: i2c bus %d register FAILED\n", | ||
519 | dev->name, bus->nr); | ||
520 | |||
521 | return bus->i2c_rc; | ||
522 | } | ||
523 | |||
524 | /* | ||
525 | * cx231xx_i2c_unregister() | ||
526 | * unregister i2c_bus | ||
527 | */ | ||
528 | int cx231xx_i2c_unregister(struct cx231xx_i2c *bus) | ||
529 | { | ||
530 | i2c_del_adapter(&bus->i2c_adap); | ||
531 | return 0; | ||
532 | } | ||