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