ACPI: Kconfig: ACPI should depend on, not select PCI
[pandora-kernel.git] / drivers / media / dvb / frontends / cx24123.c
1 /*
2     Conexant cx24123/cx24109 - DVB QPSK Satellite demod/tuner driver
3
4     Copyright (C) 2005 Steven Toth <stoth@hauppauge.com>
5
6     Support for KWorld DVB-S 100 by Vadim Catana <skystar@moldova.cc>
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/slab.h>
24 #include <linux/kernel.h>
25 #include <linux/module.h>
26 #include <linux/moduleparam.h>
27 #include <linux/init.h>
28
29 #include "dvb_frontend.h"
30 #include "cx24123.h"
31
32 static int debug;
33 #define dprintk(args...) \
34         do { \
35                 if (debug) printk (KERN_DEBUG "cx24123: " args); \
36         } while (0)
37
38 struct cx24123_state
39 {
40         struct i2c_adapter* i2c;
41         struct dvb_frontend_ops ops;
42         const struct cx24123_config* config;
43
44         struct dvb_frontend frontend;
45
46         u32 lastber;
47         u16 snr;
48         u8  lnbreg;
49
50         /* Some PLL specifics for tuning */
51         u32 VCAarg;
52         u32 VGAarg;
53         u32 bandselectarg;
54         u32 pllarg;
55
56         /* The Demod/Tuner can't easily provide these, we cache them */
57         u32 currentfreq;
58         u32 currentsymbolrate;
59 };
60
61 /* Various tuner defaults need to be established for a given symbol rate Sps */
62 static struct
63 {
64         u32 symbolrate_low;
65         u32 symbolrate_high;
66         u32 VCAslope;
67         u32 VCAoffset;
68         u32 VGA1offset;
69         u32 VGA2offset;
70         u32 VCAprogdata;
71         u32 VGAprogdata;
72 } cx24123_AGC_vals[] =
73 {
74         {
75                 .symbolrate_low         = 1000000,
76                 .symbolrate_high        = 4999999,
77                 .VCAslope               = 0x07,
78                 .VCAoffset              = 0x0f,
79                 .VGA1offset             = 0x1f8,
80                 .VGA2offset             = 0x1f8,
81                 .VGAprogdata            = (2 << 18) | (0x1f8 << 9) | 0x1f8,
82                 .VCAprogdata            = (4 << 18) | (0x07 << 9) | 0x07,
83         },
84         {
85                 .symbolrate_low         =  5000000,
86                 .symbolrate_high        = 14999999,
87                 .VCAslope               = 0x1f,
88                 .VCAoffset              = 0x1f,
89                 .VGA1offset             = 0x1e0,
90                 .VGA2offset             = 0x180,
91                 .VGAprogdata            = (2 << 18) | (0x180 << 9) | 0x1e0,
92                 .VCAprogdata            = (4 << 18) | (0x07 << 9) | 0x1f,
93         },
94         {
95                 .symbolrate_low         = 15000000,
96                 .symbolrate_high        = 45000000,
97                 .VCAslope               = 0x3f,
98                 .VCAoffset              = 0x3f,
99                 .VGA1offset             = 0x180,
100                 .VGA2offset             = 0x100,
101                 .VGAprogdata            = (2 << 18) | (0x100 << 9) | 0x180,
102                 .VCAprogdata            = (4 << 18) | (0x07 << 9) | 0x3f,
103         },
104 };
105
106 /*
107  * Various tuner defaults need to be established for a given frequency kHz.
108  * fixme: The bounds on the bands do not match the doc in real life.
109  * fixme: Some of them have been moved, other might need adjustment.
110  */
111 static struct
112 {
113         u32 freq_low;
114         u32 freq_high;
115         u32 bandselect;
116         u32 VCOdivider;
117         u32 VCOnumber;
118         u32 progdata;
119 } cx24123_bandselect_vals[] =
120 {
121         {
122                 .freq_low       = 950000,
123                 .freq_high      = 1018999,
124                 .bandselect     = 0x40,
125                 .VCOdivider     = 4,
126                 .VCOnumber      = 7,
127                 .progdata       = (0 << 18) | (0 << 9) | 0x40,
128         },
129         {
130                 .freq_low       = 1019000,
131                 .freq_high      = 1074999,
132                 .bandselect     = 0x80,
133                 .VCOdivider     = 4,
134                 .VCOnumber      = 8,
135                 .progdata       = (0 << 18) | (0 << 9) | 0x80,
136         },
137         {
138                 .freq_low       = 1075000,
139                 .freq_high      = 1227999,
140                 .bandselect     = 0x01,
141                 .VCOdivider     = 2,
142                 .VCOnumber      = 1,
143                 .progdata       = (0 << 18) | (1 << 9) | 0x01,
144         },
145         {
146                 .freq_low       = 1228000,
147                 .freq_high      = 1349999,
148                 .bandselect     = 0x02,
149                 .VCOdivider     = 2,
150                 .VCOnumber      = 2,
151                 .progdata       = (0 << 18) | (1 << 9) | 0x02,
152         },
153         {
154                 .freq_low       = 1350000,
155                 .freq_high      = 1481999,
156                 .bandselect     = 0x04,
157                 .VCOdivider     = 2,
158                 .VCOnumber      = 3,
159                 .progdata       = (0 << 18) | (1 << 9) | 0x04,
160         },
161         {
162                 .freq_low       = 1482000,
163                 .freq_high      = 1595999,
164                 .bandselect     = 0x08,
165                 .VCOdivider     = 2,
166                 .VCOnumber      = 4,
167                 .progdata       = (0 << 18) | (1 << 9) | 0x08,
168         },
169         {
170                 .freq_low       = 1596000,
171                 .freq_high      = 1717999,
172                 .bandselect     = 0x10,
173                 .VCOdivider     = 2,
174                 .VCOnumber      = 5,
175                 .progdata       = (0 << 18) | (1 << 9) | 0x10,
176         },
177         {
178                 .freq_low       = 1718000,
179                 .freq_high      = 1855999,
180                 .bandselect     = 0x20,
181                 .VCOdivider     = 2,
182                 .VCOnumber      = 6,
183                 .progdata       = (0 << 18) | (1 << 9) | 0x20,
184         },
185         {
186                 .freq_low       = 1856000,
187                 .freq_high      = 2035999,
188                 .bandselect     = 0x40,
189                 .VCOdivider     = 2,
190                 .VCOnumber      = 7,
191                 .progdata       = (0 << 18) | (1 << 9) | 0x40,
192         },
193         {
194                 .freq_low       = 2036000,
195                 .freq_high      = 2149999,
196                 .bandselect     = 0x80,
197                 .VCOdivider     = 2,
198                 .VCOnumber      = 8,
199                 .progdata       = (0 << 18) | (1 << 9) | 0x80,
200         },
201 };
202
203 static struct {
204         u8 reg;
205         u8 data;
206 } cx24123_regdata[] =
207 {
208         {0x00, 0x03}, /* Reset system */
209         {0x00, 0x00}, /* Clear reset */
210         {0x01, 0x3b}, /* Apply sensible defaults, from an i2c sniffer */
211         {0x03, 0x07},
212         {0x04, 0x10},
213         {0x05, 0x04},
214         {0x06, 0x31},
215         {0x0d, 0x02},
216         {0x0e, 0x03},
217         {0x0f, 0xfe},
218         {0x10, 0x01},
219         {0x14, 0x01},
220         {0x15, 0x98},
221         {0x16, 0x00},
222         {0x17, 0x01},
223         {0x1b, 0x05},
224         {0x1c, 0x80},
225         {0x1d, 0x00},
226         {0x1e, 0x00},
227         {0x20, 0x41},
228         {0x21, 0x15},
229         {0x27, 0x14},
230         {0x28, 0x46},
231         {0x29, 0x00},
232         {0x2a, 0xb0},
233         {0x2b, 0x73},
234         {0x2c, 0x00},
235         {0x2d, 0x00},
236         {0x2e, 0x00},
237         {0x2f, 0x00},
238         {0x30, 0x00},
239         {0x31, 0x00},
240         {0x32, 0x8c},
241         {0x33, 0x00},
242         {0x34, 0x00},
243         {0x35, 0x03},
244         {0x36, 0x02},
245         {0x37, 0x3a},
246         {0x3a, 0x00},   /* Enable AGC accumulator */
247         {0x44, 0x00},
248         {0x45, 0x00},
249         {0x46, 0x05},
250         {0x56, 0x41},
251         {0x57, 0xff},
252         {0x67, 0x83},
253 };
254
255 static int cx24123_writereg(struct cx24123_state* state, int reg, int data)
256 {
257         u8 buf[] = { reg, data };
258         struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
259         int err;
260
261         if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
262                 printk("%s: writereg error(err == %i, reg == 0x%02x,"
263                          " data == 0x%02x)\n", __FUNCTION__, err, reg, data);
264                 return -EREMOTEIO;
265         }
266
267         return 0;
268 }
269
270 static int cx24123_writelnbreg(struct cx24123_state* state, int reg, int data)
271 {
272         u8 buf[] = { reg, data };
273         /* fixme: put the intersil addr int the config */
274         struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = buf, .len = 2 };
275         int err;
276
277         if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
278                 printk("%s: writelnbreg error (err == %i, reg == 0x%02x,"
279                          " data == 0x%02x)\n", __FUNCTION__, err, reg, data);
280                 return -EREMOTEIO;
281         }
282
283         /* cache the write, no way to read back */
284         state->lnbreg = data;
285
286         return 0;
287 }
288
289 static int cx24123_readreg(struct cx24123_state* state, u8 reg)
290 {
291         int ret;
292         u8 b0[] = { reg };
293         u8 b1[] = { 0 };
294         struct i2c_msg msg[] = {
295                 { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
296                 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 }
297         };
298
299         ret = i2c_transfer(state->i2c, msg, 2);
300
301         if (ret != 2) {
302                 printk("%s: reg=0x%x (error=%d)\n", __FUNCTION__, reg, ret);
303                 return ret;
304         }
305
306         return b1[0];
307 }
308
309 static int cx24123_readlnbreg(struct cx24123_state* state, u8 reg)
310 {
311         return state->lnbreg;
312 }
313
314 static int cx24123_set_inversion(struct cx24123_state* state, fe_spectral_inversion_t inversion)
315 {
316         switch (inversion) {
317         case INVERSION_OFF:
318                 cx24123_writereg(state, 0x0e, cx24123_readreg(state, 0x0e) & 0x7f);
319                 cx24123_writereg(state, 0x10, cx24123_readreg(state, 0x10) | 0x80);
320                 break;
321         case INVERSION_ON:
322                 cx24123_writereg(state, 0x0e, cx24123_readreg(state, 0x0e) | 0x80);
323                 cx24123_writereg(state, 0x10, cx24123_readreg(state, 0x10) | 0x80);
324                 break;
325         case INVERSION_AUTO:
326                 cx24123_writereg(state, 0x10, cx24123_readreg(state, 0x10) & 0x7f);
327                 break;
328         default:
329                 return -EINVAL;
330         }
331
332         return 0;
333 }
334
335 static int cx24123_get_inversion(struct cx24123_state* state, fe_spectral_inversion_t *inversion)
336 {
337         u8 val;
338
339         val = cx24123_readreg(state, 0x1b) >> 7;
340
341         if (val == 0)
342                 *inversion = INVERSION_OFF;
343         else
344                 *inversion = INVERSION_ON;
345
346         return 0;
347 }
348
349 static int cx24123_set_fec(struct cx24123_state* state, fe_code_rate_t fec)
350 {
351         if ( (fec < FEC_NONE) || (fec > FEC_AUTO) )
352                 fec = FEC_AUTO;
353
354         /* Hardware has 5/11 and 3/5 but are never unused */
355         switch (fec) {
356         case FEC_NONE:
357                 return cx24123_writereg(state, 0x0f, 0x01);
358         case FEC_1_2:
359                 return cx24123_writereg(state, 0x0f, 0x02);
360         case FEC_2_3:
361                 return cx24123_writereg(state, 0x0f, 0x04);
362         case FEC_3_4:
363                 return cx24123_writereg(state, 0x0f, 0x08);
364         case FEC_5_6:
365                 return cx24123_writereg(state, 0x0f, 0x20);
366         case FEC_7_8:
367                 return cx24123_writereg(state, 0x0f, 0x80);
368         case FEC_AUTO:
369                 return cx24123_writereg(state, 0x0f, 0xae);
370         default:
371                 return -EOPNOTSUPP;
372         }
373 }
374
375 static int cx24123_get_fec(struct cx24123_state* state, fe_code_rate_t *fec)
376 {
377         int ret;
378         u8 val;
379
380         ret = cx24123_readreg (state, 0x1b);
381         if (ret < 0)
382                 return ret;
383         val = ret & 0x07;
384         switch (val) {
385         case 1:
386                 *fec = FEC_1_2;
387                 break;
388         case 3:
389                 *fec = FEC_2_3;
390                 break;
391         case 4:
392                 *fec = FEC_3_4;
393                 break;
394         case 5:
395                 *fec = FEC_4_5;
396                 break;
397         case 6:
398                 *fec = FEC_5_6;
399                 break;
400         case 7:
401                 *fec = FEC_7_8;
402                 break;
403         case 2: /* *fec = FEC_3_5; break; */
404         case 0: /* *fec = FEC_5_11; break; */
405                 *fec = FEC_AUTO;
406                 break;
407         default:
408                 *fec = FEC_NONE; // can't happen
409         }
410
411         return 0;
412 }
413
414 /* fixme: Symbol rates < 3MSps may not work because of precision loss */
415 static int cx24123_set_symbolrate(struct cx24123_state* state, u32 srate)
416 {
417         u32 val;
418
419         val = (srate / 1185) * 100;
420
421         /* Compensate for scaling up, by removing 17 symbols per 1Msps */
422         val = val - (17 * (srate / 1000000));
423
424         cx24123_writereg(state, 0x08, (val >> 16) & 0xff );
425         cx24123_writereg(state, 0x09, (val >>  8) & 0xff );
426         cx24123_writereg(state, 0x0a, (val      ) & 0xff );
427
428         return 0;
429 }
430
431 /*
432  * Based on the required frequency and symbolrate, the tuner AGC has to be configured
433  * and the correct band selected. Calculate those values
434  */
435 static int cx24123_pll_calculate(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
436 {
437         struct cx24123_state *state = fe->demodulator_priv;
438         u32 ndiv = 0, adiv = 0, vco_div = 0;
439         int i = 0;
440
441         /* Defaults for low freq, low rate */
442         state->VCAarg = cx24123_AGC_vals[0].VCAprogdata;
443         state->VGAarg = cx24123_AGC_vals[0].VGAprogdata;
444         state->bandselectarg = cx24123_bandselect_vals[0].progdata;
445         vco_div = cx24123_bandselect_vals[0].VCOdivider;
446
447         /* For the given symbolerate, determine the VCA and VGA programming bits */
448         for (i = 0; i < sizeof(cx24123_AGC_vals) / sizeof(cx24123_AGC_vals[0]); i++)
449         {
450                 if ((cx24123_AGC_vals[i].symbolrate_low <= p->u.qpsk.symbol_rate) &&
451                                 (cx24123_AGC_vals[i].symbolrate_high >= p->u.qpsk.symbol_rate) ) {
452                         state->VCAarg = cx24123_AGC_vals[i].VCAprogdata;
453                         state->VGAarg = cx24123_AGC_vals[i].VGAprogdata;
454                 }
455         }
456
457         /* For the given frequency, determine the bandselect programming bits */
458         for (i = 0; i < sizeof(cx24123_bandselect_vals) / sizeof(cx24123_bandselect_vals[0]); i++)
459         {
460                 if ((cx24123_bandselect_vals[i].freq_low <= p->frequency) &&
461                                 (cx24123_bandselect_vals[i].freq_high >= p->frequency) ) {
462                         state->bandselectarg = cx24123_bandselect_vals[i].progdata;
463                         vco_div = cx24123_bandselect_vals[i].VCOdivider;
464                 }
465         }
466
467         /* Determine the N/A dividers for the requested lband freq (in kHz). */
468         /* Note: 10111 (kHz) is the Crystal Freq and divider of 10. */
469         ndiv = ( ((p->frequency * vco_div) / (10111 / 10) / 2) / 32) & 0x1ff;
470         adiv = ( ((p->frequency * vco_div) / (10111 / 10) / 2) % 32) & 0x1f;
471
472         if (adiv == 0)
473                 adiv++;
474
475         /* determine the correct pll frequency values. */
476         /* Command 11, refdiv 11, cpump polarity 1, cpump current 3mA 10. */
477         state->pllarg = (3 << 19) | (3 << 17) | (1 << 16) | (2 << 14);
478         state->pllarg |= (ndiv << 5) | adiv;
479
480         return 0;
481 }
482
483 /*
484  * Tuner data is 21 bits long, must be left-aligned in data.
485  * Tuner cx24109 is written through a dedicated 3wire interface on the demod chip.
486  */
487 static int cx24123_pll_writereg(struct dvb_frontend* fe, struct dvb_frontend_parameters *p, u32 data)
488 {
489         struct cx24123_state *state = fe->demodulator_priv;
490         unsigned long timeout;
491
492         /* align the 21 bytes into to bit23 boundary */
493         data = data << 3;
494
495         /* Reset the demod pll word length to 0x15 bits */
496         cx24123_writereg(state, 0x21, 0x15);
497
498         /* write the msb 8 bits, wait for the send to be completed */
499         timeout = jiffies + msecs_to_jiffies(40);
500         cx24123_writereg(state, 0x22, (data >> 16) & 0xff);
501         while ((cx24123_readreg(state, 0x20) & 0x40) == 0) {
502                 if (time_after(jiffies, timeout)) {
503                         printk("%s:  demodulator is not responding, possibly hung, aborting.\n", __FUNCTION__);
504                         return -EREMOTEIO;
505                 }
506                 msleep(10);
507         }
508
509         /* send another 8 bytes, wait for the send to be completed */
510         timeout = jiffies + msecs_to_jiffies(40);
511         cx24123_writereg(state, 0x22, (data>>8) & 0xff );
512         while ((cx24123_readreg(state, 0x20) & 0x40) == 0) {
513                 if (time_after(jiffies, timeout)) {
514                         printk("%s:  demodulator is not responding, possibly hung, aborting.\n", __FUNCTION__);
515                         return -EREMOTEIO;
516                 }
517                 msleep(10);
518         }
519
520         /* send the lower 5 bits of this byte, padded with 3 LBB, wait for the send to be completed */
521         timeout = jiffies + msecs_to_jiffies(40);
522         cx24123_writereg(state, 0x22, (data) & 0xff );
523         while ((cx24123_readreg(state, 0x20) & 0x80)) {
524                 if (time_after(jiffies, timeout)) {
525                         printk("%s:  demodulator is not responding, possibly hung, aborting.\n", __FUNCTION__);
526                         return -EREMOTEIO;
527                 }
528                 msleep(10);
529         }
530
531         /* Trigger the demod to configure the tuner */
532         cx24123_writereg(state, 0x20, cx24123_readreg(state, 0x20) | 2);
533         cx24123_writereg(state, 0x20, cx24123_readreg(state, 0x20) & 0xfd);
534
535         return 0;
536 }
537
538 static int cx24123_pll_tune(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
539 {
540         struct cx24123_state *state = fe->demodulator_priv;
541
542         if (cx24123_pll_calculate(fe, p) != 0) {
543                 printk("%s: cx24123_pll_calcutate failed\n",__FUNCTION__);
544                 return -EINVAL;
545         }
546
547         /* Write the new VCO/VGA */
548         cx24123_pll_writereg(fe, p, state->VCAarg);
549         cx24123_pll_writereg(fe, p, state->VGAarg);
550
551         /* Write the new bandselect and pll args */
552         cx24123_pll_writereg(fe, p, state->bandselectarg);
553         cx24123_pll_writereg(fe, p, state->pllarg);
554
555         return 0;
556 }
557
558 static int cx24123_initfe(struct dvb_frontend* fe)
559 {
560         struct cx24123_state *state = fe->demodulator_priv;
561         int i;
562
563         /* Configure the demod to a good set of defaults */
564         for (i = 0; i < sizeof(cx24123_regdata) / sizeof(cx24123_regdata[0]); i++)
565                 cx24123_writereg(state, cx24123_regdata[i].reg, cx24123_regdata[i].data);
566
567         if (state->config->pll_init)
568                 state->config->pll_init(fe);
569
570         /* Configure the LNB for 14V */
571         if (state->config->use_isl6421)
572                 cx24123_writelnbreg(state, 0x0, 0x2a);
573
574         return 0;
575 }
576
577 static int cx24123_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
578 {
579         struct cx24123_state *state = fe->demodulator_priv;
580         u8 val;
581
582         switch (state->config->use_isl6421) {
583
584         case 1:
585
586                 val = cx24123_readlnbreg(state, 0x0);
587
588                 switch (voltage) {
589                 case SEC_VOLTAGE_13:
590                         return cx24123_writelnbreg(state, 0x0, val & 0x32); /* V 13v */
591                 case SEC_VOLTAGE_18:
592                         return cx24123_writelnbreg(state, 0x0, val | 0x04); /* H 18v */
593                 case SEC_VOLTAGE_OFF:
594                         return cx24123_writelnbreg(state, 0x0, val & 0x30);
595                 default:
596                         return -EINVAL;
597                 };
598
599         case 0:
600
601                 val = cx24123_readreg(state, 0x29);
602
603                 switch (voltage) {
604                 case SEC_VOLTAGE_13:
605                         dprintk("%s: setting voltage 13V\n", __FUNCTION__);
606                         if (state->config->enable_lnb_voltage)
607                                 state->config->enable_lnb_voltage(fe, 1);
608                         return cx24123_writereg(state, 0x29, val | 0x80);
609                 case SEC_VOLTAGE_18:
610                         dprintk("%s: setting voltage 18V\n", __FUNCTION__);
611                         if (state->config->enable_lnb_voltage)
612                                 state->config->enable_lnb_voltage(fe, 1);
613                         return cx24123_writereg(state, 0x29, val & 0x7f);
614                 case SEC_VOLTAGE_OFF:
615                         dprintk("%s: setting voltage off\n", __FUNCTION__);
616                         if (state->config->enable_lnb_voltage)
617                                 state->config->enable_lnb_voltage(fe, 0);
618                         return 0;
619                 default:
620                         return -EINVAL;
621                 };
622         }
623
624         return 0;
625 }
626
627 static int cx24123_send_diseqc_msg(struct dvb_frontend* fe,
628                                    struct dvb_diseqc_master_cmd *cmd)
629 {
630         /* fixme: Implement diseqc */
631         printk("%s: No support yet\n",__FUNCTION__);
632
633         return -ENOTSUPP;
634 }
635
636 static int cx24123_read_status(struct dvb_frontend* fe, fe_status_t* status)
637 {
638         struct cx24123_state *state = fe->demodulator_priv;
639
640         int sync = cx24123_readreg(state, 0x14);
641         int lock = cx24123_readreg(state, 0x20);
642
643         *status = 0;
644         if (lock & 0x01)
645                 *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
646         if (sync & 0x04)
647                 *status |= FE_HAS_VITERBI;
648         if (sync & 0x08)
649                 *status |= FE_HAS_CARRIER;
650         if (sync & 0x80)
651                 *status |= FE_HAS_SYNC | FE_HAS_LOCK;
652
653         return 0;
654 }
655
656 /*
657  * Configured to return the measurement of errors in blocks, because no UCBLOCKS value
658  * is available, so this value doubles up to satisfy both measurements
659  */
660 static int cx24123_read_ber(struct dvb_frontend* fe, u32* ber)
661 {
662         struct cx24123_state *state = fe->demodulator_priv;
663
664         state->lastber =
665                 ((cx24123_readreg(state, 0x1c) & 0x3f) << 16) |
666                 (cx24123_readreg(state, 0x1d) << 8 |
667                 cx24123_readreg(state, 0x1e));
668
669         /* Do the signal quality processing here, it's derived from the BER. */
670         /* Scale the BER from a 24bit to a SNR 16 bit where higher = better */
671         if (state->lastber < 5000)
672                 state->snr = 655*100;
673         else if ( (state->lastber >=   5000) && (state->lastber <  55000) )
674                 state->snr = 655*90;
675         else if ( (state->lastber >=  55000) && (state->lastber < 150000) )
676                 state->snr = 655*80;
677         else if ( (state->lastber >= 150000) && (state->lastber < 250000) )
678                 state->snr = 655*70;
679         else if ( (state->lastber >= 250000) && (state->lastber < 450000) )
680                 state->snr = 655*65;
681         else
682                 state->snr = 0;
683
684         *ber = state->lastber;
685
686         return 0;
687 }
688
689 static int cx24123_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength)
690 {
691         struct cx24123_state *state = fe->demodulator_priv;
692         *signal_strength = cx24123_readreg(state, 0x3b) << 8; /* larger = better */
693
694         return 0;
695 }
696
697 static int cx24123_read_snr(struct dvb_frontend* fe, u16* snr)
698 {
699         struct cx24123_state *state = fe->demodulator_priv;
700         *snr = state->snr;
701
702         return 0;
703 }
704
705 static int cx24123_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
706 {
707         struct cx24123_state *state = fe->demodulator_priv;
708         *ucblocks = state->lastber;
709
710         return 0;
711 }
712
713 static int cx24123_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
714 {
715         struct cx24123_state *state = fe->demodulator_priv;
716
717         if (state->config->set_ts_params)
718                 state->config->set_ts_params(fe, 0);
719
720         state->currentfreq=p->frequency;
721         state->currentsymbolrate = p->u.qpsk.symbol_rate;
722
723         cx24123_set_inversion(state, p->inversion);
724         cx24123_set_fec(state, p->u.qpsk.fec_inner);
725         cx24123_set_symbolrate(state, p->u.qpsk.symbol_rate);
726         cx24123_pll_tune(fe, p);
727
728         /* Enable automatic aquisition and reset cycle */
729         cx24123_writereg(state, 0x03, (cx24123_readreg(state, 0x03) | 0x07));
730         cx24123_writereg(state, 0x00, 0x10);
731         cx24123_writereg(state, 0x00, 0);
732
733         return 0;
734 }
735
736 static int cx24123_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
737 {
738         struct cx24123_state *state = fe->demodulator_priv;
739
740         if (cx24123_get_inversion(state, &p->inversion) != 0) {
741                 printk("%s: Failed to get inversion status\n",__FUNCTION__);
742                 return -EREMOTEIO;
743         }
744         if (cx24123_get_fec(state, &p->u.qpsk.fec_inner) != 0) {
745                 printk("%s: Failed to get fec status\n",__FUNCTION__);
746                 return -EREMOTEIO;
747         }
748         p->frequency = state->currentfreq;
749         p->u.qpsk.symbol_rate = state->currentsymbolrate;
750
751         return 0;
752 }
753
754 static int cx24123_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
755 {
756         struct cx24123_state *state = fe->demodulator_priv;
757         u8 val;
758
759         switch (state->config->use_isl6421) {
760         case 1:
761
762                 val = cx24123_readlnbreg(state, 0x0);
763
764                 switch (tone) {
765                 case SEC_TONE_ON:
766                         return cx24123_writelnbreg(state, 0x0, val | 0x10);
767                 case SEC_TONE_OFF:
768                         return cx24123_writelnbreg(state, 0x0, val & 0x2f);
769                 default:
770                         printk("%s: CASE reached default with tone=%d\n", __FUNCTION__, tone);
771                         return -EINVAL;
772                 }
773
774         case 0:
775
776                 val = cx24123_readreg(state, 0x29);
777
778                 switch (tone) {
779                 case SEC_TONE_ON:
780                         dprintk("%s: setting tone on\n", __FUNCTION__);
781                         return cx24123_writereg(state, 0x29, val | 0x10);
782                 case SEC_TONE_OFF:
783                         dprintk("%s: setting tone off\n",__FUNCTION__);
784                         return cx24123_writereg(state, 0x29, val & 0xef);
785                 default:
786                         printk("%s: CASE reached default with tone=%d\n", __FUNCTION__, tone);
787                         return -EINVAL;
788                 }
789         }
790
791         return 0;
792 }
793
794 static void cx24123_release(struct dvb_frontend* fe)
795 {
796         struct cx24123_state* state = fe->demodulator_priv;
797         dprintk("%s\n",__FUNCTION__);
798         kfree(state);
799 }
800
801 static struct dvb_frontend_ops cx24123_ops;
802
803 struct dvb_frontend* cx24123_attach(const struct cx24123_config* config,
804                                     struct i2c_adapter* i2c)
805 {
806         struct cx24123_state* state = NULL;
807         int ret;
808
809         dprintk("%s\n",__FUNCTION__);
810
811         /* allocate memory for the internal state */
812         state = kmalloc(sizeof(struct cx24123_state), GFP_KERNEL);
813         if (state == NULL) {
814                 printk("Unable to kmalloc\n");
815                 goto error;
816         }
817
818         /* setup the state */
819         state->config = config;
820         state->i2c = i2c;
821         memcpy(&state->ops, &cx24123_ops, sizeof(struct dvb_frontend_ops));
822         state->lastber = 0;
823         state->snr = 0;
824         state->lnbreg = 0;
825         state->VCAarg = 0;
826         state->VGAarg = 0;
827         state->bandselectarg = 0;
828         state->pllarg = 0;
829         state->currentfreq = 0;
830         state->currentsymbolrate = 0;
831
832         /* check if the demod is there */
833         ret = cx24123_readreg(state, 0x00);
834         if ((ret != 0xd1) && (ret != 0xe1)) {
835                 printk("Version != d1 or e1\n");
836                 goto error;
837         }
838
839         /* create dvb_frontend */
840         state->frontend.ops = &state->ops;
841         state->frontend.demodulator_priv = state;
842         return &state->frontend;
843
844 error:
845         kfree(state);
846
847         return NULL;
848 }
849
850 static struct dvb_frontend_ops cx24123_ops = {
851
852         .info = {
853                 .name = "Conexant CX24123/CX24109",
854                 .type = FE_QPSK,
855                 .frequency_min = 950000,
856                 .frequency_max = 2150000,
857                 .frequency_stepsize = 1011, /* kHz for QPSK frontends */
858                 .frequency_tolerance = 29500,
859                 .symbol_rate_min = 1000000,
860                 .symbol_rate_max = 45000000,
861                 .caps = FE_CAN_INVERSION_AUTO |
862                         FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
863                         FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
864                         FE_CAN_QPSK | FE_CAN_RECOVER
865         },
866
867         .release = cx24123_release,
868
869         .init = cx24123_initfe,
870         .set_frontend = cx24123_set_frontend,
871         .get_frontend = cx24123_get_frontend,
872         .read_status = cx24123_read_status,
873         .read_ber = cx24123_read_ber,
874         .read_signal_strength = cx24123_read_signal_strength,
875         .read_snr = cx24123_read_snr,
876         .read_ucblocks = cx24123_read_ucblocks,
877         .diseqc_send_master_cmd = cx24123_send_diseqc_msg,
878         .set_tone = cx24123_set_tone,
879         .set_voltage = cx24123_set_voltage,
880 };
881
882 module_param(debug, int, 0644);
883 MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
884
885 MODULE_DESCRIPTION("DVB Frontend module for Conexant cx24123/cx24109 hardware");
886 MODULE_AUTHOR("Steven Toth");
887 MODULE_LICENSE("GPL");
888
889 EXPORT_SYMBOL(cx24123_attach);