1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21#include <linux/i2c.h>
22#include "pvrusb2-i2c-core.h"
23#include "pvrusb2-hdw-internal.h"
24#include "pvrusb2-debug.h"
25#include "pvrusb2-fx2-cmd.h"
26#include "pvrusb2.h"
27
28#define trace_i2c(...) pvr2_trace(PVR2_TRACE_I2C,__VA_ARGS__)
29
30
31
32
33
34
35
36
37static unsigned int i2c_scan;
38module_param(i2c_scan, int, S_IRUGO|S_IWUSR);
39MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time");
40
41static int ir_mode[PVR_NUM] = { [0 ... PVR_NUM-1] = 1 };
42module_param_array(ir_mode, int, NULL, 0444);
43MODULE_PARM_DESC(ir_mode,"specify: 0=disable IR reception, 1=normal IR");
44
45static int pvr2_disable_ir_video;
46module_param_named(disable_autoload_ir_video, pvr2_disable_ir_video,
47 int, S_IRUGO|S_IWUSR);
48MODULE_PARM_DESC(disable_autoload_ir_video,
49 "1=do not try to autoload ir_video IR receiver");
50
51
52static const unsigned char ir_video_addresses[] = {
53 [PVR2_IR_SCHEME_29XXX] = 0x18,
54 [PVR2_IR_SCHEME_24XXX] = 0x18,
55};
56
57static int pvr2_i2c_write(struct pvr2_hdw *hdw,
58 u8 i2c_addr,
59 u8 *data,
60 u16 length)
61{
62
63 int ret;
64
65
66 if (!data) length = 0;
67 if (length > (sizeof(hdw->cmd_buffer) - 3)) {
68 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
69 "Killing an I2C write to %u that is too large"
70 " (desired=%u limit=%u)",
71 i2c_addr,
72 length,(unsigned int)(sizeof(hdw->cmd_buffer) - 3));
73 return -ENOTSUPP;
74 }
75
76 LOCK_TAKE(hdw->ctl_lock);
77
78
79 memset(hdw->cmd_buffer, 0, sizeof(hdw->cmd_buffer));
80
81
82 hdw->cmd_buffer[0] = FX2CMD_I2C_WRITE;
83 hdw->cmd_buffer[1] = i2c_addr;
84 hdw->cmd_buffer[2] = length;
85 if (length) memcpy(hdw->cmd_buffer + 3, data, length);
86
87
88 ret = pvr2_send_request(hdw,
89 hdw->cmd_buffer,
90 length + 3,
91 hdw->cmd_buffer,
92 1);
93 if (!ret) {
94 if (hdw->cmd_buffer[0] != 8) {
95 ret = -EIO;
96 if (hdw->cmd_buffer[0] != 7) {
97 trace_i2c("unexpected status"
98 " from i2_write[%d]: %d",
99 i2c_addr,hdw->cmd_buffer[0]);
100 }
101 }
102 }
103
104 LOCK_GIVE(hdw->ctl_lock);
105
106 return ret;
107}
108
109static int pvr2_i2c_read(struct pvr2_hdw *hdw,
110 u8 i2c_addr,
111 u8 *data,
112 u16 dlen,
113 u8 *res,
114 u16 rlen)
115{
116
117 int ret;
118
119
120 if (!data) dlen = 0;
121 if (dlen > (sizeof(hdw->cmd_buffer) - 4)) {
122 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
123 "Killing an I2C read to %u that has wlen too large"
124 " (desired=%u limit=%u)",
125 i2c_addr,
126 dlen,(unsigned int)(sizeof(hdw->cmd_buffer) - 4));
127 return -ENOTSUPP;
128 }
129 if (res && (rlen > (sizeof(hdw->cmd_buffer) - 1))) {
130 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
131 "Killing an I2C read to %u that has rlen too large"
132 " (desired=%u limit=%u)",
133 i2c_addr,
134 rlen,(unsigned int)(sizeof(hdw->cmd_buffer) - 1));
135 return -ENOTSUPP;
136 }
137
138 LOCK_TAKE(hdw->ctl_lock);
139
140
141 memset(hdw->cmd_buffer, 0, sizeof(hdw->cmd_buffer));
142
143
144 hdw->cmd_buffer[0] = FX2CMD_I2C_READ;
145 hdw->cmd_buffer[1] = dlen;
146 hdw->cmd_buffer[2] = rlen;
147
148 hdw->cmd_buffer[3] = i2c_addr;
149 if (dlen) memcpy(hdw->cmd_buffer + 4, data, dlen);
150
151
152 ret = pvr2_send_request(hdw,
153 hdw->cmd_buffer,
154 4 + dlen,
155 hdw->cmd_buffer,
156 rlen + 1);
157 if (!ret) {
158 if (hdw->cmd_buffer[0] != 8) {
159 ret = -EIO;
160 if (hdw->cmd_buffer[0] != 7) {
161 trace_i2c("unexpected status"
162 " from i2_read[%d]: %d",
163 i2c_addr,hdw->cmd_buffer[0]);
164 }
165 }
166 }
167
168
169 if (res && rlen) {
170 if (ret) {
171
172 memset(res, 0, rlen);
173 } else {
174 memcpy(res, hdw->cmd_buffer + 1, rlen);
175 }
176 }
177
178 LOCK_GIVE(hdw->ctl_lock);
179
180 return ret;
181}
182
183
184
185static int pvr2_i2c_basic_op(struct pvr2_hdw *hdw,
186 u8 i2c_addr,
187 u8 *wdata,
188 u16 wlen,
189 u8 *rdata,
190 u16 rlen)
191{
192 if (!rdata) rlen = 0;
193 if (!wdata) wlen = 0;
194 if (rlen || !wlen) {
195 return pvr2_i2c_read(hdw,i2c_addr,wdata,wlen,rdata,rlen);
196 } else {
197 return pvr2_i2c_write(hdw,i2c_addr,wdata,wlen);
198 }
199}
200
201
202
203
204
205
206
207
208static int i2c_24xxx_ir(struct pvr2_hdw *hdw,
209 u8 i2c_addr,u8 *wdata,u16 wlen,u8 *rdata,u16 rlen)
210{
211 u8 dat[4];
212 unsigned int stat;
213
214 if (!(rlen || wlen)) {
215
216 return 0;
217 }
218
219
220 if ((wlen != 0) || (rlen == 0)) return -EIO;
221
222 if (rlen < 3) {
223
224
225
226
227
228
229
230 if (rlen > 0) rdata[0] = 0;
231 if (rlen > 1) rdata[1] = 0;
232 return 0;
233 }
234
235
236 LOCK_TAKE(hdw->ctl_lock); do {
237 hdw->cmd_buffer[0] = FX2CMD_GET_IR_CODE;
238 stat = pvr2_send_request(hdw,
239 hdw->cmd_buffer,1,
240 hdw->cmd_buffer,4);
241 dat[0] = hdw->cmd_buffer[0];
242 dat[1] = hdw->cmd_buffer[1];
243 dat[2] = hdw->cmd_buffer[2];
244 dat[3] = hdw->cmd_buffer[3];
245 } while (0); LOCK_GIVE(hdw->ctl_lock);
246
247
248 if (stat != 0) return stat;
249
250
251
252 rdata[2] = 0xc1;
253 if (dat[0] != 1) {
254
255 rdata[0] = 0;
256 rdata[1] = 0;
257 } else {
258 u16 val;
259
260
261 val = dat[1];
262 val <<= 8;
263 val |= dat[2];
264 val >>= 1;
265 val &= ~0x0003;
266 val |= 0x8000;
267 rdata[0] = (val >> 8) & 0xffu;
268 rdata[1] = val & 0xffu;
269 }
270
271 return 0;
272}
273
274
275
276
277
278static int i2c_hack_wm8775(struct pvr2_hdw *hdw,
279 u8 i2c_addr,u8 *wdata,u16 wlen,u8 *rdata,u16 rlen)
280{
281 if (!(rlen || wlen)) {
282
283 return 0;
284 }
285 return pvr2_i2c_basic_op(hdw,i2c_addr,wdata,wlen,rdata,rlen);
286}
287
288
289
290
291static int i2c_black_hole(struct pvr2_hdw *hdw,
292 u8 i2c_addr,u8 *wdata,u16 wlen,u8 *rdata,u16 rlen)
293{
294 return -EIO;
295}
296
297
298
299
300
301
302
303
304static int i2c_hack_cx25840(struct pvr2_hdw *hdw,
305 u8 i2c_addr,u8 *wdata,u16 wlen,u8 *rdata,u16 rlen)
306{
307 int ret;
308 unsigned int subaddr;
309 u8 wbuf[2];
310 int state = hdw->i2c_cx25840_hack_state;
311
312 if (!(rlen || wlen)) {
313
314
315
316 return 0;
317 }
318
319 if (state == 3) {
320 return pvr2_i2c_basic_op(hdw,i2c_addr,wdata,wlen,rdata,rlen);
321 }
322
323
324
325
326
327
328
329
330
331 if (wlen == 0) {
332 switch (state) {
333 case 1: subaddr = 0x0100; break;
334 case 2: subaddr = 0x0101; break;
335 default: goto fail;
336 }
337 } else if (wlen == 2) {
338 subaddr = (wdata[0] << 8) | wdata[1];
339 switch (subaddr) {
340 case 0x0100: state = 1; break;
341 case 0x0101: state = 2; break;
342 default: goto fail;
343 }
344 } else {
345 goto fail;
346 }
347 if (!rlen) goto success;
348 state = 0;
349 if (rlen != 1) goto fail;
350
351
352
353 wbuf[0] = subaddr >> 8;
354 wbuf[1] = subaddr;
355 ret = pvr2_i2c_basic_op(hdw,i2c_addr,wbuf,2,rdata,rlen);
356
357 if ((ret != 0) || (*rdata == 0x04) || (*rdata == 0x0a)) {
358 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
359 "WARNING: Detected a wedged cx25840 chip;"
360 " the device will not work.");
361 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
362 "WARNING: Try power cycling the pvrusb2 device.");
363 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
364 "WARNING: Disabling further access to the device"
365 " to prevent other foul-ups.");
366
367 hdw->i2c_func[0x44] = NULL;
368 pvr2_hdw_render_useless(hdw);
369 goto fail;
370 }
371
372
373 pvr2_trace(PVR2_TRACE_CHIPS,"cx25840 appears to be OK.");
374 state = 3;
375
376 success:
377 hdw->i2c_cx25840_hack_state = state;
378 return 0;
379
380 fail:
381 hdw->i2c_cx25840_hack_state = state;
382 return -EIO;
383}
384
385
386
387static int pvr2_i2c_xfer(struct i2c_adapter *i2c_adap,
388 struct i2c_msg msgs[],
389 int num)
390{
391 int ret = -ENOTSUPP;
392 pvr2_i2c_func funcp = NULL;
393 struct pvr2_hdw *hdw = (struct pvr2_hdw *)(i2c_adap->algo_data);
394
395 if (!num) {
396 ret = -EINVAL;
397 goto done;
398 }
399 if (msgs[0].addr < PVR2_I2C_FUNC_CNT) {
400 funcp = hdw->i2c_func[msgs[0].addr];
401 }
402 if (!funcp) {
403 ret = -EIO;
404 goto done;
405 }
406
407 if (num == 1) {
408 if (msgs[0].flags & I2C_M_RD) {
409
410 u16 tcnt,bcnt,offs;
411 if (!msgs[0].len) {
412
413 if (funcp(hdw,msgs[0].addr,NULL,0,NULL,0)) {
414 ret = -EIO;
415 goto done;
416 }
417 ret = 1;
418 goto done;
419 }
420
421
422
423 tcnt = msgs[0].len;
424 offs = 0;
425 while (tcnt) {
426 bcnt = tcnt;
427 if (bcnt > sizeof(hdw->cmd_buffer)-1) {
428 bcnt = sizeof(hdw->cmd_buffer)-1;
429 }
430 if (funcp(hdw,msgs[0].addr,NULL,0,
431 msgs[0].buf+offs,bcnt)) {
432 ret = -EIO;
433 goto done;
434 }
435 offs += bcnt;
436 tcnt -= bcnt;
437 }
438 ret = 1;
439 goto done;
440 } else {
441
442 ret = 1;
443 if (funcp(hdw,msgs[0].addr,
444 msgs[0].buf,msgs[0].len,NULL,0)) {
445 ret = -EIO;
446 }
447 goto done;
448 }
449 } else if (num == 2) {
450 if (msgs[0].addr != msgs[1].addr) {
451 trace_i2c("i2c refusing 2 phase transfer with"
452 " conflicting target addresses");
453 ret = -ENOTSUPP;
454 goto done;
455 }
456 if ((!((msgs[0].flags & I2C_M_RD))) &&
457 (msgs[1].flags & I2C_M_RD)) {
458 u16 tcnt,bcnt,wcnt,offs;
459
460
461
462
463 tcnt = msgs[1].len;
464 wcnt = msgs[0].len;
465 offs = 0;
466 while (tcnt || wcnt) {
467 bcnt = tcnt;
468 if (bcnt > sizeof(hdw->cmd_buffer)-1) {
469 bcnt = sizeof(hdw->cmd_buffer)-1;
470 }
471 if (funcp(hdw,msgs[0].addr,
472 msgs[0].buf,wcnt,
473 msgs[1].buf+offs,bcnt)) {
474 ret = -EIO;
475 goto done;
476 }
477 offs += bcnt;
478 tcnt -= bcnt;
479 wcnt = 0;
480 }
481 ret = 2;
482 goto done;
483 } else {
484 trace_i2c("i2c refusing complex transfer"
485 " read0=%d read1=%d",
486 (msgs[0].flags & I2C_M_RD),
487 (msgs[1].flags & I2C_M_RD));
488 }
489 } else {
490 trace_i2c("i2c refusing %d phase transfer",num);
491 }
492
493 done:
494 if (pvrusb2_debug & PVR2_TRACE_I2C_TRAF) {
495 unsigned int idx,offs,cnt;
496 for (idx = 0; idx < num; idx++) {
497 cnt = msgs[idx].len;
498 printk(KERN_INFO
499 "pvrusb2 i2c xfer %u/%u:"
500 " addr=0x%x len=%d %s",
501 idx+1,num,
502 msgs[idx].addr,
503 cnt,
504 (msgs[idx].flags & I2C_M_RD ?
505 "read" : "write"));
506 if ((ret > 0) || !(msgs[idx].flags & I2C_M_RD)) {
507 if (cnt > 8) cnt = 8;
508 printk(" [");
509 for (offs = 0; offs < (cnt>8?8:cnt); offs++) {
510 if (offs) printk(" ");
511 printk("%02x",msgs[idx].buf[offs]);
512 }
513 if (offs < cnt) printk(" ...");
514 printk("]");
515 }
516 if (idx+1 == num) {
517 printk(" result=%d",ret);
518 }
519 printk("\n");
520 }
521 if (!num) {
522 printk(KERN_INFO
523 "pvrusb2 i2c xfer null transfer result=%d\n",
524 ret);
525 }
526 }
527 return ret;
528}
529
530static u32 pvr2_i2c_functionality(struct i2c_adapter *adap)
531{
532 return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C;
533}
534
535static struct i2c_algorithm pvr2_i2c_algo_template = {
536 .master_xfer = pvr2_i2c_xfer,
537 .functionality = pvr2_i2c_functionality,
538};
539
540static struct i2c_adapter pvr2_i2c_adap_template = {
541 .owner = THIS_MODULE,
542 .class = 0,
543};
544
545
546
547static int do_i2c_probe(struct pvr2_hdw *hdw, int addr)
548{
549 struct i2c_msg msg[1];
550 int rc;
551 msg[0].addr = 0;
552 msg[0].flags = I2C_M_RD;
553 msg[0].len = 0;
554 msg[0].buf = NULL;
555 msg[0].addr = addr;
556 rc = i2c_transfer(&hdw->i2c_adap, msg, ARRAY_SIZE(msg));
557 return rc == 1;
558}
559
560static void do_i2c_scan(struct pvr2_hdw *hdw)
561{
562 int i;
563 printk(KERN_INFO "%s: i2c scan beginning\n", hdw->name);
564 for (i = 0; i < 128; i++) {
565 if (do_i2c_probe(hdw, i)) {
566 printk(KERN_INFO "%s: i2c scan: found device @ 0x%x\n",
567 hdw->name, i);
568 }
569 }
570 printk(KERN_INFO "%s: i2c scan done.\n", hdw->name);
571}
572
573static void pvr2_i2c_register_ir(struct pvr2_hdw *hdw)
574{
575 struct i2c_board_info info;
576 unsigned char addr = 0;
577 if (pvr2_disable_ir_video) {
578 pvr2_trace(PVR2_TRACE_INFO,
579 "Automatic binding of ir_video has been disabled.");
580 return;
581 }
582 if (hdw->ir_scheme_active < ARRAY_SIZE(ir_video_addresses)) {
583 addr = ir_video_addresses[hdw->ir_scheme_active];
584 }
585 if (!addr) {
586
587
588 return;
589 }
590 pvr2_trace(PVR2_TRACE_INFO,
591 "Binding ir_video to i2c address 0x%02x.", addr);
592 memset(&info, 0, sizeof(struct i2c_board_info));
593 strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
594 info.addr = addr;
595 i2c_new_device(&hdw->i2c_adap, &info);
596}
597
598void pvr2_i2c_core_init(struct pvr2_hdw *hdw)
599{
600 unsigned int idx;
601
602
603
604 for (idx = 0; idx < PVR2_I2C_FUNC_CNT; idx++) {
605 hdw->i2c_func[idx] = pvr2_i2c_basic_op;
606 }
607
608
609 if (ir_mode[hdw->unit_number] == 0) {
610 printk(KERN_INFO "%s: IR disabled\n",hdw->name);
611 hdw->i2c_func[0x18] = i2c_black_hole;
612 } else if (ir_mode[hdw->unit_number] == 1) {
613 if (hdw->ir_scheme_active == PVR2_IR_SCHEME_24XXX) {
614
615
616 hdw->i2c_func[0x18] = i2c_24xxx_ir;
617 }
618 }
619 if (hdw->hdw_desc->flag_has_cx25840) {
620 hdw->i2c_func[0x44] = i2c_hack_cx25840;
621 }
622 if (hdw->hdw_desc->flag_has_wm8775) {
623 hdw->i2c_func[0x1b] = i2c_hack_wm8775;
624 }
625
626
627 memcpy(&hdw->i2c_adap,&pvr2_i2c_adap_template,sizeof(hdw->i2c_adap));
628 memcpy(&hdw->i2c_algo,&pvr2_i2c_algo_template,sizeof(hdw->i2c_algo));
629 strlcpy(hdw->i2c_adap.name,hdw->name,sizeof(hdw->i2c_adap.name));
630 hdw->i2c_adap.dev.parent = &hdw->usb_dev->dev;
631 hdw->i2c_adap.algo = &hdw->i2c_algo;
632 hdw->i2c_adap.algo_data = hdw;
633 hdw->i2c_linked = !0;
634 i2c_set_adapdata(&hdw->i2c_adap, &hdw->v4l2_dev);
635 i2c_add_adapter(&hdw->i2c_adap);
636 if (hdw->i2c_func[0x18] == i2c_24xxx_ir) {
637
638
639
640
641
642
643 if (do_i2c_probe(hdw, 0x71)) {
644 pvr2_trace(PVR2_TRACE_INFO,
645 "Device has newer IR hardware;"
646 " disabling unneeded virtual IR device");
647 hdw->i2c_func[0x18] = NULL;
648
649 hdw->ir_scheme_active = PVR2_IR_SCHEME_24XXX_MCE;
650 }
651 }
652 if (i2c_scan) do_i2c_scan(hdw);
653
654 pvr2_i2c_register_ir(hdw);
655}
656
657void pvr2_i2c_core_done(struct pvr2_hdw *hdw)
658{
659 if (hdw->i2c_linked) {
660 i2c_del_adapter(&hdw->i2c_adap);
661 hdw->i2c_linked = 0;
662 }
663}
664
665
666
667
668
669
670
671
672
673
674