^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) // Socionext UniPhier EVEA ADC/DAC codec driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) // Copyright (c) 2016-2017 Socionext Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/reset.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <sound/pcm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <sound/soc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #define DRV_NAME "evea"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #define EVEA_RATES SNDRV_PCM_RATE_48000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #define EVEA_FORMATS SNDRV_PCM_FMTBIT_S32_LE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define AADCPOW(n) (0x0078 + 0x04 * (n))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define AADCPOW_AADC_POWD BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define ALINSW1 0x0088
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define ALINSW1_SEL1_SHIFT 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define AHPOUTPOW 0x0098
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define AHPOUTPOW_HP_ON BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define ALINEPOW 0x009c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define ALINEPOW_LIN2_POWD BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define ALINEPOW_LIN1_POWD BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define ALO1OUTPOW 0x00a8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define ALO1OUTPOW_LO1_ON BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define ALO2OUTPOW 0x00ac
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define ALO2OUTPOW_ADAC2_MUTE BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define ALO2OUTPOW_LO2_ON BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define AANAPOW 0x00b8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define AANAPOW_A_POWD BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define ADACSEQ1(n) (0x0144 + 0x40 * (n))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define ADACSEQ1_MMUTE BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define ADACSEQ2(n) (0x0160 + 0x40 * (n))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define ADACSEQ2_ADACIN_FIX BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define ADAC1ODC 0x0200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define ADAC1ODC_HP_DIS_RES_MASK GENMASK(2, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define ADAC1ODC_HP_DIS_RES_OFF (0x0 << 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define ADAC1ODC_HP_DIS_RES_ON (0x3 << 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define ADAC1ODC_ADAC_RAMPCLT_MASK GENMASK(8, 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define ADAC1ODC_ADAC_RAMPCLT_NORMAL (0x0 << 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define ADAC1ODC_ADAC_RAMPCLT_REDUCE (0x1 << 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) struct evea_priv {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) struct clk *clk, *clk_exiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) struct reset_control *rst, *rst_exiv, *rst_adamv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) int switch_lin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) int switch_lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) int switch_hp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) static const char * const linsw1_sel1_text[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) "LIN1", "LIN2", "LIN3"
^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 SOC_ENUM_SINGLE_DECL(linsw1_sel1_enum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) ALINSW1, ALINSW1_SEL1_SHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) linsw1_sel1_text);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) static const struct snd_kcontrol_new linesw1_mux[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) SOC_DAPM_ENUM("Line In 1 Source", linsw1_sel1_enum),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) static const struct snd_soc_dapm_widget evea_widgets[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) SND_SOC_DAPM_ADC("ADC", NULL, SND_SOC_NOPM, 0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) SND_SOC_DAPM_MUX("Line In 1 Mux", SND_SOC_NOPM, 0, 0, linesw1_mux),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) SND_SOC_DAPM_INPUT("LIN1_LP"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) SND_SOC_DAPM_INPUT("LIN1_RP"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) SND_SOC_DAPM_INPUT("LIN2_LP"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) SND_SOC_DAPM_INPUT("LIN2_RP"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) SND_SOC_DAPM_INPUT("LIN3_LP"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) SND_SOC_DAPM_INPUT("LIN3_RP"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) SND_SOC_DAPM_DAC("DAC HP", NULL, SND_SOC_NOPM, 0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) SND_SOC_DAPM_DAC("DAC LO1", NULL, SND_SOC_NOPM, 0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) SND_SOC_DAPM_DAC("DAC LO2", NULL, SND_SOC_NOPM, 0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) SND_SOC_DAPM_OUTPUT("HP1_L"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) SND_SOC_DAPM_OUTPUT("HP1_R"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) SND_SOC_DAPM_OUTPUT("LO2_L"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) SND_SOC_DAPM_OUTPUT("LO2_R"),
^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 const struct snd_soc_dapm_route evea_routes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) { "Line In 1", NULL, "ADC" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) { "ADC", NULL, "Line In 1 Mux" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) { "Line In 1 Mux", "LIN1", "LIN1_LP" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) { "Line In 1 Mux", "LIN1", "LIN1_RP" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) { "Line In 1 Mux", "LIN2", "LIN2_LP" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) { "Line In 1 Mux", "LIN2", "LIN2_RP" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) { "Line In 1 Mux", "LIN3", "LIN3_LP" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) { "Line In 1 Mux", "LIN3", "LIN3_RP" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) { "DAC HP", NULL, "Headphone 1" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) { "DAC LO1", NULL, "Line Out 1" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) { "DAC LO2", NULL, "Line Out 2" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) { "HP1_L", NULL, "DAC HP" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) { "HP1_R", NULL, "DAC HP" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) { "LO2_L", NULL, "DAC LO2" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) { "LO2_R", NULL, "DAC LO2" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static void evea_set_power_state_on(struct evea_priv *evea)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) struct regmap *map = evea->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) regmap_update_bits(map, AANAPOW, AANAPOW_A_POWD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) AANAPOW_A_POWD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) regmap_update_bits(map, ADAC1ODC, ADAC1ODC_HP_DIS_RES_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) ADAC1ODC_HP_DIS_RES_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) regmap_update_bits(map, ADAC1ODC, ADAC1ODC_ADAC_RAMPCLT_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) ADAC1ODC_ADAC_RAMPCLT_REDUCE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) regmap_update_bits(map, ADACSEQ2(0), ADACSEQ2_ADACIN_FIX, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) regmap_update_bits(map, ADACSEQ2(1), ADACSEQ2_ADACIN_FIX, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) regmap_update_bits(map, ADACSEQ2(2), ADACSEQ2_ADACIN_FIX, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) static void evea_set_power_state_off(struct evea_priv *evea)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) struct regmap *map = evea->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) regmap_update_bits(map, ADAC1ODC, ADAC1ODC_HP_DIS_RES_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) ADAC1ODC_HP_DIS_RES_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) regmap_update_bits(map, ADACSEQ1(0), ADACSEQ1_MMUTE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) ADACSEQ1_MMUTE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) regmap_update_bits(map, ADACSEQ1(1), ADACSEQ1_MMUTE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) ADACSEQ1_MMUTE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) regmap_update_bits(map, ADACSEQ1(2), ADACSEQ1_MMUTE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) ADACSEQ1_MMUTE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) regmap_update_bits(map, ALO1OUTPOW, ALO1OUTPOW_LO1_ON, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) regmap_update_bits(map, ALO2OUTPOW, ALO2OUTPOW_LO2_ON, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) regmap_update_bits(map, AHPOUTPOW, AHPOUTPOW_HP_ON, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) static int evea_update_switch_lin(struct evea_priv *evea)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) struct regmap *map = evea->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) if (evea->switch_lin) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) regmap_update_bits(map, ALINEPOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) ALINEPOW_LIN2_POWD | ALINEPOW_LIN1_POWD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) ALINEPOW_LIN2_POWD | ALINEPOW_LIN1_POWD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) regmap_update_bits(map, AADCPOW(0), AADCPOW_AADC_POWD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) AADCPOW_AADC_POWD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) regmap_update_bits(map, AADCPOW(1), AADCPOW_AADC_POWD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) AADCPOW_AADC_POWD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) regmap_update_bits(map, AADCPOW(0), AADCPOW_AADC_POWD, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) regmap_update_bits(map, AADCPOW(1), AADCPOW_AADC_POWD, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) regmap_update_bits(map, ALINEPOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) ALINEPOW_LIN2_POWD | ALINEPOW_LIN1_POWD, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) static int evea_update_switch_lo(struct evea_priv *evea)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) struct regmap *map = evea->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) if (evea->switch_lo) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) regmap_update_bits(map, ADACSEQ1(0), ADACSEQ1_MMUTE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) regmap_update_bits(map, ADACSEQ1(2), ADACSEQ1_MMUTE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) regmap_update_bits(map, ALO1OUTPOW, ALO1OUTPOW_LO1_ON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) ALO1OUTPOW_LO1_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) regmap_update_bits(map, ALO2OUTPOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) ALO2OUTPOW_ADAC2_MUTE | ALO2OUTPOW_LO2_ON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) ALO2OUTPOW_ADAC2_MUTE | ALO2OUTPOW_LO2_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) regmap_update_bits(map, ADACSEQ1(0), ADACSEQ1_MMUTE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) ADACSEQ1_MMUTE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) regmap_update_bits(map, ADACSEQ1(2), ADACSEQ1_MMUTE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) ADACSEQ1_MMUTE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) regmap_update_bits(map, ALO1OUTPOW, ALO1OUTPOW_LO1_ON, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) regmap_update_bits(map, ALO2OUTPOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) ALO2OUTPOW_ADAC2_MUTE | ALO2OUTPOW_LO2_ON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) static int evea_update_switch_hp(struct evea_priv *evea)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) struct regmap *map = evea->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) if (evea->switch_hp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) regmap_update_bits(map, ADACSEQ1(1), ADACSEQ1_MMUTE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) regmap_update_bits(map, AHPOUTPOW, AHPOUTPOW_HP_ON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) AHPOUTPOW_HP_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) regmap_update_bits(map, ADAC1ODC, ADAC1ODC_HP_DIS_RES_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) ADAC1ODC_HP_DIS_RES_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) regmap_update_bits(map, ADAC1ODC, ADAC1ODC_HP_DIS_RES_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) ADAC1ODC_HP_DIS_RES_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) regmap_update_bits(map, ADACSEQ1(1), ADACSEQ1_MMUTE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) ADACSEQ1_MMUTE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) regmap_update_bits(map, AHPOUTPOW, AHPOUTPOW_HP_ON, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) static void evea_update_switch_all(struct evea_priv *evea)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) evea_update_switch_lin(evea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) evea_update_switch_lo(evea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) evea_update_switch_hp(evea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) static int evea_get_switch_lin(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) struct evea_priv *evea = snd_soc_component_get_drvdata(component);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) ucontrol->value.integer.value[0] = evea->switch_lin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) static int evea_set_switch_lin(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) struct evea_priv *evea = snd_soc_component_get_drvdata(component);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) if (evea->switch_lin == ucontrol->value.integer.value[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) evea->switch_lin = ucontrol->value.integer.value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) return evea_update_switch_lin(evea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) static int evea_get_switch_lo(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) struct evea_priv *evea = snd_soc_component_get_drvdata(component);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) ucontrol->value.integer.value[0] = evea->switch_lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) static int evea_set_switch_lo(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) struct evea_priv *evea = snd_soc_component_get_drvdata(component);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) if (evea->switch_lo == ucontrol->value.integer.value[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) evea->switch_lo = ucontrol->value.integer.value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) return evea_update_switch_lo(evea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) static int evea_get_switch_hp(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) struct evea_priv *evea = snd_soc_component_get_drvdata(component);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) ucontrol->value.integer.value[0] = evea->switch_hp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) static int evea_set_switch_hp(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) struct evea_priv *evea = snd_soc_component_get_drvdata(component);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) if (evea->switch_hp == ucontrol->value.integer.value[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) evea->switch_hp = ucontrol->value.integer.value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) return evea_update_switch_hp(evea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) static const struct snd_kcontrol_new evea_controls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) SOC_SINGLE_BOOL_EXT("Line Capture Switch", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) evea_get_switch_lin, evea_set_switch_lin),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) SOC_SINGLE_BOOL_EXT("Line Playback Switch", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) evea_get_switch_lo, evea_set_switch_lo),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) SOC_SINGLE_BOOL_EXT("Headphone Playback Switch", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) evea_get_switch_hp, evea_set_switch_hp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) static int evea_codec_probe(struct snd_soc_component *component)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) struct evea_priv *evea = snd_soc_component_get_drvdata(component);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) evea->switch_lin = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) evea->switch_lo = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) evea->switch_hp = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) evea_set_power_state_on(evea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) evea_update_switch_all(evea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) static int evea_codec_suspend(struct snd_soc_component *component)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) struct evea_priv *evea = snd_soc_component_get_drvdata(component);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) evea_set_power_state_off(evea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) reset_control_assert(evea->rst_adamv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) reset_control_assert(evea->rst_exiv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) reset_control_assert(evea->rst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) clk_disable_unprepare(evea->clk_exiv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) clk_disable_unprepare(evea->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) static int evea_codec_resume(struct snd_soc_component *component)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) struct evea_priv *evea = snd_soc_component_get_drvdata(component);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) ret = clk_prepare_enable(evea->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) ret = clk_prepare_enable(evea->clk_exiv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) goto err_out_clock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) ret = reset_control_deassert(evea->rst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) goto err_out_clock_exiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) ret = reset_control_deassert(evea->rst_exiv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) goto err_out_reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) ret = reset_control_deassert(evea->rst_adamv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) goto err_out_reset_exiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) evea_set_power_state_on(evea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) evea_update_switch_all(evea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) err_out_reset_exiv:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) reset_control_assert(evea->rst_exiv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) err_out_reset:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) reset_control_assert(evea->rst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) err_out_clock_exiv:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) clk_disable_unprepare(evea->clk_exiv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) err_out_clock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) clk_disable_unprepare(evea->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) static struct snd_soc_component_driver soc_codec_evea = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) .probe = evea_codec_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) .suspend = evea_codec_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) .resume = evea_codec_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) .dapm_widgets = evea_widgets,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) .num_dapm_widgets = ARRAY_SIZE(evea_widgets),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) .dapm_routes = evea_routes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) .num_dapm_routes = ARRAY_SIZE(evea_routes),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) .controls = evea_controls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) .num_controls = ARRAY_SIZE(evea_controls),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) .idle_bias_on = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) .use_pmdown_time = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) .endianness = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) .non_legacy_dai_naming = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) static struct snd_soc_dai_driver soc_dai_evea[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) .name = DRV_NAME "-line1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) .playback = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) .stream_name = "Line Out 1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) .formats = EVEA_FORMATS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) .rates = EVEA_RATES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) .channels_min = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) .channels_max = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) .capture = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) .stream_name = "Line In 1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) .formats = EVEA_FORMATS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) .rates = EVEA_RATES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) .channels_min = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) .channels_max = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) .name = DRV_NAME "-hp1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) .playback = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) .stream_name = "Headphone 1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) .formats = EVEA_FORMATS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) .rates = EVEA_RATES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) .channels_min = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) .channels_max = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) .name = DRV_NAME "-lo2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) .playback = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) .stream_name = "Line Out 2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) .formats = EVEA_FORMATS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) .rates = EVEA_RATES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) .channels_min = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) .channels_max = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) static const struct regmap_config evea_regmap_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) .reg_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) .reg_stride = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) .val_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) .max_register = 0xffc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) .cache_type = REGCACHE_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) static int evea_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) struct evea_priv *evea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) void __iomem *preg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) evea = devm_kzalloc(&pdev->dev, sizeof(struct evea_priv), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) if (!evea)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) evea->clk = devm_clk_get(&pdev->dev, "evea");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) if (IS_ERR(evea->clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) return PTR_ERR(evea->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) evea->clk_exiv = devm_clk_get(&pdev->dev, "exiv");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) if (IS_ERR(evea->clk_exiv))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) return PTR_ERR(evea->clk_exiv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) evea->rst = devm_reset_control_get_shared(&pdev->dev, "evea");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) if (IS_ERR(evea->rst))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) return PTR_ERR(evea->rst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) evea->rst_exiv = devm_reset_control_get_shared(&pdev->dev, "exiv");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) if (IS_ERR(evea->rst_exiv))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) return PTR_ERR(evea->rst_exiv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) preg = devm_platform_ioremap_resource(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) if (IS_ERR(preg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) return PTR_ERR(preg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) evea->regmap = devm_regmap_init_mmio(&pdev->dev, preg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) &evea_regmap_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) if (IS_ERR(evea->regmap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) return PTR_ERR(evea->regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) ret = clk_prepare_enable(evea->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) ret = clk_prepare_enable(evea->clk_exiv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) goto err_out_clock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) ret = reset_control_deassert(evea->rst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) goto err_out_clock_exiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) ret = reset_control_deassert(evea->rst_exiv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) goto err_out_reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) /* ADAMV will hangup if EXIV reset is asserted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) evea->rst_adamv = devm_reset_control_get_shared(&pdev->dev, "adamv");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) if (IS_ERR(evea->rst_adamv)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) ret = PTR_ERR(evea->rst_adamv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) goto err_out_reset_exiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) ret = reset_control_deassert(evea->rst_adamv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) goto err_out_reset_exiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) platform_set_drvdata(pdev, evea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) ret = devm_snd_soc_register_component(&pdev->dev, &soc_codec_evea,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) soc_dai_evea, ARRAY_SIZE(soc_dai_evea));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) goto err_out_reset_adamv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) err_out_reset_adamv:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) reset_control_assert(evea->rst_adamv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) err_out_reset_exiv:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) reset_control_assert(evea->rst_exiv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) err_out_reset:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) reset_control_assert(evea->rst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) err_out_clock_exiv:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) clk_disable_unprepare(evea->clk_exiv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) err_out_clock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) clk_disable_unprepare(evea->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) static int evea_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) struct evea_priv *evea = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) reset_control_assert(evea->rst_adamv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) reset_control_assert(evea->rst_exiv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) reset_control_assert(evea->rst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) clk_disable_unprepare(evea->clk_exiv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) clk_disable_unprepare(evea->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) static const struct of_device_id evea_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) { .compatible = "socionext,uniphier-evea", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) MODULE_DEVICE_TABLE(of, evea_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) static struct platform_driver evea_codec_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) .name = DRV_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) .of_match_table = of_match_ptr(evea_of_match),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) .probe = evea_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) .remove = evea_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) module_platform_driver(evea_codec_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) MODULE_AUTHOR("Katsuhiro Suzuki <suzuki.katsuhiro@socionext.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) MODULE_DESCRIPTION("UniPhier EVEA codec driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) MODULE_LICENSE("GPL v2");