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