~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to drivers/media/dvb/frontends/cx22702.c

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
    Conexant 22702 DVB OFDM demodulator driver
 
3
 
 
4
    based on:
 
5
        Alps TDMB7 DVB OFDM demodulator driver
 
6
 
 
7
    Copyright (C) 2001-2002 Convergence Integrated Media GmbH
 
8
          Holger Waechtler <holger@convergence.de>
 
9
 
 
10
    Copyright (C) 2004 Steven Toth <stoth@linuxtv.org>
 
11
 
 
12
    This program is free software; you can redistribute it and/or modify
 
13
    it under the terms of the GNU General Public License as published by
 
14
    the Free Software Foundation; either version 2 of the License, or
 
15
    (at your option) any later version.
 
16
 
 
17
    This program is distributed in the hope that it will be useful,
 
18
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
19
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
20
    GNU General Public License for more details.
 
21
 
 
22
    You should have received a copy of the GNU General Public License
 
23
    along with this program; if not, write to the Free Software
 
24
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
25
 
 
26
*/
 
27
 
 
28
#include <linux/kernel.h>
 
29
#include <linux/init.h>
 
30
#include <linux/module.h>
 
31
#include <linux/string.h>
 
32
#include <linux/slab.h>
 
33
#include <linux/delay.h>
 
34
#include "dvb_frontend.h"
 
35
#include "cx22702.h"
 
36
 
 
37
struct cx22702_state {
 
38
 
 
39
        struct i2c_adapter *i2c;
 
40
 
 
41
        /* configuration settings */
 
42
        const struct cx22702_config *config;
 
43
 
 
44
        struct dvb_frontend frontend;
 
45
 
 
46
        /* previous uncorrected block counter */
 
47
        u8 prevUCBlocks;
 
48
};
 
49
 
 
50
static int debug;
 
51
module_param(debug, int, 0644);
 
52
MODULE_PARM_DESC(debug, "Enable verbose debug messages");
 
53
 
 
54
#define dprintk if (debug) printk
 
55
 
 
56
/* Register values to initialise the demod */
 
57
static const u8 init_tab[] = {
 
58
        0x00, 0x00, /* Stop acquisition */
 
59
        0x0B, 0x06,
 
60
        0x09, 0x01,
 
61
        0x0D, 0x41,
 
62
        0x16, 0x32,
 
63
        0x20, 0x0A,
 
64
        0x21, 0x17,
 
65
        0x24, 0x3e,
 
66
        0x26, 0xff,
 
67
        0x27, 0x10,
 
68
        0x28, 0x00,
 
69
        0x29, 0x00,
 
70
        0x2a, 0x10,
 
71
        0x2b, 0x00,
 
72
        0x2c, 0x10,
 
73
        0x2d, 0x00,
 
74
        0x48, 0xd4,
 
75
        0x49, 0x56,
 
76
        0x6b, 0x1e,
 
77
        0xc8, 0x02,
 
78
        0xf9, 0x00,
 
79
        0xfa, 0x00,
 
80
        0xfb, 0x00,
 
81
        0xfc, 0x00,
 
82
        0xfd, 0x00,
 
83
};
 
84
 
 
85
static int cx22702_writereg(struct cx22702_state *state, u8 reg, u8 data)
 
86
{
 
87
        int ret;
 
88
        u8 buf[] = { reg, data };
 
89
        struct i2c_msg msg = {
 
90
                .addr = state->config->demod_address, .flags = 0,
 
91
                        .buf = buf, .len = 2 };
 
92
 
 
93
        ret = i2c_transfer(state->i2c, &msg, 1);
 
94
 
 
95
        if (unlikely(ret != 1)) {
 
96
                printk(KERN_ERR
 
97
                        "%s: error (reg == 0x%02x, val == 0x%02x, ret == %i)\n",
 
98
                        __func__, reg, data, ret);
 
99
                return -1;
 
100
        }
 
101
 
 
102
        return 0;
 
103
}
 
104
 
 
105
static u8 cx22702_readreg(struct cx22702_state *state, u8 reg)
 
106
{
 
107
        int ret;
 
108
        u8 data;
 
109
 
 
110
        struct i2c_msg msg[] = {
 
111
                { .addr = state->config->demod_address, .flags = 0,
 
112
                        .buf = &reg, .len = 1 },
 
113
                { .addr = state->config->demod_address, .flags = I2C_M_RD,
 
114
                        .buf = &data, .len = 1 } };
 
115
 
 
116
        ret = i2c_transfer(state->i2c, msg, 2);
 
117
 
 
118
        if (unlikely(ret != 2)) {
 
119
                printk(KERN_ERR "%s: error (reg == 0x%02x, ret == %i)\n",
 
120
                        __func__, reg, ret);
 
121
                return 0;
 
122
        }
 
123
 
 
124
        return data;
 
125
}
 
126
 
 
127
static int cx22702_set_inversion(struct cx22702_state *state, int inversion)
 
128
{
 
129
        u8 val;
 
130
 
 
131
        val = cx22702_readreg(state, 0x0C);
 
132
        switch (inversion) {
 
133
        case INVERSION_AUTO:
 
134
                return -EOPNOTSUPP;
 
135
        case INVERSION_ON:
 
136
                val |= 0x01;
 
137
                break;
 
138
        case INVERSION_OFF:
 
139
                val &= 0xfe;
 
140
                break;
 
141
        default:
 
142
                return -EINVAL;
 
143
        }
 
144
        return cx22702_writereg(state, 0x0C, val);
 
145
}
 
146
 
 
147
/* Retrieve the demod settings */
 
148
static int cx22702_get_tps(struct cx22702_state *state,
 
149
        struct dvb_ofdm_parameters *p)
 
150
{
 
151
        u8 val;
 
152
 
 
153
        /* Make sure the TPS regs are valid */
 
154
        if (!(cx22702_readreg(state, 0x0A) & 0x20))
 
155
                return -EAGAIN;
 
156
 
 
157
        val = cx22702_readreg(state, 0x01);
 
158
        switch ((val & 0x18) >> 3) {
 
159
        case 0:
 
160
                p->constellation = QPSK;
 
161
                break;
 
162
        case 1:
 
163
                p->constellation = QAM_16;
 
164
                break;
 
165
        case 2:
 
166
                p->constellation = QAM_64;
 
167
                break;
 
168
        }
 
169
        switch (val & 0x07) {
 
170
        case 0:
 
171
                p->hierarchy_information = HIERARCHY_NONE;
 
172
                break;
 
173
        case 1:
 
174
                p->hierarchy_information = HIERARCHY_1;
 
175
                break;
 
176
        case 2:
 
177
                p->hierarchy_information = HIERARCHY_2;
 
178
                break;
 
179
        case 3:
 
180
                p->hierarchy_information = HIERARCHY_4;
 
181
                break;
 
182
        }
 
183
 
 
184
 
 
185
        val = cx22702_readreg(state, 0x02);
 
186
        switch ((val & 0x38) >> 3) {
 
187
        case 0:
 
188
                p->code_rate_HP = FEC_1_2;
 
189
                break;
 
190
        case 1:
 
191
                p->code_rate_HP = FEC_2_3;
 
192
                break;
 
193
        case 2:
 
194
                p->code_rate_HP = FEC_3_4;
 
195
                break;
 
196
        case 3:
 
197
                p->code_rate_HP = FEC_5_6;
 
198
                break;
 
199
        case 4:
 
200
                p->code_rate_HP = FEC_7_8;
 
201
                break;
 
202
        }
 
203
        switch (val & 0x07) {
 
204
        case 0:
 
205
                p->code_rate_LP = FEC_1_2;
 
206
                break;
 
207
        case 1:
 
208
                p->code_rate_LP = FEC_2_3;
 
209
                break;
 
210
        case 2:
 
211
                p->code_rate_LP = FEC_3_4;
 
212
                break;
 
213
        case 3:
 
214
                p->code_rate_LP = FEC_5_6;
 
215
                break;
 
216
        case 4:
 
217
                p->code_rate_LP = FEC_7_8;
 
218
                break;
 
219
        }
 
220
 
 
221
        val = cx22702_readreg(state, 0x03);
 
222
        switch ((val & 0x0c) >> 2) {
 
223
        case 0:
 
224
                p->guard_interval = GUARD_INTERVAL_1_32;
 
225
                break;
 
226
        case 1:
 
227
                p->guard_interval = GUARD_INTERVAL_1_16;
 
228
                break;
 
229
        case 2:
 
230
                p->guard_interval = GUARD_INTERVAL_1_8;
 
231
                break;
 
232
        case 3:
 
233
                p->guard_interval = GUARD_INTERVAL_1_4;
 
234
                break;
 
235
        }
 
236
        switch (val & 0x03) {
 
237
        case 0:
 
238
                p->transmission_mode = TRANSMISSION_MODE_2K;
 
239
                break;
 
240
        case 1:
 
241
                p->transmission_mode = TRANSMISSION_MODE_8K;
 
242
                break;
 
243
        }
 
244
 
 
245
        return 0;
 
246
}
 
247
 
 
248
static int cx22702_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
 
249
{
 
250
        struct cx22702_state *state = fe->demodulator_priv;
 
251
        u8 val;
 
252
 
 
253
        dprintk("%s(%d)\n", __func__, enable);
 
254
        val = cx22702_readreg(state, 0x0D);
 
255
        if (enable)
 
256
                val &= 0xfe;
 
257
        else
 
258
                val |= 0x01;
 
259
        return cx22702_writereg(state, 0x0D, val);
 
260
}
 
261
 
 
262
/* Talk to the demod, set the FEC, GUARD, QAM settings etc */
 
263
static int cx22702_set_tps(struct dvb_frontend *fe,
 
264
        struct dvb_frontend_parameters *p)
 
265
{
 
266
        u8 val;
 
267
        struct cx22702_state *state = fe->demodulator_priv;
 
268
 
 
269
        if (fe->ops.tuner_ops.set_params) {
 
270
                fe->ops.tuner_ops.set_params(fe, p);
 
271
                if (fe->ops.i2c_gate_ctrl)
 
272
                        fe->ops.i2c_gate_ctrl(fe, 0);
 
273
        }
 
274
 
 
275
        /* set inversion */
 
276
        cx22702_set_inversion(state, p->inversion);
 
277
 
 
278
        /* set bandwidth */
 
279
        val = cx22702_readreg(state, 0x0C) & 0xcf;
 
280
        switch (p->u.ofdm.bandwidth) {
 
281
        case BANDWIDTH_6_MHZ:
 
282
                val |= 0x20;
 
283
                break;
 
284
        case BANDWIDTH_7_MHZ:
 
285
                val |= 0x10;
 
286
                break;
 
287
        case BANDWIDTH_8_MHZ:
 
288
                break;
 
289
        default:
 
290
                dprintk("%s: invalid bandwidth\n", __func__);
 
291
                return -EINVAL;
 
292
        }
 
293
        cx22702_writereg(state, 0x0C, val);
 
294
 
 
295
        p->u.ofdm.code_rate_LP = FEC_AUTO; /* temp hack as manual not working */
 
296
 
 
297
        /* use auto configuration? */
 
298
        if ((p->u.ofdm.hierarchy_information == HIERARCHY_AUTO) ||
 
299
           (p->u.ofdm.constellation == QAM_AUTO) ||
 
300
           (p->u.ofdm.code_rate_HP == FEC_AUTO) ||
 
301
           (p->u.ofdm.code_rate_LP == FEC_AUTO) ||
 
302
           (p->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO) ||
 
303
           (p->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO)) {
 
304
 
 
305
                /* TPS Source - use hardware driven values */
 
306
                cx22702_writereg(state, 0x06, 0x10);
 
307
                cx22702_writereg(state, 0x07, 0x9);
 
308
                cx22702_writereg(state, 0x08, 0xC1);
 
309
                cx22702_writereg(state, 0x0B, cx22702_readreg(state, 0x0B)
 
310
                        & 0xfc);
 
311
                cx22702_writereg(state, 0x0C,
 
312
                        (cx22702_readreg(state, 0x0C) & 0xBF) | 0x40);
 
313
                cx22702_writereg(state, 0x00, 0x01); /* Begin acquisition */
 
314
                dprintk("%s: Autodetecting\n", __func__);
 
315
                return 0;
 
316
        }
 
317
 
 
318
        /* manually programmed values */
 
319
        switch (p->u.ofdm.constellation) {              /* mask 0x18 */
 
320
        case QPSK:
 
321
                val = 0x00;
 
322
                break;
 
323
        case QAM_16:
 
324
                val = 0x08;
 
325
                break;
 
326
        case QAM_64:
 
327
                val = 0x10;
 
328
                break;
 
329
        default:
 
330
                dprintk("%s: invalid constellation\n", __func__);
 
331
                return -EINVAL;
 
332
        }
 
333
        switch (p->u.ofdm.hierarchy_information) {      /* mask 0x07 */
 
334
        case HIERARCHY_NONE:
 
335
                break;
 
336
        case HIERARCHY_1:
 
337
                val |= 0x01;
 
338
                break;
 
339
        case HIERARCHY_2:
 
340
                val |= 0x02;
 
341
                break;
 
342
        case HIERARCHY_4:
 
343
                val |= 0x03;
 
344
                break;
 
345
        default:
 
346
                dprintk("%s: invalid hierarchy\n", __func__);
 
347
                return -EINVAL;
 
348
        }
 
349
        cx22702_writereg(state, 0x06, val);
 
350
 
 
351
        switch (p->u.ofdm.code_rate_HP) {               /* mask 0x38 */
 
352
        case FEC_NONE:
 
353
        case FEC_1_2:
 
354
                val = 0x00;
 
355
                break;
 
356
        case FEC_2_3:
 
357
                val = 0x08;
 
358
                break;
 
359
        case FEC_3_4:
 
360
                val = 0x10;
 
361
                break;
 
362
        case FEC_5_6:
 
363
                val = 0x18;
 
364
                break;
 
365
        case FEC_7_8:
 
366
                val = 0x20;
 
367
                break;
 
368
        default:
 
369
                dprintk("%s: invalid code_rate_HP\n", __func__);
 
370
                return -EINVAL;
 
371
        }
 
372
        switch (p->u.ofdm.code_rate_LP) {               /* mask 0x07 */
 
373
        case FEC_NONE:
 
374
        case FEC_1_2:
 
375
                break;
 
376
        case FEC_2_3:
 
377
                val |= 0x01;
 
378
                break;
 
379
        case FEC_3_4:
 
380
                val |= 0x02;
 
381
                break;
 
382
        case FEC_5_6:
 
383
                val |= 0x03;
 
384
                break;
 
385
        case FEC_7_8:
 
386
                val |= 0x04;
 
387
                break;
 
388
        default:
 
389
                dprintk("%s: invalid code_rate_LP\n", __func__);
 
390
                return -EINVAL;
 
391
        }
 
392
        cx22702_writereg(state, 0x07, val);
 
393
 
 
394
        switch (p->u.ofdm.guard_interval) {             /* mask 0x0c */
 
395
        case GUARD_INTERVAL_1_32:
 
396
                val = 0x00;
 
397
                break;
 
398
        case GUARD_INTERVAL_1_16:
 
399
                val = 0x04;
 
400
                break;
 
401
        case GUARD_INTERVAL_1_8:
 
402
                val = 0x08;
 
403
                break;
 
404
        case GUARD_INTERVAL_1_4:
 
405
                val = 0x0c;
 
406
                break;
 
407
        default:
 
408
                dprintk("%s: invalid guard_interval\n", __func__);
 
409
                return -EINVAL;
 
410
        }
 
411
        switch (p->u.ofdm.transmission_mode) {          /* mask 0x03 */
 
412
        case TRANSMISSION_MODE_2K:
 
413
                break;
 
414
        case TRANSMISSION_MODE_8K:
 
415
                val |= 0x1;
 
416
                break;
 
417
        default:
 
418
                dprintk("%s: invalid transmission_mode\n", __func__);
 
419
                return -EINVAL;
 
420
        }
 
421
        cx22702_writereg(state, 0x08, val);
 
422
        cx22702_writereg(state, 0x0B,
 
423
                (cx22702_readreg(state, 0x0B) & 0xfc) | 0x02);
 
424
        cx22702_writereg(state, 0x0C,
 
425
                (cx22702_readreg(state, 0x0C) & 0xBF) | 0x40);
 
426
 
 
427
        /* Begin channel acquisition */
 
428
        cx22702_writereg(state, 0x00, 0x01);
 
429
 
 
430
        return 0;
 
431
}
 
432
 
 
433
/* Reset the demod hardware and reset all of the configuration registers
 
434
   to a default state. */
 
435
static int cx22702_init(struct dvb_frontend *fe)
 
436
{
 
437
        int i;
 
438
        struct cx22702_state *state = fe->demodulator_priv;
 
439
 
 
440
        cx22702_writereg(state, 0x00, 0x02);
 
441
 
 
442
        msleep(10);
 
443
 
 
444
        for (i = 0; i < ARRAY_SIZE(init_tab); i += 2)
 
445
                cx22702_writereg(state, init_tab[i], init_tab[i + 1]);
 
446
 
 
447
        cx22702_writereg(state, 0xf8, (state->config->output_mode << 1)
 
448
                & 0x02);
 
449
 
 
450
        cx22702_i2c_gate_ctrl(fe, 0);
 
451
 
 
452
        return 0;
 
453
}
 
454
 
 
455
static int cx22702_read_status(struct dvb_frontend *fe, fe_status_t *status)
 
456
{
 
457
        struct cx22702_state *state = fe->demodulator_priv;
 
458
        u8 reg0A;
 
459
        u8 reg23;
 
460
 
 
461
        *status = 0;
 
462
 
 
463
        reg0A = cx22702_readreg(state, 0x0A);
 
464
        reg23 = cx22702_readreg(state, 0x23);
 
465
 
 
466
        dprintk("%s: status demod=0x%02x agc=0x%02x\n"
 
467
                , __func__, reg0A, reg23);
 
468
 
 
469
        if (reg0A & 0x10) {
 
470
                *status |= FE_HAS_LOCK;
 
471
                *status |= FE_HAS_VITERBI;
 
472
                *status |= FE_HAS_SYNC;
 
473
        }
 
474
 
 
475
        if (reg0A & 0x20)
 
476
                *status |= FE_HAS_CARRIER;
 
477
 
 
478
        if (reg23 < 0xf0)
 
479
                *status |= FE_HAS_SIGNAL;
 
480
 
 
481
        return 0;
 
482
}
 
483
 
 
484
static int cx22702_read_ber(struct dvb_frontend *fe, u32 *ber)
 
485
{
 
486
        struct cx22702_state *state = fe->demodulator_priv;
 
487
 
 
488
        if (cx22702_readreg(state, 0xE4) & 0x02) {
 
489
                /* Realtime statistics */
 
490
                *ber = (cx22702_readreg(state, 0xDE) & 0x7F) << 7
 
491
                        | (cx22702_readreg(state, 0xDF) & 0x7F);
 
492
        } else {
 
493
                /* Averagtine statistics */
 
494
                *ber = (cx22702_readreg(state, 0xDE) & 0x7F) << 7
 
495
                        | cx22702_readreg(state, 0xDF);
 
496
        }
 
497
 
 
498
        return 0;
 
499
}
 
500
 
 
501
static int cx22702_read_signal_strength(struct dvb_frontend *fe,
 
502
        u16 *signal_strength)
 
503
{
 
504
        struct cx22702_state *state = fe->demodulator_priv;
 
505
 
 
506
        u16 rs_ber;
 
507
        rs_ber = cx22702_readreg(state, 0x23);
 
508
        *signal_strength = (rs_ber << 8) | rs_ber;
 
509
 
 
510
        return 0;
 
511
}
 
512
 
 
513
static int cx22702_read_snr(struct dvb_frontend *fe, u16 *snr)
 
514
{
 
515
        struct cx22702_state *state = fe->demodulator_priv;
 
516
 
 
517
        u16 rs_ber;
 
518
        if (cx22702_readreg(state, 0xE4) & 0x02) {
 
519
                /* Realtime statistics */
 
520
                rs_ber = (cx22702_readreg(state, 0xDE) & 0x7F) << 7
 
521
                        | (cx22702_readreg(state, 0xDF) & 0x7F);
 
522
        } else {
 
523
                /* Averagine statistics */
 
524
                rs_ber = (cx22702_readreg(state, 0xDE) & 0x7F) << 8
 
525
                        | cx22702_readreg(state, 0xDF);
 
526
        }
 
527
        *snr = ~rs_ber;
 
528
 
 
529
        return 0;
 
530
}
 
531
 
 
532
static int cx22702_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
 
533
{
 
534
        struct cx22702_state *state = fe->demodulator_priv;
 
535
 
 
536
        u8 _ucblocks;
 
537
 
 
538
        /* RS Uncorrectable Packet Count then reset */
 
539
        _ucblocks = cx22702_readreg(state, 0xE3);
 
540
        if (state->prevUCBlocks < _ucblocks)
 
541
                *ucblocks = (_ucblocks - state->prevUCBlocks);
 
542
        else
 
543
                *ucblocks = state->prevUCBlocks - _ucblocks;
 
544
        state->prevUCBlocks = _ucblocks;
 
545
 
 
546
        return 0;
 
547
}
 
548
 
 
549
static int cx22702_get_frontend(struct dvb_frontend *fe,
 
550
        struct dvb_frontend_parameters *p)
 
551
{
 
552
        struct cx22702_state *state = fe->demodulator_priv;
 
553
 
 
554
        u8 reg0C = cx22702_readreg(state, 0x0C);
 
555
 
 
556
        p->inversion = reg0C & 0x1 ? INVERSION_ON : INVERSION_OFF;
 
557
        return cx22702_get_tps(state, &p->u.ofdm);
 
558
}
 
559
 
 
560
static int cx22702_get_tune_settings(struct dvb_frontend *fe,
 
561
        struct dvb_frontend_tune_settings *tune)
 
562
{
 
563
        tune->min_delay_ms = 1000;
 
564
        return 0;
 
565
}
 
566
 
 
567
static void cx22702_release(struct dvb_frontend *fe)
 
568
{
 
569
        struct cx22702_state *state = fe->demodulator_priv;
 
570
        kfree(state);
 
571
}
 
572
 
 
573
static const struct dvb_frontend_ops cx22702_ops;
 
574
 
 
575
struct dvb_frontend *cx22702_attach(const struct cx22702_config *config,
 
576
        struct i2c_adapter *i2c)
 
577
{
 
578
        struct cx22702_state *state = NULL;
 
579
 
 
580
        /* allocate memory for the internal state */
 
581
        state = kzalloc(sizeof(struct cx22702_state), GFP_KERNEL);
 
582
        if (state == NULL)
 
583
                goto error;
 
584
 
 
585
        /* setup the state */
 
586
        state->config = config;
 
587
        state->i2c = i2c;
 
588
 
 
589
        /* check if the demod is there */
 
590
        if (cx22702_readreg(state, 0x1f) != 0x3)
 
591
                goto error;
 
592
 
 
593
        /* create dvb_frontend */
 
594
        memcpy(&state->frontend.ops, &cx22702_ops,
 
595
                sizeof(struct dvb_frontend_ops));
 
596
        state->frontend.demodulator_priv = state;
 
597
        return &state->frontend;
 
598
 
 
599
error:
 
600
        kfree(state);
 
601
        return NULL;
 
602
}
 
603
EXPORT_SYMBOL(cx22702_attach);
 
604
 
 
605
static const struct dvb_frontend_ops cx22702_ops = {
 
606
 
 
607
        .info = {
 
608
                .name                   = "Conexant CX22702 DVB-T",
 
609
                .type                   = FE_OFDM,
 
610
                .frequency_min          = 177000000,
 
611
                .frequency_max          = 858000000,
 
612
                .frequency_stepsize     = 166666,
 
613
                .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
 
614
                FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
 
615
                FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
 
616
                FE_CAN_HIERARCHY_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
 
617
                FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER
 
618
        },
 
619
 
 
620
        .release = cx22702_release,
 
621
 
 
622
        .init = cx22702_init,
 
623
        .i2c_gate_ctrl = cx22702_i2c_gate_ctrl,
 
624
 
 
625
        .set_frontend = cx22702_set_tps,
 
626
        .get_frontend = cx22702_get_frontend,
 
627
        .get_tune_settings = cx22702_get_tune_settings,
 
628
 
 
629
        .read_status = cx22702_read_status,
 
630
        .read_ber = cx22702_read_ber,
 
631
        .read_signal_strength = cx22702_read_signal_strength,
 
632
        .read_snr = cx22702_read_snr,
 
633
        .read_ucblocks = cx22702_read_ucblocks,
 
634
};
 
635
 
 
636
MODULE_DESCRIPTION("Conexant CX22702 DVB-T Demodulator driver");
 
637
MODULE_AUTHOR("Steven Toth");
 
638
MODULE_LICENSE("GPL");