diff options
Diffstat (limited to 'linux/drivers')
-rw-r--r-- | linux/drivers/media/common/saa7146.h | 6 | ||||
-rw-r--r-- | linux/drivers/media/common/saa7146_core.c | 11 | ||||
-rw-r--r-- | linux/drivers/media/common/saa7146_i2c.c | 89 | ||||
-rw-r--r-- | linux/drivers/media/dvb/ttpci/av7110.c | 67 | ||||
-rw-r--r-- | linux/drivers/media/video/mxb.c | 2 |
5 files changed, 72 insertions, 103 deletions
diff --git a/linux/drivers/media/common/saa7146.h b/linux/drivers/media/common/saa7146.h index b5ee99d64..39ecdda33 100644 --- a/linux/drivers/media/common/saa7146.h +++ b/linux/drivers/media/common/saa7146.h @@ -73,6 +73,9 @@ struct saa7146_pgtable { struct saa7146_extension { char name[32]; /* name of the device */ +#define SAA7146_USE_I2C_IRQ 0x1 + int flags; + struct saa7146_ext_vv *ext_vv_data; struct list_head item; @@ -80,8 +83,7 @@ struct saa7146_extension /* pairs of subvendor and subdevice ids for supported devices, last entry 0xffff, 0xfff */ struct saa7146_sub_info *devices; - - struct module* module; + struct module *module; #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51) void (*inc_use)(struct saa7146_dev*); diff --git a/linux/drivers/media/common/saa7146_core.c b/linux/drivers/media/common/saa7146_core.c index bd079b0e5..f064b49d0 100644 --- a/linux/drivers/media/common/saa7146_core.c +++ b/linux/drivers/media/common/saa7146_core.c @@ -180,12 +180,12 @@ static void interrupt_hw(int irq, void *dev_id, struct pt_regs *regs) DEB_I2C(("irq: i2c, status: 0x%08x, psr:0x%02x, ssr:0x%02x).\n",status,psr,ssr)); dev->i2c_op = 0; wake_up(&dev->i2c_wq); - } - else + } else { DEB_I2C(("unexpected irq: i2c, status: 0x%08x, isr %#x\n",status, isr)); - } - else + } + } else { DEB_I2C(("unhandled irq: i2c, status: 0x%08x, isr %#x\n",status, isr)); + } isr &= ~(MASK_16|MASK_17); } if( 0 != isr ) { @@ -229,14 +229,15 @@ void try_attach_extension_and_device(struct saa7146_dev *dev, struct saa7146_ext return; } + dev->ext = ext; if( 0 != ext->probe) { if( 0 != ext->probe(dev, dev->pci->subsystem_vendor, dev->pci->subsystem_device) ) { DEB_D(("ext->probe() failed for %p. skipping device.\n",dev)); + dev->ext = NULL; return; } } - dev->ext = ext; if( 0 != ext->attach(dev, &ext->devices[i]) ) { DEB_D(("ext->attach() failed for %p. skipping device.\n",dev)); dev->ext = NULL; diff --git a/linux/drivers/media/common/saa7146_i2c.c b/linux/drivers/media/common/saa7146_i2c.c index 8a8c86265..9a62cb176 100644 --- a/linux/drivers/media/common/saa7146_i2c.c +++ b/linux/drivers/media/common/saa7146_i2c.c @@ -7,10 +7,8 @@ static void my_wait(struct saa7146_dev *dev, long ms) { - unsigned long timeout = jiffies + ((ms+9)/10); - while(time_before(jiffies, timeout)) { - schedule(); - } + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout((((ms+10)/10)*HZ)/1000); } u32 saa7146_i2c_func(struct i2c_adapter *adapter) @@ -188,74 +186,53 @@ int saa7146_i2c_reset(struct saa7146_dev *dev) return 0; } -static int use_i2c_irq = 1; - /* this functions writes out the data-byte 'dword' to the i2c-device. it returns 0 if ok, -1 if the transfer failed, -2 if the transfer failed badly (e.g. address error) */ static int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword) { - int i = 0; u32 status = 0, mc2 = 0; - const int timeout = SAA7146_I2C_TIMEOUT * HZ / 1000; /* write out i2c-command */ -if( 0 != use_i2c_irq ) { - dev->i2c_op = 1; DEB_I2C(("before: 0x%08x (status: 0x%08x), %d\n",*dword,saa7146_read(dev, I2C_STATUS), dev->i2c_op)); - saa7146_write(dev, I2C_STATUS, dev->i2c_bitrate); - saa7146_write(dev, I2C_TRANSFER, *dword); - IER_ENABLE(dev, MASK_17); - saa7146_write(dev, MC2, (MASK_00 | MASK_16)); + if( 0 != (SAA7146_USE_I2C_IRQ & dev->ext->flags)) { - interruptible_sleep_on_timeout(&dev->i2c_wq, timeout); - if( 0 != dev->i2c_op ) { - DEB_I2C(("error: i2c timeout\n")); - dev->i2c_op = 0; - status = saa7146_read(dev, I2C_STATUS); - if( 0 != (status & SAA7146_I2C_APERR) ) { - DEB_I2C(("timeout in address phase.\n")); - return -2; + saa7146_write(dev, I2C_STATUS, dev->i2c_bitrate); + saa7146_write(dev, I2C_TRANSFER, *dword); + + dev->i2c_op = 1; + IER_ENABLE(dev, MASK_16|MASK_17); + saa7146_write(dev, MC2, (MASK_00 | MASK_16)); + + wait_event_interruptible(dev->i2c_wq, dev->i2c_op == 0); + if (signal_pending (current)) { + /* a signal arrived */ + return -ERESTARTSYS; } - return -1; - } - status = saa7146_read(dev, I2C_STATUS); -} else { - saa7146_write(dev, I2C_STATUS, dev->i2c_bitrate); - saa7146_write(dev, I2C_TRANSFER, *dword); - saa7146_write(dev, MC2, (MASK_00 | MASK_16)); - - /* do not poll for i2c-status before upload is complete */ - for (i = 5; i > 0; i--) { - mc2 = (saa7146_read(dev, MC2) & 0x1); - if( 0 != mc2 ) - break; - my_wait(dev,SAA7146_I2C_DELAY); - } - if (0 == i) { - DEB_I2C(("timeout error. #1\n")); - return -1; - } + status = saa7146_read(dev, I2C_STATUS); + } else { + saa7146_write(dev, I2C_STATUS, dev->i2c_bitrate); + saa7146_write(dev, I2C_TRANSFER, *dword); + saa7146_write(dev, MC2, (MASK_00 | MASK_16)); - /* wait until busy flag becomes inactive or we time out */ - for (i = 5; i > 0; i--) { - status = saa7146_i2c_status(dev); - /* check busy flag */ - if ( 0 == (status & SAA7146_I2C_BUSY)) - break; - /* check error flag */ - if ( 0 != (status & SAA7146_I2C_ERR)) { - break; + /* do not poll for i2c-status before upload is complete */ + while(1) { + mc2 = (saa7146_read(dev, MC2) & 0x1); + if( 0 != mc2 ) { + break; + } + } + /* wait until we get a transfer done or error */ + while(1) { + status = saa7146_i2c_status(dev); + if( (0x3 == (status & 0x3)) || (0 == (status & 0x1)) ) { + break; + } + my_wait(dev,1); } - my_wait(dev,SAA7146_I2C_DELAY); - } - if (0 == i) { - DEB_I2C(("timeout error. #2\n")); - return -1; } -} /* give a detailed status report */ if ( 0 != (status & SAA7146_I2C_ERR)) { diff --git a/linux/drivers/media/dvb/ttpci/av7110.c b/linux/drivers/media/dvb/ttpci/av7110.c index 113e7d968..369542f6d 100644 --- a/linux/drivers/media/dvb/ttpci/av7110.c +++ b/linux/drivers/media/dvb/ttpci/av7110.c @@ -166,8 +166,6 @@ static int debiwrite(av7110_t *av7110, u32 config, struct saa7146_dev *dev = av7110->dev; u32 cmd; -// DEB_EE(("av7110: %p\n",av7110)); - if (count <= 0 || count > 32764) return -1; if (wait_for_debi_done(av7110) < 0) @@ -187,8 +185,6 @@ static u32 debiread(av7110_t *av7110, u32 config, int addr, int count) struct saa7146_dev *dev = av7110->dev; u32 result = 0; -// DEB_EE(("av7110: %p\n",av7110)); - if (count > 32764 || count <= 0) return 0; if (wait_for_debi_done(av7110) < 0) @@ -280,24 +276,18 @@ ARM_ResetMailBox(av7110_t *av7110) static inline void ARM_ClearMailBox(av7110_t *av7110) { - DEB_EE(("av7110: %p\n",av7110)); - iwdebi(av7110, DEBINOSWAP, IRQ_RX, 0, 2); } static inline void ARM_ClearIrq(av7110_t *av7110) { - DEB_EE(("av7110: %p\n",av7110)); - irdebi(av7110, DEBINOSWAP, IRQ_RX, 0, 2); } static void reset_arm(av7110_t *av7110) { - DEB_EE(("av7110: %p\n",av7110)); - saa7146_setgpio(av7110->dev, RESET_LINE, SAA7146_GPIO_OUTLO); /* Disable DEBI and GPIO irq */ @@ -356,7 +346,10 @@ static int arm_thread(void *data) lock_kernel(); #if 0 - daemonize(); + daemonize(); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51) + reparent_to_init (); +#endif #else exit_mm(current); current->session=current->pgrp=1; @@ -880,13 +873,12 @@ void debiirq (unsigned long data) struct av7110_s *av7110 = (struct av7110_s*) data; int type=av7110->debitype; int handle=(type>>8)&0x1f; - - DEB_EE(("av7110: %p\n",av7110)); + +// DEB_EE(("av7110: %p\n",av7110)); print_time("debi"); - IER_DISABLE(av7110->dev, MASK_19); -// saa7146_write(av7110->dev, IER, -// saa7146_read(av7110->dev, IER) & ~MASK_19 ); + saa7146_write(av7110->dev, IER, + saa7146_read(av7110->dev, IER) & ~MASK_19 ); saa7146_write(av7110->dev, ISR, MASK_19 ); if (type==-1) { @@ -1063,6 +1055,7 @@ pes_play(void *dest, ring_buffer_t *buf, int dlen) return blen; } + static void gpioirq (unsigned long data) { @@ -1070,19 +1063,17 @@ void gpioirq (unsigned long data) u32 rxbuf, txbuf; int len; - DEB_EE(("av7110: %p\n",av7110)); + //printk("GPIO0 irq\n"); - if (av7110->debitype !=-1) { + if (av7110->debitype !=-1) printk("GPIO0 irq oops @ %ld, psr:0x%08x, ssr:0x%08x\n",jiffies,saa7146_read(av7110->dev,PSR),saa7146_read(av7110->dev,SSR)); - } - + spin_lock(&av7110->debilock); ARM_ClearIrq(av7110); - IER_DISABLE(av7110->dev, MASK_19); -// saa7146_write(av7110->dev, IER, -// saa7146_read(av7110->dev, IER) & ~MASK_19 ); + 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); @@ -1095,7 +1086,7 @@ void gpioirq (unsigned long data) DEB_D(("GPIO0 irq %d %d\n", av7110->debitype, av7110->debilen)); print_time("gpio"); - DEB_D(("GPIO0 irq %02x\n", av7110->debitype&0xff)); + DEB_D(("GPIO0 irq %02x\n", av7110->debitype&0xff)); switch (av7110->debitype&0xff) { case DATA_TS_PLAY: @@ -1140,9 +1131,8 @@ 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); - IER_ENABLE(av7110->dev, MASK_19); -// saa7146_write(av7110->dev, IER, -// saa7146_read(av7110->dev, IER) | 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); @@ -1174,13 +1164,12 @@ void gpioirq (unsigned long data) iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2); break; } - DEB_D(("GPIO0 PES_PLAY len=%04x\n", len)); + DEB_D(("GPIO0 PES_PLAY len=%04x\n", len)); iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2); iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2); wait_for_debi_done(av7110); - IER_ENABLE(av7110->dev, MASK_19); -// saa7146_write(av7110->dev, IER, -// saa7146_read(av7110->dev, IER) | 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); @@ -1206,9 +1195,8 @@ void gpioirq (unsigned long data) av7110->bmpp+=len; av7110->bmplen-=len; wait_for_debi_done(av7110); - IER_ENABLE(av7110->dev, MASK_19); -// saa7146_write(av7110->dev, IER, -// saa7146_read(av7110->dev, IER) | 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); @@ -1226,9 +1214,8 @@ void gpioirq (unsigned long data) case DATA_TS_RECORD: case DATA_PES_RECORD: wait_for_debi_done(av7110); - IER_ENABLE(av7110->dev, MASK_19); -// saa7146_write(av7110->dev, IER, -// saa7146_read(av7110->dev, IER) | 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; @@ -1239,9 +1226,8 @@ void gpioirq (unsigned long data) iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2); break; } - IER_ENABLE(av7110->dev, MASK_19); -// saa7146_write(av7110->dev, IER, -// saa7146_read(av7110->dev, IER) | 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; @@ -4500,6 +4486,7 @@ struct saa7146_ext_vv av7110_vv_data = { static struct saa7146_extension av7110_extension = { .name = "dvb\0", + .flags = 0, .devices = &sub_data[0], .module = THIS_MODULE, diff --git a/linux/drivers/media/video/mxb.c b/linux/drivers/media/video/mxb.c index 38538a0fb..a65f6ebff 100644 --- a/linux/drivers/media/video/mxb.c +++ b/linux/drivers/media/video/mxb.c @@ -1021,6 +1021,8 @@ struct saa7146_ext_vv vv_data = { static struct saa7146_extension extension = { .name = MXB_IDENTIFIER, + .flags = SAA7146_USE_I2C_IRQ, + .devices = &sub_data[0], .module = THIS_MODULE, .ext_vv_data = &vv_data, |