aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/saa7134
diff options
context:
space:
mode:
authorOldřich Jedlička <oldium.pro@seznam.cz>2009-08-22 14:13:51 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-09-12 11:19:41 -0400
commit736dadaa17218b6e516053ee896dbb075eadba4b (patch)
tree1a7ef0b80e77bf7f65236abacfa7e0f35840692e /drivers/media/video/saa7134
parented44f66e4039dfc8fb7905078d546c83adf76811 (diff)
V4L/DVB (12586): Update ALSA capture controls according to selected source.
The patch introduces new snd_saa7134_capsrc_set (code taken from snd_saa7134_capsrc_put) that updates also the ALSA capture controls during snd_card_saa7134_capture_prepare and snd_saa7134_capsrc_put. There can be much more work done in order to unify the control of the card (now the card's capture source is tuned/switched in saa7134-video.c too), but I don't have enough time. This work could be a starting point, but it can be applied as-is too (it doesn't need any further work to make it working). Signed-off-by: Oldřich Jedlička <oldium.pro@seznam.cz> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/saa7134')
-rw-r--r--drivers/media/video/saa7134/saa7134-alsa.c228
1 files changed, 150 insertions, 78 deletions
diff --git a/drivers/media/video/saa7134/saa7134-alsa.c b/drivers/media/video/saa7134/saa7134-alsa.c
index 7c0a3a3d61a6..d48c450ed77c 100644
--- a/drivers/media/video/saa7134/saa7134-alsa.c
+++ b/drivers/media/video/saa7134/saa7134-alsa.c
@@ -40,6 +40,7 @@ MODULE_PARM_DESC(debug,"enable debug messages [alsa]");
40 */ 40 */
41 41
42/* defaults */ 42/* defaults */
43#define MIXER_ADDR_UNSELECTED -1
43#define MIXER_ADDR_TVTUNER 0 44#define MIXER_ADDR_TVTUNER 0
44#define MIXER_ADDR_LINE1 1 45#define MIXER_ADDR_LINE1 1
45#define MIXER_ADDR_LINE2 2 46#define MIXER_ADDR_LINE2 2
@@ -68,7 +69,9 @@ typedef struct snd_card_saa7134 {
68 struct snd_card *card; 69 struct snd_card *card;
69 spinlock_t mixer_lock; 70 spinlock_t mixer_lock;
70 int mixer_volume[MIXER_ADDR_LAST+1][2]; 71 int mixer_volume[MIXER_ADDR_LAST+1][2];
71 int capture_source[MIXER_ADDR_LAST+1][2]; 72 int capture_source_addr;
73 int capture_source[2];
74 struct snd_kcontrol *capture_ctl[MIXER_ADDR_LAST+1];
72 struct pci_dev *pci; 75 struct pci_dev *pci;
73 struct saa7134_dev *dev; 76 struct saa7134_dev *dev;
74 77
@@ -314,6 +317,115 @@ static int dsp_buffer_free(struct saa7134_dev *dev)
314 return 0; 317 return 0;
315} 318}
316 319
320/*
321 * Setting the capture source and updating the ALSA controls
322 */
323static int snd_saa7134_capsrc_set(struct snd_kcontrol *kcontrol,
324 int left, int right, bool force_notify)
325{
326 snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
327 int change = 0, addr = kcontrol->private_value;
328 int active, old_addr;
329 u32 anabar, xbarin;
330 int analog_io, rate;
331 struct saa7134_dev *dev;
332
333 dev = chip->dev;
334
335 spin_lock_irq(&chip->mixer_lock);
336
337 active = left != 0 || right != 0;
338 old_addr = chip->capture_source_addr;
339
340 /* The active capture source cannot be deactivated */
341 if (active) {
342 change = old_addr != addr ||
343 chip->capture_source[0] != left ||
344 chip->capture_source[1] != right;
345
346 chip->capture_source[0] = left;
347 chip->capture_source[1] = right;
348 chip->capture_source_addr = addr;
349 dev->dmasound.input = addr;
350 }
351 spin_unlock_irq(&chip->mixer_lock);
352
353 if (change) {
354 switch (dev->pci->device) {
355
356 case PCI_DEVICE_ID_PHILIPS_SAA7134:
357 switch (addr) {
358 case MIXER_ADDR_TVTUNER:
359 saa_andorb(SAA7134_AUDIO_FORMAT_CTRL,
360 0xc0, 0xc0);
361 saa_andorb(SAA7134_SIF_SAMPLE_FREQ,
362 0x03, 0x00);
363 break;
364 case MIXER_ADDR_LINE1:
365 case MIXER_ADDR_LINE2:
366 analog_io = (MIXER_ADDR_LINE1 == addr) ?
367 0x00 : 0x08;
368 rate = (32000 == dev->dmasound.rate) ?
369 0x01 : 0x03;
370 saa_andorb(SAA7134_ANALOG_IO_SELECT,
371 0x08, analog_io);
372 saa_andorb(SAA7134_AUDIO_FORMAT_CTRL,
373 0xc0, 0x80);
374 saa_andorb(SAA7134_SIF_SAMPLE_FREQ,
375 0x03, rate);
376 break;
377 }
378
379 break;
380 case PCI_DEVICE_ID_PHILIPS_SAA7133:
381 case PCI_DEVICE_ID_PHILIPS_SAA7135:
382 xbarin = 0x03; /* adc */
383 anabar = 0;
384 switch (addr) {
385 case MIXER_ADDR_TVTUNER:
386 xbarin = 0; /* Demodulator */
387 anabar = 2; /* DACs */
388 break;
389 case MIXER_ADDR_LINE1:
390 anabar = 0; /* aux1, aux1 */
391 break;
392 case MIXER_ADDR_LINE2:
393 anabar = 9; /* aux2, aux2 */
394 break;
395 }
396
397 /* output xbar always main channel */
398 saa_dsp_writel(dev, SAA7133_DIGITAL_OUTPUT_SEL1,
399 0xbbbb10);
400
401 if (left || right) {
402 /* We've got data, turn the input on */
403 saa_dsp_writel(dev, SAA7133_DIGITAL_INPUT_XBAR1,
404 xbarin);
405 saa_writel(SAA7133_ANALOG_IO_SELECT, anabar);
406 } else {
407 saa_dsp_writel(dev, SAA7133_DIGITAL_INPUT_XBAR1,
408 0);
409 saa_writel(SAA7133_ANALOG_IO_SELECT, 0);
410 }
411 break;
412 }
413 }
414
415 if (change) {
416 if (force_notify)
417 snd_ctl_notify(chip->card,
418 SNDRV_CTL_EVENT_MASK_VALUE,
419 &chip->capture_ctl[addr]->id);
420
421 if (old_addr != MIXER_ADDR_UNSELECTED && old_addr != addr)
422 snd_ctl_notify(chip->card,
423 SNDRV_CTL_EVENT_MASK_VALUE,
424 &chip->capture_ctl[old_addr]->id);
425 }
426
427 return change;
428}
317 429
318/* 430/*
319 * ALSA PCM preparation 431 * ALSA PCM preparation
@@ -401,6 +513,10 @@ static int snd_card_saa7134_capture_prepare(struct snd_pcm_substream * substream
401 513
402 dev->dmasound.rate = runtime->rate; 514 dev->dmasound.rate = runtime->rate;
403 515
516 /* Setup and update the card/ALSA controls */
517 snd_saa7134_capsrc_set(saa7134->capture_ctl[dev->dmasound.input], 1, 1,
518 true);
519
404 return 0; 520 return 0;
405 521
406} 522}
@@ -846,8 +962,13 @@ static int snd_saa7134_capsrc_get(struct snd_kcontrol * kcontrol,
846 int addr = kcontrol->private_value; 962 int addr = kcontrol->private_value;
847 963
848 spin_lock_irq(&chip->mixer_lock); 964 spin_lock_irq(&chip->mixer_lock);
849 ucontrol->value.integer.value[0] = chip->capture_source[addr][0]; 965 if (chip->capture_source_addr == addr) {
850 ucontrol->value.integer.value[1] = chip->capture_source[addr][1]; 966 ucontrol->value.integer.value[0] = chip->capture_source[0];
967 ucontrol->value.integer.value[1] = chip->capture_source[1];
968 } else {
969 ucontrol->value.integer.value[0] = 0;
970 ucontrol->value.integer.value[1] = 0;
971 }
851 spin_unlock_irq(&chip->mixer_lock); 972 spin_unlock_irq(&chip->mixer_lock);
852 973
853 return 0; 974 return 0;
@@ -856,87 +977,22 @@ static int snd_saa7134_capsrc_get(struct snd_kcontrol * kcontrol,
856static int snd_saa7134_capsrc_put(struct snd_kcontrol * kcontrol, 977static int snd_saa7134_capsrc_put(struct snd_kcontrol * kcontrol,
857 struct snd_ctl_elem_value * ucontrol) 978 struct snd_ctl_elem_value * ucontrol)
858{ 979{
859 snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
860 int change, addr = kcontrol->private_value;
861 int left, right; 980 int left, right;
862 u32 anabar, xbarin;
863 int analog_io, rate;
864 struct saa7134_dev *dev;
865
866 dev = chip->dev;
867
868 left = ucontrol->value.integer.value[0] & 1; 981 left = ucontrol->value.integer.value[0] & 1;
869 right = ucontrol->value.integer.value[1] & 1; 982 right = ucontrol->value.integer.value[1] & 1;
870 spin_lock_irq(&chip->mixer_lock);
871 983
872 change = chip->capture_source[addr][0] != left || 984 return snd_saa7134_capsrc_set(kcontrol, left, right, false);
873 chip->capture_source[addr][1] != right;
874 chip->capture_source[addr][0] = left;
875 chip->capture_source[addr][1] = right;
876 dev->dmasound.input=addr;
877 spin_unlock_irq(&chip->mixer_lock);
878
879
880 if (change) {
881 switch (dev->pci->device) {
882
883 case PCI_DEVICE_ID_PHILIPS_SAA7134:
884 switch (addr) {
885 case MIXER_ADDR_TVTUNER:
886 saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0xc0);
887 saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, 0x00);
888 break;
889 case MIXER_ADDR_LINE1:
890 case MIXER_ADDR_LINE2:
891 analog_io = (MIXER_ADDR_LINE1 == addr) ? 0x00 : 0x08;
892 rate = (32000 == dev->dmasound.rate) ? 0x01 : 0x03;
893 saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x08, analog_io);
894 saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0x80);
895 saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, rate);
896 break;
897 }
898
899 break;
900 case PCI_DEVICE_ID_PHILIPS_SAA7133:
901 case PCI_DEVICE_ID_PHILIPS_SAA7135:
902 xbarin = 0x03; // adc
903 anabar = 0;
904 switch (addr) {
905 case MIXER_ADDR_TVTUNER:
906 xbarin = 0; // Demodulator
907 anabar = 2; // DACs
908 break;
909 case MIXER_ADDR_LINE1:
910 anabar = 0; // aux1, aux1
911 break;
912 case MIXER_ADDR_LINE2:
913 anabar = 9; // aux2, aux2
914 break;
915 }
916
917 /* output xbar always main channel */
918 saa_dsp_writel(dev, SAA7133_DIGITAL_OUTPUT_SEL1, 0xbbbb10);
919
920 if (left || right) { // We've got data, turn the input on
921 saa_dsp_writel(dev, SAA7133_DIGITAL_INPUT_XBAR1, xbarin);
922 saa_writel(SAA7133_ANALOG_IO_SELECT, anabar);
923 } else {
924 saa_dsp_writel(dev, SAA7133_DIGITAL_INPUT_XBAR1, 0);
925 saa_writel(SAA7133_ANALOG_IO_SELECT, 0);
926 }
927 break;
928 }
929 }
930
931 return change;
932} 985}
933 986
934static struct snd_kcontrol_new snd_saa7134_controls[] = { 987static struct snd_kcontrol_new snd_saa7134_volume_controls[] = {
935SAA713x_VOLUME("Video Volume", 0, MIXER_ADDR_TVTUNER), 988SAA713x_VOLUME("Video Volume", 0, MIXER_ADDR_TVTUNER),
936SAA713x_CAPSRC("Video Capture Switch", 0, MIXER_ADDR_TVTUNER),
937SAA713x_VOLUME("Line Volume", 1, MIXER_ADDR_LINE1), 989SAA713x_VOLUME("Line Volume", 1, MIXER_ADDR_LINE1),
938SAA713x_CAPSRC("Line Capture Switch", 1, MIXER_ADDR_LINE1),
939SAA713x_VOLUME("Line Volume", 2, MIXER_ADDR_LINE2), 990SAA713x_VOLUME("Line Volume", 2, MIXER_ADDR_LINE2),
991};
992
993static struct snd_kcontrol_new snd_saa7134_capture_controls[] = {
994SAA713x_CAPSRC("Video Capture Switch", 0, MIXER_ADDR_TVTUNER),
995SAA713x_CAPSRC("Line Capture Switch", 1, MIXER_ADDR_LINE1),
940SAA713x_CAPSRC("Line Capture Switch", 2, MIXER_ADDR_LINE2), 996SAA713x_CAPSRC("Line Capture Switch", 2, MIXER_ADDR_LINE2),
941}; 997};
942 998
@@ -951,17 +1007,33 @@ SAA713x_CAPSRC("Line Capture Switch", 2, MIXER_ADDR_LINE2),
951static int snd_card_saa7134_new_mixer(snd_card_saa7134_t * chip) 1007static int snd_card_saa7134_new_mixer(snd_card_saa7134_t * chip)
952{ 1008{
953 struct snd_card *card = chip->card; 1009 struct snd_card *card = chip->card;
1010 struct snd_kcontrol *kcontrol;
954 unsigned int idx; 1011 unsigned int idx;
955 int err; 1012 int err, addr;
956 1013
957 if (snd_BUG_ON(!chip)) 1014 if (snd_BUG_ON(!chip))
958 return -EINVAL; 1015 return -EINVAL;
959 strcpy(card->mixername, "SAA7134 Mixer"); 1016 strcpy(card->mixername, "SAA7134 Mixer");
960 1017
961 for (idx = 0; idx < ARRAY_SIZE(snd_saa7134_controls); idx++) { 1018 for (idx = 0; idx < ARRAY_SIZE(snd_saa7134_volume_controls); idx++) {
962 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_saa7134_controls[idx], chip))) < 0) 1019 kcontrol = snd_ctl_new1(&snd_saa7134_volume_controls[idx],
1020 chip);
1021 err = snd_ctl_add(card, kcontrol);
1022 if (err < 0)
963 return err; 1023 return err;
964 } 1024 }
1025
1026 for (idx = 0; idx < ARRAY_SIZE(snd_saa7134_capture_controls); idx++) {
1027 kcontrol = snd_ctl_new1(&snd_saa7134_capture_controls[idx],
1028 chip);
1029 addr = snd_saa7134_capture_controls[idx].private_value;
1030 chip->capture_ctl[addr] = kcontrol;
1031 err = snd_ctl_add(card, kcontrol);
1032 if (err < 0)
1033 return err;
1034 }
1035
1036 chip->capture_source_addr = MIXER_ADDR_UNSELECTED;
965 return 0; 1037 return 0;
966} 1038}
967 1039