Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
fc2580.c
Go to the documentation of this file.
1 /*
2  * FCI FC2580 silicon tuner driver
3  *
4  * Copyright (C) 2012 Antti Palosaari <[email protected]>
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;
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__,
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 
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 }
526 
527 MODULE_DESCRIPTION("FCI FC2580 silicon tuner driver");
528 MODULE_AUTHOR("Antti Palosaari <[email protected]>");
529 MODULE_LICENSE("GPL");