162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci 462306a36Sopenharmony_ci bttv-i2c.c -- all the i2c code is here 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci bttv - Bt848 frame grabber driver 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) 962306a36Sopenharmony_ci & Marcus Metzler (mocm@thp.uni-koeln.de) 1062306a36Sopenharmony_ci (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org> 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci (c) 2005 Mauro Carvalho Chehab <mchehab@kernel.org> 1362306a36Sopenharmony_ci - Multituner support and i2c address binding 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci*/ 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ci#include <linux/module.h> 2162306a36Sopenharmony_ci#include <linux/init.h> 2262306a36Sopenharmony_ci#include <linux/delay.h> 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci#include "bttvp.h" 2562306a36Sopenharmony_ci#include <media/v4l2-common.h> 2662306a36Sopenharmony_ci#include <linux/jiffies.h> 2762306a36Sopenharmony_ci#include <asm/io.h> 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_cistatic int i2c_debug; 3062306a36Sopenharmony_cistatic int i2c_hw; 3162306a36Sopenharmony_cistatic int i2c_scan; 3262306a36Sopenharmony_cimodule_param(i2c_debug, int, 0644); 3362306a36Sopenharmony_ciMODULE_PARM_DESC(i2c_debug, "configure i2c debug level"); 3462306a36Sopenharmony_cimodule_param(i2c_hw, int, 0444); 3562306a36Sopenharmony_ciMODULE_PARM_DESC(i2c_hw, "force use of hardware i2c support, instead of software bitbang"); 3662306a36Sopenharmony_cimodule_param(i2c_scan, int, 0444); 3762306a36Sopenharmony_ciMODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time"); 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_cistatic unsigned int i2c_udelay = 5; 4062306a36Sopenharmony_cimodule_param(i2c_udelay, int, 0444); 4162306a36Sopenharmony_ciMODULE_PARM_DESC(i2c_udelay, "soft i2c delay at insmod time, in usecs (should be 5 or higher). Lower value means higher bus speed."); 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci/* ----------------------------------------------------------------------- */ 4462306a36Sopenharmony_ci/* I2C functions - bitbanging adapter (software i2c) */ 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_cistatic void bttv_bit_setscl(void *data, int state) 4762306a36Sopenharmony_ci{ 4862306a36Sopenharmony_ci struct bttv *btv = (struct bttv*)data; 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci if (state) 5162306a36Sopenharmony_ci btv->i2c_state |= 0x02; 5262306a36Sopenharmony_ci else 5362306a36Sopenharmony_ci btv->i2c_state &= ~0x02; 5462306a36Sopenharmony_ci btwrite(btv->i2c_state, BT848_I2C); 5562306a36Sopenharmony_ci btread(BT848_I2C); 5662306a36Sopenharmony_ci} 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_cistatic void bttv_bit_setsda(void *data, int state) 5962306a36Sopenharmony_ci{ 6062306a36Sopenharmony_ci struct bttv *btv = (struct bttv*)data; 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci if (state) 6362306a36Sopenharmony_ci btv->i2c_state |= 0x01; 6462306a36Sopenharmony_ci else 6562306a36Sopenharmony_ci btv->i2c_state &= ~0x01; 6662306a36Sopenharmony_ci btwrite(btv->i2c_state, BT848_I2C); 6762306a36Sopenharmony_ci btread(BT848_I2C); 6862306a36Sopenharmony_ci} 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_cistatic int bttv_bit_getscl(void *data) 7162306a36Sopenharmony_ci{ 7262306a36Sopenharmony_ci struct bttv *btv = (struct bttv*)data; 7362306a36Sopenharmony_ci int state; 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci state = btread(BT848_I2C) & 0x02 ? 1 : 0; 7662306a36Sopenharmony_ci return state; 7762306a36Sopenharmony_ci} 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_cistatic int bttv_bit_getsda(void *data) 8062306a36Sopenharmony_ci{ 8162306a36Sopenharmony_ci struct bttv *btv = (struct bttv*)data; 8262306a36Sopenharmony_ci int state; 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci state = btread(BT848_I2C) & 0x01; 8562306a36Sopenharmony_ci return state; 8662306a36Sopenharmony_ci} 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_cistatic const struct i2c_algo_bit_data bttv_i2c_algo_bit_template = { 8962306a36Sopenharmony_ci .setsda = bttv_bit_setsda, 9062306a36Sopenharmony_ci .setscl = bttv_bit_setscl, 9162306a36Sopenharmony_ci .getsda = bttv_bit_getsda, 9262306a36Sopenharmony_ci .getscl = bttv_bit_getscl, 9362306a36Sopenharmony_ci .udelay = 16, 9462306a36Sopenharmony_ci .timeout = 200, 9562306a36Sopenharmony_ci}; 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci/* ----------------------------------------------------------------------- */ 9862306a36Sopenharmony_ci/* I2C functions - hardware i2c */ 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_cistatic u32 functionality(struct i2c_adapter *adap) 10162306a36Sopenharmony_ci{ 10262306a36Sopenharmony_ci return I2C_FUNC_SMBUS_EMUL; 10362306a36Sopenharmony_ci} 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_cistatic int 10662306a36Sopenharmony_cibttv_i2c_wait_done(struct bttv *btv) 10762306a36Sopenharmony_ci{ 10862306a36Sopenharmony_ci int rc = 0; 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci /* timeout */ 11162306a36Sopenharmony_ci if (wait_event_interruptible_timeout(btv->i2c_queue, 11262306a36Sopenharmony_ci btv->i2c_done, msecs_to_jiffies(85)) == -ERESTARTSYS) 11362306a36Sopenharmony_ci rc = -EIO; 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci if (btv->i2c_done & BT848_INT_RACK) 11662306a36Sopenharmony_ci rc = 1; 11762306a36Sopenharmony_ci btv->i2c_done = 0; 11862306a36Sopenharmony_ci return rc; 11962306a36Sopenharmony_ci} 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci#define I2C_HW (BT878_I2C_MODE | BT848_I2C_SYNC |\ 12262306a36Sopenharmony_ci BT848_I2C_SCL | BT848_I2C_SDA) 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_cistatic int 12562306a36Sopenharmony_cibttv_i2c_sendbytes(struct bttv *btv, const struct i2c_msg *msg, int last) 12662306a36Sopenharmony_ci{ 12762306a36Sopenharmony_ci u32 xmit; 12862306a36Sopenharmony_ci int retval,cnt; 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci /* sanity checks */ 13162306a36Sopenharmony_ci if (0 == msg->len) 13262306a36Sopenharmony_ci return -EINVAL; 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_ci /* start, address + first byte */ 13562306a36Sopenharmony_ci xmit = (msg->addr << 25) | (msg->buf[0] << 16) | I2C_HW; 13662306a36Sopenharmony_ci if (msg->len > 1 || !last) 13762306a36Sopenharmony_ci xmit |= BT878_I2C_NOSTOP; 13862306a36Sopenharmony_ci btwrite(xmit, BT848_I2C); 13962306a36Sopenharmony_ci retval = bttv_i2c_wait_done(btv); 14062306a36Sopenharmony_ci if (retval < 0) 14162306a36Sopenharmony_ci goto err; 14262306a36Sopenharmony_ci if (retval == 0) 14362306a36Sopenharmony_ci goto eio; 14462306a36Sopenharmony_ci if (i2c_debug) { 14562306a36Sopenharmony_ci pr_cont(" <W %02x %02x", msg->addr << 1, msg->buf[0]); 14662306a36Sopenharmony_ci } 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_ci for (cnt = 1; cnt < msg->len; cnt++ ) { 14962306a36Sopenharmony_ci /* following bytes */ 15062306a36Sopenharmony_ci xmit = (msg->buf[cnt] << 24) | I2C_HW | BT878_I2C_NOSTART; 15162306a36Sopenharmony_ci if (cnt < msg->len-1 || !last) 15262306a36Sopenharmony_ci xmit |= BT878_I2C_NOSTOP; 15362306a36Sopenharmony_ci btwrite(xmit, BT848_I2C); 15462306a36Sopenharmony_ci retval = bttv_i2c_wait_done(btv); 15562306a36Sopenharmony_ci if (retval < 0) 15662306a36Sopenharmony_ci goto err; 15762306a36Sopenharmony_ci if (retval == 0) 15862306a36Sopenharmony_ci goto eio; 15962306a36Sopenharmony_ci if (i2c_debug) 16062306a36Sopenharmony_ci pr_cont(" %02x", msg->buf[cnt]); 16162306a36Sopenharmony_ci } 16262306a36Sopenharmony_ci if (i2c_debug && !(xmit & BT878_I2C_NOSTOP)) 16362306a36Sopenharmony_ci pr_cont(">\n"); 16462306a36Sopenharmony_ci return msg->len; 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_ci eio: 16762306a36Sopenharmony_ci retval = -EIO; 16862306a36Sopenharmony_ci err: 16962306a36Sopenharmony_ci if (i2c_debug) 17062306a36Sopenharmony_ci pr_cont(" ERR: %d\n",retval); 17162306a36Sopenharmony_ci return retval; 17262306a36Sopenharmony_ci} 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_cistatic int 17562306a36Sopenharmony_cibttv_i2c_readbytes(struct bttv *btv, const struct i2c_msg *msg, int last) 17662306a36Sopenharmony_ci{ 17762306a36Sopenharmony_ci u32 xmit; 17862306a36Sopenharmony_ci u32 cnt; 17962306a36Sopenharmony_ci int retval; 18062306a36Sopenharmony_ci 18162306a36Sopenharmony_ci for (cnt = 0; cnt < msg->len; cnt++) { 18262306a36Sopenharmony_ci xmit = (msg->addr << 25) | (1 << 24) | I2C_HW; 18362306a36Sopenharmony_ci if (cnt < msg->len-1) 18462306a36Sopenharmony_ci xmit |= BT848_I2C_W3B; 18562306a36Sopenharmony_ci if (cnt < msg->len-1 || !last) 18662306a36Sopenharmony_ci xmit |= BT878_I2C_NOSTOP; 18762306a36Sopenharmony_ci if (cnt) 18862306a36Sopenharmony_ci xmit |= BT878_I2C_NOSTART; 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ci if (i2c_debug) { 19162306a36Sopenharmony_ci if (!(xmit & BT878_I2C_NOSTART)) 19262306a36Sopenharmony_ci pr_cont(" <R %02x", (msg->addr << 1) +1); 19362306a36Sopenharmony_ci } 19462306a36Sopenharmony_ci 19562306a36Sopenharmony_ci btwrite(xmit, BT848_I2C); 19662306a36Sopenharmony_ci retval = bttv_i2c_wait_done(btv); 19762306a36Sopenharmony_ci if (retval < 0) 19862306a36Sopenharmony_ci goto err; 19962306a36Sopenharmony_ci if (retval == 0) 20062306a36Sopenharmony_ci goto eio; 20162306a36Sopenharmony_ci msg->buf[cnt] = ((u32)btread(BT848_I2C) >> 8) & 0xff; 20262306a36Sopenharmony_ci if (i2c_debug) { 20362306a36Sopenharmony_ci pr_cont(" =%02x", msg->buf[cnt]); 20462306a36Sopenharmony_ci } 20562306a36Sopenharmony_ci if (i2c_debug && !(xmit & BT878_I2C_NOSTOP)) 20662306a36Sopenharmony_ci pr_cont(" >\n"); 20762306a36Sopenharmony_ci } 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_ci 21062306a36Sopenharmony_ci return msg->len; 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_ci eio: 21362306a36Sopenharmony_ci retval = -EIO; 21462306a36Sopenharmony_ci err: 21562306a36Sopenharmony_ci if (i2c_debug) 21662306a36Sopenharmony_ci pr_cont(" ERR: %d\n",retval); 21762306a36Sopenharmony_ci return retval; 21862306a36Sopenharmony_ci} 21962306a36Sopenharmony_ci 22062306a36Sopenharmony_cistatic int bttv_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num) 22162306a36Sopenharmony_ci{ 22262306a36Sopenharmony_ci struct v4l2_device *v4l2_dev = i2c_get_adapdata(i2c_adap); 22362306a36Sopenharmony_ci struct bttv *btv = to_bttv(v4l2_dev); 22462306a36Sopenharmony_ci int retval = 0; 22562306a36Sopenharmony_ci int i; 22662306a36Sopenharmony_ci 22762306a36Sopenharmony_ci if (i2c_debug) 22862306a36Sopenharmony_ci pr_debug("bt-i2c:"); 22962306a36Sopenharmony_ci 23062306a36Sopenharmony_ci btwrite(BT848_INT_I2CDONE|BT848_INT_RACK, BT848_INT_STAT); 23162306a36Sopenharmony_ci for (i = 0 ; i < num; i++) { 23262306a36Sopenharmony_ci if (msgs[i].flags & I2C_M_RD) { 23362306a36Sopenharmony_ci /* read */ 23462306a36Sopenharmony_ci retval = bttv_i2c_readbytes(btv, &msgs[i], i+1 == num); 23562306a36Sopenharmony_ci if (retval < 0) 23662306a36Sopenharmony_ci goto err; 23762306a36Sopenharmony_ci } else { 23862306a36Sopenharmony_ci /* write */ 23962306a36Sopenharmony_ci retval = bttv_i2c_sendbytes(btv, &msgs[i], i+1 == num); 24062306a36Sopenharmony_ci if (retval < 0) 24162306a36Sopenharmony_ci goto err; 24262306a36Sopenharmony_ci } 24362306a36Sopenharmony_ci } 24462306a36Sopenharmony_ci return num; 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_ci err: 24762306a36Sopenharmony_ci return retval; 24862306a36Sopenharmony_ci} 24962306a36Sopenharmony_ci 25062306a36Sopenharmony_cistatic const struct i2c_algorithm bttv_algo = { 25162306a36Sopenharmony_ci .master_xfer = bttv_i2c_xfer, 25262306a36Sopenharmony_ci .functionality = functionality, 25362306a36Sopenharmony_ci}; 25462306a36Sopenharmony_ci 25562306a36Sopenharmony_ci/* ----------------------------------------------------------------------- */ 25662306a36Sopenharmony_ci/* I2C functions - common stuff */ 25762306a36Sopenharmony_ci 25862306a36Sopenharmony_ci/* read I2C */ 25962306a36Sopenharmony_ciint bttv_I2CRead(struct bttv *btv, unsigned char addr, char *probe_for) 26062306a36Sopenharmony_ci{ 26162306a36Sopenharmony_ci unsigned char buffer = 0; 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_ci if (0 != btv->i2c_rc) 26462306a36Sopenharmony_ci return -1; 26562306a36Sopenharmony_ci if (bttv_verbose && NULL != probe_for) 26662306a36Sopenharmony_ci pr_info("%d: i2c: checking for %s @ 0x%02x... ", 26762306a36Sopenharmony_ci btv->c.nr, probe_for, addr); 26862306a36Sopenharmony_ci btv->i2c_client.addr = addr >> 1; 26962306a36Sopenharmony_ci if (1 != i2c_master_recv(&btv->i2c_client, &buffer, 1)) { 27062306a36Sopenharmony_ci if (NULL != probe_for) { 27162306a36Sopenharmony_ci if (bttv_verbose) 27262306a36Sopenharmony_ci pr_cont("not found\n"); 27362306a36Sopenharmony_ci } else 27462306a36Sopenharmony_ci pr_warn("%d: i2c read 0x%x: error\n", 27562306a36Sopenharmony_ci btv->c.nr, addr); 27662306a36Sopenharmony_ci return -1; 27762306a36Sopenharmony_ci } 27862306a36Sopenharmony_ci if (bttv_verbose && NULL != probe_for) 27962306a36Sopenharmony_ci pr_cont("found\n"); 28062306a36Sopenharmony_ci return buffer; 28162306a36Sopenharmony_ci} 28262306a36Sopenharmony_ci 28362306a36Sopenharmony_ci/* write I2C */ 28462306a36Sopenharmony_ciint bttv_I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1, 28562306a36Sopenharmony_ci unsigned char b2, int both) 28662306a36Sopenharmony_ci{ 28762306a36Sopenharmony_ci unsigned char buffer[2]; 28862306a36Sopenharmony_ci int bytes = both ? 2 : 1; 28962306a36Sopenharmony_ci 29062306a36Sopenharmony_ci if (0 != btv->i2c_rc) 29162306a36Sopenharmony_ci return -1; 29262306a36Sopenharmony_ci btv->i2c_client.addr = addr >> 1; 29362306a36Sopenharmony_ci buffer[0] = b1; 29462306a36Sopenharmony_ci buffer[1] = b2; 29562306a36Sopenharmony_ci if (bytes != i2c_master_send(&btv->i2c_client, buffer, bytes)) 29662306a36Sopenharmony_ci return -1; 29762306a36Sopenharmony_ci return 0; 29862306a36Sopenharmony_ci} 29962306a36Sopenharmony_ci 30062306a36Sopenharmony_ci/* read EEPROM content */ 30162306a36Sopenharmony_civoid bttv_readee(struct bttv *btv, unsigned char *eedata, int addr) 30262306a36Sopenharmony_ci{ 30362306a36Sopenharmony_ci memset(eedata, 0, 256); 30462306a36Sopenharmony_ci if (0 != btv->i2c_rc) 30562306a36Sopenharmony_ci return; 30662306a36Sopenharmony_ci btv->i2c_client.addr = addr >> 1; 30762306a36Sopenharmony_ci tveeprom_read(&btv->i2c_client, eedata, 256); 30862306a36Sopenharmony_ci} 30962306a36Sopenharmony_ci 31062306a36Sopenharmony_cistatic char *i2c_devs[128] = { 31162306a36Sopenharmony_ci [ 0x1c >> 1 ] = "lgdt330x", 31262306a36Sopenharmony_ci [ 0x30 >> 1 ] = "IR (hauppauge)", 31362306a36Sopenharmony_ci [ 0x80 >> 1 ] = "msp34xx", 31462306a36Sopenharmony_ci [ 0x86 >> 1 ] = "tda9887", 31562306a36Sopenharmony_ci [ 0xa0 >> 1 ] = "eeprom", 31662306a36Sopenharmony_ci [ 0xc0 >> 1 ] = "tuner (analog)", 31762306a36Sopenharmony_ci [ 0xc2 >> 1 ] = "tuner (analog)", 31862306a36Sopenharmony_ci}; 31962306a36Sopenharmony_ci 32062306a36Sopenharmony_cistatic void do_i2c_scan(char *name, struct i2c_client *c) 32162306a36Sopenharmony_ci{ 32262306a36Sopenharmony_ci unsigned char buf; 32362306a36Sopenharmony_ci int i,rc; 32462306a36Sopenharmony_ci 32562306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(i2c_devs); i++) { 32662306a36Sopenharmony_ci c->addr = i; 32762306a36Sopenharmony_ci rc = i2c_master_recv(c,&buf,0); 32862306a36Sopenharmony_ci if (rc < 0) 32962306a36Sopenharmony_ci continue; 33062306a36Sopenharmony_ci pr_info("%s: i2c scan: found device @ 0x%x [%s]\n", 33162306a36Sopenharmony_ci name, i << 1, i2c_devs[i] ? i2c_devs[i] : "???"); 33262306a36Sopenharmony_ci } 33362306a36Sopenharmony_ci} 33462306a36Sopenharmony_ci 33562306a36Sopenharmony_ci/* init + register i2c adapter */ 33662306a36Sopenharmony_ciint init_bttv_i2c(struct bttv *btv) 33762306a36Sopenharmony_ci{ 33862306a36Sopenharmony_ci strscpy(btv->i2c_client.name, "bttv internal", I2C_NAME_SIZE); 33962306a36Sopenharmony_ci 34062306a36Sopenharmony_ci if (i2c_hw) 34162306a36Sopenharmony_ci btv->use_i2c_hw = 1; 34262306a36Sopenharmony_ci if (btv->use_i2c_hw) { 34362306a36Sopenharmony_ci /* bt878 */ 34462306a36Sopenharmony_ci strscpy(btv->c.i2c_adap.name, "bt878", 34562306a36Sopenharmony_ci sizeof(btv->c.i2c_adap.name)); 34662306a36Sopenharmony_ci btv->c.i2c_adap.algo = &bttv_algo; 34762306a36Sopenharmony_ci } else { 34862306a36Sopenharmony_ci /* bt848 */ 34962306a36Sopenharmony_ci /* Prevents usage of invalid delay values */ 35062306a36Sopenharmony_ci if (i2c_udelay<5) 35162306a36Sopenharmony_ci i2c_udelay=5; 35262306a36Sopenharmony_ci 35362306a36Sopenharmony_ci strscpy(btv->c.i2c_adap.name, "bttv", 35462306a36Sopenharmony_ci sizeof(btv->c.i2c_adap.name)); 35562306a36Sopenharmony_ci btv->i2c_algo = bttv_i2c_algo_bit_template; 35662306a36Sopenharmony_ci btv->i2c_algo.udelay = i2c_udelay; 35762306a36Sopenharmony_ci btv->i2c_algo.data = btv; 35862306a36Sopenharmony_ci btv->c.i2c_adap.algo_data = &btv->i2c_algo; 35962306a36Sopenharmony_ci } 36062306a36Sopenharmony_ci btv->c.i2c_adap.owner = THIS_MODULE; 36162306a36Sopenharmony_ci 36262306a36Sopenharmony_ci btv->c.i2c_adap.dev.parent = &btv->c.pci->dev; 36362306a36Sopenharmony_ci snprintf(btv->c.i2c_adap.name, sizeof(btv->c.i2c_adap.name), 36462306a36Sopenharmony_ci "bt%d #%d [%s]", btv->id, btv->c.nr, 36562306a36Sopenharmony_ci btv->use_i2c_hw ? "hw" : "sw"); 36662306a36Sopenharmony_ci 36762306a36Sopenharmony_ci i2c_set_adapdata(&btv->c.i2c_adap, &btv->c.v4l2_dev); 36862306a36Sopenharmony_ci btv->i2c_client.adapter = &btv->c.i2c_adap; 36962306a36Sopenharmony_ci 37062306a36Sopenharmony_ci 37162306a36Sopenharmony_ci if (btv->use_i2c_hw) { 37262306a36Sopenharmony_ci btv->i2c_rc = i2c_add_adapter(&btv->c.i2c_adap); 37362306a36Sopenharmony_ci } else { 37462306a36Sopenharmony_ci bttv_bit_setscl(btv,1); 37562306a36Sopenharmony_ci bttv_bit_setsda(btv,1); 37662306a36Sopenharmony_ci btv->i2c_rc = i2c_bit_add_bus(&btv->c.i2c_adap); 37762306a36Sopenharmony_ci } 37862306a36Sopenharmony_ci if (0 == btv->i2c_rc && i2c_scan) 37962306a36Sopenharmony_ci do_i2c_scan(btv->c.v4l2_dev.name, &btv->i2c_client); 38062306a36Sopenharmony_ci 38162306a36Sopenharmony_ci return btv->i2c_rc; 38262306a36Sopenharmony_ci} 38362306a36Sopenharmony_ci 38462306a36Sopenharmony_ciint fini_bttv_i2c(struct bttv *btv) 38562306a36Sopenharmony_ci{ 38662306a36Sopenharmony_ci if (btv->i2c_rc == 0) 38762306a36Sopenharmony_ci i2c_del_adapter(&btv->c.i2c_adap); 38862306a36Sopenharmony_ci 38962306a36Sopenharmony_ci return 0; 39062306a36Sopenharmony_ci} 391