aboutsummaryrefslogtreecommitdiff
path: root/drivers/media/dvb/b2c2/flexcop.c
diff options
context:
space:
mode:
authorPatrick Boettcher <pb@linuxtv.org>2005-07-07 17:57:49 -0700
committerLinus Torvalds <torvalds@g5.osdl.org>2005-07-07 18:23:56 -0700
commit64221be7b9006338e4a45228f013e467ee4bf045 (patch)
treeacf137799c31c966f6d8083aee39c27f331905ab /drivers/media/dvb/b2c2/flexcop.c
parent2819639b5630cd26d399ee0481be9a752280cf4d (diff)
[PATCH] dvb: flexcop: woraround irq stop problem
The flexcop chip often stops generating interrupts after some hours of operation. Apparently this can be fixed by resetting register block 0x300 at each channel change (this is not detailed in the flexcop data books). This patch also restructures DMA handling and adds a bit of debug code for the irq problem in case it still happens for someone. Signed-off-by: Patrick Boettcher <pb@linuxtv.org> Signed-off-by: Johannes Stezenbach <js@linuxtv.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/media/dvb/b2c2/flexcop.c')
-rw-r--r--drivers/media/dvb/b2c2/flexcop.c34
1 files changed, 32 insertions, 2 deletions
diff --git a/drivers/media/dvb/b2c2/flexcop.c b/drivers/media/dvb/b2c2/flexcop.c
index 8b5d14dd36e..12873d43540 100644
--- a/drivers/media/dvb/b2c2/flexcop.c
+++ b/drivers/media/dvb/b2c2/flexcop.c
@@ -46,7 +46,7 @@
int b2c2_flexcop_debug;
module_param_named(debug, b2c2_flexcop_debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debug level (1=info,2=tuner,4=i2c,8=ts,16=sram (|-able))." DEBSTATUS);
+MODULE_PARM_DESC(debug, "set debug level (1=info,2=tuner,4=i2c,8=ts,16=sram,32=reg (|-able))." DEBSTATUS);
#undef DEBSTATUS
/* global zero for ibi values */
@@ -173,9 +173,20 @@ static void flexcop_reset(struct flexcop_device *fc)
fc->write_ibi_reg(fc,ctrl_208,ibi_zero);
v210.raw = 0;
- v210.sw_reset_210.reset_blocks = 0xff;
+ v210.sw_reset_210.reset_block_000 = 1;
+ v210.sw_reset_210.reset_block_100 = 1;
+ v210.sw_reset_210.reset_block_200 = 1;
+ v210.sw_reset_210.reset_block_300 = 1;
+ v210.sw_reset_210.reset_block_400 = 1;
+ v210.sw_reset_210.reset_block_500 = 1;
+ v210.sw_reset_210.reset_block_600 = 1;
+ v210.sw_reset_210.reset_block_700 = 1;
v210.sw_reset_210.Block_reset_enable = 0xb2;
+
+ v210.sw_reset_210.Special_controls = 0xc259;
+
fc->write_ibi_reg(fc,sw_reset_210,v210);
+ msleep(1);
/* reset the periphical devices */
@@ -186,6 +197,25 @@ static void flexcop_reset(struct flexcop_device *fc)
fc->write_ibi_reg(fc,misc_204,v204);
}
+void flexcop_reset_block_300(struct flexcop_device *fc)
+{
+ flexcop_ibi_value v208_save = fc->read_ibi_reg(fc,ctrl_208),
+ v210 = fc->read_ibi_reg(fc,sw_reset_210);
+
+ deb_rdump("208: %08x, 210: %08x\n",v208_save.raw,v210.raw);
+
+ fc->write_ibi_reg(fc,ctrl_208,ibi_zero);
+
+ v210.sw_reset_210.reset_block_300 = 1;
+ v210.sw_reset_210.Block_reset_enable = 0xb2;
+
+ fc->write_ibi_reg(fc,sw_reset_210,v210);
+ msleep(1);
+
+ fc->write_ibi_reg(fc,ctrl_208,v208_save);
+}
+EXPORT_SYMBOL(flexcop_reset_block_300);
+
struct flexcop_device *flexcop_device_kmalloc(size_t bus_specific_len)
{
void *bus;