1 /* 2 * Driver for the Conexant CX23885 PCIe bridge 3 * 4 * Copyright (c) 2006 Steven Toth <stoth@linuxtv.org> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 */ 21 22 #include <linux/module.h> 23 #include <linux/moduleparam.h> 24 #include <linux/init.h> 25 #include <linux/delay.h> 26 #include <asm/io.h> 27 28 #include "cx23885.h" 29 30 #include <media/v4l2-common.h> 31 32 static unsigned int i2c_debug; 33 module_param(i2c_debug, int, 0644); 34 MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]"); 35 36 static unsigned int i2c_scan; 37 module_param(i2c_scan, int, 0444); 38 MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time"); 39 40 #define dprintk(level, fmt, arg...)\ 41 do { if (i2c_debug >= level)\ 42 printk(KERN_DEBUG "%s/0: " fmt, dev->name, ## arg);\ 43 } while (0) 44 45 #define I2C_WAIT_DELAY 32 46 #define I2C_WAIT_RETRY 64 47 48 #define I2C_EXTEND (1 << 3) 49 #define I2C_NOSTOP (1 << 4) 50 51 static inline int i2c_slave_did_ack(struct i2c_adapter *i2c_adap) 52 { 53 struct cx23885_i2c *bus = i2c_adap->algo_data; 54 struct cx23885_dev *dev = bus->dev; 55 return cx_read(bus->reg_stat) & 0x01; 56 } 57 58 static inline int i2c_is_busy(struct i2c_adapter *i2c_adap) 59 { 60 struct cx23885_i2c *bus = i2c_adap->algo_data; 61 struct cx23885_dev *dev = bus->dev; 62 return cx_read(bus->reg_stat) & 0x02 ? 1 : 0; 63 } 64 65 static int i2c_wait_done(struct i2c_adapter *i2c_adap) 66 { 67 int count; 68 69 for (count = 0; count < I2C_WAIT_RETRY; count++) { 70 if (!i2c_is_busy(i2c_adap)) 71 break; 72 udelay(I2C_WAIT_DELAY); 73 } 74 75 if (I2C_WAIT_RETRY == count) 76 return 0; 77 78 return 1; 79 } 80 81 static int i2c_sendbytes(struct i2c_adapter *i2c_adap, 82 const struct i2c_msg *msg, int joined_rlen) 83 { 84 struct cx23885_i2c *bus = i2c_adap->algo_data; 85 struct cx23885_dev *dev = bus->dev; 86 u32 wdata, addr, ctrl; 87 int retval, cnt; 88 89 if (joined_rlen) 90 dprintk(1, "%s(msg->wlen=%d, nextmsg->rlen=%d)\n", __func__, 91 msg->len, joined_rlen); 92 else 93 dprintk(1, "%s(msg->len=%d)\n", __func__, msg->len); 94 95 /* Deal with i2c probe functions with zero payload */ 96 if (msg->len == 0) { 97 cx_write(bus->reg_addr, msg->addr << 25); 98 cx_write(bus->reg_ctrl, bus->i2c_period | (1 << 2)); 99 if (!i2c_wait_done(i2c_adap)) 100 return -EIO; 101 if (!i2c_slave_did_ack(i2c_adap)) 102 return -ENXIO; 103 104 dprintk(1, "%s() returns 0\n", __func__); 105 return 0; 106 } 107 108 109 /* dev, reg + first byte */ 110 addr = (msg->addr << 25) | msg->buf[0]; 111 wdata = msg->buf[0]; 112 ctrl = bus->i2c_period | (1 << 12) | (1 << 2); 113 114 if (msg->len > 1) 115 ctrl |= I2C_NOSTOP | I2C_EXTEND; 116 else if (joined_rlen) 117 ctrl |= I2C_NOSTOP; 118 119 cx_write(bus->reg_addr, addr); 120 cx_write(bus->reg_wdata, wdata); 121 cx_write(bus->reg_ctrl, ctrl); 122 123 if (!i2c_wait_done(i2c_adap)) 124 goto eio; 125 if (i2c_debug) { 126 printk(" <W %02x %02x", msg->addr << 1, msg->buf[0]); 127 if (!(ctrl & I2C_NOSTOP)) 128 printk(" >\n"); 129 } 130 131 for (cnt = 1; cnt < msg->len; cnt++) { 132 /* following bytes */ 133 wdata = msg->buf[cnt]; 134 ctrl = bus->i2c_period | (1 << 12) | (1 << 2); 135 136 if (cnt < msg->len - 1) 137 ctrl |= I2C_NOSTOP | I2C_EXTEND; 138 else if (joined_rlen) 139 ctrl |= I2C_NOSTOP; 140 141 cx_write(bus->reg_addr, addr); 142 cx_write(bus->reg_wdata, wdata); 143 cx_write(bus->reg_ctrl, ctrl); 144 145 if (!i2c_wait_done(i2c_adap)) 146 goto eio; 147 if (i2c_debug) { 148 dprintk(1, " %02x", msg->buf[cnt]); 149 if (!(ctrl & I2C_NOSTOP)) 150 dprintk(1, " >\n"); 151 } 152 } 153 return msg->len; 154 155 eio: 156 retval = -EIO; 157 if (i2c_debug) 158 printk(KERN_ERR " ERR: %d\n", retval); 159 return retval; 160 } 161 162 static int i2c_readbytes(struct i2c_adapter *i2c_adap, 163 const struct i2c_msg *msg, int joined) 164 { 165 struct cx23885_i2c *bus = i2c_adap->algo_data; 166 struct cx23885_dev *dev = bus->dev; 167 u32 ctrl, cnt; 168 int retval; 169 170 171 if (i2c_debug && !joined) 172 dprintk(1, "%s(msg->len=%d)\n", __func__, msg->len); 173 174 /* Deal with i2c probe functions with zero payload */ 175 if (msg->len == 0) { 176 cx_write(bus->reg_addr, msg->addr << 25); 177 cx_write(bus->reg_ctrl, bus->i2c_period | (1 << 2) | 1); 178 if (!i2c_wait_done(i2c_adap)) 179 return -EIO; 180 if (!i2c_slave_did_ack(i2c_adap)) 181 return -ENXIO; 182 183 184 dprintk(1, "%s() returns 0\n", __func__); 185 return 0; 186 } 187 188 if (i2c_debug) { 189 if (joined) 190 dprintk(1, " R"); 191 else 192 dprintk(1, " <R %02x", (msg->addr << 1) + 1); 193 } 194 195 for (cnt = 0; cnt < msg->len; cnt++) { 196 197 ctrl = bus->i2c_period | (1 << 12) | (1 << 2) | 1; 198 199 if (cnt < msg->len - 1) 200 ctrl |= I2C_NOSTOP | I2C_EXTEND; 201 202 cx_write(bus->reg_addr, msg->addr << 25); 203 cx_write(bus->reg_ctrl, ctrl); 204 205 if (!i2c_wait_done(i2c_adap)) 206 goto eio; 207 msg->buf[cnt] = cx_read(bus->reg_rdata) & 0xff; 208 if (i2c_debug) { 209 dprintk(1, " %02x", msg->buf[cnt]); 210 if (!(ctrl & I2C_NOSTOP)) 211 dprintk(1, " >\n"); 212 } 213 } 214 return msg->len; 215 216 eio: 217 retval = -EIO; 218 if (i2c_debug) 219 printk(KERN_ERR " ERR: %d\n", retval); 220 return retval; 221 } 222 223 static int i2c_xfer(struct i2c_adapter *i2c_adap, 224 struct i2c_msg *msgs, int num) 225 { 226 struct cx23885_i2c *bus = i2c_adap->algo_data; 227 struct cx23885_dev *dev = bus->dev; 228 int i, retval = 0; 229 230 dprintk(1, "%s(num = %d)\n", __func__, num); 231 232 for (i = 0 ; i < num; i++) { 233 dprintk(1, "%s(num = %d) addr = 0x%02x len = 0x%x\n", 234 __func__, num, msgs[i].addr, msgs[i].len); 235 if (msgs[i].flags & I2C_M_RD) { 236 /* read */ 237 retval = i2c_readbytes(i2c_adap, &msgs[i], 0); 238 } else if (i + 1 < num && (msgs[i + 1].flags & I2C_M_RD) && 239 msgs[i].addr == msgs[i + 1].addr) { 240 /* write then read from same address */ 241 retval = i2c_sendbytes(i2c_adap, &msgs[i], 242 msgs[i + 1].len); 243 if (retval < 0) 244 goto err; 245 i++; 246 retval = i2c_readbytes(i2c_adap, &msgs[i], 1); 247 } else { 248 /* write */ 249 retval = i2c_sendbytes(i2c_adap, &msgs[i], 0); 250 } 251 if (retval < 0) 252 goto err; 253 } 254 return num; 255 256 err: 257 return retval; 258 } 259 260 static u32 cx23885_functionality(struct i2c_adapter *adap) 261 { 262 return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C; 263 } 264 265 static struct i2c_algorithm cx23885_i2c_algo_template = { 266 .master_xfer = i2c_xfer, 267 .functionality = cx23885_functionality, 268 }; 269 270 /* ----------------------------------------------------------------------- */ 271 272 static struct i2c_adapter cx23885_i2c_adap_template = { 273 .name = "cx23885", 274 .owner = THIS_MODULE, 275 .algo = &cx23885_i2c_algo_template, 276 }; 277 278 static struct i2c_client cx23885_i2c_client_template = { 279 .name = "cx23885 internal", 280 }; 281 282 static char *i2c_devs[128] = { 283 [0x10 >> 1] = "tda10048", 284 [0x12 >> 1] = "dib7000pc", 285 [0x1c >> 1] = "lgdt3303", 286 [0x86 >> 1] = "tda9887", 287 [0x32 >> 1] = "cx24227", 288 [0x88 >> 1] = "cx25837", 289 [0x84 >> 1] = "tda8295", 290 [0x98 >> 1] = "flatiron", 291 [0xa0 >> 1] = "eeprom", 292 [0xc0 >> 1] = "tuner/mt2131/tda8275", 293 [0xc2 >> 1] = "tuner/mt2131/tda8275/xc5000/xc3028", 294 [0xc8 >> 1] = "tuner/xc3028L", 295 }; 296 297 static void do_i2c_scan(char *name, struct i2c_client *c) 298 { 299 unsigned char buf; 300 int i, rc; 301 302 for (i = 0; i < 128; i++) { 303 c->addr = i; 304 rc = i2c_master_recv(c, &buf, 0); 305 if (rc < 0) 306 continue; 307 printk(KERN_INFO "%s: i2c scan: found device @ 0x%x [%s]\n", 308 name, i << 1, i2c_devs[i] ? i2c_devs[i] : "???"); 309 } 310 } 311 312 /* init + register i2c adapter */ 313 int cx23885_i2c_register(struct cx23885_i2c *bus) 314 { 315 struct cx23885_dev *dev = bus->dev; 316 317 dprintk(1, "%s(bus = %d)\n", __func__, bus->nr); 318 319 bus->i2c_adap = cx23885_i2c_adap_template; 320 bus->i2c_client = cx23885_i2c_client_template; 321 bus->i2c_adap.dev.parent = &dev->pci->dev; 322 323 strlcpy(bus->i2c_adap.name, bus->dev->name, 324 sizeof(bus->i2c_adap.name)); 325 326 bus->i2c_adap.algo_data = bus; 327 i2c_set_adapdata(&bus->i2c_adap, &dev->v4l2_dev); 328 i2c_add_adapter(&bus->i2c_adap); 329 330 bus->i2c_client.adapter = &bus->i2c_adap; 331 332 if (0 == bus->i2c_rc) { 333 dprintk(1, "%s: i2c bus %d registered\n", dev->name, bus->nr); 334 if (i2c_scan) { 335 printk(KERN_INFO "%s: scan bus %d:\n", 336 dev->name, bus->nr); 337 do_i2c_scan(dev->name, &bus->i2c_client); 338 } 339 } else 340 printk(KERN_WARNING "%s: i2c bus %d register FAILED\n", 341 dev->name, bus->nr); 342 343 /* Instantiate the IR receiver device, if present */ 344 if (0 == bus->i2c_rc) { 345 struct i2c_board_info info; 346 const unsigned short addr_list[] = { 347 0x6b, I2C_CLIENT_END 348 }; 349 350 memset(&info, 0, sizeof(struct i2c_board_info)); 351 strlcpy(info.type, "ir_video", I2C_NAME_SIZE); 352 /* Use quick read command for probe, some IR chips don't 353 * support writes */ 354 i2c_new_probed_device(&bus->i2c_adap, &info, addr_list, 355 i2c_probe_func_quick_read); 356 } 357 358 return bus->i2c_rc; 359 } 360 361 int cx23885_i2c_unregister(struct cx23885_i2c *bus) 362 { 363 i2c_del_adapter(&bus->i2c_adap); 364 return 0; 365 } 366 367 void cx23885_av_clk(struct cx23885_dev *dev, int enable) 368 { 369 /* write 0 to bus 2 addr 0x144 via i2x_xfer() */ 370 char buffer[3]; 371 struct i2c_msg msg; 372 dprintk(1, "%s(enabled = %d)\n", __func__, enable); 373 374 /* Register 0x144 */ 375 buffer[0] = 0x01; 376 buffer[1] = 0x44; 377 if (enable == 1) 378 buffer[2] = 0x05; 379 else 380 buffer[2] = 0x00; 381 382 msg.addr = 0x44; 383 msg.flags = I2C_M_TEN; 384 msg.len = 3; 385 msg.buf = buffer; 386 387 i2c_xfer(&dev->i2c_bus[2].i2c_adap, &msg, 1); 388 } 389 390 /* ----------------------------------------------------------------------- */ 391 392 /* 393 * Local variables: 394 * c-basic-offset: 8 395 * End: 396 */ 397