- patches.suse/slab-handle-memoryless-nodes-v2a.patch: Refresh.
[linux-flexiantxendom0-3.2.10.git] / sound / pci / oxygen / oxygen_mixer.c
index 5401c54..f375b8a 100644 (file)
@@ -99,11 +99,15 @@ static int dac_mute_put(struct snd_kcontrol *ctl,
 
 static int upmix_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info)
 {
-       static const char *const names[3] = {
-               "Front", "Front+Surround", "Front+Surround+Back"
+       static const char *const names[5] = {
+               "Front",
+               "Front+Surround",
+               "Front+Surround+Back",
+               "Front+Surround+Center/LFE",
+               "Front+Surround+Center/LFE+Back",
        };
        struct oxygen *chip = ctl->private_data;
-       unsigned int count = 2 + (chip->model.dac_channels == 8);
+       unsigned int count = chip->model.update_center_lfe_mix ? 5 : 3;
 
        info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
        info->count = 1;
@@ -127,7 +131,7 @@ static int upmix_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
 void oxygen_update_dac_routing(struct oxygen *chip)
 {
        /* DAC 0: front, DAC 1: surround, DAC 2: center/LFE, DAC 3: back */
-       static const unsigned int reg_values[3] = {
+       static const unsigned int reg_values[5] = {
                /* stereo -> front */
                (0 << OXYGEN_PLAY_DAC0_SOURCE_SHIFT) |
                (1 << OXYGEN_PLAY_DAC1_SOURCE_SHIFT) |
@@ -143,6 +147,16 @@ void oxygen_update_dac_routing(struct oxygen *chip)
                (0 << OXYGEN_PLAY_DAC1_SOURCE_SHIFT) |
                (2 << OXYGEN_PLAY_DAC2_SOURCE_SHIFT) |
                (0 << OXYGEN_PLAY_DAC3_SOURCE_SHIFT),
+               /* stereo -> front+surround+center/LFE */
+               (0 << OXYGEN_PLAY_DAC0_SOURCE_SHIFT) |
+               (0 << OXYGEN_PLAY_DAC1_SOURCE_SHIFT) |
+               (0 << OXYGEN_PLAY_DAC2_SOURCE_SHIFT) |
+               (3 << OXYGEN_PLAY_DAC3_SOURCE_SHIFT),
+               /* stereo -> front+surround+center/LFE+back */
+               (0 << OXYGEN_PLAY_DAC0_SOURCE_SHIFT) |
+               (0 << OXYGEN_PLAY_DAC1_SOURCE_SHIFT) |
+               (0 << OXYGEN_PLAY_DAC2_SOURCE_SHIFT) |
+               (0 << OXYGEN_PLAY_DAC3_SOURCE_SHIFT),
        };
        u8 channels;
        unsigned int reg_value;
@@ -167,22 +181,23 @@ void oxygen_update_dac_routing(struct oxygen *chip)
                              OXYGEN_PLAY_DAC1_SOURCE_MASK |
                              OXYGEN_PLAY_DAC2_SOURCE_MASK |
                              OXYGEN_PLAY_DAC3_SOURCE_MASK);
+       if (chip->model.update_center_lfe_mix)
+               chip->model.update_center_lfe_mix(chip, chip->dac_routing > 2);
 }
 
 static int upmix_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
 {
        struct oxygen *chip = ctl->private_data;
-       unsigned int count = 2 + (chip->model.dac_channels == 8);
+       unsigned int count = chip->model.update_center_lfe_mix ? 5 : 3;
        int changed;
 
+       if (value->value.enumerated.item[0] >= count)
+               return -EINVAL;
        mutex_lock(&chip->mutex);
        changed = value->value.enumerated.item[0] != chip->dac_routing;
        if (changed) {
-               chip->dac_routing = min(value->value.enumerated.item[0],
-                                       count - 1);
-               spin_lock_irq(&chip->reg_lock);
+               chip->dac_routing = value->value.enumerated.item[0];
                oxygen_update_dac_routing(chip);
-               spin_unlock_irq(&chip->reg_lock);
        }
        mutex_unlock(&chip->mutex);
        return changed;
@@ -790,7 +805,7 @@ static const struct {
                .controls = {
                        {
                                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-                               .name = "Analog Input Monitor Switch",
+                               .name = "Analog Input Monitor Playback Switch",
                                .info = snd_ctl_boolean_mono_info,
                                .get = monitor_get,
                                .put = monitor_put,
@@ -798,7 +813,7 @@ static const struct {
                        },
                        {
                                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-                               .name = "Analog Input Monitor Volume",
+                               .name = "Analog Input Monitor Playback Volume",
                                .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
                                          SNDRV_CTL_ELEM_ACCESS_TLV_READ,
                                .info = monitor_volume_info,
@@ -815,7 +830,7 @@ static const struct {
                .controls = {
                        {
                                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-                               .name = "Analog Input Monitor Switch",
+                               .name = "Analog Input Monitor Playback Switch",
                                .info = snd_ctl_boolean_mono_info,
                                .get = monitor_get,
                                .put = monitor_put,
@@ -823,7 +838,7 @@ static const struct {
                        },
                        {
                                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-                               .name = "Analog Input Monitor Volume",
+                               .name = "Analog Input Monitor Playback Volume",
                                .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
                                          SNDRV_CTL_ELEM_ACCESS_TLV_READ,
                                .info = monitor_volume_info,
@@ -840,7 +855,7 @@ static const struct {
                .controls = {
                        {
                                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-                               .name = "Analog Input Monitor Switch",
+                               .name = "Analog Input Monitor Playback Switch",
                                .index = 1,
                                .info = snd_ctl_boolean_mono_info,
                                .get = monitor_get,
@@ -849,7 +864,7 @@ static const struct {
                        },
                        {
                                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-                               .name = "Analog Input Monitor Volume",
+                               .name = "Analog Input Monitor Playback Volume",
                                .index = 1,
                                .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
                                          SNDRV_CTL_ELEM_ACCESS_TLV_READ,
@@ -867,7 +882,7 @@ static const struct {
                .controls = {
                        {
                                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-                               .name = "Digital Input Monitor Switch",
+                               .name = "Digital Input Monitor Playback Switch",
                                .info = snd_ctl_boolean_mono_info,
                                .get = monitor_get,
                                .put = monitor_put,
@@ -875,7 +890,7 @@ static const struct {
                        },
                        {
                                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-                               .name = "Digital Input Monitor Volume",
+                               .name = "Digital Input Monitor Playback Volume",
                                .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
                                          SNDRV_CTL_ELEM_ACCESS_TLV_READ,
                                .info = monitor_volume_info,
@@ -954,6 +969,9 @@ static int add_controls(struct oxygen *chip,
                        if (err == 1)
                                continue;
                }
+               if (!strcmp(template.name, "Stereo Upmixing") &&
+                   chip->model.dac_channels == 2)
+                       continue;
                if (!strcmp(template.name, "Master Playback Volume") &&
                    chip->model.dac_tlv) {
                        template.tlv.p = chip->model.dac_tlv;