Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
e4000.c
Go to the documentation of this file.
1 /*
2  * Elonics E4000 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 "e4000_priv.h"
22 
23 /* write multiple registers */
24 static int e4000_wr_regs(struct e4000_priv *priv, u8 reg, u8 *val, int len)
25 {
26  int ret;
27  u8 buf[1 + len];
28  struct i2c_msg msg[1] = {
29  {
30  .addr = priv->cfg->i2c_addr,
31  .flags = 0,
32  .len = sizeof(buf),
33  .buf = buf,
34  }
35  };
36 
37  buf[0] = reg;
38  memcpy(&buf[1], val, len);
39 
40  ret = i2c_transfer(priv->i2c, msg, 1);
41  if (ret == 1) {
42  ret = 0;
43  } else {
44  dev_warn(&priv->i2c->dev, "%s: i2c wr failed=%d reg=%02x " \
45  "len=%d\n", KBUILD_MODNAME, ret, reg, len);
46  ret = -EREMOTEIO;
47  }
48  return ret;
49 }
50 
51 /* read multiple registers */
52 static int e4000_rd_regs(struct e4000_priv *priv, u8 reg, u8 *val, int len)
53 {
54  int ret;
55  u8 buf[len];
56  struct i2c_msg msg[2] = {
57  {
58  .addr = priv->cfg->i2c_addr,
59  .flags = 0,
60  .len = 1,
61  .buf = &reg,
62  }, {
63  .addr = priv->cfg->i2c_addr,
64  .flags = I2C_M_RD,
65  .len = sizeof(buf),
66  .buf = buf,
67  }
68  };
69 
70  ret = i2c_transfer(priv->i2c, msg, 2);
71  if (ret == 2) {
72  memcpy(val, buf, len);
73  ret = 0;
74  } else {
75  dev_warn(&priv->i2c->dev, "%s: i2c rd failed=%d reg=%02x " \
76  "len=%d\n", KBUILD_MODNAME, ret, reg, len);
77  ret = -EREMOTEIO;
78  }
79 
80  return ret;
81 }
82 
83 /* write single register */
84 static int e4000_wr_reg(struct e4000_priv *priv, u8 reg, u8 val)
85 {
86  return e4000_wr_regs(priv, reg, &val, 1);
87 }
88 
89 /* read single register */
90 static int e4000_rd_reg(struct e4000_priv *priv, u8 reg, u8 *val)
91 {
92  return e4000_rd_regs(priv, reg, val, 1);
93 }
94 
95 static int e4000_init(struct dvb_frontend *fe)
96 {
97  struct e4000_priv *priv = fe->tuner_priv;
98  int ret;
99 
100  dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
101 
102  if (fe->ops.i2c_gate_ctrl)
103  fe->ops.i2c_gate_ctrl(fe, 1);
104 
105  /* dummy I2C to ensure I2C wakes up */
106  ret = e4000_wr_reg(priv, 0x02, 0x40);
107 
108  /* reset */
109  ret = e4000_wr_reg(priv, 0x00, 0x01);
110  if (ret < 0)
111  goto err;
112 
113  /* disable output clock */
114  ret = e4000_wr_reg(priv, 0x06, 0x00);
115  if (ret < 0)
116  goto err;
117 
118  ret = e4000_wr_reg(priv, 0x7a, 0x96);
119  if (ret < 0)
120  goto err;
121 
122  /* configure gains */
123  ret = e4000_wr_regs(priv, 0x7e, "\x01\xfe", 2);
124  if (ret < 0)
125  goto err;
126 
127  ret = e4000_wr_reg(priv, 0x82, 0x00);
128  if (ret < 0)
129  goto err;
130 
131  ret = e4000_wr_reg(priv, 0x24, 0x05);
132  if (ret < 0)
133  goto err;
134 
135  ret = e4000_wr_regs(priv, 0x87, "\x20\x01", 2);
136  if (ret < 0)
137  goto err;
138 
139  ret = e4000_wr_regs(priv, 0x9f, "\x7f\x07", 2);
140  if (ret < 0)
141  goto err;
142 
143  /*
144  * TODO: Implement DC offset control correctly.
145  * DC offsets has quite much effect for received signal quality in case
146  * of direct conversion tuners (Zero-IF). Surely we will now lose few
147  * decimals or even decibels from SNR...
148  */
149  /* DC offset control */
150  ret = e4000_wr_reg(priv, 0x2d, 0x0c);
151  if (ret < 0)
152  goto err;
153 
154  /* gain control */
155  ret = e4000_wr_reg(priv, 0x1a, 0x17);
156  if (ret < 0)
157  goto err;
158 
159  ret = e4000_wr_reg(priv, 0x1f, 0x1a);
160  if (ret < 0)
161  goto err;
162 
163  if (fe->ops.i2c_gate_ctrl)
164  fe->ops.i2c_gate_ctrl(fe, 0);
165 
166  return 0;
167 err:
168  if (fe->ops.i2c_gate_ctrl)
169  fe->ops.i2c_gate_ctrl(fe, 0);
170 
171  dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
172  return ret;
173 }
174 
175 static int e4000_sleep(struct dvb_frontend *fe)
176 {
177  struct e4000_priv *priv = fe->tuner_priv;
178  int ret;
179 
180  dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
181 
182  if (fe->ops.i2c_gate_ctrl)
183  fe->ops.i2c_gate_ctrl(fe, 1);
184 
185  ret = e4000_wr_reg(priv, 0x00, 0x00);
186  if (ret < 0)
187  goto err;
188 
189  if (fe->ops.i2c_gate_ctrl)
190  fe->ops.i2c_gate_ctrl(fe, 0);
191 
192  return 0;
193 err:
194  if (fe->ops.i2c_gate_ctrl)
195  fe->ops.i2c_gate_ctrl(fe, 0);
196 
197  dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
198  return ret;
199 }
200 
201 static int e4000_set_params(struct dvb_frontend *fe)
202 {
203  struct e4000_priv *priv = fe->tuner_priv;
205  int ret, i, sigma_delta;
206  unsigned int f_VCO;
207  u8 buf[5];
208 
209  dev_dbg(&priv->i2c->dev, "%s: delivery_system=%d frequency=%d " \
210  "bandwidth_hz=%d\n", __func__,
212 
213  if (fe->ops.i2c_gate_ctrl)
214  fe->ops.i2c_gate_ctrl(fe, 1);
215 
216  /* gain control manual */
217  ret = e4000_wr_reg(priv, 0x1a, 0x00);
218  if (ret < 0)
219  goto err;
220 
221  /* PLL */
222  for (i = 0; i < ARRAY_SIZE(e4000_pll_lut); i++) {
223  if (c->frequency <= e4000_pll_lut[i].freq)
224  break;
225  }
226 
227  if (i == ARRAY_SIZE(e4000_pll_lut))
228  goto err;
229 
230  /*
231  * Note: Currently f_VCO overflows when c->frequency is 1 073 741 824 Hz
232  * or more.
233  */
234  f_VCO = c->frequency * e4000_pll_lut[i].mul;
235  sigma_delta = 0x10000UL * (f_VCO % priv->cfg->clock) / priv->cfg->clock;
236  buf[0] = f_VCO / priv->cfg->clock;
237  buf[1] = (sigma_delta >> 0) & 0xff;
238  buf[2] = (sigma_delta >> 8) & 0xff;
239  buf[3] = 0x00;
240  buf[4] = e4000_pll_lut[i].div;
241 
242  dev_dbg(&priv->i2c->dev, "%s: f_VCO=%u pll div=%d sigma_delta=%04x\n",
243  __func__, f_VCO, buf[0], sigma_delta);
244 
245  ret = e4000_wr_regs(priv, 0x09, buf, 5);
246  if (ret < 0)
247  goto err;
248 
249  /* LNA filter (RF filter) */
250  for (i = 0; i < ARRAY_SIZE(e400_lna_filter_lut); i++) {
251  if (c->frequency <= e400_lna_filter_lut[i].freq)
252  break;
253  }
254 
255  if (i == ARRAY_SIZE(e400_lna_filter_lut))
256  goto err;
257 
258  ret = e4000_wr_reg(priv, 0x10, e400_lna_filter_lut[i].val);
259  if (ret < 0)
260  goto err;
261 
262  /* IF filters */
263  for (i = 0; i < ARRAY_SIZE(e4000_if_filter_lut); i++) {
264  if (c->bandwidth_hz <= e4000_if_filter_lut[i].freq)
265  break;
266  }
267 
268  if (i == ARRAY_SIZE(e4000_if_filter_lut))
269  goto err;
270 
271  buf[0] = e4000_if_filter_lut[i].reg11_val;
272  buf[1] = e4000_if_filter_lut[i].reg12_val;
273 
274  ret = e4000_wr_regs(priv, 0x11, buf, 2);
275  if (ret < 0)
276  goto err;
277 
278  /* frequency band */
279  for (i = 0; i < ARRAY_SIZE(e4000_band_lut); i++) {
280  if (c->frequency <= e4000_band_lut[i].freq)
281  break;
282  }
283 
284  if (i == ARRAY_SIZE(e4000_band_lut))
285  goto err;
286 
287  ret = e4000_wr_reg(priv, 0x07, e4000_band_lut[i].reg07_val);
288  if (ret < 0)
289  goto err;
290 
291  ret = e4000_wr_reg(priv, 0x78, e4000_band_lut[i].reg78_val);
292  if (ret < 0)
293  goto err;
294 
295  /* gain control auto */
296  ret = e4000_wr_reg(priv, 0x1a, 0x17);
297  if (ret < 0)
298  goto err;
299 
300  if (fe->ops.i2c_gate_ctrl)
301  fe->ops.i2c_gate_ctrl(fe, 0);
302 
303  return 0;
304 err:
305  if (fe->ops.i2c_gate_ctrl)
306  fe->ops.i2c_gate_ctrl(fe, 0);
307 
308  dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
309  return ret;
310 }
311 
312 static int e4000_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
313 {
314  struct e4000_priv *priv = fe->tuner_priv;
315 
316  dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
317 
318  *frequency = 0; /* Zero-IF */
319 
320  return 0;
321 }
322 
323 static int e4000_release(struct dvb_frontend *fe)
324 {
325  struct e4000_priv *priv = fe->tuner_priv;
326 
327  dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
328 
329  kfree(fe->tuner_priv);
330 
331  return 0;
332 }
333 
334 static const struct dvb_tuner_ops e4000_tuner_ops = {
335  .info = {
336  .name = "Elonics E4000",
337  .frequency_min = 174000000,
338  .frequency_max = 862000000,
339  },
340 
341  .release = e4000_release,
342 
343  .init = e4000_init,
344  .sleep = e4000_sleep,
345  .set_params = e4000_set_params,
346 
347  .get_if_frequency = e4000_get_if_frequency,
348 };
349 
351  struct i2c_adapter *i2c, const struct e4000_config *cfg)
352 {
353  struct e4000_priv *priv;
354  int ret;
355  u8 chip_id;
356 
357  if (fe->ops.i2c_gate_ctrl)
358  fe->ops.i2c_gate_ctrl(fe, 1);
359 
360  priv = kzalloc(sizeof(struct e4000_priv), GFP_KERNEL);
361  if (!priv) {
362  ret = -ENOMEM;
363  dev_err(&i2c->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME);
364  goto err;
365  }
366 
367  priv->cfg = cfg;
368  priv->i2c = i2c;
369 
370  /* check if the tuner is there */
371  ret = e4000_rd_reg(priv, 0x02, &chip_id);
372  if (ret < 0)
373  goto err;
374 
375  dev_dbg(&priv->i2c->dev, "%s: chip_id=%02x\n", __func__, chip_id);
376 
377  if (chip_id != 0x40)
378  goto err;
379 
380  /* put sleep as chip seems to be in normal mode by default */
381  ret = e4000_wr_reg(priv, 0x00, 0x00);
382  if (ret < 0)
383  goto err;
384 
385  dev_info(&priv->i2c->dev,
386  "%s: Elonics E4000 successfully identified\n",
387  KBUILD_MODNAME);
388 
389  fe->tuner_priv = priv;
390  memcpy(&fe->ops.tuner_ops, &e4000_tuner_ops,
391  sizeof(struct dvb_tuner_ops));
392 
393  if (fe->ops.i2c_gate_ctrl)
394  fe->ops.i2c_gate_ctrl(fe, 0);
395 
396  return fe;
397 err:
398  if (fe->ops.i2c_gate_ctrl)
399  fe->ops.i2c_gate_ctrl(fe, 0);
400 
401  dev_dbg(&i2c->dev, "%s: failed=%d\n", __func__, ret);
402  kfree(priv);
403  return NULL;
404 }
406 
407 MODULE_DESCRIPTION("Elonics E4000 silicon tuner driver");
408 MODULE_AUTHOR("Antti Palosaari <[email protected]>");
409 MODULE_LICENSE("GPL");