1/* 2 * tm6000-i2c.c - driver for TM5600/TM6000/TM6010 USB video capture devices 3 * 4 * Copyright (C) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org> 5 * 6 * Copyright (C) 2007 Michel Ludwig <michel.ludwig@gmail.com> 7 * - Fix SMBus Read Byte command 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation version 2 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21 */ 22 23#include <linux/module.h> 24#include <linux/kernel.h> 25#include <linux/usb.h> 26#include <linux/i2c.h> 27 28#include "tm6000.h" 29#include "tm6000-regs.h" 30#include <media/v4l2-common.h> 31#include <media/tuner.h> 32#include "tuner-xc2028.h" 33 34 35/* ----------------------------------------------------------- */ 36 37static unsigned int i2c_debug; 38module_param(i2c_debug, int, 0644); 39MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]"); 40 41#define i2c_dprintk(lvl, fmt, args...) if (i2c_debug >= lvl) do { \ 42 printk(KERN_DEBUG "%s at %s: " fmt, \ 43 dev->name, __func__, ##args); } while (0) 44 45static int tm6000_i2c_send_regs(struct tm6000_core *dev, unsigned char addr, 46 __u8 reg, char *buf, int len) 47{ 48 int rc; 49 unsigned int i2c_packet_limit = 16; 50 51 if (dev->dev_type == TM6010) 52 i2c_packet_limit = 80; 53 54 if (!buf) 55 return -1; 56 57 if (len < 1 || len > i2c_packet_limit) { 58 printk(KERN_ERR "Incorrect length of i2c packet = %d, limit set to %d\n", 59 len, i2c_packet_limit); 60 return -1; 61 } 62 63 /* capture mutex */ 64 rc = tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR | 65 USB_RECIP_DEVICE, REQ_16_SET_GET_I2C_WR1_RDN, 66 addr | reg << 8, 0, buf, len); 67 68 if (rc < 0) { 69 /* release mutex */ 70 return rc; 71 } 72 73 /* release mutex */ 74 return rc; 75} 76 77/* Generic read - doesn't work fine with 16bit registers */ 78static int tm6000_i2c_recv_regs(struct tm6000_core *dev, unsigned char addr, 79 __u8 reg, char *buf, int len) 80{ 81 int rc; 82 u8 b[2]; 83 unsigned int i2c_packet_limit = 16; 84 85 if (dev->dev_type == TM6010) 86 i2c_packet_limit = 64; 87 88 if (!buf) 89 return -1; 90 91 if (len < 1 || len > i2c_packet_limit) { 92 printk(KERN_ERR "Incorrect length of i2c packet = %d, limit set to %d\n", 93 len, i2c_packet_limit); 94 return -1; 95 } 96 97 /* capture mutex */ 98 if ((dev->caps.has_zl10353) && (dev->demod_addr << 1 == addr) && (reg % 2 == 0)) { 99 /* 100 * Workaround an I2C bug when reading from zl10353 101 */ 102 reg -= 1; 103 len += 1; 104 105 rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 106 REQ_16_SET_GET_I2C_WR1_RDN, addr | reg << 8, 0, b, len); 107 108 *buf = b[1]; 109 } else { 110 rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 111 REQ_16_SET_GET_I2C_WR1_RDN, addr | reg << 8, 0, buf, len); 112 } 113 114 /* release mutex */ 115 return rc; 116} 117 118/* 119 * read from a 16bit register 120 * for example xc2028, xc3028 or xc3028L 121 */ 122static int tm6000_i2c_recv_regs16(struct tm6000_core *dev, unsigned char addr, 123 __u16 reg, char *buf, int len) 124{ 125 int rc; 126 unsigned char ureg; 127 128 if (!buf || len != 2) 129 return -1; 130 131 /* capture mutex */ 132 if (dev->dev_type == TM6010) { 133 ureg = reg & 0xFF; 134 rc = tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR | 135 USB_RECIP_DEVICE, REQ_16_SET_GET_I2C_WR1_RDN, 136 addr | (reg & 0xFF00), 0, &ureg, 1); 137 138 if (rc < 0) { 139 /* release mutex */ 140 return rc; 141 } 142 143 rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR | 144 USB_RECIP_DEVICE, REQ_35_AFTEK_TUNER_READ, 145 reg, 0, buf, len); 146 } else { 147 rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR | 148 USB_RECIP_DEVICE, REQ_14_SET_GET_I2C_WR2_RDN, 149 addr, reg, buf, len); 150 } 151 152 /* release mutex */ 153 return rc; 154} 155 156static int tm6000_i2c_xfer(struct i2c_adapter *i2c_adap, 157 struct i2c_msg msgs[], int num) 158{ 159 struct tm6000_core *dev = i2c_adap->algo_data; 160 int addr, rc, i, byte; 161 162 if (num <= 0) 163 return 0; 164 for (i = 0; i < num; i++) { 165 addr = (msgs[i].addr << 1) & 0xff; 166 i2c_dprintk(2, "%s %s addr=0x%x len=%d:", 167 (msgs[i].flags & I2C_M_RD) ? "read" : "write", 168 i == num - 1 ? "stop" : "nonstop", addr, msgs[i].len); 169 if (msgs[i].flags & I2C_M_RD) { 170 /* read request without preceding register selection */ 171 /* 172 * The TM6000 only supports a read transaction 173 * immediately after a 1 or 2 byte write to select 174 * a register. We cannot fulfil this request. 175 */ 176 i2c_dprintk(2, " read without preceding write not" 177 " supported"); 178 rc = -EOPNOTSUPP; 179 goto err; 180 } else if (i + 1 < num && msgs[i].len <= 2 && 181 (msgs[i + 1].flags & I2C_M_RD) && 182 msgs[i].addr == msgs[i + 1].addr) { 183 /* 1 or 2 byte write followed by a read */ 184 if (i2c_debug >= 2) 185 for (byte = 0; byte < msgs[i].len; byte++) 186 printk(KERN_CONT " %02x", msgs[i].buf[byte]); 187 i2c_dprintk(2, "; joined to read %s len=%d:", 188 i == num - 2 ? "stop" : "nonstop", 189 msgs[i + 1].len); 190 191 if (msgs[i].len == 2) { 192 rc = tm6000_i2c_recv_regs16(dev, addr, 193 msgs[i].buf[0] << 8 | msgs[i].buf[1], 194 msgs[i + 1].buf, msgs[i + 1].len); 195 } else { 196 rc = tm6000_i2c_recv_regs(dev, addr, msgs[i].buf[0], 197 msgs[i + 1].buf, msgs[i + 1].len); 198 } 199 200 i++; 201 202 if (addr == dev->tuner_addr << 1) { 203 tm6000_set_reg(dev, REQ_50_SET_START, 0, 0); 204 tm6000_set_reg(dev, REQ_51_SET_STOP, 0, 0); 205 } 206 if (i2c_debug >= 2) 207 for (byte = 0; byte < msgs[i].len; byte++) 208 printk(KERN_CONT " %02x", msgs[i].buf[byte]); 209 } else { 210 /* write bytes */ 211 if (i2c_debug >= 2) 212 for (byte = 0; byte < msgs[i].len; byte++) 213 printk(KERN_CONT " %02x", msgs[i].buf[byte]); 214 rc = tm6000_i2c_send_regs(dev, addr, msgs[i].buf[0], 215 msgs[i].buf + 1, msgs[i].len - 1); 216 } 217 if (i2c_debug >= 2) 218 printk(KERN_CONT "\n"); 219 if (rc < 0) 220 goto err; 221 } 222 223 return num; 224err: 225 i2c_dprintk(2, " ERROR: %i\n", rc); 226 return rc; 227} 228 229static int tm6000_i2c_eeprom(struct tm6000_core *dev) 230{ 231 int i, rc; 232 unsigned char *p = dev->eedata; 233 unsigned char bytes[17]; 234 235 dev->i2c_client.addr = 0xa0 >> 1; 236 dev->eedata_size = 0; 237 238 bytes[16] = '\0'; 239 for (i = 0; i < sizeof(dev->eedata); ) { 240 *p = i; 241 rc = tm6000_i2c_recv_regs(dev, 0xa0, i, p, 1); 242 if (rc < 1) { 243 if (p == dev->eedata) 244 goto noeeprom; 245 else { 246 printk(KERN_WARNING 247 "%s: i2c eeprom read error (err=%d)\n", 248 dev->name, rc); 249 } 250 return -EINVAL; 251 } 252 dev->eedata_size++; 253 p++; 254 if (0 == (i % 16)) 255 printk(KERN_INFO "%s: i2c eeprom %02x:", dev->name, i); 256 printk(KERN_CONT " %02x", dev->eedata[i]); 257 if ((dev->eedata[i] >= ' ') && (dev->eedata[i] <= 'z')) 258 bytes[i%16] = dev->eedata[i]; 259 else 260 bytes[i%16] = '.'; 261 262 i++; 263 264 if (0 == (i % 16)) { 265 bytes[16] = '\0'; 266 printk(KERN_CONT " %s\n", bytes); 267 } 268 } 269 if (0 != (i%16)) { 270 bytes[i%16] = '\0'; 271 for (i %= 16; i < 16; i++) 272 printk(KERN_CONT " "); 273 printk(KERN_CONT " %s\n", bytes); 274 } 275 276 return 0; 277 278noeeprom: 279 printk(KERN_INFO "%s: Huh, no eeprom present (err=%d)?\n", 280 dev->name, rc); 281 return -EINVAL; 282} 283 284/* ----------------------------------------------------------- */ 285 286/* 287 * functionality() 288 */ 289static u32 functionality(struct i2c_adapter *adap) 290{ 291 return I2C_FUNC_SMBUS_EMUL; 292} 293 294static const struct i2c_algorithm tm6000_algo = { 295 .master_xfer = tm6000_i2c_xfer, 296 .functionality = functionality, 297}; 298 299/* ----------------------------------------------------------- */ 300 301/* 302 * tm6000_i2c_register() 303 * register i2c bus 304 */ 305int tm6000_i2c_register(struct tm6000_core *dev) 306{ 307 int rc; 308 309 dev->i2c_adap.owner = THIS_MODULE; 310 dev->i2c_adap.algo = &tm6000_algo; 311 dev->i2c_adap.dev.parent = &dev->udev->dev; 312 strlcpy(dev->i2c_adap.name, dev->name, sizeof(dev->i2c_adap.name)); 313 dev->i2c_adap.algo_data = dev; 314 i2c_set_adapdata(&dev->i2c_adap, &dev->v4l2_dev); 315 rc = i2c_add_adapter(&dev->i2c_adap); 316 if (rc) 317 return rc; 318 319 dev->i2c_client.adapter = &dev->i2c_adap; 320 strlcpy(dev->i2c_client.name, "tm6000 internal", I2C_NAME_SIZE); 321 tm6000_i2c_eeprom(dev); 322 323 return 0; 324} 325 326/* 327 * tm6000_i2c_unregister() 328 * unregister i2c_bus 329 */ 330int tm6000_i2c_unregister(struct tm6000_core *dev) 331{ 332 i2c_del_adapter(&dev->i2c_adap); 333 return 0; 334} 335