^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * This driver supports the analog controls for the internal codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * found in Allwinner's A64 SoC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2016 Chen-Yu Tsai <wens@csie.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (C) 2017 Marcus Cooper <codekipper@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (C) 2018 Vasily Khoruzhick <anarsoul@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Based on sun8i-codec-analog.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <sound/soc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <sound/soc-dapm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <sound/tlv.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include "sun8i-adda-pr-regmap.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) /* Codec analog control register offsets and bit fields */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define SUN50I_ADDA_HP_CTRL 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define SUN50I_ADDA_HP_CTRL_PA_CLK_GATE 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define SUN50I_ADDA_HP_CTRL_HPPA_EN 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define SUN50I_ADDA_HP_CTRL_HPVOL 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define SUN50I_ADDA_OL_MIX_CTRL 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define SUN50I_ADDA_OL_MIX_CTRL_MIC1 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define SUN50I_ADDA_OL_MIX_CTRL_MIC2 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define SUN50I_ADDA_OL_MIX_CTRL_PHONE 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define SUN50I_ADDA_OL_MIX_CTRL_PHONEN 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define SUN50I_ADDA_OL_MIX_CTRL_LINEINL 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define SUN50I_ADDA_OL_MIX_CTRL_DACL 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define SUN50I_ADDA_OL_MIX_CTRL_DACR 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define SUN50I_ADDA_OR_MIX_CTRL 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define SUN50I_ADDA_OR_MIX_CTRL_MIC1 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define SUN50I_ADDA_OR_MIX_CTRL_MIC2 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define SUN50I_ADDA_OR_MIX_CTRL_PHONE 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define SUN50I_ADDA_OR_MIX_CTRL_PHONEP 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define SUN50I_ADDA_OR_MIX_CTRL_LINEINR 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define SUN50I_ADDA_OR_MIX_CTRL_DACR 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define SUN50I_ADDA_OR_MIX_CTRL_DACL 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define SUN50I_ADDA_EARPIECE_CTRL0 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define SUN50I_ADDA_EARPIECE_CTRL0_EAR_RAMP_TIME 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define SUN50I_ADDA_EARPIECE_CTRL0_ESPSR 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define SUN50I_ADDA_EARPIECE_CTRL1 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define SUN50I_ADDA_EARPIECE_CTRL1_ESPPA_EN 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define SUN50I_ADDA_EARPIECE_CTRL1_ESPPA_MUTE 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define SUN50I_ADDA_EARPIECE_CTRL1_ESP_VOL 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define SUN50I_ADDA_LINEOUT_CTRL0 0x05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define SUN50I_ADDA_LINEOUT_CTRL0_LEN 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define SUN50I_ADDA_LINEOUT_CTRL0_REN 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define SUN50I_ADDA_LINEOUT_CTRL0_LSRC_SEL 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define SUN50I_ADDA_LINEOUT_CTRL0_RSRC_SEL 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define SUN50I_ADDA_LINEOUT_CTRL1 0x06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define SUN50I_ADDA_LINEOUT_CTRL1_VOL 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define SUN50I_ADDA_MIC1_CTRL 0x07
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define SUN50I_ADDA_MIC1_CTRL_MIC1G 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define SUN50I_ADDA_MIC1_CTRL_MIC1AMPEN 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define SUN50I_ADDA_MIC1_CTRL_MIC1BOOST 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define SUN50I_ADDA_MIC2_CTRL 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define SUN50I_ADDA_MIC2_CTRL_MIC2G 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define SUN50I_ADDA_MIC2_CTRL_MIC2AMPEN 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define SUN50I_ADDA_MIC2_CTRL_MIC2BOOST 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define SUN50I_ADDA_LINEIN_CTRL 0x09
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define SUN50I_ADDA_LINEIN_CTRL_LINEING 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define SUN50I_ADDA_MIX_DAC_CTRL 0x0a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define SUN50I_ADDA_MIX_DAC_CTRL_DACAREN 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define SUN50I_ADDA_MIX_DAC_CTRL_DACALEN 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define SUN50I_ADDA_MIX_DAC_CTRL_RMIXEN 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define SUN50I_ADDA_MIX_DAC_CTRL_LMIXEN 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define SUN50I_ADDA_MIX_DAC_CTRL_RHPPAMUTE 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define SUN50I_ADDA_MIX_DAC_CTRL_LHPPAMUTE 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define SUN50I_ADDA_MIX_DAC_CTRL_RHPIS 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define SUN50I_ADDA_MIX_DAC_CTRL_LHPIS 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define SUN50I_ADDA_L_ADCMIX_SRC 0x0b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define SUN50I_ADDA_L_ADCMIX_SRC_MIC1 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define SUN50I_ADDA_L_ADCMIX_SRC_MIC2 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define SUN50I_ADDA_L_ADCMIX_SRC_PHONE 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define SUN50I_ADDA_L_ADCMIX_SRC_PHONEN 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define SUN50I_ADDA_L_ADCMIX_SRC_LINEINL 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define SUN50I_ADDA_L_ADCMIX_SRC_OMIXRL 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define SUN50I_ADDA_L_ADCMIX_SRC_OMIXRR 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define SUN50I_ADDA_R_ADCMIX_SRC 0x0c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define SUN50I_ADDA_R_ADCMIX_SRC_MIC1 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define SUN50I_ADDA_R_ADCMIX_SRC_MIC2 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #define SUN50I_ADDA_R_ADCMIX_SRC_PHONE 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #define SUN50I_ADDA_R_ADCMIX_SRC_PHONEP 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define SUN50I_ADDA_R_ADCMIX_SRC_LINEINR 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #define SUN50I_ADDA_R_ADCMIX_SRC_OMIXR 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define SUN50I_ADDA_R_ADCMIX_SRC_OMIXL 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #define SUN50I_ADDA_ADC_CTRL 0x0d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) #define SUN50I_ADDA_ADC_CTRL_ADCREN 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) #define SUN50I_ADDA_ADC_CTRL_ADCLEN 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #define SUN50I_ADDA_ADC_CTRL_ADCG 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) #define SUN50I_ADDA_HS_MBIAS_CTRL 0x0e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) #define SUN50I_ADDA_HS_MBIAS_CTRL_MMICBIASEN 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) #define SUN50I_ADDA_JACK_MIC_CTRL 0x1d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) #define SUN50I_ADDA_JACK_MIC_CTRL_HMICBIASEN 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) /* mixer controls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) static const struct snd_kcontrol_new sun50i_a64_codec_mixer_controls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) SOC_DAPM_DOUBLE_R("Mic1 Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) SUN50I_ADDA_OL_MIX_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) SUN50I_ADDA_OR_MIX_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) SUN50I_ADDA_OL_MIX_CTRL_MIC1, 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) SOC_DAPM_DOUBLE_R("Mic2 Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) SUN50I_ADDA_OL_MIX_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) SUN50I_ADDA_OR_MIX_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) SUN50I_ADDA_OL_MIX_CTRL_MIC2, 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) SOC_DAPM_DOUBLE_R("Line In Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) SUN50I_ADDA_OL_MIX_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) SUN50I_ADDA_OR_MIX_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) SUN50I_ADDA_OL_MIX_CTRL_LINEINL, 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) SOC_DAPM_DOUBLE_R("DAC Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) SUN50I_ADDA_OL_MIX_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) SUN50I_ADDA_OR_MIX_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) SUN50I_ADDA_OL_MIX_CTRL_DACL, 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) SOC_DAPM_DOUBLE_R("DAC Reversed Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) SUN50I_ADDA_OL_MIX_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) SUN50I_ADDA_OR_MIX_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) SUN50I_ADDA_OL_MIX_CTRL_DACR, 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) /* ADC mixer controls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) static const struct snd_kcontrol_new sun50i_codec_adc_mixer_controls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) SOC_DAPM_DOUBLE_R("Mic1 Capture Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) SUN50I_ADDA_L_ADCMIX_SRC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) SUN50I_ADDA_R_ADCMIX_SRC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) SUN50I_ADDA_L_ADCMIX_SRC_MIC1, 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) SOC_DAPM_DOUBLE_R("Mic2 Capture Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) SUN50I_ADDA_L_ADCMIX_SRC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) SUN50I_ADDA_R_ADCMIX_SRC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) SUN50I_ADDA_L_ADCMIX_SRC_MIC2, 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) SOC_DAPM_DOUBLE_R("Line In Capture Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) SUN50I_ADDA_L_ADCMIX_SRC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) SUN50I_ADDA_R_ADCMIX_SRC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) SUN50I_ADDA_L_ADCMIX_SRC_LINEINL, 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) SOC_DAPM_DOUBLE_R("Mixer Capture Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) SUN50I_ADDA_L_ADCMIX_SRC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) SUN50I_ADDA_R_ADCMIX_SRC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) SUN50I_ADDA_L_ADCMIX_SRC_OMIXRL, 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) SOC_DAPM_DOUBLE_R("Mixer Reversed Capture Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) SUN50I_ADDA_L_ADCMIX_SRC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) SUN50I_ADDA_R_ADCMIX_SRC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) SUN50I_ADDA_L_ADCMIX_SRC_OMIXRR, 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) static const DECLARE_TLV_DB_SCALE(sun50i_codec_out_mixer_pregain_scale,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) -450, 150, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) static const DECLARE_TLV_DB_RANGE(sun50i_codec_mic_gain_scale,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 1, 7, TLV_DB_SCALE_ITEM(2400, 300, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) static const DECLARE_TLV_DB_SCALE(sun50i_codec_hp_vol_scale, -6300, 100, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) static const DECLARE_TLV_DB_RANGE(sun50i_codec_lineout_vol_scale,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 0, 1, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 2, 31, TLV_DB_SCALE_ITEM(-4350, 150, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) static const DECLARE_TLV_DB_RANGE(sun50i_codec_earpiece_vol_scale,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 0, 1, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 2, 31, TLV_DB_SCALE_ITEM(-4350, 150, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) /* volume / mute controls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) static const struct snd_kcontrol_new sun50i_a64_codec_controls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) SOC_SINGLE_TLV("Headphone Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) SUN50I_ADDA_HP_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) SUN50I_ADDA_HP_CTRL_HPVOL, 0x3f, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) sun50i_codec_hp_vol_scale),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) /* Mixer pre-gain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) SOC_SINGLE_TLV("Mic1 Playback Volume", SUN50I_ADDA_MIC1_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) SUN50I_ADDA_MIC1_CTRL_MIC1G,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 0x7, 0, sun50i_codec_out_mixer_pregain_scale),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) /* Microphone Amp boost gain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) SOC_SINGLE_TLV("Mic1 Boost Volume", SUN50I_ADDA_MIC1_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) SUN50I_ADDA_MIC1_CTRL_MIC1BOOST, 0x7, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) sun50i_codec_mic_gain_scale),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) /* Mixer pre-gain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) SOC_SINGLE_TLV("Mic2 Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) SUN50I_ADDA_MIC2_CTRL, SUN50I_ADDA_MIC2_CTRL_MIC2G,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 0x7, 0, sun50i_codec_out_mixer_pregain_scale),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) /* Microphone Amp boost gain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) SOC_SINGLE_TLV("Mic2 Boost Volume", SUN50I_ADDA_MIC2_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) SUN50I_ADDA_MIC2_CTRL_MIC2BOOST, 0x7, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) sun50i_codec_mic_gain_scale),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) /* ADC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) SOC_SINGLE_TLV("ADC Gain Capture Volume", SUN50I_ADDA_ADC_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) SUN50I_ADDA_ADC_CTRL_ADCG, 0x7, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) sun50i_codec_out_mixer_pregain_scale),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) /* Mixer pre-gain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) SOC_SINGLE_TLV("Line In Playback Volume", SUN50I_ADDA_LINEIN_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) SUN50I_ADDA_LINEIN_CTRL_LINEING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 0x7, 0, sun50i_codec_out_mixer_pregain_scale),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) SOC_SINGLE_TLV("Line Out Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) SUN50I_ADDA_LINEOUT_CTRL1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) SUN50I_ADDA_LINEOUT_CTRL1_VOL, 0x1f, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) sun50i_codec_lineout_vol_scale),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) SOC_SINGLE_TLV("Earpiece Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) SUN50I_ADDA_EARPIECE_CTRL1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) SUN50I_ADDA_EARPIECE_CTRL1_ESP_VOL, 0x1f, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) sun50i_codec_earpiece_vol_scale),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) static const char * const sun50i_codec_hp_src_enum_text[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) "DAC", "Mixer",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) static SOC_ENUM_DOUBLE_DECL(sun50i_codec_hp_src_enum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) SUN50I_ADDA_MIX_DAC_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) SUN50I_ADDA_MIX_DAC_CTRL_LHPIS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) SUN50I_ADDA_MIX_DAC_CTRL_RHPIS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) sun50i_codec_hp_src_enum_text);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) static const struct snd_kcontrol_new sun50i_codec_hp_src[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) SOC_DAPM_ENUM("Headphone Source Playback Route",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) sun50i_codec_hp_src_enum),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) static const struct snd_kcontrol_new sun50i_codec_hp_switch =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) SOC_DAPM_DOUBLE("Headphone Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) SUN50I_ADDA_MIX_DAC_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) SUN50I_ADDA_MIX_DAC_CTRL_LHPPAMUTE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) SUN50I_ADDA_MIX_DAC_CTRL_RHPPAMUTE, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) static const char * const sun50i_codec_lineout_src_enum_text[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) "Stereo", "Mono Differential",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) static SOC_ENUM_DOUBLE_DECL(sun50i_codec_lineout_src_enum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) SUN50I_ADDA_LINEOUT_CTRL0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) SUN50I_ADDA_LINEOUT_CTRL0_LSRC_SEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) SUN50I_ADDA_LINEOUT_CTRL0_RSRC_SEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) sun50i_codec_lineout_src_enum_text);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) static const struct snd_kcontrol_new sun50i_codec_lineout_src[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) SOC_DAPM_ENUM("Line Out Source Playback Route",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) sun50i_codec_lineout_src_enum),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) static const struct snd_kcontrol_new sun50i_codec_lineout_switch =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) SOC_DAPM_DOUBLE("Line Out Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) SUN50I_ADDA_LINEOUT_CTRL0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) SUN50I_ADDA_LINEOUT_CTRL0_LEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) SUN50I_ADDA_LINEOUT_CTRL0_REN, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) static const char * const sun50i_codec_earpiece_src_enum_text[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) "DACR", "DACL", "Right Mixer", "Left Mixer",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) static SOC_ENUM_SINGLE_DECL(sun50i_codec_earpiece_src_enum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) SUN50I_ADDA_EARPIECE_CTRL0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) SUN50I_ADDA_EARPIECE_CTRL0_ESPSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) sun50i_codec_earpiece_src_enum_text);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) static const struct snd_kcontrol_new sun50i_codec_earpiece_src[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) SOC_DAPM_ENUM("Earpiece Source Playback Route",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) sun50i_codec_earpiece_src_enum),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) static const struct snd_kcontrol_new sun50i_codec_earpiece_switch[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) SOC_DAPM_SINGLE("Earpiece Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) SUN50I_ADDA_EARPIECE_CTRL1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) SUN50I_ADDA_EARPIECE_CTRL1_ESPPA_MUTE, 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) static const struct snd_soc_dapm_widget sun50i_a64_codec_widgets[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) /* DAC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) SND_SOC_DAPM_DAC("Left DAC", NULL, SUN50I_ADDA_MIX_DAC_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) SUN50I_ADDA_MIX_DAC_CTRL_DACALEN, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) SND_SOC_DAPM_DAC("Right DAC", NULL, SUN50I_ADDA_MIX_DAC_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) SUN50I_ADDA_MIX_DAC_CTRL_DACAREN, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) /* ADC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) SND_SOC_DAPM_ADC("Left ADC", NULL, SUN50I_ADDA_ADC_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) SUN50I_ADDA_ADC_CTRL_ADCLEN, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) SND_SOC_DAPM_ADC("Right ADC", NULL, SUN50I_ADDA_ADC_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) SUN50I_ADDA_ADC_CTRL_ADCREN, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) * Due to this component and the codec belonging to separate DAPM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) * contexts, we need to manually link the above widgets to their
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) * stream widgets at the card level.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) SND_SOC_DAPM_REGULATOR_SUPPLY("cpvdd", 0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) SND_SOC_DAPM_MUX("Left Headphone Source",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) SND_SOC_NOPM, 0, 0, sun50i_codec_hp_src),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) SND_SOC_DAPM_MUX("Right Headphone Source",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) SND_SOC_NOPM, 0, 0, sun50i_codec_hp_src),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) SND_SOC_DAPM_SWITCH("Left Headphone Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) SND_SOC_NOPM, 0, 0, &sun50i_codec_hp_switch),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) SND_SOC_DAPM_SWITCH("Right Headphone Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) SND_SOC_NOPM, 0, 0, &sun50i_codec_hp_switch),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) SND_SOC_DAPM_OUT_DRV("Left Headphone Amp",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) SND_SOC_NOPM, 0, 0, NULL, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) SND_SOC_DAPM_OUT_DRV("Right Headphone Amp",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) SND_SOC_NOPM, 0, 0, NULL, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) SND_SOC_DAPM_SUPPLY("Headphone Amp", SUN50I_ADDA_HP_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) SUN50I_ADDA_HP_CTRL_HPPA_EN, 0, NULL, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) SND_SOC_DAPM_OUTPUT("HP"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) SND_SOC_DAPM_MUX("Left Line Out Source",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) SND_SOC_NOPM, 0, 0, sun50i_codec_lineout_src),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) SND_SOC_DAPM_MUX("Right Line Out Source",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) SND_SOC_NOPM, 0, 0, sun50i_codec_lineout_src),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) SND_SOC_DAPM_SWITCH("Left Line Out Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) SND_SOC_NOPM, 0, 0, &sun50i_codec_lineout_switch),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) SND_SOC_DAPM_SWITCH("Right Line Out Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) SND_SOC_NOPM, 0, 0, &sun50i_codec_lineout_switch),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) SND_SOC_DAPM_OUTPUT("LINEOUT"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) SND_SOC_DAPM_MUX("Earpiece Source Playback Route",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) SND_SOC_NOPM, 0, 0, sun50i_codec_earpiece_src),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) SOC_MIXER_NAMED_CTL_ARRAY("Earpiece Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) SND_SOC_NOPM, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) sun50i_codec_earpiece_switch),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) SND_SOC_DAPM_OUT_DRV("Earpiece Amp", SUN50I_ADDA_EARPIECE_CTRL1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) SUN50I_ADDA_EARPIECE_CTRL1_ESPPA_EN, 0, NULL, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) SND_SOC_DAPM_OUTPUT("EARPIECE"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) /* Microphone inputs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) SND_SOC_DAPM_INPUT("MIC1"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) /* Microphone Bias */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) SND_SOC_DAPM_SUPPLY("MBIAS", SUN50I_ADDA_HS_MBIAS_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) SUN50I_ADDA_HS_MBIAS_CTRL_MMICBIASEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 0, NULL, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) /* Mic input path */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) SND_SOC_DAPM_PGA("Mic1 Amplifier", SUN50I_ADDA_MIC1_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) SUN50I_ADDA_MIC1_CTRL_MIC1AMPEN, 0, NULL, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) /* Microphone input */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) SND_SOC_DAPM_INPUT("MIC2"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) /* Microphone Bias */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) SND_SOC_DAPM_SUPPLY("HBIAS", SUN50I_ADDA_JACK_MIC_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) SUN50I_ADDA_JACK_MIC_CTRL_HMICBIASEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 0, NULL, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) /* Mic input path */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) SND_SOC_DAPM_PGA("Mic2 Amplifier", SUN50I_ADDA_MIC2_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) SUN50I_ADDA_MIC2_CTRL_MIC2AMPEN, 0, NULL, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) /* Line input */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) SND_SOC_DAPM_INPUT("LINEIN"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) /* Mixers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) SND_SOC_DAPM_MIXER("Left Mixer", SUN50I_ADDA_MIX_DAC_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) SUN50I_ADDA_MIX_DAC_CTRL_LMIXEN, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) sun50i_a64_codec_mixer_controls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) ARRAY_SIZE(sun50i_a64_codec_mixer_controls)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) SND_SOC_DAPM_MIXER("Right Mixer", SUN50I_ADDA_MIX_DAC_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) SUN50I_ADDA_MIX_DAC_CTRL_RMIXEN, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) sun50i_a64_codec_mixer_controls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) ARRAY_SIZE(sun50i_a64_codec_mixer_controls)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) SND_SOC_DAPM_MIXER("Left ADC Mixer", SND_SOC_NOPM, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) sun50i_codec_adc_mixer_controls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) ARRAY_SIZE(sun50i_codec_adc_mixer_controls)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) SND_SOC_DAPM_MIXER("Right ADC Mixer", SND_SOC_NOPM, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) sun50i_codec_adc_mixer_controls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) ARRAY_SIZE(sun50i_codec_adc_mixer_controls)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) static const struct snd_soc_dapm_route sun50i_a64_codec_routes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) /* Left Mixer Routes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) { "Left Mixer", "Mic1 Playback Switch", "Mic1 Amplifier" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) { "Left Mixer", "Mic2 Playback Switch", "Mic2 Amplifier" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) { "Left Mixer", "Line In Playback Switch", "LINEIN" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) { "Left Mixer", "DAC Playback Switch", "Left DAC" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) { "Left Mixer", "DAC Reversed Playback Switch", "Right DAC" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) /* Right Mixer Routes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) { "Right Mixer", "Mic1 Playback Switch", "Mic1 Amplifier" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) { "Right Mixer", "Mic2 Playback Switch", "Mic2 Amplifier" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) { "Right Mixer", "Line In Playback Switch", "LINEIN" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) { "Right Mixer", "DAC Playback Switch", "Right DAC" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) { "Right Mixer", "DAC Reversed Playback Switch", "Left DAC" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) /* Left ADC Mixer Routes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) { "Left ADC Mixer", "Mic1 Capture Switch", "Mic1 Amplifier" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) { "Left ADC Mixer", "Mic2 Capture Switch", "Mic2 Amplifier" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) { "Left ADC Mixer", "Line In Capture Switch", "LINEIN" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) { "Left ADC Mixer", "Mixer Capture Switch", "Left Mixer" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) { "Left ADC Mixer", "Mixer Reversed Capture Switch", "Right Mixer" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) /* Right ADC Mixer Routes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) { "Right ADC Mixer", "Mic1 Capture Switch", "Mic1 Amplifier" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) { "Right ADC Mixer", "Mic2 Capture Switch", "Mic2 Amplifier" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) { "Right ADC Mixer", "Line In Capture Switch", "LINEIN" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) { "Right ADC Mixer", "Mixer Capture Switch", "Right Mixer" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) { "Right ADC Mixer", "Mixer Reversed Capture Switch", "Left Mixer" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) /* ADC Routes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) { "Left ADC", NULL, "Left ADC Mixer" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) { "Right ADC", NULL, "Right ADC Mixer" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) /* Headphone Routes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) { "Left Headphone Source", "DAC", "Left DAC" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) { "Left Headphone Source", "Mixer", "Left Mixer" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) { "Left Headphone Switch", "Headphone Playback Switch", "Left Headphone Source" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) { "Left Headphone Amp", NULL, "Left Headphone Switch" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) { "Left Headphone Amp", NULL, "Headphone Amp" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) { "HP", NULL, "Left Headphone Amp" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) { "Right Headphone Source", "DAC", "Right DAC" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) { "Right Headphone Source", "Mixer", "Right Mixer" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) { "Right Headphone Switch", "Headphone Playback Switch", "Right Headphone Source" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) { "Right Headphone Amp", NULL, "Right Headphone Switch" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) { "Right Headphone Amp", NULL, "Headphone Amp" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) { "HP", NULL, "Right Headphone Amp" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) { "Headphone Amp", NULL, "cpvdd" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) /* Microphone Routes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) { "Mic1 Amplifier", NULL, "MIC1"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) /* Microphone Routes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) { "Mic2 Amplifier", NULL, "MIC2"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) /* Line-out Routes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) { "Left Line Out Source", "Stereo", "Left Mixer" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) { "Left Line Out Source", "Mono Differential", "Left Mixer" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) { "Left Line Out Source", "Mono Differential", "Right Mixer" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) { "Left Line Out Switch", "Line Out Playback Switch", "Left Line Out Source" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) { "LINEOUT", NULL, "Left Line Out Switch" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) { "Right Line Out Switch", "Line Out Playback Switch", "Right Mixer" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) { "Right Line Out Source", "Stereo", "Right Line Out Switch" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) { "Right Line Out Source", "Mono Differential", "Left Line Out Switch" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) { "LINEOUT", NULL, "Right Line Out Source" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) /* Earpiece Routes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) { "Earpiece Source Playback Route", "DACL", "Left DAC" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) { "Earpiece Source Playback Route", "DACR", "Right DAC" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) { "Earpiece Source Playback Route", "Left Mixer", "Left Mixer" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) { "Earpiece Source Playback Route", "Right Mixer", "Right Mixer" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) { "Earpiece Switch", "Earpiece Playback Switch", "Earpiece Source Playback Route" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) { "Earpiece Amp", NULL, "Earpiece Switch" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) { "EARPIECE", NULL, "Earpiece Amp" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) static int sun50i_a64_codec_suspend(struct snd_soc_component *component)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) return regmap_update_bits(component->regmap, SUN50I_ADDA_HP_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) BIT(SUN50I_ADDA_HP_CTRL_PA_CLK_GATE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) BIT(SUN50I_ADDA_HP_CTRL_PA_CLK_GATE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) static int sun50i_a64_codec_resume(struct snd_soc_component *component)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) return regmap_update_bits(component->regmap, SUN50I_ADDA_HP_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) BIT(SUN50I_ADDA_HP_CTRL_PA_CLK_GATE), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) static const struct snd_soc_component_driver sun50i_codec_analog_cmpnt_drv = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) .controls = sun50i_a64_codec_controls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) .num_controls = ARRAY_SIZE(sun50i_a64_codec_controls),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) .dapm_widgets = sun50i_a64_codec_widgets,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) .num_dapm_widgets = ARRAY_SIZE(sun50i_a64_codec_widgets),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) .dapm_routes = sun50i_a64_codec_routes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) .num_dapm_routes = ARRAY_SIZE(sun50i_a64_codec_routes),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) .suspend = sun50i_a64_codec_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) .resume = sun50i_a64_codec_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) static const struct of_device_id sun50i_codec_analog_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) .compatible = "allwinner,sun50i-a64-codec-analog",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) },
^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) MODULE_DEVICE_TABLE(of, sun50i_codec_analog_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) static int sun50i_codec_analog_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) void __iomem *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) base = devm_platform_ioremap_resource(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) if (IS_ERR(base)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) dev_err(&pdev->dev, "Failed to map the registers\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) return PTR_ERR(base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) regmap = sun8i_adda_pr_regmap_init(&pdev->dev, base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) if (IS_ERR(regmap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) dev_err(&pdev->dev, "Failed to create regmap\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) return PTR_ERR(regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) return devm_snd_soc_register_component(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) &sun50i_codec_analog_cmpnt_drv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) static struct platform_driver sun50i_codec_analog_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) .name = "sun50i-codec-analog",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) .of_match_table = sun50i_codec_analog_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) .probe = sun50i_codec_analog_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) module_platform_driver(sun50i_codec_analog_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) MODULE_DESCRIPTION("Allwinner internal codec analog controls driver for A64");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) MODULE_AUTHOR("Vasily Khoruzhick <anarsoul@gmail.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) MODULE_ALIAS("platform:sun50i-codec-analog");