diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-11-20 11:39:39 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-12-29 14:53:37 -0500 |
commit | e879b8ebb000298f8124fc8fae570afc9eb37cbb (patch) | |
tree | bab36de8b6415335809fe01350423e97c541b48e /drivers/media/video/em28xx | |
parent | 209acc02249d831e7f2e3d8083b6b562dde5fc6f (diff) |
V4L/DVB (9672): Allow opening more than one output at the same time
Some devices use more than one AC97 outputs. This patch allows such
devices to properly work.
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/em28xx')
-rw-r--r-- | drivers/media/video/em28xx/em28xx-core.c | 33 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx-video.c | 6 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx.h | 10 |
3 files changed, 31 insertions, 18 deletions
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c index cb60864041e7..413428aeccd7 100644 --- a/drivers/media/video/em28xx/em28xx-core.c +++ b/drivers/media/video/em28xx/em28xx-core.c | |||
@@ -304,12 +304,12 @@ static int em28xx_write_ac97(struct em28xx *dev, u8 reg, u16 val) | |||
304 | return 0; | 304 | return 0; |
305 | } | 305 | } |
306 | 306 | ||
307 | struct em28xx_input_table { | 307 | struct em28xx_vol_table { |
308 | enum em28xx_amux amux; | 308 | enum em28xx_amux mux; |
309 | u8 reg; | 309 | u8 reg; |
310 | }; | 310 | }; |
311 | 311 | ||
312 | static struct em28xx_input_table inputs[] = { | 312 | static struct em28xx_vol_table inputs[] = { |
313 | { EM28XX_AMUX_VIDEO, AC97_VIDEO_VOL }, | 313 | { EM28XX_AMUX_VIDEO, AC97_VIDEO_VOL }, |
314 | { EM28XX_AMUX_LINE_IN, AC97_LINEIN_VOL }, | 314 | { EM28XX_AMUX_LINE_IN, AC97_LINEIN_VOL }, |
315 | { EM28XX_AMUX_PHONE, AC97_PHONE_VOL }, | 315 | { EM28XX_AMUX_PHONE, AC97_PHONE_VOL }, |
@@ -332,7 +332,7 @@ static int set_ac97_input(struct em28xx *dev) | |||
332 | 332 | ||
333 | /* Mute all entres but the one that were selected */ | 333 | /* Mute all entres but the one that were selected */ |
334 | for (i = 0; i < ARRAY_SIZE(inputs); i++) { | 334 | for (i = 0; i < ARRAY_SIZE(inputs); i++) { |
335 | if (amux == inputs[i].amux) | 335 | if (amux == inputs[i].mux) |
336 | ret = em28xx_write_ac97(dev, inputs[i].reg, 0x0808); | 336 | ret = em28xx_write_ac97(dev, inputs[i].reg, 0x0808); |
337 | else | 337 | else |
338 | ret = em28xx_write_ac97(dev, inputs[i].reg, 0x8000); | 338 | ret = em28xx_write_ac97(dev, inputs[i].reg, 0x8000); |
@@ -388,12 +388,12 @@ static int em28xx_set_audio_source(struct em28xx *dev) | |||
388 | return ret; | 388 | return ret; |
389 | } | 389 | } |
390 | 390 | ||
391 | static int outputs[] = { | 391 | struct em28xx_vol_table outputs[] = { |
392 | [EM28XX_AOUT_MASTER] = AC97_MASTER_VOL, | 392 | { EM28XX_AOUT_MASTER, AC97_MASTER_VOL }, |
393 | [EM28XX_AOUT_LINE] = AC97_LINE_LEVEL_VOL, | 393 | { EM28XX_AOUT_LINE, AC97_LINE_LEVEL_VOL }, |
394 | [EM28XX_AOUT_MONO] = AC97_MASTER_MONO_VOL, | 394 | { EM28XX_AOUT_MONO, AC97_MASTER_MONO_VOL }, |
395 | [EM28XX_AOUT_LFE] = AC97_LFE_MASTER_VOL, | 395 | { EM28XX_AOUT_LFE, AC97_LFE_MASTER_VOL }, |
396 | [EM28XX_AOUT_SURR] = AC97_SURR_MASTER_VOL, | 396 | { EM28XX_AOUT_SURR, AC97_SURR_MASTER_VOL }, |
397 | }; | 397 | }; |
398 | 398 | ||
399 | int em28xx_audio_analog_set(struct em28xx *dev) | 399 | int em28xx_audio_analog_set(struct em28xx *dev) |
@@ -410,10 +410,10 @@ int em28xx_audio_analog_set(struct em28xx *dev) | |||
410 | if (dev->audio_mode.ac97 != EM28XX_NO_AC97) { | 410 | if (dev->audio_mode.ac97 != EM28XX_NO_AC97) { |
411 | /* Mute all outputs */ | 411 | /* Mute all outputs */ |
412 | for (i = 0; i < ARRAY_SIZE(outputs); i++) { | 412 | for (i = 0; i < ARRAY_SIZE(outputs); i++) { |
413 | ret = em28xx_write_ac97(dev, outputs[i], 0x8000); | 413 | ret = em28xx_write_ac97(dev, outputs[i].reg, 0x8000); |
414 | if (ret < 0) | 414 | if (ret < 0) |
415 | em28xx_warn("couldn't setup AC97 register %d\n", | 415 | em28xx_warn("couldn't setup AC97 register %d\n", |
416 | outputs[i]); | 416 | outputs[i].reg); |
417 | } | 417 | } |
418 | } | 418 | } |
419 | 419 | ||
@@ -443,7 +443,14 @@ int em28xx_audio_analog_set(struct em28xx *dev) | |||
443 | vol |= 0x8000; | 443 | vol |= 0x8000; |
444 | 444 | ||
445 | /* Sets volume */ | 445 | /* Sets volume */ |
446 | ret = em28xx_write_ac97(dev, outputs[dev->ctl_aoutput], vol); | 446 | for (i = 0; i < ARRAY_SIZE(outputs); i++) { |
447 | if (dev->ctl_aoutput & outputs[i].mux) | ||
448 | ret = em28xx_write_ac97(dev, outputs[i].reg, | ||
449 | vol); | ||
450 | if (ret < 0) | ||
451 | em28xx_warn("couldn't setup AC97 register %d\n", | ||
452 | outputs[i].reg); | ||
453 | } | ||
447 | } | 454 | } |
448 | 455 | ||
449 | return ret; | 456 | return ret; |
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index bea74fd9a520..b262091415bb 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c | |||
@@ -568,6 +568,9 @@ static void video_mux(struct em28xx *dev, int index) | |||
568 | dev->ctl_ainput = INPUT(index)->amux; | 568 | dev->ctl_ainput = INPUT(index)->amux; |
569 | dev->ctl_aoutput = INPUT(index)->aout; | 569 | dev->ctl_aoutput = INPUT(index)->aout; |
570 | 570 | ||
571 | if (!dev->ctl_aoutput) | ||
572 | dev->ctl_aoutput = EM28XX_AOUT_MASTER; | ||
573 | |||
571 | em28xx_i2c_call_clients(dev, VIDIOC_INT_S_VIDEO_ROUTING, &route); | 574 | em28xx_i2c_call_clients(dev, VIDIOC_INT_S_VIDEO_ROUTING, &route); |
572 | 575 | ||
573 | if (dev->has_msp34xx) { | 576 | if (dev->has_msp34xx) { |
@@ -972,6 +975,9 @@ static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a) | |||
972 | 975 | ||
973 | dev->ctl_ainput = INPUT(a->index)->amux; | 976 | dev->ctl_ainput = INPUT(a->index)->amux; |
974 | dev->ctl_aoutput = INPUT(a->index)->aout; | 977 | dev->ctl_aoutput = INPUT(a->index)->aout; |
978 | |||
979 | if (!dev->ctl_aoutput) | ||
980 | dev->ctl_aoutput = EM28XX_AOUT_MASTER; | ||
975 | return 0; | 981 | return 0; |
976 | } | 982 | } |
977 | 983 | ||
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index 206f59c1e938..4d50d60278c5 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h | |||
@@ -297,11 +297,11 @@ enum em28xx_amux { | |||
297 | }; | 297 | }; |
298 | 298 | ||
299 | enum em28xx_aout { | 299 | enum em28xx_aout { |
300 | EM28XX_AOUT_MASTER = 0, /* should be the default */ | 300 | EM28XX_AOUT_MASTER = 1 << 0, |
301 | EM28XX_AOUT_LINE, | 301 | EM28XX_AOUT_LINE = 1 << 1, |
302 | EM28XX_AOUT_MONO, | 302 | EM28XX_AOUT_MONO = 1 << 2, |
303 | EM28XX_AOUT_LFE, | 303 | EM28XX_AOUT_LFE = 1 << 3, |
304 | EM28XX_AOUT_SURR, | 304 | EM28XX_AOUT_SURR = 1 << 4, |
305 | }; | 305 | }; |
306 | 306 | ||
307 | struct em28xx_input { | 307 | struct em28xx_input { |