xref: /openbmc/linux/drivers/media/tuners/fc2580.c (revision 05bcf503)
1 /*
2  * FCI FC2580 silicon tuner driver
3  *
4  * Copyright (C) 2012 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 along
17  *    with this program; if not, write to the Free Software Foundation, Inc.,
18  *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19  */
20 
21 #include "fc2580_priv.h"
22 
23 /*
24  * TODO:
25  * I2C write and read works only for one single register. Multiple registers
26  * could not be accessed using normal register address auto-increment.
27  * There could be (very likely) register to change that behavior....
28  *
29  * Due to that limitation functions:
30  *   fc2580_wr_regs()
31  *   fc2580_rd_regs()
32  * could not be used for accessing more than one register at once.
33  *
34  * TODO:
35  * Currently it blind writes bunch of static registers from the
36  * fc2580_freq_regs_lut[] when fc2580_set_params() is called. Add some
37  * logic to reduce unneeded register writes.
38  * There is also don't-care registers, initialized with value 0xff, and those
39  * are also written to the chip currently (yes, not wise).
40  */
41 
42 /* write multiple registers */
43 static int fc2580_wr_regs(struct fc2580_priv *priv, u8 reg, u8 *val, int len)
44 {
45 	int ret;
46 	u8 buf[1 + len];
47 	struct i2c_msg msg[1] = {
48 		{
49 			.addr = priv->cfg->i2c_addr,
50 			.flags = 0,
51 			.len = sizeof(buf),
52 			.buf = buf,
53 		}
54 	};
55 
56 	buf[0] = reg;
57 	memcpy(&buf[1], val, len);
58 
59 	ret = i2c_transfer(priv->i2c, msg, 1);
60 	if (ret == 1) {
61 		ret = 0;
62 	} else {
63 		dev_warn(&priv->i2c->dev, "%s: i2c wr failed=%d reg=%02x " \
64 				"len=%d\n", KBUILD_MODNAME, ret, reg, len);
65 		ret = -EREMOTEIO;
66 	}
67 	return ret;
68 }
69 
70 /* read multiple registers */
71 static int fc2580_rd_regs(struct fc2580_priv *priv, u8 reg, u8 *val, int len)
72 {
73 	int ret;
74 	u8 buf[len];
75 	struct i2c_msg msg[2] = {
76 		{
77 			.addr = priv->cfg->i2c_addr,
78 			.flags = 0,
79 			.len = 1,
80 			.buf = &reg,
81 		}, {
82 			.addr = priv->cfg->i2c_addr,
83 			.flags = I2C_M_RD,
84 			.len = sizeof(buf),
85 			.buf = buf,
86 		}
87 	};
88 
89 	ret = i2c_transfer(priv->i2c, msg, 2);
90 	if (ret == 2) {
91 		memcpy(val, buf, len);
92 		ret = 0;
93 	} else {
94 		dev_warn(&priv->i2c->dev, "%s: i2c rd failed=%d reg=%02x " \
95 				"len=%d\n", KBUILD_MODNAME, ret, reg, len);
96 		ret = -EREMOTEIO;
97 	}
98 
99 	return ret;
100 }
101 
102 /* write single register */
103 static int fc2580_wr_reg(struct fc2580_priv *priv, u8 reg, u8 val)
104 {
105 	return fc2580_wr_regs(priv, reg, &val, 1);
106 }
107 
108 /* read single register */
109 static int fc2580_rd_reg(struct fc2580_priv *priv, u8 reg, u8 *val)
110 {
111 	return fc2580_rd_regs(priv, reg, val, 1);
112 }
113 
114 static int fc2580_set_params(struct dvb_frontend *fe)
115 {
116 	struct fc2580_priv *priv = fe->tuner_priv;
117 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
118 	int ret = 0, i;
119 	unsigned int r_val, n_val, k_val, k_val_reg, f_ref;
120 	u8 tmp_val, r18_val;
121 	u64 f_vco;
122 
123 	/*
124 	 * Fractional-N synthesizer/PLL.
125 	 * Most likely all those PLL calculations are not correct. I am not
126 	 * sure, but it looks like it is divider based Fractional-N synthesizer.
127 	 * There is divider for reference clock too?
128 	 * Anyhow, synthesizer calculation results seems to be quite correct.
129 	 */
130 
131 	dev_dbg(&priv->i2c->dev, "%s: delivery_system=%d frequency=%d " \
132 			"bandwidth_hz=%d\n", __func__,
133 			c->delivery_system, c->frequency, c->bandwidth_hz);
134 
135 	if (fe->ops.i2c_gate_ctrl)
136 		fe->ops.i2c_gate_ctrl(fe, 1);
137 
138 	/* PLL */
139 	for (i = 0; i < ARRAY_SIZE(fc2580_pll_lut); i++) {
140 		if (c->frequency <= fc2580_pll_lut[i].freq)
141 			break;
142 	}
143 
144 	if (i == ARRAY_SIZE(fc2580_pll_lut))
145 		goto err;
146 
147 	f_vco = c->frequency;
148 	f_vco *= fc2580_pll_lut[i].div;
149 
150 	if (f_vco >= 2600000000UL)
151 		tmp_val = 0x0e | fc2580_pll_lut[i].band;
152 	else
153 		tmp_val = 0x06 | fc2580_pll_lut[i].band;
154 
155 	ret = fc2580_wr_reg(priv, 0x02, tmp_val);
156 	if (ret < 0)
157 		goto err;
158 
159 	if (f_vco >= 2UL * 76 * priv->cfg->clock) {
160 		r_val = 1;
161 		r18_val = 0x00;
162 	} else if (f_vco >= 1UL * 76 * priv->cfg->clock) {
163 		r_val = 2;
164 		r18_val = 0x10;
165 	} else {
166 		r_val = 4;
167 		r18_val = 0x20;
168 	}
169 
170 	f_ref = 2UL * priv->cfg->clock / r_val;
171 	n_val = div_u64_rem(f_vco, f_ref, &k_val);
172 	k_val_reg = 1UL * k_val * (1 << 20) / f_ref;
173 
174 	ret = fc2580_wr_reg(priv, 0x18, r18_val | ((k_val_reg >> 16) & 0xff));
175 	if (ret < 0)
176 		goto err;
177 
178 	ret = fc2580_wr_reg(priv, 0x1a, (k_val_reg >> 8) & 0xff);
179 	if (ret < 0)
180 		goto err;
181 
182 	ret = fc2580_wr_reg(priv, 0x1b, (k_val_reg >> 0) & 0xff);
183 	if (ret < 0)
184 		goto err;
185 
186 	ret = fc2580_wr_reg(priv, 0x1c, n_val);
187 	if (ret < 0)
188 		goto err;
189 
190 	if (priv->cfg->clock >= 28000000) {
191 		ret = fc2580_wr_reg(priv, 0x4b, 0x22);
192 		if (ret < 0)
193 			goto err;
194 	}
195 
196 	if (fc2580_pll_lut[i].band == 0x00) {
197 		if (c->frequency <= 794000000)
198 			tmp_val = 0x9f;
199 		else
200 			tmp_val = 0x8f;
201 
202 		ret = fc2580_wr_reg(priv, 0x2d, tmp_val);
203 		if (ret < 0)
204 			goto err;
205 	}
206 
207 	/* registers */
208 	for (i = 0; i < ARRAY_SIZE(fc2580_freq_regs_lut); i++) {
209 		if (c->frequency <= fc2580_freq_regs_lut[i].freq)
210 			break;
211 	}
212 
213 	if (i == ARRAY_SIZE(fc2580_freq_regs_lut))
214 		goto err;
215 
216 	ret = fc2580_wr_reg(priv, 0x25, fc2580_freq_regs_lut[i].r25_val);
217 	if (ret < 0)
218 		goto err;
219 
220 	ret = fc2580_wr_reg(priv, 0x27, fc2580_freq_regs_lut[i].r27_val);
221 	if (ret < 0)
222 		goto err;
223 
224 	ret = fc2580_wr_reg(priv, 0x28, fc2580_freq_regs_lut[i].r28_val);
225 	if (ret < 0)
226 		goto err;
227 
228 	ret = fc2580_wr_reg(priv, 0x29, fc2580_freq_regs_lut[i].r29_val);
229 	if (ret < 0)
230 		goto err;
231 
232 	ret = fc2580_wr_reg(priv, 0x2b, fc2580_freq_regs_lut[i].r2b_val);
233 	if (ret < 0)
234 		goto err;
235 
236 	ret = fc2580_wr_reg(priv, 0x2c, fc2580_freq_regs_lut[i].r2c_val);
237 	if (ret < 0)
238 		goto err;
239 
240 	ret = fc2580_wr_reg(priv, 0x2d, fc2580_freq_regs_lut[i].r2d_val);
241 	if (ret < 0)
242 		goto err;
243 
244 	ret = fc2580_wr_reg(priv, 0x30, fc2580_freq_regs_lut[i].r30_val);
245 	if (ret < 0)
246 		goto err;
247 
248 	ret = fc2580_wr_reg(priv, 0x44, fc2580_freq_regs_lut[i].r44_val);
249 	if (ret < 0)
250 		goto err;
251 
252 	ret = fc2580_wr_reg(priv, 0x50, fc2580_freq_regs_lut[i].r50_val);
253 	if (ret < 0)
254 		goto err;
255 
256 	ret = fc2580_wr_reg(priv, 0x53, fc2580_freq_regs_lut[i].r53_val);
257 	if (ret < 0)
258 		goto err;
259 
260 	ret = fc2580_wr_reg(priv, 0x5f, fc2580_freq_regs_lut[i].r5f_val);
261 	if (ret < 0)
262 		goto err;
263 
264 	ret = fc2580_wr_reg(priv, 0x61, fc2580_freq_regs_lut[i].r61_val);
265 	if (ret < 0)
266 		goto err;
267 
268 	ret = fc2580_wr_reg(priv, 0x62, fc2580_freq_regs_lut[i].r62_val);
269 	if (ret < 0)
270 		goto err;
271 
272 	ret = fc2580_wr_reg(priv, 0x63, fc2580_freq_regs_lut[i].r63_val);
273 	if (ret < 0)
274 		goto err;
275 
276 	ret = fc2580_wr_reg(priv, 0x67, fc2580_freq_regs_lut[i].r67_val);
277 	if (ret < 0)
278 		goto err;
279 
280 	ret = fc2580_wr_reg(priv, 0x68, fc2580_freq_regs_lut[i].r68_val);
281 	if (ret < 0)
282 		goto err;
283 
284 	ret = fc2580_wr_reg(priv, 0x69, fc2580_freq_regs_lut[i].r69_val);
285 	if (ret < 0)
286 		goto err;
287 
288 	ret = fc2580_wr_reg(priv, 0x6a, fc2580_freq_regs_lut[i].r6a_val);
289 	if (ret < 0)
290 		goto err;
291 
292 	ret = fc2580_wr_reg(priv, 0x6b, fc2580_freq_regs_lut[i].r6b_val);
293 	if (ret < 0)
294 		goto err;
295 
296 	ret = fc2580_wr_reg(priv, 0x6c, fc2580_freq_regs_lut[i].r6c_val);
297 	if (ret < 0)
298 		goto err;
299 
300 	ret = fc2580_wr_reg(priv, 0x6d, fc2580_freq_regs_lut[i].r6d_val);
301 	if (ret < 0)
302 		goto err;
303 
304 	ret = fc2580_wr_reg(priv, 0x6e, fc2580_freq_regs_lut[i].r6e_val);
305 	if (ret < 0)
306 		goto err;
307 
308 	ret = fc2580_wr_reg(priv, 0x6f, fc2580_freq_regs_lut[i].r6f_val);
309 	if (ret < 0)
310 		goto err;
311 
312 	/* IF filters */
313 	for (i = 0; i < ARRAY_SIZE(fc2580_if_filter_lut); i++) {
314 		if (c->bandwidth_hz <= fc2580_if_filter_lut[i].freq)
315 			break;
316 	}
317 
318 	if (i == ARRAY_SIZE(fc2580_if_filter_lut))
319 		goto err;
320 
321 	ret = fc2580_wr_reg(priv, 0x36, fc2580_if_filter_lut[i].r36_val);
322 	if (ret < 0)
323 		goto err;
324 
325 	ret = fc2580_wr_reg(priv, 0x37, 1UL * priv->cfg->clock * \
326 			fc2580_if_filter_lut[i].mul / 1000000000);
327 	if (ret < 0)
328 		goto err;
329 
330 	ret = fc2580_wr_reg(priv, 0x39, fc2580_if_filter_lut[i].r39_val);
331 	if (ret < 0)
332 		goto err;
333 
334 	/* calibration? */
335 	ret = fc2580_wr_reg(priv, 0x2e, 0x09);
336 	if (ret < 0)
337 		goto err;
338 
339 	for (i = 0; i < 5; i++) {
340 		ret = fc2580_rd_reg(priv, 0x2f, &tmp_val);
341 		if (ret < 0)
342 			goto err;
343 
344 		/* done when [7:6] are set */
345 		if ((tmp_val & 0xc0) == 0xc0)
346 			break;
347 
348 		ret = fc2580_wr_reg(priv, 0x2e, 0x01);
349 		if (ret < 0)
350 			goto err;
351 
352 		ret = fc2580_wr_reg(priv, 0x2e, 0x09);
353 		if (ret < 0)
354 			goto err;
355 
356 		usleep_range(5000, 25000);
357 	}
358 
359 	dev_dbg(&priv->i2c->dev, "%s: loop=%i\n", __func__, i);
360 
361 	ret = fc2580_wr_reg(priv, 0x2e, 0x01);
362 	if (ret < 0)
363 		goto err;
364 
365 	if (fe->ops.i2c_gate_ctrl)
366 		fe->ops.i2c_gate_ctrl(fe, 0);
367 
368 	return 0;
369 err:
370 	if (fe->ops.i2c_gate_ctrl)
371 		fe->ops.i2c_gate_ctrl(fe, 0);
372 
373 	dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
374 	return ret;
375 }
376 
377 static int fc2580_init(struct dvb_frontend *fe)
378 {
379 	struct fc2580_priv *priv = fe->tuner_priv;
380 	int ret, i;
381 
382 	dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
383 
384 	if (fe->ops.i2c_gate_ctrl)
385 		fe->ops.i2c_gate_ctrl(fe, 1);
386 
387 	for (i = 0; i < ARRAY_SIZE(fc2580_init_reg_vals); i++) {
388 		ret = fc2580_wr_reg(priv, fc2580_init_reg_vals[i].reg,
389 				fc2580_init_reg_vals[i].val);
390 		if (ret < 0)
391 			goto err;
392 	}
393 
394 	if (fe->ops.i2c_gate_ctrl)
395 		fe->ops.i2c_gate_ctrl(fe, 0);
396 
397 	return 0;
398 err:
399 	if (fe->ops.i2c_gate_ctrl)
400 		fe->ops.i2c_gate_ctrl(fe, 0);
401 
402 	dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
403 	return ret;
404 }
405 
406 static int fc2580_sleep(struct dvb_frontend *fe)
407 {
408 	struct fc2580_priv *priv = fe->tuner_priv;
409 	int ret;
410 
411 	dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
412 
413 	if (fe->ops.i2c_gate_ctrl)
414 		fe->ops.i2c_gate_ctrl(fe, 1);
415 
416 	ret = fc2580_wr_reg(priv, 0x02, 0x0a);
417 	if (ret < 0)
418 		goto err;
419 
420 	if (fe->ops.i2c_gate_ctrl)
421 		fe->ops.i2c_gate_ctrl(fe, 0);
422 
423 	return 0;
424 err:
425 	if (fe->ops.i2c_gate_ctrl)
426 		fe->ops.i2c_gate_ctrl(fe, 0);
427 
428 	dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
429 	return ret;
430 }
431 
432 static int fc2580_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
433 {
434 	struct fc2580_priv *priv = fe->tuner_priv;
435 
436 	dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
437 
438 	*frequency = 0; /* Zero-IF */
439 
440 	return 0;
441 }
442 
443 static int fc2580_release(struct dvb_frontend *fe)
444 {
445 	struct fc2580_priv *priv = fe->tuner_priv;
446 
447 	dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
448 
449 	kfree(fe->tuner_priv);
450 
451 	return 0;
452 }
453 
454 static const struct dvb_tuner_ops fc2580_tuner_ops = {
455 	.info = {
456 		.name           = "FCI FC2580",
457 		.frequency_min  = 174000000,
458 		.frequency_max  = 862000000,
459 	},
460 
461 	.release = fc2580_release,
462 
463 	.init = fc2580_init,
464 	.sleep = fc2580_sleep,
465 	.set_params = fc2580_set_params,
466 
467 	.get_if_frequency = fc2580_get_if_frequency,
468 };
469 
470 struct dvb_frontend *fc2580_attach(struct dvb_frontend *fe,
471 		struct i2c_adapter *i2c, const struct fc2580_config *cfg)
472 {
473 	struct fc2580_priv *priv;
474 	int ret;
475 	u8 chip_id;
476 
477 	if (fe->ops.i2c_gate_ctrl)
478 		fe->ops.i2c_gate_ctrl(fe, 1);
479 
480 	priv = kzalloc(sizeof(struct fc2580_priv), GFP_KERNEL);
481 	if (!priv) {
482 		ret = -ENOMEM;
483 		dev_err(&i2c->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME);
484 		goto err;
485 	}
486 
487 	priv->cfg = cfg;
488 	priv->i2c = i2c;
489 
490 	/* check if the tuner is there */
491 	ret = fc2580_rd_reg(priv, 0x01, &chip_id);
492 	if (ret < 0)
493 		goto err;
494 
495 	dev_dbg(&priv->i2c->dev, "%s: chip_id=%02x\n", __func__, chip_id);
496 
497 	switch (chip_id) {
498 	case 0x56:
499 	case 0x5a:
500 		break;
501 	default:
502 		goto err;
503 	}
504 
505 	dev_info(&priv->i2c->dev,
506 			"%s: FCI FC2580 successfully identified\n",
507 			KBUILD_MODNAME);
508 
509 	fe->tuner_priv = priv;
510 	memcpy(&fe->ops.tuner_ops, &fc2580_tuner_ops,
511 			sizeof(struct dvb_tuner_ops));
512 
513 	if (fe->ops.i2c_gate_ctrl)
514 		fe->ops.i2c_gate_ctrl(fe, 0);
515 
516 	return fe;
517 err:
518 	if (fe->ops.i2c_gate_ctrl)
519 		fe->ops.i2c_gate_ctrl(fe, 0);
520 
521 	dev_dbg(&i2c->dev, "%s: failed=%d\n", __func__, ret);
522 	kfree(priv);
523 	return NULL;
524 }
525 EXPORT_SYMBOL(fc2580_attach);
526 
527 MODULE_DESCRIPTION("FCI FC2580 silicon tuner driver");
528 MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
529 MODULE_LICENSE("GPL");
530