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