linux/drivers/media/pci/saa7134/saa7134-i2c.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 *
   4 * device driver for philips saa7134 based TV cards
   5 * i2c interface support
   6 *
   7 * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
   8 */
   9
  10#include "saa7134.h"
  11#include "saa7134-reg.h"
  12
  13#include <linux/init.h>
  14#include <linux/list.h>
  15#include <linux/module.h>
  16#include <linux/kernel.h>
  17#include <linux/delay.h>
  18
  19#include <media/v4l2-common.h>
  20
  21/* ----------------------------------------------------------- */
  22
  23static unsigned int i2c_debug;
  24module_param(i2c_debug, int, 0644);
  25MODULE_PARM_DESC(i2c_debug,"enable debug messages [i2c]");
  26
  27static unsigned int i2c_scan;
  28module_param(i2c_scan, int, 0444);
  29MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time");
  30
  31#define i2c_dbg(level, fmt, arg...) do { \
  32        if (i2c_debug == level) \
  33                printk(KERN_DEBUG pr_fmt("i2c: " fmt), ## arg); \
  34        } while (0)
  35
  36#define i2c_cont(level, fmt, arg...) do { \
  37        if (i2c_debug == level) \
  38                pr_cont(fmt, ## arg); \
  39        } while (0)
  40
  41#define I2C_WAIT_DELAY  32
  42#define I2C_WAIT_RETRY  16
  43
  44/* ----------------------------------------------------------- */
  45
  46static char *str_i2c_status[] = {
  47        "IDLE", "DONE_STOP", "BUSY", "TO_SCL", "TO_ARB", "DONE_WRITE",
  48        "DONE_READ", "DONE_WRITE_TO", "DONE_READ_TO", "NO_DEVICE",
  49        "NO_ACKN", "BUS_ERR", "ARB_LOST", "SEQ_ERR", "ST_ERR", "SW_ERR"
  50};
  51
  52enum i2c_status {
  53        IDLE          = 0,  // no I2C command pending
  54        DONE_STOP     = 1,  // I2C command done and STOP executed
  55        BUSY          = 2,  // executing I2C command
  56        TO_SCL        = 3,  // executing I2C command, time out on clock stretching
  57        TO_ARB        = 4,  // time out on arbitration trial, still trying
  58        DONE_WRITE    = 5,  // I2C command done and awaiting next write command
  59        DONE_READ     = 6,  // I2C command done and awaiting next read command
  60        DONE_WRITE_TO = 7,  // see 5, and time out on status echo
  61        DONE_READ_TO  = 8,  // see 6, and time out on status echo
  62        NO_DEVICE     = 9,  // no acknowledge on device slave address
  63        NO_ACKN       = 10, // no acknowledge after data byte transfer
  64        BUS_ERR       = 11, // bus error
  65        ARB_LOST      = 12, // arbitration lost during transfer
  66        SEQ_ERR       = 13, // erroneous programming sequence
  67        ST_ERR        = 14, // wrong status echoing
  68        SW_ERR        = 15  // software error
  69};
  70
  71static char *str_i2c_attr[] = {
  72        "NOP", "STOP", "CONTINUE", "START"
  73};
  74
  75enum i2c_attr {
  76        NOP           = 0,  // no operation on I2C bus
  77        STOP          = 1,  // stop condition, no associated byte transfer
  78        CONTINUE      = 2,  // continue with byte transfer
  79        START         = 3   // start condition with byte transfer
  80};
  81
  82static inline enum i2c_status i2c_get_status(struct saa7134_dev *dev)
  83{
  84        enum i2c_status status;
  85
  86        status = saa_readb(SAA7134_I2C_ATTR_STATUS) & 0x0f;
  87        i2c_dbg(2, "i2c stat <= %s\n", str_i2c_status[status]);
  88        return status;
  89}
  90
  91static inline void i2c_set_status(struct saa7134_dev *dev,
  92                                  enum i2c_status status)
  93{
  94        i2c_dbg(2, "i2c stat => %s\n", str_i2c_status[status]);
  95        saa_andorb(SAA7134_I2C_ATTR_STATUS,0x0f,status);
  96}
  97
  98static inline void i2c_set_attr(struct saa7134_dev *dev, enum i2c_attr attr)
  99{
 100        i2c_dbg(2, "i2c attr => %s\n", str_i2c_attr[attr]);
 101        saa_andorb(SAA7134_I2C_ATTR_STATUS,0xc0,attr << 6);
 102}
 103
 104static inline int i2c_is_error(enum i2c_status status)
 105{
 106        switch (status) {
 107        case NO_DEVICE:
 108        case NO_ACKN:
 109        case BUS_ERR:
 110        case ARB_LOST:
 111        case SEQ_ERR:
 112        case ST_ERR:
 113                return true;
 114        default:
 115                return false;
 116        }
 117}
 118
 119static inline int i2c_is_idle(enum i2c_status status)
 120{
 121        switch (status) {
 122        case IDLE:
 123        case DONE_STOP:
 124                return true;
 125        default:
 126                return false;
 127        }
 128}
 129
 130static inline int i2c_is_busy(enum i2c_status status)
 131{
 132        switch (status) {
 133        case BUSY:
 134        case TO_SCL:
 135        case TO_ARB:
 136                return true;
 137        default:
 138                return false;
 139        }
 140}
 141
 142static int i2c_is_busy_wait(struct saa7134_dev *dev)
 143{
 144        enum i2c_status status;
 145        int count;
 146
 147        for (count = 0; count < I2C_WAIT_RETRY; count++) {
 148                status = i2c_get_status(dev);
 149                if (!i2c_is_busy(status))
 150                        break;
 151                saa_wait(I2C_WAIT_DELAY);
 152        }
 153        if (I2C_WAIT_RETRY == count)
 154                return false;
 155        return true;
 156}
 157
 158static int i2c_reset(struct saa7134_dev *dev)
 159{
 160        enum i2c_status status;
 161        int count;
 162
 163        i2c_dbg(2, "i2c reset\n");
 164        status = i2c_get_status(dev);
 165        if (!i2c_is_error(status))
 166                return true;
 167        i2c_set_status(dev,status);
 168
 169        for (count = 0; count < I2C_WAIT_RETRY; count++) {
 170                status = i2c_get_status(dev);
 171                if (!i2c_is_error(status))
 172                        break;
 173                udelay(I2C_WAIT_DELAY);
 174        }
 175        if (I2C_WAIT_RETRY == count)
 176                return false;
 177
 178        if (!i2c_is_idle(status))
 179                return false;
 180
 181        i2c_set_attr(dev,NOP);
 182        return true;
 183}
 184
 185static inline int i2c_send_byte(struct saa7134_dev *dev,
 186                                enum i2c_attr attr,
 187                                unsigned char data)
 188{
 189        enum i2c_status status;
 190        __u32 dword;
 191
 192        /* have to write both attr + data in one 32bit word */
 193        dword  = saa_readl(SAA7134_I2C_ATTR_STATUS >> 2);
 194        dword &= 0x0f;
 195        dword |= (attr << 6);
 196        dword |= ((__u32)data << 8);
 197        dword |= 0x00 << 16;  /* 100 kHz */
 198//      dword |= 0x40 << 16;  /* 400 kHz */
 199        dword |= 0xf0 << 24;
 200        saa_writel(SAA7134_I2C_ATTR_STATUS >> 2, dword);
 201        i2c_dbg(2, "i2c data => 0x%x\n", data);
 202
 203        if (!i2c_is_busy_wait(dev))
 204                return -EIO;
 205        status = i2c_get_status(dev);
 206        if (i2c_is_error(status))
 207                return -EIO;
 208        return 0;
 209}
 210
 211static inline int i2c_recv_byte(struct saa7134_dev *dev)
 212{
 213        enum i2c_status status;
 214        unsigned char data;
 215
 216        i2c_set_attr(dev,CONTINUE);
 217        if (!i2c_is_busy_wait(dev))
 218                return -EIO;
 219        status = i2c_get_status(dev);
 220        if (i2c_is_error(status))
 221                return -EIO;
 222        data = saa_readb(SAA7134_I2C_DATA);
 223        i2c_dbg(2, "i2c data <= 0x%x\n", data);
 224        return data;
 225}
 226
 227static int saa7134_i2c_xfer(struct i2c_adapter *i2c_adap,
 228                            struct i2c_msg *msgs, int num)
 229{
 230        struct saa7134_dev *dev = i2c_adap->algo_data;
 231        enum i2c_status status;
 232        unsigned char data;
 233        int addr,rc,i,byte;
 234
 235        status = i2c_get_status(dev);
 236        if (!i2c_is_idle(status))
 237                if (!i2c_reset(dev))
 238                        return -EIO;
 239
 240        i2c_dbg(2, "start xfer\n");
 241        i2c_dbg(1, "i2c xfer:");
 242        for (i = 0; i < num; i++) {
 243                if (!(msgs[i].flags & I2C_M_NOSTART) || 0 == i) {
 244                        /* send address */
 245                        i2c_dbg(2, "send address\n");
 246                        addr  = msgs[i].addr << 1;
 247                        if (msgs[i].flags & I2C_M_RD)
 248                                addr |= 1;
 249                        if (i > 0 && msgs[i].flags &
 250                            I2C_M_RD && msgs[i].addr != 0x40 &&
 251                            msgs[i].addr != 0x41 &&
 252                            msgs[i].addr != 0x19) {
 253                                /* workaround for a saa7134 i2c bug
 254                                 * needed to talk to the mt352 demux
 255                                 * thanks to pinnacle for the hint */
 256                                int quirk = 0xfe;
 257                                i2c_cont(1, " [%02x quirk]", quirk);
 258                                i2c_send_byte(dev,START,quirk);
 259                                i2c_recv_byte(dev);
 260                        }
 261                        i2c_cont(1, " < %02x", addr);
 262                        rc = i2c_send_byte(dev,START,addr);
 263                        if (rc < 0)
 264                                 goto err;
 265                }
 266                if (msgs[i].flags & I2C_M_RD) {
 267                        /* read bytes */
 268                        i2c_dbg(2, "read bytes\n");
 269                        for (byte = 0; byte < msgs[i].len; byte++) {
 270                                i2c_cont(1, " =");
 271                                rc = i2c_recv_byte(dev);
 272                                if (rc < 0)
 273                                        goto err;
 274                                i2c_cont(1, "%02x", rc);
 275                                msgs[i].buf[byte] = rc;
 276                        }
 277                        /* discard mysterious extra byte when reading
 278                           from Samsung S5H1411.  i2c bus gets error
 279                           if we do not. */
 280                        if (0x19 == msgs[i].addr) {
 281                                i2c_cont(1, " ?");
 282                                rc = i2c_recv_byte(dev);
 283                                if (rc < 0)
 284                                        goto err;
 285                                i2c_cont(1, "%02x", rc);
 286                        }
 287                } else {
 288                        /* write bytes */
 289                        i2c_dbg(2, "write bytes\n");
 290                        for (byte = 0; byte < msgs[i].len; byte++) {
 291                                data = msgs[i].buf[byte];
 292                                i2c_cont(1, " %02x", data);
 293                                rc = i2c_send_byte(dev,CONTINUE,data);
 294                                if (rc < 0)
 295                                        goto err;
 296                        }
 297                }
 298        }
 299        i2c_dbg(2, "xfer done\n");
 300        i2c_cont(1, " >");
 301        i2c_set_attr(dev,STOP);
 302        rc = -EIO;
 303        if (!i2c_is_busy_wait(dev))
 304                goto err;
 305        status = i2c_get_status(dev);
 306        if (i2c_is_error(status))
 307                goto err;
 308        /* ensure that the bus is idle for at least one bit slot */
 309        msleep(1);
 310
 311        i2c_cont(1, "\n");
 312        return num;
 313 err:
 314        if (1 == i2c_debug) {
 315                status = i2c_get_status(dev);
 316                i2c_cont(1, " ERROR: %s\n", str_i2c_status[status]);
 317        }
 318        return rc;
 319}
 320
 321/* ----------------------------------------------------------- */
 322
 323static u32 functionality(struct i2c_adapter *adap)
 324{
 325        return I2C_FUNC_SMBUS_EMUL;
 326}
 327
 328static const struct i2c_algorithm saa7134_algo = {
 329        .master_xfer   = saa7134_i2c_xfer,
 330        .functionality = functionality,
 331};
 332
 333static const struct i2c_adapter saa7134_adap_template = {
 334        .owner         = THIS_MODULE,
 335        .name          = "saa7134",
 336        .algo          = &saa7134_algo,
 337};
 338
 339static const struct i2c_client saa7134_client_template = {
 340        .name   = "saa7134 internal",
 341};
 342
 343/* ----------------------------------------------------------- */
 344
 345/*
 346 * On Medion 7134 reading the SAA7134 chip config EEPROM needs DVB-T
 347 * demod i2c gate closed due to an address clash between this EEPROM
 348 * and the demod one.
 349 */
 350static void saa7134_i2c_eeprom_md7134_gate(struct saa7134_dev *dev)
 351{
 352        u8 subaddr = 0x7, dmdregval;
 353        u8 data[2];
 354        int ret;
 355        struct i2c_msg i2cgatemsg_r[] = { {.addr = 0x08, .flags = 0,
 356                                           .buf = &subaddr, .len = 1},
 357                                          {.addr = 0x08,
 358                                           .flags = I2C_M_RD,
 359                                           .buf = &dmdregval, .len = 1}
 360                                        };
 361        struct i2c_msg i2cgatemsg_w[] = { {.addr = 0x08, .flags = 0,
 362                                           .buf = data, .len = 2} };
 363
 364        ret = i2c_transfer(&dev->i2c_adap, i2cgatemsg_r, 2);
 365        if ((ret == 2) && (dmdregval & 0x2)) {
 366                pr_debug("%s: DVB-T demod i2c gate was left open\n",
 367                         dev->name);
 368
 369                data[0] = subaddr;
 370                data[1] = (dmdregval & ~0x2);
 371                if (i2c_transfer(&dev->i2c_adap, i2cgatemsg_w, 1) != 1)
 372                        pr_err("%s: EEPROM i2c gate close failure\n",
 373                               dev->name);
 374        }
 375}
 376
 377static int
 378saa7134_i2c_eeprom(struct saa7134_dev *dev, unsigned char *eedata, int len)
 379{
 380        unsigned char buf;
 381        int i,err;
 382
 383        if (dev->board == SAA7134_BOARD_MD7134)
 384                saa7134_i2c_eeprom_md7134_gate(dev);
 385
 386        dev->i2c_client.addr = 0xa0 >> 1;
 387        buf = 0;
 388        if (1 != (err = i2c_master_send(&dev->i2c_client,&buf,1))) {
 389                pr_info("%s: Huh, no eeprom present (err=%d)?\n",
 390                       dev->name,err);
 391                return -1;
 392        }
 393        if (len != (err = i2c_master_recv(&dev->i2c_client,eedata,len))) {
 394                pr_warn("%s: i2c eeprom read error (err=%d)\n",
 395                       dev->name,err);
 396                return -1;
 397        }
 398
 399        for (i = 0; i < len; i += 16) {
 400                int size = (len - i) > 16 ? 16 : len - i;
 401
 402                pr_info("i2c eeprom %02x: %*ph\n", i, size, &eedata[i]);
 403        }
 404
 405        return 0;
 406}
 407
 408static char *i2c_devs[128] = {
 409        [ 0x20      ] = "mpeg encoder (saa6752hs)",
 410        [ 0xa0 >> 1 ] = "eeprom",
 411        [ 0xc0 >> 1 ] = "tuner (analog)",
 412        [ 0x86 >> 1 ] = "tda9887",
 413        [ 0x5a >> 1 ] = "remote control",
 414};
 415
 416static void do_i2c_scan(struct i2c_client *c)
 417{
 418        unsigned char buf;
 419        int i,rc;
 420
 421        for (i = 0; i < ARRAY_SIZE(i2c_devs); i++) {
 422                c->addr = i;
 423                rc = i2c_master_recv(c,&buf,0);
 424                if (rc < 0)
 425                        continue;
 426                pr_info("i2c scan: found device @ 0x%x  [%s]\n",
 427                         i << 1, i2c_devs[i] ? i2c_devs[i] : "???");
 428        }
 429}
 430
 431int saa7134_i2c_register(struct saa7134_dev *dev)
 432{
 433        dev->i2c_adap = saa7134_adap_template;
 434        dev->i2c_adap.dev.parent = &dev->pci->dev;
 435        strscpy(dev->i2c_adap.name, dev->name, sizeof(dev->i2c_adap.name));
 436        dev->i2c_adap.algo_data = dev;
 437        i2c_set_adapdata(&dev->i2c_adap, &dev->v4l2_dev);
 438        i2c_add_adapter(&dev->i2c_adap);
 439
 440        dev->i2c_client = saa7134_client_template;
 441        dev->i2c_client.adapter = &dev->i2c_adap;
 442
 443        saa7134_i2c_eeprom(dev,dev->eedata,sizeof(dev->eedata));
 444        if (i2c_scan)
 445                do_i2c_scan(&dev->i2c_client);
 446
 447        /* Instantiate the IR receiver device, if present */
 448        saa7134_probe_i2c_ir(dev);
 449        return 0;
 450}
 451
 452int saa7134_i2c_unregister(struct saa7134_dev *dev)
 453{
 454        i2c_del_adapter(&dev->i2c_adap);
 455        return 0;
 456}
 457