aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/bt8xx
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/dvb/bt8xx')
-rw-r--r--drivers/media/dvb/bt8xx/Kconfig3
-rw-r--r--drivers/media/dvb/bt8xx/Makefile4
-rw-r--r--drivers/media/dvb/bt8xx/bt878.c54
-rw-r--r--drivers/media/dvb/bt8xx/bt878.h6
-rw-r--r--drivers/media/dvb/bt8xx/dst.c865
-rw-r--r--drivers/media/dvb/bt8xx/dst.h40
-rw-r--r--drivers/media/dvb/bt8xx/dst_ca.c861
-rw-r--r--drivers/media/dvb/bt8xx/dst_ca.h58
-rw-r--r--drivers/media/dvb/bt8xx/dst_common.h153
-rw-r--r--drivers/media/dvb/bt8xx/dst_priv.h1
-rw-r--r--drivers/media/dvb/bt8xx/dvb-bt8xx.c121
-rw-r--r--drivers/media/dvb/bt8xx/dvb-bt8xx.h4
12 files changed, 1757 insertions, 413 deletions
diff --git a/drivers/media/dvb/bt8xx/Kconfig b/drivers/media/dvb/bt8xx/Kconfig
index e7d11e0667a8..b12545f093f8 100644
--- a/drivers/media/dvb/bt8xx/Kconfig
+++ b/drivers/media/dvb/bt8xx/Kconfig
@@ -11,9 +11,8 @@ config DVB_BT8XX
11 the Nebula cards, the Pinnacle PCTV cards, the Twinhan DST cards and 11 the Nebula cards, the Pinnacle PCTV cards, the Twinhan DST cards and
12 pcHDTV HD2000 cards. 12 pcHDTV HD2000 cards.
13 13
14 Since these cards have no MPEG decoder onboard, they transmit 14 Since these cards have no MPEG decoder onboard, they transmit
15 only compressed MPEG data over the PCI bus, so you need 15 only compressed MPEG data over the PCI bus, so you need
16 an external software decoder to watch TV on your computer. 16 an external software decoder to watch TV on your computer.
17 17
18 Say Y if you own such a device and want to use it. 18 Say Y if you own such a device and want to use it.
19
diff --git a/drivers/media/dvb/bt8xx/Makefile b/drivers/media/dvb/bt8xx/Makefile
index 9da8604b9e18..d188e4c670b5 100644
--- a/drivers/media/dvb/bt8xx/Makefile
+++ b/drivers/media/dvb/bt8xx/Makefile
@@ -1,5 +1,3 @@
1 1obj-$(CONFIG_DVB_BT8XX) += bt878.o dvb-bt8xx.o dst.o dst_ca.o
2obj-$(CONFIG_DVB_BT8XX) += bt878.o dvb-bt8xx.o dst.o
3 2
4EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/video -Idrivers/media/dvb/frontends 3EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/video -Idrivers/media/dvb/frontends
5
diff --git a/drivers/media/dvb/bt8xx/bt878.c b/drivers/media/dvb/bt8xx/bt878.c
index 213ff7902024..3c5a8e273c4a 100644
--- a/drivers/media/dvb/bt8xx/bt878.c
+++ b/drivers/media/dvb/bt8xx/bt878.c
@@ -4,27 +4,27 @@
4 * Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@t-online.de> 4 * Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@t-online.de>
5 * 5 *
6 * large parts based on the bttv driver 6 * large parts based on the bttv driver
7 * Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) 7 * Copyright (C) 1996,97,98 Ralph Metzler (rjkm@metzlerbros.de)
8 * & Marcus Metzler (mocm@thp.uni-koeln.de) 8 * & Marcus Metzler (mocm@metzlerbros.de)
9 * (c) 1999,2000 Gerd Knorr <kraxel@goldbach.in-berlin.de> 9 * (c) 1999,2000 Gerd Knorr <kraxel@goldbach.in-berlin.de>
10 * 10 *
11 * This program is free software; you can redistribute it and/or 11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License 12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2 13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version. 14 * of the License, or (at your option) any later version.
15 * 15 *
16 16
17 * This program is distributed in the hope that it will be useful, 17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details. 20 * GNU General Public License for more details.
21 * 21 *
22 22
23 * You should have received a copy of the GNU General Public License 23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software 24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 25 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html 26 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
27 * 27 *
28 */ 28 */
29 29
30#include <linux/module.h> 30#include <linux/module.h>
@@ -58,7 +58,7 @@ module_param_named(verbose, bt878_verbose, int, 0444);
58MODULE_PARM_DESC(verbose, 58MODULE_PARM_DESC(verbose,
59 "verbose startup messages, default is 1 (yes)"); 59 "verbose startup messages, default is 1 (yes)");
60module_param_named(debug, bt878_debug, int, 0644); 60module_param_named(debug, bt878_debug, int, 0644);
61MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off)."); 61MODULE_PARM_DESC(debug, "Turn on/off debugging, default is 0 (off).");
62 62
63int bt878_num; 63int bt878_num;
64struct bt878 bt878[BT878_MAX]; 64struct bt878 bt878[BT878_MAX];
@@ -128,21 +128,21 @@ static int bt878_mem_alloc(struct bt878 *bt)
128} 128}
129 129
130/* RISC instructions */ 130/* RISC instructions */
131#define RISC_WRITE (0x01 << 28) 131#define RISC_WRITE (0x01 << 28)
132#define RISC_JUMP (0x07 << 28) 132#define RISC_JUMP (0x07 << 28)
133#define RISC_SYNC (0x08 << 28) 133#define RISC_SYNC (0x08 << 28)
134 134
135/* RISC bits */ 135/* RISC bits */
136#define RISC_WR_SOL (1 << 27) 136#define RISC_WR_SOL (1 << 27)
137#define RISC_WR_EOL (1 << 26) 137#define RISC_WR_EOL (1 << 26)
138#define RISC_IRQ (1 << 24) 138#define RISC_IRQ (1 << 24)
139#define RISC_STATUS(status) ((((~status) & 0x0F) << 20) | ((status & 0x0F) << 16)) 139#define RISC_STATUS(status) ((((~status) & 0x0F) << 20) | ((status & 0x0F) << 16))
140#define RISC_SYNC_RESYNC (1 << 15) 140#define RISC_SYNC_RESYNC (1 << 15)
141#define RISC_SYNC_FM1 0x06 141#define RISC_SYNC_FM1 0x06
142#define RISC_SYNC_VRO 0x0C 142#define RISC_SYNC_VRO 0x0C
143 143
144#define RISC_FLUSH() bt->risc_pos = 0 144#define RISC_FLUSH() bt->risc_pos = 0
145#define RISC_INSTR(instr) bt->risc_cpu[bt->risc_pos++] = cpu_to_le32(instr) 145#define RISC_INSTR(instr) bt->risc_cpu[bt->risc_pos++] = cpu_to_le32(instr)
146 146
147static int bt878_make_risc(struct bt878 *bt) 147static int bt878_make_risc(struct bt878 *bt)
148{ 148{
@@ -173,7 +173,7 @@ static void bt878_risc_program(struct bt878 *bt, u32 op_sync_orin)
173 RISC_INSTR(RISC_SYNC | RISC_SYNC_FM1 | op_sync_orin); 173 RISC_INSTR(RISC_SYNC | RISC_SYNC_FM1 | op_sync_orin);
174 RISC_INSTR(0); 174 RISC_INSTR(0);
175 175
176 dprintk("bt878: risc len lines %u, bytes per line %u\n", 176 dprintk("bt878: risc len lines %u, bytes per line %u\n",
177 bt->line_count, bt->line_bytes); 177 bt->line_count, bt->line_bytes);
178 for (line = 0; line < bt->line_count; line++) { 178 for (line = 0; line < bt->line_count; line++) {
179 // At the beginning of every block we issue an IRQ with previous (finished) block number set 179 // At the beginning of every block we issue an IRQ with previous (finished) block number set
@@ -228,14 +228,14 @@ void bt878_start(struct bt878 *bt, u32 controlreg, u32 op_sync_orin,
228 * Hacked for DST to: 228 * Hacked for DST to:
229 * SCERR | OCERR | FDSR | FTRGT | FBUS | RISCI 229 * SCERR | OCERR | FDSR | FTRGT | FBUS | RISCI
230 */ 230 */
231 int_mask = BT878_ASCERR | BT878_AOCERR | BT878_APABORT | 231 int_mask = BT878_ASCERR | BT878_AOCERR | BT878_APABORT |
232 BT878_ARIPERR | BT878_APPERR | BT878_AFDSR | BT878_AFTRGT | 232 BT878_ARIPERR | BT878_APPERR | BT878_AFDSR | BT878_AFTRGT |
233 BT878_AFBUS | BT878_ARISCI; 233 BT878_AFBUS | BT878_ARISCI;
234 234
235 235
236 /* ignore pesky bits */ 236 /* ignore pesky bits */
237 int_mask &= ~irq_err_ignore; 237 int_mask &= ~irq_err_ignore;
238 238
239 btwrite(int_mask, BT878_AINT_MASK); 239 btwrite(int_mask, BT878_AINT_MASK);
240 btwrite(controlreg, BT878_AGPIO_DMA_CTL); 240 btwrite(controlreg, BT878_AGPIO_DMA_CTL);
241} 241}
@@ -461,9 +461,9 @@ static int __devinit bt878_probe(struct pci_dev *dev,
461 pci_set_drvdata(dev, bt); 461 pci_set_drvdata(dev, bt);
462 462
463/* if(init_bt878(btv) < 0) { 463/* if(init_bt878(btv) < 0) {
464 bt878_remove(dev); 464 bt878_remove(dev);
465 return -EIO; 465 return -EIO;
466 } 466 }
467*/ 467*/
468 468
469 if ((result = bt878_mem_alloc(bt))) { 469 if ((result = bt878_mem_alloc(bt))) {
@@ -536,10 +536,10 @@ static struct pci_device_id bt878_pci_tbl[] __devinitdata = {
536MODULE_DEVICE_TABLE(pci, bt878_pci_tbl); 536MODULE_DEVICE_TABLE(pci, bt878_pci_tbl);
537 537
538static struct pci_driver bt878_pci_driver = { 538static struct pci_driver bt878_pci_driver = {
539 .name = "bt878", 539 .name = "bt878",
540 .id_table = bt878_pci_tbl, 540 .id_table = bt878_pci_tbl,
541 .probe = bt878_probe, 541 .probe = bt878_probe,
542 .remove = bt878_remove, 542 .remove = bt878_remove,
543}; 543};
544 544
545static int bt878_pci_driver_registered = 0; 545static int bt878_pci_driver_registered = 0;
@@ -558,7 +558,7 @@ static int bt878_init_module(void)
558 (BT878_VERSION_CODE >> 8) & 0xff, 558 (BT878_VERSION_CODE >> 8) & 0xff,
559 BT878_VERSION_CODE & 0xff); 559 BT878_VERSION_CODE & 0xff);
560/* 560/*
561 bt878_check_chipset(); 561 bt878_check_chipset();
562*/ 562*/
563 /* later we register inside of bt878_find_audio_dma() 563 /* later we register inside of bt878_find_audio_dma()
564 * because we may want to ignore certain cards */ 564 * because we may want to ignore certain cards */
diff --git a/drivers/media/dvb/bt8xx/bt878.h b/drivers/media/dvb/bt8xx/bt878.h
index e1b9809d1b08..837623f7fcdf 100644
--- a/drivers/media/dvb/bt8xx/bt878.h
+++ b/drivers/media/dvb/bt8xx/bt878.h
@@ -1,4 +1,4 @@
1/* 1/*
2 bt878.h - Bt878 audio module (register offsets) 2 bt878.h - Bt878 audio module (register offsets)
3 3
4 Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@t-online.de> 4 Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@t-online.de>
@@ -120,14 +120,14 @@ struct bt878 {
120 u32 risc_pos; 120 u32 risc_pos;
121 121
122 struct tasklet_struct tasklet; 122 struct tasklet_struct tasklet;
123 int shutdown; 123 int shutdown;
124}; 124};
125 125
126extern struct bt878 bt878[BT878_MAX]; 126extern struct bt878 bt878[BT878_MAX];
127 127
128void bt878_start(struct bt878 *bt, u32 controlreg, u32 op_sync_orin, 128void bt878_start(struct bt878 *bt, u32 controlreg, u32 op_sync_orin,
129 u32 irq_err_ignore); 129 u32 irq_err_ignore);
130void bt878_stop(struct bt878 *bt); 130void bt878_stop(struct bt878 *bt);
131 131
132#if defined(__powerpc__) /* big-endian */ 132#if defined(__powerpc__) /* big-endian */
133extern __inline__ void io_st_le32(volatile unsigned __iomem *addr, unsigned val) 133extern __inline__ void io_st_le32(volatile unsigned __iomem *addr, unsigned val)
diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c
index eac83768dfd0..d047e349d706 100644
--- a/drivers/media/dvb/bt8xx/dst.c
+++ b/drivers/media/dvb/bt8xx/dst.c
@@ -1,25 +1,25 @@
1/* 1/*
2 Frontend-driver for TwinHan DST Frontend
3 2
4 Copyright (C) 2003 Jamie Honan 3 Frontend/Card driver for TwinHan DST Frontend
4 Copyright (C) 2003 Jamie Honan
5 Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com)
5 6
6 This program is free software; you can redistribute it and/or modify 7 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by 8 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or 9 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version. 10 (at your option) any later version.
10 11
11 This program is distributed in the hope that it will be useful, 12 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 15 GNU General Public License for more details.
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21*/ 20*/
22 21
22
23#include <linux/kernel.h> 23#include <linux/kernel.h>
24#include <linux/module.h> 24#include <linux/module.h>
25#include <linux/init.h> 25#include <linux/init.h>
@@ -31,59 +31,22 @@
31 31
32#include "dvb_frontend.h" 32#include "dvb_frontend.h"
33#include "dst_priv.h" 33#include "dst_priv.h"
34#include "dst.h" 34#include "dst_common.h"
35
36struct dst_state {
37
38 struct i2c_adapter* i2c;
39
40 struct bt878* bt;
41
42 struct dvb_frontend_ops ops;
43
44 /* configuration settings */
45 const struct dst_config* config;
46
47 struct dvb_frontend frontend;
48
49 /* private demodulator data */
50 u8 tx_tuna[10];
51 u8 rx_tuna[10];
52 u8 rxbuffer[10];
53 u8 diseq_flags;
54 u8 dst_type;
55 u32 type_flags;
56 u32 frequency; /* intermediate frequency in kHz for QPSK */
57 fe_spectral_inversion_t inversion;
58 u32 symbol_rate; /* symbol rate in Symbols per second */
59 fe_code_rate_t fec;
60 fe_sec_voltage_t voltage;
61 fe_sec_tone_mode_t tone;
62 u32 decode_freq;
63 u8 decode_lock;
64 u16 decode_strength;
65 u16 decode_snr;
66 unsigned long cur_jiff;
67 u8 k22;
68 fe_bandwidth_t bandwidth;
69};
70 35
71static unsigned int dst_verbose = 0;
72module_param(dst_verbose, int, 0644);
73MODULE_PARM_DESC(dst_verbose, "verbose startup messages, default is 1 (yes)");
74static unsigned int dst_debug = 0;
75module_param(dst_debug, int, 0644);
76MODULE_PARM_DESC(dst_debug, "debug messages, default is 0 (no)");
77 36
78#define dprintk if (dst_debug) printk 37static unsigned int verbose = 1;
38module_param(verbose, int, 0644);
39MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)");
79 40
80#define DST_TYPE_IS_SAT 0 41static unsigned int debug = 1;
81#define DST_TYPE_IS_TERR 1 42module_param(debug, int, 0644);
82#define DST_TYPE_IS_CABLE 2 43MODULE_PARM_DESC(debug, "debug messages, default is 0 (yes)");
83 44
84#define DST_TYPE_HAS_NEWTUNE 1 45static unsigned int dst_addons;
85#define DST_TYPE_HAS_TS204 2 46module_param(dst_addons, int, 0644);
86#define DST_TYPE_HAS_SYMDIV 4 47MODULE_PARM_DESC(dst_addons, "CA daughterboard, default is 0 (No addons)");
48
49#define dprintk if (debug) printk
87 50
88#define HAS_LOCK 1 51#define HAS_LOCK 1
89#define ATTEMPT_TUNE 2 52#define ATTEMPT_TUNE 2
@@ -97,7 +60,7 @@ static void dst_packsize(struct dst_state* state, int psize)
97 bt878_device_control(state->bt, DST_IG_TS, &bits); 60 bt878_device_control(state->bt, DST_IG_TS, &bits);
98} 61}
99 62
100static int dst_gpio_outb(struct dst_state* state, u32 mask, u32 enbb, u32 outhigh) 63int dst_gpio_outb(struct dst_state* state, u32 mask, u32 enbb, u32 outhigh, int delay)
101{ 64{
102 union dst_gpio_packet enb; 65 union dst_gpio_packet enb;
103 union dst_gpio_packet bits; 66 union dst_gpio_packet bits;
@@ -105,26 +68,33 @@ static int dst_gpio_outb(struct dst_state* state, u32 mask, u32 enbb, u32 outhig
105 68
106 enb.enb.mask = mask; 69 enb.enb.mask = mask;
107 enb.enb.enable = enbb; 70 enb.enb.enable = enbb;
71 if (verbose > 4)
72 dprintk("%s: mask=[%04x], enbb=[%04x], outhigh=[%04x]\n", __FUNCTION__, mask, enbb, outhigh);
73
108 if ((err = bt878_device_control(state->bt, DST_IG_ENABLE, &enb)) < 0) { 74 if ((err = bt878_device_control(state->bt, DST_IG_ENABLE, &enb)) < 0) {
109 dprintk("%s: dst_gpio_enb error (err == %i, mask == 0x%02x, enb == 0x%02x)\n", __FUNCTION__, err, mask, enbb); 75 dprintk("%s: dst_gpio_enb error (err == %i, mask == %02x, enb == %02x)\n", __FUNCTION__, err, mask, enbb);
110 return -EREMOTEIO; 76 return -EREMOTEIO;
111 } 77 }
112 78 udelay(1000);
113 /* because complete disabling means no output, no need to do output packet */ 79 /* because complete disabling means no output, no need to do output packet */
114 if (enbb == 0) 80 if (enbb == 0)
115 return 0; 81 return 0;
116 82
83 if (delay)
84 msleep(10);
85
117 bits.outp.mask = enbb; 86 bits.outp.mask = enbb;
118 bits.outp.highvals = outhigh; 87 bits.outp.highvals = outhigh;
119 88
120 if ((err = bt878_device_control(state->bt, DST_IG_WRITE, &bits)) < 0) { 89 if ((err = bt878_device_control(state->bt, DST_IG_WRITE, &bits)) < 0) {
121 dprintk("%s: dst_gpio_outb error (err == %i, enbb == 0x%02x, outhigh == 0x%02x)\n", __FUNCTION__, err, enbb, outhigh); 90 dprintk("%s: dst_gpio_outb error (err == %i, enbb == %02x, outhigh == %02x)\n", __FUNCTION__, err, enbb, outhigh);
122 return -EREMOTEIO; 91 return -EREMOTEIO;
123 } 92 }
124 return 0; 93 return 0;
125} 94}
95EXPORT_SYMBOL(dst_gpio_outb);
126 96
127static int dst_gpio_inb(struct dst_state *state, u8 * result) 97int dst_gpio_inb(struct dst_state *state, u8 * result)
128{ 98{
129 union dst_gpio_packet rd_packet; 99 union dst_gpio_packet rd_packet;
130 int err; 100 int err;
@@ -139,143 +109,225 @@ static int dst_gpio_inb(struct dst_state *state, u8 * result)
139 *result = (u8) rd_packet.rd.value; 109 *result = (u8) rd_packet.rd.value;
140 return 0; 110 return 0;
141} 111}
112EXPORT_SYMBOL(dst_gpio_inb);
142 113
143#define DST_I2C_ENABLE 1 114int rdc_reset_state(struct dst_state *state)
144#define DST_8820 2
145
146static int dst_reset8820(struct dst_state *state)
147{ 115{
148 int retval; 116 if (verbose > 1)
149 /* pull 8820 gpio pin low, wait, high, wait, then low */ 117 dprintk("%s: Resetting state machine\n", __FUNCTION__);
150 // dprintk ("%s: reset 8820\n", __FUNCTION__); 118
151 retval = dst_gpio_outb(state, DST_8820, DST_8820, 0); 119 if (dst_gpio_outb(state, RDC_8820_INT, RDC_8820_INT, 0, NO_DELAY) < 0) {
152 if (retval < 0) 120 dprintk("%s: dst_gpio_outb ERROR !\n", __FUNCTION__);
153 return retval; 121 return -1;
122 }
123
154 msleep(10); 124 msleep(10);
155 retval = dst_gpio_outb(state, DST_8820, DST_8820, DST_8820); 125
156 if (retval < 0) 126 if (dst_gpio_outb(state, RDC_8820_INT, RDC_8820_INT, RDC_8820_INT, NO_DELAY) < 0) {
157 return retval; 127 dprintk("%s: dst_gpio_outb ERROR !\n", __FUNCTION__);
158 /* wait for more feedback on what works here * 128 msleep(10);
159 msleep(10); 129 return -1;
160 retval = dst_gpio_outb(dst, DST_8820, DST_8820, 0); 130 }
161 if (retval < 0) 131
162 return retval;
163 */
164 return 0; 132 return 0;
165} 133}
134EXPORT_SYMBOL(rdc_reset_state);
166 135
167static int dst_i2c_enable(struct dst_state *state) 136int rdc_8820_reset(struct dst_state *state)
168{ 137{
169 int retval; 138 if (verbose > 1)
170 /* pull I2C enable gpio pin low, wait */ 139 dprintk("%s: Resetting DST\n", __FUNCTION__);
171 // dprintk ("%s: i2c enable\n", __FUNCTION__); 140
172 retval = dst_gpio_outb(state, ~0, DST_I2C_ENABLE, 0); 141 if (dst_gpio_outb(state, RDC_8820_RESET, RDC_8820_RESET, 0, NO_DELAY) < 0) {
173 if (retval < 0) 142 dprintk("%s: dst_gpio_outb ERROR !\n", __FUNCTION__);
174 return retval; 143 return -1;
175 // dprintk ("%s: i2c enable delay\n", __FUNCTION__); 144 }
176 msleep(33); 145 udelay(1000);
146 if (dst_gpio_outb(state, RDC_8820_RESET, RDC_8820_RESET, RDC_8820_RESET, DELAY) < 0) {
147 dprintk("%s: dst_gpio_outb ERROR !\n", __FUNCTION__);
148 return -1;
149 }
150
177 return 0; 151 return 0;
178} 152}
153EXPORT_SYMBOL(rdc_8820_reset);
179 154
180static int dst_i2c_disable(struct dst_state *state) 155int dst_pio_enable(struct dst_state *state)
181{ 156{
182 int retval; 157 if (dst_gpio_outb(state, ~0, RDC_8820_PIO_0_ENABLE, 0, NO_DELAY) < 0) {
183 /* release I2C enable gpio pin, wait */ 158 dprintk("%s: dst_gpio_outb ERROR !\n", __FUNCTION__);
184 // dprintk ("%s: i2c disable\n", __FUNCTION__); 159 return -1;
185 retval = dst_gpio_outb(state, ~0, 0, 0); 160 }
186 if (retval < 0) 161 udelay(1000);
187 return retval; 162 return 0;
188 // dprintk ("%s: i2c disable delay\n", __FUNCTION__); 163}
189 msleep(33); 164EXPORT_SYMBOL(dst_pio_enable);
165
166int dst_pio_disable(struct dst_state *state)
167{
168 if (dst_gpio_outb(state, ~0, RDC_8820_PIO_0_DISABLE, RDC_8820_PIO_0_DISABLE, NO_DELAY) < 0) {
169 dprintk("%s: dst_gpio_outb ERROR !\n", __FUNCTION__);
170 return -1;
171 }
172 if (state->type_flags & DST_TYPE_HAS_FW_1)
173 udelay(1000);
174
190 return 0; 175 return 0;
191} 176}
177EXPORT_SYMBOL(dst_pio_disable);
192 178
193static int dst_wait_dst_ready(struct dst_state *state) 179int dst_wait_dst_ready(struct dst_state *state, u8 delay_mode)
194{ 180{
195 u8 reply; 181 u8 reply;
196 int retval;
197 int i; 182 int i;
183
198 for (i = 0; i < 200; i++) { 184 for (i = 0; i < 200; i++) {
199 retval = dst_gpio_inb(state, &reply); 185 if (dst_gpio_inb(state, &reply) < 0) {
200 if (retval < 0) 186 dprintk("%s: dst_gpio_inb ERROR !\n", __FUNCTION__);
201 return retval; 187 return -1;
202 if ((reply & DST_I2C_ENABLE) == 0) { 188 }
203 dprintk("%s: dst wait ready after %d\n", __FUNCTION__, i); 189
190 if ((reply & RDC_8820_PIO_0_ENABLE) == 0) {
191 if (verbose > 4)
192 dprintk("%s: dst wait ready after %d\n", __FUNCTION__, i);
204 return 1; 193 return 1;
205 } 194 }
206 msleep(10); 195 msleep(10);
207 } 196 }
208 dprintk("%s: dst wait NOT ready after %d\n", __FUNCTION__, i); 197 if (verbose > 1)
198 dprintk("%s: dst wait NOT ready after %d\n", __FUNCTION__, i);
199
200 return 0;
201}
202EXPORT_SYMBOL(dst_wait_dst_ready);
203
204int dst_error_recovery(struct dst_state *state)
205{
206 dprintk("%s: Trying to return from previous errors...\n", __FUNCTION__);
207 dst_pio_disable(state);
208 msleep(10);
209 dst_pio_enable(state);
210 msleep(10);
211
212 return 0;
213}
214EXPORT_SYMBOL(dst_error_recovery);
215
216int dst_error_bailout(struct dst_state *state)
217{
218 dprintk("%s: Trying to bailout from previous error...\n", __FUNCTION__);
219 rdc_8820_reset(state);
220 dst_pio_disable(state);
221 msleep(10);
222
223 return 0;
224}
225EXPORT_SYMBOL(dst_error_bailout);
226
227
228int dst_comm_init(struct dst_state* state)
229{
230 if (verbose > 1)
231 dprintk ("%s: Initializing DST..\n", __FUNCTION__);
232 if ((dst_pio_enable(state)) < 0) {
233 dprintk("%s: PIO Enable Failed.\n", __FUNCTION__);
234 return -1;
235 }
236 if ((rdc_reset_state(state)) < 0) {
237 dprintk("%s: RDC 8820 State RESET Failed.\n", __FUNCTION__);
238 return -1;
239 }
240 if (state->type_flags & DST_TYPE_HAS_FW_1)
241 msleep(100);
242 else
243 msleep(5);
244
209 return 0; 245 return 0;
210} 246}
247EXPORT_SYMBOL(dst_comm_init);
211 248
212static int write_dst(struct dst_state *state, u8 * data, u8 len) 249
250int write_dst(struct dst_state *state, u8 *data, u8 len)
213{ 251{
214 struct i2c_msg msg = { 252 struct i2c_msg msg = {
215 .addr = state->config->demod_address,.flags = 0,.buf = data,.len = len 253 .addr = state->config->demod_address,.flags = 0,.buf = data,.len = len
216 }; 254 };
255
217 int err; 256 int err;
218 int cnt; 257 int cnt;
219 258 if (debug && (verbose > 4)) {
220 if (dst_debug && dst_verbose) {
221 u8 i; 259 u8 i;
222 dprintk("%s writing", __FUNCTION__); 260 if (verbose > 4) {
223 for (i = 0; i < len; i++) { 261 dprintk("%s writing", __FUNCTION__);
224 dprintk(" 0x%02x", data[i]); 262 for (i = 0; i < len; i++)
263 dprintk(" %02x", data[i]);
264 dprintk("\n");
225 } 265 }
226 dprintk("\n");
227 } 266 }
228 msleep(30); 267 for (cnt = 0; cnt < 2; cnt++) {
229 for (cnt = 0; cnt < 4; cnt++) {
230 if ((err = i2c_transfer(state->i2c, &msg, 1)) < 0) { 268 if ((err = i2c_transfer(state->i2c, &msg, 1)) < 0) {
231 dprintk("%s: write_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)\n", __FUNCTION__, err, len, data[0]); 269 dprintk("%s: _write_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)\n", __FUNCTION__, err, len, data[0]);
232 dst_i2c_disable(state); 270 dst_error_recovery(state);
233 msleep(500);
234 dst_i2c_enable(state);
235 msleep(500);
236 continue; 271 continue;
237 } else 272 } else
238 break; 273 break;
239 } 274 }
240 if (cnt >= 4) 275
241 return -EREMOTEIO; 276 if (cnt >= 2) {
277 if (verbose > 1)
278 printk("%s: RDC 8820 RESET...\n", __FUNCTION__);
279 dst_error_bailout(state);
280
281 return -1;
282 }
283
242 return 0; 284 return 0;
243} 285}
286EXPORT_SYMBOL(write_dst);
244 287
245static int read_dst(struct dst_state *state, u8 * ret, u8 len) 288int read_dst(struct dst_state *state, u8 * ret, u8 len)
246{ 289{
247 struct i2c_msg msg = {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = ret,.len = len }; 290 struct i2c_msg msg = {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = ret,.len = len };
248 int err; 291 int err;
249 int cnt; 292 int cnt;
250 293
251 for (cnt = 0; cnt < 4; cnt++) { 294 for (cnt = 0; cnt < 2; cnt++) {
252 if ((err = i2c_transfer(state->i2c, &msg, 1)) < 0) { 295 if ((err = i2c_transfer(state->i2c, &msg, 1)) < 0) {
296
253 dprintk("%s: read_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)\n", __FUNCTION__, err, len, ret[0]); 297 dprintk("%s: read_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)\n", __FUNCTION__, err, len, ret[0]);
254 dst_i2c_disable(state); 298 dst_error_recovery(state);
255 dst_i2c_enable(state); 299
256 continue; 300 continue;
257 } else 301 } else
258 break; 302 break;
259 } 303 }
260 if (cnt >= 4) 304 if (cnt >= 2) {
261 return -EREMOTEIO; 305 if (verbose > 1)
262 dprintk("%s reply is 0x%x\n", __FUNCTION__, ret[0]); 306 printk("%s: RDC 8820 RESET...\n", __FUNCTION__);
263 if (dst_debug && dst_verbose) { 307 dst_error_bailout(state);
308
309 return -1;
310 }
311 if (debug && (verbose > 4)) {
312 dprintk("%s reply is 0x%x\n", __FUNCTION__, ret[0]);
264 for (err = 1; err < len; err++) 313 for (err = 1; err < len; err++)
265 dprintk(" 0x%x", ret[err]); 314 dprintk(" 0x%x", ret[err]);
266 if (err > 1) 315 if (err > 1)
267 dprintk("\n"); 316 dprintk("\n");
268 } 317 }
318
269 return 0; 319 return 0;
270} 320}
321EXPORT_SYMBOL(read_dst);
271 322
272static int dst_set_freq(struct dst_state *state, u32 freq) 323static int dst_set_freq(struct dst_state *state, u32 freq)
273{ 324{
274 u8 *val; 325 u8 *val;
275 326
276 state->frequency = freq; 327 state->frequency = freq;
328 if (debug > 4)
329 dprintk("%s: set Frequency %u\n", __FUNCTION__, freq);
277 330
278 // dprintk("%s: set frequency %u\n", __FUNCTION__, freq);
279 if (state->dst_type == DST_TYPE_IS_SAT) { 331 if (state->dst_type == DST_TYPE_IS_SAT) {
280 freq = freq / 1000; 332 freq = freq / 1000;
281 if (freq < 950 || freq > 2150) 333 if (freq < 950 || freq > 2150)
@@ -398,7 +450,8 @@ static int dst_set_symbolrate(struct dst_state* state, u32 srate)
398 if (state->dst_type == DST_TYPE_IS_TERR) { 450 if (state->dst_type == DST_TYPE_IS_TERR) {
399 return 0; 451 return 0;
400 } 452 }
401 // dprintk("%s: set srate %u\n", __FUNCTION__, srate); 453 if (debug > 4)
454 dprintk("%s: set symrate %u\n", __FUNCTION__, srate);
402 srate /= 1000; 455 srate /= 1000;
403 val = &state->tx_tuna[0]; 456 val = &state->tx_tuna[0];
404 457
@@ -407,7 +460,10 @@ static int dst_set_symbolrate(struct dst_state* state, u32 srate)
407 sval <<= 20; 460 sval <<= 20;
408 do_div(sval, 88000); 461 do_div(sval, 88000);
409 symcalc = (u32) sval; 462 symcalc = (u32) sval;
410 // dprintk("%s: set symcalc %u\n", __FUNCTION__, symcalc); 463
464 if (debug > 4)
465 dprintk("%s: set symcalc %u\n", __FUNCTION__, symcalc);
466
411 val[5] = (u8) (symcalc >> 12); 467 val[5] = (u8) (symcalc >> 12);
412 val[6] = (u8) (symcalc >> 4); 468 val[6] = (u8) (symcalc >> 4);
413 val[7] = (u8) (symcalc << 4); 469 val[7] = (u8) (symcalc << 4);
@@ -422,7 +478,7 @@ static int dst_set_symbolrate(struct dst_state* state, u32 srate)
422 return 0; 478 return 0;
423} 479}
424 480
425static u8 dst_check_sum(u8 * buf, u32 len) 481u8 dst_check_sum(u8 * buf, u32 len)
426{ 482{
427 u32 i; 483 u32 i;
428 u8 val = 0; 484 u8 val = 0;
@@ -433,28 +489,7 @@ static u8 dst_check_sum(u8 * buf, u32 len)
433 } 489 }
434 return ((~val) + 1); 490 return ((~val) + 1);
435} 491}
436 492EXPORT_SYMBOL(dst_check_sum);
437struct dst_types {
438 char *mstr;
439 int offs;
440 u8 dst_type;
441 u32 type_flags;
442};
443
444static struct dst_types dst_tlist[] = {
445 {"DST-020", 0, DST_TYPE_IS_SAT, DST_TYPE_HAS_SYMDIV},
446 {"DST-030", 0, DST_TYPE_IS_SAT, DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE},
447 {"DST-03T", 0, DST_TYPE_IS_SAT, DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_TS204},
448 {"DST-MOT", 0, DST_TYPE_IS_SAT, DST_TYPE_HAS_SYMDIV},
449 {"DST-CI", 1, DST_TYPE_IS_SAT, DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE},
450 {"DSTMCI", 1, DST_TYPE_IS_SAT, DST_TYPE_HAS_NEWTUNE},
451 {"DSTFCI", 1, DST_TYPE_IS_SAT, DST_TYPE_HAS_NEWTUNE},
452 {"DCTNEW", 1, DST_TYPE_IS_CABLE, DST_TYPE_HAS_NEWTUNE},
453 {"DCT-CI", 1, DST_TYPE_IS_CABLE, DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_TS204},
454 {"DTTDIG", 1, DST_TYPE_IS_TERR, 0}
455};
456
457/* DCTNEW and DCT-CI are guesses */
458 493
459static void dst_type_flags_print(u32 type_flags) 494static void dst_type_flags_print(u32 type_flags)
460{ 495{
@@ -465,93 +500,270 @@ static void dst_type_flags_print(u32 type_flags)
465 printk(" 0x%x ts204", DST_TYPE_HAS_TS204); 500 printk(" 0x%x ts204", DST_TYPE_HAS_TS204);
466 if (type_flags & DST_TYPE_HAS_SYMDIV) 501 if (type_flags & DST_TYPE_HAS_SYMDIV)
467 printk(" 0x%x symdiv", DST_TYPE_HAS_SYMDIV); 502 printk(" 0x%x symdiv", DST_TYPE_HAS_SYMDIV);
503 if (type_flags & DST_TYPE_HAS_FW_1)
504 printk(" 0x%x firmware version = 1", DST_TYPE_HAS_FW_1);
505 if (type_flags & DST_TYPE_HAS_FW_2)
506 printk(" 0x%x firmware version = 2", DST_TYPE_HAS_FW_2);
507 if (type_flags & DST_TYPE_HAS_FW_3)
508 printk(" 0x%x firmware version = 3", DST_TYPE_HAS_FW_3);
509// if ((type_flags & DST_TYPE_HAS_FW_BUILD) && new_fw)
510
468 printk("\n"); 511 printk("\n");
469} 512}
470 513
471static int dst_type_print(u8 type) 514
515static int dst_type_print (u8 type)
472{ 516{
473 char *otype; 517 char *otype;
474 switch (type) { 518 switch (type) {
475 case DST_TYPE_IS_SAT: 519 case DST_TYPE_IS_SAT:
476 otype = "satellite"; 520 otype = "satellite";
477 break; 521 break;
522
478 case DST_TYPE_IS_TERR: 523 case DST_TYPE_IS_TERR:
479 otype = "terrestrial"; 524 otype = "terrestrial";
480 break; 525 break;
526
481 case DST_TYPE_IS_CABLE: 527 case DST_TYPE_IS_CABLE:
482 otype = "cable"; 528 otype = "cable";
483 break; 529 break;
530
484 default: 531 default:
485 printk("%s: invalid dst type %d\n", __FUNCTION__, type); 532 printk("%s: invalid dst type %d\n", __FUNCTION__, type);
486 return -EINVAL; 533 return -EINVAL;
487 } 534 }
488 printk("DST type : %s\n", otype); 535 printk("DST type : %s\n", otype);
536
489 return 0; 537 return 0;
490} 538}
491 539
492static int dst_check_ci(struct dst_state *state) 540/*
541 Known cards list
542 Satellite
543 -------------------
544 200103A
545 VP-1020 DST-MOT LG(old), TS=188
546
547 VP-1020 DST-03T LG(new), TS=204
548 VP-1022 DST-03T LG(new), TS=204
549 VP-1025 DST-03T LG(new), TS=204
550
551 VP-1030 DSTMCI, LG(new), TS=188
552 VP-1032 DSTMCI, LG(new), TS=188
553
554 Cable
555 -------------------
556 VP-2030 DCT-CI, Samsung, TS=204
557 VP-2021 DCT-CI, Unknown, TS=204
558 VP-2031 DCT-CI, Philips, TS=188
559 VP-2040 DCT-CI, Philips, TS=188, with CA daughter board
560 VP-2040 DCT-CI, Philips, TS=204, without CA daughter board
561
562 Terrestrial
563 -------------------
564 VP-3050 DTTNXT TS=188
565 VP-3040 DTT-CI, Philips, TS=188
566 VP-3040 DTT-CI, Philips, TS=204
567
568 ATSC
569 -------------------
570 VP-3220 ATSCDI, TS=188
571 VP-3250 ATSCAD, TS=188
572
573*/
574
575struct dst_types dst_tlist[] = {
576 {
577 .device_id = "200103A",
578 .offset = 0,
579 .dst_type = DST_TYPE_IS_SAT,
580 .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1,
581 .dst_feature = 0
582 }, /* obsolete */
583
584 {
585 .device_id = "DST-020",
586 .offset = 0,
587 .dst_type = DST_TYPE_IS_SAT,
588 .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1,
589 .dst_feature = 0
590 }, /* obsolete */
591
592 {
593 .device_id = "DST-030",
594 .offset = 0,
595 .dst_type = DST_TYPE_IS_SAT,
596 .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_1,
597 .dst_feature = 0
598 }, /* obsolete */
599
600 {
601 .device_id = "DST-03T",
602 .offset = 0,
603 .dst_type = DST_TYPE_IS_SAT,
604 .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_2,
605 .dst_feature = DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4 | DST_TYPE_HAS_DISEQC5
606 | DST_TYPE_HAS_MAC | DST_TYPE_HAS_MOTO
607 },
608
609 {
610 .device_id = "DST-MOT",
611 .offset = 0,
612 .dst_type = DST_TYPE_IS_SAT,
613 .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1,
614 .dst_feature = 0
615 }, /* obsolete */
616
617 {
618 .device_id = "DST-CI",
619 .offset = 1,
620 .dst_type = DST_TYPE_IS_SAT,
621 .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_1,
622 .dst_feature = DST_TYPE_HAS_CA
623 }, /* An OEM board */
624
625 {
626 .device_id = "DSTMCI",
627 .offset = 1,
628 .dst_type = DST_TYPE_IS_SAT,
629 .type_flags = DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD,
630 .dst_feature = DST_TYPE_HAS_CA | DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4
631 | DST_TYPE_HAS_MOTO | DST_TYPE_HAS_MAC
632 },
633
634 {
635 .device_id = "DSTFCI",
636 .offset = 1,
637 .dst_type = DST_TYPE_IS_SAT,
638 .type_flags = DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_1,
639 .dst_feature = 0
640 }, /* unknown to vendor */
641
642 {
643 .device_id = "DCT-CI",
644 .offset = 1,
645 .dst_type = DST_TYPE_IS_CABLE,
646 .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_1
647 | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD,
648 .dst_feature = DST_TYPE_HAS_CA
649 },
650
651 {
652 .device_id = "DCTNEW",
653 .offset = 1,
654 .dst_type = DST_TYPE_IS_CABLE,
655 .type_flags = DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_3,
656 .dst_feature = 0
657 },
658
659 {
660 .device_id = "DTT-CI",
661 .offset = 1,
662 .dst_type = DST_TYPE_IS_TERR,
663 .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD,
664 .dst_feature = 0
665 },
666
667 {
668 .device_id = "DTTDIG",
669 .offset = 1,
670 .dst_type = DST_TYPE_IS_TERR,
671 .type_flags = DST_TYPE_HAS_FW_2,
672 .dst_feature = 0
673 },
674
675 {
676 .device_id = "DTTNXT",
677 .offset = 1,
678 .dst_type = DST_TYPE_IS_TERR,
679 .type_flags = DST_TYPE_HAS_FW_2,
680 .dst_feature = DST_TYPE_HAS_ANALOG
681 },
682
683 {
684 .device_id = "ATSCDI",
685 .offset = 1,
686 .dst_type = DST_TYPE_IS_ATSC,
687 .type_flags = DST_TYPE_HAS_FW_2,
688 .dst_feature = 0
689 },
690
691 {
692 .device_id = "ATSCAD",
693 .offset = 1,
694 .dst_type = DST_TYPE_IS_ATSC,
695 .type_flags = DST_TYPE_HAS_FW_2,
696 .dst_feature = 0
697 },
698
699 { }
700
701};
702
703
704static int dst_get_device_id(struct dst_state *state)
493{ 705{
494 u8 txbuf[8]; 706 u8 reply;
495 u8 rxbuf[8]; 707
496 int retval;
497 int i; 708 int i;
498 struct dst_types *dsp; 709 struct dst_types *p_dst_type;
499 u8 use_dst_type; 710 u8 use_dst_type = 0;
500 u32 use_type_flags; 711 u32 use_type_flags = 0;
501 712
502 memset(txbuf, 0, sizeof(txbuf)); 713 static u8 device_type[8] = {0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff};
503 txbuf[1] = 6;
504 txbuf[7] = dst_check_sum(txbuf, 7);
505 714
506 dst_i2c_enable(state); 715 device_type[7] = dst_check_sum(device_type, 7);
507 dst_reset8820(state); 716
508 retval = write_dst(state, txbuf, 8); 717 if (write_dst(state, device_type, FIXED_COMM))
509 if (retval < 0) { 718 return -1; /* Write failed */
510 dst_i2c_disable(state); 719
511 dprintk("%s: write not successful, maybe no card?\n", __FUNCTION__); 720 if ((dst_pio_disable(state)) < 0)
512 return retval; 721 return -1;
513 } 722
514 msleep(3); 723 if (read_dst(state, &reply, GET_ACK))
515 retval = read_dst(state, rxbuf, 1); 724 return -1; /* Read failure */
516 dst_i2c_disable(state); 725
517 if (retval < 0) { 726 if (reply != ACK) {
518 dprintk("%s: read not successful, maybe no card?\n", __FUNCTION__); 727 dprintk("%s: Write not Acknowledged! [Reply=0x%02x]\n", __FUNCTION__, reply);
519 return retval; 728 return -1; /* Unack'd write */
520 }
521 if (rxbuf[0] != 0xff) {
522 dprintk("%s: write reply not 0xff, not ci (%02x)\n", __FUNCTION__, rxbuf[0]);
523 return retval;
524 }
525 if (!dst_wait_dst_ready(state))
526 return 0;
527 // dst_i2c_enable(i2c); Dimitri
528 retval = read_dst(state, rxbuf, 8);
529 dst_i2c_disable(state);
530 if (retval < 0) {
531 dprintk("%s: read not successful\n", __FUNCTION__);
532 return retval;
533 } 729 }
534 if (rxbuf[7] != dst_check_sum(rxbuf, 7)) { 730
535 dprintk("%s: checksum failure\n", __FUNCTION__); 731 if (!dst_wait_dst_ready(state, DEVICE_INIT))
536 return retval; 732 return -1; /* DST not ready yet */
733
734 if (read_dst(state, state->rxbuffer, FIXED_COMM))
735 return -1;
736
737 dst_pio_disable(state);
738
739 if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) {
740 dprintk("%s: Checksum failure! \n", __FUNCTION__);
741 return -1; /* Checksum failure */
537 } 742 }
538 rxbuf[7] = '\0'; 743
539 for (i = 0, dsp = &dst_tlist[0]; i < sizeof(dst_tlist) / sizeof(dst_tlist[0]); i++, dsp++) { 744 state->rxbuffer[7] = '\0';
540 if (!strncmp(&rxbuf[dsp->offs], dsp->mstr, strlen(dsp->mstr))) { 745
541 use_type_flags = dsp->type_flags; 746 for (i = 0, p_dst_type = dst_tlist; i < ARRAY_SIZE (dst_tlist); i++, p_dst_type++) {
542 use_dst_type = dsp->dst_type; 747 if (!strncmp (&state->rxbuffer[p_dst_type->offset], p_dst_type->device_id, strlen (p_dst_type->device_id))) {
543 printk("%s: recognize %s\n", __FUNCTION__, dsp->mstr); 748 use_type_flags = p_dst_type->type_flags;
749 use_dst_type = p_dst_type->dst_type;
750
751 /* Card capabilities */
752 state->dst_hw_cap = p_dst_type->dst_feature;
753 printk ("%s: Recognise [%s]\n", __FUNCTION__, p_dst_type->device_id);
754
544 break; 755 break;
545 } 756 }
546 } 757 }
547 if (i >= sizeof(dst_tlist) / sizeof(dst_tlist[0])) { 758
548 printk("%s: unable to recognize %s or %s\n", __FUNCTION__, &rxbuf[0], &rxbuf[1]); 759 if (i >= sizeof (dst_tlist) / sizeof (dst_tlist [0])) {
549 printk("%s please email linux-dvb@linuxtv.org with this type in\n", __FUNCTION__); 760 printk("%s: Unable to recognize %s or %s\n", __FUNCTION__, &state->rxbuffer[0], &state->rxbuffer[1]);
761 printk("%s: please email linux-dvb@linuxtv.org with this type in\n", __FUNCTION__);
550 use_dst_type = DST_TYPE_IS_SAT; 762 use_dst_type = DST_TYPE_IS_SAT;
551 use_type_flags = DST_TYPE_HAS_SYMDIV; 763 use_type_flags = DST_TYPE_HAS_SYMDIV;
552 } 764 }
553 dst_type_print(use_dst_type);
554 765
766 dst_type_print(use_dst_type);
555 state->type_flags = use_type_flags; 767 state->type_flags = use_type_flags;
556 state->dst_type = use_dst_type; 768 state->dst_type = use_dst_type;
557 dst_type_flags_print(state->type_flags); 769 dst_type_flags_print(state->type_flags);
@@ -559,50 +771,102 @@ static int dst_check_ci(struct dst_state *state)
559 if (state->type_flags & DST_TYPE_HAS_TS204) { 771 if (state->type_flags & DST_TYPE_HAS_TS204) {
560 dst_packsize(state, 204); 772 dst_packsize(state, 204);
561 } 773 }
774
562 return 0; 775 return 0;
563} 776}
564 777
565static int dst_command(struct dst_state* state, u8 * data, u8 len) 778static int dst_probe(struct dst_state *state)
779{
780 if ((rdc_8820_reset(state)) < 0) {
781 dprintk("%s: RDC 8820 RESET Failed.\n", __FUNCTION__);
782 return -1;
783 }
784 if (dst_addons & DST_TYPE_HAS_CA)
785 msleep(4000);
786 else
787 msleep(100);
788
789 if ((dst_comm_init(state)) < 0) {
790 dprintk("%s: DST Initialization Failed.\n", __FUNCTION__);
791 return -1;
792 }
793 msleep(100);
794 if (dst_get_device_id(state) < 0) {
795 dprintk("%s: unknown device.\n", __FUNCTION__);
796 return -1;
797 }
798
799 return 0;
800}
801
802int dst_command(struct dst_state* state, u8 * data, u8 len)
566{ 803{
567 int retval;
568 u8 reply; 804 u8 reply;
805 if ((dst_comm_init(state)) < 0) {
806 dprintk("%s: DST Communication Initialization Failed.\n", __FUNCTION__);
807 return -1;
808 }
569 809
570 dst_i2c_enable(state); 810 if (write_dst(state, data, len)) {
571 dst_reset8820(state); 811 if (verbose > 1)
572 retval = write_dst(state, data, len); 812 dprintk("%s: Tring to recover.. \n", __FUNCTION__);
573 if (retval < 0) { 813 if ((dst_error_recovery(state)) < 0) {
574 dst_i2c_disable(state); 814 dprintk("%s: Recovery Failed.\n", __FUNCTION__);
575 dprintk("%s: write not successful\n", __FUNCTION__); 815 return -1;
576 return retval; 816 }
817 return -1;
577 } 818 }
578 msleep(33); 819 if ((dst_pio_disable(state)) < 0) {
579 retval = read_dst(state, &reply, 1); 820 dprintk("%s: PIO Disable Failed.\n", __FUNCTION__);
580 dst_i2c_disable(state); 821 return -1;
581 if (retval < 0) {
582 dprintk("%s: read verify not successful\n", __FUNCTION__);
583 return retval;
584 } 822 }
585 if (reply != 0xff) { 823 if (state->type_flags & DST_TYPE_HAS_FW_1)
586 dprintk("%s: write reply not 0xff 0x%02x \n", __FUNCTION__, reply); 824 udelay(3000);
587 return 0; 825
826 if (read_dst(state, &reply, GET_ACK)) {
827 if (verbose > 1)
828 dprintk("%s: Trying to recover.. \n", __FUNCTION__);
829 if ((dst_error_recovery(state)) < 0) {
830 dprintk("%s: Recovery Failed.\n", __FUNCTION__);
831 return -1;
832 }
833 return -1;
834 }
835
836 if (reply != ACK) {
837 dprintk("%s: write not acknowledged 0x%02x \n", __FUNCTION__, reply);
838 return -1;
588 } 839 }
589 if (len >= 2 && data[0] == 0 && (data[1] == 1 || data[1] == 3)) 840 if (len >= 2 && data[0] == 0 && (data[1] == 1 || data[1] == 3))
590 return 0; 841 return 0;
591 if (!dst_wait_dst_ready(state)) 842
592 return 0; 843// udelay(3000);
593 // dst_i2c_enable(i2c); Per dimitri 844 if (state->type_flags & DST_TYPE_HAS_FW_1)
594 retval = read_dst(state, state->rxbuffer, 8); 845 udelay(3000);
595 dst_i2c_disable(state); 846 else
596 if (retval < 0) { 847 udelay(2000);
597 dprintk("%s: read not successful\n", __FUNCTION__); 848
598 return 0; 849 if (!dst_wait_dst_ready(state, NO_DELAY))
850 return -1;
851
852 if (read_dst(state, state->rxbuffer, FIXED_COMM)) {
853 if (verbose > 1)
854 dprintk("%s: Trying to recover.. \n", __FUNCTION__);
855 if ((dst_error_recovery(state)) < 0) {
856 dprintk("%s: Recovery failed.\n", __FUNCTION__);
857 return -1;
858 }
859 return -1;
599 } 860 }
861
600 if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) { 862 if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) {
601 dprintk("%s: checksum failure\n", __FUNCTION__); 863 dprintk("%s: checksum failure\n", __FUNCTION__);
602 return 0; 864 return -1;
603 } 865 }
866
604 return 0; 867 return 0;
605} 868}
869EXPORT_SYMBOL(dst_command);
606 870
607static int dst_get_signal(struct dst_state* state) 871static int dst_get_signal(struct dst_state* state)
608{ 872{
@@ -646,11 +910,17 @@ static int dst_tone_power_cmd(struct dst_state* state)
646 paket[4] = 0; 910 paket[4] = 0;
647 else 911 else
648 paket[4] = 1; 912 paket[4] = 1;
913
649 if (state->tone == SEC_TONE_ON) 914 if (state->tone == SEC_TONE_ON)
650 paket[2] = state->k22; 915 paket[2] = 0x02;
651 else 916 else
652 paket[2] = 0; 917 paket[2] = 0;
653 paket[7] = dst_check_sum(&paket[0], 7); 918 if (state->minicmd == SEC_MINI_A)
919 paket[3] = 0x02;
920 else
921 paket[3] = 0;
922
923 paket[7] = dst_check_sum (paket, 7);
654 dst_command(state, paket, 8); 924 dst_command(state, paket, 8);
655 return 0; 925 return 0;
656} 926}
@@ -658,21 +928,26 @@ static int dst_tone_power_cmd(struct dst_state* state)
658static int dst_get_tuna(struct dst_state* state) 928static int dst_get_tuna(struct dst_state* state)
659{ 929{
660 int retval; 930 int retval;
931
661 if ((state->diseq_flags & ATTEMPT_TUNE) == 0) 932 if ((state->diseq_flags & ATTEMPT_TUNE) == 0)
662 return 0; 933 return 0;
934
663 state->diseq_flags &= ~(HAS_LOCK); 935 state->diseq_flags &= ~(HAS_LOCK);
664 if (!dst_wait_dst_ready(state)) 936 if (!dst_wait_dst_ready(state, NO_DELAY))
665 return 0; 937 return 0;
938
666 if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { 939 if (state->type_flags & DST_TYPE_HAS_NEWTUNE) {
667 /* how to get variable length reply ???? */ 940 /* how to get variable length reply ???? */
668 retval = read_dst(state, state->rx_tuna, 10); 941 retval = read_dst(state, state->rx_tuna, 10);
669 } else { 942 } else {
670 retval = read_dst(state, &state->rx_tuna[2], 8); 943 retval = read_dst(state, &state->rx_tuna[2], FIXED_COMM);
671 } 944 }
945
672 if (retval < 0) { 946 if (retval < 0) {
673 dprintk("%s: read not successful\n", __FUNCTION__); 947 dprintk("%s: read not successful\n", __FUNCTION__);
674 return 0; 948 return 0;
675 } 949 }
950
676 if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { 951 if (state->type_flags & DST_TYPE_HAS_NEWTUNE) {
677 if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) { 952 if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) {
678 dprintk("%s: checksum failure?\n", __FUNCTION__); 953 dprintk("%s: checksum failure?\n", __FUNCTION__);
@@ -709,7 +984,9 @@ static int dst_write_tuna(struct dvb_frontend* fe)
709 int retval; 984 int retval;
710 u8 reply; 985 u8 reply;
711 986
712 dprintk("%s: type_flags 0x%x \n", __FUNCTION__, state->type_flags); 987 if (debug > 4)
988 dprintk("%s: type_flags 0x%x \n", __FUNCTION__, state->type_flags);
989
713 state->decode_freq = 0; 990 state->decode_freq = 0;
714 state->decode_lock = state->decode_strength = state->decode_snr = 0; 991 state->decode_lock = state->decode_strength = state->decode_snr = 0;
715 if (state->dst_type == DST_TYPE_IS_SAT) { 992 if (state->dst_type == DST_TYPE_IS_SAT) {
@@ -717,32 +994,41 @@ static int dst_write_tuna(struct dvb_frontend* fe)
717 dst_set_voltage(fe, SEC_VOLTAGE_13); 994 dst_set_voltage(fe, SEC_VOLTAGE_13);
718 } 995 }
719 state->diseq_flags &= ~(HAS_LOCK | ATTEMPT_TUNE); 996 state->diseq_flags &= ~(HAS_LOCK | ATTEMPT_TUNE);
720 dst_i2c_enable(state); 997
998 if ((dst_comm_init(state)) < 0) {
999 dprintk("%s: DST Communication initialization failed.\n", __FUNCTION__);
1000 return -1;
1001 }
1002
721 if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { 1003 if (state->type_flags & DST_TYPE_HAS_NEWTUNE) {
722 dst_reset8820(state);
723 state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[0], 9); 1004 state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[0], 9);
724 retval = write_dst(state, &state->tx_tuna[0], 10); 1005 retval = write_dst(state, &state->tx_tuna[0], 10);
1006
725 } else { 1007 } else {
726 state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[2], 7); 1008 state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[2], 7);
727 retval = write_dst(state, &state->tx_tuna[2], 8); 1009 retval = write_dst(state, &state->tx_tuna[2], FIXED_COMM);
728 } 1010 }
729 if (retval < 0) { 1011 if (retval < 0) {
730 dst_i2c_disable(state); 1012 dst_pio_disable(state);
731 dprintk("%s: write not successful\n", __FUNCTION__); 1013 dprintk("%s: write not successful\n", __FUNCTION__);
732 return retval; 1014 return retval;
733 } 1015 }
734 msleep(3); 1016
735 retval = read_dst(state, &reply, 1); 1017 if ((dst_pio_disable(state)) < 0) {
736 dst_i2c_disable(state); 1018 dprintk("%s: DST PIO disable failed !\n", __FUNCTION__);
737 if (retval < 0) { 1019 return -1;
738 dprintk("%s: read verify not successful\n", __FUNCTION__); 1020 }
739 return retval; 1021
1022 if ((read_dst(state, &reply, GET_ACK) < 0)) {
1023 dprintk("%s: read verify not successful.\n", __FUNCTION__);
1024 return -1;
740 } 1025 }
741 if (reply != 0xff) { 1026 if (reply != ACK) {
742 dprintk("%s: write reply not 0xff 0x%02x \n", __FUNCTION__, reply); 1027 dprintk("%s: write not acknowledged 0x%02x \n", __FUNCTION__, reply);
743 return 0; 1028 return 0;
744 } 1029 }
745 state->diseq_flags |= ATTEMPT_TUNE; 1030 state->diseq_flags |= ATTEMPT_TUNE;
1031
746 return dst_get_tuna(state); 1032 return dst_get_tuna(state);
747} 1033}
748 1034
@@ -796,22 +1082,25 @@ static int dst_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
796 need_cmd = 1; 1082 need_cmd = 1;
797 state->diseq_flags |= HAS_POWER; 1083 state->diseq_flags |= HAS_POWER;
798 break; 1084 break;
1085
799 case SEC_VOLTAGE_18: 1086 case SEC_VOLTAGE_18:
800 if ((state->diseq_flags & HAS_POWER) == 0) 1087 if ((state->diseq_flags & HAS_POWER) == 0)
801 need_cmd = 1; 1088 need_cmd = 1;
802 state->diseq_flags |= HAS_POWER; 1089 state->diseq_flags |= HAS_POWER;
803 val[8] |= 0x40; 1090 val[8] |= 0x40;
804 break; 1091 break;
1092
805 case SEC_VOLTAGE_OFF: 1093 case SEC_VOLTAGE_OFF:
806 need_cmd = 1; 1094 need_cmd = 1;
807 state->diseq_flags &= ~(HAS_POWER | HAS_LOCK | ATTEMPT_TUNE); 1095 state->diseq_flags &= ~(HAS_POWER | HAS_LOCK | ATTEMPT_TUNE);
808 break; 1096 break;
1097
809 default: 1098 default:
810 return -EINVAL; 1099 return -EINVAL;
811 } 1100 }
812 if (need_cmd) { 1101 if (need_cmd)
813 dst_tone_power_cmd(state); 1102 dst_tone_power_cmd(state);
814 } 1103
815 return 0; 1104 return 0;
816} 1105}
817 1106
@@ -832,13 +1121,16 @@ static int dst_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
832 switch (tone) { 1121 switch (tone) {
833 case SEC_TONE_OFF: 1122 case SEC_TONE_OFF:
834 break; 1123 break;
1124
835 case SEC_TONE_ON: 1125 case SEC_TONE_ON:
836 val[8] |= 1; 1126 val[8] |= 1;
837 break; 1127 break;
1128
838 default: 1129 default:
839 return -EINVAL; 1130 return -EINVAL;
840 } 1131 }
841 dst_tone_power_cmd(state); 1132 dst_tone_power_cmd(state);
1133
842 return 0; 1134 return 0;
843} 1135}
844 1136
@@ -913,10 +1205,16 @@ static int dst_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_paramet
913 struct dst_state* state = (struct dst_state*) fe->demodulator_priv; 1205 struct dst_state* state = (struct dst_state*) fe->demodulator_priv;
914 1206
915 dst_set_freq(state, p->frequency); 1207 dst_set_freq(state, p->frequency);
1208 if (verbose > 4)
1209 dprintk("Set Frequency = [%d]\n", p->frequency);
1210
916 dst_set_inversion(state, p->inversion); 1211 dst_set_inversion(state, p->inversion);
917 if (state->dst_type == DST_TYPE_IS_SAT) { 1212 if (state->dst_type == DST_TYPE_IS_SAT) {
918 dst_set_fec(state, p->u.qpsk.fec_inner); 1213 dst_set_fec(state, p->u.qpsk.fec_inner);
919 dst_set_symbolrate(state, p->u.qpsk.symbol_rate); 1214 dst_set_symbolrate(state, p->u.qpsk.symbol_rate);
1215 if (verbose > 4)
1216 dprintk("Set Symbolrate = [%d]\n", p->u.qpsk.symbol_rate);
1217
920 } else if (state->dst_type == DST_TYPE_IS_TERR) { 1218 } else if (state->dst_type == DST_TYPE_IS_TERR) {
921 dst_set_bandwidth(state, p->u.ofdm.bandwidth); 1219 dst_set_bandwidth(state, p->u.ofdm.bandwidth);
922 } else if (state->dst_type == DST_TYPE_IS_CABLE) { 1220 } else if (state->dst_type == DST_TYPE_IS_CABLE) {
@@ -958,50 +1256,47 @@ static struct dvb_frontend_ops dst_dvbt_ops;
958static struct dvb_frontend_ops dst_dvbs_ops; 1256static struct dvb_frontend_ops dst_dvbs_ops;
959static struct dvb_frontend_ops dst_dvbc_ops; 1257static struct dvb_frontend_ops dst_dvbc_ops;
960 1258
961struct dvb_frontend* dst_attach(const struct dst_config* config, 1259struct dst_state* dst_attach(struct dst_state *state, struct dvb_adapter *dvb_adapter)
962 struct i2c_adapter* i2c,
963 struct bt878 *bt)
964{ 1260{
965 struct dst_state* state = NULL;
966
967 /* allocate memory for the internal state */
968 state = (struct dst_state*) kmalloc(sizeof(struct dst_state), GFP_KERNEL);
969 if (state == NULL) goto error;
970 1261
971 /* setup the state */ 1262 /* check if the ASIC is there */
972 state->config = config; 1263 if (dst_probe(state) < 0) {
973 state->i2c = i2c; 1264 if (state)
974 state->bt = bt; 1265 kfree(state);
975
976 /* check if the demod is there */
977 if (dst_check_ci(state) < 0) goto error;
978 1266
1267 return NULL;
1268 }
979 /* determine settings based on type */ 1269 /* determine settings based on type */
980 switch (state->dst_type) { 1270 switch (state->dst_type) {
981 case DST_TYPE_IS_TERR: 1271 case DST_TYPE_IS_TERR:
982 memcpy(&state->ops, &dst_dvbt_ops, sizeof(struct dvb_frontend_ops)); 1272 memcpy(&state->ops, &dst_dvbt_ops, sizeof(struct dvb_frontend_ops));
983 break; 1273 break;
1274
984 case DST_TYPE_IS_CABLE: 1275 case DST_TYPE_IS_CABLE:
985 memcpy(&state->ops, &dst_dvbc_ops, sizeof(struct dvb_frontend_ops)); 1276 memcpy(&state->ops, &dst_dvbc_ops, sizeof(struct dvb_frontend_ops));
986 break; 1277 break;
1278
987 case DST_TYPE_IS_SAT: 1279 case DST_TYPE_IS_SAT:
988 memcpy(&state->ops, &dst_dvbs_ops, sizeof(struct dvb_frontend_ops)); 1280 memcpy(&state->ops, &dst_dvbs_ops, sizeof(struct dvb_frontend_ops));
989 break; 1281 break;
1282
990 default: 1283 default:
991 printk("dst: unknown frontend type. please report to the LinuxTV.org DVB mailinglist.\n"); 1284 printk("%s: unknown DST type. please report to the LinuxTV.org DVB mailinglist.\n", __FUNCTION__);
992 goto error; 1285 if (state)
1286 kfree(state);
1287
1288 return NULL;
993 } 1289 }
994 1290
995 /* create dvb_frontend */ 1291 /* create dvb_frontend */
996 state->frontend.ops = &state->ops; 1292 state->frontend.ops = &state->ops;
997 state->frontend.demodulator_priv = state; 1293 state->frontend.demodulator_priv = state;
998 return &state->frontend;
999 1294
1000error: 1295 return state; /* Manu (DST is a card not a frontend) */
1001 kfree(state);
1002 return NULL;
1003} 1296}
1004 1297
1298EXPORT_SYMBOL(dst_attach);
1299
1005static struct dvb_frontend_ops dst_dvbt_ops = { 1300static struct dvb_frontend_ops dst_dvbt_ops = {
1006 1301
1007 .info = { 1302 .info = {
@@ -1051,6 +1346,7 @@ static struct dvb_frontend_ops dst_dvbs_ops = {
1051 .read_signal_strength = dst_read_signal_strength, 1346 .read_signal_strength = dst_read_signal_strength,
1052 .read_snr = dst_read_snr, 1347 .read_snr = dst_read_snr,
1053 1348
1349 .diseqc_send_burst = dst_set_tone,
1054 .diseqc_send_master_cmd = dst_set_diseqc, 1350 .diseqc_send_master_cmd = dst_set_diseqc,
1055 .set_voltage = dst_set_voltage, 1351 .set_voltage = dst_set_voltage,
1056 .set_tone = dst_set_tone, 1352 .set_tone = dst_set_tone,
@@ -1082,8 +1378,7 @@ static struct dvb_frontend_ops dst_dvbc_ops = {
1082 .read_snr = dst_read_snr, 1378 .read_snr = dst_read_snr,
1083}; 1379};
1084 1380
1381
1085MODULE_DESCRIPTION("DST DVB-S/T/C Combo Frontend driver"); 1382MODULE_DESCRIPTION("DST DVB-S/T/C Combo Frontend driver");
1086MODULE_AUTHOR("Jamie Honan"); 1383MODULE_AUTHOR("Jamie Honan, Manu Abraham");
1087MODULE_LICENSE("GPL"); 1384MODULE_LICENSE("GPL");
1088
1089EXPORT_SYMBOL(dst_attach);
diff --git a/drivers/media/dvb/bt8xx/dst.h b/drivers/media/dvb/bt8xx/dst.h
deleted file mode 100644
index bcb418c5c121..000000000000
--- a/drivers/media/dvb/bt8xx/dst.h
+++ /dev/null
@@ -1,40 +0,0 @@
1/*
2 Frontend-driver for TwinHan DST Frontend
3
4 Copyright (C) 2003 Jamie Honan
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21*/
22
23#ifndef DST_H
24#define DST_H
25
26#include <linux/dvb/frontend.h>
27#include <linux/device.h>
28#include "bt878.h"
29
30struct dst_config
31{
32 /* the demodulator's i2c address */
33 u8 demod_address;
34};
35
36extern struct dvb_frontend* dst_attach(const struct dst_config* config,
37 struct i2c_adapter* i2c,
38 struct bt878 *bt);
39
40#endif // DST_H
diff --git a/drivers/media/dvb/bt8xx/dst_ca.c b/drivers/media/dvb/bt8xx/dst_ca.c
new file mode 100644
index 000000000000..d781504cc2fa
--- /dev/null
+++ b/drivers/media/dvb/bt8xx/dst_ca.c
@@ -0,0 +1,861 @@
1/*
2 CA-driver for TwinHan DST Frontend/Card
3
4 Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com)
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20
21
22
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <linux/init.h>
26#include <linux/string.h>
27
28#include <linux/dvb/ca.h>
29#include "dvbdev.h"
30#include "dvb_frontend.h"
31
32#include "dst_ca.h"
33#include "dst_common.h"
34
35static unsigned int verbose = 1;
36module_param(verbose, int, 0644);
37MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)");
38
39static unsigned int debug = 1;
40module_param(debug, int, 0644);
41MODULE_PARM_DESC(debug, "debug messages, default is 1 (yes)");
42
43#define dprintk if (debug) printk
44
45/* Need some more work */
46static int ca_set_slot_descr(void)
47{
48 /* We could make this more graceful ? */
49 return -EOPNOTSUPP;
50}
51
52/* Need some more work */
53static int ca_set_pid(void)
54{
55 /* We could make this more graceful ? */
56 return -EOPNOTSUPP;
57}
58
59
60static int put_checksum(u8 *check_string, int length)
61{
62 u8 i = 0, checksum = 0;
63
64 if (verbose > 3) {
65 dprintk("%s: ========================= Checksum calculation ===========================\n", __FUNCTION__);
66 dprintk("%s: String Length=[0x%02x]\n", __FUNCTION__, length);
67
68 dprintk("%s: String=[", __FUNCTION__);
69 }
70 while (i < length) {
71 if (verbose > 3)
72 dprintk(" %02x", check_string[i]);
73 checksum += check_string[i];
74 i++;
75 }
76 if (verbose > 3) {
77 dprintk(" ]\n");
78 dprintk("%s: Sum=[%02x]\n", __FUNCTION__, checksum);
79 }
80 check_string[length] = ~checksum + 1;
81 if (verbose > 3) {
82 dprintk("%s: Checksum=[%02x]\n", __FUNCTION__, check_string[length]);
83 dprintk("%s: ==========================================================================\n", __FUNCTION__);
84 }
85
86 return 0;
87}
88
89static int dst_ci_command(struct dst_state* state, u8 * data, u8 *ca_string, u8 len, int read)
90{
91 u8 reply;
92
93 dst_comm_init(state);
94 msleep(65);
95
96 if (write_dst(state, data, len)) {
97 dprintk("%s: Write not successful, trying to recover\n", __FUNCTION__);
98 dst_error_recovery(state);
99 return -1;
100 }
101
102 if ((dst_pio_disable(state)) < 0) {
103 dprintk("%s: DST PIO disable failed.\n", __FUNCTION__);
104 return -1;
105 }
106
107 if (read_dst(state, &reply, GET_ACK) < 0) {
108 dprintk("%s: Read not successful, trying to recover\n", __FUNCTION__);
109 dst_error_recovery(state);
110 return -1;
111 }
112
113 if (read) {
114 if (! dst_wait_dst_ready(state, LONG_DELAY)) {
115 dprintk("%s: 8820 not ready\n", __FUNCTION__);
116 return -1;
117 }
118
119 if (read_dst(state, ca_string, 128) < 0) { /* Try to make this dynamic */
120 dprintk("%s: Read not successful, trying to recover\n", __FUNCTION__);
121 dst_error_recovery(state);
122 return -1;
123 }
124 }
125
126 return 0;
127}
128
129
130static int dst_put_ci(struct dst_state *state, u8 *data, int len, u8 *ca_string, int read)
131{
132 u8 dst_ca_comm_err = 0;
133
134 while (dst_ca_comm_err < RETRIES) {
135 dst_comm_init(state);
136 if (verbose > 2)
137 dprintk("%s: Put Command\n", __FUNCTION__);
138 if (dst_ci_command(state, data, ca_string, len, read)) { // If error
139 dst_error_recovery(state);
140 dst_ca_comm_err++; // work required here.
141 }
142 break;
143 }
144
145 return 0;
146}
147
148
149
150static int ca_get_app_info(struct dst_state *state)
151{
152 static u8 command[8] = {0x07, 0x40, 0x01, 0x00, 0x01, 0x00, 0x00, 0xff};
153
154 put_checksum(&command[0], command[0]);
155 if ((dst_put_ci(state, command, sizeof(command), state->messages, GET_REPLY)) < 0) {
156 dprintk("%s: -->dst_put_ci FAILED !\n", __FUNCTION__);
157 return -1;
158 }
159 if (verbose > 1) {
160 dprintk("%s: -->dst_put_ci SUCCESS !\n", __FUNCTION__);
161
162 dprintk("%s: ================================ CI Module Application Info ======================================\n", __FUNCTION__);
163 dprintk("%s: Application Type=[%d], Application Vendor=[%d], Vendor Code=[%d]\n%s: Application info=[%s]\n",
164 __FUNCTION__, state->messages[7], (state->messages[8] << 8) | state->messages[9],
165 (state->messages[10] << 8) | state->messages[11], __FUNCTION__, (char *)(&state->messages[12]));
166 dprintk("%s: ==================================================================================================\n", __FUNCTION__);
167 }
168
169 return 0;
170}
171
172static int ca_get_slot_caps(struct dst_state *state, struct ca_caps *p_ca_caps, void *arg)
173{
174 int i;
175 u8 slot_cap[256];
176 static u8 slot_command[8] = {0x07, 0x40, 0x02, 0x00, 0x02, 0x00, 0x00, 0xff};
177
178 put_checksum(&slot_command[0], slot_command[0]);
179 if ((dst_put_ci(state, slot_command, sizeof (slot_command), slot_cap, GET_REPLY)) < 0) {
180 dprintk("%s: -->dst_put_ci FAILED !\n", __FUNCTION__);
181 return -1;
182 }
183 if (verbose > 1)
184 dprintk("%s: -->dst_put_ci SUCCESS !\n", __FUNCTION__);
185
186 /* Will implement the rest soon */
187
188 if (verbose > 1) {
189 dprintk("%s: Slot cap = [%d]\n", __FUNCTION__, slot_cap[7]);
190 dprintk("===================================\n");
191 for (i = 0; i < 8; i++)
192 dprintk(" %d", slot_cap[i]);
193 dprintk("\n");
194 }
195
196 p_ca_caps->slot_num = 1;
197 p_ca_caps->slot_type = 1;
198 p_ca_caps->descr_num = slot_cap[7];
199 p_ca_caps->descr_type = 1;
200
201
202 if (copy_to_user((struct ca_caps *)arg, p_ca_caps, sizeof (struct ca_caps))) {
203 return -EFAULT;
204 }
205
206 return 0;
207}
208
209/* Need some more work */
210static int ca_get_slot_descr(struct dst_state *state, struct ca_msg *p_ca_message, void *arg)
211{
212 return -EOPNOTSUPP;
213}
214
215
216static int ca_get_slot_info(struct dst_state *state, struct ca_slot_info *p_ca_slot_info, void *arg)
217{
218 int i;
219 static u8 slot_command[8] = {0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff};
220
221 u8 *slot_info = state->rxbuffer;
222
223 put_checksum(&slot_command[0], 7);
224 if ((dst_put_ci(state, slot_command, sizeof (slot_command), slot_info, GET_REPLY)) < 0) {
225 dprintk("%s: -->dst_put_ci FAILED !\n", __FUNCTION__);
226 return -1;
227 }
228 if (verbose > 1)
229 dprintk("%s: -->dst_put_ci SUCCESS !\n", __FUNCTION__);
230
231 /* Will implement the rest soon */
232
233 if (verbose > 1) {
234 dprintk("%s: Slot info = [%d]\n", __FUNCTION__, slot_info[3]);
235 dprintk("===================================\n");
236 for (i = 0; i < 8; i++)
237 dprintk(" %d", slot_info[i]);
238 dprintk("\n");
239 }
240
241 if (slot_info[4] & 0x80) {
242 p_ca_slot_info->flags = CA_CI_MODULE_PRESENT;
243 p_ca_slot_info->num = 1;
244 p_ca_slot_info->type = CA_CI;
245 }
246 else if (slot_info[4] & 0x40) {
247 p_ca_slot_info->flags = CA_CI_MODULE_READY;
248 p_ca_slot_info->num = 1;
249 p_ca_slot_info->type = CA_CI;
250 }
251 else {
252 p_ca_slot_info->flags = 0;
253 }
254
255 if (copy_to_user((struct ca_slot_info *)arg, p_ca_slot_info, sizeof (struct ca_slot_info))) {
256 return -EFAULT;
257 }
258
259 return 0;
260}
261
262
263
264
265static int ca_get_message(struct dst_state *state, struct ca_msg *p_ca_message, void *arg)
266{
267 u8 i = 0;
268 u32 command = 0;
269
270 if (copy_from_user(p_ca_message, (void *)arg, sizeof (struct ca_msg)))
271 return -EFAULT;
272
273
274 if (p_ca_message->msg) {
275 if (verbose > 3)
276 dprintk("Message = [%02x %02x %02x]\n", p_ca_message->msg[0], p_ca_message->msg[1], p_ca_message->msg[2]);
277
278 for (i = 0; i < 3; i++) {
279 command = command | p_ca_message->msg[i];
280 if (i < 2)
281 command = command << 8;
282 }
283 if (verbose > 3)
284 dprintk("%s:Command=[0x%x]\n", __FUNCTION__, command);
285
286 switch (command) {
287 case CA_APP_INFO:
288 memcpy(p_ca_message->msg, state->messages, 128);
289 if (copy_to_user((void *)arg, p_ca_message, sizeof (struct ca_msg)) )
290 return -EFAULT;
291 break;
292 }
293 }
294
295 return 0;
296}
297
298static int handle_en50221_tag(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer)
299{
300 if (state->dst_hw_cap & DST_TYPE_HAS_SESSION) {
301 hw_buffer->msg[2] = p_ca_message->msg[1]; /* MSB */
302 hw_buffer->msg[3] = p_ca_message->msg[2]; /* LSB */
303 }
304 else {
305 hw_buffer->msg[2] = 0x03;
306 hw_buffer->msg[3] = 0x00;
307 }
308 return 0;
309}
310
311static int debug_8820_buffer(struct ca_msg *hw_buffer)
312{
313 unsigned int i;
314
315 dprintk("%s:Debug=[", __FUNCTION__);
316 for (i = 0; i < (hw_buffer->msg[0] + 1); i++)
317 dprintk(" %02x", hw_buffer->msg[i]);
318 dprintk("]\n");
319
320 return 0;
321}
322
323static int write_to_8820(struct dst_state *state, struct ca_msg *hw_buffer, u8 reply)
324{
325 if ((dst_put_ci(state, hw_buffer->msg, (hw_buffer->length + 1), hw_buffer->msg, reply)) < 0) {
326 dprintk("%s: DST-CI Command failed.\n", __FUNCTION__);
327 dprintk("%s: Resetting DST.\n", __FUNCTION__);
328 rdc_reset_state(state);
329 return -1;
330 }
331 if (verbose > 2)
332 dprintk("%s: DST-CI Command succes.\n", __FUNCTION__);
333
334 return 0;
335}
336
337
338static int ca_set_pmt(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer, u8 reply, u8 query)
339{
340 u32 hw_offset, buf_offset, i, k;
341 u32 program_info_length = 0, es_info_length = 0, length = 0, words = 0;
342 u8 found_prog_ca_desc = 0, found_stream_ca_desc = 0, error_condition = 0, hw_buffer_length = 0;
343
344 if (verbose > 3)
345 dprintk("%s, p_ca_message length %d (0x%x)\n", __FUNCTION__,p_ca_message->length,p_ca_message->length );
346
347 handle_en50221_tag(state, p_ca_message, hw_buffer); /* EN50221 tag */
348
349 /* Handle the length field (variable) */
350 if (!(p_ca_message->msg[3] & 0x80)) { /* Length = 1 */
351 length = p_ca_message->msg[3] & 0x7f;
352 words = 0; /* domi's suggestion */
353 }
354 else { /* Length = words */
355 words = p_ca_message->msg[3] & 0x7f;
356 for (i = 0; i < words; i++) {
357 length = length << 8;
358 length = length | p_ca_message->msg[4 + i];
359 }
360 }
361 if (verbose > 4) {
362 dprintk("%s:Length=[%d (0x%x)], Words=[%d]\n", __FUNCTION__, length,length, words);
363
364 /* Debug Input string */
365 for (i = 0; i < length; i++)
366 dprintk(" %02x", p_ca_message->msg[i]);
367 dprintk("]\n");
368 }
369
370 hw_offset = 7;
371 buf_offset = words + 4;
372
373 /* Program Header */
374 if (verbose > 4)
375 dprintk("\n%s:Program Header=[", __FUNCTION__);
376 for (i = 0; i < 6; i++) {
377 hw_buffer->msg[hw_offset] = p_ca_message->msg[buf_offset];
378 if (verbose > 4)
379 dprintk(" %02x", p_ca_message->msg[buf_offset]);
380 hw_offset++, buf_offset++, hw_buffer_length++;
381 }
382 if (verbose > 4)
383 dprintk("]\n");
384
385 program_info_length = 0;
386 program_info_length = (((program_info_length | p_ca_message->msg[words + 8]) & 0x0f) << 8) | p_ca_message->msg[words + 9];
387 if (verbose > 4)
388 dprintk("%s:Program info Length=[%d][%02x], hw_offset=[%d], buf_offset=[%d] \n",
389 __FUNCTION__, program_info_length, program_info_length, hw_offset, buf_offset);
390
391 if (program_info_length && (program_info_length < 256)) { /* If program_info_length */
392 hw_buffer->msg[11] = hw_buffer->msg[11] & 0x0f; /* req only 4 bits */
393 hw_buffer->msg[12] = hw_buffer->msg[12] + 1; /* increment! ASIC bug! */
394
395 if (p_ca_message->msg[buf_offset + 1] == 0x09) { /* Check CA descriptor */
396 found_prog_ca_desc = 1;
397 if (verbose > 4)
398 dprintk("%s: Found CA descriptor @ Program level\n", __FUNCTION__);
399 }
400
401 if (found_prog_ca_desc) { /* Command only if CA descriptor */
402 hw_buffer->msg[13] = p_ca_message->msg[buf_offset]; /* CA PMT command ID */
403 hw_offset++, buf_offset++, hw_buffer_length++;
404 }
405
406 /* Program descriptors */
407 if (verbose > 4) {
408 dprintk("%s:**********>buf_offset=[%d], hw_offset=[%d]\n", __FUNCTION__, buf_offset, hw_offset);
409 dprintk("%s:Program descriptors=[", __FUNCTION__);
410 }
411 while (program_info_length && !error_condition) { /* Copy prog descriptors */
412 if (program_info_length > p_ca_message->length) { /* Error situation */
413 dprintk ("%s:\"WARNING\" Length error, line=[%d], prog_info_length=[%d]\n",
414 __FUNCTION__, __LINE__, program_info_length);
415 dprintk("%s:\"WARNING\" Bailing out of possible loop\n", __FUNCTION__);
416 error_condition = 1;
417 break;
418 }
419
420 hw_buffer->msg[hw_offset] = p_ca_message->msg[buf_offset];
421 dprintk(" %02x", p_ca_message->msg[buf_offset]);
422 hw_offset++, buf_offset++, hw_buffer_length++, program_info_length--;
423 }
424 if (verbose > 4) {
425 dprintk("]\n");
426 dprintk("%s:**********>buf_offset=[%d], hw_offset=[%d]\n", __FUNCTION__, buf_offset, hw_offset);
427 }
428 if (found_prog_ca_desc) {
429 if (!reply) {
430 hw_buffer->msg[13] = 0x01; /* OK descrambling */
431 if (verbose > 1)
432 dprintk("CA PMT Command = OK Descrambling\n");
433 }
434 else {
435 hw_buffer->msg[13] = 0x02; /* Ok MMI */
436 if (verbose > 1)
437 dprintk("CA PMT Command = Ok MMI\n");
438 }
439 if (query) {
440 hw_buffer->msg[13] = 0x03; /* Query */
441 if (verbose > 1)
442 dprintk("CA PMT Command = CA PMT query\n");
443 }
444 }
445 }
446 else {
447 hw_buffer->msg[11] = hw_buffer->msg[11] & 0xf0; /* Don't write to ASIC */
448 hw_buffer->msg[12] = hw_buffer->msg[12] = 0x00;
449 }
450 if (verbose > 4)
451 dprintk("%s:**********>p_ca_message->length=[%d], buf_offset=[%d], hw_offset=[%d]\n",
452 __FUNCTION__, p_ca_message->length, buf_offset, hw_offset);
453
454 while ((buf_offset < p_ca_message->length) && !error_condition) {
455 /* Bail out in case of an indefinite loop */
456 if ((es_info_length > p_ca_message->length) || (buf_offset > p_ca_message->length)) {
457 dprintk("%s:\"WARNING\" Length error, line=[%d], prog_info_length=[%d], buf_offset=[%d]\n",
458 __FUNCTION__, __LINE__, program_info_length, buf_offset);
459
460 dprintk("%s:\"WARNING\" Bailing out of possible loop\n", __FUNCTION__);
461 error_condition = 1;
462 break;
463 }
464
465 /* Stream Header */
466
467 for (k = 0; k < 5; k++) {
468 hw_buffer->msg[hw_offset + k] = p_ca_message->msg[buf_offset + k];
469 }
470
471 es_info_length = 0;
472 es_info_length = (es_info_length | (p_ca_message->msg[buf_offset + 3] & 0x0f)) << 8 | p_ca_message->msg[buf_offset + 4];
473
474 if (verbose > 4) {
475 dprintk("\n%s:----->Stream header=[%02x %02x %02x %02x %02x]\n", __FUNCTION__,
476 p_ca_message->msg[buf_offset + 0], p_ca_message->msg[buf_offset + 1],
477 p_ca_message->msg[buf_offset + 2], p_ca_message->msg[buf_offset + 3],
478 p_ca_message->msg[buf_offset + 4]);
479
480 dprintk("%s:----->Stream type=[%02x], es length=[%d (0x%x)], Chars=[%02x] [%02x], buf_offset=[%d]\n", __FUNCTION__,
481 p_ca_message->msg[buf_offset + 0], es_info_length, es_info_length,
482 p_ca_message->msg[buf_offset + 3], p_ca_message->msg[buf_offset + 4], buf_offset);
483 }
484
485 hw_buffer->msg[hw_offset + 3] &= 0x0f; /* req only 4 bits */
486
487 if (found_prog_ca_desc) {
488 hw_buffer->msg[hw_offset + 3] = 0x00;
489 hw_buffer->msg[hw_offset + 4] = 0x00;
490 }
491
492 hw_offset += 5, buf_offset += 5, hw_buffer_length += 5;
493
494 /* Check for CA descriptor */
495 if (p_ca_message->msg[buf_offset + 1] == 0x09) {
496 if (verbose > 4)
497 dprintk("%s:Found CA descriptor @ Stream level\n", __FUNCTION__);
498 found_stream_ca_desc = 1;
499 }
500
501 /* ES descriptors */
502
503 if (es_info_length && !error_condition && !found_prog_ca_desc && found_stream_ca_desc) {
504// if (!ca_pmt_done) {
505 hw_buffer->msg[hw_offset] = p_ca_message->msg[buf_offset]; /* CA PMT cmd(es) */
506 if (verbose > 4)
507 printk("%s:----->CA PMT Command ID=[%02x]\n", __FUNCTION__, p_ca_message->msg[buf_offset]);
508// hw_offset++, buf_offset++, hw_buffer_length++, es_info_length--, ca_pmt_done = 1;
509 hw_offset++, buf_offset++, hw_buffer_length++, es_info_length--;
510// }
511 if (verbose > 4)
512 dprintk("%s:----->ES descriptors=[", __FUNCTION__);
513
514 while (es_info_length && !error_condition) { /* ES descriptors */
515 if ((es_info_length > p_ca_message->length) || (buf_offset > p_ca_message->length)) {
516 if (verbose > 4) {
517 dprintk("%s:\"WARNING\" ES Length error, line=[%d], es_info_length=[%d], buf_offset=[%d]\n",
518 __FUNCTION__, __LINE__, es_info_length, buf_offset);
519
520 dprintk("%s:\"WARNING\" Bailing out of possible loop\n", __FUNCTION__);
521 }
522 error_condition = 1;
523 break;
524 }
525
526 hw_buffer->msg[hw_offset] = p_ca_message->msg[buf_offset];
527 if (verbose > 3)
528 dprintk("%02x ", hw_buffer->msg[hw_offset]);
529 hw_offset++, buf_offset++, hw_buffer_length++, es_info_length--;
530 }
531 found_stream_ca_desc = 0; /* unset for new streams */
532 dprintk("]\n");
533 }
534 }
535
536 /* MCU Magic words */
537
538 hw_buffer_length += 7;
539 hw_buffer->msg[0] = hw_buffer_length;
540 hw_buffer->msg[1] = 64;
541 hw_buffer->msg[4] = 3;
542 hw_buffer->msg[5] = hw_buffer->msg[0] - 7;
543 hw_buffer->msg[6] = 0;
544
545
546 /* Fix length */
547 hw_buffer->length = hw_buffer->msg[0];
548
549 put_checksum(&hw_buffer->msg[0], hw_buffer->msg[0]);
550 /* Do the actual write */
551 if (verbose > 4) {
552 dprintk("%s:======================DEBUGGING================================\n", __FUNCTION__);
553 dprintk("%s: Actual Length=[%d]\n", __FUNCTION__, hw_buffer_length);
554 }
555 /* Only for debugging! */
556 if (verbose > 2)
557 debug_8820_buffer(hw_buffer);
558 if (verbose > 3)
559 dprintk("%s: Reply = [%d]\n", __FUNCTION__, reply);
560 write_to_8820(state, hw_buffer, reply);
561
562 return 0;
563}
564
565/* Board supports CA PMT reply ? */
566static int dst_check_ca_pmt(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer)
567{
568 int ca_pmt_reply_test = 0;
569
570 /* Do test board */
571 /* Not there yet but soon */
572
573
574 /* CA PMT Reply capable */
575 if (ca_pmt_reply_test) {
576 if ((ca_set_pmt(state, p_ca_message, hw_buffer, 1, GET_REPLY)) < 0) {
577 dprintk("%s: ca_set_pmt.. failed !\n", __FUNCTION__);
578 return -1;
579 }
580
581 /* Process CA PMT Reply */
582 /* will implement soon */
583 dprintk("%s: Not there yet\n", __FUNCTION__);
584 }
585 /* CA PMT Reply not capable */
586 if (!ca_pmt_reply_test) {
587 if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, NO_REPLY)) < 0) {
588 dprintk("%s: ca_set_pmt.. failed !\n", __FUNCTION__);
589 return -1;
590 }
591 if (verbose > 3)
592 dprintk("%s: ca_set_pmt.. success !\n", __FUNCTION__);
593 /* put a dummy message */
594
595 }
596 return 0;
597}
598
599static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message, void *arg)
600{
601 int i = 0;
602 unsigned int ca_message_header_len;
603
604 u32 command = 0;
605 struct ca_msg *hw_buffer;
606
607 if ((hw_buffer = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) {
608 printk("%s: Memory allocation failure\n", __FUNCTION__);
609 return -ENOMEM;
610 }
611 if (verbose > 3)
612 dprintk("%s\n", __FUNCTION__);
613
614 if (copy_from_user(p_ca_message, (void *)arg, sizeof (struct ca_msg)))
615 return -EFAULT;
616
617 if (p_ca_message->msg) {
618 ca_message_header_len = p_ca_message->length; /* Restore it back when you are done */
619 /* EN50221 tag */
620 command = 0;
621
622 for (i = 0; i < 3; i++) {
623 command = command | p_ca_message->msg[i];
624 if (i < 2)
625 command = command << 8;
626 }
627 if (verbose > 3)
628 dprintk("%s:Command=[0x%x]\n", __FUNCTION__, command);
629
630 switch (command) {
631 case CA_PMT:
632 if (verbose > 3)
633 dprintk("Command = SEND_CA_PMT\n");
634 if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, 0)) < 0) {
635 dprintk("%s: -->CA_PMT Failed !\n", __FUNCTION__);
636 return -1;
637 }
638 if (verbose > 3)
639 dprintk("%s: -->CA_PMT Success !\n", __FUNCTION__);
640// retval = dummy_set_pmt(state, p_ca_message, hw_buffer, 0, 0);
641
642 break;
643
644 case CA_PMT_REPLY:
645 if (verbose > 3)
646 dprintk("Command = CA_PMT_REPLY\n");
647 /* Have to handle the 2 basic types of cards here */
648 if ((dst_check_ca_pmt(state, p_ca_message, hw_buffer)) < 0) {
649 dprintk("%s: -->CA_PMT_REPLY Failed !\n", __FUNCTION__);
650 return -1;
651 }
652 if (verbose > 3)
653 dprintk("%s: -->CA_PMT_REPLY Success !\n", __FUNCTION__);
654
655 /* Certain boards do behave different ? */
656// retval = ca_set_pmt(state, p_ca_message, hw_buffer, 1, 1);
657
658 case CA_APP_INFO_ENQUIRY: // only for debugging
659 if (verbose > 3)
660 dprintk("%s: Getting Cam Application information\n", __FUNCTION__);
661
662 if ((ca_get_app_info(state)) < 0) {
663 dprintk("%s: -->CA_APP_INFO_ENQUIRY Failed !\n", __FUNCTION__);
664 return -1;
665 }
666 if (verbose > 3)
667 printk("%s: -->CA_APP_INFO_ENQUIRY Success !\n", __FUNCTION__);
668
669 break;
670 }
671 }
672 return 0;
673}
674
675static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg)
676{
677 struct dvb_device* dvbdev = (struct dvb_device*) file->private_data;
678 struct dst_state* state = (struct dst_state*) dvbdev->priv;
679 struct ca_slot_info *p_ca_slot_info;
680 struct ca_caps *p_ca_caps;
681 struct ca_msg *p_ca_message;
682
683 if ((p_ca_message = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) {
684 printk("%s: Memory allocation failure\n", __FUNCTION__);
685 return -ENOMEM;
686 }
687
688 if ((p_ca_slot_info = (struct ca_slot_info *) kmalloc(sizeof (struct ca_slot_info), GFP_KERNEL)) == NULL) {
689 printk("%s: Memory allocation failure\n", __FUNCTION__);
690 return -ENOMEM;
691 }
692
693 if ((p_ca_caps = (struct ca_caps *) kmalloc(sizeof (struct ca_caps), GFP_KERNEL)) == NULL) {
694 printk("%s: Memory allocation failure\n", __FUNCTION__);
695 return -ENOMEM;
696 }
697
698 /* We have now only the standard ioctl's, the driver is upposed to handle internals. */
699 switch (cmd) {
700 case CA_SEND_MSG:
701 if (verbose > 1)
702 dprintk("%s: Sending message\n", __FUNCTION__);
703 if ((ca_send_message(state, p_ca_message, arg)) < 0) {
704 dprintk("%s: -->CA_SEND_MSG Failed !\n", __FUNCTION__);
705 return -1;
706 }
707
708 break;
709
710 case CA_GET_MSG:
711 if (verbose > 1)
712 dprintk("%s: Getting message\n", __FUNCTION__);
713 if ((ca_get_message(state, p_ca_message, arg)) < 0) {
714 dprintk("%s: -->CA_GET_MSG Failed !\n", __FUNCTION__);
715 return -1;
716 }
717 if (verbose > 1)
718 dprintk("%s: -->CA_GET_MSG Success !\n", __FUNCTION__);
719
720 break;
721
722 case CA_RESET:
723 if (verbose > 1)
724 dprintk("%s: Resetting DST\n", __FUNCTION__);
725 dst_error_bailout(state);
726 msleep(4000);
727
728 break;
729
730 case CA_GET_SLOT_INFO:
731 if (verbose > 1)
732 dprintk("%s: Getting Slot info\n", __FUNCTION__);
733 if ((ca_get_slot_info(state, p_ca_slot_info, arg)) < 0) {
734 dprintk("%s: -->CA_GET_SLOT_INFO Failed !\n", __FUNCTION__);
735 return -1;
736 }
737 if (verbose > 1)
738 dprintk("%s: -->CA_GET_SLOT_INFO Success !\n", __FUNCTION__);
739
740 break;
741
742 case CA_GET_CAP:
743 if (verbose > 1)
744 dprintk("%s: Getting Slot capabilities\n", __FUNCTION__);
745 if ((ca_get_slot_caps(state, p_ca_caps, arg)) < 0) {
746 dprintk("%s: -->CA_GET_CAP Failed !\n", __FUNCTION__);
747 return -1;
748 }
749 if (verbose > 1)
750 dprintk("%s: -->CA_GET_CAP Success !\n", __FUNCTION__);
751
752 break;
753
754 case CA_GET_DESCR_INFO:
755 if (verbose > 1)
756 dprintk("%s: Getting descrambler description\n", __FUNCTION__);
757 if ((ca_get_slot_descr(state, p_ca_message, arg)) < 0) {
758 dprintk("%s: -->CA_GET_DESCR_INFO Failed !\n", __FUNCTION__);
759 return -1;
760 }
761 if (verbose > 1)
762 dprintk("%s: -->CA_GET_DESCR_INFO Success !\n", __FUNCTION__);
763
764 break;
765
766 case CA_SET_DESCR:
767 if (verbose > 1)
768 dprintk("%s: Setting descrambler\n", __FUNCTION__);
769 if ((ca_set_slot_descr()) < 0) {
770 dprintk("%s: -->CA_SET_DESCR Failed !\n", __FUNCTION__);
771 return -1;
772 }
773 if (verbose > 1)
774 dprintk("%s: -->CA_SET_DESCR Success !\n", __FUNCTION__);
775
776 break;
777
778 case CA_SET_PID:
779 if (verbose > 1)
780 dprintk("%s: Setting PID\n", __FUNCTION__);
781 if ((ca_set_pid()) < 0) {
782 dprintk("%s: -->CA_SET_PID Failed !\n", __FUNCTION__);
783 return -1;
784 }
785 if (verbose > 1)
786 dprintk("%s: -->CA_SET_PID Success !\n", __FUNCTION__);
787
788 default:
789 return -EOPNOTSUPP;
790 };
791
792 return 0;
793}
794
795static int dst_ca_open(struct inode *inode, struct file *file)
796{
797 if (verbose > 4)
798 dprintk("%s:Device opened [%p]\n", __FUNCTION__, file);
799 try_module_get(THIS_MODULE);
800
801 return 0;
802}
803
804static int dst_ca_release(struct inode *inode, struct file *file)
805{
806 if (verbose > 4)
807 dprintk("%s:Device closed.\n", __FUNCTION__);
808 module_put(THIS_MODULE);
809
810 return 0;
811}
812
813static int dst_ca_read(struct file *file, char __user * buffer, size_t length, loff_t * offset)
814{
815 int bytes_read = 0;
816
817 if (verbose > 4)
818 dprintk("%s:Device read.\n", __FUNCTION__);
819
820 return bytes_read;
821}
822
823static int dst_ca_write(struct file *file, const char __user * buffer, size_t length, loff_t * offset)
824{
825 if (verbose > 4)
826 dprintk("%s:Device write.\n", __FUNCTION__);
827
828 return 0;
829}
830
831static struct file_operations dst_ca_fops = {
832 .owner = THIS_MODULE,
833 .ioctl = (void *)dst_ca_ioctl,
834 .open = dst_ca_open,
835 .release = dst_ca_release,
836 .read = dst_ca_read,
837 .write = dst_ca_write
838};
839
840static struct dvb_device dvbdev_ca = {
841 .priv = NULL,
842 .users = 1,
843 .readers = 1,
844 .writers = 1,
845 .fops = &dst_ca_fops
846};
847
848int dst_ca_attach(struct dst_state *dst, struct dvb_adapter *dvb_adapter)
849{
850 struct dvb_device *dvbdev;
851 if (verbose > 4)
852 dprintk("%s:registering DST-CA device\n", __FUNCTION__);
853 dvb_register_device(dvb_adapter, &dvbdev, &dvbdev_ca, dst, DVB_DEVICE_CA);
854 return 0;
855}
856
857EXPORT_SYMBOL(dst_ca_attach);
858
859MODULE_DESCRIPTION("DST DVB-S/T/C Combo CA driver");
860MODULE_AUTHOR("Manu Abraham");
861MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/bt8xx/dst_ca.h b/drivers/media/dvb/bt8xx/dst_ca.h
new file mode 100644
index 000000000000..59cd0ddd6d8e
--- /dev/null
+++ b/drivers/media/dvb/bt8xx/dst_ca.h
@@ -0,0 +1,58 @@
1/*
2 CA-driver for TwinHan DST Frontend/Card
3
4 Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com)
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20
21#ifndef _DST_CA_H_
22#define _DST_CA_H_
23
24#define RETRIES 5
25
26
27#define CA_APP_INFO_ENQUIRY 0x9f8020
28#define CA_APP_INFO 0x9f8021
29#define CA_ENTER_MENU 0x9f8022
30#define CA_INFO_ENQUIRY 0x9f8030
31#define CA_INFO 0x9f8031
32#define CA_PMT 0x9f8032
33#define CA_PMT_REPLY 0x9f8033
34
35#define CA_CLOSE_MMI 0x9f8800
36#define CA_DISPLAY_CONTROL 0x9f8801
37#define CA_DISPLAY_REPLY 0x9f8802
38#define CA_TEXT_LAST 0x9f8803
39#define CA_TEXT_MORE 0x9f8804
40#define CA_KEYPAD_CONTROL 0x9f8805
41#define CA_KEYPRESS 0x9f8806
42
43#define CA_ENQUIRY 0x9f8807
44#define CA_ANSWER 0x9f8808
45#define CA_MENU_LAST 0x9f8809
46#define CA_MENU_MORE 0x9f880a
47#define CA_MENU_ANSWER 0x9f880b
48#define CA_LIST_LAST 0x9f880c
49#define CA_LIST_MORE 0x9f880d
50
51
52struct dst_ca_private {
53 struct dst_state *dst;
54 struct dvb_device *dvbdev;
55};
56
57
58#endif
diff --git a/drivers/media/dvb/bt8xx/dst_common.h b/drivers/media/dvb/bt8xx/dst_common.h
new file mode 100644
index 000000000000..0b3da29245fb
--- /dev/null
+++ b/drivers/media/dvb/bt8xx/dst_common.h
@@ -0,0 +1,153 @@
1/*
2 Frontend-driver for TwinHan DST Frontend
3
4 Copyright (C) 2003 Jamie Honan
5 Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com)
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20*/
21
22#ifndef DST_COMMON_H
23#define DST_COMMON_H
24
25#include <linux/dvb/frontend.h>
26#include <linux/device.h>
27#include "bt878.h"
28
29#include "dst_ca.h"
30
31
32#define NO_DELAY 0
33#define LONG_DELAY 1
34#define DEVICE_INIT 2
35
36#define DELAY 1
37
38#define DST_TYPE_IS_SAT 0
39#define DST_TYPE_IS_TERR 1
40#define DST_TYPE_IS_CABLE 2
41#define DST_TYPE_IS_ATSC 3
42
43#define DST_TYPE_HAS_NEWTUNE 1
44#define DST_TYPE_HAS_TS204 2
45#define DST_TYPE_HAS_SYMDIV 4
46#define DST_TYPE_HAS_FW_1 8
47#define DST_TYPE_HAS_FW_2 16
48#define DST_TYPE_HAS_FW_3 32
49#define DST_TYPE_HAS_FW_BUILD 64
50
51/* Card capability list */
52
53#define DST_TYPE_HAS_MAC 1
54#define DST_TYPE_HAS_DISEQC3 2
55#define DST_TYPE_HAS_DISEQC4 4
56#define DST_TYPE_HAS_DISEQC5 8
57#define DST_TYPE_HAS_MOTO 16
58#define DST_TYPE_HAS_CA 32
59#define DST_TYPE_HAS_ANALOG 64 /* Analog inputs */
60#define DST_TYPE_HAS_SESSION 128
61
62
63#define RDC_8820_PIO_0_DISABLE 0
64#define RDC_8820_PIO_0_ENABLE 1
65#define RDC_8820_INT 2
66#define RDC_8820_RESET 4
67
68/* DST Communication */
69#define GET_REPLY 1
70#define NO_REPLY 0
71
72#define GET_ACK 1
73#define FIXED_COMM 8
74
75#define ACK 0xff
76
77struct dst_state {
78
79 struct i2c_adapter* i2c;
80
81 struct bt878* bt;
82
83 struct dvb_frontend_ops ops;
84
85 /* configuration settings */
86 const struct dst_config* config;
87
88 struct dvb_frontend frontend;
89
90 /* private ASIC data */
91 u8 tx_tuna[10];
92 u8 rx_tuna[10];
93 u8 rxbuffer[10];
94 u8 diseq_flags;
95 u8 dst_type;
96 u32 type_flags;
97 u32 frequency; /* intermediate frequency in kHz for QPSK */
98 fe_spectral_inversion_t inversion;
99 u32 symbol_rate; /* symbol rate in Symbols per second */
100 fe_code_rate_t fec;
101 fe_sec_voltage_t voltage;
102 fe_sec_tone_mode_t tone;
103 u32 decode_freq;
104 u8 decode_lock;
105 u16 decode_strength;
106 u16 decode_snr;
107 unsigned long cur_jiff;
108 u8 k22;
109 fe_bandwidth_t bandwidth;
110 u32 dst_hw_cap;
111 u8 dst_fw_version;
112 fe_sec_mini_cmd_t minicmd;
113 u8 messages[256];
114};
115
116struct dst_types {
117 char *device_id;
118 int offset;
119 u8 dst_type;
120 u32 type_flags;
121 u32 dst_feature;
122};
123
124
125
126struct dst_config
127{
128 /* the ASIC i2c address */
129 u8 demod_address;
130};
131
132
133int rdc_reset_state(struct dst_state *state);
134int rdc_8820_reset(struct dst_state *state);
135
136int dst_wait_dst_ready(struct dst_state *state, u8 delay_mode);
137int dst_pio_enable(struct dst_state *state);
138int dst_pio_disable(struct dst_state *state);
139int dst_error_recovery(struct dst_state* state);
140int dst_error_bailout(struct dst_state *state);
141int dst_comm_init(struct dst_state* state);
142
143int write_dst(struct dst_state *state, u8 * data, u8 len);
144int read_dst(struct dst_state *state, u8 * ret, u8 len);
145u8 dst_check_sum(u8 * buf, u32 len);
146struct dst_state* dst_attach(struct dst_state* state, struct dvb_adapter *dvb_adapter);
147int dst_ca_attach(struct dst_state *state, struct dvb_adapter *dvb_adapter);
148int dst_gpio_outb(struct dst_state* state, u32 mask, u32 enbb, u32 outhigh, int delay);
149
150int dst_command(struct dst_state* state, u8 * data, u8 len);
151
152
153#endif // DST_COMMON_H
diff --git a/drivers/media/dvb/bt8xx/dst_priv.h b/drivers/media/dvb/bt8xx/dst_priv.h
index 80488aa628b4..3974a4c6ebe7 100644
--- a/drivers/media/dvb/bt8xx/dst_priv.h
+++ b/drivers/media/dvb/bt8xx/dst_priv.h
@@ -33,4 +33,3 @@ union dst_gpio_packet {
33struct bt878; 33struct bt878;
34 34
35int bt878_device_control(struct bt878 *bt, unsigned int cmd, union dst_gpio_packet *mp); 35int bt878_device_control(struct bt878 *bt, unsigned int cmd, union dst_gpio_packet *mp);
36
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
index b735397f59aa..6f857c6091f3 100644
--- a/drivers/media/dvb/bt8xx/dvb-bt8xx.c
+++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
@@ -142,7 +142,7 @@ static int thomson_dtt7579_demod_init(struct dvb_frontend* fe)
142 mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg)); 142 mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
143 143
144 mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg)); 144 mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg));
145 mt352_write(fe, mt352_gpp_ctl_cfg, sizeof(mt352_gpp_ctl_cfg)); 145 mt352_write(fe, mt352_gpp_ctl_cfg, sizeof(mt352_gpp_ctl_cfg));
146 mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg)); 146 mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
147 147
148 return 0; 148 return 0;
@@ -161,7 +161,7 @@ static int thomson_dtt7579_pll_set(struct dvb_frontend* fe, struct dvb_frontend_
161 else if (params->frequency < 771000000) cp = 0xbc; 161 else if (params->frequency < 771000000) cp = 0xbc;
162 else cp = 0xf4; 162 else cp = 0xf4;
163 163
164 if (params->frequency == 0) bs = 0x03; 164 if (params->frequency == 0) bs = 0x03;
165 else if (params->frequency < 443250000) bs = 0x02; 165 else if (params->frequency < 443250000) bs = 0x02;
166 else bs = 0x08; 166 else bs = 0x08;
167 167
@@ -190,44 +190,44 @@ static int cx24108_pll_set(struct dvb_frontend* fe, struct dvb_frontend_paramete
190 190
191 191
192 u32 osci[]={950000,1019000,1075000,1178000,1296000,1432000, 192 u32 osci[]={950000,1019000,1075000,1178000,1296000,1432000,
193 1576000,1718000,1856000,2036000,2150000}; 193 1576000,1718000,1856000,2036000,2150000};
194 u32 bandsel[]={0,0x00020000,0x00040000,0x00100800,0x00101000, 194 u32 bandsel[]={0,0x00020000,0x00040000,0x00100800,0x00101000,
195 0x00102000,0x00104000,0x00108000,0x00110000, 195 0x00102000,0x00104000,0x00108000,0x00110000,
196 0x00120000,0x00140000}; 196 0x00120000,0x00140000};
197 197
198#define XTAL 1011100 /* Hz, really 1.0111 MHz and a /10 prescaler */ 198#define XTAL 1011100 /* Hz, really 1.0111 MHz and a /10 prescaler */
199 printk("cx24108 debug: entering SetTunerFreq, freq=%d\n",freq); 199 printk("cx24108 debug: entering SetTunerFreq, freq=%d\n",freq);
200 200
201 /* This is really the bit driving the tuner chip cx24108 */ 201 /* This is really the bit driving the tuner chip cx24108 */
202 202
203 if(freq<950000) freq=950000; /* kHz */ 203 if(freq<950000) freq=950000; /* kHz */
204 if(freq>2150000) freq=2150000; /* satellite IF is 950..2150MHz */ 204 if(freq>2150000) freq=2150000; /* satellite IF is 950..2150MHz */
205 205
206 /* decide which VCO to use for the input frequency */ 206 /* decide which VCO to use for the input frequency */
207 for(i=1;(i<sizeof(osci)/sizeof(osci[0]))&&(osci[i]<freq);i++); 207 for(i=1;(i<sizeof(osci)/sizeof(osci[0]))&&(osci[i]<freq);i++);
208 printk("cx24108 debug: select vco #%d (f=%d)\n",i,freq); 208 printk("cx24108 debug: select vco #%d (f=%d)\n",i,freq);
209 band=bandsel[i]; 209 band=bandsel[i];
210 /* the gain values must be set by SetSymbolrate */ 210 /* the gain values must be set by SetSymbolrate */
211 /* compute the pll divider needed, from Conexant data sheet, 211 /* compute the pll divider needed, from Conexant data sheet,
212 resolved for (n*32+a), remember f(vco) is f(receive) *2 or *4, 212 resolved for (n*32+a), remember f(vco) is f(receive) *2 or *4,
213 depending on the divider bit. It is set to /4 on the 2 lowest 213 depending on the divider bit. It is set to /4 on the 2 lowest
214 bands */ 214 bands */
215 n=((i<=2?2:1)*freq*10L)/(XTAL/100); 215 n=((i<=2?2:1)*freq*10L)/(XTAL/100);
216 a=n%32; n/=32; if(a==0) n--; 216 a=n%32; n/=32; if(a==0) n--;
217 pump=(freq<(osci[i-1]+osci[i])/2); 217 pump=(freq<(osci[i-1]+osci[i])/2);
218 pll=0xf8000000| 218 pll=0xf8000000|
219 ((pump?1:2)<<(14+11))| 219 ((pump?1:2)<<(14+11))|
220 ((n&0x1ff)<<(5+11))| 220 ((n&0x1ff)<<(5+11))|
221 ((a&0x1f)<<11); 221 ((a&0x1f)<<11);
222 /* everything is shifted left 11 bits to left-align the bits in the 222 /* everything is shifted left 11 bits to left-align the bits in the
223 32bit word. Output to the tuner goes MSB-aligned, after all */ 223 32bit word. Output to the tuner goes MSB-aligned, after all */
224 printk("cx24108 debug: pump=%d, n=%d, a=%d\n",pump,n,a); 224 printk("cx24108 debug: pump=%d, n=%d, a=%d\n",pump,n,a);
225 cx24110_pll_write(fe,band); 225 cx24110_pll_write(fe,band);
226 /* set vga and vca to their widest-band settings, as a precaution. 226 /* set vga and vca to their widest-band settings, as a precaution.
227 SetSymbolrate might not be called to set this up */ 227 SetSymbolrate might not be called to set this up */
228 cx24110_pll_write(fe,0x500c0000); 228 cx24110_pll_write(fe,0x500c0000);
229 cx24110_pll_write(fe,0x83f1f800); 229 cx24110_pll_write(fe,0x83f1f800);
230 cx24110_pll_write(fe,pll); 230 cx24110_pll_write(fe,pll);
231/* writereg(client,0x56,0x7f);*/ 231/* writereg(client,0x56,0x7f);*/
232 232
233 return 0; 233 return 0;
@@ -299,7 +299,7 @@ static int advbt771_samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe)
299 static u8 mt352_reset [] = { 0x50, 0x80 }; 299 static u8 mt352_reset [] = { 0x50, 0x80 };
300 static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 }; 300 static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 };
301 static u8 mt352_agc_cfg [] = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF, 301 static u8 mt352_agc_cfg [] = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF,
302 0x00, 0xFF, 0x00, 0x40, 0x40 }; 302 0x00, 0xFF, 0x00, 0x40, 0x40 };
303 static u8 mt352_av771_extra[] = { 0xB5, 0x7A }; 303 static u8 mt352_av771_extra[] = { 0xB5, 0x7A };
304 static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 }; 304 static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };
305 305
@@ -463,6 +463,9 @@ static struct nxt6000_config vp3021_alps_tded4_config = {
463 463
464static void frontend_init(struct dvb_bt8xx_card *card, u32 type) 464static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
465{ 465{
466 int ret;
467 struct dst_state* state = NULL;
468
466 switch(type) { 469 switch(type) {
467#ifdef BTTV_DVICO_DVBT_LITE 470#ifdef BTTV_DVICO_DVBT_LITE
468 case BTTV_DVICO_DVBT_LITE: 471 case BTTV_DVICO_DVBT_LITE:
@@ -503,7 +506,25 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
503 break; 506 break;
504 507
505 case BTTV_TWINHAN_DST: 508 case BTTV_TWINHAN_DST:
506 card->fe = dst_attach(&dst_config, card->i2c_adapter, card->bt); 509 /* DST is not a frontend driver !!! */
510 state = (struct dst_state *) kmalloc(sizeof (struct dst_state), GFP_KERNEL);
511 /* Setup the Card */
512 state->config = &dst_config;
513 state->i2c = card->i2c_adapter;
514 state->bt = card->bt;
515
516 /* DST is not a frontend, attaching the ASIC */
517 if ((dst_attach(state, &card->dvb_adapter)) == NULL) {
518 printk("%s: Could not find a Twinhan DST.\n", __FUNCTION__);
519 break;
520 }
521 card->fe = &state->frontend;
522
523 /* Attach other DST peripherals if any */
524 /* Conditional Access device */
525 if (state->dst_hw_cap & DST_TYPE_HAS_CA) {
526 ret = dst_ca_attach(state, &card->dvb_adapter);
527 }
507 if (card->fe != NULL) { 528 if (card->fe != NULL) {
508 break; 529 break;
509 } 530 }
@@ -531,7 +552,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
531 card->bt->dev->subsystem_vendor, 552 card->bt->dev->subsystem_vendor,
532 card->bt->dev->subsystem_device); 553 card->bt->dev->subsystem_device);
533 } else { 554 } else {
534 if (dvb_register_frontend(card->dvb_adapter, card->fe)) { 555 if (dvb_register_frontend(&card->dvb_adapter, card->fe)) {
535 printk("dvb-bt8xx: Frontend registration failed!\n"); 556 printk("dvb-bt8xx: Frontend registration failed!\n");
536 if (card->fe->ops->release) 557 if (card->fe->ops->release)
537 card->fe->ops->release(card->fe); 558 card->fe->ops->release(card->fe);
@@ -550,7 +571,7 @@ static int __init dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type)
550 return result; 571 return result;
551 572
552 } 573 }
553 card->dvb_adapter->priv = card; 574 card->dvb_adapter.priv = card;
554 575
555 card->bt->adapter = card->i2c_adapter; 576 card->bt->adapter = card->i2c_adapter;
556 577
@@ -568,7 +589,7 @@ static int __init dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type)
568 if ((result = dvb_dmx_init(&card->demux)) < 0) { 589 if ((result = dvb_dmx_init(&card->demux)) < 0) {
569 printk("dvb_bt8xx: dvb_dmx_init failed (errno = %d)\n", result); 590 printk("dvb_bt8xx: dvb_dmx_init failed (errno = %d)\n", result);
570 591
571 dvb_unregister_adapter(card->dvb_adapter); 592 dvb_unregister_adapter(&card->dvb_adapter);
572 return result; 593 return result;
573 } 594 }
574 595
@@ -576,11 +597,11 @@ static int __init dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type)
576 card->dmxdev.demux = &card->demux.dmx; 597 card->dmxdev.demux = &card->demux.dmx;
577 card->dmxdev.capabilities = 0; 598 card->dmxdev.capabilities = 0;
578 599
579 if ((result = dvb_dmxdev_init(&card->dmxdev, card->dvb_adapter)) < 0) { 600 if ((result = dvb_dmxdev_init(&card->dmxdev, &card->dvb_adapter)) < 0) {
580 printk("dvb_bt8xx: dvb_dmxdev_init failed (errno = %d)\n", result); 601 printk("dvb_bt8xx: dvb_dmxdev_init failed (errno = %d)\n", result);
581 602
582 dvb_dmx_release(&card->demux); 603 dvb_dmx_release(&card->demux);
583 dvb_unregister_adapter(card->dvb_adapter); 604 dvb_unregister_adapter(&card->dvb_adapter);
584 return result; 605 return result;
585 } 606 }
586 607
@@ -591,7 +612,7 @@ static int __init dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type)
591 612
592 dvb_dmxdev_release(&card->dmxdev); 613 dvb_dmxdev_release(&card->dmxdev);
593 dvb_dmx_release(&card->demux); 614 dvb_dmx_release(&card->demux);
594 dvb_unregister_adapter(card->dvb_adapter); 615 dvb_unregister_adapter(&card->dvb_adapter);
595 return result; 616 return result;
596 } 617 }
597 618
@@ -603,7 +624,7 @@ static int __init dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type)
603 card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw); 624 card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw);
604 dvb_dmxdev_release(&card->dmxdev); 625 dvb_dmxdev_release(&card->dmxdev);
605 dvb_dmx_release(&card->demux); 626 dvb_dmx_release(&card->demux);
606 dvb_unregister_adapter(card->dvb_adapter); 627 dvb_unregister_adapter(&card->dvb_adapter);
607 return result; 628 return result;
608 } 629 }
609 630
@@ -614,11 +635,11 @@ static int __init dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type)
614 card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw); 635 card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw);
615 dvb_dmxdev_release(&card->dmxdev); 636 dvb_dmxdev_release(&card->dmxdev);
616 dvb_dmx_release(&card->demux); 637 dvb_dmx_release(&card->demux);
617 dvb_unregister_adapter(card->dvb_adapter); 638 dvb_unregister_adapter(&card->dvb_adapter);
618 return result; 639 return result;
619 } 640 }
620 641
621 dvb_net_init(card->dvb_adapter, &card->dvbnet, &card->demux.dmx); 642 dvb_net_init(&card->dvb_adapter, &card->dvbnet, &card->demux.dmx);
622 643
623 tasklet_init(&card->bt->tasklet, dvb_bt8xx_task, (unsigned long) card); 644 tasklet_init(&card->bt->tasklet, dvb_bt8xx_task, (unsigned long) card);
624 645
@@ -648,7 +669,7 @@ static int dvb_bt8xx_probe(struct device *dev)
648 case BTTV_PINNACLESAT: 669 case BTTV_PINNACLESAT:
649 card->gpio_mode = 0x0400c060; 670 card->gpio_mode = 0x0400c060;
650 /* should be: BT878_A_GAIN=0,BT878_A_PWRDN,BT878_DA_DPM,BT878_DA_SBR, 671 /* should be: BT878_A_GAIN=0,BT878_A_PWRDN,BT878_DA_DPM,BT878_DA_SBR,
651 BT878_DA_IOM=1,BT878_DA_APP to enable serial highspeed mode. */ 672 BT878_DA_IOM=1,BT878_DA_APP to enable serial highspeed mode. */
652 card->op_sync_orin = 0; 673 card->op_sync_orin = 0;
653 card->irq_err_ignore = 0; 674 card->irq_err_ignore = 0;
654 break; 675 break;
@@ -759,7 +780,7 @@ static int dvb_bt8xx_remove(struct device *dev)
759 dvb_dmxdev_release(&card->dmxdev); 780 dvb_dmxdev_release(&card->dmxdev);
760 dvb_dmx_release(&card->demux); 781 dvb_dmx_release(&card->demux);
761 if (card->fe) dvb_unregister_frontend(card->fe); 782 if (card->fe) dvb_unregister_frontend(card->fe);
762 dvb_unregister_adapter(card->dvb_adapter); 783 dvb_unregister_adapter(&card->dvb_adapter);
763 784
764 kfree(card); 785 kfree(card);
765 786
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.h b/drivers/media/dvb/bt8xx/dvb-bt8xx.h
index 80ef189f930f..2923b3b0dd3c 100644
--- a/drivers/media/dvb/bt8xx/dvb-bt8xx.h
+++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.h
@@ -31,7 +31,7 @@
31#include "bttv.h" 31#include "bttv.h"
32#include "mt352.h" 32#include "mt352.h"
33#include "sp887x.h" 33#include "sp887x.h"
34#include "dst.h" 34#include "dst_common.h"
35#include "nxt6000.h" 35#include "nxt6000.h"
36#include "cx24110.h" 36#include "cx24110.h"
37#include "or51211.h" 37#include "or51211.h"
@@ -40,7 +40,7 @@ struct dvb_bt8xx_card {
40 struct semaphore lock; 40 struct semaphore lock;
41 int nfeeds; 41 int nfeeds;
42 char card_name[32]; 42 char card_name[32];
43 struct dvb_adapter *dvb_adapter; 43 struct dvb_adapter dvb_adapter;
44 struct bt878 *bt; 44 struct bt878 *bt;
45 unsigned int bttv_nr; 45 unsigned int bttv_nr;
46 struct dvb_demux demux; 46 struct dvb_demux demux;