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#define I2C_HW_B_TM6000 I2C_HW_B_EM28XX 36/* ----------------------------------------------------------- */ 37 38static unsigned int i2c_debug = 0; 39module_param(i2c_debug, int, 0644); 40MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]"); 41 42#define i2c_dprintk(lvl, fmt, args...) if (i2c_debug >= lvl) do { \ 43 printk(KERN_DEBUG "%s at %s: " fmt, \ 44 dev->name, __FUNCTION__ , ##args); } while (0) 45 46static int tm6000_i2c_send_regs(struct tm6000_core *dev, unsigned char addr, 47 __u8 reg, char *buf, int len) 48{ 49 int rc; 50 unsigned int tsleep; 51 unsigned int i2c_packet_limit = 16; 52 53 if (dev->dev_type == TM6010) 54 i2c_packet_limit = 64; 55 56 if (!buf) 57 return -1; 58 59 if (len < 1 || len > i2c_packet_limit) { 60 printk(KERN_ERR "Incorrect length of i2c packet = %d, limit set to %d\n", 61 len, i2c_packet_limit); 62 return -1; 63 } 64 65 /* capture mutex */ 66 rc = tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR | 67 USB_RECIP_DEVICE, REQ_16_SET_GET_I2C_WR1_RDN, 68 addr | reg << 8, 0, buf, len); 69 70 if (rc < 0) { 71 /* release mutex */ 72 return rc; 73 } 74 75 /* Calculate delay time, 14000us for 64 bytes */ 76 tsleep = ((len * 200) + 200 + 1000) / 1000; 77 msleep(tsleep); 78 79 /* release mutex */ 80 return rc; 81} 82 83/* Generic read - doesn't work fine with 16bit registers */ 84static int tm6000_i2c_recv_regs(struct tm6000_core *dev, unsigned char addr, 85 __u8 reg, char *buf, int len) 86{ 87 int rc; 88 u8 b[2]; 89 unsigned int i2c_packet_limit = 16; 90 91 if (dev->dev_type == TM6010) 92 i2c_packet_limit = 64; 93 94 if (!buf) 95 return -1; 96 97 if (len < 1 || len > i2c_packet_limit) { 98 printk(KERN_ERR "Incorrect length of i2c packet = %d, limit set to %d\n", 99 len, i2c_packet_limit); 100 return -1; 101 } 102 103 /* capture mutex */ 104 if ((dev->caps.has_zl10353) && (dev->demod_addr << 1 == addr) && (reg % 2 == 0)) { 105 reg -= 1; 106 len += 1; 107 108 rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 109 REQ_16_SET_GET_I2C_WR1_RDN, addr | reg << 8, 0, b, len); 110 111 *buf = b[1]; 112 } else { 113 rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 114 REQ_16_SET_GET_I2C_WR1_RDN, addr | reg << 8, 0, buf, len); 115 } 116 117 /* release mutex */ 118 return rc; 119} 120 121/* 122 * read from a 16bit register 123 * for example xc2028, xc3028 or xc3028L 124 */ 125static int tm6000_i2c_recv_regs16(struct tm6000_core *dev, unsigned char addr, 126 __u16 reg, char *buf, int len) 127{ 128 int rc; 129 unsigned char ureg; 130 131 if (!buf || len != 2) 132 return -1; 133 134 /* capture mutex */ 135 if (dev->dev_type == TM6010) { 136 ureg = reg & 0xFF; 137 rc = tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR | 138 USB_RECIP_DEVICE, REQ_16_SET_GET_I2C_WR1_RDN, 139 addr | (reg & 0xFF00), 0, &ureg, 1); 140 141 if (rc < 0) { 142 /* release mutex */ 143 return rc; 144 } 145 146 msleep(1400 / 1000); 147 rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR | 148 USB_RECIP_DEVICE, REQ_35_AFTEK_TUNER_READ, 149 reg, 0, buf, len); 150 } else { 151 rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR | 152 USB_RECIP_DEVICE, REQ_14_SET_GET_I2C_WR2_RDN, 153 addr, reg, buf, len); 154 } 155 156 /* release mutex */ 157 return rc; 158} 159 160static int tm6000_i2c_xfer(struct i2c_adapter *i2c_adap, 161 struct i2c_msg msgs[], int num) 162{ 163 struct tm6000_core *dev = i2c_adap->algo_data; 164 int addr, rc, i, byte; 165 166 if (num <= 0) 167 return 0; 168 for (i = 0; i < num; i++) { 169 addr = (msgs[i].addr << 1) & 0xff; 170 i2c_dprintk(2, "%s %s addr=0x%x len=%d:", 171 (msgs[i].flags & I2C_M_RD) ? "read" : "write", 172 i == num - 1 ? "stop" : "nonstop", addr, msgs[i].len); 173 if (msgs[i].flags & I2C_M_RD) { 174 /* read request without preceding register selection */ 175 /* 176 * The TM6000 only supports a read transaction 177 * immediately after a 1 or 2 byte write to select 178 * a register. We cannot fulfil this request. 179 */ 180 i2c_dprintk(2, " read without preceding write not" 181 " supported"); 182 rc = -EOPNOTSUPP; 183 goto err; 184 } else if (i + 1 < num && msgs[i].len <= 2 && 185 (msgs[i + 1].flags & I2C_M_RD) && 186 msgs[i].addr == msgs[i + 1].addr) { 187 /* 1 or 2 byte write followed by a read */ 188 if (i2c_debug >= 2) 189 for (byte = 0; byte < msgs[i].len; byte++) 190 printk(" %02x", msgs[i].buf[byte]); 191 i2c_dprintk(2, "; joined to read %s len=%d:", 192 i == num - 2 ? "stop" : "nonstop", 193 msgs[i + 1].len); 194 195 if (msgs[i].len == 2) { 196 rc = tm6000_i2c_recv_regs16(dev, addr, 197 msgs[i].buf[0] << 8 | msgs[i].buf[1], 198 msgs[i + 1].buf, msgs[i + 1].len); 199 } else { 200 rc = tm6000_i2c_recv_regs(dev, addr, msgs[i].buf[0], 201 msgs[i + 1].buf, msgs[i + 1].len); 202 } 203 204 i++; 205 206 if (addr == dev->tuner_addr << 1) { 207 tm6000_set_reg(dev, REQ_50_SET_START, 0, 0); 208 tm6000_set_reg(dev, REQ_51_SET_STOP, 0, 0); 209 } 210 if (i2c_debug >= 2) 211 for (byte = 0; byte < msgs[i].len; byte++) 212 printk(" %02x", msgs[i].buf[byte]); 213 } else { 214 /* write bytes */ 215 if (i2c_debug >= 2) 216 for (byte = 0; byte < msgs[i].len; byte++) 217 printk(" %02x", msgs[i].buf[byte]); 218 rc = tm6000_i2c_send_regs(dev, addr, msgs[i].buf[0], 219 msgs[i].buf + 1, msgs[i].len - 1); 220 221 if (addr == dev->tuner_addr << 1) { 222 tm6000_set_reg(dev, REQ_50_SET_START, 0, 0); 223 tm6000_set_reg(dev, REQ_51_SET_STOP, 0, 0); 224 } 225 } 226 if (i2c_debug >= 2) 227 printk("\n"); 228 if (rc < 0) 229 goto err; 230 } 231 232 return num; 233err: 234 i2c_dprintk(2, " ERROR: %i\n", rc); 235 return rc; 236} 237 238static int tm6000_i2c_eeprom(struct tm6000_core *dev, 239 unsigned char *eedata, int len) 240{ 241 int i, rc; 242 unsigned char *p = eedata; 243 unsigned char bytes[17]; 244 245 dev->i2c_client.addr = 0xa0 >> 1; 246 247 bytes[16] = '\0'; 248 for (i = 0; i < len; ) { 249 *p = i; 250 rc = tm6000_i2c_recv_regs(dev, 0xa0, i, p, 1); 251 if (rc < 1) { 252 if (p == eedata) 253 goto noeeprom; 254 else { 255 printk(KERN_WARNING 256 "%s: i2c eeprom read error (err=%d)\n", 257 dev->name, rc); 258 } 259 return -1; 260 } 261 p++; 262 if (0 == (i % 16)) 263 printk(KERN_INFO "%s: i2c eeprom %02x:", dev->name, i); 264 printk(" %02x", eedata[i]); 265 if ((eedata[i] >= ' ') && (eedata[i] <= 'z')) 266 bytes[i%16] = eedata[i]; 267 else 268 bytes[i%16] = '.'; 269 270 i++; 271 272 if (0 == (i % 16)) { 273 bytes[16] = '\0'; 274 printk(" %s\n", bytes); 275 } 276 } 277 if (0 != (i%16)) { 278 bytes[i%16] = '\0'; 279 for (i %= 16; i < 16; i++) 280 printk(" "); 281 } 282 printk(" %s\n", bytes); 283 284 return 0; 285 286noeeprom: 287 printk(KERN_INFO "%s: Huh, no eeprom present (err=%d)?\n", 288 dev->name, rc); 289 return rc; 290} 291 292/* ----------------------------------------------------------- */ 293 294/* 295 * functionality() 296 */ 297static u32 functionality(struct i2c_adapter *adap) 298{ 299 return I2C_FUNC_SMBUS_EMUL; 300} 301 302#define mass_write(addr, reg, data...) \ 303 { static const u8 _val[] = data; \ 304 rc = tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR, \ 305 REQ_16_SET_GET_I2C_WR1_RDN, (reg<<8)+addr, 0x00, (u8 *) _val, \ 306 ARRAY_SIZE(_val)); \ 307 if (rc < 0) { \ 308 printk(KERN_ERR "Error on line %d: %d\n", __LINE__, rc); \ 309 return rc; \ 310 } \ 311 msleep(10); \ 312 } 313 314static struct i2c_algorithm tm6000_algo = { 315 .master_xfer = tm6000_i2c_xfer, 316 .functionality = functionality, 317}; 318 319static struct i2c_adapter tm6000_adap_template = { 320 .owner = THIS_MODULE, 321 .class = I2C_CLASS_TV_ANALOG | I2C_CLASS_TV_DIGITAL, 322 .name = "tm6000", 323 .id = I2C_HW_B_TM6000, 324 .algo = &tm6000_algo, 325}; 326 327static struct i2c_client tm6000_client_template = { 328 .name = "tm6000 internal", 329}; 330 331/* ----------------------------------------------------------- */ 332 333/* 334 * tm6000_i2c_register() 335 * register i2c bus 336 */ 337int tm6000_i2c_register(struct tm6000_core *dev) 338{ 339 unsigned char eedata[256]; 340 341 dev->i2c_adap = tm6000_adap_template; 342 dev->i2c_adap.dev.parent = &dev->udev->dev; 343 strcpy(dev->i2c_adap.name, dev->name); 344 dev->i2c_adap.algo_data = dev; 345 i2c_add_adapter(&dev->i2c_adap); 346 347 dev->i2c_client = tm6000_client_template; 348 dev->i2c_client.adapter = &dev->i2c_adap; 349 350 i2c_set_adapdata(&dev->i2c_adap, &dev->v4l2_dev); 351 352 tm6000_i2c_eeprom(dev, eedata, sizeof(eedata)); 353 354 return 0; 355} 356 357/* 358 * tm6000_i2c_unregister() 359 * unregister i2c_bus 360 */ 361int tm6000_i2c_unregister(struct tm6000_core *dev) 362{ 363 i2c_del_adapter(&dev->i2c_adap); 364 return 0; 365} 366