aboutsummaryrefslogtreecommitdiff
path: root/drivers/media/video/em28xx/em28xx-core.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@infradead.org>2008-01-05 09:53:54 -0300
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-01-25 19:04:30 -0200
commit539c96d0fd86bfdcfac75c88b74aa5798439293d (patch)
treefb72c663b71fb2e9eef6eeaf859e774c8bb027a8 /drivers/media/video/em28xx/em28xx-core.c
parent6596a4f6032f13f1bef47550fcf1d4134cd978a4 (diff)
V4L/DVB (6947): Improve audio setup handling
It is possible to select audio inputs via em28xx or via ac97 functions. This patch allows configuring a board to use either one way. It also do some cleanups at audio setup configurations. Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/em28xx/em28xx-core.c')
-rw-r--r--drivers/media/video/em28xx/em28xx-core.c81
1 files changed, 78 insertions, 3 deletions
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index d56484f2046..70c5ec268f6 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -252,7 +252,7 @@ int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val,
* em28xx_write_ac97()
* write a 16 bit value to the specified AC97 address (LSB first!)
*/
-int em28xx_write_ac97(struct em28xx *dev, u8 reg, u8 * val)
+static int em28xx_write_ac97(struct em28xx *dev, u8 reg, u8 *val)
{
int ret;
u8 addr = reg & 0x7f;
@@ -268,16 +268,91 @@ int em28xx_write_ac97(struct em28xx *dev, u8 reg, u8 * val)
return 0;
}
+int em28xx_set_audio_source(struct em28xx *dev)
+{
+ static char *enable = "\x08\x08";
+ static char *disable = "\x08\x88";
+ char *video = enable, *line = disable;
+ int ret, no_ac97;
+ u8 input;
+
+ if (dev->is_em2800) {
+ if (dev->ctl_ainput)
+ input = EM2800_AUDIO_SRC_LINE;
+ else
+ input = EM2800_AUDIO_SRC_TUNER;
+
+ ret = em28xx_write_regs(dev, EM2800_AUDIOSRC_REG, &input, 1);
+ if (ret < 0)
+ return ret;
+ }
+
+ if (dev->has_msp34xx)
+ input = EM28XX_AUDIO_SRC_TUNER;
+ else {
+ switch (dev->ctl_ainput) {
+ case EM28XX_AMUX_VIDEO:
+ input = EM28XX_AUDIO_SRC_TUNER;
+ no_ac97 = 1;
+ break;
+ case EM28XX_AMUX_LINE_IN:
+ input = EM28XX_AUDIO_SRC_LINE;
+ no_ac97 = 1;
+ break;
+ case EM28XX_AMUX_AC97_VIDEO:
+ input = EM28XX_AUDIO_SRC_LINE;
+ break;
+ case EM28XX_AMUX_AC97_LINE_IN:
+ input = EM28XX_AUDIO_SRC_LINE;
+ video = disable;
+ line = enable;
+ break;
+ }
+ }
+
+ ret = em28xx_write_reg_bits(dev, AUDIOSRC_REG, input, 0xc0);
+ if (ret < 0)
+ return ret;
+
+ if (no_ac97)
+ return 0;
+
+ /* Sets AC97 mixer registers */
+
+ ret = em28xx_write_ac97(dev, VIDEO_AC97, video);
+ if (ret < 0)
+ return ret;
+
+ ret = em28xx_write_ac97(dev, LINE_IN_AC97, line);
+
+ return ret;
+}
+
int em28xx_audio_analog_set(struct em28xx *dev)
{
+ int ret;
char s[2] = { 0x00, 0x00 };
+
s[0] |= 0x1f - dev->volume;
s[1] |= 0x1f - dev->volume;
+
if (dev->mute)
s[1] |= 0x80;
- return em28xx_write_ac97(dev, MASTER_AC97, s);
-}
+ ret = em28xx_write_ac97(dev, MASTER_AC97, s);
+ if (ret < 0)
+ return ret;
+ ret = em28xx_write_reg_bits(dev, XCLK_REG,
+ dev->mute ? 0x00 : 0x80, 0x80);
+ if (ret < 0)
+ return ret;
+
+ /* Selects the proper audio input */
+ ret = em28xx_set_audio_source(dev);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(em28xx_audio_analog_set);
int em28xx_colorlevels_set_default(struct em28xx *dev)
{