xref: /linux/sound/soc/codecs/es8375.c (revision af477f4d5a6c183e2dd44f49dd9a7950bfa7bd50)
1de2b3119SZhang Yi // SPDX-License-Identifier: GPL-2.0-only
2de2b3119SZhang Yi /*
3de2b3119SZhang Yi  * es8375.c  --  ES8375 ALSA SoC Audio Codec
4de2b3119SZhang Yi  *
5de2b3119SZhang Yi  * Copyright Everest Semiconductor Co., Ltd
6de2b3119SZhang Yi  *
7de2b3119SZhang Yi  * Authors:  Michael Zhang (zhangyi@everest-semi.com)
8de2b3119SZhang Yi  */
9de2b3119SZhang Yi 
10de2b3119SZhang Yi #include <linux/gpio/consumer.h>
11de2b3119SZhang Yi #include <linux/clk.h>
12de2b3119SZhang Yi #include <linux/module.h>
13de2b3119SZhang Yi #include <linux/kernel.h>
14de2b3119SZhang Yi #include <linux/delay.h>
15de2b3119SZhang Yi #include <linux/i2c.h>
16de2b3119SZhang Yi #include <linux/regmap.h>
17de2b3119SZhang Yi #include <linux/regulator/consumer.h>
18de2b3119SZhang Yi #include <sound/core.h>
19de2b3119SZhang Yi #include <sound/pcm.h>
20de2b3119SZhang Yi #include <sound/pcm_params.h>
21de2b3119SZhang Yi #include <sound/tlv.h>
22de2b3119SZhang Yi #include <sound/soc.h>
23de2b3119SZhang Yi #include <linux/acpi.h>
24de2b3119SZhang Yi #include "es8375.h"
25de2b3119SZhang Yi 
26de2b3119SZhang Yi struct	es8375_priv {
27de2b3119SZhang Yi 	struct regmap *regmap;
28de2b3119SZhang Yi 	struct clk *mclk;
29de2b3119SZhang Yi 	struct regulator_bulk_data core_supply[2];
30de2b3119SZhang Yi 	unsigned int  mclk_freq;
31de2b3119SZhang Yi 	int mastermode;
32de2b3119SZhang Yi 	u8 mclk_src;
33de2b3119SZhang Yi 	u8 vddd;
34de2b3119SZhang Yi 	enum snd_soc_bias_level bias_level;
35de2b3119SZhang Yi };
36de2b3119SZhang Yi 
37de2b3119SZhang Yi static const char * const es8375_core_supplies[] = {
38de2b3119SZhang Yi 	"vddd",
39de2b3119SZhang Yi 	"vdda",
40de2b3119SZhang Yi };
41de2b3119SZhang Yi 
42de2b3119SZhang Yi static const DECLARE_TLV_DB_SCALE(es8375_adc_osr_gain_tlv, -3100, 100, 0);
43de2b3119SZhang Yi static const DECLARE_TLV_DB_SCALE(es8375_adc_volume_tlv, -9550, 50, 0);
44de2b3119SZhang Yi static const DECLARE_TLV_DB_SCALE(es8375_adc_automute_attn_tlv, 0, 100, 0);
45de2b3119SZhang Yi static const DECLARE_TLV_DB_SCALE(es8375_adc_dmic_volume_tlv, 0, 600, 0);
46de2b3119SZhang Yi static const DECLARE_TLV_DB_SCALE(es8375_dac_volume_tlv, -9550, 50, 0);
47de2b3119SZhang Yi static const DECLARE_TLV_DB_SCALE(es8375_dac_vppscale_tlv, -388, 12, 0);
48de2b3119SZhang Yi static const DECLARE_TLV_DB_SCALE(es8375_dac_automute_attn_tlv, 0, 400, 0);
49de2b3119SZhang Yi static const DECLARE_TLV_DB_SCALE(es8375_automute_ng_tlv, -9600, 600, 0);
50de2b3119SZhang Yi 
51de2b3119SZhang Yi static const char *const es8375_ramprate_txt[] = {
52de2b3119SZhang Yi 	"0.125dB/LRCK",
53de2b3119SZhang Yi 	"0.125dB/2LRCK",
54de2b3119SZhang Yi 	"0.125dB/4LRCK",
55de2b3119SZhang Yi 	"0.125dB/8LRCK",
56de2b3119SZhang Yi 	"0.125dB/16LRCK",
57de2b3119SZhang Yi 	"0.125dB/32LRCK",
58de2b3119SZhang Yi 	"0.125dB/64LRCK",
59de2b3119SZhang Yi 	"0.125dB/128LRCK",
60de2b3119SZhang Yi 	"disable softramp",
61de2b3119SZhang Yi };
62de2b3119SZhang Yi static SOC_ENUM_SINGLE_DECL(es8375_adc_ramprate, ES8375_ADC2,
63de2b3119SZhang Yi 		ADC_RAMPRATE_SHIFT_0, es8375_ramprate_txt);
64de2b3119SZhang Yi static SOC_ENUM_SINGLE_DECL(es8375_dac_ramprate, ES8375_DAC2,
65de2b3119SZhang Yi 		DAC_RAMPRATE_SHIFT_0, es8375_ramprate_txt);
66de2b3119SZhang Yi 
67de2b3119SZhang Yi static const char *const es8375_automute_ws_txt[] = {
68de2b3119SZhang Yi 	"256 samples",
69de2b3119SZhang Yi 	"512 samples",
70de2b3119SZhang Yi 	"1024 samples",
71de2b3119SZhang Yi 	"2048 samples",
72de2b3119SZhang Yi 	"4096 samples",
73de2b3119SZhang Yi 	"8192 samples",
74de2b3119SZhang Yi 	"16384 samples",
75de2b3119SZhang Yi 	"32768 samples",
76de2b3119SZhang Yi };
77de2b3119SZhang Yi static SOC_ENUM_SINGLE_DECL(es8375_adc_automute_ws, ES8375_ADC_AUTOMUTE,
78de2b3119SZhang Yi 		ADC_AUTOMUTE_WS_SHIFT_3, es8375_automute_ws_txt);
79de2b3119SZhang Yi static SOC_ENUM_SINGLE_DECL(es8375_dac_automute_ws, ES8375_DAC_AUTOMUTE,
80de2b3119SZhang Yi 		DAC_AUTOMUTE_WS_SHIFT_5, es8375_automute_ws_txt);
81de2b3119SZhang Yi 
82de2b3119SZhang Yi static const char *const es8375_dmic_pol_txt[] = {
83de2b3119SZhang Yi 	"Low",
84de2b3119SZhang Yi 	"High",
85de2b3119SZhang Yi };
86de2b3119SZhang Yi 
87de2b3119SZhang Yi static SOC_ENUM_SINGLE_DECL(es8375_dmic_pol, ES8375_ADC1,
88de2b3119SZhang Yi 		DMIC_POL_SHIFT_4, es8375_dmic_pol_txt);
89de2b3119SZhang Yi 
90de2b3119SZhang Yi static const char *const es8375_adc_hpf_txt[] = {
91de2b3119SZhang Yi 	"Freeze Offset",
92de2b3119SZhang Yi 	"Dynamic HPF",
93de2b3119SZhang Yi };
94de2b3119SZhang Yi 
95de2b3119SZhang Yi static SOC_ENUM_SINGLE_DECL(es8375_adc_hpf, ES8375_HPF1,
96de2b3119SZhang Yi 		ADC_HPF_SHIFT_5, es8375_adc_hpf_txt);
97de2b3119SZhang Yi 
98de2b3119SZhang Yi static const char *const es8375_dmic_mux_txt[] = {
99de2b3119SZhang Yi 	"AMIC",
100de2b3119SZhang Yi 	"DMIC",
101de2b3119SZhang Yi };
102de2b3119SZhang Yi static const struct soc_enum es8375_dmic_mux_enum =
103de2b3119SZhang Yi 	SOC_ENUM_SINGLE(ES8375_ADC1, ADC_SRC_SHIFT_7,
104de2b3119SZhang Yi 			ARRAY_SIZE(es8375_dmic_mux_txt), es8375_dmic_mux_txt);
105de2b3119SZhang Yi 
106de2b3119SZhang Yi static const struct snd_kcontrol_new es8375_dmic_mux_controls =
107de2b3119SZhang Yi 	SOC_DAPM_ENUM("ADC MUX", es8375_dmic_mux_enum);
108de2b3119SZhang Yi 
109de2b3119SZhang Yi static const struct snd_kcontrol_new es8375_snd_controls[] = {
110de2b3119SZhang Yi 	SOC_SINGLE_TLV("ADC OSR Volume", ES8375_ADC_OSR_GAIN,
111de2b3119SZhang Yi 			ADC_OSR_GAIN_SHIFT_0, ES8375_ADC_OSR_GAIN_MAX, 0,
112de2b3119SZhang Yi 			es8375_adc_osr_gain_tlv),
113de2b3119SZhang Yi 	SOC_SINGLE("ADC Invert Switch", ES8375_ADC1, ADC_INV_SHIFT_6, 1, 0),
114de2b3119SZhang Yi 	SOC_SINGLE("ADC RAM Clear", ES8375_ADC1, ADC_RAMCLR_SHIFT_5, 1, 0),
115de2b3119SZhang Yi 	SOC_ENUM("DMIC Polarity", es8375_dmic_pol),
116de2b3119SZhang Yi 	SOC_SINGLE_TLV("DMIC Volume", ES8375_ADC1,
117de2b3119SZhang Yi 		DMIC_GAIN_SHIFT_2, ES8375_DMIC_GAIN_MAX,
118de2b3119SZhang Yi 		0, es8375_adc_dmic_volume_tlv),
119de2b3119SZhang Yi 	SOC_ENUM("ADC Ramp Rate", es8375_adc_ramprate),
120de2b3119SZhang Yi 	SOC_SINGLE_TLV("ADC Volume", ES8375_ADC_VOLUME,
121de2b3119SZhang Yi 			ADC_VOLUME_SHIFT_0, ES8375_ADC_VOLUME_MAX,
122de2b3119SZhang Yi 			0, es8375_adc_volume_tlv),
123de2b3119SZhang Yi 	SOC_SINGLE("ADC Automute Switch", ES8375_ADC_AUTOMUTE,
124de2b3119SZhang Yi 			ADC_AUTOMUTE_SHIFT_7, 1, 0),
125de2b3119SZhang Yi 	SOC_ENUM("ADC Automute Winsize", es8375_adc_automute_ws),
126de2b3119SZhang Yi 	SOC_SINGLE_TLV("ADC Automute Noise Gate", ES8375_ADC_AUTOMUTE,
127de2b3119SZhang Yi 		ADC_AUTOMUTE_NG_SHIFT_0, ES8375_AUTOMUTE_NG_MAX,
128de2b3119SZhang Yi 		0, es8375_automute_ng_tlv),
129de2b3119SZhang Yi 	SOC_SINGLE_TLV("ADC Automute Volume", ES8375_ADC_AUTOMUTE_ATTN,
130de2b3119SZhang Yi 			ADC_AUTOMUTE_ATTN_SHIFT_0, ES8375_ADC_AUTOMUTE_ATTN_MAX,
131de2b3119SZhang Yi 			0, es8375_adc_automute_attn_tlv),
132de2b3119SZhang Yi 	SOC_ENUM("ADC HPF", es8375_adc_hpf),
133de2b3119SZhang Yi 
134de2b3119SZhang Yi 	SOC_SINGLE("DAC DSM Mute Switch", ES8375_DAC1, DAC_DSMMUTE_SHIFT_7, 1, 0),
135de2b3119SZhang Yi 	SOC_SINGLE("DAC DEM Mute Switch", ES8375_DAC1, DAC_DEMMUTE_SHIFT_6, 1, 0),
136de2b3119SZhang Yi 	SOC_SINGLE("DAC Invert Switch", ES8375_DAC1, DAC_INV_SHIFT_5, 1, 0),
137de2b3119SZhang Yi 	SOC_SINGLE("DAC RAM Clear", ES8375_DAC1, DAC_RAMCLR_SHIFT_4, 1, 0),
138de2b3119SZhang Yi 	SOC_ENUM("DAC Ramp Rate", es8375_dac_ramprate),
139de2b3119SZhang Yi 	SOC_SINGLE_TLV("DAC Volume", ES8375_DAC_VOLUME,
140de2b3119SZhang Yi 			DAC_VOLUME_SHIFT_0, ES8375_DAC_VOLUME_MAX,
141de2b3119SZhang Yi 			0, es8375_dac_volume_tlv),
142de2b3119SZhang Yi 	SOC_SINGLE_TLV("DAC VPP Scale", ES8375_DAC_VPPSCALE,
143de2b3119SZhang Yi 			DAC_VPPSCALE_SHIFT_0, ES8375_DAC_VPPSCALE_MAX,
144de2b3119SZhang Yi 			0, es8375_dac_vppscale_tlv),
145de2b3119SZhang Yi 	SOC_SINGLE("DAC Automute Switch", ES8375_DAC_AUTOMUTE1,
146de2b3119SZhang Yi 			DAC_AUTOMUTE_EN_SHIFT_7, 1, 0),
147de2b3119SZhang Yi 	SOC_SINGLE_TLV("DAC Automute Noise Gate", ES8375_DAC_AUTOMUTE1,
148de2b3119SZhang Yi 		DAC_AUTOMUTE_NG_SHIFT_0, ES8375_AUTOMUTE_NG_MAX,
149de2b3119SZhang Yi 		0, es8375_automute_ng_tlv),
150de2b3119SZhang Yi 	SOC_ENUM("DAC Automute Winsize", es8375_dac_automute_ws),
151de2b3119SZhang Yi 	SOC_SINGLE_TLV("DAC Automute Volume", ES8375_DAC_AUTOMUTE,
152de2b3119SZhang Yi 			DAC_AUTOMUTE_ATTN_SHIFT_0, ES8375_DAC_AUTOMUTE_ATTN_MAX,
153de2b3119SZhang Yi 			0, es8375_dac_automute_attn_tlv),
154de2b3119SZhang Yi };
155de2b3119SZhang Yi 
156de2b3119SZhang Yi static const struct snd_soc_dapm_widget es8375_dapm_widgets[] = {
157de2b3119SZhang Yi 	SND_SOC_DAPM_INPUT("MIC1"),
158de2b3119SZhang Yi 	SND_SOC_DAPM_INPUT("DMIC"),
159de2b3119SZhang Yi 	SND_SOC_DAPM_PGA("PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
160de2b3119SZhang Yi 	SND_SOC_DAPM_ADC("Mono ADC", NULL, SND_SOC_NOPM, 0, 0),
161de2b3119SZhang Yi 	SND_SOC_DAPM_AIF_OUT("AIF1TX", "AIF1 Capture", 0, ES8375_SDP2,
162de2b3119SZhang Yi 			ES8375_ADC_P2S_MUTE_SHIFT_5, 1),
163de2b3119SZhang Yi 
164de2b3119SZhang Yi 	SND_SOC_DAPM_MUX("ADC MUX", SND_SOC_NOPM, 0, 0, &es8375_dmic_mux_controls),
165de2b3119SZhang Yi 
166de2b3119SZhang Yi 	SND_SOC_DAPM_AIF_IN("AIF1RX", "AIF1 Playback", 0, ES8375_SDP,
167de2b3119SZhang Yi 		SND_SOC_NOPM, 0),
168de2b3119SZhang Yi 	SND_SOC_DAPM_DAC("Mono DAC", NULL, SND_SOC_NOPM, 0, 0),
169de2b3119SZhang Yi 	SND_SOC_DAPM_OUTPUT("OUT"),
170de2b3119SZhang Yi };
171de2b3119SZhang Yi 
172de2b3119SZhang Yi static const struct snd_soc_dapm_route es8375_dapm_routes[] = {
173de2b3119SZhang Yi 	{"ADC MUX", "AMIC", "MIC1"},
174de2b3119SZhang Yi 	{"ADC MUX", "DMIC", "DMIC"},
175de2b3119SZhang Yi 	{"PGA", NULL, "ADC MUX"},
176de2b3119SZhang Yi 	{"Mono ADC", NULL, "PGA"},
177de2b3119SZhang Yi 	{"AIF1TX", NULL, "Mono ADC"},
178de2b3119SZhang Yi 
179de2b3119SZhang Yi 	{"Mono DAC", NULL, "AIF1RX"},
180de2b3119SZhang Yi 	{"OUT", NULL, "Mono DAC"},
181de2b3119SZhang Yi };
182de2b3119SZhang Yi 
183de2b3119SZhang Yi struct _coeff_div {
184de2b3119SZhang Yi 	u16 mclk_lrck_ratio;
185de2b3119SZhang Yi 	u32 mclk;
186de2b3119SZhang Yi 	u32 rate;
187de2b3119SZhang Yi 	u8 Reg0x04;
188de2b3119SZhang Yi 	u8 Reg0x05;
189de2b3119SZhang Yi 	u8 Reg0x06;
190de2b3119SZhang Yi 	u8 Reg0x07;
191de2b3119SZhang Yi 	u8 Reg0x08;
192de2b3119SZhang Yi 	u8 Reg0x09;
193de2b3119SZhang Yi 	u8 Reg0x0A;
194de2b3119SZhang Yi 	u8 Reg0x0B;
195de2b3119SZhang Yi 	u8 Reg0x19;
196de2b3119SZhang Yi 	u8 dvdd_vol;
197de2b3119SZhang Yi 	u8 dmic_sel;
198de2b3119SZhang Yi };
199de2b3119SZhang Yi 
200de2b3119SZhang Yi static const struct _coeff_div coeff_div[] = {
201de2b3119SZhang Yi 	{32, 256000, 8000, 0x05, 0x34, 0xDD, 0x55, 0x1F, 0x00, 0x95, 0x00, 0x1F, 2, 2},
202de2b3119SZhang Yi 	{32, 512000, 16000, 0x05, 0x34, 0xDD, 0x55, 0x1F, 0x00, 0x94, 0x00, 0x1F, 2, 2},
203de2b3119SZhang Yi 	{32, 1536000, 48000, 0x05, 0x33, 0xD5, 0x55, 0x1F, 0x00, 0x93, 0x00, 0x1F, 2, 2},
204de2b3119SZhang Yi 	{36, 288000, 8000, 0x05, 0x34, 0xDD, 0x55, 0x23, 0x08, 0x95, 0x00, 0x1F, 2, 2},
205de2b3119SZhang Yi 	{36, 576000, 16000, 0x05, 0x34, 0xDD, 0x55, 0x23, 0x08, 0x94, 0x00, 0x1F, 2, 2},
206de2b3119SZhang Yi 	{36, 1728000, 48000, 0x05, 0x33, 0xD5, 0x55, 0x23, 0x08, 0x93, 0x00, 0x1F, 2, 2},
207de2b3119SZhang Yi 	{48, 384000, 8000, 0x05, 0x14, 0x5D, 0x55, 0x17, 0x20, 0x94, 0x00, 0x28, 2, 2},
208de2b3119SZhang Yi 	{48, 768000, 16000, 0x05, 0x14, 0x5D, 0x55, 0x17, 0x20, 0x94, 0x00, 0x28, 2, 2},
209de2b3119SZhang Yi 	{48, 2304000, 48000, 0x05, 0x11, 0x53, 0x55, 0x17, 0x20, 0x92, 0x00, 0x28, 2, 2},
210de2b3119SZhang Yi 	{50, 400000, 8000, 0x05, 0x14, 0x5D, 0x55, 0x18, 0x24, 0x94, 0x00, 0x27, 2, 2},
211de2b3119SZhang Yi 	{50, 800000, 16000, 0x05, 0x14, 0x5D, 0x55, 0x18, 0x24, 0x94, 0x00, 0x27, 2, 2},
212de2b3119SZhang Yi 	{50, 2400000, 48000, 0x05, 0x11, 0x53, 0x55, 0x18, 0x24, 0x92, 0x00, 0x27, 2, 2},
213de2b3119SZhang Yi 	{64, 512000, 8000, 0x05, 0x14, 0x5D, 0x33, 0x1F, 0x00, 0x94, 0x00, 0x1F, 2, 2},
214de2b3119SZhang Yi 	{64, 1024000, 16000, 0x05, 0x13, 0x55, 0x33, 0x1F, 0x00, 0x93, 0x00, 0x1F, 2, 2},
215de2b3119SZhang Yi 	{64, 3072000, 48000, 0x05, 0x11, 0x53, 0x33, 0x1F, 0x00, 0x92, 0x00, 0x1F, 2, 2},
216de2b3119SZhang Yi 	{72, 576000, 8000, 0x05, 0x14, 0x5D, 0x33, 0x23, 0x08, 0x94, 0x00, 0x1F, 2, 2},
217de2b3119SZhang Yi 	{72, 1152000, 16000, 0x05, 0x13, 0x55, 0x33, 0x23, 0x08, 0x93, 0x00, 0x1F, 2, 2},
218de2b3119SZhang Yi 	{72, 3456000, 48000, 0x05, 0x11, 0x53, 0x33, 0x23, 0x08, 0x92, 0x00, 0x1F, 2, 2},
219de2b3119SZhang Yi 	{96, 768000, 8000, 0x15, 0x34, 0xDD, 0x55, 0x1F, 0x00, 0x94, 0x00, 0x1F, 2, 2},
220de2b3119SZhang Yi 	{96, 1536000, 16000, 0x15, 0x34, 0xDD, 0x55, 0x1F, 0x00, 0x93, 0x00, 0x1F, 2, 2},
221de2b3119SZhang Yi 	{96, 4608000, 48000, 0x15, 0x33, 0xD5, 0x55, 0x1F, 0x00, 0x92, 0x00, 0x1F, 2, 2},
222de2b3119SZhang Yi 	{100, 800000, 8000, 0x05, 0x03, 0x35, 0x33, 0x18, 0x24, 0x94, 0x00, 0x27, 2, 2},
223de2b3119SZhang Yi 	{100, 1600000, 16000, 0x05, 0x03, 0x35, 0x33, 0x18, 0x24, 0x93, 0x00, 0x27, 2, 2},
224de2b3119SZhang Yi 	{100, 4800000, 48000, 0x03, 0x00, 0x31, 0x33, 0x18, 0x24, 0x92, 0x00, 0x27, 2, 2},
225de2b3119SZhang Yi 	{128, 1024000, 8000, 0x05, 0x03, 0x35, 0x11, 0x1F, 0x00, 0x93, 0x01, 0x1F, 2, 2},
226de2b3119SZhang Yi 	{128, 2048000, 16000, 0x03, 0x01, 0x33, 0x11, 0x1F, 0x00, 0x92, 0x01, 0x1F, 2, 2},
227de2b3119SZhang Yi 	{128, 6144000, 48000, 0x03, 0x00, 0x31, 0x11, 0x1F, 0x00, 0x92, 0x01, 0x1F, 2, 2},
228de2b3119SZhang Yi 	{144, 1152000, 8000, 0x05, 0x03, 0x35, 0x11, 0x23, 0x08, 0x93, 0x01, 0x1F, 2, 2},
229de2b3119SZhang Yi 	{144, 2304000, 16000, 0x03, 0x01, 0x33, 0x11, 0x23, 0x08, 0x92, 0x01, 0x1F, 2, 2},
230de2b3119SZhang Yi 	{144, 6912000, 48000, 0x03, 0x00, 0x31, 0x11, 0x23, 0x08, 0x92, 0x01, 0x1F, 2, 2},
231de2b3119SZhang Yi 	{192, 1536000, 8000, 0x15, 0x14, 0x5D, 0x33, 0x1F, 0x00, 0x93, 0x02, 0x1F, 2, 2},
232de2b3119SZhang Yi 	{192, 3072000, 16000, 0x15, 0x13, 0x55, 0x33, 0x1F, 0x00, 0x92, 0x02, 0x1F, 2, 2},
233de2b3119SZhang Yi 	{192, 9216000, 48000, 0x15, 0x11, 0x53, 0x33, 0x1F, 0x00, 0x92, 0x02, 0x1F, 2, 2},
234de2b3119SZhang Yi 	{250, 12000000, 48000, 0x25, 0x11, 0x53, 0x55, 0x18, 0x24, 0x92, 0x04, 0x27, 2, 2},
235de2b3119SZhang Yi 	{256, 2048000, 8000, 0x0D, 0x03, 0x35, 0x11, 0x1F, 0x00, 0x92, 0x03, 0x1F, 2, 2},
236de2b3119SZhang Yi 	{256, 4096000, 16000, 0x0B, 0x01, 0x33, 0x11, 0x1F, 0x00, 0x92, 0x03, 0x1F, 2, 2},
237de2b3119SZhang Yi 	{256, 12288000, 48000, 0x0B, 0x00, 0x31, 0x11, 0x1F, 0x00, 0x92, 0x03, 0x1F, 2, 2},
238de2b3119SZhang Yi 	{384, 3072000, 8000, 0x15, 0x03, 0x35, 0x11, 0x1F, 0x00, 0x92, 0x05, 0x1F, 2, 2},
239de2b3119SZhang Yi 	{384, 6144000, 16000, 0x13, 0x01, 0x33, 0x11, 0x1F, 0x00, 0x92, 0x05, 0x1F, 2, 2},
240de2b3119SZhang Yi 	{384, 18432000, 48000, 0x13, 0x00, 0x31, 0x11, 0x1F, 0x00, 0x92, 0x05, 0x1F, 2, 2},
241de2b3119SZhang Yi 	{400, 19200000, 48000, 0x1B, 0x00, 0x31, 0x33, 0x18, 0x24, 0x92, 0x04, 0x27, 2, 2},
242de2b3119SZhang Yi 	{500, 24000000, 48000, 0x23, 0x00, 0x31, 0x33, 0x18, 0x24, 0x92, 0x04, 0x27, 2, 2},
243de2b3119SZhang Yi 	{512, 4096000, 8000, 0x1D, 0x03, 0x35, 0x11, 0x1F, 0x00, 0x92, 0x07, 0x1F, 2, 2},
244de2b3119SZhang Yi 	{512, 8192000, 16000, 0x1B, 0x01, 0x33, 0x11, 0x1F, 0x00, 0x92, 0x07, 0x1F, 2, 2},
245de2b3119SZhang Yi 	{512, 24576000, 48000, 0x1B, 0x00, 0x31, 0x11, 0x1F, 0x00, 0x92, 0x07, 0x1F, 2, 2},
246de2b3119SZhang Yi 	{768, 6144000, 8000, 0x2D, 0x03, 0x35, 0x11, 0x1F, 0x00, 0x92, 0x0B, 0x1F, 2, 2},
247de2b3119SZhang Yi 	{768, 12288000, 16000, 0x2B, 0x01, 0x33, 0x11, 0x1F, 0x00, 0x92, 0x0B, 0x1F, 2, 2},
248de2b3119SZhang Yi 	{1024, 8192000, 8000, 0x3D, 0x03, 0x35, 0x11, 0x1F, 0x00, 0x92, 0x0F, 0x1F, 2, 2},
249de2b3119SZhang Yi 	{1024, 16384000, 16000, 0x3B, 0x01, 0x33, 0x11, 0x1F, 0x00, 0x92, 0x0F, 0x1F, 2, 2},
250de2b3119SZhang Yi 	{1152, 9216000, 8000, 0x45, 0x03, 0x35, 0x11, 0x1F, 0x00, 0x92, 0x0F, 0x1F, 2, 2},
251de2b3119SZhang Yi 	{1152, 18432000, 16000, 0x43, 0x01, 0x33, 0x11, 0x1F, 0x00, 0x92, 0x0F, 0x1F, 2, 2},
252de2b3119SZhang Yi 	{1200, 9600000, 8000, 0x5D, 0x03, 0x35, 0x33, 0x18, 0x24, 0x92, 0x11, 0x27, 2, 2},
253de2b3119SZhang Yi 	{1200, 19200000, 16000, 0x5D, 0x03, 0x35, 0x33, 0x18, 0x24, 0x92, 0x11, 0x27, 2, 2},
254de2b3119SZhang Yi 	{1536, 12288000, 8000, 0x5D, 0x03, 0x35, 0x11, 0x1F, 0x00, 0x92, 0x17, 0x1F, 2, 2},
255de2b3119SZhang Yi 	{1536, 24576000, 16000, 0x5B, 0x01, 0x33, 0x11, 0x1F, 0x00, 0x92, 0x17, 0x1F, 2, 2},
256de2b3119SZhang Yi 	{2048, 16384000, 8000, 0x7D, 0x03, 0x35, 0x11, 0x1F, 0x00, 0x92, 0x1F, 0x1F, 2, 2},
257de2b3119SZhang Yi 	{2304, 18432000, 8000, 0x8D, 0x03, 0x35, 0x11, 0x1F, 0x00, 0x92, 0x23, 0x1F, 2, 2},
258de2b3119SZhang Yi 	{2400, 19200000, 8000, 0xBD, 0x03, 0x35, 0x33, 0x18, 0x24, 0x92, 0x25, 0x27, 2, 2},
259de2b3119SZhang Yi 	{3072, 24576000, 8000, 0xBD, 0x03, 0x35, 0x11, 0x1F, 0x00, 0x92, 0x2F, 0x1F, 2, 2},
260de2b3119SZhang Yi 	{32, 3072000, 96000, 0x05, 0x11, 0x53, 0x55, 0x0F, 0x00, 0x92, 0x00, 0x37, 2, 2},
261de2b3119SZhang Yi 	{64, 6144000, 96000, 0x03, 0x00, 0x31, 0x33, 0x0F, 0x00, 0x92, 0x00, 0x37, 2, 2},
262de2b3119SZhang Yi 	{96, 9216000, 96000, 0x15, 0x11, 0x53, 0x55, 0x0F, 0x00, 0x92, 0x00, 0x37, 2, 2},
263de2b3119SZhang Yi 	{128, 12288000, 96000, 0x0B, 0x00, 0x31, 0x33, 0x0F, 0x00, 0x92, 0x01, 0x37, 2, 2},
264de2b3119SZhang Yi };
265de2b3119SZhang Yi 
get_coeff(u8 vddd,u8 dmic,int mclk,int rate)266de2b3119SZhang Yi static inline int get_coeff(u8 vddd, u8 dmic, int mclk, int rate)
267de2b3119SZhang Yi {
268de2b3119SZhang Yi 	int i;
269de2b3119SZhang Yi 	u8 dmic_det, vddd_det;
270de2b3119SZhang Yi 
271de2b3119SZhang Yi 	for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
272de2b3119SZhang Yi 		if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk) {
273de2b3119SZhang Yi 			vddd_det = ~(coeff_div[i].dvdd_vol ^ vddd) & 0x01;
274de2b3119SZhang Yi 			dmic_det = ~(coeff_div[i].dmic_sel ^ dmic) & 0x01;
275de2b3119SZhang Yi 			vddd_det |= ~(coeff_div[i].dvdd_vol % 2) & 0x01;
276de2b3119SZhang Yi 			dmic_det |= ~(coeff_div[i].dmic_sel % 2) & 0x01;
277de2b3119SZhang Yi 
278de2b3119SZhang Yi 			if (vddd_det && dmic_det)
279de2b3119SZhang Yi 				return i;
280de2b3119SZhang Yi 		}
281de2b3119SZhang Yi 	}
282de2b3119SZhang Yi 
283de2b3119SZhang Yi 	return -EINVAL;
284de2b3119SZhang Yi }
285de2b3119SZhang Yi 
es8375_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * dai)286de2b3119SZhang Yi static int es8375_hw_params(struct snd_pcm_substream *substream,
287de2b3119SZhang Yi 		struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
288de2b3119SZhang Yi {
289de2b3119SZhang Yi 	struct snd_soc_component *component = dai->component;
290de2b3119SZhang Yi 	struct es8375_priv *es8375 = snd_soc_component_get_drvdata(component);
291de2b3119SZhang Yi 	int par_width = params_width(params);
292de2b3119SZhang Yi 	u8 dmic_enable, iface = 0;
293de2b3119SZhang Yi 	unsigned int regv;
294de2b3119SZhang Yi 	int coeff, ret;
295de2b3119SZhang Yi 
296de2b3119SZhang Yi 	if (es8375->mclk_src == ES8375_BCLK_PIN) {
297de2b3119SZhang Yi 		regmap_update_bits(es8375->regmap,
298de2b3119SZhang Yi 				ES8375_MCLK_SEL, 0x80, 0x80);
299de2b3119SZhang Yi 
300de2b3119SZhang Yi 		es8375->mclk_freq = 2 * (unsigned int)par_width * params_rate(params);
301de2b3119SZhang Yi 	}
302de2b3119SZhang Yi 
303de2b3119SZhang Yi 	regmap_read(es8375->regmap, ES8375_ADC1, &regv);
304de2b3119SZhang Yi 	dmic_enable = regv >> 7 & 0x01;
305de2b3119SZhang Yi 
306de2b3119SZhang Yi 	ret = regulator_get_voltage(es8375->core_supply[ES8375_SUPPLY_VD].consumer);
307de2b3119SZhang Yi 	switch (ret) {
308de2b3119SZhang Yi 	case 1800000 ... 2000000:
309de2b3119SZhang Yi 		es8375->vddd = ES8375_1V8;
310de2b3119SZhang Yi 		break;
311de2b3119SZhang Yi 	case 2500000 ... 3300000:
312de2b3119SZhang Yi 		es8375->vddd = ES8375_3V3;
313de2b3119SZhang Yi 		break;
314de2b3119SZhang Yi 	default:
315de2b3119SZhang Yi 		es8375->vddd = ES8375_3V3;
316de2b3119SZhang Yi 		break;
317de2b3119SZhang Yi 	}
318de2b3119SZhang Yi 
319de2b3119SZhang Yi 	coeff = get_coeff(es8375->vddd, dmic_enable, es8375->mclk_freq, params_rate(params));
320de2b3119SZhang Yi 	if (coeff < 0) {
321de2b3119SZhang Yi 		dev_warn(component->dev, "Clock coefficients do not match");
322*16719d48SQasim Ijaz 		return coeff;
323de2b3119SZhang Yi 	}
324de2b3119SZhang Yi 	regmap_write(es8375->regmap, ES8375_CLK_MGR4,
325de2b3119SZhang Yi 			coeff_div[coeff].Reg0x04);
326de2b3119SZhang Yi 	regmap_write(es8375->regmap, ES8375_CLK_MGR5,
327de2b3119SZhang Yi 			coeff_div[coeff].Reg0x05);
328de2b3119SZhang Yi 	regmap_write(es8375->regmap, ES8375_CLK_MGR6,
329de2b3119SZhang Yi 			coeff_div[coeff].Reg0x06);
330de2b3119SZhang Yi 	regmap_write(es8375->regmap, ES8375_CLK_MGR7,
331de2b3119SZhang Yi 			coeff_div[coeff].Reg0x07);
332de2b3119SZhang Yi 	regmap_write(es8375->regmap, ES8375_CLK_MGR8,
333de2b3119SZhang Yi 			coeff_div[coeff].Reg0x08);
334de2b3119SZhang Yi 	regmap_write(es8375->regmap, ES8375_CLK_MGR9,
335de2b3119SZhang Yi 			coeff_div[coeff].Reg0x09);
336de2b3119SZhang Yi 	regmap_write(es8375->regmap, ES8375_CLK_MGR10,
337de2b3119SZhang Yi 			coeff_div[coeff].Reg0x0A);
338de2b3119SZhang Yi 	regmap_write(es8375->regmap, ES8375_CLK_MGR11,
339de2b3119SZhang Yi 			coeff_div[coeff].Reg0x0B);
340de2b3119SZhang Yi 	regmap_write(es8375->regmap, ES8375_ADC_OSR_GAIN,
341de2b3119SZhang Yi 			coeff_div[coeff].Reg0x19);
342de2b3119SZhang Yi 
343de2b3119SZhang Yi 	switch (params_format(params)) {
344de2b3119SZhang Yi 	case SNDRV_PCM_FORMAT_S16_LE:
345de2b3119SZhang Yi 		iface |= 0x0c;
346de2b3119SZhang Yi 		break;
347de2b3119SZhang Yi 	case SNDRV_PCM_FORMAT_S20_3LE:
348de2b3119SZhang Yi 		iface |= 0x04;
349de2b3119SZhang Yi 		break;
350de2b3119SZhang Yi 	case SNDRV_PCM_FORMAT_S24_LE:
351de2b3119SZhang Yi 		break;
352de2b3119SZhang Yi 	case SNDRV_PCM_FORMAT_S32_LE:
353de2b3119SZhang Yi 		iface |= 0x10;
354de2b3119SZhang Yi 		break;
355de2b3119SZhang Yi 	}
356de2b3119SZhang Yi 
357de2b3119SZhang Yi 	regmap_update_bits(es8375->regmap, ES8375_SDP, 0x1c, iface);
358de2b3119SZhang Yi 
359de2b3119SZhang Yi 	return 0;
360de2b3119SZhang Yi }
361de2b3119SZhang Yi 
es8375_set_sysclk(struct snd_soc_dai * dai,int clk_id,unsigned int freq,int dir)362de2b3119SZhang Yi static int es8375_set_sysclk(struct snd_soc_dai *dai, int clk_id,
363de2b3119SZhang Yi 		unsigned int freq, int dir)
364de2b3119SZhang Yi {
365de2b3119SZhang Yi 	struct snd_soc_component *component = dai->component;
366de2b3119SZhang Yi 	struct es8375_priv *es8375 = snd_soc_component_get_drvdata(component);
367de2b3119SZhang Yi 
368de2b3119SZhang Yi 	es8375->mclk_freq = freq;
369de2b3119SZhang Yi 
370de2b3119SZhang Yi 	return 0;
371de2b3119SZhang Yi }
372de2b3119SZhang Yi 
es8375_set_dai_fmt(struct snd_soc_dai * dai,unsigned int fmt)373de2b3119SZhang Yi static int es8375_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
374de2b3119SZhang Yi {
375de2b3119SZhang Yi 	struct snd_soc_component *component = dai->component;
376de2b3119SZhang Yi 	struct es8375_priv *es8375 = snd_soc_component_get_drvdata(component);
377de2b3119SZhang Yi 	unsigned int iface, codeciface;
378de2b3119SZhang Yi 
379de2b3119SZhang Yi 	regmap_read(es8375->regmap, ES8375_SDP, &codeciface);
380de2b3119SZhang Yi 
381de2b3119SZhang Yi 	switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
382de2b3119SZhang Yi 	case SND_SOC_DAIFMT_CBC_CFP:
383de2b3119SZhang Yi 		es8375->mastermode = 1;
384de2b3119SZhang Yi 		regmap_update_bits(es8375->regmap, ES8375_RESET1,
385de2b3119SZhang Yi 				0x80, 0x80);
386de2b3119SZhang Yi 		break;
387de2b3119SZhang Yi 	case SND_SOC_DAIFMT_CBC_CFC:
388de2b3119SZhang Yi 		es8375->mastermode = 0;
389de2b3119SZhang Yi 		regmap_update_bits(es8375->regmap, ES8375_RESET1,
390de2b3119SZhang Yi 				0x80, 0x00);
391de2b3119SZhang Yi 		break;
392de2b3119SZhang Yi 	default:
393de2b3119SZhang Yi 		return -EINVAL;
394de2b3119SZhang Yi 	}
395de2b3119SZhang Yi 
396de2b3119SZhang Yi 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
397de2b3119SZhang Yi 	case SND_SOC_DAIFMT_I2S:
398de2b3119SZhang Yi 		codeciface &= 0xFC;
399de2b3119SZhang Yi 		break;
400de2b3119SZhang Yi 	case SND_SOC_DAIFMT_RIGHT_J:
401de2b3119SZhang Yi 		return -EINVAL;
402de2b3119SZhang Yi 	case SND_SOC_DAIFMT_LEFT_J:
403de2b3119SZhang Yi 		codeciface &= 0xFC;
404de2b3119SZhang Yi 		codeciface |= 0x01;
405de2b3119SZhang Yi 		break;
406de2b3119SZhang Yi 	case SND_SOC_DAIFMT_DSP_A:
407de2b3119SZhang Yi 		codeciface &= 0xDC;
408de2b3119SZhang Yi 		codeciface |= 0x03;
409de2b3119SZhang Yi 		break;
410de2b3119SZhang Yi 	case SND_SOC_DAIFMT_DSP_B:
411de2b3119SZhang Yi 		codeciface &= 0xDC;
412de2b3119SZhang Yi 		codeciface |= 0x23;
413de2b3119SZhang Yi 		break;
414de2b3119SZhang Yi 	default:
415de2b3119SZhang Yi 		return -EINVAL;
416de2b3119SZhang Yi 	}
417de2b3119SZhang Yi 
418de2b3119SZhang Yi 	regmap_read(es8375->regmap, ES8375_CLK_MGR3, &iface);
419de2b3119SZhang Yi 
420de2b3119SZhang Yi 	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
421de2b3119SZhang Yi 	case SND_SOC_DAIFMT_NB_NF:
422de2b3119SZhang Yi 		iface      &= 0xFE;
423de2b3119SZhang Yi 		codeciface &= 0xDF;
424de2b3119SZhang Yi 		break;
425de2b3119SZhang Yi 	case SND_SOC_DAIFMT_IB_IF:
426de2b3119SZhang Yi 		iface      |= 0x01;
427de2b3119SZhang Yi 		codeciface |= 0x20;
428de2b3119SZhang Yi 		break;
429de2b3119SZhang Yi 	case SND_SOC_DAIFMT_IB_NF:
430de2b3119SZhang Yi 		iface      |= 0x01;
431de2b3119SZhang Yi 		codeciface &= 0xDF;
432de2b3119SZhang Yi 		break;
433de2b3119SZhang Yi 	case SND_SOC_DAIFMT_NB_IF:
434de2b3119SZhang Yi 		iface      &= 0xFE;
435de2b3119SZhang Yi 		codeciface |= 0x20;
436de2b3119SZhang Yi 		break;
437de2b3119SZhang Yi 	default:
438de2b3119SZhang Yi 		return -EINVAL;
439de2b3119SZhang Yi 	}
440de2b3119SZhang Yi 
441de2b3119SZhang Yi 	regmap_write(es8375->regmap, ES8375_CLK_MGR3, iface);
442de2b3119SZhang Yi 	regmap_write(es8375->regmap, ES8375_SDP, codeciface);
443de2b3119SZhang Yi 
444de2b3119SZhang Yi 	return 0;
445de2b3119SZhang Yi }
446de2b3119SZhang Yi 
es8375_set_bias_level(struct snd_soc_component * component,enum snd_soc_bias_level level)447de2b3119SZhang Yi static int es8375_set_bias_level(struct snd_soc_component *component,
448de2b3119SZhang Yi 		enum snd_soc_bias_level level)
449de2b3119SZhang Yi {
450de2b3119SZhang Yi 	struct es8375_priv *es8375 = snd_soc_component_get_drvdata(component);
451de2b3119SZhang Yi 	int ret;
452de2b3119SZhang Yi 
453de2b3119SZhang Yi 	switch (level) {
454de2b3119SZhang Yi 	case SND_SOC_BIAS_ON:
455de2b3119SZhang Yi 		ret = clk_prepare_enable(es8375->mclk);
456de2b3119SZhang Yi 		if (ret) {
457de2b3119SZhang Yi 			dev_err(component->dev, "unable to prepare mclk\n");
458de2b3119SZhang Yi 			return  ret;
459de2b3119SZhang Yi 		}
460de2b3119SZhang Yi 		regmap_write(es8375->regmap, ES8375_CSM1, 0xA6);
461de2b3119SZhang Yi 		break;
462de2b3119SZhang Yi 	case SND_SOC_BIAS_PREPARE:
463de2b3119SZhang Yi 		break;
464de2b3119SZhang Yi 	case SND_SOC_BIAS_STANDBY:
465de2b3119SZhang Yi 		regmap_write(es8375->regmap, ES8375_CSM1, 0x96);
466de2b3119SZhang Yi 		clk_disable_unprepare(es8375->mclk);
467de2b3119SZhang Yi 		break;
468de2b3119SZhang Yi 	case SND_SOC_BIAS_OFF:
469de2b3119SZhang Yi 		break;
470de2b3119SZhang Yi 	}
471de2b3119SZhang Yi 	return 0;
472de2b3119SZhang Yi }
473de2b3119SZhang Yi 
es8375_mute(struct snd_soc_dai * dai,int mute,int stream)474de2b3119SZhang Yi static int es8375_mute(struct snd_soc_dai *dai, int mute, int stream)
475de2b3119SZhang Yi {
476de2b3119SZhang Yi 	struct snd_soc_component *component = dai->component;
477de2b3119SZhang Yi 	struct es8375_priv *es8375 = snd_soc_component_get_drvdata(component);
478de2b3119SZhang Yi 
479de2b3119SZhang Yi 	if (mute) {
480de2b3119SZhang Yi 		if (stream == SNDRV_PCM_STREAM_PLAYBACK)
481de2b3119SZhang Yi 			regmap_update_bits(es8375->regmap, ES8375_SDP, 0x40, 0x40);
482de2b3119SZhang Yi 		else
483de2b3119SZhang Yi 			regmap_update_bits(es8375->regmap, ES8375_SDP2, 0x20, 0x20);
484de2b3119SZhang Yi 	} else {
485de2b3119SZhang Yi 		if (stream == SNDRV_PCM_STREAM_PLAYBACK)
486de2b3119SZhang Yi 			regmap_update_bits(es8375->regmap, ES8375_SDP, 0x40, 0x00);
487de2b3119SZhang Yi 		else
488de2b3119SZhang Yi 			regmap_update_bits(es8375->regmap, ES8375_SDP2, 0x20, 0x00);
489de2b3119SZhang Yi 	}
490de2b3119SZhang Yi 
491de2b3119SZhang Yi 	return 0;
492de2b3119SZhang Yi }
493de2b3119SZhang Yi 
494de2b3119SZhang Yi #define es8375_RATES SNDRV_PCM_RATE_8000_96000
495de2b3119SZhang Yi 
496de2b3119SZhang Yi #define es8375_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
497de2b3119SZhang Yi 		SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
498de2b3119SZhang Yi 
499de2b3119SZhang Yi static const struct snd_soc_dai_ops es8375_ops = {
500de2b3119SZhang Yi 	.hw_params = es8375_hw_params,
501de2b3119SZhang Yi 	.mute_stream = es8375_mute,
502de2b3119SZhang Yi 	.set_sysclk = es8375_set_sysclk,
503de2b3119SZhang Yi 	.set_fmt = es8375_set_dai_fmt,
504de2b3119SZhang Yi };
505de2b3119SZhang Yi 
506de2b3119SZhang Yi static struct snd_soc_dai_driver es8375_dai = {
507de2b3119SZhang Yi 	.name = "ES8375 HiFi",
508de2b3119SZhang Yi 	.playback = {
509de2b3119SZhang Yi 		.stream_name = "AIF1 Playback",
510de2b3119SZhang Yi 		.channels_min = 1,
511de2b3119SZhang Yi 		.channels_max = 2,
512de2b3119SZhang Yi 		.rates = es8375_RATES,
513de2b3119SZhang Yi 		.formats = es8375_FORMATS,
514de2b3119SZhang Yi 	},
515de2b3119SZhang Yi 	.capture = {
516de2b3119SZhang Yi 		.stream_name = "AIF1 Capture",
517de2b3119SZhang Yi 		.channels_min = 1,
518de2b3119SZhang Yi 		.channels_max = 2,
519de2b3119SZhang Yi 		.rates = es8375_RATES,
520de2b3119SZhang Yi 		.formats = es8375_FORMATS,
521de2b3119SZhang Yi 	},
522de2b3119SZhang Yi 	.ops = &es8375_ops,
523de2b3119SZhang Yi 	.symmetric_rate = 1,
524de2b3119SZhang Yi };
525de2b3119SZhang Yi 
es8375_init(struct snd_soc_component * component)526de2b3119SZhang Yi static void es8375_init(struct snd_soc_component *component)
527de2b3119SZhang Yi {
528de2b3119SZhang Yi 	struct es8375_priv *es8375 = snd_soc_component_get_drvdata(component);
529de2b3119SZhang Yi 
530de2b3119SZhang Yi 	regmap_write(es8375->regmap, ES8375_CLK_MGR10, 0x95);
531de2b3119SZhang Yi 	regmap_write(es8375->regmap, ES8375_CLK_MGR3, 0x48);
532de2b3119SZhang Yi 	regmap_write(es8375->regmap, ES8375_DIV_SPKCLK, 0x18);
533de2b3119SZhang Yi 	regmap_write(es8375->regmap, ES8375_CLK_MGR4, 0x02);
534de2b3119SZhang Yi 	regmap_write(es8375->regmap, ES8375_CLK_MGR5, 0x05);
535de2b3119SZhang Yi 	regmap_write(es8375->regmap, ES8375_CSM1, 0x82);
536de2b3119SZhang Yi 	regmap_write(es8375->regmap, ES8375_VMID_CHARGE2, 0x20);
537de2b3119SZhang Yi 	regmap_write(es8375->regmap, ES8375_VMID_CHARGE3, 0x20);
538de2b3119SZhang Yi 	regmap_write(es8375->regmap, ES8375_DAC_CAL, 0x28);
539de2b3119SZhang Yi 	regmap_write(es8375->regmap, ES8375_ANALOG_SPK1, 0xFC);
540de2b3119SZhang Yi 	regmap_write(es8375->regmap, ES8375_ANALOG_SPK2, 0xE0);
541de2b3119SZhang Yi 	regmap_write(es8375->regmap, ES8375_VMID_SEL, 0xFE);
542de2b3119SZhang Yi 	regmap_write(es8375->regmap, ES8375_ANALOG1, 0xB8);
543de2b3119SZhang Yi 	regmap_write(es8375->regmap, ES8375_SYS_CTRL2, 0x03);
544de2b3119SZhang Yi 	regmap_write(es8375->regmap, ES8375_CLK_MGR2, 0x16);
545de2b3119SZhang Yi 	regmap_write(es8375->regmap, ES8375_RESET1, 0x00);
546de2b3119SZhang Yi 	msleep(80);
547de2b3119SZhang Yi 	regmap_write(es8375->regmap, ES8375_CLK_MGR3, 0x00);
548de2b3119SZhang Yi 	regmap_write(es8375->regmap, ES8375_CSM1, 0x86);
549de2b3119SZhang Yi 	regmap_write(es8375->regmap, ES8375_CLK_MGR4, 0x0B);
550de2b3119SZhang Yi 	regmap_write(es8375->regmap, ES8375_CLK_MGR5, 0x00);
551de2b3119SZhang Yi 	regmap_write(es8375->regmap, ES8375_CLK_MGR6, 0x31);
552de2b3119SZhang Yi 	regmap_write(es8375->regmap, ES8375_CLK_MGR7, 0x11);
553de2b3119SZhang Yi 	regmap_write(es8375->regmap, ES8375_CLK_MGR8, 0x1F);
554de2b3119SZhang Yi 	regmap_write(es8375->regmap, ES8375_CLK_MGR9, 0x00);
555de2b3119SZhang Yi 	regmap_write(es8375->regmap, ES8375_ADC_OSR_GAIN, 0x1F);
556de2b3119SZhang Yi 	regmap_write(es8375->regmap, ES8375_ADC2, 0x00);
557de2b3119SZhang Yi 	regmap_write(es8375->regmap, ES8375_DAC2, 0x00);
558de2b3119SZhang Yi 	regmap_write(es8375->regmap, ES8375_DAC_OTP, 0x88);
559de2b3119SZhang Yi 	regmap_write(es8375->regmap, ES8375_ANALOG_SPK2, 0xE7);
560de2b3119SZhang Yi 	regmap_write(es8375->regmap, ES8375_ANALOG2, 0xF0);
561de2b3119SZhang Yi 	regmap_write(es8375->regmap, ES8375_ANALOG3, 0x40);
562de2b3119SZhang Yi 	regmap_write(es8375->regmap, ES8375_CLK_MGR2, 0xFE);
563de2b3119SZhang Yi 
564de2b3119SZhang Yi 	regmap_update_bits(es8375->regmap, ES8375_SDP, 0x40, 0x40);
565de2b3119SZhang Yi 	regmap_update_bits(es8375->regmap, ES8375_SDP2, 0x20, 0x20);
566de2b3119SZhang Yi }
567de2b3119SZhang Yi 
es8375_suspend(struct snd_soc_component * component)568de2b3119SZhang Yi static int es8375_suspend(struct snd_soc_component *component)
569de2b3119SZhang Yi {
570de2b3119SZhang Yi 	struct es8375_priv *es8375 = snd_soc_component_get_drvdata(component);
571de2b3119SZhang Yi 
572de2b3119SZhang Yi 	regmap_write(es8375->regmap, ES8375_CSM1, 0x96);
573de2b3119SZhang Yi 	regcache_cache_only(es8375->regmap, true);
574de2b3119SZhang Yi 	regcache_mark_dirty(es8375->regmap);
575de2b3119SZhang Yi 	return 0;
576de2b3119SZhang Yi }
577de2b3119SZhang Yi 
es8375_resume(struct snd_soc_component * component)578de2b3119SZhang Yi static int es8375_resume(struct snd_soc_component *component)
579de2b3119SZhang Yi {
580de2b3119SZhang Yi 	struct es8375_priv *es8375 = snd_soc_component_get_drvdata(component);
581de2b3119SZhang Yi 	unsigned int reg;
582de2b3119SZhang Yi 
583de2b3119SZhang Yi 	regcache_cache_only(es8375->regmap, false);
584de2b3119SZhang Yi 	regcache_cache_bypass(es8375->regmap, true);
585de2b3119SZhang Yi 	regmap_read(es8375->regmap, ES8375_CLK_MGR2, &reg);
586de2b3119SZhang Yi 	regcache_cache_bypass(es8375->regmap, false);
587de2b3119SZhang Yi 
588de2b3119SZhang Yi 	if (reg == 0x00)
589de2b3119SZhang Yi 		es8375_init(component);
590de2b3119SZhang Yi 	else
591de2b3119SZhang Yi 		es8375_set_bias_level(component, SND_SOC_BIAS_ON);
592de2b3119SZhang Yi 
593de2b3119SZhang Yi 	regcache_sync(es8375->regmap);
594de2b3119SZhang Yi 
595de2b3119SZhang Yi 	return 0;
596de2b3119SZhang Yi }
597de2b3119SZhang Yi 
es8375_codec_probe(struct snd_soc_component * component)598de2b3119SZhang Yi static int es8375_codec_probe(struct snd_soc_component *component)
599de2b3119SZhang Yi {
600de2b3119SZhang Yi 	struct es8375_priv *es8375 = snd_soc_component_get_drvdata(component);
601de2b3119SZhang Yi 
602de2b3119SZhang Yi 	es8375->mastermode = 0;
603de2b3119SZhang Yi 
604de2b3119SZhang Yi 	es8375_init(component);
605de2b3119SZhang Yi 
606de2b3119SZhang Yi 	return 0;
607de2b3119SZhang Yi }
608de2b3119SZhang Yi 
es8375_writeable_register(struct device * dev,unsigned int reg)609de2b3119SZhang Yi static bool es8375_writeable_register(struct device *dev, unsigned int reg)
610de2b3119SZhang Yi {
611de2b3119SZhang Yi 	switch (reg) {
612de2b3119SZhang Yi 	case ES8375_CHIP_VERSION:
613de2b3119SZhang Yi 	case ES8375_CHIP_ID0:
614de2b3119SZhang Yi 	case ES8375_CHIP_ID1:
615de2b3119SZhang Yi 	case ES8375_SPK_OFFSET:
616de2b3119SZhang Yi 	case ES8375_FLAGS2:
617de2b3119SZhang Yi 		return false;
618de2b3119SZhang Yi 	default:
619de2b3119SZhang Yi 		return true;
620de2b3119SZhang Yi 	}
621de2b3119SZhang Yi }
622de2b3119SZhang Yi 
623de2b3119SZhang Yi static struct regmap_config es8375_regmap_config = {
624de2b3119SZhang Yi 	.reg_bits = 8,
625de2b3119SZhang Yi 	.val_bits = 8,
626de2b3119SZhang Yi 	.max_register = ES8375_REG_MAX,
627de2b3119SZhang Yi 	.cache_type = REGCACHE_MAPLE,
628de2b3119SZhang Yi 	.use_single_read = true,
629de2b3119SZhang Yi 	.use_single_write = true,
630de2b3119SZhang Yi 	.writeable_reg = es8375_writeable_register,
631de2b3119SZhang Yi };
632de2b3119SZhang Yi 
633de2b3119SZhang Yi static struct snd_soc_component_driver es8375_codec_driver = {
634de2b3119SZhang Yi 	.probe = es8375_codec_probe,
635de2b3119SZhang Yi 	.suspend = es8375_suspend,
636de2b3119SZhang Yi 	.resume = es8375_resume,
637de2b3119SZhang Yi 	.set_bias_level = es8375_set_bias_level,
638de2b3119SZhang Yi 	.controls = es8375_snd_controls,
639de2b3119SZhang Yi 	.num_controls = ARRAY_SIZE(es8375_snd_controls),
640de2b3119SZhang Yi 	.dapm_widgets = es8375_dapm_widgets,
641de2b3119SZhang Yi 	.num_dapm_widgets = ARRAY_SIZE(es8375_dapm_widgets),
642de2b3119SZhang Yi 	.dapm_routes = es8375_dapm_routes,
643de2b3119SZhang Yi 	.num_dapm_routes = ARRAY_SIZE(es8375_dapm_routes),
644de2b3119SZhang Yi 
645de2b3119SZhang Yi 	.idle_bias_on = 1,
646de2b3119SZhang Yi 	.suspend_bias_off = 1,
647de2b3119SZhang Yi };
648de2b3119SZhang Yi 
es8375_read_device_properities(struct device * dev,struct es8375_priv * es8375)649de2b3119SZhang Yi static int es8375_read_device_properities(struct device *dev, struct es8375_priv *es8375)
650de2b3119SZhang Yi {
651de2b3119SZhang Yi 	int ret, i;
652de2b3119SZhang Yi 
653de2b3119SZhang Yi 	ret = device_property_read_u8(dev, "everest,mclk-src", &es8375->mclk_src);
654de2b3119SZhang Yi 	if (ret != 0)
655de2b3119SZhang Yi 		es8375->mclk_src = ES8375_MCLK_SOURCE;
656de2b3119SZhang Yi 	dev_dbg(dev, "mclk-src %x", es8375->mclk_src);
657de2b3119SZhang Yi 
658de2b3119SZhang Yi 	for (i = 0; i < ARRAY_SIZE(es8375_core_supplies); i++)
659de2b3119SZhang Yi 		es8375->core_supply[i].supply = es8375_core_supplies[i];
660de2b3119SZhang Yi 	ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(es8375_core_supplies), es8375->core_supply);
661de2b3119SZhang Yi 	if (ret) {
662de2b3119SZhang Yi 		dev_err(dev, "Failed to request core supplies %d\n", ret);
663de2b3119SZhang Yi 		return ret;
664de2b3119SZhang Yi 	}
665de2b3119SZhang Yi 
666de2b3119SZhang Yi 	es8375->mclk = devm_clk_get(dev, "mclk");
667de2b3119SZhang Yi 	if (IS_ERR(es8375->mclk))
668de2b3119SZhang Yi 		return dev_err_probe(dev, PTR_ERR(es8375->mclk), "unable to get mclk\n");
669de2b3119SZhang Yi 
670de2b3119SZhang Yi 	if (!es8375->mclk)
671de2b3119SZhang Yi 		dev_warn(dev, "assuming static mclk\n");
672de2b3119SZhang Yi 
673de2b3119SZhang Yi 	ret = clk_prepare_enable(es8375->mclk);
674de2b3119SZhang Yi 	if (ret) {
675de2b3119SZhang Yi 		dev_err(dev, "unable to enable mclk\n");
676de2b3119SZhang Yi 		return ret;
677de2b3119SZhang Yi 	}
678de2b3119SZhang Yi 	ret = regulator_bulk_enable(ARRAY_SIZE(es8375_core_supplies), es8375->core_supply);
679de2b3119SZhang Yi 	if (ret) {
680de2b3119SZhang Yi 		dev_err(dev, "Failed to enable core supplies: %d\n", ret);
681de2b3119SZhang Yi 		clk_disable_unprepare(es8375->mclk);
682de2b3119SZhang Yi 		return ret;
683de2b3119SZhang Yi 	}
684de2b3119SZhang Yi 
685de2b3119SZhang Yi 	return 0;
686de2b3119SZhang Yi }
687de2b3119SZhang Yi 
es8375_i2c_probe(struct i2c_client * i2c_client)688de2b3119SZhang Yi static int es8375_i2c_probe(struct i2c_client *i2c_client)
689de2b3119SZhang Yi {
690de2b3119SZhang Yi 	struct es8375_priv *es8375;
691de2b3119SZhang Yi 	struct device *dev = &i2c_client->dev;
692de2b3119SZhang Yi 	int ret;
693de2b3119SZhang Yi 	unsigned int val;
694de2b3119SZhang Yi 
695de2b3119SZhang Yi 	es8375 = devm_kzalloc(&i2c_client->dev, sizeof(*es8375), GFP_KERNEL);
696de2b3119SZhang Yi 	if (!es8375)
697de2b3119SZhang Yi 		return -ENOMEM;
698de2b3119SZhang Yi 
699de2b3119SZhang Yi 	es8375->regmap = devm_regmap_init_i2c(i2c_client,
700de2b3119SZhang Yi 			&es8375_regmap_config);
701de2b3119SZhang Yi 	if (IS_ERR(es8375->regmap))
702de2b3119SZhang Yi 		return dev_err_probe(&i2c_client->dev, PTR_ERR(es8375->regmap),
703de2b3119SZhang Yi 			"regmap_init() failed\n");
704de2b3119SZhang Yi 
705de2b3119SZhang Yi 	i2c_set_clientdata(i2c_client, es8375);
706de2b3119SZhang Yi 
707de2b3119SZhang Yi 	ret = regmap_read(es8375->regmap, ES8375_CHIP_ID1, &val);
708de2b3119SZhang Yi 	if (ret < 0) {
709de2b3119SZhang Yi 		dev_err(&i2c_client->dev, "failed to read i2c at addr %X\n",
710de2b3119SZhang Yi 				i2c_client->addr);
711de2b3119SZhang Yi 		return ret;
712de2b3119SZhang Yi 	}
713de2b3119SZhang Yi 
714de2b3119SZhang Yi 	if (val != 0x83) {
715de2b3119SZhang Yi 		dev_err(&i2c_client->dev, "device at addr %X is not an es8375\n",
716de2b3119SZhang Yi 				i2c_client->addr);
717de2b3119SZhang Yi 		return -ENODEV;
718de2b3119SZhang Yi 	}
719de2b3119SZhang Yi 
720de2b3119SZhang Yi 	ret = regmap_read(es8375->regmap, ES8375_CHIP_ID0, &val);
721de2b3119SZhang Yi 	if (val != 0x75) {
722de2b3119SZhang Yi 		dev_err(&i2c_client->dev, "device at addr %X is not an es8375\n",
723de2b3119SZhang Yi 				i2c_client->addr);
724de2b3119SZhang Yi 		return -ENODEV;
725de2b3119SZhang Yi 	}
726de2b3119SZhang Yi 
727de2b3119SZhang Yi 	ret = es8375_read_device_properities(dev, es8375);
728de2b3119SZhang Yi 	if (ret != 0) {
729de2b3119SZhang Yi 		dev_err(&i2c_client->dev, "get an error from dts info %X\n", ret);
730de2b3119SZhang Yi 		return ret;
731de2b3119SZhang Yi 	}
732de2b3119SZhang Yi 
733de2b3119SZhang Yi 	return devm_snd_soc_register_component(&i2c_client->dev, &es8375_codec_driver,
734de2b3119SZhang Yi 			&es8375_dai, 1);
735de2b3119SZhang Yi }
736de2b3119SZhang Yi 
es8375_i2c_shutdown(struct i2c_client * i2c)737de2b3119SZhang Yi static void es8375_i2c_shutdown(struct i2c_client *i2c)
738de2b3119SZhang Yi {
739de2b3119SZhang Yi 	struct es8375_priv *es8375;
740de2b3119SZhang Yi 
741de2b3119SZhang Yi 	es8375 = i2c_get_clientdata(i2c);
742de2b3119SZhang Yi 
743de2b3119SZhang Yi 	regmap_write(es8375->regmap, ES8375_CSM1, 0x3C);
744de2b3119SZhang Yi 	regmap_write(es8375->regmap, ES8375_CLK_MGR3, 0x48);
745de2b3119SZhang Yi 	regmap_write(es8375->regmap, ES8375_CSM2, 0x80);
746de2b3119SZhang Yi 	regmap_write(es8375->regmap, ES8375_CSM1, 0x3E);
747de2b3119SZhang Yi 	regmap_write(es8375->regmap, ES8375_CLK_MGR10, 0x15);
748de2b3119SZhang Yi 	regmap_write(es8375->regmap, ES8375_SYS_CTRL2, 0x0C);
749de2b3119SZhang Yi 	regmap_write(es8375->regmap, ES8375_RESET1, 0x00);
750de2b3119SZhang Yi 	regmap_write(es8375->regmap, ES8375_CSM2, 0x00);
751de2b3119SZhang Yi 
752de2b3119SZhang Yi 	regulator_bulk_disable(ARRAY_SIZE(es8375_core_supplies), es8375->core_supply);
753de2b3119SZhang Yi 	clk_disable_unprepare(es8375->mclk);
754de2b3119SZhang Yi }
755de2b3119SZhang Yi 
756de2b3119SZhang Yi static const struct i2c_device_id es8375_id[] = {
757de2b3119SZhang Yi 	{"es8375"},
758de2b3119SZhang Yi 	{ }
759de2b3119SZhang Yi };
760de2b3119SZhang Yi MODULE_DEVICE_TABLE(i2c, es8375_id);
761de2b3119SZhang Yi 
762de2b3119SZhang Yi #ifdef CONFIG_ACPI
763de2b3119SZhang Yi static const struct acpi_device_id es8375_acpi_match[] = {
764de2b3119SZhang Yi 	{"ESSX8375", 0},
765de2b3119SZhang Yi 	{},
766de2b3119SZhang Yi };
767de2b3119SZhang Yi 
768de2b3119SZhang Yi MODULE_DEVICE_TABLE(acpi, es8375_acpi_match);
769de2b3119SZhang Yi #endif
770de2b3119SZhang Yi 
771de2b3119SZhang Yi #ifdef CONFIG_OF
772de2b3119SZhang Yi static const struct of_device_id es8375_of_match[] = {
773de2b3119SZhang Yi 	{.compatible = "everest,es8375",},
774de2b3119SZhang Yi 	{}
775de2b3119SZhang Yi };
776de2b3119SZhang Yi 
777de2b3119SZhang Yi MODULE_DEVICE_TABLE(of, es8375_of_match);
778de2b3119SZhang Yi #endif
779de2b3119SZhang Yi 
780de2b3119SZhang Yi static struct i2c_driver es8375_i2c_driver = {
781de2b3119SZhang Yi 	.driver = {
782de2b3119SZhang Yi 		.name	= "es8375",
783de2b3119SZhang Yi 		.of_match_table = of_match_ptr(es8375_of_match),
784de2b3119SZhang Yi 		.acpi_match_table = ACPI_PTR(es8375_acpi_match),
785de2b3119SZhang Yi 	},
786de2b3119SZhang Yi 	.shutdown = es8375_i2c_shutdown,
787de2b3119SZhang Yi 	.probe = es8375_i2c_probe,
788de2b3119SZhang Yi 	.id_table = es8375_id,
789de2b3119SZhang Yi };
790de2b3119SZhang Yi module_i2c_driver(es8375_i2c_driver);
791de2b3119SZhang Yi 
792de2b3119SZhang Yi MODULE_DESCRIPTION("ASoC ES8375 driver");
793de2b3119SZhang Yi MODULE_AUTHOR("Michael Zhang <zhangyi@everest-semi.com>");
794de2b3119SZhang Yi MODULE_LICENSE("GPL");
795