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