[PATCH] dvb: DST: reorganize Twinhan DST driver to support CI
[linux-2.6] / drivers / media / dvb / bt8xx / dst.c
1 /*
2
3         Frontend/Card driver for TwinHan DST Frontend
4         Copyright (C) 2003 Jamie Honan
5         Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com)
6
7         This program is free software; you can redistribute it and/or modify
8         it under the terms of the GNU General Public License as published by
9         the Free Software Foundation; either version 2 of the License, or
10         (at your option) any later version.
11
12         This program is distributed in the hope that it will be useful,
13         but WITHOUT ANY WARRANTY; without even the implied warranty of
14         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15         GNU General Public License for more details.
16
17         You should have received a copy of the GNU General Public License
18         along with this program; if not, write to the Free Software
19         Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22
23 #include <linux/kernel.h>
24 #include <linux/module.h>
25 #include <linux/init.h>
26 #include <linux/string.h>
27 #include <linux/slab.h>
28 #include <linux/vmalloc.h>
29 #include <linux/delay.h>
30 #include <asm/div64.h>
31
32 #include "dvb_frontend.h"
33 #include "dst_priv.h"
34 #include "dst_common.h"
35
36
37 static unsigned int verbose = 1;
38 module_param(verbose, int, 0644);
39 MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)");
40
41 static unsigned int debug = 1;
42 module_param(debug, int, 0644);
43 MODULE_PARM_DESC(debug, "debug messages, default is 0 (yes)");
44
45 static unsigned int dst_addons;
46 module_param(dst_addons, int, 0644);
47 MODULE_PARM_DESC(dst_addons, "CA daughterboard, default is 0 (no)");
48
49 static unsigned int new_fw;
50 module_param(new_fw, int, 0644);
51 MODULE_PARM_DESC(new_fw, "Support for the new interface firmware, default 0");
52
53
54
55 #define dprintk if (debug) printk
56
57 #define HAS_LOCK        1
58 #define ATTEMPT_TUNE    2
59 #define HAS_POWER       4
60
61 static void dst_packsize(struct dst_state* state, int psize)
62 {
63         union dst_gpio_packet bits;
64
65         bits.psize = psize;
66         bt878_device_control(state->bt, DST_IG_TS, &bits);
67 }
68
69 int dst_gpio_outb(struct dst_state* state, u32 mask, u32 enbb, u32 outhigh, int delay)
70 {
71         union dst_gpio_packet enb;
72         union dst_gpio_packet bits;
73         int err;
74
75         enb.enb.mask = mask;
76         enb.enb.enable = enbb;
77         if (verbose > 4)
78                 dprintk("%s: mask=[%04x], enbb=[%04x], outhigh=[%04x]\n", __FUNCTION__, mask, enbb, outhigh);
79
80         if ((err = bt878_device_control(state->bt, DST_IG_ENABLE, &enb)) < 0) {
81                 dprintk("%s: dst_gpio_enb error (err == %i, mask == %02x, enb == %02x)\n", __FUNCTION__, err, mask, enbb);
82                 return -EREMOTEIO;
83         }
84
85         msleep(1);
86
87         /* because complete disabling means no output, no need to do output packet */
88         if (enbb == 0)
89                 return 0;
90
91         if (delay)
92                 msleep(10);
93
94         bits.outp.mask = enbb;
95         bits.outp.highvals = outhigh;
96
97         if ((err = bt878_device_control(state->bt, DST_IG_WRITE, &bits)) < 0) {
98                 dprintk("%s: dst_gpio_outb error (err == %i, enbb == %02x, outhigh == %02x)\n", __FUNCTION__, err, enbb, outhigh);
99                 return -EREMOTEIO;
100         }
101         return 0;
102 }
103 EXPORT_SYMBOL(dst_gpio_outb);
104
105 int dst_gpio_inb(struct dst_state *state, u8 * result)
106 {
107         union dst_gpio_packet rd_packet;
108         int err;
109
110         *result = 0;
111
112         if ((err = bt878_device_control(state->bt, DST_IG_READ, &rd_packet)) < 0) {
113                 dprintk("%s: dst_gpio_inb error (err == %i)\n", __FUNCTION__, err);
114                 return -EREMOTEIO;
115         }
116
117         *result = (u8) rd_packet.rd.value;
118         return 0;
119 }
120 EXPORT_SYMBOL(dst_gpio_inb);
121
122 int rdc_reset_state(struct dst_state *state)
123 {
124         if (verbose > 1)
125                 dprintk("%s: Resetting state machine\n", __FUNCTION__);
126
127         if (dst_gpio_outb(state, RDC_8820_INT, RDC_8820_INT, 0, NO_DELAY) < 0) {
128                 dprintk("%s: dst_gpio_outb ERROR !\n", __FUNCTION__);
129                 return -1;
130         }
131
132         msleep(10);
133
134         if (dst_gpio_outb(state, RDC_8820_INT, RDC_8820_INT, RDC_8820_INT, NO_DELAY) < 0) {
135                 dprintk("%s: dst_gpio_outb ERROR !\n", __FUNCTION__);
136                 msleep(10);
137                 return -1;
138         }
139
140         return 0;
141 }
142 EXPORT_SYMBOL(rdc_reset_state);
143
144 int rdc_8820_reset(struct dst_state *state)
145 {
146         if (verbose > 1)
147                 dprintk("%s: Resetting DST\n", __FUNCTION__);
148
149         if (dst_gpio_outb(state, RDC_8820_RESET, RDC_8820_RESET, 0, NO_DELAY) < 0) {
150                 dprintk("%s: dst_gpio_outb ERROR !\n", __FUNCTION__);
151                 return -1;
152         }
153         msleep(1);
154
155         if (dst_gpio_outb(state, RDC_8820_RESET, RDC_8820_RESET, RDC_8820_RESET, DELAY) < 0) {
156                 dprintk("%s: dst_gpio_outb ERROR !\n", __FUNCTION__);
157                 return -1;
158         }
159
160         return 0;
161 }
162 EXPORT_SYMBOL(rdc_8820_reset);
163
164 int dst_pio_enable(struct dst_state *state)
165 {
166         if (dst_gpio_outb(state, ~0, RDC_8820_PIO_0_ENABLE, 0, NO_DELAY) < 0) {
167                 dprintk("%s: dst_gpio_outb ERROR !\n", __FUNCTION__);
168                 return -1;
169         }
170         msleep(1);
171
172         return 0;
173 }
174 EXPORT_SYMBOL(dst_pio_enable);
175
176 int dst_pio_disable(struct dst_state *state)
177 {
178         if (dst_gpio_outb(state, ~0, RDC_8820_PIO_0_DISABLE, RDC_8820_PIO_0_DISABLE, NO_DELAY) < 0) {
179                 dprintk("%s: dst_gpio_outb ERROR !\n", __FUNCTION__);
180                 return -1;
181         }
182
183         return 0;
184 }
185 EXPORT_SYMBOL(dst_pio_disable);
186
187 int dst_wait_dst_ready(struct dst_state *state, u8 delay_mode)
188 {
189         u8 reply;
190         int i;
191
192         for (i = 0; i < 200; i++) {
193                 if (dst_gpio_inb(state, &reply) < 0) {
194                         dprintk("%s: dst_gpio_inb ERROR !\n", __FUNCTION__);
195                         return -1;
196                 }
197
198                 if ((reply & RDC_8820_PIO_0_ENABLE) == 0) {
199                         if (verbose > 4)
200                                 dprintk("%s: dst wait ready after %d\n", __FUNCTION__, i);
201                         return 1;
202                 }
203                 msleep(1);
204         }
205         if (verbose > 1)
206                 dprintk("%s: dst wait NOT ready after %d\n", __FUNCTION__, i);
207
208         return 0;
209 }
210 EXPORT_SYMBOL(dst_wait_dst_ready);
211
212 int dst_error_recovery(struct dst_state *state)
213 {
214         dprintk("%s: Trying to return from previous errors...\n", __FUNCTION__);
215         dst_pio_disable(state);
216         msleep(10);
217         dst_pio_enable(state);
218         msleep(10);
219
220         return 0;
221 }
222 EXPORT_SYMBOL(dst_error_recovery);
223
224 int dst_error_bailout(struct dst_state *state)
225 {
226         dprintk("%s: Trying to bailout from previous error...\n", __FUNCTION__);
227         rdc_8820_reset(state);
228         dst_pio_disable(state);
229         msleep(10);
230
231         return 0;
232 }
233 EXPORT_SYMBOL(dst_error_bailout);
234
235
236 int dst_comm_init(struct dst_state* state)
237 {
238         if (verbose > 1)
239                 dprintk ("%s: Initializing DST..\n", __FUNCTION__);
240         if ((dst_pio_enable(state)) < 0) {
241                 dprintk("%s: PIO Enable Failed.\n", __FUNCTION__);
242                 return -1;
243         }
244         if ((rdc_reset_state(state)) < 0) {
245                 dprintk("%s: RDC 8820 State RESET Failed.\n", __FUNCTION__);
246                 return -1;
247         }
248         return 0;
249 }
250 EXPORT_SYMBOL(dst_comm_init);
251
252
253 int write_dst(struct dst_state *state, u8 *data, u8 len)
254 {
255         struct i2c_msg msg = {
256                 .addr = state->config->demod_address,.flags = 0,.buf = data,.len = len
257         };
258
259         int err;
260         int cnt;
261         if (debug && (verbose > 4)) {
262                 u8 i;
263                 if (verbose > 4) {
264                         dprintk("%s writing", __FUNCTION__);
265                         for (i = 0; i < len; i++)
266                                 dprintk(" %02x", data[i]);
267                         dprintk("\n");
268                 }
269         }
270         for (cnt = 0; cnt < 2; cnt++) {
271                 if ((err = i2c_transfer(state->i2c, &msg, 1)) < 0) {
272                         dprintk("%s: _write_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)\n", __FUNCTION__, err, len, data[0]);
273                         dst_error_recovery(state);
274                         continue;
275                 } else
276                         break;
277         }
278
279         if (cnt >= 2) {
280                 if (verbose > 1)
281                         printk("%s: RDC 8820 RESET...\n", __FUNCTION__);
282                 dst_error_bailout(state);
283
284                 return -1;
285         }
286
287         return 0;
288 }
289 EXPORT_SYMBOL(write_dst);
290
291 int read_dst(struct dst_state *state, u8 * ret, u8 len)
292 {
293         struct i2c_msg msg = {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = ret,.len = len };
294         int err;
295         int cnt;
296
297         for (cnt = 0; cnt < 2; cnt++) {
298                 if ((err = i2c_transfer(state->i2c, &msg, 1)) < 0) {
299
300                         dprintk("%s: read_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)\n", __FUNCTION__, err, len, ret[0]);
301                         dst_error_recovery(state);
302
303                         continue;
304                 } else
305                         break;
306         }
307         if (cnt >= 2) {
308                 if (verbose > 1)
309                         printk("%s: RDC 8820 RESET...\n", __FUNCTION__);
310                 dst_error_bailout(state);
311
312                 return -1;
313         }
314         if (debug && (verbose > 4)) {
315                 dprintk("%s reply is 0x%x\n", __FUNCTION__, ret[0]);
316                 for (err = 1; err < len; err++)
317                         dprintk(" 0x%x", ret[err]);
318                 if (err > 1)
319                         dprintk("\n");
320         }
321
322         return 0;
323 }
324 EXPORT_SYMBOL(read_dst);
325
326 static int dst_set_freq(struct dst_state *state, u32 freq)
327 {
328         u8 *val;
329
330         state->frequency = freq;
331
332         // dprintk("%s: set frequency %u\n", __FUNCTION__, freq);
333         if (state->dst_type == DST_TYPE_IS_SAT) {
334                 freq = freq / 1000;
335                 if (freq < 950 || freq > 2150)
336                         return -EINVAL;
337                 val = &state->tx_tuna[0];
338                 val[2] = (freq >> 8) & 0x7f;
339                 val[3] = (u8) freq;
340                 val[4] = 1;
341                 val[8] &= ~4;
342                 if (freq < 1531)
343                         val[8] |= 4;
344         } else if (state->dst_type == DST_TYPE_IS_TERR) {
345                 freq = freq / 1000;
346                 if (freq < 137000 || freq > 858000)
347                         return -EINVAL;
348                 val = &state->tx_tuna[0];
349                 val[2] = (freq >> 16) & 0xff;
350                 val[3] = (freq >> 8) & 0xff;
351                 val[4] = (u8) freq;
352                 val[5] = 0;
353                 switch (state->bandwidth) {
354                 case BANDWIDTH_6_MHZ:
355                         val[6] = 6;
356                         break;
357
358                 case BANDWIDTH_7_MHZ:
359                 case BANDWIDTH_AUTO:
360                         val[6] = 7;
361                         break;
362
363                 case BANDWIDTH_8_MHZ:
364                         val[6] = 8;
365                         break;
366                 }
367
368                 val[7] = 0;
369                 val[8] = 0;
370         } else if (state->dst_type == DST_TYPE_IS_CABLE) {
371                 /* guess till will get one */
372                 freq = freq / 1000;
373                 val = &state->tx_tuna[0];
374                 val[2] = (freq >> 16) & 0xff;
375                 val[3] = (freq >> 8) & 0xff;
376                 val[4] = (u8) freq;
377         } else
378                 return -EINVAL;
379         return 0;
380 }
381
382 static int dst_set_bandwidth(struct dst_state* state, fe_bandwidth_t bandwidth)
383 {
384         u8 *val;
385
386         state->bandwidth = bandwidth;
387
388         if (state->dst_type != DST_TYPE_IS_TERR)
389                 return 0;
390
391         val = &state->tx_tuna[0];
392         switch (bandwidth) {
393         case BANDWIDTH_6_MHZ:
394                 val[6] = 6;
395                 break;
396
397         case BANDWIDTH_7_MHZ:
398                 val[6] = 7;
399                 break;
400
401         case BANDWIDTH_8_MHZ:
402                 val[6] = 8;
403                 break;
404
405         default:
406                 return -EINVAL;
407         }
408         return 0;
409 }
410
411 static int dst_set_inversion(struct dst_state* state, fe_spectral_inversion_t inversion)
412 {
413         u8 *val;
414
415         state->inversion = inversion;
416
417         val = &state->tx_tuna[0];
418
419         val[8] &= ~0x80;
420
421         switch (inversion) {
422         case INVERSION_OFF:
423                 break;
424         case INVERSION_ON:
425                 val[8] |= 0x80;
426                 break;
427         default:
428                 return -EINVAL;
429         }
430         return 0;
431 }
432
433 static int dst_set_fec(struct dst_state* state, fe_code_rate_t fec)
434 {
435         state->fec = fec;
436         return 0;
437 }
438
439 static fe_code_rate_t dst_get_fec(struct dst_state* state)
440 {
441         return state->fec;
442 }
443
444 static int dst_set_symbolrate(struct dst_state* state, u32 srate)
445 {
446         u8 *val;
447         u32 symcalc;
448         u64 sval;
449
450         state->symbol_rate = srate;
451
452         if (state->dst_type == DST_TYPE_IS_TERR) {
453                 return 0;
454         }
455         // dprintk("%s: set srate %u\n", __FUNCTION__, srate);
456         srate /= 1000;
457         val = &state->tx_tuna[0];
458
459         if (state->type_flags & DST_TYPE_HAS_SYMDIV) {
460                 sval = srate;
461                 sval <<= 20;
462                 do_div(sval, 88000);
463                 symcalc = (u32) sval;
464                 // dprintk("%s: set symcalc %u\n", __FUNCTION__, symcalc);
465                 val[5] = (u8) (symcalc >> 12);
466                 val[6] = (u8) (symcalc >> 4);
467                 val[7] = (u8) (symcalc << 4);
468         } else {
469                 val[5] = (u8) (srate >> 16) & 0x7f;
470                 val[6] = (u8) (srate >> 8);
471                 val[7] = (u8) srate;
472         }
473         val[8] &= ~0x20;
474         if (srate > 8000)
475                 val[8] |= 0x20;
476         return 0;
477 }
478
479 u8 dst_check_sum(u8 * buf, u32 len)
480 {
481         u32 i;
482         u8 val = 0;
483         if (!len)
484                 return 0;
485         for (i = 0; i < len; i++) {
486                 val += buf[i];
487         }
488         return ((~val) + 1);
489 }
490 EXPORT_SYMBOL(dst_check_sum);
491
492 static void dst_type_flags_print(u32 type_flags)
493 {
494         printk("DST type flags :");
495         if (type_flags & DST_TYPE_HAS_NEWTUNE)
496                 printk(" 0x%x newtuner", DST_TYPE_HAS_NEWTUNE);
497         if (type_flags & DST_TYPE_HAS_TS204)
498                 printk(" 0x%x ts204", DST_TYPE_HAS_TS204);
499         if (type_flags & DST_TYPE_HAS_SYMDIV)
500                 printk(" 0x%x symdiv", DST_TYPE_HAS_SYMDIV);
501         if (type_flags & DST_TYPE_HAS_FW_1)
502                 printk(" 0x%x firmware version = 1", DST_TYPE_HAS_FW_1);
503         if (type_flags & DST_TYPE_HAS_FW_2)
504                 printk(" 0x%x firmware version = 2", DST_TYPE_HAS_FW_2);
505         if (type_flags & DST_TYPE_HAS_FW_3)
506                 printk(" 0x%x firmware version = 3", DST_TYPE_HAS_FW_3);
507
508         printk("\n");
509 }
510
511
512 static int dst_type_print (u8 type)
513 {
514         char *otype;
515         switch (type) {
516         case DST_TYPE_IS_SAT:
517                 otype = "satellite";
518                 break;
519
520         case DST_TYPE_IS_TERR:
521                 otype = "terrestrial";
522                 break;
523
524         case DST_TYPE_IS_CABLE:
525                 otype = "cable";
526                 break;
527
528         default:
529                 printk("%s: invalid dst type %d\n", __FUNCTION__, type);
530                 return -EINVAL;
531         }
532         printk("DST type : %s\n", otype);
533
534         return 0;
535 }
536
537 /*
538         Known cards list
539         Satellite
540         -------------------
541
542         VP-1020   DST-MOT       LG(old), TS=188
543
544         VP-1020   DST-03T       LG(new), TS=204
545         VP-1022   DST-03T       LG(new), TS=204
546         VP-1025   DST-03T       LG(new), TS=204
547
548         VP-1030   DSTMCI,       LG(new), TS=188
549         VP-1032   DSTMCI,       LG(new), TS=188
550
551         Cable
552         -------------------
553         VP-2030   DCT-CI,       Samsung, TS=204
554         VP-2021   DCT-CI,       Unknown, TS=204
555         VP-2031   DCT-CI,       Philips, TS=188
556         VP-2040   DCT-CI,       Philips, TS=188, with CA daughter board
557         VP-2040   DCT-CI,       Philips, TS=204, without CA daughter board
558
559         Terrestrial
560         -------------------
561         VP-3050  DTTNXT                  TS=188
562         VP-3040  DTT-CI,        Philips, TS=188
563         VP-3040  DTT-CI,        Philips, TS=204
564
565         ATSC
566         -------------------
567         VP-3220  ATSCDI,                 TS=188
568         VP-3250  ATSCAD,                 TS=188
569
570 */
571
572 struct dst_types dst_tlist[] = {
573         {
574                 .device_id = "DST-020",
575                 .offset = 0,
576                 .dst_type =  DST_TYPE_IS_SAT,
577                 .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1,
578                 .dst_feature = 0
579         },      /*      obsolete        */
580
581         {
582                 .device_id = "DST-030",
583                 .offset =  0,
584                 .dst_type = DST_TYPE_IS_SAT,
585                 .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_1,
586                 .dst_feature = 0
587         },      /*      obsolete        */
588
589         {
590                 .device_id = "DST-03T",
591                 .offset = 0,
592                 .dst_type = DST_TYPE_IS_SAT,
593                 .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_2,
594                 .dst_feature = DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4 | DST_TYPE_HAS_DISEQC5
595                                                          | DST_TYPE_HAS_MAC | DST_TYPE_HAS_MOTO
596          },
597
598         {
599                 .device_id = "DST-MOT",
600                 .offset =  0,
601                 .dst_type = DST_TYPE_IS_SAT,
602                 .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1,
603                 .dst_feature = 0
604         },      /*      obsolete        */
605
606         {
607                 .device_id = "DST-CI",
608                 .offset = 1,
609                 .dst_type = DST_TYPE_IS_SAT,
610                 .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_1,
611                 .dst_feature = DST_TYPE_HAS_CA
612         },      /* unknown to vendor    */
613
614         {
615                 .device_id = "DSTMCI",
616                 .offset = 1,
617                 .dst_type = DST_TYPE_IS_SAT,
618                 .type_flags = DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_2,
619                 .dst_feature = DST_TYPE_HAS_CA | DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4
620                                                         | DST_TYPE_HAS_MOTO | DST_TYPE_HAS_MAC
621         },
622
623         {
624                 .device_id = "DSTFCI",
625                 .offset = 1,
626                 .dst_type = DST_TYPE_IS_SAT,
627                 .type_flags = DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_1,
628                 .dst_feature = 0
629         },      /* unknown to vendor    */
630
631         {
632                 .device_id = "DCT-CI",
633                 .offset = 1,
634                 .dst_type = DST_TYPE_IS_CABLE,
635                 .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_1                                                                     | DST_TYPE_HAS_FW_2,
636                 .dst_feature = DST_TYPE_HAS_CA
637         },
638
639         {
640                 .device_id = "DCTNEW",
641                 .offset = 1,
642                 .dst_type = DST_TYPE_IS_CABLE,
643                 .type_flags = DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_3,
644                 .dst_feature = 0
645         },
646
647         {
648                 .device_id = "DTT-CI",
649                 .offset = 1,
650                 .dst_type = DST_TYPE_IS_TERR,
651                 .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_2,
652                 .dst_feature = 0
653         },
654
655         {
656                 .device_id = "DTTDIG",
657                 .offset = 1,
658                 .dst_type = DST_TYPE_IS_TERR,
659                 .type_flags = DST_TYPE_HAS_FW_2,
660                 .dst_feature = 0
661         },
662
663         {
664                 .device_id = "DTTNXT",
665                 .offset = 1,
666                 .dst_type = DST_TYPE_IS_TERR,
667                 .type_flags = DST_TYPE_HAS_FW_2,
668                 .dst_feature = DST_TYPE_HAS_ANALOG
669         },
670
671         {
672                 .device_id = "ATSCDI",
673                 .offset = 1,
674                 .dst_type = DST_TYPE_IS_ATSC,
675                 .type_flags = DST_TYPE_HAS_FW_2,
676                 .dst_feature = 0
677         },
678
679         {
680                 .device_id = "ATSCAD",
681                 .offset = 1,
682                 .dst_type = DST_TYPE_IS_ATSC,
683                 .type_flags = DST_TYPE_HAS_FW_2,
684                 .dst_feature = 0
685         },
686
687         { }
688
689 };
690
691
692 static int dst_get_device_id(struct dst_state *state)
693 {
694         u8 reply;
695
696         int i;
697         struct dst_types *p_dst_type;
698         u8 use_dst_type = 0;
699         u32 use_type_flags = 0;
700
701         static u8 device_type[8] = {0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff};
702
703         device_type[7] = dst_check_sum(device_type, 7);
704
705         if (write_dst(state, device_type, FIXED_COMM))
706                 return -1;              /*      Write failed            */
707
708         if ((dst_pio_disable(state)) < 0)
709                 return -1;
710
711         if (read_dst(state, &reply, GET_ACK))
712                 return -1;              /*      Read failure            */
713
714         if (reply != ACK) {
715                 dprintk("%s: Write not Acknowledged! [Reply=0x%02x]\n", __FUNCTION__, reply);
716                 return -1;              /*      Unack'd write           */
717         }
718
719         if (!dst_wait_dst_ready(state, DEVICE_INIT))
720                 return -1;              /*      DST not ready yet       */
721
722         if (read_dst(state, state->rxbuffer, FIXED_COMM))
723                 return -1;
724
725         dst_pio_disable(state);
726
727         if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) {
728                 dprintk("%s: Checksum failure! \n", __FUNCTION__);
729                 return -1;              /*      Checksum failure        */
730         }
731
732         state->rxbuffer[7] = '\0';
733
734         for (i = 0, p_dst_type = dst_tlist; i < ARRAY_SIZE (dst_tlist); i++, p_dst_type++) {
735                 if (!strncmp (&state->rxbuffer[p_dst_type->offset], p_dst_type->device_id, strlen (p_dst_type->device_id))) {
736                         use_type_flags = p_dst_type->type_flags;
737                         use_dst_type = p_dst_type->dst_type;
738
739                         /*      Card capabilities       */
740                         state->dst_hw_cap = p_dst_type->dst_feature;
741                         printk ("%s: Recognise [%s]\n", __FUNCTION__, p_dst_type->device_id);
742
743                         break;
744                 }
745         }
746
747         if (i >= sizeof (dst_tlist) / sizeof (dst_tlist [0])) {
748                 printk("%s: Unable to recognize %s or %s\n", __FUNCTION__, &state->rxbuffer[0], &state->rxbuffer[1]);
749                 printk("%s: please email linux-dvb@linuxtv.org with this type in\n", __FUNCTION__);
750                 use_dst_type = DST_TYPE_IS_SAT;
751                 use_type_flags = DST_TYPE_HAS_SYMDIV;
752         }
753
754         dst_type_print(use_dst_type);
755         state->type_flags = use_type_flags;
756         state->dst_type = use_dst_type;
757         dst_type_flags_print(state->type_flags);
758
759         if (state->type_flags & DST_TYPE_HAS_TS204) {
760                 dst_packsize(state, 204);
761         }
762
763         return 0;
764 }
765
766 static int dst_probe(struct dst_state *state)
767 {
768         if ((rdc_8820_reset(state)) < 0) {
769                 dprintk("%s: RDC 8820 RESET Failed.\n", __FUNCTION__);
770                 return -1;
771         }
772         msleep(4000);
773         if ((dst_comm_init(state)) < 0) {
774                 dprintk("%s: DST Initialization Failed.\n", __FUNCTION__);
775                 return -1;
776         }
777
778         if (dst_get_device_id(state) < 0) {
779                 dprintk("%s: unknown device.\n", __FUNCTION__);
780                 return -1;
781         }
782
783         return 0;
784 }
785
786 int dst_command(struct dst_state* state, u8 * data, u8 len)
787 {
788         u8 reply;
789         if ((dst_comm_init(state)) < 0) {
790                 dprintk("%s: DST Communication Initialization Failed.\n", __FUNCTION__);
791                 return -1;
792         }
793
794         if (write_dst(state, data, len)) {
795                 if (verbose > 1)
796                         dprintk("%s: Tring to recover.. \n", __FUNCTION__);
797                 if ((dst_error_recovery(state)) < 0) {
798                         dprintk("%s: Recovery Failed.\n", __FUNCTION__);
799                         return -1;
800                 }
801                 return -1;
802         }
803         if ((dst_pio_disable(state)) < 0) {
804                 dprintk("%s: PIO Disable Failed.\n", __FUNCTION__);
805                 return -1;
806         }
807
808         if (read_dst(state, &reply, GET_ACK)) {
809                 if (verbose > 1)
810                         dprintk("%s: Trying to recover.. \n", __FUNCTION__);
811                 if ((dst_error_recovery(state)) < 0) {
812                         dprintk("%s: Recovery Failed.\n", __FUNCTION__);
813                         return -1;
814                 }
815                 return -1;
816         }
817
818         if (reply != ACK) {
819                 dprintk("%s: write not acknowledged 0x%02x \n", __FUNCTION__, reply);
820                 return -1;
821         }
822         if (len >= 2 && data[0] == 0 && (data[1] == 1 || data[1] == 3))
823                 return 0;
824         if (!dst_wait_dst_ready(state, NO_DELAY))
825                 return -1;
826
827         if (read_dst(state, state->rxbuffer, FIXED_COMM)) {
828                 if (verbose > 1)
829                         dprintk("%s: Trying to recover.. \n", __FUNCTION__);
830                 if ((dst_error_recovery(state)) < 0) {
831                         dprintk("%s: Recovery failed.\n", __FUNCTION__);
832                         return -1;
833                 }
834                 return -1;
835         }
836
837         if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) {
838                 dprintk("%s: checksum failure\n", __FUNCTION__);
839                 return -1;
840         }
841
842         return 0;
843 }
844 EXPORT_SYMBOL(dst_command);
845
846 static int dst_get_signal(struct dst_state* state)
847 {
848         int retval;
849         u8 get_signal[] = { 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb };
850
851         if ((state->diseq_flags & ATTEMPT_TUNE) == 0) {
852                 state->decode_lock = state->decode_strength = state->decode_snr = 0;
853                 return 0;
854         }
855         if (0 == (state->diseq_flags & HAS_LOCK)) {
856                 state->decode_lock = state->decode_strength = state->decode_snr = 0;
857                 return 0;
858         }
859         if (time_after_eq(jiffies, state->cur_jiff + (HZ / 5))) {
860                 retval = dst_command(state, get_signal, 8);
861                 if (retval < 0)
862                         return retval;
863                 if (state->dst_type == DST_TYPE_IS_SAT) {
864                         state->decode_lock = ((state->rxbuffer[6] & 0x10) == 0) ? 1 : 0;
865                         state->decode_strength = state->rxbuffer[5] << 8;
866                         state->decode_snr = state->rxbuffer[2] << 8 | state->rxbuffer[3];
867                 } else if ((state->dst_type == DST_TYPE_IS_TERR) || (state->dst_type == DST_TYPE_IS_CABLE)) {
868                         state->decode_lock = (state->rxbuffer[1]) ? 1 : 0;
869                         state->decode_strength = state->rxbuffer[4] << 8;
870                         state->decode_snr = state->rxbuffer[3] << 8;
871                 }
872                 state->cur_jiff = jiffies;
873         }
874         return 0;
875 }
876
877 static int dst_tone_power_cmd(struct dst_state* state)
878 {
879         u8 paket[8] = { 0x00, 0x09, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00 };
880
881         if (state->dst_type == DST_TYPE_IS_TERR)
882                 return 0;
883
884         if (state->voltage == SEC_VOLTAGE_OFF)
885                 paket[4] = 0;
886         else
887                 paket[4] = 1;
888
889         if (state->tone == SEC_TONE_ON)
890                 paket[2] = 0x02;
891         else
892                 paket[2] = 0;
893         if (state->minicmd == SEC_MINI_A)
894                 paket[3] = 0x02;
895         else
896                 paket[3] = 0;
897
898         paket[7] = dst_check_sum (paket, 7);
899         dst_command(state, paket, 8);
900         return 0;
901 }
902
903 static int dst_get_tuna(struct dst_state* state)
904 {
905         int retval;
906
907         if ((state->diseq_flags & ATTEMPT_TUNE) == 0)
908                 return 0;
909
910         state->diseq_flags &= ~(HAS_LOCK);
911         if (!dst_wait_dst_ready(state, NO_DELAY))
912                 return 0;
913
914         msleep(10);
915
916         if (state->type_flags & DST_TYPE_HAS_NEWTUNE) {
917                 /* how to get variable length reply ???? */
918                 retval = read_dst(state, state->rx_tuna, 10);
919         } else {
920                 retval = read_dst(state, &state->rx_tuna[2], FIXED_COMM);
921         }
922
923         if (retval < 0) {
924                 dprintk("%s: read not successful\n", __FUNCTION__);
925                 return 0;
926         }
927
928         if (state->type_flags & DST_TYPE_HAS_NEWTUNE) {
929                 if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) {
930                         dprintk("%s: checksum failure?\n", __FUNCTION__);
931                         return 0;
932                 }
933         } else {
934                 if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[2], 7)) {
935                         dprintk("%s: checksum failure?\n", __FUNCTION__);
936                         return 0;
937                 }
938         }
939         if (state->rx_tuna[2] == 0 && state->rx_tuna[3] == 0)
940                 return 0;
941         state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 8) + state->rx_tuna[3];
942
943         state->decode_lock = 1;
944         /*
945            dst->decode_n1 = (dst->rx_tuna[4] << 8) +
946            (dst->rx_tuna[5]);
947
948            dst->decode_n2 = (dst->rx_tuna[8] << 8) +
949            (dst->rx_tuna[7]);
950          */
951         state->diseq_flags |= HAS_LOCK;
952         /* dst->cur_jiff = jiffies; */
953         return 1;
954 }
955
956 static int dst_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage);
957
958 static int dst_write_tuna(struct dvb_frontend* fe)
959 {
960         struct dst_state* state = (struct dst_state*) fe->demodulator_priv;
961         int retval;
962         u8 reply;
963
964         dprintk("%s: type_flags 0x%x \n", __FUNCTION__, state->type_flags);
965         state->decode_freq = 0;
966         state->decode_lock = state->decode_strength = state->decode_snr = 0;
967         if (state->dst_type == DST_TYPE_IS_SAT) {
968                 if (!(state->diseq_flags & HAS_POWER))
969                         dst_set_voltage(fe, SEC_VOLTAGE_13);
970         }
971         state->diseq_flags &= ~(HAS_LOCK | ATTEMPT_TUNE);
972
973         if ((dst_comm_init(state)) < 0) {
974                 dprintk("%s: DST Communication initialization failed.\n", __FUNCTION__);
975                 return -1;
976         }
977
978         if (state->type_flags & DST_TYPE_HAS_NEWTUNE) {
979                 state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[0], 9);
980                 retval = write_dst(state, &state->tx_tuna[0], 10);
981
982         } else {
983                 state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[2], 7);
984                 retval = write_dst(state, &state->tx_tuna[2], FIXED_COMM);
985         }
986         if (retval < 0) {
987                 dst_pio_disable(state);
988                 dprintk("%s: write not successful\n", __FUNCTION__);
989                 return retval;
990         }
991
992         if ((dst_pio_disable(state)) < 0) {
993                 dprintk("%s: DST PIO disable failed !\n", __FUNCTION__);
994                 return -1;
995         }
996
997         if ((read_dst(state, &reply, GET_ACK) < 0)) {
998                 dprintk("%s: read verify not successful.\n", __FUNCTION__);
999                 return -1;
1000         }
1001         if (reply != ACK) {
1002                 dprintk("%s: write not acknowledged 0x%02x \n", __FUNCTION__, reply);
1003                 return 0;
1004         }
1005         state->diseq_flags |= ATTEMPT_TUNE;
1006
1007         return dst_get_tuna(state);
1008 }
1009
1010 /*
1011  * line22k0    0x00, 0x09, 0x00, 0xff, 0x01, 0x00, 0x00, 0x00
1012  * line22k1    0x00, 0x09, 0x01, 0xff, 0x01, 0x00, 0x00, 0x00
1013  * line22k2    0x00, 0x09, 0x02, 0xff, 0x01, 0x00, 0x00, 0x00
1014  * tone        0x00, 0x09, 0xff, 0x00, 0x01, 0x00, 0x00, 0x00
1015  * data        0x00, 0x09, 0xff, 0x01, 0x01, 0x00, 0x00, 0x00
1016  * power_off   0x00, 0x09, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
1017  * power_on    0x00, 0x09, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00
1018  * Diseqc 1    0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf0, 0xec
1019  * Diseqc 2    0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf4, 0xe8
1020  * Diseqc 3    0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf8, 0xe4
1021  * Diseqc 4    0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xfc, 0xe0
1022  */
1023
1024 static int dst_set_diseqc(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd)
1025 {
1026         struct dst_state* state = (struct dst_state*) fe->demodulator_priv;
1027         u8 paket[8] = { 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf0, 0xec };
1028
1029         if (state->dst_type == DST_TYPE_IS_TERR)
1030                 return 0;
1031
1032         if (cmd->msg_len == 0 || cmd->msg_len > 4)
1033                 return -EINVAL;
1034         memcpy(&paket[3], cmd->msg, cmd->msg_len);
1035         paket[7] = dst_check_sum(&paket[0], 7);
1036         dst_command(state, paket, 8);
1037         return 0;
1038 }
1039
1040 static int dst_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
1041 {
1042         u8 *val;
1043         int need_cmd;
1044         struct dst_state* state = (struct dst_state*) fe->demodulator_priv;
1045
1046         state->voltage = voltage;
1047
1048         if (state->dst_type == DST_TYPE_IS_TERR)
1049                 return 0;
1050
1051         need_cmd = 0;
1052         val = &state->tx_tuna[0];
1053         val[8] &= ~0x40;
1054         switch (voltage) {
1055         case SEC_VOLTAGE_13:
1056                 if ((state->diseq_flags & HAS_POWER) == 0)
1057                         need_cmd = 1;
1058                 state->diseq_flags |= HAS_POWER;
1059                 break;
1060
1061         case SEC_VOLTAGE_18:
1062                 if ((state->diseq_flags & HAS_POWER) == 0)
1063                         need_cmd = 1;
1064                 state->diseq_flags |= HAS_POWER;
1065                 val[8] |= 0x40;
1066                 break;
1067
1068         case SEC_VOLTAGE_OFF:
1069                 need_cmd = 1;
1070                 state->diseq_flags &= ~(HAS_POWER | HAS_LOCK | ATTEMPT_TUNE);
1071                 break;
1072
1073         default:
1074                 return -EINVAL;
1075         }
1076         if (need_cmd)
1077                 dst_tone_power_cmd(state);
1078
1079         return 0;
1080 }
1081
1082 static int dst_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
1083 {
1084         u8 *val;
1085         struct dst_state* state = (struct dst_state*) fe->demodulator_priv;
1086
1087         state->tone = tone;
1088
1089         if (state->dst_type == DST_TYPE_IS_TERR)
1090                 return 0;
1091
1092         val = &state->tx_tuna[0];
1093
1094         val[8] &= ~0x1;
1095
1096         switch (tone) {
1097         case SEC_TONE_OFF:
1098                 break;
1099
1100         case SEC_TONE_ON:
1101                 val[8] |= 1;
1102                 break;
1103
1104         default:
1105                 return -EINVAL;
1106         }
1107         dst_tone_power_cmd(state);
1108
1109         return 0;
1110 }
1111
1112 static int dst_init(struct dvb_frontend* fe)
1113 {
1114         struct dst_state* state = (struct dst_state*) fe->demodulator_priv;
1115         static u8 ini_satci_tuna[] = { 9, 0, 3, 0xb6, 1, 0, 0x73, 0x21, 0, 0 };
1116         static u8 ini_satfta_tuna[] = { 0, 0, 3, 0xb6, 1, 0x55, 0xbd, 0x50, 0, 0 };
1117         static u8 ini_tvfta_tuna[] = { 0, 0, 3, 0xb6, 1, 7, 0x0, 0x0, 0, 0 };
1118         static u8 ini_tvci_tuna[] = { 9, 0, 3, 0xb6, 1, 7, 0x0, 0x0, 0, 0 };
1119         static u8 ini_cabfta_tuna[] = { 0, 0, 3, 0xb6, 1, 7, 0x0, 0x0, 0, 0 };
1120         static u8 ini_cabci_tuna[] = { 9, 0, 3, 0xb6, 1, 7, 0x0, 0x0, 0, 0 };
1121         state->inversion = INVERSION_ON;
1122         state->voltage = SEC_VOLTAGE_13;
1123         state->tone = SEC_TONE_OFF;
1124         state->symbol_rate = 29473000;
1125         state->fec = FEC_AUTO;
1126         state->diseq_flags = 0;
1127         state->k22 = 0x02;
1128         state->bandwidth = BANDWIDTH_7_MHZ;
1129         state->cur_jiff = jiffies;
1130         if (state->dst_type == DST_TYPE_IS_SAT) {
1131                 state->frequency = 950000;
1132                 memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_NEWTUNE) ? ini_satci_tuna : ini_satfta_tuna), sizeof(ini_satfta_tuna));
1133         } else if (state->dst_type == DST_TYPE_IS_TERR) {
1134                 state->frequency = 137000000;
1135                 memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_NEWTUNE) ? ini_tvci_tuna : ini_tvfta_tuna), sizeof(ini_tvfta_tuna));
1136         } else if (state->dst_type == DST_TYPE_IS_CABLE) {
1137                 state->frequency = 51000000;
1138                 memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_NEWTUNE) ? ini_cabci_tuna : ini_cabfta_tuna), sizeof(ini_cabfta_tuna));
1139         }
1140
1141         return 0;
1142 }
1143
1144 static int dst_read_status(struct dvb_frontend* fe, fe_status_t* status)
1145 {
1146         struct dst_state* state = (struct dst_state*) fe->demodulator_priv;
1147
1148         *status = 0;
1149         if (state->diseq_flags & HAS_LOCK) {
1150                 dst_get_signal(state);
1151                 if (state->decode_lock)
1152                         *status |= FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_SYNC | FE_HAS_VITERBI;
1153         }
1154
1155         return 0;
1156 }
1157
1158 static int dst_read_signal_strength(struct dvb_frontend* fe, u16* strength)
1159 {
1160         struct dst_state* state = (struct dst_state*) fe->demodulator_priv;
1161
1162         dst_get_signal(state);
1163         *strength = state->decode_strength;
1164
1165         return 0;
1166 }
1167
1168 static int dst_read_snr(struct dvb_frontend* fe, u16* snr)
1169 {
1170         struct dst_state* state = (struct dst_state*) fe->demodulator_priv;
1171
1172         dst_get_signal(state);
1173         *snr = state->decode_snr;
1174
1175         return 0;
1176 }
1177
1178 static int dst_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
1179 {
1180         struct dst_state* state = (struct dst_state*) fe->demodulator_priv;
1181
1182         dst_set_freq(state, p->frequency);
1183         if (verbose > 4)
1184                 dprintk("Set Frequency = [%d]\n", p->frequency);
1185
1186         dst_set_inversion(state, p->inversion);
1187         if (state->dst_type == DST_TYPE_IS_SAT) {
1188                 dst_set_fec(state, p->u.qpsk.fec_inner);
1189                 dst_set_symbolrate(state, p->u.qpsk.symbol_rate);
1190                 if (verbose > 4)
1191                         dprintk("Set Symbolrate = [%d]\n", p->u.qpsk.symbol_rate);
1192
1193         } else if (state->dst_type == DST_TYPE_IS_TERR) {
1194                 dst_set_bandwidth(state, p->u.ofdm.bandwidth);
1195         } else if (state->dst_type == DST_TYPE_IS_CABLE) {
1196                 dst_set_fec(state, p->u.qam.fec_inner);
1197                 dst_set_symbolrate(state, p->u.qam.symbol_rate);
1198         }
1199         dst_write_tuna(fe);
1200
1201         return 0;
1202 }
1203
1204 static int dst_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
1205 {
1206         struct dst_state* state = (struct dst_state*) fe->demodulator_priv;
1207
1208         p->frequency = state->decode_freq;
1209         p->inversion = state->inversion;
1210         if (state->dst_type == DST_TYPE_IS_SAT) {
1211                 p->u.qpsk.symbol_rate = state->symbol_rate;
1212                 p->u.qpsk.fec_inner = dst_get_fec(state);
1213         } else if (state->dst_type == DST_TYPE_IS_TERR) {
1214                 p->u.ofdm.bandwidth = state->bandwidth;
1215         } else if (state->dst_type == DST_TYPE_IS_CABLE) {
1216                 p->u.qam.symbol_rate = state->symbol_rate;
1217                 p->u.qam.fec_inner = dst_get_fec(state);
1218                 p->u.qam.modulation = QAM_AUTO;
1219         }
1220
1221         return 0;
1222 }
1223
1224 static void dst_release(struct dvb_frontend* fe)
1225 {
1226         struct dst_state* state = (struct dst_state*) fe->demodulator_priv;
1227         kfree(state);
1228 }
1229
1230 static struct dvb_frontend_ops dst_dvbt_ops;
1231 static struct dvb_frontend_ops dst_dvbs_ops;
1232 static struct dvb_frontend_ops dst_dvbc_ops;
1233
1234 struct dst_state* dst_attach(struct dst_state *state, struct dvb_adapter *dvb_adapter)
1235 {
1236
1237         /* check if the ASIC is there */
1238         if (dst_probe(state) < 0) {
1239                 if (state)
1240                         kfree(state);
1241
1242                 return NULL;
1243         }
1244         /* determine settings based on type */
1245         switch (state->dst_type) {
1246         case DST_TYPE_IS_TERR:
1247                 memcpy(&state->ops, &dst_dvbt_ops, sizeof(struct dvb_frontend_ops));
1248                 break;
1249
1250         case DST_TYPE_IS_CABLE:
1251                 memcpy(&state->ops, &dst_dvbc_ops, sizeof(struct dvb_frontend_ops));
1252                 break;
1253
1254         case DST_TYPE_IS_SAT:
1255                 memcpy(&state->ops, &dst_dvbs_ops, sizeof(struct dvb_frontend_ops));
1256                 break;
1257
1258         default:
1259                 printk("%s: unknown DST type. please report to the LinuxTV.org DVB mailinglist.\n", __FUNCTION__);
1260                 if (state)
1261                         kfree(state);
1262
1263                 return NULL;
1264         }
1265
1266         /* create dvb_frontend */
1267         state->frontend.ops = &state->ops;
1268         state->frontend.demodulator_priv = state;
1269
1270         return state;                           /*      Manu (DST is a card not a frontend)     */
1271 }
1272
1273 EXPORT_SYMBOL(dst_attach);
1274
1275 static struct dvb_frontend_ops dst_dvbt_ops = {
1276
1277         .info = {
1278                 .name = "DST DVB-T",
1279                 .type = FE_OFDM,
1280                 .frequency_min = 137000000,
1281                 .frequency_max = 858000000,
1282                 .frequency_stepsize = 166667,
1283                 .caps = FE_CAN_FEC_AUTO | FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO
1284         },
1285
1286         .release = dst_release,
1287
1288         .init = dst_init,
1289
1290         .set_frontend = dst_set_frontend,
1291         .get_frontend = dst_get_frontend,
1292
1293         .read_status = dst_read_status,
1294         .read_signal_strength = dst_read_signal_strength,
1295         .read_snr = dst_read_snr,
1296 };
1297
1298 static struct dvb_frontend_ops dst_dvbs_ops = {
1299
1300         .info = {
1301                 .name = "DST DVB-S",
1302                 .type = FE_QPSK,
1303                 .frequency_min = 950000,
1304                 .frequency_max = 2150000,
1305                 .frequency_stepsize = 1000,     /* kHz for QPSK frontends */
1306                 .frequency_tolerance = 29500,
1307                 .symbol_rate_min = 1000000,
1308                 .symbol_rate_max = 45000000,
1309         /*     . symbol_rate_tolerance  =       ???,*/
1310                 .caps = FE_CAN_FEC_AUTO | FE_CAN_QPSK
1311         },
1312
1313         .release = dst_release,
1314
1315         .init = dst_init,
1316
1317         .set_frontend = dst_set_frontend,
1318         .get_frontend = dst_get_frontend,
1319
1320         .read_status = dst_read_status,
1321         .read_signal_strength = dst_read_signal_strength,
1322         .read_snr = dst_read_snr,
1323
1324         .diseqc_send_burst = dst_set_tone,
1325         .diseqc_send_master_cmd = dst_set_diseqc,
1326         .set_voltage = dst_set_voltage,
1327         .set_tone = dst_set_tone,
1328 };
1329
1330 static struct dvb_frontend_ops dst_dvbc_ops = {
1331
1332         .info = {
1333                 .name = "DST DVB-C",
1334                 .type = FE_QAM,
1335                 .frequency_stepsize = 62500,
1336                 .frequency_min = 51000000,
1337                 .frequency_max = 858000000,
1338                 .symbol_rate_min = 1000000,
1339                 .symbol_rate_max = 45000000,
1340         /*     . symbol_rate_tolerance  =       ???,*/
1341                 .caps = FE_CAN_FEC_AUTO | FE_CAN_QAM_AUTO
1342         },
1343
1344         .release = dst_release,
1345
1346         .init = dst_init,
1347
1348         .set_frontend = dst_set_frontend,
1349         .get_frontend = dst_get_frontend,
1350
1351         .read_status = dst_read_status,
1352         .read_signal_strength = dst_read_signal_strength,
1353         .read_snr = dst_read_snr,
1354 };
1355
1356
1357 MODULE_DESCRIPTION("DST DVB-S/T/C Combo Frontend driver");
1358 MODULE_AUTHOR("Jamie Honan, Manu Abraham");
1359 MODULE_LICENSE("GPL");