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