File Index
Files and directories
Sign in
FILE

es8375.c

File preview with syntax highlighting.

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