aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/pci/bt8xx
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2012-06-14 15:35:57 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-08-13 22:30:06 -0400
commit25aee3debe0464f6c680173041fa3de30ec9ff54 (patch)
treee2b14f952a0831399f9cbb444cfb9c7980b6485b /drivers/media/pci/bt8xx
parent786baecfe78f8e25547c628b48a60fc8e5636056 (diff)
[media] Rename media/dvb as media/pci
The remaining dvb drivers are pci, so rename them to match the bus. Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/pci/bt8xx')
-rw-r--r--drivers/media/pci/bt8xx/Kconfig22
-rw-r--r--drivers/media/pci/bt8xx/Makefile6
-rw-r--r--drivers/media/pci/bt8xx/bt878.c609
-rw-r--r--drivers/media/pci/bt8xx/bt878.h159
-rw-r--r--drivers/media/pci/bt8xx/dst.c1873
-rw-r--r--drivers/media/pci/bt8xx/dst_ca.c726
-rw-r--r--drivers/media/pci/bt8xx/dst_ca.h58
-rw-r--r--drivers/media/pci/bt8xx/dst_common.h182
-rw-r--r--drivers/media/pci/bt8xx/dst_priv.h35
-rw-r--r--drivers/media/pci/bt8xx/dvb-bt8xx.c975
-rw-r--r--drivers/media/pci/bt8xx/dvb-bt8xx.h63
11 files changed, 4708 insertions, 0 deletions
diff --git a/drivers/media/pci/bt8xx/Kconfig b/drivers/media/pci/bt8xx/Kconfig
new file mode 100644
index 000000000000..8668e634c7ec
--- /dev/null
+++ b/drivers/media/pci/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/pci/bt8xx/Makefile b/drivers/media/pci/bt8xx/Makefile
new file mode 100644
index 000000000000..36591ae505f4
--- /dev/null
+++ b/drivers/media/pci/bt8xx/Makefile
@@ -0,0 +1,6 @@
1obj-$(CONFIG_DVB_BT8XX) += bt878.o dvb-bt8xx.o dst.o dst_ca.o
2
3ccflags-y += -Idrivers/media/dvb-core
4ccflags-y += -Idrivers/media/dvb-frontends
5ccflags-y += -Idrivers/media/video/bt8xx
6ccflags-y += -Idrivers/media/common/tuners
diff --git a/drivers/media/pci/bt8xx/bt878.c b/drivers/media/pci/bt8xx/bt878.c
new file mode 100644
index 000000000000..b34fa95185e4
--- /dev/null
+++ b/drivers/media/pci/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/pci/bt8xx/bt878.h b/drivers/media/pci/bt8xx/bt878.h
new file mode 100644
index 000000000000..d19b59299d78
--- /dev/null
+++ b/drivers/media/pci/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/pci/bt8xx/dst.c b/drivers/media/pci/bt8xx/dst.c
new file mode 100644
index 000000000000..430b3eb11815
--- /dev/null
+++ b/drivers/media/pci/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, u32 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 6000000:
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 7000000:
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 8000000:
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 = 7000000;
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)
1613{
1614 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
1615 int retval = -EINVAL;
1616 struct dst_state *state = fe->demodulator_priv;
1617
1618 if (p != NULL) {
1619 retval = dst_set_freq(state, p->frequency);
1620 if(retval != 0)
1621 return retval;
1622 dprintk(verbose, DST_DEBUG, 1, "Set Frequency=[%d]", p->frequency);
1623
1624 if (state->dst_type == DST_TYPE_IS_SAT) {
1625 if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
1626 dst_set_inversion(state, p->inversion);
1627 dst_set_fec(state, p->fec_inner);
1628 dst_set_symbolrate(state, p->symbol_rate);
1629 dst_set_polarization(state);
1630 dprintk(verbose, DST_DEBUG, 1, "Set Symbolrate=[%d]", p->symbol_rate);
1631
1632 } else if (state->dst_type == DST_TYPE_IS_TERR)
1633 dst_set_bandwidth(state, p->bandwidth_hz);
1634 else if (state->dst_type == DST_TYPE_IS_CABLE) {
1635 dst_set_fec(state, p->fec_inner);
1636 dst_set_symbolrate(state, p->symbol_rate);
1637 dst_set_modulation(state, p->modulation);
1638 }
1639 retval = dst_write_tuna(fe);
1640 }
1641
1642 return retval;
1643}
1644
1645static int dst_tune_frontend(struct dvb_frontend* fe,
1646 bool re_tune,
1647 unsigned int mode_flags,
1648 unsigned int *delay,
1649 fe_status_t *status)
1650{
1651 struct dst_state *state = fe->demodulator_priv;
1652 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
1653
1654 if (re_tune) {
1655 dst_set_freq(state, p->frequency);
1656 dprintk(verbose, DST_DEBUG, 1, "Set Frequency=[%d]", p->frequency);
1657
1658 if (state->dst_type == DST_TYPE_IS_SAT) {
1659 if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
1660 dst_set_inversion(state, p->inversion);
1661 dst_set_fec(state, p->fec_inner);
1662 dst_set_symbolrate(state, p->symbol_rate);
1663 dst_set_polarization(state);
1664 dprintk(verbose, DST_DEBUG, 1, "Set Symbolrate=[%d]", p->symbol_rate);
1665
1666 } else if (state->dst_type == DST_TYPE_IS_TERR)
1667 dst_set_bandwidth(state, p->bandwidth_hz);
1668 else if (state->dst_type == DST_TYPE_IS_CABLE) {
1669 dst_set_fec(state, p->fec_inner);
1670 dst_set_symbolrate(state, p->symbol_rate);
1671 dst_set_modulation(state, p->modulation);
1672 }
1673 dst_write_tuna(fe);
1674 }
1675
1676 if (!(mode_flags & FE_TUNE_MODE_ONESHOT))
1677 dst_read_status(fe, status);
1678
1679 *delay = HZ/10;
1680 return 0;
1681}
1682
1683static int dst_get_tuning_algo(struct dvb_frontend *fe)
1684{
1685 return dst_algo ? DVBFE_ALGO_HW : DVBFE_ALGO_SW;
1686}
1687
1688static int dst_get_frontend(struct dvb_frontend *fe)
1689{
1690 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
1691 struct dst_state *state = fe->demodulator_priv;
1692
1693 p->frequency = state->decode_freq;
1694 if (state->dst_type == DST_TYPE_IS_SAT) {
1695 if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
1696 p->inversion = state->inversion;
1697 p->symbol_rate = state->symbol_rate;
1698 p->fec_inner = dst_get_fec(state);
1699 } else if (state->dst_type == DST_TYPE_IS_TERR) {
1700 p->bandwidth_hz = state->bandwidth;
1701 } else if (state->dst_type == DST_TYPE_IS_CABLE) {
1702 p->symbol_rate = state->symbol_rate;
1703 p->fec_inner = dst_get_fec(state);
1704 p->modulation = dst_get_modulation(state);
1705 }
1706
1707 return 0;
1708}
1709
1710static void dst_release(struct dvb_frontend *fe)
1711{
1712 struct dst_state *state = fe->demodulator_priv;
1713 if (state->dst_ca) {
1714 dvb_unregister_device(state->dst_ca);
1715#ifdef CONFIG_MEDIA_ATTACH
1716 symbol_put(dst_ca_attach);
1717#endif
1718 }
1719 kfree(state);
1720}
1721
1722static struct dvb_frontend_ops dst_dvbt_ops;
1723static struct dvb_frontend_ops dst_dvbs_ops;
1724static struct dvb_frontend_ops dst_dvbc_ops;
1725static struct dvb_frontend_ops dst_atsc_ops;
1726
1727struct dst_state *dst_attach(struct dst_state *state, struct dvb_adapter *dvb_adapter)
1728{
1729 /* check if the ASIC is there */
1730 if (dst_probe(state) < 0) {
1731 kfree(state);
1732 return NULL;
1733 }
1734 /* determine settings based on type */
1735 /* create dvb_frontend */
1736 switch (state->dst_type) {
1737 case DST_TYPE_IS_TERR:
1738 memcpy(&state->frontend.ops, &dst_dvbt_ops, sizeof(struct dvb_frontend_ops));
1739 break;
1740 case DST_TYPE_IS_CABLE:
1741 memcpy(&state->frontend.ops, &dst_dvbc_ops, sizeof(struct dvb_frontend_ops));
1742 break;
1743 case DST_TYPE_IS_SAT:
1744 memcpy(&state->frontend.ops, &dst_dvbs_ops, sizeof(struct dvb_frontend_ops));
1745 break;
1746 case DST_TYPE_IS_ATSC:
1747 memcpy(&state->frontend.ops, &dst_atsc_ops, sizeof(struct dvb_frontend_ops));
1748 break;
1749 default:
1750 dprintk(verbose, DST_ERROR, 1, "unknown DST type. please report to the LinuxTV.org DVB mailinglist.");
1751 kfree(state);
1752 return NULL;
1753 }
1754 state->frontend.demodulator_priv = state;
1755
1756 return state; /* Manu (DST is a card not a frontend) */
1757}
1758
1759EXPORT_SYMBOL(dst_attach);
1760
1761static struct dvb_frontend_ops dst_dvbt_ops = {
1762 .delsys = { SYS_DVBT },
1763 .info = {
1764 .name = "DST DVB-T",
1765 .frequency_min = 137000000,
1766 .frequency_max = 858000000,
1767 .frequency_stepsize = 166667,
1768 .caps = FE_CAN_FEC_AUTO |
1769 FE_CAN_QAM_AUTO |
1770 FE_CAN_QAM_16 |
1771 FE_CAN_QAM_32 |
1772 FE_CAN_QAM_64 |
1773 FE_CAN_QAM_128 |
1774 FE_CAN_QAM_256 |
1775 FE_CAN_TRANSMISSION_MODE_AUTO |
1776 FE_CAN_GUARD_INTERVAL_AUTO
1777 },
1778
1779 .release = dst_release,
1780 .init = dst_init,
1781 .tune = dst_tune_frontend,
1782 .set_frontend = dst_set_frontend,
1783 .get_frontend = dst_get_frontend,
1784 .get_frontend_algo = dst_get_tuning_algo,
1785 .read_status = dst_read_status,
1786 .read_signal_strength = dst_read_signal_strength,
1787 .read_snr = dst_read_snr,
1788};
1789
1790static struct dvb_frontend_ops dst_dvbs_ops = {
1791 .delsys = { SYS_DVBS },
1792 .info = {
1793 .name = "DST DVB-S",
1794 .frequency_min = 950000,
1795 .frequency_max = 2150000,
1796 .frequency_stepsize = 1000, /* kHz for QPSK frontends */
1797 .frequency_tolerance = 29500,
1798 .symbol_rate_min = 1000000,
1799 .symbol_rate_max = 45000000,
1800 /* . symbol_rate_tolerance = ???,*/
1801 .caps = FE_CAN_FEC_AUTO | FE_CAN_QPSK
1802 },
1803
1804 .release = dst_release,
1805 .init = dst_init,
1806 .tune = dst_tune_frontend,
1807 .set_frontend = dst_set_frontend,
1808 .get_frontend = dst_get_frontend,
1809 .get_frontend_algo = dst_get_tuning_algo,
1810 .read_status = dst_read_status,
1811 .read_signal_strength = dst_read_signal_strength,
1812 .read_snr = dst_read_snr,
1813 .diseqc_send_burst = dst_send_burst,
1814 .diseqc_send_master_cmd = dst_set_diseqc,
1815 .set_voltage = dst_set_voltage,
1816 .set_tone = dst_set_tone,
1817};
1818
1819static struct dvb_frontend_ops dst_dvbc_ops = {
1820 .delsys = { SYS_DVBC_ANNEX_A },
1821 .info = {
1822 .name = "DST DVB-C",
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 .delsys = { SYS_ATSC },
1850 .info = {
1851 .name = "DST 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/pci/bt8xx/dst_ca.c b/drivers/media/pci/bt8xx/dst_ca.c
new file mode 100644
index 000000000000..ee3884fbc9ce
--- /dev/null
+++ b/drivers/media/pci/bt8xx/dst_ca.c
@@ -0,0 +1,726 @@
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 = [%*ph]",
325 3, p_ca_message->msg);
326
327 for (i = 0; i < 3; i++) {
328 command = command | p_ca_message->msg[i];
329 if (i < 2)
330 command = command << 8;
331 }
332 dprintk(verbose, DST_CA_NOTICE, 1, " Command=[0x%x]", command);
333
334 switch (command) {
335 case CA_APP_INFO:
336 memcpy(p_ca_message->msg, state->messages, 128);
337 if (copy_to_user(arg, p_ca_message, sizeof (struct ca_msg)) )
338 return -EFAULT;
339 break;
340 case CA_INFO:
341 memcpy(p_ca_message->msg, state->messages, 128);
342 if (copy_to_user(arg, p_ca_message, sizeof (struct ca_msg)) )
343 return -EFAULT;
344 break;
345 }
346 }
347
348 return 0;
349}
350
351static int handle_dst_tag(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer, u32 length)
352{
353 if (state->dst_hw_cap & DST_TYPE_HAS_SESSION) {
354 hw_buffer->msg[2] = p_ca_message->msg[1]; /* MSB */
355 hw_buffer->msg[3] = p_ca_message->msg[2]; /* LSB */
356 } else {
357 if (length > 247) {
358 dprintk(verbose, DST_CA_ERROR, 1, " Message too long ! *** Bailing Out *** !");
359 return -1;
360 }
361 hw_buffer->msg[0] = (length & 0xff) + 7;
362 hw_buffer->msg[1] = 0x40;
363 hw_buffer->msg[2] = 0x03;
364 hw_buffer->msg[3] = 0x00;
365 hw_buffer->msg[4] = 0x03;
366 hw_buffer->msg[5] = length & 0xff;
367 hw_buffer->msg[6] = 0x00;
368
369 /*
370 * Need to compute length for EN50221 section 8.3.2, for the time being
371 * assuming 8.3.2 is not applicable
372 */
373 memcpy(&hw_buffer->msg[7], &p_ca_message->msg[4], length);
374 }
375
376 return 0;
377}
378
379static int write_to_8820(struct dst_state *state, struct ca_msg *hw_buffer, u8 length, u8 reply)
380{
381 if ((dst_put_ci(state, hw_buffer->msg, length, hw_buffer->msg, reply)) < 0) {
382 dprintk(verbose, DST_CA_ERROR, 1, " DST-CI Command failed.");
383 dprintk(verbose, DST_CA_NOTICE, 1, " Resetting DST.");
384 rdc_reset_state(state);
385 return -1;
386 }
387 dprintk(verbose, DST_CA_NOTICE, 1, " DST-CI Command success.");
388
389 return 0;
390}
391
392static u32 asn_1_decode(u8 *asn_1_array)
393{
394 u8 length_field = 0, word_count = 0, count = 0;
395 u32 length = 0;
396
397 length_field = asn_1_array[0];
398 dprintk(verbose, DST_CA_DEBUG, 1, " Length field=[%02x]", length_field);
399 if (length_field < 0x80) {
400 length = length_field & 0x7f;
401 dprintk(verbose, DST_CA_DEBUG, 1, " Length=[%02x]\n", length);
402 } else {
403 word_count = length_field & 0x7f;
404 for (count = 0; count < word_count; count++) {
405 length = length << 8;
406 length += asn_1_array[count + 1];
407 dprintk(verbose, DST_CA_DEBUG, 1, " Length=[%04x]", length);
408 }
409 }
410 return length;
411}
412
413static int debug_string(u8 *msg, u32 length, u32 offset)
414{
415 u32 i;
416
417 dprintk(verbose, DST_CA_DEBUG, 0, " String=[ ");
418 for (i = offset; i < length; i++)
419 dprintk(verbose, DST_CA_DEBUG, 0, "%02x ", msg[i]);
420 dprintk(verbose, DST_CA_DEBUG, 0, "]\n");
421
422 return 0;
423}
424
425
426static int ca_set_pmt(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer, u8 reply, u8 query)
427{
428 u32 length = 0;
429 u8 tag_length = 8;
430
431 length = asn_1_decode(&p_ca_message->msg[3]);
432 dprintk(verbose, DST_CA_DEBUG, 1, " CA Message length=[%d]", length);
433 debug_string(&p_ca_message->msg[4], length, 0); /* length is excluding tag & length */
434
435 memset(hw_buffer->msg, '\0', length);
436 handle_dst_tag(state, p_ca_message, hw_buffer, length);
437 put_checksum(hw_buffer->msg, hw_buffer->msg[0]);
438
439 debug_string(hw_buffer->msg, (length + tag_length), 0); /* tags too */
440 write_to_8820(state, hw_buffer, (length + tag_length), reply);
441
442 return 0;
443}
444
445
446/* Board supports CA PMT reply ? */
447static int dst_check_ca_pmt(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer)
448{
449 int ca_pmt_reply_test = 0;
450
451 /* Do test board */
452 /* Not there yet but soon */
453
454 /* CA PMT Reply capable */
455 if (ca_pmt_reply_test) {
456 if ((ca_set_pmt(state, p_ca_message, hw_buffer, 1, GET_REPLY)) < 0) {
457 dprintk(verbose, DST_CA_ERROR, 1, " ca_set_pmt.. failed !");
458 return -1;
459 }
460
461 /* Process CA PMT Reply */
462 /* will implement soon */
463 dprintk(verbose, DST_CA_ERROR, 1, " Not there yet");
464 }
465 /* CA PMT Reply not capable */
466 if (!ca_pmt_reply_test) {
467 if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, NO_REPLY)) < 0) {
468 dprintk(verbose, DST_CA_ERROR, 1, " ca_set_pmt.. failed !");
469 return -1;
470 }
471 dprintk(verbose, DST_CA_NOTICE, 1, " ca_set_pmt.. success !");
472 /* put a dummy message */
473
474 }
475 return 0;
476}
477
478static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message, void __user *arg)
479{
480 int i = 0;
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 /* EN50221 tag */
500 command = 0;
501
502 for (i = 0; i < 3; i++) {
503 command = command | p_ca_message->msg[i];
504 if (i < 2)
505 command = command << 8;
506 }
507 dprintk(verbose, DST_CA_DEBUG, 1, " Command=[0x%x]\n", command);
508
509 switch (command) {
510 case CA_PMT:
511 dprintk(verbose, DST_CA_DEBUG, 1, "Command = SEND_CA_PMT");
512 if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, 0)) < 0) { // code simplification started
513 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_PMT Failed !");
514 result = -1;
515 goto free_mem_and_exit;
516 }
517 dprintk(verbose, DST_CA_INFO, 1, " -->CA_PMT Success !");
518 break;
519 case CA_PMT_REPLY:
520 dprintk(verbose, DST_CA_INFO, 1, "Command = CA_PMT_REPLY");
521 /* Have to handle the 2 basic types of cards here */
522 if ((dst_check_ca_pmt(state, p_ca_message, hw_buffer)) < 0) {
523 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_PMT_REPLY Failed !");
524 result = -1;
525 goto free_mem_and_exit;
526 }
527 dprintk(verbose, DST_CA_INFO, 1, " -->CA_PMT_REPLY Success !");
528 break;
529 case CA_APP_INFO_ENQUIRY: // only for debugging
530 dprintk(verbose, DST_CA_INFO, 1, " Getting Cam Application information");
531
532 if ((ca_get_app_info(state)) < 0) {
533 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_APP_INFO_ENQUIRY Failed !");
534 result = -1;
535 goto free_mem_and_exit;
536 }
537 dprintk(verbose, DST_CA_INFO, 1, " -->CA_APP_INFO_ENQUIRY Success !");
538 break;
539 case CA_INFO_ENQUIRY:
540 dprintk(verbose, DST_CA_INFO, 1, " Getting CA Information");
541
542 if ((ca_get_ca_info(state)) < 0) {
543 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_INFO_ENQUIRY Failed !");
544 result = -1;
545 goto free_mem_and_exit;
546 }
547 dprintk(verbose, DST_CA_INFO, 1, " -->CA_INFO_ENQUIRY Success !");
548 break;
549 }
550 }
551free_mem_and_exit:
552 kfree (hw_buffer);
553
554 return result;
555}
556
557static long dst_ca_ioctl(struct file *file, unsigned int cmd, unsigned long ioctl_arg)
558{
559 struct dvb_device *dvbdev;
560 struct dst_state *state;
561 struct ca_slot_info *p_ca_slot_info;
562 struct ca_caps *p_ca_caps;
563 struct ca_msg *p_ca_message;
564 void __user *arg = (void __user *)ioctl_arg;
565 int result = 0;
566
567 mutex_lock(&dst_ca_mutex);
568 dvbdev = file->private_data;
569 state = (struct dst_state *)dvbdev->priv;
570 p_ca_message = kmalloc(sizeof (struct ca_msg), GFP_KERNEL);
571 p_ca_slot_info = kmalloc(sizeof (struct ca_slot_info), GFP_KERNEL);
572 p_ca_caps = kmalloc(sizeof (struct ca_caps), GFP_KERNEL);
573 if (!p_ca_message || !p_ca_slot_info || !p_ca_caps) {
574 dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure");
575 result = -ENOMEM;
576 goto free_mem_and_exit;
577 }
578
579 /* We have now only the standard ioctl's, the driver is upposed to handle internals. */
580 switch (cmd) {
581 case CA_SEND_MSG:
582 dprintk(verbose, DST_CA_INFO, 1, " Sending message");
583 if ((ca_send_message(state, p_ca_message, arg)) < 0) {
584 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SEND_MSG Failed !");
585 result = -1;
586 goto free_mem_and_exit;
587 }
588 break;
589 case CA_GET_MSG:
590 dprintk(verbose, DST_CA_INFO, 1, " Getting message");
591 if ((ca_get_message(state, p_ca_message, arg)) < 0) {
592 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_MSG Failed !");
593 result = -1;
594 goto free_mem_and_exit;
595 }
596 dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_MSG Success !");
597 break;
598 case CA_RESET:
599 dprintk(verbose, DST_CA_ERROR, 1, " Resetting DST");
600 dst_error_bailout(state);
601 msleep(4000);
602 break;
603 case CA_GET_SLOT_INFO:
604 dprintk(verbose, DST_CA_INFO, 1, " Getting Slot info");
605 if ((ca_get_slot_info(state, p_ca_slot_info, arg)) < 0) {
606 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_SLOT_INFO Failed !");
607 result = -1;
608 goto free_mem_and_exit;
609 }
610 dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_SLOT_INFO Success !");
611 break;
612 case CA_GET_CAP:
613 dprintk(verbose, DST_CA_INFO, 1, " Getting Slot capabilities");
614 if ((ca_get_slot_caps(state, p_ca_caps, arg)) < 0) {
615 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_CAP Failed !");
616 result = -1;
617 goto free_mem_and_exit;
618 }
619 dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_CAP Success !");
620 break;
621 case CA_GET_DESCR_INFO:
622 dprintk(verbose, DST_CA_INFO, 1, " Getting descrambler description");
623 if ((ca_get_slot_descr(state, p_ca_message, arg)) < 0) {
624 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_DESCR_INFO Failed !");
625 result = -1;
626 goto free_mem_and_exit;
627 }
628 dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_DESCR_INFO Success !");
629 break;
630 case CA_SET_DESCR:
631 dprintk(verbose, DST_CA_INFO, 1, " Setting descrambler");
632 if ((ca_set_slot_descr()) < 0) {
633 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SET_DESCR Failed !");
634 result = -1;
635 goto free_mem_and_exit;
636 }
637 dprintk(verbose, DST_CA_INFO, 1, " -->CA_SET_DESCR Success !");
638 break;
639 case CA_SET_PID:
640 dprintk(verbose, DST_CA_INFO, 1, " Setting PID");
641 if ((ca_set_pid()) < 0) {
642 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SET_PID Failed !");
643 result = -1;
644 goto free_mem_and_exit;
645 }
646 dprintk(verbose, DST_CA_INFO, 1, " -->CA_SET_PID Success !");
647 default:
648 result = -EOPNOTSUPP;
649 };
650 free_mem_and_exit:
651 kfree (p_ca_message);
652 kfree (p_ca_slot_info);
653 kfree (p_ca_caps);
654
655 mutex_unlock(&dst_ca_mutex);
656 return result;
657}
658
659static int dst_ca_open(struct inode *inode, struct file *file)
660{
661 dprintk(verbose, DST_CA_DEBUG, 1, " Device opened [%p] ", file);
662 try_module_get(THIS_MODULE);
663
664 return 0;
665}
666
667static int dst_ca_release(struct inode *inode, struct file *file)
668{
669 dprintk(verbose, DST_CA_DEBUG, 1, " Device closed.");
670 module_put(THIS_MODULE);
671
672 return 0;
673}
674
675static ssize_t dst_ca_read(struct file *file, char __user *buffer, size_t length, loff_t *offset)
676{
677 ssize_t bytes_read = 0;
678
679 dprintk(verbose, DST_CA_DEBUG, 1, " Device read.");
680
681 return bytes_read;
682}
683
684static ssize_t dst_ca_write(struct file *file, const char __user *buffer, size_t length, loff_t *offset)
685{
686 dprintk(verbose, DST_CA_DEBUG, 1, " Device write.");
687
688 return 0;
689}
690
691static const struct file_operations dst_ca_fops = {
692 .owner = THIS_MODULE,
693 .unlocked_ioctl = dst_ca_ioctl,
694 .open = dst_ca_open,
695 .release = dst_ca_release,
696 .read = dst_ca_read,
697 .write = dst_ca_write,
698 .llseek = noop_llseek,
699};
700
701static struct dvb_device dvbdev_ca = {
702 .priv = NULL,
703 .users = 1,
704 .readers = 1,
705 .writers = 1,
706 .fops = &dst_ca_fops
707};
708
709struct dvb_device *dst_ca_attach(struct dst_state *dst, struct dvb_adapter *dvb_adapter)
710{
711 struct dvb_device *dvbdev;
712
713 dprintk(verbose, DST_CA_ERROR, 1, "registering DST-CA device");
714 if (dvb_register_device(dvb_adapter, &dvbdev, &dvbdev_ca, dst, DVB_DEVICE_CA) == 0) {
715 dst->dst_ca = dvbdev;
716 return dst->dst_ca;
717 }
718
719 return NULL;
720}
721
722EXPORT_SYMBOL(dst_ca_attach);
723
724MODULE_DESCRIPTION("DST DVB-S/T/C Combo CA driver");
725MODULE_AUTHOR("Manu Abraham");
726MODULE_LICENSE("GPL");
diff --git a/drivers/media/pci/bt8xx/dst_ca.h b/drivers/media/pci/bt8xx/dst_ca.h
new file mode 100644
index 000000000000..59cd0ddd6d8e
--- /dev/null
+++ b/drivers/media/pci/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/pci/bt8xx/dst_common.h b/drivers/media/pci/bt8xx/dst_common.h
new file mode 100644
index 000000000000..d70d98f1a571
--- /dev/null
+++ b/drivers/media/pci/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 u32 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/pci/bt8xx/dst_priv.h b/drivers/media/pci/bt8xx/dst_priv.h
new file mode 100644
index 000000000000..3974a4c6ebe7
--- /dev/null
+++ b/drivers/media/pci/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/pci/bt8xx/dvb-bt8xx.c b/drivers/media/pci/bt8xx/dvb-bt8xx.c
new file mode 100644
index 000000000000..81fab9adc1ca
--- /dev/null
+++ b/drivers/media/pci/bt8xx/dvb-bt8xx.c
@@ -0,0 +1,975 @@
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#define pr_fmt(fmt) "dvb_bt8xx: " fmt
23
24#include <linux/bitops.h>
25#include <linux/module.h>
26#include <linux/init.h>
27#include <linux/kernel.h>
28#include <linux/device.h>
29#include <linux/delay.h>
30#include <linux/slab.h>
31#include <linux/i2c.h>
32
33#include "dmxdev.h"
34#include "dvbdev.h"
35#include "dvb_demux.h"
36#include "dvb_frontend.h"
37#include "dvb-bt8xx.h"
38#include "bt878.h"
39
40static int debug;
41
42module_param(debug, int, 0644);
43MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
44
45DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
46
47#define dprintk( args... ) \
48 do { \
49 if (debug) printk(KERN_DEBUG args); \
50 } while (0)
51
52#define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */
53
54static void dvb_bt8xx_task(unsigned long data)
55{
56 struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *)data;
57
58 //printk("%d ", card->bt->finished_block);
59
60 while (card->bt->last_block != card->bt->finished_block) {
61 (card->bt->TS_Size ? dvb_dmx_swfilter_204 : dvb_dmx_swfilter)
62 (&card->demux,
63 &card->bt->buf_cpu[card->bt->last_block *
64 card->bt->block_bytes],
65 card->bt->block_bytes);
66 card->bt->last_block = (card->bt->last_block + 1) %
67 card->bt->block_count;
68 }
69}
70
71static int dvb_bt8xx_start_feed(struct dvb_demux_feed *dvbdmxfeed)
72{
73 struct dvb_demux*dvbdmx = dvbdmxfeed->demux;
74 struct dvb_bt8xx_card *card = dvbdmx->priv;
75 int rc;
76
77 dprintk("dvb_bt8xx: start_feed\n");
78
79 if (!dvbdmx->dmx.frontend)
80 return -EINVAL;
81
82 mutex_lock(&card->lock);
83 card->nfeeds++;
84 rc = card->nfeeds;
85 if (card->nfeeds == 1)
86 bt878_start(card->bt, card->gpio_mode,
87 card->op_sync_orin, card->irq_err_ignore);
88 mutex_unlock(&card->lock);
89 return rc;
90}
91
92static int dvb_bt8xx_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
93{
94 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
95 struct dvb_bt8xx_card *card = dvbdmx->priv;
96
97 dprintk("dvb_bt8xx: stop_feed\n");
98
99 if (!dvbdmx->dmx.frontend)
100 return -EINVAL;
101
102 mutex_lock(&card->lock);
103 card->nfeeds--;
104 if (card->nfeeds == 0)
105 bt878_stop(card->bt);
106 mutex_unlock(&card->lock);
107
108 return 0;
109}
110
111static int is_pci_slot_eq(struct pci_dev* adev, struct pci_dev* bdev)
112{
113 if ((adev->subsystem_vendor == bdev->subsystem_vendor) &&
114 (adev->subsystem_device == bdev->subsystem_device) &&
115 (adev->bus->number == bdev->bus->number) &&
116 (PCI_SLOT(adev->devfn) == PCI_SLOT(bdev->devfn)))
117 return 1;
118 return 0;
119}
120
121static struct bt878 __devinit *dvb_bt8xx_878_match(unsigned int bttv_nr, struct pci_dev* bttv_pci_dev)
122{
123 unsigned int card_nr;
124
125 /* Hmm, n squared. Hope n is small */
126 for (card_nr = 0; card_nr < bt878_num; card_nr++)
127 if (is_pci_slot_eq(bt878[card_nr].dev, bttv_pci_dev))
128 return &bt878[card_nr];
129 return NULL;
130}
131
132static int thomson_dtt7579_demod_init(struct dvb_frontend* fe)
133{
134 static u8 mt352_clock_config [] = { 0x89, 0x38, 0x38 };
135 static u8 mt352_reset [] = { 0x50, 0x80 };
136 static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 };
137 static u8 mt352_agc_cfg [] = { 0x67, 0x28, 0x20 };
138 static u8 mt352_gpp_ctl_cfg [] = { 0x8C, 0x33 };
139 static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };
140
141 mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
142 udelay(2000);
143 mt352_write(fe, mt352_reset, sizeof(mt352_reset));
144 mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
145
146 mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg));
147 mt352_write(fe, mt352_gpp_ctl_cfg, sizeof(mt352_gpp_ctl_cfg));
148 mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
149
150 return 0;
151}
152
153static int thomson_dtt7579_tuner_calc_regs(struct dvb_frontend *fe, u8* pllbuf, int buf_len)
154{
155 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
156 u32 div;
157 unsigned char bs = 0;
158 unsigned char cp = 0;
159
160 if (buf_len < 5)
161 return -EINVAL;
162
163 div = (((c->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
164
165 if (c->frequency < 542000000)
166 cp = 0xb4;
167 else if (c->frequency < 771000000)
168 cp = 0xbc;
169 else
170 cp = 0xf4;
171
172 if (c->frequency == 0)
173 bs = 0x03;
174 else if (c->frequency < 443250000)
175 bs = 0x02;
176 else
177 bs = 0x08;
178
179 pllbuf[0] = 0x60;
180 pllbuf[1] = div >> 8;
181 pllbuf[2] = div & 0xff;
182 pllbuf[3] = cp;
183 pllbuf[4] = bs;
184
185 return 5;
186}
187
188static struct mt352_config thomson_dtt7579_config = {
189 .demod_address = 0x0f,
190 .demod_init = thomson_dtt7579_demod_init,
191};
192
193static struct zl10353_config thomson_dtt7579_zl10353_config = {
194 .demod_address = 0x0f,
195};
196
197static int cx24108_tuner_set_params(struct dvb_frontend *fe)
198{
199 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
200 u32 freq = c->frequency;
201 int i, a, n, pump;
202 u32 band, pll;
203 u32 osci[]={950000,1019000,1075000,1178000,1296000,1432000,
204 1576000,1718000,1856000,2036000,2150000};
205 u32 bandsel[]={0,0x00020000,0x00040000,0x00100800,0x00101000,
206 0x00102000,0x00104000,0x00108000,0x00110000,
207 0x00120000,0x00140000};
208
209 #define XTAL 1011100 /* Hz, really 1.0111 MHz and a /10 prescaler */
210 dprintk("cx24108 debug: entering SetTunerFreq, freq=%d\n", freq);
211
212 /* This is really the bit driving the tuner chip cx24108 */
213
214 if (freq<950000)
215 freq = 950000; /* kHz */
216 else if (freq>2150000)
217 freq = 2150000; /* satellite IF is 950..2150MHz */
218
219 /* decide which VCO to use for the input frequency */
220 for(i = 1; (i < ARRAY_SIZE(osci) - 1) && (osci[i] < freq); i++);
221 dprintk("cx24108 debug: select vco #%d (f=%d)\n", i, freq);
222 band=bandsel[i];
223 /* the gain values must be set by SetSymbolrate */
224 /* compute the pll divider needed, from Conexant data sheet,
225 resolved for (n*32+a), remember f(vco) is f(receive) *2 or *4,
226 depending on the divider bit. It is set to /4 on the 2 lowest
227 bands */
228 n=((i<=2?2:1)*freq*10L)/(XTAL/100);
229 a=n%32; n/=32; if(a==0) n--;
230 pump=(freq<(osci[i-1]+osci[i])/2);
231 pll=0xf8000000|
232 ((pump?1:2)<<(14+11))|
233 ((n&0x1ff)<<(5+11))|
234 ((a&0x1f)<<11);
235 /* everything is shifted left 11 bits to left-align the bits in the
236 32bit word. Output to the tuner goes MSB-aligned, after all */
237 dprintk("cx24108 debug: pump=%d, n=%d, a=%d\n", pump, n, a);
238 cx24110_pll_write(fe,band);
239 /* set vga and vca to their widest-band settings, as a precaution.
240 SetSymbolrate might not be called to set this up */
241 cx24110_pll_write(fe,0x500c0000);
242 cx24110_pll_write(fe,0x83f1f800);
243 cx24110_pll_write(fe,pll);
244 //writereg(client,0x56,0x7f);
245
246 return 0;
247}
248
249static int pinnsat_tuner_init(struct dvb_frontend* fe)
250{
251 struct dvb_bt8xx_card *card = fe->dvb->priv;
252
253 bttv_gpio_enable(card->bttv_nr, 1, 1); /* output */
254 bttv_write_gpio(card->bttv_nr, 1, 1); /* relay on */
255
256 return 0;
257}
258
259static int pinnsat_tuner_sleep(struct dvb_frontend* fe)
260{
261 struct dvb_bt8xx_card *card = fe->dvb->priv;
262
263 bttv_write_gpio(card->bttv_nr, 1, 0); /* relay off */
264
265 return 0;
266}
267
268static struct cx24110_config pctvsat_config = {
269 .demod_address = 0x55,
270};
271
272static int microtune_mt7202dtf_tuner_set_params(struct dvb_frontend *fe)
273{
274 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
275 struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv;
276 u8 cfg, cpump, band_select;
277 u8 data[4];
278 u32 div;
279 struct i2c_msg msg = { .addr = 0x60, .flags = 0, .buf = data, .len = sizeof(data) };
280
281 div = (36000000 + c->frequency + 83333) / 166666;
282 cfg = 0x88;
283
284 if (c->frequency < 175000000)
285 cpump = 2;
286 else if (c->frequency < 390000000)
287 cpump = 1;
288 else if (c->frequency < 470000000)
289 cpump = 2;
290 else if (c->frequency < 750000000)
291 cpump = 2;
292 else
293 cpump = 3;
294
295 if (c->frequency < 175000000)
296 band_select = 0x0e;
297 else if (c->frequency < 470000000)
298 band_select = 0x05;
299 else
300 band_select = 0x03;
301
302 data[0] = (div >> 8) & 0x7f;
303 data[1] = div & 0xff;
304 data[2] = ((div >> 10) & 0x60) | cfg;
305 data[3] = (cpump << 6) | band_select;
306
307 if (fe->ops.i2c_gate_ctrl)
308 fe->ops.i2c_gate_ctrl(fe, 1);
309 i2c_transfer(card->i2c_adapter, &msg, 1);
310 return (div * 166666 - 36000000);
311}
312
313static int microtune_mt7202dtf_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
314{
315 struct dvb_bt8xx_card* bt = (struct dvb_bt8xx_card*) fe->dvb->priv;
316
317 return request_firmware(fw, name, &bt->bt->dev->dev);
318}
319
320static struct sp887x_config microtune_mt7202dtf_config = {
321 .demod_address = 0x70,
322 .request_firmware = microtune_mt7202dtf_request_firmware,
323};
324
325static int advbt771_samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe)
326{
327 static u8 mt352_clock_config [] = { 0x89, 0x38, 0x2d };
328 static u8 mt352_reset [] = { 0x50, 0x80 };
329 static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 };
330 static u8 mt352_agc_cfg [] = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF,
331 0x00, 0xFF, 0x00, 0x40, 0x40 };
332 static u8 mt352_av771_extra[] = { 0xB5, 0x7A };
333 static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };
334
335 mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
336 udelay(2000);
337 mt352_write(fe, mt352_reset, sizeof(mt352_reset));
338 mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
339
340 mt352_write(fe, mt352_agc_cfg,sizeof(mt352_agc_cfg));
341 udelay(2000);
342 mt352_write(fe, mt352_av771_extra,sizeof(mt352_av771_extra));
343 mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
344
345 return 0;
346}
347
348static int advbt771_samsung_tdtc9251dh0_tuner_calc_regs(struct dvb_frontend *fe, u8 *pllbuf, int buf_len)
349{
350 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
351 u32 div;
352 unsigned char bs = 0;
353 unsigned char cp = 0;
354
355 if (buf_len < 5) return -EINVAL;
356
357 div = (((c->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
358
359 if (c->frequency < 150000000)
360 cp = 0xB4;
361 else if (c->frequency < 173000000)
362 cp = 0xBC;
363 else if (c->frequency < 250000000)
364 cp = 0xB4;
365 else if (c->frequency < 400000000)
366 cp = 0xBC;
367 else if (c->frequency < 420000000)
368 cp = 0xF4;
369 else if (c->frequency < 470000000)
370 cp = 0xFC;
371 else if (c->frequency < 600000000)
372 cp = 0xBC;
373 else if (c->frequency < 730000000)
374 cp = 0xF4;
375 else
376 cp = 0xFC;
377
378 if (c->frequency < 150000000)
379 bs = 0x01;
380 else if (c->frequency < 173000000)
381 bs = 0x01;
382 else if (c->frequency < 250000000)
383 bs = 0x02;
384 else if (c->frequency < 400000000)
385 bs = 0x02;
386 else if (c->frequency < 420000000)
387 bs = 0x02;
388 else if (c->frequency < 470000000)
389 bs = 0x02;
390 else if (c->frequency < 600000000)
391 bs = 0x08;
392 else if (c->frequency < 730000000)
393 bs = 0x08;
394 else
395 bs = 0x08;
396
397 pllbuf[0] = 0x61;
398 pllbuf[1] = div >> 8;
399 pllbuf[2] = div & 0xff;
400 pllbuf[3] = cp;
401 pllbuf[4] = bs;
402
403 return 5;
404}
405
406static struct mt352_config advbt771_samsung_tdtc9251dh0_config = {
407 .demod_address = 0x0f,
408 .demod_init = advbt771_samsung_tdtc9251dh0_demod_init,
409};
410
411static struct dst_config dst_config = {
412 .demod_address = 0x55,
413};
414
415static int or51211_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
416{
417 struct dvb_bt8xx_card* bt = (struct dvb_bt8xx_card*) fe->dvb->priv;
418
419 return request_firmware(fw, name, &bt->bt->dev->dev);
420}
421
422static void or51211_setmode(struct dvb_frontend * fe, int mode)
423{
424 struct dvb_bt8xx_card *bt = fe->dvb->priv;
425 bttv_write_gpio(bt->bttv_nr, 0x0002, mode); /* Reset */
426 msleep(20);
427}
428
429static void or51211_reset(struct dvb_frontend * fe)
430{
431 struct dvb_bt8xx_card *bt = fe->dvb->priv;
432
433 /* RESET DEVICE
434 * reset is controlled by GPIO-0
435 * when set to 0 causes reset and when to 1 for normal op
436 * must remain reset for 128 clock cycles on a 50Mhz clock
437 * also PRM1 PRM2 & PRM4 are controlled by GPIO-1,GPIO-2 & GPIO-4
438 * We assume that the reset has be held low long enough or we
439 * have been reset by a power on. When the driver is unloaded
440 * reset set to 0 so if reloaded we have been reset.
441 */
442 /* reset & PRM1,2&4 are outputs */
443 int ret = bttv_gpio_enable(bt->bttv_nr, 0x001F, 0x001F);
444 if (ret != 0)
445 printk(KERN_WARNING "or51211: Init Error - Can't Reset DVR (%i)\n", ret);
446 bttv_write_gpio(bt->bttv_nr, 0x001F, 0x0000); /* Reset */
447 msleep(20);
448 /* Now set for normal operation */
449 bttv_write_gpio(bt->bttv_nr, 0x0001F, 0x0001);
450 /* wait for operation to begin */
451 msleep(500);
452}
453
454static void or51211_sleep(struct dvb_frontend * fe)
455{
456 struct dvb_bt8xx_card *bt = fe->dvb->priv;
457 bttv_write_gpio(bt->bttv_nr, 0x0001, 0x0000);
458}
459
460static struct or51211_config or51211_config = {
461 .demod_address = 0x15,
462 .request_firmware = or51211_request_firmware,
463 .setmode = or51211_setmode,
464 .reset = or51211_reset,
465 .sleep = or51211_sleep,
466};
467
468static int vp3021_alps_tded4_tuner_set_params(struct dvb_frontend *fe)
469{
470 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
471 struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv;
472 u8 buf[4];
473 u32 div;
474 struct i2c_msg msg = { .addr = 0x60, .flags = 0, .buf = buf, .len = sizeof(buf) };
475
476 div = (c->frequency + 36166667) / 166667;
477
478 buf[0] = (div >> 8) & 0x7F;
479 buf[1] = div & 0xFF;
480 buf[2] = 0x85;
481 if ((c->frequency >= 47000000) && (c->frequency < 153000000))
482 buf[3] = 0x01;
483 else if ((c->frequency >= 153000000) && (c->frequency < 430000000))
484 buf[3] = 0x02;
485 else if ((c->frequency >= 430000000) && (c->frequency < 824000000))
486 buf[3] = 0x0C;
487 else if ((c->frequency >= 824000000) && (c->frequency < 863000000))
488 buf[3] = 0x8C;
489 else
490 return -EINVAL;
491
492 if (fe->ops.i2c_gate_ctrl)
493 fe->ops.i2c_gate_ctrl(fe, 1);
494 i2c_transfer(card->i2c_adapter, &msg, 1);
495 return 0;
496}
497
498static struct nxt6000_config vp3021_alps_tded4_config = {
499 .demod_address = 0x0a,
500 .clock_inversion = 1,
501};
502
503static int digitv_alps_tded4_demod_init(struct dvb_frontend* fe)
504{
505 static u8 mt352_clock_config [] = { 0x89, 0x38, 0x2d };
506 static u8 mt352_reset [] = { 0x50, 0x80 };
507 static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 };
508 static u8 mt352_agc_cfg [] = { 0x67, 0x20, 0xa0 };
509 static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };
510
511 mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
512 udelay(2000);
513 mt352_write(fe, mt352_reset, sizeof(mt352_reset));
514 mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
515 mt352_write(fe, mt352_agc_cfg,sizeof(mt352_agc_cfg));
516 mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
517
518 return 0;
519}
520
521static int digitv_alps_tded4_tuner_calc_regs(struct dvb_frontend *fe, u8 *pllbuf, int buf_len)
522{
523 u32 div;
524 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
525
526 if (buf_len < 5)
527 return -EINVAL;
528
529 div = (((c->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
530
531 pllbuf[0] = 0x61;
532 pllbuf[1] = (div >> 8) & 0x7F;
533 pllbuf[2] = div & 0xFF;
534 pllbuf[3] = 0x85;
535
536 dprintk("frequency %u, div %u\n", c->frequency, div);
537
538 if (c->frequency < 470000000)
539 pllbuf[4] = 0x02;
540 else if (c->frequency > 823000000)
541 pllbuf[4] = 0x88;
542 else
543 pllbuf[4] = 0x08;
544
545 if (c->bandwidth_hz == 8000000)
546 pllbuf[4] |= 0x04;
547
548 return 5;
549}
550
551static void digitv_alps_tded4_reset(struct dvb_bt8xx_card *bt)
552{
553 /*
554 * Reset the frontend, must be called before trying
555 * to initialise the MT352 or mt352_attach
556 * will fail. Same goes for the nxt6000 frontend.
557 *
558 */
559
560 int ret = bttv_gpio_enable(bt->bttv_nr, 0x08, 0x08);
561 if (ret != 0)
562 printk(KERN_WARNING "digitv_alps_tded4: Init Error - Can't Reset DVR (%i)\n", ret);
563
564 /* Pulse the reset line */
565 bttv_write_gpio(bt->bttv_nr, 0x08, 0x08); /* High */
566 bttv_write_gpio(bt->bttv_nr, 0x08, 0x00); /* Low */
567 msleep(100);
568
569 bttv_write_gpio(bt->bttv_nr, 0x08, 0x08); /* High */
570}
571
572static struct mt352_config digitv_alps_tded4_config = {
573 .demod_address = 0x0a,
574 .demod_init = digitv_alps_tded4_demod_init,
575};
576
577static struct lgdt330x_config tdvs_tua6034_config = {
578 .demod_address = 0x0e,
579 .demod_chip = LGDT3303,
580 .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */
581};
582
583static void lgdt330x_reset(struct dvb_bt8xx_card *bt)
584{
585 /* Set pin 27 of the lgdt3303 chip high to reset the frontend */
586
587 /* Pulse the reset line */
588 bttv_write_gpio(bt->bttv_nr, 0x00e00007, 0x00000001); /* High */
589 bttv_write_gpio(bt->bttv_nr, 0x00e00007, 0x00000000); /* Low */
590 msleep(100);
591
592 bttv_write_gpio(bt->bttv_nr, 0x00e00007, 0x00000001); /* High */
593 msleep(100);
594}
595
596static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
597{
598 struct dst_state* state = NULL;
599
600 switch(type) {
601 case BTTV_BOARD_DVICO_DVBT_LITE:
602 card->fe = dvb_attach(mt352_attach, &thomson_dtt7579_config, card->i2c_adapter);
603
604 if (card->fe == NULL)
605 card->fe = dvb_attach(zl10353_attach, &thomson_dtt7579_zl10353_config,
606 card->i2c_adapter);
607
608 if (card->fe != NULL) {
609 card->fe->ops.tuner_ops.calc_regs = thomson_dtt7579_tuner_calc_regs;
610 card->fe->ops.info.frequency_min = 174000000;
611 card->fe->ops.info.frequency_max = 862000000;
612 }
613 break;
614
615 case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE:
616 lgdt330x_reset(card);
617 card->fe = dvb_attach(lgdt330x_attach, &tdvs_tua6034_config, card->i2c_adapter);
618 if (card->fe != NULL) {
619 dvb_attach(simple_tuner_attach, card->fe,
620 card->i2c_adapter, 0x61,
621 TUNER_LG_TDVS_H06XF);
622 dprintk ("dvb_bt8xx: lgdt330x detected\n");
623 }
624 break;
625
626 case BTTV_BOARD_NEBULA_DIGITV:
627 /*
628 * It is possible to determine the correct frontend using the I2C bus (see the Nebula SDK);
629 * this would be a cleaner solution than trying each frontend in turn.
630 */
631
632 /* Old Nebula (marked (c)2003 on high profile pci card) has nxt6000 demod */
633 digitv_alps_tded4_reset(card);
634 card->fe = dvb_attach(nxt6000_attach, &vp3021_alps_tded4_config, card->i2c_adapter);
635 if (card->fe != NULL) {
636 card->fe->ops.tuner_ops.set_params = vp3021_alps_tded4_tuner_set_params;
637 dprintk ("dvb_bt8xx: an nxt6000 was detected on your digitv card\n");
638 break;
639 }
640
641 /* New Nebula (marked (c)2005 on low profile pci card) has mt352 demod */
642 digitv_alps_tded4_reset(card);
643 card->fe = dvb_attach(mt352_attach, &digitv_alps_tded4_config, card->i2c_adapter);
644
645 if (card->fe != NULL) {
646 card->fe->ops.tuner_ops.calc_regs = digitv_alps_tded4_tuner_calc_regs;
647 dprintk ("dvb_bt8xx: an mt352 was detected on your digitv card\n");
648 }
649 break;
650
651 case BTTV_BOARD_AVDVBT_761:
652 card->fe = dvb_attach(sp887x_attach, &microtune_mt7202dtf_config, card->i2c_adapter);
653 if (card->fe) {
654 card->fe->ops.tuner_ops.set_params = microtune_mt7202dtf_tuner_set_params;
655 }
656 break;
657
658 case BTTV_BOARD_AVDVBT_771:
659 card->fe = dvb_attach(mt352_attach, &advbt771_samsung_tdtc9251dh0_config, card->i2c_adapter);
660 if (card->fe != NULL) {
661 card->fe->ops.tuner_ops.calc_regs = advbt771_samsung_tdtc9251dh0_tuner_calc_regs;
662 card->fe->ops.info.frequency_min = 174000000;
663 card->fe->ops.info.frequency_max = 862000000;
664 }
665 break;
666
667 case BTTV_BOARD_TWINHAN_DST:
668 /* DST is not a frontend driver !!! */
669 state = kmalloc(sizeof (struct dst_state), GFP_KERNEL);
670 if (!state) {
671 pr_err("No memory\n");
672 break;
673 }
674 /* Setup the Card */
675 state->config = &dst_config;
676 state->i2c = card->i2c_adapter;
677 state->bt = card->bt;
678 state->dst_ca = NULL;
679 /* DST is not a frontend, attaching the ASIC */
680 if (dvb_attach(dst_attach, state, &card->dvb_adapter) == NULL) {
681 pr_err("%s: Could not find a Twinhan DST\n", __func__);
682 break;
683 }
684 /* Attach other DST peripherals if any */
685 /* Conditional Access device */
686 card->fe = &state->frontend;
687 if (state->dst_hw_cap & DST_TYPE_HAS_CA)
688 dvb_attach(dst_ca_attach, state, &card->dvb_adapter);
689 break;
690
691 case BTTV_BOARD_PINNACLESAT:
692 card->fe = dvb_attach(cx24110_attach, &pctvsat_config, card->i2c_adapter);
693 if (card->fe) {
694 card->fe->ops.tuner_ops.init = pinnsat_tuner_init;
695 card->fe->ops.tuner_ops.sleep = pinnsat_tuner_sleep;
696 card->fe->ops.tuner_ops.set_params = cx24108_tuner_set_params;
697 }
698 break;
699
700 case BTTV_BOARD_PC_HDTV:
701 card->fe = dvb_attach(or51211_attach, &or51211_config, card->i2c_adapter);
702 if (card->fe != NULL)
703 dvb_attach(simple_tuner_attach, card->fe,
704 card->i2c_adapter, 0x61,
705 TUNER_PHILIPS_FCV1236D);
706 break;
707 }
708
709 if (card->fe == NULL)
710 pr_err("A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n",
711 card->bt->dev->vendor,
712 card->bt->dev->device,
713 card->bt->dev->subsystem_vendor,
714 card->bt->dev->subsystem_device);
715 else
716 if (dvb_register_frontend(&card->dvb_adapter, card->fe)) {
717 pr_err("Frontend registration failed!\n");
718 dvb_frontend_detach(card->fe);
719 card->fe = NULL;
720 }
721}
722
723static int __devinit dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type)
724{
725 int result;
726
727 result = dvb_register_adapter(&card->dvb_adapter, card->card_name,
728 THIS_MODULE, &card->bt->dev->dev,
729 adapter_nr);
730 if (result < 0) {
731 pr_err("dvb_register_adapter failed (errno = %d)\n", result);
732 return result;
733 }
734 card->dvb_adapter.priv = card;
735
736 card->bt->adapter = card->i2c_adapter;
737
738 memset(&card->demux, 0, sizeof(struct dvb_demux));
739
740 card->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING;
741
742 card->demux.priv = card;
743 card->demux.filternum = 256;
744 card->demux.feednum = 256;
745 card->demux.start_feed = dvb_bt8xx_start_feed;
746 card->demux.stop_feed = dvb_bt8xx_stop_feed;
747 card->demux.write_to_decoder = NULL;
748
749 result = dvb_dmx_init(&card->demux);
750 if (result < 0) {
751 pr_err("dvb_dmx_init failed (errno = %d)\n", result);
752 goto err_unregister_adaptor;
753 }
754
755 card->dmxdev.filternum = 256;
756 card->dmxdev.demux = &card->demux.dmx;
757 card->dmxdev.capabilities = 0;
758
759 result = dvb_dmxdev_init(&card->dmxdev, &card->dvb_adapter);
760 if (result < 0) {
761 pr_err("dvb_dmxdev_init failed (errno = %d)\n", result);
762 goto err_dmx_release;
763 }
764
765 card->fe_hw.source = DMX_FRONTEND_0;
766
767 result = card->demux.dmx.add_frontend(&card->demux.dmx, &card->fe_hw);
768 if (result < 0) {
769 pr_err("dvb_dmx_init failed (errno = %d)\n", result);
770 goto err_dmxdev_release;
771 }
772
773 card->fe_mem.source = DMX_MEMORY_FE;
774
775 result = card->demux.dmx.add_frontend(&card->demux.dmx, &card->fe_mem);
776 if (result < 0) {
777 pr_err("dvb_dmx_init failed (errno = %d)\n", result);
778 goto err_remove_hw_frontend;
779 }
780
781 result = card->demux.dmx.connect_frontend(&card->demux.dmx, &card->fe_hw);
782 if (result < 0) {
783 pr_err("dvb_dmx_init failed (errno = %d)\n", result);
784 goto err_remove_mem_frontend;
785 }
786
787 result = dvb_net_init(&card->dvb_adapter, &card->dvbnet, &card->demux.dmx);
788 if (result < 0) {
789 pr_err("dvb_net_init failed (errno = %d)\n", result);
790 goto err_disconnect_frontend;
791 }
792
793 tasklet_init(&card->bt->tasklet, dvb_bt8xx_task, (unsigned long) card);
794
795 frontend_init(card, type);
796
797 return 0;
798
799err_disconnect_frontend:
800 card->demux.dmx.disconnect_frontend(&card->demux.dmx);
801err_remove_mem_frontend:
802 card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_mem);
803err_remove_hw_frontend:
804 card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw);
805err_dmxdev_release:
806 dvb_dmxdev_release(&card->dmxdev);
807err_dmx_release:
808 dvb_dmx_release(&card->demux);
809err_unregister_adaptor:
810 dvb_unregister_adapter(&card->dvb_adapter);
811 return result;
812}
813
814static int __devinit dvb_bt8xx_probe(struct bttv_sub_device *sub)
815{
816 struct dvb_bt8xx_card *card;
817 struct pci_dev* bttv_pci_dev;
818 int ret;
819
820 if (!(card = kzalloc(sizeof(struct dvb_bt8xx_card), GFP_KERNEL)))
821 return -ENOMEM;
822
823 mutex_init(&card->lock);
824 card->bttv_nr = sub->core->nr;
825 strlcpy(card->card_name, sub->core->v4l2_dev.name, sizeof(card->card_name));
826 card->i2c_adapter = &sub->core->i2c_adap;
827
828 switch(sub->core->type) {
829 case BTTV_BOARD_PINNACLESAT:
830 card->gpio_mode = 0x0400c060;
831 /* should be: BT878_A_GAIN=0,BT878_A_PWRDN,BT878_DA_DPM,BT878_DA_SBR,
832 BT878_DA_IOM=1,BT878_DA_APP to enable serial highspeed mode. */
833 card->op_sync_orin = BT878_RISC_SYNC_MASK;
834 card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR;
835 break;
836
837 case BTTV_BOARD_DVICO_DVBT_LITE:
838 card->gpio_mode = 0x0400C060;
839 card->op_sync_orin = BT878_RISC_SYNC_MASK;
840 card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR;
841 /* 26, 15, 14, 6, 5
842 * A_PWRDN DA_DPM DA_SBR DA_IOM_DA
843 * DA_APP(parallel) */
844 break;
845
846 case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE:
847 card->gpio_mode = 0x0400c060;
848 card->op_sync_orin = BT878_RISC_SYNC_MASK;
849 card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR;
850 break;
851
852 case BTTV_BOARD_NEBULA_DIGITV:
853 case BTTV_BOARD_AVDVBT_761:
854 card->gpio_mode = (1 << 26) | (1 << 14) | (1 << 5);
855 card->op_sync_orin = BT878_RISC_SYNC_MASK;
856 card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR;
857 /* A_PWRDN DA_SBR DA_APP (high speed serial) */
858 break;
859
860 case BTTV_BOARD_AVDVBT_771: //case 0x07711461:
861 card->gpio_mode = 0x0400402B;
862 card->op_sync_orin = BT878_RISC_SYNC_MASK;
863 card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR;
864 /* A_PWRDN DA_SBR DA_APP[0] PKTP=10 RISC_ENABLE FIFO_ENABLE*/
865 break;
866
867 case BTTV_BOARD_TWINHAN_DST:
868 card->gpio_mode = 0x2204f2c;
869 card->op_sync_orin = BT878_RISC_SYNC_MASK;
870 card->irq_err_ignore = BT878_APABORT | BT878_ARIPERR |
871 BT878_APPERR | BT878_AFBUS;
872 /* 25,21,14,11,10,9,8,3,2 then
873 * 0x33 = 5,4,1,0
874 * A_SEL=SML, DA_MLB, DA_SBR,
875 * DA_SDR=f, fifo trigger = 32 DWORDS
876 * IOM = 0 == audio A/D
877 * DPM = 0 == digital audio mode
878 * == async data parallel port
879 * then 0x33 (13 is set by start_capture)
880 * DA_APP = async data parallel port,
881 * ACAP_EN = 1,
882 * RISC+FIFO ENABLE */
883 break;
884
885 case BTTV_BOARD_PC_HDTV:
886 card->gpio_mode = 0x0100EC7B;
887 card->op_sync_orin = BT878_RISC_SYNC_MASK;
888 card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR;
889 break;
890
891 default:
892 pr_err("Unknown bttv card type: %d\n", sub->core->type);
893 kfree(card);
894 return -ENODEV;
895 }
896
897 dprintk("dvb_bt8xx: identified card%d as %s\n", card->bttv_nr, card->card_name);
898
899 if (!(bttv_pci_dev = bttv_get_pcidev(card->bttv_nr))) {
900 pr_err("no pci device for card %d\n", card->bttv_nr);
901 kfree(card);
902 return -ENODEV;
903 }
904
905 if (!(card->bt = dvb_bt8xx_878_match(card->bttv_nr, bttv_pci_dev))) {
906 pr_err("unable to determine DMA core of card %d,\n", card->bttv_nr);
907 pr_err("if you have the ALSA bt87x audio driver installed, try removing it.\n");
908
909 kfree(card);
910 return -ENODEV;
911 }
912
913 mutex_init(&card->bt->gpio_lock);
914 card->bt->bttv_nr = sub->core->nr;
915
916 if ( (ret = dvb_bt8xx_load_card(card, sub->core->type)) ) {
917 kfree(card);
918 return ret;
919 }
920
921 dev_set_drvdata(&sub->dev, card);
922 return 0;
923}
924
925static void dvb_bt8xx_remove(struct bttv_sub_device *sub)
926{
927 struct dvb_bt8xx_card *card = dev_get_drvdata(&sub->dev);
928
929 dprintk("dvb_bt8xx: unloading card%d\n", card->bttv_nr);
930
931 bt878_stop(card->bt);
932 tasklet_kill(&card->bt->tasklet);
933 dvb_net_release(&card->dvbnet);
934 card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_mem);
935 card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw);
936 dvb_dmxdev_release(&card->dmxdev);
937 dvb_dmx_release(&card->demux);
938 if (card->fe) {
939 dvb_unregister_frontend(card->fe);
940 dvb_frontend_detach(card->fe);
941 }
942 dvb_unregister_adapter(&card->dvb_adapter);
943
944 kfree(card);
945}
946
947static struct bttv_sub_driver driver = {
948 .drv = {
949 .name = "dvb-bt8xx",
950 },
951 .probe = dvb_bt8xx_probe,
952 .remove = dvb_bt8xx_remove,
953 /* FIXME:
954 * .shutdown = dvb_bt8xx_shutdown,
955 * .suspend = dvb_bt8xx_suspend,
956 * .resume = dvb_bt8xx_resume,
957 */
958};
959
960static int __init dvb_bt8xx_init(void)
961{
962 return bttv_sub_register(&driver, "dvb");
963}
964
965static void __exit dvb_bt8xx_exit(void)
966{
967 bttv_sub_unregister(&driver);
968}
969
970module_init(dvb_bt8xx_init);
971module_exit(dvb_bt8xx_exit);
972
973MODULE_DESCRIPTION("Bt8xx based DVB adapter driver");
974MODULE_AUTHOR("Florian Schirmer <jolt@tuxbox.org>");
975MODULE_LICENSE("GPL");
diff --git a/drivers/media/pci/bt8xx/dvb-bt8xx.h b/drivers/media/pci/bt8xx/dvb-bt8xx.h
new file mode 100644
index 000000000000..4499ed2ac0ed
--- /dev/null
+++ b/drivers/media/pci/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 */