aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/bt8xx
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
commitfcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch)
treea57612d1888735a2ec7972891b68c1ac5ec8faea /drivers/media/dvb/bt8xx
parent8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff)
Added missing tegra files.HEADmaster
Diffstat (limited to 'drivers/media/dvb/bt8xx')
-rw-r--r--drivers/media/dvb/bt8xx/Kconfig22
-rw-r--r--drivers/media/dvb/bt8xx/Makefile6
-rw-r--r--drivers/media/dvb/bt8xx/bt878.c609
-rw-r--r--drivers/media/dvb/bt8xx/bt878.h159
-rw-r--r--drivers/media/dvb/bt8xx/dst.c1873
-rw-r--r--drivers/media/dvb/bt8xx/dst_ca.c727
-rw-r--r--drivers/media/dvb/bt8xx/dst_ca.h58
-rw-r--r--drivers/media/dvb/bt8xx/dst_common.h182
-rw-r--r--drivers/media/dvb/bt8xx/dst_priv.h35
-rw-r--r--drivers/media/dvb/bt8xx/dvb-bt8xx.c970
-rw-r--r--drivers/media/dvb/bt8xx/dvb-bt8xx.h63
11 files changed, 4704 insertions, 0 deletions
diff --git a/drivers/media/dvb/bt8xx/Kconfig b/drivers/media/dvb/bt8xx/Kconfig
new file mode 100644
index 00000000000..8668e634c7e
--- /dev/null
+++ b/drivers/media/dvb/bt8xx/Kconfig
@@ -0,0 +1,22 @@
1config DVB_BT8XX
2 tristate "BT8xx based PCI cards"
3 depends on DVB_CORE && PCI && I2C && VIDEO_BT848
4 select DVB_MT352 if !DVB_FE_CUSTOMISE
5 select DVB_SP887X if !DVB_FE_CUSTOMISE
6 select DVB_NXT6000 if !DVB_FE_CUSTOMISE
7 select DVB_CX24110 if !DVB_FE_CUSTOMISE
8 select DVB_OR51211 if !DVB_FE_CUSTOMISE
9 select DVB_LGDT330X if !DVB_FE_CUSTOMISE
10 select DVB_ZL10353 if !DVB_FE_CUSTOMISE
11 select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
12 help
13 Support for PCI cards based on the Bt8xx PCI bridge. Examples are
14 the Nebula cards, the Pinnacle PCTV cards, the Twinhan DST cards,
15 the pcHDTV HD2000 cards, the DViCO FusionHDTV Lite cards, and
16 some AVerMedia cards.
17
18 Since these cards have no MPEG decoder onboard, they transmit
19 only compressed MPEG data over the PCI bus, so you need
20 an external software decoder to watch TV on your computer.
21
22 Say Y if you own such a device and want to use it.
diff --git a/drivers/media/dvb/bt8xx/Makefile b/drivers/media/dvb/bt8xx/Makefile
new file mode 100644
index 00000000000..d98f1d49ffa
--- /dev/null
+++ b/drivers/media/dvb/bt8xx/Makefile
@@ -0,0 +1,6 @@
1obj-$(CONFIG_DVB_BT8XX) += bt878.o dvb-bt8xx.o dst.o dst_ca.o
2
3EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
4EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
5EXTRA_CFLAGS += -Idrivers/media/video/bt8xx
6EXTRA_CFLAGS += -Idrivers/media/common/tuners
diff --git a/drivers/media/dvb/bt8xx/bt878.c b/drivers/media/dvb/bt8xx/bt878.c
new file mode 100644
index 00000000000..b34fa95185e
--- /dev/null
+++ b/drivers/media/dvb/bt8xx/bt878.c
@@ -0,0 +1,609 @@
1/*
2 * bt878.c: part of the driver for the Pinnacle PCTV Sat DVB PCI card
3 *
4 * Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@htp-tel.de>
5 *
6 * large parts based on the bttv driver
7 * Copyright (C) 1996,97,98 Ralph Metzler (rjkm@metzlerbros.de)
8 * & Marcus Metzler (mocm@metzlerbros.de)
9 * (c) 1999,2000 Gerd Knorr <kraxel@goldbach.in-berlin.de>
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22
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
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
27 *
28 */
29
30#include <linux/module.h>
31#include <linux/kernel.h>
32#include <linux/pci.h>
33#include <asm/io.h>
34#include <linux/ioport.h>
35#include <asm/pgtable.h>
36#include <asm/page.h>
37#include <linux/types.h>
38#include <linux/interrupt.h>
39#include <linux/kmod.h>
40#include <linux/vmalloc.h>
41#include <linux/init.h>
42
43#include "dmxdev.h"
44#include "dvbdev.h"
45#include "bt878.h"
46#include "dst_priv.h"
47
48
49/**************************************/
50/* Miscellaneous utility definitions */
51/**************************************/
52
53static unsigned int bt878_verbose = 1;
54static unsigned int bt878_debug;
55
56module_param_named(verbose, bt878_verbose, int, 0444);
57MODULE_PARM_DESC(verbose,
58 "verbose startup messages, default is 1 (yes)");
59module_param_named(debug, bt878_debug, int, 0644);
60MODULE_PARM_DESC(debug, "Turn on/off debugging, default is 0 (off).");
61
62int bt878_num;
63struct bt878 bt878[BT878_MAX];
64
65EXPORT_SYMBOL(bt878_num);
66EXPORT_SYMBOL(bt878);
67
68#define btwrite(dat,adr) bmtwrite((dat), (bt->bt878_mem+(adr)))
69#define btread(adr) bmtread(bt->bt878_mem+(adr))
70
71#define btand(dat,adr) btwrite((dat) & btread(adr), adr)
72#define btor(dat,adr) btwrite((dat) | btread(adr), adr)
73#define btaor(dat,mask,adr) btwrite((dat) | ((mask) & btread(adr)), adr)
74
75#if defined(dprintk)
76#undef dprintk
77#endif
78#define dprintk(fmt, arg...) \
79 do { \
80 if (bt878_debug) \
81 printk(KERN_DEBUG fmt, ##arg); \
82 } while (0)
83
84static void bt878_mem_free(struct bt878 *bt)
85{
86 if (bt->buf_cpu) {
87 pci_free_consistent(bt->dev, bt->buf_size, bt->buf_cpu,
88 bt->buf_dma);
89 bt->buf_cpu = NULL;
90 }
91
92 if (bt->risc_cpu) {
93 pci_free_consistent(bt->dev, bt->risc_size, bt->risc_cpu,
94 bt->risc_dma);
95 bt->risc_cpu = NULL;
96 }
97}
98
99static int bt878_mem_alloc(struct bt878 *bt)
100{
101 if (!bt->buf_cpu) {
102 bt->buf_size = 128 * 1024;
103
104 bt->buf_cpu =
105 pci_alloc_consistent(bt->dev, bt->buf_size,
106 &bt->buf_dma);
107
108 if (!bt->buf_cpu)
109 return -ENOMEM;
110
111 memset(bt->buf_cpu, 0, bt->buf_size);
112 }
113
114 if (!bt->risc_cpu) {
115 bt->risc_size = PAGE_SIZE;
116 bt->risc_cpu =
117 pci_alloc_consistent(bt->dev, bt->risc_size,
118 &bt->risc_dma);
119
120 if (!bt->risc_cpu) {
121 bt878_mem_free(bt);
122 return -ENOMEM;
123 }
124
125 memset(bt->risc_cpu, 0, bt->risc_size);
126 }
127
128 return 0;
129}
130
131/* RISC instructions */
132#define RISC_WRITE (0x01 << 28)
133#define RISC_JUMP (0x07 << 28)
134#define RISC_SYNC (0x08 << 28)
135
136/* RISC bits */
137#define RISC_WR_SOL (1 << 27)
138#define RISC_WR_EOL (1 << 26)
139#define RISC_IRQ (1 << 24)
140#define RISC_STATUS(status) ((((~status) & 0x0F) << 20) | ((status & 0x0F) << 16))
141#define RISC_SYNC_RESYNC (1 << 15)
142#define RISC_SYNC_FM1 0x06
143#define RISC_SYNC_VRO 0x0C
144
145#define RISC_FLUSH() bt->risc_pos = 0
146#define RISC_INSTR(instr) bt->risc_cpu[bt->risc_pos++] = cpu_to_le32(instr)
147
148static int bt878_make_risc(struct bt878 *bt)
149{
150 bt->block_bytes = bt->buf_size >> 4;
151 bt->block_count = 1 << 4;
152 bt->line_bytes = bt->block_bytes;
153 bt->line_count = bt->block_count;
154
155 while (bt->line_bytes > 4095) {
156 bt->line_bytes >>= 1;
157 bt->line_count <<= 1;
158 }
159
160 if (bt->line_count > 255) {
161 printk(KERN_ERR "bt878: buffer size error!\n");
162 return -EINVAL;
163 }
164 return 0;
165}
166
167
168static void bt878_risc_program(struct bt878 *bt, u32 op_sync_orin)
169{
170 u32 buf_pos = 0;
171 u32 line;
172
173 RISC_FLUSH();
174 RISC_INSTR(RISC_SYNC | RISC_SYNC_FM1 | op_sync_orin);
175 RISC_INSTR(0);
176
177 dprintk("bt878: risc len lines %u, bytes per line %u\n",
178 bt->line_count, bt->line_bytes);
179 for (line = 0; line < bt->line_count; line++) {
180 // At the beginning of every block we issue an IRQ with previous (finished) block number set
181 if (!(buf_pos % bt->block_bytes))
182 RISC_INSTR(RISC_WRITE | RISC_WR_SOL | RISC_WR_EOL |
183 RISC_IRQ |
184 RISC_STATUS(((buf_pos /
185 bt->block_bytes) +
186 (bt->block_count -
187 1)) %
188 bt->block_count) | bt->
189 line_bytes);
190 else
191 RISC_INSTR(RISC_WRITE | RISC_WR_SOL | RISC_WR_EOL |
192 bt->line_bytes);
193 RISC_INSTR(bt->buf_dma + buf_pos);
194 buf_pos += bt->line_bytes;
195 }
196
197 RISC_INSTR(RISC_SYNC | op_sync_orin | RISC_SYNC_VRO);
198 RISC_INSTR(0);
199
200 RISC_INSTR(RISC_JUMP);
201 RISC_INSTR(bt->risc_dma);
202
203 btwrite((bt->line_count << 16) | bt->line_bytes, BT878_APACK_LEN);
204}
205
206/*****************************/
207/* Start/Stop grabbing funcs */
208/*****************************/
209
210void bt878_start(struct bt878 *bt, u32 controlreg, u32 op_sync_orin,
211 u32 irq_err_ignore)
212{
213 u32 int_mask;
214
215 dprintk("bt878 debug: bt878_start (ctl=%8.8x)\n", controlreg);
216 /* complete the writing of the risc dma program now we have
217 * the card specifics
218 */
219 bt878_risc_program(bt, op_sync_orin);
220 controlreg &= ~0x1f;
221 controlreg |= 0x1b;
222
223 btwrite(bt->risc_dma, BT878_ARISC_START);
224
225 /* original int mask had :
226 * 6 2 8 4 0
227 * 1111 1111 1000 0000 0000
228 * SCERR|OCERR|PABORT|RIPERR|FDSR|FTRGT|FBUS|RISCI
229 * Hacked for DST to:
230 * SCERR | OCERR | FDSR | FTRGT | FBUS | RISCI
231 */
232 int_mask = BT878_ASCERR | BT878_AOCERR | BT878_APABORT |
233 BT878_ARIPERR | BT878_APPERR | BT878_AFDSR | BT878_AFTRGT |
234 BT878_AFBUS | BT878_ARISCI;
235
236
237 /* ignore pesky bits */
238 int_mask &= ~irq_err_ignore;
239
240 btwrite(int_mask, BT878_AINT_MASK);
241 btwrite(controlreg, BT878_AGPIO_DMA_CTL);
242}
243
244void bt878_stop(struct bt878 *bt)
245{
246 u32 stat;
247 int i = 0;
248
249 dprintk("bt878 debug: bt878_stop\n");
250
251 btwrite(0, BT878_AINT_MASK);
252 btand(~0x13, BT878_AGPIO_DMA_CTL);
253
254 do {
255 stat = btread(BT878_AINT_STAT);
256 if (!(stat & BT878_ARISC_EN))
257 break;
258 i++;
259 } while (i < 500);
260
261 dprintk("bt878(%d) debug: bt878_stop, i=%d, stat=0x%8.8x\n",
262 bt->nr, i, stat);
263}
264
265EXPORT_SYMBOL(bt878_start);
266EXPORT_SYMBOL(bt878_stop);
267
268/*****************************/
269/* Interrupt service routine */
270/*****************************/
271
272static irqreturn_t bt878_irq(int irq, void *dev_id)
273{
274 u32 stat, astat, mask;
275 int count;
276 struct bt878 *bt;
277
278 bt = (struct bt878 *) dev_id;
279
280 count = 0;
281 while (1) {
282 stat = btread(BT878_AINT_STAT);
283 mask = btread(BT878_AINT_MASK);
284 if (!(astat = (stat & mask)))
285 return IRQ_NONE; /* this interrupt is not for me */
286/* dprintk("bt878(%d) debug: irq count %d, stat 0x%8.8x, mask 0x%8.8x\n",bt->nr,count,stat,mask); */
287 btwrite(astat, BT878_AINT_STAT); /* try to clear interrupt condition */
288
289
290 if (astat & (BT878_ASCERR | BT878_AOCERR)) {
291 if (bt878_verbose) {
292 printk(KERN_INFO
293 "bt878(%d): irq%s%s risc_pc=%08x\n",
294 bt->nr,
295 (astat & BT878_ASCERR) ? " SCERR" :
296 "",
297 (astat & BT878_AOCERR) ? " OCERR" :
298 "", btread(BT878_ARISC_PC));
299 }
300 }
301 if (astat & (BT878_APABORT | BT878_ARIPERR | BT878_APPERR)) {
302 if (bt878_verbose) {
303 printk(KERN_INFO
304 "bt878(%d): irq%s%s%s risc_pc=%08x\n",
305 bt->nr,
306 (astat & BT878_APABORT) ? " PABORT" :
307 "",
308 (astat & BT878_ARIPERR) ? " RIPERR" :
309 "",
310 (astat & BT878_APPERR) ? " PPERR" :
311 "", btread(BT878_ARISC_PC));
312 }
313 }
314 if (astat & (BT878_AFDSR | BT878_AFTRGT | BT878_AFBUS)) {
315 if (bt878_verbose) {
316 printk(KERN_INFO
317 "bt878(%d): irq%s%s%s risc_pc=%08x\n",
318 bt->nr,
319 (astat & BT878_AFDSR) ? " FDSR" : "",
320 (astat & BT878_AFTRGT) ? " FTRGT" :
321 "",
322 (astat & BT878_AFBUS) ? " FBUS" : "",
323 btread(BT878_ARISC_PC));
324 }
325 }
326 if (astat & BT878_ARISCI) {
327 bt->finished_block = (stat & BT878_ARISCS) >> 28;
328 tasklet_schedule(&bt->tasklet);
329 break;
330 }
331 count++;
332 if (count > 20) {
333 btwrite(0, BT878_AINT_MASK);
334 printk(KERN_ERR
335 "bt878(%d): IRQ lockup, cleared int mask\n",
336 bt->nr);
337 break;
338 }
339 }
340 return IRQ_HANDLED;
341}
342
343int
344bt878_device_control(struct bt878 *bt, unsigned int cmd, union dst_gpio_packet *mp)
345{
346 int retval;
347
348 retval = 0;
349 if (mutex_lock_interruptible(&bt->gpio_lock))
350 return -ERESTARTSYS;
351 /* special gpio signal */
352 switch (cmd) {
353 case DST_IG_ENABLE:
354 // dprintk("dvb_bt8xx: dst enable mask 0x%02x enb 0x%02x \n", mp->dstg.enb.mask, mp->dstg.enb.enable);
355 retval = bttv_gpio_enable(bt->bttv_nr,
356 mp->enb.mask,
357 mp->enb.enable);
358 break;
359 case DST_IG_WRITE:
360 // dprintk("dvb_bt8xx: dst write gpio mask 0x%02x out 0x%02x\n", mp->dstg.outp.mask, mp->dstg.outp.highvals);
361 retval = bttv_write_gpio(bt->bttv_nr,
362 mp->outp.mask,
363 mp->outp.highvals);
364
365 break;
366 case DST_IG_READ:
367 /* read */
368 retval = bttv_read_gpio(bt->bttv_nr, &mp->rd.value);
369 // dprintk("dvb_bt8xx: dst read gpio 0x%02x\n", (unsigned)mp->dstg.rd.value);
370 break;
371 case DST_IG_TS:
372 /* Set packet size */
373 bt->TS_Size = mp->psize;
374 break;
375
376 default:
377 retval = -EINVAL;
378 break;
379 }
380 mutex_unlock(&bt->gpio_lock);
381 return retval;
382}
383
384EXPORT_SYMBOL(bt878_device_control);
385
386#define BROOKTREE_878_DEVICE(vend, dev, name) \
387 { \
388 .vendor = PCI_VENDOR_ID_BROOKTREE, \
389 .device = PCI_DEVICE_ID_BROOKTREE_878, \
390 .subvendor = (vend), .subdevice = (dev), \
391 .driver_data = (unsigned long) name \
392 }
393
394static struct pci_device_id bt878_pci_tbl[] __devinitdata = {
395 BROOKTREE_878_DEVICE(0x0071, 0x0101, "Nebula Electronics DigiTV"),
396 BROOKTREE_878_DEVICE(0x1461, 0x0761, "AverMedia AverTV DVB-T 761"),
397 BROOKTREE_878_DEVICE(0x11bd, 0x001c, "Pinnacle PCTV Sat"),
398 BROOKTREE_878_DEVICE(0x11bd, 0x0026, "Pinnacle PCTV SAT CI"),
399 BROOKTREE_878_DEVICE(0x1822, 0x0001, "Twinhan VisionPlus DVB"),
400 BROOKTREE_878_DEVICE(0x270f, 0xfc00,
401 "ChainTech digitop DST-1000 DVB-S"),
402 BROOKTREE_878_DEVICE(0x1461, 0x0771, "AVermedia AverTV DVB-T 771"),
403 BROOKTREE_878_DEVICE(0x18ac, 0xdb10, "DViCO FusionHDTV DVB-T Lite"),
404 BROOKTREE_878_DEVICE(0x18ac, 0xdb11, "Ultraview DVB-T Lite"),
405 BROOKTREE_878_DEVICE(0x18ac, 0xd500, "DViCO FusionHDTV 5 Lite"),
406 BROOKTREE_878_DEVICE(0x7063, 0x2000, "pcHDTV HD-2000 TV"),
407 BROOKTREE_878_DEVICE(0x1822, 0x0026, "DNTV Live! Mini"),
408 { }
409};
410
411MODULE_DEVICE_TABLE(pci, bt878_pci_tbl);
412
413static const char * __devinit card_name(const struct pci_device_id *id)
414{
415 return id->driver_data ? (const char *)id->driver_data : "Unknown";
416}
417
418/***********************/
419/* PCI device handling */
420/***********************/
421
422static int __devinit bt878_probe(struct pci_dev *dev,
423 const struct pci_device_id *pci_id)
424{
425 int result = 0;
426 unsigned char lat;
427 struct bt878 *bt;
428#if defined(__powerpc__)
429 unsigned int cmd;
430#endif
431 unsigned int cardid;
432
433 printk(KERN_INFO "bt878: Bt878 AUDIO function found (%d).\n",
434 bt878_num);
435 if (bt878_num >= BT878_MAX) {
436 printk(KERN_ERR "bt878: Too many devices inserted\n");
437 result = -ENOMEM;
438 goto fail0;
439 }
440 if (pci_enable_device(dev))
441 return -EIO;
442
443 cardid = dev->subsystem_device << 16;
444 cardid |= dev->subsystem_vendor;
445
446 printk(KERN_INFO "%s: card id=[0x%x],[ %s ] has DVB functions.\n",
447 __func__, cardid, card_name(pci_id));
448
449 bt = &bt878[bt878_num];
450 bt->dev = dev;
451 bt->nr = bt878_num;
452 bt->shutdown = 0;
453
454 bt->id = dev->device;
455 bt->irq = dev->irq;
456 bt->bt878_adr = pci_resource_start(dev, 0);
457 if (!request_mem_region(pci_resource_start(dev, 0),
458 pci_resource_len(dev, 0), "bt878")) {
459 result = -EBUSY;
460 goto fail0;
461 }
462
463 bt->revision = dev->revision;
464 pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
465
466
467 printk(KERN_INFO "bt878(%d): Bt%x (rev %d) at %02x:%02x.%x, ",
468 bt878_num, bt->id, bt->revision, dev->bus->number,
469 PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
470 printk("irq: %d, latency: %d, memory: 0x%lx\n",
471 bt->irq, lat, bt->bt878_adr);
472
473
474#if defined(__powerpc__)
475 /* on OpenFirmware machines (PowerMac at least), PCI memory cycle */
476 /* response on cards with no firmware is not enabled by OF */
477 pci_read_config_dword(dev, PCI_COMMAND, &cmd);
478 cmd = (cmd | PCI_COMMAND_MEMORY);
479 pci_write_config_dword(dev, PCI_COMMAND, cmd);
480#endif
481
482#ifdef __sparc__
483 bt->bt878_mem = (unsigned char *) bt->bt878_adr;
484#else
485 bt->bt878_mem = ioremap(bt->bt878_adr, 0x1000);
486#endif
487
488 /* clear interrupt mask */
489 btwrite(0, BT848_INT_MASK);
490
491 result = request_irq(bt->irq, bt878_irq,
492 IRQF_SHARED | IRQF_DISABLED, "bt878",
493 (void *) bt);
494 if (result == -EINVAL) {
495 printk(KERN_ERR "bt878(%d): Bad irq number or handler\n",
496 bt878_num);
497 goto fail1;
498 }
499 if (result == -EBUSY) {
500 printk(KERN_ERR
501 "bt878(%d): IRQ %d busy, change your PnP config in BIOS\n",
502 bt878_num, bt->irq);
503 goto fail1;
504 }
505 if (result < 0)
506 goto fail1;
507
508 pci_set_master(dev);
509 pci_set_drvdata(dev, bt);
510
511 if ((result = bt878_mem_alloc(bt))) {
512 printk(KERN_ERR "bt878: failed to allocate memory!\n");
513 goto fail2;
514 }
515
516 bt878_make_risc(bt);
517 btwrite(0, BT878_AINT_MASK);
518 bt878_num++;
519
520 return 0;
521
522 fail2:
523 free_irq(bt->irq, bt);
524 fail1:
525 release_mem_region(pci_resource_start(bt->dev, 0),
526 pci_resource_len(bt->dev, 0));
527 fail0:
528 pci_disable_device(dev);
529 return result;
530}
531
532static void __devexit bt878_remove(struct pci_dev *pci_dev)
533{
534 u8 command;
535 struct bt878 *bt = pci_get_drvdata(pci_dev);
536
537 if (bt878_verbose)
538 printk(KERN_INFO "bt878(%d): unloading\n", bt->nr);
539
540 /* turn off all capturing, DMA and IRQs */
541 btand(~0x13, BT878_AGPIO_DMA_CTL);
542
543 /* first disable interrupts before unmapping the memory! */
544 btwrite(0, BT878_AINT_MASK);
545 btwrite(~0U, BT878_AINT_STAT);
546
547 /* disable PCI bus-mastering */
548 pci_read_config_byte(bt->dev, PCI_COMMAND, &command);
549 /* Should this be &=~ ?? */
550 command &= ~PCI_COMMAND_MASTER;
551 pci_write_config_byte(bt->dev, PCI_COMMAND, command);
552
553 free_irq(bt->irq, bt);
554 printk(KERN_DEBUG "bt878_mem: 0x%p.\n", bt->bt878_mem);
555 if (bt->bt878_mem)
556 iounmap(bt->bt878_mem);
557
558 release_mem_region(pci_resource_start(bt->dev, 0),
559 pci_resource_len(bt->dev, 0));
560 /* wake up any waiting processes
561 because shutdown flag is set, no new processes (in this queue)
562 are expected
563 */
564 bt->shutdown = 1;
565 bt878_mem_free(bt);
566
567 pci_set_drvdata(pci_dev, NULL);
568 pci_disable_device(pci_dev);
569 return;
570}
571
572static struct pci_driver bt878_pci_driver = {
573 .name = "bt878",
574 .id_table = bt878_pci_tbl,
575 .probe = bt878_probe,
576 .remove = __devexit_p(bt878_remove),
577};
578
579/*******************************/
580/* Module management functions */
581/*******************************/
582
583static int __init bt878_init_module(void)
584{
585 bt878_num = 0;
586
587 printk(KERN_INFO "bt878: AUDIO driver version %d.%d.%d loaded\n",
588 (BT878_VERSION_CODE >> 16) & 0xff,
589 (BT878_VERSION_CODE >> 8) & 0xff,
590 BT878_VERSION_CODE & 0xff);
591
592 return pci_register_driver(&bt878_pci_driver);
593}
594
595static void __exit bt878_cleanup_module(void)
596{
597 pci_unregister_driver(&bt878_pci_driver);
598}
599
600module_init(bt878_init_module);
601module_exit(bt878_cleanup_module);
602
603MODULE_LICENSE("GPL");
604
605/*
606 * Local variables:
607 * c-basic-offset: 8
608 * End:
609 */
diff --git a/drivers/media/dvb/bt8xx/bt878.h b/drivers/media/dvb/bt8xx/bt878.h
new file mode 100644
index 00000000000..d19b59299d7
--- /dev/null
+++ b/drivers/media/dvb/bt8xx/bt878.h
@@ -0,0 +1,159 @@
1/*
2 bt878.h - Bt878 audio module (register offsets)
3
4 Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@htp-tel.de>
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 _BT878_H_
22#define _BT878_H_
23
24#include <linux/interrupt.h>
25#include <linux/pci.h>
26#include <linux/sched.h>
27#include <linux/spinlock.h>
28#include <linux/mutex.h>
29
30#include "bt848.h"
31#include "bttv.h"
32
33#define BT878_VERSION_CODE 0x000000
34
35#define BT878_AINT_STAT 0x100
36#define BT878_ARISCS (0xf<<28)
37#define BT878_ARISC_EN (1<<27)
38#define BT878_ASCERR (1<<19)
39#define BT878_AOCERR (1<<18)
40#define BT878_APABORT (1<<17)
41#define BT878_ARIPERR (1<<16)
42#define BT878_APPERR (1<<15)
43#define BT878_AFDSR (1<<14)
44#define BT878_AFTRGT (1<<13)
45#define BT878_AFBUS (1<<12)
46#define BT878_ARISCI (1<<11)
47#define BT878_AOFLOW (1<<3)
48
49#define BT878_AINT_MASK 0x104
50
51#define BT878_AGPIO_DMA_CTL 0x10c
52#define BT878_A_GAIN (0xf<<28)
53#define BT878_A_G2X (1<<27)
54#define BT878_A_PWRDN (1<<26)
55#define BT878_A_SEL (3<<24)
56#define BT878_DA_SCE (1<<23)
57#define BT878_DA_LRI (1<<22)
58#define BT878_DA_MLB (1<<21)
59#define BT878_DA_LRD (0x1f<<16)
60#define BT878_DA_DPM (1<<15)
61#define BT878_DA_SBR (1<<14)
62#define BT878_DA_ES2 (1<<13)
63#define BT878_DA_LMT (1<<12)
64#define BT878_DA_SDR (0xf<<8)
65#define BT878_DA_IOM (3<<6)
66#define BT878_DA_APP (1<<5)
67#define BT878_ACAP_EN (1<<4)
68#define BT878_PKTP (3<<2)
69#define BT878_RISC_EN (1<<1)
70#define BT878_FIFO_EN 1
71
72#define BT878_APACK_LEN 0x110
73#define BT878_AFP_LEN (0xff<<16)
74#define BT878_ALP_LEN 0xfff
75
76#define BT878_ARISC_START 0x114
77
78#define BT878_ARISC_PC 0x120
79
80/* BT878 FUNCTION 0 REGISTERS */
81#define BT878_GPIO_DMA_CTL 0x10c
82
83/* Interrupt register */
84#define BT878_INT_STAT 0x100
85#define BT878_INT_MASK 0x104
86#define BT878_I2CRACK (1<<25)
87#define BT878_I2CDONE (1<<8)
88
89#define BT878_MAX 4
90
91#define BT878_RISC_SYNC_MASK (1 << 15)
92
93
94#define BTTV_BOARD_UNKNOWN 0x00
95#define BTTV_BOARD_PINNACLESAT 0x5e
96#define BTTV_BOARD_NEBULA_DIGITV 0x68
97#define BTTV_BOARD_PC_HDTV 0x70
98#define BTTV_BOARD_TWINHAN_DST 0x71
99#define BTTV_BOARD_AVDVBT_771 0x7b
100#define BTTV_BOARD_AVDVBT_761 0x7c
101#define BTTV_BOARD_DVICO_DVBT_LITE 0x80
102#define BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE 0x87
103
104extern int bt878_num;
105
106struct bt878 {
107 struct mutex gpio_lock;
108 unsigned int nr;
109 unsigned int bttv_nr;
110 struct i2c_adapter *adapter;
111 struct pci_dev *dev;
112 unsigned int id;
113 unsigned int TS_Size;
114 unsigned char revision;
115 unsigned int irq;
116 unsigned long bt878_adr;
117 volatile void __iomem *bt878_mem; /* function 1 */
118
119 volatile u32 finished_block;
120 volatile u32 last_block;
121 u32 block_count;
122 u32 block_bytes;
123 u32 line_bytes;
124 u32 line_count;
125
126 u32 buf_size;
127 u8 *buf_cpu;
128 dma_addr_t buf_dma;
129
130 u32 risc_size;
131 __le32 *risc_cpu;
132 dma_addr_t risc_dma;
133 u32 risc_pos;
134
135 struct tasklet_struct tasklet;
136 int shutdown;
137};
138
139extern struct bt878 bt878[BT878_MAX];
140
141void bt878_start(struct bt878 *bt, u32 controlreg, u32 op_sync_orin,
142 u32 irq_err_ignore);
143void bt878_stop(struct bt878 *bt);
144
145#if defined(__powerpc__) /* big-endian */
146static inline void io_st_le32(volatile unsigned __iomem *addr, unsigned val)
147{
148 st_le32(addr, val);
149 eieio();
150}
151
152#define bmtwrite(dat,adr) io_st_le32((adr),(dat))
153#define bmtread(adr) ld_le32((adr))
154#else
155#define bmtwrite(dat,adr) writel((dat), (adr))
156#define bmtread(adr) readl(adr)
157#endif
158
159#endif
diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c
new file mode 100644
index 00000000000..caa4e18ed1c
--- /dev/null
+++ b/drivers/media/dvb/bt8xx/dst.c
@@ -0,0 +1,1873 @@
1/*
2 Frontend/Card driver for TwinHan DST Frontend
3 Copyright (C) 2003 Jamie Honan
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#include <linux/kernel.h>
22#include <linux/module.h>
23#include <linux/init.h>
24#include <linux/string.h>
25#include <linux/slab.h>
26#include <linux/vmalloc.h>
27#include <linux/delay.h>
28#include <asm/div64.h>
29#include "dvb_frontend.h"
30#include "dst_priv.h"
31#include "dst_common.h"
32
33static unsigned int verbose = 1;
34module_param(verbose, int, 0644);
35MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)");
36
37static unsigned int dst_addons;
38module_param(dst_addons, int, 0644);
39MODULE_PARM_DESC(dst_addons, "CA daughterboard, default is 0 (No addons)");
40
41static unsigned int dst_algo;
42module_param(dst_algo, int, 0644);
43MODULE_PARM_DESC(dst_algo, "tuning algo: default is 0=(SW), 1=(HW)");
44
45#define HAS_LOCK 1
46#define ATTEMPT_TUNE 2
47#define HAS_POWER 4
48
49#define DST_ERROR 0
50#define DST_NOTICE 1
51#define DST_INFO 2
52#define DST_DEBUG 3
53
54#define dprintk(x, y, z, format, arg...) do { \
55 if (z) { \
56 if ((x > DST_ERROR) && (x > y)) \
57 printk(KERN_ERR "dst(%d) %s: " format "\n", \
58 state->bt->nr, __func__ , ##arg); \
59 else if ((x > DST_NOTICE) && (x > y)) \
60 printk(KERN_NOTICE "dst(%d) %s: " format "\n", \
61 state->bt->nr, __func__ , ##arg); \
62 else if ((x > DST_INFO) && (x > y)) \
63 printk(KERN_INFO "dst(%d) %s: " format "\n", \
64 state->bt->nr, __func__ , ##arg); \
65 else if ((x > DST_DEBUG) && (x > y)) \
66 printk(KERN_DEBUG "dst(%d) %s: " format "\n", \
67 state->bt->nr, __func__ , ##arg); \
68 } else { \
69 if (x > y) \
70 printk(format, ##arg); \
71 } \
72} while(0)
73
74static int dst_command(struct dst_state *state, u8 *data, u8 len);
75
76static void dst_packsize(struct dst_state *state, int psize)
77{
78 union dst_gpio_packet bits;
79
80 bits.psize = psize;
81 bt878_device_control(state->bt, DST_IG_TS, &bits);
82}
83
84static int dst_gpio_outb(struct dst_state *state, u32 mask, u32 enbb,
85 u32 outhigh, int delay)
86{
87 union dst_gpio_packet enb;
88 union dst_gpio_packet bits;
89 int err;
90
91 enb.enb.mask = mask;
92 enb.enb.enable = enbb;
93
94 dprintk(verbose, DST_INFO, 1, "mask=[%04x], enbb=[%04x], outhigh=[%04x]", mask, enbb, outhigh);
95 if ((err = bt878_device_control(state->bt, DST_IG_ENABLE, &enb)) < 0) {
96 dprintk(verbose, DST_INFO, 1, "dst_gpio_enb error (err == %i, mask == %02x, enb == %02x)", err, mask, enbb);
97 return -EREMOTEIO;
98 }
99 udelay(1000);
100 /* because complete disabling means no output, no need to do output packet */
101 if (enbb == 0)
102 return 0;
103 if (delay)
104 msleep(10);
105 bits.outp.mask = enbb;
106 bits.outp.highvals = outhigh;
107 if ((err = bt878_device_control(state->bt, DST_IG_WRITE, &bits)) < 0) {
108 dprintk(verbose, DST_INFO, 1, "dst_gpio_outb error (err == %i, enbb == %02x, outhigh == %02x)", err, enbb, outhigh);
109 return -EREMOTEIO;
110 }
111
112 return 0;
113}
114
115static int dst_gpio_inb(struct dst_state *state, u8 *result)
116{
117 union dst_gpio_packet rd_packet;
118 int err;
119
120 *result = 0;
121 if ((err = bt878_device_control(state->bt, DST_IG_READ, &rd_packet)) < 0) {
122 dprintk(verbose, DST_ERROR, 1, "dst_gpio_inb error (err == %i)", err);
123 return -EREMOTEIO;
124 }
125 *result = (u8) rd_packet.rd.value;
126
127 return 0;
128}
129
130int rdc_reset_state(struct dst_state *state)
131{
132 dprintk(verbose, DST_INFO, 1, "Resetting state machine");
133 if (dst_gpio_outb(state, RDC_8820_INT, RDC_8820_INT, 0, NO_DELAY) < 0) {
134 dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !");
135 return -1;
136 }
137 msleep(10);
138 if (dst_gpio_outb(state, RDC_8820_INT, RDC_8820_INT, RDC_8820_INT, NO_DELAY) < 0) {
139 dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !");
140 msleep(10);
141 return -1;
142 }
143
144 return 0;
145}
146EXPORT_SYMBOL(rdc_reset_state);
147
148static int rdc_8820_reset(struct dst_state *state)
149{
150 dprintk(verbose, DST_DEBUG, 1, "Resetting DST");
151 if (dst_gpio_outb(state, RDC_8820_RESET, RDC_8820_RESET, 0, NO_DELAY) < 0) {
152 dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !");
153 return -1;
154 }
155 udelay(1000);
156 if (dst_gpio_outb(state, RDC_8820_RESET, RDC_8820_RESET, RDC_8820_RESET, DELAY) < 0) {
157 dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !");
158 return -1;
159 }
160
161 return 0;
162}
163
164static int dst_pio_enable(struct dst_state *state)
165{
166 if (dst_gpio_outb(state, ~0, RDC_8820_PIO_0_ENABLE, 0, NO_DELAY) < 0) {
167 dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !");
168 return -1;
169 }
170 udelay(1000);
171
172 return 0;
173}
174
175int dst_pio_disable(struct dst_state *state)
176{
177 if (dst_gpio_outb(state, ~0, RDC_8820_PIO_0_DISABLE, RDC_8820_PIO_0_DISABLE, NO_DELAY) < 0) {
178 dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !");
179 return -1;
180 }
181 if (state->type_flags & DST_TYPE_HAS_FW_1)
182 udelay(1000);
183
184 return 0;
185}
186EXPORT_SYMBOL(dst_pio_disable);
187
188int dst_wait_dst_ready(struct dst_state *state, u8 delay_mode)
189{
190 u8 reply;
191 int i;
192
193 for (i = 0; i < 200; i++) {
194 if (dst_gpio_inb(state, &reply) < 0) {
195 dprintk(verbose, DST_ERROR, 1, "dst_gpio_inb ERROR !");
196 return -1;
197 }
198 if ((reply & RDC_8820_PIO_0_ENABLE) == 0) {
199 dprintk(verbose, DST_INFO, 1, "dst wait ready after %d", i);
200 return 1;
201 }
202 msleep(10);
203 }
204 dprintk(verbose, DST_NOTICE, 1, "dst wait NOT ready after %d", i);
205
206 return 0;
207}
208EXPORT_SYMBOL(dst_wait_dst_ready);
209
210int dst_error_recovery(struct dst_state *state)
211{
212 dprintk(verbose, DST_NOTICE, 1, "Trying to return from previous errors.");
213 dst_pio_disable(state);
214 msleep(10);
215 dst_pio_enable(state);
216 msleep(10);
217
218 return 0;
219}
220EXPORT_SYMBOL(dst_error_recovery);
221
222int dst_error_bailout(struct dst_state *state)
223{
224 dprintk(verbose, DST_INFO, 1, "Trying to bailout from previous error.");
225 rdc_8820_reset(state);
226 dst_pio_disable(state);
227 msleep(10);
228
229 return 0;
230}
231EXPORT_SYMBOL(dst_error_bailout);
232
233int dst_comm_init(struct dst_state *state)
234{
235 dprintk(verbose, DST_INFO, 1, "Initializing DST.");
236 if ((dst_pio_enable(state)) < 0) {
237 dprintk(verbose, DST_ERROR, 1, "PIO Enable Failed");
238 return -1;
239 }
240 if ((rdc_reset_state(state)) < 0) {
241 dprintk(verbose, DST_ERROR, 1, "RDC 8820 State RESET Failed.");
242 return -1;
243 }
244 if (state->type_flags & DST_TYPE_HAS_FW_1)
245 msleep(100);
246 else
247 msleep(5);
248
249 return 0;
250}
251EXPORT_SYMBOL(dst_comm_init);
252
253int write_dst(struct dst_state *state, u8 *data, u8 len)
254{
255 struct i2c_msg msg = {
256 .addr = state->config->demod_address,
257 .flags = 0,
258 .buf = data,
259 .len = len
260 };
261
262 int err;
263 u8 cnt, i;
264
265 dprintk(verbose, DST_NOTICE, 0, "writing [ ");
266 for (i = 0; i < len; i++)
267 dprintk(verbose, DST_NOTICE, 0, "%02x ", data[i]);
268 dprintk(verbose, DST_NOTICE, 0, "]\n");
269
270 for (cnt = 0; cnt < 2; cnt++) {
271 if ((err = i2c_transfer(state->i2c, &msg, 1)) < 0) {
272 dprintk(verbose, DST_INFO, 1, "_write_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)", err, len, data[0]);
273 dst_error_recovery(state);
274 continue;
275 } else
276 break;
277 }
278 if (cnt >= 2) {
279 dprintk(verbose, DST_INFO, 1, "RDC 8820 RESET");
280 dst_error_bailout(state);
281
282 return -1;
283 }
284
285 return 0;
286}
287EXPORT_SYMBOL(write_dst);
288
289int read_dst(struct dst_state *state, u8 *ret, u8 len)
290{
291 struct i2c_msg msg = {
292 .addr = state->config->demod_address,
293 .flags = I2C_M_RD,
294 .buf = ret,
295 .len = len
296 };
297
298 int err;
299 int cnt;
300
301 for (cnt = 0; cnt < 2; cnt++) {
302 if ((err = i2c_transfer(state->i2c, &msg, 1)) < 0) {
303 dprintk(verbose, DST_INFO, 1, "read_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)", err, len, ret[0]);
304 dst_error_recovery(state);
305 continue;
306 } else
307 break;
308 }
309 if (cnt >= 2) {
310 dprintk(verbose, DST_INFO, 1, "RDC 8820 RESET");
311 dst_error_bailout(state);
312
313 return -1;
314 }
315 dprintk(verbose, DST_DEBUG, 1, "reply is 0x%x", ret[0]);
316 for (err = 1; err < len; err++)
317 dprintk(verbose, DST_DEBUG, 0, " 0x%x", ret[err]);
318 if (err > 1)
319 dprintk(verbose, DST_DEBUG, 0, "\n");
320
321 return 0;
322}
323EXPORT_SYMBOL(read_dst);
324
325static int dst_set_polarization(struct dst_state *state)
326{
327 switch (state->voltage) {
328 case SEC_VOLTAGE_13: /* Vertical */
329 dprintk(verbose, DST_INFO, 1, "Polarization=[Vertical]");
330 state->tx_tuna[8] &= ~0x40;
331 break;
332 case SEC_VOLTAGE_18: /* Horizontal */
333 dprintk(verbose, DST_INFO, 1, "Polarization=[Horizontal]");
334 state->tx_tuna[8] |= 0x40;
335 break;
336 case SEC_VOLTAGE_OFF:
337 break;
338 }
339
340 return 0;
341}
342
343static int dst_set_freq(struct dst_state *state, u32 freq)
344{
345 state->frequency = freq;
346 dprintk(verbose, DST_INFO, 1, "set Frequency %u", freq);
347
348 if (state->dst_type == DST_TYPE_IS_SAT) {
349 freq = freq / 1000;
350 if (freq < 950 || freq > 2150)
351 return -EINVAL;
352 state->tx_tuna[2] = (freq >> 8);
353 state->tx_tuna[3] = (u8) freq;
354 state->tx_tuna[4] = 0x01;
355 state->tx_tuna[8] &= ~0x04;
356 if (state->type_flags & DST_TYPE_HAS_OBS_REGS) {
357 if (freq < 1531)
358 state->tx_tuna[8] |= 0x04;
359 }
360 } else if (state->dst_type == DST_TYPE_IS_TERR) {
361 freq = freq / 1000;
362 if (freq < 137000 || freq > 858000)
363 return -EINVAL;
364 state->tx_tuna[2] = (freq >> 16) & 0xff;
365 state->tx_tuna[3] = (freq >> 8) & 0xff;
366 state->tx_tuna[4] = (u8) freq;
367 } else if (state->dst_type == DST_TYPE_IS_CABLE) {
368 freq = freq / 1000;
369 state->tx_tuna[2] = (freq >> 16) & 0xff;
370 state->tx_tuna[3] = (freq >> 8) & 0xff;
371 state->tx_tuna[4] = (u8) freq;
372 } else if (state->dst_type == DST_TYPE_IS_ATSC) {
373 freq = freq / 1000;
374 if (freq < 51000 || freq > 858000)
375 return -EINVAL;
376 state->tx_tuna[2] = (freq >> 16) & 0xff;
377 state->tx_tuna[3] = (freq >> 8) & 0xff;
378 state->tx_tuna[4] = (u8) freq;
379 state->tx_tuna[5] = 0x00; /* ATSC */
380 state->tx_tuna[6] = 0x00;
381 if (state->dst_hw_cap & DST_TYPE_HAS_ANALOG)
382 state->tx_tuna[7] = 0x00; /* Digital */
383 } else
384 return -EINVAL;
385
386 return 0;
387}
388
389static int dst_set_bandwidth(struct dst_state *state, fe_bandwidth_t bandwidth)
390{
391 state->bandwidth = bandwidth;
392
393 if (state->dst_type != DST_TYPE_IS_TERR)
394 return -EOPNOTSUPP;
395
396 switch (bandwidth) {
397 case BANDWIDTH_6_MHZ:
398 if (state->dst_hw_cap & DST_TYPE_HAS_CA)
399 state->tx_tuna[7] = 0x06;
400 else {
401 state->tx_tuna[6] = 0x06;
402 state->tx_tuna[7] = 0x00;
403 }
404 break;
405 case BANDWIDTH_7_MHZ:
406 if (state->dst_hw_cap & DST_TYPE_HAS_CA)
407 state->tx_tuna[7] = 0x07;
408 else {
409 state->tx_tuna[6] = 0x07;
410 state->tx_tuna[7] = 0x00;
411 }
412 break;
413 case BANDWIDTH_8_MHZ:
414 if (state->dst_hw_cap & DST_TYPE_HAS_CA)
415 state->tx_tuna[7] = 0x08;
416 else {
417 state->tx_tuna[6] = 0x08;
418 state->tx_tuna[7] = 0x00;
419 }
420 break;
421 default:
422 return -EINVAL;
423 }
424
425 return 0;
426}
427
428static int dst_set_inversion(struct dst_state *state, fe_spectral_inversion_t inversion)
429{
430 state->inversion = inversion;
431 switch (inversion) {
432 case INVERSION_OFF: /* Inversion = Normal */
433 state->tx_tuna[8] &= ~0x80;
434 break;
435 case INVERSION_ON:
436 state->tx_tuna[8] |= 0x80;
437 break;
438 default:
439 return -EINVAL;
440 }
441
442 return 0;
443}
444
445static int dst_set_fec(struct dst_state *state, fe_code_rate_t fec)
446{
447 state->fec = fec;
448 return 0;
449}
450
451static fe_code_rate_t dst_get_fec(struct dst_state *state)
452{
453 return state->fec;
454}
455
456static int dst_set_symbolrate(struct dst_state *state, u32 srate)
457{
458 u32 symcalc;
459 u64 sval;
460
461 state->symbol_rate = srate;
462 if (state->dst_type == DST_TYPE_IS_TERR) {
463 return -EOPNOTSUPP;
464 }
465 dprintk(verbose, DST_INFO, 1, "set symrate %u", srate);
466 srate /= 1000;
467 if (state->dst_type == DST_TYPE_IS_SAT) {
468 if (state->type_flags & DST_TYPE_HAS_SYMDIV) {
469 sval = srate;
470 sval <<= 20;
471 do_div(sval, 88000);
472 symcalc = (u32) sval;
473 dprintk(verbose, DST_INFO, 1, "set symcalc %u", symcalc);
474 state->tx_tuna[5] = (u8) (symcalc >> 12);
475 state->tx_tuna[6] = (u8) (symcalc >> 4);
476 state->tx_tuna[7] = (u8) (symcalc << 4);
477 } else {
478 state->tx_tuna[5] = (u8) (srate >> 16) & 0x7f;
479 state->tx_tuna[6] = (u8) (srate >> 8);
480 state->tx_tuna[7] = (u8) srate;
481 }
482 state->tx_tuna[8] &= ~0x20;
483 if (state->type_flags & DST_TYPE_HAS_OBS_REGS) {
484 if (srate > 8000)
485 state->tx_tuna[8] |= 0x20;
486 }
487 } else if (state->dst_type == DST_TYPE_IS_CABLE) {
488 dprintk(verbose, DST_DEBUG, 1, "%s", state->fw_name);
489 if (!strncmp(state->fw_name, "DCTNEW", 6)) {
490 state->tx_tuna[5] = (u8) (srate >> 8);
491 state->tx_tuna[6] = (u8) srate;
492 state->tx_tuna[7] = 0x00;
493 } else if (!strncmp(state->fw_name, "DCT-CI", 6)) {
494 state->tx_tuna[5] = 0x00;
495 state->tx_tuna[6] = (u8) (srate >> 8);
496 state->tx_tuna[7] = (u8) srate;
497 }
498 }
499 return 0;
500}
501
502static int dst_set_modulation(struct dst_state *state, fe_modulation_t modulation)
503{
504 if (state->dst_type != DST_TYPE_IS_CABLE)
505 return -EOPNOTSUPP;
506
507 state->modulation = modulation;
508 switch (modulation) {
509 case QAM_16:
510 state->tx_tuna[8] = 0x10;
511 break;
512 case QAM_32:
513 state->tx_tuna[8] = 0x20;
514 break;
515 case QAM_64:
516 state->tx_tuna[8] = 0x40;
517 break;
518 case QAM_128:
519 state->tx_tuna[8] = 0x80;
520 break;
521 case QAM_256:
522 if (!strncmp(state->fw_name, "DCTNEW", 6))
523 state->tx_tuna[8] = 0xff;
524 else if (!strncmp(state->fw_name, "DCT-CI", 6))
525 state->tx_tuna[8] = 0x00;
526 break;
527 case QPSK:
528 case QAM_AUTO:
529 case VSB_8:
530 case VSB_16:
531 default:
532 return -EINVAL;
533
534 }
535
536 return 0;
537}
538
539static fe_modulation_t dst_get_modulation(struct dst_state *state)
540{
541 return state->modulation;
542}
543
544
545u8 dst_check_sum(u8 *buf, u32 len)
546{
547 u32 i;
548 u8 val = 0;
549 if (!len)
550 return 0;
551 for (i = 0; i < len; i++) {
552 val += buf[i];
553 }
554 return ((~val) + 1);
555}
556EXPORT_SYMBOL(dst_check_sum);
557
558static void dst_type_flags_print(struct dst_state *state)
559{
560 u32 type_flags = state->type_flags;
561
562 dprintk(verbose, DST_ERROR, 0, "DST type flags :");
563 if (type_flags & DST_TYPE_HAS_TS188)
564 dprintk(verbose, DST_ERROR, 0, " 0x%x newtuner", DST_TYPE_HAS_TS188);
565 if (type_flags & DST_TYPE_HAS_NEWTUNE_2)
566 dprintk(verbose, DST_ERROR, 0, " 0x%x newtuner 2", DST_TYPE_HAS_NEWTUNE_2);
567 if (type_flags & DST_TYPE_HAS_TS204)
568 dprintk(verbose, DST_ERROR, 0, " 0x%x ts204", DST_TYPE_HAS_TS204);
569 if (type_flags & DST_TYPE_HAS_VLF)
570 dprintk(verbose, DST_ERROR, 0, " 0x%x VLF", DST_TYPE_HAS_VLF);
571 if (type_flags & DST_TYPE_HAS_SYMDIV)
572 dprintk(verbose, DST_ERROR, 0, " 0x%x symdiv", DST_TYPE_HAS_SYMDIV);
573 if (type_flags & DST_TYPE_HAS_FW_1)
574 dprintk(verbose, DST_ERROR, 0, " 0x%x firmware version = 1", DST_TYPE_HAS_FW_1);
575 if (type_flags & DST_TYPE_HAS_FW_2)
576 dprintk(verbose, DST_ERROR, 0, " 0x%x firmware version = 2", DST_TYPE_HAS_FW_2);
577 if (type_flags & DST_TYPE_HAS_FW_3)
578 dprintk(verbose, DST_ERROR, 0, " 0x%x firmware version = 3", DST_TYPE_HAS_FW_3);
579 dprintk(verbose, DST_ERROR, 0, "\n");
580}
581
582
583static int dst_type_print(struct dst_state *state, u8 type)
584{
585 char *otype;
586 switch (type) {
587 case DST_TYPE_IS_SAT:
588 otype = "satellite";
589 break;
590
591 case DST_TYPE_IS_TERR:
592 otype = "terrestrial";
593 break;
594
595 case DST_TYPE_IS_CABLE:
596 otype = "cable";
597 break;
598
599 case DST_TYPE_IS_ATSC:
600 otype = "atsc";
601 break;
602
603 default:
604 dprintk(verbose, DST_INFO, 1, "invalid dst type %d", type);
605 return -EINVAL;
606 }
607 dprintk(verbose, DST_INFO, 1, "DST type: %s", otype);
608
609 return 0;
610}
611
612static struct tuner_types tuner_list[] = {
613 {
614 .tuner_type = TUNER_TYPE_L64724,
615 .tuner_name = "L 64724",
616 .board_name = "UNKNOWN",
617 .fw_name = "UNKNOWN"
618 },
619
620 {
621 .tuner_type = TUNER_TYPE_STV0299,
622 .tuner_name = "STV 0299",
623 .board_name = "VP1020",
624 .fw_name = "DST-MOT"
625 },
626
627 {
628 .tuner_type = TUNER_TYPE_STV0299,
629 .tuner_name = "STV 0299",
630 .board_name = "VP1020",
631 .fw_name = "DST-03T"
632 },
633
634 {
635 .tuner_type = TUNER_TYPE_MB86A15,
636 .tuner_name = "MB 86A15",
637 .board_name = "VP1022",
638 .fw_name = "DST-03T"
639 },
640
641 {
642 .tuner_type = TUNER_TYPE_MB86A15,
643 .tuner_name = "MB 86A15",
644 .board_name = "VP1025",
645 .fw_name = "DST-03T"
646 },
647
648 {
649 .tuner_type = TUNER_TYPE_STV0299,
650 .tuner_name = "STV 0299",
651 .board_name = "VP1030",
652 .fw_name = "DST-CI"
653 },
654
655 {
656 .tuner_type = TUNER_TYPE_STV0299,
657 .tuner_name = "STV 0299",
658 .board_name = "VP1030",
659 .fw_name = "DSTMCI"
660 },
661
662 {
663 .tuner_type = TUNER_TYPE_UNKNOWN,
664 .tuner_name = "UNKNOWN",
665 .board_name = "VP2021",
666 .fw_name = "DCTNEW"
667 },
668
669 {
670 .tuner_type = TUNER_TYPE_UNKNOWN,
671 .tuner_name = "UNKNOWN",
672 .board_name = "VP2030",
673 .fw_name = "DCT-CI"
674 },
675
676 {
677 .tuner_type = TUNER_TYPE_UNKNOWN,
678 .tuner_name = "UNKNOWN",
679 .board_name = "VP2031",
680 .fw_name = "DCT-CI"
681 },
682
683 {
684 .tuner_type = TUNER_TYPE_UNKNOWN,
685 .tuner_name = "UNKNOWN",
686 .board_name = "VP2040",
687 .fw_name = "DCT-CI"
688 },
689
690 {
691 .tuner_type = TUNER_TYPE_UNKNOWN,
692 .tuner_name = "UNKNOWN",
693 .board_name = "VP3020",
694 .fw_name = "DTTFTA"
695 },
696
697 {
698 .tuner_type = TUNER_TYPE_UNKNOWN,
699 .tuner_name = "UNKNOWN",
700 .board_name = "VP3021",
701 .fw_name = "DTTFTA"
702 },
703
704 {
705 .tuner_type = TUNER_TYPE_TDA10046,
706 .tuner_name = "TDA10046",
707 .board_name = "VP3040",
708 .fw_name = "DTT-CI"
709 },
710
711 {
712 .tuner_type = TUNER_TYPE_UNKNOWN,
713 .tuner_name = "UNKNOWN",
714 .board_name = "VP3051",
715 .fw_name = "DTTNXT"
716 },
717
718 {
719 .tuner_type = TUNER_TYPE_NXT200x,
720 .tuner_name = "NXT200x",
721 .board_name = "VP3220",
722 .fw_name = "ATSCDI"
723 },
724
725 {
726 .tuner_type = TUNER_TYPE_NXT200x,
727 .tuner_name = "NXT200x",
728 .board_name = "VP3250",
729 .fw_name = "ATSCAD"
730 },
731};
732
733/*
734 Known cards list
735 Satellite
736 -------------------
737 200103A
738 VP-1020 DST-MOT LG(old), TS=188
739
740 VP-1020 DST-03T LG(new), TS=204
741 VP-1022 DST-03T LG(new), TS=204
742 VP-1025 DST-03T LG(new), TS=204
743
744 VP-1030 DSTMCI, LG(new), TS=188
745 VP-1032 DSTMCI, LG(new), TS=188
746
747 Cable
748 -------------------
749 VP-2030 DCT-CI, Samsung, TS=204
750 VP-2021 DCT-CI, Unknown, TS=204
751 VP-2031 DCT-CI, Philips, TS=188
752 VP-2040 DCT-CI, Philips, TS=188, with CA daughter board
753 VP-2040 DCT-CI, Philips, TS=204, without CA daughter board
754
755 Terrestrial
756 -------------------
757 VP-3050 DTTNXT TS=188
758 VP-3040 DTT-CI, Philips, TS=188
759 VP-3040 DTT-CI, Philips, TS=204
760
761 ATSC
762 -------------------
763 VP-3220 ATSCDI, TS=188
764 VP-3250 ATSCAD, TS=188
765
766*/
767
768static struct dst_types dst_tlist[] = {
769 {
770 .device_id = "200103A",
771 .offset = 0,
772 .dst_type = DST_TYPE_IS_SAT,
773 .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1 | DST_TYPE_HAS_OBS_REGS,
774 .dst_feature = 0,
775 .tuner_type = 0
776 }, /* obsolete */
777
778 {
779 .device_id = "DST-020",
780 .offset = 0,
781 .dst_type = DST_TYPE_IS_SAT,
782 .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1,
783 .dst_feature = 0,
784 .tuner_type = 0
785 }, /* obsolete */
786
787 {
788 .device_id = "DST-030",
789 .offset = 0,
790 .dst_type = DST_TYPE_IS_SAT,
791 .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_1,
792 .dst_feature = 0,
793 .tuner_type = 0
794 }, /* obsolete */
795
796 {
797 .device_id = "DST-03T",
798 .offset = 0,
799 .dst_type = DST_TYPE_IS_SAT,
800 .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_2,
801 .dst_feature = DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4 | DST_TYPE_HAS_DISEQC5
802 | DST_TYPE_HAS_MAC | DST_TYPE_HAS_MOTO,
803 .tuner_type = TUNER_TYPE_MULTI
804 },
805
806 {
807 .device_id = "DST-MOT",
808 .offset = 0,
809 .dst_type = DST_TYPE_IS_SAT,
810 .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1,
811 .dst_feature = 0,
812 .tuner_type = 0
813 }, /* obsolete */
814
815 {
816 .device_id = "DST-CI",
817 .offset = 1,
818 .dst_type = DST_TYPE_IS_SAT,
819 .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_1,
820 .dst_feature = DST_TYPE_HAS_CA,
821 .tuner_type = 0
822 }, /* An OEM board */
823
824 {
825 .device_id = "DSTMCI",
826 .offset = 1,
827 .dst_type = DST_TYPE_IS_SAT,
828 .type_flags = DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD | DST_TYPE_HAS_INC_COUNT | DST_TYPE_HAS_VLF,
829 .dst_feature = DST_TYPE_HAS_CA | DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4
830 | DST_TYPE_HAS_MOTO | DST_TYPE_HAS_MAC,
831 .tuner_type = TUNER_TYPE_MULTI
832 },
833
834 {
835 .device_id = "DSTFCI",
836 .offset = 1,
837 .dst_type = DST_TYPE_IS_SAT,
838 .type_flags = DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_1,
839 .dst_feature = 0,
840 .tuner_type = 0
841 }, /* unknown to vendor */
842
843 {
844 .device_id = "DCT-CI",
845 .offset = 1,
846 .dst_type = DST_TYPE_IS_CABLE,
847 .type_flags = DST_TYPE_HAS_MULTI_FE | DST_TYPE_HAS_FW_1 | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_VLF,
848 .dst_feature = DST_TYPE_HAS_CA,
849 .tuner_type = 0
850 },
851
852 {
853 .device_id = "DCTNEW",
854 .offset = 1,
855 .dst_type = DST_TYPE_IS_CABLE,
856 .type_flags = DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_3 | DST_TYPE_HAS_FW_BUILD | DST_TYPE_HAS_MULTI_FE,
857 .dst_feature = 0,
858 .tuner_type = 0
859 },
860
861 {
862 .device_id = "DTT-CI",
863 .offset = 1,
864 .dst_type = DST_TYPE_IS_TERR,
865 .type_flags = DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_MULTI_FE | DST_TYPE_HAS_VLF,
866 .dst_feature = DST_TYPE_HAS_CA,
867 .tuner_type = 0
868 },
869
870 {
871 .device_id = "DTTDIG",
872 .offset = 1,
873 .dst_type = DST_TYPE_IS_TERR,
874 .type_flags = DST_TYPE_HAS_FW_2,
875 .dst_feature = 0,
876 .tuner_type = 0
877 },
878
879 {
880 .device_id = "DTTNXT",
881 .offset = 1,
882 .dst_type = DST_TYPE_IS_TERR,
883 .type_flags = DST_TYPE_HAS_FW_2,
884 .dst_feature = DST_TYPE_HAS_ANALOG,
885 .tuner_type = 0
886 },
887
888 {
889 .device_id = "ATSCDI",
890 .offset = 1,
891 .dst_type = DST_TYPE_IS_ATSC,
892 .type_flags = DST_TYPE_HAS_FW_2,
893 .dst_feature = 0,
894 .tuner_type = 0
895 },
896
897 {
898 .device_id = "ATSCAD",
899 .offset = 1,
900 .dst_type = DST_TYPE_IS_ATSC,
901 .type_flags = DST_TYPE_HAS_MULTI_FE | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD,
902 .dst_feature = DST_TYPE_HAS_MAC | DST_TYPE_HAS_ANALOG,
903 .tuner_type = 0
904 },
905
906 { }
907
908};
909
910static int dst_get_mac(struct dst_state *state)
911{
912 u8 get_mac[] = { 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
913 get_mac[7] = dst_check_sum(get_mac, 7);
914 if (dst_command(state, get_mac, 8) < 0) {
915 dprintk(verbose, DST_INFO, 1, "Unsupported Command");
916 return -1;
917 }
918 memset(&state->mac_address, '\0', 8);
919 memcpy(&state->mac_address, &state->rxbuffer, 6);
920 dprintk(verbose, DST_ERROR, 1, "MAC Address=[%pM]", state->mac_address);
921
922 return 0;
923}
924
925static int dst_fw_ver(struct dst_state *state)
926{
927 u8 get_ver[] = { 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
928 get_ver[7] = dst_check_sum(get_ver, 7);
929 if (dst_command(state, get_ver, 8) < 0) {
930 dprintk(verbose, DST_INFO, 1, "Unsupported Command");
931 return -1;
932 }
933 memcpy(&state->fw_version, &state->rxbuffer, 8);
934 dprintk(verbose, DST_ERROR, 1, "Firmware Ver = %x.%x Build = %02x, on %x:%x, %x-%x-20%02x",
935 state->fw_version[0] >> 4, state->fw_version[0] & 0x0f,
936 state->fw_version[1],
937 state->fw_version[5], state->fw_version[6],
938 state->fw_version[4], state->fw_version[3], state->fw_version[2]);
939
940 return 0;
941}
942
943static int dst_card_type(struct dst_state *state)
944{
945 int j;
946 struct tuner_types *p_tuner_list = NULL;
947
948 u8 get_type[] = { 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
949 get_type[7] = dst_check_sum(get_type, 7);
950 if (dst_command(state, get_type, 8) < 0) {
951 dprintk(verbose, DST_INFO, 1, "Unsupported Command");
952 return -1;
953 }
954 memset(&state->card_info, '\0', 8);
955 memcpy(&state->card_info, &state->rxbuffer, 7);
956 dprintk(verbose, DST_ERROR, 1, "Device Model=[%s]", &state->card_info[0]);
957
958 for (j = 0, p_tuner_list = tuner_list; j < ARRAY_SIZE(tuner_list); j++, p_tuner_list++) {
959 if (!strcmp(&state->card_info[0], p_tuner_list->board_name)) {
960 state->tuner_type = p_tuner_list->tuner_type;
961 dprintk(verbose, DST_ERROR, 1, "DST has [%s] tuner, tuner type=[%d]",
962 p_tuner_list->tuner_name, p_tuner_list->tuner_type);
963 }
964 }
965
966 return 0;
967}
968
969static int dst_get_vendor(struct dst_state *state)
970{
971 u8 get_vendor[] = { 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
972 get_vendor[7] = dst_check_sum(get_vendor, 7);
973 if (dst_command(state, get_vendor, 8) < 0) {
974 dprintk(verbose, DST_INFO, 1, "Unsupported Command");
975 return -1;
976 }
977 memset(&state->vendor, '\0', 8);
978 memcpy(&state->vendor, &state->rxbuffer, 7);
979 dprintk(verbose, DST_ERROR, 1, "Vendor=[%s]", &state->vendor[0]);
980
981 return 0;
982}
983
984static void debug_dst_buffer(struct dst_state *state)
985{
986 int i;
987
988 if (verbose > 2) {
989 printk("%s: [", __func__);
990 for (i = 0; i < 8; i++)
991 printk(" %02x", state->rxbuffer[i]);
992 printk("]\n");
993 }
994}
995
996static int dst_check_stv0299(struct dst_state *state)
997{
998 u8 check_stv0299[] = { 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
999
1000 check_stv0299[7] = dst_check_sum(check_stv0299, 7);
1001 if (dst_command(state, check_stv0299, 8) < 0) {
1002 dprintk(verbose, DST_ERROR, 1, "Cmd=[0x04] failed");
1003 return -1;
1004 }
1005 debug_dst_buffer(state);
1006
1007 if (memcmp(&check_stv0299, &state->rxbuffer, 8)) {
1008 dprintk(verbose, DST_ERROR, 1, "Found a STV0299 NIM");
1009 state->tuner_type = TUNER_TYPE_STV0299;
1010 return 0;
1011 }
1012
1013 return -1;
1014}
1015
1016static int dst_check_mb86a15(struct dst_state *state)
1017{
1018 u8 check_mb86a15[] = { 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1019
1020 check_mb86a15[7] = dst_check_sum(check_mb86a15, 7);
1021 if (dst_command(state, check_mb86a15, 8) < 0) {
1022 dprintk(verbose, DST_ERROR, 1, "Cmd=[0x10], failed");
1023 return -1;
1024 }
1025 debug_dst_buffer(state);
1026
1027 if (memcmp(&check_mb86a15, &state->rxbuffer, 8) < 0) {
1028 dprintk(verbose, DST_ERROR, 1, "Found a MB86A15 NIM");
1029 state->tuner_type = TUNER_TYPE_MB86A15;
1030 return 0;
1031 }
1032
1033 return -1;
1034}
1035
1036static int dst_get_tuner_info(struct dst_state *state)
1037{
1038 u8 get_tuner_1[] = { 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1039 u8 get_tuner_2[] = { 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1040
1041 get_tuner_1[7] = dst_check_sum(get_tuner_1, 7);
1042 get_tuner_2[7] = dst_check_sum(get_tuner_2, 7);
1043 dprintk(verbose, DST_ERROR, 1, "DST TYpe = MULTI FE");
1044 if (state->type_flags & DST_TYPE_HAS_MULTI_FE) {
1045 if (dst_command(state, get_tuner_1, 8) < 0) {
1046 dprintk(verbose, DST_INFO, 1, "Cmd=[0x13], Unsupported");
1047 goto force;
1048 }
1049 } else {
1050 if (dst_command(state, get_tuner_2, 8) < 0) {
1051 dprintk(verbose, DST_INFO, 1, "Cmd=[0xb], Unsupported");
1052 goto force;
1053 }
1054 }
1055 memcpy(&state->board_info, &state->rxbuffer, 8);
1056 if (state->type_flags & DST_TYPE_HAS_MULTI_FE) {
1057 dprintk(verbose, DST_ERROR, 1, "DST type has TS=188");
1058 }
1059 if (state->board_info[0] == 0xbc) {
1060 if (state->dst_type != DST_TYPE_IS_ATSC)
1061 state->type_flags |= DST_TYPE_HAS_TS188;
1062 else
1063 state->type_flags |= DST_TYPE_HAS_NEWTUNE_2;
1064
1065 if (state->board_info[1] == 0x01) {
1066 state->dst_hw_cap |= DST_TYPE_HAS_DBOARD;
1067 dprintk(verbose, DST_ERROR, 1, "DST has Daughterboard");
1068 }
1069 }
1070
1071 return 0;
1072force:
1073 if (!strncmp(state->fw_name, "DCT-CI", 6)) {
1074 state->type_flags |= DST_TYPE_HAS_TS204;
1075 dprintk(verbose, DST_ERROR, 1, "Forcing [%s] to TS188", state->fw_name);
1076 }
1077
1078 return -1;
1079}
1080
1081static int dst_get_device_id(struct dst_state *state)
1082{
1083 u8 reply;
1084
1085 int i, j;
1086 struct dst_types *p_dst_type = NULL;
1087 struct tuner_types *p_tuner_list = NULL;
1088
1089 u8 use_dst_type = 0;
1090 u32 use_type_flags = 0;
1091
1092 static u8 device_type[8] = {0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff};
1093
1094 state->tuner_type = 0;
1095 device_type[7] = dst_check_sum(device_type, 7);
1096
1097 if (write_dst(state, device_type, FIXED_COMM))
1098 return -1; /* Write failed */
1099 if ((dst_pio_disable(state)) < 0)
1100 return -1;
1101 if (read_dst(state, &reply, GET_ACK))
1102 return -1; /* Read failure */
1103 if (reply != ACK) {
1104 dprintk(verbose, DST_INFO, 1, "Write not Acknowledged! [Reply=0x%02x]", reply);
1105 return -1; /* Unack'd write */
1106 }
1107 if (!dst_wait_dst_ready(state, DEVICE_INIT))
1108 return -1; /* DST not ready yet */
1109 if (read_dst(state, state->rxbuffer, FIXED_COMM))
1110 return -1;
1111
1112 dst_pio_disable(state);
1113 if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) {
1114 dprintk(verbose, DST_INFO, 1, "Checksum failure!");
1115 return -1; /* Checksum failure */
1116 }
1117 state->rxbuffer[7] = '\0';
1118
1119 for (i = 0, p_dst_type = dst_tlist; i < ARRAY_SIZE(dst_tlist); i++, p_dst_type++) {
1120 if (!strncmp (&state->rxbuffer[p_dst_type->offset], p_dst_type->device_id, strlen (p_dst_type->device_id))) {
1121 use_type_flags = p_dst_type->type_flags;
1122 use_dst_type = p_dst_type->dst_type;
1123
1124 /* Card capabilities */
1125 state->dst_hw_cap = p_dst_type->dst_feature;
1126 dprintk(verbose, DST_ERROR, 1, "Recognise [%s]", p_dst_type->device_id);
1127 strncpy(&state->fw_name[0], p_dst_type->device_id, 6);
1128 /* Multiple tuners */
1129 if (p_dst_type->tuner_type & TUNER_TYPE_MULTI) {
1130 switch (use_dst_type) {
1131 case DST_TYPE_IS_SAT:
1132 /* STV0299 check */
1133 if (dst_check_stv0299(state) < 0) {
1134 dprintk(verbose, DST_ERROR, 1, "Unsupported");
1135 state->tuner_type = TUNER_TYPE_MB86A15;
1136 }
1137 break;
1138 default:
1139 break;
1140 }
1141 if (dst_check_mb86a15(state) < 0)
1142 dprintk(verbose, DST_ERROR, 1, "Unsupported");
1143 /* Single tuner */
1144 } else {
1145 state->tuner_type = p_dst_type->tuner_type;
1146 }
1147 for (j = 0, p_tuner_list = tuner_list; j < ARRAY_SIZE(tuner_list); j++, p_tuner_list++) {
1148 if (!(strncmp(p_dst_type->device_id, p_tuner_list->fw_name, 7)) &&
1149 p_tuner_list->tuner_type == state->tuner_type) {
1150 dprintk(verbose, DST_ERROR, 1, "[%s] has a [%s]",
1151 p_dst_type->device_id, p_tuner_list->tuner_name);
1152 }
1153 }
1154 break;
1155 }
1156 }
1157
1158 if (i >= ARRAY_SIZE(dst_tlist)) {
1159 dprintk(verbose, DST_ERROR, 1, "Unable to recognize %s or %s", &state->rxbuffer[0], &state->rxbuffer[1]);
1160 dprintk(verbose, DST_ERROR, 1, "please email linux-dvb@linuxtv.org with this type in");
1161 use_dst_type = DST_TYPE_IS_SAT;
1162 use_type_flags = DST_TYPE_HAS_SYMDIV;
1163 }
1164 dst_type_print(state, use_dst_type);
1165 state->type_flags = use_type_flags;
1166 state->dst_type = use_dst_type;
1167 dst_type_flags_print(state);
1168
1169 return 0;
1170}
1171
1172static int dst_probe(struct dst_state *state)
1173{
1174 mutex_init(&state->dst_mutex);
1175 if (dst_addons & DST_TYPE_HAS_CA) {
1176 if ((rdc_8820_reset(state)) < 0) {
1177 dprintk(verbose, DST_ERROR, 1, "RDC 8820 RESET Failed.");
1178 return -1;
1179 }
1180 msleep(4000);
1181 } else {
1182 msleep(100);
1183 }
1184 if ((dst_comm_init(state)) < 0) {
1185 dprintk(verbose, DST_ERROR, 1, "DST Initialization Failed.");
1186 return -1;
1187 }
1188 msleep(100);
1189 if (dst_get_device_id(state) < 0) {
1190 dprintk(verbose, DST_ERROR, 1, "unknown device.");
1191 return -1;
1192 }
1193 if (dst_get_mac(state) < 0) {
1194 dprintk(verbose, DST_INFO, 1, "MAC: Unsupported command");
1195 }
1196 if ((state->type_flags & DST_TYPE_HAS_MULTI_FE) || (state->type_flags & DST_TYPE_HAS_FW_BUILD)) {
1197 if (dst_get_tuner_info(state) < 0)
1198 dprintk(verbose, DST_INFO, 1, "Tuner: Unsupported command");
1199 }
1200 if (state->type_flags & DST_TYPE_HAS_TS204) {
1201 dst_packsize(state, 204);
1202 }
1203 if (state->type_flags & DST_TYPE_HAS_FW_BUILD) {
1204 if (dst_fw_ver(state) < 0) {
1205 dprintk(verbose, DST_INFO, 1, "FW: Unsupported command");
1206 return 0;
1207 }
1208 if (dst_card_type(state) < 0) {
1209 dprintk(verbose, DST_INFO, 1, "Card: Unsupported command");
1210 return 0;
1211 }
1212 if (dst_get_vendor(state) < 0) {
1213 dprintk(verbose, DST_INFO, 1, "Vendor: Unsupported command");
1214 return 0;
1215 }
1216 }
1217
1218 return 0;
1219}
1220
1221static int dst_command(struct dst_state *state, u8 *data, u8 len)
1222{
1223 u8 reply;
1224
1225 mutex_lock(&state->dst_mutex);
1226 if ((dst_comm_init(state)) < 0) {
1227 dprintk(verbose, DST_NOTICE, 1, "DST Communication Initialization Failed.");
1228 goto error;
1229 }
1230 if (write_dst(state, data, len)) {
1231 dprintk(verbose, DST_INFO, 1, "Trying to recover.. ");
1232 if ((dst_error_recovery(state)) < 0) {
1233 dprintk(verbose, DST_ERROR, 1, "Recovery Failed.");
1234 goto error;
1235 }
1236 goto error;
1237 }
1238 if ((dst_pio_disable(state)) < 0) {
1239 dprintk(verbose, DST_ERROR, 1, "PIO Disable Failed.");
1240 goto error;
1241 }
1242 if (state->type_flags & DST_TYPE_HAS_FW_1)
1243 mdelay(3);
1244 if (read_dst(state, &reply, GET_ACK)) {
1245 dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. ");
1246 if ((dst_error_recovery(state)) < 0) {
1247 dprintk(verbose, DST_INFO, 1, "Recovery Failed.");
1248 goto error;
1249 }
1250 goto error;
1251 }
1252 if (reply != ACK) {
1253 dprintk(verbose, DST_INFO, 1, "write not acknowledged 0x%02x ", reply);
1254 goto error;
1255 }
1256 if (len >= 2 && data[0] == 0 && (data[1] == 1 || data[1] == 3))
1257 goto error;
1258 if (state->type_flags & DST_TYPE_HAS_FW_1)
1259 mdelay(3);
1260 else
1261 udelay(2000);
1262 if (!dst_wait_dst_ready(state, NO_DELAY))
1263 goto error;
1264 if (read_dst(state, state->rxbuffer, FIXED_COMM)) {
1265 dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. ");
1266 if ((dst_error_recovery(state)) < 0) {
1267 dprintk(verbose, DST_INFO, 1, "Recovery failed.");
1268 goto error;
1269 }
1270 goto error;
1271 }
1272 if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) {
1273 dprintk(verbose, DST_INFO, 1, "checksum failure");
1274 goto error;
1275 }
1276 mutex_unlock(&state->dst_mutex);
1277 return 0;
1278
1279error:
1280 mutex_unlock(&state->dst_mutex);
1281 return -EIO;
1282
1283}
1284
1285static int dst_get_signal(struct dst_state *state)
1286{
1287 int retval;
1288 u8 get_signal[] = { 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb };
1289 //dprintk("%s: Getting Signal strength and other parameters\n", __func__);
1290 if ((state->diseq_flags & ATTEMPT_TUNE) == 0) {
1291 state->decode_lock = state->decode_strength = state->decode_snr = 0;
1292 return 0;
1293 }
1294 if (0 == (state->diseq_flags & HAS_LOCK)) {
1295 state->decode_lock = state->decode_strength = state->decode_snr = 0;
1296 return 0;
1297 }
1298 if (time_after_eq(jiffies, state->cur_jiff + (HZ / 5))) {
1299 retval = dst_command(state, get_signal, 8);
1300 if (retval < 0)
1301 return retval;
1302 if (state->dst_type == DST_TYPE_IS_SAT) {
1303 state->decode_lock = ((state->rxbuffer[6] & 0x10) == 0) ? 1 : 0;
1304 state->decode_strength = state->rxbuffer[5] << 8;
1305 state->decode_snr = state->rxbuffer[2] << 8 | state->rxbuffer[3];
1306 } else if ((state->dst_type == DST_TYPE_IS_TERR) || (state->dst_type == DST_TYPE_IS_CABLE)) {
1307 state->decode_lock = (state->rxbuffer[1]) ? 1 : 0;
1308 state->decode_strength = state->rxbuffer[4] << 8;
1309 state->decode_snr = state->rxbuffer[3] << 8;
1310 } else if (state->dst_type == DST_TYPE_IS_ATSC) {
1311 state->decode_lock = (state->rxbuffer[6] == 0x00) ? 1 : 0;
1312 state->decode_strength = state->rxbuffer[4] << 8;
1313 state->decode_snr = state->rxbuffer[2] << 8 | state->rxbuffer[3];
1314 }
1315 state->cur_jiff = jiffies;
1316 }
1317 return 0;
1318}
1319
1320static int dst_tone_power_cmd(struct dst_state *state)
1321{
1322 u8 paket[8] = { 0x00, 0x09, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00 };
1323
1324 if (state->dst_type != DST_TYPE_IS_SAT)
1325 return -EOPNOTSUPP;
1326 paket[4] = state->tx_tuna[4];
1327 paket[2] = state->tx_tuna[2];
1328 paket[3] = state->tx_tuna[3];
1329 paket[7] = dst_check_sum (paket, 7);
1330 return dst_command(state, paket, 8);
1331}
1332
1333static int dst_get_tuna(struct dst_state *state)
1334{
1335 int retval;
1336
1337 if ((state->diseq_flags & ATTEMPT_TUNE) == 0)
1338 return 0;
1339 state->diseq_flags &= ~(HAS_LOCK);
1340 if (!dst_wait_dst_ready(state, NO_DELAY))
1341 return -EIO;
1342 if ((state->type_flags & DST_TYPE_HAS_VLF) &&
1343 !(state->dst_type == DST_TYPE_IS_ATSC))
1344
1345 retval = read_dst(state, state->rx_tuna, 10);
1346 else
1347 retval = read_dst(state, &state->rx_tuna[2], FIXED_COMM);
1348 if (retval < 0) {
1349 dprintk(verbose, DST_DEBUG, 1, "read not successful");
1350 return retval;
1351 }
1352 if ((state->type_flags & DST_TYPE_HAS_VLF) &&
1353 !(state->dst_type == DST_TYPE_IS_ATSC)) {
1354
1355 if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) {
1356 dprintk(verbose, DST_INFO, 1, "checksum failure ? ");
1357 return -EIO;
1358 }
1359 } else {
1360 if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[2], 7)) {
1361 dprintk(verbose, DST_INFO, 1, "checksum failure? ");
1362 return -EIO;
1363 }
1364 }
1365 if (state->rx_tuna[2] == 0 && state->rx_tuna[3] == 0)
1366 return 0;
1367 if (state->dst_type == DST_TYPE_IS_SAT) {
1368 state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 8) + state->rx_tuna[3];
1369 } else {
1370 state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 16) + (state->rx_tuna[3] << 8) + state->rx_tuna[4];
1371 }
1372 state->decode_freq = state->decode_freq * 1000;
1373 state->decode_lock = 1;
1374 state->diseq_flags |= HAS_LOCK;
1375
1376 return 1;
1377}
1378
1379static int dst_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage);
1380
1381static int dst_write_tuna(struct dvb_frontend *fe)
1382{
1383 struct dst_state *state = fe->demodulator_priv;
1384 int retval;
1385 u8 reply;
1386
1387 dprintk(verbose, DST_INFO, 1, "type_flags 0x%x ", state->type_flags);
1388 state->decode_freq = 0;
1389 state->decode_lock = state->decode_strength = state->decode_snr = 0;
1390 if (state->dst_type == DST_TYPE_IS_SAT) {
1391 if (!(state->diseq_flags & HAS_POWER))
1392 dst_set_voltage(fe, SEC_VOLTAGE_13);
1393 }
1394 state->diseq_flags &= ~(HAS_LOCK | ATTEMPT_TUNE);
1395 mutex_lock(&state->dst_mutex);
1396 if ((dst_comm_init(state)) < 0) {
1397 dprintk(verbose, DST_DEBUG, 1, "DST Communication initialization failed.");
1398 goto error;
1399 }
1400// if (state->type_flags & DST_TYPE_HAS_NEWTUNE) {
1401 if ((state->type_flags & DST_TYPE_HAS_VLF) &&
1402 (!(state->dst_type == DST_TYPE_IS_ATSC))) {
1403
1404 state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[0], 9);
1405 retval = write_dst(state, &state->tx_tuna[0], 10);
1406 } else {
1407 state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[2], 7);
1408 retval = write_dst(state, &state->tx_tuna[2], FIXED_COMM);
1409 }
1410 if (retval < 0) {
1411 dst_pio_disable(state);
1412 dprintk(verbose, DST_DEBUG, 1, "write not successful");
1413 goto werr;
1414 }
1415 if ((dst_pio_disable(state)) < 0) {
1416 dprintk(verbose, DST_DEBUG, 1, "DST PIO disable failed !");
1417 goto error;
1418 }
1419 if ((read_dst(state, &reply, GET_ACK) < 0)) {
1420 dprintk(verbose, DST_DEBUG, 1, "read verify not successful.");
1421 goto error;
1422 }
1423 if (reply != ACK) {
1424 dprintk(verbose, DST_DEBUG, 1, "write not acknowledged 0x%02x ", reply);
1425 goto error;
1426 }
1427 state->diseq_flags |= ATTEMPT_TUNE;
1428 retval = dst_get_tuna(state);
1429werr:
1430 mutex_unlock(&state->dst_mutex);
1431 return retval;
1432
1433error:
1434 mutex_unlock(&state->dst_mutex);
1435 return -EIO;
1436}
1437
1438/*
1439 * line22k0 0x00, 0x09, 0x00, 0xff, 0x01, 0x00, 0x00, 0x00
1440 * line22k1 0x00, 0x09, 0x01, 0xff, 0x01, 0x00, 0x00, 0x00
1441 * line22k2 0x00, 0x09, 0x02, 0xff, 0x01, 0x00, 0x00, 0x00
1442 * tone 0x00, 0x09, 0xff, 0x00, 0x01, 0x00, 0x00, 0x00
1443 * data 0x00, 0x09, 0xff, 0x01, 0x01, 0x00, 0x00, 0x00
1444 * power_off 0x00, 0x09, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
1445 * power_on 0x00, 0x09, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00
1446 * Diseqc 1 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf0, 0xec
1447 * Diseqc 2 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf4, 0xe8
1448 * Diseqc 3 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf8, 0xe4
1449 * Diseqc 4 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xfc, 0xe0
1450 */
1451
1452static int dst_set_diseqc(struct dvb_frontend *fe, struct dvb_diseqc_master_cmd *cmd)
1453{
1454 struct dst_state *state = fe->demodulator_priv;
1455 u8 paket[8] = { 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf0, 0xec };
1456
1457 if (state->dst_type != DST_TYPE_IS_SAT)
1458 return -EOPNOTSUPP;
1459 if (cmd->msg_len > 0 && cmd->msg_len < 5)
1460 memcpy(&paket[3], cmd->msg, cmd->msg_len);
1461 else if (cmd->msg_len == 5 && state->dst_hw_cap & DST_TYPE_HAS_DISEQC5)
1462 memcpy(&paket[2], cmd->msg, cmd->msg_len);
1463 else
1464 return -EINVAL;
1465 paket[7] = dst_check_sum(&paket[0], 7);
1466 return dst_command(state, paket, 8);
1467}
1468
1469static int dst_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
1470{
1471 int need_cmd, retval = 0;
1472 struct dst_state *state = fe->demodulator_priv;
1473
1474 state->voltage = voltage;
1475 if (state->dst_type != DST_TYPE_IS_SAT)
1476 return -EOPNOTSUPP;
1477
1478 need_cmd = 0;
1479
1480 switch (voltage) {
1481 case SEC_VOLTAGE_13:
1482 case SEC_VOLTAGE_18:
1483 if ((state->diseq_flags & HAS_POWER) == 0)
1484 need_cmd = 1;
1485 state->diseq_flags |= HAS_POWER;
1486 state->tx_tuna[4] = 0x01;
1487 break;
1488 case SEC_VOLTAGE_OFF:
1489 need_cmd = 1;
1490 state->diseq_flags &= ~(HAS_POWER | HAS_LOCK | ATTEMPT_TUNE);
1491 state->tx_tuna[4] = 0x00;
1492 break;
1493 default:
1494 return -EINVAL;
1495 }
1496
1497 if (need_cmd)
1498 retval = dst_tone_power_cmd(state);
1499
1500 return retval;
1501}
1502
1503static int dst_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
1504{
1505 struct dst_state *state = fe->demodulator_priv;
1506
1507 state->tone = tone;
1508 if (state->dst_type != DST_TYPE_IS_SAT)
1509 return -EOPNOTSUPP;
1510
1511 switch (tone) {
1512 case SEC_TONE_OFF:
1513 if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
1514 state->tx_tuna[2] = 0x00;
1515 else
1516 state->tx_tuna[2] = 0xff;
1517 break;
1518
1519 case SEC_TONE_ON:
1520 state->tx_tuna[2] = 0x02;
1521 break;
1522 default:
1523 return -EINVAL;
1524 }
1525 return dst_tone_power_cmd(state);
1526}
1527
1528static int dst_send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t minicmd)
1529{
1530 struct dst_state *state = fe->demodulator_priv;
1531
1532 if (state->dst_type != DST_TYPE_IS_SAT)
1533 return -EOPNOTSUPP;
1534 state->minicmd = minicmd;
1535 switch (minicmd) {
1536 case SEC_MINI_A:
1537 state->tx_tuna[3] = 0x02;
1538 break;
1539 case SEC_MINI_B:
1540 state->tx_tuna[3] = 0xff;
1541 break;
1542 }
1543 return dst_tone_power_cmd(state);
1544}
1545
1546
1547static int dst_init(struct dvb_frontend *fe)
1548{
1549 struct dst_state *state = fe->demodulator_priv;
1550
1551 static u8 sat_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x00, 0x73, 0x21, 0x00, 0x00 };
1552 static u8 sat_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x55, 0xbd, 0x50, 0x00, 0x00 };
1553 static u8 ter_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
1554 static u8 ter_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
1555 static u8 cab_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
1556 static u8 cab_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
1557 static u8 atsc_tuner[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
1558
1559 state->inversion = INVERSION_OFF;
1560 state->voltage = SEC_VOLTAGE_13;
1561 state->tone = SEC_TONE_OFF;
1562 state->diseq_flags = 0;
1563 state->k22 = 0x02;
1564 state->bandwidth = BANDWIDTH_7_MHZ;
1565 state->cur_jiff = jiffies;
1566 if (state->dst_type == DST_TYPE_IS_SAT)
1567 memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_VLF) ? sat_tuna_188 : sat_tuna_204), sizeof (sat_tuna_204));
1568 else if (state->dst_type == DST_TYPE_IS_TERR)
1569 memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_VLF) ? ter_tuna_188 : ter_tuna_204), sizeof (ter_tuna_204));
1570 else if (state->dst_type == DST_TYPE_IS_CABLE)
1571 memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_VLF) ? cab_tuna_188 : cab_tuna_204), sizeof (cab_tuna_204));
1572 else if (state->dst_type == DST_TYPE_IS_ATSC)
1573 memcpy(state->tx_tuna, atsc_tuner, sizeof (atsc_tuner));
1574
1575 return 0;
1576}
1577
1578static int dst_read_status(struct dvb_frontend *fe, fe_status_t *status)
1579{
1580 struct dst_state *state = fe->demodulator_priv;
1581
1582 *status = 0;
1583 if (state->diseq_flags & HAS_LOCK) {
1584// dst_get_signal(state); // don't require(?) to ask MCU
1585 if (state->decode_lock)
1586 *status |= FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_SYNC | FE_HAS_VITERBI;
1587 }
1588
1589 return 0;
1590}
1591
1592static int dst_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
1593{
1594 struct dst_state *state = fe->demodulator_priv;
1595
1596 int retval = dst_get_signal(state);
1597 *strength = state->decode_strength;
1598
1599 return retval;
1600}
1601
1602static int dst_read_snr(struct dvb_frontend *fe, u16 *snr)
1603{
1604 struct dst_state *state = fe->demodulator_priv;
1605
1606 int retval = dst_get_signal(state);
1607 *snr = state->decode_snr;
1608
1609 return retval;
1610}
1611
1612static int dst_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
1613{
1614 int retval = -EINVAL;
1615 struct dst_state *state = fe->demodulator_priv;
1616
1617 if (p != NULL) {
1618 retval = dst_set_freq(state, p->frequency);
1619 if(retval != 0)
1620 return retval;
1621 dprintk(verbose, DST_DEBUG, 1, "Set Frequency=[%d]", p->frequency);
1622
1623 if (state->dst_type == DST_TYPE_IS_SAT) {
1624 if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
1625 dst_set_inversion(state, p->inversion);
1626 dst_set_fec(state, p->u.qpsk.fec_inner);
1627 dst_set_symbolrate(state, p->u.qpsk.symbol_rate);
1628 dst_set_polarization(state);
1629 dprintk(verbose, DST_DEBUG, 1, "Set Symbolrate=[%d]", p->u.qpsk.symbol_rate);
1630
1631 } else if (state->dst_type == DST_TYPE_IS_TERR)
1632 dst_set_bandwidth(state, p->u.ofdm.bandwidth);
1633 else if (state->dst_type == DST_TYPE_IS_CABLE) {
1634 dst_set_fec(state, p->u.qam.fec_inner);
1635 dst_set_symbolrate(state, p->u.qam.symbol_rate);
1636 dst_set_modulation(state, p->u.qam.modulation);
1637 }
1638 retval = dst_write_tuna(fe);
1639 }
1640
1641 return retval;
1642}
1643
1644static int dst_tune_frontend(struct dvb_frontend* fe,
1645 struct dvb_frontend_parameters* p,
1646 unsigned int mode_flags,
1647 unsigned int *delay,
1648 fe_status_t *status)
1649{
1650 struct dst_state *state = fe->demodulator_priv;
1651
1652 if (p != NULL) {
1653 dst_set_freq(state, p->frequency);
1654 dprintk(verbose, DST_DEBUG, 1, "Set Frequency=[%d]", p->frequency);
1655
1656 if (state->dst_type == DST_TYPE_IS_SAT) {
1657 if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
1658 dst_set_inversion(state, p->inversion);
1659 dst_set_fec(state, p->u.qpsk.fec_inner);
1660 dst_set_symbolrate(state, p->u.qpsk.symbol_rate);
1661 dst_set_polarization(state);
1662 dprintk(verbose, DST_DEBUG, 1, "Set Symbolrate=[%d]", p->u.qpsk.symbol_rate);
1663
1664 } else if (state->dst_type == DST_TYPE_IS_TERR)
1665 dst_set_bandwidth(state, p->u.ofdm.bandwidth);
1666 else if (state->dst_type == DST_TYPE_IS_CABLE) {
1667 dst_set_fec(state, p->u.qam.fec_inner);
1668 dst_set_symbolrate(state, p->u.qam.symbol_rate);
1669 dst_set_modulation(state, p->u.qam.modulation);
1670 }
1671 dst_write_tuna(fe);
1672 }
1673
1674 if (!(mode_flags & FE_TUNE_MODE_ONESHOT))
1675 dst_read_status(fe, status);
1676
1677 *delay = HZ/10;
1678 return 0;
1679}
1680
1681static int dst_get_tuning_algo(struct dvb_frontend *fe)
1682{
1683 return dst_algo ? DVBFE_ALGO_HW : DVBFE_ALGO_SW;
1684}
1685
1686static int dst_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
1687{
1688 struct dst_state *state = fe->demodulator_priv;
1689
1690 p->frequency = state->decode_freq;
1691 if (state->dst_type == DST_TYPE_IS_SAT) {
1692 if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
1693 p->inversion = state->inversion;
1694 p->u.qpsk.symbol_rate = state->symbol_rate;
1695 p->u.qpsk.fec_inner = dst_get_fec(state);
1696 } else if (state->dst_type == DST_TYPE_IS_TERR) {
1697 p->u.ofdm.bandwidth = state->bandwidth;
1698 } else if (state->dst_type == DST_TYPE_IS_CABLE) {
1699 p->u.qam.symbol_rate = state->symbol_rate;
1700 p->u.qam.fec_inner = dst_get_fec(state);
1701 p->u.qam.modulation = dst_get_modulation(state);
1702 }
1703
1704 return 0;
1705}
1706
1707static void dst_release(struct dvb_frontend *fe)
1708{
1709 struct dst_state *state = fe->demodulator_priv;
1710 if (state->dst_ca) {
1711 dvb_unregister_device(state->dst_ca);
1712#ifdef CONFIG_MEDIA_ATTACH
1713 symbol_put(dst_ca_attach);
1714#endif
1715 }
1716 kfree(state);
1717}
1718
1719static struct dvb_frontend_ops dst_dvbt_ops;
1720static struct dvb_frontend_ops dst_dvbs_ops;
1721static struct dvb_frontend_ops dst_dvbc_ops;
1722static struct dvb_frontend_ops dst_atsc_ops;
1723
1724struct dst_state *dst_attach(struct dst_state *state, struct dvb_adapter *dvb_adapter)
1725{
1726 /* check if the ASIC is there */
1727 if (dst_probe(state) < 0) {
1728 kfree(state);
1729 return NULL;
1730 }
1731 /* determine settings based on type */
1732 /* create dvb_frontend */
1733 switch (state->dst_type) {
1734 case DST_TYPE_IS_TERR:
1735 memcpy(&state->frontend.ops, &dst_dvbt_ops, sizeof(struct dvb_frontend_ops));
1736 break;
1737 case DST_TYPE_IS_CABLE:
1738 memcpy(&state->frontend.ops, &dst_dvbc_ops, sizeof(struct dvb_frontend_ops));
1739 break;
1740 case DST_TYPE_IS_SAT:
1741 memcpy(&state->frontend.ops, &dst_dvbs_ops, sizeof(struct dvb_frontend_ops));
1742 break;
1743 case DST_TYPE_IS_ATSC:
1744 memcpy(&state->frontend.ops, &dst_atsc_ops, sizeof(struct dvb_frontend_ops));
1745 break;
1746 default:
1747 dprintk(verbose, DST_ERROR, 1, "unknown DST type. please report to the LinuxTV.org DVB mailinglist.");
1748 kfree(state);
1749 return NULL;
1750 }
1751 state->frontend.demodulator_priv = state;
1752
1753 return state; /* Manu (DST is a card not a frontend) */
1754}
1755
1756EXPORT_SYMBOL(dst_attach);
1757
1758static struct dvb_frontend_ops dst_dvbt_ops = {
1759
1760 .info = {
1761 .name = "DST DVB-T",
1762 .type = FE_OFDM,
1763 .frequency_min = 137000000,
1764 .frequency_max = 858000000,
1765 .frequency_stepsize = 166667,
1766 .caps = FE_CAN_FEC_AUTO |
1767 FE_CAN_QAM_AUTO |
1768 FE_CAN_QAM_16 |
1769 FE_CAN_QAM_32 |
1770 FE_CAN_QAM_64 |
1771 FE_CAN_QAM_128 |
1772 FE_CAN_QAM_256 |
1773 FE_CAN_TRANSMISSION_MODE_AUTO |
1774 FE_CAN_GUARD_INTERVAL_AUTO
1775 },
1776
1777 .release = dst_release,
1778 .init = dst_init,
1779 .tune = dst_tune_frontend,
1780 .set_frontend = dst_set_frontend,
1781 .get_frontend = dst_get_frontend,
1782 .get_frontend_algo = dst_get_tuning_algo,
1783 .read_status = dst_read_status,
1784 .read_signal_strength = dst_read_signal_strength,
1785 .read_snr = dst_read_snr,
1786};
1787
1788static struct dvb_frontend_ops dst_dvbs_ops = {
1789
1790 .info = {
1791 .name = "DST DVB-S",
1792 .type = FE_QPSK,
1793 .frequency_min = 950000,
1794 .frequency_max = 2150000,
1795 .frequency_stepsize = 1000, /* kHz for QPSK frontends */
1796 .frequency_tolerance = 29500,
1797 .symbol_rate_min = 1000000,
1798 .symbol_rate_max = 45000000,
1799 /* . symbol_rate_tolerance = ???,*/
1800 .caps = FE_CAN_FEC_AUTO | FE_CAN_QPSK
1801 },
1802
1803 .release = dst_release,
1804 .init = dst_init,
1805 .tune = dst_tune_frontend,
1806 .set_frontend = dst_set_frontend,
1807 .get_frontend = dst_get_frontend,
1808 .get_frontend_algo = dst_get_tuning_algo,
1809 .read_status = dst_read_status,
1810 .read_signal_strength = dst_read_signal_strength,
1811 .read_snr = dst_read_snr,
1812 .diseqc_send_burst = dst_send_burst,
1813 .diseqc_send_master_cmd = dst_set_diseqc,
1814 .set_voltage = dst_set_voltage,
1815 .set_tone = dst_set_tone,
1816};
1817
1818static struct dvb_frontend_ops dst_dvbc_ops = {
1819
1820 .info = {
1821 .name = "DST DVB-C",
1822 .type = FE_QAM,
1823 .frequency_stepsize = 62500,
1824 .frequency_min = 51000000,
1825 .frequency_max = 858000000,
1826 .symbol_rate_min = 1000000,
1827 .symbol_rate_max = 45000000,
1828 .caps = FE_CAN_FEC_AUTO |
1829 FE_CAN_QAM_AUTO |
1830 FE_CAN_QAM_16 |
1831 FE_CAN_QAM_32 |
1832 FE_CAN_QAM_64 |
1833 FE_CAN_QAM_128 |
1834 FE_CAN_QAM_256
1835 },
1836
1837 .release = dst_release,
1838 .init = dst_init,
1839 .tune = dst_tune_frontend,
1840 .set_frontend = dst_set_frontend,
1841 .get_frontend = dst_get_frontend,
1842 .get_frontend_algo = dst_get_tuning_algo,
1843 .read_status = dst_read_status,
1844 .read_signal_strength = dst_read_signal_strength,
1845 .read_snr = dst_read_snr,
1846};
1847
1848static struct dvb_frontend_ops dst_atsc_ops = {
1849 .info = {
1850 .name = "DST ATSC",
1851 .type = FE_ATSC,
1852 .frequency_stepsize = 62500,
1853 .frequency_min = 510000000,
1854 .frequency_max = 858000000,
1855 .symbol_rate_min = 1000000,
1856 .symbol_rate_max = 45000000,
1857 .caps = FE_CAN_FEC_AUTO | FE_CAN_QAM_AUTO | FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
1858 },
1859
1860 .release = dst_release,
1861 .init = dst_init,
1862 .tune = dst_tune_frontend,
1863 .set_frontend = dst_set_frontend,
1864 .get_frontend = dst_get_frontend,
1865 .get_frontend_algo = dst_get_tuning_algo,
1866 .read_status = dst_read_status,
1867 .read_signal_strength = dst_read_signal_strength,
1868 .read_snr = dst_read_snr,
1869};
1870
1871MODULE_DESCRIPTION("DST DVB-S/T/C/ATSC Combo Frontend driver");
1872MODULE_AUTHOR("Jamie Honan, Manu Abraham");
1873MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/bt8xx/dst_ca.c b/drivers/media/dvb/bt8xx/dst_ca.c
new file mode 100644
index 00000000000..48e48e8af55
--- /dev/null
+++ b/drivers/media/dvb/bt8xx/dst_ca.c
@@ -0,0 +1,727 @@
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#include <linux/kernel.h>
22#include <linux/module.h>
23#include <linux/slab.h>
24#include <linux/init.h>
25#include <linux/mutex.h>
26#include <linux/string.h>
27#include <linux/dvb/ca.h>
28#include "dvbdev.h"
29#include "dvb_frontend.h"
30#include "dst_ca.h"
31#include "dst_common.h"
32
33#define DST_CA_ERROR 0
34#define DST_CA_NOTICE 1
35#define DST_CA_INFO 2
36#define DST_CA_DEBUG 3
37
38#define dprintk(x, y, z, format, arg...) do { \
39 if (z) { \
40 if ((x > DST_CA_ERROR) && (x > y)) \
41 printk(KERN_ERR "%s: " format "\n", __func__ , ##arg); \
42 else if ((x > DST_CA_NOTICE) && (x > y)) \
43 printk(KERN_NOTICE "%s: " format "\n", __func__ , ##arg); \
44 else if ((x > DST_CA_INFO) && (x > y)) \
45 printk(KERN_INFO "%s: " format "\n", __func__ , ##arg); \
46 else if ((x > DST_CA_DEBUG) && (x > y)) \
47 printk(KERN_DEBUG "%s: " format "\n", __func__ , ##arg); \
48 } else { \
49 if (x > y) \
50 printk(format, ## arg); \
51 } \
52} while(0)
53
54
55static DEFINE_MUTEX(dst_ca_mutex);
56static unsigned int verbose = 5;
57module_param(verbose, int, 0644);
58MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)");
59
60/* Need some more work */
61static int ca_set_slot_descr(void)
62{
63 /* We could make this more graceful ? */
64 return -EOPNOTSUPP;
65}
66
67/* Need some more work */
68static int ca_set_pid(void)
69{
70 /* We could make this more graceful ? */
71 return -EOPNOTSUPP;
72}
73
74static void put_command_and_length(u8 *data, int command, int length)
75{
76 data[0] = (command >> 16) & 0xff;
77 data[1] = (command >> 8) & 0xff;
78 data[2] = command & 0xff;
79 data[3] = length;
80}
81
82static void put_checksum(u8 *check_string, int length)
83{
84 dprintk(verbose, DST_CA_DEBUG, 1, " Computing string checksum.");
85 dprintk(verbose, DST_CA_DEBUG, 1, " -> string length : 0x%02x", length);
86 check_string[length] = dst_check_sum (check_string, length);
87 dprintk(verbose, DST_CA_DEBUG, 1, " -> checksum : 0x%02x", check_string[length]);
88}
89
90static int dst_ci_command(struct dst_state* state, u8 * data, u8 *ca_string, u8 len, int read)
91{
92 u8 reply;
93
94 mutex_lock(&state->dst_mutex);
95 dst_comm_init(state);
96 msleep(65);
97
98 if (write_dst(state, data, len)) {
99 dprintk(verbose, DST_CA_INFO, 1, " Write not successful, trying to recover");
100 dst_error_recovery(state);
101 goto error;
102 }
103 if ((dst_pio_disable(state)) < 0) {
104 dprintk(verbose, DST_CA_ERROR, 1, " DST PIO disable failed.");
105 goto error;
106 }
107 if (read_dst(state, &reply, GET_ACK) < 0) {
108 dprintk(verbose, DST_CA_INFO, 1, " Read not successful, trying to recover");
109 dst_error_recovery(state);
110 goto error;
111 }
112 if (read) {
113 if (! dst_wait_dst_ready(state, LONG_DELAY)) {
114 dprintk(verbose, DST_CA_NOTICE, 1, " 8820 not ready");
115 goto error;
116 }
117 if (read_dst(state, ca_string, 128) < 0) { /* Try to make this dynamic */
118 dprintk(verbose, DST_CA_INFO, 1, " Read not successful, trying to recover");
119 dst_error_recovery(state);
120 goto error;
121 }
122 }
123 mutex_unlock(&state->dst_mutex);
124 return 0;
125
126error:
127 mutex_unlock(&state->dst_mutex);
128 return -EIO;
129}
130
131
132static int dst_put_ci(struct dst_state *state, u8 *data, int len, u8 *ca_string, int read)
133{
134 u8 dst_ca_comm_err = 0;
135
136 while (dst_ca_comm_err < RETRIES) {
137 dprintk(verbose, DST_CA_NOTICE, 1, " Put Command");
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 } else {
142 break;
143 }
144 }
145
146 if(dst_ca_comm_err == RETRIES)
147 return -1;
148
149 return 0;
150}
151
152
153
154static int ca_get_app_info(struct dst_state *state)
155{
156 int length, str_length;
157 static u8 command[8] = {0x07, 0x40, 0x01, 0x00, 0x01, 0x00, 0x00, 0xff};
158
159 put_checksum(&command[0], command[0]);
160 if ((dst_put_ci(state, command, sizeof(command), state->messages, GET_REPLY)) < 0) {
161 dprintk(verbose, DST_CA_ERROR, 1, " -->dst_put_ci FAILED !");
162 return -1;
163 }
164 dprintk(verbose, DST_CA_INFO, 1, " -->dst_put_ci SUCCESS !");
165 dprintk(verbose, DST_CA_INFO, 1, " ================================ CI Module Application Info ======================================");
166 dprintk(verbose, DST_CA_INFO, 1, " Application Type=[%d], Application Vendor=[%d], Vendor Code=[%d]\n%s: Application info=[%s]",
167 state->messages[7], (state->messages[8] << 8) | state->messages[9],
168 (state->messages[10] << 8) | state->messages[11], __func__, (char *)(&state->messages[12]));
169 dprintk(verbose, DST_CA_INFO, 1, " ==================================================================================================");
170
171 // Transform dst message to correct application_info message
172 length = state->messages[5];
173 str_length = length - 6;
174 if (str_length < 0) {
175 str_length = 0;
176 dprintk(verbose, DST_CA_ERROR, 1, "Invalid string length returned in ca_get_app_info(). Recovering.");
177 }
178
179 // First, the command and length fields
180 put_command_and_length(&state->messages[0], CA_APP_INFO, length);
181
182 // Copy application_type, application_manufacturer and manufacturer_code
183 memcpy(&state->messages[4], &state->messages[7], 5);
184
185 // Set string length and copy string
186 state->messages[9] = str_length;
187 memcpy(&state->messages[10], &state->messages[12], str_length);
188
189 return 0;
190}
191
192static int ca_get_ca_info(struct dst_state *state)
193{
194 int srcPtr, dstPtr, i, num_ids;
195 static u8 slot_command[8] = {0x07, 0x40, 0x00, 0x00, 0x02, 0x00, 0x00, 0xff};
196 const int in_system_id_pos = 8, out_system_id_pos = 4, in_num_ids_pos = 7;
197
198 put_checksum(&slot_command[0], slot_command[0]);
199 if ((dst_put_ci(state, slot_command, sizeof (slot_command), state->messages, GET_REPLY)) < 0) {
200 dprintk(verbose, DST_CA_ERROR, 1, " -->dst_put_ci FAILED !");
201 return -1;
202 }
203 dprintk(verbose, DST_CA_INFO, 1, " -->dst_put_ci SUCCESS !");
204
205 // Print raw data
206 dprintk(verbose, DST_CA_INFO, 0, " DST data = [");
207 for (i = 0; i < state->messages[0] + 1; i++) {
208 dprintk(verbose, DST_CA_INFO, 0, " 0x%02x", state->messages[i]);
209 }
210 dprintk(verbose, DST_CA_INFO, 0, "]\n");
211
212 // Set the command and length of the output
213 num_ids = state->messages[in_num_ids_pos];
214 if (num_ids >= 100) {
215 num_ids = 100;
216 dprintk(verbose, DST_CA_ERROR, 1, "Invalid number of ids (>100). Recovering.");
217 }
218 put_command_and_length(&state->messages[0], CA_INFO, num_ids * 2);
219
220 dprintk(verbose, DST_CA_INFO, 0, " CA_INFO = [");
221 srcPtr = in_system_id_pos;
222 dstPtr = out_system_id_pos;
223 for(i = 0; i < num_ids; i++) {
224 dprintk(verbose, DST_CA_INFO, 0, " 0x%02x%02x", state->messages[srcPtr + 0], state->messages[srcPtr + 1]);
225 // Append to output
226 state->messages[dstPtr + 0] = state->messages[srcPtr + 0];
227 state->messages[dstPtr + 1] = state->messages[srcPtr + 1];
228 srcPtr += 2;
229 dstPtr += 2;
230 }
231 dprintk(verbose, DST_CA_INFO, 0, "]\n");
232
233 return 0;
234}
235
236static int ca_get_slot_caps(struct dst_state *state, struct ca_caps *p_ca_caps, void __user *arg)
237{
238 int i;
239 u8 slot_cap[256];
240 static u8 slot_command[8] = {0x07, 0x40, 0x02, 0x00, 0x02, 0x00, 0x00, 0xff};
241
242 put_checksum(&slot_command[0], slot_command[0]);
243 if ((dst_put_ci(state, slot_command, sizeof (slot_command), slot_cap, GET_REPLY)) < 0) {
244 dprintk(verbose, DST_CA_ERROR, 1, " -->dst_put_ci FAILED !");
245 return -1;
246 }
247 dprintk(verbose, DST_CA_NOTICE, 1, " -->dst_put_ci SUCCESS !");
248
249 /* Will implement the rest soon */
250
251 dprintk(verbose, DST_CA_INFO, 1, " Slot cap = [%d]", slot_cap[7]);
252 dprintk(verbose, DST_CA_INFO, 0, "===================================\n");
253 for (i = 0; i < slot_cap[0] + 1; i++)
254 dprintk(verbose, DST_CA_INFO, 0, " %d", slot_cap[i]);
255 dprintk(verbose, DST_CA_INFO, 0, "\n");
256
257 p_ca_caps->slot_num = 1;
258 p_ca_caps->slot_type = 1;
259 p_ca_caps->descr_num = slot_cap[7];
260 p_ca_caps->descr_type = 1;
261
262 if (copy_to_user(arg, p_ca_caps, sizeof (struct ca_caps)))
263 return -EFAULT;
264
265 return 0;
266}
267
268/* Need some more work */
269static int ca_get_slot_descr(struct dst_state *state, struct ca_msg *p_ca_message, void __user *arg)
270{
271 return -EOPNOTSUPP;
272}
273
274
275static int ca_get_slot_info(struct dst_state *state, struct ca_slot_info *p_ca_slot_info, void __user *arg)
276{
277 int i;
278 static u8 slot_command[8] = {0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff};
279
280 u8 *slot_info = state->messages;
281
282 put_checksum(&slot_command[0], 7);
283 if ((dst_put_ci(state, slot_command, sizeof (slot_command), slot_info, GET_REPLY)) < 0) {
284 dprintk(verbose, DST_CA_ERROR, 1, " -->dst_put_ci FAILED !");
285 return -1;
286 }
287 dprintk(verbose, DST_CA_INFO, 1, " -->dst_put_ci SUCCESS !");
288
289 /* Will implement the rest soon */
290
291 dprintk(verbose, DST_CA_INFO, 1, " Slot info = [%d]", slot_info[3]);
292 dprintk(verbose, DST_CA_INFO, 0, "===================================\n");
293 for (i = 0; i < 8; i++)
294 dprintk(verbose, DST_CA_INFO, 0, " %d", slot_info[i]);
295 dprintk(verbose, DST_CA_INFO, 0, "\n");
296
297 if (slot_info[4] & 0x80) {
298 p_ca_slot_info->flags = CA_CI_MODULE_PRESENT;
299 p_ca_slot_info->num = 1;
300 p_ca_slot_info->type = CA_CI;
301 } else if (slot_info[4] & 0x40) {
302 p_ca_slot_info->flags = CA_CI_MODULE_READY;
303 p_ca_slot_info->num = 1;
304 p_ca_slot_info->type = CA_CI;
305 } else
306 p_ca_slot_info->flags = 0;
307
308 if (copy_to_user(arg, p_ca_slot_info, sizeof (struct ca_slot_info)))
309 return -EFAULT;
310
311 return 0;
312}
313
314
315static int ca_get_message(struct dst_state *state, struct ca_msg *p_ca_message, void __user *arg)
316{
317 u8 i = 0;
318 u32 command = 0;
319
320 if (copy_from_user(p_ca_message, arg, sizeof (struct ca_msg)))
321 return -EFAULT;
322
323 if (p_ca_message->msg) {
324 dprintk(verbose, DST_CA_NOTICE, 1, " Message = [%02x %02x %02x]", p_ca_message->msg[0], p_ca_message->msg[1], p_ca_message->msg[2]);
325
326 for (i = 0; i < 3; i++) {
327 command = command | p_ca_message->msg[i];
328 if (i < 2)
329 command = command << 8;
330 }
331 dprintk(verbose, DST_CA_NOTICE, 1, " Command=[0x%x]", command);
332
333 switch (command) {
334 case CA_APP_INFO:
335 memcpy(p_ca_message->msg, state->messages, 128);
336 if (copy_to_user(arg, p_ca_message, sizeof (struct ca_msg)) )
337 return -EFAULT;
338 break;
339 case CA_INFO:
340 memcpy(p_ca_message->msg, state->messages, 128);
341 if (copy_to_user(arg, p_ca_message, sizeof (struct ca_msg)) )
342 return -EFAULT;
343 break;
344 }
345 }
346
347 return 0;
348}
349
350static int handle_dst_tag(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer, u32 length)
351{
352 if (state->dst_hw_cap & DST_TYPE_HAS_SESSION) {
353 hw_buffer->msg[2] = p_ca_message->msg[1]; /* MSB */
354 hw_buffer->msg[3] = p_ca_message->msg[2]; /* LSB */
355 } else {
356 if (length > 247) {
357 dprintk(verbose, DST_CA_ERROR, 1, " Message too long ! *** Bailing Out *** !");
358 return -1;
359 }
360 hw_buffer->msg[0] = (length & 0xff) + 7;
361 hw_buffer->msg[1] = 0x40;
362 hw_buffer->msg[2] = 0x03;
363 hw_buffer->msg[3] = 0x00;
364 hw_buffer->msg[4] = 0x03;
365 hw_buffer->msg[5] = length & 0xff;
366 hw_buffer->msg[6] = 0x00;
367
368 /*
369 * Need to compute length for EN50221 section 8.3.2, for the time being
370 * assuming 8.3.2 is not applicable
371 */
372 memcpy(&hw_buffer->msg[7], &p_ca_message->msg[4], length);
373 }
374
375 return 0;
376}
377
378static int write_to_8820(struct dst_state *state, struct ca_msg *hw_buffer, u8 length, u8 reply)
379{
380 if ((dst_put_ci(state, hw_buffer->msg, length, hw_buffer->msg, reply)) < 0) {
381 dprintk(verbose, DST_CA_ERROR, 1, " DST-CI Command failed.");
382 dprintk(verbose, DST_CA_NOTICE, 1, " Resetting DST.");
383 rdc_reset_state(state);
384 return -1;
385 }
386 dprintk(verbose, DST_CA_NOTICE, 1, " DST-CI Command success.");
387
388 return 0;
389}
390
391static u32 asn_1_decode(u8 *asn_1_array)
392{
393 u8 length_field = 0, word_count = 0, count = 0;
394 u32 length = 0;
395
396 length_field = asn_1_array[0];
397 dprintk(verbose, DST_CA_DEBUG, 1, " Length field=[%02x]", length_field);
398 if (length_field < 0x80) {
399 length = length_field & 0x7f;
400 dprintk(verbose, DST_CA_DEBUG, 1, " Length=[%02x]\n", length);
401 } else {
402 word_count = length_field & 0x7f;
403 for (count = 0; count < word_count; count++) {
404 length = length << 8;
405 length += asn_1_array[count + 1];
406 dprintk(verbose, DST_CA_DEBUG, 1, " Length=[%04x]", length);
407 }
408 }
409 return length;
410}
411
412static int debug_string(u8 *msg, u32 length, u32 offset)
413{
414 u32 i;
415
416 dprintk(verbose, DST_CA_DEBUG, 0, " String=[ ");
417 for (i = offset; i < length; i++)
418 dprintk(verbose, DST_CA_DEBUG, 0, "%02x ", msg[i]);
419 dprintk(verbose, DST_CA_DEBUG, 0, "]\n");
420
421 return 0;
422}
423
424
425static int ca_set_pmt(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer, u8 reply, u8 query)
426{
427 u32 length = 0;
428 u8 tag_length = 8;
429
430 length = asn_1_decode(&p_ca_message->msg[3]);
431 dprintk(verbose, DST_CA_DEBUG, 1, " CA Message length=[%d]", length);
432 debug_string(&p_ca_message->msg[4], length, 0); /* length is excluding tag & length */
433
434 memset(hw_buffer->msg, '\0', length);
435 handle_dst_tag(state, p_ca_message, hw_buffer, length);
436 put_checksum(hw_buffer->msg, hw_buffer->msg[0]);
437
438 debug_string(hw_buffer->msg, (length + tag_length), 0); /* tags too */
439 write_to_8820(state, hw_buffer, (length + tag_length), reply);
440
441 return 0;
442}
443
444
445/* Board supports CA PMT reply ? */
446static int dst_check_ca_pmt(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer)
447{
448 int ca_pmt_reply_test = 0;
449
450 /* Do test board */
451 /* Not there yet but soon */
452
453 /* CA PMT Reply capable */
454 if (ca_pmt_reply_test) {
455 if ((ca_set_pmt(state, p_ca_message, hw_buffer, 1, GET_REPLY)) < 0) {
456 dprintk(verbose, DST_CA_ERROR, 1, " ca_set_pmt.. failed !");
457 return -1;
458 }
459
460 /* Process CA PMT Reply */
461 /* will implement soon */
462 dprintk(verbose, DST_CA_ERROR, 1, " Not there yet");
463 }
464 /* CA PMT Reply not capable */
465 if (!ca_pmt_reply_test) {
466 if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, NO_REPLY)) < 0) {
467 dprintk(verbose, DST_CA_ERROR, 1, " ca_set_pmt.. failed !");
468 return -1;
469 }
470 dprintk(verbose, DST_CA_NOTICE, 1, " ca_set_pmt.. success !");
471 /* put a dummy message */
472
473 }
474 return 0;
475}
476
477static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message, void __user *arg)
478{
479 int i = 0;
480 unsigned int ca_message_header_len;
481
482 u32 command = 0;
483 struct ca_msg *hw_buffer;
484 int result = 0;
485
486 if ((hw_buffer = kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) {
487 dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure");
488 return -ENOMEM;
489 }
490 dprintk(verbose, DST_CA_DEBUG, 1, " ");
491
492 if (copy_from_user(p_ca_message, arg, sizeof (struct ca_msg))) {
493 result = -EFAULT;
494 goto free_mem_and_exit;
495 }
496
497
498 if (p_ca_message->msg) {
499 ca_message_header_len = p_ca_message->length; /* Restore it back when you are done */
500 /* EN50221 tag */
501 command = 0;
502
503 for (i = 0; i < 3; i++) {
504 command = command | p_ca_message->msg[i];
505 if (i < 2)
506 command = command << 8;
507 }
508 dprintk(verbose, DST_CA_DEBUG, 1, " Command=[0x%x]\n", command);
509
510 switch (command) {
511 case CA_PMT:
512 dprintk(verbose, DST_CA_DEBUG, 1, "Command = SEND_CA_PMT");
513 if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, 0)) < 0) { // code simplification started
514 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_PMT Failed !");
515 result = -1;
516 goto free_mem_and_exit;
517 }
518 dprintk(verbose, DST_CA_INFO, 1, " -->CA_PMT Success !");
519 break;
520 case CA_PMT_REPLY:
521 dprintk(verbose, DST_CA_INFO, 1, "Command = CA_PMT_REPLY");
522 /* Have to handle the 2 basic types of cards here */
523 if ((dst_check_ca_pmt(state, p_ca_message, hw_buffer)) < 0) {
524 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_PMT_REPLY Failed !");
525 result = -1;
526 goto free_mem_and_exit;
527 }
528 dprintk(verbose, DST_CA_INFO, 1, " -->CA_PMT_REPLY Success !");
529 break;
530 case CA_APP_INFO_ENQUIRY: // only for debugging
531 dprintk(verbose, DST_CA_INFO, 1, " Getting Cam Application information");
532
533 if ((ca_get_app_info(state)) < 0) {
534 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_APP_INFO_ENQUIRY Failed !");
535 result = -1;
536 goto free_mem_and_exit;
537 }
538 dprintk(verbose, DST_CA_INFO, 1, " -->CA_APP_INFO_ENQUIRY Success !");
539 break;
540 case CA_INFO_ENQUIRY:
541 dprintk(verbose, DST_CA_INFO, 1, " Getting CA Information");
542
543 if ((ca_get_ca_info(state)) < 0) {
544 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_INFO_ENQUIRY Failed !");
545 result = -1;
546 goto free_mem_and_exit;
547 }
548 dprintk(verbose, DST_CA_INFO, 1, " -->CA_INFO_ENQUIRY Success !");
549 break;
550 }
551 }
552free_mem_and_exit:
553 kfree (hw_buffer);
554
555 return result;
556}
557
558static long dst_ca_ioctl(struct file *file, unsigned int cmd, unsigned long ioctl_arg)
559{
560 struct dvb_device *dvbdev;
561 struct dst_state *state;
562 struct ca_slot_info *p_ca_slot_info;
563 struct ca_caps *p_ca_caps;
564 struct ca_msg *p_ca_message;
565 void __user *arg = (void __user *)ioctl_arg;
566 int result = 0;
567
568 mutex_lock(&dst_ca_mutex);
569 dvbdev = file->private_data;
570 state = (struct dst_state *)dvbdev->priv;
571 p_ca_message = kmalloc(sizeof (struct ca_msg), GFP_KERNEL);
572 p_ca_slot_info = kmalloc(sizeof (struct ca_slot_info), GFP_KERNEL);
573 p_ca_caps = kmalloc(sizeof (struct ca_caps), GFP_KERNEL);
574 if (!p_ca_message || !p_ca_slot_info || !p_ca_caps) {
575 dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure");
576 result = -ENOMEM;
577 goto free_mem_and_exit;
578 }
579
580 /* We have now only the standard ioctl's, the driver is upposed to handle internals. */
581 switch (cmd) {
582 case CA_SEND_MSG:
583 dprintk(verbose, DST_CA_INFO, 1, " Sending message");
584 if ((ca_send_message(state, p_ca_message, arg)) < 0) {
585 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SEND_MSG Failed !");
586 result = -1;
587 goto free_mem_and_exit;
588 }
589 break;
590 case CA_GET_MSG:
591 dprintk(verbose, DST_CA_INFO, 1, " Getting message");
592 if ((ca_get_message(state, p_ca_message, arg)) < 0) {
593 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_MSG Failed !");
594 result = -1;
595 goto free_mem_and_exit;
596 }
597 dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_MSG Success !");
598 break;
599 case CA_RESET:
600 dprintk(verbose, DST_CA_ERROR, 1, " Resetting DST");
601 dst_error_bailout(state);
602 msleep(4000);
603 break;
604 case CA_GET_SLOT_INFO:
605 dprintk(verbose, DST_CA_INFO, 1, " Getting Slot info");
606 if ((ca_get_slot_info(state, p_ca_slot_info, arg)) < 0) {
607 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_SLOT_INFO Failed !");
608 result = -1;
609 goto free_mem_and_exit;
610 }
611 dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_SLOT_INFO Success !");
612 break;
613 case CA_GET_CAP:
614 dprintk(verbose, DST_CA_INFO, 1, " Getting Slot capabilities");
615 if ((ca_get_slot_caps(state, p_ca_caps, arg)) < 0) {
616 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_CAP Failed !");
617 result = -1;
618 goto free_mem_and_exit;
619 }
620 dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_CAP Success !");
621 break;
622 case CA_GET_DESCR_INFO:
623 dprintk(verbose, DST_CA_INFO, 1, " Getting descrambler description");
624 if ((ca_get_slot_descr(state, p_ca_message, arg)) < 0) {
625 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_DESCR_INFO Failed !");
626 result = -1;
627 goto free_mem_and_exit;
628 }
629 dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_DESCR_INFO Success !");
630 break;
631 case CA_SET_DESCR:
632 dprintk(verbose, DST_CA_INFO, 1, " Setting descrambler");
633 if ((ca_set_slot_descr()) < 0) {
634 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SET_DESCR Failed !");
635 result = -1;
636 goto free_mem_and_exit;
637 }
638 dprintk(verbose, DST_CA_INFO, 1, " -->CA_SET_DESCR Success !");
639 break;
640 case CA_SET_PID:
641 dprintk(verbose, DST_CA_INFO, 1, " Setting PID");
642 if ((ca_set_pid()) < 0) {
643 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SET_PID Failed !");
644 result = -1;
645 goto free_mem_and_exit;
646 }
647 dprintk(verbose, DST_CA_INFO, 1, " -->CA_SET_PID Success !");
648 default:
649 result = -EOPNOTSUPP;
650 };
651 free_mem_and_exit:
652 kfree (p_ca_message);
653 kfree (p_ca_slot_info);
654 kfree (p_ca_caps);
655
656 mutex_unlock(&dst_ca_mutex);
657 return result;
658}
659
660static int dst_ca_open(struct inode *inode, struct file *file)
661{
662 dprintk(verbose, DST_CA_DEBUG, 1, " Device opened [%p] ", file);
663 try_module_get(THIS_MODULE);
664
665 return 0;
666}
667
668static int dst_ca_release(struct inode *inode, struct file *file)
669{
670 dprintk(verbose, DST_CA_DEBUG, 1, " Device closed.");
671 module_put(THIS_MODULE);
672
673 return 0;
674}
675
676static ssize_t dst_ca_read(struct file *file, char __user *buffer, size_t length, loff_t *offset)
677{
678 ssize_t bytes_read = 0;
679
680 dprintk(verbose, DST_CA_DEBUG, 1, " Device read.");
681
682 return bytes_read;
683}
684
685static ssize_t dst_ca_write(struct file *file, const char __user *buffer, size_t length, loff_t *offset)
686{
687 dprintk(verbose, DST_CA_DEBUG, 1, " Device write.");
688
689 return 0;
690}
691
692static const struct file_operations dst_ca_fops = {
693 .owner = THIS_MODULE,
694 .unlocked_ioctl = dst_ca_ioctl,
695 .open = dst_ca_open,
696 .release = dst_ca_release,
697 .read = dst_ca_read,
698 .write = dst_ca_write,
699 .llseek = noop_llseek,
700};
701
702static struct dvb_device dvbdev_ca = {
703 .priv = NULL,
704 .users = 1,
705 .readers = 1,
706 .writers = 1,
707 .fops = &dst_ca_fops
708};
709
710struct dvb_device *dst_ca_attach(struct dst_state *dst, struct dvb_adapter *dvb_adapter)
711{
712 struct dvb_device *dvbdev;
713
714 dprintk(verbose, DST_CA_ERROR, 1, "registering DST-CA device");
715 if (dvb_register_device(dvb_adapter, &dvbdev, &dvbdev_ca, dst, DVB_DEVICE_CA) == 0) {
716 dst->dst_ca = dvbdev;
717 return dst->dst_ca;
718 }
719
720 return NULL;
721}
722
723EXPORT_SYMBOL(dst_ca_attach);
724
725MODULE_DESCRIPTION("DST DVB-S/T/C Combo CA driver");
726MODULE_AUTHOR("Manu Abraham");
727MODULE_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..d88cf2add82
--- /dev/null
+++ b/drivers/media/dvb/bt8xx/dst_common.h
@@ -0,0 +1,182 @@
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 <linux/mutex.h>
28#include "bt878.h"
29
30#include "dst_ca.h"
31
32
33#define NO_DELAY 0
34#define LONG_DELAY 1
35#define DEVICE_INIT 2
36
37#define DELAY 1
38
39#define DST_TYPE_IS_SAT 0
40#define DST_TYPE_IS_TERR 1
41#define DST_TYPE_IS_CABLE 2
42#define DST_TYPE_IS_ATSC 3
43
44#define DST_TYPE_HAS_TS188 1
45#define DST_TYPE_HAS_TS204 2
46#define DST_TYPE_HAS_SYMDIV 4
47#define DST_TYPE_HAS_FW_1 8
48#define DST_TYPE_HAS_FW_2 16
49#define DST_TYPE_HAS_FW_3 32
50#define DST_TYPE_HAS_FW_BUILD 64
51#define DST_TYPE_HAS_OBS_REGS 128
52#define DST_TYPE_HAS_INC_COUNT 256
53#define DST_TYPE_HAS_MULTI_FE 512
54#define DST_TYPE_HAS_NEWTUNE_2 1024
55#define DST_TYPE_HAS_DBOARD 2048
56#define DST_TYPE_HAS_VLF 4096
57
58/* Card capability list */
59
60#define DST_TYPE_HAS_MAC 1
61#define DST_TYPE_HAS_DISEQC3 2
62#define DST_TYPE_HAS_DISEQC4 4
63#define DST_TYPE_HAS_DISEQC5 8
64#define DST_TYPE_HAS_MOTO 16
65#define DST_TYPE_HAS_CA 32
66#define DST_TYPE_HAS_ANALOG 64 /* Analog inputs */
67#define DST_TYPE_HAS_SESSION 128
68
69#define TUNER_TYPE_MULTI 1
70#define TUNER_TYPE_UNKNOWN 2
71/* DVB-S */
72#define TUNER_TYPE_L64724 4
73#define TUNER_TYPE_STV0299 8
74#define TUNER_TYPE_MB86A15 16
75
76/* DVB-T */
77#define TUNER_TYPE_TDA10046 32
78
79/* ATSC */
80#define TUNER_TYPE_NXT200x 64
81
82
83#define RDC_8820_PIO_0_DISABLE 0
84#define RDC_8820_PIO_0_ENABLE 1
85#define RDC_8820_INT 2
86#define RDC_8820_RESET 4
87
88/* DST Communication */
89#define GET_REPLY 1
90#define NO_REPLY 0
91
92#define GET_ACK 1
93#define FIXED_COMM 8
94
95#define ACK 0xff
96
97struct dst_state {
98
99 struct i2c_adapter* i2c;
100
101 struct bt878* bt;
102
103 /* configuration settings */
104 const struct dst_config* config;
105
106 struct dvb_frontend frontend;
107
108 /* private ASIC data */
109 u8 tx_tuna[10];
110 u8 rx_tuna[10];
111 u8 rxbuffer[10];
112 u8 diseq_flags;
113 u8 dst_type;
114 u32 type_flags;
115 u32 frequency; /* intermediate frequency in kHz for QPSK */
116 fe_spectral_inversion_t inversion;
117 u32 symbol_rate; /* symbol rate in Symbols per second */
118 fe_code_rate_t fec;
119 fe_sec_voltage_t voltage;
120 fe_sec_tone_mode_t tone;
121 u32 decode_freq;
122 u8 decode_lock;
123 u16 decode_strength;
124 u16 decode_snr;
125 unsigned long cur_jiff;
126 u8 k22;
127 fe_bandwidth_t bandwidth;
128 u32 dst_hw_cap;
129 u8 dst_fw_version;
130 fe_sec_mini_cmd_t minicmd;
131 fe_modulation_t modulation;
132 u8 messages[256];
133 u8 mac_address[8];
134 u8 fw_version[8];
135 u8 card_info[8];
136 u8 vendor[8];
137 u8 board_info[8];
138 u32 tuner_type;
139 char *tuner_name;
140 struct mutex dst_mutex;
141 u8 fw_name[8];
142 struct dvb_device *dst_ca;
143};
144
145struct tuner_types {
146 u32 tuner_type;
147 char *tuner_name;
148 char *board_name;
149 char *fw_name;
150};
151
152struct dst_types {
153 char *device_id;
154 int offset;
155 u8 dst_type;
156 u32 type_flags;
157 u32 dst_feature;
158 u32 tuner_type;
159};
160
161struct dst_config
162{
163 /* the ASIC i2c address */
164 u8 demod_address;
165};
166
167int rdc_reset_state(struct dst_state *state);
168
169int dst_wait_dst_ready(struct dst_state *state, u8 delay_mode);
170int dst_pio_disable(struct dst_state *state);
171int dst_error_recovery(struct dst_state* state);
172int dst_error_bailout(struct dst_state *state);
173int dst_comm_init(struct dst_state* state);
174
175int write_dst(struct dst_state *state, u8 * data, u8 len);
176int read_dst(struct dst_state *state, u8 * ret, u8 len);
177u8 dst_check_sum(u8 * buf, u32 len);
178struct dst_state* dst_attach(struct dst_state* state, struct dvb_adapter *dvb_adapter);
179struct dvb_device *dst_ca_attach(struct dst_state *state, struct dvb_adapter *dvb_adapter);
180
181
182#endif // DST_COMMON_H
diff --git a/drivers/media/dvb/bt8xx/dst_priv.h b/drivers/media/dvb/bt8xx/dst_priv.h
new file mode 100644
index 00000000000..3974a4c6ebe
--- /dev/null
+++ b/drivers/media/dvb/bt8xx/dst_priv.h
@@ -0,0 +1,35 @@
1/*
2 * dst-bt878.h: part of the DST driver for the TwinHan DST Frontend
3 *
4 * Copyright (C) 2003 Jamie Honan
5 */
6
7struct dst_gpio_enable {
8 u32 mask;
9 u32 enable;
10};
11
12struct dst_gpio_output {
13 u32 mask;
14 u32 highvals;
15};
16
17struct dst_gpio_read {
18 unsigned long value;
19};
20
21union dst_gpio_packet {
22 struct dst_gpio_enable enb;
23 struct dst_gpio_output outp;
24 struct dst_gpio_read rd;
25 int psize;
26};
27
28#define DST_IG_ENABLE 0
29#define DST_IG_WRITE 1
30#define DST_IG_READ 2
31#define DST_IG_TS 3
32
33struct bt878;
34
35int bt878_device_control(struct bt878 *bt, unsigned int cmd, union dst_gpio_packet *mp);
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
new file mode 100644
index 00000000000..521d6910498
--- /dev/null
+++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
@@ -0,0 +1,970 @@
1/*
2 * Bt8xx based DVB adapter driver
3 *
4 * Copyright (C) 2002,2003 Florian Schirmer <jolt@tuxbox.org>
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#include <linux/bitops.h>
23#include <linux/module.h>
24#include <linux/init.h>
25#include <linux/kernel.h>
26#include <linux/device.h>
27#include <linux/delay.h>
28#include <linux/slab.h>
29#include <linux/i2c.h>
30
31#include "dmxdev.h"
32#include "dvbdev.h"
33#include "dvb_demux.h"
34#include "dvb_frontend.h"
35#include "dvb-bt8xx.h"
36#include "bt878.h"
37
38static int debug;
39
40module_param(debug, int, 0644);
41MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
42
43DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
44
45#define dprintk( args... ) \
46 do { \
47 if (debug) printk(KERN_DEBUG args); \
48 } while (0)
49
50#define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */
51
52static void dvb_bt8xx_task(unsigned long data)
53{
54 struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *)data;
55
56 //printk("%d ", card->bt->finished_block);
57
58 while (card->bt->last_block != card->bt->finished_block) {
59 (card->bt->TS_Size ? dvb_dmx_swfilter_204 : dvb_dmx_swfilter)
60 (&card->demux,
61 &card->bt->buf_cpu[card->bt->last_block *
62 card->bt->block_bytes],
63 card->bt->block_bytes);
64 card->bt->last_block = (card->bt->last_block + 1) %
65 card->bt->block_count;
66 }
67}
68
69static int dvb_bt8xx_start_feed(struct dvb_demux_feed *dvbdmxfeed)
70{
71 struct dvb_demux*dvbdmx = dvbdmxfeed->demux;
72 struct dvb_bt8xx_card *card = dvbdmx->priv;
73 int rc;
74
75 dprintk("dvb_bt8xx: start_feed\n");
76
77 if (!dvbdmx->dmx.frontend)
78 return -EINVAL;
79
80 mutex_lock(&card->lock);
81 card->nfeeds++;
82 rc = card->nfeeds;
83 if (card->nfeeds == 1)
84 bt878_start(card->bt, card->gpio_mode,
85 card->op_sync_orin, card->irq_err_ignore);
86 mutex_unlock(&card->lock);
87 return rc;
88}
89
90static int dvb_bt8xx_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
91{
92 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
93 struct dvb_bt8xx_card *card = dvbdmx->priv;
94
95 dprintk("dvb_bt8xx: stop_feed\n");
96
97 if (!dvbdmx->dmx.frontend)
98 return -EINVAL;
99
100 mutex_lock(&card->lock);
101 card->nfeeds--;
102 if (card->nfeeds == 0)
103 bt878_stop(card->bt);
104 mutex_unlock(&card->lock);
105
106 return 0;
107}
108
109static int is_pci_slot_eq(struct pci_dev* adev, struct pci_dev* bdev)
110{
111 if ((adev->subsystem_vendor == bdev->subsystem_vendor) &&
112 (adev->subsystem_device == bdev->subsystem_device) &&
113 (adev->bus->number == bdev->bus->number) &&
114 (PCI_SLOT(adev->devfn) == PCI_SLOT(bdev->devfn)))
115 return 1;
116 return 0;
117}
118
119static struct bt878 __devinit *dvb_bt8xx_878_match(unsigned int bttv_nr, struct pci_dev* bttv_pci_dev)
120{
121 unsigned int card_nr;
122
123 /* Hmm, n squared. Hope n is small */
124 for (card_nr = 0; card_nr < bt878_num; card_nr++)
125 if (is_pci_slot_eq(bt878[card_nr].dev, bttv_pci_dev))
126 return &bt878[card_nr];
127 return NULL;
128}
129
130static int thomson_dtt7579_demod_init(struct dvb_frontend* fe)
131{
132 static u8 mt352_clock_config [] = { 0x89, 0x38, 0x38 };
133 static u8 mt352_reset [] = { 0x50, 0x80 };
134 static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 };
135 static u8 mt352_agc_cfg [] = { 0x67, 0x28, 0x20 };
136 static u8 mt352_gpp_ctl_cfg [] = { 0x8C, 0x33 };
137 static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };
138
139 mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
140 udelay(2000);
141 mt352_write(fe, mt352_reset, sizeof(mt352_reset));
142 mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
143
144 mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_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));
147
148 return 0;
149}
150
151static int thomson_dtt7579_tuner_calc_regs(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf, int buf_len)
152{
153 u32 div;
154 unsigned char bs = 0;
155 unsigned char cp = 0;
156
157 if (buf_len < 5)
158 return -EINVAL;
159
160 div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
161
162 if (params->frequency < 542000000)
163 cp = 0xb4;
164 else if (params->frequency < 771000000)
165 cp = 0xbc;
166 else
167 cp = 0xf4;
168
169 if (params->frequency == 0)
170 bs = 0x03;
171 else if (params->frequency < 443250000)
172 bs = 0x02;
173 else
174 bs = 0x08;
175
176 pllbuf[0] = 0x60;
177 pllbuf[1] = div >> 8;
178 pllbuf[2] = div & 0xff;
179 pllbuf[3] = cp;
180 pllbuf[4] = bs;
181
182 return 5;
183}
184
185static struct mt352_config thomson_dtt7579_config = {
186 .demod_address = 0x0f,
187 .demod_init = thomson_dtt7579_demod_init,
188};
189
190static struct zl10353_config thomson_dtt7579_zl10353_config = {
191 .demod_address = 0x0f,
192};
193
194static int cx24108_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
195{
196 u32 freq = params->frequency;
197
198 int i, a, n, pump;
199 u32 band, pll;
200
201 u32 osci[]={950000,1019000,1075000,1178000,1296000,1432000,
202 1576000,1718000,1856000,2036000,2150000};
203 u32 bandsel[]={0,0x00020000,0x00040000,0x00100800,0x00101000,
204 0x00102000,0x00104000,0x00108000,0x00110000,
205 0x00120000,0x00140000};
206
207 #define XTAL 1011100 /* Hz, really 1.0111 MHz and a /10 prescaler */
208 printk("cx24108 debug: entering SetTunerFreq, freq=%d\n",freq);
209
210 /* This is really the bit driving the tuner chip cx24108 */
211
212 if (freq<950000)
213 freq = 950000; /* kHz */
214 else if (freq>2150000)
215 freq = 2150000; /* satellite IF is 950..2150MHz */
216
217 /* decide which VCO to use for the input frequency */
218 for(i = 1; (i < ARRAY_SIZE(osci) - 1) && (osci[i] < freq); i++);
219 printk("cx24108 debug: select vco #%d (f=%d)\n",i,freq);
220 band=bandsel[i];
221 /* the gain values must be set by SetSymbolrate */
222 /* compute the pll divider needed, from Conexant data sheet,
223 resolved for (n*32+a), remember f(vco) is f(receive) *2 or *4,
224 depending on the divider bit. It is set to /4 on the 2 lowest
225 bands */
226 n=((i<=2?2:1)*freq*10L)/(XTAL/100);
227 a=n%32; n/=32; if(a==0) n--;
228 pump=(freq<(osci[i-1]+osci[i])/2);
229 pll=0xf8000000|
230 ((pump?1:2)<<(14+11))|
231 ((n&0x1ff)<<(5+11))|
232 ((a&0x1f)<<11);
233 /* everything is shifted left 11 bits to left-align the bits in the
234 32bit word. Output to the tuner goes MSB-aligned, after all */
235 printk("cx24108 debug: pump=%d, n=%d, a=%d\n",pump,n,a);
236 cx24110_pll_write(fe,band);
237 /* set vga and vca to their widest-band settings, as a precaution.
238 SetSymbolrate might not be called to set this up */
239 cx24110_pll_write(fe,0x500c0000);
240 cx24110_pll_write(fe,0x83f1f800);
241 cx24110_pll_write(fe,pll);
242 //writereg(client,0x56,0x7f);
243
244 return 0;
245}
246
247static int pinnsat_tuner_init(struct dvb_frontend* fe)
248{
249 struct dvb_bt8xx_card *card = fe->dvb->priv;
250
251 bttv_gpio_enable(card->bttv_nr, 1, 1); /* output */
252 bttv_write_gpio(card->bttv_nr, 1, 1); /* relay on */
253
254 return 0;
255}
256
257static int pinnsat_tuner_sleep(struct dvb_frontend* fe)
258{
259 struct dvb_bt8xx_card *card = fe->dvb->priv;
260
261 bttv_write_gpio(card->bttv_nr, 1, 0); /* relay off */
262
263 return 0;
264}
265
266static struct cx24110_config pctvsat_config = {
267 .demod_address = 0x55,
268};
269
270static int microtune_mt7202dtf_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
271{
272 struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv;
273 u8 cfg, cpump, band_select;
274 u8 data[4];
275 u32 div;
276 struct i2c_msg msg = { .addr = 0x60, .flags = 0, .buf = data, .len = sizeof(data) };
277
278 div = (36000000 + params->frequency + 83333) / 166666;
279 cfg = 0x88;
280
281 if (params->frequency < 175000000)
282 cpump = 2;
283 else if (params->frequency < 390000000)
284 cpump = 1;
285 else if (params->frequency < 470000000)
286 cpump = 2;
287 else if (params->frequency < 750000000)
288 cpump = 2;
289 else
290 cpump = 3;
291
292 if (params->frequency < 175000000)
293 band_select = 0x0e;
294 else if (params->frequency < 470000000)
295 band_select = 0x05;
296 else
297 band_select = 0x03;
298
299 data[0] = (div >> 8) & 0x7f;
300 data[1] = div & 0xff;
301 data[2] = ((div >> 10) & 0x60) | cfg;
302 data[3] = (cpump << 6) | band_select;
303
304 if (fe->ops.i2c_gate_ctrl)
305 fe->ops.i2c_gate_ctrl(fe, 1);
306 i2c_transfer(card->i2c_adapter, &msg, 1);
307 return (div * 166666 - 36000000);
308}
309
310static int microtune_mt7202dtf_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
311{
312 struct dvb_bt8xx_card* bt = (struct dvb_bt8xx_card*) fe->dvb->priv;
313
314 return request_firmware(fw, name, &bt->bt->dev->dev);
315}
316
317static struct sp887x_config microtune_mt7202dtf_config = {
318 .demod_address = 0x70,
319 .request_firmware = microtune_mt7202dtf_request_firmware,
320};
321
322static int advbt771_samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe)
323{
324 static u8 mt352_clock_config [] = { 0x89, 0x38, 0x2d };
325 static u8 mt352_reset [] = { 0x50, 0x80 };
326 static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 };
327 static u8 mt352_agc_cfg [] = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF,
328 0x00, 0xFF, 0x00, 0x40, 0x40 };
329 static u8 mt352_av771_extra[] = { 0xB5, 0x7A };
330 static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };
331
332 mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
333 udelay(2000);
334 mt352_write(fe, mt352_reset, sizeof(mt352_reset));
335 mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
336
337 mt352_write(fe, mt352_agc_cfg,sizeof(mt352_agc_cfg));
338 udelay(2000);
339 mt352_write(fe, mt352_av771_extra,sizeof(mt352_av771_extra));
340 mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
341
342 return 0;
343}
344
345static int advbt771_samsung_tdtc9251dh0_tuner_calc_regs(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf, int buf_len)
346{
347 u32 div;
348 unsigned char bs = 0;
349 unsigned char cp = 0;
350
351 if (buf_len < 5) return -EINVAL;
352
353 div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
354
355 if (params->frequency < 150000000)
356 cp = 0xB4;
357 else if (params->frequency < 173000000)
358 cp = 0xBC;
359 else if (params->frequency < 250000000)
360 cp = 0xB4;
361 else if (params->frequency < 400000000)
362 cp = 0xBC;
363 else if (params->frequency < 420000000)
364 cp = 0xF4;
365 else if (params->frequency < 470000000)
366 cp = 0xFC;
367 else if (params->frequency < 600000000)
368 cp = 0xBC;
369 else if (params->frequency < 730000000)
370 cp = 0xF4;
371 else
372 cp = 0xFC;
373
374 if (params->frequency < 150000000)
375 bs = 0x01;
376 else if (params->frequency < 173000000)
377 bs = 0x01;
378 else if (params->frequency < 250000000)
379 bs = 0x02;
380 else if (params->frequency < 400000000)
381 bs = 0x02;
382 else if (params->frequency < 420000000)
383 bs = 0x02;
384 else if (params->frequency < 470000000)
385 bs = 0x02;
386 else if (params->frequency < 600000000)
387 bs = 0x08;
388 else if (params->frequency < 730000000)
389 bs = 0x08;
390 else
391 bs = 0x08;
392
393 pllbuf[0] = 0x61;
394 pllbuf[1] = div >> 8;
395 pllbuf[2] = div & 0xff;
396 pllbuf[3] = cp;
397 pllbuf[4] = bs;
398
399 return 5;
400}
401
402static struct mt352_config advbt771_samsung_tdtc9251dh0_config = {
403 .demod_address = 0x0f,
404 .demod_init = advbt771_samsung_tdtc9251dh0_demod_init,
405};
406
407static struct dst_config dst_config = {
408 .demod_address = 0x55,
409};
410
411static int or51211_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
412{
413 struct dvb_bt8xx_card* bt = (struct dvb_bt8xx_card*) fe->dvb->priv;
414
415 return request_firmware(fw, name, &bt->bt->dev->dev);
416}
417
418static void or51211_setmode(struct dvb_frontend * fe, int mode)
419{
420 struct dvb_bt8xx_card *bt = fe->dvb->priv;
421 bttv_write_gpio(bt->bttv_nr, 0x0002, mode); /* Reset */
422 msleep(20);
423}
424
425static void or51211_reset(struct dvb_frontend * fe)
426{
427 struct dvb_bt8xx_card *bt = fe->dvb->priv;
428
429 /* RESET DEVICE
430 * reset is controlled by GPIO-0
431 * when set to 0 causes reset and when to 1 for normal op
432 * must remain reset for 128 clock cycles on a 50Mhz clock
433 * also PRM1 PRM2 & PRM4 are controlled by GPIO-1,GPIO-2 & GPIO-4
434 * We assume that the reset has be held low long enough or we
435 * have been reset by a power on. When the driver is unloaded
436 * reset set to 0 so if reloaded we have been reset.
437 */
438 /* reset & PRM1,2&4 are outputs */
439 int ret = bttv_gpio_enable(bt->bttv_nr, 0x001F, 0x001F);
440 if (ret != 0)
441 printk(KERN_WARNING "or51211: Init Error - Can't Reset DVR (%i)\n", ret);
442 bttv_write_gpio(bt->bttv_nr, 0x001F, 0x0000); /* Reset */
443 msleep(20);
444 /* Now set for normal operation */
445 bttv_write_gpio(bt->bttv_nr, 0x0001F, 0x0001);
446 /* wait for operation to begin */
447 msleep(500);
448}
449
450static void or51211_sleep(struct dvb_frontend * fe)
451{
452 struct dvb_bt8xx_card *bt = fe->dvb->priv;
453 bttv_write_gpio(bt->bttv_nr, 0x0001, 0x0000);
454}
455
456static struct or51211_config or51211_config = {
457 .demod_address = 0x15,
458 .request_firmware = or51211_request_firmware,
459 .setmode = or51211_setmode,
460 .reset = or51211_reset,
461 .sleep = or51211_sleep,
462};
463
464static int vp3021_alps_tded4_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
465{
466 struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv;
467 u8 buf[4];
468 u32 div;
469 struct i2c_msg msg = { .addr = 0x60, .flags = 0, .buf = buf, .len = sizeof(buf) };
470
471 div = (params->frequency + 36166667) / 166667;
472
473 buf[0] = (div >> 8) & 0x7F;
474 buf[1] = div & 0xFF;
475 buf[2] = 0x85;
476 if ((params->frequency >= 47000000) && (params->frequency < 153000000))
477 buf[3] = 0x01;
478 else if ((params->frequency >= 153000000) && (params->frequency < 430000000))
479 buf[3] = 0x02;
480 else if ((params->frequency >= 430000000) && (params->frequency < 824000000))
481 buf[3] = 0x0C;
482 else if ((params->frequency >= 824000000) && (params->frequency < 863000000))
483 buf[3] = 0x8C;
484 else
485 return -EINVAL;
486
487 if (fe->ops.i2c_gate_ctrl)
488 fe->ops.i2c_gate_ctrl(fe, 1);
489 i2c_transfer(card->i2c_adapter, &msg, 1);
490 return 0;
491}
492
493static struct nxt6000_config vp3021_alps_tded4_config = {
494 .demod_address = 0x0a,
495 .clock_inversion = 1,
496};
497
498static int digitv_alps_tded4_demod_init(struct dvb_frontend* fe)
499{
500 static u8 mt352_clock_config [] = { 0x89, 0x38, 0x2d };
501 static u8 mt352_reset [] = { 0x50, 0x80 };
502 static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 };
503 static u8 mt352_agc_cfg [] = { 0x67, 0x20, 0xa0 };
504 static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };
505
506 mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
507 udelay(2000);
508 mt352_write(fe, mt352_reset, sizeof(mt352_reset));
509 mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
510 mt352_write(fe, mt352_agc_cfg,sizeof(mt352_agc_cfg));
511 mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
512
513 return 0;
514}
515
516static int digitv_alps_tded4_tuner_calc_regs(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf, int buf_len)
517{
518 u32 div;
519 struct dvb_ofdm_parameters *op = &params->u.ofdm;
520
521 if (buf_len < 5)
522 return -EINVAL;
523
524 div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
525
526 pllbuf[0] = 0x61;
527 pllbuf[1] = (div >> 8) & 0x7F;
528 pllbuf[2] = div & 0xFF;
529 pllbuf[3] = 0x85;
530
531 dprintk("frequency %u, div %u\n", params->frequency, div);
532
533 if (params->frequency < 470000000)
534 pllbuf[4] = 0x02;
535 else if (params->frequency > 823000000)
536 pllbuf[4] = 0x88;
537 else
538 pllbuf[4] = 0x08;
539
540 if (op->bandwidth == 8)
541 pllbuf[4] |= 0x04;
542
543 return 5;
544}
545
546static void digitv_alps_tded4_reset(struct dvb_bt8xx_card *bt)
547{
548 /*
549 * Reset the frontend, must be called before trying
550 * to initialise the MT352 or mt352_attach
551 * will fail. Same goes for the nxt6000 frontend.
552 *
553 */
554
555 int ret = bttv_gpio_enable(bt->bttv_nr, 0x08, 0x08);
556 if (ret != 0)
557 printk(KERN_WARNING "digitv_alps_tded4: Init Error - Can't Reset DVR (%i)\n", ret);
558
559 /* Pulse the reset line */
560 bttv_write_gpio(bt->bttv_nr, 0x08, 0x08); /* High */
561 bttv_write_gpio(bt->bttv_nr, 0x08, 0x00); /* Low */
562 msleep(100);
563
564 bttv_write_gpio(bt->bttv_nr, 0x08, 0x08); /* High */
565}
566
567static struct mt352_config digitv_alps_tded4_config = {
568 .demod_address = 0x0a,
569 .demod_init = digitv_alps_tded4_demod_init,
570};
571
572static struct lgdt330x_config tdvs_tua6034_config = {
573 .demod_address = 0x0e,
574 .demod_chip = LGDT3303,
575 .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */
576};
577
578static void lgdt330x_reset(struct dvb_bt8xx_card *bt)
579{
580 /* Set pin 27 of the lgdt3303 chip high to reset the frontend */
581
582 /* Pulse the reset line */
583 bttv_write_gpio(bt->bttv_nr, 0x00e00007, 0x00000001); /* High */
584 bttv_write_gpio(bt->bttv_nr, 0x00e00007, 0x00000000); /* Low */
585 msleep(100);
586
587 bttv_write_gpio(bt->bttv_nr, 0x00e00007, 0x00000001); /* High */
588 msleep(100);
589}
590
591static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
592{
593 struct dst_state* state = NULL;
594
595 switch(type) {
596 case BTTV_BOARD_DVICO_DVBT_LITE:
597 card->fe = dvb_attach(mt352_attach, &thomson_dtt7579_config, card->i2c_adapter);
598
599 if (card->fe == NULL)
600 card->fe = dvb_attach(zl10353_attach, &thomson_dtt7579_zl10353_config,
601 card->i2c_adapter);
602
603 if (card->fe != NULL) {
604 card->fe->ops.tuner_ops.calc_regs = thomson_dtt7579_tuner_calc_regs;
605 card->fe->ops.info.frequency_min = 174000000;
606 card->fe->ops.info.frequency_max = 862000000;
607 }
608 break;
609
610 case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE:
611 lgdt330x_reset(card);
612 card->fe = dvb_attach(lgdt330x_attach, &tdvs_tua6034_config, card->i2c_adapter);
613 if (card->fe != NULL) {
614 dvb_attach(simple_tuner_attach, card->fe,
615 card->i2c_adapter, 0x61,
616 TUNER_LG_TDVS_H06XF);
617 dprintk ("dvb_bt8xx: lgdt330x detected\n");
618 }
619 break;
620
621 case BTTV_BOARD_NEBULA_DIGITV:
622 /*
623 * It is possible to determine the correct frontend using the I2C bus (see the Nebula SDK);
624 * this would be a cleaner solution than trying each frontend in turn.
625 */
626
627 /* Old Nebula (marked (c)2003 on high profile pci card) has nxt6000 demod */
628 digitv_alps_tded4_reset(card);
629 card->fe = dvb_attach(nxt6000_attach, &vp3021_alps_tded4_config, card->i2c_adapter);
630 if (card->fe != NULL) {
631 card->fe->ops.tuner_ops.set_params = vp3021_alps_tded4_tuner_set_params;
632 dprintk ("dvb_bt8xx: an nxt6000 was detected on your digitv card\n");
633 break;
634 }
635
636 /* New Nebula (marked (c)2005 on low profile pci card) has mt352 demod */
637 digitv_alps_tded4_reset(card);
638 card->fe = dvb_attach(mt352_attach, &digitv_alps_tded4_config, card->i2c_adapter);
639
640 if (card->fe != NULL) {
641 card->fe->ops.tuner_ops.calc_regs = digitv_alps_tded4_tuner_calc_regs;
642 dprintk ("dvb_bt8xx: an mt352 was detected on your digitv card\n");
643 }
644 break;
645
646 case BTTV_BOARD_AVDVBT_761:
647 card->fe = dvb_attach(sp887x_attach, &microtune_mt7202dtf_config, card->i2c_adapter);
648 if (card->fe) {
649 card->fe->ops.tuner_ops.set_params = microtune_mt7202dtf_tuner_set_params;
650 }
651 break;
652
653 case BTTV_BOARD_AVDVBT_771:
654 card->fe = dvb_attach(mt352_attach, &advbt771_samsung_tdtc9251dh0_config, card->i2c_adapter);
655 if (card->fe != NULL) {
656 card->fe->ops.tuner_ops.calc_regs = advbt771_samsung_tdtc9251dh0_tuner_calc_regs;
657 card->fe->ops.info.frequency_min = 174000000;
658 card->fe->ops.info.frequency_max = 862000000;
659 }
660 break;
661
662 case BTTV_BOARD_TWINHAN_DST:
663 /* DST is not a frontend driver !!! */
664 state = kmalloc(sizeof (struct dst_state), GFP_KERNEL);
665 if (!state) {
666 printk("dvb_bt8xx: No memory\n");
667 break;
668 }
669 /* Setup the Card */
670 state->config = &dst_config;
671 state->i2c = card->i2c_adapter;
672 state->bt = card->bt;
673 state->dst_ca = NULL;
674 /* DST is not a frontend, attaching the ASIC */
675 if (dvb_attach(dst_attach, state, &card->dvb_adapter) == NULL) {
676 printk("%s: Could not find a Twinhan DST.\n", __func__);
677 break;
678 }
679 /* Attach other DST peripherals if any */
680 /* Conditional Access device */
681 card->fe = &state->frontend;
682 if (state->dst_hw_cap & DST_TYPE_HAS_CA)
683 dvb_attach(dst_ca_attach, state, &card->dvb_adapter);
684 break;
685
686 case BTTV_BOARD_PINNACLESAT:
687 card->fe = dvb_attach(cx24110_attach, &pctvsat_config, card->i2c_adapter);
688 if (card->fe) {
689 card->fe->ops.tuner_ops.init = pinnsat_tuner_init;
690 card->fe->ops.tuner_ops.sleep = pinnsat_tuner_sleep;
691 card->fe->ops.tuner_ops.set_params = cx24108_tuner_set_params;
692 }
693 break;
694
695 case BTTV_BOARD_PC_HDTV:
696 card->fe = dvb_attach(or51211_attach, &or51211_config, card->i2c_adapter);
697 if (card->fe != NULL)
698 dvb_attach(simple_tuner_attach, card->fe,
699 card->i2c_adapter, 0x61,
700 TUNER_PHILIPS_FCV1236D);
701 break;
702 }
703
704 if (card->fe == NULL)
705 printk("dvb-bt8xx: A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n",
706 card->bt->dev->vendor,
707 card->bt->dev->device,
708 card->bt->dev->subsystem_vendor,
709 card->bt->dev->subsystem_device);
710 else
711 if (dvb_register_frontend(&card->dvb_adapter, card->fe)) {
712 printk("dvb-bt8xx: Frontend registration failed!\n");
713 dvb_frontend_detach(card->fe);
714 card->fe = NULL;
715 }
716}
717
718static int __devinit dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type)
719{
720 int result;
721
722 result = dvb_register_adapter(&card->dvb_adapter, card->card_name,
723 THIS_MODULE, &card->bt->dev->dev,
724 adapter_nr);
725 if (result < 0) {
726 printk("dvb_bt8xx: dvb_register_adapter failed (errno = %d)\n", result);
727 return result;
728 }
729 card->dvb_adapter.priv = card;
730
731 card->bt->adapter = card->i2c_adapter;
732
733 memset(&card->demux, 0, sizeof(struct dvb_demux));
734
735 card->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING;
736
737 card->demux.priv = card;
738 card->demux.filternum = 256;
739 card->demux.feednum = 256;
740 card->demux.start_feed = dvb_bt8xx_start_feed;
741 card->demux.stop_feed = dvb_bt8xx_stop_feed;
742 card->demux.write_to_decoder = NULL;
743
744 if ((result = dvb_dmx_init(&card->demux)) < 0) {
745 printk("dvb_bt8xx: dvb_dmx_init failed (errno = %d)\n", result);
746
747 dvb_unregister_adapter(&card->dvb_adapter);
748 return result;
749 }
750
751 card->dmxdev.filternum = 256;
752 card->dmxdev.demux = &card->demux.dmx;
753 card->dmxdev.capabilities = 0;
754
755 if ((result = dvb_dmxdev_init(&card->dmxdev, &card->dvb_adapter)) < 0) {
756 printk("dvb_bt8xx: dvb_dmxdev_init failed (errno = %d)\n", result);
757
758 dvb_dmx_release(&card->demux);
759 dvb_unregister_adapter(&card->dvb_adapter);
760 return result;
761 }
762
763 card->fe_hw.source = DMX_FRONTEND_0;
764
765 if ((result = card->demux.dmx.add_frontend(&card->demux.dmx, &card->fe_hw)) < 0) {
766 printk("dvb_bt8xx: dvb_dmx_init failed (errno = %d)\n", result);
767
768 dvb_dmxdev_release(&card->dmxdev);
769 dvb_dmx_release(&card->demux);
770 dvb_unregister_adapter(&card->dvb_adapter);
771 return result;
772 }
773
774 card->fe_mem.source = DMX_MEMORY_FE;
775
776 if ((result = card->demux.dmx.add_frontend(&card->demux.dmx, &card->fe_mem)) < 0) {
777 printk("dvb_bt8xx: dvb_dmx_init failed (errno = %d)\n", result);
778
779 card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw);
780 dvb_dmxdev_release(&card->dmxdev);
781 dvb_dmx_release(&card->demux);
782 dvb_unregister_adapter(&card->dvb_adapter);
783 return result;
784 }
785
786 if ((result = card->demux.dmx.connect_frontend(&card->demux.dmx, &card->fe_hw)) < 0) {
787 printk("dvb_bt8xx: dvb_dmx_init failed (errno = %d)\n", result);
788
789 card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_mem);
790 card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw);
791 dvb_dmxdev_release(&card->dmxdev);
792 dvb_dmx_release(&card->demux);
793 dvb_unregister_adapter(&card->dvb_adapter);
794 return result;
795 }
796
797 dvb_net_init(&card->dvb_adapter, &card->dvbnet, &card->demux.dmx);
798
799 tasklet_init(&card->bt->tasklet, dvb_bt8xx_task, (unsigned long) card);
800
801 frontend_init(card, type);
802
803 return 0;
804}
805
806static int __devinit dvb_bt8xx_probe(struct bttv_sub_device *sub)
807{
808 struct dvb_bt8xx_card *card;
809 struct pci_dev* bttv_pci_dev;
810 int ret;
811
812 if (!(card = kzalloc(sizeof(struct dvb_bt8xx_card), GFP_KERNEL)))
813 return -ENOMEM;
814
815 mutex_init(&card->lock);
816 card->bttv_nr = sub->core->nr;
817 strlcpy(card->card_name, sub->core->v4l2_dev.name, sizeof(card->card_name));
818 card->i2c_adapter = &sub->core->i2c_adap;
819
820 switch(sub->core->type) {
821 case BTTV_BOARD_PINNACLESAT:
822 card->gpio_mode = 0x0400c060;
823 /* should be: BT878_A_GAIN=0,BT878_A_PWRDN,BT878_DA_DPM,BT878_DA_SBR,
824 BT878_DA_IOM=1,BT878_DA_APP to enable serial highspeed mode. */
825 card->op_sync_orin = BT878_RISC_SYNC_MASK;
826 card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR;
827 break;
828
829 case BTTV_BOARD_DVICO_DVBT_LITE:
830 card->gpio_mode = 0x0400C060;
831 card->op_sync_orin = BT878_RISC_SYNC_MASK;
832 card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR;
833 /* 26, 15, 14, 6, 5
834 * A_PWRDN DA_DPM DA_SBR DA_IOM_DA
835 * DA_APP(parallel) */
836 break;
837
838 case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE:
839 card->gpio_mode = 0x0400c060;
840 card->op_sync_orin = BT878_RISC_SYNC_MASK;
841 card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR;
842 break;
843
844 case BTTV_BOARD_NEBULA_DIGITV:
845 case BTTV_BOARD_AVDVBT_761:
846 card->gpio_mode = (1 << 26) | (1 << 14) | (1 << 5);
847 card->op_sync_orin = BT878_RISC_SYNC_MASK;
848 card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR;
849 /* A_PWRDN DA_SBR DA_APP (high speed serial) */
850 break;
851
852 case BTTV_BOARD_AVDVBT_771: //case 0x07711461:
853 card->gpio_mode = 0x0400402B;
854 card->op_sync_orin = BT878_RISC_SYNC_MASK;
855 card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR;
856 /* A_PWRDN DA_SBR DA_APP[0] PKTP=10 RISC_ENABLE FIFO_ENABLE*/
857 break;
858
859 case BTTV_BOARD_TWINHAN_DST:
860 card->gpio_mode = 0x2204f2c;
861 card->op_sync_orin = BT878_RISC_SYNC_MASK;
862 card->irq_err_ignore = BT878_APABORT | BT878_ARIPERR |
863 BT878_APPERR | BT878_AFBUS;
864 /* 25,21,14,11,10,9,8,3,2 then
865 * 0x33 = 5,4,1,0
866 * A_SEL=SML, DA_MLB, DA_SBR,
867 * DA_SDR=f, fifo trigger = 32 DWORDS
868 * IOM = 0 == audio A/D
869 * DPM = 0 == digital audio mode
870 * == async data parallel port
871 * then 0x33 (13 is set by start_capture)
872 * DA_APP = async data parallel port,
873 * ACAP_EN = 1,
874 * RISC+FIFO ENABLE */
875 break;
876
877 case BTTV_BOARD_PC_HDTV:
878 card->gpio_mode = 0x0100EC7B;
879 card->op_sync_orin = BT878_RISC_SYNC_MASK;
880 card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR;
881 break;
882
883 default:
884 printk(KERN_WARNING "dvb_bt8xx: Unknown bttv card type: %d.\n",
885 sub->core->type);
886 kfree(card);
887 return -ENODEV;
888 }
889
890 dprintk("dvb_bt8xx: identified card%d as %s\n", card->bttv_nr, card->card_name);
891
892 if (!(bttv_pci_dev = bttv_get_pcidev(card->bttv_nr))) {
893 printk("dvb_bt8xx: no pci device for card %d\n", card->bttv_nr);
894 kfree(card);
895 return -ENODEV;
896 }
897
898 if (!(card->bt = dvb_bt8xx_878_match(card->bttv_nr, bttv_pci_dev))) {
899 printk("dvb_bt8xx: unable to determine DMA core of card %d,\n",
900 card->bttv_nr);
901 printk("dvb_bt8xx: if you have the ALSA bt87x audio driver "
902 "installed, try removing it.\n");
903
904 kfree(card);
905 return -ENODEV;
906 }
907
908 mutex_init(&card->bt->gpio_lock);
909 card->bt->bttv_nr = sub->core->nr;
910
911 if ( (ret = dvb_bt8xx_load_card(card, sub->core->type)) ) {
912 kfree(card);
913 return ret;
914 }
915
916 dev_set_drvdata(&sub->dev, card);
917 return 0;
918}
919
920static void dvb_bt8xx_remove(struct bttv_sub_device *sub)
921{
922 struct dvb_bt8xx_card *card = dev_get_drvdata(&sub->dev);
923
924 dprintk("dvb_bt8xx: unloading card%d\n", card->bttv_nr);
925
926 bt878_stop(card->bt);
927 tasklet_kill(&card->bt->tasklet);
928 dvb_net_release(&card->dvbnet);
929 card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_mem);
930 card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw);
931 dvb_dmxdev_release(&card->dmxdev);
932 dvb_dmx_release(&card->demux);
933 if (card->fe) {
934 dvb_unregister_frontend(card->fe);
935 dvb_frontend_detach(card->fe);
936 }
937 dvb_unregister_adapter(&card->dvb_adapter);
938
939 kfree(card);
940}
941
942static struct bttv_sub_driver driver = {
943 .drv = {
944 .name = "dvb-bt8xx",
945 },
946 .probe = dvb_bt8xx_probe,
947 .remove = dvb_bt8xx_remove,
948 /* FIXME:
949 * .shutdown = dvb_bt8xx_shutdown,
950 * .suspend = dvb_bt8xx_suspend,
951 * .resume = dvb_bt8xx_resume,
952 */
953};
954
955static int __init dvb_bt8xx_init(void)
956{
957 return bttv_sub_register(&driver, "dvb");
958}
959
960static void __exit dvb_bt8xx_exit(void)
961{
962 bttv_sub_unregister(&driver);
963}
964
965module_init(dvb_bt8xx_init);
966module_exit(dvb_bt8xx_exit);
967
968MODULE_DESCRIPTION("Bt8xx based DVB adapter driver");
969MODULE_AUTHOR("Florian Schirmer <jolt@tuxbox.org>");
970MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.h b/drivers/media/dvb/bt8xx/dvb-bt8xx.h
new file mode 100644
index 00000000000..4499ed2ac0e
--- /dev/null
+++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.h
@@ -0,0 +1,63 @@
1/*
2 * Bt8xx based DVB adapter driver
3 *
4 * Copyright (C) 2002,2003 Florian Schirmer <jolt@tuxbox.org>
5 * Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@htp-tel.de>
6 * Copyright (C) 1999-2001 Ralph Metzler & Marcus Metzler for convergence integrated media GmbH
7 * Copyright (C) 1998,1999 Christian Theiss <mistert@rz.fh-augsburg.de>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 *
23 */
24
25#ifndef DVB_BT8XX_H
26#define DVB_BT8XX_H
27
28#include <linux/i2c.h>
29#include <linux/mutex.h>
30#include "dvbdev.h"
31#include "dvb_net.h"
32#include "bttv.h"
33#include "mt352.h"
34#include "sp887x.h"
35#include "dst_common.h"
36#include "nxt6000.h"
37#include "cx24110.h"
38#include "or51211.h"
39#include "lgdt330x.h"
40#include "zl10353.h"
41#include "tuner-simple.h"
42
43struct dvb_bt8xx_card {
44 struct mutex lock;
45 int nfeeds;
46 char card_name[32];
47 struct dvb_adapter dvb_adapter;
48 struct bt878 *bt;
49 unsigned int bttv_nr;
50 struct dvb_demux demux;
51 struct dmxdev dmxdev;
52 struct dmx_frontend fe_hw;
53 struct dmx_frontend fe_mem;
54 u32 gpio_mode;
55 u32 op_sync_orin;
56 u32 irq_err_ignore;
57 struct i2c_adapter *i2c_adapter;
58 struct dvb_net dvbnet;
59
60 struct dvb_frontend* fe;
61};
62
63#endif /* DVB_BT8XX_H */