xref: /openbmc/linux/sound/soc/uniphier/evea.c (revision 1ac731c529cd4d6adbce134754b51ff7d822b145)
13a47b1dfSKatsuhiro Suzuki // SPDX-License-Identifier: GPL-2.0
224745dcaSKatsuhiro Suzuki //
324745dcaSKatsuhiro Suzuki // Socionext UniPhier EVEA ADC/DAC codec driver.
424745dcaSKatsuhiro Suzuki //
524745dcaSKatsuhiro Suzuki // Copyright (c) 2016-2017 Socionext Inc.
63a47b1dfSKatsuhiro Suzuki 
73a47b1dfSKatsuhiro Suzuki #include <linux/clk.h>
83a47b1dfSKatsuhiro Suzuki #include <linux/module.h>
93a47b1dfSKatsuhiro Suzuki #include <linux/of.h>
103a47b1dfSKatsuhiro Suzuki #include <linux/regmap.h>
113a47b1dfSKatsuhiro Suzuki #include <linux/reset.h>
123a47b1dfSKatsuhiro Suzuki #include <sound/pcm.h>
133a47b1dfSKatsuhiro Suzuki #include <sound/soc.h>
143a47b1dfSKatsuhiro Suzuki 
153a47b1dfSKatsuhiro Suzuki #define DRV_NAME        "evea"
163a47b1dfSKatsuhiro Suzuki #define EVEA_RATES      SNDRV_PCM_RATE_48000
173a47b1dfSKatsuhiro Suzuki #define EVEA_FORMATS    SNDRV_PCM_FMTBIT_S32_LE
183a47b1dfSKatsuhiro Suzuki 
193a47b1dfSKatsuhiro Suzuki #define AADCPOW(n)                           (0x0078 + 0x04 * (n))
203a47b1dfSKatsuhiro Suzuki #define   AADCPOW_AADC_POWD                   BIT(0)
2190e0fb05SKatsuhiro Suzuki #define ALINSW1                              0x0088
2290e0fb05SKatsuhiro Suzuki #define   ALINSW1_SEL1_SHIFT                  3
233a47b1dfSKatsuhiro Suzuki #define AHPOUTPOW                            0x0098
243a47b1dfSKatsuhiro Suzuki #define   AHPOUTPOW_HP_ON                     BIT(4)
253a47b1dfSKatsuhiro Suzuki #define ALINEPOW                             0x009c
263a47b1dfSKatsuhiro Suzuki #define   ALINEPOW_LIN2_POWD                  BIT(3)
273a47b1dfSKatsuhiro Suzuki #define   ALINEPOW_LIN1_POWD                  BIT(4)
283a47b1dfSKatsuhiro Suzuki #define ALO1OUTPOW                           0x00a8
293a47b1dfSKatsuhiro Suzuki #define   ALO1OUTPOW_LO1_ON                   BIT(4)
303a47b1dfSKatsuhiro Suzuki #define ALO2OUTPOW                           0x00ac
313a47b1dfSKatsuhiro Suzuki #define   ALO2OUTPOW_ADAC2_MUTE               BIT(0)
323a47b1dfSKatsuhiro Suzuki #define   ALO2OUTPOW_LO2_ON                   BIT(4)
333a47b1dfSKatsuhiro Suzuki #define AANAPOW                              0x00b8
343a47b1dfSKatsuhiro Suzuki #define   AANAPOW_A_POWD                      BIT(4)
353a47b1dfSKatsuhiro Suzuki #define ADACSEQ1(n)                          (0x0144 + 0x40 * (n))
363a47b1dfSKatsuhiro Suzuki #define   ADACSEQ1_MMUTE                      BIT(1)
373a47b1dfSKatsuhiro Suzuki #define ADACSEQ2(n)                          (0x0160 + 0x40 * (n))
383a47b1dfSKatsuhiro Suzuki #define   ADACSEQ2_ADACIN_FIX                 BIT(0)
393a47b1dfSKatsuhiro Suzuki #define ADAC1ODC                             0x0200
403a47b1dfSKatsuhiro Suzuki #define   ADAC1ODC_HP_DIS_RES_MASK            GENMASK(2, 1)
413a47b1dfSKatsuhiro Suzuki #define   ADAC1ODC_HP_DIS_RES_OFF             (0x0 << 1)
423a47b1dfSKatsuhiro Suzuki #define   ADAC1ODC_HP_DIS_RES_ON              (0x3 << 1)
433a47b1dfSKatsuhiro Suzuki #define   ADAC1ODC_ADAC_RAMPCLT_MASK          GENMASK(8, 7)
443a47b1dfSKatsuhiro Suzuki #define   ADAC1ODC_ADAC_RAMPCLT_NORMAL        (0x0 << 7)
453a47b1dfSKatsuhiro Suzuki #define   ADAC1ODC_ADAC_RAMPCLT_REDUCE        (0x1 << 7)
463a47b1dfSKatsuhiro Suzuki 
473a47b1dfSKatsuhiro Suzuki struct evea_priv {
483a47b1dfSKatsuhiro Suzuki 	struct clk *clk, *clk_exiv;
493a47b1dfSKatsuhiro Suzuki 	struct reset_control *rst, *rst_exiv, *rst_adamv;
503a47b1dfSKatsuhiro Suzuki 	struct regmap *regmap;
513a47b1dfSKatsuhiro Suzuki 
523a47b1dfSKatsuhiro Suzuki 	int switch_lin;
533a47b1dfSKatsuhiro Suzuki 	int switch_lo;
543a47b1dfSKatsuhiro Suzuki 	int switch_hp;
553a47b1dfSKatsuhiro Suzuki };
563a47b1dfSKatsuhiro Suzuki 
57e5ba3198SKatsuhiro Suzuki static const char * const linsw1_sel1_text[] = {
58e5ba3198SKatsuhiro Suzuki 	"LIN1", "LIN2", "LIN3"
59e5ba3198SKatsuhiro Suzuki };
60e5ba3198SKatsuhiro Suzuki 
61e5ba3198SKatsuhiro Suzuki static SOC_ENUM_SINGLE_DECL(linsw1_sel1_enum,
62e5ba3198SKatsuhiro Suzuki 	ALINSW1, ALINSW1_SEL1_SHIFT,
63e5ba3198SKatsuhiro Suzuki 	linsw1_sel1_text);
64e5ba3198SKatsuhiro Suzuki 
65e5ba3198SKatsuhiro Suzuki static const struct snd_kcontrol_new linesw1_mux[] = {
66e5ba3198SKatsuhiro Suzuki 	SOC_DAPM_ENUM("Line In 1 Source", linsw1_sel1_enum),
67e5ba3198SKatsuhiro Suzuki };
68e5ba3198SKatsuhiro Suzuki 
693a47b1dfSKatsuhiro Suzuki static const struct snd_soc_dapm_widget evea_widgets[] = {
70e5ba3198SKatsuhiro Suzuki 	SND_SOC_DAPM_ADC("ADC", NULL, SND_SOC_NOPM, 0, 0),
71e5ba3198SKatsuhiro Suzuki 	SND_SOC_DAPM_MUX("Line In 1 Mux", SND_SOC_NOPM, 0, 0, linesw1_mux),
723a47b1dfSKatsuhiro Suzuki 	SND_SOC_DAPM_INPUT("LIN1_LP"),
733a47b1dfSKatsuhiro Suzuki 	SND_SOC_DAPM_INPUT("LIN1_RP"),
743a47b1dfSKatsuhiro Suzuki 	SND_SOC_DAPM_INPUT("LIN2_LP"),
753a47b1dfSKatsuhiro Suzuki 	SND_SOC_DAPM_INPUT("LIN2_RP"),
763a47b1dfSKatsuhiro Suzuki 	SND_SOC_DAPM_INPUT("LIN3_LP"),
773a47b1dfSKatsuhiro Suzuki 	SND_SOC_DAPM_INPUT("LIN3_RP"),
783a47b1dfSKatsuhiro Suzuki 
79e5ba3198SKatsuhiro Suzuki 	SND_SOC_DAPM_DAC("DAC HP", NULL, SND_SOC_NOPM, 0, 0),
80e5ba3198SKatsuhiro Suzuki 	SND_SOC_DAPM_DAC("DAC LO1", NULL, SND_SOC_NOPM, 0, 0),
81e5ba3198SKatsuhiro Suzuki 	SND_SOC_DAPM_DAC("DAC LO2", NULL, SND_SOC_NOPM, 0, 0),
823a47b1dfSKatsuhiro Suzuki 	SND_SOC_DAPM_OUTPUT("HP1_L"),
833a47b1dfSKatsuhiro Suzuki 	SND_SOC_DAPM_OUTPUT("HP1_R"),
843a47b1dfSKatsuhiro Suzuki 	SND_SOC_DAPM_OUTPUT("LO2_L"),
853a47b1dfSKatsuhiro Suzuki 	SND_SOC_DAPM_OUTPUT("LO2_R"),
863a47b1dfSKatsuhiro Suzuki };
873a47b1dfSKatsuhiro Suzuki 
883a47b1dfSKatsuhiro Suzuki static const struct snd_soc_dapm_route evea_routes[] = {
89e5ba3198SKatsuhiro Suzuki 	{ "Line In 1", NULL, "ADC" },
90e5ba3198SKatsuhiro Suzuki 	{ "ADC", NULL, "Line In 1 Mux" },
91e5ba3198SKatsuhiro Suzuki 	{ "Line In 1 Mux", "LIN1", "LIN1_LP" },
92e5ba3198SKatsuhiro Suzuki 	{ "Line In 1 Mux", "LIN1", "LIN1_RP" },
93e5ba3198SKatsuhiro Suzuki 	{ "Line In 1 Mux", "LIN2", "LIN2_LP" },
94e5ba3198SKatsuhiro Suzuki 	{ "Line In 1 Mux", "LIN2", "LIN2_RP" },
95e5ba3198SKatsuhiro Suzuki 	{ "Line In 1 Mux", "LIN3", "LIN3_LP" },
96e5ba3198SKatsuhiro Suzuki 	{ "Line In 1 Mux", "LIN3", "LIN3_RP" },
973a47b1dfSKatsuhiro Suzuki 
98e5ba3198SKatsuhiro Suzuki 	{ "DAC HP", NULL, "Headphone 1" },
99e5ba3198SKatsuhiro Suzuki 	{ "DAC LO1", NULL, "Line Out 1" },
100e5ba3198SKatsuhiro Suzuki 	{ "DAC LO2", NULL, "Line Out 2" },
101e5ba3198SKatsuhiro Suzuki 	{ "HP1_L", NULL, "DAC HP" },
102e5ba3198SKatsuhiro Suzuki 	{ "HP1_R", NULL, "DAC HP" },
103e5ba3198SKatsuhiro Suzuki 	{ "LO2_L", NULL, "DAC LO2" },
104e5ba3198SKatsuhiro Suzuki 	{ "LO2_R", NULL, "DAC LO2" },
1053a47b1dfSKatsuhiro Suzuki };
1063a47b1dfSKatsuhiro Suzuki 
evea_set_power_state_on(struct evea_priv * evea)1073a47b1dfSKatsuhiro Suzuki static void evea_set_power_state_on(struct evea_priv *evea)
1083a47b1dfSKatsuhiro Suzuki {
1093a47b1dfSKatsuhiro Suzuki 	struct regmap *map = evea->regmap;
1103a47b1dfSKatsuhiro Suzuki 
1113a47b1dfSKatsuhiro Suzuki 	regmap_update_bits(map, AANAPOW, AANAPOW_A_POWD,
1123a47b1dfSKatsuhiro Suzuki 			   AANAPOW_A_POWD);
1133a47b1dfSKatsuhiro Suzuki 
1143a47b1dfSKatsuhiro Suzuki 	regmap_update_bits(map, ADAC1ODC, ADAC1ODC_HP_DIS_RES_MASK,
1153a47b1dfSKatsuhiro Suzuki 			   ADAC1ODC_HP_DIS_RES_ON);
1163a47b1dfSKatsuhiro Suzuki 
1173a47b1dfSKatsuhiro Suzuki 	regmap_update_bits(map, ADAC1ODC, ADAC1ODC_ADAC_RAMPCLT_MASK,
1183a47b1dfSKatsuhiro Suzuki 			   ADAC1ODC_ADAC_RAMPCLT_REDUCE);
1193a47b1dfSKatsuhiro Suzuki 
1203a47b1dfSKatsuhiro Suzuki 	regmap_update_bits(map, ADACSEQ2(0), ADACSEQ2_ADACIN_FIX, 0);
1213a47b1dfSKatsuhiro Suzuki 	regmap_update_bits(map, ADACSEQ2(1), ADACSEQ2_ADACIN_FIX, 0);
1223a47b1dfSKatsuhiro Suzuki 	regmap_update_bits(map, ADACSEQ2(2), ADACSEQ2_ADACIN_FIX, 0);
1233a47b1dfSKatsuhiro Suzuki }
1243a47b1dfSKatsuhiro Suzuki 
evea_set_power_state_off(struct evea_priv * evea)1253a47b1dfSKatsuhiro Suzuki static void evea_set_power_state_off(struct evea_priv *evea)
1263a47b1dfSKatsuhiro Suzuki {
1273a47b1dfSKatsuhiro Suzuki 	struct regmap *map = evea->regmap;
1283a47b1dfSKatsuhiro Suzuki 
1293a47b1dfSKatsuhiro Suzuki 	regmap_update_bits(map, ADAC1ODC, ADAC1ODC_HP_DIS_RES_MASK,
1303a47b1dfSKatsuhiro Suzuki 			   ADAC1ODC_HP_DIS_RES_ON);
1313a47b1dfSKatsuhiro Suzuki 
1323a47b1dfSKatsuhiro Suzuki 	regmap_update_bits(map, ADACSEQ1(0), ADACSEQ1_MMUTE,
1333a47b1dfSKatsuhiro Suzuki 			   ADACSEQ1_MMUTE);
1343a47b1dfSKatsuhiro Suzuki 	regmap_update_bits(map, ADACSEQ1(1), ADACSEQ1_MMUTE,
1353a47b1dfSKatsuhiro Suzuki 			   ADACSEQ1_MMUTE);
1363a47b1dfSKatsuhiro Suzuki 	regmap_update_bits(map, ADACSEQ1(2), ADACSEQ1_MMUTE,
1373a47b1dfSKatsuhiro Suzuki 			   ADACSEQ1_MMUTE);
1383a47b1dfSKatsuhiro Suzuki 
1393a47b1dfSKatsuhiro Suzuki 	regmap_update_bits(map, ALO1OUTPOW, ALO1OUTPOW_LO1_ON, 0);
1403a47b1dfSKatsuhiro Suzuki 	regmap_update_bits(map, ALO2OUTPOW, ALO2OUTPOW_LO2_ON, 0);
1413a47b1dfSKatsuhiro Suzuki 	regmap_update_bits(map, AHPOUTPOW, AHPOUTPOW_HP_ON, 0);
1423a47b1dfSKatsuhiro Suzuki }
1433a47b1dfSKatsuhiro Suzuki 
evea_update_switch_lin(struct evea_priv * evea)1443a47b1dfSKatsuhiro Suzuki static int evea_update_switch_lin(struct evea_priv *evea)
1453a47b1dfSKatsuhiro Suzuki {
1463a47b1dfSKatsuhiro Suzuki 	struct regmap *map = evea->regmap;
1473a47b1dfSKatsuhiro Suzuki 
1483a47b1dfSKatsuhiro Suzuki 	if (evea->switch_lin) {
1493a47b1dfSKatsuhiro Suzuki 		regmap_update_bits(map, ALINEPOW,
1503a47b1dfSKatsuhiro Suzuki 				   ALINEPOW_LIN2_POWD | ALINEPOW_LIN1_POWD,
1513a47b1dfSKatsuhiro Suzuki 				   ALINEPOW_LIN2_POWD | ALINEPOW_LIN1_POWD);
1523a47b1dfSKatsuhiro Suzuki 
1533a47b1dfSKatsuhiro Suzuki 		regmap_update_bits(map, AADCPOW(0), AADCPOW_AADC_POWD,
1543a47b1dfSKatsuhiro Suzuki 				   AADCPOW_AADC_POWD);
1553a47b1dfSKatsuhiro Suzuki 		regmap_update_bits(map, AADCPOW(1), AADCPOW_AADC_POWD,
1563a47b1dfSKatsuhiro Suzuki 				   AADCPOW_AADC_POWD);
1573a47b1dfSKatsuhiro Suzuki 	} else {
1583a47b1dfSKatsuhiro Suzuki 		regmap_update_bits(map, AADCPOW(0), AADCPOW_AADC_POWD, 0);
1593a47b1dfSKatsuhiro Suzuki 		regmap_update_bits(map, AADCPOW(1), AADCPOW_AADC_POWD, 0);
1603a47b1dfSKatsuhiro Suzuki 
1613a47b1dfSKatsuhiro Suzuki 		regmap_update_bits(map, ALINEPOW,
1623a47b1dfSKatsuhiro Suzuki 				   ALINEPOW_LIN2_POWD | ALINEPOW_LIN1_POWD, 0);
1633a47b1dfSKatsuhiro Suzuki 	}
1643a47b1dfSKatsuhiro Suzuki 
1653a47b1dfSKatsuhiro Suzuki 	return 0;
1663a47b1dfSKatsuhiro Suzuki }
1673a47b1dfSKatsuhiro Suzuki 
evea_update_switch_lo(struct evea_priv * evea)1683a47b1dfSKatsuhiro Suzuki static int evea_update_switch_lo(struct evea_priv *evea)
1693a47b1dfSKatsuhiro Suzuki {
1703a47b1dfSKatsuhiro Suzuki 	struct regmap *map = evea->regmap;
1713a47b1dfSKatsuhiro Suzuki 
1723a47b1dfSKatsuhiro Suzuki 	if (evea->switch_lo) {
1733a47b1dfSKatsuhiro Suzuki 		regmap_update_bits(map, ADACSEQ1(0), ADACSEQ1_MMUTE, 0);
1743a47b1dfSKatsuhiro Suzuki 		regmap_update_bits(map, ADACSEQ1(2), ADACSEQ1_MMUTE, 0);
1753a47b1dfSKatsuhiro Suzuki 
1763a47b1dfSKatsuhiro Suzuki 		regmap_update_bits(map, ALO1OUTPOW, ALO1OUTPOW_LO1_ON,
1773a47b1dfSKatsuhiro Suzuki 				   ALO1OUTPOW_LO1_ON);
1783a47b1dfSKatsuhiro Suzuki 		regmap_update_bits(map, ALO2OUTPOW,
1793a47b1dfSKatsuhiro Suzuki 				   ALO2OUTPOW_ADAC2_MUTE | ALO2OUTPOW_LO2_ON,
1803a47b1dfSKatsuhiro Suzuki 				   ALO2OUTPOW_ADAC2_MUTE | ALO2OUTPOW_LO2_ON);
1813a47b1dfSKatsuhiro Suzuki 	} else {
1823a47b1dfSKatsuhiro Suzuki 		regmap_update_bits(map, ADACSEQ1(0), ADACSEQ1_MMUTE,
1833a47b1dfSKatsuhiro Suzuki 				   ADACSEQ1_MMUTE);
1843a47b1dfSKatsuhiro Suzuki 		regmap_update_bits(map, ADACSEQ1(2), ADACSEQ1_MMUTE,
1853a47b1dfSKatsuhiro Suzuki 				   ADACSEQ1_MMUTE);
1863a47b1dfSKatsuhiro Suzuki 
1873a47b1dfSKatsuhiro Suzuki 		regmap_update_bits(map, ALO1OUTPOW, ALO1OUTPOW_LO1_ON, 0);
1883a47b1dfSKatsuhiro Suzuki 		regmap_update_bits(map, ALO2OUTPOW,
1893a47b1dfSKatsuhiro Suzuki 				   ALO2OUTPOW_ADAC2_MUTE | ALO2OUTPOW_LO2_ON,
1903a47b1dfSKatsuhiro Suzuki 				   0);
1913a47b1dfSKatsuhiro Suzuki 	}
1923a47b1dfSKatsuhiro Suzuki 
1933a47b1dfSKatsuhiro Suzuki 	return 0;
1943a47b1dfSKatsuhiro Suzuki }
1953a47b1dfSKatsuhiro Suzuki 
evea_update_switch_hp(struct evea_priv * evea)1963a47b1dfSKatsuhiro Suzuki static int evea_update_switch_hp(struct evea_priv *evea)
1973a47b1dfSKatsuhiro Suzuki {
1983a47b1dfSKatsuhiro Suzuki 	struct regmap *map = evea->regmap;
1993a47b1dfSKatsuhiro Suzuki 
2003a47b1dfSKatsuhiro Suzuki 	if (evea->switch_hp) {
2013a47b1dfSKatsuhiro Suzuki 		regmap_update_bits(map, ADACSEQ1(1), ADACSEQ1_MMUTE, 0);
2023a47b1dfSKatsuhiro Suzuki 
2033a47b1dfSKatsuhiro Suzuki 		regmap_update_bits(map, AHPOUTPOW, AHPOUTPOW_HP_ON,
2043a47b1dfSKatsuhiro Suzuki 				   AHPOUTPOW_HP_ON);
2053a47b1dfSKatsuhiro Suzuki 
2063a47b1dfSKatsuhiro Suzuki 		regmap_update_bits(map, ADAC1ODC, ADAC1ODC_HP_DIS_RES_MASK,
2073a47b1dfSKatsuhiro Suzuki 				   ADAC1ODC_HP_DIS_RES_OFF);
2083a47b1dfSKatsuhiro Suzuki 	} else {
2093a47b1dfSKatsuhiro Suzuki 		regmap_update_bits(map, ADAC1ODC, ADAC1ODC_HP_DIS_RES_MASK,
2103a47b1dfSKatsuhiro Suzuki 				   ADAC1ODC_HP_DIS_RES_ON);
2113a47b1dfSKatsuhiro Suzuki 
2123a47b1dfSKatsuhiro Suzuki 		regmap_update_bits(map, ADACSEQ1(1), ADACSEQ1_MMUTE,
2133a47b1dfSKatsuhiro Suzuki 				   ADACSEQ1_MMUTE);
2143a47b1dfSKatsuhiro Suzuki 
2153a47b1dfSKatsuhiro Suzuki 		regmap_update_bits(map, AHPOUTPOW, AHPOUTPOW_HP_ON, 0);
2163a47b1dfSKatsuhiro Suzuki 	}
2173a47b1dfSKatsuhiro Suzuki 
2183a47b1dfSKatsuhiro Suzuki 	return 0;
2193a47b1dfSKatsuhiro Suzuki }
2203a47b1dfSKatsuhiro Suzuki 
evea_update_switch_all(struct evea_priv * evea)2213a47b1dfSKatsuhiro Suzuki static void evea_update_switch_all(struct evea_priv *evea)
2223a47b1dfSKatsuhiro Suzuki {
2233a47b1dfSKatsuhiro Suzuki 	evea_update_switch_lin(evea);
2243a47b1dfSKatsuhiro Suzuki 	evea_update_switch_lo(evea);
2253a47b1dfSKatsuhiro Suzuki 	evea_update_switch_hp(evea);
2263a47b1dfSKatsuhiro Suzuki }
2273a47b1dfSKatsuhiro Suzuki 
evea_get_switch_lin(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2283a47b1dfSKatsuhiro Suzuki static int evea_get_switch_lin(struct snd_kcontrol *kcontrol,
2293a47b1dfSKatsuhiro Suzuki 			       struct snd_ctl_elem_value *ucontrol)
2303a47b1dfSKatsuhiro Suzuki {
231f12df661SKuninori Morimoto 	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
232f12df661SKuninori Morimoto 	struct evea_priv *evea = snd_soc_component_get_drvdata(component);
2333a47b1dfSKatsuhiro Suzuki 
2343a47b1dfSKatsuhiro Suzuki 	ucontrol->value.integer.value[0] = evea->switch_lin;
2353a47b1dfSKatsuhiro Suzuki 
2363a47b1dfSKatsuhiro Suzuki 	return 0;
2373a47b1dfSKatsuhiro Suzuki }
2383a47b1dfSKatsuhiro Suzuki 
evea_set_switch_lin(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2393a47b1dfSKatsuhiro Suzuki static int evea_set_switch_lin(struct snd_kcontrol *kcontrol,
2403a47b1dfSKatsuhiro Suzuki 			       struct snd_ctl_elem_value *ucontrol)
2413a47b1dfSKatsuhiro Suzuki {
242f12df661SKuninori Morimoto 	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
243f12df661SKuninori Morimoto 	struct evea_priv *evea = snd_soc_component_get_drvdata(component);
2443a47b1dfSKatsuhiro Suzuki 
2453a47b1dfSKatsuhiro Suzuki 	if (evea->switch_lin == ucontrol->value.integer.value[0])
2463a47b1dfSKatsuhiro Suzuki 		return 0;
2473a47b1dfSKatsuhiro Suzuki 
2483a47b1dfSKatsuhiro Suzuki 	evea->switch_lin = ucontrol->value.integer.value[0];
2493a47b1dfSKatsuhiro Suzuki 
2503a47b1dfSKatsuhiro Suzuki 	return evea_update_switch_lin(evea);
2513a47b1dfSKatsuhiro Suzuki }
2523a47b1dfSKatsuhiro Suzuki 
evea_get_switch_lo(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2533a47b1dfSKatsuhiro Suzuki static int evea_get_switch_lo(struct snd_kcontrol *kcontrol,
2543a47b1dfSKatsuhiro Suzuki 			      struct snd_ctl_elem_value *ucontrol)
2553a47b1dfSKatsuhiro Suzuki {
256f12df661SKuninori Morimoto 	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
257f12df661SKuninori Morimoto 	struct evea_priv *evea = snd_soc_component_get_drvdata(component);
2583a47b1dfSKatsuhiro Suzuki 
2593a47b1dfSKatsuhiro Suzuki 	ucontrol->value.integer.value[0] = evea->switch_lo;
2603a47b1dfSKatsuhiro Suzuki 
2613a47b1dfSKatsuhiro Suzuki 	return 0;
2623a47b1dfSKatsuhiro Suzuki }
2633a47b1dfSKatsuhiro Suzuki 
evea_set_switch_lo(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2643a47b1dfSKatsuhiro Suzuki static int evea_set_switch_lo(struct snd_kcontrol *kcontrol,
2653a47b1dfSKatsuhiro Suzuki 			      struct snd_ctl_elem_value *ucontrol)
2663a47b1dfSKatsuhiro Suzuki {
267f12df661SKuninori Morimoto 	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
268f12df661SKuninori Morimoto 	struct evea_priv *evea = snd_soc_component_get_drvdata(component);
2693a47b1dfSKatsuhiro Suzuki 
2703a47b1dfSKatsuhiro Suzuki 	if (evea->switch_lo == ucontrol->value.integer.value[0])
2713a47b1dfSKatsuhiro Suzuki 		return 0;
2723a47b1dfSKatsuhiro Suzuki 
2733a47b1dfSKatsuhiro Suzuki 	evea->switch_lo = ucontrol->value.integer.value[0];
2743a47b1dfSKatsuhiro Suzuki 
2753a47b1dfSKatsuhiro Suzuki 	return evea_update_switch_lo(evea);
2763a47b1dfSKatsuhiro Suzuki }
2773a47b1dfSKatsuhiro Suzuki 
evea_get_switch_hp(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2783a47b1dfSKatsuhiro Suzuki static int evea_get_switch_hp(struct snd_kcontrol *kcontrol,
2793a47b1dfSKatsuhiro Suzuki 			      struct snd_ctl_elem_value *ucontrol)
2803a47b1dfSKatsuhiro Suzuki {
281f12df661SKuninori Morimoto 	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
282f12df661SKuninori Morimoto 	struct evea_priv *evea = snd_soc_component_get_drvdata(component);
2833a47b1dfSKatsuhiro Suzuki 
2843a47b1dfSKatsuhiro Suzuki 	ucontrol->value.integer.value[0] = evea->switch_hp;
2853a47b1dfSKatsuhiro Suzuki 
2863a47b1dfSKatsuhiro Suzuki 	return 0;
2873a47b1dfSKatsuhiro Suzuki }
2883a47b1dfSKatsuhiro Suzuki 
evea_set_switch_hp(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2893a47b1dfSKatsuhiro Suzuki static int evea_set_switch_hp(struct snd_kcontrol *kcontrol,
2903a47b1dfSKatsuhiro Suzuki 			      struct snd_ctl_elem_value *ucontrol)
2913a47b1dfSKatsuhiro Suzuki {
292f12df661SKuninori Morimoto 	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
293f12df661SKuninori Morimoto 	struct evea_priv *evea = snd_soc_component_get_drvdata(component);
2943a47b1dfSKatsuhiro Suzuki 
2953a47b1dfSKatsuhiro Suzuki 	if (evea->switch_hp == ucontrol->value.integer.value[0])
2963a47b1dfSKatsuhiro Suzuki 		return 0;
2973a47b1dfSKatsuhiro Suzuki 
2983a47b1dfSKatsuhiro Suzuki 	evea->switch_hp = ucontrol->value.integer.value[0];
2993a47b1dfSKatsuhiro Suzuki 
3003a47b1dfSKatsuhiro Suzuki 	return evea_update_switch_hp(evea);
3013a47b1dfSKatsuhiro Suzuki }
3023a47b1dfSKatsuhiro Suzuki 
30309ad28a3SKatsuhiro Suzuki static const struct snd_kcontrol_new evea_controls[] = {
3043a47b1dfSKatsuhiro Suzuki 	SOC_SINGLE_BOOL_EXT("Line Capture Switch", 0,
3053a47b1dfSKatsuhiro Suzuki 			    evea_get_switch_lin, evea_set_switch_lin),
3063a47b1dfSKatsuhiro Suzuki 	SOC_SINGLE_BOOL_EXT("Line Playback Switch", 0,
3073a47b1dfSKatsuhiro Suzuki 			    evea_get_switch_lo, evea_set_switch_lo),
3083a47b1dfSKatsuhiro Suzuki 	SOC_SINGLE_BOOL_EXT("Headphone Playback Switch", 0,
3093a47b1dfSKatsuhiro Suzuki 			    evea_get_switch_hp, evea_set_switch_hp),
3103a47b1dfSKatsuhiro Suzuki };
3113a47b1dfSKatsuhiro Suzuki 
evea_codec_probe(struct snd_soc_component * component)312f12df661SKuninori Morimoto static int evea_codec_probe(struct snd_soc_component *component)
3133a47b1dfSKatsuhiro Suzuki {
314f12df661SKuninori Morimoto 	struct evea_priv *evea = snd_soc_component_get_drvdata(component);
3153a47b1dfSKatsuhiro Suzuki 
3163a47b1dfSKatsuhiro Suzuki 	evea->switch_lin = 1;
3173a47b1dfSKatsuhiro Suzuki 	evea->switch_lo = 1;
3183a47b1dfSKatsuhiro Suzuki 	evea->switch_hp = 1;
3193a47b1dfSKatsuhiro Suzuki 
3203a47b1dfSKatsuhiro Suzuki 	evea_set_power_state_on(evea);
3213a47b1dfSKatsuhiro Suzuki 	evea_update_switch_all(evea);
3223a47b1dfSKatsuhiro Suzuki 
3233a47b1dfSKatsuhiro Suzuki 	return 0;
3243a47b1dfSKatsuhiro Suzuki }
3253a47b1dfSKatsuhiro Suzuki 
evea_codec_suspend(struct snd_soc_component * component)326f12df661SKuninori Morimoto static int evea_codec_suspend(struct snd_soc_component *component)
3273a47b1dfSKatsuhiro Suzuki {
328f12df661SKuninori Morimoto 	struct evea_priv *evea = snd_soc_component_get_drvdata(component);
3293a47b1dfSKatsuhiro Suzuki 
3303a47b1dfSKatsuhiro Suzuki 	evea_set_power_state_off(evea);
3313a47b1dfSKatsuhiro Suzuki 
3323a47b1dfSKatsuhiro Suzuki 	reset_control_assert(evea->rst_adamv);
3333a47b1dfSKatsuhiro Suzuki 	reset_control_assert(evea->rst_exiv);
3343a47b1dfSKatsuhiro Suzuki 	reset_control_assert(evea->rst);
3353a47b1dfSKatsuhiro Suzuki 
3363a47b1dfSKatsuhiro Suzuki 	clk_disable_unprepare(evea->clk_exiv);
3373a47b1dfSKatsuhiro Suzuki 	clk_disable_unprepare(evea->clk);
3383a47b1dfSKatsuhiro Suzuki 
3393a47b1dfSKatsuhiro Suzuki 	return 0;
3403a47b1dfSKatsuhiro Suzuki }
3413a47b1dfSKatsuhiro Suzuki 
evea_codec_resume(struct snd_soc_component * component)342f12df661SKuninori Morimoto static int evea_codec_resume(struct snd_soc_component *component)
3433a47b1dfSKatsuhiro Suzuki {
344f12df661SKuninori Morimoto 	struct evea_priv *evea = snd_soc_component_get_drvdata(component);
3453a47b1dfSKatsuhiro Suzuki 	int ret;
3463a47b1dfSKatsuhiro Suzuki 
3473a47b1dfSKatsuhiro Suzuki 	ret = clk_prepare_enable(evea->clk);
3483a47b1dfSKatsuhiro Suzuki 	if (ret)
3493a47b1dfSKatsuhiro Suzuki 		return ret;
3503a47b1dfSKatsuhiro Suzuki 
3513a47b1dfSKatsuhiro Suzuki 	ret = clk_prepare_enable(evea->clk_exiv);
3523a47b1dfSKatsuhiro Suzuki 	if (ret)
3533a47b1dfSKatsuhiro Suzuki 		goto err_out_clock;
3543a47b1dfSKatsuhiro Suzuki 
3553a47b1dfSKatsuhiro Suzuki 	ret = reset_control_deassert(evea->rst);
3563a47b1dfSKatsuhiro Suzuki 	if (ret)
3573a47b1dfSKatsuhiro Suzuki 		goto err_out_clock_exiv;
3583a47b1dfSKatsuhiro Suzuki 
3593a47b1dfSKatsuhiro Suzuki 	ret = reset_control_deassert(evea->rst_exiv);
3603a47b1dfSKatsuhiro Suzuki 	if (ret)
3613a47b1dfSKatsuhiro Suzuki 		goto err_out_reset;
3623a47b1dfSKatsuhiro Suzuki 
3633a47b1dfSKatsuhiro Suzuki 	ret = reset_control_deassert(evea->rst_adamv);
3643a47b1dfSKatsuhiro Suzuki 	if (ret)
3653a47b1dfSKatsuhiro Suzuki 		goto err_out_reset_exiv;
3663a47b1dfSKatsuhiro Suzuki 
3673a47b1dfSKatsuhiro Suzuki 	evea_set_power_state_on(evea);
3683a47b1dfSKatsuhiro Suzuki 	evea_update_switch_all(evea);
3693a47b1dfSKatsuhiro Suzuki 
3703a47b1dfSKatsuhiro Suzuki 	return 0;
3713a47b1dfSKatsuhiro Suzuki 
3723a47b1dfSKatsuhiro Suzuki err_out_reset_exiv:
3733a47b1dfSKatsuhiro Suzuki 	reset_control_assert(evea->rst_exiv);
3743a47b1dfSKatsuhiro Suzuki 
3753a47b1dfSKatsuhiro Suzuki err_out_reset:
3763a47b1dfSKatsuhiro Suzuki 	reset_control_assert(evea->rst);
3773a47b1dfSKatsuhiro Suzuki 
3783a47b1dfSKatsuhiro Suzuki err_out_clock_exiv:
3793a47b1dfSKatsuhiro Suzuki 	clk_disable_unprepare(evea->clk_exiv);
3803a47b1dfSKatsuhiro Suzuki 
3813a47b1dfSKatsuhiro Suzuki err_out_clock:
3823a47b1dfSKatsuhiro Suzuki 	clk_disable_unprepare(evea->clk);
3833a47b1dfSKatsuhiro Suzuki 
3843a47b1dfSKatsuhiro Suzuki 	return ret;
3853a47b1dfSKatsuhiro Suzuki }
3863a47b1dfSKatsuhiro Suzuki 
387f12df661SKuninori Morimoto static struct snd_soc_component_driver soc_codec_evea = {
3883a47b1dfSKatsuhiro Suzuki 	.probe			= evea_codec_probe,
3893a47b1dfSKatsuhiro Suzuki 	.suspend		= evea_codec_suspend,
3903a47b1dfSKatsuhiro Suzuki 	.resume			= evea_codec_resume,
3913a47b1dfSKatsuhiro Suzuki 	.dapm_widgets		= evea_widgets,
3923a47b1dfSKatsuhiro Suzuki 	.num_dapm_widgets	= ARRAY_SIZE(evea_widgets),
3933a47b1dfSKatsuhiro Suzuki 	.dapm_routes		= evea_routes,
3943a47b1dfSKatsuhiro Suzuki 	.num_dapm_routes	= ARRAY_SIZE(evea_routes),
39509ad28a3SKatsuhiro Suzuki 	.controls		= evea_controls,
39609ad28a3SKatsuhiro Suzuki 	.num_controls		= ARRAY_SIZE(evea_controls),
397f12df661SKuninori Morimoto 	.idle_bias_on		= 1,
398f12df661SKuninori Morimoto 	.use_pmdown_time	= 1,
399f12df661SKuninori Morimoto 	.endianness		= 1,
4003a47b1dfSKatsuhiro Suzuki };
4013a47b1dfSKatsuhiro Suzuki 
4023a47b1dfSKatsuhiro Suzuki static struct snd_soc_dai_driver soc_dai_evea[] = {
4033a47b1dfSKatsuhiro Suzuki 	{
4043a47b1dfSKatsuhiro Suzuki 		.name     = DRV_NAME "-line1",
4053a47b1dfSKatsuhiro Suzuki 		.playback = {
4063a47b1dfSKatsuhiro Suzuki 			.stream_name  = "Line Out 1",
4073a47b1dfSKatsuhiro Suzuki 			.formats      = EVEA_FORMATS,
4083a47b1dfSKatsuhiro Suzuki 			.rates        = EVEA_RATES,
4093a47b1dfSKatsuhiro Suzuki 			.channels_min = 2,
4103a47b1dfSKatsuhiro Suzuki 			.channels_max = 2,
4113a47b1dfSKatsuhiro Suzuki 		},
4123a47b1dfSKatsuhiro Suzuki 		.capture = {
4133a47b1dfSKatsuhiro Suzuki 			.stream_name  = "Line In 1",
4143a47b1dfSKatsuhiro Suzuki 			.formats      = EVEA_FORMATS,
4153a47b1dfSKatsuhiro Suzuki 			.rates        = EVEA_RATES,
4163a47b1dfSKatsuhiro Suzuki 			.channels_min = 2,
4173a47b1dfSKatsuhiro Suzuki 			.channels_max = 2,
4183a47b1dfSKatsuhiro Suzuki 		},
4193a47b1dfSKatsuhiro Suzuki 	},
4203a47b1dfSKatsuhiro Suzuki 	{
4213a47b1dfSKatsuhiro Suzuki 		.name     = DRV_NAME "-hp1",
4223a47b1dfSKatsuhiro Suzuki 		.playback = {
4233a47b1dfSKatsuhiro Suzuki 			.stream_name  = "Headphone 1",
4243a47b1dfSKatsuhiro Suzuki 			.formats      = EVEA_FORMATS,
4253a47b1dfSKatsuhiro Suzuki 			.rates        = EVEA_RATES,
4263a47b1dfSKatsuhiro Suzuki 			.channels_min = 2,
4273a47b1dfSKatsuhiro Suzuki 			.channels_max = 2,
4283a47b1dfSKatsuhiro Suzuki 		},
4293a47b1dfSKatsuhiro Suzuki 	},
4303a47b1dfSKatsuhiro Suzuki 	{
4313a47b1dfSKatsuhiro Suzuki 		.name     = DRV_NAME "-lo2",
4323a47b1dfSKatsuhiro Suzuki 		.playback = {
4333a47b1dfSKatsuhiro Suzuki 			.stream_name  = "Line Out 2",
4343a47b1dfSKatsuhiro Suzuki 			.formats      = EVEA_FORMATS,
4353a47b1dfSKatsuhiro Suzuki 			.rates        = EVEA_RATES,
4363a47b1dfSKatsuhiro Suzuki 			.channels_min = 2,
4373a47b1dfSKatsuhiro Suzuki 			.channels_max = 2,
4383a47b1dfSKatsuhiro Suzuki 		},
4393a47b1dfSKatsuhiro Suzuki 	},
4403a47b1dfSKatsuhiro Suzuki };
4413a47b1dfSKatsuhiro Suzuki 
4423a47b1dfSKatsuhiro Suzuki static const struct regmap_config evea_regmap_config = {
4433a47b1dfSKatsuhiro Suzuki 	.reg_bits      = 32,
4443a47b1dfSKatsuhiro Suzuki 	.reg_stride    = 4,
4453a47b1dfSKatsuhiro Suzuki 	.val_bits      = 32,
4463a47b1dfSKatsuhiro Suzuki 	.max_register  = 0xffc,
4473a47b1dfSKatsuhiro Suzuki 	.cache_type    = REGCACHE_NONE,
4483a47b1dfSKatsuhiro Suzuki };
4493a47b1dfSKatsuhiro Suzuki 
evea_probe(struct platform_device * pdev)4503a47b1dfSKatsuhiro Suzuki static int evea_probe(struct platform_device *pdev)
4513a47b1dfSKatsuhiro Suzuki {
4523a47b1dfSKatsuhiro Suzuki 	struct evea_priv *evea;
4533a47b1dfSKatsuhiro Suzuki 	void __iomem *preg;
4543a47b1dfSKatsuhiro Suzuki 	int ret;
4553a47b1dfSKatsuhiro Suzuki 
4563a47b1dfSKatsuhiro Suzuki 	evea = devm_kzalloc(&pdev->dev, sizeof(struct evea_priv), GFP_KERNEL);
4573a47b1dfSKatsuhiro Suzuki 	if (!evea)
4583a47b1dfSKatsuhiro Suzuki 		return -ENOMEM;
4593a47b1dfSKatsuhiro Suzuki 
4603a47b1dfSKatsuhiro Suzuki 	evea->clk = devm_clk_get(&pdev->dev, "evea");
4613a47b1dfSKatsuhiro Suzuki 	if (IS_ERR(evea->clk))
4623a47b1dfSKatsuhiro Suzuki 		return PTR_ERR(evea->clk);
4633a47b1dfSKatsuhiro Suzuki 
4643a47b1dfSKatsuhiro Suzuki 	evea->clk_exiv = devm_clk_get(&pdev->dev, "exiv");
4653a47b1dfSKatsuhiro Suzuki 	if (IS_ERR(evea->clk_exiv))
4663a47b1dfSKatsuhiro Suzuki 		return PTR_ERR(evea->clk_exiv);
4673a47b1dfSKatsuhiro Suzuki 
4683a47b1dfSKatsuhiro Suzuki 	evea->rst = devm_reset_control_get_shared(&pdev->dev, "evea");
4693a47b1dfSKatsuhiro Suzuki 	if (IS_ERR(evea->rst))
4703a47b1dfSKatsuhiro Suzuki 		return PTR_ERR(evea->rst);
4713a47b1dfSKatsuhiro Suzuki 
4723a47b1dfSKatsuhiro Suzuki 	evea->rst_exiv = devm_reset_control_get_shared(&pdev->dev, "exiv");
4733a47b1dfSKatsuhiro Suzuki 	if (IS_ERR(evea->rst_exiv))
4743a47b1dfSKatsuhiro Suzuki 		return PTR_ERR(evea->rst_exiv);
4753a47b1dfSKatsuhiro Suzuki 
4764e5bc359SYueHaibing 	preg = devm_platform_ioremap_resource(pdev, 0);
4773a47b1dfSKatsuhiro Suzuki 	if (IS_ERR(preg))
4783a47b1dfSKatsuhiro Suzuki 		return PTR_ERR(preg);
4793a47b1dfSKatsuhiro Suzuki 
4803a47b1dfSKatsuhiro Suzuki 	evea->regmap = devm_regmap_init_mmio(&pdev->dev, preg,
4813a47b1dfSKatsuhiro Suzuki 					     &evea_regmap_config);
4823a47b1dfSKatsuhiro Suzuki 	if (IS_ERR(evea->regmap))
4833a47b1dfSKatsuhiro Suzuki 		return PTR_ERR(evea->regmap);
4843a47b1dfSKatsuhiro Suzuki 
4853a47b1dfSKatsuhiro Suzuki 	ret = clk_prepare_enable(evea->clk);
4863a47b1dfSKatsuhiro Suzuki 	if (ret)
4873a47b1dfSKatsuhiro Suzuki 		return ret;
4883a47b1dfSKatsuhiro Suzuki 
4893a47b1dfSKatsuhiro Suzuki 	ret = clk_prepare_enable(evea->clk_exiv);
4903a47b1dfSKatsuhiro Suzuki 	if (ret)
4913a47b1dfSKatsuhiro Suzuki 		goto err_out_clock;
4923a47b1dfSKatsuhiro Suzuki 
4933a47b1dfSKatsuhiro Suzuki 	ret = reset_control_deassert(evea->rst);
4943a47b1dfSKatsuhiro Suzuki 	if (ret)
4953a47b1dfSKatsuhiro Suzuki 		goto err_out_clock_exiv;
4963a47b1dfSKatsuhiro Suzuki 
4973a47b1dfSKatsuhiro Suzuki 	ret = reset_control_deassert(evea->rst_exiv);
4983a47b1dfSKatsuhiro Suzuki 	if (ret)
4993a47b1dfSKatsuhiro Suzuki 		goto err_out_reset;
5003a47b1dfSKatsuhiro Suzuki 
5013a47b1dfSKatsuhiro Suzuki 	/* ADAMV will hangup if EXIV reset is asserted */
5023a47b1dfSKatsuhiro Suzuki 	evea->rst_adamv = devm_reset_control_get_shared(&pdev->dev, "adamv");
5033a47b1dfSKatsuhiro Suzuki 	if (IS_ERR(evea->rst_adamv)) {
5043a47b1dfSKatsuhiro Suzuki 		ret = PTR_ERR(evea->rst_adamv);
5053a47b1dfSKatsuhiro Suzuki 		goto err_out_reset_exiv;
5063a47b1dfSKatsuhiro Suzuki 	}
5073a47b1dfSKatsuhiro Suzuki 
5083a47b1dfSKatsuhiro Suzuki 	ret = reset_control_deassert(evea->rst_adamv);
5093a47b1dfSKatsuhiro Suzuki 	if (ret)
5103a47b1dfSKatsuhiro Suzuki 		goto err_out_reset_exiv;
5113a47b1dfSKatsuhiro Suzuki 
5123a47b1dfSKatsuhiro Suzuki 	platform_set_drvdata(pdev, evea);
5133a47b1dfSKatsuhiro Suzuki 
514f12df661SKuninori Morimoto 	ret = devm_snd_soc_register_component(&pdev->dev, &soc_codec_evea,
5153a47b1dfSKatsuhiro Suzuki 				     soc_dai_evea, ARRAY_SIZE(soc_dai_evea));
5163a47b1dfSKatsuhiro Suzuki 	if (ret)
5173a47b1dfSKatsuhiro Suzuki 		goto err_out_reset_adamv;
5183a47b1dfSKatsuhiro Suzuki 
5193a47b1dfSKatsuhiro Suzuki 	return 0;
5203a47b1dfSKatsuhiro Suzuki 
5213a47b1dfSKatsuhiro Suzuki err_out_reset_adamv:
5223a47b1dfSKatsuhiro Suzuki 	reset_control_assert(evea->rst_adamv);
5233a47b1dfSKatsuhiro Suzuki 
5243a47b1dfSKatsuhiro Suzuki err_out_reset_exiv:
5253a47b1dfSKatsuhiro Suzuki 	reset_control_assert(evea->rst_exiv);
5263a47b1dfSKatsuhiro Suzuki 
5273a47b1dfSKatsuhiro Suzuki err_out_reset:
5283a47b1dfSKatsuhiro Suzuki 	reset_control_assert(evea->rst);
5293a47b1dfSKatsuhiro Suzuki 
5303a47b1dfSKatsuhiro Suzuki err_out_clock_exiv:
5313a47b1dfSKatsuhiro Suzuki 	clk_disable_unprepare(evea->clk_exiv);
5323a47b1dfSKatsuhiro Suzuki 
5333a47b1dfSKatsuhiro Suzuki err_out_clock:
5343a47b1dfSKatsuhiro Suzuki 	clk_disable_unprepare(evea->clk);
5353a47b1dfSKatsuhiro Suzuki 
5363a47b1dfSKatsuhiro Suzuki 	return ret;
5373a47b1dfSKatsuhiro Suzuki }
5383a47b1dfSKatsuhiro Suzuki 
evea_remove(struct platform_device * pdev)539*048d6589SUwe Kleine-König static void evea_remove(struct platform_device *pdev)
5403a47b1dfSKatsuhiro Suzuki {
5413a47b1dfSKatsuhiro Suzuki 	struct evea_priv *evea = platform_get_drvdata(pdev);
5423a47b1dfSKatsuhiro Suzuki 
5433a47b1dfSKatsuhiro Suzuki 	reset_control_assert(evea->rst_adamv);
5443a47b1dfSKatsuhiro Suzuki 	reset_control_assert(evea->rst_exiv);
5453a47b1dfSKatsuhiro Suzuki 	reset_control_assert(evea->rst);
5463a47b1dfSKatsuhiro Suzuki 
5473a47b1dfSKatsuhiro Suzuki 	clk_disable_unprepare(evea->clk_exiv);
5483a47b1dfSKatsuhiro Suzuki 	clk_disable_unprepare(evea->clk);
5493a47b1dfSKatsuhiro Suzuki }
5503a47b1dfSKatsuhiro Suzuki 
551c0b7cf59SKrzysztof Kozlowski static const struct of_device_id evea_of_match[] __maybe_unused = {
5523a47b1dfSKatsuhiro Suzuki 	{ .compatible = "socionext,uniphier-evea", },
5533a47b1dfSKatsuhiro Suzuki 	{}
5543a47b1dfSKatsuhiro Suzuki };
5553a47b1dfSKatsuhiro Suzuki MODULE_DEVICE_TABLE(of, evea_of_match);
5563a47b1dfSKatsuhiro Suzuki 
5573a47b1dfSKatsuhiro Suzuki static struct platform_driver evea_codec_driver = {
5583a47b1dfSKatsuhiro Suzuki 	.driver = {
5593a47b1dfSKatsuhiro Suzuki 		.name = DRV_NAME,
5603a47b1dfSKatsuhiro Suzuki 		.of_match_table = of_match_ptr(evea_of_match),
5613a47b1dfSKatsuhiro Suzuki 	},
5623a47b1dfSKatsuhiro Suzuki 	.probe  = evea_probe,
563*048d6589SUwe Kleine-König 	.remove_new = evea_remove,
5643a47b1dfSKatsuhiro Suzuki };
5653a47b1dfSKatsuhiro Suzuki module_platform_driver(evea_codec_driver);
5663a47b1dfSKatsuhiro Suzuki 
5673a47b1dfSKatsuhiro Suzuki MODULE_AUTHOR("Katsuhiro Suzuki <suzuki.katsuhiro@socionext.com>");
5683a47b1dfSKatsuhiro Suzuki MODULE_DESCRIPTION("UniPhier EVEA codec driver");
5693a47b1dfSKatsuhiro Suzuki MODULE_LICENSE("GPL v2");
570