iommu/exynos: Fix checkpatch warning
[deliverable/linux.git] / drivers / media / tuners / fc2580.c
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 = 1UL * 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, 1UL * 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");
This page took 0.05221 seconds and 5 git commands to generate.