aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/media/video/em28xx/em28xx-core.c24
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c42
-rw-r--r--drivers/media/video/em28xx/em28xx.h10
3 files changed, 57 insertions, 19 deletions
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index 2842ddf6dda..8aead5e84d0 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -388,9 +388,17 @@ static int em28xx_set_audio_source(struct em28xx *dev)
return ret;
}
+static int outputs[] = {
+ [EM28XX_AOUT_MASTER] = AC97_MASTER_VOL,
+ [EM28XX_AOUT_LINE] = AC97_LINE_LEVEL_VOL,
+ [EM28XX_AOUT_MONO] = AC97_MASTER_MONO_VOL,
+ [EM28XX_AOUT_LFE] = AC97_LFE_MASTER_VOL,
+ [EM28XX_AOUT_SURR] = AC97_SURR_MASTER_VOL,
+};
+
int em28xx_audio_analog_set(struct em28xx *dev)
{
- int ret;
+ int ret, i;
u8 xclk = 0x07;
if (!dev->audio_mode.has_audio)
@@ -400,11 +408,13 @@ int em28xx_audio_analog_set(struct em28xx *dev)
It would be possible to use also line output.
*/
if (dev->audio_mode.ac97 != EM28XX_NO_AC97) {
- /* Mute */
- ret = em28xx_write_ac97(dev, AC97_MASTER_VOL, 0x8000);
-
- if (ret < 0)
- return ret;
+ /* Mute all outputs */
+ for (i = 0; i < ARRAY_SIZE(outputs); i++) {
+ ret = em28xx_write_ac97(dev, outputs[i], 0x8000);
+ if (ret < 0)
+ em28xx_warn("couldn't setup AC97 register %d\n",
+ outputs[i]);
+ }
}
if (dev->has_12mhz_i2s)
@@ -433,7 +443,7 @@ int em28xx_audio_analog_set(struct em28xx *dev)
vol |= 0x8000;
/* Sets volume */
- ret = em28xx_write_ac97(dev, AC97_MASTER_VOL, vol);
+ ret = em28xx_write_ac97(dev, outputs[dev->ctl_aoutput], vol);
}
return ret;
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index 6b7d44a7117..bea74fd9a52 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -566,6 +566,7 @@ static void video_mux(struct em28xx *dev, int index)
route.output = 0;
dev->ctl_input = index;
dev->ctl_ainput = INPUT(index)->amux;
+ dev->ctl_aoutput = INPUT(index)->aout;
em28xx_i2c_call_clients(dev, VIDIOC_INT_S_VIDEO_ROUTING, &route);
@@ -928,20 +929,38 @@ static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
{
struct em28xx_fh *fh = priv;
struct em28xx *dev = fh->dev;
- unsigned int index = a->index;
- if (a->index > 1)
- return -EINVAL;
-
- index = dev->ctl_ainput;
-
- if (index == 0)
+ switch (a->index) {
+ case EM28XX_AMUX_VIDEO:
strcpy(a->name, "Television");
- else
+ break;
+ case EM28XX_AMUX_LINE_IN:
strcpy(a->name, "Line In");
+ break;
+ case EM28XX_AMUX_VIDEO2:
+ strcpy(a->name, "Television alt");
+ break;
+ case EM28XX_AMUX_PHONE:
+ strcpy(a->name, "Phone");
+ break;
+ case EM28XX_AMUX_MIC:
+ strcpy(a->name, "Mic");
+ break;
+ case EM28XX_AMUX_CD:
+ strcpy(a->name, "CD");
+ break;
+ case EM28XX_AMUX_AUX:
+ strcpy(a->name, "Aux");
+ break;
+ case EM28XX_AMUX_PCM_OUT:
+ strcpy(a->name, "PCM");
+ break;
+ default:
+ return -EINVAL;
+ }
+ a->index = dev->ctl_ainput;
a->capability = V4L2_AUDCAP_STEREO;
- a->index = index;
return 0;
}
@@ -951,9 +970,8 @@ static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a)
struct em28xx_fh *fh = priv;
struct em28xx *dev = fh->dev;
- if (a->index != dev->ctl_ainput)
- return -EINVAL;
-
+ dev->ctl_ainput = INPUT(a->index)->amux;
+ dev->ctl_aoutput = INPUT(a->index)->aout;
return 0;
}
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index 4fde52bd7e9..89e13c599f8 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -295,10 +295,19 @@ enum em28xx_amux {
EM28XX_AMUX_PCM_OUT,
};
+enum em28xx_aout {
+ EM28XX_AOUT_MASTER = 0, /* should be the default */
+ EM28XX_AOUT_LINE,
+ EM28XX_AOUT_MONO,
+ EM28XX_AOUT_LFE,
+ EM28XX_AOUT_SURR,
+};
+
struct em28xx_input {
enum enum28xx_itype type;
unsigned int vmux;
enum em28xx_amux amux;
+ enum em28xx_aout aout;
};
#define INPUT(nr) (&em28xx_boards[dev->model].input[nr])
@@ -450,6 +459,7 @@ struct em28xx {
int ctl_freq; /* selected frequency */
unsigned int ctl_input; /* selected input */
unsigned int ctl_ainput;/* selected audio input */
+ unsigned int ctl_aoutput;/* selected audio output */
int mute;
int volume;
/* frame properties */