diff options
Diffstat (limited to 'linux/drivers/media')
-rw-r--r-- | linux/drivers/media/dvb/av7110/Makefile | 7 | ||||
-rw-r--r-- | linux/drivers/media/dvb/av7110/av7110.c | 1082 | ||||
-rw-r--r-- | linux/drivers/media/dvb/av7110/av7110.h | 36 |
3 files changed, 464 insertions, 661 deletions
diff --git a/linux/drivers/media/dvb/av7110/Makefile b/linux/drivers/media/dvb/av7110/Makefile index 301a73216..809a68d3f 100644 --- a/linux/drivers/media/dvb/av7110/Makefile +++ b/linux/drivers/media/dvb/av7110/Makefile @@ -2,11 +2,8 @@ # Makefile for the kernel AV7110 DVB device driver # -dvb-ttpci-objs := saa7146_core.o saa7146_v4l.o av7110.o av7110_ir.o +dvb-ttpci-objs := av7110.o av7110_ir.o obj-$(CONFIG_DVB_AV7110) += dvb-ttpci.o -EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ - -include $(TOPDIR)/Rules.make - +EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -I$(src)/../../common/ -I$(src)/../../common/saa7146 diff --git a/linux/drivers/media/dvb/av7110/av7110.c b/linux/drivers/media/dvb/av7110/av7110.c index d42704a3f..edd80dcd7 100644 --- a/linux/drivers/media/dvb/av7110/av7110.c +++ b/linux/drivers/media/dvb/av7110/av7110.c @@ -73,12 +73,9 @@ #include "dvb_i2c.h" #include "dvb_frontend.h" -#include "compat.h" +// #include "compat.h" #include "av7110.h" -#include "saa7146_core.h" -#include "saa7146_v4l.h" -#include "saa7146_defs.h" static int AV_StartPlay(av7110_t *av7110, int av); @@ -92,9 +89,6 @@ static void SetMode(av7110_t *av7110, int mode); void pes_to_ts(u8 const *buf, long int length, u16 pid, p2t_t *p); void p_to_t(u8 const *buf, long int length, u16 pid, u8 *counter, struct dvb_demux_feed *feed); -static u32 vidmem = 0; -static u32 vidlow = 0; - static int av7110_debug = 0; #define dprintk if (av7110_debug) printk @@ -102,8 +96,7 @@ static int vidmode=CVBS_RGB_OUT; static int pids_off; static int adac=DVB_ADAC_TI; -#define saacomm(x,y) av7110->saa->command(av7110->saa->i2c_bus, (x), (y)) - +int av7110_num = 0; /**************************************************************************** * General helper functions @@ -120,19 +113,16 @@ static inline void ddelay(int i) * GPIO and DEBI functions ****************************************************************************/ -#define saaread(adr) saa7146_read(saamem,(adr)) -#define saawrite(dat,adr) saa7146_write(saamem,(adr),(dat)) - inline static void setgpio(av7110_t *av7110, int port, u32 data) { - void *saamem=av7110->saa_mem; - u32 val; + struct saa7146_dev *dev = av7110->dev; + u32 val; - val=saaread(GPIO_CTRL); + val=saa7146_read(dev,GPIO_CTRL); val&=~(0xff << (8*(port))); val|=(data)<<(8*(port)); - saawrite(val, GPIO_CTRL); + saa7146_write(dev, GPIO_CTRL, val); } /* This DEBI code is based on the Stradis driver @@ -141,13 +131,13 @@ setgpio(av7110_t *av7110, int port, u32 data) static int wait_for_debi_done(av7110_t *av7110) { - void *saamem=av7110->saa_mem; + struct saa7146_dev *dev = av7110->dev; int start; /* wait for registers to be programmed */ start = jiffies; while (1) { - if (saaread(MC2) & 2) + if (saa7146_read(dev, MC2) & 2) break; if (jiffies-start > HZ/20) { printk ("%s: timed out while waiting for registers " @@ -159,9 +149,9 @@ int wait_for_debi_done(av7110_t *av7110) /* wait for transfer to complete */ start = jiffies; while (1) { - if (!(saaread(PSR) & SPCI_DEBI_S)) + if (!(saa7146_read(dev, PSR) & SPCI_DEBI_S)) break; - saaread(MC2); + saa7146_read(dev, MC2); if (jiffies-start > HZ/4) { printk ("%s: timed out while waiting for transfer " "completion\n", __FUNCTION__); @@ -175,42 +165,41 @@ int wait_for_debi_done(av7110_t *av7110) static int debiwrite(av7110_t *av7110, u32 config, int addr, u32 val, int count) { - void *saamem=av7110->saa_mem; + struct saa7146_dev *dev = av7110->dev; u32 cmd; if (count <= 0 || count > 32764) return -1; if (wait_for_debi_done(av7110) < 0) return -1; - saawrite(config, DEBI_CONFIG); + saa7146_write(dev, DEBI_CONFIG, config); if (count <= 4) /* immediate transfer */ - saawrite(val, DEBI_AD); + saa7146_write(dev, DEBI_AD, val ); else /* block transfer */ - saawrite(av7110->debi_bus, DEBI_AD); - saawrite((cmd = (count << 17) | (addr & 0xffff)), DEBI_COMMAND); - saawrite((2 << 16) | 2, MC2); + saa7146_write(dev, DEBI_AD, av7110->debi_bus); + saa7146_write(dev, DEBI_COMMAND, (cmd = (count << 17) | (addr & 0xffff))); + saa7146_write(dev, MC2, (2 << 16) | 2); return 0; } static u32 debiread(av7110_t *av7110, u32 config, int addr, int count) { - void *saamem=av7110->saa_mem; + struct saa7146_dev *dev = av7110->dev; u32 result = 0; if (count > 32764 || count <= 0) return 0; if (wait_for_debi_done(av7110) < 0) return 0; - saawrite(av7110->debi_bus, DEBI_AD); - saawrite((count << 17) | 0x10000 | (addr & 0xffff), - DEBI_COMMAND); + saa7146_write(dev, DEBI_AD, av7110->debi_bus); + saa7146_write(dev, DEBI_COMMAND, (count << 17) | 0x10000 | (addr & 0xffff)); - saawrite(config, DEBI_CONFIG); - saawrite((2 << 16) | 2, MC2); + saa7146_write(dev, DEBI_CONFIG, config); + saa7146_write(dev, MC2, (2 << 16) | 2); if (count > 4) return count; wait_for_debi_done(av7110); - result = saaread(DEBI_AD); + result = saa7146_read(dev, DEBI_AD); result &= (0xffffffffUL >> ((4-count)*8)); return result; } @@ -302,9 +291,10 @@ reset_arm(av7110_t *av7110) setgpio(av7110, RESET_LINE, GPIO_OUTLO); /* Disable DEBI and GPIO irq */ - saa7146_write(av7110->saa_mem, IER, - saa7146_read(av7110->saa_mem, IER) & ~(MASK_19 | MASK_03)); - saa7146_write(av7110->saa_mem, ISR, (MASK_19 | MASK_03)); + IER_DISABLE(av7110->dev, (MASK_19 | MASK_03)); +// saa7146_write(av7110->dev, IER, +// saa7146_read(av7110->dev, IER) & ~(MASK_19 | MASK_03)); + saa7146_write(av7110->dev, ISR, (MASK_19 | MASK_03)); mdelay(800); setgpio(av7110, RESET_LINE, GPIO_OUTHI); @@ -312,9 +302,11 @@ reset_arm(av7110_t *av7110) ARM_ResetMailBox(av7110); - saa7146_write(av7110->saa_mem, ISR, (MASK_19 | MASK_03)); - saa7146_write(av7110->saa_mem, IER, - saa7146_read(av7110->saa_mem, IER) | MASK_03 ); + saa7146_write(av7110->dev, ISR, (MASK_19 | MASK_03)); + + IER_ENABLE(av7110->dev, MASK_03); +// saa7146_write(av7110->dev, IER, +// saa7146_read(av7110->dev, IER) | MASK_03 ); av7110->arm_ready=1; printk("av7110: ARM RESET\n"); @@ -347,15 +339,14 @@ static int arm_thread(void *data) u16 newloops; lock_kernel(); -#if 1 +#if 0 daemonize(); - reparent_to_init (); #else exit_mm(current); current->session=current->pgrp=1; #endif sigfillset(¤t->blocked); - strncpy(current->comm, "kdvb-av7110", sizeof(current->comm)); + strcpy(current->comm, "arm_mon"); av7110->arm_thread = current; unlock_kernel(); @@ -373,7 +364,7 @@ static int arm_thread(void *data) if (newloops==av7110->arm_loops) { printk("av7110%d: ARM crashed!\n", - av7110->saa->dvb_adapter->num); + av7110->dvb_adapter->num); arm_error(av7110); @@ -684,12 +675,16 @@ TTBStop(av7110_t *av7110) { if (--av7110->feeding) return av7110->feeding; - saa7146_write(av7110->saa_mem, MC1, MASK_20); // DMA3 off - saa7146_write(av7110->saa_mem, MC1, MASK_28); // RPS0 off - saa7146_write(av7110->saa_mem, IER, - saa7146_read(av7110->saa_mem, IER) & ~MASK_10 ); - saa7146_write(av7110->saa_mem, IER, - saa7146_read(av7110->saa_mem, IER)& ~MASK_07); + saa7146_write(av7110->dev, MC1, MASK_20); // DMA3 off + saa7146_write(av7110->dev, MC1, MASK_28); // RPS0 off + + IER_DISABLE(av7110->dev, (MASK_07 | MASK_10)); +/* + saa7146_write(av7110->dev, IER, + saa7146_read(av7110->dev, IER) & ~MASK_10 ); + saa7146_write(av7110->dev, IER, + saa7146_read(av7110->dev, IER)& ~MASK_07); +*/ return 0; } @@ -698,43 +693,45 @@ TTBStop(av7110_t *av7110) static int TTBStart(av7110_t *av7110) { - struct saa7146 *saa=av7110->saa; + struct saa7146_dev *dev=av7110->dev; //printk ("function : %s\n", __FUNCTION__); if (av7110->feeding) return ++av7110->feeding; - saa7146_write(saa->mem, MC1, MASK_20); // DMA3 off + saa7146_write(dev, MC1, MASK_20); // DMA3 off - memset(saa->grabbing, 0x00, TS_HEIGHT*TS_WIDTH); + memset(av7110->grabbing, 0x00, TS_HEIGHT*TS_WIDTH); - saa7146_write(saa->mem, PCI_BT_V1, 0x001c0000); + saa7146_write(dev, PCI_BT_V1, 0x001c0000); av7110->tsf=0; av7110->ttbp=0; - saa7146_write(saa->mem, DD1_INIT, 0x02000680); - saa7146_write(saa->mem, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); + saa7146_write(dev, DD1_INIT, 0x02000680); + saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); - saa7146_write(saa->mem, BRS_CTRL, 0x60000000); - saa7146_write(saa->mem, MC2, (MASK_08 | MASK_24)); + saa7146_write(dev, BRS_CTRL, 0x60000000); + saa7146_write(dev, MC2, (MASK_08 | MASK_24)); mdelay(10); - saa7146_write(saa->mem, BASE_ODD3, 0); - saa7146_write(saa->mem, BASE_EVEN3, TS_WIDTH*TS_HEIGHT/2); - saa7146_write(saa->mem, PROT_ADDR3, TS_WIDTH*TS_HEIGHT); - saa7146_write(saa->mem, BASE_PAGE3, virt_to_bus(saa->page_table[0])|ME1|0xb0); - saa7146_write(saa->mem, PITCH3, TS_WIDTH); + saa7146_write(dev, BASE_ODD3, 0); + saa7146_write(dev, BASE_EVEN3, TS_WIDTH*TS_HEIGHT/2); + saa7146_write(dev, PROT_ADDR3, TS_WIDTH*TS_HEIGHT); + saa7146_write(dev, BASE_PAGE3, av7110->pt.dma |ME1|0xb0); + saa7146_write(dev, PITCH3, TS_WIDTH); - saa7146_write(saa->mem, NUM_LINE_BYTE3, ((TS_HEIGHT/2)<<16)|TS_WIDTH); - saa7146_write(saa->mem, MC2, (MASK_04 | MASK_20)); + saa7146_write(dev, NUM_LINE_BYTE3, ((TS_HEIGHT/2)<<16)|TS_WIDTH); + saa7146_write(dev, MC2, (MASK_04 | MASK_20)); // VPE - saa7146_write(saa->mem, IER, saa7146_read(saa->mem, IER)|MASK_10); + IER_ENABLE(av7110->dev, MASK_10); +// saa7146_write(dev, IER, saa7146_read(saa->mem, IER)|MASK_10); - saa7146_write(saa->mem, MC1, (MASK_04 | MASK_20)); // DMA3 on + saa7146_write(dev, MC1, (MASK_04 | MASK_20)); // DMA3 on // FIDB - saa7146_write(saa->mem, IER, saa7146_read(saa->mem, IER)|MASK_07); + IER_ENABLE(av7110->dev, MASK_07); +// saa7146_write(dev, IER, saa7146_read(saa->mem, IER)|MASK_07); return ++av7110->feeding; } @@ -882,26 +879,26 @@ u8 pshead[0x26] = { static void vpeirq (unsigned long data) { - //printk("vpeirq %08x\n", saa7146_read(av7110->saa_mem, PCI_VDP3)); + //printk("vpeirq %08x\n", saa7146_read(av7110->dev, PCI_VDP3)); } #if 0 -static void fidbirq(struct saa7146* saa, void *data) +static void fidbirq(struct saa7146_dev* saa, void *data) { av7110_t *av7110=(av7110_t *) data; u8 *mem; - mem=(av7110->tsf ? TS_HEIGHT*TS_WIDTH/2 :0)+(u8 *)av7110->saa->grabbing; + mem=(av7110->tsf ? TS_HEIGHT*TS_WIDTH/2 :0)+(u8 *)av7110->grabbing; // FIXME: think of something better without busy waiting if (av7110->tsf) - while (saa7146_read(av7110->saa_mem, PCI_VDP3)>0x20000); + while (saa7146_read(av7110->dev, PCI_VDP3)>0x20000); else - while (saa7146_read(av7110->saa_mem, PCI_VDP3)<0x17800); + while (saa7146_read(av7110->dev, PCI_VDP3)<0x17800); av7110->tsf^=1; - saa7146_write(av7110->saa_mem, DD1_INIT, 0x02000600|(av7110->tsf ? 0x40:0x80)); - saa7146_write(av7110->saa_mem, MC2, + saa7146_write(av7110->dev, DD1_INIT, 0x02000600|(av7110->tsf ? 0x40:0x80)); + saa7146_write(av7110->dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); // FIXME: use bottom half or tasklet @@ -913,11 +910,11 @@ static void fidbirq (unsigned long data) { struct av7110_s *av7110 = (struct av7110_s*) data; - u8 *mem=(u8 *)(av7110->saa->grabbing); + u8 *mem=(u8 *)(av7110->grabbing); int num; u32 dmapos; - dmapos=saa7146_read(av7110->saa_mem, PCI_VDP3); + dmapos=saa7146_read(av7110->dev, PCI_VDP3); dmapos-=(dmapos%188); if (av7110->tsf) { @@ -941,8 +938,8 @@ void fidbirq (unsigned long data) } av7110->tsf^=1; - saa7146_write(av7110->saa_mem, DD1_INIT, 0x02000600|(av7110->tsf ? 0x40:0x80)); - saa7146_write(av7110->saa_mem, MC2, + saa7146_write(av7110->dev, DD1_INIT, 0x02000600|(av7110->tsf ? 0x40:0x80)); + saa7146_write(av7110->dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); // FIXME: use bottom half or tasklet @@ -994,11 +991,14 @@ void debiirq (unsigned long data) struct av7110_s *av7110 = (struct av7110_s*) data; int type=av7110->debitype; int handle=(type>>8)&0x1f; + +// printk("debiirq()\n"); print_time("debi"); - saa7146_write(av7110->saa_mem, IER, - saa7146_read(av7110->saa_mem, IER) & ~MASK_19 ); - saa7146_write(av7110->saa_mem, ISR, MASK_19 ); + IER_DISABLE(av7110->dev, MASK_19); +// saa7146_write(av7110->dev, IER, +// saa7146_read(av7110->dev, IER) & ~MASK_19 ); + saa7146_write(av7110->dev, ISR, MASK_19 ); if (type==-1) { printk("DEBI irq oops\n"); @@ -1181,7 +1181,7 @@ void gpioirq (unsigned long data) u32 rxbuf, txbuf; int len; - //printk("GPIO0 irq\n"); +// printk("GPIO0 irq\n"); if (av7110->debitype !=-1) printk("GPIO0 irq oops\n"); @@ -1190,9 +1190,10 @@ void gpioirq (unsigned long data) ARM_ClearIrq(av7110); - saa7146_write(av7110->saa_mem, IER, - saa7146_read(av7110->saa_mem, IER) & ~MASK_19 ); - saa7146_write(av7110->saa_mem, ISR, MASK_19 ); + IER_DISABLE(av7110->dev, MASK_10); +// saa7146_write(av7110->dev, IER, +// saa7146_read(av7110->dev, IER) & ~MASK_19 ); + saa7146_write(av7110->dev, ISR, MASK_19 ); av7110->debitype = irdebi(av7110, DEBINOSWAP, IRQ_STATE, 0, 2); av7110->debilen = irdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2); @@ -1249,8 +1250,9 @@ void gpioirq (unsigned long data) iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2); iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2); wait_for_debi_done(av7110); - saa7146_write(av7110->saa_mem, IER, - saa7146_read(av7110->saa_mem, IER) | MASK_19 ); + IER_ENABLE(av7110->dev, MASK_19); +// saa7146_write(av7110->dev, IER, +// saa7146_read(av7110->dev, IER) | MASK_19 ); if (len<5) len=5; /* we want a real DEBI DMA */ iwdebi(av7110, DEBISWAB, DPRAM_BASE+txbuf, 0, (len+3)&~3); spin_unlock(&av7110->debilock); @@ -1286,8 +1288,9 @@ void gpioirq (unsigned long data) iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2); iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2); wait_for_debi_done(av7110); - saa7146_write(av7110->saa_mem, IER, - saa7146_read(av7110->saa_mem, IER) | MASK_19 ); + IER_ENABLE(av7110->dev, MASK_19); +// saa7146_write(av7110->dev, IER, +// saa7146_read(av7110->dev, IER) | MASK_19 ); iwdebi(av7110, DEBISWAB, DPRAM_BASE+txbuf, 0, (len+3)&~3); spin_unlock(&av7110->debilock); @@ -1313,8 +1316,9 @@ void gpioirq (unsigned long data) av7110->bmpp+=len; av7110->bmplen-=len; wait_for_debi_done(av7110); - saa7146_write(av7110->saa_mem, IER, - saa7146_read(av7110->saa_mem, IER) | MASK_19 ); + IER_ENABLE(av7110->dev, MASK_19); +// saa7146_write(av7110->dev, IER, +// saa7146_read(av7110->dev, IER) | MASK_19 ); if (len<5) len=5; /* we want a real DEBI DMA */ iwdebi(av7110, DEBISWAB, DPRAM_BASE+txbuf, 0, (len+3)&~3); spin_unlock(&av7110->debilock); @@ -1331,8 +1335,9 @@ void gpioirq (unsigned long data) } /* yes, fall through */ case DATA_TS_RECORD: case DATA_PES_RECORD: - saa7146_write(av7110->saa_mem, IER, - saa7146_read(av7110->saa_mem, IER) | MASK_19); + IER_ENABLE(av7110->dev, MASK_19); +// saa7146_write(av7110->dev, IER, +// saa7146_read(av7110->dev, IER) | MASK_19); irdebi(av7110, DEBISWAB, DPRAM_BASE+rxbuf, 0, len); spin_unlock(&av7110->debilock); return; @@ -1342,8 +1347,9 @@ void gpioirq (unsigned long data) iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2); break; } - saa7146_write(av7110->saa_mem, IER, - saa7146_read(av7110->saa_mem, IER) | MASK_19); + IER_ENABLE(av7110->dev, MASK_19); +// saa7146_write(av7110->dev, IER, +// saa7146_read(av7110->dev, IER) | MASK_19); irdebi(av7110, DEBISWAB, Reserved, 0, len); spin_unlock(&av7110->debilock); return; @@ -1554,38 +1560,29 @@ SendDAC(av7110_t *av7110, u8 addr, u8 data) static int SetVolume(av7110_t *av7110, int volleft, int volright) { - int err=0; - int chleft, chright; + int err; switch (av7110->adac_type) { case DVB_ADAC_TI: - chleft=(volleft*256)/946; - chright=(volright*256)/946; - if (chleft > 0x45) - chleft=0x45; - if (chright > 0x45) - chright=0x45; - err=SendDAC(av7110, 3, 0x80 + chleft); + volleft=(volleft*256)/946; + volright=(volright*256)/946; + if (volleft > 0x45) + volleft=0x45; + if (volright > 0x45) + volright=0x45; + err=SendDAC(av7110, 3, 0x80 + volleft); if (err) return err; - err=SendDAC(av7110, 4, chright); - break; + return SendDAC(av7110, 4, volright); case DVB_ADAC_CRYSTAL: - chleft=127-volleft/2; - chright=127-volright/2; - i2c_writereg(av7110, 0x20, 0x03, chleft); - i2c_writereg(av7110, 0x20, 0x04, chright); - - default: - err = -1; + volleft=127-volleft/2; + volright=127-volright/2; + i2c_writereg(av7110, 0x20, 0x03, volleft); + i2c_writereg(av7110, 0x20, 0x04, volright); + return 0; } - - if(!err) { - av7110->audiostate.mixer_state.volume_left = volleft; - av7110->audiostate.mixer_state.volume_right = volright; - } - return err; + return 0; } #ifdef CONFIG_DVB_AV7110_OSD @@ -2059,7 +2056,7 @@ firmversion(av7110_t *av7110) av7110->avtype=(buf[8] << 16) + buf[9]; printk ("DVB: AV711%d(%d) - firm %08x, rtsl %08x, vid %08x, app %08x\n", - av7110->avtype, av7110->saa->dvb_adapter->num, av7110->arm_fw, + av7110->avtype, av7110->dvb_adapter->num, av7110->arm_fw, av7110->arm_rtsl, av7110->arm_vid, av7110->arm_app); return; @@ -2158,18 +2155,23 @@ bootarm(av7110_t *av7110) u32 ret; int i; + printk("bootarm: %p => %p\n",av7110,av7110 != 0 ? av7110->dev : 0); + setgpio(av7110, RESET_LINE, GPIO_OUTLO); /* Disable DEBI and GPIO irq */ - saa7146_write(av7110->saa_mem, IER, - saa7146_read(av7110->saa_mem, IER) & + IER_DISABLE(av7110->dev, MASK_03|MASK_19); +/* + saa7146_write(av7110->dev, IER, + saa7146_read(av7110->dev, IER) & ~(MASK_19 | MASK_03)); - saa7146_write(av7110->saa_mem, ISR, (MASK_19 | MASK_03)); +*/ + saa7146_write(av7110->dev, ISR, (MASK_19 | MASK_03)); /* enable DEBI */ - saa7146_write(av7110->saa_mem, MC1, 0x08800880); - saa7146_write(av7110->saa_mem, DD1_STREAM_B, 0x00000000); - saa7146_write(av7110->saa_mem, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); + saa7146_write(av7110->dev, MC1, 0x08800880); + saa7146_write(av7110->dev, DD1_STREAM_B, 0x00000000); + saa7146_write(av7110->dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); /* test DEBI */ iwdebi(av7110, DEBISWAP, DPRAM_BASE, 0x76543210, 4); @@ -2216,9 +2218,10 @@ bootarm(av7110_t *av7110) //ARM_ClearIrq(av7110); ARM_ResetMailBox(av7110); - saa7146_write(av7110->saa_mem, ISR, (MASK_19 | MASK_03)); - saa7146_write(av7110->saa_mem, IER, - saa7146_read(av7110->saa_mem, IER) | MASK_03 ); + saa7146_write(av7110->dev, ISR, (MASK_19 | MASK_03)); + IER_ENABLE(av7110->dev, MASK_03); +// saa7146_write(av7110->dev, IER, +// saa7146_read(av7110->dev, IER) | MASK_03 ); av7110->arm_errors=0; av7110->arm_ready=1; @@ -2303,9 +2306,9 @@ audcom(av7110_t *av7110, u32 com) inline static void Set22K(av7110_t *av7110, int state) { - if (av7110->saa->card_type==DVB_CARD_TT_SIEMENS) + if (av7110->card_type->type==DVB_CARD_TT_SIEMENS) outcom(av7110, COMTYPE_AUDIODAC, (state ? ON22K : OFF22K), 0); - if (av7110->saa->card_type==DVB_CARD_TT_BUDGET) + if (av7110->card_type->type==DVB_CARD_TT_BUDGET) setgpio(av7110, 3, (state ? GPIO_OUTHI : GPIO_OUTLO)); } @@ -2343,7 +2346,7 @@ SendDiSEqCMsg(av7110_t *av7110, int len, u8 *msg, int burst) { int i; - switch (av7110->saa->card_type) { + switch (av7110->card_type->type) { case DVB_CARD_TT_SIEMENS: { u16 buf[18] = { ((COMTYPE_AUDIODAC << 8) + SendDiSEqC), @@ -2405,7 +2408,7 @@ static inline int i2c_writereg(av7110_t *av7110, u8 id, u8 reg, u8 val) { u8 msg[2]={ reg, val }; - struct dvb_i2c_bus *i2c = av7110->saa->i2c_bus; + struct dvb_i2c_bus *i2c = av7110->i2c_bus; struct i2c_msg msgs; msgs.flags=0; @@ -2419,7 +2422,7 @@ static inline int msp_writereg(av7110_t *av7110, u8 dev, u16 reg, u16 val) { u8 msg[5]={ dev, reg>>8, reg&0xff, val>>8 , val&0xff }; - struct dvb_i2c_bus *i2c = av7110->saa->i2c_bus; + struct dvb_i2c_bus *i2c = av7110->i2c_bus; struct i2c_msg msgs; msgs.flags=0; @@ -2432,7 +2435,7 @@ msp_writereg(av7110_t *av7110, u8 dev, u16 reg, u16 val) static inline u8 i2c_readreg(av7110_t *av7110, u8 id, u8 reg) { - struct dvb_i2c_bus *i2c = av7110->saa->i2c_bus; + struct dvb_i2c_bus *i2c = av7110->i2c_bus; u8 mm1[] = {0x00}; u8 mm2[] = {0x00}; struct i2c_msg msgs[2]; @@ -2827,375 +2830,47 @@ void p_to_t(u8 const *buf, long int length, u16 pid, u8 *counter, * V4L SECTION ****************************************************************************/ -static -int av7110_video_ioctl (struct av7110_s *av7110, unsigned int cmd, void *arg) -{ - switch (cmd) { - case VIDIOCGCAP: - { - struct video_capability *b = arg; - - dprintk(KERN_ERR "dvb: VIDIOCGCAP called\n"); - - strcpy(b->name, "DVB Board"); - - b->type = av7110->video.type; - - b->channels = 1; - b->audios = 2; - b->maxwidth = 768; - b->maxheight = 576; - b->minwidth = 32; - b->minheight = 32; - - return 0; - } - - case VIDIOCGCHAN: - { - static const - struct video_channel dvb_chan = { 0, "DVB", 1, 3, 1, 1 }; - struct video_channel *v = arg; - - dprintk(KERN_ERR "dvb: VIDIOCGCHAN called\n"); - - memcpy(v, &dvb_chan, sizeof(struct video_channel)); - - return 0; - - } - - case VIDIOCSCHAN: - { - struct video_channel *v = arg; - - dprintk(KERN_ERR "dvb: VIDIOCSCHAN called\n"); - - if (v->channel>0) - return -EINVAL; - - if (v->norm > 1) - return -EOPNOTSUPP; - - av7110->vidmode = v->norm; - SetMode(av7110, v->norm); - av7110->saa->mode = v->norm; - return 0; - } +/**************************************************************************** + * V4L SECTION + ****************************************************************************/ - case VIDIOCGTUNER: - { - struct video_tuner *v = arg; - - dprintk(KERN_ERR "dvb: VIDIOCGTUNER called\n"); - - /* only channel 0 has a tuner */ - if(!v->tuner) - return -EINVAL; - - /* fill the structure */ - strcpy(v->name, "DVB"); - v->rangelow = 0x00000000; - v->rangehigh = 0xffffffff; - - v->flags= VIDEO_TUNER_PAL | VIDEO_TUNER_NTSC; - v->mode = av7110->vidmode; +int av7110_ioctl(struct saa7146_dev *dev, unsigned int cmd, void *arg) +{ +/* + av7110_t *av7110 = dev->ext_priv; +*/ + switch(cmd) { + case VIDIOC_ENUMINPUT: + { + struct v4l2_input *i = arg; - /* fixme: fill in signal strength here */ - v->signal = 0xffff; - - return 0; - } - - case VIDIOCSTUNER: - { - struct video_tuner *v = arg; - - dprintk(KERN_ERR "dvb: VIDIOCSTUNER called\n"); - - /* only channel 0 has a tuner */ - if (!v->tuner) - return -EINVAL; - - /* check if format is supported */ - if(v->mode != VIDEO_MODE_PAL && v->mode != VIDEO_MODE_NTSC - /* && v->mode != VIDEO_MODE_SECAM */ ) - return -EOPNOTSUPP; - - av7110->vidmode = v->mode; - SetMode(av7110, v->mode); - - return 0; - } - - case VIDIOCGPICT: - { - struct video_picture *p = arg; - - dprintk(KERN_ERR "dvb: VIDIOCGPICT called\n"); - - saacomm(SAA7146_V4L_GPICT, p); - - dprintk("dvb: VIDIOCGPICT called: b:%d c:%d s:%d d:%d p:%d\n", - p->brightness, p->contrast, p->colour, - p->depth, p->palette); - - return 0; - } - - case VIDIOCSPICT: - { - struct video_picture *p = arg; - - dprintk("dvb: VIDIOCSPICT called: b:%d c:%d s:%d d:%d p:%d\n", - p->brightness, p->contrast, p->colour, - p->depth, p->palette); - - switch (p->palette) { - case VIDEO_PALETTE_RGB555: - case VIDEO_PALETTE_RGB565: - case VIDEO_PALETTE_RGB24: - case VIDEO_PALETTE_RGB32: - case VIDEO_PALETTE_UYVY: - case VIDEO_PALETTE_YUV422P: - case VIDEO_PALETTE_YUV420P: - case VIDEO_PALETTE_YUV411P: - break; - default: + if( i->index != 0 ) { return -EINVAL; } - saacomm(SAA7146_V4L_SPICT, p); - - return 0; - - } - - case VIDIOCSWIN: - { - struct video_window *w = arg; - - dprintk("dvb: VIDIOCSWIN called: " - "clips: %d, x:%d, y:%d, h:%d, w:%d\n", - w->clipcount, w->x, w->y, w->height, w->width); - - saacomm(SAA7146_V4L_SWIN, w); - - return 0; - } - - case VIDIOCGWIN: - { - dprintk(KERN_ERR "dvb: VIDIOCGWIN called\n"); - return 0; - } - - case VIDIOCCAPTURE: - { - int *v = arg; - - dprintk("dvb: VIDIOCCAPTURE called, mode:%d (0=disable)\n", *v); - - saacomm(SAA7146_V4L_CCAPTURE, v); - - return 0; - } - - case VIDIOCGFBUF: - { - struct video_buffer *b = arg; - - dprintk(KERN_ERR "dvb: VIDIOCGFBUF called\n"); - - saacomm(SAA7146_V4L_GFBUF, b); - - return 0; - - } - - case VIDIOCSFBUF: - { - struct video_buffer *b = arg; - u32 vid = (vidmem << 16) | vidlow; - - /* see if vidmem-override is requested */ - if (vidmem) { - printk ("dvb: video-memory-override. (0x%08x)\n", vid); - b->base = (void*) vid; - } - - saacomm(SAA7146_V4L_SFBUF, b); - - dprintk(KERN_ERR "dvb: VIDIOCSFBUF called\n"); - - return 0; - } - - /* Video key event - to dev 255 is to all - - * cuts capture on all DMA windows with this key (0xFFFFFFFF == all) - */ - case VIDIOCKEY: - { - dprintk(KERN_ERR "dvb: VIDIOCKEY called\n"); - return 0; - } - - case VIDIOCGAUDIO: - { - struct video_audio *v = arg; - - v->flags = VIDEO_AUDIO_MUTABLE; - /* let's auto-detect */ - return 0; - } - - case VIDIOCSAUDIO: - { - //struct video_audio *v; - return 0; - } - - case VIDIOCSYNC: - { - int i = 0; - int *frame = (int*) arg; - - dprintk ("dvb: VIDIOCSYNC called - frame: %d\n", *frame); - - /* simply pass the requested frame-number to the corresponding - saa7146-function ... */ - i = saacomm(SAA7146_V4L_CSYNC, frame); - - dprintk ("dvb: VIDIOCSYNC done - frame: %d\n", *frame); - - return i; - } - - case VIDIOCMCAPTURE: - { - struct video_mmap *vm = arg; - int i = 0; - - dprintk(KERN_ERR "dvb: VIDIOCMCAPTURE called: fr:%d," - "fmt:%d, w:%d, h:%d\n", - vm->frame, vm->format, vm->width, vm->height); - - switch (vm->format) { - case VIDEO_PALETTE_YUV422P: - case VIDEO_PALETTE_YUV420P: - case VIDEO_PALETTE_YUV411P: - return -EINVAL; - } - - /* simply pass the structure for the requested frame-number - to the corresponding saa7146-function ... */ - i = saacomm(SAA7146_V4L_CMCAPTURE, vm); - - return i; - } - - case VIDIOCGMBUF: - { - struct video_mbuf *mbuf = arg; - dprintk(KERN_ERR "dvb: VIDIOCGMBUF called\n"); - saacomm(SAA7146_V4L_GMBUF, mbuf); - return 0; - - } - - case VIDIOCGUNIT: - { - /*struct video_unit vu;*/ - dprintk(KERN_ERR "dvb: VIDIOCGUNIT called\n"); - return 0; - } + memset(i,0,sizeof(*i)); + i->index = 0; + strcpy(i->name, "DVB"); + i->type = V4L2_INPUT_TYPE_CAMERA; + i->audioset = 1; - case VIDIOCGCAPTURE: - { - dprintk(KERN_ERR "dvb: VIDIOCGCAPTURE called\n"); - return 0; - } - case VIDIOCSCAPTURE: - { - dprintk(KERN_ERR "dvb: VIDIOCSCAPTURE called\n"); - return 0; - } - - default: - return -ENOIOCTLCMD; - } - - return 0; -} - - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - -static -int dvb_ioctl(struct video_device *dev, unsigned int cmd, void *arg) -{ - return av7110_video_ioctl (dev->priv, cmd, arg); -} - - -#else - - -static -int dvb_do_ioctl (struct inode *inode, struct file *file, - unsigned int cmd, void *arg) -{ - struct video_device *dev = video_devdata (file); - return av7110_video_ioctl (dev->priv, cmd, arg); -} - - -static -int dvb_ioctl (struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) -{ - return video_usercopy(inode, file, cmd, arg, dvb_do_ioctl); -} - -#endif - - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -static -int dvb_mmap(struct video_device *dev, const char *adr, unsigned long size) -{ - struct av7110_s *av7110 = dev->priv; - struct vm_area_struct vma; - - vma.vm_start = (unsigned long) adr; - vma.vm_end = vma.vm_start + size; - - if (saacomm(SAA7146_DO_MMAP, &vma)) { - printk(KERN_ERR "av7110: dvb_mmap failed!\n"); - return -1; + return 0; } - - return 0; -} -#else -static -int dvb_mmap(struct file* file, struct vm_area_struct *vma) -{ - struct video_device *dev = video_devdata (file); - av7110_t *av7110 = dev->priv; - - dprintk(KERN_ERR "av7110: dvb_mmap called, adr:%08lx, size:0x%08lx\n", - vma->vm_start, vma->vm_end - vma->vm_start); - - if (saacomm(SAA7146_DO_MMAP, vma)) { - printk(KERN_ERR "av7110: dvb_mmap failed!\n"); - return -1; + case VIDIOC_G_INPUT: + { + int *input = (int *)arg; + *input = 0; + return 0; + } + case VIDIOC_S_INPUT: + { + return 0; + } + default: + return -ENOIOCTLCMD; } - return 0; -} -#endif - +} static unsigned int dvb_audio_poll(struct file *file, poll_table *wait) @@ -3219,57 +2894,6 @@ unsigned int dvb_audio_poll(struct file *file, poll_table *wait) } -#if !(LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) -static struct file_operations dvb_fops = { - .ioctl = dvb_ioctl, - .mmap = dvb_mmap, - .llseek = no_llseek -}; -#endif - - -/* template for video_device-structure */ -static struct video_device dvb_template = { - .owner = THIS_MODULE, - .name = "DVB Board", - .type = VID_TYPE_TUNER | - VID_TYPE_CAPTURE | - VID_TYPE_OVERLAY | - VID_TYPE_CLIPPING | - VID_TYPE_FRAMERAM | - VID_TYPE_SCALES, - .hardware = VID_HARDWARE_SAA7146, -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - .ioctl = dvb_ioctl, - .mmap = dvb_mmap, -#else - .fops = &dvb_fops -#endif -}; - - -static int vid_register(av7110_t *av7110) -{ - memcpy( &av7110->video, &dvb_template, sizeof(struct video_device)); - - av7110->video.priv = av7110; - - if (video_register_device(&av7110->video, VFL_TYPE_GRABBER, -1)) { - printk(KERN_ERR "dvb: can't register videodevice\n"); - return -1; - } - - return 0; -} - -static inline int vid_unregister(av7110_t *av7110) -{ - if (av7110->video.minor != -1) - video_unregister_device(&av7110->video); - - return 0; -} - /**************************************************************************** * END OF V4L SECTION ****************************************************************************/ @@ -3477,7 +3101,7 @@ dvb_start_feed(struct dvb_demux_feed *dvbdmxfeed) if (!dvbdmx->dmx.frontend) return -EINVAL; - if (av7110->saa->card_type>=DVB_CARD_TT_BUDGET) + if (av7110->card_type->type>=DVB_CARD_TT_BUDGET) return TTBStart(av7110); if (dvbdmxfeed->pid>0x1fff) @@ -3534,7 +3158,7 @@ dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed) struct dvb_demux *dvbdmx=dvbdmxfeed->demux; av7110_t *av7110=(av7110_t *) dvbdmx->priv; - if (av7110->saa->card_type>=DVB_CARD_TT_BUDGET) + if (av7110->card_type->type>=DVB_CARD_TT_BUDGET) return TTBStop(av7110); if (dvbdmxfeed->type == DMX_TYPE_TS) { @@ -4280,7 +3904,7 @@ dvb_audio_ioctl(struct inode *inode, struct file *file, { struct audio_mixer *amix=(struct audio_mixer *)parg; - ret=SetVolume(av7110, amix->volume_left, amix->volume_right); + SetVolume(av7110, amix->volume_left, amix->volume_right); break; } case AUDIO_SET_STREAMTYPE: @@ -4437,16 +4061,16 @@ dvb_register(av7110_t *av7110) av7110->registered=1; - av7110->dvb_adapter = av7110->saa->dvb_adapter; + av7110->dvb_adapter = av7110->dvb_adapter; - if (av7110->saa->card_type==DVB_CARD_TT_SIEMENS) + if (av7110->card_type->type==DVB_CARD_TT_SIEMENS) dvb_add_frontend_notifier (av7110->dvb_adapter, av7110_before_after_tune, av7110); /** * init DiSEqC stuff */ - if (av7110->saa->card_type==DVB_CARD_TT_BUDGET || - av7110->saa->card_type==DVB_CARD_TT_SIEMENS) + if (av7110->card_type->type==DVB_CARD_TT_BUDGET || + av7110->card_type->type==DVB_CARD_TT_SIEMENS) dvb_add_frontend_ioctls (av7110->dvb_adapter, av7110_diseqc_ioctl, NULL, av7110); @@ -4465,10 +4089,10 @@ dvb_register(av7110_t *av7110) av7110->display_ar=VIDEO_FORMAT_4_3; memcpy(av7110->demux_id, "demux0_0", 9); - av7110->demux_id[7]=av7110->saa->dvb_adapter->num+0x30; + av7110->demux_id[7]=av7110->dvb_adapter->num+0x30; dvbdemux->priv=(void *) av7110; - if (av7110->saa->card_type==DVB_CARD_TT_SIEMENS) { + if (av7110->card_type->type==DVB_CARD_TT_SIEMENS) { for (i=0; i<32; i++) av7110->handle2filter[i]=NULL; @@ -4500,7 +4124,7 @@ dvb_register(av7110_t *av7110) dvb_dmxdev_init(&av7110->dmxdev, av7110->dvb_adapter); } - if (av7110->saa->card_type>=DVB_CARD_TT_BUDGET) { + if (av7110->card_type->type>=DVB_CARD_TT_BUDGET) { dvbdemux->filternum=256; dvbdemux->feednum=256; dvbdemux->start_feed=dvb_start_feed; @@ -4547,14 +4171,13 @@ dvb_register(av7110_t *av7110) if (ret<0) return ret; - if (av7110->saa->card_type==DVB_CARD_TT_SIEMENS) { + if (av7110->card_type->type==DVB_CARD_TT_SIEMENS) { dvb_register_device(av7110->dvb_adapter, &av7110->video_dev, &dvbdev_video, av7110, DVB_DEVICE_VIDEO); dvb_register_device(av7110->dvb_adapter, &av7110->audio_dev, &dvbdev_audio, av7110, DVB_DEVICE_AUDIO); dvb_register_device(av7110->dvb_adapter, &av7110->ca_dev, &dvbdev_ca, av7110, DVB_DEVICE_CA); - vid_register(av7110); #ifdef CONFIG_DVB_AV7110_OSD dvb_register_device(av7110->dvb_adapter, &av7110->osd_dev, &dvbdev_osd, av7110, DVB_DEVICE_OSD); @@ -4568,7 +4191,7 @@ dvb_register(av7110_t *av7110) #endif } - av7110->dvb_net.card_num=av7110->saa->dvb_adapter->num; + av7110->dvb_net.card_num=av7110->dvb_adapter->num; dvb_net_init(av7110->dvb_adapter, &av7110->dvb_net, &dvbdemux->dmx); return 0; @@ -4592,15 +4215,14 @@ dvb_unregister(av7110_t *av7110) dvb_dmxdev_release(&av7110->dmxdev); dvb_dmx_release(&av7110->demux); - if (av7110->saa->card_type==DVB_CARD_TT_SIEMENS) + if (av7110->card_type->type==DVB_CARD_TT_SIEMENS) dvb_remove_frontend_notifier (av7110->dvb_adapter, av7110_before_after_tune); dvb_remove_frontend_ioctls (av7110->dvb_adapter, av7110_diseqc_ioctl, NULL); - if (av7110->saa->card_type==DVB_CARD_TT_SIEMENS) { - vid_unregister(av7110); + if (av7110->card_type->type==DVB_CARD_TT_SIEMENS) { dvb_unregister_device(av7110->audio_dev); dvb_unregister_device(av7110->video_dev); dvb_unregister_device(av7110->osd_dev); @@ -4611,23 +4233,184 @@ dvb_unregister(av7110_t *av7110) } } +static +int master_xfer (struct dvb_i2c_bus *i2c, const struct i2c_msg msgs[], int num) +{ + struct saa7146_dev *dev = i2c->data; + return saa7146_i2c_transfer(dev, msgs, num, 6); +} + /**************************************************************************** * INITIALIZATION ****************************************************************************/ -static -int av7110_attach (struct saa7146 *saa, void **av7110_ptr) +struct saa7146_extension_ioctls ioctls[] = { + { VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE }, + { VIDIOC_G_INPUT, SAA7146_EXCLUSIVE }, + { VIDIOC_S_INPUT, SAA7146_EXCLUSIVE }, + { 0, 0 } +}; + +int av7110_preinit(struct saa7146_dev* dev) +{ + /* the Siemens DVB needs this if you want to have the i2c chips + get recognized before the main driver is loaded + */ + saa7146_write(dev, GPIO_CTRL, 0x500000); + + return 0; +} + +static struct card_info fs_1_5 = { DVB_CARD_TT_SIEMENS, "Siemens cable card PCI rev1.5" }; +static struct card_info fs_1_3 = { DVB_CARD_TT_SIEMENS, "Siemens/Technotrend/Hauppauge PCI rev1.3" }; +static struct card_info ttbs = { DVB_CARD_TT_BUDGET, "TT-Budget/WinTV-NOVA-S PCI" }; +static struct card_info ttbc = { DVB_CARD_TT_BUDGET, "TT-Budget/WinTV-NOVA-C PCI" }; +static struct card_info ttbt = { DVB_CARD_TT_BUDGET, "TT-Budget/WinTV-NOVA-T PCI" }; +static struct card_info ttbci = { DVB_CARD_TT_BUDGET_CI, "TT-Budget/WinTV-NOVA-CI PCI" }; +static struct card_info satel = { DVB_CARD_TT_BUDGET, "SATELCO Multimedia PCI"}; +static struct card_info unkwn = { DVB_CARD_TT_SIEMENS, "Technotrend/Hauppauge PCI rev?(unknown0)?"}; +static struct card_info tt_1_6 = { DVB_CARD_TT_SIEMENS, "Technotrend/Hauppauge PCI rev1.3 or 1.6" }; +static struct card_info tt_2_1 = { DVB_CARD_TT_SIEMENS, "Technotrend/Hauppauge PCI rev2.1" }; +static struct card_info tt_t = { DVB_CARD_TT_SIEMENS, "Technotrend/Hauppauge PCI DVB-T" }; +static struct card_info knc1 = { DVB_CARD_KNC1, "KNC1 DVB-S" }; + +struct card_match { + struct saa7146_sub_info *sub; /* Subsystem ID's or PCI_ANY_ID */ + struct card_info *card; +}; + +static struct saa7146_sub_info sub_data[] = { + { 0x110a, 0xffff }, + { 0x110a, 0x0000 }, + { 0x13c2, 0x1003 }, + { 0x13c2, 0x1004 }, + { 0x13c2, 0x1005 }, + { 0x13c2, 0x100c }, + { 0x13c2, 0x1013 }, + { 0x13c2, 0x0000 }, + { 0x13c2, 0x1002 }, + { 0x13c2, 0x0001 }, + { 0x13c2, 0x0002 }, + { 0x13c2, 0x0003 }, + { 0x13c2, 0x0004 }, + { 0x13c2, 0x0006 }, + { 0x13c2, 0x0008 }, + { 0xffc2, 0x0000 }, + { 0x1131, 0x4f56 }, + { 0xffff, 0xffff }, +}; + +static struct card_match match_data[] = { + { &sub_data[ 0], &fs_1_5 }, + { &sub_data[ 1], &fs_1_5 }, + { &sub_data[ 2], &ttbs }, + { &sub_data[ 3], &ttbc }, + { &sub_data[ 4], &ttbt }, + { &sub_data[ 5], &ttbci }, + { &sub_data[ 6], &satel }, + { &sub_data[ 7], &fs_1_3 }, + { &sub_data[ 8], &unkwn }, + { &sub_data[ 9], &tt_1_6 }, + { &sub_data[10], &tt_2_1 }, + { &sub_data[11], &tt_2_1 }, + { &sub_data[12], &tt_2_1 }, + { &sub_data[13], &tt_1_6 }, + { &sub_data[14], &tt_t }, + { &sub_data[15], &unkwn }, + { &sub_data[16], &knc1 }, + { &sub_data[17], NULL }, +}; + + +int av7110_probe(struct saa7146_dev* dev, unsigned int subvendor, unsigned int subdevice) { - struct av7110_s *av7110; + av7110_t *av7110; + int i = 0; + for(i = 0;;i++) { + if( 0xffff == match_data[i].sub->subvendor ) { + printk(KERN_ERR "dvb: device subvendor:0x%04x, subdevice:0x%04x is not a known dvb card.\n",subvendor,subdevice); + return -ENODEV; + } + if( subvendor == match_data[i].sub->subvendor && subdevice == match_data[i].sub->subdevice ) { + break; + } + } + if (!(av7110 = kmalloc (sizeof (struct av7110_s), GFP_KERNEL))) { printk ("%s: out of memory!\n", __FUNCTION__); return -ENOMEM; } + memset(av7110, 0, sizeof(av7110_t)); + av7110->card_type = match_data[i].card; - *av7110_ptr = av7110; + (av7110_t*)dev->ext_priv = av7110; - memset(av7110, 0, sizeof(av7110_t)); + return 0; +} + +static +int av7110_attach (struct saa7146_dev* dev) +{ + av7110_t *av7110 = (av7110_t*)dev->ext_priv; + struct dvb_adapter *adap; + struct scatterlist *slist; + int slen = 0; + int length = TS_WIDTH*TS_HEIGHT; + int pages = (length+PAGE_SIZE-1)/PAGE_SIZE; + + av7110->dev=(struct saa7146_dev *)dev; + + dvb_register_adapter(&adap, av7110->card_type->name); + av7110->dvb_adapter = adap; + + av7110->i2c_bus = dvb_register_i2c_bus (master_xfer, dev, av7110->dvb_adapter, 0); + if (!av7110->i2c_bus) { + dvb_unregister_adapter (av7110->dvb_adapter); + return -ENOMEM; + } + + av7110->grabbing = vmalloc(length); + if( NULL == av7110->grabbing ) { + dvb_unregister_i2c_bus (master_xfer,av7110->i2c_bus->adapter, av7110->i2c_bus->id); + dvb_unregister_adapter (av7110->dvb_adapter); + printk(KERN_ERR "dvb: vmalloc() failed.\n"); + return -ENOMEM; + } + + slist = videobuf_vmalloc_to_sg(av7110->grabbing, pages); + if( NULL == slist ) { + vfree(av7110->grabbing); + dvb_unregister_i2c_bus (master_xfer,av7110->i2c_bus->adapter, av7110->i2c_bus->id); + dvb_unregister_adapter (av7110->dvb_adapter); + printk(KERN_ERR "dvb: videobuf_vmalloc_to_sg() failed.\n"); + return -ENOMEM; + } + + // fixme: is direction ok? + if( saa7146_pgtable_alloc(dev->pci, &av7110->pt)) { + kfree(slist); + vfree(av7110->grabbing); + dvb_unregister_i2c_bus (master_xfer,av7110->i2c_bus->adapter, av7110->i2c_bus->id); + dvb_unregister_adapter (av7110->dvb_adapter); + printk(KERN_ERR "dvb: saa7146_pgtable_alloc() failed.\n"); + return -ENOMEM; + } + + slen = pci_map_sg(dev->pci,slist,pages,PCI_DMA_FROMDEVICE); + saa7146_pgtable_build_single(dev->pci, &av7110->pt, slist, slen); + + saa7146_write(dev, PCI_BT_V1, 0x1c00101f); + saa7146_write(dev, BCS_CTRL, 0x80400040); + + /* set dd1 stream a & b */ + saa7146_write(dev, DD1_STREAM_B, 0x00000000); + saa7146_write(dev, DD1_INIT, 0x02000000); + saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); + + /* upload all */ + saa7146_write(dev, MC2, 0x077c077c); + saa7146_write(dev, GPIO_CTRL, 0x000000); tasklet_init (&av7110->debi_tasklet, debiirq, (unsigned long) av7110); tasklet_init (&av7110->gpio_tasklet, gpioirq, (unsigned long) av7110); @@ -4642,9 +4425,6 @@ int av7110_attach (struct saa7146 *saa, void **av7110_ptr) av7110->debilock=SPIN_LOCK_UNLOCKED; av7110->debitype=-1; - av7110->saa=(struct saa7146 *) saa; - av7110->saa_mem=av7110->saa->mem; - /* default ADAC type */ av7110->adac_type = adac; @@ -4665,14 +4445,14 @@ int av7110_attach (struct saa7146 *saa, void **av7110_ptr) /* allocate and init buffers */ - av7110->debi_virt=pci_alloc_consistent(av7110->saa->device, 8192, + av7110->debi_virt=pci_alloc_consistent(dev->pci, 8192, &av7110->debi_bus); if (!av7110->debi_virt) - return -1; + goto err; av7110->iobuf=vmalloc(AVOUTLEN+AOUTLEN+BMPLEN+4*IPACKS); if (!av7110->iobuf) - return -1; + goto err; ring_buffer_init(&av7110->avout, av7110->iobuf, AVOUTLEN); ring_buffer_init(&av7110->aout, av7110->iobuf+AVOUTLEN, AOUTLEN); @@ -4690,7 +4470,7 @@ int av7110_attach (struct saa7146 *saa, void **av7110_ptr) /* handle different card types */ /* load firmware into AV7110 cards */ - if (av7110->saa->card_type==DVB_CARD_TT_SIEMENS) { + if (av7110->card_type->type==DVB_CARD_TT_SIEMENS) { bootarm(av7110); firmversion(av7110); if ((av7110->arm_app&0xffff)<0x2502) { @@ -4698,22 +4478,22 @@ int av7110_attach (struct saa7146 *saa, void **av7110_ptr) } kernel_thread(arm_thread, (void *) av7110, 0); } else { - saa7146_write(av7110->saa_mem, DD1_INIT, 0x02000600); - saa7146_write(av7110->saa_mem, MC2, + saa7146_write(av7110->dev, DD1_INIT, 0x02000600); + saa7146_write(av7110->dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); setgpio(av7110, 2, GPIO_OUTHI); /* frontend power on */ } SetVolume(av7110, 0xff, 0xff); - if (av7110->saa->card_type==DVB_CARD_TT_SIEMENS) { + if (av7110->card_type->type==DVB_CARD_TT_SIEMENS) { VidMode(av7110, vidmode); /* remaining inits according to card and frontend type */ if (i2c_writereg(av7110, 0x20, 0x00, 0x00)==1) { dprintk("av7110%d: Crystal audio DAC detected\n", - av7110->saa->dvb_adapter->num); + av7110->dvb_adapter->num); av7110->adac_type = DVB_ADAC_CRYSTAL; i2c_writereg(av7110, 0x20, 0x01, 0xd2); i2c_writereg(av7110, 0x20, 0x02, 0x49); @@ -4724,7 +4504,7 @@ int av7110_attach (struct saa7146 *saa, void **av7110_ptr) /** * some special handling for the Siemens DVB-C card... */ - if (av7110->saa->device->subsystem_vendor == 0x110a) { + if (dev->pci->subsystem_vendor == 0x110a) { if (i2c_writereg(av7110, 0x80, 0x0, 0x80)==1) { i2c_writereg(av7110, 0x80, 0x0, 0); printk("av7110: DVB-C analog module detected, " @@ -4747,19 +4527,24 @@ int av7110_attach (struct saa7146 *saa, void **av7110_ptr) //setgpio(av7110, 3, GPIO_OUTLO); // SCARTpin 8 av7110->adac_type = DVB_ADAC_NONE; } - } - + } + av7110_setup_irc_config (av7110, 0); dvb_register(av7110); - + + av7110_num++; return 0; -} +err: + dvb_unregister_i2c_bus (master_xfer,av7110->i2c_bus->adapter, av7110->i2c_bus->id); + dvb_unregister_adapter (av7110->dvb_adapter); + return -1; +} static -int av7110_detach (struct saa7146 *saa, void** av7110_ptr) +int av7110_detach (struct saa7146_dev* saa) { - struct av7110_s *av7110 = *av7110_ptr; + av7110_t *av7110 = (av7110_t*)saa->ext_priv; av7110->arm_rmmod=1; wake_up_interruptible(&av7110->arm_wait); @@ -4768,116 +4553,139 @@ int av7110_detach (struct saa7146 *saa, void** av7110_ptr) ddelay(1); dvb_unregister(av7110); - - saa7146_write (av7110->saa_mem, IER, - saa7146_read(av7110->saa_mem, IER) & ~(MASK_19 | MASK_03)); - saa7146_write(av7110->saa_mem, ISR,(MASK_19 | MASK_03)); + IER_DISABLE(saa, (MASK_19 | MASK_03)); +// saa7146_write (av7110->dev, IER, +// saa7146_read(av7110->dev, IER) & ~(MASK_19 | MASK_03)); + + saa7146_write(av7110->dev, ISR,(MASK_19 | MASK_03)); ci_ll_release(&av7110->ci_rbuffer, &av7110->ci_wbuffer); dvb_filter_ipack_free(&av7110->ipack[0]); dvb_filter_ipack_free(&av7110->ipack[1]); vfree(av7110->iobuf); - pci_free_consistent(av7110->saa->device, 8192, av7110->debi_virt, + pci_free_consistent(saa->pci, 8192, av7110->debi_virt, av7110->debi_bus); + saa7146_pgtable_free(saa->pci, &av7110->pt); + + dvb_unregister_i2c_bus (master_xfer,av7110->i2c_bus->adapter, av7110->i2c_bus->id); + dvb_unregister_adapter (av7110->dvb_adapter); + kfree (av7110); - *av7110_ptr = NULL; + saa->ext_priv = NULL; + av7110_num--; + return 0; } static -void av7110_irq(struct saa7146 *saa, u32 isr, void *data) +void av7110_irq(struct saa7146_dev* dev, u32 *isr) { - struct av7110_s *av7110 = (struct av7110_s*) data; + av7110_t *av7110 = (av7110_t*)dev->ext_priv; - if (isr & MASK_19) + if (*isr & MASK_19) tasklet_schedule (&av7110->debi_tasklet); - if (isr & MASK_03) + if (*isr & MASK_03) tasklet_schedule (&av7110->gpio_tasklet); - if (isr & MASK_10) + if (*isr & MASK_10) tasklet_schedule (&av7110->vpe_tasklet); - if (isr & MASK_07) + if (*isr & MASK_07) tasklet_schedule (&av7110->fidb_tasklet); } - -static -int av7110_command(struct saa7146 *saa, void *p, unsigned int cmd, void *arg) -{ - switch(cmd) { - case SAA7146_SUSPEND: - printk("dvb_suspend()\n"); - break; - case SAA7146_RESUME: - printk("dvb_resume()\n"); - break; - default: - return -ENOIOCTLCMD; - } - return 0; -} - - +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51) static -void av7110_inc_use(struct saa7146* adap) +void av7110_inc_use(struct saa7146_dev* adap) { MOD_INC_USE_COUNT; } - static -void av7110_dec_use(struct saa7146* adap) +void av7110_dec_use(struct saa7146_dev* adap) { MOD_DEC_USE_COUNT; } +#endif +struct saa7146_standard standard[] = { + { "PAL", V4L2_STD_PAL, 0x15, 288, 576, 0x3a, 720, 721, 576, 768 }, +/* fixme: more to come here */ +}; static struct saa7146_extension av7110_extension = { - "dvb extension\0", - MASK_07|MASK_10|MASK_19|MASK_03|MASK_27, - av7110_irq, - av7110_command, + "dvb\0", + 1, /* inputs */ + 1, /* audios */ + 0, /* additional capabilities: none */ + + &sub_data[0], + + THIS_MODULE, + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51) + av7110_inc_use, + av7110_dec_use, +#endif + + &standard[0], + sizeof(standard)/sizeof(struct saa7146_standard), + NULL, + + 0, /* don't use kernel i2c */ + NULL, /* don't provide vbi, no bypass */ + + &ioctls[0], + + av7110_preinit, + av7110_probe, + av7110_attach, av7110_detach, - av7110_inc_use, - av7110_dec_use -}; + av7110_ioctl, + + MASK_07|MASK_10|MASK_19|MASK_03|MASK_27, + av7110_irq, +}; int __init av7110_init(void) { int result = 0; - if ((result = saa7146_add_extension(&av7110_extension))) { - printk("%s: saa7146_add_extension() failed!\n", - __FUNCTION__); - return result; + if( 0 != saa7146_register_extension(&av7110_extension)) { + return -ENODEV; + } + + if( 0 == av7110_num ) { + printk(KERN_ERR "no av7110(s) found.\n"); + return -ENODEV; } + printk(KERN_INFO "%d av7110(s) found.\n", av7110_num); return result; } - void __exit av7110_exit(void) { - if (saa7146_del_extension(&av7110_extension)) + if (saa7146_unregister_extension(&av7110_extension)) printk(KERN_ERR "dvb: extension deregistration failed.\n"); } -//MODULE_DESCRIPTION("driver for the SAA7146 based AV110 PCI DVB cards by " -// "Siemens, Technotrend, Hauppauge"); -//MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, others"); -//MODULE_LICENSE("GPL"); +module_init(av7110_init); +module_exit(av7110_exit); + +MODULE_DESCRIPTION("driver for the SAA7146 based AV110 PCI DVB cards by " + "Siemens, Technotrend, Hauppauge"); +MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, others"); +MODULE_LICENSE("GPL"); MODULE_PARM(av7110_debug,"i"); -MODULE_PARM(vidmem,"l"); -MODULE_PARM(vidlow,"l"); MODULE_PARM(vidmode,"i"); MODULE_PARM(pids_off,"i"); MODULE_PARM(adac,"i"); diff --git a/linux/drivers/media/dvb/av7110/av7110.h b/linux/drivers/media/dvb/av7110/av7110.h index 9d285e483..8987b8de1 100644 --- a/linux/drivers/media/dvb/av7110/av7110.h +++ b/linux/drivers/media/dvb/av7110/av7110.h @@ -4,7 +4,6 @@ #define DVB_FIRM_PATH "/lib/DVB/" #include <linux/interrupt.h> -#include <linux/videodev.h> #include <linux/socket.h> #include <linux/netdevice.h> @@ -12,6 +11,8 @@ #include <linux/devfs_fs_kernel.h> #endif +#include "saa7146.h" + /* DEBI transfer mode defs */ #define DEBINOSWAP 0x000e0000 @@ -22,24 +23,8 @@ #define ARM_WAIT_SHAKE (HZ/5) #define ARM_WAIT_OSD (HZ) -#if LINUX_VERSION_CODE < 0x020300 -#define net_device device -#define DECLARE_MUTEX(foo) struct semaphore foo = MUTEX -#define DECLARE_MUTEX_LOCKED(foo) struct semaphore foo = MUTEX_LOCKED -#define WAIT_QUEUE struct wait_queue* -#define init_waitqueue_head(wq) *(wq) = NULL; -#define DECLARE_WAITQUEUE(wait, current) struct wait_queue wait = { current, NULL } -#define set_current_state(state_value) \ - do { current->state = state_value; } while (0) -#define list_for_each(pos, head) \ - for (pos = (head)->next; pos != (head); pos = pos->next) - -#else - #define WAIT_QUEUE wait_queue_head_t -#endif - #include <linux/dvb/video.h> #include <linux/dvb/audio.h> #include <linux/dvb/dmx.h> @@ -54,6 +39,10 @@ #include "dvb_filter.h" #include "dvb_net.h" +#define DVB_CARD_TT_SIEMENS 0 +#define DVB_CARD_TT_BUDGET 1 +#define DVB_CARD_TT_BUDGET_CI 2 +#define DVB_CARD_KNC1 3 typedef enum BOOTSTATES { @@ -482,6 +471,10 @@ typedef struct p2t_s { struct dvb_demux_feed *feed; } p2t_t; +struct card_info { + int type; + char *name; +}; /* place to store all the necessary device information */ typedef struct av7110_s { @@ -492,7 +485,13 @@ typedef struct av7110_s { dvb_net_t dvb_net; struct video_device video; - struct saa7146 *saa; + struct saa7146_dev *dev; + + struct dvb_i2c_bus *i2c_bus; + struct card_info *card_type; + + unsigned char *grabbing; + struct saa7146_pgtable pt; struct tasklet_struct debi_tasklet; struct tasklet_struct gpio_tasklet; @@ -611,7 +610,6 @@ typedef struct av7110_s { u16 arm_loops; int arm_rmmod; - void *saa_mem; void *debi_virt; dma_addr_t debi_bus; |