Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 // tm6000-i2c.c - driver for TM5600/TM6000/TM6010 USB video capture devices
0003 //
0004 // Copyright (c) 2006-2007 Mauro Carvalho Chehab <mchehab@kernel.org>
0005 //
0006 // Copyright (c) 2007 Michel Ludwig <michel.ludwig@gmail.com>
0007 //  - Fix SMBus Read Byte command
0008 
0009 #include <linux/module.h>
0010 #include <linux/kernel.h>
0011 #include <linux/usb.h>
0012 #include <linux/i2c.h>
0013 
0014 #include "tm6000.h"
0015 #include "tm6000-regs.h"
0016 #include <media/v4l2-common.h>
0017 #include <media/tuner.h>
0018 #include "xc2028.h"
0019 
0020 
0021 /* ----------------------------------------------------------- */
0022 
0023 static unsigned int i2c_debug;
0024 module_param(i2c_debug, int, 0644);
0025 MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]");
0026 
0027 #define i2c_dprintk(lvl, fmt, args...) if (i2c_debug >= lvl) do { \
0028             printk(KERN_DEBUG "%s at %s: " fmt, \
0029             dev->name, __func__, ##args); } while (0)
0030 
0031 static int tm6000_i2c_send_regs(struct tm6000_core *dev, unsigned char addr,
0032                 __u8 reg, char *buf, int len)
0033 {
0034     int rc;
0035     unsigned int i2c_packet_limit = 16;
0036 
0037     if (dev->dev_type == TM6010)
0038         i2c_packet_limit = 80;
0039 
0040     if (!buf)
0041         return -1;
0042 
0043     if (len < 1 || len > i2c_packet_limit) {
0044         printk(KERN_ERR "Incorrect length of i2c packet = %d, limit set to %d\n",
0045             len, i2c_packet_limit);
0046         return -1;
0047     }
0048 
0049     /* capture mutex */
0050     rc = tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR |
0051         USB_RECIP_DEVICE, REQ_16_SET_GET_I2C_WR1_RDN,
0052         addr | reg << 8, 0, buf, len);
0053 
0054     if (rc < 0) {
0055         /* release mutex */
0056         return rc;
0057     }
0058 
0059     /* release mutex */
0060     return rc;
0061 }
0062 
0063 /* Generic read - doesn't work fine with 16bit registers */
0064 static int tm6000_i2c_recv_regs(struct tm6000_core *dev, unsigned char addr,
0065                 __u8 reg, char *buf, int len)
0066 {
0067     int rc;
0068     u8 b[2];
0069     unsigned int i2c_packet_limit = 16;
0070 
0071     if (dev->dev_type == TM6010)
0072         i2c_packet_limit = 64;
0073 
0074     if (!buf)
0075         return -1;
0076 
0077     if (len < 1 || len > i2c_packet_limit) {
0078         printk(KERN_ERR "Incorrect length of i2c packet = %d, limit set to %d\n",
0079             len, i2c_packet_limit);
0080         return -1;
0081     }
0082 
0083     /* capture mutex */
0084     if ((dev->caps.has_zl10353) && (dev->demod_addr << 1 == addr) && (reg % 2 == 0)) {
0085         /*
0086          * Workaround an I2C bug when reading from zl10353
0087          */
0088         reg -= 1;
0089         len += 1;
0090 
0091         rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0092             REQ_16_SET_GET_I2C_WR1_RDN, addr | reg << 8, 0, b, len);
0093 
0094         *buf = b[1];
0095     } else {
0096         rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0097             REQ_16_SET_GET_I2C_WR1_RDN, addr | reg << 8, 0, buf, len);
0098     }
0099 
0100     /* release mutex */
0101     return rc;
0102 }
0103 
0104 /*
0105  * read from a 16bit register
0106  * for example xc2028, xc3028 or xc3028L
0107  */
0108 static int tm6000_i2c_recv_regs16(struct tm6000_core *dev, unsigned char addr,
0109                   __u16 reg, char *buf, int len)
0110 {
0111     int rc;
0112     unsigned char ureg;
0113 
0114     if (!buf || len != 2)
0115         return -1;
0116 
0117     /* capture mutex */
0118     if (dev->dev_type == TM6010) {
0119         ureg = reg & 0xFF;
0120         rc = tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR |
0121             USB_RECIP_DEVICE, REQ_16_SET_GET_I2C_WR1_RDN,
0122             addr | (reg & 0xFF00), 0, &ureg, 1);
0123 
0124         if (rc < 0) {
0125             /* release mutex */
0126             return rc;
0127         }
0128 
0129         rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR |
0130             USB_RECIP_DEVICE, REQ_35_AFTEK_TUNER_READ,
0131             reg, 0, buf, len);
0132     } else {
0133         rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR |
0134             USB_RECIP_DEVICE, REQ_14_SET_GET_I2C_WR2_RDN,
0135             addr, reg, buf, len);
0136     }
0137 
0138     /* release mutex */
0139     return rc;
0140 }
0141 
0142 static int tm6000_i2c_xfer(struct i2c_adapter *i2c_adap,
0143                struct i2c_msg msgs[], int num)
0144 {
0145     struct tm6000_core *dev = i2c_adap->algo_data;
0146     int addr, rc, i, byte;
0147 
0148     for (i = 0; i < num; i++) {
0149         addr = (msgs[i].addr << 1) & 0xff;
0150         i2c_dprintk(2, "%s %s addr=0x%x len=%d:",
0151              (msgs[i].flags & I2C_M_RD) ? "read" : "write",
0152              i == num - 1 ? "stop" : "nonstop", addr, msgs[i].len);
0153         if (msgs[i].flags & I2C_M_RD) {
0154             /* read request without preceding register selection */
0155             /*
0156              * The TM6000 only supports a read transaction
0157              * immediately after a 1 or 2 byte write to select
0158              * a register.  We cannot fulfill this request.
0159              */
0160             i2c_dprintk(2, " read without preceding write not supported");
0161             rc = -EOPNOTSUPP;
0162             goto err;
0163         } else if (i + 1 < num && msgs[i].len <= 2 &&
0164                (msgs[i + 1].flags & I2C_M_RD) &&
0165                msgs[i].addr == msgs[i + 1].addr) {
0166             /* 1 or 2 byte write followed by a read */
0167             if (i2c_debug >= 2)
0168                 for (byte = 0; byte < msgs[i].len; byte++)
0169                     printk(KERN_CONT " %02x", msgs[i].buf[byte]);
0170             i2c_dprintk(2, "; joined to read %s len=%d:",
0171                     i == num - 2 ? "stop" : "nonstop",
0172                     msgs[i + 1].len);
0173 
0174             if (msgs[i].len == 2) {
0175                 rc = tm6000_i2c_recv_regs16(dev, addr,
0176                     msgs[i].buf[0] << 8 | msgs[i].buf[1],
0177                     msgs[i + 1].buf, msgs[i + 1].len);
0178             } else {
0179                 rc = tm6000_i2c_recv_regs(dev, addr, msgs[i].buf[0],
0180                     msgs[i + 1].buf, msgs[i + 1].len);
0181             }
0182 
0183             i++;
0184 
0185             if (addr == dev->tuner_addr << 1) {
0186                 tm6000_set_reg(dev, REQ_50_SET_START, 0, 0);
0187                 tm6000_set_reg(dev, REQ_51_SET_STOP, 0, 0);
0188             }
0189             if (i2c_debug >= 2)
0190                 for (byte = 0; byte < msgs[i].len; byte++)
0191                     printk(KERN_CONT " %02x", msgs[i].buf[byte]);
0192         } else {
0193             /* write bytes */
0194             if (i2c_debug >= 2)
0195                 for (byte = 0; byte < msgs[i].len; byte++)
0196                     printk(KERN_CONT " %02x", msgs[i].buf[byte]);
0197             rc = tm6000_i2c_send_regs(dev, addr, msgs[i].buf[0],
0198                 msgs[i].buf + 1, msgs[i].len - 1);
0199         }
0200         if (i2c_debug >= 2)
0201             printk(KERN_CONT "\n");
0202         if (rc < 0)
0203             goto err;
0204     }
0205 
0206     return num;
0207 err:
0208     i2c_dprintk(2, " ERROR: %i\n", rc);
0209     return rc;
0210 }
0211 
0212 static int tm6000_i2c_eeprom(struct tm6000_core *dev)
0213 {
0214     int i, rc;
0215     unsigned char *p = dev->eedata;
0216     unsigned char bytes[17];
0217 
0218     dev->i2c_client.addr = 0xa0 >> 1;
0219     dev->eedata_size = 0;
0220 
0221     bytes[16] = '\0';
0222     for (i = 0; i < sizeof(dev->eedata); ) {
0223         *p = i;
0224         rc = tm6000_i2c_recv_regs(dev, 0xa0, i, p, 1);
0225         if (rc < 1) {
0226             if (p == dev->eedata)
0227                 goto noeeprom;
0228             else {
0229                 printk(KERN_WARNING
0230                 "%s: i2c eeprom read error (err=%d)\n",
0231                 dev->name, rc);
0232             }
0233             return -EINVAL;
0234         }
0235         dev->eedata_size++;
0236         p++;
0237         if (0 == (i % 16))
0238             printk(KERN_INFO "%s: i2c eeprom %02x:", dev->name, i);
0239         printk(KERN_CONT " %02x", dev->eedata[i]);
0240         if ((dev->eedata[i] >= ' ') && (dev->eedata[i] <= 'z'))
0241             bytes[i%16] = dev->eedata[i];
0242         else
0243             bytes[i%16] = '.';
0244 
0245         i++;
0246 
0247         if (0 == (i % 16)) {
0248             bytes[16] = '\0';
0249             printk(KERN_CONT "  %s\n", bytes);
0250         }
0251     }
0252     if (0 != (i%16)) {
0253         bytes[i%16] = '\0';
0254         for (i %= 16; i < 16; i++)
0255             printk(KERN_CONT "   ");
0256         printk(KERN_CONT "  %s\n", bytes);
0257     }
0258 
0259     return 0;
0260 
0261 noeeprom:
0262     printk(KERN_INFO "%s: Huh, no eeprom present (err=%d)?\n",
0263            dev->name, rc);
0264     return -EINVAL;
0265 }
0266 
0267 /* ----------------------------------------------------------- */
0268 
0269 /*
0270  * functionality()
0271  */
0272 static u32 functionality(struct i2c_adapter *adap)
0273 {
0274     return I2C_FUNC_SMBUS_EMUL;
0275 }
0276 
0277 static const struct i2c_algorithm tm6000_algo = {
0278     .master_xfer   = tm6000_i2c_xfer,
0279     .functionality = functionality,
0280 };
0281 
0282 /* ----------------------------------------------------------- */
0283 
0284 /*
0285  * tm6000_i2c_register()
0286  * register i2c bus
0287  */
0288 int tm6000_i2c_register(struct tm6000_core *dev)
0289 {
0290     int rc;
0291 
0292     dev->i2c_adap.owner = THIS_MODULE;
0293     dev->i2c_adap.algo = &tm6000_algo;
0294     dev->i2c_adap.dev.parent = &dev->udev->dev;
0295     strscpy(dev->i2c_adap.name, dev->name, sizeof(dev->i2c_adap.name));
0296     dev->i2c_adap.algo_data = dev;
0297     i2c_set_adapdata(&dev->i2c_adap, &dev->v4l2_dev);
0298     rc = i2c_add_adapter(&dev->i2c_adap);
0299     if (rc)
0300         return rc;
0301 
0302     dev->i2c_client.adapter = &dev->i2c_adap;
0303     strscpy(dev->i2c_client.name, "tm6000 internal", I2C_NAME_SIZE);
0304     tm6000_i2c_eeprom(dev);
0305 
0306     return 0;
0307 }
0308 
0309 /*
0310  * tm6000_i2c_unregister()
0311  * unregister i2c_bus
0312  */
0313 int tm6000_i2c_unregister(struct tm6000_core *dev)
0314 {
0315     i2c_del_adapter(&dev->i2c_adap);
0316     return 0;
0317 }