diff options
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/video/em28xx/em28xx-core.c | 24 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx-video.c | 42 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx.h | 10 |
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 | ||
391 | static 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 | |||
391 | int em28xx_audio_analog_set(struct em28xx *dev) | 399 | int 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 | ||
298 | enum 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 | |||
298 | struct em28xx_input { | 306 | struct 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 */ |