OSDN Git Service

Merge tag 'perf-urgent-2023-09-10' of git://git.kernel.org/pub/scm/linux/kernel/git...
[tomoyo/tomoyo-test1.git] / drivers / media / pci / bt8xx / dst.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
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 */
8
9 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
10
11 #include <linux/kernel.h>
12 #include <linux/module.h>
13 #include <linux/init.h>
14 #include <linux/string.h>
15 #include <linux/slab.h>
16 #include <linux/vmalloc.h>
17 #include <linux/delay.h>
18 #include <asm/div64.h>
19 #include <media/dvb_frontend.h>
20 #include "dst_priv.h"
21 #include "dst_common.h"
22
23 static unsigned int verbose;
24 module_param(verbose, int, 0644);
25 MODULE_PARM_DESC(verbose, "verbosity level (0 to 3)");
26
27 static unsigned int dst_addons;
28 module_param(dst_addons, int, 0644);
29 MODULE_PARM_DESC(dst_addons, "CA daughterboard, default is 0 (No addons)");
30
31 static unsigned int dst_algo;
32 module_param(dst_algo, int, 0644);
33 MODULE_PARM_DESC(dst_algo, "tuning algo: default is 0=(SW), 1=(HW)");
34
35 #define HAS_LOCK                1
36 #define ATTEMPT_TUNE            2
37 #define HAS_POWER               4
38
39 #define dprintk(level, fmt, arg...) do {                                \
40         if (level >= verbose)                                           \
41                 printk(KERN_DEBUG pr_fmt("%s: " fmt),                   \
42                        __func__, ##arg);                                \
43 } while(0)
44
45 static int dst_command(struct dst_state *state, u8 *data, u8 len);
46
47 static void dst_packsize(struct dst_state *state, int psize)
48 {
49         union dst_gpio_packet bits;
50
51         bits.psize = psize;
52         bt878_device_control(state->bt, DST_IG_TS, &bits);
53 }
54
55 static int dst_gpio_outb(struct dst_state *state, u32 mask, u32 enbb,
56                          u32 outhigh, int delay)
57 {
58         union dst_gpio_packet enb;
59         union dst_gpio_packet bits;
60         int err;
61
62         enb.enb.mask = mask;
63         enb.enb.enable = enbb;
64
65         dprintk(2, "mask=[%04x], enbb=[%04x], outhigh=[%04x]\n",
66                 mask, enbb, outhigh);
67         if ((err = bt878_device_control(state->bt, DST_IG_ENABLE, &enb)) < 0) {
68                 dprintk(2, "dst_gpio_enb error (err == %i, mask == %02x, enb == %02x)\n",
69                         err, mask, enbb);
70                 return -EREMOTEIO;
71         }
72         udelay(1000);
73         /* because complete disabling means no output, no need to do output packet */
74         if (enbb == 0)
75                 return 0;
76         if (delay)
77                 msleep(10);
78         bits.outp.mask = enbb;
79         bits.outp.highvals = outhigh;
80         if ((err = bt878_device_control(state->bt, DST_IG_WRITE, &bits)) < 0) {
81                 dprintk(2, "dst_gpio_outb error (err == %i, enbb == %02x, outhigh == %02x)\n",
82                         err, enbb, outhigh);
83                 return -EREMOTEIO;
84         }
85
86         return 0;
87 }
88
89 static int dst_gpio_inb(struct dst_state *state, u8 *result)
90 {
91         union dst_gpio_packet rd_packet;
92         int err;
93
94         *result = 0;
95         if ((err = bt878_device_control(state->bt, DST_IG_READ, &rd_packet)) < 0) {
96                 pr_err("dst_gpio_inb error (err == %i)\n", err);
97                 return -EREMOTEIO;
98         }
99         *result = (u8) rd_packet.rd.value;
100
101         return 0;
102 }
103
104 int rdc_reset_state(struct dst_state *state)
105 {
106         dprintk(2, "Resetting state machine\n");
107         if (dst_gpio_outb(state, RDC_8820_INT, RDC_8820_INT, 0, NO_DELAY) < 0) {
108                 pr_err("dst_gpio_outb ERROR !\n");
109                 return -1;
110         }
111         msleep(10);
112         if (dst_gpio_outb(state, RDC_8820_INT, RDC_8820_INT, RDC_8820_INT, NO_DELAY) < 0) {
113                 pr_err("dst_gpio_outb ERROR !\n");
114                 msleep(10);
115                 return -1;
116         }
117
118         return 0;
119 }
120 EXPORT_SYMBOL(rdc_reset_state);
121
122 static int rdc_8820_reset(struct dst_state *state)
123 {
124         dprintk(3, "Resetting DST\n");
125         if (dst_gpio_outb(state, RDC_8820_RESET, RDC_8820_RESET, 0, NO_DELAY) < 0) {
126                 pr_err("dst_gpio_outb ERROR !\n");
127                 return -1;
128         }
129         udelay(1000);
130         if (dst_gpio_outb(state, RDC_8820_RESET, RDC_8820_RESET, RDC_8820_RESET, DELAY) < 0) {
131                 pr_err("dst_gpio_outb ERROR !\n");
132                 return -1;
133         }
134
135         return 0;
136 }
137
138 static int dst_pio_enable(struct dst_state *state)
139 {
140         if (dst_gpio_outb(state, ~0, RDC_8820_PIO_0_ENABLE, 0, NO_DELAY) < 0) {
141                 pr_err("dst_gpio_outb ERROR !\n");
142                 return -1;
143         }
144         udelay(1000);
145
146         return 0;
147 }
148
149 int dst_pio_disable(struct dst_state *state)
150 {
151         if (dst_gpio_outb(state, ~0, RDC_8820_PIO_0_DISABLE, RDC_8820_PIO_0_DISABLE, NO_DELAY) < 0) {
152                 pr_err("dst_gpio_outb ERROR !\n");
153                 return -1;
154         }
155         if (state->type_flags & DST_TYPE_HAS_FW_1)
156                 udelay(1000);
157
158         return 0;
159 }
160 EXPORT_SYMBOL(dst_pio_disable);
161
162 int dst_wait_dst_ready(struct dst_state *state, u8 delay_mode)
163 {
164         u8 reply;
165         int i;
166
167         for (i = 0; i < 200; i++) {
168                 if (dst_gpio_inb(state, &reply) < 0) {
169                         pr_err("dst_gpio_inb ERROR !\n");
170                         return -1;
171                 }
172                 if ((reply & RDC_8820_PIO_0_ENABLE) == 0) {
173                         dprintk(2, "dst wait ready after %d\n", i);
174                         return 1;
175                 }
176                 msleep(10);
177         }
178         dprintk(1, "dst wait NOT ready after %d\n", i);
179
180         return 0;
181 }
182 EXPORT_SYMBOL(dst_wait_dst_ready);
183
184 int dst_error_recovery(struct dst_state *state)
185 {
186         dprintk(1, "Trying to return from previous errors.\n");
187         dst_pio_disable(state);
188         msleep(10);
189         dst_pio_enable(state);
190         msleep(10);
191
192         return 0;
193 }
194 EXPORT_SYMBOL(dst_error_recovery);
195
196 int dst_error_bailout(struct dst_state *state)
197 {
198         dprintk(2, "Trying to bailout from previous error.\n");
199         rdc_8820_reset(state);
200         dst_pio_disable(state);
201         msleep(10);
202
203         return 0;
204 }
205 EXPORT_SYMBOL(dst_error_bailout);
206
207 int dst_comm_init(struct dst_state *state)
208 {
209         dprintk(2, "Initializing DST.\n");
210         if ((dst_pio_enable(state)) < 0) {
211                 pr_err("PIO Enable Failed\n");
212                 return -1;
213         }
214         if ((rdc_reset_state(state)) < 0) {
215                 pr_err("RDC 8820 State RESET Failed.\n");
216                 return -1;
217         }
218         if (state->type_flags & DST_TYPE_HAS_FW_1)
219                 msleep(100);
220         else
221                 msleep(5);
222
223         return 0;
224 }
225 EXPORT_SYMBOL(dst_comm_init);
226
227 int write_dst(struct dst_state *state, u8 *data, u8 len)
228 {
229         struct i2c_msg msg = {
230                 .addr = state->config->demod_address,
231                 .flags = 0,
232                 .buf = data,
233                 .len = len
234         };
235
236         int err;
237         u8 cnt;
238
239         dprintk(1, "writing [ %*ph ]\n", len, data);
240
241         for (cnt = 0; cnt < 2; cnt++) {
242                 if ((err = i2c_transfer(state->i2c, &msg, 1)) < 0) {
243                         dprintk(2, "_write_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)\n",
244                                 err, len, data[0]);
245                         dst_error_recovery(state);
246                         continue;
247                 } else
248                         break;
249         }
250         if (cnt >= 2) {
251                 dprintk(2, "RDC 8820 RESET\n");
252                 dst_error_bailout(state);
253
254                 return -1;
255         }
256
257         return 0;
258 }
259 EXPORT_SYMBOL(write_dst);
260
261 int read_dst(struct dst_state *state, u8 *ret, u8 len)
262 {
263         struct i2c_msg msg = {
264                 .addr = state->config->demod_address,
265                 .flags = I2C_M_RD,
266                 .buf = ret,
267                 .len = len
268         };
269
270         int err;
271         int cnt;
272
273         for (cnt = 0; cnt < 2; cnt++) {
274                 if ((err = i2c_transfer(state->i2c, &msg, 1)) < 0) {
275                         dprintk(2, "read_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)\n",
276                                 err, len, ret[0]);
277                         dst_error_recovery(state);
278                         continue;
279                 } else
280                         break;
281         }
282         if (cnt >= 2) {
283                 dprintk(2, "RDC 8820 RESET\n");
284                 dst_error_bailout(state);
285
286                 return -1;
287         }
288         dprintk(3, "reply is %*ph\n", len, ret);
289
290         return 0;
291 }
292 EXPORT_SYMBOL(read_dst);
293
294 static int dst_set_polarization(struct dst_state *state)
295 {
296         switch (state->voltage) {
297         case SEC_VOLTAGE_13:    /*      Vertical        */
298                 dprintk(2, "Polarization=[Vertical]\n");
299                 state->tx_tuna[8] &= ~0x40;
300                 break;
301         case SEC_VOLTAGE_18:    /*      Horizontal      */
302                 dprintk(2, "Polarization=[Horizontal]\n");
303                 state->tx_tuna[8] |= 0x40;
304                 break;
305         case SEC_VOLTAGE_OFF:
306                 break;
307         }
308
309         return 0;
310 }
311
312 static int dst_set_freq(struct dst_state *state, u32 freq)
313 {
314         state->frequency = freq;
315         dprintk(2, "set Frequency %u\n", freq);
316
317         if (state->dst_type == DST_TYPE_IS_SAT) {
318                 freq = freq / 1000;
319                 if (freq < 950 || freq > 2150)
320                         return -EINVAL;
321                 state->tx_tuna[2] = (freq >> 8);
322                 state->tx_tuna[3] = (u8) freq;
323                 state->tx_tuna[4] = 0x01;
324                 state->tx_tuna[8] &= ~0x04;
325                 if (state->type_flags & DST_TYPE_HAS_OBS_REGS) {
326                         if (freq < 1531)
327                                 state->tx_tuna[8] |= 0x04;
328                 }
329         } else if (state->dst_type == DST_TYPE_IS_TERR) {
330                 freq = freq / 1000;
331                 if (freq < 137000 || freq > 858000)
332                         return -EINVAL;
333                 state->tx_tuna[2] = (freq >> 16) & 0xff;
334                 state->tx_tuna[3] = (freq >> 8) & 0xff;
335                 state->tx_tuna[4] = (u8) freq;
336         } else if (state->dst_type == DST_TYPE_IS_CABLE) {
337                 freq = freq / 1000;
338                 state->tx_tuna[2] = (freq >> 16) & 0xff;
339                 state->tx_tuna[3] = (freq >> 8) & 0xff;
340                 state->tx_tuna[4] = (u8) freq;
341         } else if (state->dst_type == DST_TYPE_IS_ATSC) {
342                 freq = freq / 1000;
343                 if (freq < 51000 || freq > 858000)
344                         return -EINVAL;
345                 state->tx_tuna[2] = (freq >> 16) & 0xff;
346                 state->tx_tuna[3] = (freq >>  8) & 0xff;
347                 state->tx_tuna[4] = (u8) freq;
348                 state->tx_tuna[5] = 0x00;               /*      ATSC    */
349                 state->tx_tuna[6] = 0x00;
350                 if (state->dst_hw_cap & DST_TYPE_HAS_ANALOG)
351                         state->tx_tuna[7] = 0x00;       /*      Digital */
352         } else
353                 return -EINVAL;
354
355         return 0;
356 }
357
358 static int dst_set_bandwidth(struct dst_state *state, u32 bandwidth)
359 {
360         state->bandwidth = bandwidth;
361
362         if (state->dst_type != DST_TYPE_IS_TERR)
363                 return -EOPNOTSUPP;
364
365         switch (bandwidth) {
366         case 6000000:
367                 if (state->dst_hw_cap & DST_TYPE_HAS_CA)
368                         state->tx_tuna[7] = 0x06;
369                 else {
370                         state->tx_tuna[6] = 0x06;
371                         state->tx_tuna[7] = 0x00;
372                 }
373                 break;
374         case 7000000:
375                 if (state->dst_hw_cap & DST_TYPE_HAS_CA)
376                         state->tx_tuna[7] = 0x07;
377                 else {
378                         state->tx_tuna[6] = 0x07;
379                         state->tx_tuna[7] = 0x00;
380                 }
381                 break;
382         case 8000000:
383                 if (state->dst_hw_cap & DST_TYPE_HAS_CA)
384                         state->tx_tuna[7] = 0x08;
385                 else {
386                         state->tx_tuna[6] = 0x08;
387                         state->tx_tuna[7] = 0x00;
388                 }
389                 break;
390         default:
391                 return -EINVAL;
392         }
393
394         return 0;
395 }
396
397 static int dst_set_inversion(struct dst_state *state,
398                              enum fe_spectral_inversion inversion)
399 {
400         state->inversion = inversion;
401         switch (inversion) {
402         case INVERSION_OFF:     /*      Inversion = Normal      */
403                 state->tx_tuna[8] &= ~0x80;
404                 break;
405         case INVERSION_ON:
406                 state->tx_tuna[8] |= 0x80;
407                 break;
408         default:
409                 return -EINVAL;
410         }
411
412         return 0;
413 }
414
415 static int dst_set_fec(struct dst_state *state, enum fe_code_rate fec)
416 {
417         state->fec = fec;
418         return 0;
419 }
420
421 static enum fe_code_rate dst_get_fec(struct dst_state *state)
422 {
423         return state->fec;
424 }
425
426 static int dst_set_symbolrate(struct dst_state *state, u32 srate)
427 {
428         u32 symcalc;
429         u64 sval;
430
431         state->symbol_rate = srate;
432         if (state->dst_type == DST_TYPE_IS_TERR) {
433                 return -EOPNOTSUPP;
434         }
435         dprintk(2, "set symrate %u\n", srate);
436         srate /= 1000;
437         if (state->dst_type == DST_TYPE_IS_SAT) {
438                 if (state->type_flags & DST_TYPE_HAS_SYMDIV) {
439                         sval = srate;
440                         sval <<= 20;
441                         do_div(sval, 88000);
442                         symcalc = (u32) sval;
443                         dprintk(2, "set symcalc %u\n", symcalc);
444                         state->tx_tuna[5] = (u8) (symcalc >> 12);
445                         state->tx_tuna[6] = (u8) (symcalc >> 4);
446                         state->tx_tuna[7] = (u8) (symcalc << 4);
447                 } else {
448                         state->tx_tuna[5] = (u8) (srate >> 16) & 0x7f;
449                         state->tx_tuna[6] = (u8) (srate >> 8);
450                         state->tx_tuna[7] = (u8) srate;
451                 }
452                 state->tx_tuna[8] &= ~0x20;
453                 if (state->type_flags & DST_TYPE_HAS_OBS_REGS) {
454                         if (srate > 8000)
455                                 state->tx_tuna[8] |= 0x20;
456                 }
457         } else if (state->dst_type == DST_TYPE_IS_CABLE) {
458                 dprintk(3, "%s\n", state->fw_name);
459                 if (!strncmp(state->fw_name, "DCTNEW", 6)) {
460                         state->tx_tuna[5] = (u8) (srate >> 8);
461                         state->tx_tuna[6] = (u8) srate;
462                         state->tx_tuna[7] = 0x00;
463                 } else if (!strncmp(state->fw_name, "DCT-CI", 6)) {
464                         state->tx_tuna[5] = 0x00;
465                         state->tx_tuna[6] = (u8) (srate >> 8);
466                         state->tx_tuna[7] = (u8) srate;
467                 }
468         }
469         return 0;
470 }
471
472 static int dst_set_modulation(struct dst_state *state,
473                               enum fe_modulation modulation)
474 {
475         if (state->dst_type != DST_TYPE_IS_CABLE)
476                 return -EOPNOTSUPP;
477
478         state->modulation = modulation;
479         switch (modulation) {
480         case QAM_16:
481                 state->tx_tuna[8] = 0x10;
482                 break;
483         case QAM_32:
484                 state->tx_tuna[8] = 0x20;
485                 break;
486         case QAM_64:
487                 state->tx_tuna[8] = 0x40;
488                 break;
489         case QAM_128:
490                 state->tx_tuna[8] = 0x80;
491                 break;
492         case QAM_256:
493                 if (!strncmp(state->fw_name, "DCTNEW", 6))
494                         state->tx_tuna[8] = 0xff;
495                 else if (!strncmp(state->fw_name, "DCT-CI", 6))
496                         state->tx_tuna[8] = 0x00;
497                 break;
498         case QPSK:
499         case QAM_AUTO:
500         case VSB_8:
501         case VSB_16:
502         default:
503                 return -EINVAL;
504
505         }
506
507         return 0;
508 }
509
510 static enum fe_modulation dst_get_modulation(struct dst_state *state)
511 {
512         return state->modulation;
513 }
514
515
516 u8 dst_check_sum(u8 *buf, u32 len)
517 {
518         u32 i;
519         u8 val = 0;
520         if (!len)
521                 return 0;
522         for (i = 0; i < len; i++) {
523                 val += buf[i];
524         }
525         return ((~val) + 1);
526 }
527 EXPORT_SYMBOL(dst_check_sum);
528
529 static void dst_type_flags_print(struct dst_state *state)
530 {
531         u32 type_flags = state->type_flags;
532
533         pr_err("DST type flags :\n");
534         if (type_flags & DST_TYPE_HAS_TS188)
535                 pr_err(" 0x%x newtuner\n", DST_TYPE_HAS_TS188);
536         if (type_flags & DST_TYPE_HAS_NEWTUNE_2)
537                 pr_err(" 0x%x newtuner 2\n", DST_TYPE_HAS_NEWTUNE_2);
538         if (type_flags & DST_TYPE_HAS_TS204)
539                 pr_err(" 0x%x ts204\n", DST_TYPE_HAS_TS204);
540         if (type_flags & DST_TYPE_HAS_VLF)
541                 pr_err(" 0x%x VLF\n", DST_TYPE_HAS_VLF);
542         if (type_flags & DST_TYPE_HAS_SYMDIV)
543                 pr_err(" 0x%x symdiv\n", DST_TYPE_HAS_SYMDIV);
544         if (type_flags & DST_TYPE_HAS_FW_1)
545                 pr_err(" 0x%x firmware version = 1\n", DST_TYPE_HAS_FW_1);
546         if (type_flags & DST_TYPE_HAS_FW_2)
547                 pr_err(" 0x%x firmware version = 2\n", DST_TYPE_HAS_FW_2);
548         if (type_flags & DST_TYPE_HAS_FW_3)
549                 pr_err(" 0x%x firmware version = 3\n", DST_TYPE_HAS_FW_3);
550         pr_err("\n");
551 }
552
553
554 static int dst_type_print(struct dst_state *state, u8 type)
555 {
556         char *otype;
557         switch (type) {
558         case DST_TYPE_IS_SAT:
559                 otype = "satellite";
560                 break;
561
562         case DST_TYPE_IS_TERR:
563                 otype = "terrestrial";
564                 break;
565
566         case DST_TYPE_IS_CABLE:
567                 otype = "cable";
568                 break;
569
570         case DST_TYPE_IS_ATSC:
571                 otype = "atsc";
572                 break;
573
574         default:
575                 dprintk(2, "invalid dst type %d\n", type);
576                 return -EINVAL;
577         }
578         dprintk(2, "DST type: %s\n", otype);
579
580         return 0;
581 }
582
583 static struct tuner_types tuner_list[] = {
584         {
585                 .tuner_type = TUNER_TYPE_L64724,
586                 .tuner_name = "L 64724",
587                 .board_name = "UNKNOWN",
588                 .fw_name    = "UNKNOWN"
589         },
590
591         {
592                 .tuner_type = TUNER_TYPE_STV0299,
593                 .tuner_name = "STV 0299",
594                 .board_name = "VP1020",
595                 .fw_name    = "DST-MOT"
596         },
597
598         {
599                 .tuner_type = TUNER_TYPE_STV0299,
600                 .tuner_name = "STV 0299",
601                 .board_name = "VP1020",
602                 .fw_name    = "DST-03T"
603         },
604
605         {
606                 .tuner_type = TUNER_TYPE_MB86A15,
607                 .tuner_name = "MB 86A15",
608                 .board_name = "VP1022",
609                 .fw_name    = "DST-03T"
610         },
611
612         {
613                 .tuner_type = TUNER_TYPE_MB86A15,
614                 .tuner_name = "MB 86A15",
615                 .board_name = "VP1025",
616                 .fw_name    = "DST-03T"
617         },
618
619         {
620                 .tuner_type = TUNER_TYPE_STV0299,
621                 .tuner_name = "STV 0299",
622                 .board_name = "VP1030",
623                 .fw_name    = "DST-CI"
624         },
625
626         {
627                 .tuner_type = TUNER_TYPE_STV0299,
628                 .tuner_name = "STV 0299",
629                 .board_name = "VP1030",
630                 .fw_name    = "DSTMCI"
631         },
632
633         {
634                 .tuner_type = TUNER_TYPE_UNKNOWN,
635                 .tuner_name = "UNKNOWN",
636                 .board_name = "VP2021",
637                 .fw_name    = "DCTNEW"
638         },
639
640         {
641                 .tuner_type = TUNER_TYPE_UNKNOWN,
642                 .tuner_name = "UNKNOWN",
643                 .board_name = "VP2030",
644                 .fw_name    = "DCT-CI"
645         },
646
647         {
648                 .tuner_type = TUNER_TYPE_UNKNOWN,
649                 .tuner_name = "UNKNOWN",
650                 .board_name = "VP2031",
651                 .fw_name    = "DCT-CI"
652         },
653
654         {
655                 .tuner_type = TUNER_TYPE_UNKNOWN,
656                 .tuner_name = "UNKNOWN",
657                 .board_name = "VP2040",
658                 .fw_name    = "DCT-CI"
659         },
660
661         {
662                 .tuner_type = TUNER_TYPE_UNKNOWN,
663                 .tuner_name = "UNKNOWN",
664                 .board_name = "VP3020",
665                 .fw_name    = "DTTFTA"
666         },
667
668         {
669                 .tuner_type = TUNER_TYPE_UNKNOWN,
670                 .tuner_name = "UNKNOWN",
671                 .board_name = "VP3021",
672                 .fw_name    = "DTTFTA"
673         },
674
675         {
676                 .tuner_type = TUNER_TYPE_TDA10046,
677                 .tuner_name = "TDA10046",
678                 .board_name = "VP3040",
679                 .fw_name    = "DTT-CI"
680         },
681
682         {
683                 .tuner_type = TUNER_TYPE_UNKNOWN,
684                 .tuner_name = "UNKNOWN",
685                 .board_name = "VP3051",
686                 .fw_name    = "DTTNXT"
687         },
688
689         {
690                 .tuner_type = TUNER_TYPE_NXT200x,
691                 .tuner_name = "NXT200x",
692                 .board_name = "VP3220",
693                 .fw_name    = "ATSCDI"
694         },
695
696         {
697                 .tuner_type = TUNER_TYPE_NXT200x,
698                 .tuner_name = "NXT200x",
699                 .board_name = "VP3250",
700                 .fw_name    = "ATSCAD"
701         },
702 };
703
704 /*
705         Known cards list
706         Satellite
707         -------------------
708                   200103A
709         VP-1020   DST-MOT       LG(old), TS=188
710
711         VP-1020   DST-03T       LG(new), TS=204
712         VP-1022   DST-03T       LG(new), TS=204
713         VP-1025   DST-03T       LG(new), TS=204
714
715         VP-1030   DSTMCI,       LG(new), TS=188
716         VP-1032   DSTMCI,       LG(new), TS=188
717
718         Cable
719         -------------------
720         VP-2030   DCT-CI,       Samsung, TS=204
721         VP-2021   DCT-CI,       Unknown, TS=204
722         VP-2031   DCT-CI,       Philips, TS=188
723         VP-2040   DCT-CI,       Philips, TS=188, with CA daughter board
724         VP-2040   DCT-CI,       Philips, TS=204, without CA daughter board
725
726         Terrestrial
727         -------------------
728         VP-3050  DTTNXT                  TS=188
729         VP-3040  DTT-CI,        Philips, TS=188
730         VP-3040  DTT-CI,        Philips, TS=204
731
732         ATSC
733         -------------------
734         VP-3220  ATSCDI,                 TS=188
735         VP-3250  ATSCAD,                 TS=188
736
737 */
738
739 static struct dst_types dst_tlist[] = {
740         {
741                 .device_id = "200103A",
742                 .offset = 0,
743                 .dst_type =  DST_TYPE_IS_SAT,
744                 .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1 | DST_TYPE_HAS_OBS_REGS,
745                 .dst_feature = 0,
746                 .tuner_type = 0
747         },      /*      obsolete        */
748
749         {
750                 .device_id = "DST-020",
751                 .offset = 0,
752                 .dst_type =  DST_TYPE_IS_SAT,
753                 .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1,
754                 .dst_feature = 0,
755                 .tuner_type = 0
756         },      /*      obsolete        */
757
758         {
759                 .device_id = "DST-030",
760                 .offset =  0,
761                 .dst_type = DST_TYPE_IS_SAT,
762                 .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_1,
763                 .dst_feature = 0,
764                 .tuner_type = 0
765         },      /*      obsolete        */
766
767         {
768                 .device_id = "DST-03T",
769                 .offset = 0,
770                 .dst_type = DST_TYPE_IS_SAT,
771                 .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_2,
772                 .dst_feature = DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4 | DST_TYPE_HAS_DISEQC5
773                                                          | DST_TYPE_HAS_MAC | DST_TYPE_HAS_MOTO,
774                 .tuner_type = TUNER_TYPE_MULTI
775          },
776
777         {
778                 .device_id = "DST-MOT",
779                 .offset =  0,
780                 .dst_type = DST_TYPE_IS_SAT,
781                 .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1,
782                 .dst_feature = 0,
783                 .tuner_type = 0
784         },      /*      obsolete        */
785
786         {
787                 .device_id = "DST-CI",
788                 .offset = 1,
789                 .dst_type = DST_TYPE_IS_SAT,
790                 .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_1,
791                 .dst_feature = DST_TYPE_HAS_CA,
792                 .tuner_type = 0
793         },      /*      An OEM board    */
794
795         {
796                 .device_id = "DSTMCI",
797                 .offset = 1,
798                 .dst_type = DST_TYPE_IS_SAT,
799                 .type_flags = DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD | DST_TYPE_HAS_INC_COUNT | DST_TYPE_HAS_VLF,
800                 .dst_feature = DST_TYPE_HAS_CA | DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4
801                                                         | DST_TYPE_HAS_MOTO | DST_TYPE_HAS_MAC,
802                 .tuner_type = TUNER_TYPE_MULTI
803         },
804
805         {
806                 .device_id = "DSTFCI",
807                 .offset = 1,
808                 .dst_type = DST_TYPE_IS_SAT,
809                 .type_flags = DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_1,
810                 .dst_feature = 0,
811                 .tuner_type = 0
812         },      /* unknown to vendor    */
813
814         {
815                 .device_id = "DCT-CI",
816                 .offset = 1,
817                 .dst_type = DST_TYPE_IS_CABLE,
818                 .type_flags = DST_TYPE_HAS_MULTI_FE | DST_TYPE_HAS_FW_1 | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_VLF,
819                 .dst_feature = DST_TYPE_HAS_CA,
820                 .tuner_type = 0
821         },
822
823         {
824                 .device_id = "DCTNEW",
825                 .offset = 1,
826                 .dst_type = DST_TYPE_IS_CABLE,
827                 .type_flags = DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_3 | DST_TYPE_HAS_FW_BUILD | DST_TYPE_HAS_MULTI_FE,
828                 .dst_feature = 0,
829                 .tuner_type = 0
830         },
831
832         {
833                 .device_id = "DTT-CI",
834                 .offset = 1,
835                 .dst_type = DST_TYPE_IS_TERR,
836                 .type_flags = DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_MULTI_FE | DST_TYPE_HAS_VLF,
837                 .dst_feature = DST_TYPE_HAS_CA,
838                 .tuner_type = 0
839         },
840
841         {
842                 .device_id = "DTTDIG",
843                 .offset = 1,
844                 .dst_type = DST_TYPE_IS_TERR,
845                 .type_flags = DST_TYPE_HAS_FW_2,
846                 .dst_feature = 0,
847                 .tuner_type = 0
848         },
849
850         {
851                 .device_id = "DTTNXT",
852                 .offset = 1,
853                 .dst_type = DST_TYPE_IS_TERR,
854                 .type_flags = DST_TYPE_HAS_FW_2,
855                 .dst_feature = DST_TYPE_HAS_ANALOG,
856                 .tuner_type = 0
857         },
858
859         {
860                 .device_id = "ATSCDI",
861                 .offset = 1,
862                 .dst_type = DST_TYPE_IS_ATSC,
863                 .type_flags = DST_TYPE_HAS_FW_2,
864                 .dst_feature = 0,
865                 .tuner_type = 0
866         },
867
868         {
869                 .device_id = "ATSCAD",
870                 .offset = 1,
871                 .dst_type = DST_TYPE_IS_ATSC,
872                 .type_flags = DST_TYPE_HAS_MULTI_FE | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD,
873                 .dst_feature = DST_TYPE_HAS_MAC | DST_TYPE_HAS_ANALOG,
874                 .tuner_type = 0
875         },
876
877         { }
878
879 };
880
881 static int dst_get_mac(struct dst_state *state)
882 {
883         u8 get_mac[] = { 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
884         get_mac[7] = dst_check_sum(get_mac, 7);
885         if (dst_command(state, get_mac, 8) < 0) {
886                 dprintk(2, "Unsupported Command\n");
887                 return -1;
888         }
889         memset(&state->mac_address, '\0', 8);
890         memcpy(&state->mac_address, &state->rxbuffer, 6);
891         pr_err("MAC Address=[%pM]\n", state->mac_address);
892
893         return 0;
894 }
895
896 static int dst_fw_ver(struct dst_state *state)
897 {
898         u8 get_ver[] = { 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
899         get_ver[7] = dst_check_sum(get_ver, 7);
900         if (dst_command(state, get_ver, 8) < 0) {
901                 dprintk(2, "Unsupported Command\n");
902                 return -1;
903         }
904         memcpy(&state->fw_version, &state->rxbuffer, 8);
905         pr_err("Firmware Ver = %x.%x Build = %02x, on %x:%x, %x-%x-20%02x\n",
906                 state->fw_version[0] >> 4, state->fw_version[0] & 0x0f,
907                 state->fw_version[1],
908                 state->fw_version[5], state->fw_version[6],
909                 state->fw_version[4], state->fw_version[3], state->fw_version[2]);
910
911         return 0;
912 }
913
914 static int dst_card_type(struct dst_state *state)
915 {
916         int j;
917         struct tuner_types *p_tuner_list = NULL;
918
919         u8 get_type[] = { 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
920         get_type[7] = dst_check_sum(get_type, 7);
921         if (dst_command(state, get_type, 8) < 0) {
922                 dprintk(2, "Unsupported Command\n");
923                 return -1;
924         }
925         memset(&state->card_info, '\0', 8);
926         memcpy(&state->card_info, &state->rxbuffer, 7);
927         pr_err("Device Model=[%s]\n", &state->card_info[0]);
928
929         for (j = 0, p_tuner_list = tuner_list; j < ARRAY_SIZE(tuner_list); j++, p_tuner_list++) {
930                 if (!strcmp(&state->card_info[0], p_tuner_list->board_name)) {
931                         state->tuner_type = p_tuner_list->tuner_type;
932                         pr_err("DST has [%s] tuner, tuner type=[%d]\n",
933                                 p_tuner_list->tuner_name, p_tuner_list->tuner_type);
934                 }
935         }
936
937         return 0;
938 }
939
940 static int dst_get_vendor(struct dst_state *state)
941 {
942         u8 get_vendor[] = { 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
943         get_vendor[7] = dst_check_sum(get_vendor, 7);
944         if (dst_command(state, get_vendor, 8) < 0) {
945                 dprintk(2, "Unsupported Command\n");
946                 return -1;
947         }
948         memset(&state->vendor, '\0', 8);
949         memcpy(&state->vendor, &state->rxbuffer, 7);
950         pr_err("Vendor=[%s]\n", &state->vendor[0]);
951
952         return 0;
953 }
954
955 static void debug_dst_buffer(struct dst_state *state)
956 {
957         dprintk(3, "%s: [ %*ph ]\n", __func__, 8, state->rxbuffer);
958 }
959
960 static int dst_check_stv0299(struct dst_state *state)
961 {
962         u8 check_stv0299[] = { 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
963
964         check_stv0299[7] = dst_check_sum(check_stv0299, 7);
965         if (dst_command(state, check_stv0299, 8) < 0) {
966                 pr_err("Cmd=[0x04] failed\n");
967                 return -1;
968         }
969         debug_dst_buffer(state);
970
971         if (memcmp(&check_stv0299, &state->rxbuffer, 8)) {
972                 pr_err("Found a STV0299 NIM\n");
973                 state->tuner_type = TUNER_TYPE_STV0299;
974                 return 0;
975         }
976
977         return -1;
978 }
979
980 static int dst_check_mb86a15(struct dst_state *state)
981 {
982         u8 check_mb86a15[] = { 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
983
984         check_mb86a15[7] = dst_check_sum(check_mb86a15, 7);
985         if (dst_command(state, check_mb86a15, 8) < 0) {
986                 pr_err("Cmd=[0x10], failed\n");
987                 return -1;
988         }
989         debug_dst_buffer(state);
990
991         if (memcmp(&check_mb86a15, &state->rxbuffer, 8) < 0) {
992                 pr_err("Found a MB86A15 NIM\n");
993                 state->tuner_type = TUNER_TYPE_MB86A15;
994                 return 0;
995         }
996
997         return -1;
998 }
999
1000 static int dst_get_tuner_info(struct dst_state *state)
1001 {
1002         u8 get_tuner_1[] = { 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1003         u8 get_tuner_2[] = { 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1004
1005         get_tuner_1[7] = dst_check_sum(get_tuner_1, 7);
1006         get_tuner_2[7] = dst_check_sum(get_tuner_2, 7);
1007         pr_err("DST TYpe = MULTI FE\n");
1008         if (state->type_flags & DST_TYPE_HAS_MULTI_FE) {
1009                 if (dst_command(state, get_tuner_1, 8) < 0) {
1010                         dprintk(2, "Cmd=[0x13], Unsupported\n");
1011                         goto force;
1012                 }
1013         } else {
1014                 if (dst_command(state, get_tuner_2, 8) < 0) {
1015                         dprintk(2, "Cmd=[0xb], Unsupported\n");
1016                         goto force;
1017                 }
1018         }
1019         memcpy(&state->board_info, &state->rxbuffer, 8);
1020         if (state->type_flags & DST_TYPE_HAS_MULTI_FE) {
1021                 pr_err("DST type has TS=188\n");
1022         }
1023         if (state->board_info[0] == 0xbc) {
1024                 if (state->dst_type != DST_TYPE_IS_ATSC)
1025                         state->type_flags |= DST_TYPE_HAS_TS188;
1026                 else
1027                         state->type_flags |= DST_TYPE_HAS_NEWTUNE_2;
1028
1029                 if (state->board_info[1] == 0x01) {
1030                         state->dst_hw_cap |= DST_TYPE_HAS_DBOARD;
1031                         pr_err("DST has Daughterboard\n");
1032                 }
1033         }
1034
1035         return 0;
1036 force:
1037         if (!strncmp(state->fw_name, "DCT-CI", 6)) {
1038                 state->type_flags |= DST_TYPE_HAS_TS204;
1039                 pr_err("Forcing [%s] to TS188\n", state->fw_name);
1040         }
1041
1042         return -1;
1043 }
1044
1045 static int dst_get_device_id(struct dst_state *state)
1046 {
1047         u8 reply;
1048
1049         int i, j;
1050         struct dst_types *p_dst_type = NULL;
1051         struct tuner_types *p_tuner_list = NULL;
1052
1053         u8 use_dst_type = 0;
1054         u32 use_type_flags = 0;
1055
1056         static u8 device_type[8] = {0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff};
1057
1058         state->tuner_type = 0;
1059         device_type[7] = dst_check_sum(device_type, 7);
1060
1061         if (write_dst(state, device_type, FIXED_COMM))
1062                 return -1;              /*      Write failed            */
1063         if ((dst_pio_disable(state)) < 0)
1064                 return -1;
1065         if (read_dst(state, &reply, GET_ACK))
1066                 return -1;              /*      Read failure            */
1067         if (reply != ACK) {
1068                 dprintk(2, "Write not Acknowledged! [Reply=0x%02x]\n", reply);
1069                 return -1;              /*      Unack'd write           */
1070         }
1071         if (!dst_wait_dst_ready(state, DEVICE_INIT))
1072                 return -1;              /*      DST not ready yet       */
1073         if (read_dst(state, state->rxbuffer, FIXED_COMM))
1074                 return -1;
1075
1076         dst_pio_disable(state);
1077         if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) {
1078                 dprintk(2, "Checksum failure!\n");
1079                 return -1;              /*      Checksum failure        */
1080         }
1081         state->rxbuffer[7] = '\0';
1082
1083         for (i = 0, p_dst_type = dst_tlist; i < ARRAY_SIZE(dst_tlist); i++, p_dst_type++) {
1084                 if (!strncmp (&state->rxbuffer[p_dst_type->offset], p_dst_type->device_id, strlen (p_dst_type->device_id))) {
1085                         use_type_flags = p_dst_type->type_flags;
1086                         use_dst_type = p_dst_type->dst_type;
1087
1088                         /*      Card capabilities       */
1089                         state->dst_hw_cap = p_dst_type->dst_feature;
1090                         pr_err("Recognise [%s]\n", p_dst_type->device_id);
1091                         strscpy(state->fw_name, p_dst_type->device_id,
1092                                 sizeof(state->fw_name));
1093                         /*      Multiple tuners         */
1094                         if (p_dst_type->tuner_type & TUNER_TYPE_MULTI) {
1095                                 switch (use_dst_type) {
1096                                 case DST_TYPE_IS_SAT:
1097                                         /*      STV0299 check   */
1098                                         if (dst_check_stv0299(state) < 0) {
1099                                                 pr_err("Unsupported\n");
1100                                                 state->tuner_type = TUNER_TYPE_MB86A15;
1101                                         }
1102                                         break;
1103                                 default:
1104                                         break;
1105                                 }
1106                                 if (dst_check_mb86a15(state) < 0)
1107                                         pr_err("Unsupported\n");
1108                         /*      Single tuner            */
1109                         } else {
1110                                 state->tuner_type = p_dst_type->tuner_type;
1111                         }
1112                         for (j = 0, p_tuner_list = tuner_list; j < ARRAY_SIZE(tuner_list); j++, p_tuner_list++) {
1113                                 if (!(strncmp(p_dst_type->device_id, p_tuner_list->fw_name, 7)) &&
1114                                         p_tuner_list->tuner_type == state->tuner_type) {
1115                                         pr_err("[%s] has a [%s]\n",
1116                                                 p_dst_type->device_id, p_tuner_list->tuner_name);
1117                                 }
1118                         }
1119                         break;
1120                 }
1121         }
1122
1123         if (i >= ARRAY_SIZE(dst_tlist)) {
1124                 pr_err("Unable to recognize %s or %s\n", &state->rxbuffer[0], &state->rxbuffer[1]);
1125                 pr_err("please email linux-dvb@linuxtv.org with this type in");
1126                 use_dst_type = DST_TYPE_IS_SAT;
1127                 use_type_flags = DST_TYPE_HAS_SYMDIV;
1128         }
1129         dst_type_print(state, use_dst_type);
1130         state->type_flags = use_type_flags;
1131         state->dst_type = use_dst_type;
1132         dst_type_flags_print(state);
1133
1134         return 0;
1135 }
1136
1137 static int dst_probe(struct dst_state *state)
1138 {
1139         mutex_init(&state->dst_mutex);
1140         if (dst_addons & DST_TYPE_HAS_CA) {
1141                 if ((rdc_8820_reset(state)) < 0) {
1142                         pr_err("RDC 8820 RESET Failed.\n");
1143                         return -1;
1144                 }
1145                 msleep(4000);
1146         } else {
1147                 msleep(100);
1148         }
1149         if ((dst_comm_init(state)) < 0) {
1150                 pr_err("DST Initialization Failed.\n");
1151                 return -1;
1152         }
1153         msleep(100);
1154         if (dst_get_device_id(state) < 0) {
1155                 pr_err("unknown device.\n");
1156                 return -1;
1157         }
1158         if (dst_get_mac(state) < 0) {
1159                 dprintk(2, "MAC: Unsupported command\n");
1160         }
1161         if ((state->type_flags & DST_TYPE_HAS_MULTI_FE) || (state->type_flags & DST_TYPE_HAS_FW_BUILD)) {
1162                 if (dst_get_tuner_info(state) < 0)
1163                         dprintk(2, "Tuner: Unsupported command\n");
1164         }
1165         if (state->type_flags & DST_TYPE_HAS_TS204) {
1166                 dst_packsize(state, 204);
1167         }
1168         if (state->type_flags & DST_TYPE_HAS_FW_BUILD) {
1169                 if (dst_fw_ver(state) < 0) {
1170                         dprintk(2, "FW: Unsupported command\n");
1171                         return 0;
1172                 }
1173                 if (dst_card_type(state) < 0) {
1174                         dprintk(2, "Card: Unsupported command\n");
1175                         return 0;
1176                 }
1177                 if (dst_get_vendor(state) < 0) {
1178                         dprintk(2, "Vendor: Unsupported command\n");
1179                         return 0;
1180                 }
1181         }
1182
1183         return 0;
1184 }
1185
1186 static int dst_command(struct dst_state *state, u8 *data, u8 len)
1187 {
1188         u8 reply;
1189
1190         mutex_lock(&state->dst_mutex);
1191         if ((dst_comm_init(state)) < 0) {
1192                 dprintk(1, "DST Communication Initialization Failed.\n");
1193                 goto error;
1194         }
1195         if (write_dst(state, data, len)) {
1196                 dprintk(2, "Trying to recover..\n");
1197                 if ((dst_error_recovery(state)) < 0) {
1198                         pr_err("Recovery Failed.\n");
1199                         goto error;
1200                 }
1201                 goto error;
1202         }
1203         if ((dst_pio_disable(state)) < 0) {
1204                 pr_err("PIO Disable Failed.\n");
1205                 goto error;
1206         }
1207         if (state->type_flags & DST_TYPE_HAS_FW_1)
1208                 mdelay(3);
1209         if (read_dst(state, &reply, GET_ACK)) {
1210                 dprintk(3, "Trying to recover..\n");
1211                 if ((dst_error_recovery(state)) < 0) {
1212                         dprintk(2, "Recovery Failed.\n");
1213                         goto error;
1214                 }
1215                 goto error;
1216         }
1217         if (reply != ACK) {
1218                 dprintk(2, "write not acknowledged 0x%02x\n", reply);
1219                 goto error;
1220         }
1221         if (len >= 2 && data[0] == 0 && (data[1] == 1 || data[1] == 3))
1222                 goto error;
1223         if (state->type_flags & DST_TYPE_HAS_FW_1)
1224                 mdelay(3);
1225         else
1226                 udelay(2000);
1227         if (!dst_wait_dst_ready(state, NO_DELAY))
1228                 goto error;
1229         if (read_dst(state, state->rxbuffer, FIXED_COMM)) {
1230                 dprintk(3, "Trying to recover..\n");
1231                 if ((dst_error_recovery(state)) < 0) {
1232                         dprintk(2, "Recovery failed.\n");
1233                         goto error;
1234                 }
1235                 goto error;
1236         }
1237         if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) {
1238                 dprintk(2, "checksum failure\n");
1239                 goto error;
1240         }
1241         mutex_unlock(&state->dst_mutex);
1242         return 0;
1243
1244 error:
1245         mutex_unlock(&state->dst_mutex);
1246         return -EIO;
1247
1248 }
1249
1250 static int dst_get_signal(struct dst_state *state)
1251 {
1252         int retval;
1253         u8 get_signal[] = { 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb };
1254         //dprintk("%s: Getting Signal strength and other parameters\n", __func__);
1255         if ((state->diseq_flags & ATTEMPT_TUNE) == 0) {
1256                 state->decode_lock = state->decode_strength = state->decode_snr = 0;
1257                 return 0;
1258         }
1259         if (0 == (state->diseq_flags & HAS_LOCK)) {
1260                 state->decode_lock = state->decode_strength = state->decode_snr = 0;
1261                 return 0;
1262         }
1263         if (time_after_eq(jiffies, state->cur_jiff + (HZ / 5))) {
1264                 retval = dst_command(state, get_signal, 8);
1265                 if (retval < 0)
1266                         return retval;
1267                 if (state->dst_type == DST_TYPE_IS_SAT) {
1268                         state->decode_lock = ((state->rxbuffer[6] & 0x10) == 0) ? 1 : 0;
1269                         state->decode_strength = state->rxbuffer[5] << 8;
1270                         state->decode_snr = state->rxbuffer[2] << 8 | state->rxbuffer[3];
1271                 } else if ((state->dst_type == DST_TYPE_IS_TERR) || (state->dst_type == DST_TYPE_IS_CABLE)) {
1272                         state->decode_lock = (state->rxbuffer[1]) ? 1 : 0;
1273                         state->decode_strength = state->rxbuffer[4] << 8;
1274                         state->decode_snr = state->rxbuffer[3] << 8;
1275                 } else if (state->dst_type == DST_TYPE_IS_ATSC) {
1276                         state->decode_lock = (state->rxbuffer[6] == 0x00) ? 1 : 0;
1277                         state->decode_strength = state->rxbuffer[4] << 8;
1278                         state->decode_snr = state->rxbuffer[2] << 8 | state->rxbuffer[3];
1279                 }
1280                 state->cur_jiff = jiffies;
1281         }
1282         return 0;
1283 }
1284
1285 static int dst_tone_power_cmd(struct dst_state *state)
1286 {
1287         u8 packet[8] = { 0x00, 0x09, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00 };
1288
1289         if (state->dst_type != DST_TYPE_IS_SAT)
1290                 return -EOPNOTSUPP;
1291         packet[4] = state->tx_tuna[4];
1292         packet[2] = state->tx_tuna[2];
1293         packet[3] = state->tx_tuna[3];
1294         packet[7] = dst_check_sum (packet, 7);
1295         return dst_command(state, packet, 8);
1296 }
1297
1298 static int dst_get_tuna(struct dst_state *state)
1299 {
1300         int retval;
1301
1302         if ((state->diseq_flags & ATTEMPT_TUNE) == 0)
1303                 return 0;
1304         state->diseq_flags &= ~(HAS_LOCK);
1305         if (!dst_wait_dst_ready(state, NO_DELAY))
1306                 return -EIO;
1307         if ((state->type_flags & DST_TYPE_HAS_VLF) &&
1308                 !(state->dst_type == DST_TYPE_IS_ATSC))
1309
1310                 retval = read_dst(state, state->rx_tuna, 10);
1311         else
1312                 retval = read_dst(state, &state->rx_tuna[2], FIXED_COMM);
1313         if (retval < 0) {
1314                 dprintk(3, "read not successful\n");
1315                 return retval;
1316         }
1317         if ((state->type_flags & DST_TYPE_HAS_VLF) &&
1318            !(state->dst_type == DST_TYPE_IS_ATSC)) {
1319
1320                 if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) {
1321                         dprintk(2, "checksum failure ?\n");
1322                         return -EIO;
1323                 }
1324         } else {
1325                 if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[2], 7)) {
1326                         dprintk(2, "checksum failure?\n");
1327                         return -EIO;
1328                 }
1329         }
1330         if (state->rx_tuna[2] == 0 && state->rx_tuna[3] == 0)
1331                 return 0;
1332         if (state->dst_type == DST_TYPE_IS_SAT) {
1333                 state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 8) + state->rx_tuna[3];
1334         } else {
1335                 state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 16) + (state->rx_tuna[3] << 8) + state->rx_tuna[4];
1336         }
1337         state->decode_freq = state->decode_freq * 1000;
1338         state->decode_lock = 1;
1339         state->diseq_flags |= HAS_LOCK;
1340
1341         return 1;
1342 }
1343
1344 static int dst_set_voltage(struct dvb_frontend *fe,
1345                            enum fe_sec_voltage voltage);
1346
1347 static int dst_write_tuna(struct dvb_frontend *fe)
1348 {
1349         struct dst_state *state = fe->demodulator_priv;
1350         int retval;
1351         u8 reply;
1352
1353         dprintk(2, "type_flags 0x%x\n", state->type_flags);
1354         state->decode_freq = 0;
1355         state->decode_lock = state->decode_strength = state->decode_snr = 0;
1356         if (state->dst_type == DST_TYPE_IS_SAT) {
1357                 if (!(state->diseq_flags & HAS_POWER))
1358                         dst_set_voltage(fe, SEC_VOLTAGE_13);
1359         }
1360         state->diseq_flags &= ~(HAS_LOCK | ATTEMPT_TUNE);
1361         mutex_lock(&state->dst_mutex);
1362         if ((dst_comm_init(state)) < 0) {
1363                 dprintk(3, "DST Communication initialization failed.\n");
1364                 goto error;
1365         }
1366 //      if (state->type_flags & DST_TYPE_HAS_NEWTUNE) {
1367         if ((state->type_flags & DST_TYPE_HAS_VLF) &&
1368                 (!(state->dst_type == DST_TYPE_IS_ATSC))) {
1369
1370                 state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[0], 9);
1371                 retval = write_dst(state, &state->tx_tuna[0], 10);
1372         } else {
1373                 state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[2], 7);
1374                 retval = write_dst(state, &state->tx_tuna[2], FIXED_COMM);
1375         }
1376         if (retval < 0) {
1377                 dst_pio_disable(state);
1378                 dprintk(3, "write not successful\n");
1379                 goto werr;
1380         }
1381         if ((dst_pio_disable(state)) < 0) {
1382                 dprintk(3, "DST PIO disable failed !\n");
1383                 goto error;
1384         }
1385         if ((read_dst(state, &reply, GET_ACK) < 0)) {
1386                 dprintk(3, "read verify not successful.\n");
1387                 goto error;
1388         }
1389         if (reply != ACK) {
1390                 dprintk(3, "write not acknowledged 0x%02x\n", reply);
1391                 goto error;
1392         }
1393         state->diseq_flags |= ATTEMPT_TUNE;
1394         retval = dst_get_tuna(state);
1395 werr:
1396         mutex_unlock(&state->dst_mutex);
1397         return retval;
1398
1399 error:
1400         mutex_unlock(&state->dst_mutex);
1401         return -EIO;
1402 }
1403
1404 /*
1405  * line22k0    0x00, 0x09, 0x00, 0xff, 0x01, 0x00, 0x00, 0x00
1406  * line22k1    0x00, 0x09, 0x01, 0xff, 0x01, 0x00, 0x00, 0x00
1407  * line22k2    0x00, 0x09, 0x02, 0xff, 0x01, 0x00, 0x00, 0x00
1408  * tone        0x00, 0x09, 0xff, 0x00, 0x01, 0x00, 0x00, 0x00
1409  * data        0x00, 0x09, 0xff, 0x01, 0x01, 0x00, 0x00, 0x00
1410  * power_off   0x00, 0x09, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
1411  * power_on    0x00, 0x09, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00
1412  * Diseqc 1    0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf0, 0xec
1413  * Diseqc 2    0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf4, 0xe8
1414  * Diseqc 3    0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf8, 0xe4
1415  * Diseqc 4    0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xfc, 0xe0
1416  */
1417
1418 static int dst_set_diseqc(struct dvb_frontend *fe, struct dvb_diseqc_master_cmd *cmd)
1419 {
1420         struct dst_state *state = fe->demodulator_priv;
1421         u8 packet[8] = { 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf0, 0xec };
1422
1423         if (state->dst_type != DST_TYPE_IS_SAT)
1424                 return -EOPNOTSUPP;
1425         if (cmd->msg_len > 0 && cmd->msg_len < 5)
1426                 memcpy(&packet[3], cmd->msg, cmd->msg_len);
1427         else if (cmd->msg_len == 5 && state->dst_hw_cap & DST_TYPE_HAS_DISEQC5)
1428                 memcpy(&packet[2], cmd->msg, cmd->msg_len);
1429         else
1430                 return -EINVAL;
1431         packet[7] = dst_check_sum(&packet[0], 7);
1432         return dst_command(state, packet, 8);
1433 }
1434
1435 static int dst_set_voltage(struct dvb_frontend *fe, enum fe_sec_voltage voltage)
1436 {
1437         int need_cmd, retval = 0;
1438         struct dst_state *state = fe->demodulator_priv;
1439
1440         state->voltage = voltage;
1441         if (state->dst_type != DST_TYPE_IS_SAT)
1442                 return -EOPNOTSUPP;
1443
1444         need_cmd = 0;
1445
1446         switch (voltage) {
1447         case SEC_VOLTAGE_13:
1448         case SEC_VOLTAGE_18:
1449                 if ((state->diseq_flags & HAS_POWER) == 0)
1450                         need_cmd = 1;
1451                 state->diseq_flags |= HAS_POWER;
1452                 state->tx_tuna[4] = 0x01;
1453                 break;
1454         case SEC_VOLTAGE_OFF:
1455                 need_cmd = 1;
1456                 state->diseq_flags &= ~(HAS_POWER | HAS_LOCK | ATTEMPT_TUNE);
1457                 state->tx_tuna[4] = 0x00;
1458                 break;
1459         default:
1460                 return -EINVAL;
1461         }
1462
1463         if (need_cmd)
1464                 retval = dst_tone_power_cmd(state);
1465
1466         return retval;
1467 }
1468
1469 static int dst_set_tone(struct dvb_frontend *fe, enum fe_sec_tone_mode tone)
1470 {
1471         struct dst_state *state = fe->demodulator_priv;
1472
1473         state->tone = tone;
1474         if (state->dst_type != DST_TYPE_IS_SAT)
1475                 return -EOPNOTSUPP;
1476
1477         switch (tone) {
1478         case SEC_TONE_OFF:
1479                 if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
1480                     state->tx_tuna[2] = 0x00;
1481                 else
1482                     state->tx_tuna[2] = 0xff;
1483                 break;
1484
1485         case SEC_TONE_ON:
1486                 state->tx_tuna[2] = 0x02;
1487                 break;
1488         default:
1489                 return -EINVAL;
1490         }
1491         return dst_tone_power_cmd(state);
1492 }
1493
1494 static int dst_send_burst(struct dvb_frontend *fe, enum fe_sec_mini_cmd minicmd)
1495 {
1496         struct dst_state *state = fe->demodulator_priv;
1497
1498         if (state->dst_type != DST_TYPE_IS_SAT)
1499                 return -EOPNOTSUPP;
1500         state->minicmd = minicmd;
1501         switch (minicmd) {
1502         case SEC_MINI_A:
1503                 state->tx_tuna[3] = 0x02;
1504                 break;
1505         case SEC_MINI_B:
1506                 state->tx_tuna[3] = 0xff;
1507                 break;
1508         }
1509         return dst_tone_power_cmd(state);
1510 }
1511
1512
1513 static int bt8xx_dst_init(struct dvb_frontend *fe)
1514 {
1515         struct dst_state *state = fe->demodulator_priv;
1516
1517         static u8 sat_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x00, 0x73, 0x21, 0x00, 0x00 };
1518         static u8 sat_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x55, 0xbd, 0x50, 0x00, 0x00 };
1519         static u8 ter_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
1520         static u8 ter_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
1521         static u8 cab_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
1522         static u8 cab_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
1523         static u8 atsc_tuner[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
1524
1525         state->inversion = INVERSION_OFF;
1526         state->voltage = SEC_VOLTAGE_13;
1527         state->tone = SEC_TONE_OFF;
1528         state->diseq_flags = 0;
1529         state->k22 = 0x02;
1530         state->bandwidth = 7000000;
1531         state->cur_jiff = jiffies;
1532         if (state->dst_type == DST_TYPE_IS_SAT)
1533                 memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_VLF) ? sat_tuna_188 : sat_tuna_204), sizeof (sat_tuna_204));
1534         else if (state->dst_type == DST_TYPE_IS_TERR)
1535                 memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_VLF) ? ter_tuna_188 : ter_tuna_204), sizeof (ter_tuna_204));
1536         else if (state->dst_type == DST_TYPE_IS_CABLE)
1537                 memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_VLF) ? cab_tuna_188 : cab_tuna_204), sizeof (cab_tuna_204));
1538         else if (state->dst_type == DST_TYPE_IS_ATSC)
1539                 memcpy(state->tx_tuna, atsc_tuner, sizeof (atsc_tuner));
1540
1541         return 0;
1542 }
1543
1544 static int dst_read_status(struct dvb_frontend *fe, enum fe_status *status)
1545 {
1546         struct dst_state *state = fe->demodulator_priv;
1547
1548         *status = 0;
1549         if (state->diseq_flags & HAS_LOCK) {
1550 //              dst_get_signal(state);  // don't require(?) to ask MCU
1551                 if (state->decode_lock)
1552                         *status |= FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_SYNC | FE_HAS_VITERBI;
1553         }
1554
1555         return 0;
1556 }
1557
1558 static int dst_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
1559 {
1560         struct dst_state *state = fe->demodulator_priv;
1561
1562         int retval = dst_get_signal(state);
1563         *strength = state->decode_strength;
1564
1565         return retval;
1566 }
1567
1568 static int dst_read_snr(struct dvb_frontend *fe, u16 *snr)
1569 {
1570         struct dst_state *state = fe->demodulator_priv;
1571
1572         int retval = dst_get_signal(state);
1573         *snr = state->decode_snr;
1574
1575         return retval;
1576 }
1577
1578 static int dst_set_frontend(struct dvb_frontend *fe)
1579 {
1580         struct dtv_frontend_properties *p = &fe->dtv_property_cache;
1581         int retval = -EINVAL;
1582         struct dst_state *state = fe->demodulator_priv;
1583
1584         if (p != NULL) {
1585                 retval = dst_set_freq(state, p->frequency);
1586                 if(retval != 0)
1587                         return retval;
1588                 dprintk(3, "Set Frequency=[%d]\n", p->frequency);
1589
1590                 if (state->dst_type == DST_TYPE_IS_SAT) {
1591                         if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
1592                                 dst_set_inversion(state, p->inversion);
1593                         dst_set_fec(state, p->fec_inner);
1594                         dst_set_symbolrate(state, p->symbol_rate);
1595                         dst_set_polarization(state);
1596                         dprintk(3, "Set Symbolrate=[%d]\n", p->symbol_rate);
1597
1598                 } else if (state->dst_type == DST_TYPE_IS_TERR)
1599                         dst_set_bandwidth(state, p->bandwidth_hz);
1600                 else if (state->dst_type == DST_TYPE_IS_CABLE) {
1601                         dst_set_fec(state, p->fec_inner);
1602                         dst_set_symbolrate(state, p->symbol_rate);
1603                         dst_set_modulation(state, p->modulation);
1604                 }
1605                 retval = dst_write_tuna(fe);
1606         }
1607
1608         return retval;
1609 }
1610
1611 static int dst_tune_frontend(struct dvb_frontend* fe,
1612                             bool re_tune,
1613                             unsigned int mode_flags,
1614                             unsigned int *delay,
1615                             enum fe_status *status)
1616 {
1617         struct dst_state *state = fe->demodulator_priv;
1618         struct dtv_frontend_properties *p = &fe->dtv_property_cache;
1619
1620         if (re_tune) {
1621                 dst_set_freq(state, p->frequency);
1622                 dprintk(3, "Set Frequency=[%d]\n", p->frequency);
1623
1624                 if (state->dst_type == DST_TYPE_IS_SAT) {
1625                         if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
1626                                 dst_set_inversion(state, p->inversion);
1627                         dst_set_fec(state, p->fec_inner);
1628                         dst_set_symbolrate(state, p->symbol_rate);
1629                         dst_set_polarization(state);
1630                         dprintk(3, "Set Symbolrate=[%d]\n", p->symbol_rate);
1631
1632                 } else if (state->dst_type == DST_TYPE_IS_TERR)
1633                         dst_set_bandwidth(state, p->bandwidth_hz);
1634                 else if (state->dst_type == DST_TYPE_IS_CABLE) {
1635                         dst_set_fec(state, p->fec_inner);
1636                         dst_set_symbolrate(state, p->symbol_rate);
1637                         dst_set_modulation(state, p->modulation);
1638                 }
1639                 dst_write_tuna(fe);
1640         }
1641
1642         if (!(mode_flags & FE_TUNE_MODE_ONESHOT))
1643                 dst_read_status(fe, status);
1644
1645         *delay = HZ/10;
1646         return 0;
1647 }
1648
1649 static enum dvbfe_algo dst_get_tuning_algo(struct dvb_frontend *fe)
1650 {
1651         return dst_algo ? DVBFE_ALGO_HW : DVBFE_ALGO_SW;
1652 }
1653
1654 static int dst_get_frontend(struct dvb_frontend *fe,
1655                             struct dtv_frontend_properties *p)
1656 {
1657         struct dst_state *state = fe->demodulator_priv;
1658
1659         p->frequency = state->decode_freq;
1660         if (state->dst_type == DST_TYPE_IS_SAT) {
1661                 if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
1662                         p->inversion = state->inversion;
1663                 p->symbol_rate = state->symbol_rate;
1664                 p->fec_inner = dst_get_fec(state);
1665         } else if (state->dst_type == DST_TYPE_IS_TERR) {
1666                 p->bandwidth_hz = state->bandwidth;
1667         } else if (state->dst_type == DST_TYPE_IS_CABLE) {
1668                 p->symbol_rate = state->symbol_rate;
1669                 p->fec_inner = dst_get_fec(state);
1670                 p->modulation = dst_get_modulation(state);
1671         }
1672
1673         return 0;
1674 }
1675
1676 static void bt8xx_dst_release(struct dvb_frontend *fe)
1677 {
1678         struct dst_state *state = fe->demodulator_priv;
1679         if (state->dst_ca) {
1680                 dvb_unregister_device(state->dst_ca);
1681 #ifdef CONFIG_MEDIA_ATTACH
1682                 symbol_put(dst_ca_attach);
1683 #endif
1684         }
1685         kfree(state);
1686 }
1687
1688 static const struct dvb_frontend_ops dst_dvbt_ops;
1689 static const struct dvb_frontend_ops dst_dvbs_ops;
1690 static const struct dvb_frontend_ops dst_dvbc_ops;
1691 static const struct dvb_frontend_ops dst_atsc_ops;
1692
1693 struct dst_state *dst_attach(struct dst_state *state, struct dvb_adapter *dvb_adapter)
1694 {
1695         /* check if the ASIC is there */
1696         if (dst_probe(state) < 0) {
1697                 kfree(state);
1698                 return NULL;
1699         }
1700         /* determine settings based on type */
1701         /* create dvb_frontend */
1702         switch (state->dst_type) {
1703         case DST_TYPE_IS_TERR:
1704                 memcpy(&state->frontend.ops, &dst_dvbt_ops, sizeof(struct dvb_frontend_ops));
1705                 break;
1706         case DST_TYPE_IS_CABLE:
1707                 memcpy(&state->frontend.ops, &dst_dvbc_ops, sizeof(struct dvb_frontend_ops));
1708                 break;
1709         case DST_TYPE_IS_SAT:
1710                 memcpy(&state->frontend.ops, &dst_dvbs_ops, sizeof(struct dvb_frontend_ops));
1711                 break;
1712         case DST_TYPE_IS_ATSC:
1713                 memcpy(&state->frontend.ops, &dst_atsc_ops, sizeof(struct dvb_frontend_ops));
1714                 break;
1715         default:
1716                 pr_err("unknown DST type. please report to the LinuxTV.org DVB mailinglist.\n");
1717                 kfree(state);
1718                 return NULL;
1719         }
1720         state->frontend.demodulator_priv = state;
1721
1722         return state;                           /*      Manu (DST is a card not a frontend)     */
1723 }
1724
1725 EXPORT_SYMBOL_GPL(dst_attach);
1726
1727 static const struct dvb_frontend_ops dst_dvbt_ops = {
1728         .delsys = { SYS_DVBT },
1729         .info = {
1730                 .name = "DST DVB-T",
1731                 .frequency_min_hz = 137 * MHz,
1732                 .frequency_max_hz = 858 * MHz,
1733                 .frequency_stepsize_hz = 166667,
1734                 .caps = FE_CAN_FEC_AUTO                 |
1735                         FE_CAN_QAM_AUTO                 |
1736                         FE_CAN_QAM_16                   |
1737                         FE_CAN_QAM_32                   |
1738                         FE_CAN_QAM_64                   |
1739                         FE_CAN_QAM_128                  |
1740                         FE_CAN_QAM_256                  |
1741                         FE_CAN_TRANSMISSION_MODE_AUTO   |
1742                         FE_CAN_GUARD_INTERVAL_AUTO
1743         },
1744
1745         .release = bt8xx_dst_release,
1746         .init = bt8xx_dst_init,
1747         .tune = dst_tune_frontend,
1748         .set_frontend = dst_set_frontend,
1749         .get_frontend = dst_get_frontend,
1750         .get_frontend_algo = dst_get_tuning_algo,
1751         .read_status = dst_read_status,
1752         .read_signal_strength = dst_read_signal_strength,
1753         .read_snr = dst_read_snr,
1754 };
1755
1756 static const struct dvb_frontend_ops dst_dvbs_ops = {
1757         .delsys = { SYS_DVBS },
1758         .info = {
1759                 .name = "DST DVB-S",
1760                 .frequency_min_hz   =  950 * MHz,
1761                 .frequency_max_hz   = 2150 * MHz,
1762                 .frequency_stepsize_hz = 1 * MHz,
1763                 .frequency_tolerance_hz = 29500 * kHz,
1764                 .symbol_rate_min = 1000000,
1765                 .symbol_rate_max = 45000000,
1766         /*     . symbol_rate_tolerance  =       ???,*/
1767                 .caps = FE_CAN_FEC_AUTO | FE_CAN_QPSK
1768         },
1769
1770         .release = bt8xx_dst_release,
1771         .init = bt8xx_dst_init,
1772         .tune = dst_tune_frontend,
1773         .set_frontend = dst_set_frontend,
1774         .get_frontend = dst_get_frontend,
1775         .get_frontend_algo = dst_get_tuning_algo,
1776         .read_status = dst_read_status,
1777         .read_signal_strength = dst_read_signal_strength,
1778         .read_snr = dst_read_snr,
1779         .diseqc_send_burst = dst_send_burst,
1780         .diseqc_send_master_cmd = dst_set_diseqc,
1781         .set_voltage = dst_set_voltage,
1782         .set_tone = dst_set_tone,
1783 };
1784
1785 static const struct dvb_frontend_ops dst_dvbc_ops = {
1786         .delsys = { SYS_DVBC_ANNEX_A },
1787         .info = {
1788                 .name = "DST DVB-C",
1789                 .frequency_min_hz =  51 * MHz,
1790                 .frequency_max_hz = 858 * MHz,
1791                 .frequency_stepsize_hz = 62500,
1792                 .symbol_rate_min = 1000000,
1793                 .symbol_rate_max = 45000000,
1794                 .caps = FE_CAN_FEC_AUTO |
1795                         FE_CAN_QAM_AUTO |
1796                         FE_CAN_QAM_16   |
1797                         FE_CAN_QAM_32   |
1798                         FE_CAN_QAM_64   |
1799                         FE_CAN_QAM_128  |
1800                         FE_CAN_QAM_256
1801         },
1802
1803         .release = bt8xx_dst_release,
1804         .init = bt8xx_dst_init,
1805         .tune = dst_tune_frontend,
1806         .set_frontend = dst_set_frontend,
1807         .get_frontend = dst_get_frontend,
1808         .get_frontend_algo = dst_get_tuning_algo,
1809         .read_status = dst_read_status,
1810         .read_signal_strength = dst_read_signal_strength,
1811         .read_snr = dst_read_snr,
1812 };
1813
1814 static const struct dvb_frontend_ops dst_atsc_ops = {
1815         .delsys = { SYS_ATSC },
1816         .info = {
1817                 .name = "DST ATSC",
1818                 .frequency_min_hz = 510 * MHz,
1819                 .frequency_max_hz = 858 * MHz,
1820                 .frequency_stepsize_hz = 62500,
1821                 .symbol_rate_min = 1000000,
1822                 .symbol_rate_max = 45000000,
1823                 .caps = FE_CAN_FEC_AUTO | FE_CAN_QAM_AUTO | FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
1824         },
1825
1826         .release = bt8xx_dst_release,
1827         .init = bt8xx_dst_init,
1828         .tune = dst_tune_frontend,
1829         .set_frontend = dst_set_frontend,
1830         .get_frontend = dst_get_frontend,
1831         .get_frontend_algo = dst_get_tuning_algo,
1832         .read_status = dst_read_status,
1833         .read_signal_strength = dst_read_signal_strength,
1834         .read_snr = dst_read_snr,
1835 };
1836
1837 MODULE_DESCRIPTION("DST DVB-S/T/C/ATSC Combo Frontend driver");
1838 MODULE_AUTHOR("Jamie Honan, Manu Abraham");
1839 MODULE_LICENSE("GPL");