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