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