au0828-i2c.c (9062B)
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Driver for the Auvitek AU0828 USB bridge 4 * 5 * Copyright (c) 2008 Steven Toth <stoth@linuxtv.org> 6 */ 7 8#include "au0828.h" 9 10#include <linux/module.h> 11#include <linux/moduleparam.h> 12#include <linux/init.h> 13#include <linux/delay.h> 14#include <linux/io.h> 15 16#include "media/tuner.h" 17#include <media/v4l2-common.h> 18 19static int i2c_scan; 20module_param(i2c_scan, int, 0444); 21MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time"); 22 23#define I2C_WAIT_DELAY 25 24#define I2C_WAIT_RETRY 1000 25 26static inline int i2c_slave_did_read_ack(struct i2c_adapter *i2c_adap) 27{ 28 struct au0828_dev *dev = i2c_adap->algo_data; 29 return au0828_read(dev, AU0828_I2C_STATUS_201) & 30 AU0828_I2C_STATUS_NO_READ_ACK ? 0 : 1; 31} 32 33static int i2c_wait_read_ack(struct i2c_adapter *i2c_adap) 34{ 35 int count; 36 37 for (count = 0; count < I2C_WAIT_RETRY; count++) { 38 if (!i2c_slave_did_read_ack(i2c_adap)) 39 break; 40 udelay(I2C_WAIT_DELAY); 41 } 42 43 if (I2C_WAIT_RETRY == count) 44 return 0; 45 46 return 1; 47} 48 49static inline int i2c_is_read_busy(struct i2c_adapter *i2c_adap) 50{ 51 struct au0828_dev *dev = i2c_adap->algo_data; 52 return au0828_read(dev, AU0828_I2C_STATUS_201) & 53 AU0828_I2C_STATUS_READ_DONE ? 0 : 1; 54} 55 56static int i2c_wait_read_done(struct i2c_adapter *i2c_adap) 57{ 58 int count; 59 60 for (count = 0; count < I2C_WAIT_RETRY; count++) { 61 if (!i2c_is_read_busy(i2c_adap)) 62 break; 63 udelay(I2C_WAIT_DELAY); 64 } 65 66 if (I2C_WAIT_RETRY == count) 67 return 0; 68 69 return 1; 70} 71 72static inline int i2c_is_write_done(struct i2c_adapter *i2c_adap) 73{ 74 struct au0828_dev *dev = i2c_adap->algo_data; 75 return au0828_read(dev, AU0828_I2C_STATUS_201) & 76 AU0828_I2C_STATUS_WRITE_DONE ? 1 : 0; 77} 78 79static int i2c_wait_write_done(struct i2c_adapter *i2c_adap) 80{ 81 int count; 82 83 for (count = 0; count < I2C_WAIT_RETRY; count++) { 84 if (i2c_is_write_done(i2c_adap)) 85 break; 86 udelay(I2C_WAIT_DELAY); 87 } 88 89 if (I2C_WAIT_RETRY == count) 90 return 0; 91 92 return 1; 93} 94 95static inline int i2c_is_busy(struct i2c_adapter *i2c_adap) 96{ 97 struct au0828_dev *dev = i2c_adap->algo_data; 98 return au0828_read(dev, AU0828_I2C_STATUS_201) & 99 AU0828_I2C_STATUS_BUSY ? 1 : 0; 100} 101 102static int i2c_wait_done(struct i2c_adapter *i2c_adap) 103{ 104 int count; 105 106 for (count = 0; count < I2C_WAIT_RETRY; count++) { 107 if (!i2c_is_busy(i2c_adap)) 108 break; 109 udelay(I2C_WAIT_DELAY); 110 } 111 112 if (I2C_WAIT_RETRY == count) 113 return 0; 114 115 return 1; 116} 117 118/* FIXME: Implement join handling correctly */ 119static int i2c_sendbytes(struct i2c_adapter *i2c_adap, 120 const struct i2c_msg *msg, int joined_rlen) 121{ 122 int i, strobe = 0; 123 struct au0828_dev *dev = i2c_adap->algo_data; 124 u8 i2c_speed = dev->board.i2c_clk_divider; 125 126 dprintk(4, "%s()\n", __func__); 127 128 au0828_write(dev, AU0828_I2C_MULTIBYTE_MODE_2FF, 0x01); 129 130 if (((dev->board.tuner_type == TUNER_XC5000) || 131 (dev->board.tuner_type == TUNER_XC5000C)) && 132 (dev->board.tuner_addr == msg->addr)) { 133 /* 134 * Due to I2C clock stretch, we need to use a lower speed 135 * on xc5000 for commands. However, firmware transfer can 136 * speed up to 400 KHz. 137 */ 138 if (msg->len == 64) 139 i2c_speed = AU0828_I2C_CLK_250KHZ; 140 else 141 i2c_speed = AU0828_I2C_CLK_20KHZ; 142 } 143 /* Set the I2C clock */ 144 au0828_write(dev, AU0828_I2C_CLK_DIVIDER_202, i2c_speed); 145 146 /* Hardware needs 8 bit addresses */ 147 au0828_write(dev, AU0828_I2C_DEST_ADDR_203, msg->addr << 1); 148 149 dprintk(4, "SEND: %02x\n", msg->addr); 150 151 /* Deal with i2c_scan */ 152 if (msg->len == 0) { 153 /* The analog tuner detection code makes use of the SMBUS_QUICK 154 message (which involves a zero length i2c write). To avoid 155 checking the status register when we didn't strobe out any 156 actual bytes to the bus, just do a read check. This is 157 consistent with how I saw i2c device checking done in the 158 USB trace of the Windows driver */ 159 au0828_write(dev, AU0828_I2C_TRIGGER_200, 160 AU0828_I2C_TRIGGER_READ); 161 162 if (!i2c_wait_done(i2c_adap)) 163 return -EIO; 164 165 if (i2c_wait_read_ack(i2c_adap)) 166 return -EIO; 167 168 return 0; 169 } 170 171 for (i = 0; i < msg->len;) { 172 173 dprintk(4, " %02x\n", msg->buf[i]); 174 175 au0828_write(dev, AU0828_I2C_WRITE_FIFO_205, msg->buf[i]); 176 177 strobe++; 178 i++; 179 180 if ((strobe >= 4) || (i >= msg->len)) { 181 182 /* Strobe the byte into the bus */ 183 if (i < msg->len) 184 au0828_write(dev, AU0828_I2C_TRIGGER_200, 185 AU0828_I2C_TRIGGER_WRITE | 186 AU0828_I2C_TRIGGER_HOLD); 187 else 188 au0828_write(dev, AU0828_I2C_TRIGGER_200, 189 AU0828_I2C_TRIGGER_WRITE); 190 191 /* Reset strobe trigger */ 192 strobe = 0; 193 194 if (!i2c_wait_write_done(i2c_adap)) 195 return -EIO; 196 197 } 198 199 } 200 if (!i2c_wait_done(i2c_adap)) 201 return -EIO; 202 203 dprintk(4, "\n"); 204 205 return msg->len; 206} 207 208/* FIXME: Implement join handling correctly */ 209static int i2c_readbytes(struct i2c_adapter *i2c_adap, 210 const struct i2c_msg *msg, int joined) 211{ 212 struct au0828_dev *dev = i2c_adap->algo_data; 213 u8 i2c_speed = dev->board.i2c_clk_divider; 214 int i; 215 216 dprintk(4, "%s()\n", __func__); 217 218 au0828_write(dev, AU0828_I2C_MULTIBYTE_MODE_2FF, 0x01); 219 220 /* 221 * Due to xc5000c clock stretch, we cannot use full speed at 222 * readings from xc5000, as otherwise they'll fail. 223 */ 224 if (((dev->board.tuner_type == TUNER_XC5000) || 225 (dev->board.tuner_type == TUNER_XC5000C)) && 226 (dev->board.tuner_addr == msg->addr)) 227 i2c_speed = AU0828_I2C_CLK_20KHZ; 228 229 /* Set the I2C clock */ 230 au0828_write(dev, AU0828_I2C_CLK_DIVIDER_202, i2c_speed); 231 232 /* Hardware needs 8 bit addresses */ 233 au0828_write(dev, AU0828_I2C_DEST_ADDR_203, msg->addr << 1); 234 235 dprintk(4, " RECV:\n"); 236 237 /* Deal with i2c_scan */ 238 if (msg->len == 0) { 239 au0828_write(dev, AU0828_I2C_TRIGGER_200, 240 AU0828_I2C_TRIGGER_READ); 241 242 if (i2c_wait_read_ack(i2c_adap)) 243 return -EIO; 244 return 0; 245 } 246 247 for (i = 0; i < msg->len;) { 248 249 i++; 250 251 if (i < msg->len) 252 au0828_write(dev, AU0828_I2C_TRIGGER_200, 253 AU0828_I2C_TRIGGER_READ | 254 AU0828_I2C_TRIGGER_HOLD); 255 else 256 au0828_write(dev, AU0828_I2C_TRIGGER_200, 257 AU0828_I2C_TRIGGER_READ); 258 259 if (!i2c_wait_read_done(i2c_adap)) 260 return -EIO; 261 262 msg->buf[i-1] = au0828_read(dev, AU0828_I2C_READ_FIFO_209) & 263 0xff; 264 265 dprintk(4, " %02x\n", msg->buf[i-1]); 266 } 267 if (!i2c_wait_done(i2c_adap)) 268 return -EIO; 269 270 dprintk(4, "\n"); 271 272 return msg->len; 273} 274 275static int i2c_xfer(struct i2c_adapter *i2c_adap, 276 struct i2c_msg *msgs, int num) 277{ 278 int i, retval = 0; 279 280 dprintk(4, "%s(num = %d)\n", __func__, num); 281 282 for (i = 0; i < num; i++) { 283 dprintk(4, "%s(num = %d) addr = 0x%02x len = 0x%x\n", 284 __func__, num, msgs[i].addr, msgs[i].len); 285 if (msgs[i].flags & I2C_M_RD) { 286 /* read */ 287 retval = i2c_readbytes(i2c_adap, &msgs[i], 0); 288 } else if (i + 1 < num && (msgs[i + 1].flags & I2C_M_RD) && 289 msgs[i].addr == msgs[i + 1].addr) { 290 /* write then read from same address */ 291 retval = i2c_sendbytes(i2c_adap, &msgs[i], 292 msgs[i + 1].len); 293 if (retval < 0) 294 goto err; 295 i++; 296 retval = i2c_readbytes(i2c_adap, &msgs[i], 1); 297 } else { 298 /* write */ 299 retval = i2c_sendbytes(i2c_adap, &msgs[i], 0); 300 } 301 if (retval < 0) 302 goto err; 303 } 304 return num; 305 306err: 307 return retval; 308} 309 310static u32 au0828_functionality(struct i2c_adapter *adap) 311{ 312 return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C; 313} 314 315static const struct i2c_algorithm au0828_i2c_algo_template = { 316 .master_xfer = i2c_xfer, 317 .functionality = au0828_functionality, 318}; 319 320/* ----------------------------------------------------------------------- */ 321 322static const struct i2c_adapter au0828_i2c_adap_template = { 323 .name = KBUILD_MODNAME, 324 .owner = THIS_MODULE, 325 .algo = &au0828_i2c_algo_template, 326}; 327 328static const struct i2c_client au0828_i2c_client_template = { 329 .name = "au0828 internal", 330}; 331 332static char *i2c_devs[128] = { 333 [0x8e >> 1] = "au8522", 334 [0xa0 >> 1] = "eeprom", 335 [0xc2 >> 1] = "tuner/xc5000", 336}; 337 338static void do_i2c_scan(char *name, struct i2c_client *c) 339{ 340 unsigned char buf; 341 int i, rc; 342 343 for (i = 0; i < 128; i++) { 344 c->addr = i; 345 rc = i2c_master_recv(c, &buf, 0); 346 if (rc < 0) 347 continue; 348 pr_info("%s: i2c scan: found device @ 0x%x [%s]\n", 349 name, i << 1, i2c_devs[i] ? i2c_devs[i] : "???"); 350 } 351} 352 353/* init + register i2c adapter */ 354int au0828_i2c_register(struct au0828_dev *dev) 355{ 356 dprintk(1, "%s()\n", __func__); 357 358 dev->i2c_adap = au0828_i2c_adap_template; 359 dev->i2c_algo = au0828_i2c_algo_template; 360 dev->i2c_client = au0828_i2c_client_template; 361 362 dev->i2c_adap.dev.parent = &dev->usbdev->dev; 363 364 strscpy(dev->i2c_adap.name, KBUILD_MODNAME, 365 sizeof(dev->i2c_adap.name)); 366 367 dev->i2c_adap.algo = &dev->i2c_algo; 368 dev->i2c_adap.algo_data = dev; 369#ifdef CONFIG_VIDEO_AU0828_V4L2 370 i2c_set_adapdata(&dev->i2c_adap, &dev->v4l2_dev); 371#else 372 i2c_set_adapdata(&dev->i2c_adap, dev); 373#endif 374 i2c_add_adapter(&dev->i2c_adap); 375 376 dev->i2c_client.adapter = &dev->i2c_adap; 377 378 if (0 == dev->i2c_rc) { 379 pr_info("i2c bus registered\n"); 380 if (i2c_scan) 381 do_i2c_scan(KBUILD_MODNAME, &dev->i2c_client); 382 } else 383 pr_info("i2c bus register FAILED\n"); 384 385 return dev->i2c_rc; 386} 387 388int au0828_i2c_unregister(struct au0828_dev *dev) 389{ 390 i2c_del_adapter(&dev->i2c_adap); 391 return 0; 392} 393