aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@infradead.org>2008-02-06 16:34:13 -0500
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-02-18 09:15:16 -0500
commit00b8730f5db19f9ea0985d7f14f869df79a0bf76 (patch)
tree043a721acdae940c0f26fadce689a3e0fb421655 /drivers/media
parent0df8130fe80ebde052516c1d729aa5d1c69ebc5c (diff)
V4L/DVB (7163): em28xx: makes audio settings more stable
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 'drivers/media')
-rw-r--r--drivers/media/video/em28xx/em28xx-core.c28
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c3
2 files changed, 21 insertions, 10 deletions
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index 6965bafe54a1..275f1e936304 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -255,21 +255,26 @@ static int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val,
255 */ 255 */
256static int em28xx_write_ac97(struct em28xx *dev, u8 reg, u8 *val) 256static int em28xx_write_ac97(struct em28xx *dev, u8 reg, u8 *val)
257{ 257{
258 int ret; 258 int ret, i;
259 u8 addr = reg & 0x7f; 259 u8 addr = reg & 0x7f;
260 if ((ret = em28xx_write_regs(dev, AC97LSB_REG, val, 2)) < 0) 260 if ((ret = em28xx_write_regs(dev, AC97LSB_REG, val, 2)) < 0)
261 return ret; 261 return ret;
262 if ((ret = em28xx_write_regs(dev, AC97ADDR_REG, &addr, 1)) < 0) 262 if ((ret = em28xx_write_regs(dev, AC97ADDR_REG, &addr, 1)) < 0)
263 return ret; 263 return ret;
264 if ((ret = em28xx_read_reg(dev, AC97BUSY_REG)) < 0) 264
265 return ret; 265 /* Wait up to 50 ms for AC97 command to complete */
266 else if (((u8) ret) & 0x01) { 266 for (i = 0; i < 10; i++) {
267 em28xx_warn ("AC97 command still being executed: not handled properly!\n"); 267 if ((ret = em28xx_read_reg(dev, AC97BUSY_REG)) < 0)
268 return ret;
269 if (!((u8) ret) & 0x01)
270 return 0;
271 msleep(5);
268 } 272 }
273 em28xx_warn ("AC97 command still being executed: not handled properly!\n");
269 return 0; 274 return 0;
270} 275}
271 276
272int em28xx_set_audio_source(struct em28xx *dev) 277static int em28xx_set_audio_source(struct em28xx *dev)
273{ 278{
274 static char *enable = "\x08\x08"; 279 static char *enable = "\x08\x08";
275 static char *disable = "\x08\x88"; 280 static char *disable = "\x08\x88";
@@ -312,6 +317,7 @@ int em28xx_set_audio_source(struct em28xx *dev)
312 ret = em28xx_write_reg_bits(dev, AUDIOSRC_REG, input, 0xc0); 317 ret = em28xx_write_reg_bits(dev, AUDIOSRC_REG, input, 0xc0);
313 if (ret < 0) 318 if (ret < 0)
314 return ret; 319 return ret;
320 msleep(5);
315 321
316 /* Sets AC97 mixer registers 322 /* Sets AC97 mixer registers
317 This is seems to be needed, even for non-ac97 configs 323 This is seems to be needed, even for non-ac97 configs
@@ -334,9 +340,10 @@ int em28xx_audio_analog_set(struct em28xx *dev)
334 s[0] |= 0x1f - dev->volume; 340 s[0] |= 0x1f - dev->volume;
335 s[1] |= 0x1f - dev->volume; 341 s[1] |= 0x1f - dev->volume;
336 342
337 if (dev->mute) 343 /* Mute */
338 s[1] |= 0x80; 344 s[1] |= 0x80;
339 ret = em28xx_write_ac97(dev, MASTER_AC97, s); 345 ret = em28xx_write_ac97(dev, MASTER_AC97, s);
346
340 if (ret < 0) 347 if (ret < 0)
341 return ret; 348 return ret;
342 349
@@ -354,6 +361,11 @@ int em28xx_audio_analog_set(struct em28xx *dev)
354 /* Selects the proper audio input */ 361 /* Selects the proper audio input */
355 ret = em28xx_set_audio_source(dev); 362 ret = em28xx_set_audio_source(dev);
356 363
364 /* Unmute device */
365 if (!dev->mute)
366 s[1] &= ~0x80;
367 ret = em28xx_write_ac97(dev, MASTER_AC97, s);
368
357 return ret; 369 return ret;
358} 370}
359EXPORT_SYMBOL_GPL(em28xx_audio_analog_set); 371EXPORT_SYMBOL_GPL(em28xx_audio_analog_set);
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index f69f591eeaf6..eeda3b2faec8 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -189,7 +189,7 @@ static void video_mux(struct em28xx *dev, int index)
189 em28xx_i2c_call_clients(dev, VIDIOC_INT_S_AUDIO_ROUTING, &route); 189 em28xx_i2c_call_clients(dev, VIDIOC_INT_S_AUDIO_ROUTING, &route);
190 } 190 }
191 191
192 em28xx_set_audio_source(dev); 192 em28xx_audio_analog_set(dev);
193} 193}
194 194
195/* Usage lock check functions */ 195/* Usage lock check functions */
@@ -837,7 +837,6 @@ static int em28xx_reg_len(int reg)
837 case AC97LSB_REG: 837 case AC97LSB_REG:
838 case HSCALELOW_REG: 838 case HSCALELOW_REG:
839 case VSCALELOW_REG: 839 case VSCALELOW_REG:
840
841 return 2; 840 return 2;
842 default: 841 default:
843 return 1; 842 return 1;