Linux Audio

Check our new training course

Loading...
v6.13.7
  1// SPDX-License-Identifier: GPL-2.0
  2// Copyright (c) 2017, Maxim Integrated
  3
  4#include <linux/acpi.h>
  5#include <linux/delay.h>
  6#include <linux/i2c.h>
  7#include <linux/module.h>
  8#include <linux/pm_runtime.h>
  9#include <linux/regmap.h>
 10#include <linux/slab.h>
 11#include <linux/cdev.h>
 12#include <sound/pcm.h>
 13#include <sound/pcm_params.h>
 14#include <sound/soc.h>
 15#include <linux/gpio/consumer.h>
 16#include <linux/of.h>
 
 17#include <sound/tlv.h>
 18#include "max98373.h"
 19
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 20static int max98373_dac_event(struct snd_soc_dapm_widget *w,
 21	struct snd_kcontrol *kcontrol, int event)
 22{
 23	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 24	struct max98373_priv *max98373 = snd_soc_component_get_drvdata(component);
 25
 26	switch (event) {
 27	case SND_SOC_DAPM_POST_PMU:
 28		regmap_update_bits(max98373->regmap,
 29			MAX98373_R20FF_GLOBAL_SHDN,
 30			MAX98373_GLOBAL_EN_MASK, 1);
 31		usleep_range(30000, 31000);
 32		break;
 33	case SND_SOC_DAPM_PRE_PMD:
 34		regmap_update_bits(max98373->regmap,
 35			MAX98373_R20FF_GLOBAL_SHDN,
 36			MAX98373_GLOBAL_EN_MASK, 0);
 37		usleep_range(30000, 31000);
 38		max98373->tdm_mode = false;
 39		break;
 40	default:
 41		return 0;
 42	}
 43	return 0;
 44}
 45
 46static const char * const max98373_switch_text[] = {
 47	"Left", "Right", "LeftRight"};
 48
 49static const struct soc_enum dai_sel_enum =
 50	SOC_ENUM_SINGLE(MAX98373_R2029_PCM_TO_SPK_MONO_MIX_1,
 51		MAX98373_PCM_TO_SPK_MONOMIX_CFG_SHIFT,
 52		3, max98373_switch_text);
 53
 54static const struct snd_kcontrol_new max98373_dai_controls =
 55	SOC_DAPM_ENUM("DAI Sel", dai_sel_enum);
 56
 57static const struct snd_kcontrol_new max98373_vi_control =
 58	SOC_DAPM_SINGLE("Switch", MAX98373_R202C_PCM_TX_EN, 0, 1, 0);
 59
 60static const struct snd_kcontrol_new max98373_spkfb_control =
 61	SOC_DAPM_SINGLE("Switch", MAX98373_R2043_AMP_EN, 1, 1, 0);
 62
 63static const struct snd_soc_dapm_widget max98373_dapm_widgets[] = {
 64SND_SOC_DAPM_DAC_E("Amp Enable", "HiFi Playback",
 65	MAX98373_R202B_PCM_RX_EN, 0, 0, max98373_dac_event,
 66	SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
 67SND_SOC_DAPM_MUX("DAI Sel Mux", SND_SOC_NOPM, 0, 0,
 68	&max98373_dai_controls),
 69SND_SOC_DAPM_OUTPUT("BE_OUT"),
 70SND_SOC_DAPM_AIF_OUT("Voltage Sense", "HiFi Capture", 0,
 71	MAX98373_R2047_IV_SENSE_ADC_EN, 0, 0),
 72SND_SOC_DAPM_AIF_OUT("Current Sense", "HiFi Capture", 0,
 73	MAX98373_R2047_IV_SENSE_ADC_EN, 1, 0),
 74SND_SOC_DAPM_AIF_OUT("Speaker FB Sense", "HiFi Capture", 0,
 75	SND_SOC_NOPM, 0, 0),
 76SND_SOC_DAPM_SWITCH("VI Sense", SND_SOC_NOPM, 0, 0,
 77	&max98373_vi_control),
 78SND_SOC_DAPM_SWITCH("SpkFB Sense", SND_SOC_NOPM, 0, 0,
 79	&max98373_spkfb_control),
 80SND_SOC_DAPM_SIGGEN("VMON"),
 81SND_SOC_DAPM_SIGGEN("IMON"),
 82SND_SOC_DAPM_SIGGEN("FBMON"),
 83};
 84
 85static DECLARE_TLV_DB_SCALE(max98373_digital_tlv, -6350, 50, 1);
 86static const DECLARE_TLV_DB_RANGE(max98373_spk_tlv,
 87	0, 8, TLV_DB_SCALE_ITEM(0, 50, 0),
 88	9, 10, TLV_DB_SCALE_ITEM(500, 100, 0),
 89);
 90static const DECLARE_TLV_DB_RANGE(max98373_spkgain_max_tlv,
 91	0, 9, TLV_DB_SCALE_ITEM(800, 100, 0),
 92);
 93static const DECLARE_TLV_DB_RANGE(max98373_dht_step_size_tlv,
 94	0, 1, TLV_DB_SCALE_ITEM(25, 25, 0),
 95	2, 4, TLV_DB_SCALE_ITEM(100, 100, 0),
 96);
 97static const DECLARE_TLV_DB_RANGE(max98373_dht_spkgain_min_tlv,
 98	0, 9, TLV_DB_SCALE_ITEM(800, 100, 0),
 99);
100static const DECLARE_TLV_DB_RANGE(max98373_dht_rotation_point_tlv,
101	0, 1, TLV_DB_SCALE_ITEM(-3000, 500, 0),
102	2, 4, TLV_DB_SCALE_ITEM(-2200, 200, 0),
103	5, 6, TLV_DB_SCALE_ITEM(-1500, 300, 0),
104	7, 9, TLV_DB_SCALE_ITEM(-1000, 200, 0),
105	10, 13, TLV_DB_SCALE_ITEM(-500, 100, 0),
106	14, 15, TLV_DB_SCALE_ITEM(-100, 50, 0),
107);
108static const DECLARE_TLV_DB_RANGE(max98373_limiter_thresh_tlv,
109	0, 15, TLV_DB_SCALE_ITEM(-1500, 100, 0),
110);
111
112static const DECLARE_TLV_DB_RANGE(max98373_bde_gain_tlv,
113	0, 60, TLV_DB_SCALE_ITEM(-1500, 25, 0),
114);
115
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
116static const char * const max98373_output_voltage_lvl_text[] = {
117	"5.43V", "6.09V", "6.83V", "7.67V", "8.60V",
118	"9.65V", "10.83V", "12.15V", "13.63V", "15.29V"
119};
120
121static SOC_ENUM_SINGLE_DECL(max98373_out_volt_enum,
122			    MAX98373_R203E_AMP_PATH_GAIN, 0,
123			    max98373_output_voltage_lvl_text);
124
125static const char * const max98373_dht_attack_rate_text[] = {
126	"17.5us", "35us", "70us", "140us",
127	"280us", "560us", "1120us", "2240us"
128};
129
130static SOC_ENUM_SINGLE_DECL(max98373_dht_attack_rate_enum,
131			    MAX98373_R20D2_DHT_ATTACK_CFG, 0,
132			    max98373_dht_attack_rate_text);
133
134static const char * const max98373_dht_release_rate_text[] = {
135	"45ms", "225ms", "450ms", "1150ms",
136	"2250ms", "3100ms", "4500ms", "6750ms"
137};
138
139static SOC_ENUM_SINGLE_DECL(max98373_dht_release_rate_enum,
140			    MAX98373_R20D3_DHT_RELEASE_CFG, 0,
141			    max98373_dht_release_rate_text);
142
143static const char * const max98373_limiter_attack_rate_text[] = {
144	"10us", "20us", "40us", "80us",
145	"160us", "320us", "640us", "1.28ms",
146	"2.56ms", "5.12ms", "10.24ms", "20.48ms",
147	"40.96ms", "81.92ms", "16.384ms", "32.768ms"
148};
149
150static SOC_ENUM_SINGLE_DECL(max98373_limiter_attack_rate_enum,
151			    MAX98373_R20E1_LIMITER_ATK_REL_RATES, 4,
152			    max98373_limiter_attack_rate_text);
153
154static const char * const max98373_limiter_release_rate_text[] = {
155	"40us", "80us", "160us", "320us",
156	"640us", "1.28ms", "2.56ms", "5.120ms",
157	"10.24ms", "20.48ms", "40.96ms", "81.92ms",
158	"163.84ms", "327.68ms", "655.36ms", "1310.72ms"
159};
160
161static SOC_ENUM_SINGLE_DECL(max98373_limiter_release_rate_enum,
162			    MAX98373_R20E1_LIMITER_ATK_REL_RATES, 0,
163			    max98373_limiter_release_rate_text);
164
165static const char * const max98373_ADC_samplerate_text[] = {
166	"333kHz", "192kHz", "64kHz", "48kHz"
167};
168
169static SOC_ENUM_SINGLE_DECL(max98373_adc_samplerate_enum,
170			    MAX98373_R2051_MEAS_ADC_SAMPLING_RATE, 0,
171			    max98373_ADC_samplerate_text);
172
173static int max98373_feedback_get(struct snd_kcontrol *kcontrol,
174				 struct snd_ctl_elem_value *ucontrol)
175{
176	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
177	struct soc_mixer_control *mc =
178		(struct soc_mixer_control *)kcontrol->private_value;
179	struct max98373_priv *max98373 = snd_soc_component_get_drvdata(component);
180	int i;
181
182	if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
183		/*
184		 * Register values will be cached before suspend. The cached value
185		 * will be a valid value and userspace will happy with that.
186		 */
187		for (i = 0; i < max98373->cache_num; i++) {
188			if (mc->reg == max98373->cache[i].reg) {
189				ucontrol->value.integer.value[0] = max98373->cache[i].val;
190				return 0;
191			}
192		}
193	}
194
195	return snd_soc_get_volsw(kcontrol, ucontrol);
196}
197
198static const struct snd_kcontrol_new max98373_snd_controls[] = {
199SOC_SINGLE("Digital Vol Sel Switch", MAX98373_R203F_AMP_DSP_CFG,
200	MAX98373_AMP_VOL_SEL_SHIFT, 1, 0),
201SOC_SINGLE("Volume Location Switch", MAX98373_R203F_AMP_DSP_CFG,
202	MAX98373_AMP_VOL_SEL_SHIFT, 1, 0),
203SOC_SINGLE("Ramp Up Switch", MAX98373_R203F_AMP_DSP_CFG,
204	MAX98373_AMP_DSP_CFG_RMP_UP_SHIFT, 1, 0),
205SOC_SINGLE("Ramp Down Switch", MAX98373_R203F_AMP_DSP_CFG,
206	MAX98373_AMP_DSP_CFG_RMP_DN_SHIFT, 1, 0),
207/* Speaker Amplifier Overcurrent Automatic Restart Enable */
208SOC_SINGLE("OVC Autorestart Switch", MAX98373_R20FE_DEVICE_AUTO_RESTART_CFG,
209	MAX98373_OVC_AUTORESTART_SHIFT, 1, 0),
210/* Thermal Shutdown Automatic Restart Enable */
211SOC_SINGLE("THERM Autorestart Switch", MAX98373_R20FE_DEVICE_AUTO_RESTART_CFG,
212	MAX98373_THERM_AUTORESTART_SHIFT, 1, 0),
213/* Clock Monitor Automatic Restart Enable */
214SOC_SINGLE("CMON Autorestart Switch", MAX98373_R20FE_DEVICE_AUTO_RESTART_CFG,
215	MAX98373_CMON_AUTORESTART_SHIFT, 1, 0),
216SOC_SINGLE("CLK Monitor Switch", MAX98373_R20FE_DEVICE_AUTO_RESTART_CFG,
217	MAX98373_CLOCK_MON_SHIFT, 1, 0),
218SOC_SINGLE("Dither Switch", MAX98373_R203F_AMP_DSP_CFG,
219	MAX98373_AMP_DSP_CFG_DITH_SHIFT, 1, 0),
220SOC_SINGLE("DC Blocker Switch", MAX98373_R203F_AMP_DSP_CFG,
221	MAX98373_AMP_DSP_CFG_DCBLK_SHIFT, 1, 0),
222SOC_SINGLE_TLV("Digital Volume", MAX98373_R203D_AMP_DIG_VOL_CTRL,
223	0, 0x7F, 1, max98373_digital_tlv),
224SOC_SINGLE_TLV("Speaker Volume", MAX98373_R203E_AMP_PATH_GAIN,
225	MAX98373_SPK_DIGI_GAIN_SHIFT, 10, 0, max98373_spk_tlv),
226SOC_SINGLE_TLV("FS Max Volume", MAX98373_R203E_AMP_PATH_GAIN,
227	MAX98373_FS_GAIN_MAX_SHIFT, 9, 0, max98373_spkgain_max_tlv),
228SOC_ENUM("Output Voltage", max98373_out_volt_enum),
229/* Dynamic Headroom Tracking */
230SOC_SINGLE("DHT Switch", MAX98373_R20D4_DHT_EN,
231	MAX98373_DHT_EN_SHIFT, 1, 0),
232SOC_SINGLE_TLV("DHT Min Volume", MAX98373_R20D1_DHT_CFG,
233	MAX98373_DHT_SPK_GAIN_MIN_SHIFT, 9, 0, max98373_dht_spkgain_min_tlv),
234SOC_SINGLE_TLV("DHT Rot Pnt Volume", MAX98373_R20D1_DHT_CFG,
235	MAX98373_DHT_ROT_PNT_SHIFT, 15, 1, max98373_dht_rotation_point_tlv),
236SOC_SINGLE_TLV("DHT Attack Step Volume", MAX98373_R20D2_DHT_ATTACK_CFG,
237	MAX98373_DHT_ATTACK_STEP_SHIFT, 4, 0, max98373_dht_step_size_tlv),
238SOC_SINGLE_TLV("DHT Release Step Volume", MAX98373_R20D3_DHT_RELEASE_CFG,
239	MAX98373_DHT_RELEASE_STEP_SHIFT, 4, 0, max98373_dht_step_size_tlv),
240SOC_ENUM("DHT Attack Rate", max98373_dht_attack_rate_enum),
241SOC_ENUM("DHT Release Rate", max98373_dht_release_rate_enum),
242/* ADC configuration */
243SOC_SINGLE("ADC PVDD CH Switch", MAX98373_R2056_MEAS_ADC_PVDD_CH_EN, 0, 1, 0),
244SOC_SINGLE("ADC PVDD FLT Switch", MAX98373_R2052_MEAS_ADC_PVDD_FLT_CFG,
245	MAX98373_FLT_EN_SHIFT, 1, 0),
246SOC_SINGLE("ADC TEMP FLT Switch", MAX98373_R2053_MEAS_ADC_THERM_FLT_CFG,
247	MAX98373_FLT_EN_SHIFT, 1, 0),
248SOC_SINGLE_EXT("ADC PVDD", MAX98373_R2054_MEAS_ADC_PVDD_CH_READBACK, 0, 0xFF, 0,
249	max98373_feedback_get, NULL),
250SOC_SINGLE_EXT("ADC TEMP", MAX98373_R2055_MEAS_ADC_THERM_CH_READBACK, 0, 0xFF, 0,
251	max98373_feedback_get, NULL),
252SOC_SINGLE("ADC PVDD FLT Coeff", MAX98373_R2052_MEAS_ADC_PVDD_FLT_CFG,
253	0, 0x3, 0),
254SOC_SINGLE("ADC TEMP FLT Coeff", MAX98373_R2053_MEAS_ADC_THERM_FLT_CFG,
255	0, 0x3, 0),
256SOC_ENUM("ADC SampleRate", max98373_adc_samplerate_enum),
257/* Brownout Detection Engine */
258SOC_SINGLE("BDE Switch", MAX98373_R20B5_BDE_EN, MAX98373_BDE_EN_SHIFT, 1, 0),
259SOC_SINGLE("BDE LVL4 Mute Switch", MAX98373_R20B2_BDE_L4_CFG_2,
260	MAX98373_LVL4_MUTE_EN_SHIFT, 1, 0),
261SOC_SINGLE("BDE LVL4 Hold Switch", MAX98373_R20B2_BDE_L4_CFG_2,
262	MAX98373_LVL4_HOLD_EN_SHIFT, 1, 0),
263SOC_SINGLE("BDE LVL1 Thresh", MAX98373_R2097_BDE_L1_THRESH, 0, 0xFF, 0),
264SOC_SINGLE("BDE LVL2 Thresh", MAX98373_R2098_BDE_L2_THRESH, 0, 0xFF, 0),
265SOC_SINGLE("BDE LVL3 Thresh", MAX98373_R2099_BDE_L3_THRESH, 0, 0xFF, 0),
266SOC_SINGLE("BDE LVL4 Thresh", MAX98373_R209A_BDE_L4_THRESH, 0, 0xFF, 0),
267SOC_SINGLE_EXT("BDE Active Level", MAX98373_R20B6_BDE_CUR_STATE_READBACK, 0, 8, 0,
268	max98373_feedback_get, NULL),
269SOC_SINGLE("BDE Clip Mode Switch", MAX98373_R2092_BDE_CLIPPER_MODE, 0, 1, 0),
270SOC_SINGLE("BDE Thresh Hysteresis", MAX98373_R209B_BDE_THRESH_HYST, 0, 0xFF, 0),
271SOC_SINGLE("BDE Hold Time", MAX98373_R2090_BDE_LVL_HOLD, 0, 0xFF, 0),
272SOC_SINGLE("BDE Attack Rate", MAX98373_R2091_BDE_GAIN_ATK_REL_RATE, 4, 0xF, 0),
273SOC_SINGLE("BDE Release Rate", MAX98373_R2091_BDE_GAIN_ATK_REL_RATE, 0, 0xF, 0),
274SOC_SINGLE_TLV("BDE LVL1 Clip Thresh Volume", MAX98373_R20A9_BDE_L1_CFG_2,
275	0, 0x3C, 1, max98373_bde_gain_tlv),
276SOC_SINGLE_TLV("BDE LVL2 Clip Thresh Volume", MAX98373_R20AC_BDE_L2_CFG_2,
277	0, 0x3C, 1, max98373_bde_gain_tlv),
278SOC_SINGLE_TLV("BDE LVL3 Clip Thresh Volume", MAX98373_R20AF_BDE_L3_CFG_2,
279	0, 0x3C, 1, max98373_bde_gain_tlv),
280SOC_SINGLE_TLV("BDE LVL4 Clip Thresh Volume", MAX98373_R20B2_BDE_L4_CFG_2,
281	0, 0x3C, 1, max98373_bde_gain_tlv),
282SOC_SINGLE_TLV("BDE LVL1 Clip Reduction Volume", MAX98373_R20AA_BDE_L1_CFG_3,
283	0, 0x3C, 1, max98373_bde_gain_tlv),
284SOC_SINGLE_TLV("BDE LVL2 Clip Reduction Volume", MAX98373_R20AD_BDE_L2_CFG_3,
285	0, 0x3C, 1, max98373_bde_gain_tlv),
286SOC_SINGLE_TLV("BDE LVL3 Clip Reduction Volume", MAX98373_R20B0_BDE_L3_CFG_3,
287	0, 0x3C, 1, max98373_bde_gain_tlv),
288SOC_SINGLE_TLV("BDE LVL4 Clip Reduction Volume", MAX98373_R20B3_BDE_L4_CFG_3,
289	0, 0x3C, 1, max98373_bde_gain_tlv),
290SOC_SINGLE_TLV("BDE LVL1 Limiter Thresh Volume", MAX98373_R20A8_BDE_L1_CFG_1,
291	0, 0xF, 1, max98373_limiter_thresh_tlv),
292SOC_SINGLE_TLV("BDE LVL2 Limiter Thresh Volume", MAX98373_R20AB_BDE_L2_CFG_1,
293	0, 0xF, 1, max98373_limiter_thresh_tlv),
294SOC_SINGLE_TLV("BDE LVL3 Limiter Thresh Volume", MAX98373_R20AE_BDE_L3_CFG_1,
295	0, 0xF, 1, max98373_limiter_thresh_tlv),
296SOC_SINGLE_TLV("BDE LVL4 Limiter Thresh Volume", MAX98373_R20B1_BDE_L4_CFG_1,
297	0, 0xF, 1, max98373_limiter_thresh_tlv),
298/* Limiter */
299SOC_SINGLE("Limiter Switch", MAX98373_R20E2_LIMITER_EN,
300	MAX98373_LIMITER_EN_SHIFT, 1, 0),
301SOC_SINGLE("Limiter Src Switch", MAX98373_R20E0_LIMITER_THRESH_CFG,
302	MAX98373_LIMITER_THRESH_SRC_SHIFT, 1, 0),
303SOC_SINGLE_TLV("Limiter Thresh Volume", MAX98373_R20E0_LIMITER_THRESH_CFG,
304	MAX98373_LIMITER_THRESH_SHIFT, 15, 0, max98373_limiter_thresh_tlv),
305SOC_ENUM("Limiter Attack Rate", max98373_limiter_attack_rate_enum),
306SOC_ENUM("Limiter Release Rate", max98373_limiter_release_rate_enum),
307};
308
309static const struct snd_soc_dapm_route max98373_audio_map[] = {
310	/* Plabyack */
311	{"DAI Sel Mux", "Left", "Amp Enable"},
312	{"DAI Sel Mux", "Right", "Amp Enable"},
313	{"DAI Sel Mux", "LeftRight", "Amp Enable"},
314	{"BE_OUT", NULL, "DAI Sel Mux"},
315	/* Capture */
316	{ "VI Sense", "Switch", "VMON" },
317	{ "VI Sense", "Switch", "IMON" },
318	{ "SpkFB Sense", "Switch", "FBMON" },
319	{ "Voltage Sense", NULL, "VI Sense" },
320	{ "Current Sense", NULL, "VI Sense" },
321	{ "Speaker FB Sense", NULL, "SpkFB Sense" },
322};
323
324void max98373_reset(struct max98373_priv *max98373, struct device *dev)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
325{
326	int ret, reg, count;
327
328	/* Software Reset */
329	ret = regmap_update_bits(max98373->regmap,
330		MAX98373_R2000_SW_RESET,
331		MAX98373_SOFT_RESET,
332		MAX98373_SOFT_RESET);
333	if (ret)
334		dev_err(dev, "Reset command failed. (ret:%d)\n", ret);
335
336	count = 0;
337	while (count < 3) {
338		usleep_range(10000, 11000);
339		/* Software Reset Verification */
340		ret = regmap_read(max98373->regmap,
341			MAX98373_R21FF_REV_ID, &reg);
342		if (!ret) {
343			dev_info(dev, "Reset completed (retry:%d)\n", count);
344			return;
345		}
346		count++;
347	}
348	dev_err(dev, "Reset failed. (ret:%d)\n", ret);
349}
350EXPORT_SYMBOL_GPL(max98373_reset);
351
352static int max98373_probe(struct snd_soc_component *component)
353{
354	struct max98373_priv *max98373 = snd_soc_component_get_drvdata(component);
355
356	/* Software Reset */
357	max98373_reset(max98373, component->dev);
358
359	/* IV default slot configuration */
360	regmap_write(max98373->regmap,
361		MAX98373_R2020_PCM_TX_HIZ_EN_1,
362		0xFF);
363	regmap_write(max98373->regmap,
364		MAX98373_R2021_PCM_TX_HIZ_EN_2,
365		0xFF);
366	/* L/R mix configuration */
367	regmap_write(max98373->regmap,
368		MAX98373_R2029_PCM_TO_SPK_MONO_MIX_1,
369		0x80);
370	regmap_write(max98373->regmap,
371		MAX98373_R202A_PCM_TO_SPK_MONO_MIX_2,
372		0x1);
 
 
 
 
 
 
 
373	/* Enable DC blocker */
374	regmap_write(max98373->regmap,
375		MAX98373_R203F_AMP_DSP_CFG,
376		0x3);
377	/* Enable IMON VMON DC blocker */
378	regmap_write(max98373->regmap,
379		MAX98373_R2046_IV_SENSE_ADC_DSP_CFG,
380		0x7);
381	/* voltage, current slot configuration */
382	regmap_write(max98373->regmap,
383		MAX98373_R2022_PCM_TX_SRC_1,
384		(max98373->i_slot << MAX98373_PCM_TX_CH_SRC_A_I_SHIFT |
385		max98373->v_slot) & 0xFF);
386	if (max98373->v_slot < 8)
387		regmap_update_bits(max98373->regmap,
388			MAX98373_R2020_PCM_TX_HIZ_EN_1,
389			1 << max98373->v_slot, 0);
390	else
391		regmap_update_bits(max98373->regmap,
392			MAX98373_R2021_PCM_TX_HIZ_EN_2,
393			1 << (max98373->v_slot - 8), 0);
394
395	if (max98373->i_slot < 8)
396		regmap_update_bits(max98373->regmap,
397			MAX98373_R2020_PCM_TX_HIZ_EN_1,
398			1 << max98373->i_slot, 0);
399	else
400		regmap_update_bits(max98373->regmap,
401			MAX98373_R2021_PCM_TX_HIZ_EN_2,
402			1 << (max98373->i_slot - 8), 0);
403
404	/* enable auto restart function by default */
405	regmap_write(max98373->regmap,
406		MAX98373_R20FE_DEVICE_AUTO_RESTART_CFG,
407		0xF);
408
409	/* speaker feedback slot configuration */
410	regmap_write(max98373->regmap,
411		MAX98373_R2023_PCM_TX_SRC_2,
412		max98373->spkfb_slot & 0xFF);
413
414	/* Set interleave mode */
415	if (max98373->interleave_mode)
416		regmap_update_bits(max98373->regmap,
417			MAX98373_R2024_PCM_DATA_FMT_CFG,
418			MAX98373_PCM_TX_CH_INTERLEAVE_MASK,
419			MAX98373_PCM_TX_CH_INTERLEAVE_MASK);
420
421	/* Speaker enable */
422	regmap_update_bits(max98373->regmap,
423		MAX98373_R2043_AMP_EN,
424		MAX98373_SPK_EN_MASK, 1);
425
426	return 0;
427}
428
429const struct snd_soc_component_driver soc_codec_dev_max98373 = {
430	.probe			= max98373_probe,
431	.controls		= max98373_snd_controls,
432	.num_controls		= ARRAY_SIZE(max98373_snd_controls),
433	.dapm_widgets		= max98373_dapm_widgets,
434	.num_dapm_widgets	= ARRAY_SIZE(max98373_dapm_widgets),
435	.dapm_routes		= max98373_audio_map,
436	.num_dapm_routes	= ARRAY_SIZE(max98373_audio_map),
437	.use_pmdown_time	= 1,
438	.endianness		= 1,
439};
440EXPORT_SYMBOL_GPL(soc_codec_dev_max98373);
441
442static int max98373_sdw_probe(struct snd_soc_component *component)
443{
444	int ret;
445
446	ret = pm_runtime_resume(component->dev);
447	if (ret < 0 && ret != -EACCES)
448		return ret;
 
 
 
 
449
 
 
 
450	return 0;
451}
 
 
 
 
 
452
453const struct snd_soc_component_driver soc_codec_dev_max98373_sdw = {
454	.probe			= max98373_sdw_probe,
455	.controls		= max98373_snd_controls,
456	.num_controls		= ARRAY_SIZE(max98373_snd_controls),
457	.dapm_widgets		= max98373_dapm_widgets,
458	.num_dapm_widgets	= ARRAY_SIZE(max98373_dapm_widgets),
459	.dapm_routes		= max98373_audio_map,
460	.num_dapm_routes	= ARRAY_SIZE(max98373_audio_map),
 
461	.use_pmdown_time	= 1,
462	.endianness		= 1,
 
 
 
 
 
 
 
 
 
 
 
 
463};
464EXPORT_SYMBOL_GPL(soc_codec_dev_max98373_sdw);
465
466void max98373_slot_config(struct device *dev,
467			  struct max98373_priv *max98373)
468{
469	int value;
 
470
471	if (!device_property_read_u32(dev, "maxim,vmon-slot-no", &value))
472		max98373->v_slot = value & 0xF;
473	else
474		max98373->v_slot = 0;
475
476	if (!device_property_read_u32(dev, "maxim,imon-slot-no", &value))
477		max98373->i_slot = value & 0xF;
478	else
479		max98373->i_slot = 1;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
480
481	/* This will assert RESET */
482	max98373->reset = devm_gpiod_get_optional(dev,
483						  "maxim,reset",
484						  GPIOD_OUT_HIGH);
485	if (IS_ERR(max98373->reset)) {
486		dev_err(dev, "error %ld looking up RESET GPIO line\n",
487			PTR_ERR(max98373->reset));
488		return;
489	}
490
491	/* Cycle reset */
492	if (max98373->reset) {
493		gpiod_set_consumer_name(max98373->reset ,"MAX98373_RESET");
494		gpiod_direction_output(max98373->reset, 1);
 
 
 
 
 
 
 
 
 
495		msleep(50);
496		gpiod_direction_output(max98373->reset, 0);
497		msleep(20);
498	}
499
500	if (!device_property_read_u32(dev, "maxim,spkfb-slot-no", &value))
501		max98373->spkfb_slot = value & 0xF;
502	else
503		max98373->spkfb_slot = 2;
 
 
 
 
 
 
 
 
 
 
 
 
 
504}
505EXPORT_SYMBOL_GPL(max98373_slot_config);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
506
507MODULE_DESCRIPTION("ALSA SoC MAX98373 driver");
508MODULE_AUTHOR("Ryan Lee <ryans.lee@maximintegrated.com>");
509MODULE_LICENSE("GPL");
v5.4
   1// SPDX-License-Identifier: GPL-2.0
   2// Copyright (c) 2017, Maxim Integrated
   3
   4#include <linux/acpi.h>
   5#include <linux/delay.h>
   6#include <linux/i2c.h>
   7#include <linux/module.h>
 
   8#include <linux/regmap.h>
   9#include <linux/slab.h>
  10#include <linux/cdev.h>
  11#include <sound/pcm.h>
  12#include <sound/pcm_params.h>
  13#include <sound/soc.h>
  14#include <linux/gpio.h>
  15#include <linux/of.h>
  16#include <linux/of_gpio.h>
  17#include <sound/tlv.h>
  18#include "max98373.h"
  19
  20static struct reg_default max98373_reg[] = {
  21	{MAX98373_R2000_SW_RESET, 0x00},
  22	{MAX98373_R2001_INT_RAW1, 0x00},
  23	{MAX98373_R2002_INT_RAW2, 0x00},
  24	{MAX98373_R2003_INT_RAW3, 0x00},
  25	{MAX98373_R2004_INT_STATE1, 0x00},
  26	{MAX98373_R2005_INT_STATE2, 0x00},
  27	{MAX98373_R2006_INT_STATE3, 0x00},
  28	{MAX98373_R2007_INT_FLAG1, 0x00},
  29	{MAX98373_R2008_INT_FLAG2, 0x00},
  30	{MAX98373_R2009_INT_FLAG3, 0x00},
  31	{MAX98373_R200A_INT_EN1, 0x00},
  32	{MAX98373_R200B_INT_EN2, 0x00},
  33	{MAX98373_R200C_INT_EN3, 0x00},
  34	{MAX98373_R200D_INT_FLAG_CLR1, 0x00},
  35	{MAX98373_R200E_INT_FLAG_CLR2, 0x00},
  36	{MAX98373_R200F_INT_FLAG_CLR3, 0x00},
  37	{MAX98373_R2010_IRQ_CTRL, 0x00},
  38	{MAX98373_R2014_THERM_WARN_THRESH, 0x10},
  39	{MAX98373_R2015_THERM_SHDN_THRESH, 0x27},
  40	{MAX98373_R2016_THERM_HYSTERESIS, 0x01},
  41	{MAX98373_R2017_THERM_FOLDBACK_SET, 0xC0},
  42	{MAX98373_R2018_THERM_FOLDBACK_EN, 0x00},
  43	{MAX98373_R201E_PIN_DRIVE_STRENGTH, 0x55},
  44	{MAX98373_R2020_PCM_TX_HIZ_EN_1, 0xFE},
  45	{MAX98373_R2021_PCM_TX_HIZ_EN_2, 0xFF},
  46	{MAX98373_R2022_PCM_TX_SRC_1, 0x00},
  47	{MAX98373_R2023_PCM_TX_SRC_2, 0x00},
  48	{MAX98373_R2024_PCM_DATA_FMT_CFG, 0xC0},
  49	{MAX98373_R2025_AUDIO_IF_MODE, 0x00},
  50	{MAX98373_R2026_PCM_CLOCK_RATIO, 0x04},
  51	{MAX98373_R2027_PCM_SR_SETUP_1, 0x08},
  52	{MAX98373_R2028_PCM_SR_SETUP_2, 0x88},
  53	{MAX98373_R2029_PCM_TO_SPK_MONO_MIX_1, 0x00},
  54	{MAX98373_R202A_PCM_TO_SPK_MONO_MIX_2, 0x00},
  55	{MAX98373_R202B_PCM_RX_EN, 0x00},
  56	{MAX98373_R202C_PCM_TX_EN, 0x00},
  57	{MAX98373_R202E_ICC_RX_CH_EN_1, 0x00},
  58	{MAX98373_R202F_ICC_RX_CH_EN_2, 0x00},
  59	{MAX98373_R2030_ICC_TX_HIZ_EN_1, 0xFF},
  60	{MAX98373_R2031_ICC_TX_HIZ_EN_2, 0xFF},
  61	{MAX98373_R2032_ICC_LINK_EN_CFG, 0x30},
  62	{MAX98373_R2034_ICC_TX_CNTL, 0x00},
  63	{MAX98373_R2035_ICC_TX_EN, 0x00},
  64	{MAX98373_R2036_SOUNDWIRE_CTRL, 0x05},
  65	{MAX98373_R203D_AMP_DIG_VOL_CTRL, 0x00},
  66	{MAX98373_R203E_AMP_PATH_GAIN, 0x08},
  67	{MAX98373_R203F_AMP_DSP_CFG, 0x02},
  68	{MAX98373_R2040_TONE_GEN_CFG, 0x00},
  69	{MAX98373_R2041_AMP_CFG, 0x03},
  70	{MAX98373_R2042_AMP_EDGE_RATE_CFG, 0x00},
  71	{MAX98373_R2043_AMP_EN, 0x00},
  72	{MAX98373_R2046_IV_SENSE_ADC_DSP_CFG, 0x04},
  73	{MAX98373_R2047_IV_SENSE_ADC_EN, 0x00},
  74	{MAX98373_R2051_MEAS_ADC_SAMPLING_RATE, 0x00},
  75	{MAX98373_R2052_MEAS_ADC_PVDD_FLT_CFG, 0x00},
  76	{MAX98373_R2053_MEAS_ADC_THERM_FLT_CFG, 0x00},
  77	{MAX98373_R2054_MEAS_ADC_PVDD_CH_READBACK, 0x00},
  78	{MAX98373_R2055_MEAS_ADC_THERM_CH_READBACK, 0x00},
  79	{MAX98373_R2056_MEAS_ADC_PVDD_CH_EN, 0x00},
  80	{MAX98373_R2090_BDE_LVL_HOLD, 0x00},
  81	{MAX98373_R2091_BDE_GAIN_ATK_REL_RATE, 0x00},
  82	{MAX98373_R2092_BDE_CLIPPER_MODE, 0x00},
  83	{MAX98373_R2097_BDE_L1_THRESH, 0x00},
  84	{MAX98373_R2098_BDE_L2_THRESH, 0x00},
  85	{MAX98373_R2099_BDE_L3_THRESH, 0x00},
  86	{MAX98373_R209A_BDE_L4_THRESH, 0x00},
  87	{MAX98373_R209B_BDE_THRESH_HYST, 0x00},
  88	{MAX98373_R20A8_BDE_L1_CFG_1, 0x00},
  89	{MAX98373_R20A9_BDE_L1_CFG_2, 0x00},
  90	{MAX98373_R20AA_BDE_L1_CFG_3, 0x00},
  91	{MAX98373_R20AB_BDE_L2_CFG_1, 0x00},
  92	{MAX98373_R20AC_BDE_L2_CFG_2, 0x00},
  93	{MAX98373_R20AD_BDE_L2_CFG_3, 0x00},
  94	{MAX98373_R20AE_BDE_L3_CFG_1, 0x00},
  95	{MAX98373_R20AF_BDE_L3_CFG_2, 0x00},
  96	{MAX98373_R20B0_BDE_L3_CFG_3, 0x00},
  97	{MAX98373_R20B1_BDE_L4_CFG_1, 0x00},
  98	{MAX98373_R20B2_BDE_L4_CFG_2, 0x00},
  99	{MAX98373_R20B3_BDE_L4_CFG_3, 0x00},
 100	{MAX98373_R20B4_BDE_INFINITE_HOLD_RELEASE, 0x00},
 101	{MAX98373_R20B5_BDE_EN, 0x00},
 102	{MAX98373_R20B6_BDE_CUR_STATE_READBACK, 0x00},
 103	{MAX98373_R20D1_DHT_CFG, 0x01},
 104	{MAX98373_R20D2_DHT_ATTACK_CFG, 0x02},
 105	{MAX98373_R20D3_DHT_RELEASE_CFG, 0x03},
 106	{MAX98373_R20D4_DHT_EN, 0x00},
 107	{MAX98373_R20E0_LIMITER_THRESH_CFG, 0x00},
 108	{MAX98373_R20E1_LIMITER_ATK_REL_RATES, 0x00},
 109	{MAX98373_R20E2_LIMITER_EN, 0x00},
 110	{MAX98373_R20FE_DEVICE_AUTO_RESTART_CFG, 0x00},
 111	{MAX98373_R20FF_GLOBAL_SHDN, 0x00},
 112	{MAX98373_R21FF_REV_ID, 0x42},
 113};
 114
 115static int max98373_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 116{
 117	struct snd_soc_component *component = codec_dai->component;
 118	struct max98373_priv *max98373 = snd_soc_component_get_drvdata(component);
 119	unsigned int format = 0;
 120	unsigned int invert = 0;
 121
 122	dev_dbg(component->dev, "%s: fmt 0x%08X\n", __func__, fmt);
 123
 124	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
 125	case SND_SOC_DAIFMT_NB_NF:
 126		break;
 127	case SND_SOC_DAIFMT_IB_NF:
 128		invert = MAX98373_PCM_MODE_CFG_PCM_BCLKEDGE;
 129		break;
 130	default:
 131		dev_err(component->dev, "DAI invert mode unsupported\n");
 132		return -EINVAL;
 133	}
 134
 135	regmap_update_bits(max98373->regmap,
 136		MAX98373_R2026_PCM_CLOCK_RATIO,
 137		MAX98373_PCM_MODE_CFG_PCM_BCLKEDGE,
 138		invert);
 139
 140	/* interface format */
 141	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 142	case SND_SOC_DAIFMT_I2S:
 143		format = MAX98373_PCM_FORMAT_I2S;
 144		break;
 145	case SND_SOC_DAIFMT_LEFT_J:
 146		format = MAX98373_PCM_FORMAT_LJ;
 147		break;
 148	case SND_SOC_DAIFMT_DSP_A:
 149		format = MAX98373_PCM_FORMAT_TDM_MODE1;
 150		break;
 151	case SND_SOC_DAIFMT_DSP_B:
 152		format = MAX98373_PCM_FORMAT_TDM_MODE0;
 153		break;
 154	default:
 155		return -EINVAL;
 156	}
 157
 158	regmap_update_bits(max98373->regmap,
 159		MAX98373_R2024_PCM_DATA_FMT_CFG,
 160		MAX98373_PCM_MODE_CFG_FORMAT_MASK,
 161		format << MAX98373_PCM_MODE_CFG_FORMAT_SHIFT);
 162
 163	return 0;
 164}
 165
 166/* BCLKs per LRCLK */
 167static const int bclk_sel_table[] = {
 168	32, 48, 64, 96, 128, 192, 256, 384, 512, 320,
 169};
 170
 171static int max98373_get_bclk_sel(int bclk)
 172{
 173	int i;
 174	/* match BCLKs per LRCLK */
 175	for (i = 0; i < ARRAY_SIZE(bclk_sel_table); i++) {
 176		if (bclk_sel_table[i] == bclk)
 177			return i + 2;
 178	}
 179	return 0;
 180}
 181
 182static int max98373_set_clock(struct snd_soc_component *component,
 183	struct snd_pcm_hw_params *params)
 184{
 185	struct max98373_priv *max98373 = snd_soc_component_get_drvdata(component);
 186	/* BCLK/LRCLK ratio calculation */
 187	int blr_clk_ratio = params_channels(params) * max98373->ch_size;
 188	int value;
 189
 190	if (!max98373->tdm_mode) {
 191		/* BCLK configuration */
 192		value = max98373_get_bclk_sel(blr_clk_ratio);
 193		if (!value) {
 194			dev_err(component->dev, "format unsupported %d\n",
 195				params_format(params));
 196			return -EINVAL;
 197		}
 198
 199		regmap_update_bits(max98373->regmap,
 200			MAX98373_R2026_PCM_CLOCK_RATIO,
 201			MAX98373_PCM_CLK_SETUP_BSEL_MASK,
 202			value);
 203	}
 204	return 0;
 205}
 206
 207static int max98373_dai_hw_params(struct snd_pcm_substream *substream,
 208	struct snd_pcm_hw_params *params,
 209	struct snd_soc_dai *dai)
 210{
 211	struct snd_soc_component *component = dai->component;
 212	struct max98373_priv *max98373 = snd_soc_component_get_drvdata(component);
 213	unsigned int sampling_rate = 0;
 214	unsigned int chan_sz = 0;
 215
 216	/* pcm mode configuration */
 217	switch (snd_pcm_format_width(params_format(params))) {
 218	case 16:
 219		chan_sz = MAX98373_PCM_MODE_CFG_CHANSZ_16;
 220		break;
 221	case 24:
 222		chan_sz = MAX98373_PCM_MODE_CFG_CHANSZ_24;
 223		break;
 224	case 32:
 225		chan_sz = MAX98373_PCM_MODE_CFG_CHANSZ_32;
 226		break;
 227	default:
 228		dev_err(component->dev, "format unsupported %d\n",
 229			params_format(params));
 230		goto err;
 231	}
 232
 233	max98373->ch_size = snd_pcm_format_width(params_format(params));
 234
 235	regmap_update_bits(max98373->regmap,
 236		MAX98373_R2024_PCM_DATA_FMT_CFG,
 237		MAX98373_PCM_MODE_CFG_CHANSZ_MASK, chan_sz);
 238
 239	dev_dbg(component->dev, "format supported %d",
 240		params_format(params));
 241
 242	/* sampling rate configuration */
 243	switch (params_rate(params)) {
 244	case 8000:
 245		sampling_rate = MAX98373_PCM_SR_SET1_SR_8000;
 246		break;
 247	case 11025:
 248		sampling_rate = MAX98373_PCM_SR_SET1_SR_11025;
 249		break;
 250	case 12000:
 251		sampling_rate = MAX98373_PCM_SR_SET1_SR_12000;
 252		break;
 253	case 16000:
 254		sampling_rate = MAX98373_PCM_SR_SET1_SR_16000;
 255		break;
 256	case 22050:
 257		sampling_rate = MAX98373_PCM_SR_SET1_SR_22050;
 258		break;
 259	case 24000:
 260		sampling_rate = MAX98373_PCM_SR_SET1_SR_24000;
 261		break;
 262	case 32000:
 263		sampling_rate = MAX98373_PCM_SR_SET1_SR_32000;
 264		break;
 265	case 44100:
 266		sampling_rate = MAX98373_PCM_SR_SET1_SR_44100;
 267		break;
 268	case 48000:
 269		sampling_rate = MAX98373_PCM_SR_SET1_SR_48000;
 270		break;
 271	case 88200:
 272		sampling_rate = MAX98373_PCM_SR_SET1_SR_88200;
 273		break;
 274	case 96000:
 275		sampling_rate = MAX98373_PCM_SR_SET1_SR_96000;
 276		break;
 277	default:
 278		dev_err(component->dev, "rate %d not supported\n",
 279			params_rate(params));
 280		goto err;
 281	}
 282
 283	/* set DAI_SR to correct LRCLK frequency */
 284	regmap_update_bits(max98373->regmap,
 285		MAX98373_R2027_PCM_SR_SETUP_1,
 286		MAX98373_PCM_SR_SET1_SR_MASK,
 287		sampling_rate);
 288	regmap_update_bits(max98373->regmap,
 289		MAX98373_R2028_PCM_SR_SETUP_2,
 290		MAX98373_PCM_SR_SET2_SR_MASK,
 291		sampling_rate << MAX98373_PCM_SR_SET2_SR_SHIFT);
 292
 293	/* set sampling rate of IV */
 294	if (max98373->interleave_mode &&
 295	    sampling_rate > MAX98373_PCM_SR_SET1_SR_16000)
 296		regmap_update_bits(max98373->regmap,
 297			MAX98373_R2028_PCM_SR_SETUP_2,
 298			MAX98373_PCM_SR_SET2_IVADC_SR_MASK,
 299			sampling_rate - 3);
 300	else
 301		regmap_update_bits(max98373->regmap,
 302			MAX98373_R2028_PCM_SR_SETUP_2,
 303			MAX98373_PCM_SR_SET2_IVADC_SR_MASK,
 304			sampling_rate);
 305
 306	return max98373_set_clock(component, params);
 307err:
 308	return -EINVAL;
 309}
 310
 311static int max98373_dai_tdm_slot(struct snd_soc_dai *dai,
 312	unsigned int tx_mask, unsigned int rx_mask,
 313	int slots, int slot_width)
 314{
 315	struct snd_soc_component *component = dai->component;
 316	struct max98373_priv *max98373 = snd_soc_component_get_drvdata(component);
 317	int bsel = 0;
 318	unsigned int chan_sz = 0;
 319	unsigned int mask;
 320	int x, slot_found;
 321
 322	if (!tx_mask && !rx_mask && !slots && !slot_width)
 323		max98373->tdm_mode = false;
 324	else
 325		max98373->tdm_mode = true;
 326
 327	/* BCLK configuration */
 328	bsel = max98373_get_bclk_sel(slots * slot_width);
 329	if (bsel == 0) {
 330		dev_err(component->dev, "BCLK %d not supported\n",
 331			slots * slot_width);
 332		return -EINVAL;
 333	}
 334
 335	regmap_update_bits(max98373->regmap,
 336		MAX98373_R2026_PCM_CLOCK_RATIO,
 337		MAX98373_PCM_CLK_SETUP_BSEL_MASK,
 338		bsel);
 339
 340	/* Channel size configuration */
 341	switch (slot_width) {
 342	case 16:
 343		chan_sz = MAX98373_PCM_MODE_CFG_CHANSZ_16;
 344		break;
 345	case 24:
 346		chan_sz = MAX98373_PCM_MODE_CFG_CHANSZ_24;
 347		break;
 348	case 32:
 349		chan_sz = MAX98373_PCM_MODE_CFG_CHANSZ_32;
 350		break;
 351	default:
 352		dev_err(component->dev, "format unsupported %d\n",
 353			slot_width);
 354		return -EINVAL;
 355	}
 356
 357	regmap_update_bits(max98373->regmap,
 358		MAX98373_R2024_PCM_DATA_FMT_CFG,
 359		MAX98373_PCM_MODE_CFG_CHANSZ_MASK, chan_sz);
 360
 361	/* Rx slot configuration */
 362	slot_found = 0;
 363	mask = rx_mask;
 364	for (x = 0 ; x < 16 ; x++, mask >>= 1) {
 365		if (mask & 0x1) {
 366			if (slot_found == 0)
 367				regmap_update_bits(max98373->regmap,
 368					MAX98373_R2029_PCM_TO_SPK_MONO_MIX_1,
 369					MAX98373_PCM_TO_SPK_CH0_SRC_MASK, x);
 370			else
 371				regmap_write(max98373->regmap,
 372					MAX98373_R202A_PCM_TO_SPK_MONO_MIX_2,
 373					x);
 374			slot_found++;
 375			if (slot_found > 1)
 376				break;
 377		}
 378	}
 379
 380	/* Tx slot Hi-Z configuration */
 381	regmap_write(max98373->regmap,
 382		MAX98373_R2020_PCM_TX_HIZ_EN_1,
 383		~tx_mask & 0xFF);
 384	regmap_write(max98373->regmap,
 385		MAX98373_R2021_PCM_TX_HIZ_EN_2,
 386		(~tx_mask & 0xFF00) >> 8);
 387
 388	return 0;
 389}
 390
 391#define MAX98373_RATES SNDRV_PCM_RATE_8000_96000
 392
 393#define MAX98373_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
 394	SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
 395
 396static const struct snd_soc_dai_ops max98373_dai_ops = {
 397	.set_fmt = max98373_dai_set_fmt,
 398	.hw_params = max98373_dai_hw_params,
 399	.set_tdm_slot = max98373_dai_tdm_slot,
 400};
 401
 402static int max98373_dac_event(struct snd_soc_dapm_widget *w,
 403	struct snd_kcontrol *kcontrol, int event)
 404{
 405	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 406	struct max98373_priv *max98373 = snd_soc_component_get_drvdata(component);
 407
 408	switch (event) {
 409	case SND_SOC_DAPM_POST_PMU:
 410		regmap_update_bits(max98373->regmap,
 411			MAX98373_R20FF_GLOBAL_SHDN,
 412			MAX98373_GLOBAL_EN_MASK, 1);
 
 413		break;
 414	case SND_SOC_DAPM_POST_PMD:
 415		regmap_update_bits(max98373->regmap,
 416			MAX98373_R20FF_GLOBAL_SHDN,
 417			MAX98373_GLOBAL_EN_MASK, 0);
 
 418		max98373->tdm_mode = false;
 419		break;
 420	default:
 421		return 0;
 422	}
 423	return 0;
 424}
 425
 426static const char * const max98373_switch_text[] = {
 427	"Left", "Right", "LeftRight"};
 428
 429static const struct soc_enum dai_sel_enum =
 430	SOC_ENUM_SINGLE(MAX98373_R2029_PCM_TO_SPK_MONO_MIX_1,
 431		MAX98373_PCM_TO_SPK_MONOMIX_CFG_SHIFT,
 432		3, max98373_switch_text);
 433
 434static const struct snd_kcontrol_new max98373_dai_controls =
 435	SOC_DAPM_ENUM("DAI Sel", dai_sel_enum);
 436
 437static const struct snd_kcontrol_new max98373_vi_control =
 438	SOC_DAPM_SINGLE("Switch", MAX98373_R202C_PCM_TX_EN, 0, 1, 0);
 439
 440static const struct snd_kcontrol_new max98373_spkfb_control =
 441	SOC_DAPM_SINGLE("Switch", MAX98373_R2043_AMP_EN, 1, 1, 0);
 442
 443static const struct snd_soc_dapm_widget max98373_dapm_widgets[] = {
 444SND_SOC_DAPM_DAC_E("Amp Enable", "HiFi Playback",
 445	MAX98373_R202B_PCM_RX_EN, 0, 0, max98373_dac_event,
 446	SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
 447SND_SOC_DAPM_MUX("DAI Sel Mux", SND_SOC_NOPM, 0, 0,
 448	&max98373_dai_controls),
 449SND_SOC_DAPM_OUTPUT("BE_OUT"),
 450SND_SOC_DAPM_AIF_OUT("Voltage Sense", "HiFi Capture", 0,
 451	MAX98373_R2047_IV_SENSE_ADC_EN, 0, 0),
 452SND_SOC_DAPM_AIF_OUT("Current Sense", "HiFi Capture", 0,
 453	MAX98373_R2047_IV_SENSE_ADC_EN, 1, 0),
 454SND_SOC_DAPM_AIF_OUT("Speaker FB Sense", "HiFi Capture", 0,
 455	SND_SOC_NOPM, 0, 0),
 456SND_SOC_DAPM_SWITCH("VI Sense", SND_SOC_NOPM, 0, 0,
 457	&max98373_vi_control),
 458SND_SOC_DAPM_SWITCH("SpkFB Sense", SND_SOC_NOPM, 0, 0,
 459	&max98373_spkfb_control),
 460SND_SOC_DAPM_SIGGEN("VMON"),
 461SND_SOC_DAPM_SIGGEN("IMON"),
 462SND_SOC_DAPM_SIGGEN("FBMON"),
 463};
 464
 465static DECLARE_TLV_DB_SCALE(max98373_digital_tlv, -6350, 50, 1);
 466static const DECLARE_TLV_DB_RANGE(max98373_spk_tlv,
 467	0, 8, TLV_DB_SCALE_ITEM(0, 50, 0),
 468	9, 10, TLV_DB_SCALE_ITEM(500, 100, 0),
 469);
 470static const DECLARE_TLV_DB_RANGE(max98373_spkgain_max_tlv,
 471	0, 9, TLV_DB_SCALE_ITEM(800, 100, 0),
 472);
 473static const DECLARE_TLV_DB_RANGE(max98373_dht_step_size_tlv,
 474	0, 1, TLV_DB_SCALE_ITEM(25, 25, 0),
 475	2, 4, TLV_DB_SCALE_ITEM(100, 100, 0),
 476);
 477static const DECLARE_TLV_DB_RANGE(max98373_dht_spkgain_min_tlv,
 478	0, 9, TLV_DB_SCALE_ITEM(800, 100, 0),
 479);
 480static const DECLARE_TLV_DB_RANGE(max98373_dht_rotation_point_tlv,
 481	0, 1, TLV_DB_SCALE_ITEM(-3000, 500, 0),
 482	2, 4, TLV_DB_SCALE_ITEM(-2200, 200, 0),
 483	5, 6, TLV_DB_SCALE_ITEM(-1500, 300, 0),
 484	7, 9, TLV_DB_SCALE_ITEM(-1000, 200, 0),
 485	10, 13, TLV_DB_SCALE_ITEM(-500, 100, 0),
 486	14, 15, TLV_DB_SCALE_ITEM(-100, 50, 0),
 487);
 488static const DECLARE_TLV_DB_RANGE(max98373_limiter_thresh_tlv,
 489	0, 15, TLV_DB_SCALE_ITEM(-1500, 100, 0),
 490);
 491
 492static const DECLARE_TLV_DB_RANGE(max98373_bde_gain_tlv,
 493	0, 60, TLV_DB_SCALE_ITEM(-1500, 25, 0),
 494);
 495
 496static bool max98373_readable_register(struct device *dev, unsigned int reg)
 497{
 498	switch (reg) {
 499	case MAX98373_R2000_SW_RESET:
 500	case MAX98373_R2001_INT_RAW1 ... MAX98373_R200C_INT_EN3:
 501	case MAX98373_R2010_IRQ_CTRL:
 502	case MAX98373_R2014_THERM_WARN_THRESH
 503		... MAX98373_R2018_THERM_FOLDBACK_EN:
 504	case MAX98373_R201E_PIN_DRIVE_STRENGTH
 505		... MAX98373_R2036_SOUNDWIRE_CTRL:
 506	case MAX98373_R203D_AMP_DIG_VOL_CTRL ... MAX98373_R2043_AMP_EN:
 507	case MAX98373_R2046_IV_SENSE_ADC_DSP_CFG
 508		... MAX98373_R2047_IV_SENSE_ADC_EN:
 509	case MAX98373_R2051_MEAS_ADC_SAMPLING_RATE
 510		... MAX98373_R2056_MEAS_ADC_PVDD_CH_EN:
 511	case MAX98373_R2090_BDE_LVL_HOLD ... MAX98373_R2092_BDE_CLIPPER_MODE:
 512	case MAX98373_R2097_BDE_L1_THRESH
 513		... MAX98373_R209B_BDE_THRESH_HYST:
 514	case MAX98373_R20A8_BDE_L1_CFG_1 ... MAX98373_R20B3_BDE_L4_CFG_3:
 515	case MAX98373_R20B5_BDE_EN ... MAX98373_R20B6_BDE_CUR_STATE_READBACK:
 516	case MAX98373_R20D1_DHT_CFG ... MAX98373_R20D4_DHT_EN:
 517	case MAX98373_R20E0_LIMITER_THRESH_CFG ... MAX98373_R20E2_LIMITER_EN:
 518	case MAX98373_R20FE_DEVICE_AUTO_RESTART_CFG
 519		... MAX98373_R20FF_GLOBAL_SHDN:
 520	case MAX98373_R21FF_REV_ID:
 521		return true;
 522	default:
 523		return false;
 524	}
 525};
 526
 527static bool max98373_volatile_reg(struct device *dev, unsigned int reg)
 528{
 529	switch (reg) {
 530	case MAX98373_R2000_SW_RESET ... MAX98373_R2009_INT_FLAG3:
 531	case MAX98373_R203E_AMP_PATH_GAIN:
 532	case MAX98373_R2054_MEAS_ADC_PVDD_CH_READBACK:
 533	case MAX98373_R2055_MEAS_ADC_THERM_CH_READBACK:
 534	case MAX98373_R20B6_BDE_CUR_STATE_READBACK:
 535	case MAX98373_R21FF_REV_ID:
 536		return true;
 537	default:
 538		return false;
 539	}
 540}
 541
 542static const char * const max98373_output_voltage_lvl_text[] = {
 543	"5.43V", "6.09V", "6.83V", "7.67V", "8.60V",
 544	"9.65V", "10.83V", "12.15V", "13.63V", "15.29V"
 545};
 546
 547static SOC_ENUM_SINGLE_DECL(max98373_out_volt_enum,
 548			    MAX98373_R203E_AMP_PATH_GAIN, 0,
 549			    max98373_output_voltage_lvl_text);
 550
 551static const char * const max98373_dht_attack_rate_text[] = {
 552	"17.5us", "35us", "70us", "140us",
 553	"280us", "560us", "1120us", "2240us"
 554};
 555
 556static SOC_ENUM_SINGLE_DECL(max98373_dht_attack_rate_enum,
 557			    MAX98373_R20D2_DHT_ATTACK_CFG, 0,
 558			    max98373_dht_attack_rate_text);
 559
 560static const char * const max98373_dht_release_rate_text[] = {
 561	"45ms", "225ms", "450ms", "1150ms",
 562	"2250ms", "3100ms", "4500ms", "6750ms"
 563};
 564
 565static SOC_ENUM_SINGLE_DECL(max98373_dht_release_rate_enum,
 566			    MAX98373_R20D3_DHT_RELEASE_CFG, 0,
 567			    max98373_dht_release_rate_text);
 568
 569static const char * const max98373_limiter_attack_rate_text[] = {
 570	"10us", "20us", "40us", "80us",
 571	"160us", "320us", "640us", "1.28ms",
 572	"2.56ms", "5.12ms", "10.24ms", "20.48ms",
 573	"40.96ms", "81.92ms", "16.384ms", "32.768ms"
 574};
 575
 576static SOC_ENUM_SINGLE_DECL(max98373_limiter_attack_rate_enum,
 577			    MAX98373_R20E1_LIMITER_ATK_REL_RATES, 4,
 578			    max98373_limiter_attack_rate_text);
 579
 580static const char * const max98373_limiter_release_rate_text[] = {
 581	"40us", "80us", "160us", "320us",
 582	"640us", "1.28ms", "2.56ms", "5.120ms",
 583	"10.24ms", "20.48ms", "40.96ms", "81.92ms",
 584	"163.84ms", "327.68ms", "655.36ms", "1310.72ms"
 585};
 586
 587static SOC_ENUM_SINGLE_DECL(max98373_limiter_release_rate_enum,
 588			    MAX98373_R20E1_LIMITER_ATK_REL_RATES, 0,
 589			    max98373_limiter_release_rate_text);
 590
 591static const char * const max98373_ADC_samplerate_text[] = {
 592	"333kHz", "192kHz", "64kHz", "48kHz"
 593};
 594
 595static SOC_ENUM_SINGLE_DECL(max98373_adc_samplerate_enum,
 596			    MAX98373_R2051_MEAS_ADC_SAMPLING_RATE, 0,
 597			    max98373_ADC_samplerate_text);
 598
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 599static const struct snd_kcontrol_new max98373_snd_controls[] = {
 600SOC_SINGLE("Digital Vol Sel Switch", MAX98373_R203F_AMP_DSP_CFG,
 601	MAX98373_AMP_VOL_SEL_SHIFT, 1, 0),
 602SOC_SINGLE("Volume Location Switch", MAX98373_R203F_AMP_DSP_CFG,
 603	MAX98373_AMP_VOL_SEL_SHIFT, 1, 0),
 604SOC_SINGLE("Ramp Up Switch", MAX98373_R203F_AMP_DSP_CFG,
 605	MAX98373_AMP_DSP_CFG_RMP_UP_SHIFT, 1, 0),
 606SOC_SINGLE("Ramp Down Switch", MAX98373_R203F_AMP_DSP_CFG,
 607	MAX98373_AMP_DSP_CFG_RMP_DN_SHIFT, 1, 0),
 
 
 
 
 
 
 
 
 
 608SOC_SINGLE("CLK Monitor Switch", MAX98373_R20FE_DEVICE_AUTO_RESTART_CFG,
 609	MAX98373_CLOCK_MON_SHIFT, 1, 0),
 610SOC_SINGLE("Dither Switch", MAX98373_R203F_AMP_DSP_CFG,
 611	MAX98373_AMP_DSP_CFG_DITH_SHIFT, 1, 0),
 612SOC_SINGLE("DC Blocker Switch", MAX98373_R203F_AMP_DSP_CFG,
 613	MAX98373_AMP_DSP_CFG_DCBLK_SHIFT, 1, 0),
 614SOC_SINGLE_TLV("Digital Volume", MAX98373_R203D_AMP_DIG_VOL_CTRL,
 615	0, 0x7F, 1, max98373_digital_tlv),
 616SOC_SINGLE_TLV("Speaker Volume", MAX98373_R203E_AMP_PATH_GAIN,
 617	MAX98373_SPK_DIGI_GAIN_SHIFT, 10, 0, max98373_spk_tlv),
 618SOC_SINGLE_TLV("FS Max Volume", MAX98373_R203E_AMP_PATH_GAIN,
 619	MAX98373_FS_GAIN_MAX_SHIFT, 9, 0, max98373_spkgain_max_tlv),
 620SOC_ENUM("Output Voltage", max98373_out_volt_enum),
 621/* Dynamic Headroom Tracking */
 622SOC_SINGLE("DHT Switch", MAX98373_R20D4_DHT_EN,
 623	MAX98373_DHT_EN_SHIFT, 1, 0),
 624SOC_SINGLE_TLV("DHT Min Volume", MAX98373_R20D1_DHT_CFG,
 625	MAX98373_DHT_SPK_GAIN_MIN_SHIFT, 9, 0, max98373_dht_spkgain_min_tlv),
 626SOC_SINGLE_TLV("DHT Rot Pnt Volume", MAX98373_R20D1_DHT_CFG,
 627	MAX98373_DHT_ROT_PNT_SHIFT, 15, 1, max98373_dht_rotation_point_tlv),
 628SOC_SINGLE_TLV("DHT Attack Step Volume", MAX98373_R20D2_DHT_ATTACK_CFG,
 629	MAX98373_DHT_ATTACK_STEP_SHIFT, 4, 0, max98373_dht_step_size_tlv),
 630SOC_SINGLE_TLV("DHT Release Step Volume", MAX98373_R20D3_DHT_RELEASE_CFG,
 631	MAX98373_DHT_RELEASE_STEP_SHIFT, 4, 0, max98373_dht_step_size_tlv),
 632SOC_ENUM("DHT Attack Rate", max98373_dht_attack_rate_enum),
 633SOC_ENUM("DHT Release Rate", max98373_dht_release_rate_enum),
 634/* ADC configuration */
 635SOC_SINGLE("ADC PVDD CH Switch", MAX98373_R2056_MEAS_ADC_PVDD_CH_EN, 0, 1, 0),
 636SOC_SINGLE("ADC PVDD FLT Switch", MAX98373_R2052_MEAS_ADC_PVDD_FLT_CFG,
 637	MAX98373_FLT_EN_SHIFT, 1, 0),
 638SOC_SINGLE("ADC TEMP FLT Switch", MAX98373_R2053_MEAS_ADC_THERM_FLT_CFG,
 639	MAX98373_FLT_EN_SHIFT, 1, 0),
 640SOC_SINGLE("ADC PVDD", MAX98373_R2054_MEAS_ADC_PVDD_CH_READBACK, 0, 0xFF, 0),
 641SOC_SINGLE("ADC TEMP", MAX98373_R2055_MEAS_ADC_THERM_CH_READBACK, 0, 0xFF, 0),
 
 
 642SOC_SINGLE("ADC PVDD FLT Coeff", MAX98373_R2052_MEAS_ADC_PVDD_FLT_CFG,
 643	0, 0x3, 0),
 644SOC_SINGLE("ADC TEMP FLT Coeff", MAX98373_R2053_MEAS_ADC_THERM_FLT_CFG,
 645	0, 0x3, 0),
 646SOC_ENUM("ADC SampleRate", max98373_adc_samplerate_enum),
 647/* Brownout Detection Engine */
 648SOC_SINGLE("BDE Switch", MAX98373_R20B5_BDE_EN, MAX98373_BDE_EN_SHIFT, 1, 0),
 649SOC_SINGLE("BDE LVL4 Mute Switch", MAX98373_R20B2_BDE_L4_CFG_2,
 650	MAX98373_LVL4_MUTE_EN_SHIFT, 1, 0),
 651SOC_SINGLE("BDE LVL4 Hold Switch", MAX98373_R20B2_BDE_L4_CFG_2,
 652	MAX98373_LVL4_HOLD_EN_SHIFT, 1, 0),
 653SOC_SINGLE("BDE LVL1 Thresh", MAX98373_R2097_BDE_L1_THRESH, 0, 0xFF, 0),
 654SOC_SINGLE("BDE LVL2 Thresh", MAX98373_R2098_BDE_L2_THRESH, 0, 0xFF, 0),
 655SOC_SINGLE("BDE LVL3 Thresh", MAX98373_R2099_BDE_L3_THRESH, 0, 0xFF, 0),
 656SOC_SINGLE("BDE LVL4 Thresh", MAX98373_R209A_BDE_L4_THRESH, 0, 0xFF, 0),
 657SOC_SINGLE("BDE Active Level", MAX98373_R20B6_BDE_CUR_STATE_READBACK, 0, 8, 0),
 
 658SOC_SINGLE("BDE Clip Mode Switch", MAX98373_R2092_BDE_CLIPPER_MODE, 0, 1, 0),
 659SOC_SINGLE("BDE Thresh Hysteresis", MAX98373_R209B_BDE_THRESH_HYST, 0, 0xFF, 0),
 660SOC_SINGLE("BDE Hold Time", MAX98373_R2090_BDE_LVL_HOLD, 0, 0xFF, 0),
 661SOC_SINGLE("BDE Attack Rate", MAX98373_R2091_BDE_GAIN_ATK_REL_RATE, 4, 0xF, 0),
 662SOC_SINGLE("BDE Release Rate", MAX98373_R2091_BDE_GAIN_ATK_REL_RATE, 0, 0xF, 0),
 663SOC_SINGLE_TLV("BDE LVL1 Clip Thresh Volume", MAX98373_R20A9_BDE_L1_CFG_2,
 664	0, 0x3C, 1, max98373_bde_gain_tlv),
 665SOC_SINGLE_TLV("BDE LVL2 Clip Thresh Volume", MAX98373_R20AC_BDE_L2_CFG_2,
 666	0, 0x3C, 1, max98373_bde_gain_tlv),
 667SOC_SINGLE_TLV("BDE LVL3 Clip Thresh Volume", MAX98373_R20AF_BDE_L3_CFG_2,
 668	0, 0x3C, 1, max98373_bde_gain_tlv),
 669SOC_SINGLE_TLV("BDE LVL4 Clip Thresh Volume", MAX98373_R20B2_BDE_L4_CFG_2,
 670	0, 0x3C, 1, max98373_bde_gain_tlv),
 671SOC_SINGLE_TLV("BDE LVL1 Clip Reduction Volume", MAX98373_R20AA_BDE_L1_CFG_3,
 672	0, 0x3C, 1, max98373_bde_gain_tlv),
 673SOC_SINGLE_TLV("BDE LVL2 Clip Reduction Volume", MAX98373_R20AD_BDE_L2_CFG_3,
 674	0, 0x3C, 1, max98373_bde_gain_tlv),
 675SOC_SINGLE_TLV("BDE LVL3 Clip Reduction Volume", MAX98373_R20B0_BDE_L3_CFG_3,
 676	0, 0x3C, 1, max98373_bde_gain_tlv),
 677SOC_SINGLE_TLV("BDE LVL4 Clip Reduction Volume", MAX98373_R20B3_BDE_L4_CFG_3,
 678	0, 0x3C, 1, max98373_bde_gain_tlv),
 679SOC_SINGLE_TLV("BDE LVL1 Limiter Thresh Volume", MAX98373_R20A8_BDE_L1_CFG_1,
 680	0, 0xF, 1, max98373_limiter_thresh_tlv),
 681SOC_SINGLE_TLV("BDE LVL2 Limiter Thresh Volume", MAX98373_R20AB_BDE_L2_CFG_1,
 682	0, 0xF, 1, max98373_limiter_thresh_tlv),
 683SOC_SINGLE_TLV("BDE LVL3 Limiter Thresh Volume", MAX98373_R20AE_BDE_L3_CFG_1,
 684	0, 0xF, 1, max98373_limiter_thresh_tlv),
 685SOC_SINGLE_TLV("BDE LVL4 Limiter Thresh Volume", MAX98373_R20B1_BDE_L4_CFG_1,
 686	0, 0xF, 1, max98373_limiter_thresh_tlv),
 687/* Limiter */
 688SOC_SINGLE("Limiter Switch", MAX98373_R20E2_LIMITER_EN,
 689	MAX98373_LIMITER_EN_SHIFT, 1, 0),
 690SOC_SINGLE("Limiter Src Switch", MAX98373_R20E0_LIMITER_THRESH_CFG,
 691	MAX98373_LIMITER_THRESH_SRC_SHIFT, 1, 0),
 692SOC_SINGLE_TLV("Limiter Thresh Volume", MAX98373_R20E0_LIMITER_THRESH_CFG,
 693	MAX98373_LIMITER_THRESH_SHIFT, 15, 0, max98373_limiter_thresh_tlv),
 694SOC_ENUM("Limiter Attack Rate", max98373_limiter_attack_rate_enum),
 695SOC_ENUM("Limiter Release Rate", max98373_limiter_release_rate_enum),
 696};
 697
 698static const struct snd_soc_dapm_route max98373_audio_map[] = {
 699	/* Plabyack */
 700	{"DAI Sel Mux", "Left", "Amp Enable"},
 701	{"DAI Sel Mux", "Right", "Amp Enable"},
 702	{"DAI Sel Mux", "LeftRight", "Amp Enable"},
 703	{"BE_OUT", NULL, "DAI Sel Mux"},
 704	/* Capture */
 705	{ "VI Sense", "Switch", "VMON" },
 706	{ "VI Sense", "Switch", "IMON" },
 707	{ "SpkFB Sense", "Switch", "FBMON" },
 708	{ "Voltage Sense", NULL, "VI Sense" },
 709	{ "Current Sense", NULL, "VI Sense" },
 710	{ "Speaker FB Sense", NULL, "SpkFB Sense" },
 711};
 712
 713static struct snd_soc_dai_driver max98373_dai[] = {
 714	{
 715		.name = "max98373-aif1",
 716		.playback = {
 717			.stream_name = "HiFi Playback",
 718			.channels_min = 1,
 719			.channels_max = 2,
 720			.rates = MAX98373_RATES,
 721			.formats = MAX98373_FORMATS,
 722		},
 723		.capture = {
 724			.stream_name = "HiFi Capture",
 725			.channels_min = 1,
 726			.channels_max = 2,
 727			.rates = MAX98373_RATES,
 728			.formats = MAX98373_FORMATS,
 729		},
 730		.ops = &max98373_dai_ops,
 731	}
 732};
 733
 734static void max98373_reset(struct max98373_priv *max98373, struct device *dev)
 735{
 736	int ret, reg, count;
 737
 738	/* Software Reset */
 739	ret = regmap_update_bits(max98373->regmap,
 740		MAX98373_R2000_SW_RESET,
 741		MAX98373_SOFT_RESET,
 742		MAX98373_SOFT_RESET);
 743	if (ret)
 744		dev_err(dev, "Reset command failed. (ret:%d)\n", ret);
 745
 746	count = 0;
 747	while (count < 3) {
 748		usleep_range(10000, 11000);
 749		/* Software Reset Verification */
 750		ret = regmap_read(max98373->regmap,
 751			MAX98373_R21FF_REV_ID, &reg);
 752		if (!ret) {
 753			dev_info(dev, "Reset completed (retry:%d)\n", count);
 754			return;
 755		}
 756		count++;
 757	}
 758	dev_err(dev, "Reset failed. (ret:%d)\n", ret);
 759}
 
 760
 761static int max98373_probe(struct snd_soc_component *component)
 762{
 763	struct max98373_priv *max98373 = snd_soc_component_get_drvdata(component);
 764
 765	/* Software Reset */
 766	max98373_reset(max98373, component->dev);
 767
 768	/* IV default slot configuration */
 769	regmap_write(max98373->regmap,
 770		MAX98373_R2020_PCM_TX_HIZ_EN_1,
 771		0xFF);
 772	regmap_write(max98373->regmap,
 773		MAX98373_R2021_PCM_TX_HIZ_EN_2,
 774		0xFF);
 775	/* L/R mix configuration */
 776	regmap_write(max98373->regmap,
 777		MAX98373_R2029_PCM_TO_SPK_MONO_MIX_1,
 778		0x80);
 779	regmap_write(max98373->regmap,
 780		MAX98373_R202A_PCM_TO_SPK_MONO_MIX_2,
 781		0x1);
 782	/* Set inital volume (0dB) */
 783	regmap_write(max98373->regmap,
 784		MAX98373_R203D_AMP_DIG_VOL_CTRL,
 785		0x00);
 786	regmap_write(max98373->regmap,
 787		MAX98373_R203E_AMP_PATH_GAIN,
 788		0x00);
 789	/* Enable DC blocker */
 790	regmap_write(max98373->regmap,
 791		MAX98373_R203F_AMP_DSP_CFG,
 792		0x3);
 793	/* Enable IMON VMON DC blocker */
 794	regmap_write(max98373->regmap,
 795		MAX98373_R2046_IV_SENSE_ADC_DSP_CFG,
 796		0x7);
 797	/* voltage, current slot configuration */
 798	regmap_write(max98373->regmap,
 799		MAX98373_R2022_PCM_TX_SRC_1,
 800		(max98373->i_slot << MAX98373_PCM_TX_CH_SRC_A_I_SHIFT |
 801		max98373->v_slot) & 0xFF);
 802	if (max98373->v_slot < 8)
 803		regmap_update_bits(max98373->regmap,
 804			MAX98373_R2020_PCM_TX_HIZ_EN_1,
 805			1 << max98373->v_slot, 0);
 806	else
 807		regmap_update_bits(max98373->regmap,
 808			MAX98373_R2021_PCM_TX_HIZ_EN_2,
 809			1 << (max98373->v_slot - 8), 0);
 810
 811	if (max98373->i_slot < 8)
 812		regmap_update_bits(max98373->regmap,
 813			MAX98373_R2020_PCM_TX_HIZ_EN_1,
 814			1 << max98373->i_slot, 0);
 815	else
 816		regmap_update_bits(max98373->regmap,
 817			MAX98373_R2021_PCM_TX_HIZ_EN_2,
 818			1 << (max98373->i_slot - 8), 0);
 819
 
 
 
 
 
 820	/* speaker feedback slot configuration */
 821	regmap_write(max98373->regmap,
 822		MAX98373_R2023_PCM_TX_SRC_2,
 823		max98373->spkfb_slot & 0xFF);
 824
 825	/* Set interleave mode */
 826	if (max98373->interleave_mode)
 827		regmap_update_bits(max98373->regmap,
 828			MAX98373_R2024_PCM_DATA_FMT_CFG,
 829			MAX98373_PCM_TX_CH_INTERLEAVE_MASK,
 830			MAX98373_PCM_TX_CH_INTERLEAVE_MASK);
 831
 832	/* Speaker enable */
 833	regmap_update_bits(max98373->regmap,
 834		MAX98373_R2043_AMP_EN,
 835		MAX98373_SPK_EN_MASK, 1);
 836
 837	return 0;
 838}
 839
 840#ifdef CONFIG_PM_SLEEP
 841static int max98373_suspend(struct device *dev)
 
 
 
 
 
 
 
 
 
 
 
 
 842{
 843	struct max98373_priv *max98373 = dev_get_drvdata(dev);
 844
 845	regcache_cache_only(max98373->regmap, true);
 846	regcache_mark_dirty(max98373->regmap);
 847	return 0;
 848}
 849static int max98373_resume(struct device *dev)
 850{
 851	struct max98373_priv *max98373 = dev_get_drvdata(dev);
 852
 853	max98373_reset(max98373, dev);
 854	regcache_cache_only(max98373->regmap, false);
 855	regcache_sync(max98373->regmap);
 856	return 0;
 857}
 858#endif
 859
 860static const struct dev_pm_ops max98373_pm = {
 861	SET_SYSTEM_SLEEP_PM_OPS(max98373_suspend, max98373_resume)
 862};
 863
 864static const struct snd_soc_component_driver soc_codec_dev_max98373 = {
 865	.probe			= max98373_probe,
 866	.controls		= max98373_snd_controls,
 867	.num_controls		= ARRAY_SIZE(max98373_snd_controls),
 868	.dapm_widgets		= max98373_dapm_widgets,
 869	.num_dapm_widgets	= ARRAY_SIZE(max98373_dapm_widgets),
 870	.dapm_routes		= max98373_audio_map,
 871	.num_dapm_routes	= ARRAY_SIZE(max98373_audio_map),
 872	.idle_bias_on		= 1,
 873	.use_pmdown_time	= 1,
 874	.endianness		= 1,
 875	.non_legacy_dai_naming	= 1,
 876};
 877
 878static const struct regmap_config max98373_regmap = {
 879	.reg_bits = 16,
 880	.val_bits = 8,
 881	.max_register = MAX98373_R21FF_REV_ID,
 882	.reg_defaults  = max98373_reg,
 883	.num_reg_defaults = ARRAY_SIZE(max98373_reg),
 884	.readable_reg = max98373_readable_register,
 885	.volatile_reg = max98373_volatile_reg,
 886	.cache_type = REGCACHE_RBTREE,
 887};
 
 888
 889static void max98373_slot_config(struct i2c_client *i2c,
 890	struct max98373_priv *max98373)
 891{
 892	int value;
 893	struct device *dev = &i2c->dev;
 894
 895	if (!device_property_read_u32(dev, "maxim,vmon-slot-no", &value))
 896		max98373->v_slot = value & 0xF;
 897	else
 898		max98373->v_slot = 0;
 899
 900	if (!device_property_read_u32(dev, "maxim,imon-slot-no", &value))
 901		max98373->i_slot = value & 0xF;
 902	else
 903		max98373->i_slot = 1;
 904	if (dev->of_node) {
 905		max98373->reset_gpio = of_get_named_gpio(dev->of_node,
 906						"maxim,reset-gpio", 0);
 907		if (!gpio_is_valid(max98373->reset_gpio)) {
 908			dev_err(dev, "Looking up %s property in node %s failed %d\n",
 909				"maxim,reset-gpio", dev->of_node->full_name,
 910				max98373->reset_gpio);
 911		} else {
 912			dev_dbg(dev, "maxim,reset-gpio=%d",
 913				max98373->reset_gpio);
 914		}
 915	} else {
 916		/* this makes reset_gpio as invalid */
 917		max98373->reset_gpio = -1;
 918	}
 919
 920	if (!device_property_read_u32(dev, "maxim,spkfb-slot-no", &value))
 921		max98373->spkfb_slot = value & 0xF;
 922	else
 923		max98373->spkfb_slot = 2;
 924}
 925
 926static int max98373_i2c_probe(struct i2c_client *i2c,
 927	const struct i2c_device_id *id)
 928{
 929
 930	int ret = 0;
 931	int reg = 0;
 932	struct max98373_priv *max98373 = NULL;
 933
 934	max98373 = devm_kzalloc(&i2c->dev, sizeof(*max98373), GFP_KERNEL);
 935
 936	if (!max98373) {
 937		ret = -ENOMEM;
 938		return ret;
 939	}
 940	i2c_set_clientdata(i2c, max98373);
 941
 942	/* update interleave mode info */
 943	if (device_property_read_bool(&i2c->dev, "maxim,interleave_mode"))
 944		max98373->interleave_mode = true;
 945	else
 946		max98373->interleave_mode = false;
 947
 948	/* regmap initialization */
 949	max98373->regmap
 950		= devm_regmap_init_i2c(i2c, &max98373_regmap);
 951	if (IS_ERR(max98373->regmap)) {
 952		ret = PTR_ERR(max98373->regmap);
 953		dev_err(&i2c->dev,
 954			"Failed to allocate regmap: %d\n", ret);
 955		return ret;
 956	}
 957
 958	/* voltage/current slot & gpio configuration */
 959	max98373_slot_config(i2c, max98373);
 960
 961	/* Power on device */
 962	if (gpio_is_valid(max98373->reset_gpio)) {
 963		ret = devm_gpio_request(&i2c->dev, max98373->reset_gpio,
 964					"MAX98373_RESET");
 965		if (ret) {
 966			dev_err(&i2c->dev, "%s: Failed to request gpio %d\n",
 967				__func__, max98373->reset_gpio);
 968			return -EINVAL;
 969		}
 970		gpio_direction_output(max98373->reset_gpio, 0);
 971		msleep(50);
 972		gpio_direction_output(max98373->reset_gpio, 1);
 973		msleep(20);
 974	}
 975
 976	/* Check Revision ID */
 977	ret = regmap_read(max98373->regmap,
 978		MAX98373_R21FF_REV_ID, &reg);
 979	if (ret < 0) {
 980		dev_err(&i2c->dev,
 981			"Failed to read: 0x%02X\n", MAX98373_R21FF_REV_ID);
 982		return ret;
 983	}
 984	dev_info(&i2c->dev, "MAX98373 revisionID: 0x%02X\n", reg);
 985
 986	/* codec registeration */
 987	ret = devm_snd_soc_register_component(&i2c->dev, &soc_codec_dev_max98373,
 988		max98373_dai, ARRAY_SIZE(max98373_dai));
 989	if (ret < 0)
 990		dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
 991
 992	return ret;
 993}
 994
 995static const struct i2c_device_id max98373_i2c_id[] = {
 996	{ "max98373", 0},
 997	{ },
 998};
 999
1000MODULE_DEVICE_TABLE(i2c, max98373_i2c_id);
1001
1002#if defined(CONFIG_OF)
1003static const struct of_device_id max98373_of_match[] = {
1004	{ .compatible = "maxim,max98373", },
1005	{ }
1006};
1007MODULE_DEVICE_TABLE(of, max98373_of_match);
1008#endif
1009
1010#ifdef CONFIG_ACPI
1011static const struct acpi_device_id max98373_acpi_match[] = {
1012	{ "MX98373", 0 },
1013	{},
1014};
1015MODULE_DEVICE_TABLE(acpi, max98373_acpi_match);
1016#endif
1017
1018static struct i2c_driver max98373_i2c_driver = {
1019	.driver = {
1020		.name = "max98373",
1021		.of_match_table = of_match_ptr(max98373_of_match),
1022		.acpi_match_table = ACPI_PTR(max98373_acpi_match),
1023		.pm = &max98373_pm,
1024	},
1025	.probe = max98373_i2c_probe,
1026	.id_table = max98373_i2c_id,
1027};
1028
1029module_i2c_driver(max98373_i2c_driver)
1030
1031MODULE_DESCRIPTION("ALSA SoC MAX98373 driver");
1032MODULE_AUTHOR("Ryan Lee <ryans.lee@maximintegrated.com>");
1033MODULE_LICENSE("GPL");