457 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 *4 * device driver for philips saa7134 based TV cards5 * i2c interface support6 *7 * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]8 */9 10#include "saa7134.h"11#include "saa7134-reg.h"12 13#include <linux/init.h>14#include <linux/list.h>15#include <linux/module.h>16#include <linux/kernel.h>17#include <linux/delay.h>18 19#include <media/v4l2-common.h>20 21/* ----------------------------------------------------------- */22 23static unsigned int i2c_debug;24module_param(i2c_debug, int, 0644);25MODULE_PARM_DESC(i2c_debug,"enable debug messages [i2c]");26 27static unsigned int i2c_scan;28module_param(i2c_scan, int, 0444);29MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time");30 31#define i2c_dbg(level, fmt, arg...) do { \32 if (i2c_debug == level) \33 printk(KERN_DEBUG pr_fmt("i2c: " fmt), ## arg); \34 } while (0)35 36#define i2c_cont(level, fmt, arg...) do { \37 if (i2c_debug == level) \38 pr_cont(fmt, ## arg); \39 } while (0)40 41#define I2C_WAIT_DELAY 3242#define I2C_WAIT_RETRY 1643 44/* ----------------------------------------------------------- */45 46static char *str_i2c_status[] = {47 "IDLE", "DONE_STOP", "BUSY", "TO_SCL", "TO_ARB", "DONE_WRITE",48 "DONE_READ", "DONE_WRITE_TO", "DONE_READ_TO", "NO_DEVICE",49 "NO_ACKN", "BUS_ERR", "ARB_LOST", "SEQ_ERR", "ST_ERR", "SW_ERR"50};51 52enum i2c_status {53 IDLE = 0, // no I2C command pending54 DONE_STOP = 1, // I2C command done and STOP executed55 BUSY = 2, // executing I2C command56 TO_SCL = 3, // executing I2C command, time out on clock stretching57 TO_ARB = 4, // time out on arbitration trial, still trying58 DONE_WRITE = 5, // I2C command done and awaiting next write command59 DONE_READ = 6, // I2C command done and awaiting next read command60 DONE_WRITE_TO = 7, // see 5, and time out on status echo61 DONE_READ_TO = 8, // see 6, and time out on status echo62 NO_DEVICE = 9, // no acknowledge on device slave address63 NO_ACKN = 10, // no acknowledge after data byte transfer64 BUS_ERR = 11, // bus error65 ARB_LOST = 12, // arbitration lost during transfer66 SEQ_ERR = 13, // erroneous programming sequence67 ST_ERR = 14, // wrong status echoing68 SW_ERR = 15 // software error69};70 71static char *str_i2c_attr[] = {72 "NOP", "STOP", "CONTINUE", "START"73};74 75enum i2c_attr {76 NOP = 0, // no operation on I2C bus77 STOP = 1, // stop condition, no associated byte transfer78 CONTINUE = 2, // continue with byte transfer79 START = 3 // start condition with byte transfer80};81 82static inline enum i2c_status i2c_get_status(struct saa7134_dev *dev)83{84 enum i2c_status status;85 86 status = saa_readb(SAA7134_I2C_ATTR_STATUS) & 0x0f;87 i2c_dbg(2, "i2c stat <= %s\n", str_i2c_status[status]);88 return status;89}90 91static inline void i2c_set_status(struct saa7134_dev *dev,92 enum i2c_status status)93{94 i2c_dbg(2, "i2c stat => %s\n", str_i2c_status[status]);95 saa_andorb(SAA7134_I2C_ATTR_STATUS,0x0f,status);96}97 98static inline void i2c_set_attr(struct saa7134_dev *dev, enum i2c_attr attr)99{100 i2c_dbg(2, "i2c attr => %s\n", str_i2c_attr[attr]);101 saa_andorb(SAA7134_I2C_ATTR_STATUS,0xc0,attr << 6);102}103 104static inline int i2c_is_error(enum i2c_status status)105{106 switch (status) {107 case NO_DEVICE:108 case NO_ACKN:109 case BUS_ERR:110 case ARB_LOST:111 case SEQ_ERR:112 case ST_ERR:113 return true;114 default:115 return false;116 }117}118 119static inline int i2c_is_idle(enum i2c_status status)120{121 switch (status) {122 case IDLE:123 case DONE_STOP:124 return true;125 default:126 return false;127 }128}129 130static inline int i2c_is_busy(enum i2c_status status)131{132 switch (status) {133 case BUSY:134 case TO_SCL:135 case TO_ARB:136 return true;137 default:138 return false;139 }140}141 142static int i2c_is_busy_wait(struct saa7134_dev *dev)143{144 enum i2c_status status;145 int count;146 147 for (count = 0; count < I2C_WAIT_RETRY; count++) {148 status = i2c_get_status(dev);149 if (!i2c_is_busy(status))150 break;151 saa_wait(I2C_WAIT_DELAY);152 }153 if (I2C_WAIT_RETRY == count)154 return false;155 return true;156}157 158static int i2c_reset(struct saa7134_dev *dev)159{160 enum i2c_status status;161 int count;162 163 i2c_dbg(2, "i2c reset\n");164 status = i2c_get_status(dev);165 if (!i2c_is_error(status))166 return true;167 i2c_set_status(dev,status);168 169 for (count = 0; count < I2C_WAIT_RETRY; count++) {170 status = i2c_get_status(dev);171 if (!i2c_is_error(status))172 break;173 udelay(I2C_WAIT_DELAY);174 }175 if (I2C_WAIT_RETRY == count)176 return false;177 178 if (!i2c_is_idle(status))179 return false;180 181 i2c_set_attr(dev,NOP);182 return true;183}184 185static inline int i2c_send_byte(struct saa7134_dev *dev,186 enum i2c_attr attr,187 unsigned char data)188{189 enum i2c_status status;190 __u32 dword;191 192 /* have to write both attr + data in one 32bit word */193 dword = saa_readl(SAA7134_I2C_ATTR_STATUS >> 2);194 dword &= 0x0f;195 dword |= (attr << 6);196 dword |= ((__u32)data << 8);197 dword |= 0x00 << 16; /* 100 kHz */198// dword |= 0x40 << 16; /* 400 kHz */199 dword |= 0xf0 << 24;200 saa_writel(SAA7134_I2C_ATTR_STATUS >> 2, dword);201 i2c_dbg(2, "i2c data => 0x%x\n", data);202 203 if (!i2c_is_busy_wait(dev))204 return -EIO;205 status = i2c_get_status(dev);206 if (i2c_is_error(status))207 return -EIO;208 return 0;209}210 211static inline int i2c_recv_byte(struct saa7134_dev *dev)212{213 enum i2c_status status;214 unsigned char data;215 216 i2c_set_attr(dev,CONTINUE);217 if (!i2c_is_busy_wait(dev))218 return -EIO;219 status = i2c_get_status(dev);220 if (i2c_is_error(status))221 return -EIO;222 data = saa_readb(SAA7134_I2C_DATA);223 i2c_dbg(2, "i2c data <= 0x%x\n", data);224 return data;225}226 227static int saa7134_i2c_xfer(struct i2c_adapter *i2c_adap,228 struct i2c_msg *msgs, int num)229{230 struct saa7134_dev *dev = i2c_adap->algo_data;231 enum i2c_status status;232 unsigned char data;233 int addr,rc,i,byte;234 235 status = i2c_get_status(dev);236 if (!i2c_is_idle(status))237 if (!i2c_reset(dev))238 return -EIO;239 240 i2c_dbg(2, "start xfer\n");241 i2c_dbg(1, "i2c xfer:");242 for (i = 0; i < num; i++) {243 if (!(msgs[i].flags & I2C_M_NOSTART) || 0 == i) {244 /* send address */245 i2c_dbg(2, "send address\n");246 addr = msgs[i].addr << 1;247 if (msgs[i].flags & I2C_M_RD)248 addr |= 1;249 if (i > 0 && msgs[i].flags &250 I2C_M_RD && msgs[i].addr != 0x40 &&251 msgs[i].addr != 0x41 &&252 msgs[i].addr != 0x19) {253 /* workaround for a saa7134 i2c bug254 * needed to talk to the mt352 demux255 * thanks to pinnacle for the hint */256 int quirk = 0xfe;257 i2c_cont(1, " [%02x quirk]", quirk);258 i2c_send_byte(dev,START,quirk);259 i2c_recv_byte(dev);260 }261 i2c_cont(1, " < %02x", addr);262 rc = i2c_send_byte(dev,START,addr);263 if (rc < 0)264 goto err;265 }266 if (msgs[i].flags & I2C_M_RD) {267 /* read bytes */268 i2c_dbg(2, "read bytes\n");269 for (byte = 0; byte < msgs[i].len; byte++) {270 i2c_cont(1, " =");271 rc = i2c_recv_byte(dev);272 if (rc < 0)273 goto err;274 i2c_cont(1, "%02x", rc);275 msgs[i].buf[byte] = rc;276 }277 /* discard mysterious extra byte when reading278 from Samsung S5H1411. i2c bus gets error279 if we do not. */280 if (0x19 == msgs[i].addr) {281 i2c_cont(1, " ?");282 rc = i2c_recv_byte(dev);283 if (rc < 0)284 goto err;285 i2c_cont(1, "%02x", rc);286 }287 } else {288 /* write bytes */289 i2c_dbg(2, "write bytes\n");290 for (byte = 0; byte < msgs[i].len; byte++) {291 data = msgs[i].buf[byte];292 i2c_cont(1, " %02x", data);293 rc = i2c_send_byte(dev,CONTINUE,data);294 if (rc < 0)295 goto err;296 }297 }298 }299 i2c_dbg(2, "xfer done\n");300 i2c_cont(1, " >");301 i2c_set_attr(dev,STOP);302 rc = -EIO;303 if (!i2c_is_busy_wait(dev))304 goto err;305 status = i2c_get_status(dev);306 if (i2c_is_error(status))307 goto err;308 /* ensure that the bus is idle for at least one bit slot */309 msleep(1);310 311 i2c_cont(1, "\n");312 return num;313 err:314 if (1 == i2c_debug) {315 status = i2c_get_status(dev);316 i2c_cont(1, " ERROR: %s\n", str_i2c_status[status]);317 }318 return rc;319}320 321/* ----------------------------------------------------------- */322 323static u32 functionality(struct i2c_adapter *adap)324{325 return I2C_FUNC_SMBUS_EMUL;326}327 328static const struct i2c_algorithm saa7134_algo = {329 .master_xfer = saa7134_i2c_xfer,330 .functionality = functionality,331};332 333static const struct i2c_adapter saa7134_adap_template = {334 .owner = THIS_MODULE,335 .name = "saa7134",336 .algo = &saa7134_algo,337};338 339static const struct i2c_client saa7134_client_template = {340 .name = "saa7134 internal",341};342 343/* ----------------------------------------------------------- */344 345/*346 * On Medion 7134 reading the SAA7134 chip config EEPROM needs DVB-T347 * demod i2c gate closed due to an address clash between this EEPROM348 * and the demod one.349 */350static void saa7134_i2c_eeprom_md7134_gate(struct saa7134_dev *dev)351{352 u8 subaddr = 0x7, dmdregval;353 u8 data[2];354 int ret;355 struct i2c_msg i2cgatemsg_r[] = { {.addr = 0x08, .flags = 0,356 .buf = &subaddr, .len = 1},357 {.addr = 0x08,358 .flags = I2C_M_RD,359 .buf = &dmdregval, .len = 1}360 };361 struct i2c_msg i2cgatemsg_w[] = { {.addr = 0x08, .flags = 0,362 .buf = data, .len = 2} };363 364 ret = i2c_transfer(&dev->i2c_adap, i2cgatemsg_r, 2);365 if ((ret == 2) && (dmdregval & 0x2)) {366 pr_debug("%s: DVB-T demod i2c gate was left open\n",367 dev->name);368 369 data[0] = subaddr;370 data[1] = (dmdregval & ~0x2);371 if (i2c_transfer(&dev->i2c_adap, i2cgatemsg_w, 1) != 1)372 pr_err("%s: EEPROM i2c gate close failure\n",373 dev->name);374 }375}376 377static int378saa7134_i2c_eeprom(struct saa7134_dev *dev, unsigned char *eedata, int len)379{380 unsigned char buf;381 int i,err;382 383 if (dev->board == SAA7134_BOARD_MD7134)384 saa7134_i2c_eeprom_md7134_gate(dev);385 386 dev->i2c_client.addr = 0xa0 >> 1;387 buf = 0;388 if (1 != (err = i2c_master_send(&dev->i2c_client,&buf,1))) {389 pr_info("%s: Huh, no eeprom present (err=%d)?\n",390 dev->name,err);391 return -1;392 }393 if (len != (err = i2c_master_recv(&dev->i2c_client,eedata,len))) {394 pr_warn("%s: i2c eeprom read error (err=%d)\n",395 dev->name,err);396 return -1;397 }398 399 for (i = 0; i < len; i += 16) {400 int size = (len - i) > 16 ? 16 : len - i;401 402 pr_info("i2c eeprom %02x: %*ph\n", i, size, &eedata[i]);403 }404 405 return 0;406}407 408static char *i2c_devs[128] = {409 [ 0x20 ] = "mpeg encoder (saa6752hs)",410 [ 0xa0 >> 1 ] = "eeprom",411 [ 0xc0 >> 1 ] = "tuner (analog)",412 [ 0x86 >> 1 ] = "tda9887",413 [ 0x5a >> 1 ] = "remote control",414};415 416static void do_i2c_scan(struct i2c_client *c)417{418 unsigned char buf;419 int i,rc;420 421 for (i = 0; i < ARRAY_SIZE(i2c_devs); i++) {422 c->addr = i;423 rc = i2c_master_recv(c,&buf,0);424 if (rc < 0)425 continue;426 pr_info("i2c scan: found device @ 0x%x [%s]\n",427 i << 1, i2c_devs[i] ? i2c_devs[i] : "???");428 }429}430 431int saa7134_i2c_register(struct saa7134_dev *dev)432{433 dev->i2c_adap = saa7134_adap_template;434 dev->i2c_adap.dev.parent = &dev->pci->dev;435 strscpy(dev->i2c_adap.name, dev->name, sizeof(dev->i2c_adap.name));436 dev->i2c_adap.algo_data = dev;437 i2c_set_adapdata(&dev->i2c_adap, &dev->v4l2_dev);438 i2c_add_adapter(&dev->i2c_adap);439 440 dev->i2c_client = saa7134_client_template;441 dev->i2c_client.adapter = &dev->i2c_adap;442 443 saa7134_i2c_eeprom(dev,dev->eedata,sizeof(dev->eedata));444 if (i2c_scan)445 do_i2c_scan(&dev->i2c_client);446 447 /* Instantiate the IR receiver device, if present */448 saa7134_probe_i2c_ir(dev);449 return 0;450}451 452int saa7134_i2c_unregister(struct saa7134_dev *dev)453{454 i2c_del_adapter(&dev->i2c_adap);455 return 0;456}457