]>
Commit | Line | Data |
---|---|---|
e0d3bafd SD |
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> | |
b9255176 SD |
5 | Based on em28xx driver |
6 | Based on Cx23885 driver | |
e0d3bafd SD |
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 | ||
e0d3bafd SD |
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 | ||
e0d3bafd SD |
42 | #define dprintk1(lvl, fmt, args...) \ |
43 | do { \ | |
44 | if (i2c_debug >= lvl) { \ | |
6e4f574b SD |
45 | printk(fmt, ##args); \ |
46 | } \ | |
e0d3bafd SD |
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 | ||
e0d3bafd SD |
57 | /* |
58 | * cx231xx_i2c_send_bytes() | |
59 | */ | |
60 | int cx231xx_i2c_send_bytes(struct i2c_adapter *i2c_adap, | |
84b5dbf3 | 61 | const struct i2c_msg *msg) |
e0d3bafd SD |
62 | { |
63 | struct cx231xx_i2c *bus = i2c_adap->algo_data; | |
64 | struct cx231xx *dev = bus->dev; | |
84b5dbf3 MCC |
65 | struct cx231xx_i2c_xfer_data req_data; |
66 | int status = 0; | |
67 | u16 size = 0; | |
68 | u8 loop = 0; | |
69 | u8 saddr_len = 1; | |
70 | u8 *buf_ptr = NULL; | |
71 | u16 saddr = 0; | |
72 | u8 need_gpio = 0; | |
73 | ||
74 | if ((bus->nr == 1) && (msg->addr == 0x61) | |
75 | && (dev->tuner_type == TUNER_XC5000)) { | |
76 | ||
77 | size = msg->len; | |
78 | ||
79 | if (size == 2) { /* register write sub addr */ | |
6e4f574b SD |
80 | /* Just writing sub address will cause problem |
81 | * to XC5000. So ignore the request */ | |
84b5dbf3 | 82 | return 0; |
84b5dbf3 | 83 | } else if (size == 4) { /* register write with sub addr */ |
84b5dbf3 MCC |
84 | if (msg->len >= 2) |
85 | saddr = msg->buf[0] << 8 | msg->buf[1]; | |
86 | else if (msg->len == 1) | |
87 | saddr = msg->buf[0]; | |
88 | ||
89 | switch (saddr) { | |
90 | case 0x0000: /* start tuner calibration mode */ | |
91 | need_gpio = 1; | |
b9255176 SD |
92 | /* FW Loading is done */ |
93 | dev->xc_fw_load_done = 1; | |
84b5dbf3 MCC |
94 | break; |
95 | case 0x000D: /* Set signal source */ | |
96 | case 0x0001: /* Set TV standard - Video */ | |
97 | case 0x0002: /* Set TV standard - Audio */ | |
98 | case 0x0003: /* Set RF Frequency */ | |
99 | need_gpio = 1; | |
100 | break; | |
101 | default: | |
102 | if (dev->xc_fw_load_done) | |
103 | need_gpio = 1; | |
104 | break; | |
105 | } | |
106 | ||
107 | if (need_gpio) { | |
108 | dprintk1(1, | |
b9255176 SD |
109 | "GPIO WRITE: addr 0x%x, len %d, saddr 0x%x\n", |
110 | msg->addr, msg->len, saddr); | |
84b5dbf3 MCC |
111 | |
112 | return dev->cx231xx_gpio_i2c_write(dev, | |
113 | msg->addr, | |
114 | msg->buf, | |
115 | msg->len); | |
116 | } | |
84b5dbf3 MCC |
117 | } |
118 | ||
119 | /* special case for Xc5000 tuner case */ | |
120 | saddr_len = 1; | |
121 | ||
122 | /* adjust the length to correct length */ | |
123 | size -= saddr_len; | |
124 | buf_ptr = (u8 *) (msg->buf + 1); | |
125 | ||
126 | do { | |
127 | /* prepare xfer_data struct */ | |
128 | req_data.dev_addr = msg->addr; | |
129 | req_data.direction = msg->flags; | |
130 | req_data.saddr_len = saddr_len; | |
131 | req_data.saddr_dat = msg->buf[0]; | |
132 | req_data.buf_size = size > 16 ? 16 : size; | |
133 | req_data.p_buffer = (u8 *) (buf_ptr + loop * 16); | |
134 | ||
135 | bus->i2c_nostop = (size > 16) ? 1 : 0; | |
136 | bus->i2c_reserve = (loop == 0) ? 0 : 1; | |
137 | ||
138 | /* usb send command */ | |
139 | status = dev->cx231xx_send_usb_command(bus, &req_data); | |
140 | loop++; | |
141 | ||
142 | if (size >= 16) | |
143 | size -= 16; | |
144 | else | |
145 | size = 0; | |
146 | ||
147 | } while (size > 0); | |
148 | ||
149 | bus->i2c_nostop = 0; | |
150 | bus->i2c_reserve = 0; | |
151 | ||
152 | } else { /* regular case */ | |
153 | ||
154 | /* prepare xfer_data struct */ | |
155 | req_data.dev_addr = msg->addr; | |
156 | req_data.direction = msg->flags; | |
157 | req_data.saddr_len = 0; | |
158 | req_data.saddr_dat = 0; | |
159 | req_data.buf_size = msg->len; | |
160 | req_data.p_buffer = msg->buf; | |
161 | ||
162 | /* usb send command */ | |
163 | status = dev->cx231xx_send_usb_command(bus, &req_data); | |
164 | } | |
165 | ||
166 | return status < 0 ? status : 0; | |
e0d3bafd SD |
167 | } |
168 | ||
169 | /* | |
170 | * cx231xx_i2c_recv_bytes() | |
171 | * read a byte from the i2c device | |
172 | */ | |
173 | static int cx231xx_i2c_recv_bytes(struct i2c_adapter *i2c_adap, | |
84b5dbf3 | 174 | const struct i2c_msg *msg) |
e0d3bafd | 175 | { |
84b5dbf3 | 176 | struct cx231xx_i2c *bus = i2c_adap->algo_data; |
e0d3bafd | 177 | struct cx231xx *dev = bus->dev; |
84b5dbf3 MCC |
178 | struct cx231xx_i2c_xfer_data req_data; |
179 | int status = 0; | |
180 | u16 saddr = 0; | |
181 | u8 need_gpio = 0; | |
182 | ||
183 | if ((bus->nr == 1) && (msg->addr == 0x61) | |
184 | && dev->tuner_type == TUNER_XC5000) { | |
185 | ||
186 | if (msg->len == 2) | |
187 | saddr = msg->buf[0] << 8 | msg->buf[1]; | |
188 | else if (msg->len == 1) | |
189 | saddr = msg->buf[0]; | |
190 | ||
191 | if (dev->xc_fw_load_done) { | |
192 | ||
193 | switch (saddr) { | |
194 | case 0x0009: /* BUSY check */ | |
195 | dprintk1(1, | |
b9255176 SD |
196 | "GPIO R E A D: Special case BUSY check \n"); |
197 | /*Try read BUSY register, just set it to zero*/ | |
84b5dbf3 MCC |
198 | msg->buf[0] = 0; |
199 | if (msg->len == 2) | |
200 | msg->buf[1] = 0; | |
201 | return 0; | |
202 | case 0x0004: /* read Lock status */ | |
203 | need_gpio = 1; | |
204 | break; | |
205 | ||
206 | } | |
207 | ||
208 | if (need_gpio) { | |
b9255176 SD |
209 | /* this is a special case to handle Xceive tuner |
210 | clock stretch issue with gpio based I2C */ | |
211 | ||
84b5dbf3 | 212 | dprintk1(1, |
b9255176 SD |
213 | "GPIO R E A D: addr 0x%x, len %d, saddr 0x%x\n", |
214 | msg->addr, msg->len, | |
215 | msg->buf[0] << 8 | msg->buf[1]); | |
216 | ||
84b5dbf3 MCC |
217 | status = |
218 | dev->cx231xx_gpio_i2c_write(dev, msg->addr, | |
219 | msg->buf, | |
220 | msg->len); | |
221 | status = | |
222 | dev->cx231xx_gpio_i2c_read(dev, msg->addr, | |
223 | msg->buf, | |
224 | msg->len); | |
225 | return status; | |
226 | } | |
227 | } | |
228 | ||
229 | /* prepare xfer_data struct */ | |
230 | req_data.dev_addr = msg->addr; | |
231 | req_data.direction = msg->flags; | |
232 | req_data.saddr_len = msg->len; | |
233 | req_data.saddr_dat = msg->buf[0] << 8 | msg->buf[1]; | |
234 | req_data.buf_size = msg->len; | |
235 | req_data.p_buffer = msg->buf; | |
236 | ||
237 | /* usb send command */ | |
238 | status = dev->cx231xx_send_usb_command(bus, &req_data); | |
239 | ||
240 | } else { | |
241 | ||
242 | /* prepare xfer_data struct */ | |
243 | req_data.dev_addr = msg->addr; | |
244 | req_data.direction = msg->flags; | |
245 | req_data.saddr_len = 0; | |
246 | req_data.saddr_dat = 0; | |
247 | req_data.buf_size = msg->len; | |
248 | req_data.p_buffer = msg->buf; | |
249 | ||
250 | /* usb send command */ | |
251 | status = dev->cx231xx_send_usb_command(bus, &req_data); | |
252 | } | |
253 | ||
254 | return status < 0 ? status : 0; | |
e0d3bafd SD |
255 | } |
256 | ||
257 | /* | |
258 | * cx231xx_i2c_recv_bytes_with_saddr() | |
259 | * read a byte from the i2c device | |
260 | */ | |
261 | static int cx231xx_i2c_recv_bytes_with_saddr(struct i2c_adapter *i2c_adap, | |
84b5dbf3 MCC |
262 | const struct i2c_msg *msg1, |
263 | const struct i2c_msg *msg2) | |
e0d3bafd | 264 | { |
84b5dbf3 | 265 | struct cx231xx_i2c *bus = i2c_adap->algo_data; |
e0d3bafd | 266 | struct cx231xx *dev = bus->dev; |
84b5dbf3 MCC |
267 | struct cx231xx_i2c_xfer_data req_data; |
268 | int status = 0; | |
269 | u16 saddr = 0; | |
270 | u8 need_gpio = 0; | |
271 | ||
272 | if (msg1->len == 2) | |
273 | saddr = msg1->buf[0] << 8 | msg1->buf[1]; | |
274 | else if (msg1->len == 1) | |
275 | saddr = msg1->buf[0]; | |
276 | ||
277 | if ((bus->nr == 1) && (msg2->addr == 0x61) | |
278 | && dev->tuner_type == TUNER_XC5000) { | |
279 | ||
280 | if ((msg2->len < 16)) { | |
281 | ||
282 | dprintk1(1, | |
b9255176 SD |
283 | "i2c_read: addr 0x%x, len %d, saddr 0x%x, len %d\n", |
284 | msg2->addr, msg2->len, saddr, msg1->len); | |
84b5dbf3 MCC |
285 | |
286 | switch (saddr) { | |
287 | case 0x0008: /* read FW load status */ | |
288 | need_gpio = 1; | |
289 | break; | |
290 | case 0x0004: /* read Lock status */ | |
291 | need_gpio = 1; | |
292 | break; | |
293 | } | |
294 | ||
295 | if (need_gpio) { | |
296 | status = | |
297 | dev->cx231xx_gpio_i2c_write(dev, msg1->addr, | |
298 | msg1->buf, | |
299 | msg1->len); | |
300 | status = | |
301 | dev->cx231xx_gpio_i2c_read(dev, msg2->addr, | |
302 | msg2->buf, | |
303 | msg2->len); | |
304 | return status; | |
305 | } | |
306 | } | |
307 | } | |
308 | ||
309 | /* prepare xfer_data struct */ | |
310 | req_data.dev_addr = msg2->addr; | |
311 | req_data.direction = msg2->flags; | |
312 | req_data.saddr_len = msg1->len; | |
313 | req_data.saddr_dat = saddr; | |
314 | req_data.buf_size = msg2->len; | |
315 | req_data.p_buffer = msg2->buf; | |
316 | ||
317 | /* usb send command */ | |
318 | status = dev->cx231xx_send_usb_command(bus, &req_data); | |
319 | ||
320 | return status < 0 ? status : 0; | |
e0d3bafd SD |
321 | } |
322 | ||
323 | /* | |
324 | * cx231xx_i2c_check_for_device() | |
325 | * check if there is a i2c_device at the supplied address | |
326 | */ | |
327 | static int cx231xx_i2c_check_for_device(struct i2c_adapter *i2c_adap, | |
84b5dbf3 | 328 | const struct i2c_msg *msg) |
e0d3bafd | 329 | { |
84b5dbf3 | 330 | struct cx231xx_i2c *bus = i2c_adap->algo_data; |
e0d3bafd | 331 | struct cx231xx *dev = bus->dev; |
84b5dbf3 MCC |
332 | struct cx231xx_i2c_xfer_data req_data; |
333 | int status = 0; | |
e0d3bafd | 334 | |
84b5dbf3 MCC |
335 | /* prepare xfer_data struct */ |
336 | req_data.dev_addr = msg->addr; | |
337 | req_data.direction = msg->flags; | |
338 | req_data.saddr_len = 0; | |
339 | req_data.saddr_dat = 0; | |
340 | req_data.buf_size = 0; | |
341 | req_data.p_buffer = NULL; | |
e0d3bafd | 342 | |
84b5dbf3 MCC |
343 | /* usb send command */ |
344 | status = dev->cx231xx_send_usb_command(bus, &req_data); | |
e0d3bafd | 345 | |
84b5dbf3 | 346 | return status < 0 ? status : 0; |
e0d3bafd SD |
347 | } |
348 | ||
349 | /* | |
350 | * cx231xx_i2c_xfer() | |
351 | * the main i2c transfer function | |
352 | */ | |
353 | static int cx231xx_i2c_xfer(struct i2c_adapter *i2c_adap, | |
84b5dbf3 | 354 | struct i2c_msg msgs[], int num) |
e0d3bafd SD |
355 | { |
356 | struct cx231xx_i2c *bus = i2c_adap->algo_data; | |
357 | struct cx231xx *dev = bus->dev; | |
358 | int addr, rc, i, byte; | |
359 | ||
360 | if (num <= 0) | |
361 | return 0; | |
64fbf444 | 362 | mutex_lock(&dev->i2c_lock); |
e0d3bafd SD |
363 | for (i = 0; i < num; i++) { |
364 | ||
365 | addr = msgs[i].addr >> 1; | |
366 | ||
367 | dprintk2(2, "%s %s addr=%x len=%d:", | |
368 | (msgs[i].flags & I2C_M_RD) ? "read" : "write", | |
369 | i == num - 1 ? "stop" : "nonstop", addr, msgs[i].len); | |
b9255176 SD |
370 | if (!msgs[i].len) { |
371 | /* no len: check only for device presence */ | |
e0d3bafd SD |
372 | rc = cx231xx_i2c_check_for_device(i2c_adap, &msgs[i]); |
373 | if (rc < 0) { | |
374 | dprintk2(2, " no device\n"); | |
b8383962 | 375 | mutex_unlock(&dev->i2c_lock); |
e0d3bafd SD |
376 | return rc; |
377 | } | |
378 | ||
379 | } else if (msgs[i].flags & I2C_M_RD) { | |
380 | /* read bytes */ | |
381 | rc = cx231xx_i2c_recv_bytes(i2c_adap, &msgs[i]); | |
382 | if (i2c_debug >= 2) { | |
383 | for (byte = 0; byte < msgs[i].len; byte++) | |
384 | printk(" %02x", msgs[i].buf[byte]); | |
385 | } | |
386 | } else if (i + 1 < num && (msgs[i + 1].flags & I2C_M_RD) && | |
84b5dbf3 | 387 | msgs[i].addr == msgs[i + 1].addr |
64fbf444 | 388 | && (msgs[i].len <= 2) && (bus->nr < 3)) { |
e0d3bafd | 389 | /* read bytes */ |
84b5dbf3 MCC |
390 | rc = cx231xx_i2c_recv_bytes_with_saddr(i2c_adap, |
391 | &msgs[i], | |
392 | &msgs[i + 1]); | |
e0d3bafd SD |
393 | if (i2c_debug >= 2) { |
394 | for (byte = 0; byte < msgs[i].len; byte++) | |
395 | printk(" %02x", msgs[i].buf[byte]); | |
396 | } | |
84b5dbf3 | 397 | i++; |
e0d3bafd SD |
398 | } else { |
399 | /* write bytes */ | |
400 | if (i2c_debug >= 2) { | |
401 | for (byte = 0; byte < msgs[i].len; byte++) | |
402 | printk(" %02x", msgs[i].buf[byte]); | |
403 | } | |
84b5dbf3 | 404 | rc = cx231xx_i2c_send_bytes(i2c_adap, &msgs[i]); |
e0d3bafd SD |
405 | } |
406 | if (rc < 0) | |
407 | goto err; | |
408 | if (i2c_debug >= 2) | |
409 | printk("\n"); | |
410 | } | |
64fbf444 | 411 | mutex_unlock(&dev->i2c_lock); |
e0d3bafd | 412 | return num; |
b9255176 | 413 | err: |
e0d3bafd | 414 | dprintk2(2, " ERROR: %i\n", rc); |
64fbf444 | 415 | mutex_unlock(&dev->i2c_lock); |
e0d3bafd SD |
416 | return rc; |
417 | } | |
418 | ||
419 | /* ----------------------------------------------------------- */ | |
420 | ||
421 | /* | |
422 | * functionality() | |
423 | */ | |
424 | static u32 functionality(struct i2c_adapter *adap) | |
425 | { | |
426 | return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C; | |
427 | } | |
428 | ||
e0d3bafd | 429 | static struct i2c_algorithm cx231xx_algo = { |
84b5dbf3 | 430 | .master_xfer = cx231xx_i2c_xfer, |
e0d3bafd SD |
431 | .functionality = functionality, |
432 | }; | |
433 | ||
434 | static struct i2c_adapter cx231xx_adap_template = { | |
435 | .owner = THIS_MODULE, | |
e0d3bafd | 436 | .name = "cx231xx", |
e0d3bafd | 437 | .algo = &cx231xx_algo, |
e0d3bafd SD |
438 | }; |
439 | ||
440 | static struct i2c_client cx231xx_client_template = { | |
441 | .name = "cx231xx internal", | |
442 | }; | |
443 | ||
444 | /* ----------------------------------------------------------- */ | |
445 | ||
446 | /* | |
447 | * i2c_devs | |
448 | * incomplete list of known devices | |
449 | */ | |
450 | static char *i2c_devs[128] = { | |
451 | [0x60 >> 1] = "colibri", | |
452 | [0x88 >> 1] = "hammerhead", | |
84b5dbf3 | 453 | [0x8e >> 1] = "CIR", |
e0d3bafd | 454 | [0x32 >> 1] = "GeminiIII", |
84b5dbf3 | 455 | [0x02 >> 1] = "Aquarius", |
e0d3bafd SD |
456 | [0xa0 >> 1] = "eeprom", |
457 | [0xc0 >> 1] = "tuner/XC3028", | |
458 | [0xc2 >> 1] = "tuner/XC5000", | |
459 | }; | |
460 | ||
461 | /* | |
462 | * cx231xx_do_i2c_scan() | |
463 | * check i2c address range for devices | |
464 | */ | |
465 | void cx231xx_do_i2c_scan(struct cx231xx *dev, struct i2c_client *c) | |
466 | { | |
467 | unsigned char buf; | |
468 | int i, rc; | |
469 | ||
84b5dbf3 | 470 | cx231xx_info(": Checking for I2C devices ..\n"); |
e0d3bafd SD |
471 | for (i = 0; i < 128; i++) { |
472 | c->addr = i; | |
473 | rc = i2c_master_recv(c, &buf, 0); | |
474 | if (rc < 0) | |
475 | continue; | |
476 | cx231xx_info("%s: i2c scan: found device @ 0x%x [%s]\n", | |
84b5dbf3 MCC |
477 | dev->name, i << 1, |
478 | i2c_devs[i] ? i2c_devs[i] : "???"); | |
e0d3bafd | 479 | } |
84b5dbf3 | 480 | cx231xx_info(": Completed Checking for I2C devices.\n"); |
e0d3bafd SD |
481 | } |
482 | ||
e0d3bafd SD |
483 | /* |
484 | * cx231xx_i2c_register() | |
485 | * register i2c bus | |
486 | */ | |
487 | int cx231xx_i2c_register(struct cx231xx_i2c *bus) | |
488 | { | |
84b5dbf3 | 489 | struct cx231xx *dev = bus->dev; |
e0d3bafd | 490 | |
84b5dbf3 | 491 | BUG_ON(!dev->cx231xx_send_usb_command); |
e0d3bafd | 492 | |
84b5dbf3 MCC |
493 | memcpy(&bus->i2c_adap, &cx231xx_adap_template, sizeof(bus->i2c_adap)); |
494 | memcpy(&bus->i2c_algo, &cx231xx_algo, sizeof(bus->i2c_algo)); | |
e0d3bafd SD |
495 | memcpy(&bus->i2c_client, &cx231xx_client_template, |
496 | sizeof(bus->i2c_client)); | |
497 | ||
498 | bus->i2c_adap.dev.parent = &dev->udev->dev; | |
499 | ||
84b5dbf3 | 500 | strlcpy(bus->i2c_adap.name, bus->dev->name, sizeof(bus->i2c_adap.name)); |
e0d3bafd SD |
501 | |
502 | bus->i2c_algo.data = bus; | |
503 | bus->i2c_adap.algo_data = bus; | |
b1196126 | 504 | i2c_set_adapdata(&bus->i2c_adap, &dev->v4l2_dev); |
e0d3bafd SD |
505 | i2c_add_adapter(&bus->i2c_adap); |
506 | ||
507 | bus->i2c_client.adapter = &bus->i2c_adap; | |
508 | ||
509 | if (0 == bus->i2c_rc) { | |
e0d3bafd SD |
510 | if (i2c_scan) |
511 | cx231xx_do_i2c_scan(dev, &bus->i2c_client); | |
512 | } else | |
513 | cx231xx_warn("%s: i2c bus %d register FAILED\n", | |
84b5dbf3 | 514 | dev->name, bus->nr); |
e0d3bafd SD |
515 | |
516 | return bus->i2c_rc; | |
517 | } | |
518 | ||
519 | /* | |
520 | * cx231xx_i2c_unregister() | |
521 | * unregister i2c_bus | |
522 | */ | |
523 | int cx231xx_i2c_unregister(struct cx231xx_i2c *bus) | |
524 | { | |
525 | i2c_del_adapter(&bus->i2c_adap); | |
526 | return 0; | |
527 | } |