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