]> git.proxmox.com Git - mirror_ubuntu-kernels.git/blame - drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
Merge branch 'for-linus' of git://git.kernel.dk/linux-2.6-block
[mirror_ubuntu-kernels.git] / drivers / media / video / pvrusb2 / pvrusb2-i2c-core.c
CommitLineData
d855497e
MI
1/*
2 *
d855497e
MI
3 *
4 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 */
20
59af3367 21#include <linux/i2c.h>
d855497e
MI
22#include "pvrusb2-i2c-core.h"
23#include "pvrusb2-hdw-internal.h"
24#include "pvrusb2-debug.h"
8d364363 25#include "pvrusb2-fx2-cmd.h"
5c808e64 26#include "pvrusb2.h"
d855497e
MI
27
28#define trace_i2c(...) pvr2_trace(PVR2_TRACE_I2C,__VA_ARGS__)
29
30/*
31
32 This module attempts to implement a compliant I2C adapter for the pvrusb2
59af3367 33 device.
d855497e
MI
34
35*/
36
ff699e6b 37static unsigned int i2c_scan;
d855497e
MI
38module_param(i2c_scan, int, S_IRUGO|S_IWUSR);
39MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time");
40
5c808e64
MI
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
d855497e
MI
45static int pvr2_i2c_write(struct pvr2_hdw *hdw, /* Context */
46 u8 i2c_addr, /* I2C address we're talking to */
47 u8 *data, /* Data to write */
48 u16 length) /* Size of data to write */
49{
50 /* Return value - default 0 means success */
51 int ret;
52
53
54 if (!data) length = 0;
55 if (length > (sizeof(hdw->cmd_buffer) - 3)) {
56 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
57 "Killing an I2C write to %u that is too large"
58 " (desired=%u limit=%u)",
59 i2c_addr,
60 length,(unsigned int)(sizeof(hdw->cmd_buffer) - 3));
61 return -ENOTSUPP;
62 }
63
64 LOCK_TAKE(hdw->ctl_lock);
65
66 /* Clear the command buffer (likely to be paranoia) */
67 memset(hdw->cmd_buffer, 0, sizeof(hdw->cmd_buffer));
68
69 /* Set up command buffer for an I2C write */
8d364363 70 hdw->cmd_buffer[0] = FX2CMD_I2C_WRITE; /* write prefix */
d855497e
MI
71 hdw->cmd_buffer[1] = i2c_addr; /* i2c addr of chip */
72 hdw->cmd_buffer[2] = length; /* length of what follows */
73 if (length) memcpy(hdw->cmd_buffer + 3, data, length);
74
75 /* Do the operation */
76 ret = pvr2_send_request(hdw,
77 hdw->cmd_buffer,
78 length + 3,
79 hdw->cmd_buffer,
80 1);
81 if (!ret) {
82 if (hdw->cmd_buffer[0] != 8) {
83 ret = -EIO;
84 if (hdw->cmd_buffer[0] != 7) {
85 trace_i2c("unexpected status"
86 " from i2_write[%d]: %d",
87 i2c_addr,hdw->cmd_buffer[0]);
88 }
89 }
90 }
91
92 LOCK_GIVE(hdw->ctl_lock);
93
94 return ret;
95}
96
97static int pvr2_i2c_read(struct pvr2_hdw *hdw, /* Context */
98 u8 i2c_addr, /* I2C address we're talking to */
99 u8 *data, /* Data to write */
100 u16 dlen, /* Size of data to write */
101 u8 *res, /* Where to put data we read */
102 u16 rlen) /* Amount of data to read */
103{
104 /* Return value - default 0 means success */
105 int ret;
106
107
108 if (!data) dlen = 0;
109 if (dlen > (sizeof(hdw->cmd_buffer) - 4)) {
110 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
111 "Killing an I2C read to %u that has wlen too large"
112 " (desired=%u limit=%u)",
113 i2c_addr,
114 dlen,(unsigned int)(sizeof(hdw->cmd_buffer) - 4));
115 return -ENOTSUPP;
116 }
117 if (res && (rlen > (sizeof(hdw->cmd_buffer) - 1))) {
118 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
119 "Killing an I2C read to %u that has rlen too large"
120 " (desired=%u limit=%u)",
121 i2c_addr,
122 rlen,(unsigned int)(sizeof(hdw->cmd_buffer) - 1));
123 return -ENOTSUPP;
124 }
125
126 LOCK_TAKE(hdw->ctl_lock);
127
128 /* Clear the command buffer (likely to be paranoia) */
129 memset(hdw->cmd_buffer, 0, sizeof(hdw->cmd_buffer));
130
131 /* Set up command buffer for an I2C write followed by a read */
8d364363 132 hdw->cmd_buffer[0] = FX2CMD_I2C_READ; /* read prefix */
d855497e
MI
133 hdw->cmd_buffer[1] = dlen; /* arg length */
134 hdw->cmd_buffer[2] = rlen; /* answer length. Device will send one
135 more byte (status). */
136 hdw->cmd_buffer[3] = i2c_addr; /* i2c addr of chip */
137 if (dlen) memcpy(hdw->cmd_buffer + 4, data, dlen);
138
139 /* Do the operation */
140 ret = pvr2_send_request(hdw,
141 hdw->cmd_buffer,
142 4 + dlen,
143 hdw->cmd_buffer,
144 rlen + 1);
145 if (!ret) {
146 if (hdw->cmd_buffer[0] != 8) {
147 ret = -EIO;
148 if (hdw->cmd_buffer[0] != 7) {
149 trace_i2c("unexpected status"
150 " from i2_read[%d]: %d",
151 i2c_addr,hdw->cmd_buffer[0]);
152 }
153 }
154 }
155
156 /* Copy back the result */
157 if (res && rlen) {
158 if (ret) {
159 /* Error, just blank out the return buffer */
160 memset(res, 0, rlen);
161 } else {
162 memcpy(res, hdw->cmd_buffer + 1, rlen);
163 }
164 }
165
166 LOCK_GIVE(hdw->ctl_lock);
167
168 return ret;
169}
170
171/* This is the common low level entry point for doing I2C operations to the
172 hardware. */
07e337ee
AB
173static int pvr2_i2c_basic_op(struct pvr2_hdw *hdw,
174 u8 i2c_addr,
175 u8 *wdata,
176 u16 wlen,
177 u8 *rdata,
178 u16 rlen)
d855497e
MI
179{
180 if (!rdata) rlen = 0;
181 if (!wdata) wlen = 0;
182 if (rlen || !wlen) {
183 return pvr2_i2c_read(hdw,i2c_addr,wdata,wlen,rdata,rlen);
184 } else {
185 return pvr2_i2c_write(hdw,i2c_addr,wdata,wlen);
186 }
187}
188
cc75aede
MI
189
190/* This is a special entry point for cases of I2C transaction attempts to
191 the IR receiver. The implementation here simulates the IR receiver by
192 issuing a command to the FX2 firmware and using that response to return
193 what the real I2C receiver would have returned. We use this for 24xxx
194 devices, where the IR receiver chip has been removed and replaced with
195 FX2 related logic. */
196static int i2c_24xxx_ir(struct pvr2_hdw *hdw,
197 u8 i2c_addr,u8 *wdata,u16 wlen,u8 *rdata,u16 rlen)
198{
199 u8 dat[4];
200 unsigned int stat;
201
202 if (!(rlen || wlen)) {
203 /* This is a probe attempt. Just let it succeed. */
204 return 0;
205 }
206
207 /* We don't understand this kind of transaction */
208 if ((wlen != 0) || (rlen == 0)) return -EIO;
209
210 if (rlen < 3) {
211 /* Mike Isely <isely@pobox.com> Appears to be a probe
212 attempt from lirc. Just fill in zeroes and return. If
213 we try instead to do the full transaction here, then bad
214 things seem to happen within the lirc driver module
215 (version 0.8.0-7 sources from Debian, when run under
216 vanilla 2.6.17.6 kernel) - and I don't have the patience
217 to chase it down. */
218 if (rlen > 0) rdata[0] = 0;
219 if (rlen > 1) rdata[1] = 0;
220 return 0;
221 }
222
223 /* Issue a command to the FX2 to read the IR receiver. */
224 LOCK_TAKE(hdw->ctl_lock); do {
8d364363 225 hdw->cmd_buffer[0] = FX2CMD_GET_IR_CODE;
cc75aede
MI
226 stat = pvr2_send_request(hdw,
227 hdw->cmd_buffer,1,
228 hdw->cmd_buffer,4);
229 dat[0] = hdw->cmd_buffer[0];
230 dat[1] = hdw->cmd_buffer[1];
231 dat[2] = hdw->cmd_buffer[2];
232 dat[3] = hdw->cmd_buffer[3];
233 } while (0); LOCK_GIVE(hdw->ctl_lock);
234
235 /* Give up if that operation failed. */
236 if (stat != 0) return stat;
237
238 /* Mangle the results into something that looks like the real IR
239 receiver. */
240 rdata[2] = 0xc1;
241 if (dat[0] != 1) {
242 /* No code received. */
243 rdata[0] = 0;
244 rdata[1] = 0;
245 } else {
246 u16 val;
247 /* Mash the FX2 firmware-provided IR code into something
248 that the normal i2c chip-level driver expects. */
249 val = dat[1];
250 val <<= 8;
251 val |= dat[2];
252 val >>= 1;
253 val &= ~0x0003;
254 val |= 0x8000;
255 rdata[0] = (val >> 8) & 0xffu;
256 rdata[1] = val & 0xffu;
257 }
258
259 return 0;
260}
261
d855497e
MI
262/* This is a special entry point that is entered if an I2C operation is
263 attempted to a wm8775 chip on model 24xxx hardware. Autodetect of this
264 part doesn't work, but we know it is really there. So let's look for
265 the autodetect attempt and just return success if we see that. */
266static int i2c_hack_wm8775(struct pvr2_hdw *hdw,
267 u8 i2c_addr,u8 *wdata,u16 wlen,u8 *rdata,u16 rlen)
268{
269 if (!(rlen || wlen)) {
270 // This is a probe attempt. Just let it succeed.
271 return 0;
272 }
273 return pvr2_i2c_basic_op(hdw,i2c_addr,wdata,wlen,rdata,rlen);
274}
275
5c808e64
MI
276/* This is an entry point designed to always fail any attempt to perform a
277 transfer. We use this to cause certain I2C addresses to not be
278 probed. */
279static int i2c_black_hole(struct pvr2_hdw *hdw,
280 u8 i2c_addr,u8 *wdata,u16 wlen,u8 *rdata,u16 rlen)
281{
282 return -EIO;
283}
284
d855497e
MI
285/* This is a special entry point that is entered if an I2C operation is
286 attempted to a cx25840 chip on model 24xxx hardware. This chip can
287 sometimes wedge itself. Worse still, when this happens msp3400 can
288 falsely detect this part and then the system gets hosed up after msp3400
289 gets confused and dies. What we want to do here is try to keep msp3400
290 away and also try to notice if the chip is wedged and send a warning to
291 the system log. */
292static int i2c_hack_cx25840(struct pvr2_hdw *hdw,
293 u8 i2c_addr,u8 *wdata,u16 wlen,u8 *rdata,u16 rlen)
294{
295 int ret;
296 unsigned int subaddr;
297 u8 wbuf[2];
298 int state = hdw->i2c_cx25840_hack_state;
299
300 if (!(rlen || wlen)) {
301 // Probe attempt - always just succeed and don't bother the
302 // hardware (this helps to make the state machine further
303 // down somewhat easier).
304 return 0;
305 }
306
307 if (state == 3) {
308 return pvr2_i2c_basic_op(hdw,i2c_addr,wdata,wlen,rdata,rlen);
309 }
310
311 /* We're looking for the exact pattern where the revision register
312 is being read. The cx25840 module will always look at the
313 revision register first. Any other pattern of access therefore
314 has to be a probe attempt from somebody else so we'll reject it.
315 Normally we could just let each client just probe the part
316 anyway, but when the cx25840 is wedged, msp3400 will get a false
317 positive and that just screws things up... */
318
319 if (wlen == 0) {
320 switch (state) {
321 case 1: subaddr = 0x0100; break;
322 case 2: subaddr = 0x0101; break;
323 default: goto fail;
324 }
325 } else if (wlen == 2) {
326 subaddr = (wdata[0] << 8) | wdata[1];
327 switch (subaddr) {
328 case 0x0100: state = 1; break;
329 case 0x0101: state = 2; break;
330 default: goto fail;
331 }
332 } else {
333 goto fail;
334 }
335 if (!rlen) goto success;
336 state = 0;
337 if (rlen != 1) goto fail;
338
339 /* If we get to here then we have a legitimate read for one of the
340 two revision bytes, so pass it through. */
341 wbuf[0] = subaddr >> 8;
342 wbuf[1] = subaddr;
343 ret = pvr2_i2c_basic_op(hdw,i2c_addr,wbuf,2,rdata,rlen);
344
345 if ((ret != 0) || (*rdata == 0x04) || (*rdata == 0x0a)) {
346 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
347 "WARNING: Detected a wedged cx25840 chip;"
348 " the device will not work.");
349 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
350 "WARNING: Try power cycling the pvrusb2 device.");
351 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
352 "WARNING: Disabling further access to the device"
353 " to prevent other foul-ups.");
354 // This blocks all further communication with the part.
a0fd1cb1 355 hdw->i2c_func[0x44] = NULL;
d855497e
MI
356 pvr2_hdw_render_useless(hdw);
357 goto fail;
358 }
359
360 /* Success! */
361 pvr2_trace(PVR2_TRACE_CHIPS,"cx25840 appears to be OK.");
362 state = 3;
363
364 success:
365 hdw->i2c_cx25840_hack_state = state;
366 return 0;
367
368 fail:
369 hdw->i2c_cx25840_hack_state = state;
370 return -EIO;
371}
372
d855497e
MI
373/* This is a very, very limited I2C adapter implementation. We can only
374 support what we actually know will work on the device... */
375static int pvr2_i2c_xfer(struct i2c_adapter *i2c_adap,
376 struct i2c_msg msgs[],
377 int num)
378{
379 int ret = -ENOTSUPP;
a0fd1cb1 380 pvr2_i2c_func funcp = NULL;
d855497e
MI
381 struct pvr2_hdw *hdw = (struct pvr2_hdw *)(i2c_adap->algo_data);
382
383 if (!num) {
384 ret = -EINVAL;
385 goto done;
386 }
d855497e
MI
387 if (msgs[0].addr < PVR2_I2C_FUNC_CNT) {
388 funcp = hdw->i2c_func[msgs[0].addr];
389 }
390 if (!funcp) {
391 ret = -EIO;
392 goto done;
393 }
394
395 if (num == 1) {
396 if (msgs[0].flags & I2C_M_RD) {
397 /* Simple read */
398 u16 tcnt,bcnt,offs;
399 if (!msgs[0].len) {
400 /* Length == 0 read. This is a probe. */
a0fd1cb1 401 if (funcp(hdw,msgs[0].addr,NULL,0,NULL,0)) {
d855497e
MI
402 ret = -EIO;
403 goto done;
404 }
405 ret = 1;
406 goto done;
407 }
408 /* If the read is short enough we'll do the whole
409 thing atomically. Otherwise we have no choice
410 but to break apart the reads. */
411 tcnt = msgs[0].len;
412 offs = 0;
413 while (tcnt) {
414 bcnt = tcnt;
415 if (bcnt > sizeof(hdw->cmd_buffer)-1) {
416 bcnt = sizeof(hdw->cmd_buffer)-1;
417 }
a0fd1cb1 418 if (funcp(hdw,msgs[0].addr,NULL,0,
d855497e
MI
419 msgs[0].buf+offs,bcnt)) {
420 ret = -EIO;
421 goto done;
422 }
423 offs += bcnt;
424 tcnt -= bcnt;
425 }
426 ret = 1;
427 goto done;
428 } else {
429 /* Simple write */
430 ret = 1;
431 if (funcp(hdw,msgs[0].addr,
a0fd1cb1 432 msgs[0].buf,msgs[0].len,NULL,0)) {
d855497e
MI
433 ret = -EIO;
434 }
435 goto done;
436 }
437 } else if (num == 2) {
438 if (msgs[0].addr != msgs[1].addr) {
439 trace_i2c("i2c refusing 2 phase transfer with"
440 " conflicting target addresses");
441 ret = -ENOTSUPP;
442 goto done;
443 }
444 if ((!((msgs[0].flags & I2C_M_RD))) &&
445 (msgs[1].flags & I2C_M_RD)) {
446 u16 tcnt,bcnt,wcnt,offs;
447 /* Write followed by atomic read. If the read
448 portion is short enough we'll do the whole thing
449 atomically. Otherwise we have no choice but to
450 break apart the reads. */
451 tcnt = msgs[1].len;
452 wcnt = msgs[0].len;
453 offs = 0;
454 while (tcnt || wcnt) {
455 bcnt = tcnt;
456 if (bcnt > sizeof(hdw->cmd_buffer)-1) {
457 bcnt = sizeof(hdw->cmd_buffer)-1;
458 }
459 if (funcp(hdw,msgs[0].addr,
460 msgs[0].buf,wcnt,
461 msgs[1].buf+offs,bcnt)) {
462 ret = -EIO;
463 goto done;
464 }
465 offs += bcnt;
466 tcnt -= bcnt;
467 wcnt = 0;
468 }
469 ret = 2;
470 goto done;
471 } else {
472 trace_i2c("i2c refusing complex transfer"
473 " read0=%d read1=%d",
474 (msgs[0].flags & I2C_M_RD),
475 (msgs[1].flags & I2C_M_RD));
476 }
477 } else {
478 trace_i2c("i2c refusing %d phase transfer",num);
479 }
480
481 done:
482 if (pvrusb2_debug & PVR2_TRACE_I2C_TRAF) {
483 unsigned int idx,offs,cnt;
484 for (idx = 0; idx < num; idx++) {
485 cnt = msgs[idx].len;
486 printk(KERN_INFO
487 "pvrusb2 i2c xfer %u/%u:"
7fb0dfc8 488 " addr=0x%x len=%d %s",
d855497e
MI
489 idx+1,num,
490 msgs[idx].addr,
491 cnt,
492 (msgs[idx].flags & I2C_M_RD ?
7fb0dfc8 493 "read" : "write"));
d855497e
MI
494 if ((ret > 0) || !(msgs[idx].flags & I2C_M_RD)) {
495 if (cnt > 8) cnt = 8;
496 printk(" [");
497 for (offs = 0; offs < (cnt>8?8:cnt); offs++) {
498 if (offs) printk(" ");
499 printk("%02x",msgs[idx].buf[offs]);
500 }
501 if (offs < cnt) printk(" ...");
502 printk("]");
503 }
504 if (idx+1 == num) {
505 printk(" result=%d",ret);
506 }
507 printk("\n");
508 }
509 if (!num) {
510 printk(KERN_INFO
511 "pvrusb2 i2c xfer null transfer result=%d\n",
512 ret);
513 }
514 }
515 return ret;
516}
517
d855497e
MI
518static u32 pvr2_i2c_functionality(struct i2c_adapter *adap)
519{
7fb0dfc8 520 return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C;
d855497e
MI
521}
522
d855497e
MI
523static struct i2c_algorithm pvr2_i2c_algo_template = {
524 .master_xfer = pvr2_i2c_xfer,
d855497e
MI
525 .functionality = pvr2_i2c_functionality,
526};
527
528static struct i2c_adapter pvr2_i2c_adap_template = {
529 .owner = THIS_MODULE,
15b47442 530 .class = 0,
d855497e 531 .id = I2C_HW_B_BT848,
d855497e
MI
532};
533
0cc11867
MI
534
535/* Return true if device exists at given address */
536static int do_i2c_probe(struct pvr2_hdw *hdw, int addr)
d855497e
MI
537{
538 struct i2c_msg msg[1];
0cc11867 539 int rc;
d855497e
MI
540 msg[0].addr = 0;
541 msg[0].flags = I2C_M_RD;
542 msg[0].len = 0;
a0fd1cb1 543 msg[0].buf = NULL;
0cc11867
MI
544 msg[0].addr = addr;
545 rc = i2c_transfer(&hdw->i2c_adap, msg, ARRAY_SIZE(msg));
546 return rc == 1;
547}
548
549static void do_i2c_scan(struct pvr2_hdw *hdw)
550{
551 int i;
552 printk(KERN_INFO "%s: i2c scan beginning\n", hdw->name);
d855497e 553 for (i = 0; i < 128; i++) {
0cc11867
MI
554 if (do_i2c_probe(hdw, i)) {
555 printk(KERN_INFO "%s: i2c scan: found device @ 0x%x\n",
556 hdw->name, i);
557 }
d855497e 558 }
0cc11867 559 printk(KERN_INFO "%s: i2c scan done.\n", hdw->name);
d855497e
MI
560}
561
562void pvr2_i2c_core_init(struct pvr2_hdw *hdw)
563{
564 unsigned int idx;
565
cc75aede
MI
566 /* The default action for all possible I2C addresses is just to do
567 the transfer normally. */
d855497e
MI
568 for (idx = 0; idx < PVR2_I2C_FUNC_CNT; idx++) {
569 hdw->i2c_func[idx] = pvr2_i2c_basic_op;
570 }
571
cc75aede 572 /* However, deal with various special cases for 24xxx hardware. */
5c808e64
MI
573 if (ir_mode[hdw->unit_number] == 0) {
574 printk(KERN_INFO "%s: IR disabled\n",hdw->name);
575 hdw->i2c_func[0x18] = i2c_black_hole;
576 } else if (ir_mode[hdw->unit_number] == 1) {
31335b13 577 if (hdw->hdw_desc->ir_scheme == PVR2_IR_SCHEME_24XXX) {
5c808e64
MI
578 hdw->i2c_func[0x18] = i2c_24xxx_ir;
579 }
580 }
989eb154 581 if (hdw->hdw_desc->flag_has_cx25840) {
d855497e
MI
582 hdw->i2c_func[0x44] = i2c_hack_cx25840;
583 }
989eb154
MI
584 if (hdw->hdw_desc->flag_has_wm8775) {
585 hdw->i2c_func[0x1b] = i2c_hack_wm8775;
586 }
d855497e
MI
587
588 // Configure the adapter and set up everything else related to it.
589 memcpy(&hdw->i2c_adap,&pvr2_i2c_adap_template,sizeof(hdw->i2c_adap));
590 memcpy(&hdw->i2c_algo,&pvr2_i2c_algo_template,sizeof(hdw->i2c_algo));
591 strlcpy(hdw->i2c_adap.name,hdw->name,sizeof(hdw->i2c_adap.name));
12a917f6 592 hdw->i2c_adap.dev.parent = &hdw->usb_dev->dev;
d855497e
MI
593 hdw->i2c_adap.algo = &hdw->i2c_algo;
594 hdw->i2c_adap.algo_data = hdw;
d855497e 595 hdw->i2c_linked = !0;
e9c64a78 596 i2c_set_adapdata(&hdw->i2c_adap, &hdw->v4l2_dev);
d855497e 597 i2c_add_adapter(&hdw->i2c_adap);
0cc11867
MI
598 if (hdw->i2c_func[0x18] == i2c_24xxx_ir) {
599 /* Probe for a different type of IR receiver on this
600 device. If present, disable the emulated IR receiver. */
601 if (do_i2c_probe(hdw, 0x71)) {
602 pvr2_trace(PVR2_TRACE_INFO,
603 "Device has newer IR hardware;"
604 " disabling unneeded virtual IR device");
605 hdw->i2c_func[0x18] = NULL;
606 }
607 }
d855497e
MI
608 if (i2c_scan) do_i2c_scan(hdw);
609}
610
611void pvr2_i2c_core_done(struct pvr2_hdw *hdw)
612{
613 if (hdw->i2c_linked) {
614 i2c_del_adapter(&hdw->i2c_adap);
615 hdw->i2c_linked = 0;
616 }
617}
618
619/*
620 Stuff for Emacs to see, in order to encourage consistent editing style:
621 *** Local Variables: ***
622 *** mode: c ***
623 *** fill-column: 75 ***
624 *** tab-width: 8 ***
625 *** c-basic-offset: 8 ***
626 *** End: ***
627 */