V4L/DVB (7390): saa7134: clear audio DSP interface after access error
authorHartmut Hackmann <hartmut.hackmann@t-online.de>
Tue, 22 Apr 2008 17:46:07 +0000 (14:46 -0300)
committerMauro Carvalho Chehab <mchehab@infradead.org>
Thu, 24 Apr 2008 17:07:52 +0000 (14:07 -0300)
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>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
drivers/media/video/saa7134/saa7134-reg.h
drivers/media/video/saa7134/saa7134-tvaudio.c

index ac6431ba4fc37e9467b1c43b3ebb76582ff424f1..86f5eefdb0f6d94f5f245e4ded082688e91f975c 100644 (file)
 #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:
index b90c55c0536e06132d9f8207adb97ce10fc5957f..232af598d94709a9d66ef0bd898f13efca3cffeb 100644 (file)
@@ -653,6 +653,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)
 {
@@ -660,8 +671,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)) {