summaryrefslogtreecommitdiff
path: root/linux/drivers
diff options
context:
space:
mode:
authorMichael Hunold <devnull@localhost>2003-01-05 21:49:06 +0000
committerMichael Hunold <devnull@localhost>2003-01-05 21:49:06 +0000
commit23198c11bc5d221469b73ce5def50b7d4dbbff81 (patch)
tree3806b08353aec9686d90bbcfb227fb1fe4a61785 /linux/drivers
parenta721eb6c53f0402661b3549ec99701c15714beca (diff)
downloadmediapointer-dvb-s2-23198c11bc5d221469b73ce5def50b7d4dbbff81.tar.gz
mediapointer-dvb-s2-23198c11bc5d221469b73ce5def50b7d4dbbff81.tar.bz2
After all, using the i2c irq wasn't a good idea. After long hours of
testing why the !#+?ยง"1 TS stream stops and "debi oops" messages appear, I found out that this is caused by the i2c irq handler. Don't ask me why, but returning to the old code solved this mystery. Apparently, the additional i2c interrupts caused some timing problems or the saa7146 is simply too f*cked up. I left the code in however, it works for the analog MXB driver, so the extension should decide if it should be used. Removed some additional debug messages, which were commented out anyway.
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,