Browse Source

V4L/DVB (7390): saa7134: clear audio DSP interface after access error

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>
Hartmut Hackmann 17 years ago
parent
commit
867bc6cccc

+ 3 - 0
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:

+ 13 - 2
drivers/media/video/saa7134/saa7134-tvaudio.c

@@ -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)) {