2 * Bt8xx based DVB adapter driver
4 * Copyright (C) 2002,2003 Florian Schirmer <jolt@tuxbox.org>
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.
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.
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.
22 #include <asm/bitops.h>
23 #include <linux/module.h>
24 #include <linux/init.h>
25 #include <linux/delay.h>
26 #include <linux/slab.h>
27 #include <linux/i2c.h>
31 #include "dvb_demux.h"
32 #include "dvb_frontend.h"
34 #include "dvb-bt8xx.h"
36 #include "dvb_functions.h"
40 /* ID THAT MUST GO INTO i2c ids */
41 #ifndef I2C_DRIVERID_DVB_BT878A
42 # define I2C_DRIVERID_DVB_BT878A I2C_DRIVERID_EXP0+10
46 #define dprintk if (debug) printk
48 extern int bttv_get_cardinfo(unsigned int card, int *type, int *cardid);
49 extern struct pci_dev* bttv_get_pcidev(unsigned int card);
51 static LIST_HEAD(card_list);
54 static void dvb_bt8xx_task(unsigned long data)
56 struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *)data;
58 //printk("%d ", finished_block);
60 while (card->bt->last_block != card->bt->finished_block) {
61 (card->bt->TS_Size ? dvb_dmx_swfilter_204 : dvb_dmx_swfilter)(&card->demux, &card->bt->buf_cpu[card->bt->last_block * card->bt->block_bytes], card->bt->block_bytes);
62 card->bt->last_block = (card->bt->last_block + 1) % card->bt->block_count;
66 static int dvb_bt8xx_start_feed(struct dvb_demux_feed *dvbdmxfeed)
68 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
69 struct dvb_bt8xx_card *card = dvbdmx->priv;
71 dprintk("dvb_bt8xx: start_feed\n");
73 if (!dvbdmx->dmx.frontend)
81 // bt878_start(card->bt, card->gpio_mode);
86 static int dvb_bt8xx_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
88 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
89 struct dvb_bt8xx_card *card = dvbdmx->priv;
91 dprintk("dvb_bt8xx: stop_feed\n");
93 if (!dvbdmx->dmx.frontend)
99 // bt878_stop(card->bt);
106 static int master_xfer (struct dvb_i2c_bus *i2c, const struct i2c_msg msgs[], int num)
108 struct dvb_bt8xx_card *card = i2c->data;
111 if (down_interruptible (&card->bt->gpio_lock))
114 retval = i2c_transfer(card->i2c_adapter,
115 (struct i2c_msg*) msgs,
118 up(&card->bt->gpio_lock);
123 static int is_pci_slot_eq(struct pci_dev* adev, struct pci_dev* bdev)
125 if ((adev->subsystem_vendor == bdev->subsystem_vendor) &&
126 (adev->subsystem_device == bdev->subsystem_device) &&
127 (adev->bus->number == bdev->bus->number) &&
128 (PCI_SLOT(adev->devfn) == PCI_SLOT(bdev->devfn)))
133 static struct bt878 __init *dvb_bt8xx_878_match(unsigned int bttv_nr, struct pci_dev* bttv_pci_dev)
135 unsigned int card_nr;
137 /* Hmm, n squared. Hope n is small */
138 for (card_nr = 0; card_nr < bt878_num; card_nr++) {
139 if (is_pci_slot_eq(bt878[card_nr].dev, bttv_pci_dev))
140 return &bt878[card_nr];
145 static int __init dvb_bt8xx_card_match(unsigned int bttv_nr, char *card_name, u32 gpio_mode, u32 op_sync_orin, u32 irq_err_ignore)
147 struct dvb_bt8xx_card *card;
148 struct pci_dev* bttv_pci_dev;
150 dprintk("dvb_bt8xx: identified card%d as %s\n", bttv_nr, card_name);
152 if (!(card = kmalloc(sizeof(struct dvb_bt8xx_card), GFP_KERNEL)))
155 memset(card, 0, sizeof(*card));
156 card->bttv_nr = bttv_nr;
157 strncpy(card->card_name, card_name, sizeof(card_name) - 1);
159 if (!(bttv_pci_dev = bttv_get_pcidev(bttv_nr))) {
160 printk("dvb_bt8xx: no pci device for card %d\n", card->bttv_nr);
165 if (!(card->bt = dvb_bt8xx_878_match(card->bttv_nr, bttv_pci_dev))) {
166 printk("dvb_bt8xx: unable to determine DMA core of card %d\n", card->bttv_nr);
172 init_MUTEX(&card->bt->gpio_lock);
173 card->bt->bttv_nr = bttv_nr;
174 card->gpio_mode = gpio_mode;
175 card->op_sync_orin = op_sync_orin;
176 card->irq_err_ignore = irq_err_ignore;
177 list_add_tail(&card->list, &card_list);
182 static struct dvb_bt8xx_card *dvb_bt8xx_find_by_i2c_adap(struct i2c_adapter *adap)
184 struct dvb_bt8xx_card *card;
185 struct list_head *item;
187 printk("find by i2c adap: checking \"%s\"\n",adap->name);
188 list_for_each(item, &card_list) {
189 card = list_entry(item, struct dvb_bt8xx_card, list);
190 if (card->i2c_adapter == adap)
196 static struct dvb_bt8xx_card *dvb_bt8xx_find_by_pci(struct i2c_adapter *adap)
198 struct dvb_bt8xx_card *card;
199 struct list_head *item;
203 printk("find by pci: checking \"%s\"\n",adap->name);
204 dev = adap->dev.parent;
206 /* shoudn't happen with 2.6.0-test7 + newer */
207 printk("attach: Huh? i2c adapter not in sysfs tree?\n");
210 pci = to_pci_dev(dev);
211 list_for_each(item, &card_list) {
212 card = list_entry(item, struct dvb_bt8xx_card, list);
213 if (is_pci_slot_eq(pci, card->bt->dev)) {
220 static int dvb_bt8xx_attach(struct i2c_adapter *adap)
222 struct dvb_bt8xx_card *card;
224 printk("attach: checking \"%s\"\n",adap->name);
226 /* looking for bt878 cards ... */
227 if (adap->id != (I2C_ALGO_BIT | I2C_HW_B_BT848))
229 card = dvb_bt8xx_find_by_pci(adap);
232 card->i2c_adapter = adap;
233 printk("attach: \"%s\", to card %d\n",
234 adap->name, card->bttv_nr);
235 try_module_get(adap->owner);
240 static void dvb_bt8xx_i2c_adap_free(struct i2c_adapter *adap)
242 module_put(adap->owner);
245 static int dvb_bt8xx_detach(struct i2c_adapter *adap)
247 struct dvb_bt8xx_card *card;
249 card = dvb_bt8xx_find_by_i2c_adap(adap);
253 /* This should not happen. We have locked the module! */
254 printk("detach: \"%s\", for card %d removed\n",
255 adap->name, card->bttv_nr);
259 static struct i2c_driver dvb_bt8xx_driver = {
260 .owner = THIS_MODULE,
262 .id = I2C_DRIVERID_DVB_BT878A,
263 .flags = I2C_DF_NOTIFY,
264 .attach_adapter = dvb_bt8xx_attach,
265 .detach_adapter = dvb_bt8xx_detach,
268 static void __init dvb_bt8xx_get_adaps(void)
270 i2c_add_driver(&dvb_bt8xx_driver);
273 static void __exit dvb_bt8xx_exit_adaps(void)
275 i2c_del_driver(&dvb_bt8xx_driver);
278 static int __init dvb_bt8xx_load_card( struct dvb_bt8xx_card *card)
282 if (!card->i2c_adapter) {
283 printk("dvb_bt8xx: unable to determine i2c adaptor of card %d, deleting\n", card->bttv_nr);
289 if ((result = dvb_register_adapter(&card->dvb_adapter, card->card_name, THIS_MODULE)) < 0) {
291 printk("dvb_bt8xx: dvb_register_adapter failed (errno = %d)\n", result);
293 dvb_bt8xx_i2c_adap_free(card->i2c_adapter);
297 card->bt->adap_ptr = card->dvb_adapter;
299 if (!(dvb_register_i2c_bus(master_xfer, card, card->dvb_adapter, 0))) {
300 printk("dvb_bt8xx: dvb_register_i2c_bus of card%d failed\n", card->bttv_nr);
302 dvb_unregister_adapter(card->dvb_adapter);
303 dvb_bt8xx_i2c_adap_free(card->i2c_adapter);
308 memset(&card->demux, 0, sizeof(struct dvb_demux));
310 card->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING;
312 card->demux.priv = card;
313 card->demux.filternum = 256;
314 card->demux.feednum = 256;
315 card->demux.start_feed = dvb_bt8xx_start_feed;
316 card->demux.stop_feed = dvb_bt8xx_stop_feed;
317 card->demux.write_to_decoder = NULL;
319 if ((result = dvb_dmx_init(&card->demux)) < 0) {
320 printk("dvb_bt8xx: dvb_dmx_init failed (errno = %d)\n", result);
322 dvb_unregister_i2c_bus(master_xfer, card->dvb_adapter, 0);
323 dvb_unregister_adapter(card->dvb_adapter);
324 dvb_bt8xx_i2c_adap_free(card->i2c_adapter);
329 card->dmxdev.filternum = 256;
330 card->dmxdev.demux = &card->demux.dmx;
331 card->dmxdev.capabilities = 0;
333 if ((result = dvb_dmxdev_init(&card->dmxdev, card->dvb_adapter)) < 0) {
334 printk("dvb_bt8xx: dvb_dmxdev_init failed (errno = %d)\n", result);
336 dvb_dmx_release(&card->demux);
337 dvb_unregister_i2c_bus(master_xfer, card->dvb_adapter, 0);
338 dvb_unregister_adapter(card->dvb_adapter);
339 dvb_bt8xx_i2c_adap_free(card->i2c_adapter);
344 card->fe_hw.source = DMX_FRONTEND_0;
346 if ((result = card->demux.dmx.add_frontend(&card->demux.dmx, &card->fe_hw)) < 0) {
347 printk("dvb_bt8xx: dvb_dmx_init failed (errno = %d)\n", result);
349 dvb_dmxdev_release(&card->dmxdev);
350 dvb_dmx_release(&card->demux);
351 dvb_unregister_i2c_bus(master_xfer, card->dvb_adapter, 0);
352 dvb_unregister_adapter(card->dvb_adapter);
353 dvb_bt8xx_i2c_adap_free(card->i2c_adapter);
358 card->fe_mem.source = DMX_MEMORY_FE;
360 if ((result = card->demux.dmx.add_frontend(&card->demux.dmx, &card->fe_mem)) < 0) {
361 printk("dvb_bt8xx: dvb_dmx_init failed (errno = %d)\n", result);
363 card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw);
364 dvb_dmxdev_release(&card->dmxdev);
365 dvb_dmx_release(&card->demux);
366 dvb_unregister_i2c_bus(master_xfer, card->dvb_adapter, 0);
367 dvb_unregister_adapter(card->dvb_adapter);
368 dvb_bt8xx_i2c_adap_free(card->i2c_adapter);
373 if ((result = card->demux.dmx.connect_frontend(&card->demux.dmx, &card->fe_hw)) < 0) {
374 printk("dvb_bt8xx: dvb_dmx_init failed (errno = %d)\n", result);
376 card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_mem);
377 card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw);
378 dvb_dmxdev_release(&card->dmxdev);
379 dvb_dmx_release(&card->demux);
380 dvb_unregister_i2c_bus(master_xfer, card->dvb_adapter, 0);
381 dvb_unregister_adapter(card->dvb_adapter);
382 dvb_bt8xx_i2c_adap_free(card->i2c_adapter);
387 dvb_net_init(card->dvb_adapter, &card->dvbnet, &card->demux.dmx);
389 tasklet_init(&card->bt->tasklet, dvb_bt8xx_task, (unsigned long) card);
391 bt878_start(card->bt, card->gpio_mode, card->op_sync_orin, card->irq_err_ignore);
396 static int __init dvb_bt8xx_load_all(void)
398 struct dvb_bt8xx_card *card;
399 struct list_head *entry, *entry_safe;
401 list_for_each_safe(entry, entry_safe, &card_list) {
402 card = list_entry(entry, struct dvb_bt8xx_card, list);
403 if (dvb_bt8xx_load_card(card) < 0) {
404 list_del(&card->list);
413 #define BT878_NEBULA 0x68
414 #define BT878_TWINHAN_DST 0x71
416 static int __init dvb_bt8xx_init(void)
418 unsigned int card_nr = 0;
422 dprintk("dvb_bt8xx: enumerating available bttv cards...\n");
424 while (bttv_get_cardinfo(card_nr, &card_type, &card_id) == 0) {
427 dvb_bt8xx_card_match(card_nr, "Pinnacle PCTV DVB-S",
430 * A_G2X DA_DPM DA_SBR DA_IOM_DA
431 * DA_APP(parallel) */
435 dvb_bt8xx_card_match(card_nr, "Nebula DigiTV DVB-T",
436 (1 << 26) | (1 << 14) | (1 << 5),
438 /* A_PWRDN DA_SBR DA_APP (high speed serial) */
441 dvb_bt8xx_card_match(card_nr, "Avermedia DVB-T",
442 (1 << 26) | (1 << 14) | (1 << 5),
444 /* A_PWRDN DA_SBR DA_APP (high speed serial) */
447 if (card_type == BT878_NEBULA ||
448 card_type == BT878_TWINHAN_DST)
454 dvb_bt8xx_card_match(card_nr, "DST DVB-S", 0x2204f2c,
455 BT878_RISC_SYNC_MASK,
456 BT878_APABORT | BT878_ARIPERR | BT878_APPERR | BT878_AFBUS);
457 /* 25,21,14,11,10,9,8,3,2 then
459 * A_SEL=SML, DA_MLB, DA_SBR,
460 * DA_SDR=f, fifo trigger = 32 DWORDS
461 * IOM = 0 == audio A/D
462 * DPM = 0 == digital audio mode
463 * == async data parallel port
464 * then 0x33 (13 is set by start_capture)
465 * DA_APP = async data parallel port,
467 * RISC+FIFO ENABLE */
471 printk("%s: unknown card_id found %0X\n",
472 __FUNCTION__, card_id);
473 if (card_type == BT878_NEBULA) {
474 printk("%s: bttv type set to nebula\n",
478 if (card_type == BT878_TWINHAN_DST) {
479 printk("%s: bttv type set to Twinhan DST\n",
483 printk("%s: unknown card_type found %0X, NOT LOADED\n",
484 __FUNCTION__, card_type);
485 printk("%s: unknown card_nr found %0X\n",
486 __FUNCTION__, card_nr);
490 dvb_bt8xx_get_adaps();
491 dvb_bt8xx_load_all();
497 static void __exit dvb_bt8xx_exit(void)
499 struct dvb_bt8xx_card *card;
500 struct list_head *entry, *entry_safe;
502 dvb_bt8xx_exit_adaps();
503 list_for_each_safe(entry, entry_safe, &card_list) {
504 card = list_entry(entry, struct dvb_bt8xx_card, list);
506 dprintk("dvb_bt8xx: unloading card%d\n", card->bttv_nr);
508 bt878_stop(card->bt);
509 tasklet_kill(&card->bt->tasklet);
510 dvb_net_release(&card->dvbnet);
511 card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_mem);
512 card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw);
513 dvb_dmxdev_release(&card->dmxdev);
514 dvb_dmx_release(&card->demux);
515 dvb_unregister_i2c_bus(master_xfer, card->dvb_adapter, 0);
516 dvb_bt8xx_i2c_adap_free(card->i2c_adapter);
517 dvb_unregister_adapter(card->dvb_adapter);
519 list_del(&card->list);
525 module_init(dvb_bt8xx_init);
526 module_exit(dvb_bt8xx_exit);
527 MODULE_DESCRIPTION("Bt8xx based DVB adapter driver");
528 MODULE_AUTHOR("Florian Schirmer <jolt@tuxbox.org>");
529 MODULE_LICENSE("GPL");
530 MODULE_PARM(debug, "i");