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