Merge branch 'linus' into irq/threaded
[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-hdw-internal.h"
24 #include "pvrusb2-debug.h"
25 #include "pvrusb2-fx2-cmd.h"
26 #include "pvrusb2.h"
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
33   device.
34
35 */
36
37 static unsigned int i2c_scan;
38 module_param(i2c_scan, int, S_IRUGO|S_IWUSR);
39 MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time");
40
41 static int ir_mode[PVR_NUM] = { [0 ... PVR_NUM-1] = 1 };
42 module_param_array(ir_mode, int, NULL, 0444);
43 MODULE_PARM_DESC(ir_mode,"specify: 0=disable IR reception, 1=normal IR");
44
45 static 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 */
70         hdw->cmd_buffer[0] = FX2CMD_I2C_WRITE;      /* write prefix */
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
97 static 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 */
132         hdw->cmd_buffer[0] = FX2CMD_I2C_READ;  /* read prefix */
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. */
173 static 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)
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
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. */
196 static 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 {
225                 hdw->cmd_buffer[0] = FX2CMD_GET_IR_CODE;
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
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. */
266 static 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
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. */
279 static 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
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. */
292 static 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.
355                 hdw->i2c_func[0x44] = NULL;
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
373 /* This is a very, very limited I2C adapter implementation.  We can only
374    support what we actually know will work on the device... */
375 static int pvr2_i2c_xfer(struct i2c_adapter *i2c_adap,
376                          struct i2c_msg msgs[],
377                          int num)
378 {
379         int ret = -ENOTSUPP;
380         pvr2_i2c_func funcp = NULL;
381         struct pvr2_hdw *hdw = (struct pvr2_hdw *)(i2c_adap->algo_data);
382
383         if (!num) {
384                 ret = -EINVAL;
385                 goto done;
386         }
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. */
401                                 if (funcp(hdw,msgs[0].addr,NULL,0,NULL,0)) {
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                                 }
418                                 if (funcp(hdw,msgs[0].addr,NULL,0,
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,
432                                   msgs[0].buf,msgs[0].len,NULL,0)) {
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:"
488                                " addr=0x%x len=%d %s",
489                                idx+1,num,
490                                msgs[idx].addr,
491                                cnt,
492                                (msgs[idx].flags & I2C_M_RD ?
493                                 "read" : "write"));
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
518 static u32 pvr2_i2c_functionality(struct i2c_adapter *adap)
519 {
520         return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C;
521 }
522
523 static int pvr2_i2c_attach_inform(struct i2c_client *client)
524 {
525         return 0;
526 }
527
528 static int pvr2_i2c_detach_inform(struct i2c_client *client)
529 {
530         return 0;
531 }
532
533 static struct i2c_algorithm pvr2_i2c_algo_template = {
534         .master_xfer   = pvr2_i2c_xfer,
535         .functionality = pvr2_i2c_functionality,
536 };
537
538 static struct i2c_adapter pvr2_i2c_adap_template = {
539         .owner         = THIS_MODULE,
540         .class         = 0,
541         .id            = I2C_HW_B_BT848,
542         .client_register = pvr2_i2c_attach_inform,
543         .client_unregister = pvr2_i2c_detach_inform,
544 };
545
546
547 /* Return true if device exists at given address */
548 static int do_i2c_probe(struct pvr2_hdw *hdw, int addr)
549 {
550         struct i2c_msg msg[1];
551         int rc;
552         msg[0].addr = 0;
553         msg[0].flags = I2C_M_RD;
554         msg[0].len = 0;
555         msg[0].buf = NULL;
556         msg[0].addr = addr;
557         rc = i2c_transfer(&hdw->i2c_adap, msg, ARRAY_SIZE(msg));
558         return rc == 1;
559 }
560
561 static void do_i2c_scan(struct pvr2_hdw *hdw)
562 {
563         int i;
564         printk(KERN_INFO "%s: i2c scan beginning\n", hdw->name);
565         for (i = 0; i < 128; i++) {
566                 if (do_i2c_probe(hdw, i)) {
567                         printk(KERN_INFO "%s: i2c scan: found device @ 0x%x\n",
568                                hdw->name, i);
569                 }
570         }
571         printk(KERN_INFO "%s: i2c scan done.\n", hdw->name);
572 }
573
574 void pvr2_i2c_core_init(struct pvr2_hdw *hdw)
575 {
576         unsigned int idx;
577
578         /* The default action for all possible I2C addresses is just to do
579            the transfer normally. */
580         for (idx = 0; idx < PVR2_I2C_FUNC_CNT; idx++) {
581                 hdw->i2c_func[idx] = pvr2_i2c_basic_op;
582         }
583
584         /* However, deal with various special cases for 24xxx hardware. */
585         if (ir_mode[hdw->unit_number] == 0) {
586                 printk(KERN_INFO "%s: IR disabled\n",hdw->name);
587                 hdw->i2c_func[0x18] = i2c_black_hole;
588         } else if (ir_mode[hdw->unit_number] == 1) {
589                 if (hdw->hdw_desc->ir_scheme == PVR2_IR_SCHEME_24XXX) {
590                         hdw->i2c_func[0x18] = i2c_24xxx_ir;
591                 }
592         }
593         if (hdw->hdw_desc->flag_has_cx25840) {
594                 hdw->i2c_func[0x44] = i2c_hack_cx25840;
595         }
596         if (hdw->hdw_desc->flag_has_wm8775) {
597                 hdw->i2c_func[0x1b] = i2c_hack_wm8775;
598         }
599
600         // Configure the adapter and set up everything else related to it.
601         memcpy(&hdw->i2c_adap,&pvr2_i2c_adap_template,sizeof(hdw->i2c_adap));
602         memcpy(&hdw->i2c_algo,&pvr2_i2c_algo_template,sizeof(hdw->i2c_algo));
603         strlcpy(hdw->i2c_adap.name,hdw->name,sizeof(hdw->i2c_adap.name));
604         hdw->i2c_adap.dev.parent = &hdw->usb_dev->dev;
605         hdw->i2c_adap.algo = &hdw->i2c_algo;
606         hdw->i2c_adap.algo_data = hdw;
607         hdw->i2c_linked = !0;
608         i2c_set_adapdata(&hdw->i2c_adap, &hdw->v4l2_dev);
609         i2c_add_adapter(&hdw->i2c_adap);
610         if (hdw->i2c_func[0x18] == i2c_24xxx_ir) {
611                 /* Probe for a different type of IR receiver on this
612                    device.  If present, disable the emulated IR receiver. */
613                 if (do_i2c_probe(hdw, 0x71)) {
614                         pvr2_trace(PVR2_TRACE_INFO,
615                                    "Device has newer IR hardware;"
616                                    " disabling unneeded virtual IR device");
617                         hdw->i2c_func[0x18] = NULL;
618                 }
619         }
620         if (i2c_scan) do_i2c_scan(hdw);
621 }
622
623 void pvr2_i2c_core_done(struct pvr2_hdw *hdw)
624 {
625         if (hdw->i2c_linked) {
626                 i2c_del_adapter(&hdw->i2c_adap);
627                 hdw->i2c_linked = 0;
628         }
629 }
630
631 /*
632   Stuff for Emacs to see, in order to encourage consistent editing style:
633   *** Local Variables: ***
634   *** mode: c ***
635   *** fill-column: 75 ***
636   *** tab-width: 8 ***
637   *** c-basic-offset: 8 ***
638   *** End: ***
639   */