diff options
-rw-r--r-- | sound/pci/ca0106/ca0106_mixer.c | 91 |
1 files changed, 69 insertions, 22 deletions
diff --git a/sound/pci/ca0106/ca0106_mixer.c b/sound/pci/ca0106/ca0106_mixer.c index b522401b0318..630aa4998189 100644 --- a/sound/pci/ca0106/ca0106_mixer.c +++ b/sound/pci/ca0106/ca0106_mixer.c | |||
@@ -676,28 +676,65 @@ static struct snd_kcontrol_new snd_ca0106_volume_i2c_adc_ctls[] __devinitdata = | |||
676 | I2C_VOLUME("Aux Capture Volume", 3), | 676 | I2C_VOLUME("Aux Capture Volume", 3), |
677 | }; | 677 | }; |
678 | 678 | ||
679 | #define SPI_SWITCH(xname,reg,bit) \ | 679 | static const int spi_dmute_reg[] = { |
680 | { \ | 680 | SPI_DMUTE0_REG, |
681 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ | 681 | SPI_DMUTE1_REG, |
682 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \ | 682 | SPI_DMUTE2_REG, |
683 | .info = spi_mute_info, \ | 683 | 0, |
684 | .get = spi_mute_get, \ | 684 | SPI_DMUTE4_REG, |
685 | .put = spi_mute_put, \ | 685 | }; |
686 | .private_value = (reg<<SPI_REG_SHIFT) | (bit) \ | 686 | static const int spi_dmute_bit[] = { |
687 | } | 687 | SPI_DMUTE0_BIT, |
688 | 688 | SPI_DMUTE1_BIT, | |
689 | static struct snd_kcontrol_new snd_ca0106_volume_spi_dac_ctls[] | 689 | SPI_DMUTE2_BIT, |
690 | __devinitdata = { | 690 | 0, |
691 | SPI_SWITCH("Analog Front Playback Switch", | 691 | SPI_DMUTE4_BIT, |
692 | SPI_DMUTE4_REG, SPI_DMUTE4_BIT), | ||
693 | SPI_SWITCH("Analog Rear Playback Switch", | ||
694 | SPI_DMUTE0_REG, SPI_DMUTE0_BIT), | ||
695 | SPI_SWITCH("Analog Center/LFE Playback Switch", | ||
696 | SPI_DMUTE2_REG, SPI_DMUTE2_BIT), | ||
697 | SPI_SWITCH("Analog Side Playback Switch", | ||
698 | SPI_DMUTE1_REG, SPI_DMUTE1_BIT), | ||
699 | }; | 692 | }; |
700 | 693 | ||
694 | static struct snd_kcontrol_new __devinit | ||
695 | snd_ca0106_volume_spi_dac_ctl(struct snd_ca0106_details *details, | ||
696 | int channel_id) | ||
697 | { | ||
698 | struct snd_kcontrol_new spi_switch = {0}; | ||
699 | int reg, bit; | ||
700 | int dac_id; | ||
701 | |||
702 | spi_switch.iface = SNDRV_CTL_ELEM_IFACE_MIXER; | ||
703 | spi_switch.access = SNDRV_CTL_ELEM_ACCESS_READWRITE; | ||
704 | spi_switch.info = spi_mute_info; | ||
705 | spi_switch.get = spi_mute_get; | ||
706 | spi_switch.put = spi_mute_put; | ||
707 | |||
708 | switch (channel_id) { | ||
709 | case PCM_FRONT_CHANNEL: | ||
710 | spi_switch.name = "Analog Front Playback Switch"; | ||
711 | dac_id = (details->spi_dac & 0xf000) >> (4 * 3); | ||
712 | break; | ||
713 | case PCM_REAR_CHANNEL: | ||
714 | spi_switch.name = "Analog Rear Playback Switch"; | ||
715 | dac_id = (details->spi_dac & 0x0f00) >> (4 * 2); | ||
716 | break; | ||
717 | case PCM_CENTER_LFE_CHANNEL: | ||
718 | spi_switch.name = "Analog Center/LFE Playback Switch"; | ||
719 | dac_id = (details->spi_dac & 0x00f0) >> (4 * 1); | ||
720 | break; | ||
721 | case PCM_UNKNOWN_CHANNEL: | ||
722 | spi_switch.name = "Analog Side Playback Switch"; | ||
723 | dac_id = (details->spi_dac & 0x000f) >> (4 * 0); | ||
724 | break; | ||
725 | default: | ||
726 | /* Unused channel */ | ||
727 | spi_switch.name = NULL; | ||
728 | dac_id = 0; | ||
729 | } | ||
730 | reg = spi_dmute_reg[dac_id]; | ||
731 | bit = spi_dmute_bit[dac_id]; | ||
732 | |||
733 | spi_switch.private_value = (reg << SPI_REG_SHIFT) | bit; | ||
734 | |||
735 | return spi_switch; | ||
736 | } | ||
737 | |||
701 | static int __devinit remove_ctl(struct snd_card *card, const char *name) | 738 | static int __devinit remove_ctl(struct snd_card *card, const char *name) |
702 | { | 739 | { |
703 | struct snd_ctl_elem_id id; | 740 | struct snd_ctl_elem_id id; |
@@ -832,8 +869,18 @@ int __devinit snd_ca0106_mixer(struct snd_ca0106 *emu) | |||
832 | if (err < 0) | 869 | if (err < 0) |
833 | return err; | 870 | return err; |
834 | } | 871 | } |
835 | if (emu->details->spi_dac) | 872 | if (emu->details->spi_dac) { |
836 | ADD_CTLS(emu, snd_ca0106_volume_spi_dac_ctls); | 873 | int i; |
874 | for (i = 0;; i++) { | ||
875 | struct snd_kcontrol_new ctl; | ||
876 | ctl = snd_ca0106_volume_spi_dac_ctl(emu->details, i); | ||
877 | if (!ctl.name) | ||
878 | break; | ||
879 | err = snd_ctl_add(card, snd_ctl_new1(&ctl, emu)); | ||
880 | if (err < 0) | ||
881 | return err; | ||
882 | } | ||
883 | } | ||
837 | 884 | ||
838 | /* Create virtual master controls */ | 885 | /* Create virtual master controls */ |
839 | vmaster = snd_ctl_make_virtual_master("Master Playback Volume", | 886 | vmaster = snd_ctl_make_virtual_master("Master Playback Volume", |