^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * C-Media CMI8788 driver - mixer code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <sound/ac97_codec.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <sound/asoundef.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <sound/control.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <sound/tlv.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "oxygen.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "cm9780.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) static int dac_volume_info(struct snd_kcontrol *ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) struct snd_ctl_elem_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) struct oxygen *chip = ctl->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) info->count = chip->model.dac_channels_mixer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) info->value.integer.min = chip->model.dac_volume_min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) info->value.integer.max = chip->model.dac_volume_max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) static int dac_volume_get(struct snd_kcontrol *ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) struct snd_ctl_elem_value *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) struct oxygen *chip = ctl->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) mutex_lock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) for (i = 0; i < chip->model.dac_channels_mixer; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) value->value.integer.value[i] = chip->dac_volume[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) mutex_unlock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) static int dac_volume_put(struct snd_kcontrol *ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) struct snd_ctl_elem_value *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) struct oxygen *chip = ctl->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) int changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) changed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) mutex_lock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) for (i = 0; i < chip->model.dac_channels_mixer; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) if (value->value.integer.value[i] != chip->dac_volume[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) chip->dac_volume[i] = value->value.integer.value[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) changed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) if (changed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) chip->model.update_dac_volume(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) mutex_unlock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) static int dac_mute_get(struct snd_kcontrol *ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) struct snd_ctl_elem_value *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) struct oxygen *chip = ctl->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) mutex_lock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) value->value.integer.value[0] = !chip->dac_mute;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) mutex_unlock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) static int dac_mute_put(struct snd_kcontrol *ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) struct snd_ctl_elem_value *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) struct oxygen *chip = ctl->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) int changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) mutex_lock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) changed = (!value->value.integer.value[0]) != chip->dac_mute;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) if (changed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) chip->dac_mute = !value->value.integer.value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) chip->model.update_dac_mute(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) mutex_unlock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) static unsigned int upmix_item_count(struct oxygen *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) if (chip->model.dac_channels_pcm < 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) return 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) else if (chip->model.update_center_lfe_mix)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) return 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) return 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) static int upmix_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static const char *const names[5] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) "Front",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) "Front+Surround",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) "Front+Surround+Back",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) "Front+Surround+Center/LFE",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) "Front+Surround+Center/LFE+Back",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) struct oxygen *chip = ctl->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) unsigned int count = upmix_item_count(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) return snd_ctl_enum_info(info, 1, count, names);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) static int upmix_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) struct oxygen *chip = ctl->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) mutex_lock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) value->value.enumerated.item[0] = chip->dac_routing;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) mutex_unlock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) void oxygen_update_dac_routing(struct oxygen *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) /* DAC 0: front, DAC 1: surround, DAC 2: center/LFE, DAC 3: back */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) static const unsigned int reg_values[5] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) /* stereo -> front */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) (0 << OXYGEN_PLAY_DAC0_SOURCE_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) (1 << OXYGEN_PLAY_DAC1_SOURCE_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) (2 << OXYGEN_PLAY_DAC2_SOURCE_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) (3 << OXYGEN_PLAY_DAC3_SOURCE_SHIFT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) /* stereo -> front+surround */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) (0 << OXYGEN_PLAY_DAC0_SOURCE_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) (0 << OXYGEN_PLAY_DAC1_SOURCE_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) (2 << OXYGEN_PLAY_DAC2_SOURCE_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) (3 << OXYGEN_PLAY_DAC3_SOURCE_SHIFT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) /* stereo -> front+surround+back */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) (0 << OXYGEN_PLAY_DAC0_SOURCE_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) (0 << OXYGEN_PLAY_DAC1_SOURCE_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) (2 << OXYGEN_PLAY_DAC2_SOURCE_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) (0 << OXYGEN_PLAY_DAC3_SOURCE_SHIFT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) /* stereo -> front+surround+center/LFE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) (0 << OXYGEN_PLAY_DAC0_SOURCE_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) (0 << OXYGEN_PLAY_DAC1_SOURCE_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) (0 << OXYGEN_PLAY_DAC2_SOURCE_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) (3 << OXYGEN_PLAY_DAC3_SOURCE_SHIFT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) /* stereo -> front+surround+center/LFE+back */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) (0 << OXYGEN_PLAY_DAC0_SOURCE_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) (0 << OXYGEN_PLAY_DAC1_SOURCE_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) (0 << OXYGEN_PLAY_DAC2_SOURCE_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) (0 << OXYGEN_PLAY_DAC3_SOURCE_SHIFT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) u8 channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) unsigned int reg_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) channels = oxygen_read8(chip, OXYGEN_PLAY_CHANNELS) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) OXYGEN_PLAY_CHANNELS_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) if (channels == OXYGEN_PLAY_CHANNELS_2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) reg_value = reg_values[chip->dac_routing];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) else if (channels == OXYGEN_PLAY_CHANNELS_8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) /* in 7.1 mode, "rear" channels go to the "back" jack */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) reg_value = (0 << OXYGEN_PLAY_DAC0_SOURCE_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) (3 << OXYGEN_PLAY_DAC1_SOURCE_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) (2 << OXYGEN_PLAY_DAC2_SOURCE_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) (1 << OXYGEN_PLAY_DAC3_SOURCE_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) reg_value = (0 << OXYGEN_PLAY_DAC0_SOURCE_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) (1 << OXYGEN_PLAY_DAC1_SOURCE_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) (2 << OXYGEN_PLAY_DAC2_SOURCE_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) (3 << OXYGEN_PLAY_DAC3_SOURCE_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) if (chip->model.adjust_dac_routing)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) reg_value = chip->model.adjust_dac_routing(chip, reg_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) oxygen_write16_masked(chip, OXYGEN_PLAY_ROUTING, reg_value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) OXYGEN_PLAY_DAC0_SOURCE_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) OXYGEN_PLAY_DAC1_SOURCE_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) OXYGEN_PLAY_DAC2_SOURCE_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) OXYGEN_PLAY_DAC3_SOURCE_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) if (chip->model.update_center_lfe_mix)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) chip->model.update_center_lfe_mix(chip, chip->dac_routing > 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) EXPORT_SYMBOL(oxygen_update_dac_routing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) static int upmix_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) struct oxygen *chip = ctl->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) unsigned int count = upmix_item_count(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) int changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) if (value->value.enumerated.item[0] >= count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) mutex_lock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) changed = value->value.enumerated.item[0] != chip->dac_routing;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) if (changed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) chip->dac_routing = value->value.enumerated.item[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) oxygen_update_dac_routing(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) mutex_unlock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) static int spdif_switch_get(struct snd_kcontrol *ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) struct snd_ctl_elem_value *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) struct oxygen *chip = ctl->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) mutex_lock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) value->value.integer.value[0] = chip->spdif_playback_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) mutex_unlock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) static unsigned int oxygen_spdif_rate(unsigned int oxygen_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) switch (oxygen_rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) case OXYGEN_RATE_32000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) return IEC958_AES3_CON_FS_32000 << OXYGEN_SPDIF_CS_RATE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) case OXYGEN_RATE_44100:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) return IEC958_AES3_CON_FS_44100 << OXYGEN_SPDIF_CS_RATE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) default: /* OXYGEN_RATE_48000 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) return IEC958_AES3_CON_FS_48000 << OXYGEN_SPDIF_CS_RATE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) case OXYGEN_RATE_64000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return 0xb << OXYGEN_SPDIF_CS_RATE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) case OXYGEN_RATE_88200:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) return IEC958_AES3_CON_FS_88200 << OXYGEN_SPDIF_CS_RATE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) case OXYGEN_RATE_96000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) return IEC958_AES3_CON_FS_96000 << OXYGEN_SPDIF_CS_RATE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) case OXYGEN_RATE_176400:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) return IEC958_AES3_CON_FS_176400 << OXYGEN_SPDIF_CS_RATE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) case OXYGEN_RATE_192000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) return IEC958_AES3_CON_FS_192000 << OXYGEN_SPDIF_CS_RATE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) void oxygen_update_spdif_source(struct oxygen *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) u32 old_control, new_control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) u16 old_routing, new_routing;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) unsigned int oxygen_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) old_control = oxygen_read32(chip, OXYGEN_SPDIF_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) old_routing = oxygen_read16(chip, OXYGEN_PLAY_ROUTING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) if (chip->pcm_active & (1 << PCM_SPDIF)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) new_control = old_control | OXYGEN_SPDIF_OUT_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) new_routing = (old_routing & ~OXYGEN_PLAY_SPDIF_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) | OXYGEN_PLAY_SPDIF_SPDIF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) oxygen_rate = (old_control >> OXYGEN_SPDIF_OUT_RATE_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) & OXYGEN_I2S_RATE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) /* S/PDIF rate was already set by the caller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) } else if ((chip->pcm_active & (1 << PCM_MULTICH)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) chip->spdif_playback_enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) new_routing = (old_routing & ~OXYGEN_PLAY_SPDIF_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) | OXYGEN_PLAY_SPDIF_MULTICH_01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) oxygen_rate = oxygen_read16(chip, OXYGEN_I2S_MULTICH_FORMAT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) & OXYGEN_I2S_RATE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) new_control = (old_control & ~OXYGEN_SPDIF_OUT_RATE_MASK) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) (oxygen_rate << OXYGEN_SPDIF_OUT_RATE_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) OXYGEN_SPDIF_OUT_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) new_control = old_control & ~OXYGEN_SPDIF_OUT_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) new_routing = old_routing;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) oxygen_rate = OXYGEN_RATE_44100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if (old_routing != new_routing) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) oxygen_write32(chip, OXYGEN_SPDIF_CONTROL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) new_control & ~OXYGEN_SPDIF_OUT_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) oxygen_write16(chip, OXYGEN_PLAY_ROUTING, new_routing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) if (new_control & OXYGEN_SPDIF_OUT_ENABLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) oxygen_write32(chip, OXYGEN_SPDIF_OUTPUT_BITS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) oxygen_spdif_rate(oxygen_rate) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) ((chip->pcm_active & (1 << PCM_SPDIF)) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) chip->spdif_pcm_bits : chip->spdif_bits));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) oxygen_write32(chip, OXYGEN_SPDIF_CONTROL, new_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) static int spdif_switch_put(struct snd_kcontrol *ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) struct snd_ctl_elem_value *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) struct oxygen *chip = ctl->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) int changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) mutex_lock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) changed = value->value.integer.value[0] != chip->spdif_playback_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) if (changed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) chip->spdif_playback_enable = !!value->value.integer.value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) spin_lock_irq(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) oxygen_update_spdif_source(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) spin_unlock_irq(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) mutex_unlock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) static int spdif_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) info->type = SNDRV_CTL_ELEM_TYPE_IEC958;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) info->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) static void oxygen_to_iec958(u32 bits, struct snd_ctl_elem_value *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) value->value.iec958.status[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) bits & (OXYGEN_SPDIF_NONAUDIO | OXYGEN_SPDIF_C |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) OXYGEN_SPDIF_PREEMPHASIS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) value->value.iec958.status[1] = /* category and original */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) bits >> OXYGEN_SPDIF_CATEGORY_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) static u32 iec958_to_oxygen(struct snd_ctl_elem_value *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) u32 bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) bits = value->value.iec958.status[0] &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) (OXYGEN_SPDIF_NONAUDIO | OXYGEN_SPDIF_C |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) OXYGEN_SPDIF_PREEMPHASIS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) bits |= value->value.iec958.status[1] << OXYGEN_SPDIF_CATEGORY_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) if (bits & OXYGEN_SPDIF_NONAUDIO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) bits |= OXYGEN_SPDIF_V;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) return bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) static inline void write_spdif_bits(struct oxygen *chip, u32 bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) oxygen_write32_masked(chip, OXYGEN_SPDIF_OUTPUT_BITS, bits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) OXYGEN_SPDIF_NONAUDIO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) OXYGEN_SPDIF_C |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) OXYGEN_SPDIF_PREEMPHASIS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) OXYGEN_SPDIF_CATEGORY_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) OXYGEN_SPDIF_ORIGINAL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) OXYGEN_SPDIF_V);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) static int spdif_default_get(struct snd_kcontrol *ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) struct snd_ctl_elem_value *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) struct oxygen *chip = ctl->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) mutex_lock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) oxygen_to_iec958(chip->spdif_bits, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) mutex_unlock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) static int spdif_default_put(struct snd_kcontrol *ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) struct snd_ctl_elem_value *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) struct oxygen *chip = ctl->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) u32 new_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) int changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) new_bits = iec958_to_oxygen(value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) mutex_lock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) changed = new_bits != chip->spdif_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) if (changed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) chip->spdif_bits = new_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) if (!(chip->pcm_active & (1 << PCM_SPDIF)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) write_spdif_bits(chip, new_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) mutex_unlock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) static int spdif_mask_get(struct snd_kcontrol *ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) struct snd_ctl_elem_value *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) value->value.iec958.status[0] = IEC958_AES0_NONAUDIO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) IEC958_AES0_CON_NOT_COPYRIGHT | IEC958_AES0_CON_EMPHASIS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) value->value.iec958.status[1] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) IEC958_AES1_CON_CATEGORY | IEC958_AES1_CON_ORIGINAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) static int spdif_pcm_get(struct snd_kcontrol *ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) struct snd_ctl_elem_value *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) struct oxygen *chip = ctl->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) mutex_lock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) oxygen_to_iec958(chip->spdif_pcm_bits, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) mutex_unlock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) static int spdif_pcm_put(struct snd_kcontrol *ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) struct snd_ctl_elem_value *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) struct oxygen *chip = ctl->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) u32 new_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) int changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) new_bits = iec958_to_oxygen(value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) mutex_lock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) changed = new_bits != chip->spdif_pcm_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) if (changed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) chip->spdif_pcm_bits = new_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) if (chip->pcm_active & (1 << PCM_SPDIF))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) write_spdif_bits(chip, new_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) mutex_unlock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) static int spdif_input_mask_get(struct snd_kcontrol *ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) struct snd_ctl_elem_value *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) value->value.iec958.status[0] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) value->value.iec958.status[1] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) value->value.iec958.status[2] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) value->value.iec958.status[3] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) static int spdif_input_default_get(struct snd_kcontrol *ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) struct snd_ctl_elem_value *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) struct oxygen *chip = ctl->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) u32 bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) bits = oxygen_read32(chip, OXYGEN_SPDIF_INPUT_BITS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) value->value.iec958.status[0] = bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) value->value.iec958.status[1] = bits >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) value->value.iec958.status[2] = bits >> 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) value->value.iec958.status[3] = bits >> 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) static int spdif_bit_switch_get(struct snd_kcontrol *ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) struct snd_ctl_elem_value *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) struct oxygen *chip = ctl->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) u32 bit = ctl->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) value->value.integer.value[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) !!(oxygen_read32(chip, OXYGEN_SPDIF_CONTROL) & bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) static int spdif_bit_switch_put(struct snd_kcontrol *ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) struct snd_ctl_elem_value *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) struct oxygen *chip = ctl->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) u32 bit = ctl->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) u32 oldreg, newreg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) int changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) spin_lock_irq(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) oldreg = oxygen_read32(chip, OXYGEN_SPDIF_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) if (value->value.integer.value[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) newreg = oldreg | bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) newreg = oldreg & ~bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) changed = newreg != oldreg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) if (changed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) oxygen_write32(chip, OXYGEN_SPDIF_CONTROL, newreg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) spin_unlock_irq(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) static int monitor_volume_info(struct snd_kcontrol *ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) struct snd_ctl_elem_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) info->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) info->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) info->value.integer.max = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) static int monitor_get(struct snd_kcontrol *ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) struct snd_ctl_elem_value *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) struct oxygen *chip = ctl->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) u8 bit = ctl->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) int invert = ctl->private_value & (1 << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) value->value.integer.value[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) !!invert ^ !!(oxygen_read8(chip, OXYGEN_ADC_MONITOR) & bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) static int monitor_put(struct snd_kcontrol *ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) struct snd_ctl_elem_value *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) struct oxygen *chip = ctl->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) u8 bit = ctl->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) int invert = ctl->private_value & (1 << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) u8 oldreg, newreg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) int changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) spin_lock_irq(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) oldreg = oxygen_read8(chip, OXYGEN_ADC_MONITOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) if ((!!value->value.integer.value[0] ^ !!invert) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) newreg = oldreg | bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) newreg = oldreg & ~bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) changed = newreg != oldreg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) if (changed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) oxygen_write8(chip, OXYGEN_ADC_MONITOR, newreg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) spin_unlock_irq(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) static int ac97_switch_get(struct snd_kcontrol *ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) struct snd_ctl_elem_value *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) struct oxygen *chip = ctl->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) unsigned int codec = (ctl->private_value >> 24) & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) unsigned int index = ctl->private_value & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) unsigned int bitnr = (ctl->private_value >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) int invert = ctl->private_value & (1 << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) u16 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) mutex_lock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) reg = oxygen_read_ac97(chip, codec, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) mutex_unlock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) if (!(reg & (1 << bitnr)) ^ !invert)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) value->value.integer.value[0] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) value->value.integer.value[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) static void mute_ac97_ctl(struct oxygen *chip, unsigned int control)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) unsigned int priv_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) u16 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) if (!chip->controls[control])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) priv_idx = chip->controls[control]->private_value & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) value = oxygen_read_ac97(chip, 0, priv_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) if (!(value & 0x8000)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) oxygen_write_ac97(chip, 0, priv_idx, value | 0x8000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) if (chip->model.ac97_switch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) chip->model.ac97_switch(chip, priv_idx, 0x8000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) &chip->controls[control]->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) static int ac97_switch_put(struct snd_kcontrol *ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) struct snd_ctl_elem_value *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) struct oxygen *chip = ctl->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) unsigned int codec = (ctl->private_value >> 24) & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) unsigned int index = ctl->private_value & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) unsigned int bitnr = (ctl->private_value >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) int invert = ctl->private_value & (1 << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) u16 oldreg, newreg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) int change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) mutex_lock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) oldreg = oxygen_read_ac97(chip, codec, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) newreg = oldreg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) if (!value->value.integer.value[0] ^ !invert)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) newreg |= 1 << bitnr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) newreg &= ~(1 << bitnr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) change = newreg != oldreg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) if (change) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) oxygen_write_ac97(chip, codec, index, newreg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) if (codec == 0 && chip->model.ac97_switch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) chip->model.ac97_switch(chip, index, newreg & 0x8000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) if (index == AC97_LINE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) oxygen_write_ac97_masked(chip, 0, CM9780_GPIO_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) newreg & 0x8000 ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) CM9780_GPO0 : 0, CM9780_GPO0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) if (!(newreg & 0x8000)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) mute_ac97_ctl(chip, CONTROL_MIC_CAPTURE_SWITCH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) mute_ac97_ctl(chip, CONTROL_CD_CAPTURE_SWITCH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) mute_ac97_ctl(chip, CONTROL_AUX_CAPTURE_SWITCH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) } else if ((index == AC97_MIC || index == AC97_CD ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) index == AC97_VIDEO || index == AC97_AUX) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) bitnr == 15 && !(newreg & 0x8000)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) mute_ac97_ctl(chip, CONTROL_LINE_CAPTURE_SWITCH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) oxygen_write_ac97_masked(chip, 0, CM9780_GPIO_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) CM9780_GPO0, CM9780_GPO0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) mutex_unlock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) static int ac97_volume_info(struct snd_kcontrol *ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) struct snd_ctl_elem_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) int stereo = (ctl->private_value >> 16) & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) info->count = stereo ? 2 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) info->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) info->value.integer.max = 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) static int ac97_volume_get(struct snd_kcontrol *ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) struct snd_ctl_elem_value *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) struct oxygen *chip = ctl->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) unsigned int codec = (ctl->private_value >> 24) & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) int stereo = (ctl->private_value >> 16) & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) unsigned int index = ctl->private_value & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) u16 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) mutex_lock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) reg = oxygen_read_ac97(chip, codec, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) mutex_unlock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) if (!stereo) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) value->value.integer.value[0] = 31 - (reg & 0x1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) value->value.integer.value[0] = 31 - ((reg >> 8) & 0x1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) value->value.integer.value[1] = 31 - (reg & 0x1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) static int ac97_volume_put(struct snd_kcontrol *ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) struct snd_ctl_elem_value *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) struct oxygen *chip = ctl->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) unsigned int codec = (ctl->private_value >> 24) & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) int stereo = (ctl->private_value >> 16) & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) unsigned int index = ctl->private_value & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) u16 oldreg, newreg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) int change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) mutex_lock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) oldreg = oxygen_read_ac97(chip, codec, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) if (!stereo) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) newreg = oldreg & ~0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) newreg |= 31 - (value->value.integer.value[0] & 0x1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) newreg = oldreg & ~0x1f1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) newreg |= (31 - (value->value.integer.value[0] & 0x1f)) << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) newreg |= 31 - (value->value.integer.value[1] & 0x1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) change = newreg != oldreg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) if (change)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) oxygen_write_ac97(chip, codec, index, newreg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) mutex_unlock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) static int mic_fmic_source_info(struct snd_kcontrol *ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) struct snd_ctl_elem_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) static const char *const names[] = { "Mic Jack", "Front Panel" };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) return snd_ctl_enum_info(info, 1, 2, names);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) static int mic_fmic_source_get(struct snd_kcontrol *ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) struct snd_ctl_elem_value *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) struct oxygen *chip = ctl->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) mutex_lock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) value->value.enumerated.item[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) !!(oxygen_read_ac97(chip, 0, CM9780_JACK) & CM9780_FMIC2MIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) mutex_unlock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) static int mic_fmic_source_put(struct snd_kcontrol *ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) struct snd_ctl_elem_value *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) struct oxygen *chip = ctl->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) u16 oldreg, newreg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) int change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) mutex_lock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) oldreg = oxygen_read_ac97(chip, 0, CM9780_JACK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) if (value->value.enumerated.item[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) newreg = oldreg | CM9780_FMIC2MIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) newreg = oldreg & ~CM9780_FMIC2MIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) change = newreg != oldreg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) if (change)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) oxygen_write_ac97(chip, 0, CM9780_JACK, newreg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) mutex_unlock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) static int ac97_fp_rec_volume_info(struct snd_kcontrol *ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) struct snd_ctl_elem_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) info->count = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) info->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) info->value.integer.max = 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) static int ac97_fp_rec_volume_get(struct snd_kcontrol *ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) struct snd_ctl_elem_value *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) struct oxygen *chip = ctl->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) u16 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) mutex_lock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) reg = oxygen_read_ac97(chip, 1, AC97_REC_GAIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) mutex_unlock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) value->value.integer.value[0] = reg & 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) value->value.integer.value[1] = (reg >> 8) & 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) static int ac97_fp_rec_volume_put(struct snd_kcontrol *ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) struct snd_ctl_elem_value *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) struct oxygen *chip = ctl->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) u16 oldreg, newreg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) int change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) mutex_lock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) oldreg = oxygen_read_ac97(chip, 1, AC97_REC_GAIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) newreg = oldreg & ~0x0707;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) newreg = newreg | (value->value.integer.value[0] & 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) newreg = newreg | ((value->value.integer.value[0] & 7) << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) change = newreg != oldreg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) if (change)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) oxygen_write_ac97(chip, 1, AC97_REC_GAIN, newreg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) mutex_unlock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) #define AC97_SWITCH(xname, codec, index, bitnr, invert) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) .name = xname, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) .info = snd_ctl_boolean_mono_info, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) .get = ac97_switch_get, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) .put = ac97_switch_put, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) .private_value = ((codec) << 24) | ((invert) << 16) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) ((bitnr) << 8) | (index), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) #define AC97_VOLUME(xname, codec, index, stereo) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) .name = xname, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) .info = ac97_volume_info, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) .get = ac97_volume_get, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) .put = ac97_volume_put, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) .tlv = { .p = ac97_db_scale, }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) .private_value = ((codec) << 24) | ((stereo) << 16) | (index), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) static DECLARE_TLV_DB_SCALE(monitor_db_scale, -600, 600, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) static DECLARE_TLV_DB_SCALE(ac97_db_scale, -3450, 150, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) static DECLARE_TLV_DB_SCALE(ac97_rec_db_scale, 0, 150, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) static const struct snd_kcontrol_new controls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) .name = "Master Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) .info = dac_volume_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) .get = dac_volume_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) .put = dac_volume_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) .name = "Master Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) .info = snd_ctl_boolean_mono_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) .get = dac_mute_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) .put = dac_mute_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) .name = "Stereo Upmixing",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) .info = upmix_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) .get = upmix_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) .put = upmix_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) static const struct snd_kcontrol_new spdif_output_controls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, SWITCH),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) .info = snd_ctl_boolean_mono_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) .get = spdif_switch_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) .put = spdif_switch_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) .iface = SNDRV_CTL_ELEM_IFACE_PCM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) .device = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) .info = spdif_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) .get = spdif_default_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) .put = spdif_default_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) .iface = SNDRV_CTL_ELEM_IFACE_PCM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) .device = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, CON_MASK),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) .access = SNDRV_CTL_ELEM_ACCESS_READ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) .info = spdif_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) .get = spdif_mask_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) .iface = SNDRV_CTL_ELEM_IFACE_PCM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) .device = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, PCM_STREAM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) SNDRV_CTL_ELEM_ACCESS_INACTIVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) .info = spdif_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) .get = spdif_pcm_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) .put = spdif_pcm_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) static const struct snd_kcontrol_new spdif_input_controls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) .iface = SNDRV_CTL_ELEM_IFACE_PCM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) .device = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, MASK),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) .access = SNDRV_CTL_ELEM_ACCESS_READ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) .info = spdif_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) .get = spdif_input_mask_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) .iface = SNDRV_CTL_ELEM_IFACE_PCM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) .device = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, DEFAULT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) .access = SNDRV_CTL_ELEM_ACCESS_READ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) .info = spdif_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) .get = spdif_input_default_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) .name = SNDRV_CTL_NAME_IEC958("Loopback ", NONE, SWITCH),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) .info = snd_ctl_boolean_mono_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) .get = spdif_bit_switch_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) .put = spdif_bit_switch_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) .private_value = OXYGEN_SPDIF_LOOPBACK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) .name = SNDRV_CTL_NAME_IEC958("Validity Check ",CAPTURE,SWITCH),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) .info = snd_ctl_boolean_mono_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) .get = spdif_bit_switch_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) .put = spdif_bit_switch_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) .private_value = OXYGEN_SPDIF_SPDVALID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) static const struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) unsigned int pcm_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) struct snd_kcontrol_new controls[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) } monitor_controls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) .pcm_dev = CAPTURE_0_FROM_I2S_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) .controls = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) .name = "Analog Input Monitor Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) .info = snd_ctl_boolean_mono_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) .get = monitor_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) .put = monitor_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) .private_value = OXYGEN_ADC_MONITOR_A,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) .name = "Analog Input Monitor Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) SNDRV_CTL_ELEM_ACCESS_TLV_READ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) .info = monitor_volume_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) .get = monitor_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) .put = monitor_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) .private_value = OXYGEN_ADC_MONITOR_A_HALF_VOL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) | (1 << 8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) .tlv = { .p = monitor_db_scale, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) .pcm_dev = CAPTURE_0_FROM_I2S_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) .controls = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) .name = "Analog Input Monitor Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) .info = snd_ctl_boolean_mono_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) .get = monitor_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) .put = monitor_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) .private_value = OXYGEN_ADC_MONITOR_B,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) .name = "Analog Input Monitor Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) SNDRV_CTL_ELEM_ACCESS_TLV_READ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) .info = monitor_volume_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) .get = monitor_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) .put = monitor_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) .private_value = OXYGEN_ADC_MONITOR_B_HALF_VOL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) | (1 << 8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) .tlv = { .p = monitor_db_scale, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) .pcm_dev = CAPTURE_2_FROM_I2S_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) .controls = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) .name = "Analog Input Monitor Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) .index = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) .info = snd_ctl_boolean_mono_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) .get = monitor_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) .put = monitor_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) .private_value = OXYGEN_ADC_MONITOR_B,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) .name = "Analog Input Monitor Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) .index = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) SNDRV_CTL_ELEM_ACCESS_TLV_READ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) .info = monitor_volume_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) .get = monitor_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) .put = monitor_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) .private_value = OXYGEN_ADC_MONITOR_B_HALF_VOL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) | (1 << 8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) .tlv = { .p = monitor_db_scale, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) .pcm_dev = CAPTURE_3_FROM_I2S_3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) .controls = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) .name = "Analog Input Monitor Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) .index = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) .info = snd_ctl_boolean_mono_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) .get = monitor_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) .put = monitor_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) .private_value = OXYGEN_ADC_MONITOR_C,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) .name = "Analog Input Monitor Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) .index = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) SNDRV_CTL_ELEM_ACCESS_TLV_READ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) .info = monitor_volume_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) .get = monitor_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) .put = monitor_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) .private_value = OXYGEN_ADC_MONITOR_C_HALF_VOL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) | (1 << 8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) .tlv = { .p = monitor_db_scale, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) .pcm_dev = CAPTURE_1_FROM_SPDIF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) .controls = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) .name = "Digital Input Monitor Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) .info = snd_ctl_boolean_mono_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) .get = monitor_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) .put = monitor_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) .private_value = OXYGEN_ADC_MONITOR_C,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) .name = "Digital Input Monitor Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) SNDRV_CTL_ELEM_ACCESS_TLV_READ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) .info = monitor_volume_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) .get = monitor_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) .put = monitor_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) .private_value = OXYGEN_ADC_MONITOR_C_HALF_VOL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) | (1 << 8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) .tlv = { .p = monitor_db_scale, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) static const struct snd_kcontrol_new ac97_controls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) AC97_VOLUME("Mic Capture Volume", 0, AC97_MIC, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) AC97_SWITCH("Mic Capture Switch", 0, AC97_MIC, 15, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) AC97_SWITCH("Mic Boost (+20dB)", 0, AC97_MIC, 6, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) .name = "Mic Source Capture Enum",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) .info = mic_fmic_source_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) .get = mic_fmic_source_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) .put = mic_fmic_source_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) AC97_SWITCH("Line Capture Switch", 0, AC97_LINE, 15, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) AC97_VOLUME("CD Capture Volume", 0, AC97_CD, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) AC97_SWITCH("CD Capture Switch", 0, AC97_CD, 15, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) AC97_VOLUME("Aux Capture Volume", 0, AC97_AUX, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) AC97_SWITCH("Aux Capture Switch", 0, AC97_AUX, 15, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) static const struct snd_kcontrol_new ac97_fp_controls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) AC97_VOLUME("Front Panel Playback Volume", 1, AC97_HEADPHONE, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) AC97_SWITCH("Front Panel Playback Switch", 1, AC97_HEADPHONE, 15, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) .name = "Front Panel Capture Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) SNDRV_CTL_ELEM_ACCESS_TLV_READ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) .info = ac97_fp_rec_volume_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) .get = ac97_fp_rec_volume_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) .put = ac97_fp_rec_volume_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) .tlv = { .p = ac97_rec_db_scale, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) AC97_SWITCH("Front Panel Capture Switch", 1, AC97_REC_GAIN, 15, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) static void oxygen_any_ctl_free(struct snd_kcontrol *ctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) struct oxygen *chip = ctl->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) /* I'm too lazy to write a function for each control :-) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) for (i = 0; i < ARRAY_SIZE(chip->controls); ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) chip->controls[i] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) static int add_controls(struct oxygen *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) const struct snd_kcontrol_new controls[],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) unsigned int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) static const char *const known_ctl_names[CONTROL_COUNT] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) [CONTROL_SPDIF_PCM] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) SNDRV_CTL_NAME_IEC958("", PLAYBACK, PCM_STREAM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) [CONTROL_SPDIF_INPUT_BITS] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) SNDRV_CTL_NAME_IEC958("", CAPTURE, DEFAULT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) [CONTROL_MIC_CAPTURE_SWITCH] = "Mic Capture Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) [CONTROL_LINE_CAPTURE_SWITCH] = "Line Capture Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) [CONTROL_CD_CAPTURE_SWITCH] = "CD Capture Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) [CONTROL_AUX_CAPTURE_SWITCH] = "Aux Capture Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) struct snd_kcontrol_new template;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) struct snd_kcontrol *ctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) int j, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) for (i = 0; i < count; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) template = controls[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) if (chip->model.control_filter) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) err = chip->model.control_filter(&template);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) if (err == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) if (!strcmp(template.name, "Stereo Upmixing") &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) chip->model.dac_channels_pcm == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) if (!strcmp(template.name, "Mic Source Capture Enum") &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) !(chip->model.device_config & AC97_FMIC_SWITCH))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) if (!strncmp(template.name, "CD Capture ", 11) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) !(chip->model.device_config & AC97_CD_INPUT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) if (!strcmp(template.name, "Master Playback Volume") &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) chip->model.dac_tlv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) template.tlv.p = chip->model.dac_tlv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) template.access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) ctl = snd_ctl_new1(&template, chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) if (!ctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) err = snd_ctl_add(chip->card, ctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) j = match_string(known_ctl_names, CONTROL_COUNT, ctl->id.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) if (j >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) chip->controls[j] = ctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) ctl->private_free = oxygen_any_ctl_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) int oxygen_mixer_init(struct oxygen *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) err = add_controls(chip, controls, ARRAY_SIZE(controls));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) if (chip->model.device_config & PLAYBACK_1_TO_SPDIF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) err = add_controls(chip, spdif_output_controls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) ARRAY_SIZE(spdif_output_controls));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) if (chip->model.device_config & CAPTURE_1_FROM_SPDIF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) err = add_controls(chip, spdif_input_controls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) ARRAY_SIZE(spdif_input_controls));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) for (i = 0; i < ARRAY_SIZE(monitor_controls); ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) if (!(chip->model.device_config & monitor_controls[i].pcm_dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) err = add_controls(chip, monitor_controls[i].controls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) ARRAY_SIZE(monitor_controls[i].controls));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) if (chip->has_ac97_0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) err = add_controls(chip, ac97_controls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) ARRAY_SIZE(ac97_controls));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) if (chip->has_ac97_1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) err = add_controls(chip, ac97_fp_controls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) ARRAY_SIZE(ac97_fp_controls));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) return chip->model.mixer_init ? chip->model.mixer_init(chip) : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) }