summaryrefslogtreecommitdiff
path: root/linux/drivers/media/video/em28xx
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@infradead.org>2008-02-06 16:34:13 -0200
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-02-06 16:34:13 -0200
commitdb10010189a9bdd6f1bbb39f5c575169c139ea7b (patch)
tree0d77f2df65bd5fc4aa6e4ed280846c2fb3a23311 /linux/drivers/media/video/em28xx
parentdc7b5fd0a294c2db79154467e4c635a039849ab3 (diff)
downloadmediapointer-dvb-s2-db10010189a9bdd6f1bbb39f5c575169c139ea7b.tar.gz
mediapointer-dvb-s2-db10010189a9bdd6f1bbb39f5c575169c139ea7b.tar.bz2
em28xx: makes audio settings more stable
From: Mauro Carvalho Chehab <mchehab@infradead.org> Improves audio configurations on em28xx: - mutes audio before changing amux; - adds a delay after setting audio src; - waits up to 50ms for ac97 busy. Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'linux/drivers/media/video/em28xx')
-rw-r--r--linux/drivers/media/video/em28xx/em28xx-core.c28
-rw-r--r--linux/drivers/media/video/em28xx/em28xx-video.c3
2 files changed, 21 insertions, 10 deletions
diff --git a/linux/drivers/media/video/em28xx/em28xx-core.c b/linux/drivers/media/video/em28xx/em28xx-core.c
index f2686bde0..441413016 100644
--- a/linux/drivers/media/video/em28xx/em28xx-core.c
+++ b/linux/drivers/media/video/em28xx/em28xx-core.c
@@ -306,21 +306,26 @@ static int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val,
*/
static int em28xx_write_ac97(struct em28xx *dev, u8 reg, u8 *val)
{
- int ret;
+ int ret, i;
u8 addr = reg & 0x7f;
if ((ret = em28xx_write_regs(dev, AC97LSB_REG, val, 2)) < 0)
return ret;
if ((ret = em28xx_write_regs(dev, AC97ADDR_REG, &addr, 1)) < 0)
return ret;
- if ((ret = em28xx_read_reg(dev, AC97BUSY_REG)) < 0)
- return ret;
- else if (((u8) ret) & 0x01) {
- em28xx_warn ("AC97 command still being executed: not handled properly!\n");
+
+ /* Wait up to 50 ms for AC97 command to complete */
+ for (i = 0; i < 10; i++) {
+ if ((ret = em28xx_read_reg(dev, AC97BUSY_REG)) < 0)
+ return ret;
+ if (!((u8) ret) & 0x01)
+ return 0;
+ msleep(5);
}
+ em28xx_warn ("AC97 command still being executed: not handled properly!\n");
return 0;
}
-int em28xx_set_audio_source(struct em28xx *dev)
+static int em28xx_set_audio_source(struct em28xx *dev)
{
static char *enable = "\x08\x08";
static char *disable = "\x08\x88";
@@ -363,6 +368,7 @@ int em28xx_set_audio_source(struct em28xx *dev)
ret = em28xx_write_reg_bits(dev, AUDIOSRC_REG, input, 0xc0);
if (ret < 0)
return ret;
+ msleep(5);
/* Sets AC97 mixer registers
This is seems to be needed, even for non-ac97 configs
@@ -385,9 +391,10 @@ int em28xx_audio_analog_set(struct em28xx *dev)
s[0] |= 0x1f - dev->volume;
s[1] |= 0x1f - dev->volume;
- if (dev->mute)
- s[1] |= 0x80;
+ /* Mute */
+ s[1] |= 0x80;
ret = em28xx_write_ac97(dev, MASTER_AC97, s);
+
if (ret < 0)
return ret;
@@ -405,6 +412,11 @@ int em28xx_audio_analog_set(struct em28xx *dev)
/* Selects the proper audio input */
ret = em28xx_set_audio_source(dev);
+ /* Unmute device */
+ if (!dev->mute)
+ s[1] &= ~0x80;
+ ret = em28xx_write_ac97(dev, MASTER_AC97, s);
+
return ret;
}
EXPORT_SYMBOL_GPL(em28xx_audio_analog_set);
diff --git a/linux/drivers/media/video/em28xx/em28xx-video.c b/linux/drivers/media/video/em28xx/em28xx-video.c
index a5d8797e4..bf8693dbf 100644
--- a/linux/drivers/media/video/em28xx/em28xx-video.c
+++ b/linux/drivers/media/video/em28xx/em28xx-video.c
@@ -211,7 +211,7 @@ static void video_mux(struct em28xx *dev, int index)
em28xx_i2c_call_clients(dev, VIDIOC_INT_S_AUDIO_ROUTING, &route);
}
- em28xx_set_audio_source(dev);
+ em28xx_audio_analog_set(dev);
}
/* Usage lock check functions */
@@ -859,7 +859,6 @@ static int em28xx_reg_len(int reg)
case AC97LSB_REG:
case HSCALELOW_REG:
case VSCALELOW_REG:
-
return 2;
default:
return 1;