~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/soc/codecs/max98388.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 // Copyright (c) 2022, Analog Devices Inc.
  3 
  4 #include <linux/acpi.h>
  5 #include <linux/delay.h>
  6 #include <linux/gpio/consumer.h>
  7 #include <linux/i2c.h>
  8 #include <linux/module.h>
  9 #include <linux/mod_devicetable.h>
 10 #include <linux/of.h>
 11 #include <linux/pm_runtime.h>
 12 #include <linux/regmap.h>
 13 #include <linux/slab.h>
 14 #include <linux/cdev.h>
 15 #include <sound/pcm.h>
 16 #include <sound/pcm_params.h>
 17 #include <sound/soc.h>
 18 #include <sound/tlv.h>
 19 #include "max98388.h"
 20 
 21 static struct reg_default max98388_reg[] = {
 22         {MAX98388_R2000_SW_RESET, 0x00},
 23         {MAX98388_R2001_INT_RAW1, 0x00},
 24         {MAX98388_R2002_INT_RAW2, 0x00},
 25         {MAX98388_R2004_INT_STATE1, 0x00},
 26         {MAX98388_R2005_INT_STATE2, 0x00},
 27         {MAX98388_R2020_THERM_WARN_THRESH, 0x0A},
 28         {MAX98388_R2031_SPK_MON_THRESH, 0x58},
 29         {MAX98388_R2032_SPK_MON_LD_SEL, 0x08},
 30         {MAX98388_R2033_SPK_MON_DURATION, 0x02},
 31         {MAX98388_R2037_ERR_MON_CTRL, 0x01},
 32         {MAX98388_R2040_PCM_MODE_CFG, 0xC0},
 33         {MAX98388_R2041_PCM_CLK_SETUP, 0x04},
 34         {MAX98388_R2042_PCM_SR_SETUP, 0x88},
 35         {MAX98388_R2044_PCM_TX_CTRL1, 0x00},
 36         {MAX98388_R2045_PCM_TX_CTRL2, 0x00},
 37         {MAX98388_R2050_PCM_TX_HIZ_CTRL1, 0xFF},
 38         {MAX98388_R2051_PCM_TX_HIZ_CTRL2, 0xFF},
 39         {MAX98388_R2052_PCM_TX_HIZ_CTRL3, 0xFF},
 40         {MAX98388_R2053_PCM_TX_HIZ_CTRL4, 0xFF},
 41         {MAX98388_R2054_PCM_TX_HIZ_CTRL5, 0xFF},
 42         {MAX98388_R2055_PCM_TX_HIZ_CTRL6, 0xFF},
 43         {MAX98388_R2056_PCM_TX_HIZ_CTRL7, 0xFF},
 44         {MAX98388_R2057_PCM_TX_HIZ_CTRL8, 0xFF},
 45         {MAX98388_R2058_PCM_RX_SRC1, 0x00},
 46         {MAX98388_R2059_PCM_RX_SRC2, 0x01},
 47         {MAX98388_R205C_PCM_TX_DRIVE_STRENGTH, 0x00},
 48         {MAX98388_R205D_PCM_TX_SRC_EN, 0x00},
 49         {MAX98388_R205E_PCM_RX_EN, 0x00},
 50         {MAX98388_R205F_PCM_TX_EN, 0x00},
 51         {MAX98388_R2090_SPK_CH_VOL_CTRL, 0x00},
 52         {MAX98388_R2091_SPK_CH_CFG, 0x02},
 53         {MAX98388_R2092_SPK_AMP_OUT_CFG, 0x03},
 54         {MAX98388_R2093_SPK_AMP_SSM_CFG, 0x01},
 55         {MAX98388_R2094_SPK_AMP_ER_CTRL, 0x00},
 56         {MAX98388_R209E_SPK_CH_PINK_NOISE_EN, 0x00},
 57         {MAX98388_R209F_SPK_CH_AMP_EN, 0x00},
 58         {MAX98388_R20A0_IV_DATA_DSP_CTRL, 0x10},
 59         {MAX98388_R20A7_IV_DATA_EN, 0x00},
 60         {MAX98388_R20E0_BP_ALC_THRESH, 0x04},
 61         {MAX98388_R20E1_BP_ALC_RATES, 0x20},
 62         {MAX98388_R20E2_BP_ALC_ATTEN, 0x06},
 63         {MAX98388_R20E3_BP_ALC_REL, 0x02},
 64         {MAX98388_R20E4_BP_ALC_MUTE, 0x33},
 65         {MAX98388_R20EE_BP_INF_HOLD_REL, 0x00},
 66         {MAX98388_R20EF_BP_ALC_EN, 0x00},
 67         {MAX98388_R210E_AUTO_RESTART, 0x00},
 68         {MAX98388_R210F_GLOBAL_EN, 0x00},
 69         {MAX98388_R22FF_REV_ID, 0x00},
 70 };
 71 
 72 static int max98388_dac_event(struct snd_soc_dapm_widget *w,
 73                               struct snd_kcontrol *kcontrol, int event)
 74 {
 75         struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 76         struct max98388_priv *max98388 = snd_soc_component_get_drvdata(component);
 77 
 78         switch (event) {
 79         case SND_SOC_DAPM_POST_PMU:
 80                 regmap_write(max98388->regmap,
 81                              MAX98388_R210F_GLOBAL_EN, 1);
 82                 usleep_range(30000, 31000);
 83                 break;
 84         case SND_SOC_DAPM_PRE_PMD:
 85                 regmap_write(max98388->regmap,
 86                              MAX98388_R210F_GLOBAL_EN, 0);
 87                 usleep_range(30000, 31000);
 88                 max98388->tdm_mode = false;
 89                 break;
 90         default:
 91                 return 0;
 92         }
 93         return 0;
 94 }
 95 
 96 static const char * const max98388_monomix_switch_text[] = {
 97         "Left", "Right", "LeftRight"};
 98 
 99 static const struct soc_enum dai_sel_enum =
100         SOC_ENUM_SINGLE(MAX98388_R2058_PCM_RX_SRC1,
101                         MAX98388_PCM_TO_SPK_MONOMIX_CFG_SHIFT,
102                         3, max98388_monomix_switch_text);
103 
104 static const struct snd_kcontrol_new max98388_dai_controls =
105         SOC_DAPM_ENUM("DAI Sel", dai_sel_enum);
106 
107 static const struct snd_kcontrol_new max98388_vi_control =
108         SOC_DAPM_SINGLE("Switch", MAX98388_R205F_PCM_TX_EN, 0, 1, 0);
109 
110 static const struct snd_soc_dapm_widget max98388_dapm_widgets[] = {
111         SND_SOC_DAPM_DAC_E("Amp Enable", "HiFi Playback",
112                            MAX98388_R205E_PCM_RX_EN, 0, 0, max98388_dac_event,
113                            SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
114         SND_SOC_DAPM_MUX("DAI Sel Mux", SND_SOC_NOPM, 0, 0,
115                          &max98388_dai_controls),
116         SND_SOC_DAPM_OUTPUT("BE_OUT"),
117         SND_SOC_DAPM_AIF_OUT("Voltage Sense", "HiFi Capture", 0,
118                              MAX98388_R20A7_IV_DATA_EN, 0, 0),
119         SND_SOC_DAPM_AIF_OUT("Current Sense", "HiFi Capture", 0,
120                              MAX98388_R20A7_IV_DATA_EN, 1, 0),
121         SND_SOC_DAPM_ADC("ADC Voltage", NULL,
122                          MAX98388_R205D_PCM_TX_SRC_EN, 0, 0),
123         SND_SOC_DAPM_ADC("ADC Current", NULL,
124                          MAX98388_R205D_PCM_TX_SRC_EN, 1, 0),
125         SND_SOC_DAPM_SWITCH("VI Sense", SND_SOC_NOPM, 0, 0,
126                             &max98388_vi_control),
127         SND_SOC_DAPM_SIGGEN("VMON"),
128         SND_SOC_DAPM_SIGGEN("IMON"),
129 };
130 
131 static DECLARE_TLV_DB_SCALE(max98388_digital_tlv, -6350, 50, 1);
132 static DECLARE_TLV_DB_SCALE(max98388_amp_gain_tlv, -300, 300, 0);
133 
134 static const char * const max98388_alc_max_atten_text[] = {
135         "0dBFS", "-1dBFS", "-2dBFS", "-3dBFS", "-4dBFS", "-5dBFS",
136         "-6dBFS", "-7dBFS", "-8dBFS", "-9dBFS", "-10dBFS", "-11dBFS",
137         "-12dBFS", "-13dBFS", "-14dBFS", "-15dBFS"
138 };
139 
140 static SOC_ENUM_SINGLE_DECL(max98388_alc_max_atten_enum,
141                             MAX98388_R20E2_BP_ALC_ATTEN,
142                             MAX98388_ALC_MAX_ATTEN_SHIFT,
143                             max98388_alc_max_atten_text);
144 
145 static const char * const max98388_thermal_warn_text[] = {
146         "95C", "105C", "115C", "125C"
147 };
148 
149 static SOC_ENUM_SINGLE_DECL(max98388_thermal_warning_thresh_enum,
150                             MAX98388_R2020_THERM_WARN_THRESH,
151                             MAX98388_THERM_WARN_THRESH_SHIFT,
152                             max98388_thermal_warn_text);
153 
154 static const char * const max98388_thermal_shutdown_text[] = {
155         "135C", "145C", "155C", "165C"
156 };
157 
158 static SOC_ENUM_SINGLE_DECL(max98388_thermal_shutdown_thresh_enum,
159                             MAX98388_R2020_THERM_WARN_THRESH,
160                             MAX98388_THERM_SHDN_THRESH_SHIFT,
161                             max98388_thermal_shutdown_text);
162 
163 static const char * const max98388_alc_thresh_single_text[] = {
164         "3.625V", "3.550V", "3.475V", "3.400V", "3.325V", "3.250V",
165         "3.175V", "3.100V", "3.025V", "2.950V", "2.875V", "2.800V",
166         "2.725V", "2.650V", "2.575V", "2.500V"
167 };
168 
169 static SOC_ENUM_SINGLE_DECL(max98388_alc_thresh_single_enum,
170                             MAX98388_R20E0_BP_ALC_THRESH,
171                             MAX98388_ALC_THRESH_SHIFT,
172                             max98388_alc_thresh_single_text);
173 
174 static const char * const max98388_alc_attack_rate_text[] = {
175         "", "10us", "20us", "40us", "80us", "160us",
176         "320us", "640us", "1.28ms", "2.56ms", "5.12ms", "10.24ms",
177         "20.48ms", "40.96ms", "81.92ms", "163.84ms"
178 };
179 
180 static SOC_ENUM_SINGLE_DECL(max98388_alc_attack_rate_enum,
181                             MAX98388_R20E1_BP_ALC_RATES,
182                             MAX98388_ALC_ATTACK_RATE_SHIFT,
183                             max98388_alc_attack_rate_text);
184 
185 static const char * const max98388_alc_release_rate_text[] = {
186         "20us", "40us", "80us", "160us", "320us", "640us",
187         "1.28ms", "2.56ms", "5.12ms", "10.24ms", "20.48ms", "40.96ms",
188         "81.92ms", "163.84ms", "327.68ms", "655.36ms"
189 };
190 
191 static SOC_ENUM_SINGLE_DECL(max98388_alc_release_rate_enum,
192                             MAX98388_R20E1_BP_ALC_RATES,
193                             MAX98388_ALC_RELEASE_RATE_SHIFT,
194                             max98388_alc_release_rate_text);
195 
196 static const char * const max98388_alc_debounce_text[] = {
197         "0.01ms", "0.1ms", "1ms", "10ms", "100ms", "250ms", "500ms", "hold"
198 };
199 
200 static SOC_ENUM_SINGLE_DECL(max98388_alc_debouce_enum,
201                             MAX98388_R20E3_BP_ALC_REL,
202                             MAX98388_ALC_DEBOUNCE_TIME_SHIFT,
203                             max98388_alc_debounce_text);
204 
205 static const char * const max98388_alc_mute_delay_text[] = {
206         "0.01ms", "0.05ms", "0.1ms", "0.5ms", "1ms", "5ms", "25ms", "250ms"
207 };
208 
209 static SOC_ENUM_SINGLE_DECL(max98388_alc_mute_delay_enum,
210                             MAX98388_R20E4_BP_ALC_MUTE,
211                             MAX98388_ALC_MUTE_DELAY_SHIFT,
212                             max98388_alc_mute_delay_text);
213 
214 static const char * const max98388_spkmon_duration_text[] = {
215         "10ms", "25ms", "50ms", "75ms", "100ms", "200ms", "300ms", "400ms",
216         "500ms", "600ms", "700ms", "800ms", "900ms", "1000ms", "1100ms", "1200ms"
217 };
218 
219 static SOC_ENUM_SINGLE_DECL(max98388_spkmon_duration_enum,
220                             MAX98388_R2033_SPK_MON_DURATION,
221                             MAX98388_SPKMON_DURATION_SHIFT,
222                             max98388_spkmon_duration_text);
223 
224 static const char * const max98388_spkmon_thresh_text[] = {
225         "0.03V", "0.06V", "0.09V", "0.12V", "0.15V", "0.18V", "0.20V", "0.23V",
226         "0.26V", "0.29V", "0.32V", "0.35V", "0.38V", "0.41V", "0.44V", "0.47V",
227         "0.50V", "0.53V", "0.56V", "0.58V", "0.61V", "0.64V", "0.67V", "0.70V",
228         "0.73V", "0.76V", "0.79V", "0.82V", "0.85V", "0.88V", "0.91V", "0.94V",
229         "0.96V", "0.99V", "1.02V", "1.05V", "1.08V", "1.11V", "1.14V", "1.17V",
230         "1.20V", "1.23V", "1.26V", "1.29V", "1.32V", "1.35V", "1.37V", "1.40V",
231         "1.43V", "1.46V", "1.49V", "1.52V", "1.55V", "1.58V", "1.61V", "1.64V",
232         "1.67V", "1.70V", "1.73V", "1.75V", "1.78V", "1.81V", "1.84V", "1.87V",
233         "1.90V", "1.93V", "1.96V", "1.99V", "2.02V", "2.05V", "2.08V", "2.11V",
234         "2.13V", "2.16V", "2.19V", "2.22V", "2.25V", "2.28V", "2.31V", "2.34V",
235         "2.37V", "2.40V", "2.43V", "2.46V", "2.49V", "2.51V", "2.54V", "2.57V",
236         "2.60V", "2.63V", "2.66V", "2.69V", "2.72V", "2.75V", "2.78V", "2.81V",
237         "2.84V", "2.87V", "2.89V", "2.92V", "2.95V", "2.98V", "3.01V", "3.04V",
238         "3.07V", "3.10V", "3.13V", "3.16V", "3.19V", "3.22V", "3.25V", "3.27V",
239         "3.30V", "3.33V", "3.36V", "3.39V", "3.42V", "3.45V", "3.48V", "3.51V",
240         "3.54V", "3.57V", "3.60V", "3.63V", "3.66V", "3.68V", "3.71V", "3.74V"
241 };
242 
243 static SOC_ENUM_SINGLE_DECL(max98388_spkmon_thresh_enum,
244                             MAX98388_R2031_SPK_MON_THRESH,
245                             MAX98388_SPKMON_THRESH_SHIFT,
246                             max98388_spkmon_thresh_text);
247 
248 static const char * const max98388_spkmon_load_text[] = {
249         "2.00ohm", "2.25ohm", "2.50ohm", "2.75ohm", "3.00ohm", "3.25ohm",
250         "3.50ohm", "3.75ohm", "4.00ohm", "4.25ohm", "4.50ohm", "4.75ohm",
251         "5.00ohm", "5.25ohm", "5.50ohm", "5.75ohm", "6.00ohm", "6.25ohm",
252         "6.50ohm", "6.75ohm", "7.00ohm", "7.25ohm", "7.50ohm", "7.75ohm",
253         "8.00ohm", "8.25ohm", "8.50ohm", "8.75ohm", "9.00ohm", "9.25ohm",
254         "9.50ohm", "9.75ohm", "10.00ohm", "10.25ohm", "10.50ohm", "10.75ohm",
255         "11.00ohm", "11.25ohm", "11.50ohm", "11.75ohm", "12.00ohm", "12.25ohm",
256         "12.50ohm", "12.75ohm", "13.00ohm", "13.25ohm", "13.50ohm", "13.75ohm",
257         "14.00ohm", "14.25ohm", "14.50ohm", "14.75ohm", "15.00ohm", "15.25ohm",
258         "15.50ohm", "15.75ohm", "16.00ohm", "16.25ohm", "16.50ohm", "16.75ohm",
259         "17.00ohm", "17.25ohm", "17.50ohm", "17.75ohm", "18.00ohm", "18.25ohm",
260         "18.50ohm", "18.75ohm", "19.00ohm", "19.25ohm", "19.50ohm", "19.75ohm",
261         "20.00ohm", "20.25ohm", "20.50ohm", "20.75ohm", "21.00ohm", "21.25ohm",
262         "21.50ohm", "21.75ohm", "22.00ohm", "22.25ohm", "22.50ohm", "22.75ohm",
263         "23.00ohm", "23.25ohm", "23.50ohm", "23.75ohm", "24.00ohm", "24.25ohm",
264         "24.50ohm", "24.75ohm", "25.00ohm", "25.25ohm", "25.50ohm", "25.75ohm",
265         "26.00ohm", "26.25ohm", "26.50ohm", "26.75ohm", "27.00ohm", "27.25ohm",
266         "27.50ohm", "27.75ohm", "28.00ohm", "28.25ohm", "28.50ohm", "28.75ohm",
267         "29.00ohm", "29.25ohm", "29.50ohm", "29.75ohm", "30.00ohm", "30.25ohm",
268         "30.50ohm", "30.75ohm", "31.00ohm", "31.25ohm", "31.50ohm", "31.75ohm",
269         "32.00ohm", "32.25ohm", "32.50ohm", "32.75ohm", "33.00ohm", "33.25ohm",
270         "33.50ohm", "33.75ohm"
271 };
272 
273 static SOC_ENUM_SINGLE_DECL(max98388_spkmon_load_enum,
274                             MAX98388_R2032_SPK_MON_LD_SEL,
275                             MAX98388_SPKMON_LOAD_SHIFT,
276                             max98388_spkmon_load_text);
277 
278 static const char * const max98388_edge_rate_text[] = {
279         "Normal", "Reduced", "Maximum", "Increased",
280 };
281 
282 static SOC_ENUM_SINGLE_DECL(max98388_edge_rate_falling_enum,
283                             MAX98388_R2094_SPK_AMP_ER_CTRL,
284                             MAX98388_EDGE_RATE_FALL_SHIFT,
285                             max98388_edge_rate_text);
286 
287 static SOC_ENUM_SINGLE_DECL(max98388_edge_rate_rising_enum,
288                             MAX98388_R2094_SPK_AMP_ER_CTRL,
289                             MAX98388_EDGE_RATE_RISE_SHIFT,
290                             max98388_edge_rate_text);
291 
292 static const char * const max98388_ssm_mod_text[] = {
293         "1.5%", "3.0%", "4.5%", "6.0%",
294 };
295 
296 static SOC_ENUM_SINGLE_DECL(max98388_ssm_mod_enum,
297                             MAX98388_R2093_SPK_AMP_SSM_CFG,
298                             MAX98388_SPK_AMP_SSM_MOD_SHIFT,
299                             max98388_ssm_mod_text);
300 
301 static const struct snd_kcontrol_new max98388_snd_controls[] = {
302         SOC_SINGLE("Ramp Up Switch", MAX98388_R2091_SPK_CH_CFG,
303                    MAX98388_SPK_CFG_VOL_RMPUP_SHIFT, 1, 0),
304         SOC_SINGLE("Ramp Down Switch", MAX98388_R2091_SPK_CH_CFG,
305                    MAX98388_SPK_CFG_VOL_RMPDN_SHIFT, 1, 0),
306         /* Two Cell Mode Enable */
307         SOC_SINGLE("OP Mode Switch", MAX98388_R2092_SPK_AMP_OUT_CFG,
308                    MAX98388_SPK_AMP_OUT_MODE_SHIFT, 1, 0),
309         /* Speaker Amplifier Overcurrent Automatic Restart Enable */
310         SOC_SINGLE("OVC Autorestart Switch", MAX98388_R210E_AUTO_RESTART,
311                    MAX98388_OVC_AUTORESTART_SHIFT, 1, 0),
312         /* Thermal Shutdown Automatic Restart Enable */
313         SOC_SINGLE("THERM Autorestart Switch", MAX98388_R210E_AUTO_RESTART,
314                    MAX98388_THERM_AUTORESTART_SHIFT, 1, 0),
315         /* PVDD UVLO Auto Restart */
316         SOC_SINGLE("UVLO Autorestart Switch", MAX98388_R210E_AUTO_RESTART,
317                    MAX98388_PVDD_UVLO_AUTORESTART_SHIFT, 1, 0),
318         /* Clock Monitor Automatic Restart Enable */
319         SOC_SINGLE("CMON Autorestart Switch", MAX98388_R210E_AUTO_RESTART,
320                    MAX98388_CMON_AUTORESTART_SHIFT, 1, 0),
321         SOC_SINGLE("CLK Monitor Switch", MAX98388_R2037_ERR_MON_CTRL,
322                    MAX98388_CLOCK_MON_SHIFT, 1, 0),
323         /* Pinknoise Generator Enable */
324         SOC_SINGLE("Pinknoise Gen Switch", MAX98388_R209E_SPK_CH_PINK_NOISE_EN,
325                    MAX98388_PINK_NOISE_GEN_SHIFT, 1, 0),
326         /* Dither Enable */
327         SOC_SINGLE("Dither Switch", MAX98388_R2091_SPK_CH_CFG,
328                    MAX98388_SPK_CFG_DITH_EN_SHIFT, 1, 0),
329         SOC_SINGLE("VI Dither Switch", MAX98388_R20A0_IV_DATA_DSP_CTRL,
330                    MAX98388_AMP_DSP_CTRL_DITH_SHIFT, 1, 0),
331         /* DC Blocker Enable */
332         SOC_SINGLE("DC Blocker Switch", MAX98388_R2091_SPK_CH_CFG,
333                    MAX98388_SPK_CFG_DCBLK_SHIFT, 1, 0),
334         SOC_SINGLE("Voltage DC Blocker Switch", MAX98388_R20A0_IV_DATA_DSP_CTRL,
335                    MAX98388_AMP_DSP_CTRL_VOL_DCBLK_SHIFT, 1, 0),
336         SOC_SINGLE("Current DC Blocker Switch", MAX98388_R20A0_IV_DATA_DSP_CTRL,
337                    MAX98388_AMP_DSP_CTRL_CUR_DCBLK_SHIFT, 1, 0),
338         /* Digital Volume */
339         SOC_SINGLE_TLV("Digital Volume", MAX98388_R2090_SPK_CH_VOL_CTRL,
340                        0, 0x7F, 1, max98388_digital_tlv),
341         /* Speaker Volume */
342         SOC_SINGLE_TLV("Speaker Volume", MAX98388_R2092_SPK_AMP_OUT_CFG,
343                        0, 5, 0, max98388_amp_gain_tlv),
344         SOC_ENUM("Thermal Warn Thresh", max98388_thermal_warning_thresh_enum),
345         SOC_ENUM("Thermal SHDN Thresh", max98388_thermal_shutdown_thresh_enum),
346         /* Brownout Protection Automatic Level Control */
347         SOC_SINGLE("ALC Switch", MAX98388_R20EF_BP_ALC_EN, 0, 1, 0),
348         SOC_ENUM("ALC Thresh", max98388_alc_thresh_single_enum),
349         SOC_ENUM("ALC Attack Rate", max98388_alc_attack_rate_enum),
350         SOC_ENUM("ALC Release Rate", max98388_alc_release_rate_enum),
351         SOC_ENUM("ALC Max Atten", max98388_alc_max_atten_enum),
352         SOC_ENUM("ALC Debounce Time", max98388_alc_debouce_enum),
353         SOC_SINGLE("ALC Unmute Ramp Switch", MAX98388_R20E4_BP_ALC_MUTE,
354                    MAX98388_ALC_UNMUTE_RAMP_EN_SHIFT, 1, 0),
355         SOC_SINGLE("ALC Mute Ramp Switch", MAX98388_R20E4_BP_ALC_MUTE,
356                    MAX98388_ALC_MUTE_RAMP_EN_SHIFT, 1, 0),
357         SOC_SINGLE("ALC Mute Switch", MAX98388_R20E4_BP_ALC_MUTE,
358                    MAX98388_ALC_MUTE_EN_SHIFT, 1, 0),
359         SOC_ENUM("ALC Mute Delay", max98388_alc_mute_delay_enum),
360         /* Speaker Monitor */
361         SOC_SINGLE("SPKMON Switch", MAX98388_R2037_ERR_MON_CTRL,
362                    MAX98388_SPK_MON_SHIFT, 1, 0),
363         SOC_ENUM("SPKMON Thresh", max98388_spkmon_thresh_enum),
364         SOC_ENUM("SPKMON Load", max98388_spkmon_load_enum),
365         SOC_ENUM("SPKMON Duration", max98388_spkmon_duration_enum),
366         /* General Parameters */
367         SOC_ENUM("Fall Slew Rate", max98388_edge_rate_falling_enum),
368         SOC_ENUM("Rise Slew Rate", max98388_edge_rate_rising_enum),
369         SOC_SINGLE("AMP SSM Switch", MAX98388_R2093_SPK_AMP_SSM_CFG,
370                    MAX98388_SPK_AMP_SSM_EN_SHIFT, 1, 0),
371         SOC_ENUM("AMP SSM Mod", max98388_ssm_mod_enum),
372 };
373 
374 static const struct snd_soc_dapm_route max98388_audio_map[] = {
375         /* Plabyack */
376         {"DAI Sel Mux", "Left", "Amp Enable"},
377         {"DAI Sel Mux", "Right", "Amp Enable"},
378         {"DAI Sel Mux", "LeftRight", "Amp Enable"},
379         {"BE_OUT", NULL, "DAI Sel Mux"},
380         /* Capture */
381         { "ADC Voltage", NULL, "VMON"},
382         { "ADC Current", NULL, "IMON"},
383         { "VI Sense", "Switch", "ADC Voltage"},
384         { "VI Sense", "Switch", "ADC Current"},
385         { "Voltage Sense", NULL, "VI Sense"},
386         { "Current Sense", NULL, "VI Sense"},
387 };
388 
389 static void max98388_reset(struct max98388_priv *max98388, struct device *dev)
390 {
391         int ret, reg, count;
392 
393         /* Software Reset */
394         ret = regmap_update_bits(max98388->regmap,
395                                  MAX98388_R2000_SW_RESET,
396                                  MAX98388_SOFT_RESET,
397                                  MAX98388_SOFT_RESET);
398         if (ret)
399                 dev_err(dev, "Reset command failed. (ret:%d)\n", ret);
400 
401         count = 0;
402         while (count < 3) {
403                 usleep_range(10000, 11000);
404                 /* Software Reset Verification */
405                 ret = regmap_read(max98388->regmap,
406                                   MAX98388_R22FF_REV_ID, &reg);
407                 if (!ret) {
408                         dev_info(dev, "Reset completed (retry:%d)\n", count);
409                         return;
410                 }
411                 count++;
412         }
413         dev_err(dev, "Reset failed. (ret:%d)\n", ret);
414 }
415 
416 static int max98388_probe(struct snd_soc_component *component)
417 {
418         struct max98388_priv *max98388 = snd_soc_component_get_drvdata(component);
419 
420         /* Software Reset */
421         max98388_reset(max98388, component->dev);
422 
423         /* General channel source configuration */
424         regmap_write(max98388->regmap,
425                      MAX98388_R2059_PCM_RX_SRC2,
426                      0x10);
427 
428         /* Enable DC blocker */
429         regmap_write(max98388->regmap,
430                      MAX98388_R2091_SPK_CH_CFG,
431                      0x1);
432         /* Enable IMON VMON DC blocker */
433         regmap_write(max98388->regmap,
434                      MAX98388_R20A0_IV_DATA_DSP_CTRL,
435                      0x3);
436         /* TX slot configuration */
437         regmap_write(max98388->regmap,
438                      MAX98388_R2044_PCM_TX_CTRL1,
439                      max98388->v_slot);
440 
441         regmap_write(max98388->regmap,
442                      MAX98388_R2045_PCM_TX_CTRL2,
443                      max98388->i_slot);
444         /* Enable Auto-restart behavior by default */
445         regmap_write(max98388->regmap,
446                      MAX98388_R210E_AUTO_RESTART, 0xF);
447         /* Set interleave mode */
448         if (max98388->interleave_mode)
449                 regmap_update_bits(max98388->regmap,
450                                    MAX98388_R2040_PCM_MODE_CFG,
451                                    MAX98388_PCM_TX_CH_INTERLEAVE_MASK,
452                                    MAX98388_PCM_TX_CH_INTERLEAVE_MASK);
453 
454         /* Speaker Amplifier Channel Enable */
455         regmap_update_bits(max98388->regmap,
456                            MAX98388_R209F_SPK_CH_AMP_EN,
457                            MAX98388_SPK_EN_MASK, 1);
458 
459         return 0;
460 }
461 
462 static int max98388_dai_set_fmt(struct snd_soc_dai *codec_dai,
463                                 unsigned int fmt)
464 {
465         struct snd_soc_component *component = codec_dai->component;
466         struct max98388_priv *max98388 = snd_soc_component_get_drvdata(component);
467         unsigned int format = 0;
468         unsigned int invert = 0;
469 
470         dev_dbg(component->dev, "%s: fmt 0x%08X\n", __func__, fmt);
471 
472         switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
473         case SND_SOC_DAIFMT_NB_NF:
474                 break;
475         case SND_SOC_DAIFMT_IB_NF:
476                 invert = MAX98388_PCM_MODE_CFG_PCM_BCLKEDGE;
477                 break;
478         default:
479                 dev_err(component->dev, "DAI invert mode unsupported\n");
480                 return -EINVAL;
481         }
482 
483         regmap_update_bits(max98388->regmap,
484                            MAX98388_R2041_PCM_CLK_SETUP,
485                            MAX98388_PCM_MODE_CFG_PCM_BCLKEDGE,
486                            invert);
487 
488         /* interface format */
489         switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
490         case SND_SOC_DAIFMT_I2S:
491                 format = MAX98388_PCM_FORMAT_I2S;
492                 break;
493         case SND_SOC_DAIFMT_LEFT_J:
494                 format = MAX98388_PCM_FORMAT_LJ;
495                 break;
496         case SND_SOC_DAIFMT_DSP_A:
497                 format = MAX98388_PCM_FORMAT_TDM_MODE1;
498                 break;
499         case SND_SOC_DAIFMT_DSP_B:
500                 format = MAX98388_PCM_FORMAT_TDM_MODE0;
501                 break;
502         default:
503                 return -EINVAL;
504         }
505 
506         regmap_update_bits(max98388->regmap,
507                            MAX98388_R2040_PCM_MODE_CFG,
508                            MAX98388_PCM_MODE_CFG_FORMAT_MASK,
509                            format << MAX98388_PCM_MODE_CFG_FORMAT_SHIFT);
510 
511         return 0;
512 }
513 
514 /* BCLKs per LRCLK */
515 static const int bclk_sel_table[] = {
516         32, 48, 64, 96, 128, 192, 256, 384, 512, 320,
517 };
518 
519 static int max98388_get_bclk_sel(int bclk)
520 {
521         int i;
522         /* match BCLKs per LRCLK */
523         for (i = 0; i < ARRAY_SIZE(bclk_sel_table); i++) {
524                 if (bclk_sel_table[i] == bclk)
525                         return i + 2;
526         }
527         return 0;
528 }
529 
530 static int max98388_set_clock(struct snd_soc_component *component,
531                               struct snd_pcm_hw_params *params)
532 {
533         struct max98388_priv *max98388 = snd_soc_component_get_drvdata(component);
534         /* BCLK/LRCLK ratio calculation */
535         int blr_clk_ratio = params_channels(params) * max98388->ch_size;
536         int value;
537 
538         if (!max98388->tdm_mode) {
539                 /* BCLK configuration */
540                 value = max98388_get_bclk_sel(blr_clk_ratio);
541                 if (!value) {
542                         dev_err(component->dev, "format unsupported %d\n",
543                                 params_format(params));
544                         return -EINVAL;
545                 }
546 
547                 regmap_update_bits(max98388->regmap,
548                                    MAX98388_R2041_PCM_CLK_SETUP,
549                                    MAX98388_PCM_CLK_SETUP_BSEL_MASK,
550                                    value);
551         }
552         return 0;
553 }
554 
555 static int max98388_dai_hw_params(struct snd_pcm_substream *substream,
556                                   struct snd_pcm_hw_params *params,
557                                   struct snd_soc_dai *dai)
558 {
559         struct snd_soc_component *component = dai->component;
560         struct max98388_priv *max98388 = snd_soc_component_get_drvdata(component);
561         unsigned int sampling_rate = 0;
562         unsigned int chan_sz = 0;
563         int ret, reg;
564         int status = 0;
565 
566         /* pcm mode configuration */
567         switch (snd_pcm_format_width(params_format(params))) {
568         case 16:
569                 chan_sz = MAX98388_PCM_MODE_CFG_CHANSZ_16;
570                 break;
571         case 24:
572                 chan_sz = MAX98388_PCM_MODE_CFG_CHANSZ_24;
573                 break;
574         case 32:
575                 chan_sz = MAX98388_PCM_MODE_CFG_CHANSZ_32;
576                 break;
577         default:
578                 dev_err(component->dev, "format unsupported %d\n",
579                         params_format(params));
580                 goto err;
581         }
582 
583         max98388->ch_size = snd_pcm_format_width(params_format(params));
584 
585         ret = regmap_read(max98388->regmap,
586                           MAX98388_R2040_PCM_MODE_CFG, &reg);
587         if (ret < 0)
588                 goto err;
589 
590         /* GLOBAL_EN OFF prior to the channel size re-configure */
591         if (chan_sz != (reg & MAX98388_PCM_MODE_CFG_CHANSZ_MASK))       {
592                 ret = regmap_read(max98388->regmap,
593                                   MAX98388_R210F_GLOBAL_EN, &status);
594                 if (ret < 0)
595                         goto err;
596 
597                 if (status) {
598                         regmap_write(max98388->regmap,
599                                      MAX98388_R210F_GLOBAL_EN, 0);
600                         usleep_range(30000, 31000);
601                 }
602                 regmap_update_bits(max98388->regmap,
603                                    MAX98388_R2040_PCM_MODE_CFG,
604                                    MAX98388_PCM_MODE_CFG_CHANSZ_MASK, chan_sz);
605         }
606         dev_dbg(component->dev, "format supported %d",
607                 params_format(params));
608 
609         /* sampling rate configuration */
610         switch (params_rate(params)) {
611         case 8000:
612                 sampling_rate = MAX98388_PCM_SR_8000;
613                 break;
614         case 11025:
615                 sampling_rate = MAX98388_PCM_SR_11025;
616                 break;
617         case 12000:
618                 sampling_rate = MAX98388_PCM_SR_12000;
619                 break;
620         case 16000:
621                 sampling_rate = MAX98388_PCM_SR_16000;
622                 break;
623         case 22050:
624                 sampling_rate = MAX98388_PCM_SR_22050;
625                 break;
626         case 24000:
627                 sampling_rate = MAX98388_PCM_SR_24000;
628                 break;
629         case 32000:
630                 sampling_rate = MAX98388_PCM_SR_32000;
631                 break;
632         case 44100:
633                 sampling_rate = MAX98388_PCM_SR_44100;
634                 break;
635         case 48000:
636                 sampling_rate = MAX98388_PCM_SR_48000;
637                 break;
638         case 88200:
639                 sampling_rate = MAX98388_PCM_SR_88200;
640                 break;
641         case 96000:
642                 sampling_rate = MAX98388_PCM_SR_96000;
643                 break;
644         default:
645                 dev_err(component->dev, "rate %d not supported\n",
646                         params_rate(params));
647                 goto err;
648         }
649 
650         /* set DAI_SR to correct LRCLK frequency */
651         regmap_update_bits(max98388->regmap,
652                            MAX98388_R2042_PCM_SR_SETUP,
653                            MAX98388_PCM_SR_MASK,
654                            sampling_rate);
655 
656         /* set sampling rate of IV */
657         if (max98388->interleave_mode &&
658             sampling_rate > MAX98388_PCM_SR_16000)
659                 regmap_update_bits(max98388->regmap,
660                                    MAX98388_R2042_PCM_SR_SETUP,
661                                    MAX98388_PCM_SR_IV_MASK,
662                                    (sampling_rate - 3) << MAX98388_PCM_SR_IV_SHIFT);
663         else
664                 regmap_update_bits(max98388->regmap,
665                                    MAX98388_R2042_PCM_SR_SETUP,
666                                    MAX98388_PCM_SR_IV_MASK,
667                                    sampling_rate << MAX98388_PCM_SR_IV_SHIFT);
668 
669         ret = max98388_set_clock(component, params);
670 
671         if (status) {
672                 regmap_write(max98388->regmap,
673                              MAX98388_R210F_GLOBAL_EN, 1);
674                 usleep_range(30000, 31000);
675         }
676 
677         return ret;
678 
679 err:
680         return -EINVAL;
681 }
682 
683 #define MAX_NUM_SLOTS 16
684 #define MAX_NUM_CH 2
685 
686 static int max98388_dai_tdm_slot(struct snd_soc_dai *dai,
687                                  unsigned int tx_mask, unsigned int rx_mask,
688                                  int slots, int slot_width)
689 {
690         struct snd_soc_component *component = dai->component;
691         struct max98388_priv *max98388 = snd_soc_component_get_drvdata(component);
692         int bsel = 0;
693         unsigned int chan_sz = 0;
694         unsigned int mask;
695         int cnt, slot_found;
696         int addr, bits;
697 
698         if (!tx_mask && !rx_mask && !slots && !slot_width)
699                 max98388->tdm_mode = false;
700         else
701                 max98388->tdm_mode = true;
702 
703         /* BCLK configuration */
704         bsel = max98388_get_bclk_sel(slots * slot_width);
705         if (bsel == 0) {
706                 dev_err(component->dev, "BCLK %d not supported\n",
707                         slots * slot_width);
708                 return -EINVAL;
709         }
710 
711         regmap_update_bits(max98388->regmap,
712                            MAX98388_R2041_PCM_CLK_SETUP,
713                            MAX98388_PCM_CLK_SETUP_BSEL_MASK,
714                            bsel);
715 
716         /* Channel size configuration */
717         switch (slot_width) {
718         case 16:
719                 chan_sz = MAX98388_PCM_MODE_CFG_CHANSZ_16;
720                 break;
721         case 24:
722                 chan_sz = MAX98388_PCM_MODE_CFG_CHANSZ_24;
723                 break;
724         case 32:
725                 chan_sz = MAX98388_PCM_MODE_CFG_CHANSZ_32;
726                 break;
727         default:
728                 dev_err(component->dev, "format unsupported %d\n",
729                         slot_width);
730                 return -EINVAL;
731         }
732 
733         regmap_update_bits(max98388->regmap,
734                            MAX98388_R2040_PCM_MODE_CFG,
735                            MAX98388_PCM_MODE_CFG_CHANSZ_MASK, chan_sz);
736 
737         /* Rx slot configuration */
738         slot_found = 0;
739         mask = rx_mask;
740         for (cnt = 0 ; cnt < MAX_NUM_SLOTS ; cnt++, mask >>= 1) {
741                 if (mask & 0x1) {
742                         if (slot_found == 0)
743                                 regmap_update_bits(max98388->regmap,
744                                                    MAX98388_R2059_PCM_RX_SRC2,
745                                                    MAX98388_RX_SRC_CH0_SHIFT,
746                                                    cnt);
747                         else
748                                 regmap_update_bits(max98388->regmap,
749                                                    MAX98388_R2059_PCM_RX_SRC2,
750                                                    MAX98388_RX_SRC_CH1_SHIFT,
751                                                    cnt);
752                         slot_found++;
753                         if (slot_found >= MAX_NUM_CH)
754                                 break;
755                 }
756         }
757 
758         /* speaker feedback slot configuration */
759         slot_found = 0;
760         mask = tx_mask;
761         for (cnt = 0 ; cnt < MAX_NUM_SLOTS ; cnt++, mask >>= 1) {
762                 if (mask & 0x1) {
763                         addr = MAX98388_R2044_PCM_TX_CTRL1 + (cnt / 8);
764                         bits = cnt % 8;
765                         regmap_update_bits(max98388->regmap, addr, bits, bits);
766                         if (slot_found >= MAX_NUM_CH)
767                                 break;
768                 }
769         }
770 
771         return 0;
772 }
773 
774 #define MAX98388_RATES SNDRV_PCM_RATE_8000_96000
775 
776 #define MAX98388_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
777         SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
778 
779 static const struct snd_soc_dai_ops max98388_dai_ops = {
780         .set_fmt = max98388_dai_set_fmt,
781         .hw_params = max98388_dai_hw_params,
782         .set_tdm_slot = max98388_dai_tdm_slot,
783 };
784 
785 static bool max98388_readable_register(struct device *dev,
786                                        unsigned int reg)
787 {
788         switch (reg) {
789         case MAX98388_R2001_INT_RAW1 ... MAX98388_R2002_INT_RAW2:
790         case MAX98388_R2004_INT_STATE1... MAX98388_R2005_INT_STATE2:
791         case MAX98388_R2020_THERM_WARN_THRESH:
792         case MAX98388_R2031_SPK_MON_THRESH
793                 ... MAX98388_R2033_SPK_MON_DURATION:
794         case MAX98388_R2037_ERR_MON_CTRL:
795         case MAX98388_R2040_PCM_MODE_CFG
796                 ... MAX98388_R2042_PCM_SR_SETUP:
797         case MAX98388_R2044_PCM_TX_CTRL1
798                 ... MAX98388_R2045_PCM_TX_CTRL2:
799         case MAX98388_R2050_PCM_TX_HIZ_CTRL1
800                 ... MAX98388_R2059_PCM_RX_SRC2:
801         case MAX98388_R205C_PCM_TX_DRIVE_STRENGTH
802                 ... MAX98388_R205F_PCM_TX_EN:
803         case MAX98388_R2090_SPK_CH_VOL_CTRL
804                 ... MAX98388_R2094_SPK_AMP_ER_CTRL:
805         case MAX98388_R209E_SPK_CH_PINK_NOISE_EN
806                 ... MAX98388_R209F_SPK_CH_AMP_EN:
807         case MAX98388_R20A0_IV_DATA_DSP_CTRL:
808         case MAX98388_R20A7_IV_DATA_EN:
809         case MAX98388_R20E0_BP_ALC_THRESH ... MAX98388_R20E4_BP_ALC_MUTE:
810         case MAX98388_R20EE_BP_INF_HOLD_REL ... MAX98388_R20EF_BP_ALC_EN:
811         case MAX98388_R210E_AUTO_RESTART:
812         case MAX98388_R210F_GLOBAL_EN:
813         case MAX98388_R22FF_REV_ID:
814                 return true;
815         default:
816                 return false;
817         }
818 };
819 
820 static bool max98388_volatile_reg(struct device *dev, unsigned int reg)
821 {
822         switch (reg) {
823         case MAX98388_R2001_INT_RAW1 ... MAX98388_R2005_INT_STATE2:
824         case MAX98388_R210F_GLOBAL_EN:
825         case MAX98388_R22FF_REV_ID:
826                 return true;
827         default:
828                 return false;
829         }
830 }
831 
832 static struct snd_soc_dai_driver max98388_dai[] = {
833         {
834                 .name = "max98388-aif1",
835                 .playback = {
836                         .stream_name = "HiFi Playback",
837                         .channels_min = 1,
838                         .channels_max = 2,
839                         .rates = MAX98388_RATES,
840                         .formats = MAX98388_FORMATS,
841                 },
842                 .capture = {
843                         .stream_name = "HiFi Capture",
844                         .channels_min = 1,
845                         .channels_max = 2,
846                         .rates = MAX98388_RATES,
847                         .formats = MAX98388_FORMATS,
848                 },
849                 .ops = &max98388_dai_ops,
850         }
851 };
852 
853 static int max98388_suspend(struct device *dev)
854 {
855         struct max98388_priv *max98388 = dev_get_drvdata(dev);
856 
857         regcache_cache_only(max98388->regmap, true);
858         regcache_mark_dirty(max98388->regmap);
859 
860         return 0;
861 }
862 
863 static int max98388_resume(struct device *dev)
864 {
865         struct max98388_priv *max98388 = dev_get_drvdata(dev);
866 
867         regcache_cache_only(max98388->regmap, false);
868         max98388_reset(max98388, dev);
869         regcache_sync(max98388->regmap);
870 
871         return 0;
872 }
873 
874 static const struct dev_pm_ops max98388_pm = {
875         SYSTEM_SLEEP_PM_OPS(max98388_suspend, max98388_resume)
876 };
877 
878 static const struct regmap_config max98388_regmap = {
879         .reg_bits = 16,
880         .val_bits = 8,
881         .max_register = MAX98388_R22FF_REV_ID,
882         .reg_defaults  = max98388_reg,
883         .num_reg_defaults = ARRAY_SIZE(max98388_reg),
884         .readable_reg = max98388_readable_register,
885         .volatile_reg = max98388_volatile_reg,
886         .cache_type = REGCACHE_RBTREE,
887 };
888 
889 static const struct snd_soc_component_driver soc_codec_dev_max98388 = {
890         .probe                  = max98388_probe,
891         .controls               = max98388_snd_controls,
892         .num_controls           = ARRAY_SIZE(max98388_snd_controls),
893         .dapm_widgets           = max98388_dapm_widgets,
894         .num_dapm_widgets       = ARRAY_SIZE(max98388_dapm_widgets),
895         .dapm_routes            = max98388_audio_map,
896         .num_dapm_routes        = ARRAY_SIZE(max98388_audio_map),
897         .use_pmdown_time        = 1,
898         .endianness             = 1,
899 };
900 
901 static void max98388_read_deveice_property(struct device *dev,
902                                            struct max98388_priv *max98388)
903 {
904         int value;
905 
906         if (!device_property_read_u32(dev, "adi,vmon-slot-no", &value))
907                 max98388->v_slot = value & 0xF;
908         else
909                 max98388->v_slot = 0;
910 
911         if (!device_property_read_u32(dev, "adi,imon-slot-no", &value))
912                 max98388->i_slot = value & 0xF;
913         else
914                 max98388->i_slot = 1;
915 
916         if (device_property_read_bool(dev, "adi,interleave-mode"))
917                 max98388->interleave_mode = true;
918         else
919                 max98388->interleave_mode = false;
920 }
921 
922 static int max98388_i2c_probe(struct i2c_client *i2c)
923 {
924         int ret = 0;
925         int reg = 0;
926 
927         struct max98388_priv *max98388 = NULL;
928 
929         max98388 = devm_kzalloc(&i2c->dev, sizeof(*max98388), GFP_KERNEL);
930         if (!max98388)
931                 return -ENOMEM;
932 
933         i2c_set_clientdata(i2c, max98388);
934 
935         /* regmap initialization */
936         max98388->regmap = devm_regmap_init_i2c(i2c, &max98388_regmap);
937         if (IS_ERR(max98388->regmap))
938                 return dev_err_probe(&i2c->dev, PTR_ERR(max98388->regmap),
939                                      "Failed to allocate register map.\n");
940 
941         /* voltage/current slot & gpio configuration */
942         max98388_read_deveice_property(&i2c->dev, max98388);
943 
944         /* Device Reset */
945         max98388->reset_gpio = devm_gpiod_get_optional(&i2c->dev,
946                                                        "reset", GPIOD_OUT_HIGH);
947         if (IS_ERR(max98388->reset_gpio))
948                 return dev_err_probe(&i2c->dev, PTR_ERR(max98388->reset_gpio),
949                                      "Unable to request GPIO\n");
950 
951         if (max98388->reset_gpio) {
952                 usleep_range(5000, 6000);
953                 gpiod_set_value_cansleep(max98388->reset_gpio, 0);
954                 /* Wait for the hw reset done */
955                 usleep_range(5000, 6000);
956         }
957 
958         /* Read Revision ID */
959         ret = regmap_read(max98388->regmap,
960                           MAX98388_R22FF_REV_ID, &reg);
961         if (ret < 0)
962                 return dev_err_probe(&i2c->dev, ret,
963                                      "Failed to read the revision ID\n");
964 
965         dev_info(&i2c->dev, "MAX98388 revisionID: 0x%02X\n", reg);
966 
967         /* codec registration */
968         ret = devm_snd_soc_register_component(&i2c->dev,
969                                               &soc_codec_dev_max98388,
970                                               max98388_dai,
971                                               ARRAY_SIZE(max98388_dai));
972         if (ret < 0)
973                 dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
974 
975         return ret;
976 }
977 
978 static const struct i2c_device_id max98388_i2c_id[] = {
979         { "max98388"},
980         { },
981 };
982 
983 MODULE_DEVICE_TABLE(i2c, max98388_i2c_id);
984 
985 static const struct of_device_id max98388_of_match[] = {
986         { .compatible = "adi,max98388", },
987         { }
988 };
989 MODULE_DEVICE_TABLE(of, max98388_of_match);
990 
991 static const struct acpi_device_id max98388_acpi_match[] = {
992         { "ADS8388", 0 },
993         {},
994 };
995 MODULE_DEVICE_TABLE(acpi, max98388_acpi_match);
996 
997 static struct i2c_driver max98388_i2c_driver = {
998         .driver = {
999                 .name = "max98388",
1000                 .of_match_table = max98388_of_match,
1001                 .acpi_match_table = max98388_acpi_match,
1002                 .pm = pm_sleep_ptr(&max98388_pm),
1003         },
1004         .probe = max98388_i2c_probe,
1005         .id_table = max98388_i2c_id,
1006 };
1007 
1008 module_i2c_driver(max98388_i2c_driver)
1009 
1010 MODULE_DESCRIPTION("ALSA SoC MAX98388 driver");
1011 MODULE_AUTHOR("Ryan Lee <ryans.lee@analog.com>");
1012 MODULE_LICENSE("GPL");
1013 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php