| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 1 | /* | 
 | 2 |  * | 
 | 3 |  * (c) 2005 Hartmut Hackmann | 
 | 4 |  * (c) 2007 Michael Krufky | 
 | 5 |  * | 
 | 6 |  *  This program is free software; you can redistribute it and/or modify | 
 | 7 |  *  it under the terms of the GNU General Public License as published by | 
 | 8 |  *  the Free Software Foundation; either version 2 of the License, or | 
 | 9 |  *  (at your option) any later version. | 
 | 10 |  * | 
 | 11 |  *  This program is distributed in the hope that it will be useful, | 
 | 12 |  *  but WITHOUT ANY WARRANTY; without even the implied warranty of | 
 | 13 |  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
 | 14 |  *  GNU General Public License for more details. | 
 | 15 |  * | 
 | 16 |  *  You should have received a copy of the GNU General Public License | 
 | 17 |  *  along with this program; if not, write to the Free Software | 
 | 18 |  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 
 | 19 |  */ | 
 | 20 |  | 
 | 21 | #include <linux/module.h> | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 22 | #include <asm/types.h> | 
| Michael Krufky | 746d9732 | 2007-08-25 19:08:45 -0300 | [diff] [blame] | 23 | #include <linux/dvb/frontend.h> | 
 | 24 | #include <linux/videodev2.h> | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 25 |  | 
 | 26 | #include "tda827x.h" | 
 | 27 |  | 
| Douglas Schilling Landgraf | ff699e6 | 2008-04-22 14:41:48 -0300 | [diff] [blame] | 28 | static int debug; | 
| Michael Krufky | 746d9732 | 2007-08-25 19:08:45 -0300 | [diff] [blame] | 29 | module_param(debug, int, 0644); | 
 | 30 | MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); | 
 | 31 |  | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 32 | #define dprintk(args...) \ | 
 | 33 | 	do {					    \ | 
 | 34 | 		if (debug) printk(KERN_DEBUG "tda827x: " args); \ | 
 | 35 | 	} while (0) | 
 | 36 |  | 
 | 37 | struct tda827x_priv { | 
 | 38 | 	int i2c_addr; | 
 | 39 | 	struct i2c_adapter *i2c_adap; | 
 | 40 | 	struct tda827x_config *cfg; | 
| Michael Krufky | 5c82f44 | 2007-10-22 01:10:39 -0300 | [diff] [blame] | 41 |  | 
 | 42 | 	unsigned int sgIF; | 
 | 43 | 	unsigned char lpsel; | 
 | 44 |  | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 45 | 	u32 frequency; | 
 | 46 | 	u32 bandwidth; | 
 | 47 | }; | 
 | 48 |  | 
| Michael Krufky | 5c82f44 | 2007-10-22 01:10:39 -0300 | [diff] [blame] | 49 | static void tda827x_set_std(struct dvb_frontend *fe, | 
 | 50 | 			    struct analog_parameters *params) | 
 | 51 | { | 
 | 52 | 	struct tda827x_priv *priv = fe->tuner_priv; | 
 | 53 | 	char *mode; | 
 | 54 |  | 
 | 55 | 	priv->lpsel = 0; | 
 | 56 | 	if (params->std & V4L2_STD_MN) { | 
 | 57 | 		priv->sgIF = 92; | 
 | 58 | 		priv->lpsel = 1; | 
 | 59 | 		mode = "MN"; | 
 | 60 | 	} else if (params->std & V4L2_STD_B) { | 
 | 61 | 		priv->sgIF = 108; | 
 | 62 | 		mode = "B"; | 
 | 63 | 	} else if (params->std & V4L2_STD_GH) { | 
 | 64 | 		priv->sgIF = 124; | 
 | 65 | 		mode = "GH"; | 
 | 66 | 	} else if (params->std & V4L2_STD_PAL_I) { | 
 | 67 | 		priv->sgIF = 124; | 
 | 68 | 		mode = "I"; | 
 | 69 | 	} else if (params->std & V4L2_STD_DK) { | 
 | 70 | 		priv->sgIF = 124; | 
 | 71 | 		mode = "DK"; | 
 | 72 | 	} else if (params->std & V4L2_STD_SECAM_L) { | 
 | 73 | 		priv->sgIF = 124; | 
 | 74 | 		mode = "L"; | 
 | 75 | 	} else if (params->std & V4L2_STD_SECAM_LC) { | 
 | 76 | 		priv->sgIF = 20; | 
 | 77 | 		mode = "LC"; | 
 | 78 | 	} else { | 
 | 79 | 		priv->sgIF = 124; | 
 | 80 | 		mode = "xx"; | 
 | 81 | 	} | 
 | 82 |  | 
| Mauro Carvalho Chehab | e5218ee | 2008-12-07 23:01:57 -0300 | [diff] [blame] | 83 | 	if (params->mode == V4L2_TUNER_RADIO) { | 
| Michael Krufky | 5c82f44 | 2007-10-22 01:10:39 -0300 | [diff] [blame] | 84 | 		priv->sgIF = 88; /* if frequency is 5.5 MHz */ | 
| Mauro Carvalho Chehab | e5218ee | 2008-12-07 23:01:57 -0300 | [diff] [blame] | 85 | 		dprintk("setting tda827x to radio FM\n"); | 
 | 86 | 	} else | 
 | 87 | 		dprintk("setting tda827x to system %s\n", mode); | 
| Michael Krufky | 5c82f44 | 2007-10-22 01:10:39 -0300 | [diff] [blame] | 88 | } | 
 | 89 |  | 
 | 90 |  | 
 | 91 | /* ------------------------------------------------------------------ */ | 
 | 92 |  | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 93 | struct tda827x_data { | 
 | 94 | 	u32 lomax; | 
 | 95 | 	u8  spd; | 
 | 96 | 	u8  bs; | 
 | 97 | 	u8  bp; | 
 | 98 | 	u8  cp; | 
 | 99 | 	u8  gc3; | 
 | 100 | 	u8 div1p5; | 
 | 101 | }; | 
 | 102 |  | 
| Michael Krufky | 746d9732 | 2007-08-25 19:08:45 -0300 | [diff] [blame] | 103 | static const struct tda827x_data tda827x_table[] = { | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 104 | 	{ .lomax =  62000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1}, | 
 | 105 | 	{ .lomax =  66000000, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1}, | 
 | 106 | 	{ .lomax =  76000000, .spd = 3, .bs = 1, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0}, | 
 | 107 | 	{ .lomax =  84000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0}, | 
 | 108 | 	{ .lomax =  93000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0}, | 
 | 109 | 	{ .lomax =  98000000, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0}, | 
 | 110 | 	{ .lomax = 109000000, .spd = 3, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0}, | 
 | 111 | 	{ .lomax = 123000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1}, | 
 | 112 | 	{ .lomax = 133000000, .spd = 2, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1}, | 
 | 113 | 	{ .lomax = 151000000, .spd = 2, .bs = 1, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0}, | 
 | 114 | 	{ .lomax = 154000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0}, | 
 | 115 | 	{ .lomax = 181000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 0, .div1p5 = 0}, | 
 | 116 | 	{ .lomax = 185000000, .spd = 2, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, | 
 | 117 | 	{ .lomax = 217000000, .spd = 2, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, | 
 | 118 | 	{ .lomax = 244000000, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1}, | 
 | 119 | 	{ .lomax = 265000000, .spd = 1, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1}, | 
 | 120 | 	{ .lomax = 302000000, .spd = 1, .bs = 1, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, | 
 | 121 | 	{ .lomax = 324000000, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, | 
 | 122 | 	{ .lomax = 370000000, .spd = 1, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0}, | 
 | 123 | 	{ .lomax = 454000000, .spd = 1, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0}, | 
 | 124 | 	{ .lomax = 493000000, .spd = 0, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1}, | 
 | 125 | 	{ .lomax = 530000000, .spd = 0, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1}, | 
 | 126 | 	{ .lomax = 554000000, .spd = 0, .bs = 1, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0}, | 
 | 127 | 	{ .lomax = 604000000, .spd = 0, .bs = 1, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0}, | 
 | 128 | 	{ .lomax = 696000000, .spd = 0, .bs = 2, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0}, | 
 | 129 | 	{ .lomax = 740000000, .spd = 0, .bs = 2, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0}, | 
 | 130 | 	{ .lomax = 820000000, .spd = 0, .bs = 3, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0}, | 
 | 131 | 	{ .lomax = 865000000, .spd = 0, .bs = 3, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0}, | 
 | 132 | 	{ .lomax =         0, .spd = 0, .bs = 0, .bp = 0, .cp = 0, .gc3 = 0, .div1p5 = 0} | 
 | 133 | }; | 
 | 134 |  | 
| Mauro Carvalho Chehab | 68d5ce7 | 2009-02-08 08:34:43 -0300 | [diff] [blame] | 135 | static int tuner_transfer(struct dvb_frontend *fe, | 
 | 136 | 			  struct i2c_msg *msg, | 
 | 137 | 			  const int size) | 
 | 138 | { | 
 | 139 | 	int rc; | 
 | 140 | 	struct tda827x_priv *priv = fe->tuner_priv; | 
 | 141 |  | 
 | 142 | 	if (fe->ops.i2c_gate_ctrl) | 
 | 143 | 		fe->ops.i2c_gate_ctrl(fe, 1); | 
 | 144 | 	rc = i2c_transfer(priv->i2c_adap, msg, size); | 
 | 145 | 	if (fe->ops.i2c_gate_ctrl) | 
 | 146 | 		fe->ops.i2c_gate_ctrl(fe, 0); | 
 | 147 |  | 
 | 148 | 	if (rc >= 0 && rc != size) | 
 | 149 | 		return -EIO; | 
 | 150 |  | 
 | 151 | 	return rc; | 
 | 152 | } | 
 | 153 |  | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 154 | static int tda827xo_set_params(struct dvb_frontend *fe, | 
 | 155 | 			       struct dvb_frontend_parameters *params) | 
 | 156 | { | 
 | 157 | 	struct tda827x_priv *priv = fe->tuner_priv; | 
 | 158 | 	u8 buf[14]; | 
| Mauro Carvalho Chehab | 68d5ce7 | 2009-02-08 08:34:43 -0300 | [diff] [blame] | 159 | 	int rc; | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 160 |  | 
 | 161 | 	struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0, | 
 | 162 | 			       .buf = buf, .len = sizeof(buf) }; | 
 | 163 | 	int i, tuner_freq, if_freq; | 
 | 164 | 	u32 N; | 
 | 165 |  | 
| Hartmut Hackmann | 7bff4b4 | 2008-04-22 14:46:08 -0300 | [diff] [blame] | 166 | 	dprintk("%s:\n", __func__); | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 167 | 	switch (params->u.ofdm.bandwidth) { | 
 | 168 | 	case BANDWIDTH_6_MHZ: | 
 | 169 | 		if_freq = 4000000; | 
 | 170 | 		break; | 
 | 171 | 	case BANDWIDTH_7_MHZ: | 
 | 172 | 		if_freq = 4500000; | 
 | 173 | 		break; | 
 | 174 | 	default:		   /* 8 MHz or Auto */ | 
 | 175 | 		if_freq = 5000000; | 
 | 176 | 		break; | 
 | 177 | 	} | 
 | 178 | 	tuner_freq = params->frequency + if_freq; | 
 | 179 |  | 
 | 180 | 	i = 0; | 
| Michael Krufky | 746d9732 | 2007-08-25 19:08:45 -0300 | [diff] [blame] | 181 | 	while (tda827x_table[i].lomax < tuner_freq) { | 
 | 182 | 		if (tda827x_table[i + 1].lomax == 0) | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 183 | 			break; | 
 | 184 | 		i++; | 
 | 185 | 	} | 
 | 186 |  | 
| Michael Krufky | 746d9732 | 2007-08-25 19:08:45 -0300 | [diff] [blame] | 187 | 	N = ((tuner_freq + 125000) / 250000) << (tda827x_table[i].spd + 2); | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 188 | 	buf[0] = 0; | 
 | 189 | 	buf[1] = (N>>8) | 0x40; | 
 | 190 | 	buf[2] = N & 0xff; | 
 | 191 | 	buf[3] = 0; | 
 | 192 | 	buf[4] = 0x52; | 
| Michael Krufky | 746d9732 | 2007-08-25 19:08:45 -0300 | [diff] [blame] | 193 | 	buf[5] = (tda827x_table[i].spd << 6) + (tda827x_table[i].div1p5 << 5) + | 
 | 194 | 				(tda827x_table[i].bs << 3) + | 
 | 195 | 				tda827x_table[i].bp; | 
 | 196 | 	buf[6] = (tda827x_table[i].gc3 << 4) + 0x8f; | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 197 | 	buf[7] = 0xbf; | 
 | 198 | 	buf[8] = 0x2a; | 
 | 199 | 	buf[9] = 0x05; | 
 | 200 | 	buf[10] = 0xff; | 
 | 201 | 	buf[11] = 0x00; | 
 | 202 | 	buf[12] = 0x00; | 
 | 203 | 	buf[13] = 0x40; | 
 | 204 |  | 
 | 205 | 	msg.len = 14; | 
| Mauro Carvalho Chehab | 68d5ce7 | 2009-02-08 08:34:43 -0300 | [diff] [blame] | 206 | 	rc = tuner_transfer(fe, &msg, 1); | 
 | 207 | 	if (rc < 0) | 
 | 208 | 		goto err; | 
 | 209 |  | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 210 | 	msleep(500); | 
 | 211 | 	/* correct CP value */ | 
 | 212 | 	buf[0] = 0x30; | 
| Michael Krufky | 746d9732 | 2007-08-25 19:08:45 -0300 | [diff] [blame] | 213 | 	buf[1] = 0x50 + tda827x_table[i].cp; | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 214 | 	msg.len = 2; | 
 | 215 |  | 
| Mauro Carvalho Chehab | 68d5ce7 | 2009-02-08 08:34:43 -0300 | [diff] [blame] | 216 | 	rc = tuner_transfer(fe, &msg, 1); | 
 | 217 | 	if (rc < 0) | 
 | 218 | 		goto err; | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 219 |  | 
| Mauro Carvalho Chehab | 92d90f1 | 2008-12-08 00:49:33 -0300 | [diff] [blame] | 220 | 	priv->frequency = params->frequency; | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 221 | 	priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0; | 
 | 222 |  | 
 | 223 | 	return 0; | 
| Mauro Carvalho Chehab | 68d5ce7 | 2009-02-08 08:34:43 -0300 | [diff] [blame] | 224 |  | 
 | 225 | err: | 
 | 226 | 	printk(KERN_ERR "%s: could not write to tuner at addr: 0x%02x\n", | 
 | 227 | 	       __func__, priv->i2c_addr << 1); | 
 | 228 | 	return rc; | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 229 | } | 
 | 230 |  | 
 | 231 | static int tda827xo_sleep(struct dvb_frontend *fe) | 
 | 232 | { | 
 | 233 | 	struct tda827x_priv *priv = fe->tuner_priv; | 
 | 234 | 	static u8 buf[] = { 0x30, 0xd0 }; | 
 | 235 | 	struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0, | 
 | 236 | 			       .buf = buf, .len = sizeof(buf) }; | 
 | 237 |  | 
| Hartmut Hackmann | 7bff4b4 | 2008-04-22 14:46:08 -0300 | [diff] [blame] | 238 | 	dprintk("%s:\n", __func__); | 
| Mauro Carvalho Chehab | 68d5ce7 | 2009-02-08 08:34:43 -0300 | [diff] [blame] | 239 | 	tuner_transfer(fe, &msg, 1); | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 240 |  | 
 | 241 | 	if (priv->cfg && priv->cfg->sleep) | 
 | 242 | 		priv->cfg->sleep(fe); | 
 | 243 |  | 
 | 244 | 	return 0; | 
 | 245 | } | 
 | 246 |  | 
 | 247 | /* ------------------------------------------------------------------ */ | 
 | 248 |  | 
| Michael Krufky | 746d9732 | 2007-08-25 19:08:45 -0300 | [diff] [blame] | 249 | static int tda827xo_set_analog_params(struct dvb_frontend *fe, | 
 | 250 | 				      struct analog_parameters *params) | 
 | 251 | { | 
 | 252 | 	unsigned char tuner_reg[8]; | 
 | 253 | 	unsigned char reg2[2]; | 
 | 254 | 	u32 N; | 
 | 255 | 	int i; | 
 | 256 | 	struct tda827x_priv *priv = fe->tuner_priv; | 
 | 257 | 	struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0 }; | 
 | 258 | 	unsigned int freq = params->frequency; | 
 | 259 |  | 
| Michael Krufky | 5c82f44 | 2007-10-22 01:10:39 -0300 | [diff] [blame] | 260 | 	tda827x_set_std(fe, params); | 
 | 261 |  | 
| Michael Krufky | 746d9732 | 2007-08-25 19:08:45 -0300 | [diff] [blame] | 262 | 	if (params->mode == V4L2_TUNER_RADIO) | 
 | 263 | 		freq = freq / 1000; | 
 | 264 |  | 
| Michael Krufky | 5c82f44 | 2007-10-22 01:10:39 -0300 | [diff] [blame] | 265 | 	N = freq + priv->sgIF; | 
| Michael Krufky | 746d9732 | 2007-08-25 19:08:45 -0300 | [diff] [blame] | 266 |  | 
 | 267 | 	i = 0; | 
 | 268 | 	while (tda827x_table[i].lomax < N * 62500) { | 
 | 269 | 		if (tda827x_table[i + 1].lomax == 0) | 
 | 270 | 			break; | 
 | 271 | 		i++; | 
 | 272 | 	} | 
 | 273 |  | 
 | 274 | 	N = N << tda827x_table[i].spd; | 
 | 275 |  | 
 | 276 | 	tuner_reg[0] = 0; | 
 | 277 | 	tuner_reg[1] = (unsigned char)(N>>8); | 
 | 278 | 	tuner_reg[2] = (unsigned char) N; | 
 | 279 | 	tuner_reg[3] = 0x40; | 
| Michael Krufky | 5c82f44 | 2007-10-22 01:10:39 -0300 | [diff] [blame] | 280 | 	tuner_reg[4] = 0x52 + (priv->lpsel << 5); | 
| Michael Krufky | 746d9732 | 2007-08-25 19:08:45 -0300 | [diff] [blame] | 281 | 	tuner_reg[5] = (tda827x_table[i].spd    << 6) + | 
 | 282 | 		       (tda827x_table[i].div1p5 << 5) + | 
 | 283 | 		       (tda827x_table[i].bs     << 3) + tda827x_table[i].bp; | 
 | 284 | 	tuner_reg[6] = 0x8f + (tda827x_table[i].gc3 << 4); | 
 | 285 | 	tuner_reg[7] = 0x8f; | 
 | 286 |  | 
 | 287 | 	msg.buf = tuner_reg; | 
 | 288 | 	msg.len = 8; | 
| Mauro Carvalho Chehab | 68d5ce7 | 2009-02-08 08:34:43 -0300 | [diff] [blame] | 289 | 	tuner_transfer(fe, &msg, 1); | 
| Michael Krufky | 746d9732 | 2007-08-25 19:08:45 -0300 | [diff] [blame] | 290 |  | 
 | 291 | 	msg.buf = reg2; | 
 | 292 | 	msg.len = 2; | 
 | 293 | 	reg2[0] = 0x80; | 
 | 294 | 	reg2[1] = 0; | 
| Mauro Carvalho Chehab | 68d5ce7 | 2009-02-08 08:34:43 -0300 | [diff] [blame] | 295 | 	tuner_transfer(fe, &msg, 1); | 
| Michael Krufky | 746d9732 | 2007-08-25 19:08:45 -0300 | [diff] [blame] | 296 |  | 
 | 297 | 	reg2[0] = 0x60; | 
 | 298 | 	reg2[1] = 0xbf; | 
| Mauro Carvalho Chehab | 68d5ce7 | 2009-02-08 08:34:43 -0300 | [diff] [blame] | 299 | 	tuner_transfer(fe, &msg, 1); | 
| Michael Krufky | 746d9732 | 2007-08-25 19:08:45 -0300 | [diff] [blame] | 300 |  | 
 | 301 | 	reg2[0] = 0x30; | 
 | 302 | 	reg2[1] = tuner_reg[4] + 0x80; | 
| Mauro Carvalho Chehab | 68d5ce7 | 2009-02-08 08:34:43 -0300 | [diff] [blame] | 303 | 	tuner_transfer(fe, &msg, 1); | 
| Michael Krufky | 746d9732 | 2007-08-25 19:08:45 -0300 | [diff] [blame] | 304 |  | 
 | 305 | 	msleep(1); | 
 | 306 | 	reg2[0] = 0x30; | 
 | 307 | 	reg2[1] = tuner_reg[4] + 4; | 
| Mauro Carvalho Chehab | 68d5ce7 | 2009-02-08 08:34:43 -0300 | [diff] [blame] | 308 | 	tuner_transfer(fe, &msg, 1); | 
| Michael Krufky | 746d9732 | 2007-08-25 19:08:45 -0300 | [diff] [blame] | 309 |  | 
 | 310 | 	msleep(1); | 
 | 311 | 	reg2[0] = 0x30; | 
 | 312 | 	reg2[1] = tuner_reg[4]; | 
| Mauro Carvalho Chehab | 68d5ce7 | 2009-02-08 08:34:43 -0300 | [diff] [blame] | 313 | 	tuner_transfer(fe, &msg, 1); | 
| Michael Krufky | 746d9732 | 2007-08-25 19:08:45 -0300 | [diff] [blame] | 314 |  | 
 | 315 | 	msleep(550); | 
 | 316 | 	reg2[0] = 0x30; | 
 | 317 | 	reg2[1] = (tuner_reg[4] & 0xfc) + tda827x_table[i].cp; | 
| Mauro Carvalho Chehab | 68d5ce7 | 2009-02-08 08:34:43 -0300 | [diff] [blame] | 318 | 	tuner_transfer(fe, &msg, 1); | 
| Michael Krufky | 746d9732 | 2007-08-25 19:08:45 -0300 | [diff] [blame] | 319 |  | 
 | 320 | 	reg2[0] = 0x60; | 
 | 321 | 	reg2[1] = 0x3f; | 
| Mauro Carvalho Chehab | 68d5ce7 | 2009-02-08 08:34:43 -0300 | [diff] [blame] | 322 | 	tuner_transfer(fe, &msg, 1); | 
| Michael Krufky | 746d9732 | 2007-08-25 19:08:45 -0300 | [diff] [blame] | 323 |  | 
 | 324 | 	reg2[0] = 0x80; | 
 | 325 | 	reg2[1] = 0x08;   /* Vsync en */ | 
| Mauro Carvalho Chehab | 68d5ce7 | 2009-02-08 08:34:43 -0300 | [diff] [blame] | 326 | 	tuner_transfer(fe, &msg, 1); | 
| Michael Krufky | 746d9732 | 2007-08-25 19:08:45 -0300 | [diff] [blame] | 327 |  | 
| Mauro Carvalho Chehab | 92d90f1 | 2008-12-08 00:49:33 -0300 | [diff] [blame] | 328 | 	priv->frequency = params->frequency; | 
| Michael Krufky | 746d9732 | 2007-08-25 19:08:45 -0300 | [diff] [blame] | 329 |  | 
 | 330 | 	return 0; | 
 | 331 | } | 
 | 332 |  | 
 | 333 | static void tda827xo_agcf(struct dvb_frontend *fe) | 
 | 334 | { | 
 | 335 | 	struct tda827x_priv *priv = fe->tuner_priv; | 
 | 336 | 	unsigned char data[] = { 0x80, 0x0c }; | 
 | 337 | 	struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0, | 
 | 338 | 			       .buf = data, .len = 2}; | 
 | 339 |  | 
| Mauro Carvalho Chehab | 68d5ce7 | 2009-02-08 08:34:43 -0300 | [diff] [blame] | 340 | 	tuner_transfer(fe, &msg, 1); | 
| Michael Krufky | 746d9732 | 2007-08-25 19:08:45 -0300 | [diff] [blame] | 341 | } | 
 | 342 |  | 
 | 343 | /* ------------------------------------------------------------------ */ | 
 | 344 |  | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 345 | struct tda827xa_data { | 
 | 346 | 	u32 lomax; | 
 | 347 | 	u8  svco; | 
 | 348 | 	u8  spd; | 
 | 349 | 	u8  scr; | 
 | 350 | 	u8  sbs; | 
 | 351 | 	u8  gc3; | 
 | 352 | }; | 
 | 353 |  | 
| klaas de waal | cf47d87 | 2009-03-25 17:53:02 -0300 | [diff] [blame] | 354 | static struct tda827xa_data tda827xa_dvbt[] = { | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 355 | 	{ .lomax =  56875000, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 1}, | 
 | 356 | 	{ .lomax =  67250000, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1}, | 
 | 357 | 	{ .lomax =  81250000, .svco = 1, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1}, | 
 | 358 | 	{ .lomax =  97500000, .svco = 2, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1}, | 
 | 359 | 	{ .lomax = 113750000, .svco = 3, .spd = 3, .scr = 0, .sbs = 1, .gc3 = 1}, | 
 | 360 | 	{ .lomax = 134500000, .svco = 0, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, | 
 | 361 | 	{ .lomax = 154000000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, | 
 | 362 | 	{ .lomax = 162500000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, | 
 | 363 | 	{ .lomax = 183000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, | 
 | 364 | 	{ .lomax = 195000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1}, | 
 | 365 | 	{ .lomax = 227500000, .svco = 3, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1}, | 
 | 366 | 	{ .lomax = 269000000, .svco = 0, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1}, | 
 | 367 | 	{ .lomax = 290000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1}, | 
 | 368 | 	{ .lomax = 325000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1}, | 
 | 369 | 	{ .lomax = 390000000, .svco = 2, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1}, | 
 | 370 | 	{ .lomax = 455000000, .svco = 3, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1}, | 
 | 371 | 	{ .lomax = 520000000, .svco = 0, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1}, | 
 | 372 | 	{ .lomax = 538000000, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1}, | 
 | 373 | 	{ .lomax = 550000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1}, | 
 | 374 | 	{ .lomax = 620000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0}, | 
 | 375 | 	{ .lomax = 650000000, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0}, | 
 | 376 | 	{ .lomax = 700000000, .svco = 2, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0}, | 
 | 377 | 	{ .lomax = 780000000, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0}, | 
 | 378 | 	{ .lomax = 820000000, .svco = 3, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0}, | 
 | 379 | 	{ .lomax = 870000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0}, | 
 | 380 | 	{ .lomax = 911000000, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 0}, | 
 | 381 | 	{ .lomax =         0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0} | 
 | 382 | }; | 
 | 383 |  | 
| klaas de waal | cf47d87 | 2009-03-25 17:53:02 -0300 | [diff] [blame] | 384 | static struct tda827xa_data tda827xa_dvbc[] = { | 
 | 385 | 	{ .lomax =  50125000, .svco = 2, .spd = 4, .scr = 2, .sbs = 0, .gc3 = 3}, | 
 | 386 | 	{ .lomax =  58500000, .svco = 3, .spd = 4, .scr = 2, .sbs = 0, .gc3 = 3}, | 
 | 387 | 	{ .lomax =  69250000, .svco = 0, .spd = 3, .scr = 2, .sbs = 0, .gc3 = 3}, | 
 | 388 | 	{ .lomax =  83625000, .svco = 1, .spd = 3, .scr = 2, .sbs = 0, .gc3 = 3}, | 
 | 389 | 	{ .lomax =  97500000, .svco = 2, .spd = 3, .scr = 2, .sbs = 0, .gc3 = 3}, | 
 | 390 | 	{ .lomax = 100250000, .svco = 2, .spd = 3, .scr = 2, .sbs = 1, .gc3 = 1}, | 
 | 391 | 	{ .lomax = 117000000, .svco = 3, .spd = 3, .scr = 2, .sbs = 1, .gc3 = 1}, | 
 | 392 | 	{ .lomax = 138500000, .svco = 0, .spd = 2, .scr = 2, .sbs = 1, .gc3 = 1}, | 
 | 393 | 	{ .lomax = 167250000, .svco = 1, .spd = 2, .scr = 2, .sbs = 1, .gc3 = 1}, | 
 | 394 | 	{ .lomax = 187000000, .svco = 2, .spd = 2, .scr = 2, .sbs = 1, .gc3 = 1}, | 
 | 395 | 	{ .lomax = 200500000, .svco = 2, .spd = 2, .scr = 2, .sbs = 2, .gc3 = 1}, | 
 | 396 | 	{ .lomax = 234000000, .svco = 3, .spd = 2, .scr = 2, .sbs = 2, .gc3 = 3}, | 
 | 397 | 	{ .lomax = 277000000, .svco = 0, .spd = 1, .scr = 2, .sbs = 2, .gc3 = 3}, | 
 | 398 | 	{ .lomax = 325000000, .svco = 1, .spd = 1, .scr = 2, .sbs = 2, .gc3 = 1}, | 
 | 399 | 	{ .lomax = 334500000, .svco = 1, .spd = 1, .scr = 2, .sbs = 3, .gc3 = 3}, | 
 | 400 | 	{ .lomax = 401000000, .svco = 2, .spd = 1, .scr = 2, .sbs = 3, .gc3 = 3}, | 
 | 401 | 	{ .lomax = 468000000, .svco = 3, .spd = 1, .scr = 2, .sbs = 3, .gc3 = 1}, | 
 | 402 | 	{ .lomax = 535000000, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1}, | 
 | 403 | 	{ .lomax = 554000000, .svco = 0, .spd = 0, .scr = 2, .sbs = 3, .gc3 = 1}, | 
 | 404 | 	{ .lomax = 638000000, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1}, | 
 | 405 | 	{ .lomax = 669000000, .svco = 1, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 1}, | 
 | 406 | 	{ .lomax = 720000000, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1}, | 
 | 407 | 	{ .lomax = 802000000, .svco = 2, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 1}, | 
 | 408 | 	{ .lomax = 835000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1}, | 
 | 409 | 	{ .lomax = 885000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1}, | 
 | 410 | 	{ .lomax = 911000000, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 1}, | 
 | 411 | 	{ .lomax =         0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0} | 
 | 412 | }; | 
 | 413 |  | 
| Michael Krufky | 746d9732 | 2007-08-25 19:08:45 -0300 | [diff] [blame] | 414 | static struct tda827xa_data tda827xa_analog[] = { | 
 | 415 | 	{ .lomax =  56875000, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 3}, | 
 | 416 | 	{ .lomax =  67250000, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3}, | 
 | 417 | 	{ .lomax =  81250000, .svco = 1, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3}, | 
 | 418 | 	{ .lomax =  97500000, .svco = 2, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3}, | 
 | 419 | 	{ .lomax = 113750000, .svco = 3, .spd = 3, .scr = 0, .sbs = 1, .gc3 = 1}, | 
 | 420 | 	{ .lomax = 134500000, .svco = 0, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, | 
 | 421 | 	{ .lomax = 154000000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, | 
 | 422 | 	{ .lomax = 162500000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, | 
 | 423 | 	{ .lomax = 183000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, | 
 | 424 | 	{ .lomax = 195000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1}, | 
 | 425 | 	{ .lomax = 227500000, .svco = 3, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 3}, | 
 | 426 | 	{ .lomax = 269000000, .svco = 0, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 3}, | 
 | 427 | 	{ .lomax = 325000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1}, | 
 | 428 | 	{ .lomax = 390000000, .svco = 2, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 3}, | 
 | 429 | 	{ .lomax = 455000000, .svco = 3, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 3}, | 
 | 430 | 	{ .lomax = 520000000, .svco = 0, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1}, | 
 | 431 | 	{ .lomax = 538000000, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1}, | 
 | 432 | 	{ .lomax = 554000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1}, | 
 | 433 | 	{ .lomax = 620000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0}, | 
 | 434 | 	{ .lomax = 650000000, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0}, | 
 | 435 | 	{ .lomax = 700000000, .svco = 2, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0}, | 
 | 436 | 	{ .lomax = 780000000, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0}, | 
 | 437 | 	{ .lomax = 820000000, .svco = 3, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0}, | 
 | 438 | 	{ .lomax = 870000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0}, | 
 | 439 | 	{ .lomax = 911000000, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 0}, | 
 | 440 | 	{ .lomax =         0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0} | 
 | 441 | }; | 
 | 442 |  | 
| Hartmut Hackmann | 7bff4b4 | 2008-04-22 14:46:08 -0300 | [diff] [blame] | 443 | static int tda827xa_sleep(struct dvb_frontend *fe) | 
 | 444 | { | 
 | 445 | 	struct tda827x_priv *priv = fe->tuner_priv; | 
 | 446 | 	static u8 buf[] = { 0x30, 0x90 }; | 
 | 447 | 	struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0, | 
 | 448 | 			       .buf = buf, .len = sizeof(buf) }; | 
 | 449 |  | 
 | 450 | 	dprintk("%s:\n", __func__); | 
| Hartmut Hackmann | 7bff4b4 | 2008-04-22 14:46:08 -0300 | [diff] [blame] | 451 |  | 
| Mauro Carvalho Chehab | 68d5ce7 | 2009-02-08 08:34:43 -0300 | [diff] [blame] | 452 | 	tuner_transfer(fe, &msg, 1); | 
| Hartmut Hackmann | 7bff4b4 | 2008-04-22 14:46:08 -0300 | [diff] [blame] | 453 |  | 
 | 454 | 	if (priv->cfg && priv->cfg->sleep) | 
 | 455 | 		priv->cfg->sleep(fe); | 
 | 456 |  | 
 | 457 | 	return 0; | 
 | 458 | } | 
 | 459 |  | 
 | 460 | static void tda827xa_lna_gain(struct dvb_frontend *fe, int high, | 
 | 461 | 			      struct analog_parameters *params) | 
 | 462 | { | 
 | 463 | 	struct tda827x_priv *priv = fe->tuner_priv; | 
 | 464 | 	unsigned char buf[] = {0x22, 0x01}; | 
 | 465 | 	int arg; | 
 | 466 | 	int gp_func; | 
| Sigmund Augdal | 67642a0 | 2008-06-05 12:53:08 -0300 | [diff] [blame] | 467 | 	struct i2c_msg msg = { .flags = 0, .buf = buf, .len = sizeof(buf) }; | 
| Hartmut Hackmann | 7bff4b4 | 2008-04-22 14:46:08 -0300 | [diff] [blame] | 468 |  | 
 | 469 | 	if (NULL == priv->cfg) { | 
 | 470 | 		dprintk("tda827x_config not defined, cannot set LNA gain!\n"); | 
 | 471 | 		return; | 
 | 472 | 	} | 
| Sigmund Augdal | 67642a0 | 2008-06-05 12:53:08 -0300 | [diff] [blame] | 473 | 	msg.addr = priv->cfg->switch_addr; | 
| Hartmut Hackmann | 7bff4b4 | 2008-04-22 14:46:08 -0300 | [diff] [blame] | 474 | 	if (priv->cfg->config) { | 
 | 475 | 		if (high) | 
 | 476 | 			dprintk("setting LNA to high gain\n"); | 
 | 477 | 		else | 
 | 478 | 			dprintk("setting LNA to low gain\n"); | 
 | 479 | 	} | 
 | 480 | 	switch (priv->cfg->config) { | 
 | 481 | 	case 0: /* no LNA */ | 
 | 482 | 		break; | 
 | 483 | 	case 1: /* switch is GPIO 0 of tda8290 */ | 
 | 484 | 	case 2: | 
 | 485 | 		if (params == NULL) { | 
 | 486 | 			gp_func = 0; | 
 | 487 | 			arg  = 0; | 
 | 488 | 		} else { | 
 | 489 | 			/* turn Vsync on */ | 
 | 490 | 			gp_func = 1; | 
 | 491 | 			if (params->std & V4L2_STD_MN) | 
 | 492 | 				arg = 1; | 
 | 493 | 			else | 
 | 494 | 				arg = 0; | 
 | 495 | 		} | 
| Michael Krufky | d7cba04 | 2008-09-12 13:31:45 -0300 | [diff] [blame] | 496 | 		if (fe->callback) | 
 | 497 | 			fe->callback(priv->i2c_adap->algo_data, | 
 | 498 | 				     DVB_FRONTEND_COMPONENT_TUNER, | 
 | 499 | 				     gp_func, arg); | 
| Hartmut Hackmann | 7bff4b4 | 2008-04-22 14:46:08 -0300 | [diff] [blame] | 500 | 		buf[1] = high ? 0 : 1; | 
 | 501 | 		if (priv->cfg->config == 2) | 
 | 502 | 			buf[1] = high ? 1 : 0; | 
| Mauro Carvalho Chehab | 68d5ce7 | 2009-02-08 08:34:43 -0300 | [diff] [blame] | 503 | 		tuner_transfer(fe, &msg, 1); | 
| Hartmut Hackmann | 7bff4b4 | 2008-04-22 14:46:08 -0300 | [diff] [blame] | 504 | 		break; | 
 | 505 | 	case 3: /* switch with GPIO of saa713x */ | 
| Michael Krufky | d7cba04 | 2008-09-12 13:31:45 -0300 | [diff] [blame] | 506 | 		if (fe->callback) | 
 | 507 | 			fe->callback(priv->i2c_adap->algo_data, | 
 | 508 | 				     DVB_FRONTEND_COMPONENT_TUNER, 0, high); | 
| Hartmut Hackmann | 7bff4b4 | 2008-04-22 14:46:08 -0300 | [diff] [blame] | 509 | 		break; | 
 | 510 | 	} | 
 | 511 | } | 
 | 512 |  | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 513 | static int tda827xa_set_params(struct dvb_frontend *fe, | 
 | 514 | 			       struct dvb_frontend_parameters *params) | 
 | 515 | { | 
 | 516 | 	struct tda827x_priv *priv = fe->tuner_priv; | 
| klaas de waal | cf47d87 | 2009-03-25 17:53:02 -0300 | [diff] [blame] | 517 | 	struct tda827xa_data *frequency_map = tda827xa_dvbt; | 
| Hartmut Hackmann | ede2200 | 2007-04-27 12:31:32 -0300 | [diff] [blame] | 518 | 	u8 buf[11]; | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 519 |  | 
 | 520 | 	struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0, | 
 | 521 | 			       .buf = buf, .len = sizeof(buf) }; | 
 | 522 |  | 
| Mauro Carvalho Chehab | 68d5ce7 | 2009-02-08 08:34:43 -0300 | [diff] [blame] | 523 | 	int i, tuner_freq, if_freq, rc; | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 524 | 	u32 N; | 
 | 525 |  | 
| Hartmut Hackmann | 7bff4b4 | 2008-04-22 14:46:08 -0300 | [diff] [blame] | 526 | 	dprintk("%s:\n", __func__); | 
 | 527 |  | 
 | 528 | 	tda827xa_lna_gain(fe, 1, NULL); | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 529 | 	msleep(20); | 
 | 530 |  | 
 | 531 | 	switch (params->u.ofdm.bandwidth) { | 
 | 532 | 	case BANDWIDTH_6_MHZ: | 
 | 533 | 		if_freq = 4000000; | 
 | 534 | 		break; | 
 | 535 | 	case BANDWIDTH_7_MHZ: | 
 | 536 | 		if_freq = 4500000; | 
 | 537 | 		break; | 
 | 538 | 	default:		   /* 8 MHz or Auto */ | 
 | 539 | 		if_freq = 5000000; | 
 | 540 | 		break; | 
 | 541 | 	} | 
 | 542 | 	tuner_freq = params->frequency + if_freq; | 
 | 543 |  | 
| klaas de waal | cf47d87 | 2009-03-25 17:53:02 -0300 | [diff] [blame] | 544 | 	if (fe->ops.info.type == FE_QAM) { | 
 | 545 | 		dprintk("%s select tda827xa_dvbc\n", __func__); | 
 | 546 | 		frequency_map = tda827xa_dvbc; | 
 | 547 | 	} | 
 | 548 |  | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 549 | 	i = 0; | 
| klaas de waal | cf47d87 | 2009-03-25 17:53:02 -0300 | [diff] [blame] | 550 | 	while (frequency_map[i].lomax < tuner_freq) { | 
 | 551 | 		if (frequency_map[i + 1].lomax == 0) | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 552 | 			break; | 
 | 553 | 		i++; | 
 | 554 | 	} | 
 | 555 |  | 
| klaas de waal | cf47d87 | 2009-03-25 17:53:02 -0300 | [diff] [blame] | 556 | 	N = ((tuner_freq + 31250) / 62500) << frequency_map[i].spd; | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 557 | 	buf[0] = 0;            // subaddress | 
 | 558 | 	buf[1] = N >> 8; | 
 | 559 | 	buf[2] = N & 0xff; | 
 | 560 | 	buf[3] = 0; | 
 | 561 | 	buf[4] = 0x16; | 
| klaas de waal | cf47d87 | 2009-03-25 17:53:02 -0300 | [diff] [blame] | 562 | 	buf[5] = (frequency_map[i].spd << 5) + (frequency_map[i].svco << 3) + | 
 | 563 | 			frequency_map[i].sbs; | 
 | 564 | 	buf[6] = 0x4b + (frequency_map[i].gc3 << 4); | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 565 | 	buf[7] = 0x1c; | 
 | 566 | 	buf[8] = 0x06; | 
 | 567 | 	buf[9] = 0x24; | 
 | 568 | 	buf[10] = 0x00; | 
 | 569 | 	msg.len = 11; | 
| Mauro Carvalho Chehab | 68d5ce7 | 2009-02-08 08:34:43 -0300 | [diff] [blame] | 570 | 	rc = tuner_transfer(fe, &msg, 1); | 
 | 571 | 	if (rc < 0) | 
 | 572 | 		goto err; | 
 | 573 |  | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 574 | 	buf[0] = 0x90; | 
 | 575 | 	buf[1] = 0xff; | 
 | 576 | 	buf[2] = 0x60; | 
 | 577 | 	buf[3] = 0x00; | 
 | 578 | 	buf[4] = 0x59;  // lpsel, for 6MHz + 2 | 
 | 579 | 	msg.len = 5; | 
| Mauro Carvalho Chehab | 68d5ce7 | 2009-02-08 08:34:43 -0300 | [diff] [blame] | 580 | 	rc = tuner_transfer(fe, &msg, 1); | 
 | 581 | 	if (rc < 0) | 
 | 582 | 		goto err; | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 583 |  | 
 | 584 | 	buf[0] = 0xa0; | 
 | 585 | 	buf[1] = 0x40; | 
 | 586 | 	msg.len = 2; | 
| Mauro Carvalho Chehab | 68d5ce7 | 2009-02-08 08:34:43 -0300 | [diff] [blame] | 587 | 	rc = tuner_transfer(fe, &msg, 1); | 
 | 588 | 	if (rc < 0) | 
 | 589 | 		goto err; | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 590 |  | 
 | 591 | 	msleep(11); | 
 | 592 | 	msg.flags = I2C_M_RD; | 
| Mauro Carvalho Chehab | 68d5ce7 | 2009-02-08 08:34:43 -0300 | [diff] [blame] | 593 | 	rc = tuner_transfer(fe, &msg, 1); | 
 | 594 | 	if (rc < 0) | 
 | 595 | 		goto err; | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 596 | 	msg.flags = 0; | 
 | 597 |  | 
 | 598 | 	buf[1] >>= 4; | 
 | 599 | 	dprintk("tda8275a AGC2 gain is: %d\n", buf[1]); | 
 | 600 | 	if ((buf[1]) < 2) { | 
| Hartmut Hackmann | 7bff4b4 | 2008-04-22 14:46:08 -0300 | [diff] [blame] | 601 | 		tda827xa_lna_gain(fe, 0, NULL); | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 602 | 		buf[0] = 0x60; | 
 | 603 | 		buf[1] = 0x0c; | 
| Mauro Carvalho Chehab | 68d5ce7 | 2009-02-08 08:34:43 -0300 | [diff] [blame] | 604 | 		rc = tuner_transfer(fe, &msg, 1); | 
 | 605 | 		if (rc < 0) | 
 | 606 | 			goto err; | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 607 | 	} | 
 | 608 |  | 
 | 609 | 	buf[0] = 0xc0; | 
 | 610 | 	buf[1] = 0x99;    // lpsel, for 6MHz + 2 | 
| Mauro Carvalho Chehab | 68d5ce7 | 2009-02-08 08:34:43 -0300 | [diff] [blame] | 611 | 	rc = tuner_transfer(fe, &msg, 1); | 
 | 612 | 	if (rc < 0) | 
 | 613 | 		goto err; | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 614 |  | 
 | 615 | 	buf[0] = 0x60; | 
 | 616 | 	buf[1] = 0x3c; | 
| Mauro Carvalho Chehab | 68d5ce7 | 2009-02-08 08:34:43 -0300 | [diff] [blame] | 617 | 	rc = tuner_transfer(fe, &msg, 1); | 
 | 618 | 	if (rc < 0) | 
 | 619 | 		goto err; | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 620 |  | 
 | 621 | 	/* correct CP value */ | 
 | 622 | 	buf[0] = 0x30; | 
| klaas de waal | cf47d87 | 2009-03-25 17:53:02 -0300 | [diff] [blame] | 623 | 	buf[1] = 0x10 + frequency_map[i].scr; | 
| Mauro Carvalho Chehab | 68d5ce7 | 2009-02-08 08:34:43 -0300 | [diff] [blame] | 624 | 	rc = tuner_transfer(fe, &msg, 1); | 
 | 625 | 	if (rc < 0) | 
 | 626 | 		goto err; | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 627 |  | 
 | 628 | 	msleep(163); | 
 | 629 | 	buf[0] = 0xc0; | 
 | 630 | 	buf[1] = 0x39;  // lpsel, for 6MHz + 2 | 
| Mauro Carvalho Chehab | 68d5ce7 | 2009-02-08 08:34:43 -0300 | [diff] [blame] | 631 | 	rc = tuner_transfer(fe, &msg, 1); | 
 | 632 | 	if (rc < 0) | 
 | 633 | 		goto err; | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 634 |  | 
 | 635 | 	msleep(3); | 
 | 636 | 	/* freeze AGC1 */ | 
 | 637 | 	buf[0] = 0x50; | 
| klaas de waal | cf47d87 | 2009-03-25 17:53:02 -0300 | [diff] [blame] | 638 | 	buf[1] = 0x4f + (frequency_map[i].gc3 << 4); | 
| Mauro Carvalho Chehab | 68d5ce7 | 2009-02-08 08:34:43 -0300 | [diff] [blame] | 639 | 	rc = tuner_transfer(fe, &msg, 1); | 
 | 640 | 	if (rc < 0) | 
 | 641 | 		goto err; | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 642 |  | 
| Mauro Carvalho Chehab | 92d90f1 | 2008-12-08 00:49:33 -0300 | [diff] [blame] | 643 | 	priv->frequency = params->frequency; | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 644 | 	priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0; | 
 | 645 |  | 
| Mauro Carvalho Chehab | 68d5ce7 | 2009-02-08 08:34:43 -0300 | [diff] [blame] | 646 |  | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 647 | 	return 0; | 
| Mauro Carvalho Chehab | 68d5ce7 | 2009-02-08 08:34:43 -0300 | [diff] [blame] | 648 |  | 
 | 649 | err: | 
 | 650 | 	printk(KERN_ERR "%s: could not write to tuner at addr: 0x%02x\n", | 
 | 651 | 	       __func__, priv->i2c_addr << 1); | 
 | 652 | 	return rc; | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 653 | } | 
 | 654 |  | 
| Michael Krufky | 746d9732 | 2007-08-25 19:08:45 -0300 | [diff] [blame] | 655 |  | 
 | 656 | static int tda827xa_set_analog_params(struct dvb_frontend *fe, | 
 | 657 | 				      struct analog_parameters *params) | 
 | 658 | { | 
 | 659 | 	unsigned char tuner_reg[11]; | 
 | 660 | 	u32 N; | 
 | 661 | 	int i; | 
 | 662 | 	struct tda827x_priv *priv = fe->tuner_priv; | 
 | 663 | 	struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0, | 
 | 664 | 			       .buf = tuner_reg, .len = sizeof(tuner_reg) }; | 
 | 665 | 	unsigned int freq = params->frequency; | 
 | 666 |  | 
| Michael Krufky | 5c82f44 | 2007-10-22 01:10:39 -0300 | [diff] [blame] | 667 | 	tda827x_set_std(fe, params); | 
 | 668 |  | 
| Michael Krufky | 746d9732 | 2007-08-25 19:08:45 -0300 | [diff] [blame] | 669 | 	tda827xa_lna_gain(fe, 1, params); | 
 | 670 | 	msleep(10); | 
 | 671 |  | 
 | 672 | 	if (params->mode == V4L2_TUNER_RADIO) | 
 | 673 | 		freq = freq / 1000; | 
 | 674 |  | 
| Michael Krufky | 5c82f44 | 2007-10-22 01:10:39 -0300 | [diff] [blame] | 675 | 	N = freq + priv->sgIF; | 
| Michael Krufky | 746d9732 | 2007-08-25 19:08:45 -0300 | [diff] [blame] | 676 |  | 
 | 677 | 	i = 0; | 
 | 678 | 	while (tda827xa_analog[i].lomax < N * 62500) { | 
 | 679 | 		if (tda827xa_analog[i + 1].lomax == 0) | 
 | 680 | 			break; | 
 | 681 | 		i++; | 
 | 682 | 	} | 
 | 683 |  | 
 | 684 | 	N = N << tda827xa_analog[i].spd; | 
 | 685 |  | 
 | 686 | 	tuner_reg[0] = 0; | 
 | 687 | 	tuner_reg[1] = (unsigned char)(N>>8); | 
 | 688 | 	tuner_reg[2] = (unsigned char) N; | 
 | 689 | 	tuner_reg[3] = 0; | 
 | 690 | 	tuner_reg[4] = 0x16; | 
 | 691 | 	tuner_reg[5] = (tda827xa_analog[i].spd << 5) + | 
 | 692 | 		       (tda827xa_analog[i].svco << 3) + | 
 | 693 | 			tda827xa_analog[i].sbs; | 
 | 694 | 	tuner_reg[6] = 0x8b + (tda827xa_analog[i].gc3 << 4); | 
 | 695 | 	tuner_reg[7] = 0x1c; | 
 | 696 | 	tuner_reg[8] = 4; | 
 | 697 | 	tuner_reg[9] = 0x20; | 
 | 698 | 	tuner_reg[10] = 0x00; | 
 | 699 | 	msg.len = 11; | 
| Mauro Carvalho Chehab | 68d5ce7 | 2009-02-08 08:34:43 -0300 | [diff] [blame] | 700 | 	tuner_transfer(fe, &msg, 1); | 
| Michael Krufky | 746d9732 | 2007-08-25 19:08:45 -0300 | [diff] [blame] | 701 |  | 
 | 702 | 	tuner_reg[0] = 0x90; | 
 | 703 | 	tuner_reg[1] = 0xff; | 
 | 704 | 	tuner_reg[2] = 0xe0; | 
 | 705 | 	tuner_reg[3] = 0; | 
| Michael Krufky | 5c82f44 | 2007-10-22 01:10:39 -0300 | [diff] [blame] | 706 | 	tuner_reg[4] = 0x99 + (priv->lpsel << 1); | 
| Michael Krufky | 746d9732 | 2007-08-25 19:08:45 -0300 | [diff] [blame] | 707 | 	msg.len = 5; | 
| Mauro Carvalho Chehab | 68d5ce7 | 2009-02-08 08:34:43 -0300 | [diff] [blame] | 708 | 	tuner_transfer(fe, &msg, 1); | 
| Michael Krufky | 746d9732 | 2007-08-25 19:08:45 -0300 | [diff] [blame] | 709 |  | 
 | 710 | 	tuner_reg[0] = 0xa0; | 
 | 711 | 	tuner_reg[1] = 0xc0; | 
 | 712 | 	msg.len = 2; | 
| Mauro Carvalho Chehab | 68d5ce7 | 2009-02-08 08:34:43 -0300 | [diff] [blame] | 713 | 	tuner_transfer(fe, &msg, 1); | 
| Michael Krufky | 746d9732 | 2007-08-25 19:08:45 -0300 | [diff] [blame] | 714 |  | 
 | 715 | 	tuner_reg[0] = 0x30; | 
 | 716 | 	tuner_reg[1] = 0x10 + tda827xa_analog[i].scr; | 
| Mauro Carvalho Chehab | 68d5ce7 | 2009-02-08 08:34:43 -0300 | [diff] [blame] | 717 | 	tuner_transfer(fe, &msg, 1); | 
| Michael Krufky | 746d9732 | 2007-08-25 19:08:45 -0300 | [diff] [blame] | 718 |  | 
 | 719 | 	msg.flags = I2C_M_RD; | 
| Mauro Carvalho Chehab | 68d5ce7 | 2009-02-08 08:34:43 -0300 | [diff] [blame] | 720 | 	tuner_transfer(fe, &msg, 1); | 
| Michael Krufky | 746d9732 | 2007-08-25 19:08:45 -0300 | [diff] [blame] | 721 | 	msg.flags = 0; | 
 | 722 | 	tuner_reg[1] >>= 4; | 
 | 723 | 	dprintk("AGC2 gain is: %d\n", tuner_reg[1]); | 
 | 724 | 	if (tuner_reg[1] < 1) | 
 | 725 | 		tda827xa_lna_gain(fe, 0, params); | 
 | 726 |  | 
 | 727 | 	msleep(100); | 
 | 728 | 	tuner_reg[0] = 0x60; | 
 | 729 | 	tuner_reg[1] = 0x3c; | 
| Mauro Carvalho Chehab | 68d5ce7 | 2009-02-08 08:34:43 -0300 | [diff] [blame] | 730 | 	tuner_transfer(fe, &msg, 1); | 
| Michael Krufky | 746d9732 | 2007-08-25 19:08:45 -0300 | [diff] [blame] | 731 |  | 
 | 732 | 	msleep(163); | 
 | 733 | 	tuner_reg[0] = 0x50; | 
 | 734 | 	tuner_reg[1] = 0x8f + (tda827xa_analog[i].gc3 << 4); | 
| Mauro Carvalho Chehab | 68d5ce7 | 2009-02-08 08:34:43 -0300 | [diff] [blame] | 735 | 	tuner_transfer(fe, &msg, 1); | 
| Michael Krufky | 746d9732 | 2007-08-25 19:08:45 -0300 | [diff] [blame] | 736 |  | 
 | 737 | 	tuner_reg[0] = 0x80; | 
 | 738 | 	tuner_reg[1] = 0x28; | 
| Mauro Carvalho Chehab | 68d5ce7 | 2009-02-08 08:34:43 -0300 | [diff] [blame] | 739 | 	tuner_transfer(fe, &msg, 1); | 
| Michael Krufky | 746d9732 | 2007-08-25 19:08:45 -0300 | [diff] [blame] | 740 |  | 
 | 741 | 	tuner_reg[0] = 0xb0; | 
 | 742 | 	tuner_reg[1] = 0x01; | 
| Mauro Carvalho Chehab | 68d5ce7 | 2009-02-08 08:34:43 -0300 | [diff] [blame] | 743 | 	tuner_transfer(fe, &msg, 1); | 
| Michael Krufky | 746d9732 | 2007-08-25 19:08:45 -0300 | [diff] [blame] | 744 |  | 
 | 745 | 	tuner_reg[0] = 0xc0; | 
| Michael Krufky | 5c82f44 | 2007-10-22 01:10:39 -0300 | [diff] [blame] | 746 | 	tuner_reg[1] = 0x19 + (priv->lpsel << 1); | 
| Mauro Carvalho Chehab | 68d5ce7 | 2009-02-08 08:34:43 -0300 | [diff] [blame] | 747 | 	tuner_transfer(fe, &msg, 1); | 
| Michael Krufky | 746d9732 | 2007-08-25 19:08:45 -0300 | [diff] [blame] | 748 |  | 
| Mauro Carvalho Chehab | 92d90f1 | 2008-12-08 00:49:33 -0300 | [diff] [blame] | 749 | 	priv->frequency = params->frequency; | 
| Michael Krufky | 746d9732 | 2007-08-25 19:08:45 -0300 | [diff] [blame] | 750 |  | 
 | 751 | 	return 0; | 
 | 752 | } | 
 | 753 |  | 
 | 754 | static void tda827xa_agcf(struct dvb_frontend *fe) | 
 | 755 | { | 
 | 756 | 	struct tda827x_priv *priv = fe->tuner_priv; | 
 | 757 | 	unsigned char data[] = {0x80, 0x2c}; | 
 | 758 | 	struct i2c_msg msg = {.addr = priv->i2c_addr, .flags = 0, | 
 | 759 | 			      .buf = data, .len = 2}; | 
| Mauro Carvalho Chehab | 68d5ce7 | 2009-02-08 08:34:43 -0300 | [diff] [blame] | 760 | 	tuner_transfer(fe, &msg, 1); | 
| Michael Krufky | 746d9732 | 2007-08-25 19:08:45 -0300 | [diff] [blame] | 761 | } | 
 | 762 |  | 
 | 763 | /* ------------------------------------------------------------------ */ | 
 | 764 |  | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 765 | static int tda827x_release(struct dvb_frontend *fe) | 
 | 766 | { | 
 | 767 | 	kfree(fe->tuner_priv); | 
 | 768 | 	fe->tuner_priv = NULL; | 
 | 769 | 	return 0; | 
 | 770 | } | 
 | 771 |  | 
 | 772 | static int tda827x_get_frequency(struct dvb_frontend *fe, u32 *frequency) | 
 | 773 | { | 
 | 774 | 	struct tda827x_priv *priv = fe->tuner_priv; | 
 | 775 | 	*frequency = priv->frequency; | 
 | 776 | 	return 0; | 
 | 777 | } | 
 | 778 |  | 
 | 779 | static int tda827x_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) | 
 | 780 | { | 
 | 781 | 	struct tda827x_priv *priv = fe->tuner_priv; | 
 | 782 | 	*bandwidth = priv->bandwidth; | 
 | 783 | 	return 0; | 
 | 784 | } | 
 | 785 |  | 
 | 786 | static int tda827x_init(struct dvb_frontend *fe) | 
 | 787 | { | 
 | 788 | 	struct tda827x_priv *priv = fe->tuner_priv; | 
| Hartmut Hackmann | 7bff4b4 | 2008-04-22 14:46:08 -0300 | [diff] [blame] | 789 | 	dprintk("%s:\n", __func__); | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 790 | 	if (priv->cfg && priv->cfg->init) | 
 | 791 | 		priv->cfg->init(fe); | 
 | 792 |  | 
 | 793 | 	return 0; | 
 | 794 | } | 
 | 795 |  | 
| Hartmut Hackmann | 9971f4f | 2007-03-23 21:00:07 -0300 | [diff] [blame] | 796 | static int tda827x_probe_version(struct dvb_frontend *fe); | 
 | 797 |  | 
 | 798 | static int tda827x_initial_init(struct dvb_frontend *fe) | 
 | 799 | { | 
 | 800 | 	int ret; | 
 | 801 | 	ret = tda827x_probe_version(fe); | 
 | 802 | 	if (ret) | 
 | 803 | 		return ret; | 
 | 804 | 	return fe->ops.tuner_ops.init(fe); | 
 | 805 | } | 
 | 806 |  | 
 | 807 | static int tda827x_initial_sleep(struct dvb_frontend *fe) | 
 | 808 | { | 
 | 809 | 	int ret; | 
 | 810 | 	ret = tda827x_probe_version(fe); | 
 | 811 | 	if (ret) | 
 | 812 | 		return ret; | 
 | 813 | 	return fe->ops.tuner_ops.sleep(fe); | 
 | 814 | } | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 815 |  | 
 | 816 | static struct dvb_tuner_ops tda827xo_tuner_ops = { | 
 | 817 | 	.info = { | 
 | 818 | 		.name = "Philips TDA827X", | 
| Hartmut Hackmann | 11f6510 | 2007-04-27 12:31:15 -0300 | [diff] [blame] | 819 | 		.frequency_min  =  55000000, | 
 | 820 | 		.frequency_max  = 860000000, | 
 | 821 | 		.frequency_step =    250000 | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 822 | 	}, | 
 | 823 | 	.release = tda827x_release, | 
| Hartmut Hackmann | 9971f4f | 2007-03-23 21:00:07 -0300 | [diff] [blame] | 824 | 	.init = tda827x_initial_init, | 
 | 825 | 	.sleep = tda827x_initial_sleep, | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 826 | 	.set_params = tda827xo_set_params, | 
| Michael Krufky | 746d9732 | 2007-08-25 19:08:45 -0300 | [diff] [blame] | 827 | 	.set_analog_params = tda827xo_set_analog_params, | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 828 | 	.get_frequency = tda827x_get_frequency, | 
 | 829 | 	.get_bandwidth = tda827x_get_bandwidth, | 
 | 830 | }; | 
 | 831 |  | 
 | 832 | static struct dvb_tuner_ops tda827xa_tuner_ops = { | 
 | 833 | 	.info = { | 
 | 834 | 		.name = "Philips TDA827XA", | 
| Hartmut Hackmann | 11f6510 | 2007-04-27 12:31:15 -0300 | [diff] [blame] | 835 | 		.frequency_min  =  44000000, | 
 | 836 | 		.frequency_max  = 906000000, | 
 | 837 | 		.frequency_step =     62500 | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 838 | 	}, | 
 | 839 | 	.release = tda827x_release, | 
 | 840 | 	.init = tda827x_init, | 
 | 841 | 	.sleep = tda827xa_sleep, | 
 | 842 | 	.set_params = tda827xa_set_params, | 
| Michael Krufky | 746d9732 | 2007-08-25 19:08:45 -0300 | [diff] [blame] | 843 | 	.set_analog_params = tda827xa_set_analog_params, | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 844 | 	.get_frequency = tda827x_get_frequency, | 
 | 845 | 	.get_bandwidth = tda827x_get_bandwidth, | 
 | 846 | }; | 
 | 847 |  | 
| Hartmut Hackmann | 9971f4f | 2007-03-23 21:00:07 -0300 | [diff] [blame] | 848 | static int tda827x_probe_version(struct dvb_frontend *fe) | 
| Mauro Carvalho Chehab | 68d5ce7 | 2009-02-08 08:34:43 -0300 | [diff] [blame] | 849 | { | 
 | 850 | 	u8 data; | 
 | 851 | 	int rc; | 
| Hartmut Hackmann | 9971f4f | 2007-03-23 21:00:07 -0300 | [diff] [blame] | 852 | 	struct tda827x_priv *priv = fe->tuner_priv; | 
 | 853 | 	struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = I2C_M_RD, | 
 | 854 | 			       .buf = &data, .len = 1 }; | 
| Mauro Carvalho Chehab | 68d5ce7 | 2009-02-08 08:34:43 -0300 | [diff] [blame] | 855 |  | 
 | 856 | 	rc = tuner_transfer(fe, &msg, 1); | 
 | 857 |  | 
 | 858 | 	if (rc < 0) { | 
| Hartmut Hackmann | 9971f4f | 2007-03-23 21:00:07 -0300 | [diff] [blame] | 859 | 		printk("%s: could not read from tuner at addr: 0x%02x\n", | 
| Hartmut Hackmann | 7bff4b4 | 2008-04-22 14:46:08 -0300 | [diff] [blame] | 860 | 		       __func__, msg.addr << 1); | 
| Mauro Carvalho Chehab | 68d5ce7 | 2009-02-08 08:34:43 -0300 | [diff] [blame] | 861 | 		return rc; | 
| Hartmut Hackmann | 9971f4f | 2007-03-23 21:00:07 -0300 | [diff] [blame] | 862 | 	} | 
 | 863 | 	if ((data & 0x3c) == 0) { | 
 | 864 | 		dprintk("tda827x tuner found\n"); | 
 | 865 | 		fe->ops.tuner_ops.init  = tda827x_init; | 
 | 866 | 		fe->ops.tuner_ops.sleep = tda827xo_sleep; | 
| Michael Krufky | 3b0c453 | 2007-11-18 14:15:42 -0300 | [diff] [blame] | 867 | 		if (priv->cfg) | 
 | 868 | 			priv->cfg->agcf = tda827xo_agcf; | 
| Hartmut Hackmann | 9971f4f | 2007-03-23 21:00:07 -0300 | [diff] [blame] | 869 | 	} else { | 
 | 870 | 		dprintk("tda827xa tuner found\n"); | 
 | 871 | 		memcpy(&fe->ops.tuner_ops, &tda827xa_tuner_ops, sizeof(struct dvb_tuner_ops)); | 
| Michael Krufky | 3b0c453 | 2007-11-18 14:15:42 -0300 | [diff] [blame] | 872 | 		if (priv->cfg) | 
 | 873 | 			priv->cfg->agcf = tda827xa_agcf; | 
| Hartmut Hackmann | 9971f4f | 2007-03-23 21:00:07 -0300 | [diff] [blame] | 874 | 	} | 
 | 875 | 	return 0; | 
 | 876 | } | 
 | 877 |  | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 878 | struct dvb_frontend *tda827x_attach(struct dvb_frontend *fe, int addr, | 
 | 879 | 				    struct i2c_adapter *i2c, | 
 | 880 | 				    struct tda827x_config *cfg) | 
 | 881 | { | 
 | 882 | 	struct tda827x_priv *priv = NULL; | 
| Hartmut Hackmann | 9971f4f | 2007-03-23 21:00:07 -0300 | [diff] [blame] | 883 |  | 
| Hartmut Hackmann | 7bff4b4 | 2008-04-22 14:46:08 -0300 | [diff] [blame] | 884 | 	dprintk("%s:\n", __func__); | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 885 | 	priv = kzalloc(sizeof(struct tda827x_priv), GFP_KERNEL); | 
 | 886 | 	if (priv == NULL) | 
 | 887 | 		return NULL; | 
 | 888 |  | 
 | 889 | 	priv->i2c_addr = addr; | 
 | 890 | 	priv->i2c_adap = i2c; | 
 | 891 | 	priv->cfg = cfg; | 
| Hartmut Hackmann | 9971f4f | 2007-03-23 21:00:07 -0300 | [diff] [blame] | 892 | 	memcpy(&fe->ops.tuner_ops, &tda827xo_tuner_ops, sizeof(struct dvb_tuner_ops)); | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 893 | 	fe->tuner_priv = priv; | 
| Hartmut Hackmann | 9971f4f | 2007-03-23 21:00:07 -0300 | [diff] [blame] | 894 |  | 
| Michael Krufky | 746d9732 | 2007-08-25 19:08:45 -0300 | [diff] [blame] | 895 | 	dprintk("type set to %s\n", fe->ops.tuner_ops.info.name); | 
 | 896 |  | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 897 | 	return fe; | 
 | 898 | } | 
| Michael Krufky | ce1f8bd | 2007-10-22 00:28:50 -0300 | [diff] [blame] | 899 | EXPORT_SYMBOL_GPL(tda827x_attach); | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 900 |  | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 901 | MODULE_DESCRIPTION("DVB TDA827x driver"); | 
| Hartmut Hackmann | 11f6510 | 2007-04-27 12:31:15 -0300 | [diff] [blame] | 902 | MODULE_AUTHOR("Hartmut Hackmann <hartmut.hackmann@t-online.de>"); | 
 | 903 | MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>"); | 
| Michael Krufky | 8ce47da | 2007-04-27 12:31:14 -0300 | [diff] [blame] | 904 | MODULE_LICENSE("GPL"); | 
 | 905 |  | 
 | 906 | /* | 
 | 907 |  * Overrides for Emacs so that we follow Linus's tabbing style. | 
 | 908 |  * --------------------------------------------------------------------------- | 
 | 909 |  * Local variables: | 
 | 910 |  * c-basic-offset: 8 | 
 | 911 |  * End: | 
 | 912 |  */ |