xref: /linux/drivers/media/tuners/tda18218.c (revision 0d456bad36d42d16022be045c8a53ddbb59ee478)
1 /*
2  * NXP TDA18218HN silicon tuner driver
3  *
4  * Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
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 "tda18218_priv.h"
22 
23 /* write multiple registers */
24 static int tda18218_wr_regs(struct tda18218_priv *priv, u8 reg, u8 *val, u8 len)
25 {
26 	int ret = 0, len2, remaining;
27 	u8 buf[1 + len];
28 	struct i2c_msg msg[1] = {
29 		{
30 			.addr = priv->cfg->i2c_address,
31 			.flags = 0,
32 			.buf = buf,
33 		}
34 	};
35 
36 	for (remaining = len; remaining > 0;
37 			remaining -= (priv->cfg->i2c_wr_max - 1)) {
38 		len2 = remaining;
39 		if (len2 > (priv->cfg->i2c_wr_max - 1))
40 			len2 = (priv->cfg->i2c_wr_max - 1);
41 
42 		msg[0].len = 1 + len2;
43 		buf[0] = reg + len - remaining;
44 		memcpy(&buf[1], &val[len - remaining], len2);
45 
46 		ret = i2c_transfer(priv->i2c, msg, 1);
47 		if (ret != 1)
48 			break;
49 	}
50 
51 	if (ret == 1) {
52 		ret = 0;
53 	} else {
54 		dev_warn(&priv->i2c->dev, "%s: i2c wr failed=%d reg=%02x " \
55 				"len=%d\n", KBUILD_MODNAME, ret, reg, len);
56 		ret = -EREMOTEIO;
57 	}
58 
59 	return ret;
60 }
61 
62 /* read multiple registers */
63 static int tda18218_rd_regs(struct tda18218_priv *priv, u8 reg, u8 *val, u8 len)
64 {
65 	int ret;
66 	u8 buf[reg+len]; /* we must start read always from reg 0x00 */
67 	struct i2c_msg msg[2] = {
68 		{
69 			.addr = priv->cfg->i2c_address,
70 			.flags = 0,
71 			.len = 1,
72 			.buf = "\x00",
73 		}, {
74 			.addr = priv->cfg->i2c_address,
75 			.flags = I2C_M_RD,
76 			.len = sizeof(buf),
77 			.buf = buf,
78 		}
79 	};
80 
81 	ret = i2c_transfer(priv->i2c, msg, 2);
82 	if (ret == 2) {
83 		memcpy(val, &buf[reg], len);
84 		ret = 0;
85 	} else {
86 		dev_warn(&priv->i2c->dev, "%s: i2c rd failed=%d reg=%02x " \
87 				"len=%d\n", KBUILD_MODNAME, ret, reg, len);
88 		ret = -EREMOTEIO;
89 	}
90 
91 	return ret;
92 }
93 
94 /* write single register */
95 static int tda18218_wr_reg(struct tda18218_priv *priv, u8 reg, u8 val)
96 {
97 	return tda18218_wr_regs(priv, reg, &val, 1);
98 }
99 
100 /* read single register */
101 
102 static int tda18218_rd_reg(struct tda18218_priv *priv, u8 reg, u8 *val)
103 {
104 	return tda18218_rd_regs(priv, reg, val, 1);
105 }
106 
107 static int tda18218_set_params(struct dvb_frontend *fe)
108 {
109 	struct tda18218_priv *priv = fe->tuner_priv;
110 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
111 	u32 bw = c->bandwidth_hz;
112 	int ret;
113 	u8 buf[3], i, BP_Filter, LP_Fc;
114 	u32 LO_Frac;
115 	/* TODO: find out correct AGC algorithm */
116 	u8 agc[][2] = {
117 		{ R20_AGC11, 0x60 },
118 		{ R23_AGC21, 0x02 },
119 		{ R20_AGC11, 0xa0 },
120 		{ R23_AGC21, 0x09 },
121 		{ R20_AGC11, 0xe0 },
122 		{ R23_AGC21, 0x0c },
123 		{ R20_AGC11, 0x40 },
124 		{ R23_AGC21, 0x01 },
125 		{ R20_AGC11, 0x80 },
126 		{ R23_AGC21, 0x08 },
127 		{ R20_AGC11, 0xc0 },
128 		{ R23_AGC21, 0x0b },
129 		{ R24_AGC22, 0x1c },
130 		{ R24_AGC22, 0x0c },
131 	};
132 
133 	if (fe->ops.i2c_gate_ctrl)
134 		fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
135 
136 	/* low-pass filter cut-off frequency */
137 	if (bw <= 6000000) {
138 		LP_Fc = 0;
139 		priv->if_frequency = 3000000;
140 	} else if (bw <= 7000000) {
141 		LP_Fc = 1;
142 		priv->if_frequency = 3500000;
143 	} else {
144 		LP_Fc = 2;
145 		priv->if_frequency = 4000000;
146 	}
147 
148 	LO_Frac = c->frequency + priv->if_frequency;
149 
150 	/* band-pass filter */
151 	if (LO_Frac < 188000000)
152 		BP_Filter = 3;
153 	else if (LO_Frac < 253000000)
154 		BP_Filter = 4;
155 	else if (LO_Frac < 343000000)
156 		BP_Filter = 5;
157 	else
158 		BP_Filter = 6;
159 
160 	buf[0] = (priv->regs[R1A_IF1] & ~7) | BP_Filter; /* BP_Filter */
161 	buf[1] = (priv->regs[R1B_IF2] & ~3) | LP_Fc; /* LP_Fc */
162 	buf[2] = priv->regs[R1C_AGC2B];
163 	ret = tda18218_wr_regs(priv, R1A_IF1, buf, 3);
164 	if (ret)
165 		goto error;
166 
167 	buf[0] = (LO_Frac / 1000) >> 12; /* LO_Frac_0 */
168 	buf[1] = (LO_Frac / 1000) >> 4; /* LO_Frac_1 */
169 	buf[2] = (LO_Frac / 1000) << 4 |
170 		(priv->regs[R0C_MD5] & 0x0f); /* LO_Frac_2 */
171 	ret = tda18218_wr_regs(priv, R0A_MD3, buf, 3);
172 	if (ret)
173 		goto error;
174 
175 	buf[0] = priv->regs[R0F_MD8] | (1 << 6); /* Freq_prog_Start */
176 	ret = tda18218_wr_regs(priv, R0F_MD8, buf, 1);
177 	if (ret)
178 		goto error;
179 
180 	buf[0] = priv->regs[R0F_MD8] & ~(1 << 6); /* Freq_prog_Start */
181 	ret = tda18218_wr_regs(priv, R0F_MD8, buf, 1);
182 	if (ret)
183 		goto error;
184 
185 	/* trigger AGC */
186 	for (i = 0; i < ARRAY_SIZE(agc); i++) {
187 		ret = tda18218_wr_reg(priv, agc[i][0], agc[i][1]);
188 		if (ret)
189 			goto error;
190 	}
191 
192 error:
193 	if (fe->ops.i2c_gate_ctrl)
194 		fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
195 
196 	if (ret)
197 		dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
198 
199 	return ret;
200 }
201 
202 static int tda18218_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
203 {
204 	struct tda18218_priv *priv = fe->tuner_priv;
205 	*frequency = priv->if_frequency;
206 	dev_dbg(&priv->i2c->dev, "%s: if_frequency=%d\n", __func__, *frequency);
207 	return 0;
208 }
209 
210 static int tda18218_sleep(struct dvb_frontend *fe)
211 {
212 	struct tda18218_priv *priv = fe->tuner_priv;
213 	int ret;
214 
215 	if (fe->ops.i2c_gate_ctrl)
216 		fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
217 
218 	/* standby */
219 	ret = tda18218_wr_reg(priv, R17_PD1, priv->regs[R17_PD1] | (1 << 0));
220 
221 	if (fe->ops.i2c_gate_ctrl)
222 		fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
223 
224 	if (ret)
225 		dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
226 
227 	return ret;
228 }
229 
230 static int tda18218_init(struct dvb_frontend *fe)
231 {
232 	struct tda18218_priv *priv = fe->tuner_priv;
233 	int ret;
234 
235 	/* TODO: calibrations */
236 
237 	if (fe->ops.i2c_gate_ctrl)
238 		fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
239 
240 	ret = tda18218_wr_regs(priv, R00_ID, priv->regs, TDA18218_NUM_REGS);
241 
242 	if (fe->ops.i2c_gate_ctrl)
243 		fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
244 
245 	if (ret)
246 		dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
247 
248 	return ret;
249 }
250 
251 static int tda18218_release(struct dvb_frontend *fe)
252 {
253 	kfree(fe->tuner_priv);
254 	fe->tuner_priv = NULL;
255 	return 0;
256 }
257 
258 static const struct dvb_tuner_ops tda18218_tuner_ops = {
259 	.info = {
260 		.name           = "NXP TDA18218",
261 
262 		.frequency_min  = 174000000,
263 		.frequency_max  = 864000000,
264 		.frequency_step =      1000,
265 	},
266 
267 	.release       = tda18218_release,
268 	.init          = tda18218_init,
269 	.sleep         = tda18218_sleep,
270 
271 	.set_params    = tda18218_set_params,
272 
273 	.get_if_frequency = tda18218_get_if_frequency,
274 };
275 
276 struct dvb_frontend *tda18218_attach(struct dvb_frontend *fe,
277 	struct i2c_adapter *i2c, struct tda18218_config *cfg)
278 {
279 	struct tda18218_priv *priv = NULL;
280 	u8 uninitialized_var(val);
281 	int ret;
282 	/* chip default registers values */
283 	static u8 def_regs[] = {
284 		0xc0, 0x88, 0x00, 0x8e, 0x03, 0x00, 0x00, 0xd0, 0x00, 0x40,
285 		0x00, 0x00, 0x07, 0xff, 0x84, 0x09, 0x00, 0x13, 0x00, 0x00,
286 		0x01, 0x84, 0x09, 0xf0, 0x19, 0x0a, 0x8e, 0x69, 0x98, 0x01,
287 		0x00, 0x58, 0x10, 0x40, 0x8c, 0x00, 0x0c, 0x48, 0x85, 0xc9,
288 		0xa7, 0x00, 0x00, 0x00, 0x30, 0x81, 0x80, 0x00, 0x39, 0x00,
289 		0x8a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xf6
290 	};
291 
292 	priv = kzalloc(sizeof(struct tda18218_priv), GFP_KERNEL);
293 	if (priv == NULL)
294 		return NULL;
295 
296 	priv->cfg = cfg;
297 	priv->i2c = i2c;
298 	fe->tuner_priv = priv;
299 
300 	if (fe->ops.i2c_gate_ctrl)
301 		fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
302 
303 	/* check if the tuner is there */
304 	ret = tda18218_rd_reg(priv, R00_ID, &val);
305 	dev_dbg(&priv->i2c->dev, "%s: ret=%d chip id=%02x\n", __func__, ret,
306 			val);
307 	if (ret || val != def_regs[R00_ID]) {
308 		kfree(priv);
309 		return NULL;
310 	}
311 
312 	dev_info(&priv->i2c->dev,
313 			"%s: NXP TDA18218HN successfully identified\n",
314 			KBUILD_MODNAME);
315 
316 	memcpy(&fe->ops.tuner_ops, &tda18218_tuner_ops,
317 		sizeof(struct dvb_tuner_ops));
318 	memcpy(priv->regs, def_regs, sizeof(def_regs));
319 
320 	/* loop-through enabled chip default register values */
321 	if (priv->cfg->loop_through) {
322 		priv->regs[R17_PD1] = 0xb0;
323 		priv->regs[R18_PD2] = 0x59;
324 	}
325 
326 	/* standby */
327 	ret = tda18218_wr_reg(priv, R17_PD1, priv->regs[R17_PD1] | (1 << 0));
328 	if (ret)
329 		dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
330 
331 	if (fe->ops.i2c_gate_ctrl)
332 		fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
333 
334 	return fe;
335 }
336 EXPORT_SYMBOL(tda18218_attach);
337 
338 MODULE_DESCRIPTION("NXP TDA18218HN silicon tuner driver");
339 MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
340 MODULE_LICENSE("GPL");
341