brintos

brintos / linux-shallow public Read only

0
0
Text · 8.9 KiB · 4a8a3f8 Raw
391 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 4    bttv-i2c.c  --  all the i2c code is here5 6    bttv - Bt848 frame grabber driver7 8    Copyright (C) 1996,97,98 Ralph  Metzler (rjkm@thp.uni-koeln.de)9			   & Marcus Metzler (mocm@thp.uni-koeln.de)10    (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org>11 12    (c) 2005 Mauro Carvalho Chehab <mchehab@kernel.org>13	- Multituner support and i2c address binding14 15 16*/17 18#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt19 20#include <linux/module.h>21#include <linux/init.h>22#include <linux/delay.h>23 24#include "bttvp.h"25#include <media/v4l2-common.h>26#include <linux/jiffies.h>27#include <asm/io.h>28 29static int i2c_debug;30static int i2c_hw;31static int i2c_scan;32module_param(i2c_debug, int, 0644);33MODULE_PARM_DESC(i2c_debug, "configure i2c debug level");34module_param(i2c_hw,    int, 0444);35MODULE_PARM_DESC(i2c_hw, "force use of hardware i2c support, instead of software bitbang");36module_param(i2c_scan,  int, 0444);37MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time");38 39static unsigned int i2c_udelay = 5;40module_param(i2c_udelay, int, 0444);41MODULE_PARM_DESC(i2c_udelay, "soft i2c delay at insmod time, in usecs (should be 5 or higher). Lower value means higher bus speed.");42 43/* ----------------------------------------------------------------------- */44/* I2C functions - bitbanging adapter (software i2c)                       */45 46static void bttv_bit_setscl(void *data, int state)47{48	struct bttv *btv = (struct bttv*)data;49 50	if (state)51		btv->i2c_state |= 0x02;52	else53		btv->i2c_state &= ~0x02;54	btwrite(btv->i2c_state, BT848_I2C);55	btread(BT848_I2C);56}57 58static void bttv_bit_setsda(void *data, int state)59{60	struct bttv *btv = (struct bttv*)data;61 62	if (state)63		btv->i2c_state |= 0x01;64	else65		btv->i2c_state &= ~0x01;66	btwrite(btv->i2c_state, BT848_I2C);67	btread(BT848_I2C);68}69 70static int bttv_bit_getscl(void *data)71{72	struct bttv *btv = (struct bttv*)data;73	int state;74 75	state = btread(BT848_I2C) & 0x02 ? 1 : 0;76	return state;77}78 79static int bttv_bit_getsda(void *data)80{81	struct bttv *btv = (struct bttv*)data;82	int state;83 84	state = btread(BT848_I2C) & 0x01;85	return state;86}87 88static const struct i2c_algo_bit_data bttv_i2c_algo_bit_template = {89	.setsda  = bttv_bit_setsda,90	.setscl  = bttv_bit_setscl,91	.getsda  = bttv_bit_getsda,92	.getscl  = bttv_bit_getscl,93	.udelay  = 16,94	.timeout = 200,95};96 97/* ----------------------------------------------------------------------- */98/* I2C functions - hardware i2c                                            */99 100static u32 functionality(struct i2c_adapter *adap)101{102	return I2C_FUNC_SMBUS_EMUL;103}104 105static int106bttv_i2c_wait_done(struct bttv *btv)107{108	int rc = 0;109 110	/* timeout */111	if (wait_event_interruptible_timeout(btv->i2c_queue,112	    btv->i2c_done, msecs_to_jiffies(85)) == -ERESTARTSYS)113		rc = -EIO;114 115	if (btv->i2c_done & BT848_INT_RACK)116		rc = 1;117	btv->i2c_done = 0;118	return rc;119}120 121#define I2C_HW (BT878_I2C_MODE  | BT848_I2C_SYNC |\122		BT848_I2C_SCL | BT848_I2C_SDA)123 124static int125bttv_i2c_sendbytes(struct bttv *btv, const struct i2c_msg *msg, int last)126{127	u32 xmit;128	int retval,cnt;129 130	/* sanity checks */131	if (0 == msg->len)132		return -EINVAL;133 134	/* start, address + first byte */135	xmit = (msg->addr << 25) | (msg->buf[0] << 16) | I2C_HW;136	if (msg->len > 1 || !last)137		xmit |= BT878_I2C_NOSTOP;138	btwrite(xmit, BT848_I2C);139	retval = bttv_i2c_wait_done(btv);140	if (retval < 0)141		goto err;142	if (retval == 0)143		goto eio;144	if (i2c_debug) {145		pr_cont(" <W %02x %02x", msg->addr << 1, msg->buf[0]);146	}147 148	for (cnt = 1; cnt < msg->len; cnt++ ) {149		/* following bytes */150		xmit = (msg->buf[cnt] << 24) | I2C_HW | BT878_I2C_NOSTART;151		if (cnt < msg->len-1 || !last)152			xmit |= BT878_I2C_NOSTOP;153		btwrite(xmit, BT848_I2C);154		retval = bttv_i2c_wait_done(btv);155		if (retval < 0)156			goto err;157		if (retval == 0)158			goto eio;159		if (i2c_debug)160			pr_cont(" %02x", msg->buf[cnt]);161	}162	if (i2c_debug && !(xmit & BT878_I2C_NOSTOP))163		pr_cont(">\n");164	return msg->len;165 166 eio:167	retval = -EIO;168 err:169	if (i2c_debug)170		pr_cont(" ERR: %d\n",retval);171	return retval;172}173 174static int175bttv_i2c_readbytes(struct bttv *btv, const struct i2c_msg *msg, int last)176{177	u32 xmit;178	u32 cnt;179	int retval;180 181	for (cnt = 0; cnt < msg->len; cnt++) {182		xmit = (msg->addr << 25) | (1 << 24) | I2C_HW;183		if (cnt < msg->len-1)184			xmit |= BT848_I2C_W3B;185		if (cnt < msg->len-1 || !last)186			xmit |= BT878_I2C_NOSTOP;187		if (cnt)188			xmit |= BT878_I2C_NOSTART;189 190		if (i2c_debug) {191			if (!(xmit & BT878_I2C_NOSTART))192				pr_cont(" <R %02x", (msg->addr << 1) +1);193		}194 195		btwrite(xmit, BT848_I2C);196		retval = bttv_i2c_wait_done(btv);197		if (retval < 0)198			goto err;199		if (retval == 0)200			goto eio;201		msg->buf[cnt] = ((u32)btread(BT848_I2C) >> 8) & 0xff;202		if (i2c_debug) {203			pr_cont(" =%02x", msg->buf[cnt]);204		}205		if (i2c_debug && !(xmit & BT878_I2C_NOSTOP))206			pr_cont(" >\n");207	}208 209 210	return msg->len;211 212 eio:213	retval = -EIO;214 err:215	if (i2c_debug)216		pr_cont(" ERR: %d\n",retval);217	return retval;218}219 220static int bttv_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)221{222	struct v4l2_device *v4l2_dev = i2c_get_adapdata(i2c_adap);223	struct bttv *btv = to_bttv(v4l2_dev);224	int retval = 0;225	int i;226 227	if (i2c_debug)228		pr_debug("bt-i2c:");229 230	btwrite(BT848_INT_I2CDONE|BT848_INT_RACK, BT848_INT_STAT);231	for (i = 0 ; i < num; i++) {232		if (msgs[i].flags & I2C_M_RD) {233			/* read */234			retval = bttv_i2c_readbytes(btv, &msgs[i], i+1 == num);235			if (retval < 0)236				goto err;237		} else {238			/* write */239			retval = bttv_i2c_sendbytes(btv, &msgs[i], i+1 == num);240			if (retval < 0)241				goto err;242		}243	}244	return num;245 246 err:247	return retval;248}249 250static const struct i2c_algorithm bttv_algo = {251	.master_xfer   = bttv_i2c_xfer,252	.functionality = functionality,253};254 255/* ----------------------------------------------------------------------- */256/* I2C functions - common stuff                                            */257 258/* read I2C */259int bttv_I2CRead(struct bttv *btv, unsigned char addr, char *probe_for)260{261	unsigned char buffer = 0;262 263	if (0 != btv->i2c_rc)264		return -1;265	if (bttv_verbose && NULL != probe_for)266		pr_info("%d: i2c: checking for %s @ 0x%02x... ",267			btv->c.nr, probe_for, addr);268	btv->i2c_client.addr = addr >> 1;269	if (1 != i2c_master_recv(&btv->i2c_client, &buffer, 1)) {270		if (NULL != probe_for) {271			if (bttv_verbose)272				pr_cont("not found\n");273		} else274			pr_warn("%d: i2c read 0x%x: error\n",275				btv->c.nr, addr);276		return -1;277	}278	if (bttv_verbose && NULL != probe_for)279		pr_cont("found\n");280	return buffer;281}282 283/* write I2C */284int bttv_I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1,285		    unsigned char b2, int both)286{287	unsigned char buffer[2];288	int bytes = both ? 2 : 1;289 290	if (0 != btv->i2c_rc)291		return -1;292	btv->i2c_client.addr = addr >> 1;293	buffer[0] = b1;294	buffer[1] = b2;295	if (bytes != i2c_master_send(&btv->i2c_client, buffer, bytes))296		return -1;297	return 0;298}299 300/* read EEPROM content */301void bttv_readee(struct bttv *btv, unsigned char *eedata, int addr)302{303	memset(eedata, 0, 256);304	if (0 != btv->i2c_rc)305		return;306	btv->i2c_client.addr = addr >> 1;307	tveeprom_read(&btv->i2c_client, eedata, 256);308}309 310static char *i2c_devs[128] = {311	[ 0x1c >> 1 ] = "lgdt330x",312	[ 0x30 >> 1 ] = "IR (hauppauge)",313	[ 0x80 >> 1 ] = "msp34xx",314	[ 0x86 >> 1 ] = "tda9887",315	[ 0xa0 >> 1 ] = "eeprom",316	[ 0xc0 >> 1 ] = "tuner (analog)",317	[ 0xc2 >> 1 ] = "tuner (analog)",318};319 320static void do_i2c_scan(char *name, struct i2c_client *c)321{322	unsigned char buf;323	int i,rc;324 325	for (i = 0; i < ARRAY_SIZE(i2c_devs); i++) {326		c->addr = i;327		rc = i2c_master_recv(c,&buf,0);328		if (rc < 0)329			continue;330		pr_info("%s: i2c scan: found device @ 0x%x  [%s]\n",331			name, i << 1, i2c_devs[i] ? i2c_devs[i] : "???");332	}333}334 335/* init + register i2c adapter */336int init_bttv_i2c(struct bttv *btv)337{338	strscpy(btv->i2c_client.name, "bttv internal", I2C_NAME_SIZE);339 340	if (i2c_hw)341		btv->use_i2c_hw = 1;342	if (btv->use_i2c_hw) {343		/* bt878 */344		strscpy(btv->c.i2c_adap.name, "bt878",345			sizeof(btv->c.i2c_adap.name));346		btv->c.i2c_adap.algo = &bttv_algo;347	} else {348		/* bt848 */349	/* Prevents usage of invalid delay values */350		if (i2c_udelay<5)351			i2c_udelay=5;352 353		strscpy(btv->c.i2c_adap.name, "bttv",354			sizeof(btv->c.i2c_adap.name));355		btv->i2c_algo = bttv_i2c_algo_bit_template;356		btv->i2c_algo.udelay = i2c_udelay;357		btv->i2c_algo.data = btv;358		btv->c.i2c_adap.algo_data = &btv->i2c_algo;359	}360	btv->c.i2c_adap.owner = THIS_MODULE;361 362	btv->c.i2c_adap.dev.parent = &btv->c.pci->dev;363	snprintf(btv->c.i2c_adap.name, sizeof(btv->c.i2c_adap.name),364		 "bt%d #%d [%s]", btv->id, btv->c.nr,365		 btv->use_i2c_hw ? "hw" : "sw");366 367	i2c_set_adapdata(&btv->c.i2c_adap, &btv->c.v4l2_dev);368	btv->i2c_client.adapter = &btv->c.i2c_adap;369 370 371	if (btv->use_i2c_hw) {372		btv->i2c_rc = i2c_add_adapter(&btv->c.i2c_adap);373	} else {374		bttv_bit_setscl(btv,1);375		bttv_bit_setsda(btv,1);376		btv->i2c_rc = i2c_bit_add_bus(&btv->c.i2c_adap);377	}378	if (0 == btv->i2c_rc && i2c_scan)379		do_i2c_scan(btv->c.v4l2_dev.name, &btv->i2c_client);380 381	return btv->i2c_rc;382}383 384int fini_bttv_i2c(struct bttv *btv)385{386	if (btv->i2c_rc == 0)387		i2c_del_adapter(&btv->c.i2c_adap);388 389	return 0;390}391