aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorJohannes Stezenbach <js@linuxtv.org>2005-05-17 00:54:41 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-05-17 10:59:33 -0400
commit50b215a05878ce9636dace6cd21f7e91ff005058 (patch)
tree0d3f67aeff9efceb3575dd902d91d21e02638f3d /drivers/media
parentdaeb6aa40be55b0750aea92dea78b8ebc40ca9a8 (diff)
[PATCH] dvb: DST: reorganize Twinhan DST driver to support CI
- reorganize Twinhan DST driver to support CI - add support for more cards (Manu Abraham) Signed-off-by: Johannes Stezenbach <js@linuxtv.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/dvb/bt8xx/Kconfig3
-rw-r--r--drivers/media/dvb/bt8xx/Makefile4
-rw-r--r--drivers/media/dvb/bt8xx/bt878.c18
-rw-r--r--drivers/media/dvb/bt8xx/dst.c832
-rw-r--r--drivers/media/dvb/bt8xx/dst.h40
-rw-r--r--drivers/media/dvb/bt8xx/dst_ca.c868
-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.c101
-rw-r--r--drivers/media/dvb/bt8xx/dvb-bt8xx.h2
11 files changed, 1703 insertions, 377 deletions
diff --git a/drivers/media/dvb/bt8xx/Kconfig b/drivers/media/dvb/bt8xx/Kconfig
index e7d11e0667a..b12545f093f 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 9da8604b9e1..d188e4c670b 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 213ff790202..7e51530b587 100644
--- a/drivers/media/dvb/bt8xx/bt878.c
+++ b/drivers/media/dvb/bt8xx/bt878.c
@@ -4,8 +4,8 @@
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
@@ -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/dst.c b/drivers/media/dvb/bt8xx/dst.c
index eac83768dfd..a28b7351eac 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,28 @@
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 35
36struct dst_state { 36
37 37static unsigned int verbose = 1;
38 struct i2c_adapter* i2c; 38module_param(verbose, int, 0644);
39 39MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)");
40 struct bt878* bt; 40
41 41static unsigned int debug = 1;
42 struct dvb_frontend_ops ops; 42module_param(debug, int, 0644);
43 43MODULE_PARM_DESC(debug, "debug messages, default is 0 (yes)");
44 /* configuration settings */ 44
45 const struct dst_config* config; 45static unsigned int dst_addons;
46 46module_param(dst_addons, int, 0644);
47 struct dvb_frontend frontend; 47MODULE_PARM_DESC(dst_addons, "CA daughterboard, default is 0 (no)");
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 48
71static unsigned int dst_verbose = 0; 49static unsigned int new_fw;
72module_param(dst_verbose, int, 0644); 50module_param(new_fw, int, 0644);
73MODULE_PARM_DESC(dst_verbose, "verbose startup messages, default is 1 (yes)"); 51MODULE_PARM_DESC(new_fw, "Support for the new interface firmware, default 0");
74static unsigned int dst_debug = 0;
75module_param(dst_debug, int, 0644);
76MODULE_PARM_DESC(dst_debug, "debug messages, default is 0 (no)");
77 52
78#define dprintk if (dst_debug) printk
79 53
80#define DST_TYPE_IS_SAT 0
81#define DST_TYPE_IS_TERR 1
82#define DST_TYPE_IS_CABLE 2
83 54
84#define DST_TYPE_HAS_NEWTUNE 1 55#define dprintk if (debug) printk
85#define DST_TYPE_HAS_TS204 2
86#define DST_TYPE_HAS_SYMDIV 4
87 56
88#define HAS_LOCK 1 57#define HAS_LOCK 1
89#define ATTEMPT_TUNE 2 58#define ATTEMPT_TUNE 2
@@ -97,7 +66,7 @@ static void dst_packsize(struct dst_state* state, int psize)
97 bt878_device_control(state->bt, DST_IG_TS, &bits); 66 bt878_device_control(state->bt, DST_IG_TS, &bits);
98} 67}
99 68
100static int dst_gpio_outb(struct dst_state* state, u32 mask, u32 enbb, u32 outhigh) 69int dst_gpio_outb(struct dst_state* state, u32 mask, u32 enbb, u32 outhigh, int delay)
101{ 70{
102 union dst_gpio_packet enb; 71 union dst_gpio_packet enb;
103 union dst_gpio_packet bits; 72 union dst_gpio_packet bits;
@@ -105,26 +74,35 @@ static int dst_gpio_outb(struct dst_state* state, u32 mask, u32 enbb, u32 outhig
105 74
106 enb.enb.mask = mask; 75 enb.enb.mask = mask;
107 enb.enb.enable = enbb; 76 enb.enb.enable = enbb;
77 if (verbose > 4)
78 dprintk("%s: mask=[%04x], enbb=[%04x], outhigh=[%04x]\n", __FUNCTION__, mask, enbb, outhigh);
79
108 if ((err = bt878_device_control(state->bt, DST_IG_ENABLE, &enb)) < 0) { 80 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); 81 dprintk("%s: dst_gpio_enb error (err == %i, mask == %02x, enb == %02x)\n", __FUNCTION__, err, mask, enbb);
110 return -EREMOTEIO; 82 return -EREMOTEIO;
111 } 83 }
112 84
85 msleep(1);
86
113 /* because complete disabling means no output, no need to do output packet */ 87 /* because complete disabling means no output, no need to do output packet */
114 if (enbb == 0) 88 if (enbb == 0)
115 return 0; 89 return 0;
116 90
91 if (delay)
92 msleep(10);
93
117 bits.outp.mask = enbb; 94 bits.outp.mask = enbb;
118 bits.outp.highvals = outhigh; 95 bits.outp.highvals = outhigh;
119 96
120 if ((err = bt878_device_control(state->bt, DST_IG_WRITE, &bits)) < 0) { 97 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); 98 dprintk("%s: dst_gpio_outb error (err == %i, enbb == %02x, outhigh == %02x)\n", __FUNCTION__, err, enbb, outhigh);
122 return -EREMOTEIO; 99 return -EREMOTEIO;
123 } 100 }
124 return 0; 101 return 0;
125} 102}
103EXPORT_SYMBOL(dst_gpio_outb);
126 104
127static int dst_gpio_inb(struct dst_state *state, u8 * result) 105int dst_gpio_inb(struct dst_state *state, u8 * result)
128{ 106{
129 union dst_gpio_packet rd_packet; 107 union dst_gpio_packet rd_packet;
130 int err; 108 int err;
@@ -139,135 +117,211 @@ static int dst_gpio_inb(struct dst_state *state, u8 * result)
139 *result = (u8) rd_packet.rd.value; 117 *result = (u8) rd_packet.rd.value;
140 return 0; 118 return 0;
141} 119}
120EXPORT_SYMBOL(dst_gpio_inb);
142 121
143#define DST_I2C_ENABLE 1 122int rdc_reset_state(struct dst_state *state)
144#define DST_8820 2
145
146static int dst_reset8820(struct dst_state *state)
147{ 123{
148 int retval; 124 if (verbose > 1)
149 /* pull 8820 gpio pin low, wait, high, wait, then low */ 125 dprintk("%s: Resetting state machine\n", __FUNCTION__);
150 // dprintk ("%s: reset 8820\n", __FUNCTION__); 126
151 retval = dst_gpio_outb(state, DST_8820, DST_8820, 0); 127 if (dst_gpio_outb(state, RDC_8820_INT, RDC_8820_INT, 0, NO_DELAY) < 0) {
152 if (retval < 0) 128 dprintk("%s: dst_gpio_outb ERROR !\n", __FUNCTION__);
153 return retval; 129 return -1;
130 }
131
154 msleep(10); 132 msleep(10);
155 retval = dst_gpio_outb(state, DST_8820, DST_8820, DST_8820); 133
156 if (retval < 0) 134 if (dst_gpio_outb(state, RDC_8820_INT, RDC_8820_INT, RDC_8820_INT, NO_DELAY) < 0) {
157 return retval; 135 dprintk("%s: dst_gpio_outb ERROR !\n", __FUNCTION__);
158 /* wait for more feedback on what works here * 136 msleep(10);
159 msleep(10); 137 return -1;
160 retval = dst_gpio_outb(dst, DST_8820, DST_8820, 0); 138 }
161 if (retval < 0) 139
162 return retval;
163 */
164 return 0; 140 return 0;
165} 141}
142EXPORT_SYMBOL(rdc_reset_state);
166 143
167static int dst_i2c_enable(struct dst_state *state) 144int rdc_8820_reset(struct dst_state *state)
168{ 145{
169 int retval; 146 if (verbose > 1)
170 /* pull I2C enable gpio pin low, wait */ 147 dprintk("%s: Resetting DST\n", __FUNCTION__);
171 // dprintk ("%s: i2c enable\n", __FUNCTION__); 148
172 retval = dst_gpio_outb(state, ~0, DST_I2C_ENABLE, 0); 149 if (dst_gpio_outb(state, RDC_8820_RESET, RDC_8820_RESET, 0, NO_DELAY) < 0) {
173 if (retval < 0) 150 dprintk("%s: dst_gpio_outb ERROR !\n", __FUNCTION__);
174 return retval; 151 return -1;
175 // dprintk ("%s: i2c enable delay\n", __FUNCTION__); 152 }
176 msleep(33); 153 msleep(1);
154
155 if (dst_gpio_outb(state, RDC_8820_RESET, RDC_8820_RESET, RDC_8820_RESET, DELAY) < 0) {
156 dprintk("%s: dst_gpio_outb ERROR !\n", __FUNCTION__);
157 return -1;
158 }
159
177 return 0; 160 return 0;
178} 161}
162EXPORT_SYMBOL(rdc_8820_reset);
179 163
180static int dst_i2c_disable(struct dst_state *state) 164int dst_pio_enable(struct dst_state *state)
181{ 165{
182 int retval; 166 if (dst_gpio_outb(state, ~0, RDC_8820_PIO_0_ENABLE, 0, NO_DELAY) < 0) {
183 /* release I2C enable gpio pin, wait */ 167 dprintk("%s: dst_gpio_outb ERROR !\n", __FUNCTION__);
184 // dprintk ("%s: i2c disable\n", __FUNCTION__); 168 return -1;
185 retval = dst_gpio_outb(state, ~0, 0, 0); 169 }
186 if (retval < 0) 170 msleep(1);
187 return retval; 171
188 // dprintk ("%s: i2c disable delay\n", __FUNCTION__); 172 return 0;
189 msleep(33); 173}
174EXPORT_SYMBOL(dst_pio_enable);
175
176int dst_pio_disable(struct dst_state *state)
177{
178 if (dst_gpio_outb(state, ~0, RDC_8820_PIO_0_DISABLE, RDC_8820_PIO_0_DISABLE, NO_DELAY) < 0) {
179 dprintk("%s: dst_gpio_outb ERROR !\n", __FUNCTION__);
180 return -1;
181 }
182
190 return 0; 183 return 0;
191} 184}
185EXPORT_SYMBOL(dst_pio_disable);
192 186
193static int dst_wait_dst_ready(struct dst_state *state) 187int dst_wait_dst_ready(struct dst_state *state, u8 delay_mode)
194{ 188{
195 u8 reply; 189 u8 reply;
196 int retval;
197 int i; 190 int i;
191
198 for (i = 0; i < 200; i++) { 192 for (i = 0; i < 200; i++) {
199 retval = dst_gpio_inb(state, &reply); 193 if (dst_gpio_inb(state, &reply) < 0) {
200 if (retval < 0) 194 dprintk("%s: dst_gpio_inb ERROR !\n", __FUNCTION__);
201 return retval; 195 return -1;
202 if ((reply & DST_I2C_ENABLE) == 0) { 196 }
203 dprintk("%s: dst wait ready after %d\n", __FUNCTION__, i); 197
198 if ((reply & RDC_8820_PIO_0_ENABLE) == 0) {
199 if (verbose > 4)
200 dprintk("%s: dst wait ready after %d\n", __FUNCTION__, i);
204 return 1; 201 return 1;
205 } 202 }
206 msleep(10); 203 msleep(1);
204 }
205 if (verbose > 1)
206 dprintk("%s: dst wait NOT ready after %d\n", __FUNCTION__, i);
207
208 return 0;
209}
210EXPORT_SYMBOL(dst_wait_dst_ready);
211
212int dst_error_recovery(struct dst_state *state)
213{
214 dprintk("%s: Trying to return from previous errors...\n", __FUNCTION__);
215 dst_pio_disable(state);
216 msleep(10);
217 dst_pio_enable(state);
218 msleep(10);
219
220 return 0;
221}
222EXPORT_SYMBOL(dst_error_recovery);
223
224int dst_error_bailout(struct dst_state *state)
225{
226 dprintk("%s: Trying to bailout from previous error...\n", __FUNCTION__);
227 rdc_8820_reset(state);
228 dst_pio_disable(state);
229 msleep(10);
230
231 return 0;
232}
233EXPORT_SYMBOL(dst_error_bailout);
234
235
236int dst_comm_init(struct dst_state* state)
237{
238 if (verbose > 1)
239 dprintk ("%s: Initializing DST..\n", __FUNCTION__);
240 if ((dst_pio_enable(state)) < 0) {
241 dprintk("%s: PIO Enable Failed.\n", __FUNCTION__);
242 return -1;
243 }
244 if ((rdc_reset_state(state)) < 0) {
245 dprintk("%s: RDC 8820 State RESET Failed.\n", __FUNCTION__);
246 return -1;
207 } 247 }
208 dprintk("%s: dst wait NOT ready after %d\n", __FUNCTION__, i);
209 return 0; 248 return 0;
210} 249}
250EXPORT_SYMBOL(dst_comm_init);
211 251
212static int write_dst(struct dst_state *state, u8 * data, u8 len) 252
253int write_dst(struct dst_state *state, u8 *data, u8 len)
213{ 254{
214 struct i2c_msg msg = { 255 struct i2c_msg msg = {
215 .addr = state->config->demod_address,.flags = 0,.buf = data,.len = len 256 .addr = state->config->demod_address,.flags = 0,.buf = data,.len = len
216 }; 257 };
258
217 int err; 259 int err;
218 int cnt; 260 int cnt;
219 261 if (debug && (verbose > 4)) {
220 if (dst_debug && dst_verbose) {
221 u8 i; 262 u8 i;
222 dprintk("%s writing", __FUNCTION__); 263 if (verbose > 4) {
223 for (i = 0; i < len; i++) { 264 dprintk("%s writing", __FUNCTION__);
224 dprintk(" 0x%02x", data[i]); 265 for (i = 0; i < len; i++)
266 dprintk(" %02x", data[i]);
267 dprintk("\n");
225 } 268 }
226 dprintk("\n");
227 } 269 }
228 msleep(30); 270 for (cnt = 0; cnt < 2; cnt++) {
229 for (cnt = 0; cnt < 4; cnt++) {
230 if ((err = i2c_transfer(state->i2c, &msg, 1)) < 0) { 271 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]); 272 dprintk("%s: _write_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)\n", __FUNCTION__, err, len, data[0]);
232 dst_i2c_disable(state); 273 dst_error_recovery(state);
233 msleep(500);
234 dst_i2c_enable(state);
235 msleep(500);
236 continue; 274 continue;
237 } else 275 } else
238 break; 276 break;
239 } 277 }
240 if (cnt >= 4) 278
241 return -EREMOTEIO; 279 if (cnt >= 2) {
280 if (verbose > 1)
281 printk("%s: RDC 8820 RESET...\n", __FUNCTION__);
282 dst_error_bailout(state);
283
284 return -1;
285 }
286
242 return 0; 287 return 0;
243} 288}
289EXPORT_SYMBOL(write_dst);
244 290
245static int read_dst(struct dst_state *state, u8 * ret, u8 len) 291int read_dst(struct dst_state *state, u8 * ret, u8 len)
246{ 292{
247 struct i2c_msg msg = {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = ret,.len = len }; 293 struct i2c_msg msg = {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = ret,.len = len };
248 int err; 294 int err;
249 int cnt; 295 int cnt;
250 296
251 for (cnt = 0; cnt < 4; cnt++) { 297 for (cnt = 0; cnt < 2; cnt++) {
252 if ((err = i2c_transfer(state->i2c, &msg, 1)) < 0) { 298 if ((err = i2c_transfer(state->i2c, &msg, 1)) < 0) {
299
253 dprintk("%s: read_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)\n", __FUNCTION__, err, len, ret[0]); 300 dprintk("%s: read_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)\n", __FUNCTION__, err, len, ret[0]);
254 dst_i2c_disable(state); 301 dst_error_recovery(state);
255 dst_i2c_enable(state); 302
256 continue; 303 continue;
257 } else 304 } else
258 break; 305 break;
259 } 306 }
260 if (cnt >= 4) 307 if (cnt >= 2) {
261 return -EREMOTEIO; 308 if (verbose > 1)
262 dprintk("%s reply is 0x%x\n", __FUNCTION__, ret[0]); 309 printk("%s: RDC 8820 RESET...\n", __FUNCTION__);
263 if (dst_debug && dst_verbose) { 310 dst_error_bailout(state);
311
312 return -1;
313 }
314 if (debug && (verbose > 4)) {
315 dprintk("%s reply is 0x%x\n", __FUNCTION__, ret[0]);
264 for (err = 1; err < len; err++) 316 for (err = 1; err < len; err++)
265 dprintk(" 0x%x", ret[err]); 317 dprintk(" 0x%x", ret[err]);
266 if (err > 1) 318 if (err > 1)
267 dprintk("\n"); 319 dprintk("\n");
268 } 320 }
321
269 return 0; 322 return 0;
270} 323}
324EXPORT_SYMBOL(read_dst);
271 325
272static int dst_set_freq(struct dst_state *state, u32 freq) 326static int dst_set_freq(struct dst_state *state, u32 freq)
273{ 327{
@@ -422,7 +476,7 @@ static int dst_set_symbolrate(struct dst_state* state, u32 srate)
422 return 0; 476 return 0;
423} 477}
424 478
425static u8 dst_check_sum(u8 * buf, u32 len) 479u8 dst_check_sum(u8 * buf, u32 len)
426{ 480{
427 u32 i; 481 u32 i;
428 u8 val = 0; 482 u8 val = 0;
@@ -433,28 +487,7 @@ static u8 dst_check_sum(u8 * buf, u32 len)
433 } 487 }
434 return ((~val) + 1); 488 return ((~val) + 1);
435} 489}
436 490EXPORT_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 491
459static void dst_type_flags_print(u32 type_flags) 492static void dst_type_flags_print(u32 type_flags)
460{ 493{
@@ -465,93 +498,260 @@ static void dst_type_flags_print(u32 type_flags)
465 printk(" 0x%x ts204", DST_TYPE_HAS_TS204); 498 printk(" 0x%x ts204", DST_TYPE_HAS_TS204);
466 if (type_flags & DST_TYPE_HAS_SYMDIV) 499 if (type_flags & DST_TYPE_HAS_SYMDIV)
467 printk(" 0x%x symdiv", DST_TYPE_HAS_SYMDIV); 500 printk(" 0x%x symdiv", DST_TYPE_HAS_SYMDIV);
501 if (type_flags & DST_TYPE_HAS_FW_1)
502 printk(" 0x%x firmware version = 1", DST_TYPE_HAS_FW_1);
503 if (type_flags & DST_TYPE_HAS_FW_2)
504 printk(" 0x%x firmware version = 2", DST_TYPE_HAS_FW_2);
505 if (type_flags & DST_TYPE_HAS_FW_3)
506 printk(" 0x%x firmware version = 3", DST_TYPE_HAS_FW_3);
507
468 printk("\n"); 508 printk("\n");
469} 509}
470 510
471static int dst_type_print(u8 type) 511
512static int dst_type_print (u8 type)
472{ 513{
473 char *otype; 514 char *otype;
474 switch (type) { 515 switch (type) {
475 case DST_TYPE_IS_SAT: 516 case DST_TYPE_IS_SAT:
476 otype = "satellite"; 517 otype = "satellite";
477 break; 518 break;
519
478 case DST_TYPE_IS_TERR: 520 case DST_TYPE_IS_TERR:
479 otype = "terrestrial"; 521 otype = "terrestrial";
480 break; 522 break;
523
481 case DST_TYPE_IS_CABLE: 524 case DST_TYPE_IS_CABLE:
482 otype = "cable"; 525 otype = "cable";
483 break; 526 break;
527
484 default: 528 default:
485 printk("%s: invalid dst type %d\n", __FUNCTION__, type); 529 printk("%s: invalid dst type %d\n", __FUNCTION__, type);
486 return -EINVAL; 530 return -EINVAL;
487 } 531 }
488 printk("DST type : %s\n", otype); 532 printk("DST type : %s\n", otype);
533
489 return 0; 534 return 0;
490} 535}
491 536
492static int dst_check_ci(struct dst_state *state) 537/*
538 Known cards list
539 Satellite
540 -------------------
541
542 VP-1020 DST-MOT LG(old), TS=188
543
544 VP-1020 DST-03T LG(new), TS=204
545 VP-1022 DST-03T LG(new), TS=204
546 VP-1025 DST-03T LG(new), TS=204
547
548 VP-1030 DSTMCI, LG(new), TS=188
549 VP-1032 DSTMCI, LG(new), TS=188
550
551 Cable
552 -------------------
553 VP-2030 DCT-CI, Samsung, TS=204
554 VP-2021 DCT-CI, Unknown, TS=204
555 VP-2031 DCT-CI, Philips, TS=188
556 VP-2040 DCT-CI, Philips, TS=188, with CA daughter board
557 VP-2040 DCT-CI, Philips, TS=204, without CA daughter board
558
559 Terrestrial
560 -------------------
561 VP-3050 DTTNXT TS=188
562 VP-3040 DTT-CI, Philips, TS=188
563 VP-3040 DTT-CI, Philips, TS=204
564
565 ATSC
566 -------------------
567 VP-3220 ATSCDI, TS=188
568 VP-3250 ATSCAD, TS=188
569
570*/
571
572struct dst_types dst_tlist[] = {
573 {
574 .device_id = "DST-020",
575 .offset = 0,
576 .dst_type = DST_TYPE_IS_SAT,
577 .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1,
578 .dst_feature = 0
579 }, /* obsolete */
580
581 {
582 .device_id = "DST-030",
583 .offset = 0,
584 .dst_type = DST_TYPE_IS_SAT,
585 .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_1,
586 .dst_feature = 0
587 }, /* obsolete */
588
589 {
590 .device_id = "DST-03T",
591 .offset = 0,
592 .dst_type = DST_TYPE_IS_SAT,
593 .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_2,
594 .dst_feature = DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4 | DST_TYPE_HAS_DISEQC5
595 | DST_TYPE_HAS_MAC | DST_TYPE_HAS_MOTO
596 },
597
598 {
599 .device_id = "DST-MOT",
600 .offset = 0,
601 .dst_type = DST_TYPE_IS_SAT,
602 .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1,
603 .dst_feature = 0
604 }, /* obsolete */
605
606 {
607 .device_id = "DST-CI",
608 .offset = 1,
609 .dst_type = DST_TYPE_IS_SAT,
610 .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_1,
611 .dst_feature = DST_TYPE_HAS_CA
612 }, /* unknown to vendor */
613
614 {
615 .device_id = "DSTMCI",
616 .offset = 1,
617 .dst_type = DST_TYPE_IS_SAT,
618 .type_flags = DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_2,
619 .dst_feature = DST_TYPE_HAS_CA | DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4
620 | DST_TYPE_HAS_MOTO | DST_TYPE_HAS_MAC
621 },
622
623 {
624 .device_id = "DSTFCI",
625 .offset = 1,
626 .dst_type = DST_TYPE_IS_SAT,
627 .type_flags = DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_1,
628 .dst_feature = 0
629 }, /* unknown to vendor */
630
631 {
632 .device_id = "DCT-CI",
633 .offset = 1,
634 .dst_type = DST_TYPE_IS_CABLE,
635 .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_1 | DST_TYPE_HAS_FW_2,
636 .dst_feature = DST_TYPE_HAS_CA
637 },
638
639 {
640 .device_id = "DCTNEW",
641 .offset = 1,
642 .dst_type = DST_TYPE_IS_CABLE,
643 .type_flags = DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_3,
644 .dst_feature = 0
645 },
646
647 {
648 .device_id = "DTT-CI",
649 .offset = 1,
650 .dst_type = DST_TYPE_IS_TERR,
651 .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_2,
652 .dst_feature = 0
653 },
654
655 {
656 .device_id = "DTTDIG",
657 .offset = 1,
658 .dst_type = DST_TYPE_IS_TERR,
659 .type_flags = DST_TYPE_HAS_FW_2,
660 .dst_feature = 0
661 },
662
663 {
664 .device_id = "DTTNXT",
665 .offset = 1,
666 .dst_type = DST_TYPE_IS_TERR,
667 .type_flags = DST_TYPE_HAS_FW_2,
668 .dst_feature = DST_TYPE_HAS_ANALOG
669 },
670
671 {
672 .device_id = "ATSCDI",
673 .offset = 1,
674 .dst_type = DST_TYPE_IS_ATSC,
675 .type_flags = DST_TYPE_HAS_FW_2,
676 .dst_feature = 0
677 },
678
679 {
680 .device_id = "ATSCAD",
681 .offset = 1,
682 .dst_type = DST_TYPE_IS_ATSC,
683 .type_flags = DST_TYPE_HAS_FW_2,
684 .dst_feature = 0
685 },
686
687 { }
688
689};
690
691
692static int dst_get_device_id(struct dst_state *state)
493{ 693{
494 u8 txbuf[8]; 694 u8 reply;
495 u8 rxbuf[8]; 695
496 int retval;
497 int i; 696 int i;
498 struct dst_types *dsp; 697 struct dst_types *p_dst_type;
499 u8 use_dst_type; 698 u8 use_dst_type = 0;
500 u32 use_type_flags; 699 u32 use_type_flags = 0;
501 700
502 memset(txbuf, 0, sizeof(txbuf)); 701 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 702
506 dst_i2c_enable(state); 703 device_type[7] = dst_check_sum(device_type, 7);
507 dst_reset8820(state); 704
508 retval = write_dst(state, txbuf, 8); 705 if (write_dst(state, device_type, FIXED_COMM))
509 if (retval < 0) { 706 return -1; /* Write failed */
510 dst_i2c_disable(state); 707
511 dprintk("%s: write not successful, maybe no card?\n", __FUNCTION__); 708 if ((dst_pio_disable(state)) < 0)
512 return retval; 709 return -1;
513 } 710
514 msleep(3); 711 if (read_dst(state, &reply, GET_ACK))
515 retval = read_dst(state, rxbuf, 1); 712 return -1; /* Read failure */
516 dst_i2c_disable(state); 713
517 if (retval < 0) { 714 if (reply != ACK) {
518 dprintk("%s: read not successful, maybe no card?\n", __FUNCTION__); 715 dprintk("%s: Write not Acknowledged! [Reply=0x%02x]\n", __FUNCTION__, reply);
519 return retval; 716 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 } 717 }
534 if (rxbuf[7] != dst_check_sum(rxbuf, 7)) { 718
535 dprintk("%s: checksum failure\n", __FUNCTION__); 719 if (!dst_wait_dst_ready(state, DEVICE_INIT))
536 return retval; 720 return -1; /* DST not ready yet */
721
722 if (read_dst(state, state->rxbuffer, FIXED_COMM))
723 return -1;
724
725 dst_pio_disable(state);
726
727 if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) {
728 dprintk("%s: Checksum failure! \n", __FUNCTION__);
729 return -1; /* Checksum failure */
537 } 730 }
538 rxbuf[7] = '\0'; 731
539 for (i = 0, dsp = &dst_tlist[0]; i < sizeof(dst_tlist) / sizeof(dst_tlist[0]); i++, dsp++) { 732 state->rxbuffer[7] = '\0';
540 if (!strncmp(&rxbuf[dsp->offs], dsp->mstr, strlen(dsp->mstr))) { 733
541 use_type_flags = dsp->type_flags; 734 for (i = 0, p_dst_type = dst_tlist; i < ARRAY_SIZE (dst_tlist); i++, p_dst_type++) {
542 use_dst_type = dsp->dst_type; 735 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); 736 use_type_flags = p_dst_type->type_flags;
737 use_dst_type = p_dst_type->dst_type;
738
739 /* Card capabilities */
740 state->dst_hw_cap = p_dst_type->dst_feature;
741 printk ("%s: Recognise [%s]\n", __FUNCTION__, p_dst_type->device_id);
742
544 break; 743 break;
545 } 744 }
546 } 745 }
547 if (i >= sizeof(dst_tlist) / sizeof(dst_tlist[0])) { 746
548 printk("%s: unable to recognize %s or %s\n", __FUNCTION__, &rxbuf[0], &rxbuf[1]); 747 if (i >= sizeof (dst_tlist) / sizeof (dst_tlist [0])) {
549 printk("%s please email linux-dvb@linuxtv.org with this type in\n", __FUNCTION__); 748 printk("%s: Unable to recognize %s or %s\n", __FUNCTION__, &state->rxbuffer[0], &state->rxbuffer[1]);
749 printk("%s: please email linux-dvb@linuxtv.org with this type in\n", __FUNCTION__);
550 use_dst_type = DST_TYPE_IS_SAT; 750 use_dst_type = DST_TYPE_IS_SAT;
551 use_type_flags = DST_TYPE_HAS_SYMDIV; 751 use_type_flags = DST_TYPE_HAS_SYMDIV;
552 } 752 }
553 dst_type_print(use_dst_type);
554 753
754 dst_type_print(use_dst_type);
555 state->type_flags = use_type_flags; 755 state->type_flags = use_type_flags;
556 state->dst_type = use_dst_type; 756 state->dst_type = use_dst_type;
557 dst_type_flags_print(state->type_flags); 757 dst_type_flags_print(state->type_flags);
@@ -559,50 +759,89 @@ static int dst_check_ci(struct dst_state *state)
559 if (state->type_flags & DST_TYPE_HAS_TS204) { 759 if (state->type_flags & DST_TYPE_HAS_TS204) {
560 dst_packsize(state, 204); 760 dst_packsize(state, 204);
561 } 761 }
762
562 return 0; 763 return 0;
563} 764}
564 765
565static int dst_command(struct dst_state* state, u8 * data, u8 len) 766static int dst_probe(struct dst_state *state)
767{
768 if ((rdc_8820_reset(state)) < 0) {
769 dprintk("%s: RDC 8820 RESET Failed.\n", __FUNCTION__);
770 return -1;
771 }
772 msleep(4000);
773 if ((dst_comm_init(state)) < 0) {
774 dprintk("%s: DST Initialization Failed.\n", __FUNCTION__);
775 return -1;
776 }
777
778 if (dst_get_device_id(state) < 0) {
779 dprintk("%s: unknown device.\n", __FUNCTION__);
780 return -1;
781 }
782
783 return 0;
784}
785
786int dst_command(struct dst_state* state, u8 * data, u8 len)
566{ 787{
567 int retval;
568 u8 reply; 788 u8 reply;
789 if ((dst_comm_init(state)) < 0) {
790 dprintk("%s: DST Communication Initialization Failed.\n", __FUNCTION__);
791 return -1;
792 }
569 793
570 dst_i2c_enable(state); 794 if (write_dst(state, data, len)) {
571 dst_reset8820(state); 795 if (verbose > 1)
572 retval = write_dst(state, data, len); 796 dprintk("%s: Tring to recover.. \n", __FUNCTION__);
573 if (retval < 0) { 797 if ((dst_error_recovery(state)) < 0) {
574 dst_i2c_disable(state); 798 dprintk("%s: Recovery Failed.\n", __FUNCTION__);
575 dprintk("%s: write not successful\n", __FUNCTION__); 799 return -1;
576 return retval; 800 }
801 return -1;
577 } 802 }
578 msleep(33); 803 if ((dst_pio_disable(state)) < 0) {
579 retval = read_dst(state, &reply, 1); 804 dprintk("%s: PIO Disable Failed.\n", __FUNCTION__);
580 dst_i2c_disable(state); 805 return -1;
581 if (retval < 0) {
582 dprintk("%s: read verify not successful\n", __FUNCTION__);
583 return retval;
584 } 806 }
585 if (reply != 0xff) { 807
586 dprintk("%s: write reply not 0xff 0x%02x \n", __FUNCTION__, reply); 808 if (read_dst(state, &reply, GET_ACK)) {
587 return 0; 809 if (verbose > 1)
810 dprintk("%s: Trying to recover.. \n", __FUNCTION__);
811 if ((dst_error_recovery(state)) < 0) {
812 dprintk("%s: Recovery Failed.\n", __FUNCTION__);
813 return -1;
814 }
815 return -1;
816 }
817
818 if (reply != ACK) {
819 dprintk("%s: write not acknowledged 0x%02x \n", __FUNCTION__, reply);
820 return -1;
588 } 821 }
589 if (len >= 2 && data[0] == 0 && (data[1] == 1 || data[1] == 3)) 822 if (len >= 2 && data[0] == 0 && (data[1] == 1 || data[1] == 3))
590 return 0; 823 return 0;
591 if (!dst_wait_dst_ready(state)) 824 if (!dst_wait_dst_ready(state, NO_DELAY))
592 return 0; 825 return -1;
593 // dst_i2c_enable(i2c); Per dimitri 826
594 retval = read_dst(state, state->rxbuffer, 8); 827 if (read_dst(state, state->rxbuffer, FIXED_COMM)) {
595 dst_i2c_disable(state); 828 if (verbose > 1)
596 if (retval < 0) { 829 dprintk("%s: Trying to recover.. \n", __FUNCTION__);
597 dprintk("%s: read not successful\n", __FUNCTION__); 830 if ((dst_error_recovery(state)) < 0) {
598 return 0; 831 dprintk("%s: Recovery failed.\n", __FUNCTION__);
832 return -1;
833 }
834 return -1;
599 } 835 }
836
600 if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) { 837 if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) {
601 dprintk("%s: checksum failure\n", __FUNCTION__); 838 dprintk("%s: checksum failure\n", __FUNCTION__);
602 return 0; 839 return -1;
603 } 840 }
841
604 return 0; 842 return 0;
605} 843}
844EXPORT_SYMBOL(dst_command);
606 845
607static int dst_get_signal(struct dst_state* state) 846static int dst_get_signal(struct dst_state* state)
608{ 847{
@@ -646,11 +885,17 @@ static int dst_tone_power_cmd(struct dst_state* state)
646 paket[4] = 0; 885 paket[4] = 0;
647 else 886 else
648 paket[4] = 1; 887 paket[4] = 1;
888
649 if (state->tone == SEC_TONE_ON) 889 if (state->tone == SEC_TONE_ON)
650 paket[2] = state->k22; 890 paket[2] = 0x02;
651 else 891 else
652 paket[2] = 0; 892 paket[2] = 0;
653 paket[7] = dst_check_sum(&paket[0], 7); 893 if (state->minicmd == SEC_MINI_A)
894 paket[3] = 0x02;
895 else
896 paket[3] = 0;
897
898 paket[7] = dst_check_sum (paket, 7);
654 dst_command(state, paket, 8); 899 dst_command(state, paket, 8);
655 return 0; 900 return 0;
656} 901}
@@ -658,21 +903,28 @@ static int dst_tone_power_cmd(struct dst_state* state)
658static int dst_get_tuna(struct dst_state* state) 903static int dst_get_tuna(struct dst_state* state)
659{ 904{
660 int retval; 905 int retval;
906
661 if ((state->diseq_flags & ATTEMPT_TUNE) == 0) 907 if ((state->diseq_flags & ATTEMPT_TUNE) == 0)
662 return 0; 908 return 0;
909
663 state->diseq_flags &= ~(HAS_LOCK); 910 state->diseq_flags &= ~(HAS_LOCK);
664 if (!dst_wait_dst_ready(state)) 911 if (!dst_wait_dst_ready(state, NO_DELAY))
665 return 0; 912 return 0;
913
914 msleep(10);
915
666 if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { 916 if (state->type_flags & DST_TYPE_HAS_NEWTUNE) {
667 /* how to get variable length reply ???? */ 917 /* how to get variable length reply ???? */
668 retval = read_dst(state, state->rx_tuna, 10); 918 retval = read_dst(state, state->rx_tuna, 10);
669 } else { 919 } else {
670 retval = read_dst(state, &state->rx_tuna[2], 8); 920 retval = read_dst(state, &state->rx_tuna[2], FIXED_COMM);
671 } 921 }
922
672 if (retval < 0) { 923 if (retval < 0) {
673 dprintk("%s: read not successful\n", __FUNCTION__); 924 dprintk("%s: read not successful\n", __FUNCTION__);
674 return 0; 925 return 0;
675 } 926 }
927
676 if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { 928 if (state->type_flags & DST_TYPE_HAS_NEWTUNE) {
677 if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) { 929 if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) {
678 dprintk("%s: checksum failure?\n", __FUNCTION__); 930 dprintk("%s: checksum failure?\n", __FUNCTION__);
@@ -717,32 +969,41 @@ static int dst_write_tuna(struct dvb_frontend* fe)
717 dst_set_voltage(fe, SEC_VOLTAGE_13); 969 dst_set_voltage(fe, SEC_VOLTAGE_13);
718 } 970 }
719 state->diseq_flags &= ~(HAS_LOCK | ATTEMPT_TUNE); 971 state->diseq_flags &= ~(HAS_LOCK | ATTEMPT_TUNE);
720 dst_i2c_enable(state); 972
973 if ((dst_comm_init(state)) < 0) {
974 dprintk("%s: DST Communication initialization failed.\n", __FUNCTION__);
975 return -1;
976 }
977
721 if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { 978 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); 979 state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[0], 9);
724 retval = write_dst(state, &state->tx_tuna[0], 10); 980 retval = write_dst(state, &state->tx_tuna[0], 10);
981
725 } else { 982 } else {
726 state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[2], 7); 983 state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[2], 7);
727 retval = write_dst(state, &state->tx_tuna[2], 8); 984 retval = write_dst(state, &state->tx_tuna[2], FIXED_COMM);
728 } 985 }
729 if (retval < 0) { 986 if (retval < 0) {
730 dst_i2c_disable(state); 987 dst_pio_disable(state);
731 dprintk("%s: write not successful\n", __FUNCTION__); 988 dprintk("%s: write not successful\n", __FUNCTION__);
732 return retval; 989 return retval;
733 } 990 }
734 msleep(3); 991
735 retval = read_dst(state, &reply, 1); 992 if ((dst_pio_disable(state)) < 0) {
736 dst_i2c_disable(state); 993 dprintk("%s: DST PIO disable failed !\n", __FUNCTION__);
737 if (retval < 0) { 994 return -1;
738 dprintk("%s: read verify not successful\n", __FUNCTION__); 995 }
739 return retval; 996
997 if ((read_dst(state, &reply, GET_ACK) < 0)) {
998 dprintk("%s: read verify not successful.\n", __FUNCTION__);
999 return -1;
740 } 1000 }
741 if (reply != 0xff) { 1001 if (reply != ACK) {
742 dprintk("%s: write reply not 0xff 0x%02x \n", __FUNCTION__, reply); 1002 dprintk("%s: write not acknowledged 0x%02x \n", __FUNCTION__, reply);
743 return 0; 1003 return 0;
744 } 1004 }
745 state->diseq_flags |= ATTEMPT_TUNE; 1005 state->diseq_flags |= ATTEMPT_TUNE;
1006
746 return dst_get_tuna(state); 1007 return dst_get_tuna(state);
747} 1008}
748 1009
@@ -796,22 +1057,25 @@ static int dst_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
796 need_cmd = 1; 1057 need_cmd = 1;
797 state->diseq_flags |= HAS_POWER; 1058 state->diseq_flags |= HAS_POWER;
798 break; 1059 break;
1060
799 case SEC_VOLTAGE_18: 1061 case SEC_VOLTAGE_18:
800 if ((state->diseq_flags & HAS_POWER) == 0) 1062 if ((state->diseq_flags & HAS_POWER) == 0)
801 need_cmd = 1; 1063 need_cmd = 1;
802 state->diseq_flags |= HAS_POWER; 1064 state->diseq_flags |= HAS_POWER;
803 val[8] |= 0x40; 1065 val[8] |= 0x40;
804 break; 1066 break;
1067
805 case SEC_VOLTAGE_OFF: 1068 case SEC_VOLTAGE_OFF:
806 need_cmd = 1; 1069 need_cmd = 1;
807 state->diseq_flags &= ~(HAS_POWER | HAS_LOCK | ATTEMPT_TUNE); 1070 state->diseq_flags &= ~(HAS_POWER | HAS_LOCK | ATTEMPT_TUNE);
808 break; 1071 break;
1072
809 default: 1073 default:
810 return -EINVAL; 1074 return -EINVAL;
811 } 1075 }
812 if (need_cmd) { 1076 if (need_cmd)
813 dst_tone_power_cmd(state); 1077 dst_tone_power_cmd(state);
814 } 1078
815 return 0; 1079 return 0;
816} 1080}
817 1081
@@ -832,13 +1096,16 @@ static int dst_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
832 switch (tone) { 1096 switch (tone) {
833 case SEC_TONE_OFF: 1097 case SEC_TONE_OFF:
834 break; 1098 break;
1099
835 case SEC_TONE_ON: 1100 case SEC_TONE_ON:
836 val[8] |= 1; 1101 val[8] |= 1;
837 break; 1102 break;
1103
838 default: 1104 default:
839 return -EINVAL; 1105 return -EINVAL;
840 } 1106 }
841 dst_tone_power_cmd(state); 1107 dst_tone_power_cmd(state);
1108
842 return 0; 1109 return 0;
843} 1110}
844 1111
@@ -913,10 +1180,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; 1180 struct dst_state* state = (struct dst_state*) fe->demodulator_priv;
914 1181
915 dst_set_freq(state, p->frequency); 1182 dst_set_freq(state, p->frequency);
1183 if (verbose > 4)
1184 dprintk("Set Frequency = [%d]\n", p->frequency);
1185
916 dst_set_inversion(state, p->inversion); 1186 dst_set_inversion(state, p->inversion);
917 if (state->dst_type == DST_TYPE_IS_SAT) { 1187 if (state->dst_type == DST_TYPE_IS_SAT) {
918 dst_set_fec(state, p->u.qpsk.fec_inner); 1188 dst_set_fec(state, p->u.qpsk.fec_inner);
919 dst_set_symbolrate(state, p->u.qpsk.symbol_rate); 1189 dst_set_symbolrate(state, p->u.qpsk.symbol_rate);
1190 if (verbose > 4)
1191 dprintk("Set Symbolrate = [%d]\n", p->u.qpsk.symbol_rate);
1192
920 } else if (state->dst_type == DST_TYPE_IS_TERR) { 1193 } else if (state->dst_type == DST_TYPE_IS_TERR) {
921 dst_set_bandwidth(state, p->u.ofdm.bandwidth); 1194 dst_set_bandwidth(state, p->u.ofdm.bandwidth);
922 } else if (state->dst_type == DST_TYPE_IS_CABLE) { 1195 } else if (state->dst_type == DST_TYPE_IS_CABLE) {
@@ -958,50 +1231,47 @@ static struct dvb_frontend_ops dst_dvbt_ops;
958static struct dvb_frontend_ops dst_dvbs_ops; 1231static struct dvb_frontend_ops dst_dvbs_ops;
959static struct dvb_frontend_ops dst_dvbc_ops; 1232static struct dvb_frontend_ops dst_dvbc_ops;
960 1233
961struct dvb_frontend* dst_attach(const struct dst_config* config, 1234struct dst_state* dst_attach(struct dst_state *state, struct dvb_adapter *dvb_adapter)
962 struct i2c_adapter* i2c,
963 struct bt878 *bt)
964{ 1235{
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 1236
971 /* setup the state */ 1237 /* check if the ASIC is there */
972 state->config = config; 1238 if (dst_probe(state) < 0) {
973 state->i2c = i2c; 1239 if (state)
974 state->bt = bt; 1240 kfree(state);
975
976 /* check if the demod is there */
977 if (dst_check_ci(state) < 0) goto error;
978 1241
1242 return NULL;
1243 }
979 /* determine settings based on type */ 1244 /* determine settings based on type */
980 switch (state->dst_type) { 1245 switch (state->dst_type) {
981 case DST_TYPE_IS_TERR: 1246 case DST_TYPE_IS_TERR:
982 memcpy(&state->ops, &dst_dvbt_ops, sizeof(struct dvb_frontend_ops)); 1247 memcpy(&state->ops, &dst_dvbt_ops, sizeof(struct dvb_frontend_ops));
983 break; 1248 break;
1249
984 case DST_TYPE_IS_CABLE: 1250 case DST_TYPE_IS_CABLE:
985 memcpy(&state->ops, &dst_dvbc_ops, sizeof(struct dvb_frontend_ops)); 1251 memcpy(&state->ops, &dst_dvbc_ops, sizeof(struct dvb_frontend_ops));
986 break; 1252 break;
1253
987 case DST_TYPE_IS_SAT: 1254 case DST_TYPE_IS_SAT:
988 memcpy(&state->ops, &dst_dvbs_ops, sizeof(struct dvb_frontend_ops)); 1255 memcpy(&state->ops, &dst_dvbs_ops, sizeof(struct dvb_frontend_ops));
989 break; 1256 break;
1257
990 default: 1258 default:
991 printk("dst: unknown frontend type. please report to the LinuxTV.org DVB mailinglist.\n"); 1259 printk("%s: unknown DST type. please report to the LinuxTV.org DVB mailinglist.\n", __FUNCTION__);
992 goto error; 1260 if (state)
1261 kfree(state);
1262
1263 return NULL;
993 } 1264 }
994 1265
995 /* create dvb_frontend */ 1266 /* create dvb_frontend */
996 state->frontend.ops = &state->ops; 1267 state->frontend.ops = &state->ops;
997 state->frontend.demodulator_priv = state; 1268 state->frontend.demodulator_priv = state;
998 return &state->frontend;
999 1269
1000error: 1270 return state; /* Manu (DST is a card not a frontend) */
1001 kfree(state);
1002 return NULL;
1003} 1271}
1004 1272
1273EXPORT_SYMBOL(dst_attach);
1274
1005static struct dvb_frontend_ops dst_dvbt_ops = { 1275static struct dvb_frontend_ops dst_dvbt_ops = {
1006 1276
1007 .info = { 1277 .info = {
@@ -1051,6 +1321,7 @@ static struct dvb_frontend_ops dst_dvbs_ops = {
1051 .read_signal_strength = dst_read_signal_strength, 1321 .read_signal_strength = dst_read_signal_strength,
1052 .read_snr = dst_read_snr, 1322 .read_snr = dst_read_snr,
1053 1323
1324 .diseqc_send_burst = dst_set_tone,
1054 .diseqc_send_master_cmd = dst_set_diseqc, 1325 .diseqc_send_master_cmd = dst_set_diseqc,
1055 .set_voltage = dst_set_voltage, 1326 .set_voltage = dst_set_voltage,
1056 .set_tone = dst_set_tone, 1327 .set_tone = dst_set_tone,
@@ -1082,8 +1353,7 @@ static struct dvb_frontend_ops dst_dvbc_ops = {
1082 .read_snr = dst_read_snr, 1353 .read_snr = dst_read_snr,
1083}; 1354};
1084 1355
1356
1085MODULE_DESCRIPTION("DST DVB-S/T/C Combo Frontend driver"); 1357MODULE_DESCRIPTION("DST DVB-S/T/C Combo Frontend driver");
1086MODULE_AUTHOR("Jamie Honan"); 1358MODULE_AUTHOR("Jamie Honan, Manu Abraham");
1087MODULE_LICENSE("GPL"); 1359MODULE_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 bcb418c5c12..00000000000
--- 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 00000000000..206aee3336b
--- /dev/null
+++ b/drivers/media/dvb/bt8xx/dst_ca.c
@@ -0,0 +1,868 @@
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(dst_ca_debug, "debug messages, default is 0 (yes)");
42
43static unsigned int session;
44module_param(session, int, 0644);
45MODULE_PARM_DESC(session, "Support for hardware that has multiple sessions, default 0");
46
47static unsigned int new_ca;
48module_param(new_ca, int, 0644);
49MODULE_PARM_DESC(new_ca, "Support for the new CA interface firmware, default 0");
50
51#define dprintk if (debug) printk
52
53
54static int ca_set_slot_descr(void)
55{
56 /* We could make this more graceful ? */
57 return -EOPNOTSUPP;
58}
59
60static int ca_set_pid(void)
61{
62 /* We could make this more graceful ? */
63 return -EOPNOTSUPP;
64}
65
66
67static int put_checksum(u8 *check_string, int length)
68{
69 u8 i = 0, checksum = 0;
70
71 if (verbose > 3) {
72 dprintk("%s: ========================= Checksum calculation ===========================\n", __FUNCTION__);
73 dprintk("%s: String Length=[0x%02x]\n", __FUNCTION__, length);
74
75 dprintk("%s: String=[", __FUNCTION__);
76 }
77 while (i < length) {
78 if (verbose > 3)
79 dprintk(" %02x", check_string[i]);
80 checksum += check_string[i];
81 i++;
82 }
83 if (verbose > 3) {
84 dprintk(" ]\n");
85 dprintk("%s: Sum=[%02x]\n", __FUNCTION__, checksum);
86 }
87 check_string[length] = ~checksum + 1;
88 if (verbose > 3) {
89 dprintk("%s: Checksum=[%02x]\n", __FUNCTION__, check_string[length]);
90 dprintk("%s: ==========================================================================\n", __FUNCTION__);
91 }
92
93 return 0;
94}
95
96static int dst_ci_command(struct dst_state* state, u8 * data, u8 *ca_string, u8 len, int read)
97{
98 u8 reply;
99
100 dst_comm_init(state);
101 msleep(65);
102
103 if (write_dst(state, data, len)) {
104 dprintk("%s: Write not successful, trying to recover\n", __FUNCTION__);
105 dst_error_recovery(state);
106 return -1;
107 }
108
109 if ((dst_pio_disable(state)) < 0) {
110 dprintk("%s: DST PIO disable failed.\n", __FUNCTION__);
111 return -1;
112 }
113
114 if (read_dst(state, &reply, GET_ACK) < 0) {
115 dprintk("%s: Read not successful, trying to recover\n", __FUNCTION__);
116 dst_error_recovery(state);
117 return -1;
118 }
119
120 if (read) {
121 if (! dst_wait_dst_ready(state, LONG_DELAY)) {
122 dprintk("%s: 8820 not ready\n", __FUNCTION__);
123 return -1;
124 }
125
126 if (read_dst(state, ca_string, 128) < 0) { /* Try to make this dynamic */
127 dprintk("%s: Read not successful, trying to recover\n", __FUNCTION__);
128 dst_error_recovery(state);
129 return -1;
130 }
131 }
132
133 return 0;
134}
135
136
137static int dst_put_ci(struct dst_state *state, u8 *data, int len, u8 *ca_string, int read)
138{
139 u8 dst_ca_comm_err = 0;
140
141 while (dst_ca_comm_err < RETRIES) {
142 dst_comm_init(state);
143 if (verbose > 2)
144 dprintk("%s: Put Command\n", __FUNCTION__);
145 if (dst_ci_command(state, data, ca_string, len, read)) { // If error
146 dst_error_recovery(state);
147 dst_ca_comm_err++; // work required here.
148 }
149 break;
150 }
151
152 return 0;
153}
154
155
156
157static int ca_get_app_info(struct dst_state *state)
158{
159 static u8 command[8] = {0x07, 0x40, 0x01, 0x00, 0x01, 0x00, 0x00, 0xff};
160
161 put_checksum(&command[0], command[0]);
162 if ((dst_put_ci(state, command, sizeof(command), state->messages, GET_REPLY)) < 0) {
163 dprintk("%s: -->dst_put_ci FAILED !\n", __FUNCTION__);
164 return -1;
165 }
166 if (verbose > 1) {
167 dprintk("%s: -->dst_put_ci SUCCESS !\n", __FUNCTION__);
168
169 dprintk("%s: ================================ CI Module Application Info ======================================\n", __FUNCTION__);
170 dprintk("%s: Application Type=[%d], Application Vendor=[%d], Vendor Code=[%d]\n%s: Application info=[%s]\n",
171 __FUNCTION__, state->messages[7], (state->messages[8] << 8) | state->messages[9],
172 (state->messages[10] << 8) | state->messages[11], __FUNCTION__, (char *)(&state->messages[11]));
173 dprintk("%s: ==================================================================================================\n", __FUNCTION__);
174 }
175
176 return 0;
177}
178
179static int ca_get_slot_caps(struct dst_state *state, struct ca_caps *p_ca_caps, void *arg)
180{
181 int i;
182 u8 slot_cap[256];
183 static u8 slot_command[8] = {0x07, 0x40, 0x02, 0x00, 0x02, 0x00, 0x00, 0xff};
184
185 put_checksum(&slot_command[0], slot_command[0]);
186 if ((dst_put_ci(state, slot_command, sizeof (slot_command), slot_cap, GET_REPLY)) < 0) {
187 dprintk("%s: -->dst_put_ci FAILED !\n", __FUNCTION__);
188 return -1;
189 }
190 if (verbose > 1)
191 dprintk("%s: -->dst_put_ci SUCCESS !\n", __FUNCTION__);
192
193 /* Will implement the rest soon */
194
195 if (verbose > 1) {
196 dprintk("%s: Slot cap = [%d]\n", __FUNCTION__, slot_cap[7]);
197 dprintk("===================================\n");
198 for (i = 0; i < 8; i++)
199 dprintk(" %d", slot_cap[i]);
200 dprintk("\n");
201 }
202
203 p_ca_caps->slot_num = 1;
204 p_ca_caps->slot_type = 1;
205 p_ca_caps->descr_num = slot_cap[7];
206 p_ca_caps->descr_type = 1;
207
208
209 if (copy_to_user((struct ca_caps *)arg, p_ca_caps, sizeof (struct ca_caps))) {
210 return -EFAULT;
211 }
212
213 return 0;
214}
215
216
217static int ca_get_slot_descr(struct dst_state *state, struct ca_msg *p_ca_message, void *arg)
218{
219 return -EOPNOTSUPP;
220}
221
222
223static int ca_get_slot_info(struct dst_state *state, struct ca_slot_info *p_ca_slot_info, void *arg)
224{
225 int i;
226 static u8 slot_command[8] = {0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff};
227
228 u8 *slot_info = state->rxbuffer;
229
230 put_checksum(&slot_command[0], 7);
231 if ((dst_put_ci(state, slot_command, sizeof (slot_command), slot_info, GET_REPLY)) < 0) {
232 dprintk("%s: -->dst_put_ci FAILED !\n", __FUNCTION__);
233 return -1;
234 }
235 if (verbose > 1)
236 dprintk("%s: -->dst_put_ci SUCCESS !\n", __FUNCTION__);
237
238 /* Will implement the rest soon */
239
240 if (verbose > 1) {
241 dprintk("%s: Slot info = [%d]\n", __FUNCTION__, slot_info[3]);
242 dprintk("===================================\n");
243 for (i = 0; i < 8; i++)
244 dprintk(" %d", slot_info[i]);
245 dprintk("\n");
246 }
247
248 if (slot_info[4] & 0x80) {
249 p_ca_slot_info->flags = CA_CI_MODULE_PRESENT;
250 p_ca_slot_info->num = 1;
251 p_ca_slot_info->type = CA_CI;
252 }
253 else if (slot_info[4] & 0x40) {
254 p_ca_slot_info->flags = CA_CI_MODULE_READY;
255 p_ca_slot_info->num = 1;
256 p_ca_slot_info->type = CA_CI;
257 }
258 else {
259 p_ca_slot_info->flags = 0;
260 }
261
262 if (copy_to_user((struct ca_slot_info *)arg, p_ca_slot_info, sizeof (struct ca_slot_info))) {
263 return -EFAULT;
264 }
265
266 return 0;
267}
268
269
270
271
272static int ca_get_message(struct dst_state *state, struct ca_msg *p_ca_message, void *arg)
273{
274 u8 i = 0;
275 u32 command = 0;
276
277 if (copy_from_user(p_ca_message, (void *)arg, sizeof (struct ca_msg)))
278 return -EFAULT;
279
280
281 if (p_ca_message->msg) {
282 if (verbose > 3)
283 dprintk("Message = [%02x %02x %02x]\n", p_ca_message->msg[0], p_ca_message->msg[1], p_ca_message->msg[2]);
284
285 for (i = 0; i < 3; i++) {
286 command = command | p_ca_message->msg[i];
287 if (i < 2)
288 command = command << 8;
289 }
290 if (verbose > 3)
291 dprintk("%s:Command=[0x%x]\n", __FUNCTION__, command);
292
293 switch (command) {
294 case CA_APP_INFO:
295 memcpy(p_ca_message->msg, state->messages, 128);
296 if (copy_to_user((void *)arg, p_ca_message, sizeof (struct ca_msg)) )
297 return -EFAULT;
298 break;
299 }
300 }
301
302 return 0;
303}
304
305static int handle_en50221_tag(struct ca_msg *p_ca_message, struct ca_msg *hw_buffer)
306{
307 if (session) {
308 hw_buffer->msg[2] = p_ca_message->msg[1]; /* MSB */
309 hw_buffer->msg[3] = p_ca_message->msg[2]; /* LSB */
310 }
311 else {
312 hw_buffer->msg[2] = 0x03;
313 hw_buffer->msg[3] = 0x00;
314 }
315 return 0;
316}
317
318static int debug_8820_buffer(struct ca_msg *hw_buffer)
319{
320 unsigned int i;
321
322 dprintk("%s:Debug=[", __FUNCTION__);
323 for (i = 0; i < (hw_buffer->msg[0] + 1); i++)
324 dprintk(" %02x", hw_buffer->msg[i]);
325 dprintk("]\n");
326
327 return 0;
328}
329
330static int write_to_8820(struct dst_state *state, struct ca_msg *hw_buffer, u8 reply)
331{
332 if ((dst_put_ci(state, hw_buffer->msg, (hw_buffer->length + 1), hw_buffer->msg, reply)) < 0) {
333 dprintk("%s: DST-CI Command failed.\n", __FUNCTION__);
334 dprintk("%s: Resetting DST.\n", __FUNCTION__);
335 rdc_reset_state(state);
336 return -1;
337 }
338 if (verbose > 2)
339 dprintk("%s: DST-CI Command succes.\n", __FUNCTION__);
340
341 return 0;
342}
343
344
345static int ca_set_pmt(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer, u8 reply, u8 query)
346{
347 u32 hw_offset, buf_offset, i, k;
348 u32 program_info_length = 0, es_info_length = 0, length = 0, words = 0;
349 u8 found_prog_ca_desc = 0, found_stream_ca_desc = 0, error_condition = 0, hw_buffer_length = 0;
350
351 if (verbose > 3)
352 dprintk("%s, p_ca_message length %d (0x%x)\n", __FUNCTION__,p_ca_message->length,p_ca_message->length );
353
354 handle_en50221_tag(p_ca_message, hw_buffer); /* EN50221 tag */
355
356 /* Handle the length field (variable) */
357 if (!(p_ca_message->msg[3] & 0x80)) { /* Length = 1 */
358 length = p_ca_message->msg[3] & 0x7f;
359 words = 0; /* domi's suggestion */
360 }
361 else { /* Length = words */
362 words = p_ca_message->msg[3] & 0x7f;
363 for (i = 0; i < words; i++) {
364 length = length << 8;
365 length = length | p_ca_message->msg[4 + i];
366 }
367 }
368 if (verbose > 4) {
369 dprintk("%s:Length=[%d (0x%x)], Words=[%d]\n", __FUNCTION__, length,length, words);
370
371 /* Debug Input string */
372 for (i = 0; i < length; i++)
373 dprintk(" %02x", p_ca_message->msg[i]);
374 dprintk("]\n");
375 }
376
377 hw_offset = 7;
378 buf_offset = words + 4;
379
380 /* Program Header */
381 if (verbose > 4)
382 dprintk("\n%s:Program Header=[", __FUNCTION__);
383 for (i = 0; i < 6; i++) {
384 hw_buffer->msg[hw_offset] = p_ca_message->msg[buf_offset];
385 if (verbose > 4)
386 dprintk(" %02x", p_ca_message->msg[buf_offset]);
387 hw_offset++, buf_offset++, hw_buffer_length++;
388 }
389 if (verbose > 4)
390 dprintk("]\n");
391
392 program_info_length = 0;
393 program_info_length = (((program_info_length | p_ca_message->msg[words + 8]) & 0x0f) << 8) | p_ca_message->msg[words + 9];
394 if (verbose > 4)
395 dprintk("%s:Program info Length=[%d][%02x], hw_offset=[%d], buf_offset=[%d] \n",
396 __FUNCTION__, program_info_length, program_info_length, hw_offset, buf_offset);
397
398 if (program_info_length && (program_info_length < 256)) { /* If program_info_length */
399 hw_buffer->msg[11] = hw_buffer->msg[11] & 0x0f; /* req only 4 bits */
400 hw_buffer->msg[12] = hw_buffer->msg[12] + 1; /* increment! ASIC bug! */
401
402 if (p_ca_message->msg[buf_offset + 1] == 0x09) { /* Check CA descriptor */
403 found_prog_ca_desc = 1;
404 if (verbose > 4)
405 dprintk("%s: Found CA descriptor @ Program level\n", __FUNCTION__);
406 }
407
408 if (found_prog_ca_desc) { /* Command only if CA descriptor */
409 hw_buffer->msg[13] = p_ca_message->msg[buf_offset]; /* CA PMT command ID */
410 hw_offset++, buf_offset++, hw_buffer_length++;
411 }
412
413 /* Program descriptors */
414 if (verbose > 4) {
415 dprintk("%s:**********>buf_offset=[%d], hw_offset=[%d]\n", __FUNCTION__, buf_offset, hw_offset);
416 dprintk("%s:Program descriptors=[", __FUNCTION__);
417 }
418 while (program_info_length && !error_condition) { /* Copy prog descriptors */
419 if (program_info_length > p_ca_message->length) { /* Error situation */
420 dprintk ("%s:\"WARNING\" Length error, line=[%d], prog_info_length=[%d]\n",
421 __FUNCTION__, __LINE__, program_info_length);
422 dprintk("%s:\"WARNING\" Bailing out of possible loop\n", __FUNCTION__);
423 error_condition = 1;
424 break;
425 }
426
427 hw_buffer->msg[hw_offset] = p_ca_message->msg[buf_offset];
428 dprintk(" %02x", p_ca_message->msg[buf_offset]);
429 hw_offset++, buf_offset++, hw_buffer_length++, program_info_length--;
430 }
431 if (verbose > 4) {
432 dprintk("]\n");
433 dprintk("%s:**********>buf_offset=[%d], hw_offset=[%d]\n", __FUNCTION__, buf_offset, hw_offset);
434 }
435 if (found_prog_ca_desc) {
436 if (!reply) {
437 hw_buffer->msg[13] = 0x01; /* OK descrambling */
438 if (verbose > 1)
439 dprintk("CA PMT Command = OK Descrambling\n");
440 }
441 else {
442 hw_buffer->msg[13] = 0x02; /* Ok MMI */
443 if (verbose > 1)
444 dprintk("CA PMT Command = Ok MMI\n");
445 }
446 if (query) {
447 hw_buffer->msg[13] = 0x03; /* Query */
448 if (verbose > 1)
449 dprintk("CA PMT Command = CA PMT query\n");
450 }
451 }
452 }
453 else {
454 hw_buffer->msg[11] = hw_buffer->msg[11] & 0xf0; /* Don't write to ASIC */
455 hw_buffer->msg[12] = hw_buffer->msg[12] = 0x00;
456 }
457 if (verbose > 4)
458 dprintk("%s:**********>p_ca_message->length=[%d], buf_offset=[%d], hw_offset=[%d]\n",
459 __FUNCTION__, p_ca_message->length, buf_offset, hw_offset);
460
461 while ((buf_offset < p_ca_message->length) && !error_condition) {
462 /* Bail out in case of an indefinite loop */
463 if ((es_info_length > p_ca_message->length) || (buf_offset > p_ca_message->length)) {
464 dprintk("%s:\"WARNING\" Length error, line=[%d], prog_info_length=[%d], buf_offset=[%d]\n",
465 __FUNCTION__, __LINE__, program_info_length, buf_offset);
466
467 dprintk("%s:\"WARNING\" Bailing out of possible loop\n", __FUNCTION__);
468 error_condition = 1;
469 break;
470 }
471
472 /* Stream Header */
473
474 for (k = 0; k < 5; k++) {
475 hw_buffer->msg[hw_offset + k] = p_ca_message->msg[buf_offset + k];
476 }
477
478 es_info_length = 0;
479 es_info_length = (es_info_length | (p_ca_message->msg[buf_offset + 3] & 0x0f)) << 8 | p_ca_message->msg[buf_offset + 4];
480
481 if (verbose > 4) {
482 dprintk("\n%s:----->Stream header=[%02x %02x %02x %02x %02x]\n", __FUNCTION__,
483 p_ca_message->msg[buf_offset + 0], p_ca_message->msg[buf_offset + 1],
484 p_ca_message->msg[buf_offset + 2], p_ca_message->msg[buf_offset + 3],
485 p_ca_message->msg[buf_offset + 4]);
486
487 dprintk("%s:----->Stream type=[%02x], es length=[%d (0x%x)], Chars=[%02x] [%02x], buf_offset=[%d]\n", __FUNCTION__,
488 p_ca_message->msg[buf_offset + 0], es_info_length, es_info_length,
489 p_ca_message->msg[buf_offset + 3], p_ca_message->msg[buf_offset + 4], buf_offset);
490 }
491
492 hw_buffer->msg[hw_offset + 3] &= 0x0f; /* req only 4 bits */
493
494 if (found_prog_ca_desc) {
495 hw_buffer->msg[hw_offset + 3] = 0x00;
496 hw_buffer->msg[hw_offset + 4] = 0x00;
497 }
498
499 hw_offset += 5, buf_offset += 5, hw_buffer_length += 5;
500
501 /* Check for CA descriptor */
502 if (p_ca_message->msg[buf_offset + 1] == 0x09) {
503 if (verbose > 4)
504 dprintk("%s:Found CA descriptor @ Stream level\n", __FUNCTION__);
505 found_stream_ca_desc = 1;
506 }
507
508 /* ES descriptors */
509
510 if (es_info_length && !error_condition && !found_prog_ca_desc && found_stream_ca_desc) {
511// if (!ca_pmt_done) {
512 hw_buffer->msg[hw_offset] = p_ca_message->msg[buf_offset]; /* CA PMT cmd(es) */
513 if (verbose > 4)
514 printk("%s:----->CA PMT Command ID=[%02x]\n", __FUNCTION__, p_ca_message->msg[buf_offset]);
515// hw_offset++, buf_offset++, hw_buffer_length++, es_info_length--, ca_pmt_done = 1;
516 hw_offset++, buf_offset++, hw_buffer_length++, es_info_length--;
517// }
518 if (verbose > 4)
519 dprintk("%s:----->ES descriptors=[", __FUNCTION__);
520
521 while (es_info_length && !error_condition) { /* ES descriptors */
522 if ((es_info_length > p_ca_message->length) || (buf_offset > p_ca_message->length)) {
523 if (verbose > 4) {
524 dprintk("%s:\"WARNING\" ES Length error, line=[%d], es_info_length=[%d], buf_offset=[%d]\n",
525 __FUNCTION__, __LINE__, es_info_length, buf_offset);
526
527 dprintk("%s:\"WARNING\" Bailing out of possible loop\n", __FUNCTION__);
528 }
529 error_condition = 1;
530 break;
531 }
532
533 hw_buffer->msg[hw_offset] = p_ca_message->msg[buf_offset];
534 if (verbose > 3)
535 dprintk("%02x ", hw_buffer->msg[hw_offset]);
536 hw_offset++, buf_offset++, hw_buffer_length++, es_info_length--;
537 }
538 found_stream_ca_desc = 0; /* unset for new streams */
539 dprintk("]\n");
540 }
541 }
542
543 /* MCU Magic words */
544
545 hw_buffer_length += 7;
546 hw_buffer->msg[0] = hw_buffer_length;
547 hw_buffer->msg[1] = 64;
548 hw_buffer->msg[4] = 3;
549 hw_buffer->msg[5] = hw_buffer->msg[0] - 7;
550 hw_buffer->msg[6] = 0;
551
552
553 /* Fix length */
554 hw_buffer->length = hw_buffer->msg[0];
555
556 put_checksum(&hw_buffer->msg[0], hw_buffer->msg[0]);
557 /* Do the actual write */
558 if (verbose > 4) {
559 dprintk("%s:======================DEBUGGING================================\n", __FUNCTION__);
560 dprintk("%s: Actual Length=[%d]\n", __FUNCTION__, hw_buffer_length);
561 }
562 /* Only for debugging! */
563 if (verbose > 2)
564 debug_8820_buffer(hw_buffer);
565 if (verbose > 3)
566 dprintk("%s: Reply = [%d]\n", __FUNCTION__, reply);
567 write_to_8820(state, hw_buffer, reply);
568
569 return 0;
570}
571
572/* Board supports CA PMT reply ? */
573static int dst_check_ca_pmt(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer)
574{
575 int ca_pmt_reply_test = 0;
576
577 /* Do test board */
578 /* Not there yet but soon */
579
580
581 /* CA PMT Reply capable */
582 if (ca_pmt_reply_test) {
583 if ((ca_set_pmt(state, p_ca_message, hw_buffer, 1, GET_REPLY)) < 0) {
584 dprintk("%s: ca_set_pmt.. failed !\n", __FUNCTION__);
585 return -1;
586 }
587
588 /* Process CA PMT Reply */
589 /* will implement soon */
590 dprintk("%s: Not there yet\n", __FUNCTION__);
591 }
592 /* CA PMT Reply not capable */
593 if (!ca_pmt_reply_test) {
594 if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, NO_REPLY)) < 0) {
595 dprintk("%s: ca_set_pmt.. failed !\n", __FUNCTION__);
596 return -1;
597 }
598 if (verbose > 3)
599 dprintk("%s: ca_set_pmt.. success !\n", __FUNCTION__);
600 /* put a dummy message */
601
602 }
603 return 0;
604}
605
606static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message, void *arg)
607{
608 int i = 0;
609 unsigned int ca_message_header_len;
610
611 u32 command = 0;
612 struct ca_msg *hw_buffer;
613
614 if ((hw_buffer = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) {
615 printk("%s: Memory allocation failure\n", __FUNCTION__);
616 return -ENOMEM;
617 }
618 if (verbose > 3)
619 dprintk("%s\n", __FUNCTION__);
620
621 if (copy_from_user(p_ca_message, (void *)arg, sizeof (struct ca_msg)))
622 return -EFAULT;
623
624 if (p_ca_message->msg) {
625 ca_message_header_len = p_ca_message->length; /* Restore it back when you are done */
626 /* EN50221 tag */
627 command = 0;
628
629 for (i = 0; i < 3; i++) {
630 command = command | p_ca_message->msg[i];
631 if (i < 2)
632 command = command << 8;
633 }
634 if (verbose > 3)
635 dprintk("%s:Command=[0x%x]\n", __FUNCTION__, command);
636
637 switch (command) {
638 case CA_PMT:
639 if (verbose > 3)
640 dprintk("Command = SEND_CA_PMT\n");
641 if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, 0)) < 0) {
642 dprintk("%s: -->CA_PMT Failed !\n", __FUNCTION__);
643 return -1;
644 }
645 if (verbose > 3)
646 dprintk("%s: -->CA_PMT Success !\n", __FUNCTION__);
647// retval = dummy_set_pmt(state, p_ca_message, hw_buffer, 0, 0);
648
649 break;
650
651 case CA_PMT_REPLY:
652 if (verbose > 3)
653 dprintk("Command = CA_PMT_REPLY\n");
654 /* Have to handle the 2 basic types of cards here */
655 if ((dst_check_ca_pmt(state, p_ca_message, hw_buffer)) < 0) {
656 dprintk("%s: -->CA_PMT_REPLY Failed !\n", __FUNCTION__);
657 return -1;
658 }
659 if (verbose > 3)
660 dprintk("%s: -->CA_PMT_REPLY Success !\n", __FUNCTION__);
661
662 /* Certain boards do behave different ? */
663// retval = ca_set_pmt(state, p_ca_message, hw_buffer, 1, 1);
664
665 case CA_APP_INFO_ENQUIRY: // only for debugging
666 if (verbose > 3)
667 dprintk("%s: Getting Cam Application information\n", __FUNCTION__);
668
669 if ((ca_get_app_info(state)) < 0) {
670 dprintk("%s: -->CA_APP_INFO_ENQUIRY Failed !\n", __FUNCTION__);
671 return -1;
672 }
673 if (verbose > 3)
674 printk("%s: -->CA_APP_INFO_ENQUIRY Success !\n", __FUNCTION__);
675
676 break;
677 }
678 }
679 return 0;
680}
681
682static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg)
683{
684 struct dvb_device* dvbdev = (struct dvb_device*) file->private_data;
685 struct dst_state* state = (struct dst_state*) dvbdev->priv;
686 struct ca_slot_info *p_ca_slot_info;
687 struct ca_caps *p_ca_caps;
688 struct ca_msg *p_ca_message;
689
690 if ((p_ca_message = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) {
691 printk("%s: Memory allocation failure\n", __FUNCTION__);
692 return -ENOMEM;
693 }
694
695 if ((p_ca_slot_info = (struct ca_slot_info *) kmalloc(sizeof (struct ca_slot_info), GFP_KERNEL)) == NULL) {
696 printk("%s: Memory allocation failure\n", __FUNCTION__);
697 return -ENOMEM;
698 }
699
700 if ((p_ca_caps = (struct ca_caps *) kmalloc(sizeof (struct ca_caps), GFP_KERNEL)) == NULL) {
701 printk("%s: Memory allocation failure\n", __FUNCTION__);
702 return -ENOMEM;
703 }
704
705 /* We have now only the standard ioctl's, the driver is upposed to handle internals. */
706 switch (cmd) {
707 case CA_SEND_MSG:
708 if (verbose > 1)
709 dprintk("%s: Sending message\n", __FUNCTION__);
710 if ((ca_send_message(state, p_ca_message, arg)) < 0) {
711 dprintk("%s: -->CA_SEND_MSG Failed !\n", __FUNCTION__);
712 return -1;
713 }
714
715 break;
716
717 case CA_GET_MSG:
718 if (verbose > 1)
719 dprintk("%s: Getting message\n", __FUNCTION__);
720 if ((ca_get_message(state, p_ca_message, arg)) < 0) {
721 dprintk("%s: -->CA_GET_MSG Failed !\n", __FUNCTION__);
722 return -1;
723 }
724 if (verbose > 1)
725 dprintk("%s: -->CA_GET_MSG Success !\n", __FUNCTION__);
726
727 break;
728
729 case CA_RESET:
730 if (verbose > 1)
731 dprintk("%s: Resetting DST\n", __FUNCTION__);
732 dst_error_bailout(state);
733 msleep(4000);
734
735 break;
736
737 case CA_GET_SLOT_INFO:
738 if (verbose > 1)
739 dprintk("%s: Getting Slot info\n", __FUNCTION__);
740 if ((ca_get_slot_info(state, p_ca_slot_info, arg)) < 0) {
741 dprintk("%s: -->CA_GET_SLOT_INFO Failed !\n", __FUNCTION__);
742 return -1;
743 }
744 if (verbose > 1)
745 dprintk("%s: -->CA_GET_SLOT_INFO Success !\n", __FUNCTION__);
746
747 break;
748
749 case CA_GET_CAP:
750 if (verbose > 1)
751 dprintk("%s: Getting Slot capabilities\n", __FUNCTION__);
752 if ((ca_get_slot_caps(state, p_ca_caps, arg)) < 0) {
753 dprintk("%s: -->CA_GET_CAP Failed !\n", __FUNCTION__);
754 return -1;
755 }
756 if (verbose > 1)
757 dprintk("%s: -->CA_GET_CAP Success !\n", __FUNCTION__);
758
759 break;
760
761 case CA_GET_DESCR_INFO:
762 if (verbose > 1)
763 dprintk("%s: Getting descrambler description\n", __FUNCTION__);
764 if ((ca_get_slot_descr(state, p_ca_message, arg)) < 0) {
765 dprintk("%s: -->CA_GET_DESCR_INFO Failed !\n", __FUNCTION__);
766 return -1;
767 }
768 if (verbose > 1)
769 dprintk("%s: -->CA_GET_DESCR_INFO Success !\n", __FUNCTION__);
770
771 break;
772
773 case CA_SET_DESCR:
774 if (verbose > 1)
775 dprintk("%s: Setting descrambler\n", __FUNCTION__);
776 if ((ca_set_slot_descr()) < 0) {
777 dprintk("%s: -->CA_SET_DESCR Failed !\n", __FUNCTION__);
778 return -1;
779 }
780 if (verbose > 1)
781 dprintk("%s: -->CA_SET_DESCR Success !\n", __FUNCTION__);
782
783 break;
784
785 case CA_SET_PID:
786 if (verbose > 1)
787 dprintk("%s: Setting PID\n", __FUNCTION__);
788 if ((ca_set_pid()) < 0) {
789 dprintk("%s: -->CA_SET_PID Failed !\n", __FUNCTION__);
790 return -1;
791 }
792 if (verbose > 1)
793 dprintk("%s: -->CA_SET_PID Success !\n", __FUNCTION__);
794
795 default:
796 return -EOPNOTSUPP;
797 };
798
799 return 0;
800}
801
802static int dst_ca_open(struct inode *inode, struct file *file)
803{
804 if (verbose > 4)
805 dprintk("%s:Device opened [%p]\n", __FUNCTION__, file);
806 try_module_get(THIS_MODULE);
807
808 return 0;
809}
810
811static int dst_ca_release(struct inode *inode, struct file *file)
812{
813 if (verbose > 4)
814 dprintk("%s:Device closed.\n", __FUNCTION__);
815 module_put(THIS_MODULE);
816
817 return 0;
818}
819
820static int dst_ca_read(struct file *file, char __user * buffer, size_t length, loff_t * offset)
821{
822 int bytes_read = 0;
823
824 if (verbose > 4)
825 dprintk("%s:Device read.\n", __FUNCTION__);
826
827 return bytes_read;
828}
829
830static int dst_ca_write(struct file *file, const char __user * buffer, size_t length, loff_t * offset)
831{
832 if (verbose > 4)
833 dprintk("%s:Device write.\n", __FUNCTION__);
834
835 return 0;
836}
837
838static struct file_operations dst_ca_fops = {
839 .owner = THIS_MODULE,
840 .ioctl = (void *)dst_ca_ioctl,
841 .open = dst_ca_open,
842 .release = dst_ca_release,
843 .read = dst_ca_read,
844 .write = dst_ca_write
845};
846
847static struct dvb_device dvbdev_ca = {
848 .priv = NULL,
849 .users = 1,
850 .readers = 1,
851 .writers = 1,
852 .fops = &dst_ca_fops
853};
854
855int dst_ca_attach(struct dst_state *dst, struct dvb_adapter *dvb_adapter)
856{
857 struct dvb_device *dvbdev;
858 if (verbose > 4)
859 dprintk("%s:registering DST-CA device\n", __FUNCTION__);
860 dvb_register_device(dvb_adapter, &dvbdev, &dvbdev_ca, dst, DVB_DEVICE_CA);
861 return 0;
862}
863
864EXPORT_SYMBOL(dst_ca_attach);
865
866MODULE_DESCRIPTION("DST DVB-S/T/C Combo CA driver");
867MODULE_AUTHOR("Manu Abraham");
868MODULE_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 00000000000..59cd0ddd6d8
--- /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 00000000000..10046d6292b
--- /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
50
51
52/* Card capability list */
53
54#define DST_TYPE_HAS_MAC 1
55#define DST_TYPE_HAS_DISEQC3 2
56#define DST_TYPE_HAS_DISEQC4 4
57#define DST_TYPE_HAS_DISEQC5 8
58#define DST_TYPE_HAS_MOTO 16
59#define DST_TYPE_HAS_CA 32
60#define DST_TYPE_HAS_ANALOG 64 /* Analog inputs */
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 u8 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 u8 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 80488aa628b..3974a4c6ebe 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 f9572426a14..6f857c6091f 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 }
@@ -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;
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.h b/drivers/media/dvb/bt8xx/dvb-bt8xx.h
index e9310e3a17a..2923b3b0dd3 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"