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