aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
authorClemens Ladisch <clemens@ladisch.de>2011-01-11 04:35:29 -0500
committerTakashi Iwai <tiwai@suse.de>2011-01-11 11:54:15 -0500
commitd1d7093f3f639e693fa763eb51d8d9c349bfd606 (patch)
treed502551d3690e341167615c858c8b35678972706 /sound/pci
parent5fc51524746430179c676297fd48aaab28e1b85f (diff)
ALSA: oxygen: add S/PDIF source selection for Claro cards
Add a mixer control to switch between the optical and coaxial S/PDIF inputs on the HT-Omega Claro and Claro halo cards. Signed-off-by: Clemens Ladisch <clemens@ladisch.de> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/oxygen/oxygen.c92
1 files changed, 88 insertions, 4 deletions
diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c
index db39cfc3b4f3..d7e8ddd9a67b 100644
--- a/sound/pci/oxygen/oxygen.c
+++ b/sound/pci/oxygen/oxygen.c
@@ -34,6 +34,7 @@
34 * GPIO 6 -> enable on-board S/PDIF input 34 * GPIO 6 -> enable on-board S/PDIF input
35 * 35 *
36 * Claro models: 36 * Claro models:
37 * GPIO 6 -> S/PDIF from optical (0) or coaxial (1) input
37 * GPIO 8 -> enable headphone amplifier 38 * GPIO 8 -> enable headphone amplifier
38 * 39 *
39 * CM9780: 40 * CM9780:
@@ -137,6 +138,7 @@ MODULE_DEVICE_TABLE(pci, oxygen_ids);
137#define GPIO_MERIDIAN_DIG_EXT 0x0010 138#define GPIO_MERIDIAN_DIG_EXT 0x0010
138#define GPIO_MERIDIAN_DIG_BOARD 0x0040 139#define GPIO_MERIDIAN_DIG_BOARD 0x0040
139 140
141#define GPIO_CLARO_DIG_COAX 0x0040
140#define GPIO_CLARO_HP 0x0100 142#define GPIO_CLARO_HP 0x0100
141 143
142struct generic_data { 144struct generic_data {
@@ -268,6 +270,8 @@ static void claro_enable_hp(struct oxygen *chip)
268 270
269static void claro_init(struct oxygen *chip) 271static void claro_init(struct oxygen *chip)
270{ 272{
273 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_CLARO_DIG_COAX);
274 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_CLARO_DIG_COAX);
271 ak4396_init(chip); 275 ak4396_init(chip);
272 wm8785_init(chip); 276 wm8785_init(chip);
273 claro_enable_hp(chip); 277 claro_enable_hp(chip);
@@ -275,6 +279,8 @@ static void claro_init(struct oxygen *chip)
275 279
276static void claro_halo_init(struct oxygen *chip) 280static void claro_halo_init(struct oxygen *chip)
277{ 281{
282 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_CLARO_DIG_COAX);
283 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_CLARO_DIG_COAX);
278 ak4396_init(chip); 284 ak4396_init(chip);
279 ak5385_init(chip); 285 ak5385_init(chip);
280 claro_enable_hp(chip); 286 claro_enable_hp(chip);
@@ -523,14 +529,24 @@ static const struct snd_kcontrol_new hpf_control = {
523 .put = hpf_put, 529 .put = hpf_put,
524}; 530};
525 531
526static int meridian_dig_source_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info) 532static int meridian_dig_source_info(struct snd_kcontrol *ctl,
533 struct snd_ctl_elem_info *info)
527{ 534{
528 static const char *const names[2] = { "On-board", "Extension" }; 535 static const char *const names[2] = { "On-board", "Extension" };
529 536
530 return snd_ctl_enum_info(info, 1, 2, names); 537 return snd_ctl_enum_info(info, 1, 2, names);
531} 538}
532 539
533static int meridian_dig_source_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value) 540static int claro_dig_source_info(struct snd_kcontrol *ctl,
541 struct snd_ctl_elem_info *info)
542{
543 static const char *const names[2] = { "Optical", "Coaxial" };
544
545 return snd_ctl_enum_info(info, 1, 2, names);
546}
547
548static int meridian_dig_source_get(struct snd_kcontrol *ctl,
549 struct snd_ctl_elem_value *value)
534{ 550{
535 struct oxygen *chip = ctl->private_data; 551 struct oxygen *chip = ctl->private_data;
536 552
@@ -540,7 +556,19 @@ static int meridian_dig_source_get(struct snd_kcontrol *ctl, struct snd_ctl_elem
540 return 0; 556 return 0;
541} 557}
542 558
543static int meridian_dig_source_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value) 559static int claro_dig_source_get(struct snd_kcontrol *ctl,
560 struct snd_ctl_elem_value *value)
561{
562 struct oxygen *chip = ctl->private_data;
563
564 value->value.enumerated.item[0] =
565 !!(oxygen_read16(chip, OXYGEN_GPIO_DATA) &
566 GPIO_CLARO_DIG_COAX);
567 return 0;
568}
569
570static int meridian_dig_source_put(struct snd_kcontrol *ctl,
571 struct snd_ctl_elem_value *value)
544{ 572{
545 struct oxygen *chip = ctl->private_data; 573 struct oxygen *chip = ctl->private_data;
546 u16 old_reg, new_reg; 574 u16 old_reg, new_reg;
@@ -560,6 +588,25 @@ static int meridian_dig_source_put(struct snd_kcontrol *ctl, struct snd_ctl_elem
560 return changed; 588 return changed;
561} 589}
562 590
591static int claro_dig_source_put(struct snd_kcontrol *ctl,
592 struct snd_ctl_elem_value *value)
593{
594 struct oxygen *chip = ctl->private_data;
595 u16 old_reg, new_reg;
596 int changed;
597
598 mutex_lock(&chip->mutex);
599 old_reg = oxygen_read16(chip, OXYGEN_GPIO_DATA);
600 new_reg = old_reg & ~GPIO_CLARO_DIG_COAX;
601 if (value->value.enumerated.item[0])
602 new_reg |= GPIO_CLARO_DIG_COAX;
603 changed = new_reg != old_reg;
604 if (changed)
605 oxygen_write16(chip, OXYGEN_GPIO_DATA, new_reg);
606 mutex_unlock(&chip->mutex);
607 return changed;
608}
609
563static const struct snd_kcontrol_new meridian_dig_source_control = { 610static const struct snd_kcontrol_new meridian_dig_source_control = {
564 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 611 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
565 .name = "IEC958 Source Capture Enum", 612 .name = "IEC958 Source Capture Enum",
@@ -568,6 +615,14 @@ static const struct snd_kcontrol_new meridian_dig_source_control = {
568 .put = meridian_dig_source_put, 615 .put = meridian_dig_source_put,
569}; 616};
570 617
618static const struct snd_kcontrol_new claro_dig_source_control = {
619 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
620 .name = "IEC958 Source Capture Enum",
621 .info = claro_dig_source_info,
622 .get = claro_dig_source_get,
623 .put = claro_dig_source_put,
624};
625
571static int generic_mixer_init(struct oxygen *chip) 626static int generic_mixer_init(struct oxygen *chip)
572{ 627{
573 return snd_ctl_add(chip->card, snd_ctl_new1(&rolloff_control, chip)); 628 return snd_ctl_add(chip->card, snd_ctl_new1(&rolloff_control, chip));
@@ -600,6 +655,34 @@ static int meridian_mixer_init(struct oxygen *chip)
600 return 0; 655 return 0;
601} 656}
602 657
658static int claro_mixer_init(struct oxygen *chip)
659{
660 int err;
661
662 err = generic_wm8785_mixer_init(chip);
663 if (err < 0)
664 return err;
665 err = snd_ctl_add(chip->card,
666 snd_ctl_new1(&claro_dig_source_control, chip));
667 if (err < 0)
668 return err;
669 return 0;
670}
671
672static int claro_halo_mixer_init(struct oxygen *chip)
673{
674 int err;
675
676 err = generic_mixer_init(chip);
677 if (err < 0)
678 return err;
679 err = snd_ctl_add(chip->card,
680 snd_ctl_new1(&claro_dig_source_control, chip));
681 if (err < 0)
682 return err;
683 return 0;
684}
685
603static void dump_ak4396_registers(struct oxygen *chip, 686static void dump_ak4396_registers(struct oxygen *chip,
604 struct snd_info_buffer *buffer) 687 struct snd_info_buffer *buffer)
605{ 688{
@@ -700,13 +783,14 @@ static int __devinit get_oxygen_model(struct oxygen *chip,
700 break; 783 break;
701 case MODEL_CLARO: 784 case MODEL_CLARO:
702 chip->model.init = claro_init; 785 chip->model.init = claro_init;
786 chip->model.mixer_init = claro_mixer_init;
703 chip->model.cleanup = claro_cleanup; 787 chip->model.cleanup = claro_cleanup;
704 chip->model.suspend = claro_suspend; 788 chip->model.suspend = claro_suspend;
705 chip->model.resume = claro_resume; 789 chip->model.resume = claro_resume;
706 break; 790 break;
707 case MODEL_CLARO_HALO: 791 case MODEL_CLARO_HALO:
708 chip->model.init = claro_halo_init; 792 chip->model.init = claro_halo_init;
709 chip->model.mixer_init = generic_mixer_init; 793 chip->model.mixer_init = claro_halo_mixer_init;
710 chip->model.cleanup = claro_cleanup; 794 chip->model.cleanup = claro_cleanup;
711 chip->model.suspend = claro_suspend; 795 chip->model.suspend = claro_suspend;
712 chip->model.resume = claro_resume; 796 chip->model.resume = claro_resume;