2 Frontend-driver for TwinHan DST Frontend
4 Copyright (C) 2003 Jamie Honan
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include <linux/kernel.h>
26 #include <linux/module.h>
27 #include <linux/init.h>
28 #include <linux/string.h>
29 #include <linux/slab.h>
30 #include <linux/vmalloc.h>
31 #include <linux/delay.h>
32 #include <asm/div64.h>
34 #include "dvb_frontend.h"
35 #include "dvb_functions.h"
36 #include "dst-bt878.h"
38 unsigned int dst_debug = 0;
39 unsigned int dst_verbose = 0;
41 MODULE_PARM(dst_verbose, "i");
42 MODULE_PARM_DESC(dst_verbose,
43 "verbose startup messages, default is 1 (yes)");
44 MODULE_PARM(dst_debug, "i");
45 MODULE_PARM_DESC(dst_debug, "debug messages, default is 0 (no)");
47 #define DST_MAX_CARDS 6
48 unsigned int dst_cur_no = 0;
50 unsigned int dst_type[DST_MAX_CARDS] = { [0 ... (DST_MAX_CARDS-1)] = (-1U)};
51 unsigned int dst_type_flags[DST_MAX_CARDS] = { [0 ... (DST_MAX_CARDS-1)] = (-1U)};
52 MODULE_PARM(dst_type, "1-" __stringify(DST_MAX_CARDS) "i");
53 MODULE_PARM_DESC(dst_type,
54 "Type of DST card, 0 Satellite, 1 terrestial TV, 2 Cable, default driver determined");
55 MODULE_PARM(dst_type_flags, "1-" __stringify(DST_MAX_CARDS) "i");
56 MODULE_PARM_DESC(dst_type_flags,
57 "Type flags of DST card, bitfield 1=10 byte tuner, 2=TS is 204, 4=symdiv");
59 #define dprintk if (dst_debug) printk
61 #define DST_TYPE_IS_SAT 0
62 #define DST_TYPE_IS_TERR 1
63 #define DST_TYPE_IS_CABLE 2
65 #define DST_TYPE_HAS_NEWTUNE 1
66 #define DST_TYPE_HAS_TS204 2
67 #define DST_TYPE_HAS_SYMDIV 4
70 #define ATTEMPT_TUNE 2
80 u32 frequency; /* intermediate frequency in kHz for QPSK */
81 fe_spectral_inversion_t inversion;
82 u32 symbol_rate; /* symbol rate in Symbols per second */
84 fe_sec_voltage_t voltage;
85 fe_sec_tone_mode_t tone;
90 unsigned long cur_jiff;
92 fe_bandwidth_t bandwidth;
94 struct dvb_i2c_bus *i2c;
97 static struct dvb_frontend_info dst_info_sat = {
100 .frequency_min = 950000,
101 .frequency_max = 2150000,
102 .frequency_stepsize = 1000, /* kHz for QPSK frontends */
103 .frequency_tolerance = 29500,
104 .symbol_rate_min = 1000000,
105 .symbol_rate_max = 45000000,
106 /* . symbol_rate_tolerance = ???,*/
107 .notifier_delay = 50, /* 1/20 s */
108 .caps = FE_CAN_FEC_AUTO |
112 static struct dvb_frontend_info dst_info_cable = {
115 .frequency_stepsize = 62500,
116 .frequency_min = 51000000,
117 .frequency_max = 858000000,
118 .symbol_rate_min = 1000000,
119 .symbol_rate_max = 45000000,
120 /* . symbol_rate_tolerance = ???,*/
121 .notifier_delay = 50, /* 1/20 s */
122 .caps = FE_CAN_FEC_AUTO |
126 static struct dvb_frontend_info dst_info_tv = {
129 .frequency_min = 137000000,
130 .frequency_max = 858000000,
131 .frequency_stepsize = 166667,
132 .caps = FE_CAN_FEC_AUTO |
134 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO
137 static void dst_packsize(struct dst_data *dst, int psize)
139 union dst_gpio_packet bits;
142 bt878_device_control(dst->bt, DST_IG_TS, &bits);
145 static int dst_gpio_outb(struct dst_data *dst, u32 mask, u32 enbb, u32 outhigh)
147 union dst_gpio_packet enb;
148 union dst_gpio_packet bits;
152 enb.enb.enable = enbb;
153 if ((err = bt878_device_control(dst->bt, DST_IG_ENABLE, &enb)) < 0) {
154 dprintk ("%s: dst_gpio_enb error (err == %i, mask == 0x%02x, enb == 0x%02x)\n", __FUNCTION__, err, mask, enbb);
158 /* because complete disabling means no output, no need to do
163 bits.outp.mask = enbb;
164 bits.outp.highvals = outhigh;
166 if ((err = bt878_device_control(dst->bt, DST_IG_WRITE, &bits)) < 0) {
167 dprintk ("%s: dst_gpio_outb error (err == %i, enbb == 0x%02x, outhigh == 0x%02x)\n", __FUNCTION__, err, enbb, outhigh);
173 static int dst_gpio_inb(struct dst_data *dst, u8 *result)
175 union dst_gpio_packet rd_packet;
180 if ((err = bt878_device_control(dst->bt, DST_IG_READ, &rd_packet)) < 0) {
181 dprintk ("%s: dst_gpio_inb error (err == %i)\n", __FUNCTION__, err);
184 *result = (u8)rd_packet.rd.value;
188 #define DST_I2C_ENABLE 1
192 dst_reset8820(struct dst_data *dst)
195 /* pull 8820 gpio pin low, wait, high, wait, then low */
196 // dprintk ("%s: reset 8820\n", __FUNCTION__);
197 retval = dst_gpio_outb(dst, DST_8820, DST_8820, 0);
201 retval = dst_gpio_outb(dst, DST_8820, DST_8820, DST_8820);
204 /* wait for more feedback on what works here *
206 retval = dst_gpio_outb(dst, DST_8820, DST_8820, 0);
214 dst_i2c_enable(struct dst_data *dst)
217 /* pull I2C enable gpio pin low, wait */
218 // dprintk ("%s: i2c enable\n", __FUNCTION__);
219 retval = dst_gpio_outb(dst, ~0, DST_I2C_ENABLE, 0);
222 // dprintk ("%s: i2c enable delay\n", __FUNCTION__);
228 dst_i2c_disable(struct dst_data *dst)
231 /* release I2C enable gpio pin, wait */
232 // dprintk ("%s: i2c disable\n", __FUNCTION__);
233 retval = dst_gpio_outb(dst, ~0, 0, 0);
236 // dprintk ("%s: i2c disable delay\n", __FUNCTION__);
242 dst_wait_dst_ready(struct dst_data *dst)
247 for (i = 0; i < 200; i++) {
248 retval = dst_gpio_inb(dst, &reply);
251 if ((reply & DST_I2C_ENABLE) == 0) {
252 dprintk ("%s: dst wait ready after %d\n", __FUNCTION__, i);
257 dprintk ("%s: dst wait NOT ready after %d\n", __FUNCTION__, i);
261 #define DST_I2C_ADDR 0x55
263 static int write_dst (struct dst_data *dst, u8 *data, u8 len)
265 struct i2c_msg msg = {
266 .addr = DST_I2C_ADDR, .flags = 0, .buf = data, .len = len };
270 if (dst_debug && dst_verbose) {
272 dprintk("%s writing",__FUNCTION__);
273 for (i = 0 ; i < len ; i++) {
274 dprintk(" 0x%02x", data[i]);
279 for (cnt = 0; cnt < 4; cnt++) {
280 if ((err = dst->i2c->xfer (dst->i2c, &msg, 1)) < 0) {
281 dprintk ("%s: write_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)\n", __FUNCTION__, err, len, data[0]);
282 dst_i2c_disable(dst);
295 static int read_dst (struct dst_data *dst, u8 *ret, u8 len)
298 { .addr = DST_I2C_ADDR, .flags = I2C_M_RD, .buf = ret, .len = len };
302 for (cnt = 0; cnt < 4; cnt++) {
303 if ((err = dst->i2c->xfer (dst->i2c, &msg, 1)) < 0) {
304 dprintk ("%s: read_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)\n", __FUNCTION__, err, len, ret[0]);
305 dst_i2c_disable(dst);
313 dprintk("%s reply is 0x%x\n", __FUNCTION__, ret[0]);
314 if (dst_debug && dst_verbose) {
315 for (err = 1; err < len; err++)
316 dprintk(" 0x%x", ret[err]);
323 static int dst_set_freq(struct dst_data *dst, u32 freq)
327 dst->frequency = freq;
329 // dprintk("%s: set frequency %u\n", __FUNCTION__, freq);
330 if (dst->dst_type == DST_TYPE_IS_SAT) {
332 if (freq < 950 || freq > 2150)
334 val = &dst->tx_tuna[0];
335 val[2] = (freq >> 8) & 0x7f;
341 } else if (dst->dst_type == DST_TYPE_IS_TERR) {
343 if (freq < 137000 || freq > 858000)
345 val = &dst->tx_tuna[0];
346 val[2] = (freq >> 16) & 0xff;
347 val[3] = (freq >> 8) & 0xff;
350 switch (dst->bandwidth) {
351 case BANDWIDTH_6_MHZ:
355 case BANDWIDTH_7_MHZ:
360 case BANDWIDTH_8_MHZ:
367 } else if (dst->dst_type == DST_TYPE_IS_CABLE) {
368 /* guess till will get one */
370 val = &dst->tx_tuna[0];
371 val[2] = (freq >> 16) & 0xff;
372 val[3] = (freq >> 8) & 0xff;
379 static int dst_set_bandwidth(struct dst_data *dst, fe_bandwidth_t bandwidth)
383 dst->bandwidth = bandwidth;
385 if (dst->dst_type != DST_TYPE_IS_TERR)
388 val = &dst->tx_tuna[0];
390 case BANDWIDTH_6_MHZ:
394 case BANDWIDTH_7_MHZ:
398 case BANDWIDTH_8_MHZ:
408 static int dst_set_inversion (struct dst_data *dst, fe_spectral_inversion_t inversion)
412 dst->inversion = inversion;
414 val = &dst->tx_tuna[0];
431 static int dst_set_fec (struct dst_data *dst, fe_code_rate_t fec)
437 static fe_code_rate_t dst_get_fec (struct dst_data *dst)
442 static int dst_set_symbolrate (struct dst_data *dst, u32 srate)
448 dst->symbol_rate = srate;
450 if (dst->dst_type == DST_TYPE_IS_TERR) {
454 // dprintk("%s: set srate %u\n", __FUNCTION__, srate);
456 val = &dst->tx_tuna[0];
458 if (dst->type_flags & DST_TYPE_HAS_SYMDIV) {
463 // dprintk("%s: set symcalc %u\n", __FUNCTION__, symcalc);
464 val[5] = (u8)(symcalc >> 12);
465 val[6] = (u8)(symcalc >> 4);
466 val[7] = (u8)(symcalc << 4);
468 val[5] = (u8)(srate >> 16) & 0x7f;
469 val[6] = (u8)(srate >> 8);
479 static u8 dst_check_sum(u8 *buf, u32 len)
485 for (i = 0; i < len; i++) {
491 typedef struct dst_types {
498 struct dst_types dst_tlist[] = {
499 { "DST-020", 0, DST_TYPE_IS_SAT, DST_TYPE_HAS_SYMDIV },
500 { "DST-030", 0, DST_TYPE_IS_SAT, DST_TYPE_HAS_TS204|DST_TYPE_HAS_NEWTUNE },
501 { "DST-03T", 0, DST_TYPE_IS_SAT, DST_TYPE_HAS_SYMDIV|DST_TYPE_HAS_TS204},
502 { "DST-MOT", 0, DST_TYPE_IS_SAT, DST_TYPE_HAS_SYMDIV },
503 { "DST-CI", 1, DST_TYPE_IS_SAT, DST_TYPE_HAS_TS204|DST_TYPE_HAS_NEWTUNE },
504 { "DSTMCI", 1, DST_TYPE_IS_SAT, DST_TYPE_HAS_NEWTUNE },
505 { "DSTFCI", 1, DST_TYPE_IS_SAT, DST_TYPE_HAS_NEWTUNE },
506 { "DCTNEW", 1, DST_TYPE_IS_CABLE, DST_TYPE_HAS_NEWTUNE },
507 { "DCT_CI", 1, DST_TYPE_IS_CABLE, DST_TYPE_HAS_NEWTUNE|DST_TYPE_HAS_TS204 },
508 { "DTTDIG" , 1, DST_TYPE_IS_TERR, 0} };
509 /* DCTNEW and DCT-CI are guesses */
511 static void dst_type_flags_print(u32 type_flags)
513 printk("DST type flags :");
514 if (type_flags & DST_TYPE_HAS_NEWTUNE)
515 printk(" 0x%x newtuner", DST_TYPE_HAS_NEWTUNE);
516 if (type_flags & DST_TYPE_HAS_TS204)
517 printk(" 0x%x ts204", DST_TYPE_HAS_TS204);
518 if (type_flags & DST_TYPE_HAS_SYMDIV)
519 printk(" 0x%x symdiv", DST_TYPE_HAS_SYMDIV);
523 static int dst_type_print(u8 type)
527 case DST_TYPE_IS_SAT:
530 case DST_TYPE_IS_TERR:
531 otype = "terrestial TV";
533 case DST_TYPE_IS_CABLE:
534 otype = "terrestial TV";
537 printk("%s: invalid dst type %d\n",
541 printk("DST type : %s\n", otype);
545 static int dst_check_ci (struct dst_data *dst)
551 struct dst_types *dsp;
555 memset(txbuf, 0, sizeof(txbuf));
557 txbuf[7] = dst_check_sum (txbuf, 7);
561 retval = write_dst (dst, txbuf, 8);
563 dst_i2c_disable(dst);
564 dprintk("%s: write not successful, maybe no card?\n", __FUNCTION__);
568 retval = read_dst (dst, rxbuf, 1);
569 dst_i2c_disable(dst);
571 dprintk("%s: read not successful, maybe no card?\n", __FUNCTION__);
574 if (rxbuf[0] != 0xff) {
575 dprintk("%s: write reply not 0xff, not ci (%02x)\n", __FUNCTION__, rxbuf[0]);
578 if (!dst_wait_dst_ready(dst))
580 // dst_i2c_enable(i2c); Dimitri
581 retval = read_dst (dst, rxbuf, 8);
582 dst_i2c_disable(dst);
584 dprintk("%s: read not successful\n", __FUNCTION__);
587 if (rxbuf[7] != dst_check_sum (rxbuf, 7)) {
588 dprintk("%s: checksum failure\n", __FUNCTION__);
592 for (i = 0, dsp = &dst_tlist[0]; i < sizeof(dst_tlist) / sizeof(dst_tlist[0]); i++, dsp++) {
593 if (!strncmp(&rxbuf[dsp->offs],
595 strlen(dsp->mstr))) {
596 use_type_flags = dsp->type_flags;
597 use_dst_type = dsp->dst_type;
598 printk("%s: recognize %s\n", __FUNCTION__, dsp->mstr);
602 if (i >= sizeof(dst_tlist) / sizeof(dst_tlist[0])) {
603 printk("%s: unable to recognize %s or %s\n", __FUNCTION__, &rxbuf[0], &rxbuf[1]);
604 printk("%s please email linux-dvb@linuxtv.org with this type in\n", __FUNCTION__);
605 use_dst_type = DST_TYPE_IS_SAT;
606 use_type_flags = DST_TYPE_HAS_SYMDIV;
608 switch (dst_type[dst_cur_no]) {
612 case DST_TYPE_IS_SAT:
613 case DST_TYPE_IS_TERR:
614 case DST_TYPE_IS_CABLE:
615 use_dst_type = (u8)(dst_type[dst_cur_no]);
618 printk("%s: invalid user override dst type %d, not used\n",
619 __FUNCTION__, dst_type[dst_cur_no]);
622 dst_type_print(use_dst_type);
623 if (dst_type_flags[dst_cur_no] != (-1U)) {
624 printk("%s: user override dst type flags 0x%x\n",
625 __FUNCTION__, dst_type_flags[dst_cur_no]);
626 use_type_flags = dst_type_flags[dst_cur_no];
628 dst->type_flags = use_type_flags;
629 dst->dst_type= use_dst_type;
630 dst_type_flags_print(dst->type_flags);
632 if (dst->type_flags & DST_TYPE_HAS_TS204) {
633 dst_packsize(dst, 204);
638 static int dst_command (struct dst_data *dst, u8 *data, u8 len)
645 retval = write_dst (dst, data, len);
647 dst_i2c_disable(dst);
648 dprintk("%s: write not successful\n", __FUNCTION__);
652 retval = read_dst (dst, &reply, 1);
653 dst_i2c_disable(dst);
655 dprintk("%s: read verify not successful\n", __FUNCTION__);
659 dprintk("%s: write reply not 0xff 0x%02x \n", __FUNCTION__, reply);
662 if (len >= 2 && data[0] == 0 && (data[1] == 1 || data[1] == 3))
664 if (!dst_wait_dst_ready(dst))
666 // dst_i2c_enable(i2c); Per dimitri
667 retval = read_dst (dst, dst->rxbuffer, 8);
668 dst_i2c_disable(dst);
670 dprintk("%s: read not successful\n", __FUNCTION__);
673 if (dst->rxbuffer[7] != dst_check_sum (dst->rxbuffer, 7)) {
674 dprintk("%s: checksum failure\n", __FUNCTION__);
680 static int dst_get_signal(struct dst_data *dst)
683 u8 get_signal[] = {0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb};
685 if ((dst->diseq_flags & ATTEMPT_TUNE) == 0) {
686 dst->decode_lock = dst->decode_strength = dst->decode_snr = 0;
689 if (0 == (dst->diseq_flags & HAS_LOCK)) {
690 dst->decode_lock = dst->decode_strength = dst->decode_snr = 0;
693 if (time_after_eq(jiffies, dst->cur_jiff + (HZ/5))) {
694 retval = dst_command(dst, get_signal, 8);
697 if (dst->dst_type == DST_TYPE_IS_SAT) {
698 dst->decode_lock = ((dst->rxbuffer[6] & 0x10) == 0) ?
700 dst->decode_strength = dst->rxbuffer[5] << 8;
701 dst->decode_snr = dst->rxbuffer[2] << 8 |
703 } else if ((dst->dst_type == DST_TYPE_IS_TERR) ||
704 (dst->dst_type == DST_TYPE_IS_CABLE)) {
705 dst->decode_lock = (dst->rxbuffer[1]) ?
707 dst->decode_strength = dst->rxbuffer[4] << 8;
708 dst->decode_snr = dst->rxbuffer[3] << 8;
710 dst->cur_jiff = jiffies;
716 * line22k0 0x00, 0x09, 0x00, 0xff, 0x01, 0x00, 0x00, 0x00
717 * line22k1 0x00, 0x09, 0x01, 0xff, 0x01, 0x00, 0x00, 0x00
718 * line22k2 0x00, 0x09, 0x02, 0xff, 0x01, 0x00, 0x00, 0x00
719 * tone 0x00, 0x09, 0xff, 0x00, 0x01, 0x00, 0x00, 0x00
720 * data 0x00, 0x09, 0xff, 0x01, 0x01, 0x00, 0x00, 0x00
721 * power_off 0x00, 0x09, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
722 * power_on 0x00, 0x09, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00
723 * Diseqc 1 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf0, 0xec
724 * Diseqc 2 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf4, 0xe8
725 * Diseqc 3 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf8, 0xe4
726 * Diseqc 4 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xfc, 0xe0
729 static int dst_set_diseqc (struct dst_data *dst, u8 *cmd, u8 len)
731 u8 paket[8] = {0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf0, 0xec };
733 if (dst->dst_type == DST_TYPE_IS_TERR)
736 if (len == 0 || len > 4)
738 memcpy(&paket[3], cmd, len);
739 paket[7] = dst_check_sum (&paket[0], 7);
740 dst_command(dst, paket, 8);
744 static int dst_tone_power_cmd (struct dst_data *dst)
746 u8 paket[8] = {0x00, 0x09, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00};
748 if (dst->dst_type == DST_TYPE_IS_TERR)
751 if (dst->voltage == SEC_VOLTAGE_OFF)
755 if (dst->tone == SEC_TONE_ON)
759 paket[7] = dst_check_sum (&paket[0], 7);
760 dst_command(dst, paket, 8);
764 static int dst_set_voltage (struct dst_data *dst, fe_sec_voltage_t voltage)
769 dst->voltage = voltage;
771 if (dst->dst_type == DST_TYPE_IS_TERR)
775 val = &dst->tx_tuna[0];
779 if ((dst->diseq_flags & HAS_POWER) == 0)
781 dst->diseq_flags |= HAS_POWER;
784 if ((dst->diseq_flags & HAS_POWER) == 0)
786 dst->diseq_flags |= HAS_POWER;
789 case SEC_VOLTAGE_OFF:
791 dst->diseq_flags &= ~(HAS_POWER|HAS_LOCK|ATTEMPT_TUNE);
797 dst_tone_power_cmd(dst);
803 static int dst_set_tone (struct dst_data *dst, fe_sec_tone_mode_t tone)
809 if (dst->dst_type == DST_TYPE_IS_TERR)
812 val = &dst->tx_tuna[0];
825 dst_tone_power_cmd(dst);
829 static int dst_get_tuna (struct dst_data *dst)
832 if ((dst->diseq_flags & ATTEMPT_TUNE) == 0)
834 dst->diseq_flags &= ~(HAS_LOCK);
835 if (!dst_wait_dst_ready(dst))
837 if (dst->type_flags & DST_TYPE_HAS_NEWTUNE) {
838 /* how to get variable length reply ???? */
839 retval = read_dst (dst, dst->rx_tuna, 10);
841 retval = read_dst (dst, &dst->rx_tuna[2], 8);
844 dprintk("%s: read not successful\n", __FUNCTION__);
847 if (dst->type_flags & DST_TYPE_HAS_NEWTUNE) {
848 if (dst->rx_tuna[9] != dst_check_sum (&dst->rx_tuna[0], 9)) {
849 dprintk("%s: checksum failure?\n", __FUNCTION__);
853 if (dst->rx_tuna[9] != dst_check_sum (&dst->rx_tuna[2], 7)) {
854 dprintk("%s: checksum failure?\n", __FUNCTION__);
858 if (dst->rx_tuna[2] == 0 && dst->rx_tuna[3] == 0)
860 dst->decode_freq = ((dst->rx_tuna[2] & 0x7f) << 8) + dst->rx_tuna[3];
862 dst->decode_lock = 1;
864 dst->decode_n1 = (dst->rx_tuna[4] << 8) +
867 dst->decode_n2 = (dst->rx_tuna[8] << 8) +
870 dst->diseq_flags |= HAS_LOCK;
871 /* dst->cur_jiff = jiffies; */
875 static int dst_write_tuna (struct dst_data *dst)
880 dprintk("%s: type_flags 0x%x \n", __FUNCTION__, dst->type_flags);
881 dst->decode_freq = 0;
882 dst->decode_lock = dst->decode_strength = dst->decode_snr = 0;
883 if (dst->dst_type == DST_TYPE_IS_SAT) {
884 if (!(dst->diseq_flags & HAS_POWER))
885 dst_set_voltage (dst, SEC_VOLTAGE_13);
887 dst->diseq_flags &= ~(HAS_LOCK|ATTEMPT_TUNE);
889 if (dst->type_flags & DST_TYPE_HAS_NEWTUNE) {
891 dst->tx_tuna[9] = dst_check_sum (&dst->tx_tuna[0], 9);
892 retval = write_dst (dst, &dst->tx_tuna[0], 10);
894 dst->tx_tuna[9] = dst_check_sum (&dst->tx_tuna[2], 7);
895 retval = write_dst (dst, &dst->tx_tuna[2], 8);
898 dst_i2c_disable(dst);
899 dprintk("%s: write not successful\n", __FUNCTION__);
903 retval = read_dst (dst, &reply, 1);
904 dst_i2c_disable(dst);
906 dprintk("%s: read verify not successful\n", __FUNCTION__);
910 dprintk("%s: write reply not 0xff 0x%02x \n", __FUNCTION__, reply);
913 dst->diseq_flags |= ATTEMPT_TUNE;
914 return dst_get_tuna(dst);
917 static void dst_init (struct dst_data *dst)
919 static u8 ini_satci_tuna[] = { 9, 0, 3, 0xb6, 1, 0, 0x73, 0x21, 0, 0 };
920 static u8 ini_satfta_tuna[] = { 0, 0, 3, 0xb6, 1, 0x55, 0xbd, 0x50, 0, 0 };
921 static u8 ini_tvfta_tuna[] = { 0, 0, 3, 0xb6, 1, 7, 0x0, 0x0, 0, 0 };
922 static u8 ini_tvci_tuna[] = { 9, 0, 3, 0xb6, 1, 7, 0x0, 0x0, 0, 0 };
923 static u8 ini_cabfta_tuna[] = { 0, 0, 3, 0xb6, 1, 7, 0x0, 0x0, 0, 0 };
924 static u8 ini_cabci_tuna[] = { 9, 0, 3, 0xb6, 1, 7, 0x0, 0x0, 0, 0 };
925 dst->inversion = INVERSION_ON;
926 dst->voltage = SEC_VOLTAGE_13;
927 dst->tone = SEC_TONE_OFF;
928 dst->symbol_rate = 29473000;
930 dst->diseq_flags = 0;
932 dst->bandwidth = BANDWIDTH_7_MHZ;
933 dst->cur_jiff = jiffies;
934 if (dst->dst_type == DST_TYPE_IS_SAT) {
935 dst->frequency = 950000;
936 memcpy(dst->tx_tuna, ((dst->type_flags & DST_TYPE_HAS_NEWTUNE )?
937 ini_satci_tuna : ini_satfta_tuna),
938 sizeof(ini_satfta_tuna));
939 } else if (dst->dst_type == DST_TYPE_IS_TERR) {
940 dst->frequency = 137000000;
941 memcpy(dst->tx_tuna, ((dst->type_flags & DST_TYPE_HAS_NEWTUNE )?
942 ini_tvci_tuna : ini_tvfta_tuna),
943 sizeof(ini_tvfta_tuna));
944 } else if (dst->dst_type == DST_TYPE_IS_CABLE) {
945 dst->frequency = 51000000;
946 memcpy(dst->tx_tuna, ((dst->type_flags & DST_TYPE_HAS_NEWTUNE )?
947 ini_cabci_tuna : ini_cabfta_tuna),
948 sizeof(ini_cabfta_tuna));
956 {FE_GET_INFO, "FE_GET_INFO:"},
957 {FE_READ_STATUS, "FE_READ_STATUS:" },
958 {FE_READ_BER, "FE_READ_BER:" },
959 {FE_READ_SIGNAL_STRENGTH, "FE_READ_SIGNAL_STRENGTH:" },
960 {FE_READ_SNR, "FE_READ_SNR:" },
961 {FE_READ_UNCORRECTED_BLOCKS, "FE_READ_UNCORRECTED_BLOCKS:" },
962 {FE_SET_FRONTEND, "FE_SET_FRONTEND:" },
963 {FE_GET_FRONTEND, "FE_GET_FRONTEND:" },
964 {FE_SLEEP, "FE_SLEEP:" },
965 {FE_INIT, "FE_INIT:" },
966 {FE_SET_TONE, "FE_SET_TONE:" },
967 {FE_SET_VOLTAGE, "FE_SET_VOLTAGE:" },
970 static int dst_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg)
972 struct dst_data *dst = fe->data;
978 for(retval = 0; retval < sizeof(looker) / sizeof(looker[0]); retval++) {
979 if (looker[retval].cmd == cmd) {
980 cc = looker[retval].desc;
984 dprintk("%s cmd %s (0x%x)\n",__FUNCTION__, cc, cmd);
986 // printk("%s: dst %8.8x bt %8.8x i2c %8.8x\n", __FUNCTION__, dst, dst->bt, dst->i2c);
987 /* should be set by attach, but just in case */
992 struct dvb_frontend_info *info;
993 info = &dst_info_sat;
994 if (dst->dst_type == DST_TYPE_IS_TERR)
996 else if (dst->dst_type == DST_TYPE_IS_CABLE)
997 info = &dst_info_cable;
998 memcpy (arg, info, sizeof(struct dvb_frontend_info));
1001 case FE_READ_STATUS:
1003 fe_status_t *status = arg;
1006 if (dst->diseq_flags & HAS_LOCK) {
1007 dst_get_signal(dst);
1008 if (dst->decode_lock)
1009 *status |= FE_HAS_LOCK
1021 // *(u32*) arg = dst->decode_n1;
1026 case FE_READ_SIGNAL_STRENGTH:
1028 dst_get_signal(dst);
1029 *((u16*) arg) = dst->decode_strength;
1035 dst_get_signal(dst);
1036 *((u16*) arg) = dst->decode_snr;
1040 case FE_READ_UNCORRECTED_BLOCKS:
1042 *((u32*) arg) = 0; /* the stv0299 can't measure BER and */
1043 return -EOPNOTSUPP; /* errors at the same time.... */
1046 case FE_SET_FRONTEND:
1048 struct dvb_frontend_parameters *p = arg;
1050 dst_set_freq (dst, p->frequency);
1051 dst_set_inversion (dst, p->inversion);
1052 if (dst->dst_type == DST_TYPE_IS_SAT) {
1053 dst_set_fec (dst, p->u.qpsk.fec_inner);
1054 dst_set_symbolrate (dst, p->u.qpsk.symbol_rate);
1055 } else if (dst->dst_type == DST_TYPE_IS_TERR) {
1056 dst_set_bandwidth(dst, p->u.ofdm.bandwidth);
1057 } else if (dst->dst_type == DST_TYPE_IS_CABLE) {
1058 dst_set_fec (dst, p->u.qam.fec_inner);
1059 dst_set_symbolrate (dst, p->u.qam.symbol_rate);
1061 dst_write_tuna (dst);
1066 case FE_GET_FRONTEND:
1068 struct dvb_frontend_parameters *p = arg;
1071 p->frequency = dst->decode_freq;
1072 p->inversion = dst->inversion;
1073 if (dst->dst_type == DST_TYPE_IS_SAT) {
1074 p->u.qpsk.symbol_rate = dst->symbol_rate;
1075 p->u.qpsk.fec_inner = dst_get_fec (dst);
1076 } else if (dst->dst_type == DST_TYPE_IS_TERR) {
1077 p->u.ofdm.bandwidth = dst->bandwidth;
1078 } else if (dst->dst_type == DST_TYPE_IS_CABLE) {
1079 p->u.qam.symbol_rate = dst->symbol_rate;
1080 p->u.qam.fec_inner = dst_get_fec (dst);
1081 p->u.qam.modulation = QAM_AUTO;
1093 case FE_DISEQC_SEND_MASTER_CMD:
1095 struct dvb_diseqc_master_cmd *cmd = (struct dvb_diseqc_master_cmd *)arg;
1096 retval = dst_set_diseqc (dst, cmd->msg, cmd->msg_len);
1102 retval = dst_set_tone (dst, (fe_sec_tone_mode_t) arg);
1106 case FE_SET_VOLTAGE:
1107 retval = dst_set_voltage (dst, (fe_sec_voltage_t) arg);
1119 static int dst_attach (struct dvb_i2c_bus *i2c, void **data)
1121 struct dst_data *dst;
1123 struct dvb_frontend_info *info;
1125 dprintk("%s: check ci\n", __FUNCTION__);
1126 if (dst_cur_no >= DST_MAX_CARDS) {
1127 dprintk("%s: can't have more than %d cards\n", __FUNCTION__, DST_MAX_CARDS);
1130 bt = bt878_find_by_dvb_adap(i2c->adapter);
1133 dst = kmalloc(sizeof(struct dst_data), GFP_KERNEL);
1135 printk(KERN_INFO "%s: Out of memory.\n", __FUNCTION__);
1138 memset(dst, 0, sizeof(*dst));
1142 if (dst_check_ci(dst) < 0) {
1148 dprintk("%s: register dst %8.8x bt %8.8x i2c %8.8x\n", __FUNCTION__,
1149 (u32)dst, (u32)(dst->bt), (u32)(dst->i2c));
1151 info = &dst_info_sat;
1152 if (dst->dst_type == DST_TYPE_IS_TERR)
1153 info = &dst_info_tv;
1154 else if (dst->dst_type == DST_TYPE_IS_CABLE)
1155 info = &dst_info_cable;
1157 dvb_register_frontend (dst_ioctl, i2c, dst, info);
1162 static void dst_detach (struct dvb_i2c_bus *i2c, void *data)
1164 dvb_unregister_frontend (dst_ioctl, i2c);
1165 dprintk("%s: unregister dst %8.8x\n", __FUNCTION__, (u32)(data));
1170 static int __init init_dst (void)
1172 return dvb_register_i2c_device (THIS_MODULE, dst_attach, dst_detach);
1175 static void __exit exit_dst (void)
1177 dvb_unregister_i2c_device (dst_attach);
1181 module_init(init_dst);
1182 module_exit(exit_dst);
1184 MODULE_DESCRIPTION("DST DVB-S Frontend");
1185 MODULE_AUTHOR("Jamie Honan");
1186 MODULE_LICENSE("GPL");