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