summaryrefslogtreecommitdiff
path: root/linux/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'linux/drivers')
-rw-r--r--linux/drivers/media/common/saa7146.h6
-rw-r--r--linux/drivers/media/common/saa7146_core.c11
-rw-r--r--linux/drivers/media/common/saa7146_i2c.c89
-rw-r--r--linux/drivers/media/dvb/ttpci/av7110.c67
-rw-r--r--linux/drivers/media/video/mxb.c2
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,