aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2008-11-20 10:40:51 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2008-12-29 14:53:37 -0500
commit35ae6f04ad3e4c3ed8a83382b6511bd9beb5c768 (patch)
treeac482c50af4af87bab959b6e839a8383811d8daa
parentf1990a9c39d957e6896fc506fc5388b7f302c429 (diff)
V4L/DVB (9670): em28xx: allow specifying audio output
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>
-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 2842ddf6ddac..8aead5e84d0f 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)
388 return ret; 388 return ret;
389} 389}
390 390
391static int outputs[] = {
392 [EM28XX_AOUT_MASTER] = AC97_MASTER_VOL,
393 [EM28XX_AOUT_LINE] = AC97_LINE_LEVEL_VOL,
394 [EM28XX_AOUT_MONO] = AC97_MASTER_MONO_VOL,
395 [EM28XX_AOUT_LFE] = AC97_LFE_MASTER_VOL,
396 [EM28XX_AOUT_SURR] = AC97_SURR_MASTER_VOL,
397};
398
391int em28xx_audio_analog_set(struct em28xx *dev) 399int em28xx_audio_analog_set(struct em28xx *dev)
392{ 400{
393 int ret; 401 int ret, i;
394 u8 xclk = 0x07; 402 u8 xclk = 0x07;
395 403
396 if (!dev->audio_mode.has_audio) 404 if (!dev->audio_mode.has_audio)
@@ -400,11 +408,13 @@ int em28xx_audio_analog_set(struct em28xx *dev)
400 It would be possible to use also line output. 408 It would be possible to use also line output.
401 */ 409 */
402 if (dev->audio_mode.ac97 != EM28XX_NO_AC97) { 410 if (dev->audio_mode.ac97 != EM28XX_NO_AC97) {
403 /* Mute */ 411 /* Mute all outputs */
404 ret = em28xx_write_ac97(dev, AC97_MASTER_VOL, 0x8000); 412 for (i = 0; i < ARRAY_SIZE(outputs); i++) {
405 413 ret = em28xx_write_ac97(dev, outputs[i], 0x8000);
406 if (ret < 0) 414 if (ret < 0)
407 return ret; 415 em28xx_warn("couldn't setup AC97 register %d\n",
416 outputs[i]);
417 }
408 } 418 }
409 419
410 if (dev->has_12mhz_i2s) 420 if (dev->has_12mhz_i2s)
@@ -433,7 +443,7 @@ int em28xx_audio_analog_set(struct em28xx *dev)
433 vol |= 0x8000; 443 vol |= 0x8000;
434 444
435 /* Sets volume */ 445 /* Sets volume */
436 ret = em28xx_write_ac97(dev, AC97_MASTER_VOL, vol); 446 ret = em28xx_write_ac97(dev, outputs[dev->ctl_aoutput], vol);
437 } 447 }
438 448
439 return ret; 449 return ret;
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index 6b7d44a7117f..bea74fd9a520 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)
566 route.output = 0; 566 route.output = 0;
567 dev->ctl_input = index; 567 dev->ctl_input = index;
568 dev->ctl_ainput = INPUT(index)->amux; 568 dev->ctl_ainput = INPUT(index)->amux;
569 dev->ctl_aoutput = INPUT(index)->aout;
569 570
570 em28xx_i2c_call_clients(dev, VIDIOC_INT_S_VIDEO_ROUTING, &route); 571 em28xx_i2c_call_clients(dev, VIDIOC_INT_S_VIDEO_ROUTING, &route);
571 572
@@ -928,20 +929,38 @@ static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
928{ 929{
929 struct em28xx_fh *fh = priv; 930 struct em28xx_fh *fh = priv;
930 struct em28xx *dev = fh->dev; 931 struct em28xx *dev = fh->dev;
931 unsigned int index = a->index;
932 932
933 if (a->index > 1) 933 switch (a->index) {
934 return -EINVAL; 934 case EM28XX_AMUX_VIDEO:
935
936 index = dev->ctl_ainput;
937
938 if (index == 0)
939 strcpy(a->name, "Television"); 935 strcpy(a->name, "Television");
940 else 936 break;
937 case EM28XX_AMUX_LINE_IN:
941 strcpy(a->name, "Line In"); 938 strcpy(a->name, "Line In");
939 break;
940 case EM28XX_AMUX_VIDEO2:
941 strcpy(a->name, "Television alt");
942 break;
943 case EM28XX_AMUX_PHONE:
944 strcpy(a->name, "Phone");
945 break;
946 case EM28XX_AMUX_MIC:
947 strcpy(a->name, "Mic");
948 break;
949 case EM28XX_AMUX_CD:
950 strcpy(a->name, "CD");
951 break;
952 case EM28XX_AMUX_AUX:
953 strcpy(a->name, "Aux");
954 break;
955 case EM28XX_AMUX_PCM_OUT:
956 strcpy(a->name, "PCM");
957 break;
958 default:
959 return -EINVAL;
960 }
942 961
962 a->index = dev->ctl_ainput;
943 a->capability = V4L2_AUDCAP_STEREO; 963 a->capability = V4L2_AUDCAP_STEREO;
944 a->index = index;
945 964
946 return 0; 965 return 0;
947} 966}
@@ -951,9 +970,8 @@ static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a)
951 struct em28xx_fh *fh = priv; 970 struct em28xx_fh *fh = priv;
952 struct em28xx *dev = fh->dev; 971 struct em28xx *dev = fh->dev;
953 972
954 if (a->index != dev->ctl_ainput) 973 dev->ctl_ainput = INPUT(a->index)->amux;
955 return -EINVAL; 974 dev->ctl_aoutput = INPUT(a->index)->aout;
956
957 return 0; 975 return 0;
958} 976}
959 977
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index 4fde52bd7e97..89e13c599f8d 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -295,10 +295,19 @@ enum em28xx_amux {
295 EM28XX_AMUX_PCM_OUT, 295 EM28XX_AMUX_PCM_OUT,
296}; 296};
297 297
298enum em28xx_aout {
299 EM28XX_AOUT_MASTER = 0, /* should be the default */
300 EM28XX_AOUT_LINE,
301 EM28XX_AOUT_MONO,
302 EM28XX_AOUT_LFE,
303 EM28XX_AOUT_SURR,
304};
305
298struct em28xx_input { 306struct em28xx_input {
299 enum enum28xx_itype type; 307 enum enum28xx_itype type;
300 unsigned int vmux; 308 unsigned int vmux;
301 enum em28xx_amux amux; 309 enum em28xx_amux amux;
310 enum em28xx_aout aout;
302}; 311};
303 312
304#define INPUT(nr) (&em28xx_boards[dev->model].input[nr]) 313#define INPUT(nr) (&em28xx_boards[dev->model].input[nr])
@@ -450,6 +459,7 @@ struct em28xx {
450 int ctl_freq; /* selected frequency */ 459 int ctl_freq; /* selected frequency */
451 unsigned int ctl_input; /* selected input */ 460 unsigned int ctl_input; /* selected input */
452 unsigned int ctl_ainput;/* selected audio input */ 461 unsigned int ctl_ainput;/* selected audio input */
462 unsigned int ctl_aoutput;/* selected audio output */
453 int mute; 463 int mute;
454 int volume; 464 int volume;
455 /* frame properties */ 465 /* frame properties */