1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * |
4 | * Copyright (C) 2005 Mike Isely <isely@pobox.com> |
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 | This module attempts to implement a compliant I2C adapter for the pvrusb2 |
21 | device. |
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, /* Context */ |
40 | u8 i2c_addr, /* I2C address we're talking to */ |
41 | u8 *data, /* Data to write */ |
42 | u16 length) /* Size of data to write */ |
43 | { |
44 | /* Return value - default 0 means success */ |
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 | /* Clear the command buffer (likely to be paranoia) */ |
60 | memset(hdw->cmd_buffer, 0, sizeof(hdw->cmd_buffer)); |
61 | |
62 | /* Set up command buffer for an I2C write */ |
63 | hdw->cmd_buffer[0] = FX2CMD_I2C_WRITE; /* write prefix */ |
64 | hdw->cmd_buffer[1] = i2c_addr; /* i2c addr of chip */ |
65 | hdw->cmd_buffer[2] = length; /* length of what follows */ |
66 | if (length) memcpy(hdw->cmd_buffer + 3, data, length); |
67 | |
68 | /* Do the operation */ |
69 | ret = pvr2_send_request(hdw, |
70 | write_ptr: hdw->cmd_buffer, |
71 | write_len: length + 3, |
72 | read_ptr: hdw->cmd_buffer, |
73 | read_len: 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, /* Context */ |
90 | u8 i2c_addr, /* I2C address we're talking to */ |
91 | u8 *data, /* Data to write */ |
92 | u16 dlen, /* Size of data to write */ |
93 | u8 *res, /* Where to put data we read */ |
94 | u16 rlen) /* Amount of data to read */ |
95 | { |
96 | /* Return value - default 0 means success */ |
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 | /* Clear the command buffer (likely to be paranoia) */ |
119 | memset(hdw->cmd_buffer, 0, sizeof(hdw->cmd_buffer)); |
120 | |
121 | /* Set up command buffer for an I2C write followed by a read */ |
122 | hdw->cmd_buffer[0] = FX2CMD_I2C_READ; /* read prefix */ |
123 | hdw->cmd_buffer[1] = dlen; /* arg length */ |
124 | hdw->cmd_buffer[2] = rlen; /* answer length. Device will send one |
125 | more byte (status). */ |
126 | hdw->cmd_buffer[3] = i2c_addr; /* i2c addr of chip */ |
127 | if (dlen) memcpy(hdw->cmd_buffer + 4, data, dlen); |
128 | |
129 | /* Do the operation */ |
130 | ret = pvr2_send_request(hdw, |
131 | write_ptr: hdw->cmd_buffer, |
132 | write_len: 4 + dlen, |
133 | read_ptr: hdw->cmd_buffer, |
134 | read_len: 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 | /* Copy back the result */ |
146 | if (res && rlen) { |
147 | if (ret) { |
148 | /* Error, just blank out the return buffer */ |
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 | /* This is the common low level entry point for doing I2C operations to the |
161 | hardware. */ |
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,data: wdata,dlen: wlen,res: rdata,rlen); |
173 | } else { |
174 | return pvr2_i2c_write(hdw,i2c_addr,data: wdata,length: wlen); |
175 | } |
176 | } |
177 | |
178 | |
179 | /* This is a special entry point for cases of I2C transaction attempts to |
180 | the IR receiver. The implementation here simulates the IR receiver by |
181 | issuing a command to the FX2 firmware and using that response to return |
182 | what the real I2C receiver would have returned. We use this for 24xxx |
183 | devices, where the IR receiver chip has been removed and replaced with |
184 | FX2 related logic. */ |
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 | /* This is a probe attempt. Just let it succeed. */ |
193 | return 0; |
194 | } |
195 | |
196 | /* We don't understand this kind of transaction */ |
197 | if ((wlen != 0) || (rlen == 0)) return -EIO; |
198 | |
199 | if (rlen < 3) { |
200 | /* Mike Isely <isely@pobox.com> Appears to be a probe |
201 | attempt from lirc. Just fill in zeroes and return. If |
202 | we try instead to do the full transaction here, then bad |
203 | things seem to happen within the lirc driver module |
204 | (version 0.8.0-7 sources from Debian, when run under |
205 | vanilla 2.6.17.6 kernel) - and I don't have the patience |
206 | to chase it down. */ |
207 | if (rlen > 0) rdata[0] = 0; |
208 | if (rlen > 1) rdata[1] = 0; |
209 | return 0; |
210 | } |
211 | |
212 | /* Issue a command to the FX2 to read the IR receiver. */ |
213 | LOCK_TAKE(hdw->ctl_lock); do { |
214 | hdw->cmd_buffer[0] = FX2CMD_GET_IR_CODE; |
215 | stat = pvr2_send_request(hdw, |
216 | write_ptr: hdw->cmd_buffer,write_len: 1, |
217 | read_ptr: hdw->cmd_buffer,read_len: 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 | /* Give up if that operation failed. */ |
225 | if (stat != 0) return stat; |
226 | |
227 | /* Mangle the results into something that looks like the real IR |
228 | receiver. */ |
229 | rdata[2] = 0xc1; |
230 | if (dat[0] != 1) { |
231 | /* No code received. */ |
232 | rdata[0] = 0; |
233 | rdata[1] = 0; |
234 | } else { |
235 | u16 val; |
236 | /* Mash the FX2 firmware-provided IR code into something |
237 | that the normal i2c chip-level driver expects. */ |
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 | /* This is a special entry point that is entered if an I2C operation is |
252 | attempted to a wm8775 chip on model 24xxx hardware. Autodetect of this |
253 | part doesn't work, but we know it is really there. So let's look for |
254 | the autodetect attempt and just return success if we see that. */ |
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 | // This is a probe attempt. Just let it succeed. |
260 | return 0; |
261 | } |
262 | return pvr2_i2c_basic_op(hdw,i2c_addr,wdata,wlen,rdata,rlen); |
263 | } |
264 | |
265 | /* This is an entry point designed to always fail any attempt to perform a |
266 | transfer. We use this to cause certain I2C addresses to not be |
267 | probed. */ |
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 | /* This is a special entry point that is entered if an I2C operation is |
275 | attempted to a cx25840 chip on model 24xxx hardware. This chip can |
276 | sometimes wedge itself. Worse still, when this happens msp3400 can |
277 | falsely detect this part and then the system gets hosed up after msp3400 |
278 | gets confused and dies. What we want to do here is try to keep msp3400 |
279 | away and also try to notice if the chip is wedged and send a warning to |
280 | the system log. */ |
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 | // Probe attempt - always just succeed and don't bother the |
291 | // hardware (this helps to make the state machine further |
292 | // down somewhat easier). |
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 | /* We're looking for the exact pattern where the revision register |
301 | is being read. The cx25840 module will always look at the |
302 | revision register first. Any other pattern of access therefore |
303 | has to be a probe attempt from somebody else so we'll reject it. |
304 | Normally we could just let each client just probe the part |
305 | anyway, but when the cx25840 is wedged, msp3400 will get a false |
306 | positive and that just screws things up... */ |
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 | /* If we get to here then we have a legitimate read for one of the |
329 | two revision bytes, so pass it through. */ |
330 | wbuf[0] = subaddr >> 8; |
331 | wbuf[1] = subaddr; |
332 | ret = pvr2_i2c_basic_op(hdw,i2c_addr,wdata: wbuf,wlen: 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 | // This blocks all further communication with the part. |
342 | hdw->i2c_func[0x44] = NULL; |
343 | pvr2_hdw_render_useless(hdw); |
344 | goto fail; |
345 | } |
346 | |
347 | /* Success! */ |
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 | /* This is a very, very limited I2C adapter implementation. We can only |
361 | support what we actually know will work on the device... */ |
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 | /* Simple read */ |
385 | u16 tcnt,bcnt,offs; |
386 | if (!msgs[0].len) { |
387 | /* Length == 0 read. This is a probe. */ |
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 | /* If the read is short enough we'll do the whole |
396 | thing atomically. Otherwise we have no choice |
397 | but to break apart the reads. */ |
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 | /* Simple write */ |
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 | /* Write followed by atomic read. If the read |
434 | portion is short enough we'll do the whole thing |
435 | atomically. Otherwise we have no choice but to |
436 | break apart the reads. */ |
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 | /* Return true if device exists at given address */ |
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(adap: &hdw->i2c_adap, msgs: 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, addr: 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: /* FX2-controlled IR */ |
555 | case PVR2_IR_SCHEME_29XXX: /* Original 29xxx device */ |
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; /* ms From ir-kbd-i2c */ |
561 | /* IR Receiver */ |
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_client_device(adap: &hdw->i2c_adap, info: &info); |
568 | break; |
569 | case PVR2_IR_SCHEME_ZILOG: /* HVR-1950 style */ |
570 | case PVR2_IR_SCHEME_24XXX_MCE: /* 24xxx MCE device */ |
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 | /* IR Transceiver */ |
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_client_device(adap: &hdw->i2c_adap, info: &info); |
583 | break; |
584 | default: |
585 | /* The device either doesn't support I2C-based IR or we |
586 | don't know (yet) how to operate IR on the device. */ |
587 | break; |
588 | } |
589 | } |
590 | |
591 | void pvr2_i2c_core_init(struct pvr2_hdw *hdw) |
592 | { |
593 | unsigned int idx; |
594 | |
595 | /* The default action for all possible I2C addresses is just to do |
596 | the transfer normally. */ |
597 | for (idx = 0; idx < PVR2_I2C_FUNC_CNT; idx++) { |
598 | hdw->i2c_func[idx] = pvr2_i2c_basic_op; |
599 | } |
600 | |
601 | /* However, deal with various special cases for 24xxx hardware. */ |
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 | /* Set up translation so that our IR looks like a |
608 | 29xxx device */ |
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 | // Configure the adapter and set up everything else related to it. |
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(adap: &hdw->i2c_adap, data: &hdw->v4l2_dev); |
628 | i2c_add_adapter(adap: &hdw->i2c_adap); |
629 | if (hdw->i2c_func[0x18] == i2c_24xxx_ir) { |
630 | /* Probe for a different type of IR receiver on this |
631 | device. This is really the only way to differentiate |
632 | older 24xxx devices from 24xxx variants that include an |
633 | IR blaster. If the IR blaster is present, the IR |
634 | receiver is part of that chip and thus we must disable |
635 | the emulated IR receiver. */ |
636 | if (do_i2c_probe(hdw, addr: 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 | /* Remember that this is a different device... */ |
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(adap: &hdw->i2c_adap); |
653 | hdw->i2c_linked = 0; |
654 | } |
655 | } |
656 | |