Merge branch 'omap-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind...
[pandora-kernel.git] / drivers / media / dvb / frontends / stv6110x.c
1 /*
2         STV6110(A) Silicon tuner driver
3
4         Copyright (C) Manu Abraham <abraham.manu@gmail.com>
5
6         Copyright (C) ST Microelectronics
7
8         This program is free software; you can redistribute it and/or modify
9         it under the terms of the GNU General Public License as published by
10         the Free Software Foundation; either version 2 of the License, or
11         (at your option) any later version.
12
13         This program is distributed in the hope that it will be useful,
14         but WITHOUT ANY WARRANTY; without even the implied warranty of
15         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16         GNU General Public License for more details.
17
18         You should have received a copy of the GNU General Public License
19         along with this program; if not, write to the Free Software
20         Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include <linux/init.h>
24 #include <linux/kernel.h>
25 #include <linux/module.h>
26 #include <linux/slab.h>
27 #include <linux/string.h>
28
29 #include "dvb_frontend.h"
30
31 #include "stv6110x_reg.h"
32 #include "stv6110x.h"
33 #include "stv6110x_priv.h"
34
35 static unsigned int verbose;
36 module_param(verbose, int, 0644);
37 MODULE_PARM_DESC(verbose, "Set Verbosity level");
38
39 static int stv6110x_read_reg(struct stv6110x_state *stv6110x, u8 reg, u8 *data)
40 {
41         int ret;
42         const struct stv6110x_config *config = stv6110x->config;
43         u8 b0[] = { reg };
44         u8 b1[] = { 0 };
45         struct i2c_msg msg[] = {
46                 { .addr = config->addr, .flags = 0,        .buf = b0, .len = 1 },
47                 { .addr = config->addr, .flags = I2C_M_RD, .buf = b1, .len = 1 }
48         };
49
50         ret = i2c_transfer(stv6110x->i2c, msg, 2);
51         if (ret != 2) {
52                 dprintk(FE_ERROR, 1, "I/O Error");
53                 return -EREMOTEIO;
54         }
55         *data = b1[0];
56
57         return 0;
58 }
59
60 static int stv6110x_write_regs(struct stv6110x_state *stv6110x, int start, u8 data[], int len)
61 {
62         int ret;
63         const struct stv6110x_config *config = stv6110x->config;
64         u8 buf[len + 1];
65         struct i2c_msg msg = {
66                 .addr = config->addr,
67                 .flags = 0,
68                 .buf = buf,
69                 .len = len + 1
70         };
71
72         if (start + len > 8)
73                 return -EINVAL;
74
75         buf[0] = start;
76         memcpy(&buf[1], data, len);
77
78         ret = i2c_transfer(stv6110x->i2c, &msg, 1);
79         if (ret != 1) {
80                 dprintk(FE_ERROR, 1, "I/O Error");
81                 return -EREMOTEIO;
82         }
83
84         return 0;
85 }
86
87 static int stv6110x_write_reg(struct stv6110x_state *stv6110x, u8 reg, u8 data)
88 {
89         return stv6110x_write_regs(stv6110x, reg, &data, 1);
90 }
91
92 static int stv6110x_init(struct dvb_frontend *fe)
93 {
94         struct stv6110x_state *stv6110x = fe->tuner_priv;
95         int ret;
96
97         ret = stv6110x_write_regs(stv6110x, 0, stv6110x->regs,
98                                   ARRAY_SIZE(stv6110x->regs));
99         if (ret < 0) {
100                 dprintk(FE_ERROR, 1, "Initialization failed");
101                 return -1;
102         }
103
104         return 0;
105 }
106
107 static int stv6110x_set_frequency(struct dvb_frontend *fe, u32 frequency)
108 {
109         struct stv6110x_state *stv6110x = fe->tuner_priv;
110         u32 rDiv, divider;
111         s32 pVal, pCalc, rDivOpt = 0, pCalcOpt = 1000;
112         u8 i;
113
114         STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_K, (REFCLOCK_MHz - 16));
115
116         if (frequency <= 1023000) {
117                 STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_DIV4SEL, 1);
118                 STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_PRESC32_ON, 0);
119                 pVal = 40;
120         } else if (frequency <= 1300000) {
121                 STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_DIV4SEL, 1);
122                 STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_PRESC32_ON, 1);
123                 pVal = 40;
124         } else if (frequency <= 2046000) {
125                 STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_DIV4SEL, 0);
126                 STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_PRESC32_ON, 0);
127                 pVal = 20;
128         } else {
129                 STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_DIV4SEL, 0);
130                 STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_PRESC32_ON, 1);
131                 pVal = 20;
132         }
133
134         for (rDiv = 0; rDiv <= 3; rDiv++) {
135                 pCalc = (REFCLOCK_kHz / 100) / R_DIV(rDiv);
136
137                 if ((abs((s32)(pCalc - pVal))) < (abs((s32)(pCalcOpt - pVal))))
138                         rDivOpt = rDiv;
139
140                 pCalcOpt = (REFCLOCK_kHz / 100) / R_DIV(rDivOpt);
141         }
142
143         divider = (frequency * R_DIV(rDivOpt) * pVal) / REFCLOCK_kHz;
144         divider = (divider + 5) / 10;
145
146         STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_R_DIV, rDivOpt);
147         STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_N_DIV_11_8, MSB(divider));
148         STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG0], TNG0_N_DIV_7_0, LSB(divider));
149
150         /* VCO Auto calibration */
151         STV6110x_SETFIELD(stv6110x->regs[STV6110x_STAT1], STAT1_CALVCO_STRT, 1);
152
153         stv6110x_write_reg(stv6110x, STV6110x_CTRL1, stv6110x->regs[STV6110x_CTRL1]);
154         stv6110x_write_reg(stv6110x, STV6110x_TNG1, stv6110x->regs[STV6110x_TNG1]);
155         stv6110x_write_reg(stv6110x, STV6110x_TNG0, stv6110x->regs[STV6110x_TNG0]);
156         stv6110x_write_reg(stv6110x, STV6110x_STAT1, stv6110x->regs[STV6110x_STAT1]);
157
158         for (i = 0; i < TRIALS; i++) {
159                 stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x->regs[STV6110x_STAT1]);
160                 if (!STV6110x_GETFIELD(STAT1_CALVCO_STRT, stv6110x->regs[STV6110x_STAT1]))
161                                 break;
162                 msleep(1);
163         }
164
165         return 0;
166 }
167
168 static int stv6110x_get_frequency(struct dvb_frontend *fe, u32 *frequency)
169 {
170         struct stv6110x_state *stv6110x = fe->tuner_priv;
171
172         stv6110x_read_reg(stv6110x, STV6110x_TNG1, &stv6110x->regs[STV6110x_TNG1]);
173         stv6110x_read_reg(stv6110x, STV6110x_TNG0, &stv6110x->regs[STV6110x_TNG0]);
174
175         *frequency = (MAKEWORD16(STV6110x_GETFIELD(TNG1_N_DIV_11_8, stv6110x->regs[STV6110x_TNG1]),
176                                  STV6110x_GETFIELD(TNG0_N_DIV_7_0, stv6110x->regs[STV6110x_TNG0]))) * REFCLOCK_kHz;
177
178         *frequency /= (1 << (STV6110x_GETFIELD(TNG1_R_DIV, stv6110x->regs[STV6110x_TNG1]) +
179                              STV6110x_GETFIELD(TNG1_DIV4SEL, stv6110x->regs[STV6110x_TNG1])));
180
181         *frequency >>= 2;
182
183         return 0;
184 }
185
186 static int stv6110x_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth)
187 {
188         struct stv6110x_state *stv6110x = fe->tuner_priv;
189         u32 halfbw;
190         u8 i;
191
192         halfbw = bandwidth >> 1;
193
194         if (halfbw > 36000000)
195                 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_CF, 31); /* LPF */
196         else if (halfbw < 5000000)
197                 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_CF, 0); /* LPF */
198         else
199                 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_CF, ((halfbw / 1000000) - 5)); /* LPF */
200
201
202         STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_RCCLK_OFF, 0x0); /* cal. clk activated */
203         STV6110x_SETFIELD(stv6110x->regs[STV6110x_STAT1], STAT1_CALRC_STRT, 0x1); /* LPF auto cal */
204
205         stv6110x_write_reg(stv6110x, STV6110x_CTRL3, stv6110x->regs[STV6110x_CTRL3]);
206         stv6110x_write_reg(stv6110x, STV6110x_STAT1, stv6110x->regs[STV6110x_STAT1]);
207
208         for (i = 0; i < TRIALS; i++) {
209                 stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x->regs[STV6110x_STAT1]);
210                 if (!STV6110x_GETFIELD(STAT1_CALRC_STRT, stv6110x->regs[STV6110x_STAT1]))
211                         break;
212                 msleep(1);
213         }
214         STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_RCCLK_OFF, 0x1); /* cal. done */
215         stv6110x_write_reg(stv6110x, STV6110x_CTRL3, stv6110x->regs[STV6110x_CTRL3]);
216
217         return 0;
218 }
219
220 static int stv6110x_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
221 {
222         struct stv6110x_state *stv6110x = fe->tuner_priv;
223
224         stv6110x_read_reg(stv6110x, STV6110x_CTRL3, &stv6110x->regs[STV6110x_CTRL3]);
225         *bandwidth = (STV6110x_GETFIELD(CTRL3_CF, stv6110x->regs[STV6110x_CTRL3]) + 5) * 2000000;
226
227         return 0;
228 }
229
230 static int stv6110x_set_refclock(struct dvb_frontend *fe, u32 refclock)
231 {
232         struct stv6110x_state *stv6110x = fe->tuner_priv;
233
234         /* setup divider */
235         switch (refclock) {
236         default:
237         case 1:
238                 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 0);
239                 break;
240         case 2:
241                 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 1);
242                 break;
243         case 4:
244                 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 2);
245                 break;
246         case 8:
247         case 0:
248                 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 3);
249                 break;
250         }
251         stv6110x_write_reg(stv6110x, STV6110x_CTRL2, stv6110x->regs[STV6110x_CTRL2]);
252
253         return 0;
254 }
255
256 static int stv6110x_get_bbgain(struct dvb_frontend *fe, u32 *gain)
257 {
258         struct stv6110x_state *stv6110x = fe->tuner_priv;
259
260         stv6110x_read_reg(stv6110x, STV6110x_CTRL2, &stv6110x->regs[STV6110x_CTRL2]);
261         *gain = 2 * STV6110x_GETFIELD(CTRL2_BBGAIN, stv6110x->regs[STV6110x_CTRL2]);
262
263         return 0;
264 }
265
266 static int stv6110x_set_bbgain(struct dvb_frontend *fe, u32 gain)
267 {
268         struct stv6110x_state *stv6110x = fe->tuner_priv;
269
270         STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_BBGAIN, gain / 2);
271         stv6110x_write_reg(stv6110x, STV6110x_CTRL2, stv6110x->regs[STV6110x_CTRL2]);
272
273         return 0;
274 }
275
276 static int stv6110x_set_mode(struct dvb_frontend *fe, enum tuner_mode mode)
277 {
278         struct stv6110x_state *stv6110x = fe->tuner_priv;
279         int ret;
280
281         switch (mode) {
282         case TUNER_SLEEP:
283                 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_SYN, 0);
284                 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_RX, 0);
285                 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_LPT, 0);
286                 break;
287
288         case TUNER_WAKE:
289                 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_SYN, 1);
290                 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_RX, 1);
291                 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_LPT, 1);
292                 break;
293         }
294
295         ret = stv6110x_write_reg(stv6110x, STV6110x_CTRL1, stv6110x->regs[STV6110x_CTRL1]);
296         if (ret < 0) {
297                 dprintk(FE_ERROR, 1, "I/O Error");
298                 return -EIO;
299         }
300
301         return 0;
302 }
303
304 static int stv6110x_sleep(struct dvb_frontend *fe)
305 {
306         return stv6110x_set_mode(fe, TUNER_SLEEP);
307 }
308
309 static int stv6110x_get_status(struct dvb_frontend *fe, u32 *status)
310 {
311         struct stv6110x_state *stv6110x = fe->tuner_priv;
312
313         stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x->regs[STV6110x_STAT1]);
314
315         if (STV6110x_GETFIELD(STAT1_LOCK, stv6110x->regs[STV6110x_STAT1]))
316                 *status = TUNER_PHASELOCKED;
317         else
318                 *status = 0;
319
320         return 0;
321 }
322
323
324 static int stv6110x_release(struct dvb_frontend *fe)
325 {
326         struct stv6110x_state *stv6110x = fe->tuner_priv;
327
328         fe->tuner_priv = NULL;
329         kfree(stv6110x);
330
331         return 0;
332 }
333
334 static struct dvb_tuner_ops stv6110x_ops = {
335         .info = {
336                 .name           = "STV6110(A) Silicon Tuner",
337                 .frequency_min  =  950000,
338                 .frequency_max  = 2150000,
339                 .frequency_step = 0,
340         },
341         .release                = stv6110x_release
342 };
343
344 static struct stv6110x_devctl stv6110x_ctl = {
345         .tuner_init             = stv6110x_init,
346         .tuner_sleep            = stv6110x_sleep,
347         .tuner_set_mode         = stv6110x_set_mode,
348         .tuner_set_frequency    = stv6110x_set_frequency,
349         .tuner_get_frequency    = stv6110x_get_frequency,
350         .tuner_set_bandwidth    = stv6110x_set_bandwidth,
351         .tuner_get_bandwidth    = stv6110x_get_bandwidth,
352         .tuner_set_bbgain       = stv6110x_set_bbgain,
353         .tuner_get_bbgain       = stv6110x_get_bbgain,
354         .tuner_set_refclk       = stv6110x_set_refclock,
355         .tuner_get_status       = stv6110x_get_status,
356 };
357
358 struct stv6110x_devctl *stv6110x_attach(struct dvb_frontend *fe,
359                                         const struct stv6110x_config *config,
360                                         struct i2c_adapter *i2c)
361 {
362         struct stv6110x_state *stv6110x;
363         u8 default_regs[] = {0x07, 0x11, 0xdc, 0x85, 0x17, 0x01, 0xe6, 0x1e};
364
365         stv6110x = kzalloc(sizeof (struct stv6110x_state), GFP_KERNEL);
366         if (!stv6110x)
367                 return NULL;
368
369         stv6110x->i2c           = i2c;
370         stv6110x->config        = config;
371         stv6110x->devctl        = &stv6110x_ctl;
372         memcpy(stv6110x->regs, default_regs, 8);
373
374         /* setup divider */
375         switch (stv6110x->config->clk_div) {
376         default:
377         case 1:
378                 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 0);
379                 break;
380         case 2:
381                 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 1);
382                 break;
383         case 4:
384                 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 2);
385                 break;
386         case 8:
387         case 0:
388                 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 3);
389                 break;
390         }
391
392         fe->tuner_priv          = stv6110x;
393         fe->ops.tuner_ops       = stv6110x_ops;
394
395         printk(KERN_INFO "%s: Attaching STV6110x\n", __func__);
396         return stv6110x->devctl;
397 }
398 EXPORT_SYMBOL(stv6110x_attach);
399
400 MODULE_AUTHOR("Manu Abraham");
401 MODULE_DESCRIPTION("STV6110x Silicon tuner");
402 MODULE_LICENSE("GPL");