Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit db8a6956 authored by Michael Krufky's avatar Michael Krufky Committed by Mauro Carvalho Chehab
Browse files

V4L/DVB (6127): tuner: kill i2c_client interface to tuner sub-drivers



To ease the conversion of the analog tuner sub-drivers into dvb_frontend
style tuner modules, we must remove the i2c_client interface.

dvb_frontend style tuner modules use i2c_transfer directly on the i2c_adapter.

This change only alters the interface between tuner.ko and the tuner
sub-drivers. The v4l2 / i2c_client interface to tuner.ko remains intact.

This patch adds inline functions tuner_i2c_xfer_send, and tuner_i2c_xfer_recv,
to replace i2c_master_send and i2c_master_recv inside the tuner sub-drivers.

Signed-off-by: default avatarMichael Krufky <mkrufky@linuxtv.org>
Acked-by: default avatarHans Verkuil <hverkuil@xs4all.nl>
Acked-by: default avatarMike Isely <isely@pobox.com>
Acked-by: default avatarSteven Toth <stoth@hauppauge.com>
Acked-by: default avatarPatrick Boettcher <pb@linuxtv.org>
Acked-by: default avatarJarod Wilson <jwilson@redhat.com>
Acked-by: default avatarTrent Piepho <xyzzy@speakeasy.org>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@infradead.org>
parent 293197cd
Loading
Loading
Loading
Loading
+66 −72
Original line number Diff line number Diff line
@@ -37,23 +37,22 @@ static char *microtune_part[] = {
};

struct microtune_priv {
	struct tuner_i2c_props i2c_props;

	unsigned int xogc;
	unsigned int radio_if2;
};

static void microtune_release(struct i2c_client *c)
static void microtune_release(struct tuner *t)
{
	struct tuner *t = i2c_get_clientdata(c);

	kfree(t->priv);
	t->priv = NULL;
}

// IsSpurInBand()?
static int mt2032_spurcheck(struct i2c_client *c,
static int mt2032_spurcheck(struct tuner *t,
			    int f1, int f2, int spectrum_from,int spectrum_to)
{
	struct tuner *t = i2c_get_clientdata(c);
	int n1=1,n2,f;

	f1=f1/1000; //scale to kHz to avoid 32bit overflows
@@ -81,7 +80,7 @@ static int mt2032_spurcheck(struct i2c_client *c,
	return 1;
}

static int mt2032_compute_freq(struct i2c_client *c,
static int mt2032_compute_freq(struct tuner *t,
			       unsigned int rfin,
			       unsigned int if1, unsigned int if2,
			       unsigned int spectrum_from,
@@ -90,7 +89,6 @@ static int mt2032_compute_freq(struct i2c_client *c,
			       int *ret_sel,
			       unsigned int xogc) //all in Hz
{
	struct tuner *t = i2c_get_clientdata(c);
	unsigned int fref,lo1,lo1n,lo1a,s,sel,lo1freq, desired_lo1,
		desired_lo2,lo2,lo2n,lo2a,lo2num,lo2freq;

@@ -140,7 +138,7 @@ static int mt2032_compute_freq(struct i2c_client *c,
		return(-1);
	}

	mt2032_spurcheck(c, lo1freq, desired_lo2,  spectrum_from, spectrum_to);
	mt2032_spurcheck(t, lo1freq, desired_lo2,  spectrum_from, spectrum_to);
	// should recalculate lo1 (one step up/down)

	// set up MT2032 register map for transfer over i2c
@@ -164,16 +162,16 @@ static int mt2032_compute_freq(struct i2c_client *c,
	return 0;
}

static int mt2032_check_lo_lock(struct i2c_client *c)
static int mt2032_check_lo_lock(struct tuner *t)
{
	struct tuner *t = i2c_get_clientdata(c);
	struct microtune_priv *priv = t->priv;
	int try,lock=0;
	unsigned char buf[2];

	for(try=0;try<10;try++) {
		buf[0]=0x0e;
		i2c_master_send(c,buf,1);
		i2c_master_recv(c,buf,1);
		tuner_i2c_xfer_send(&priv->i2c_props,buf,1);
		tuner_i2c_xfer_recv(&priv->i2c_props,buf,1);
		tuner_dbg("mt2032 Reg.E=0x%02x\n",buf[0]);
		lock=buf[0] &0x06;

@@ -186,15 +184,15 @@ static int mt2032_check_lo_lock(struct i2c_client *c)
	return lock;
}

static int mt2032_optimize_vco(struct i2c_client *c,int sel,int lock)
static int mt2032_optimize_vco(struct tuner *t,int sel,int lock)
{
	struct tuner *t = i2c_get_clientdata(c);
	struct microtune_priv *priv = t->priv;
	unsigned char buf[2];
	int tad1;

	buf[0]=0x0f;
	i2c_master_send(c,buf,1);
	i2c_master_recv(c,buf,1);
	tuner_i2c_xfer_send(&priv->i2c_props,buf,1);
	tuner_i2c_xfer_recv(&priv->i2c_props,buf,1);
	tuner_dbg("mt2032 Reg.F=0x%02x\n",buf[0]);
	tad1=buf[0]&0x07;

@@ -217,58 +215,57 @@ static int mt2032_optimize_vco(struct i2c_client *c,int sel,int lock)

	buf[0]=0x0f;
	buf[1]=sel;
	i2c_master_send(c,buf,2);
	lock=mt2032_check_lo_lock(c);
	tuner_i2c_xfer_send(&priv->i2c_props,buf,2);
	lock=mt2032_check_lo_lock(t);
	return lock;
}


static void mt2032_set_if_freq(struct i2c_client *c, unsigned int rfin,
static void mt2032_set_if_freq(struct tuner *t, unsigned int rfin,
			       unsigned int if1, unsigned int if2,
			       unsigned int from, unsigned int to)
{
	unsigned char buf[21];
	int lint_try,ret,sel,lock=0;
	struct tuner *t = i2c_get_clientdata(c);
	struct microtune_priv *priv = t->priv;

	tuner_dbg("mt2032_set_if_freq rfin=%d if1=%d if2=%d from=%d to=%d\n",
		  rfin,if1,if2,from,to);

	buf[0]=0;
	ret=i2c_master_send(c,buf,1);
	i2c_master_recv(c,buf,21);
	ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,1);
	tuner_i2c_xfer_recv(&priv->i2c_props,buf,21);

	buf[0]=0;
	ret=mt2032_compute_freq(c,rfin,if1,if2,from,to,&buf[1],&sel,priv->xogc);
	ret=mt2032_compute_freq(t,rfin,if1,if2,from,to,&buf[1],&sel,priv->xogc);
	if (ret<0)
		return;

	// send only the relevant registers per Rev. 1.2
	buf[0]=0;
	ret=i2c_master_send(c,buf,4);
	ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,4);
	buf[5]=5;
	ret=i2c_master_send(c,buf+5,4);
	ret=tuner_i2c_xfer_send(&priv->i2c_props,buf+5,4);
	buf[11]=11;
	ret=i2c_master_send(c,buf+11,3);
	ret=tuner_i2c_xfer_send(&priv->i2c_props,buf+11,3);
	if(ret!=3)
		tuner_warn("i2c i/o error: rc == %d (should be 3)\n",ret);

	// wait for PLLs to lock (per manual), retry LINT if not.
	for(lint_try=0; lint_try<2; lint_try++) {
		lock=mt2032_check_lo_lock(c);
		lock=mt2032_check_lo_lock(t);

		if(optimize_vco)
			lock=mt2032_optimize_vco(c,sel,lock);
			lock=mt2032_optimize_vco(t,sel,lock);
		if(lock==6) break;

		tuner_dbg("mt2032: re-init PLLs by LINT\n");
		buf[0]=7;
		buf[1]=0x80 +8+priv->xogc; // set LINT to re-init PLLs
		i2c_master_send(c,buf,2);
		tuner_i2c_xfer_send(&priv->i2c_props,buf,2);
		mdelay(10);
		buf[1]=8+priv->xogc;
		i2c_master_send(c,buf,2);
		tuner_i2c_xfer_send(&priv->i2c_props,buf,2);
	}

	if (lock!=6)
@@ -276,15 +273,14 @@ static void mt2032_set_if_freq(struct i2c_client *c, unsigned int rfin,

	buf[0]=2;
	buf[1]=0x20; // LOGC for optimal phase noise
	ret=i2c_master_send(c,buf,2);
	ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,2);
	if (ret!=2)
		tuner_warn("i2c i/o error: rc == %d (should be 2)\n",ret);
}


static void mt2032_set_tv_freq(struct i2c_client *c, unsigned int freq)
static void mt2032_set_tv_freq(struct tuner *t, unsigned int freq)
{
	struct tuner *t = i2c_get_clientdata(c);
	int if2,from,to;

	// signal bandwidth and picture carrier
@@ -300,18 +296,17 @@ static void mt2032_set_tv_freq(struct i2c_client *c, unsigned int freq)
		if2  = 38900*1000;
	}

	mt2032_set_if_freq(c, freq*62500 /* freq*1000*1000/16 */,
	mt2032_set_if_freq(t, freq*62500 /* freq*1000*1000/16 */,
			   1090*1000*1000, if2, from, to);
}

static void mt2032_set_radio_freq(struct i2c_client *c, unsigned int freq)
static void mt2032_set_radio_freq(struct tuner *t, unsigned int freq)
{
	struct tuner *t = i2c_get_clientdata(c);
	struct microtune_priv *priv = t->priv;
	int if2 = priv->radio_if2;

	// per Manual for FM tuning: first if center freq. 1085 MHz
	mt2032_set_if_freq(c, freq * 1000 / 16,
	mt2032_set_if_freq(t, freq * 1000 / 16,
			      1085*1000*1000,if2,if2,if2);
}

@@ -322,9 +317,8 @@ static struct tuner_operations mt2032_tuner_ops = {
};

// Initalization as described in "MT203x Programming Procedures", Rev 1.2, Feb.2001
static int mt2032_init(struct i2c_client *c)
static int mt2032_init(struct tuner *t)
{
	struct tuner *t = i2c_get_clientdata(c);
	struct microtune_priv *priv = t->priv;
	unsigned char buf[21];
	int ret,xogc,xok=0;
@@ -334,7 +328,7 @@ static int mt2032_init(struct i2c_client *c)
	buf[2]=0xff;
	buf[3]=0x0f;
	buf[4]=0x1f;
	ret=i2c_master_send(c,buf+1,4);
	ret=tuner_i2c_xfer_send(&priv->i2c_props,buf+1,4);

	buf[5]=6; // Index register 6
	buf[6]=0xe4;
@@ -342,11 +336,11 @@ static int mt2032_init(struct i2c_client *c)
	buf[8]=0xc3;
	buf[9]=0x4e;
	buf[10]=0xec;
	ret=i2c_master_send(c,buf+5,6);
	ret=tuner_i2c_xfer_send(&priv->i2c_props,buf+5,6);

	buf[12]=13;  // Index register 13
	buf[13]=0x32;
	ret=i2c_master_send(c,buf+12,2);
	ret=tuner_i2c_xfer_send(&priv->i2c_props,buf+12,2);

	// Adjust XOGC (register 7), wait for XOK
	xogc=7;
@@ -354,8 +348,8 @@ static int mt2032_init(struct i2c_client *c)
		tuner_dbg("mt2032: xogc = 0x%02x\n",xogc&0x07);
		mdelay(10);
		buf[0]=0x0e;
		i2c_master_send(c,buf,1);
		i2c_master_recv(c,buf,1);
		tuner_i2c_xfer_send(&priv->i2c_props,buf,1);
		tuner_i2c_xfer_recv(&priv->i2c_props,buf,1);
		xok=buf[0]&0x01;
		tuner_dbg("mt2032: xok = 0x%02x\n",xok);
		if (xok == 1) break;
@@ -368,7 +362,7 @@ static int mt2032_init(struct i2c_client *c)
		}
		buf[0]=0x07;
		buf[1]=0x88 + xogc;
		ret=i2c_master_send(c,buf,2);
		ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,2);
		if (ret!=2)
			tuner_warn("i2c i/o error: rc == %d (should be 2)\n",ret);
	} while (xok != 1 );
@@ -379,21 +373,21 @@ static int mt2032_init(struct i2c_client *c)
	return(1);
}

static void mt2050_set_antenna(struct i2c_client *c, unsigned char antenna)
static void mt2050_set_antenna(struct tuner *t, unsigned char antenna)
{
	struct tuner *t = i2c_get_clientdata(c);
	struct microtune_priv *priv = t->priv;
	unsigned char buf[2];
	int ret;

	buf[0] = 6;
	buf[1] = antenna ? 0x11 : 0x10;
	ret=i2c_master_send(c,buf,2);
	ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,2);
	tuner_dbg("mt2050: enabled antenna connector %d\n", antenna);
}

static void mt2050_set_if_freq(struct i2c_client *c,unsigned int freq, unsigned int if2)
static void mt2050_set_if_freq(struct tuner *t,unsigned int freq, unsigned int if2)
{
	struct tuner *t = i2c_get_clientdata(c);
	struct microtune_priv *priv = t->priv;
	unsigned int if1=1218*1000*1000;
	unsigned int f_lo1,f_lo2,lo1,lo2,f_lo1_modulo,f_lo2_modulo,num1,num2,div1a,div1b,div2a,div2b;
	int ret;
@@ -449,14 +443,13 @@ static void mt2050_set_if_freq(struct i2c_client *c,unsigned int freq, unsigned
		printk("\n");
	}

	ret=i2c_master_send(c,buf,6);
	ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,6);
	if (ret!=6)
		tuner_warn("i2c i/o error: rc == %d (should be 6)\n",ret);
}

static void mt2050_set_tv_freq(struct i2c_client *c, unsigned int freq)
static void mt2050_set_tv_freq(struct tuner *t, unsigned int freq)
{
	struct tuner *t = i2c_get_clientdata(c);
	unsigned int if2;

	if (t->std & V4L2_STD_525_60) {
@@ -470,18 +463,17 @@ static void mt2050_set_tv_freq(struct i2c_client *c, unsigned int freq)
		// DVB (pinnacle 300i)
		if2 = 36150*1000;
	}
	mt2050_set_if_freq(c, freq*62500, if2);
	mt2050_set_antenna(c, tv_antenna);
	mt2050_set_if_freq(t, freq*62500, if2);
	mt2050_set_antenna(t, tv_antenna);
}

static void mt2050_set_radio_freq(struct i2c_client *c, unsigned int freq)
static void mt2050_set_radio_freq(struct tuner *t, unsigned int freq)
{
	struct tuner *t = i2c_get_clientdata(c);
	struct microtune_priv *priv = t->priv;
	int if2 = priv->radio_if2;

	mt2050_set_if_freq(c, freq * 1000 / 16, if2);
	mt2050_set_antenna(c, radio_antenna);
	mt2050_set_if_freq(t, freq * 1000 / 16, if2);
	mt2050_set_antenna(t, radio_antenna);
}

static struct tuner_operations mt2050_tuner_ops = {
@@ -490,23 +482,23 @@ static struct tuner_operations mt2050_tuner_ops = {
	.release        = microtune_release,
};

static int mt2050_init(struct i2c_client *c)
static int mt2050_init(struct tuner *t)
{
	struct tuner *t = i2c_get_clientdata(c);
	struct microtune_priv *priv = t->priv;
	unsigned char buf[2];
	int ret;

	buf[0]=6;
	buf[1]=0x10;
	ret=i2c_master_send(c,buf,2); //  power
	ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,2); //  power

	buf[0]=0x0f;
	buf[1]=0x0f;
	ret=i2c_master_send(c,buf,2); // m1lo
	ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,2); // m1lo

	buf[0]=0x0d;
	ret=i2c_master_send(c,buf,1);
	i2c_master_recv(c,buf,1);
	ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,1);
	tuner_i2c_xfer_recv(&priv->i2c_props,buf,1);

	tuner_dbg("mt2050: sro is %x\n",buf[0]);

@@ -515,10 +507,9 @@ static int mt2050_init(struct i2c_client *c)
	return 0;
}

int microtune_init(struct i2c_client *c)
int microtune_init(struct tuner *t)
{
	struct microtune_priv *priv = NULL;
	struct tuner *t = i2c_get_clientdata(c);
	char *name;
	unsigned char buf[21];
	int company_code;
@@ -528,6 +519,9 @@ int microtune_init(struct i2c_client *c)
		return -ENOMEM;
	t->priv = priv;

	priv->i2c_props.addr = t->i2c.addr;
	priv->i2c_props.adap = t->i2c.adapter;

	priv->radio_if2 = 10700 * 1000;	/* 10.7MHz - FM radio */

	memset(buf,0,sizeof(buf));
@@ -541,8 +535,8 @@ int microtune_init(struct i2c_client *c)
	}
	name = "unknown";

	i2c_master_send(c,buf,1);
	i2c_master_recv(c,buf,21);
	tuner_i2c_xfer_send(&priv->i2c_props,buf,1);
	tuner_i2c_xfer_recv(&priv->i2c_props,buf,21);
	if (tuner_debug) {
		int i;
		tuner_dbg("MT20xx hexdump:");
@@ -562,10 +556,10 @@ int microtune_init(struct i2c_client *c)
		name = microtune_part[buf[0x13]];
	switch (buf[0x13]) {
	case MT2032:
		mt2032_init(c);
		mt2032_init(t);
		break;
	case MT2050:
		mt2050_init(c);
		mt2050_init(t);
		break;
	default:
		tuner_info("microtune %s found, not (yet?) supported, sorry :-/\n",
@@ -573,7 +567,7 @@ int microtune_init(struct i2c_client *c)
		return 0;
	}

	strlcpy(c->name, name, sizeof(c->name));
	strlcpy(t->i2c.name, name, sizeof(t->i2c.name));
	tuner_info("microtune %s found, OK\n",name);
	return 0;
}
+124 −123

File changed.

Preview size limit exceeded, changes collapsed.

+20 −19
Original line number Diff line number Diff line
@@ -29,6 +29,8 @@
			i2c_adapter_id(t->i2c.adapter), t->i2c.addr , ##arg); } while (0)

struct tda9887_priv {
	struct tuner_i2c_props i2c_props;

	unsigned char 	   data[4];
};

@@ -510,19 +512,19 @@ static int tda9887_set_config(struct tuner *t, char *buf)

static int tda9887_status(struct tuner *t)
{
	struct tda9887_priv *priv = t->priv;
	unsigned char buf[1];
	int rc;

	memset(buf,0,sizeof(buf));
	if (1 != (rc = i2c_master_recv(&t->i2c,buf,1)))
	if (1 != (rc = tuner_i2c_xfer_recv(&priv->i2c_props,buf,1)))
		tda9887_info("i2c i/o error: rc == %d (should be 1)\n",rc);
	dump_read_message(t, buf);
	return 0;
}

static void tda9887_configure(struct i2c_client *client)
static void tda9887_configure(struct tuner *t)
{
	struct tuner *t = i2c_get_clientdata(client);
	struct tda9887_priv *priv = t->priv;
	int rc;

@@ -557,7 +559,7 @@ static void tda9887_configure(struct i2c_client *client)
	if (tuner_debug > 1)
		dump_write_message(t, priv->data);

	if (4 != (rc = i2c_master_send(&t->i2c,priv->data,4)))
	if (4 != (rc = tuner_i2c_xfer_send(&priv->i2c_props,priv->data,4)))
		tda9887_info("i2c i/o error: rc == %d (should be 4)\n",rc);

	if (tuner_debug > 2) {
@@ -568,16 +570,15 @@ static void tda9887_configure(struct i2c_client *client)

/* ---------------------------------------------------------------------- */

static void tda9887_tuner_status(struct i2c_client *client)
static void tda9887_tuner_status(struct tuner *t)
{
	struct tuner *t = i2c_get_clientdata(client);
	struct tda9887_priv *priv = t->priv;
	tda9887_info("Data bytes: b=0x%02x c=0x%02x e=0x%02x\n", priv->data[1], priv->data[2], priv->data[3]);
}

static int tda9887_get_afc(struct i2c_client *client)
static int tda9887_get_afc(struct tuner *t)
{
	struct tuner *t = i2c_get_clientdata(client);
	struct tda9887_priv *priv = t->priv;
	static int AFC_BITS_2_kHz[] = {
		-12500,  -37500,  -62500,  -97500,
		-112500, -137500, -162500, -187500,
@@ -587,26 +588,24 @@ static int tda9887_get_afc(struct i2c_client *client)
	int afc=0;
	__u8 reg = 0;

	if (1 == i2c_master_recv(&t->i2c,&reg,1))
	if (1 == tuner_i2c_xfer_recv(&priv->i2c_props,&reg,1))
		afc = AFC_BITS_2_kHz[(reg>>1)&0x0f];

	return afc;
}

static void tda9887_standby(struct i2c_client *client)
static void tda9887_standby(struct tuner *t)
{
	tda9887_configure(client);
	tda9887_configure(t);
}

static void tda9887_set_freq(struct i2c_client *client, unsigned int freq)
static void tda9887_set_freq(struct tuner *t, unsigned int freq)
{
	tda9887_configure(client);
	tda9887_configure(t);
}

static void tda9887_release(struct i2c_client *c)
static void tda9887_release(struct tuner *t)
{
	struct tuner *t = i2c_get_clientdata(c);

	kfree(t->priv);
	t->priv = NULL;
}
@@ -620,17 +619,19 @@ static struct tuner_operations tda9887_tuner_ops = {
	.release        = tda9887_release,
};

int tda9887_tuner_init(struct i2c_client *c)
int tda9887_tuner_init(struct tuner *t)
{
	struct tda9887_priv *priv = NULL;
	struct tuner *t = i2c_get_clientdata(c);

	priv = kzalloc(sizeof(struct tda9887_priv), GFP_KERNEL);
	if (priv == NULL)
		return -ENOMEM;
	t->priv = priv;

	strlcpy(c->name, "tda9887", sizeof(c->name));
	priv->i2c_props.addr = t->i2c.addr;
	priv->i2c_props.adap = t->i2c.adapter;

	strlcpy(t->i2c.name, "tda9887", sizeof(t->i2c.name));

	tda9887_info("tda988[5/6/7] found @ 0x%x (%s)\n", t->i2c.addr,
						t->i2c.driver->driver.name);
+36 −19
Original line number Diff line number Diff line
@@ -18,6 +18,10 @@
/* from tuner-core.c */
extern int tuner_debug;

struct tea5761_priv {
	struct tuner_i2c_props i2c_props;
};

/*****************************************************************************/

/***************************
@@ -114,10 +118,8 @@ extern int tuner_debug;

/*****************************************************************************/

static void set_tv_freq(struct i2c_client *c, unsigned int freq)
static void set_tv_freq(struct tuner *t, unsigned int freq)
{
	struct tuner *t = i2c_get_clientdata(c);

	tuner_warn("This tuner doesn't support TV freq.\n");
}

@@ -135,9 +137,9 @@ static void tea5761_status_dump(unsigned char *buffer)
}

/* Freq should be specifyed at 62.5 Hz */
static void set_radio_freq(struct i2c_client *c, unsigned int frq)
static void set_radio_freq(struct tuner *t, unsigned int frq)
{
	struct tuner *t = i2c_get_clientdata(c);
	struct tea5761_priv *priv = t->priv;
	unsigned char buffer[7] = {0, 0, 0, 0, 0, 0, 0 };
	unsigned div;
	int rc;
@@ -167,31 +169,31 @@ static void set_radio_freq(struct i2c_client *c, unsigned int frq)
	if (tuner_debug)
		tea5761_status_dump(buffer);

	if (7 != (rc = i2c_master_send(c, buffer, 7)))
	if (7 != (rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 7)))
		tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
}

static int tea5761_signal(struct i2c_client *c)
static int tea5761_signal(struct tuner *t)
{
	unsigned char buffer[16];
	int rc;
	struct tuner *t = i2c_get_clientdata(c);
	struct tea5761_priv *priv = t->priv;

	memset(buffer, 0, sizeof(buffer));
	if (16 != (rc = i2c_master_recv(c, buffer, 16)))
	if (16 != (rc = tuner_i2c_xfer_recv(&priv->i2c_props, buffer, 16)))
		tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);

	return ((buffer[9] & TEA5761_TUNCHECK_LEV_MASK) << (13 - 4));
}

static int tea5761_stereo(struct i2c_client *c)
static int tea5761_stereo(struct tuner *t)
{
	unsigned char buffer[16];
	int rc;
	struct tuner *t = i2c_get_clientdata(c);
	struct tea5761_priv *priv = t->priv;

	memset(buffer, 0, sizeof(buffer));
	if (16 != (rc = i2c_master_recv(c, buffer, 16)))
	if (16 != (rc = tuner_i2c_xfer_recv(&priv->i2c_props, buffer, 16)))
		tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);

	rc = buffer[9] & TEA5761_TUNCHECK_STEREO;
@@ -201,13 +203,13 @@ static int tea5761_stereo(struct i2c_client *c)
	return (rc ? V4L2_TUNER_SUB_STEREO : 0);
}

int tea5761_autodetection(struct i2c_client *c)
int tea5761_autodetection(struct tuner *t)
{
	unsigned char buffer[16];
	int rc;
	struct tuner *t = i2c_get_clientdata(c);
	struct tuner_i2c_props i2c = { .adap = t->i2c.adapter, .addr = t->i2c.addr };

	if (16 != (rc = i2c_master_recv(c, buffer, 16))) {
	if (16 != (rc = tuner_i2c_xfer_recv(&i2c, buffer, 16))) {
		tuner_warn("it is not a TEA5761. Received %i chars.\n", rc);
		return EINVAL;
	}
@@ -220,22 +222,37 @@ int tea5761_autodetection(struct i2c_client *c)
	return 0;
}

static void tea5761_release(struct tuner *t)
{
	kfree(t->priv);
	t->priv = NULL;
}

static struct tuner_operations tea5761_tuner_ops = {
	.set_tv_freq    = set_tv_freq,
	.set_radio_freq = set_radio_freq,
	.has_signal     = tea5761_signal,
	.is_stereo      = tea5761_stereo,
	.release        = tea5761_release,
};

int tea5761_tuner_init(struct i2c_client *c)
int tea5761_tuner_init(struct tuner *t)
{
	struct tuner *t = i2c_get_clientdata(c);
	struct tea5761_priv *priv = NULL;

	if (tea5761_autodetection(c) == EINVAL)
	if (tea5761_autodetection(t) == EINVAL)
		return EINVAL;

	priv = kzalloc(sizeof(struct tea5761_priv), GFP_KERNEL);
	if (priv == NULL)
		return -ENOMEM;
	t->priv = priv;

	priv->i2c_props.addr = t->i2c.addr;
	priv->i2c_props.adap = t->i2c.adapter;

	tuner_info("type set to %d (%s)\n", t->type, "Philips TEA5761HN FM Radio");
	strlcpy(c->name, "tea5761", sizeof(c->name));
	strlcpy(t->i2c.name, "tea5761", sizeof(t->i2c.name));

	memcpy(&t->ops, &tea5761_tuner_ops, sizeof(struct tuner_operations));

+39 −22
Original line number Diff line number Diff line
@@ -20,6 +20,10 @@
/* from tuner-core.c */
extern int tuner_debug;

struct tea5767_priv {
	struct tuner_i2c_props i2c_props;
};

/*****************************************************************************/

/******************************
@@ -129,10 +133,8 @@ enum tea5767_xtal_freq {

/*****************************************************************************/

static void set_tv_freq(struct i2c_client *c, unsigned int freq)
static void set_tv_freq(struct tuner *t, unsigned int freq)
{
	struct tuner *t = i2c_get_clientdata(c);

	tuner_warn("This tuner doesn't support TV freq.\n");
}

@@ -190,9 +192,9 @@ static void tea5767_status_dump(unsigned char *buffer)
}

/* Freq should be specifyed at 62.5 Hz */
static void set_radio_freq(struct i2c_client *c, unsigned int frq)
static void set_radio_freq(struct tuner *t, unsigned int frq)
{
	struct tuner *t = i2c_get_clientdata(c);
	struct tea5767_priv *priv = t->priv;
	unsigned char buffer[5];
	unsigned div;
	int rc;
@@ -246,38 +248,38 @@ static void set_radio_freq(struct i2c_client *c, unsigned int frq)
	buffer[0] = (div >> 8) & 0x3f;
	buffer[1] = div & 0xff;

	if (5 != (rc = i2c_master_send(c, buffer, 5)))
	if (5 != (rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 5)))
		tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);

	if (tuner_debug) {
		if (5 != (rc = i2c_master_recv(c, buffer, 5)))
		if (5 != (rc = tuner_i2c_xfer_recv(&priv->i2c_props, buffer, 5)))
			tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
		else
			tea5767_status_dump(buffer);
	}
}

static int tea5767_signal(struct i2c_client *c)
static int tea5767_signal(struct tuner *t)
{
	unsigned char buffer[5];
	int rc;
	struct tuner *t = i2c_get_clientdata(c);
	struct tea5767_priv *priv = t->priv;

	memset(buffer, 0, sizeof(buffer));
	if (5 != (rc = i2c_master_recv(c, buffer, 5)))
	if (5 != (rc = tuner_i2c_xfer_recv(&priv->i2c_props, buffer, 5)))
		tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);

	return ((buffer[3] & TEA5767_ADC_LEVEL_MASK) << 8);
}

static int tea5767_stereo(struct i2c_client *c)
static int tea5767_stereo(struct tuner *t)
{
	unsigned char buffer[5];
	int rc;
	struct tuner *t = i2c_get_clientdata(c);
	struct tea5767_priv *priv = t->priv;

	memset(buffer, 0, sizeof(buffer));
	if (5 != (rc = i2c_master_recv(c, buffer, 5)))
	if (5 != (rc = tuner_i2c_xfer_recv(&priv->i2c_props, buffer, 5)))
		tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);

	rc = buffer[2] & TEA5767_STEREO_MASK;
@@ -287,10 +289,10 @@ static int tea5767_stereo(struct i2c_client *c)
	return ((buffer[2] & TEA5767_STEREO_MASK) ? V4L2_TUNER_SUB_STEREO : 0);
}

static void tea5767_standby(struct i2c_client *c)
static void tea5767_standby(struct tuner *t)
{
	unsigned char buffer[5];
	struct tuner *t = i2c_get_clientdata(c);
	struct tea5767_priv *priv = t->priv;
	unsigned div, rc;

	div = (87500 * 4 + 700 + 225 + 25) / 50; /* Set frequency to 87.5 MHz */
@@ -301,17 +303,17 @@ static void tea5767_standby(struct i2c_client *c)
		    TEA5767_ST_NOISE_CTL | TEA5767_JAPAN_BAND | TEA5767_STDBY;
	buffer[4] = 0;

	if (5 != (rc = i2c_master_send(c, buffer, 5)))
	if (5 != (rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 5)))
		tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
}

int tea5767_autodetection(struct i2c_client *c)
int tea5767_autodetection(struct tuner *t)
{
	struct tuner_i2c_props i2c = { .adap = t->i2c.adapter, .addr = t->i2c.addr };
	unsigned char buffer[7] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
	int rc;
	struct tuner *t = i2c_get_clientdata(c);

	if ((rc = i2c_master_recv(c, buffer, 7))< 5) {
	if ((rc = tuner_i2c_xfer_send(&i2c, buffer, 7))< 5) {
		tuner_warn("It is not a TEA5767. Received %i bytes.\n", rc);
		return EINVAL;
	}
@@ -343,20 +345,35 @@ int tea5767_autodetection(struct i2c_client *c)
	return 0;
}

static void tea5767_release(struct tuner *t)
{
	kfree(t->priv);
	t->priv = NULL;
}

static struct tuner_operations tea5767_tuner_ops = {
	.set_tv_freq    = set_tv_freq,
	.set_radio_freq = set_radio_freq,
	.has_signal     = tea5767_signal,
	.is_stereo      = tea5767_stereo,
	.standby        = tea5767_standby,
	.release        = tea5767_release,
};

int tea5767_tuner_init(struct i2c_client *c)
int tea5767_tuner_init(struct tuner *t)
{
	struct tuner *t = i2c_get_clientdata(c);
	struct tea5767_priv *priv = NULL;

	priv = kzalloc(sizeof(struct tea5767_priv), GFP_KERNEL);
	if (priv == NULL)
		return -ENOMEM;
	t->priv = priv;

	priv->i2c_props.addr = t->i2c.addr;
	priv->i2c_props.adap = t->i2c.adapter;

	tuner_info("type set to %d (%s)\n", t->type, "Philips TEA5767HN FM Radio");
	strlcpy(c->name, "tea5767", sizeof(c->name));
	strlcpy(t->i2c.name, "tea5767", sizeof(t->i2c.name));

	memcpy(&t->ops, &tea5767_tuner_ops, sizeof(struct tuner_operations));

Loading