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