Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
tda18218.c
Go to the documentation of this file.
1 /*
2  * NXP TDA18218HN silicon tuner driver
3  *
4  * Copyright (C) 2010 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
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  */
20 
21 #include "tda18218_priv.h"
22 
23 /* write multiple registers */
24 static int tda18218_wr_regs(struct tda18218_priv *priv, u8 reg, u8 *val, u8 len)
25 {
26  int ret = 0, len2, remaining;
27  u8 buf[1 + len];
28  struct i2c_msg msg[1] = {
29  {
30  .addr = priv->cfg->i2c_address,
31  .flags = 0,
32  .buf = buf,
33  }
34  };
35 
36  for (remaining = len; remaining > 0;
37  remaining -= (priv->cfg->i2c_wr_max - 1)) {
38  len2 = remaining;
39  if (len2 > (priv->cfg->i2c_wr_max - 1))
40  len2 = (priv->cfg->i2c_wr_max - 1);
41 
42  msg[0].len = 1 + len2;
43  buf[0] = reg + len - remaining;
44  memcpy(&buf[1], &val[len - remaining], len2);
45 
46  ret = i2c_transfer(priv->i2c, msg, 1);
47  if (ret != 1)
48  break;
49  }
50 
51  if (ret == 1) {
52  ret = 0;
53  } else {
54  dev_warn(&priv->i2c->dev, "%s: i2c wr failed=%d reg=%02x " \
55  "len=%d\n", KBUILD_MODNAME, ret, reg, len);
56  ret = -EREMOTEIO;
57  }
58 
59  return ret;
60 }
61 
62 /* read multiple registers */
63 static int tda18218_rd_regs(struct tda18218_priv *priv, u8 reg, u8 *val, u8 len)
64 {
65  int ret;
66  u8 buf[reg+len]; /* we must start read always from reg 0x00 */
67  struct i2c_msg msg[2] = {
68  {
69  .addr = priv->cfg->i2c_address,
70  .flags = 0,
71  .len = 1,
72  .buf = "\x00",
73  }, {
74  .addr = priv->cfg->i2c_address,
75  .flags = I2C_M_RD,
76  .len = sizeof(buf),
77  .buf = buf,
78  }
79  };
80 
81  ret = i2c_transfer(priv->i2c, msg, 2);
82  if (ret == 2) {
83  memcpy(val, &buf[reg], len);
84  ret = 0;
85  } else {
86  dev_warn(&priv->i2c->dev, "%s: i2c rd failed=%d reg=%02x " \
87  "len=%d\n", KBUILD_MODNAME, ret, reg, len);
88  ret = -EREMOTEIO;
89  }
90 
91  return ret;
92 }
93 
94 /* write single register */
95 static int tda18218_wr_reg(struct tda18218_priv *priv, u8 reg, u8 val)
96 {
97  return tda18218_wr_regs(priv, reg, &val, 1);
98 }
99 
100 /* read single register */
101 
102 static int tda18218_rd_reg(struct tda18218_priv *priv, u8 reg, u8 *val)
103 {
104  return tda18218_rd_regs(priv, reg, val, 1);
105 }
106 
107 static int tda18218_set_params(struct dvb_frontend *fe)
108 {
109  struct tda18218_priv *priv = fe->tuner_priv;
111  u32 bw = c->bandwidth_hz;
112  int ret;
113  u8 buf[3], i, BP_Filter, LP_Fc;
114  u32 LO_Frac;
115  /* TODO: find out correct AGC algorithm */
116  u8 agc[][2] = {
117  { R20_AGC11, 0x60 },
118  { R23_AGC21, 0x02 },
119  { R20_AGC11, 0xa0 },
120  { R23_AGC21, 0x09 },
121  { R20_AGC11, 0xe0 },
122  { R23_AGC21, 0x0c },
123  { R20_AGC11, 0x40 },
124  { R23_AGC21, 0x01 },
125  { R20_AGC11, 0x80 },
126  { R23_AGC21, 0x08 },
127  { R20_AGC11, 0xc0 },
128  { R23_AGC21, 0x0b },
129  { R24_AGC22, 0x1c },
130  { R24_AGC22, 0x0c },
131  };
132 
133  if (fe->ops.i2c_gate_ctrl)
134  fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
135 
136  /* low-pass filter cut-off frequency */
137  if (bw <= 6000000) {
138  LP_Fc = 0;
139  priv->if_frequency = 3000000;
140  } else if (bw <= 7000000) {
141  LP_Fc = 1;
142  priv->if_frequency = 3500000;
143  } else {
144  LP_Fc = 2;
145  priv->if_frequency = 4000000;
146  }
147 
148  LO_Frac = c->frequency + priv->if_frequency;
149 
150  /* band-pass filter */
151  if (LO_Frac < 188000000)
152  BP_Filter = 3;
153  else if (LO_Frac < 253000000)
154  BP_Filter = 4;
155  else if (LO_Frac < 343000000)
156  BP_Filter = 5;
157  else
158  BP_Filter = 6;
159 
160  buf[0] = (priv->regs[R1A_IF1] & ~7) | BP_Filter; /* BP_Filter */
161  buf[1] = (priv->regs[R1B_IF2] & ~3) | LP_Fc; /* LP_Fc */
162  buf[2] = priv->regs[R1C_AGC2B];
163  ret = tda18218_wr_regs(priv, R1A_IF1, buf, 3);
164  if (ret)
165  goto error;
166 
167  buf[0] = (LO_Frac / 1000) >> 12; /* LO_Frac_0 */
168  buf[1] = (LO_Frac / 1000) >> 4; /* LO_Frac_1 */
169  buf[2] = (LO_Frac / 1000) << 4 |
170  (priv->regs[R0C_MD5] & 0x0f); /* LO_Frac_2 */
171  ret = tda18218_wr_regs(priv, R0A_MD3, buf, 3);
172  if (ret)
173  goto error;
174 
175  buf[0] = priv->regs[R0F_MD8] | (1 << 6); /* Freq_prog_Start */
176  ret = tda18218_wr_regs(priv, R0F_MD8, buf, 1);
177  if (ret)
178  goto error;
179 
180  buf[0] = priv->regs[R0F_MD8] & ~(1 << 6); /* Freq_prog_Start */
181  ret = tda18218_wr_regs(priv, R0F_MD8, buf, 1);
182  if (ret)
183  goto error;
184 
185  /* trigger AGC */
186  for (i = 0; i < ARRAY_SIZE(agc); i++) {
187  ret = tda18218_wr_reg(priv, agc[i][0], agc[i][1]);
188  if (ret)
189  goto error;
190  }
191 
192 error:
193  if (fe->ops.i2c_gate_ctrl)
194  fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
195 
196  if (ret)
197  dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
198 
199  return ret;
200 }
201 
202 static int tda18218_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
203 {
204  struct tda18218_priv *priv = fe->tuner_priv;
205  *frequency = priv->if_frequency;
206  dev_dbg(&priv->i2c->dev, "%s: if_frequency=%d\n", __func__, *frequency);
207  return 0;
208 }
209 
210 static int tda18218_sleep(struct dvb_frontend *fe)
211 {
212  struct tda18218_priv *priv = fe->tuner_priv;
213  int ret;
214 
215  if (fe->ops.i2c_gate_ctrl)
216  fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
217 
218  /* standby */
219  ret = tda18218_wr_reg(priv, R17_PD1, priv->regs[R17_PD1] | (1 << 0));
220 
221  if (fe->ops.i2c_gate_ctrl)
222  fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
223 
224  if (ret)
225  dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
226 
227  return ret;
228 }
229 
230 static int tda18218_init(struct dvb_frontend *fe)
231 {
232  struct tda18218_priv *priv = fe->tuner_priv;
233  int ret;
234 
235  /* TODO: calibrations */
236 
237  if (fe->ops.i2c_gate_ctrl)
238  fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
239 
240  ret = tda18218_wr_regs(priv, R00_ID, priv->regs, TDA18218_NUM_REGS);
241 
242  if (fe->ops.i2c_gate_ctrl)
243  fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
244 
245  if (ret)
246  dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
247 
248  return ret;
249 }
250 
251 static int tda18218_release(struct dvb_frontend *fe)
252 {
253  kfree(fe->tuner_priv);
254  fe->tuner_priv = NULL;
255  return 0;
256 }
257 
258 static const struct dvb_tuner_ops tda18218_tuner_ops = {
259  .info = {
260  .name = "NXP TDA18218",
261 
262  .frequency_min = 174000000,
263  .frequency_max = 864000000,
264  .frequency_step = 1000,
265  },
266 
267  .release = tda18218_release,
268  .init = tda18218_init,
269  .sleep = tda18218_sleep,
270 
271  .set_params = tda18218_set_params,
272 
273  .get_if_frequency = tda18218_get_if_frequency,
274 };
275 
277  struct i2c_adapter *i2c, struct tda18218_config *cfg)
278 {
279  struct tda18218_priv *priv = NULL;
280  u8 uninitialized_var(val);
281  int ret;
282  /* chip default registers values */
283  static u8 def_regs[] = {
284  0xc0, 0x88, 0x00, 0x8e, 0x03, 0x00, 0x00, 0xd0, 0x00, 0x40,
285  0x00, 0x00, 0x07, 0xff, 0x84, 0x09, 0x00, 0x13, 0x00, 0x00,
286  0x01, 0x84, 0x09, 0xf0, 0x19, 0x0a, 0x8e, 0x69, 0x98, 0x01,
287  0x00, 0x58, 0x10, 0x40, 0x8c, 0x00, 0x0c, 0x48, 0x85, 0xc9,
288  0xa7, 0x00, 0x00, 0x00, 0x30, 0x81, 0x80, 0x00, 0x39, 0x00,
289  0x8a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xf6
290  };
291 
292  priv = kzalloc(sizeof(struct tda18218_priv), GFP_KERNEL);
293  if (priv == NULL)
294  return NULL;
295 
296  priv->cfg = cfg;
297  priv->i2c = i2c;
298  fe->tuner_priv = priv;
299 
300  if (fe->ops.i2c_gate_ctrl)
301  fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
302 
303  /* check if the tuner is there */
304  ret = tda18218_rd_reg(priv, R00_ID, &val);
305  dev_dbg(&priv->i2c->dev, "%s: ret=%d chip id=%02x\n", __func__, ret,
306  val);
307  if (ret || val != def_regs[R00_ID]) {
308  kfree(priv);
309  return NULL;
310  }
311 
312  dev_info(&priv->i2c->dev,
313  "%s: NXP TDA18218HN successfully identified\n",
314  KBUILD_MODNAME);
315 
316  memcpy(&fe->ops.tuner_ops, &tda18218_tuner_ops,
317  sizeof(struct dvb_tuner_ops));
318  memcpy(priv->regs, def_regs, sizeof(def_regs));
319 
320  /* loop-through enabled chip default register values */
321  if (priv->cfg->loop_through) {
322  priv->regs[R17_PD1] = 0xb0;
323  priv->regs[R18_PD2] = 0x59;
324  }
325 
326  /* standby */
327  ret = tda18218_wr_reg(priv, R17_PD1, priv->regs[R17_PD1] | (1 << 0));
328  if (ret)
329  dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
330 
331  if (fe->ops.i2c_gate_ctrl)
332  fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
333 
334  return fe;
335 }
337 
338 MODULE_DESCRIPTION("NXP TDA18218HN silicon tuner driver");
339 MODULE_AUTHOR("Antti Palosaari <[email protected]>");
340 MODULE_LICENSE("GPL");