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

TOMOYO Linux Cross Reference
Linux/sound/soc/codecs/max98390.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-or-later
  2 /*
  3  * max98390.c  --  MAX98390 ALSA Soc Audio driver
  4  *
  5  * Copyright (C) 2020 Maxim Integrated Products
  6  *
  7  */
  8 
  9 #include <linux/acpi.h>
 10 #include <linux/cdev.h>
 11 #include <linux/dmi.h>
 12 #include <linux/firmware.h>
 13 #include <linux/gpio/consumer.h>
 14 #include <linux/i2c.h>
 15 #include <linux/module.h>
 16 #include <linux/regmap.h>
 17 #include <linux/slab.h>
 18 #include <linux/time.h>
 19 #include <sound/pcm.h>
 20 #include <sound/pcm_params.h>
 21 #include <sound/soc.h>
 22 #include <sound/tlv.h>
 23 
 24 #include "max98390.h"
 25 
 26 static struct reg_default max98390_reg_defaults[] = {
 27         {MAX98390_INT_EN1, 0xf0},
 28         {MAX98390_INT_EN2, 0x00},
 29         {MAX98390_INT_EN3, 0x00},
 30         {MAX98390_INT_FLAG_CLR1, 0x00},
 31         {MAX98390_INT_FLAG_CLR2, 0x00},
 32         {MAX98390_INT_FLAG_CLR3, 0x00},
 33         {MAX98390_IRQ_CTRL, 0x01},
 34         {MAX98390_CLK_MON, 0x6d},
 35         {MAX98390_DAT_MON, 0x03},
 36         {MAX98390_WDOG_CTRL, 0x00},
 37         {MAX98390_WDOG_RST, 0x00},
 38         {MAX98390_MEAS_ADC_THERM_WARN_THRESH, 0x75},
 39         {MAX98390_MEAS_ADC_THERM_SHDN_THRESH, 0x8c},
 40         {MAX98390_MEAS_ADC_THERM_HYSTERESIS, 0x08},
 41         {MAX98390_PIN_CFG, 0x55},
 42         {MAX98390_PCM_RX_EN_A, 0x00},
 43         {MAX98390_PCM_RX_EN_B, 0x00},
 44         {MAX98390_PCM_TX_EN_A, 0x00},
 45         {MAX98390_PCM_TX_EN_B, 0x00},
 46         {MAX98390_PCM_TX_HIZ_CTRL_A, 0xff},
 47         {MAX98390_PCM_TX_HIZ_CTRL_B, 0xff},
 48         {MAX98390_PCM_CH_SRC_1, 0x00},
 49         {MAX98390_PCM_CH_SRC_2, 0x00},
 50         {MAX98390_PCM_CH_SRC_3, 0x00},
 51         {MAX98390_PCM_MODE_CFG, 0xc0},
 52         {MAX98390_PCM_MASTER_MODE, 0x1c},
 53         {MAX98390_PCM_CLK_SETUP, 0x44},
 54         {MAX98390_PCM_SR_SETUP, 0x08},
 55         {MAX98390_ICC_RX_EN_A, 0x00},
 56         {MAX98390_ICC_RX_EN_B, 0x00},
 57         {MAX98390_ICC_TX_EN_A, 0x00},
 58         {MAX98390_ICC_TX_EN_B, 0x00},
 59         {MAX98390_ICC_HIZ_MANUAL_MODE, 0x00},
 60         {MAX98390_ICC_TX_HIZ_EN_A, 0x00},
 61         {MAX98390_ICC_TX_HIZ_EN_B, 0x00},
 62         {MAX98390_ICC_LNK_EN, 0x00},
 63         {MAX98390_R2039_AMP_DSP_CFG, 0x0f},
 64         {MAX98390_R203A_AMP_EN, 0x81},
 65         {MAX98390_TONE_GEN_DC_CFG, 0x00},
 66         {MAX98390_SPK_SRC_SEL, 0x00},
 67         {MAX98390_SSM_CFG, 0x85},
 68         {MAX98390_MEAS_EN, 0x03},
 69         {MAX98390_MEAS_DSP_CFG, 0x0f},
 70         {MAX98390_BOOST_CTRL0, 0x1c},
 71         {MAX98390_BOOST_CTRL3, 0x01},
 72         {MAX98390_BOOST_CTRL1, 0x40},
 73         {MAX98390_MEAS_ADC_CFG, 0x07},
 74         {MAX98390_MEAS_ADC_BASE_MSB, 0x00},
 75         {MAX98390_MEAS_ADC_BASE_LSB, 0x23},
 76         {MAX98390_ADC_CH0_DIVIDE, 0x00},
 77         {MAX98390_ADC_CH1_DIVIDE, 0x00},
 78         {MAX98390_ADC_CH2_DIVIDE, 0x00},
 79         {MAX98390_ADC_CH0_FILT_CFG, 0x00},
 80         {MAX98390_ADC_CH1_FILT_CFG, 0x00},
 81         {MAX98390_ADC_CH2_FILT_CFG, 0x00},
 82         {MAX98390_PWR_GATE_CTL, 0x2c},
 83         {MAX98390_BROWNOUT_EN, 0x00},
 84         {MAX98390_BROWNOUT_INFINITE_HOLD, 0x00},
 85         {MAX98390_BROWNOUT_INFINITE_HOLD_CLR, 0x00},
 86         {MAX98390_BROWNOUT_LVL_HOLD, 0x00},
 87         {MAX98390_BROWNOUT_LVL1_THRESH, 0x00},
 88         {MAX98390_BROWNOUT_LVL2_THRESH, 0x00},
 89         {MAX98390_BROWNOUT_LVL3_THRESH, 0x00},
 90         {MAX98390_BROWNOUT_LVL4_THRESH, 0x00},
 91         {MAX98390_BROWNOUT_THRESH_HYSTERYSIS, 0x00},
 92         {MAX98390_BROWNOUT_AMP_LIMITER_ATK_REL, 0x1f},
 93         {MAX98390_BROWNOUT_AMP_GAIN_ATK_REL, 0x00},
 94         {MAX98390_BROWNOUT_AMP1_CLIP_MODE, 0x00},
 95         {MAX98390_BROWNOUT_LVL1_CUR_LIMIT, 0x00},
 96         {MAX98390_BROWNOUT_LVL1_AMP1_CTRL1, 0x00},
 97         {MAX98390_BROWNOUT_LVL1_AMP1_CTRL2, 0x00},
 98         {MAX98390_BROWNOUT_LVL1_AMP1_CTRL3, 0x00},
 99         {MAX98390_BROWNOUT_LVL2_CUR_LIMIT, 0x00},
100         {MAX98390_BROWNOUT_LVL2_AMP1_CTRL1, 0x00},
101         {MAX98390_BROWNOUT_LVL2_AMP1_CTRL2, 0x00},
102         {MAX98390_BROWNOUT_LVL2_AMP1_CTRL3, 0x00},
103         {MAX98390_BROWNOUT_LVL3_CUR_LIMIT, 0x00},
104         {MAX98390_BROWNOUT_LVL3_AMP1_CTRL1, 0x00},
105         {MAX98390_BROWNOUT_LVL3_AMP1_CTRL2, 0x00},
106         {MAX98390_BROWNOUT_LVL3_AMP1_CTRL3, 0x00},
107         {MAX98390_BROWNOUT_LVL4_CUR_LIMIT, 0x00},
108         {MAX98390_BROWNOUT_LVL4_AMP1_CTRL1, 0x00},
109         {MAX98390_BROWNOUT_LVL4_AMP1_CTRL2, 0x00},
110         {MAX98390_BROWNOUT_LVL4_AMP1_CTRL3, 0x00},
111         {MAX98390_BROWNOUT_ILIM_HLD, 0x00},
112         {MAX98390_BROWNOUT_LIM_HLD, 0x00},
113         {MAX98390_BROWNOUT_CLIP_HLD, 0x00},
114         {MAX98390_BROWNOUT_GAIN_HLD, 0x00},
115         {MAX98390_ENV_TRACK_VOUT_HEADROOM, 0x0f},
116         {MAX98390_ENV_TRACK_BOOST_VOUT_DELAY, 0x80},
117         {MAX98390_ENV_TRACK_REL_RATE, 0x07},
118         {MAX98390_ENV_TRACK_HOLD_RATE, 0x07},
119         {MAX98390_ENV_TRACK_CTRL, 0x01},
120         {MAX98390_BOOST_BYPASS1, 0x49},
121         {MAX98390_BOOST_BYPASS2, 0x2b},
122         {MAX98390_BOOST_BYPASS3, 0x08},
123         {MAX98390_FET_SCALING1, 0x00},
124         {MAX98390_FET_SCALING2, 0x03},
125         {MAX98390_FET_SCALING3, 0x00},
126         {MAX98390_FET_SCALING4, 0x07},
127         {MAX98390_SPK_SPEEDUP, 0x00},
128         {DSMIG_WB_DRC_RELEASE_TIME_1, 0x00},
129         {DSMIG_WB_DRC_RELEASE_TIME_2, 0x00},
130         {DSMIG_WB_DRC_ATTACK_TIME_1, 0x00},
131         {DSMIG_WB_DRC_ATTACK_TIME_2, 0x00},
132         {DSMIG_WB_DRC_COMPRESSION_RATIO, 0x00},
133         {DSMIG_WB_DRC_COMPRESSION_THRESHOLD, 0x00},
134         {DSMIG_WB_DRC_MAKEUPGAIN, 0x00},
135         {DSMIG_WB_DRC_NOISE_GATE_THRESHOLD, 0x00},
136         {DSMIG_WBDRC_HPF_ENABLE, 0x00},
137         {DSMIG_WB_DRC_TEST_SMOOTHER_OUT_EN, 0x00},
138         {DSMIG_PPR_THRESHOLD, 0x00},
139         {DSM_STEREO_BASS_CHANNEL_SELECT, 0x00},
140         {DSM_TPROT_THRESHOLD_BYTE0, 0x00},
141         {DSM_TPROT_THRESHOLD_BYTE1, 0x00},
142         {DSM_TPROT_ROOM_TEMPERATURE_BYTE0, 0x00},
143         {DSM_TPROT_ROOM_TEMPERATURE_BYTE1, 0x00},
144         {DSM_TPROT_RECIP_RDC_ROOM_BYTE0, 0x00},
145         {DSM_TPROT_RECIP_RDC_ROOM_BYTE1, 0x00},
146         {DSM_TPROT_RECIP_RDC_ROOM_BYTE2, 0x00},
147         {DSM_TPROT_RECIP_TCONST_BYTE0, 0x00},
148         {DSM_TPROT_RECIP_TCONST_BYTE1, 0x00},
149         {DSM_TPROT_RECIP_TCONST_BYTE2, 0x00},
150         {DSM_THERMAL_ATTENUATION_SETTINGS, 0x00},
151         {DSM_THERMAL_PILOT_TONE_ATTENUATION, 0x00},
152         {DSM_TPROT_PG_TEMP_THRESH_BYTE0, 0x00},
153         {DSM_TPROT_PG_TEMP_THRESH_BYTE1, 0x00},
154         {DSMIG_DEBUZZER_THRESHOLD, 0x00},
155         {DSMIG_DEBUZZER_ALPHA_COEF_TEST_ONLY, 0x08},
156         {DSM_VOL_ENA, 0x20},
157         {DSM_VOL_CTRL, 0xa0},
158         {DSMIG_EN, 0x00},
159         {MAX98390_R23E1_DSP_GLOBAL_EN, 0x00},
160         {MAX98390_R23FF_GLOBAL_EN, 0x00},
161 };
162 
163 static int max98390_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
164 {
165         struct snd_soc_component *component = codec_dai->component;
166         struct max98390_priv *max98390 =
167                 snd_soc_component_get_drvdata(component);
168         unsigned int mode;
169         unsigned int format;
170         unsigned int invert = 0;
171 
172         dev_dbg(component->dev, "%s: fmt 0x%08X\n", __func__, fmt);
173 
174         switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
175         case SND_SOC_DAIFMT_CBC_CFC:
176                 mode = MAX98390_PCM_MASTER_MODE_SLAVE;
177                 break;
178         case SND_SOC_DAIFMT_CBP_CFP:
179                 max98390->provider = true;
180                 mode = MAX98390_PCM_MASTER_MODE_MASTER;
181                 break;
182         default:
183                 dev_err(component->dev, "DAI clock mode unsupported\n");
184                 return -EINVAL;
185         }
186 
187         regmap_update_bits(max98390->regmap,
188                 MAX98390_PCM_MASTER_MODE,
189                 MAX98390_PCM_MASTER_MODE_MASK,
190                 mode);
191 
192         switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
193         case SND_SOC_DAIFMT_NB_NF:
194                 break;
195         case SND_SOC_DAIFMT_IB_NF:
196                 invert = MAX98390_PCM_MODE_CFG_PCM_BCLKEDGE;
197                 break;
198         default:
199                 dev_err(component->dev, "DAI invert mode unsupported\n");
200                 return -EINVAL;
201         }
202 
203         regmap_update_bits(max98390->regmap,
204                 MAX98390_PCM_MODE_CFG,
205                 MAX98390_PCM_MODE_CFG_PCM_BCLKEDGE,
206                 invert);
207 
208         /* interface format */
209         switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
210         case SND_SOC_DAIFMT_I2S:
211                 format = MAX98390_PCM_FORMAT_I2S;
212                 break;
213         case SND_SOC_DAIFMT_LEFT_J:
214                 format = MAX98390_PCM_FORMAT_LJ;
215                 break;
216         case SND_SOC_DAIFMT_DSP_A:
217                 format = MAX98390_PCM_FORMAT_TDM_MODE1;
218                 break;
219         case SND_SOC_DAIFMT_DSP_B:
220                 format = MAX98390_PCM_FORMAT_TDM_MODE0;
221                 break;
222         default:
223                 return -EINVAL;
224         }
225 
226         regmap_update_bits(max98390->regmap,
227                 MAX98390_PCM_MODE_CFG,
228                 MAX98390_PCM_MODE_CFG_FORMAT_MASK,
229                 format << MAX98390_PCM_MODE_CFG_FORMAT_SHIFT);
230 
231         return 0;
232 }
233 
234 static int max98390_get_bclk_sel(int bclk)
235 {
236         int i;
237         /* BCLKs per LRCLK */
238         static int bclk_sel_table[] = {
239                 32, 48, 64, 96, 128, 192, 256, 320, 384, 512,
240         };
241         /* match BCLKs per LRCLK */
242         for (i = 0; i < ARRAY_SIZE(bclk_sel_table); i++) {
243                 if (bclk_sel_table[i] == bclk)
244                         return i + 2;
245         }
246         return 0;
247 }
248 
249 static int max98390_set_clock(struct snd_soc_component *component,
250                 struct snd_pcm_hw_params *params)
251 {
252         struct max98390_priv *max98390 =
253                 snd_soc_component_get_drvdata(component);
254         /* codec MCLK rate in master mode */
255         static int rate_table[] = {
256                 5644800, 6000000, 6144000, 6500000,
257                 9600000, 11289600, 12000000, 12288000,
258                 13000000, 19200000,
259         };
260         /* BCLK/LRCLK ratio calculation */
261         int blr_clk_ratio = params_channels(params)
262                 * snd_pcm_format_width(params_format(params));
263         int value;
264 
265         if (max98390->provider) {
266                 int i;
267                 /* match rate to closest value */
268                 for (i = 0; i < ARRAY_SIZE(rate_table); i++) {
269                         if (rate_table[i] >= max98390->sysclk)
270                                 break;
271                 }
272                 if (i == ARRAY_SIZE(rate_table)) {
273                         dev_err(component->dev, "failed to find proper clock rate.\n");
274                         return -EINVAL;
275                 }
276 
277                 regmap_update_bits(max98390->regmap,
278                         MAX98390_PCM_MASTER_MODE,
279                         MAX98390_PCM_MASTER_MODE_MCLK_MASK,
280                         i << MAX98390_PCM_MASTER_MODE_MCLK_RATE_SHIFT);
281         }
282 
283         if (!max98390->tdm_mode) {
284                 /* BCLK configuration */
285                 value = max98390_get_bclk_sel(blr_clk_ratio);
286                 if (!value) {
287                         dev_err(component->dev, "format unsupported %d\n",
288                                 params_format(params));
289                         return -EINVAL;
290                 }
291 
292                 regmap_update_bits(max98390->regmap,
293                         MAX98390_PCM_CLK_SETUP,
294                         MAX98390_PCM_CLK_SETUP_BSEL_MASK,
295                         value);
296         }
297         return 0;
298 }
299 
300 static int max98390_dai_hw_params(struct snd_pcm_substream *substream,
301                 struct snd_pcm_hw_params *params,
302                 struct snd_soc_dai *dai)
303 {
304         struct snd_soc_component *component =
305                 dai->component;
306         struct max98390_priv *max98390 =
307                 snd_soc_component_get_drvdata(component);
308 
309         unsigned int sampling_rate;
310         unsigned int chan_sz;
311 
312         /* pcm mode configuration */
313         switch (snd_pcm_format_width(params_format(params))) {
314         case 16:
315                 chan_sz = MAX98390_PCM_MODE_CFG_CHANSZ_16;
316                 break;
317         case 24:
318                 chan_sz = MAX98390_PCM_MODE_CFG_CHANSZ_24;
319                 break;
320         case 32:
321                 chan_sz = MAX98390_PCM_MODE_CFG_CHANSZ_32;
322                 break;
323         default:
324                 dev_err(component->dev, "format unsupported %d\n",
325                         params_format(params));
326                 goto err;
327         }
328 
329         regmap_update_bits(max98390->regmap,
330                 MAX98390_PCM_MODE_CFG,
331                 MAX98390_PCM_MODE_CFG_CHANSZ_MASK, chan_sz);
332 
333         dev_dbg(component->dev, "format supported %d",
334                 params_format(params));
335 
336         /* sampling rate configuration */
337         switch (params_rate(params)) {
338         case 8000:
339                 sampling_rate = MAX98390_PCM_SR_SET1_SR_8000;
340                 break;
341         case 11025:
342                 sampling_rate = MAX98390_PCM_SR_SET1_SR_11025;
343                 break;
344         case 12000:
345                 sampling_rate = MAX98390_PCM_SR_SET1_SR_12000;
346                 break;
347         case 16000:
348                 sampling_rate = MAX98390_PCM_SR_SET1_SR_16000;
349                 break;
350         case 22050:
351                 sampling_rate = MAX98390_PCM_SR_SET1_SR_22050;
352                 break;
353         case 24000:
354                 sampling_rate = MAX98390_PCM_SR_SET1_SR_24000;
355                 break;
356         case 32000:
357                 sampling_rate = MAX98390_PCM_SR_SET1_SR_32000;
358                 break;
359         case 44100:
360                 sampling_rate = MAX98390_PCM_SR_SET1_SR_44100;
361                 break;
362         case 48000:
363                 sampling_rate = MAX98390_PCM_SR_SET1_SR_48000;
364                 break;
365         default:
366                 dev_err(component->dev, "rate %d not supported\n",
367                         params_rate(params));
368                 goto err;
369         }
370 
371         /* set DAI_SR to correct LRCLK frequency */
372         regmap_update_bits(max98390->regmap,
373                 MAX98390_PCM_SR_SETUP,
374                 MAX98390_PCM_SR_SET1_SR_MASK,
375                 sampling_rate);
376 
377         return max98390_set_clock(component, params);
378 err:
379         return -EINVAL;
380 }
381 
382 static int max98390_dai_tdm_slot(struct snd_soc_dai *dai,
383                 unsigned int tx_mask, unsigned int rx_mask,
384                 int slots, int slot_width)
385 {
386         struct snd_soc_component *component = dai->component;
387         struct max98390_priv *max98390 =
388                 snd_soc_component_get_drvdata(component);
389 
390         int bsel;
391         unsigned int chan_sz;
392 
393         if (!tx_mask && !rx_mask && !slots && !slot_width)
394                 max98390->tdm_mode = false;
395         else
396                 max98390->tdm_mode = true;
397 
398         dev_dbg(component->dev,
399                 "Tdm mode : %d\n", max98390->tdm_mode);
400 
401         /* BCLK configuration */
402         bsel = max98390_get_bclk_sel(slots * slot_width);
403         if (!bsel) {
404                 dev_err(component->dev, "BCLK %d not supported\n",
405                         slots * slot_width);
406                 return -EINVAL;
407         }
408 
409         regmap_update_bits(max98390->regmap,
410                 MAX98390_PCM_CLK_SETUP,
411                 MAX98390_PCM_CLK_SETUP_BSEL_MASK,
412                 bsel);
413 
414         /* Channel size configuration */
415         switch (slot_width) {
416         case 16:
417                 chan_sz = MAX98390_PCM_MODE_CFG_CHANSZ_16;
418                 break;
419         case 24:
420                 chan_sz = MAX98390_PCM_MODE_CFG_CHANSZ_24;
421                 break;
422         case 32:
423                 chan_sz = MAX98390_PCM_MODE_CFG_CHANSZ_32;
424                 break;
425         default:
426                 dev_err(component->dev, "format unsupported %d\n",
427                         slot_width);
428                 return -EINVAL;
429         }
430 
431         regmap_update_bits(max98390->regmap,
432                 MAX98390_PCM_MODE_CFG,
433                 MAX98390_PCM_MODE_CFG_CHANSZ_MASK, chan_sz);
434 
435         /* Rx slot configuration */
436         regmap_write(max98390->regmap,
437                 MAX98390_PCM_RX_EN_A,
438                 rx_mask & 0xFF);
439         regmap_write(max98390->regmap,
440                 MAX98390_PCM_RX_EN_B,
441                 (rx_mask & 0xFF00) >> 8);
442 
443         /* Tx slot Hi-Z configuration */
444         regmap_write(max98390->regmap,
445                 MAX98390_PCM_TX_HIZ_CTRL_A,
446                 ~tx_mask & 0xFF);
447         regmap_write(max98390->regmap,
448                 MAX98390_PCM_TX_HIZ_CTRL_B,
449                 (~tx_mask & 0xFF00) >> 8);
450 
451         return 0;
452 }
453 
454 static int max98390_dai_set_sysclk(struct snd_soc_dai *dai,
455                 int clk_id, unsigned int freq, int dir)
456 {
457         struct snd_soc_component *component = dai->component;
458         struct max98390_priv *max98390 =
459                 snd_soc_component_get_drvdata(component);
460 
461         max98390->sysclk = freq;
462         return 0;
463 }
464 
465 static const struct snd_soc_dai_ops max98390_dai_ops = {
466         .set_sysclk = max98390_dai_set_sysclk,
467         .set_fmt = max98390_dai_set_fmt,
468         .hw_params = max98390_dai_hw_params,
469         .set_tdm_slot = max98390_dai_tdm_slot,
470 };
471 
472 static int max98390_dac_event(struct snd_soc_dapm_widget *w,
473                 struct snd_kcontrol *kcontrol, int event)
474 {
475         struct snd_soc_component *component =
476                 snd_soc_dapm_to_component(w->dapm);
477         struct max98390_priv *max98390 =
478                 snd_soc_component_get_drvdata(component);
479 
480         switch (event) {
481         case SND_SOC_DAPM_POST_PMU:
482                 regmap_update_bits(max98390->regmap,
483                         MAX98390_R203A_AMP_EN,
484                         MAX98390_AMP_EN_MASK, 1);
485                 regmap_update_bits(max98390->regmap,
486                         MAX98390_R23FF_GLOBAL_EN,
487                         MAX98390_GLOBAL_EN_MASK, 1);
488                 break;
489         case SND_SOC_DAPM_POST_PMD:
490                 regmap_update_bits(max98390->regmap,
491                         MAX98390_R23FF_GLOBAL_EN,
492                         MAX98390_GLOBAL_EN_MASK, 0);
493                 regmap_update_bits(max98390->regmap,
494                         MAX98390_R203A_AMP_EN,
495                         MAX98390_AMP_EN_MASK, 0);
496                 break;
497         }
498         return 0;
499 }
500 
501 static const char * const max98390_switch_text[] = {
502         "Left", "Right", "LeftRight"};
503 
504 static const char * const max98390_boost_voltage_text[] = {
505         "6.5V", "6.625V", "6.75V", "6.875V", "7V", "7.125V", "7.25V", "7.375V",
506         "7.5V", "7.625V", "7.75V", "7.875V", "8V", "8.125V", "8.25V", "8.375V",
507         "8.5V", "8.625V", "8.75V", "8.875V", "9V", "9.125V", "9.25V", "9.375V",
508         "9.5V", "9.625V", "9.75V", "9.875V", "10V"
509 };
510 
511 static SOC_ENUM_SINGLE_DECL(max98390_boost_voltage,
512                 MAX98390_BOOST_CTRL0, 0,
513                 max98390_boost_voltage_text);
514 
515 static DECLARE_TLV_DB_SCALE(max98390_spk_tlv, 300, 300, 0);
516 static DECLARE_TLV_DB_SCALE(max98390_digital_tlv, -8000, 50, 0);
517 
518 static const char * const max98390_current_limit_text[] = {
519         "0.00A", "0.50A", "1.00A", "1.05A", "1.10A", "1.15A", "1.20A", "1.25A",
520         "1.30A", "1.35A", "1.40A", "1.45A", "1.50A", "1.55A", "1.60A", "1.65A",
521         "1.70A", "1.75A", "1.80A", "1.85A", "1.90A", "1.95A", "2.00A", "2.05A",
522         "2.10A", "2.15A", "2.20A", "2.25A", "2.30A", "2.35A", "2.40A", "2.45A",
523         "2.50A", "2.55A", "2.60A", "2.65A", "2.70A", "2.75A", "2.80A", "2.85A",
524         "2.90A", "2.95A", "3.00A", "3.05A", "3.10A", "3.15A", "3.20A", "3.25A",
525         "3.30A", "3.35A", "3.40A", "3.45A", "3.50A", "3.55A", "3.60A", "3.65A",
526         "3.70A", "3.75A", "3.80A", "3.85A", "3.90A", "3.95A", "4.00A", "4.05A",
527         "4.10A"
528 };
529 
530 static SOC_ENUM_SINGLE_DECL(max98390_current_limit,
531                 MAX98390_BOOST_CTRL1, 0,
532                 max98390_current_limit_text);
533 
534 static int max98390_ref_rdc_put(struct snd_kcontrol *kcontrol,
535                 struct snd_ctl_elem_value *ucontrol)
536 {
537         struct snd_soc_component *component =
538                 snd_soc_kcontrol_component(kcontrol);
539         struct max98390_priv *max98390 =
540                 snd_soc_component_get_drvdata(component);
541 
542         max98390->ref_rdc_value = ucontrol->value.integer.value[0];
543 
544         regmap_write(max98390->regmap, DSM_TPROT_RECIP_RDC_ROOM_BYTE0,
545                 max98390->ref_rdc_value & 0x000000ff);
546         regmap_write(max98390->regmap, DSM_TPROT_RECIP_RDC_ROOM_BYTE1,
547                 (max98390->ref_rdc_value >> 8) & 0x000000ff);
548         regmap_write(max98390->regmap, DSM_TPROT_RECIP_RDC_ROOM_BYTE2,
549                 (max98390->ref_rdc_value >> 16) & 0x000000ff);
550 
551         return 0;
552 }
553 
554 static int max98390_ref_rdc_get(struct snd_kcontrol *kcontrol,
555                 struct snd_ctl_elem_value *ucontrol)
556 {
557         struct snd_soc_component *component =
558                 snd_soc_kcontrol_component(kcontrol);
559         struct max98390_priv *max98390 =
560                 snd_soc_component_get_drvdata(component);
561 
562         ucontrol->value.integer.value[0] = max98390->ref_rdc_value;
563 
564         return 0;
565 }
566 
567 static int max98390_ambient_temp_put(struct snd_kcontrol *kcontrol,
568                 struct snd_ctl_elem_value *ucontrol)
569 {
570         struct snd_soc_component *component =
571                 snd_soc_kcontrol_component(kcontrol);
572         struct max98390_priv *max98390 =
573                 snd_soc_component_get_drvdata(component);
574 
575         max98390->ambient_temp_value = ucontrol->value.integer.value[0];
576 
577         regmap_write(max98390->regmap, DSM_TPROT_ROOM_TEMPERATURE_BYTE1,
578                 (max98390->ambient_temp_value >> 8) & 0x000000ff);
579         regmap_write(max98390->regmap, DSM_TPROT_ROOM_TEMPERATURE_BYTE0,
580                 (max98390->ambient_temp_value) & 0x000000ff);
581 
582         return 0;
583 }
584 
585 static int max98390_ambient_temp_get(struct snd_kcontrol *kcontrol,
586                 struct snd_ctl_elem_value *ucontrol)
587 {
588         struct snd_soc_component *component =
589                 snd_soc_kcontrol_component(kcontrol);
590         struct max98390_priv *max98390 =
591                 snd_soc_component_get_drvdata(component);
592 
593         ucontrol->value.integer.value[0] = max98390->ambient_temp_value;
594 
595         return 0;
596 }
597 
598 static int max98390_adaptive_rdc_put(struct snd_kcontrol *kcontrol,
599                 struct snd_ctl_elem_value *ucontrol)
600 {
601         struct snd_soc_component *component =
602                 snd_soc_kcontrol_component(kcontrol);
603 
604         dev_warn(component->dev, "Put adaptive rdc not supported\n");
605 
606         return 0;
607 }
608 
609 static int max98390_adaptive_rdc_get(struct snd_kcontrol *kcontrol,
610                 struct snd_ctl_elem_value *ucontrol)
611 {
612         int rdc, rdc0;
613         struct snd_soc_component *component =
614                 snd_soc_kcontrol_component(kcontrol);
615         struct max98390_priv *max98390 =
616                 snd_soc_component_get_drvdata(component);
617 
618         regmap_read(max98390->regmap, THERMAL_RDC_RD_BACK_BYTE1, &rdc);
619         regmap_read(max98390->regmap, THERMAL_RDC_RD_BACK_BYTE0, &rdc0);
620         ucontrol->value.integer.value[0] = rdc0 | rdc << 8;
621 
622         return 0;
623 }
624 
625 static int max98390_dsm_calib_get(struct snd_kcontrol *kcontrol,
626                 struct snd_ctl_elem_value *ucontrol)
627 {
628         /* Do nothing */
629         return 0;
630 }
631 
632 static int max98390_dsm_calib_put(struct snd_kcontrol *kcontrol,
633                 struct snd_ctl_elem_value *ucontrol)
634 {
635         struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
636         struct max98390_priv *max98390 = snd_soc_component_get_drvdata(component);
637         struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
638         unsigned int rdc, rdc_cal_result, rdc_integer, rdc_factor, temp, val;
639 
640         snd_soc_dapm_mutex_lock(dapm);
641 
642         regmap_read(max98390->regmap, MAX98390_R23FF_GLOBAL_EN, &val);
643         if (!val) {
644                 /* Enable the codec for the duration of calibration readout */
645                 regmap_update_bits(max98390->regmap, MAX98390_R203A_AMP_EN,
646                                    MAX98390_AMP_EN_MASK, 1);
647                 regmap_update_bits(max98390->regmap, MAX98390_R23FF_GLOBAL_EN,
648                                    MAX98390_GLOBAL_EN_MASK, 1);
649         }
650 
651         regmap_read(max98390->regmap, THERMAL_RDC_RD_BACK_BYTE1, &rdc);
652         regmap_read(max98390->regmap, THERMAL_RDC_RD_BACK_BYTE0, &rdc_cal_result);
653         regmap_read(max98390->regmap, MAX98390_MEAS_ADC_CH2_READ, &temp);
654 
655         if (!val) {
656                 /* Disable the codec if it was disabled */
657                 regmap_update_bits(max98390->regmap, MAX98390_R23FF_GLOBAL_EN,
658                                    MAX98390_GLOBAL_EN_MASK, 0);
659                 regmap_update_bits(max98390->regmap, MAX98390_R203A_AMP_EN,
660                                    MAX98390_AMP_EN_MASK, 0);
661         }
662 
663         snd_soc_dapm_mutex_unlock(dapm);
664 
665         rdc_cal_result |= (rdc << 8) & 0x0000FFFF;
666         if (rdc_cal_result)
667                 max98390->ref_rdc_value = 268435456U / rdc_cal_result;
668 
669         max98390->ambient_temp_value = temp * 52 - 1188;
670 
671         rdc_integer =  rdc_cal_result * 937  / 65536;
672         rdc_factor = ((rdc_cal_result * 937 * 100) / 65536) - (rdc_integer * 100);
673 
674         dev_info(component->dev,
675                  "rdc resistance about %d.%02d ohm, reg=0x%X temp reg=0x%X\n",
676                  rdc_integer, rdc_factor, rdc_cal_result, temp);
677 
678         return 0;
679 }
680 
681 static const struct snd_kcontrol_new max98390_snd_controls[] = {
682         SOC_SINGLE_TLV("Digital Volume", DSM_VOL_CTRL,
683                 0, 184, 0,
684                 max98390_digital_tlv),
685         SOC_SINGLE_TLV("Speaker Volume", MAX98390_R203D_SPK_GAIN,
686                 0, 6, 0,
687                 max98390_spk_tlv),
688         SOC_SINGLE("Ramp Up Bypass Switch", MAX98390_R2039_AMP_DSP_CFG,
689                 MAX98390_AMP_DSP_CFG_RMP_UP_SHIFT, 1, 0),
690         SOC_SINGLE("Ramp Down Bypass Switch", MAX98390_R2039_AMP_DSP_CFG,
691                 MAX98390_AMP_DSP_CFG_RMP_DN_SHIFT, 1, 0),
692         SOC_SINGLE("Boost Clock Phase", MAX98390_BOOST_CTRL3,
693                 MAX98390_BOOST_CLK_PHASE_CFG_SHIFT, 3, 0),
694         SOC_ENUM("Boost Output Voltage", max98390_boost_voltage),
695         SOC_ENUM("Current Limit", max98390_current_limit),
696         SOC_SINGLE_EXT("DSM Rdc", SND_SOC_NOPM, 0, 0xffffff, 0,
697                 max98390_ref_rdc_get, max98390_ref_rdc_put),
698         SOC_SINGLE_EXT("DSM Ambient Temp", SND_SOC_NOPM, 0, 0xffff, 0,
699                 max98390_ambient_temp_get, max98390_ambient_temp_put),
700         SOC_SINGLE_EXT("DSM Adaptive Rdc", SND_SOC_NOPM, 0, 0xffff, 0,
701                 max98390_adaptive_rdc_get, max98390_adaptive_rdc_put),
702         SOC_SINGLE_EXT("DSM Calibration", SND_SOC_NOPM, 0, 1, 0,
703                 max98390_dsm_calib_get, max98390_dsm_calib_put),
704 };
705 
706 static const struct soc_enum dai_sel_enum =
707         SOC_ENUM_SINGLE(MAX98390_PCM_CH_SRC_1,
708                 MAX98390_PCM_RX_CH_SRC_SHIFT,
709                 3, max98390_switch_text);
710 
711 static const struct snd_kcontrol_new max98390_dai_controls =
712         SOC_DAPM_ENUM("DAI Sel", dai_sel_enum);
713 
714 static const struct snd_soc_dapm_widget max98390_dapm_widgets[] = {
715         SND_SOC_DAPM_DAC_E("Amp Enable", "HiFi Playback",
716                 SND_SOC_NOPM, 0, 0, max98390_dac_event,
717                 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
718         SND_SOC_DAPM_MUX("DAI Sel Mux", SND_SOC_NOPM, 0, 0,
719                 &max98390_dai_controls),
720         SND_SOC_DAPM_OUTPUT("BE_OUT"),
721 };
722 
723 static const struct snd_soc_dapm_route max98390_audio_map[] = {
724         /* Plabyack */
725         {"DAI Sel Mux", "Left", "Amp Enable"},
726         {"DAI Sel Mux", "Right", "Amp Enable"},
727         {"DAI Sel Mux", "LeftRight", "Amp Enable"},
728         {"BE_OUT", NULL, "DAI Sel Mux"},
729 };
730 
731 static bool max98390_readable_register(struct device *dev, unsigned int reg)
732 {
733         switch (reg) {
734         case MAX98390_SOFTWARE_RESET ... MAX98390_INT_EN3:
735         case MAX98390_IRQ_CTRL ... MAX98390_WDOG_CTRL:
736         case MAX98390_MEAS_ADC_THERM_WARN_THRESH
737                 ... MAX98390_BROWNOUT_INFINITE_HOLD:
738         case MAX98390_BROWNOUT_LVL_HOLD ... DSMIG_DEBUZZER_THRESHOLD:
739         case DSM_VOL_ENA ... MAX98390_R24FF_REV_ID:
740                 return true;
741         default:
742                 return false;
743         }
744 };
745 
746 static bool max98390_volatile_reg(struct device *dev, unsigned int reg)
747 {
748         switch (reg) {
749         case MAX98390_SOFTWARE_RESET ... MAX98390_INT_EN3:
750         case MAX98390_MEAS_ADC_CH0_READ ... MAX98390_MEAS_ADC_CH2_READ:
751         case MAX98390_PWR_GATE_STATUS ... MAX98390_BROWNOUT_STATUS:
752         case MAX98390_BROWNOUT_LOWEST_STATUS:
753         case MAX98390_ENV_TRACK_BOOST_VOUT_READ:
754         case DSM_STBASS_HPF_B0_BYTE0 ... DSM_DEBUZZER_ATTACK_TIME_BYTE2:
755         case THERMAL_RDC_RD_BACK_BYTE1 ... DSMIG_DEBUZZER_THRESHOLD:
756         case DSM_THERMAL_GAIN ... DSM_WBDRC_GAIN:
757                 return true;
758         default:
759                 return false;
760         }
761 }
762 
763 #define MAX98390_RATES SNDRV_PCM_RATE_8000_48000
764 
765 #define MAX98390_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
766         SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
767 
768 static struct snd_soc_dai_driver max98390_dai[] = {
769         {
770                 .name = "max98390-aif1",
771                 .playback = {
772                         .stream_name = "HiFi Playback",
773                         .channels_min = 1,
774                         .channels_max = 2,
775                         .rates = MAX98390_RATES,
776                         .formats = MAX98390_FORMATS,
777                 },
778                 .capture = {
779                         .stream_name = "HiFi Capture",
780                         .channels_min = 1,
781                         .channels_max = 2,
782                         .rates = MAX98390_RATES,
783                         .formats = MAX98390_FORMATS,
784                 },
785                 .ops = &max98390_dai_ops,
786         }
787 };
788 
789 static int max98390_dsm_init(struct snd_soc_component *component)
790 {
791         int ret;
792         int param_size, param_start_addr;
793         char filename[128];
794         const char *vendor, *product;
795         struct max98390_priv *max98390 =
796                 snd_soc_component_get_drvdata(component);
797         const struct firmware *fw;
798         char *dsm_param;
799 
800         vendor = dmi_get_system_info(DMI_SYS_VENDOR);
801         product = dmi_get_system_info(DMI_PRODUCT_NAME);
802 
803         if (!strcmp(max98390->dsm_param_name, "default")) {
804                 if (vendor && product) {
805                         snprintf(filename, sizeof(filename),
806                                 "dsm_param_%s_%s.bin", vendor, product);
807                 } else {
808                         sprintf(filename, "dsm_param.bin");
809                 }
810         } else {
811                 snprintf(filename, sizeof(filename), "%s",
812                         max98390->dsm_param_name);
813         }
814         ret = request_firmware(&fw, filename, component->dev);
815         if (ret) {
816                 ret = request_firmware(&fw, "dsm_param.bin", component->dev);
817                 if (ret) {
818                         ret = request_firmware(&fw, "dsmparam.bin",
819                                 component->dev);
820                         if (ret)
821                                 goto err;
822                 }
823         }
824 
825         dev_dbg(component->dev,
826                 "max98390: param fw size %zd\n",
827                 fw->size);
828         if (fw->size < MAX98390_DSM_PARAM_MIN_SIZE) {
829                 dev_err(component->dev,
830                         "param fw is invalid.\n");
831                 ret = -EINVAL;
832                 goto err_alloc;
833         }
834         dsm_param = (char *)fw->data;
835         param_start_addr = (dsm_param[0] & 0xff) | (dsm_param[1] & 0xff) << 8;
836         param_size = (dsm_param[2] & 0xff) | (dsm_param[3] & 0xff) << 8;
837         if (param_size > MAX98390_DSM_PARAM_MAX_SIZE ||
838                 param_start_addr < MAX98390_IRQ_CTRL ||
839                 fw->size < param_size + MAX98390_DSM_PAYLOAD_OFFSET) {
840                 dev_err(component->dev,
841                         "param fw is invalid.\n");
842                 ret = -EINVAL;
843                 goto err_alloc;
844         }
845         regmap_write(max98390->regmap, MAX98390_R203A_AMP_EN, 0x80);
846         dsm_param += MAX98390_DSM_PAYLOAD_OFFSET;
847         regmap_bulk_write(max98390->regmap, param_start_addr,
848                 dsm_param, param_size);
849         regmap_write(max98390->regmap, MAX98390_R23E1_DSP_GLOBAL_EN, 0x01);
850 
851 err_alloc:
852         release_firmware(fw);
853 err:
854         return ret;
855 }
856 
857 static void max98390_init_regs(struct snd_soc_component *component)
858 {
859         struct max98390_priv *max98390 =
860                 snd_soc_component_get_drvdata(component);
861 
862         regmap_write(max98390->regmap, MAX98390_CLK_MON, 0x6f);
863         regmap_write(max98390->regmap, MAX98390_DAT_MON, 0x00);
864         regmap_write(max98390->regmap, MAX98390_PWR_GATE_CTL, 0x00);
865         regmap_write(max98390->regmap, MAX98390_PCM_RX_EN_A, 0x03);
866         regmap_write(max98390->regmap, MAX98390_ENV_TRACK_VOUT_HEADROOM, 0x0e);
867         regmap_write(max98390->regmap, MAX98390_BOOST_BYPASS1, 0x46);
868         regmap_write(max98390->regmap, MAX98390_FET_SCALING3, 0x03);
869 
870         /* voltage, current slot configuration */
871         regmap_write(max98390->regmap,
872                 MAX98390_PCM_CH_SRC_2,
873                 (max98390->i_l_slot << 4 |
874                 max98390->v_l_slot)&0xFF);
875 
876         if (max98390->v_l_slot < 8) {
877                 regmap_update_bits(max98390->regmap,
878                         MAX98390_PCM_TX_HIZ_CTRL_A,
879                         1 << max98390->v_l_slot, 0);
880                 regmap_update_bits(max98390->regmap,
881                         MAX98390_PCM_TX_EN_A,
882                         1 << max98390->v_l_slot,
883                         1 << max98390->v_l_slot);
884         } else {
885                 regmap_update_bits(max98390->regmap,
886                         MAX98390_PCM_TX_HIZ_CTRL_B,
887                         1 << (max98390->v_l_slot - 8), 0);
888                 regmap_update_bits(max98390->regmap,
889                         MAX98390_PCM_TX_EN_B,
890                         1 << (max98390->v_l_slot - 8),
891                         1 << (max98390->v_l_slot - 8));
892         }
893 
894         if (max98390->i_l_slot < 8) {
895                 regmap_update_bits(max98390->regmap,
896                         MAX98390_PCM_TX_HIZ_CTRL_A,
897                         1 << max98390->i_l_slot, 0);
898                 regmap_update_bits(max98390->regmap,
899                         MAX98390_PCM_TX_EN_A,
900                         1 << max98390->i_l_slot,
901                         1 << max98390->i_l_slot);
902         } else {
903                 regmap_update_bits(max98390->regmap,
904                         MAX98390_PCM_TX_HIZ_CTRL_B,
905                         1 << (max98390->i_l_slot - 8), 0);
906                 regmap_update_bits(max98390->regmap,
907                         MAX98390_PCM_TX_EN_B,
908                         1 << (max98390->i_l_slot - 8),
909                         1 << (max98390->i_l_slot - 8));
910         }
911 }
912 
913 static int max98390_probe(struct snd_soc_component *component)
914 {
915         struct max98390_priv *max98390 =
916                 snd_soc_component_get_drvdata(component);
917 
918         regmap_write(max98390->regmap, MAX98390_SOFTWARE_RESET, 0x01);
919         /* Sleep reset settle time */
920         msleep(20);
921 
922         /* Amp init setting */
923         max98390_init_regs(component);
924         /* Update dsm bin param */
925         max98390_dsm_init(component);
926 
927         /* Dsm Setting */
928         if (max98390->ref_rdc_value) {
929                 regmap_write(max98390->regmap, DSM_TPROT_RECIP_RDC_ROOM_BYTE0,
930                         max98390->ref_rdc_value & 0x000000ff);
931                 regmap_write(max98390->regmap, DSM_TPROT_RECIP_RDC_ROOM_BYTE1,
932                         (max98390->ref_rdc_value >> 8) & 0x000000ff);
933                 regmap_write(max98390->regmap, DSM_TPROT_RECIP_RDC_ROOM_BYTE2,
934                         (max98390->ref_rdc_value >> 16) & 0x000000ff);
935         }
936         if (max98390->ambient_temp_value) {
937                 regmap_write(max98390->regmap, DSM_TPROT_ROOM_TEMPERATURE_BYTE1,
938                         (max98390->ambient_temp_value >> 8) & 0x000000ff);
939                 regmap_write(max98390->regmap, DSM_TPROT_ROOM_TEMPERATURE_BYTE0,
940                         (max98390->ambient_temp_value) & 0x000000ff);
941         }
942 
943         return 0;
944 }
945 
946 #ifdef CONFIG_PM_SLEEP
947 static int max98390_suspend(struct device *dev)
948 {
949         struct max98390_priv *max98390 = dev_get_drvdata(dev);
950 
951         dev_dbg(dev, "%s:Enter\n", __func__);
952 
953         regcache_cache_only(max98390->regmap, true);
954         regcache_mark_dirty(max98390->regmap);
955 
956         return 0;
957 }
958 
959 static int max98390_resume(struct device *dev)
960 {
961         struct max98390_priv *max98390 = dev_get_drvdata(dev);
962 
963         dev_dbg(dev, "%s:Enter\n", __func__);
964 
965         regcache_cache_only(max98390->regmap, false);
966         regcache_sync(max98390->regmap);
967 
968         return 0;
969 }
970 #endif
971 
972 static const struct dev_pm_ops max98390_pm = {
973         SET_SYSTEM_SLEEP_PM_OPS(max98390_suspend, max98390_resume)
974 };
975 
976 static const struct snd_soc_component_driver soc_codec_dev_max98390 = {
977         .probe                  = max98390_probe,
978         .controls               = max98390_snd_controls,
979         .num_controls           = ARRAY_SIZE(max98390_snd_controls),
980         .dapm_widgets           = max98390_dapm_widgets,
981         .num_dapm_widgets       = ARRAY_SIZE(max98390_dapm_widgets),
982         .dapm_routes            = max98390_audio_map,
983         .num_dapm_routes        = ARRAY_SIZE(max98390_audio_map),
984         .idle_bias_on           = 1,
985         .use_pmdown_time        = 1,
986         .endianness             = 1,
987 };
988 
989 static const struct regmap_config max98390_regmap = {
990         .reg_bits         = 16,
991         .val_bits         = 8,
992         .max_register     = MAX98390_R24FF_REV_ID,
993         .reg_defaults     = max98390_reg_defaults,
994         .num_reg_defaults = ARRAY_SIZE(max98390_reg_defaults),
995         .readable_reg     = max98390_readable_register,
996         .volatile_reg     = max98390_volatile_reg,
997         .cache_type       = REGCACHE_RBTREE,
998 };
999 
1000 static void max98390_slot_config(struct i2c_client *i2c,
1001         struct max98390_priv *max98390)
1002 {
1003         int value;
1004         struct device *dev = &i2c->dev;
1005 
1006         if (!device_property_read_u32(dev, "maxim,vmon-slot-no", &value))
1007                 max98390->v_l_slot = value & 0xF;
1008         else
1009                 max98390->v_l_slot = 0;
1010 
1011         if (!device_property_read_u32(dev, "maxim,imon-slot-no", &value))
1012                 max98390->i_l_slot = value & 0xF;
1013         else
1014                 max98390->i_l_slot = 1;
1015 }
1016 
1017 static int max98390_i2c_probe(struct i2c_client *i2c)
1018 {
1019         int ret = 0;
1020         int reg = 0;
1021 
1022         struct max98390_priv *max98390 = NULL;
1023         struct i2c_adapter *adapter = i2c->adapter;
1024         struct gpio_desc *reset_gpio;
1025 
1026         ret = i2c_check_functionality(adapter,
1027                 I2C_FUNC_SMBUS_BYTE
1028                 | I2C_FUNC_SMBUS_BYTE_DATA);
1029         if (!ret) {
1030                 dev_err(&i2c->dev, "I2C check functionality failed\n");
1031                 return -ENXIO;
1032         }
1033 
1034         max98390 = devm_kzalloc(&i2c->dev, sizeof(*max98390), GFP_KERNEL);
1035         if (!max98390) {
1036                 ret = -ENOMEM;
1037                 return ret;
1038         }
1039         i2c_set_clientdata(i2c, max98390);
1040 
1041         ret = device_property_read_u32(&i2c->dev, "maxim,temperature_calib",
1042                                        &max98390->ambient_temp_value);
1043         if (ret) {
1044                 dev_info(&i2c->dev,
1045                          "no optional property 'temperature_calib' found, default:\n");
1046         }
1047         ret = device_property_read_u32(&i2c->dev, "maxim,r0_calib",
1048                                        &max98390->ref_rdc_value);
1049         if (ret) {
1050                 dev_info(&i2c->dev,
1051                          "no optional property 'r0_calib' found, default:\n");
1052         }
1053 
1054         dev_info(&i2c->dev,
1055                 "%s: r0_calib: 0x%x,temperature_calib: 0x%x",
1056                 __func__, max98390->ref_rdc_value,
1057                 max98390->ambient_temp_value);
1058 
1059         ret = device_property_read_string(&i2c->dev, "maxim,dsm_param_name",
1060                                        &max98390->dsm_param_name);
1061         if (ret)
1062                 max98390->dsm_param_name = "default";
1063 
1064         /* voltage/current slot configuration */
1065         max98390_slot_config(i2c, max98390);
1066 
1067         /* regmap initialization */
1068         max98390->regmap = devm_regmap_init_i2c(i2c, &max98390_regmap);
1069         if (IS_ERR(max98390->regmap)) {
1070                 ret = PTR_ERR(max98390->regmap);
1071                 dev_err(&i2c->dev,
1072                         "Failed to allocate regmap: %d\n", ret);
1073                 return ret;
1074         }
1075 
1076         reset_gpio = devm_gpiod_get_optional(&i2c->dev,
1077                                              "reset", GPIOD_OUT_HIGH);
1078 
1079         /* Power on device */
1080         if (reset_gpio) {
1081                 usleep_range(1000, 2000);
1082                 /* bring out of reset */
1083                 gpiod_set_value_cansleep(reset_gpio, 0);
1084                 usleep_range(1000, 2000);
1085         }
1086 
1087         /* Check Revision ID */
1088         ret = regmap_read(max98390->regmap,
1089                 MAX98390_R24FF_REV_ID, &reg);
1090         if (ret) {
1091                 dev_err(&i2c->dev,
1092                         "ret=%d, Failed to read: 0x%02X\n",
1093                         ret, MAX98390_R24FF_REV_ID);
1094                 return ret;
1095         }
1096         dev_info(&i2c->dev, "MAX98390 revisionID: 0x%02X\n", reg);
1097 
1098         ret = devm_snd_soc_register_component(&i2c->dev,
1099                         &soc_codec_dev_max98390,
1100                         max98390_dai, ARRAY_SIZE(max98390_dai));
1101 
1102         return ret;
1103 }
1104 
1105 static const struct i2c_device_id max98390_i2c_id[] = {
1106         { "max98390"},
1107         {},
1108 };
1109 
1110 MODULE_DEVICE_TABLE(i2c, max98390_i2c_id);
1111 
1112 #if defined(CONFIG_OF)
1113 static const struct of_device_id max98390_of_match[] = {
1114         { .compatible = "maxim,max98390", },
1115         {}
1116 };
1117 MODULE_DEVICE_TABLE(of, max98390_of_match);
1118 #endif
1119 
1120 #ifdef CONFIG_ACPI
1121 static const struct acpi_device_id max98390_acpi_match[] = {
1122         { "MX98390", 0 },
1123         {},
1124 };
1125 MODULE_DEVICE_TABLE(acpi, max98390_acpi_match);
1126 #endif
1127 
1128 static struct i2c_driver max98390_i2c_driver = {
1129         .driver = {
1130                 .name = "max98390",
1131                 .of_match_table = of_match_ptr(max98390_of_match),
1132                 .acpi_match_table = ACPI_PTR(max98390_acpi_match),
1133                 .pm = &max98390_pm,
1134         },
1135         .probe = max98390_i2c_probe,
1136         .id_table = max98390_i2c_id,
1137 };
1138 
1139 module_i2c_driver(max98390_i2c_driver)
1140 
1141 MODULE_DESCRIPTION("ALSA SoC MAX98390 driver");
1142 MODULE_AUTHOR("Steve Lee <steves.lee@maximintegrated.com>");
1143 MODULE_LICENSE("GPL");
1144 

~ [ 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