1*74ba9207SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later 268de959fSMauro Carvalho Chehab /* 368de959fSMauro Carvalho Chehab 468de959fSMauro Carvalho Chehab bttv-i2c.c -- all the i2c code is here 568de959fSMauro Carvalho Chehab 668de959fSMauro Carvalho Chehab bttv - Bt848 frame grabber driver 768de959fSMauro Carvalho Chehab 868de959fSMauro Carvalho Chehab Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) 968de959fSMauro Carvalho Chehab & Marcus Metzler (mocm@thp.uni-koeln.de) 1068de959fSMauro Carvalho Chehab (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org> 1168de959fSMauro Carvalho Chehab 1232590819SMauro Carvalho Chehab (c) 2005 Mauro Carvalho Chehab <mchehab@kernel.org> 1368de959fSMauro Carvalho Chehab - Multituner support and i2c address binding 1468de959fSMauro Carvalho Chehab 1568de959fSMauro Carvalho Chehab 1668de959fSMauro Carvalho Chehab */ 1768de959fSMauro Carvalho Chehab 1868de959fSMauro Carvalho Chehab #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 1968de959fSMauro Carvalho Chehab 2068de959fSMauro Carvalho Chehab #include <linux/module.h> 2168de959fSMauro Carvalho Chehab #include <linux/init.h> 2268de959fSMauro Carvalho Chehab #include <linux/delay.h> 2368de959fSMauro Carvalho Chehab 2468de959fSMauro Carvalho Chehab #include "bttvp.h" 2568de959fSMauro Carvalho Chehab #include <media/v4l2-common.h> 2668de959fSMauro Carvalho Chehab #include <linux/jiffies.h> 2768de959fSMauro Carvalho Chehab #include <asm/io.h> 2868de959fSMauro Carvalho Chehab 2968de959fSMauro Carvalho Chehab static int i2c_debug; 3068de959fSMauro Carvalho Chehab static int i2c_hw; 3168de959fSMauro Carvalho Chehab static int i2c_scan; 3268de959fSMauro Carvalho Chehab module_param(i2c_debug, int, 0644); 3368de959fSMauro Carvalho Chehab MODULE_PARM_DESC(i2c_debug, "configure i2c debug level"); 3468de959fSMauro Carvalho Chehab module_param(i2c_hw, int, 0444); 35652fd6eaSMauro Carvalho Chehab MODULE_PARM_DESC(i2c_hw, "force use of hardware i2c support, instead of software bitbang"); 3668de959fSMauro Carvalho Chehab module_param(i2c_scan, int, 0444); 3768de959fSMauro Carvalho Chehab MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time"); 3868de959fSMauro Carvalho Chehab 3968de959fSMauro Carvalho Chehab static unsigned int i2c_udelay = 5; 4068de959fSMauro Carvalho Chehab module_param(i2c_udelay, int, 0444); 41652fd6eaSMauro Carvalho Chehab MODULE_PARM_DESC(i2c_udelay, "soft i2c delay at insmod time, in usecs (should be 5 or higher). Lower value means higher bus speed."); 4268de959fSMauro Carvalho Chehab 4368de959fSMauro Carvalho Chehab /* ----------------------------------------------------------------------- */ 4468de959fSMauro Carvalho Chehab /* I2C functions - bitbanging adapter (software i2c) */ 4568de959fSMauro Carvalho Chehab 4668de959fSMauro Carvalho Chehab static void bttv_bit_setscl(void *data, int state) 4768de959fSMauro Carvalho Chehab { 4868de959fSMauro Carvalho Chehab struct bttv *btv = (struct bttv*)data; 4968de959fSMauro Carvalho Chehab 5068de959fSMauro Carvalho Chehab if (state) 5168de959fSMauro Carvalho Chehab btv->i2c_state |= 0x02; 5268de959fSMauro Carvalho Chehab else 5368de959fSMauro Carvalho Chehab btv->i2c_state &= ~0x02; 5468de959fSMauro Carvalho Chehab btwrite(btv->i2c_state, BT848_I2C); 5568de959fSMauro Carvalho Chehab btread(BT848_I2C); 5668de959fSMauro Carvalho Chehab } 5768de959fSMauro Carvalho Chehab 5868de959fSMauro Carvalho Chehab static void bttv_bit_setsda(void *data, int state) 5968de959fSMauro Carvalho Chehab { 6068de959fSMauro Carvalho Chehab struct bttv *btv = (struct bttv*)data; 6168de959fSMauro Carvalho Chehab 6268de959fSMauro Carvalho Chehab if (state) 6368de959fSMauro Carvalho Chehab btv->i2c_state |= 0x01; 6468de959fSMauro Carvalho Chehab else 6568de959fSMauro Carvalho Chehab btv->i2c_state &= ~0x01; 6668de959fSMauro Carvalho Chehab btwrite(btv->i2c_state, BT848_I2C); 6768de959fSMauro Carvalho Chehab btread(BT848_I2C); 6868de959fSMauro Carvalho Chehab } 6968de959fSMauro Carvalho Chehab 7068de959fSMauro Carvalho Chehab static int bttv_bit_getscl(void *data) 7168de959fSMauro Carvalho Chehab { 7268de959fSMauro Carvalho Chehab struct bttv *btv = (struct bttv*)data; 7368de959fSMauro Carvalho Chehab int state; 7468de959fSMauro Carvalho Chehab 7568de959fSMauro Carvalho Chehab state = btread(BT848_I2C) & 0x02 ? 1 : 0; 7668de959fSMauro Carvalho Chehab return state; 7768de959fSMauro Carvalho Chehab } 7868de959fSMauro Carvalho Chehab 7968de959fSMauro Carvalho Chehab static int bttv_bit_getsda(void *data) 8068de959fSMauro Carvalho Chehab { 8168de959fSMauro Carvalho Chehab struct bttv *btv = (struct bttv*)data; 8268de959fSMauro Carvalho Chehab int state; 8368de959fSMauro Carvalho Chehab 8468de959fSMauro Carvalho Chehab state = btread(BT848_I2C) & 0x01; 8568de959fSMauro Carvalho Chehab return state; 8668de959fSMauro Carvalho Chehab } 8768de959fSMauro Carvalho Chehab 884d947447SBhumika Goyal static const struct i2c_algo_bit_data bttv_i2c_algo_bit_template = { 8968de959fSMauro Carvalho Chehab .setsda = bttv_bit_setsda, 9068de959fSMauro Carvalho Chehab .setscl = bttv_bit_setscl, 9168de959fSMauro Carvalho Chehab .getsda = bttv_bit_getsda, 9268de959fSMauro Carvalho Chehab .getscl = bttv_bit_getscl, 9368de959fSMauro Carvalho Chehab .udelay = 16, 9468de959fSMauro Carvalho Chehab .timeout = 200, 9568de959fSMauro Carvalho Chehab }; 9668de959fSMauro Carvalho Chehab 9768de959fSMauro Carvalho Chehab /* ----------------------------------------------------------------------- */ 9868de959fSMauro Carvalho Chehab /* I2C functions - hardware i2c */ 9968de959fSMauro Carvalho Chehab 10068de959fSMauro Carvalho Chehab static u32 functionality(struct i2c_adapter *adap) 10168de959fSMauro Carvalho Chehab { 10268de959fSMauro Carvalho Chehab return I2C_FUNC_SMBUS_EMUL; 10368de959fSMauro Carvalho Chehab } 10468de959fSMauro Carvalho Chehab 10568de959fSMauro Carvalho Chehab static int 10668de959fSMauro Carvalho Chehab bttv_i2c_wait_done(struct bttv *btv) 10768de959fSMauro Carvalho Chehab { 10868de959fSMauro Carvalho Chehab int rc = 0; 10968de959fSMauro Carvalho Chehab 11068de959fSMauro Carvalho Chehab /* timeout */ 11168de959fSMauro Carvalho Chehab if (wait_event_interruptible_timeout(btv->i2c_queue, 11268de959fSMauro Carvalho Chehab btv->i2c_done, msecs_to_jiffies(85)) == -ERESTARTSYS) 11368de959fSMauro Carvalho Chehab rc = -EIO; 11468de959fSMauro Carvalho Chehab 11568de959fSMauro Carvalho Chehab if (btv->i2c_done & BT848_INT_RACK) 11668de959fSMauro Carvalho Chehab rc = 1; 11768de959fSMauro Carvalho Chehab btv->i2c_done = 0; 11868de959fSMauro Carvalho Chehab return rc; 11968de959fSMauro Carvalho Chehab } 12068de959fSMauro Carvalho Chehab 12168de959fSMauro Carvalho Chehab #define I2C_HW (BT878_I2C_MODE | BT848_I2C_SYNC |\ 12268de959fSMauro Carvalho Chehab BT848_I2C_SCL | BT848_I2C_SDA) 12368de959fSMauro Carvalho Chehab 12468de959fSMauro Carvalho Chehab static int 12568de959fSMauro Carvalho Chehab bttv_i2c_sendbytes(struct bttv *btv, const struct i2c_msg *msg, int last) 12668de959fSMauro Carvalho Chehab { 12768de959fSMauro Carvalho Chehab u32 xmit; 12868de959fSMauro Carvalho Chehab int retval,cnt; 12968de959fSMauro Carvalho Chehab 13068de959fSMauro Carvalho Chehab /* sanity checks */ 13168de959fSMauro Carvalho Chehab if (0 == msg->len) 13268de959fSMauro Carvalho Chehab return -EINVAL; 13368de959fSMauro Carvalho Chehab 13468de959fSMauro Carvalho Chehab /* start, address + first byte */ 13568de959fSMauro Carvalho Chehab xmit = (msg->addr << 25) | (msg->buf[0] << 16) | I2C_HW; 13668de959fSMauro Carvalho Chehab if (msg->len > 1 || !last) 13768de959fSMauro Carvalho Chehab xmit |= BT878_I2C_NOSTOP; 13868de959fSMauro Carvalho Chehab btwrite(xmit, BT848_I2C); 13968de959fSMauro Carvalho Chehab retval = bttv_i2c_wait_done(btv); 14068de959fSMauro Carvalho Chehab if (retval < 0) 14168de959fSMauro Carvalho Chehab goto err; 14268de959fSMauro Carvalho Chehab if (retval == 0) 14368de959fSMauro Carvalho Chehab goto eio; 14468de959fSMauro Carvalho Chehab if (i2c_debug) { 14568de959fSMauro Carvalho Chehab pr_cont(" <W %02x %02x", msg->addr << 1, msg->buf[0]); 14668de959fSMauro Carvalho Chehab } 14768de959fSMauro Carvalho Chehab 14868de959fSMauro Carvalho Chehab for (cnt = 1; cnt < msg->len; cnt++ ) { 14968de959fSMauro Carvalho Chehab /* following bytes */ 15068de959fSMauro Carvalho Chehab xmit = (msg->buf[cnt] << 24) | I2C_HW | BT878_I2C_NOSTART; 15168de959fSMauro Carvalho Chehab if (cnt < msg->len-1 || !last) 15268de959fSMauro Carvalho Chehab xmit |= BT878_I2C_NOSTOP; 15368de959fSMauro Carvalho Chehab btwrite(xmit, BT848_I2C); 15468de959fSMauro Carvalho Chehab retval = bttv_i2c_wait_done(btv); 15568de959fSMauro Carvalho Chehab if (retval < 0) 15668de959fSMauro Carvalho Chehab goto err; 15768de959fSMauro Carvalho Chehab if (retval == 0) 15868de959fSMauro Carvalho Chehab goto eio; 15968de959fSMauro Carvalho Chehab if (i2c_debug) 16068de959fSMauro Carvalho Chehab pr_cont(" %02x", msg->buf[cnt]); 16168de959fSMauro Carvalho Chehab } 1621ca6ae8dSJohn Törnblom if (i2c_debug && !(xmit & BT878_I2C_NOSTOP)) 16368de959fSMauro Carvalho Chehab pr_cont(">\n"); 16468de959fSMauro Carvalho Chehab return msg->len; 16568de959fSMauro Carvalho Chehab 16668de959fSMauro Carvalho Chehab eio: 16768de959fSMauro Carvalho Chehab retval = -EIO; 16868de959fSMauro Carvalho Chehab err: 16968de959fSMauro Carvalho Chehab if (i2c_debug) 17068de959fSMauro Carvalho Chehab pr_cont(" ERR: %d\n",retval); 17168de959fSMauro Carvalho Chehab return retval; 17268de959fSMauro Carvalho Chehab } 17368de959fSMauro Carvalho Chehab 17468de959fSMauro Carvalho Chehab static int 17568de959fSMauro Carvalho Chehab bttv_i2c_readbytes(struct bttv *btv, const struct i2c_msg *msg, int last) 17668de959fSMauro Carvalho Chehab { 17768de959fSMauro Carvalho Chehab u32 xmit; 17868de959fSMauro Carvalho Chehab u32 cnt; 17968de959fSMauro Carvalho Chehab int retval; 18068de959fSMauro Carvalho Chehab 18168de959fSMauro Carvalho Chehab for (cnt = 0; cnt < msg->len; cnt++) { 18268de959fSMauro Carvalho Chehab xmit = (msg->addr << 25) | (1 << 24) | I2C_HW; 18368de959fSMauro Carvalho Chehab if (cnt < msg->len-1) 18468de959fSMauro Carvalho Chehab xmit |= BT848_I2C_W3B; 18568de959fSMauro Carvalho Chehab if (cnt < msg->len-1 || !last) 18668de959fSMauro Carvalho Chehab xmit |= BT878_I2C_NOSTOP; 18768de959fSMauro Carvalho Chehab if (cnt) 18868de959fSMauro Carvalho Chehab xmit |= BT878_I2C_NOSTART; 18968de959fSMauro Carvalho Chehab 19068de959fSMauro Carvalho Chehab if (i2c_debug) { 19168de959fSMauro Carvalho Chehab if (!(xmit & BT878_I2C_NOSTART)) 19268de959fSMauro Carvalho Chehab pr_cont(" <R %02x", (msg->addr << 1) +1); 19368de959fSMauro Carvalho Chehab } 19468de959fSMauro Carvalho Chehab 19568de959fSMauro Carvalho Chehab btwrite(xmit, BT848_I2C); 19668de959fSMauro Carvalho Chehab retval = bttv_i2c_wait_done(btv); 19768de959fSMauro Carvalho Chehab if (retval < 0) 19868de959fSMauro Carvalho Chehab goto err; 19968de959fSMauro Carvalho Chehab if (retval == 0) 20068de959fSMauro Carvalho Chehab goto eio; 20168de959fSMauro Carvalho Chehab msg->buf[cnt] = ((u32)btread(BT848_I2C) >> 8) & 0xff; 20268de959fSMauro Carvalho Chehab if (i2c_debug) { 20368de959fSMauro Carvalho Chehab pr_cont(" =%02x", msg->buf[cnt]); 20468de959fSMauro Carvalho Chehab } 20568de959fSMauro Carvalho Chehab if (i2c_debug && !(xmit & BT878_I2C_NOSTOP)) 20668de959fSMauro Carvalho Chehab pr_cont(" >\n"); 20768de959fSMauro Carvalho Chehab } 20868de959fSMauro Carvalho Chehab 20968de959fSMauro Carvalho Chehab 21068de959fSMauro Carvalho Chehab return msg->len; 21168de959fSMauro Carvalho Chehab 21268de959fSMauro Carvalho Chehab eio: 21368de959fSMauro Carvalho Chehab retval = -EIO; 21468de959fSMauro Carvalho Chehab err: 21568de959fSMauro Carvalho Chehab if (i2c_debug) 21668de959fSMauro Carvalho Chehab pr_cont(" ERR: %d\n",retval); 21768de959fSMauro Carvalho Chehab return retval; 21868de959fSMauro Carvalho Chehab } 21968de959fSMauro Carvalho Chehab 22068de959fSMauro Carvalho Chehab static int bttv_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num) 22168de959fSMauro Carvalho Chehab { 22268de959fSMauro Carvalho Chehab struct v4l2_device *v4l2_dev = i2c_get_adapdata(i2c_adap); 22368de959fSMauro Carvalho Chehab struct bttv *btv = to_bttv(v4l2_dev); 22468de959fSMauro Carvalho Chehab int retval = 0; 22568de959fSMauro Carvalho Chehab int i; 22668de959fSMauro Carvalho Chehab 22768de959fSMauro Carvalho Chehab if (i2c_debug) 22868de959fSMauro Carvalho Chehab pr_debug("bt-i2c:"); 22968de959fSMauro Carvalho Chehab 23068de959fSMauro Carvalho Chehab btwrite(BT848_INT_I2CDONE|BT848_INT_RACK, BT848_INT_STAT); 23168de959fSMauro Carvalho Chehab for (i = 0 ; i < num; i++) { 23268de959fSMauro Carvalho Chehab if (msgs[i].flags & I2C_M_RD) { 23368de959fSMauro Carvalho Chehab /* read */ 23468de959fSMauro Carvalho Chehab retval = bttv_i2c_readbytes(btv, &msgs[i], i+1 == num); 23568de959fSMauro Carvalho Chehab if (retval < 0) 23668de959fSMauro Carvalho Chehab goto err; 23768de959fSMauro Carvalho Chehab } else { 23868de959fSMauro Carvalho Chehab /* write */ 23968de959fSMauro Carvalho Chehab retval = bttv_i2c_sendbytes(btv, &msgs[i], i+1 == num); 24068de959fSMauro Carvalho Chehab if (retval < 0) 24168de959fSMauro Carvalho Chehab goto err; 24268de959fSMauro Carvalho Chehab } 24368de959fSMauro Carvalho Chehab } 24468de959fSMauro Carvalho Chehab return num; 24568de959fSMauro Carvalho Chehab 24668de959fSMauro Carvalho Chehab err: 24768de959fSMauro Carvalho Chehab return retval; 24868de959fSMauro Carvalho Chehab } 24968de959fSMauro Carvalho Chehab 25068de959fSMauro Carvalho Chehab static const struct i2c_algorithm bttv_algo = { 25168de959fSMauro Carvalho Chehab .master_xfer = bttv_i2c_xfer, 25268de959fSMauro Carvalho Chehab .functionality = functionality, 25368de959fSMauro Carvalho Chehab }; 25468de959fSMauro Carvalho Chehab 25568de959fSMauro Carvalho Chehab /* ----------------------------------------------------------------------- */ 25668de959fSMauro Carvalho Chehab /* I2C functions - common stuff */ 25768de959fSMauro Carvalho Chehab 25868de959fSMauro Carvalho Chehab /* read I2C */ 25968de959fSMauro Carvalho Chehab int bttv_I2CRead(struct bttv *btv, unsigned char addr, char *probe_for) 26068de959fSMauro Carvalho Chehab { 26168de959fSMauro Carvalho Chehab unsigned char buffer = 0; 26268de959fSMauro Carvalho Chehab 26368de959fSMauro Carvalho Chehab if (0 != btv->i2c_rc) 26468de959fSMauro Carvalho Chehab return -1; 26568de959fSMauro Carvalho Chehab if (bttv_verbose && NULL != probe_for) 26668de959fSMauro Carvalho Chehab pr_info("%d: i2c: checking for %s @ 0x%02x... ", 26768de959fSMauro Carvalho Chehab btv->c.nr, probe_for, addr); 26868de959fSMauro Carvalho Chehab btv->i2c_client.addr = addr >> 1; 26968de959fSMauro Carvalho Chehab if (1 != i2c_master_recv(&btv->i2c_client, &buffer, 1)) { 27068de959fSMauro Carvalho Chehab if (NULL != probe_for) { 27168de959fSMauro Carvalho Chehab if (bttv_verbose) 27268de959fSMauro Carvalho Chehab pr_cont("not found\n"); 27368de959fSMauro Carvalho Chehab } else 27468de959fSMauro Carvalho Chehab pr_warn("%d: i2c read 0x%x: error\n", 27568de959fSMauro Carvalho Chehab btv->c.nr, addr); 27668de959fSMauro Carvalho Chehab return -1; 27768de959fSMauro Carvalho Chehab } 27868de959fSMauro Carvalho Chehab if (bttv_verbose && NULL != probe_for) 27968de959fSMauro Carvalho Chehab pr_cont("found\n"); 28068de959fSMauro Carvalho Chehab return buffer; 28168de959fSMauro Carvalho Chehab } 28268de959fSMauro Carvalho Chehab 28368de959fSMauro Carvalho Chehab /* write I2C */ 28468de959fSMauro Carvalho Chehab int bttv_I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1, 28568de959fSMauro Carvalho Chehab unsigned char b2, int both) 28668de959fSMauro Carvalho Chehab { 28768de959fSMauro Carvalho Chehab unsigned char buffer[2]; 28868de959fSMauro Carvalho Chehab int bytes = both ? 2 : 1; 28968de959fSMauro Carvalho Chehab 29068de959fSMauro Carvalho Chehab if (0 != btv->i2c_rc) 29168de959fSMauro Carvalho Chehab return -1; 29268de959fSMauro Carvalho Chehab btv->i2c_client.addr = addr >> 1; 29368de959fSMauro Carvalho Chehab buffer[0] = b1; 29468de959fSMauro Carvalho Chehab buffer[1] = b2; 29568de959fSMauro Carvalho Chehab if (bytes != i2c_master_send(&btv->i2c_client, buffer, bytes)) 29668de959fSMauro Carvalho Chehab return -1; 29768de959fSMauro Carvalho Chehab return 0; 29868de959fSMauro Carvalho Chehab } 29968de959fSMauro Carvalho Chehab 30068de959fSMauro Carvalho Chehab /* read EEPROM content */ 3014c62e976SGreg Kroah-Hartman void bttv_readee(struct bttv *btv, unsigned char *eedata, int addr) 30268de959fSMauro Carvalho Chehab { 30368de959fSMauro Carvalho Chehab memset(eedata, 0, 256); 30468de959fSMauro Carvalho Chehab if (0 != btv->i2c_rc) 30568de959fSMauro Carvalho Chehab return; 30668de959fSMauro Carvalho Chehab btv->i2c_client.addr = addr >> 1; 30768de959fSMauro Carvalho Chehab tveeprom_read(&btv->i2c_client, eedata, 256); 30868de959fSMauro Carvalho Chehab } 30968de959fSMauro Carvalho Chehab 31068de959fSMauro Carvalho Chehab static char *i2c_devs[128] = { 31168de959fSMauro Carvalho Chehab [ 0x1c >> 1 ] = "lgdt330x", 31268de959fSMauro Carvalho Chehab [ 0x30 >> 1 ] = "IR (hauppauge)", 31368de959fSMauro Carvalho Chehab [ 0x80 >> 1 ] = "msp34xx", 31468de959fSMauro Carvalho Chehab [ 0x86 >> 1 ] = "tda9887", 31568de959fSMauro Carvalho Chehab [ 0xa0 >> 1 ] = "eeprom", 31668de959fSMauro Carvalho Chehab [ 0xc0 >> 1 ] = "tuner (analog)", 31768de959fSMauro Carvalho Chehab [ 0xc2 >> 1 ] = "tuner (analog)", 31868de959fSMauro Carvalho Chehab }; 31968de959fSMauro Carvalho Chehab 32068de959fSMauro Carvalho Chehab static void do_i2c_scan(char *name, struct i2c_client *c) 32168de959fSMauro Carvalho Chehab { 32268de959fSMauro Carvalho Chehab unsigned char buf; 32368de959fSMauro Carvalho Chehab int i,rc; 32468de959fSMauro Carvalho Chehab 32568de959fSMauro Carvalho Chehab for (i = 0; i < ARRAY_SIZE(i2c_devs); i++) { 32668de959fSMauro Carvalho Chehab c->addr = i; 32768de959fSMauro Carvalho Chehab rc = i2c_master_recv(c,&buf,0); 32868de959fSMauro Carvalho Chehab if (rc < 0) 32968de959fSMauro Carvalho Chehab continue; 33068de959fSMauro Carvalho Chehab pr_info("%s: i2c scan: found device @ 0x%x [%s]\n", 33168de959fSMauro Carvalho Chehab name, i << 1, i2c_devs[i] ? i2c_devs[i] : "???"); 33268de959fSMauro Carvalho Chehab } 33368de959fSMauro Carvalho Chehab } 33468de959fSMauro Carvalho Chehab 33568de959fSMauro Carvalho Chehab /* init + register i2c adapter */ 3364c62e976SGreg Kroah-Hartman int init_bttv_i2c(struct bttv *btv) 33768de959fSMauro Carvalho Chehab { 338c0decac1SMauro Carvalho Chehab strscpy(btv->i2c_client.name, "bttv internal", I2C_NAME_SIZE); 33968de959fSMauro Carvalho Chehab 34068de959fSMauro Carvalho Chehab if (i2c_hw) 34168de959fSMauro Carvalho Chehab btv->use_i2c_hw = 1; 34268de959fSMauro Carvalho Chehab if (btv->use_i2c_hw) { 34368de959fSMauro Carvalho Chehab /* bt878 */ 344c0decac1SMauro Carvalho Chehab strscpy(btv->c.i2c_adap.name, "bt878", 34568de959fSMauro Carvalho Chehab sizeof(btv->c.i2c_adap.name)); 34668de959fSMauro Carvalho Chehab btv->c.i2c_adap.algo = &bttv_algo; 34768de959fSMauro Carvalho Chehab } else { 34868de959fSMauro Carvalho Chehab /* bt848 */ 34968de959fSMauro Carvalho Chehab /* Prevents usage of invalid delay values */ 35068de959fSMauro Carvalho Chehab if (i2c_udelay<5) 35168de959fSMauro Carvalho Chehab i2c_udelay=5; 35268de959fSMauro Carvalho Chehab 353c0decac1SMauro Carvalho Chehab strscpy(btv->c.i2c_adap.name, "bttv", 35468de959fSMauro Carvalho Chehab sizeof(btv->c.i2c_adap.name)); 355b4b1d040SEzequiel Garcia btv->i2c_algo = bttv_i2c_algo_bit_template; 35668de959fSMauro Carvalho Chehab btv->i2c_algo.udelay = i2c_udelay; 35768de959fSMauro Carvalho Chehab btv->i2c_algo.data = btv; 35868de959fSMauro Carvalho Chehab btv->c.i2c_adap.algo_data = &btv->i2c_algo; 35968de959fSMauro Carvalho Chehab } 36068de959fSMauro Carvalho Chehab btv->c.i2c_adap.owner = THIS_MODULE; 36168de959fSMauro Carvalho Chehab 36268de959fSMauro Carvalho Chehab btv->c.i2c_adap.dev.parent = &btv->c.pci->dev; 36368de959fSMauro Carvalho Chehab snprintf(btv->c.i2c_adap.name, sizeof(btv->c.i2c_adap.name), 36468de959fSMauro Carvalho Chehab "bt%d #%d [%s]", btv->id, btv->c.nr, 36568de959fSMauro Carvalho Chehab btv->use_i2c_hw ? "hw" : "sw"); 36668de959fSMauro Carvalho Chehab 36768de959fSMauro Carvalho Chehab i2c_set_adapdata(&btv->c.i2c_adap, &btv->c.v4l2_dev); 36868de959fSMauro Carvalho Chehab btv->i2c_client.adapter = &btv->c.i2c_adap; 36968de959fSMauro Carvalho Chehab 37068de959fSMauro Carvalho Chehab 37168de959fSMauro Carvalho Chehab if (btv->use_i2c_hw) { 37268de959fSMauro Carvalho Chehab btv->i2c_rc = i2c_add_adapter(&btv->c.i2c_adap); 37368de959fSMauro Carvalho Chehab } else { 37468de959fSMauro Carvalho Chehab bttv_bit_setscl(btv,1); 37568de959fSMauro Carvalho Chehab bttv_bit_setsda(btv,1); 37668de959fSMauro Carvalho Chehab btv->i2c_rc = i2c_bit_add_bus(&btv->c.i2c_adap); 37768de959fSMauro Carvalho Chehab } 37868de959fSMauro Carvalho Chehab if (0 == btv->i2c_rc && i2c_scan) 37968de959fSMauro Carvalho Chehab do_i2c_scan(btv->c.v4l2_dev.name, &btv->i2c_client); 38068de959fSMauro Carvalho Chehab 38168de959fSMauro Carvalho Chehab return btv->i2c_rc; 38268de959fSMauro Carvalho Chehab } 383457ba4ceSFrank Schaefer 384457ba4ceSFrank Schaefer int fini_bttv_i2c(struct bttv *btv) 385457ba4ceSFrank Schaefer { 38699bece77SLinus Torvalds if (btv->i2c_rc == 0) 38799bece77SLinus Torvalds i2c_del_adapter(&btv->c.i2c_adap); 388457ba4ceSFrank Schaefer 38999bece77SLinus Torvalds return 0; 390457ba4ceSFrank Schaefer } 391