18ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky/*
28ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky *
38ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky * (c) 2005 Hartmut Hackmann
48ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky * (c) 2007 Michael Krufky
58ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky *
68ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky *  This program is free software; you can redistribute it and/or modify
78ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky *  it under the terms of the GNU General Public License as published by
88ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky *  the Free Software Foundation; either version 2 of the License, or
98ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky *  (at your option) any later version.
108ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky *
118ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky *  This program is distributed in the hope that it will be useful,
128ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky *  but WITHOUT ANY WARRANTY; without even the implied warranty of
138ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
148ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky *  GNU General Public License for more details.
158ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky *
168ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky *  You should have received a copy of the GNU General Public License
178ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky *  along with this program; if not, write to the Free Software
188ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
198ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky */
208ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky
218ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky#include <linux/module.h>
225a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h>
238ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky#include <asm/types.h>
24746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky#include <linux/dvb/frontend.h>
25746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky#include <linux/videodev2.h>
268ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky
278ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky#include "tda827x.h"
288ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky
29ff699e6bd02eb1c6d02c7c2b576c2ee6caab201cDouglas Schilling Landgrafstatic int debug;
30746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufkymodule_param(debug, int, 0644);
31746d9732dbd5b95c3ba36230e2814fa2c391a311Michael KrufkyMODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
32746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky
338ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky#define dprintk(args...) \
348ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	do {					    \
358ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky		if (debug) printk(KERN_DEBUG "tda827x: " args); \
368ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	} while (0)
378ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky
388ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufkystruct tda827x_priv {
398ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	int i2c_addr;
408ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	struct i2c_adapter *i2c_adap;
418ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	struct tda827x_config *cfg;
425c82f4497b46e9c3877618bc36661a4abbf9c646Michael Krufky
435c82f4497b46e9c3877618bc36661a4abbf9c646Michael Krufky	unsigned int sgIF;
445c82f4497b46e9c3877618bc36661a4abbf9c646Michael Krufky	unsigned char lpsel;
455c82f4497b46e9c3877618bc36661a4abbf9c646Michael Krufky
468ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	u32 frequency;
478ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	u32 bandwidth;
488ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky};
498ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky
505c82f4497b46e9c3877618bc36661a4abbf9c646Michael Krufkystatic void tda827x_set_std(struct dvb_frontend *fe,
515c82f4497b46e9c3877618bc36661a4abbf9c646Michael Krufky			    struct analog_parameters *params)
525c82f4497b46e9c3877618bc36661a4abbf9c646Michael Krufky{
535c82f4497b46e9c3877618bc36661a4abbf9c646Michael Krufky	struct tda827x_priv *priv = fe->tuner_priv;
545c82f4497b46e9c3877618bc36661a4abbf9c646Michael Krufky	char *mode;
555c82f4497b46e9c3877618bc36661a4abbf9c646Michael Krufky
565c82f4497b46e9c3877618bc36661a4abbf9c646Michael Krufky	priv->lpsel = 0;
575c82f4497b46e9c3877618bc36661a4abbf9c646Michael Krufky	if (params->std & V4L2_STD_MN) {
585c82f4497b46e9c3877618bc36661a4abbf9c646Michael Krufky		priv->sgIF = 92;
595c82f4497b46e9c3877618bc36661a4abbf9c646Michael Krufky		priv->lpsel = 1;
605c82f4497b46e9c3877618bc36661a4abbf9c646Michael Krufky		mode = "MN";
615c82f4497b46e9c3877618bc36661a4abbf9c646Michael Krufky	} else if (params->std & V4L2_STD_B) {
625c82f4497b46e9c3877618bc36661a4abbf9c646Michael Krufky		priv->sgIF = 108;
635c82f4497b46e9c3877618bc36661a4abbf9c646Michael Krufky		mode = "B";
645c82f4497b46e9c3877618bc36661a4abbf9c646Michael Krufky	} else if (params->std & V4L2_STD_GH) {
655c82f4497b46e9c3877618bc36661a4abbf9c646Michael Krufky		priv->sgIF = 124;
665c82f4497b46e9c3877618bc36661a4abbf9c646Michael Krufky		mode = "GH";
675c82f4497b46e9c3877618bc36661a4abbf9c646Michael Krufky	} else if (params->std & V4L2_STD_PAL_I) {
685c82f4497b46e9c3877618bc36661a4abbf9c646Michael Krufky		priv->sgIF = 124;
695c82f4497b46e9c3877618bc36661a4abbf9c646Michael Krufky		mode = "I";
705c82f4497b46e9c3877618bc36661a4abbf9c646Michael Krufky	} else if (params->std & V4L2_STD_DK) {
715c82f4497b46e9c3877618bc36661a4abbf9c646Michael Krufky		priv->sgIF = 124;
725c82f4497b46e9c3877618bc36661a4abbf9c646Michael Krufky		mode = "DK";
735c82f4497b46e9c3877618bc36661a4abbf9c646Michael Krufky	} else if (params->std & V4L2_STD_SECAM_L) {
745c82f4497b46e9c3877618bc36661a4abbf9c646Michael Krufky		priv->sgIF = 124;
755c82f4497b46e9c3877618bc36661a4abbf9c646Michael Krufky		mode = "L";
765c82f4497b46e9c3877618bc36661a4abbf9c646Michael Krufky	} else if (params->std & V4L2_STD_SECAM_LC) {
775c82f4497b46e9c3877618bc36661a4abbf9c646Michael Krufky		priv->sgIF = 20;
785c82f4497b46e9c3877618bc36661a4abbf9c646Michael Krufky		mode = "LC";
795c82f4497b46e9c3877618bc36661a4abbf9c646Michael Krufky	} else {
805c82f4497b46e9c3877618bc36661a4abbf9c646Michael Krufky		priv->sgIF = 124;
815c82f4497b46e9c3877618bc36661a4abbf9c646Michael Krufky		mode = "xx";
825c82f4497b46e9c3877618bc36661a4abbf9c646Michael Krufky	}
835c82f4497b46e9c3877618bc36661a4abbf9c646Michael Krufky
84e5218eedaef39ed5f1ebc84ab9510dd9b99acadfMauro Carvalho Chehab	if (params->mode == V4L2_TUNER_RADIO) {
855c82f4497b46e9c3877618bc36661a4abbf9c646Michael Krufky		priv->sgIF = 88; /* if frequency is 5.5 MHz */
86e5218eedaef39ed5f1ebc84ab9510dd9b99acadfMauro Carvalho Chehab		dprintk("setting tda827x to radio FM\n");
87e5218eedaef39ed5f1ebc84ab9510dd9b99acadfMauro Carvalho Chehab	} else
88e5218eedaef39ed5f1ebc84ab9510dd9b99acadfMauro Carvalho Chehab		dprintk("setting tda827x to system %s\n", mode);
895c82f4497b46e9c3877618bc36661a4abbf9c646Michael Krufky}
905c82f4497b46e9c3877618bc36661a4abbf9c646Michael Krufky
915c82f4497b46e9c3877618bc36661a4abbf9c646Michael Krufky
925c82f4497b46e9c3877618bc36661a4abbf9c646Michael Krufky/* ------------------------------------------------------------------ */
935c82f4497b46e9c3877618bc36661a4abbf9c646Michael Krufky
948ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufkystruct tda827x_data {
958ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	u32 lomax;
968ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	u8  spd;
978ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	u8  bs;
988ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	u8  bp;
998ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	u8  cp;
1008ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	u8  gc3;
1018ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	u8 div1p5;
1028ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky};
1038ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky
104746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufkystatic const struct tda827x_data tda827x_table[] = {
1058ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax =  62000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1},
1068ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax =  66000000, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1},
1078ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax =  76000000, .spd = 3, .bs = 1, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0},
1088ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax =  84000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0},
1098ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax =  93000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0},
1108ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax =  98000000, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0},
1118ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax = 109000000, .spd = 3, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0},
1128ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax = 123000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1},
1138ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax = 133000000, .spd = 2, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1},
1148ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax = 151000000, .spd = 2, .bs = 1, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0},
1158ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax = 154000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0},
1168ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax = 181000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 0, .div1p5 = 0},
1178ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax = 185000000, .spd = 2, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
1188ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax = 217000000, .spd = 2, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
1198ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax = 244000000, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1},
1208ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax = 265000000, .spd = 1, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1},
1218ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax = 302000000, .spd = 1, .bs = 1, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
1228ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax = 324000000, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
1238ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax = 370000000, .spd = 1, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0},
1248ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax = 454000000, .spd = 1, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0},
1258ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax = 493000000, .spd = 0, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1},
1268ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax = 530000000, .spd = 0, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1},
1278ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax = 554000000, .spd = 0, .bs = 1, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0},
1288ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax = 604000000, .spd = 0, .bs = 1, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0},
1298ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax = 696000000, .spd = 0, .bs = 2, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0},
1308ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax = 740000000, .spd = 0, .bs = 2, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0},
1318ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax = 820000000, .spd = 0, .bs = 3, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0},
1328ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax = 865000000, .spd = 0, .bs = 3, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0},
1338ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax =         0, .spd = 0, .bs = 0, .bp = 0, .cp = 0, .gc3 = 0, .div1p5 = 0}
1348ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky};
1358ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky
13668d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehabstatic int tuner_transfer(struct dvb_frontend *fe,
13768d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab			  struct i2c_msg *msg,
13868d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab			  const int size)
13968d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab{
14068d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	int rc;
14168d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	struct tda827x_priv *priv = fe->tuner_priv;
14268d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab
14368d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	if (fe->ops.i2c_gate_ctrl)
14468d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab		fe->ops.i2c_gate_ctrl(fe, 1);
14568d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	rc = i2c_transfer(priv->i2c_adap, msg, size);
14668d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	if (fe->ops.i2c_gate_ctrl)
14768d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab		fe->ops.i2c_gate_ctrl(fe, 0);
14868d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab
14968d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	if (rc >= 0 && rc != size)
15068d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab		return -EIO;
15168d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab
15268d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	return rc;
15368d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab}
15468d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab
15514d24d148c7521b2b88b396652e36f55d061e195Mauro Carvalho Chehabstatic int tda827xo_set_params(struct dvb_frontend *fe)
1568ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky{
15753ccd1ca69c14e29ce927c4992e5b5ceae379d64Mauro Carvalho Chehab	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1588ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	struct tda827x_priv *priv = fe->tuner_priv;
1598ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	u8 buf[14];
16068d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	int rc;
1618ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky
1628ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
1638ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky			       .buf = buf, .len = sizeof(buf) };
1648ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	int i, tuner_freq, if_freq;
1658ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	u32 N;
1668ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky
1677bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann	dprintk("%s:\n", __func__);
16853ccd1ca69c14e29ce927c4992e5b5ceae379d64Mauro Carvalho Chehab	if (c->bandwidth_hz == 0) {
16953ccd1ca69c14e29ce927c4992e5b5ceae379d64Mauro Carvalho Chehab		if_freq = 5000000;
17053ccd1ca69c14e29ce927c4992e5b5ceae379d64Mauro Carvalho Chehab	} else if (c->bandwidth_hz <= 6000000) {
1718ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky		if_freq = 4000000;
17253ccd1ca69c14e29ce927c4992e5b5ceae379d64Mauro Carvalho Chehab	} else if (c->bandwidth_hz <= 7000000) {
1738ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky		if_freq = 4500000;
17453ccd1ca69c14e29ce927c4992e5b5ceae379d64Mauro Carvalho Chehab	} else {	/* 8 MHz */
1758ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky		if_freq = 5000000;
1768ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	}
17753ccd1ca69c14e29ce927c4992e5b5ceae379d64Mauro Carvalho Chehab	tuner_freq = c->frequency;
1788ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky
1798ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	i = 0;
180746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	while (tda827x_table[i].lomax < tuner_freq) {
181746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky		if (tda827x_table[i + 1].lomax == 0)
1828ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky			break;
1838ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky		i++;
1848ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	}
1858ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky
1862d84ca215f6d67f9ba7b3d4ab32265e085229662Jose Alberto Reguero	tuner_freq += if_freq;
1872d84ca215f6d67f9ba7b3d4ab32265e085229662Jose Alberto Reguero
188746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	N = ((tuner_freq + 125000) / 250000) << (tda827x_table[i].spd + 2);
1898ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	buf[0] = 0;
1908ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	buf[1] = (N>>8) | 0x40;
1918ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	buf[2] = N & 0xff;
1928ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	buf[3] = 0;
1938ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	buf[4] = 0x52;
194746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	buf[5] = (tda827x_table[i].spd << 6) + (tda827x_table[i].div1p5 << 5) +
195746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky				(tda827x_table[i].bs << 3) +
196746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky				tda827x_table[i].bp;
197746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	buf[6] = (tda827x_table[i].gc3 << 4) + 0x8f;
1988ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	buf[7] = 0xbf;
1998ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	buf[8] = 0x2a;
2008ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	buf[9] = 0x05;
2018ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	buf[10] = 0xff;
2028ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	buf[11] = 0x00;
2038ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	buf[12] = 0x00;
2048ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	buf[13] = 0x40;
2058ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky
2068ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	msg.len = 14;
20768d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	rc = tuner_transfer(fe, &msg, 1);
20868d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	if (rc < 0)
20968d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab		goto err;
21068d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab
2118ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	msleep(500);
2128ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	/* correct CP value */
2138ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	buf[0] = 0x30;
214746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	buf[1] = 0x50 + tda827x_table[i].cp;
2158ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	msg.len = 2;
2168ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky
21768d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	rc = tuner_transfer(fe, &msg, 1);
21868d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	if (rc < 0)
21968d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab		goto err;
2208ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky
22153ccd1ca69c14e29ce927c4992e5b5ceae379d64Mauro Carvalho Chehab	priv->frequency = c->frequency;
222c6f56e7d794cba022353d464dfa3383d1b3e0125Mauro Carvalho Chehab	priv->bandwidth = c->bandwidth_hz;
2238ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky
2248ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	return 0;
22568d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab
22668d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehaberr:
22768d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	printk(KERN_ERR "%s: could not write to tuner at addr: 0x%02x\n",
22868d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	       __func__, priv->i2c_addr << 1);
22968d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	return rc;
2308ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky}
2318ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky
2328ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufkystatic int tda827xo_sleep(struct dvb_frontend *fe)
2338ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky{
2348ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	struct tda827x_priv *priv = fe->tuner_priv;
2358ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	static u8 buf[] = { 0x30, 0xd0 };
2368ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
2378ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky			       .buf = buf, .len = sizeof(buf) };
2388ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky
2397bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann	dprintk("%s:\n", __func__);
24068d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	tuner_transfer(fe, &msg, 1);
2418ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky
2428ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	if (priv->cfg && priv->cfg->sleep)
2438ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky		priv->cfg->sleep(fe);
2448ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky
2458ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	return 0;
2468ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky}
2478ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky
2488ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky/* ------------------------------------------------------------------ */
2498ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky
250746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufkystatic int tda827xo_set_analog_params(struct dvb_frontend *fe,
251746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky				      struct analog_parameters *params)
252746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky{
253746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	unsigned char tuner_reg[8];
254746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	unsigned char reg2[2];
255746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	u32 N;
256746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	int i;
257746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	struct tda827x_priv *priv = fe->tuner_priv;
258746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0 };
259746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	unsigned int freq = params->frequency;
260746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky
2615c82f4497b46e9c3877618bc36661a4abbf9c646Michael Krufky	tda827x_set_std(fe, params);
2625c82f4497b46e9c3877618bc36661a4abbf9c646Michael Krufky
263746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	if (params->mode == V4L2_TUNER_RADIO)
264746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky		freq = freq / 1000;
265746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky
2665c82f4497b46e9c3877618bc36661a4abbf9c646Michael Krufky	N = freq + priv->sgIF;
267746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky
268746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	i = 0;
269746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	while (tda827x_table[i].lomax < N * 62500) {
270746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky		if (tda827x_table[i + 1].lomax == 0)
271746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky			break;
272746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky		i++;
273746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	}
274746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky
275746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	N = N << tda827x_table[i].spd;
276746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky
277746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	tuner_reg[0] = 0;
278746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	tuner_reg[1] = (unsigned char)(N>>8);
279746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	tuner_reg[2] = (unsigned char) N;
280746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	tuner_reg[3] = 0x40;
2815c82f4497b46e9c3877618bc36661a4abbf9c646Michael Krufky	tuner_reg[4] = 0x52 + (priv->lpsel << 5);
282746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	tuner_reg[5] = (tda827x_table[i].spd    << 6) +
283746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky		       (tda827x_table[i].div1p5 << 5) +
284746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky		       (tda827x_table[i].bs     << 3) + tda827x_table[i].bp;
285746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	tuner_reg[6] = 0x8f + (tda827x_table[i].gc3 << 4);
286746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	tuner_reg[7] = 0x8f;
287746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky
288746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	msg.buf = tuner_reg;
289746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	msg.len = 8;
29068d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	tuner_transfer(fe, &msg, 1);
291746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky
292746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	msg.buf = reg2;
293746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	msg.len = 2;
294746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	reg2[0] = 0x80;
295746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	reg2[1] = 0;
29668d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	tuner_transfer(fe, &msg, 1);
297746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky
298746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	reg2[0] = 0x60;
299746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	reg2[1] = 0xbf;
30068d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	tuner_transfer(fe, &msg, 1);
301746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky
302746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	reg2[0] = 0x30;
303746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	reg2[1] = tuner_reg[4] + 0x80;
30468d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	tuner_transfer(fe, &msg, 1);
305746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky
306746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	msleep(1);
307746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	reg2[0] = 0x30;
308746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	reg2[1] = tuner_reg[4] + 4;
30968d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	tuner_transfer(fe, &msg, 1);
310746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky
311746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	msleep(1);
312746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	reg2[0] = 0x30;
313746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	reg2[1] = tuner_reg[4];
31468d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	tuner_transfer(fe, &msg, 1);
315746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky
316746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	msleep(550);
317746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	reg2[0] = 0x30;
318746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	reg2[1] = (tuner_reg[4] & 0xfc) + tda827x_table[i].cp;
31968d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	tuner_transfer(fe, &msg, 1);
320746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky
321746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	reg2[0] = 0x60;
322746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	reg2[1] = 0x3f;
32368d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	tuner_transfer(fe, &msg, 1);
324746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky
325746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	reg2[0] = 0x80;
326746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	reg2[1] = 0x08;   /* Vsync en */
32768d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	tuner_transfer(fe, &msg, 1);
328746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky
32992d90f1a57dcb6c6ab5a7b9ad949bdb7531931a4Mauro Carvalho Chehab	priv->frequency = params->frequency;
330746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky
331746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	return 0;
332746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky}
333746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky
334746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufkystatic void tda827xo_agcf(struct dvb_frontend *fe)
335746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky{
336746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	struct tda827x_priv *priv = fe->tuner_priv;
337746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	unsigned char data[] = { 0x80, 0x0c };
338746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
339746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky			       .buf = data, .len = 2};
340746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky
34168d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	tuner_transfer(fe, &msg, 1);
342746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky}
343746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky
344746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky/* ------------------------------------------------------------------ */
345746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky
3468ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufkystruct tda827xa_data {
3478ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	u32 lomax;
3488ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	u8  svco;
3498ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	u8  spd;
3508ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	u8  scr;
3518ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	u8  sbs;
3528ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	u8  gc3;
3538ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky};
3548ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky
355cf47d878e5c7825836abf8d37fde025f7676db2bklaas de waalstatic struct tda827xa_data tda827xa_dvbt[] = {
3568ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax =  56875000, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 1},
3578ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax =  67250000, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
3588ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax =  81250000, .svco = 1, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
3598ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax =  97500000, .svco = 2, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
3608ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax = 113750000, .svco = 3, .spd = 3, .scr = 0, .sbs = 1, .gc3 = 1},
3618ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax = 134500000, .svco = 0, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
3628ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax = 154000000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
3638ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax = 162500000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
3648ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax = 183000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
3658ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax = 195000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1},
3668ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax = 227500000, .svco = 3, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1},
3678ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax = 269000000, .svco = 0, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1},
3688ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax = 290000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1},
3698ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax = 325000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1},
3708ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax = 390000000, .svco = 2, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1},
3718ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax = 455000000, .svco = 3, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1},
3728ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax = 520000000, .svco = 0, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1},
3738ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax = 538000000, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1},
3748ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax = 550000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1},
3758ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax = 620000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
3768ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax = 650000000, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
3778ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax = 700000000, .svco = 2, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
3788ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax = 780000000, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
3798ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax = 820000000, .svco = 3, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
3808ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax = 870000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
3818ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax = 911000000, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 0},
3828ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	{ .lomax =         0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0}
3838ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky};
3848ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky
385cf47d878e5c7825836abf8d37fde025f7676db2bklaas de waalstatic struct tda827xa_data tda827xa_dvbc[] = {
386cf47d878e5c7825836abf8d37fde025f7676db2bklaas de waal	{ .lomax =  50125000, .svco = 2, .spd = 4, .scr = 2, .sbs = 0, .gc3 = 3},
387cf47d878e5c7825836abf8d37fde025f7676db2bklaas de waal	{ .lomax =  58500000, .svco = 3, .spd = 4, .scr = 2, .sbs = 0, .gc3 = 3},
388cf47d878e5c7825836abf8d37fde025f7676db2bklaas de waal	{ .lomax =  69250000, .svco = 0, .spd = 3, .scr = 2, .sbs = 0, .gc3 = 3},
389cf47d878e5c7825836abf8d37fde025f7676db2bklaas de waal	{ .lomax =  83625000, .svco = 1, .spd = 3, .scr = 2, .sbs = 0, .gc3 = 3},
390cf47d878e5c7825836abf8d37fde025f7676db2bklaas de waal	{ .lomax =  97500000, .svco = 2, .spd = 3, .scr = 2, .sbs = 0, .gc3 = 3},
391cf47d878e5c7825836abf8d37fde025f7676db2bklaas de waal	{ .lomax = 100250000, .svco = 2, .spd = 3, .scr = 2, .sbs = 1, .gc3 = 1},
392cf47d878e5c7825836abf8d37fde025f7676db2bklaas de waal	{ .lomax = 117000000, .svco = 3, .spd = 3, .scr = 2, .sbs = 1, .gc3 = 1},
393cf47d878e5c7825836abf8d37fde025f7676db2bklaas de waal	{ .lomax = 138500000, .svco = 0, .spd = 2, .scr = 2, .sbs = 1, .gc3 = 1},
394cf47d878e5c7825836abf8d37fde025f7676db2bklaas de waal	{ .lomax = 167250000, .svco = 1, .spd = 2, .scr = 2, .sbs = 1, .gc3 = 1},
395cf47d878e5c7825836abf8d37fde025f7676db2bklaas de waal	{ .lomax = 187000000, .svco = 2, .spd = 2, .scr = 2, .sbs = 1, .gc3 = 1},
396cf47d878e5c7825836abf8d37fde025f7676db2bklaas de waal	{ .lomax = 200500000, .svco = 2, .spd = 2, .scr = 2, .sbs = 2, .gc3 = 1},
397cf47d878e5c7825836abf8d37fde025f7676db2bklaas de waal	{ .lomax = 234000000, .svco = 3, .spd = 2, .scr = 2, .sbs = 2, .gc3 = 3},
398cf47d878e5c7825836abf8d37fde025f7676db2bklaas de waal	{ .lomax = 277000000, .svco = 0, .spd = 1, .scr = 2, .sbs = 2, .gc3 = 3},
399cf47d878e5c7825836abf8d37fde025f7676db2bklaas de waal	{ .lomax = 325000000, .svco = 1, .spd = 1, .scr = 2, .sbs = 2, .gc3 = 1},
400cf47d878e5c7825836abf8d37fde025f7676db2bklaas de waal	{ .lomax = 334500000, .svco = 1, .spd = 1, .scr = 2, .sbs = 3, .gc3 = 3},
401cf47d878e5c7825836abf8d37fde025f7676db2bklaas de waal	{ .lomax = 401000000, .svco = 2, .spd = 1, .scr = 2, .sbs = 3, .gc3 = 3},
402cf47d878e5c7825836abf8d37fde025f7676db2bklaas de waal	{ .lomax = 468000000, .svco = 3, .spd = 1, .scr = 2, .sbs = 3, .gc3 = 1},
403cf47d878e5c7825836abf8d37fde025f7676db2bklaas de waal	{ .lomax = 535000000, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1},
404cf47d878e5c7825836abf8d37fde025f7676db2bklaas de waal	{ .lomax = 554000000, .svco = 0, .spd = 0, .scr = 2, .sbs = 3, .gc3 = 1},
405cf47d878e5c7825836abf8d37fde025f7676db2bklaas de waal	{ .lomax = 638000000, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1},
406cf47d878e5c7825836abf8d37fde025f7676db2bklaas de waal	{ .lomax = 669000000, .svco = 1, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 1},
407cf47d878e5c7825836abf8d37fde025f7676db2bklaas de waal	{ .lomax = 720000000, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1},
408cf47d878e5c7825836abf8d37fde025f7676db2bklaas de waal	{ .lomax = 802000000, .svco = 2, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 1},
409cf47d878e5c7825836abf8d37fde025f7676db2bklaas de waal	{ .lomax = 835000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1},
410cf47d878e5c7825836abf8d37fde025f7676db2bklaas de waal	{ .lomax = 885000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1},
411cf47d878e5c7825836abf8d37fde025f7676db2bklaas de waal	{ .lomax = 911000000, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 1},
412cf47d878e5c7825836abf8d37fde025f7676db2bklaas de waal	{ .lomax =         0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0}
413cf47d878e5c7825836abf8d37fde025f7676db2bklaas de waal};
414cf47d878e5c7825836abf8d37fde025f7676db2bklaas de waal
415746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufkystatic struct tda827xa_data tda827xa_analog[] = {
416746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	{ .lomax =  56875000, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 3},
417746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	{ .lomax =  67250000, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3},
418746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	{ .lomax =  81250000, .svco = 1, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3},
419746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	{ .lomax =  97500000, .svco = 2, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3},
420746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	{ .lomax = 113750000, .svco = 3, .spd = 3, .scr = 0, .sbs = 1, .gc3 = 1},
421746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	{ .lomax = 134500000, .svco = 0, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
422746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	{ .lomax = 154000000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
423746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	{ .lomax = 162500000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
424746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	{ .lomax = 183000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
425746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	{ .lomax = 195000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1},
426746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	{ .lomax = 227500000, .svco = 3, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 3},
427746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	{ .lomax = 269000000, .svco = 0, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 3},
428746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	{ .lomax = 325000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1},
429746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	{ .lomax = 390000000, .svco = 2, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 3},
430746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	{ .lomax = 455000000, .svco = 3, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 3},
431746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	{ .lomax = 520000000, .svco = 0, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1},
432746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	{ .lomax = 538000000, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1},
433746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	{ .lomax = 554000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1},
434746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	{ .lomax = 620000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
435746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	{ .lomax = 650000000, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
436746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	{ .lomax = 700000000, .svco = 2, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
437746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	{ .lomax = 780000000, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
438746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	{ .lomax = 820000000, .svco = 3, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
439746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	{ .lomax = 870000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
440746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	{ .lomax = 911000000, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 0},
441746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	{ .lomax =         0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0}
442746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky};
443746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky
4447bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmannstatic int tda827xa_sleep(struct dvb_frontend *fe)
4457bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann{
4467bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann	struct tda827x_priv *priv = fe->tuner_priv;
4477bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann	static u8 buf[] = { 0x30, 0x90 };
4487bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann	struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
4497bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann			       .buf = buf, .len = sizeof(buf) };
4507bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann
4517bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann	dprintk("%s:\n", __func__);
4527bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann
45368d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	tuner_transfer(fe, &msg, 1);
4547bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann
4557bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann	if (priv->cfg && priv->cfg->sleep)
4567bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann		priv->cfg->sleep(fe);
4577bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann
4587bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann	return 0;
4597bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann}
4607bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann
4617bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmannstatic void tda827xa_lna_gain(struct dvb_frontend *fe, int high,
4627bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann			      struct analog_parameters *params)
4637bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann{
4647bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann	struct tda827x_priv *priv = fe->tuner_priv;
4657bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann	unsigned char buf[] = {0x22, 0x01};
4667bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann	int arg;
4677bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann	int gp_func;
46867642a0a58143761d7415f0587e0ac6dd6371251Sigmund Augdal	struct i2c_msg msg = { .flags = 0, .buf = buf, .len = sizeof(buf) };
4697bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann
4707bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann	if (NULL == priv->cfg) {
4717bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann		dprintk("tda827x_config not defined, cannot set LNA gain!\n");
4727bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann		return;
4737bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann	}
47467642a0a58143761d7415f0587e0ac6dd6371251Sigmund Augdal	msg.addr = priv->cfg->switch_addr;
4757bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann	if (priv->cfg->config) {
4767bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann		if (high)
4777bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann			dprintk("setting LNA to high gain\n");
4787bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann		else
4797bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann			dprintk("setting LNA to low gain\n");
4807bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann	}
4817bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann	switch (priv->cfg->config) {
4827bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann	case 0: /* no LNA */
4837bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann		break;
4847bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann	case 1: /* switch is GPIO 0 of tda8290 */
4857bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann	case 2:
4867bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann		if (params == NULL) {
4877bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann			gp_func = 0;
4887bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann			arg  = 0;
4897bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann		} else {
4907bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann			/* turn Vsync on */
4917bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann			gp_func = 1;
4927bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann			if (params->std & V4L2_STD_MN)
4937bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann				arg = 1;
4947bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann			else
4957bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann				arg = 0;
4967bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann		}
497d7cba043d7ec840d67bd5143779d1febe7d83407Michael Krufky		if (fe->callback)
498d7cba043d7ec840d67bd5143779d1febe7d83407Michael Krufky			fe->callback(priv->i2c_adap->algo_data,
499d7cba043d7ec840d67bd5143779d1febe7d83407Michael Krufky				     DVB_FRONTEND_COMPONENT_TUNER,
500d7cba043d7ec840d67bd5143779d1febe7d83407Michael Krufky				     gp_func, arg);
5017bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann		buf[1] = high ? 0 : 1;
5027bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann		if (priv->cfg->config == 2)
5037bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann			buf[1] = high ? 1 : 0;
50468d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab		tuner_transfer(fe, &msg, 1);
5057bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann		break;
5067bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann	case 3: /* switch with GPIO of saa713x */
507d7cba043d7ec840d67bd5143779d1febe7d83407Michael Krufky		if (fe->callback)
508d7cba043d7ec840d67bd5143779d1febe7d83407Michael Krufky			fe->callback(priv->i2c_adap->algo_data,
509d7cba043d7ec840d67bd5143779d1febe7d83407Michael Krufky				     DVB_FRONTEND_COMPONENT_TUNER, 0, high);
5107bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann		break;
5117bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann	}
5127bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann}
5137bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann
51414d24d148c7521b2b88b396652e36f55d061e195Mauro Carvalho Chehabstatic int tda827xa_set_params(struct dvb_frontend *fe)
5158ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky{
51653ccd1ca69c14e29ce927c4992e5b5ceae379d64Mauro Carvalho Chehab	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
5178ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	struct tda827x_priv *priv = fe->tuner_priv;
518cf47d878e5c7825836abf8d37fde025f7676db2bklaas de waal	struct tda827xa_data *frequency_map = tda827xa_dvbt;
519ede2200d79777d461cf2f0fd19cf7a17f633d3a4Hartmut Hackmann	u8 buf[11];
5208ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky
5218ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
5228ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky			       .buf = buf, .len = sizeof(buf) };
5238ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky
52468d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	int i, tuner_freq, if_freq, rc;
5258ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	u32 N;
5268ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky
5277bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann	dprintk("%s:\n", __func__);
5287bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann
5297bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann	tda827xa_lna_gain(fe, 1, NULL);
5308ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	msleep(20);
5318ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky
53253ccd1ca69c14e29ce927c4992e5b5ceae379d64Mauro Carvalho Chehab	if (c->bandwidth_hz == 0) {
53353ccd1ca69c14e29ce927c4992e5b5ceae379d64Mauro Carvalho Chehab		if_freq = 5000000;
53453ccd1ca69c14e29ce927c4992e5b5ceae379d64Mauro Carvalho Chehab	} else if (c->bandwidth_hz <= 6000000) {
5358ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky		if_freq = 4000000;
53653ccd1ca69c14e29ce927c4992e5b5ceae379d64Mauro Carvalho Chehab	} else if (c->bandwidth_hz <= 7000000) {
5378ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky		if_freq = 4500000;
53853ccd1ca69c14e29ce927c4992e5b5ceae379d64Mauro Carvalho Chehab	} else {	/* 8 MHz */
5398ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky		if_freq = 5000000;
5408ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	}
54153ccd1ca69c14e29ce927c4992e5b5ceae379d64Mauro Carvalho Chehab	tuner_freq = c->frequency;
5428ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky
5436225f18b88b9ba6c6643aa8c1c96f51a9ad24380Mauro Carvalho Chehab	switch (c->delivery_system) {
5446225f18b88b9ba6c6643aa8c1c96f51a9ad24380Mauro Carvalho Chehab	case SYS_DVBC_ANNEX_A:
5456225f18b88b9ba6c6643aa8c1c96f51a9ad24380Mauro Carvalho Chehab	case SYS_DVBC_ANNEX_C:
546cf47d878e5c7825836abf8d37fde025f7676db2bklaas de waal		dprintk("%s select tda827xa_dvbc\n", __func__);
547cf47d878e5c7825836abf8d37fde025f7676db2bklaas de waal		frequency_map = tda827xa_dvbc;
5486225f18b88b9ba6c6643aa8c1c96f51a9ad24380Mauro Carvalho Chehab		break;
5496225f18b88b9ba6c6643aa8c1c96f51a9ad24380Mauro Carvalho Chehab	default:
5506225f18b88b9ba6c6643aa8c1c96f51a9ad24380Mauro Carvalho Chehab		break;
551cf47d878e5c7825836abf8d37fde025f7676db2bklaas de waal	}
552cf47d878e5c7825836abf8d37fde025f7676db2bklaas de waal
5538ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	i = 0;
554cf47d878e5c7825836abf8d37fde025f7676db2bklaas de waal	while (frequency_map[i].lomax < tuner_freq) {
555cf47d878e5c7825836abf8d37fde025f7676db2bklaas de waal		if (frequency_map[i + 1].lomax == 0)
5568ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky			break;
5578ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky		i++;
5588ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	}
5598ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky
5602d84ca215f6d67f9ba7b3d4ab32265e085229662Jose Alberto Reguero	tuner_freq += if_freq;
5612d84ca215f6d67f9ba7b3d4ab32265e085229662Jose Alberto Reguero
562cf47d878e5c7825836abf8d37fde025f7676db2bklaas de waal	N = ((tuner_freq + 31250) / 62500) << frequency_map[i].spd;
5638ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	buf[0] = 0;            // subaddress
5648ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	buf[1] = N >> 8;
5658ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	buf[2] = N & 0xff;
5668ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	buf[3] = 0;
5678ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	buf[4] = 0x16;
568cf47d878e5c7825836abf8d37fde025f7676db2bklaas de waal	buf[5] = (frequency_map[i].spd << 5) + (frequency_map[i].svco << 3) +
569cf47d878e5c7825836abf8d37fde025f7676db2bklaas de waal			frequency_map[i].sbs;
570cf47d878e5c7825836abf8d37fde025f7676db2bklaas de waal	buf[6] = 0x4b + (frequency_map[i].gc3 << 4);
5718ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	buf[7] = 0x1c;
5728ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	buf[8] = 0x06;
5738ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	buf[9] = 0x24;
5748ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	buf[10] = 0x00;
5758ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	msg.len = 11;
57668d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	rc = tuner_transfer(fe, &msg, 1);
57768d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	if (rc < 0)
57868d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab		goto err;
57968d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab
5808ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	buf[0] = 0x90;
5818ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	buf[1] = 0xff;
5828ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	buf[2] = 0x60;
5838ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	buf[3] = 0x00;
5848ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	buf[4] = 0x59;  // lpsel, for 6MHz + 2
5858ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	msg.len = 5;
58668d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	rc = tuner_transfer(fe, &msg, 1);
58768d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	if (rc < 0)
58868d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab		goto err;
5898ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky
5908ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	buf[0] = 0xa0;
5918ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	buf[1] = 0x40;
5928ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	msg.len = 2;
59368d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	rc = tuner_transfer(fe, &msg, 1);
59468d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	if (rc < 0)
59568d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab		goto err;
5968ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky
5978ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	msleep(11);
5988ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	msg.flags = I2C_M_RD;
59968d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	rc = tuner_transfer(fe, &msg, 1);
60068d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	if (rc < 0)
60168d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab		goto err;
6028ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	msg.flags = 0;
6038ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky
6048ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	buf[1] >>= 4;
6058ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	dprintk("tda8275a AGC2 gain is: %d\n", buf[1]);
6068ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	if ((buf[1]) < 2) {
6077bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann		tda827xa_lna_gain(fe, 0, NULL);
6088ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky		buf[0] = 0x60;
6098ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky		buf[1] = 0x0c;
61068d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab		rc = tuner_transfer(fe, &msg, 1);
61168d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab		if (rc < 0)
61268d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab			goto err;
6138ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	}
6148ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky
6158ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	buf[0] = 0xc0;
6168ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	buf[1] = 0x99;    // lpsel, for 6MHz + 2
61768d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	rc = tuner_transfer(fe, &msg, 1);
61868d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	if (rc < 0)
61968d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab		goto err;
6208ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky
6218ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	buf[0] = 0x60;
6228ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	buf[1] = 0x3c;
62368d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	rc = tuner_transfer(fe, &msg, 1);
62468d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	if (rc < 0)
62568d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab		goto err;
6268ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky
6278ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	/* correct CP value */
6288ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	buf[0] = 0x30;
629cf47d878e5c7825836abf8d37fde025f7676db2bklaas de waal	buf[1] = 0x10 + frequency_map[i].scr;
63068d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	rc = tuner_transfer(fe, &msg, 1);
63168d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	if (rc < 0)
63268d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab		goto err;
6338ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky
6348ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	msleep(163);
6358ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	buf[0] = 0xc0;
6368ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	buf[1] = 0x39;  // lpsel, for 6MHz + 2
63768d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	rc = tuner_transfer(fe, &msg, 1);
63868d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	if (rc < 0)
63968d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab		goto err;
6408ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky
6418ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	msleep(3);
6428ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	/* freeze AGC1 */
6438ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	buf[0] = 0x50;
644cf47d878e5c7825836abf8d37fde025f7676db2bklaas de waal	buf[1] = 0x4f + (frequency_map[i].gc3 << 4);
64568d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	rc = tuner_transfer(fe, &msg, 1);
64668d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	if (rc < 0)
64768d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab		goto err;
6488ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky
64953ccd1ca69c14e29ce927c4992e5b5ceae379d64Mauro Carvalho Chehab	priv->frequency = c->frequency;
650c6f56e7d794cba022353d464dfa3383d1b3e0125Mauro Carvalho Chehab	priv->bandwidth = c->bandwidth_hz;
65168d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab
6528ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	return 0;
65368d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab
65468d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehaberr:
65568d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	printk(KERN_ERR "%s: could not write to tuner at addr: 0x%02x\n",
65668d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	       __func__, priv->i2c_addr << 1);
65768d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	return rc;
6588ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky}
6598ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky
660746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky
661746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufkystatic int tda827xa_set_analog_params(struct dvb_frontend *fe,
662746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky				      struct analog_parameters *params)
663746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky{
664746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	unsigned char tuner_reg[11];
665746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	u32 N;
666746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	int i;
667746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	struct tda827x_priv *priv = fe->tuner_priv;
668746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
669746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky			       .buf = tuner_reg, .len = sizeof(tuner_reg) };
670746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	unsigned int freq = params->frequency;
671746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky
6725c82f4497b46e9c3877618bc36661a4abbf9c646Michael Krufky	tda827x_set_std(fe, params);
6735c82f4497b46e9c3877618bc36661a4abbf9c646Michael Krufky
674746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	tda827xa_lna_gain(fe, 1, params);
675746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	msleep(10);
676746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky
677746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	if (params->mode == V4L2_TUNER_RADIO)
678746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky		freq = freq / 1000;
679746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky
6805c82f4497b46e9c3877618bc36661a4abbf9c646Michael Krufky	N = freq + priv->sgIF;
681746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky
682746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	i = 0;
683746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	while (tda827xa_analog[i].lomax < N * 62500) {
684746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky		if (tda827xa_analog[i + 1].lomax == 0)
685746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky			break;
686746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky		i++;
687746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	}
688746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky
689746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	N = N << tda827xa_analog[i].spd;
690746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky
691746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	tuner_reg[0] = 0;
692746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	tuner_reg[1] = (unsigned char)(N>>8);
693746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	tuner_reg[2] = (unsigned char) N;
694746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	tuner_reg[3] = 0;
695746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	tuner_reg[4] = 0x16;
696746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	tuner_reg[5] = (tda827xa_analog[i].spd << 5) +
697746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky		       (tda827xa_analog[i].svco << 3) +
698746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky			tda827xa_analog[i].sbs;
699746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	tuner_reg[6] = 0x8b + (tda827xa_analog[i].gc3 << 4);
700746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	tuner_reg[7] = 0x1c;
701746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	tuner_reg[8] = 4;
702746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	tuner_reg[9] = 0x20;
703746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	tuner_reg[10] = 0x00;
704746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	msg.len = 11;
70568d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	tuner_transfer(fe, &msg, 1);
706746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky
707746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	tuner_reg[0] = 0x90;
708746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	tuner_reg[1] = 0xff;
709746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	tuner_reg[2] = 0xe0;
710746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	tuner_reg[3] = 0;
7115c82f4497b46e9c3877618bc36661a4abbf9c646Michael Krufky	tuner_reg[4] = 0x99 + (priv->lpsel << 1);
712746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	msg.len = 5;
71368d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	tuner_transfer(fe, &msg, 1);
714746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky
715746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	tuner_reg[0] = 0xa0;
716746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	tuner_reg[1] = 0xc0;
717746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	msg.len = 2;
71868d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	tuner_transfer(fe, &msg, 1);
719746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky
720746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	tuner_reg[0] = 0x30;
721746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	tuner_reg[1] = 0x10 + tda827xa_analog[i].scr;
72268d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	tuner_transfer(fe, &msg, 1);
723746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky
724746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	msg.flags = I2C_M_RD;
72568d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	tuner_transfer(fe, &msg, 1);
726746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	msg.flags = 0;
727746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	tuner_reg[1] >>= 4;
728746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	dprintk("AGC2 gain is: %d\n", tuner_reg[1]);
729746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	if (tuner_reg[1] < 1)
730746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky		tda827xa_lna_gain(fe, 0, params);
731746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky
732746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	msleep(100);
733746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	tuner_reg[0] = 0x60;
734746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	tuner_reg[1] = 0x3c;
73568d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	tuner_transfer(fe, &msg, 1);
736746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky
737746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	msleep(163);
738746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	tuner_reg[0] = 0x50;
739746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	tuner_reg[1] = 0x8f + (tda827xa_analog[i].gc3 << 4);
74068d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	tuner_transfer(fe, &msg, 1);
741746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky
742746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	tuner_reg[0] = 0x80;
743746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	tuner_reg[1] = 0x28;
74468d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	tuner_transfer(fe, &msg, 1);
745746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky
746746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	tuner_reg[0] = 0xb0;
747746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	tuner_reg[1] = 0x01;
74868d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	tuner_transfer(fe, &msg, 1);
749746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky
750746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	tuner_reg[0] = 0xc0;
7515c82f4497b46e9c3877618bc36661a4abbf9c646Michael Krufky	tuner_reg[1] = 0x19 + (priv->lpsel << 1);
75268d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	tuner_transfer(fe, &msg, 1);
753746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky
75492d90f1a57dcb6c6ab5a7b9ad949bdb7531931a4Mauro Carvalho Chehab	priv->frequency = params->frequency;
755746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky
756746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	return 0;
757746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky}
758746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky
759746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufkystatic void tda827xa_agcf(struct dvb_frontend *fe)
760746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky{
761746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	struct tda827x_priv *priv = fe->tuner_priv;
762746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	unsigned char data[] = {0x80, 0x2c};
763746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	struct i2c_msg msg = {.addr = priv->i2c_addr, .flags = 0,
764746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky			      .buf = data, .len = 2};
76568d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	tuner_transfer(fe, &msg, 1);
766746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky}
767746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky
768746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky/* ------------------------------------------------------------------ */
769746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky
7708ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufkystatic int tda827x_release(struct dvb_frontend *fe)
7718ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky{
7728ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	kfree(fe->tuner_priv);
7738ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	fe->tuner_priv = NULL;
7748ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	return 0;
7758ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky}
7768ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky
7778ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufkystatic int tda827x_get_frequency(struct dvb_frontend *fe, u32 *frequency)
7788ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky{
7798ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	struct tda827x_priv *priv = fe->tuner_priv;
7808ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	*frequency = priv->frequency;
7818ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	return 0;
7828ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky}
7838ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky
7848ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufkystatic int tda827x_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
7858ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky{
7868ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	struct tda827x_priv *priv = fe->tuner_priv;
7878ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	*bandwidth = priv->bandwidth;
7888ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	return 0;
7898ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky}
7908ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky
7918ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufkystatic int tda827x_init(struct dvb_frontend *fe)
7928ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky{
7938ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	struct tda827x_priv *priv = fe->tuner_priv;
7947bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann	dprintk("%s:\n", __func__);
7958ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	if (priv->cfg && priv->cfg->init)
7968ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky		priv->cfg->init(fe);
7978ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky
7988ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	return 0;
7998ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky}
8008ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky
8019971f4f1d3d71a5b6654ba226976ba82d2e047a4Hartmut Hackmannstatic int tda827x_probe_version(struct dvb_frontend *fe);
8029971f4f1d3d71a5b6654ba226976ba82d2e047a4Hartmut Hackmann
8039971f4f1d3d71a5b6654ba226976ba82d2e047a4Hartmut Hackmannstatic int tda827x_initial_init(struct dvb_frontend *fe)
8049971f4f1d3d71a5b6654ba226976ba82d2e047a4Hartmut Hackmann{
8059971f4f1d3d71a5b6654ba226976ba82d2e047a4Hartmut Hackmann	int ret;
8069971f4f1d3d71a5b6654ba226976ba82d2e047a4Hartmut Hackmann	ret = tda827x_probe_version(fe);
8079971f4f1d3d71a5b6654ba226976ba82d2e047a4Hartmut Hackmann	if (ret)
8089971f4f1d3d71a5b6654ba226976ba82d2e047a4Hartmut Hackmann		return ret;
8099971f4f1d3d71a5b6654ba226976ba82d2e047a4Hartmut Hackmann	return fe->ops.tuner_ops.init(fe);
8109971f4f1d3d71a5b6654ba226976ba82d2e047a4Hartmut Hackmann}
8119971f4f1d3d71a5b6654ba226976ba82d2e047a4Hartmut Hackmann
8129971f4f1d3d71a5b6654ba226976ba82d2e047a4Hartmut Hackmannstatic int tda827x_initial_sleep(struct dvb_frontend *fe)
8139971f4f1d3d71a5b6654ba226976ba82d2e047a4Hartmut Hackmann{
8149971f4f1d3d71a5b6654ba226976ba82d2e047a4Hartmut Hackmann	int ret;
8159971f4f1d3d71a5b6654ba226976ba82d2e047a4Hartmut Hackmann	ret = tda827x_probe_version(fe);
8169971f4f1d3d71a5b6654ba226976ba82d2e047a4Hartmut Hackmann	if (ret)
8179971f4f1d3d71a5b6654ba226976ba82d2e047a4Hartmut Hackmann		return ret;
8189971f4f1d3d71a5b6654ba226976ba82d2e047a4Hartmut Hackmann	return fe->ops.tuner_ops.sleep(fe);
8199971f4f1d3d71a5b6654ba226976ba82d2e047a4Hartmut Hackmann}
8208ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky
8218ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufkystatic struct dvb_tuner_ops tda827xo_tuner_ops = {
8228ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	.info = {
8238ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky		.name = "Philips TDA827X",
82411f65106adb25a9ef5b6d8911267b2365c97a759Hartmut Hackmann		.frequency_min  =  55000000,
82511f65106adb25a9ef5b6d8911267b2365c97a759Hartmut Hackmann		.frequency_max  = 860000000,
82611f65106adb25a9ef5b6d8911267b2365c97a759Hartmut Hackmann		.frequency_step =    250000
8278ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	},
8288ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	.release = tda827x_release,
8299971f4f1d3d71a5b6654ba226976ba82d2e047a4Hartmut Hackmann	.init = tda827x_initial_init,
8309971f4f1d3d71a5b6654ba226976ba82d2e047a4Hartmut Hackmann	.sleep = tda827x_initial_sleep,
8318ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	.set_params = tda827xo_set_params,
832746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	.set_analog_params = tda827xo_set_analog_params,
8338ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	.get_frequency = tda827x_get_frequency,
8348ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	.get_bandwidth = tda827x_get_bandwidth,
8358ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky};
8368ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky
8378ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufkystatic struct dvb_tuner_ops tda827xa_tuner_ops = {
8388ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	.info = {
8398ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky		.name = "Philips TDA827XA",
84011f65106adb25a9ef5b6d8911267b2365c97a759Hartmut Hackmann		.frequency_min  =  44000000,
84111f65106adb25a9ef5b6d8911267b2365c97a759Hartmut Hackmann		.frequency_max  = 906000000,
84211f65106adb25a9ef5b6d8911267b2365c97a759Hartmut Hackmann		.frequency_step =     62500
8438ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	},
8448ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	.release = tda827x_release,
8458ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	.init = tda827x_init,
8468ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	.sleep = tda827xa_sleep,
8478ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	.set_params = tda827xa_set_params,
848746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	.set_analog_params = tda827xa_set_analog_params,
8498ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	.get_frequency = tda827x_get_frequency,
8508ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	.get_bandwidth = tda827x_get_bandwidth,
8518ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky};
8528ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky
8539971f4f1d3d71a5b6654ba226976ba82d2e047a4Hartmut Hackmannstatic int tda827x_probe_version(struct dvb_frontend *fe)
85468d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab{
85568d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	u8 data;
85668d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	int rc;
8579971f4f1d3d71a5b6654ba226976ba82d2e047a4Hartmut Hackmann	struct tda827x_priv *priv = fe->tuner_priv;
8589971f4f1d3d71a5b6654ba226976ba82d2e047a4Hartmut Hackmann	struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = I2C_M_RD,
8598ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky			       .buf = &data, .len = 1 };
86068d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab
86168d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	rc = tuner_transfer(fe, &msg, 1);
86268d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab
86368d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab	if (rc < 0) {
8648ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky		printk("%s: could not read from tuner at addr: 0x%02x\n",
8657bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann		       __func__, msg.addr << 1);
86668d5ce70217ddd20baf3583ce25f08e869eb148fMauro Carvalho Chehab		return rc;
8679971f4f1d3d71a5b6654ba226976ba82d2e047a4Hartmut Hackmann	}
8689971f4f1d3d71a5b6654ba226976ba82d2e047a4Hartmut Hackmann	if ((data & 0x3c) == 0) {
8699971f4f1d3d71a5b6654ba226976ba82d2e047a4Hartmut Hackmann		dprintk("tda827x tuner found\n");
8709971f4f1d3d71a5b6654ba226976ba82d2e047a4Hartmut Hackmann		fe->ops.tuner_ops.init  = tda827x_init;
8719971f4f1d3d71a5b6654ba226976ba82d2e047a4Hartmut Hackmann		fe->ops.tuner_ops.sleep = tda827xo_sleep;
8723b0c453aa78be253b4414cd337c9975f91e2c894Michael Krufky		if (priv->cfg)
8733b0c453aa78be253b4414cd337c9975f91e2c894Michael Krufky			priv->cfg->agcf = tda827xo_agcf;
8749971f4f1d3d71a5b6654ba226976ba82d2e047a4Hartmut Hackmann	} else {
8759971f4f1d3d71a5b6654ba226976ba82d2e047a4Hartmut Hackmann		dprintk("tda827xa tuner found\n");
8769971f4f1d3d71a5b6654ba226976ba82d2e047a4Hartmut Hackmann		memcpy(&fe->ops.tuner_ops, &tda827xa_tuner_ops, sizeof(struct dvb_tuner_ops));
8773b0c453aa78be253b4414cd337c9975f91e2c894Michael Krufky		if (priv->cfg)
8783b0c453aa78be253b4414cd337c9975f91e2c894Michael Krufky			priv->cfg->agcf = tda827xa_agcf;
8798ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	}
8809971f4f1d3d71a5b6654ba226976ba82d2e047a4Hartmut Hackmann	return 0;
8819971f4f1d3d71a5b6654ba226976ba82d2e047a4Hartmut Hackmann}
8829971f4f1d3d71a5b6654ba226976ba82d2e047a4Hartmut Hackmann
8839971f4f1d3d71a5b6654ba226976ba82d2e047a4Hartmut Hackmannstruct dvb_frontend *tda827x_attach(struct dvb_frontend *fe, int addr,
8849971f4f1d3d71a5b6654ba226976ba82d2e047a4Hartmut Hackmann				    struct i2c_adapter *i2c,
8859971f4f1d3d71a5b6654ba226976ba82d2e047a4Hartmut Hackmann				    struct tda827x_config *cfg)
8869971f4f1d3d71a5b6654ba226976ba82d2e047a4Hartmut Hackmann{
8879971f4f1d3d71a5b6654ba226976ba82d2e047a4Hartmut Hackmann	struct tda827x_priv *priv = NULL;
8888ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky
8897bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann	dprintk("%s:\n", __func__);
8908ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	priv = kzalloc(sizeof(struct tda827x_priv), GFP_KERNEL);
8918ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	if (priv == NULL)
8928ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky		return NULL;
8938ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky
8948ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	priv->i2c_addr = addr;
8958ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	priv->i2c_adap = i2c;
8968ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	priv->cfg = cfg;
8979971f4f1d3d71a5b6654ba226976ba82d2e047a4Hartmut Hackmann	memcpy(&fe->ops.tuner_ops, &tda827xo_tuner_ops, sizeof(struct dvb_tuner_ops));
8988ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	fe->tuner_priv = priv;
8999971f4f1d3d71a5b6654ba226976ba82d2e047a4Hartmut Hackmann
900746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky	dprintk("type set to %s\n", fe->ops.tuner_ops.info.name);
901746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky
9028ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky	return fe;
9038ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky}
904ce1f8bdb0cbe9c5f57cf0256ef75fce06152547fMichael KrufkyEXPORT_SYMBOL_GPL(tda827x_attach);
9058ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky
9068ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael KrufkyMODULE_DESCRIPTION("DVB TDA827x driver");
90711f65106adb25a9ef5b6d8911267b2365c97a759Hartmut HackmannMODULE_AUTHOR("Hartmut Hackmann <hartmut.hackmann@t-online.de>");
90811f65106adb25a9ef5b6d8911267b2365c97a759Hartmut HackmannMODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
9098ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael KrufkyMODULE_LICENSE("GPL");
9108ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky
9118ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky/*
9128ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky * Overrides for Emacs so that we follow Linus's tabbing style.
9138ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky * ---------------------------------------------------------------------------
9148ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky * Local variables:
9158ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky * c-basic-offset: 8
9168ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky * End:
9178ce47dad8e2b9fcb899a67e6537337fa9c18c1f5Michael Krufky */
918