diff options
author | Hartmut Hackmann <hartmut.hackmann@t-online.de> | 2008-03-02 02:41:06 +0100 |
---|---|---|
committer | Hartmut Hackmann <hartmut.hackmann@t-online.de> | 2008-03-02 02:41:06 +0100 |
commit | e2f6f6c5ed1355bc0d7f06dbf83fe335efaf25a2 (patch) | |
tree | d524cc6397ea03863f5a868fa66a4f6dfcf9a427 | |
parent | a6d070732dd73977030e19c3bae51fc1c90a5a6c (diff) | |
download | mediapointer-dvb-s2-e2f6f6c5ed1355bc0d7f06dbf83fe335efaf25a2.tar.gz mediapointer-dvb-s2-e2f6f6c5ed1355bc0d7f06dbf83fe335efaf25a2.tar.bz2 |
saa7134: clear audio DSP interface after access error
From: Hartmut Hackmann <hartmut.hackmann@t-online.de>
In the case of an access error to the high latency registers of
the audio DSP, the interface needs to be cleared, otherwise a cascade
of errors occurs.
This patch is closely modeled after a proposal by Mirek Slugen
Signed-off-by: Hartmut Hackmann <hartmut.hackmann@t-online.de>
-rw-r--r-- | linux/drivers/media/video/saa7134/saa7134-reg.h | 3 | ||||
-rw-r--r-- | linux/drivers/media/video/saa7134/saa7134-tvaudio.c | 15 |
2 files changed, 16 insertions, 2 deletions
diff --git a/linux/drivers/media/video/saa7134/saa7134-reg.h b/linux/drivers/media/video/saa7134/saa7134-reg.h index ac6431ba4..86f5eefdb 100644 --- a/linux/drivers/media/video/saa7134/saa7134-reg.h +++ b/linux/drivers/media/video/saa7134/saa7134-reg.h @@ -365,6 +365,9 @@ #define SAA7135_DSP_RWSTATE_RDB (1 << 1) #define SAA7135_DSP_RWSTATE_WRR (1 << 0) +#define SAA7135_DSP_RWCLEAR 0x586 +#define SAA7135_DSP_RWCLEAR_RERR 1 + /* ------------------------------------------------------------------ */ /* * Local variables: diff --git a/linux/drivers/media/video/saa7134/saa7134-tvaudio.c b/linux/drivers/media/video/saa7134/saa7134-tvaudio.c index 91d57ea5f..0d24ab598 100644 --- a/linux/drivers/media/video/saa7134/saa7134-tvaudio.c +++ b/linux/drivers/media/video/saa7134/saa7134-tvaudio.c @@ -681,6 +681,17 @@ static char *stdres[0x20] = { #define DSP_RETRY 32 #define DSP_DELAY 16 +#define SAA7135_DSP_RWCLEAR_RERR 1 + +static inline int saa_dsp_reset_error_bit(struct saa7134_dev *dev) +{ + int state = saa_readb(SAA7135_DSP_RWSTATE); + if (unlikely(state & SAA7135_DSP_RWSTATE_ERR)) { + d2printk("%s: resetting error bit\n", dev->name); + saa_writeb(SAA7135_DSP_RWCLEAR, SAA7135_DSP_RWCLEAR_RERR); + } + return 0; +} static inline int saa_dsp_wait_bit(struct saa7134_dev *dev, int bit) { @@ -688,8 +699,8 @@ static inline int saa_dsp_wait_bit(struct saa7134_dev *dev, int bit) state = saa_readb(SAA7135_DSP_RWSTATE); if (unlikely(state & SAA7135_DSP_RWSTATE_ERR)) { - printk("%s: dsp access error\n",dev->name); - /* FIXME: send ack ... */ + printk(KERN_WARNING "%s: dsp access error\n", dev->name); + saa_dsp_reset_error_bit(dev); return -EIO; } while (0 == (state & bit)) { |