Skip to content

Commit

Permalink
V4L/DVB (9670): em28xx: allow specifying audio output
Browse files Browse the repository at this point in the history
Some boards use different AC97 setups for output. This patch adds the
capability of specifying the output to be used. Currently, only one
output is selected, but the better is to allow user to select it via a
mixer, on alsa driver.

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
  • Loading branch information
Mauro Carvalho Chehab committed Dec 29, 2008
1 parent f1990a9 commit 35ae6f0
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 19 deletions.
24 changes: 17 additions & 7 deletions drivers/media/video/em28xx/em28xx-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand Down Expand Up @@ -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;
Expand Down
42 changes: 30 additions & 12 deletions drivers/media/video/em28xx/em28xx-video.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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;
}
Expand All @@ -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;
}

Expand Down
10 changes: 10 additions & 0 deletions drivers/media/video/em28xx/em28xx.h
Original file line number Diff line number Diff line change
Expand Up @@ -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])
Expand Down Expand Up @@ -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 */
Expand Down

0 comments on commit 35ae6f0

Please sign in to comment.