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