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

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

Version: ~ [ linux-5.13-rc2 ] ~ [ linux-5.12.4 ] ~ [ linux-5.11.21 ] ~ [ linux-5.10.37 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.119 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.190 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.232 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.268 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.268 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.18.140 ] ~ [ linux-3.16.85 ] ~ [ linux-3.14.79 ] ~ [ linux-3.12.74 ] ~ [ 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.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * max98927.c  --  MAX98927 ALSA Soc Audio driver
  3  *
  4  * Copyright (C) 2016 Maxim Integrated Products
  5  * Author: Ryan Lee <ryans.lee@maximintegrated.com>
  6  *
  7  *  This program is free software; you can redistribute  it and/or modify it
  8  *  under  the terms of  the GNU General  Public License as published by the
  9  *  Free Software Foundation;  either version 2 of the  License, or (at your
 10  *  option) any later version.
 11  */
 12 
 13 #include <linux/acpi.h>
 14 #include <linux/i2c.h>
 15 #include <linux/module.h>
 16 #include <linux/regmap.h>
 17 #include <linux/slab.h>
 18 #include <linux/cdev.h>
 19 #include <sound/pcm.h>
 20 #include <sound/pcm_params.h>
 21 #include <sound/soc.h>
 22 #include <linux/gpio.h>
 23 #include <linux/of_gpio.h>
 24 #include <sound/tlv.h>
 25 #include "max98927.h"
 26 
 27 static struct reg_default max98927_reg[] = {
 28         {MAX98927_R0001_INT_RAW1,  0x00},
 29         {MAX98927_R0002_INT_RAW2,  0x00},
 30         {MAX98927_R0003_INT_RAW3,  0x00},
 31         {MAX98927_R0004_INT_STATE1,  0x00},
 32         {MAX98927_R0005_INT_STATE2,  0x00},
 33         {MAX98927_R0006_INT_STATE3,  0x00},
 34         {MAX98927_R0007_INT_FLAG1,  0x00},
 35         {MAX98927_R0008_INT_FLAG2,  0x00},
 36         {MAX98927_R0009_INT_FLAG3,  0x00},
 37         {MAX98927_R000A_INT_EN1,  0x00},
 38         {MAX98927_R000B_INT_EN2,  0x00},
 39         {MAX98927_R000C_INT_EN3,  0x00},
 40         {MAX98927_R000D_INT_FLAG_CLR1,  0x00},
 41         {MAX98927_R000E_INT_FLAG_CLR2,  0x00},
 42         {MAX98927_R000F_INT_FLAG_CLR3,  0x00},
 43         {MAX98927_R0010_IRQ_CTRL,  0x00},
 44         {MAX98927_R0011_CLK_MON,  0x00},
 45         {MAX98927_R0012_WDOG_CTRL,  0x00},
 46         {MAX98927_R0013_WDOG_RST,  0x00},
 47         {MAX98927_R0014_MEAS_ADC_THERM_WARN_THRESH,  0x00},
 48         {MAX98927_R0015_MEAS_ADC_THERM_SHDN_THRESH,  0x00},
 49         {MAX98927_R0016_MEAS_ADC_THERM_HYSTERESIS,  0x00},
 50         {MAX98927_R0017_PIN_CFG,  0x55},
 51         {MAX98927_R0018_PCM_RX_EN_A,  0x00},
 52         {MAX98927_R0019_PCM_RX_EN_B,  0x00},
 53         {MAX98927_R001A_PCM_TX_EN_A,  0x00},
 54         {MAX98927_R001B_PCM_TX_EN_B,  0x00},
 55         {MAX98927_R001C_PCM_TX_HIZ_CTRL_A,  0x00},
 56         {MAX98927_R001D_PCM_TX_HIZ_CTRL_B,  0x00},
 57         {MAX98927_R001E_PCM_TX_CH_SRC_A,  0x00},
 58         {MAX98927_R001F_PCM_TX_CH_SRC_B,  0x00},
 59         {MAX98927_R0020_PCM_MODE_CFG,  0x40},
 60         {MAX98927_R0021_PCM_MASTER_MODE,  0x00},
 61         {MAX98927_R0022_PCM_CLK_SETUP,  0x22},
 62         {MAX98927_R0023_PCM_SR_SETUP1,  0x00},
 63         {MAX98927_R0024_PCM_SR_SETUP2,  0x00},
 64         {MAX98927_R0025_PCM_TO_SPK_MONOMIX_A,  0x00},
 65         {MAX98927_R0026_PCM_TO_SPK_MONOMIX_B,  0x00},
 66         {MAX98927_R0027_ICC_RX_EN_A,  0x00},
 67         {MAX98927_R0028_ICC_RX_EN_B,  0x00},
 68         {MAX98927_R002B_ICC_TX_EN_A,  0x00},
 69         {MAX98927_R002C_ICC_TX_EN_B,  0x00},
 70         {MAX98927_R002E_ICC_HIZ_MANUAL_MODE,  0x00},
 71         {MAX98927_R002F_ICC_TX_HIZ_EN_A,  0x00},
 72         {MAX98927_R0030_ICC_TX_HIZ_EN_B,  0x00},
 73         {MAX98927_R0031_ICC_LNK_EN,  0x00},
 74         {MAX98927_R0032_PDM_TX_EN,  0x00},
 75         {MAX98927_R0033_PDM_TX_HIZ_CTRL,  0x00},
 76         {MAX98927_R0034_PDM_TX_CTRL,  0x00},
 77         {MAX98927_R0035_PDM_RX_CTRL,  0x00},
 78         {MAX98927_R0036_AMP_VOL_CTRL,  0x00},
 79         {MAX98927_R0037_AMP_DSP_CFG,  0x02},
 80         {MAX98927_R0038_TONE_GEN_DC_CFG,  0x00},
 81         {MAX98927_R0039_DRE_CTRL,  0x01},
 82         {MAX98927_R003A_AMP_EN,  0x00},
 83         {MAX98927_R003B_SPK_SRC_SEL,  0x00},
 84         {MAX98927_R003C_SPK_GAIN,  0x00},
 85         {MAX98927_R003D_SSM_CFG,  0x01},
 86         {MAX98927_R003E_MEAS_EN,  0x00},
 87         {MAX98927_R003F_MEAS_DSP_CFG,  0x04},
 88         {MAX98927_R0040_BOOST_CTRL0,  0x00},
 89         {MAX98927_R0041_BOOST_CTRL3,  0x00},
 90         {MAX98927_R0042_BOOST_CTRL1,  0x00},
 91         {MAX98927_R0043_MEAS_ADC_CFG,  0x00},
 92         {MAX98927_R0044_MEAS_ADC_BASE_MSB,  0x00},
 93         {MAX98927_R0045_MEAS_ADC_BASE_LSB,  0x00},
 94         {MAX98927_R0046_ADC_CH0_DIVIDE,  0x00},
 95         {MAX98927_R0047_ADC_CH1_DIVIDE,  0x00},
 96         {MAX98927_R0048_ADC_CH2_DIVIDE,  0x00},
 97         {MAX98927_R0049_ADC_CH0_FILT_CFG,  0x00},
 98         {MAX98927_R004A_ADC_CH1_FILT_CFG,  0x00},
 99         {MAX98927_R004B_ADC_CH2_FILT_CFG,  0x00},
100         {MAX98927_R004C_MEAS_ADC_CH0_READ,  0x00},
101         {MAX98927_R004D_MEAS_ADC_CH1_READ,  0x00},
102         {MAX98927_R004E_MEAS_ADC_CH2_READ,  0x00},
103         {MAX98927_R0051_BROWNOUT_STATUS,  0x00},
104         {MAX98927_R0052_BROWNOUT_EN,  0x00},
105         {MAX98927_R0053_BROWNOUT_INFINITE_HOLD,  0x00},
106         {MAX98927_R0054_BROWNOUT_INFINITE_HOLD_CLR,  0x00},
107         {MAX98927_R0055_BROWNOUT_LVL_HOLD,  0x00},
108         {MAX98927_R005A_BROWNOUT_LVL1_THRESH,  0x00},
109         {MAX98927_R005B_BROWNOUT_LVL2_THRESH,  0x00},
110         {MAX98927_R005C_BROWNOUT_LVL3_THRESH,  0x00},
111         {MAX98927_R005D_BROWNOUT_LVL4_THRESH,  0x00},
112         {MAX98927_R005E_BROWNOUT_THRESH_HYSTERYSIS,  0x00},
113         {MAX98927_R005F_BROWNOUT_AMP_LIMITER_ATK_REL,  0x00},
114         {MAX98927_R0060_BROWNOUT_AMP_GAIN_ATK_REL,  0x00},
115         {MAX98927_R0061_BROWNOUT_AMP1_CLIP_MODE,  0x00},
116         {MAX98927_R0072_BROWNOUT_LVL1_CUR_LIMIT,  0x00},
117         {MAX98927_R0073_BROWNOUT_LVL1_AMP1_CTRL1,  0x00},
118         {MAX98927_R0074_BROWNOUT_LVL1_AMP1_CTRL2,  0x00},
119         {MAX98927_R0075_BROWNOUT_LVL1_AMP1_CTRL3,  0x00},
120         {MAX98927_R0076_BROWNOUT_LVL2_CUR_LIMIT,  0x00},
121         {MAX98927_R0077_BROWNOUT_LVL2_AMP1_CTRL1,  0x00},
122         {MAX98927_R0078_BROWNOUT_LVL2_AMP1_CTRL2,  0x00},
123         {MAX98927_R0079_BROWNOUT_LVL2_AMP1_CTRL3,  0x00},
124         {MAX98927_R007A_BROWNOUT_LVL3_CUR_LIMIT,  0x00},
125         {MAX98927_R007B_BROWNOUT_LVL3_AMP1_CTRL1,  0x00},
126         {MAX98927_R007C_BROWNOUT_LVL3_AMP1_CTRL2,  0x00},
127         {MAX98927_R007D_BROWNOUT_LVL3_AMP1_CTRL3,  0x00},
128         {MAX98927_R007E_BROWNOUT_LVL4_CUR_LIMIT,  0x00},
129         {MAX98927_R007F_BROWNOUT_LVL4_AMP1_CTRL1,  0x00},
130         {MAX98927_R0080_BROWNOUT_LVL4_AMP1_CTRL2,  0x00},
131         {MAX98927_R0081_BROWNOUT_LVL4_AMP1_CTRL3,  0x00},
132         {MAX98927_R0082_ENV_TRACK_VOUT_HEADROOM,  0x00},
133         {MAX98927_R0083_ENV_TRACK_BOOST_VOUT_DELAY,  0x00},
134         {MAX98927_R0084_ENV_TRACK_REL_RATE,  0x00},
135         {MAX98927_R0085_ENV_TRACK_HOLD_RATE,  0x00},
136         {MAX98927_R0086_ENV_TRACK_CTRL,  0x00},
137         {MAX98927_R0087_ENV_TRACK_BOOST_VOUT_READ,  0x00},
138         {MAX98927_R00FF_GLOBAL_SHDN,  0x00},
139         {MAX98927_R0100_SOFT_RESET,  0x00},
140         {MAX98927_R01FF_REV_ID,  0x40},
141 };
142 
143 static int max98927_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
144 {
145         struct snd_soc_codec *codec = codec_dai->codec;
146         struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
147         unsigned int mode = 0;
148         unsigned int format = 0;
149         unsigned int invert = 0;
150 
151         dev_dbg(codec->dev, "%s: fmt 0x%08X\n", __func__, fmt);
152 
153         switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
154         case SND_SOC_DAIFMT_CBS_CFS:
155                 mode = MAX98927_PCM_MASTER_MODE_SLAVE;
156                 break;
157         case SND_SOC_DAIFMT_CBM_CFM:
158                 max98927->master = true;
159                 mode = MAX98927_PCM_MASTER_MODE_MASTER;
160                 break;
161         default:
162                 dev_err(codec->dev, "DAI clock mode unsupported");
163                 return -EINVAL;
164         }
165 
166         regmap_update_bits(max98927->regmap,
167                 MAX98927_R0021_PCM_MASTER_MODE,
168                 MAX98927_PCM_MASTER_MODE_MASK,
169                 mode);
170 
171         switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
172         case SND_SOC_DAIFMT_NB_NF:
173                 break;
174         case SND_SOC_DAIFMT_IB_NF:
175                 invert = MAX98927_PCM_MODE_CFG_PCM_BCLKEDGE;
176                 break;
177         default:
178                 dev_err(codec->dev, "DAI invert mode unsupported");
179                 return -EINVAL;
180         }
181 
182         regmap_update_bits(max98927->regmap,
183                 MAX98927_R0020_PCM_MODE_CFG,
184                 MAX98927_PCM_MODE_CFG_PCM_BCLKEDGE,
185                 invert);
186 
187         /* interface format */
188         switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
189         case SND_SOC_DAIFMT_I2S:
190                 max98927->iface |= SND_SOC_DAIFMT_I2S;
191                 format = MAX98927_PCM_FORMAT_I2S;
192                 break;
193         case SND_SOC_DAIFMT_LEFT_J:
194                 max98927->iface |= SND_SOC_DAIFMT_LEFT_J;
195                 format = MAX98927_PCM_FORMAT_LJ;
196                 break;
197         case SND_SOC_DAIFMT_PDM:
198                 max98927->iface |= SND_SOC_DAIFMT_PDM;
199                 break;
200         default:
201                 return -EINVAL;
202         }
203 
204         /* pcm channel configuration */
205         if (max98927->iface & (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_LEFT_J)) {
206                 regmap_update_bits(max98927->regmap,
207                         MAX98927_R0018_PCM_RX_EN_A,
208                         MAX98927_PCM_RX_CH0_EN | MAX98927_PCM_RX_CH1_EN,
209                         MAX98927_PCM_RX_CH0_EN | MAX98927_PCM_RX_CH1_EN);
210 
211                 regmap_update_bits(max98927->regmap,
212                         MAX98927_R0020_PCM_MODE_CFG,
213                         MAX98927_PCM_MODE_CFG_FORMAT_MASK,
214                         format << MAX98927_PCM_MODE_CFG_FORMAT_SHIFT);
215 
216                 regmap_update_bits(max98927->regmap,
217                         MAX98927_R003B_SPK_SRC_SEL,
218                         MAX98927_SPK_SRC_MASK, 0);
219 
220         } else
221                 regmap_update_bits(max98927->regmap,
222                         MAX98927_R0018_PCM_RX_EN_A,
223                         MAX98927_PCM_RX_CH0_EN | MAX98927_PCM_RX_CH1_EN, 0);
224 
225         /* pdm channel configuration */
226         if (max98927->iface & SND_SOC_DAIFMT_PDM) {
227                 regmap_update_bits(max98927->regmap,
228                         MAX98927_R0035_PDM_RX_CTRL,
229                         MAX98927_PDM_RX_EN_MASK, 1);
230 
231                 regmap_update_bits(max98927->regmap,
232                         MAX98927_R003B_SPK_SRC_SEL,
233                         MAX98927_SPK_SRC_MASK, 3);
234         } else
235                 regmap_update_bits(max98927->regmap,
236                         MAX98927_R0035_PDM_RX_CTRL,
237                         MAX98927_PDM_RX_EN_MASK, 0);
238         return 0;
239 }
240 
241 /* codec MCLK rate in master mode */
242 static const int rate_table[] = {
243         5644800, 6000000, 6144000, 6500000,
244         9600000, 11289600, 12000000, 12288000,
245         13000000, 19200000,
246 };
247 
248 static int max98927_set_clock(struct max98927_priv *max98927,
249         struct snd_pcm_hw_params *params)
250 {
251         struct snd_soc_codec *codec = max98927->codec;
252         /* BCLK/LRCLK ratio calculation */
253         int blr_clk_ratio = params_channels(params) * max98927->ch_size;
254         int value;
255 
256         if (max98927->master) {
257                 int i;
258                 /* match rate to closest value */
259                 for (i = 0; i < ARRAY_SIZE(rate_table); i++) {
260                         if (rate_table[i] >= max98927->sysclk)
261                                 break;
262                 }
263                 if (i == ARRAY_SIZE(rate_table)) {
264                         dev_err(codec->dev, "failed to find proper clock rate.\n");
265                         return -EINVAL;
266                 }
267                 regmap_update_bits(max98927->regmap,
268                         MAX98927_R0021_PCM_MASTER_MODE,
269                         MAX98927_PCM_MASTER_MODE_MCLK_MASK,
270                         i << MAX98927_PCM_MASTER_MODE_MCLK_RATE_SHIFT);
271         }
272 
273         switch (blr_clk_ratio) {
274         case 32:
275                 value = 2;
276                 break;
277         case 48:
278                 value = 3;
279                 break;
280         case 64:
281                 value = 4;
282                 break;
283         default:
284                 return -EINVAL;
285         }
286         regmap_update_bits(max98927->regmap,
287                 MAX98927_R0022_PCM_CLK_SETUP,
288                 MAX98927_PCM_CLK_SETUP_BSEL_MASK,
289                 value);
290         return 0;
291 }
292 
293 static int max98927_dai_hw_params(struct snd_pcm_substream *substream,
294         struct snd_pcm_hw_params *params,
295         struct snd_soc_dai *dai)
296 {
297         struct snd_soc_codec *codec = dai->codec;
298         struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
299         unsigned int sampling_rate = 0;
300         unsigned int chan_sz = 0;
301 
302         /* pcm mode configuration */
303         switch (snd_pcm_format_width(params_format(params))) {
304         case 16:
305                 chan_sz = MAX98927_PCM_MODE_CFG_CHANSZ_16;
306                 break;
307         case 24:
308                 chan_sz = MAX98927_PCM_MODE_CFG_CHANSZ_24;
309                 break;
310         case 32:
311                 chan_sz = MAX98927_PCM_MODE_CFG_CHANSZ_32;
312                 break;
313         default:
314                 dev_err(codec->dev, "format unsupported %d",
315                         params_format(params));
316                 goto err;
317         }
318 
319         max98927->ch_size = snd_pcm_format_width(params_format(params));
320 
321         regmap_update_bits(max98927->regmap,
322                 MAX98927_R0020_PCM_MODE_CFG,
323                 MAX98927_PCM_MODE_CFG_CHANSZ_MASK, chan_sz);
324 
325         dev_dbg(codec->dev, "format supported %d",
326                 params_format(params));
327 
328         /* sampling rate configuration */
329         switch (params_rate(params)) {
330         case 8000:
331                 sampling_rate = MAX98927_PCM_SR_SET1_SR_8000;
332                 break;
333         case 11025:
334                 sampling_rate = MAX98927_PCM_SR_SET1_SR_11025;
335                 break;
336         case 12000:
337                 sampling_rate = MAX98927_PCM_SR_SET1_SR_12000;
338                 break;
339         case 16000:
340                 sampling_rate = MAX98927_PCM_SR_SET1_SR_16000;
341                 break;
342         case 22050:
343                 sampling_rate = MAX98927_PCM_SR_SET1_SR_22050;
344                 break;
345         case 24000:
346                 sampling_rate = MAX98927_PCM_SR_SET1_SR_24000;
347                 break;
348         case 32000:
349                 sampling_rate = MAX98927_PCM_SR_SET1_SR_32000;
350                 break;
351         case 44100:
352                 sampling_rate = MAX98927_PCM_SR_SET1_SR_44100;
353                 break;
354         case 48000:
355                 sampling_rate = MAX98927_PCM_SR_SET1_SR_48000;
356                 break;
357         default:
358                 dev_err(codec->dev, "rate %d not supported\n",
359                         params_rate(params));
360                 goto err;
361         }
362         /* set DAI_SR to correct LRCLK frequency */
363         regmap_update_bits(max98927->regmap,
364                 MAX98927_R0023_PCM_SR_SETUP1,
365                 MAX98927_PCM_SR_SET1_SR_MASK,
366                 sampling_rate);
367         regmap_update_bits(max98927->regmap,
368                 MAX98927_R0024_PCM_SR_SETUP2,
369                 MAX98927_PCM_SR_SET2_SR_MASK,
370                 sampling_rate << MAX98927_PCM_SR_SET2_SR_SHIFT);
371 
372         /* set sampling rate of IV */
373         if (max98927->interleave_mode &&
374             sampling_rate > MAX98927_PCM_SR_SET1_SR_16000)
375                 regmap_update_bits(max98927->regmap,
376                         MAX98927_R0024_PCM_SR_SETUP2,
377                         MAX98927_PCM_SR_SET2_IVADC_SR_MASK,
378                         sampling_rate - 3);
379         else
380                 regmap_update_bits(max98927->regmap,
381                         MAX98927_R0024_PCM_SR_SETUP2,
382                         MAX98927_PCM_SR_SET2_IVADC_SR_MASK,
383                         sampling_rate);
384         return max98927_set_clock(max98927, params);
385 err:
386         return -EINVAL;
387 }
388 
389 #define MAX98927_RATES SNDRV_PCM_RATE_8000_48000
390 
391 #define MAX98927_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
392         SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
393 
394 static int max98927_dai_set_sysclk(struct snd_soc_dai *dai,
395         int clk_id, unsigned int freq, int dir)
396 {
397         struct snd_soc_codec *codec = dai->codec;
398         struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
399 
400         max98927->sysclk = freq;
401         return 0;
402 }
403 
404 static const struct snd_soc_dai_ops max98927_dai_ops = {
405         .set_sysclk = max98927_dai_set_sysclk,
406         .set_fmt = max98927_dai_set_fmt,
407         .hw_params = max98927_dai_hw_params,
408 };
409 
410 static int max98927_dac_event(struct snd_soc_dapm_widget *w,
411         struct snd_kcontrol *kcontrol, int event)
412 {
413         struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
414         struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
415 
416         switch (event) {
417         case SND_SOC_DAPM_POST_PMU:
418                 regmap_update_bits(max98927->regmap,
419                         MAX98927_R003A_AMP_EN,
420                         MAX98927_AMP_EN_MASK, 1);
421                 /* enable VMON and IMON */
422                 regmap_update_bits(max98927->regmap,
423                         MAX98927_R003E_MEAS_EN,
424                         MAX98927_MEAS_V_EN | MAX98927_MEAS_I_EN,
425                         MAX98927_MEAS_V_EN | MAX98927_MEAS_I_EN);
426                 regmap_update_bits(max98927->regmap,
427                         MAX98927_R00FF_GLOBAL_SHDN,
428                         MAX98927_GLOBAL_EN_MASK, 1);
429                 break;
430         case SND_SOC_DAPM_POST_PMD:
431                 regmap_update_bits(max98927->regmap,
432                         MAX98927_R00FF_GLOBAL_SHDN,
433                         MAX98927_GLOBAL_EN_MASK, 0);
434                 regmap_update_bits(max98927->regmap,
435                         MAX98927_R003A_AMP_EN,
436                         MAX98927_AMP_EN_MASK, 0);
437                 /* disable VMON and IMON */
438                 regmap_update_bits(max98927->regmap,
439                         MAX98927_R003E_MEAS_EN,
440                         MAX98927_MEAS_V_EN | MAX98927_MEAS_I_EN, 0);
441                 break;
442         default:
443                 return 0;
444         }
445         return 0;
446 }
447 
448 static const char * const max98927_switch_text[] = {
449         "Left", "Right", "LeftRight"};
450 
451 static const struct soc_enum dai_sel_enum =
452         SOC_ENUM_SINGLE(MAX98927_R0025_PCM_TO_SPK_MONOMIX_A,
453                 MAX98927_PCM_TO_SPK_MONOMIX_CFG_SHIFT,
454                 3, max98927_switch_text);
455 
456 static const struct snd_kcontrol_new max98927_dai_controls =
457         SOC_DAPM_ENUM("DAI Sel", dai_sel_enum);
458 
459 static const struct snd_soc_dapm_widget max98927_dapm_widgets[] = {
460         SND_SOC_DAPM_AIF_IN("DAI_OUT", "HiFi Playback", 0, SND_SOC_NOPM, 0, 0),
461         SND_SOC_DAPM_DAC_E("Amp Enable", "HiFi Playback", MAX98927_R003A_AMP_EN,
462                 0, 0, max98927_dac_event,
463                 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
464         SND_SOC_DAPM_MUX("DAI Sel Mux", SND_SOC_NOPM, 0, 0,
465                 &max98927_dai_controls),
466         SND_SOC_DAPM_OUTPUT("BE_OUT"),
467 };
468 
469 static DECLARE_TLV_DB_SCALE(max98927_spk_tlv, 300, 300, 0);
470 static DECLARE_TLV_DB_SCALE(max98927_digital_tlv, -1600, 25, 0);
471 
472 static bool max98927_readable_register(struct device *dev, unsigned int reg)
473 {
474         switch (reg) {
475         case MAX98927_R0001_INT_RAW1 ... MAX98927_R0028_ICC_RX_EN_B:
476         case MAX98927_R002B_ICC_TX_EN_A ... MAX98927_R002C_ICC_TX_EN_B:
477         case MAX98927_R002E_ICC_HIZ_MANUAL_MODE
478                 ... MAX98927_R004E_MEAS_ADC_CH2_READ:
479         case MAX98927_R0051_BROWNOUT_STATUS
480                 ... MAX98927_R0055_BROWNOUT_LVL_HOLD:
481         case MAX98927_R005A_BROWNOUT_LVL1_THRESH
482                 ... MAX98927_R0061_BROWNOUT_AMP1_CLIP_MODE:
483         case MAX98927_R0072_BROWNOUT_LVL1_CUR_LIMIT
484                 ... MAX98927_R0087_ENV_TRACK_BOOST_VOUT_READ:
485         case MAX98927_R00FF_GLOBAL_SHDN:
486         case MAX98927_R0100_SOFT_RESET:
487         case MAX98927_R01FF_REV_ID:
488                 return true;
489         default:
490                 return false;
491         }
492 };
493 
494 static bool max98927_volatile_reg(struct device *dev, unsigned int reg)
495 {
496         switch (reg) {
497         case MAX98927_R0001_INT_RAW1 ... MAX98927_R0009_INT_FLAG3:
498                 return true;
499         default:
500                 return false;
501         }
502 }
503 
504 static const char * const max98927_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(max98927_boost_voltage,
512                 MAX98927_R0040_BOOST_CTRL0, 0,
513                 max98927_boost_voltage_text);
514 
515 static const char * const max98927_current_limit_text[] = {
516         "1.00A", "1.10A", "1.20A", "1.30A", "1.40A", "1.50A", "1.60A", "1.70A",
517         "1.80A", "1.90A", "2.00A", "2.10A", "2.20A", "2.30A", "2.40A", "2.50A",
518         "2.60A", "2.70A", "2.80A", "2.90A", "3.00A", "3.10A", "3.20A", "3.30A",
519         "3.40A", "3.50A", "3.60A", "3.70A", "3.80A", "3.90A", "4.00A", "4.10A"
520 };
521 
522 static SOC_ENUM_SINGLE_DECL(max98927_current_limit,
523                 MAX98927_R0042_BOOST_CTRL1, 1,
524                 max98927_current_limit_text);
525 
526 static const struct snd_kcontrol_new max98927_snd_controls[] = {
527         SOC_SINGLE_TLV("Speaker Volume", MAX98927_R003C_SPK_GAIN,
528                 0, 6, 0,
529                 max98927_spk_tlv),
530         SOC_SINGLE_TLV("Digital Volume", MAX98927_R0036_AMP_VOL_CTRL,
531                 0, (1<<MAX98927_AMP_VOL_WIDTH)-1, 0,
532                 max98927_digital_tlv),
533         SOC_SINGLE("Amp DSP Switch", MAX98927_R0052_BROWNOUT_EN,
534                 MAX98927_BROWNOUT_DSP_SHIFT, 1, 0),
535         SOC_SINGLE("Ramp Switch", MAX98927_R0037_AMP_DSP_CFG,
536                 MAX98927_AMP_DSP_CFG_RMP_SHIFT, 1, 0),
537         SOC_SINGLE("DRE Switch", MAX98927_R0039_DRE_CTRL,
538                 MAX98927_DRE_EN_SHIFT, 1, 0),
539         SOC_SINGLE("Volume Location Switch", MAX98927_R0036_AMP_VOL_CTRL,
540                 MAX98927_AMP_VOL_SEL_SHIFT, 1, 0),
541         SOC_ENUM("Boost Output Voltage", max98927_boost_voltage),
542         SOC_ENUM("Current Limit", max98927_current_limit),
543 };
544 
545 static const struct snd_soc_dapm_route max98927_audio_map[] = {
546         {"Amp Enable", NULL, "DAI_OUT"},
547         {"DAI Sel Mux", "Left", "Amp Enable"},
548         {"DAI Sel Mux", "Right", "Amp Enable"},
549         {"DAI Sel Mux", "LeftRight", "Amp Enable"},
550         {"BE_OUT", NULL, "DAI Sel Mux"},
551 };
552 
553 static struct snd_soc_dai_driver max98927_dai[] = {
554         {
555                 .name = "max98927-aif1",
556                 .playback = {
557                         .stream_name = "HiFi Playback",
558                         .channels_min = 1,
559                         .channels_max = 2,
560                         .rates = MAX98927_RATES,
561                         .formats = MAX98927_FORMATS,
562                 },
563                 .capture = {
564                         .stream_name = "HiFi Capture",
565                         .channels_min = 1,
566                         .channels_max = 2,
567                         .rates = MAX98927_RATES,
568                         .formats = MAX98927_FORMATS,
569                 },
570                 .ops = &max98927_dai_ops,
571         }
572 };
573 
574 static int max98927_probe(struct snd_soc_codec *codec)
575 {
576         struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
577 
578         max98927->codec = codec;
579         codec->control_data = max98927->regmap;
580         codec->cache_bypass = 1;
581 
582         /* Software Reset */
583         regmap_write(max98927->regmap,
584                 MAX98927_R0100_SOFT_RESET, MAX98927_SOFT_RESET);
585 
586         /* IV default slot configuration */
587         regmap_write(max98927->regmap,
588                 MAX98927_R001C_PCM_TX_HIZ_CTRL_A,
589                 0xFF);
590         regmap_write(max98927->regmap,
591                 MAX98927_R001D_PCM_TX_HIZ_CTRL_B,
592                 0xFF);
593         regmap_write(max98927->regmap,
594                 MAX98927_R0025_PCM_TO_SPK_MONOMIX_A,
595                 0x80);
596         regmap_write(max98927->regmap,
597                 MAX98927_R0026_PCM_TO_SPK_MONOMIX_B,
598                 0x1);
599         /* Set inital volume (+13dB) */
600         regmap_write(max98927->regmap,
601                 MAX98927_R0036_AMP_VOL_CTRL,
602                 0x38);
603         regmap_write(max98927->regmap,
604                 MAX98927_R003C_SPK_GAIN,
605                 0x05);
606         /* Enable DC blocker */
607         regmap_write(max98927->regmap,
608                 MAX98927_R0037_AMP_DSP_CFG,
609                 0x03);
610         /* Enable IMON VMON DC blocker */
611         regmap_write(max98927->regmap,
612                 MAX98927_R003F_MEAS_DSP_CFG,
613                 0xF7);
614         /* Boost Output Voltage & Current limit */
615         regmap_write(max98927->regmap,
616                 MAX98927_R0040_BOOST_CTRL0,
617                 0x1C);
618         regmap_write(max98927->regmap,
619                 MAX98927_R0042_BOOST_CTRL1,
620                 0x3E);
621         /* Measurement ADC config */
622         regmap_write(max98927->regmap,
623                 MAX98927_R0043_MEAS_ADC_CFG,
624                 0x04);
625         regmap_write(max98927->regmap,
626                 MAX98927_R0044_MEAS_ADC_BASE_MSB,
627                 0x00);
628         regmap_write(max98927->regmap,
629                 MAX98927_R0045_MEAS_ADC_BASE_LSB,
630                 0x24);
631         /* Brownout Level */
632         regmap_write(max98927->regmap,
633                 MAX98927_R007F_BROWNOUT_LVL4_AMP1_CTRL1,
634                 0x06);
635         /* Envelope Tracking configuration */
636         regmap_write(max98927->regmap,
637                 MAX98927_R0082_ENV_TRACK_VOUT_HEADROOM,
638                 0x08);
639         regmap_write(max98927->regmap,
640                 MAX98927_R0086_ENV_TRACK_CTRL,
641                 0x01);
642         regmap_write(max98927->regmap,
643                 MAX98927_R0087_ENV_TRACK_BOOST_VOUT_READ,
644                 0x10);
645 
646         /* voltage, current slot configuration */
647         regmap_write(max98927->regmap,
648                 MAX98927_R001E_PCM_TX_CH_SRC_A,
649                 (max98927->i_l_slot<<MAX98927_PCM_TX_CH_SRC_A_I_SHIFT|
650                 max98927->v_l_slot)&0xFF);
651 
652         if (max98927->v_l_slot < 8) {
653                 regmap_update_bits(max98927->regmap,
654                         MAX98927_R001C_PCM_TX_HIZ_CTRL_A,
655                         1 << max98927->v_l_slot, 0);
656                 regmap_update_bits(max98927->regmap,
657                         MAX98927_R001A_PCM_TX_EN_A,
658                         1 << max98927->v_l_slot,
659                         1 << max98927->v_l_slot);
660         } else {
661                 regmap_update_bits(max98927->regmap,
662                         MAX98927_R001D_PCM_TX_HIZ_CTRL_B,
663                         1 << (max98927->v_l_slot - 8), 0);
664                 regmap_update_bits(max98927->regmap,
665                         MAX98927_R001B_PCM_TX_EN_B,
666                         1 << (max98927->v_l_slot - 8),
667                         1 << (max98927->v_l_slot - 8));
668         }
669 
670         if (max98927->i_l_slot < 8) {
671                 regmap_update_bits(max98927->regmap,
672                         MAX98927_R001C_PCM_TX_HIZ_CTRL_A,
673                         1 << max98927->i_l_slot, 0);
674                 regmap_update_bits(max98927->regmap,
675                         MAX98927_R001A_PCM_TX_EN_A,
676                         1 << max98927->i_l_slot,
677                         1 << max98927->i_l_slot);
678         } else {
679                 regmap_update_bits(max98927->regmap,
680                         MAX98927_R001D_PCM_TX_HIZ_CTRL_B,
681                         1 << (max98927->i_l_slot - 8), 0);
682                 regmap_update_bits(max98927->regmap,
683                         MAX98927_R001B_PCM_TX_EN_B,
684                         1 << (max98927->i_l_slot - 8),
685                         1 << (max98927->i_l_slot - 8));
686         }
687 
688         /* Set interleave mode */
689         if (max98927->interleave_mode)
690                 regmap_update_bits(max98927->regmap,
691                         MAX98927_R001F_PCM_TX_CH_SRC_B,
692                         MAX98927_PCM_TX_CH_INTERLEAVE_MASK,
693                         MAX98927_PCM_TX_CH_INTERLEAVE_MASK);
694         return 0;
695 }
696 
697 static const struct snd_soc_codec_driver soc_codec_dev_max98927 = {
698         .probe = max98927_probe,
699         .component_driver = {
700                 .controls = max98927_snd_controls,
701                 .num_controls = ARRAY_SIZE(max98927_snd_controls),
702                 .dapm_widgets = max98927_dapm_widgets,
703                 .num_dapm_widgets = ARRAY_SIZE(max98927_dapm_widgets),
704                 .dapm_routes = max98927_audio_map,
705                 .num_dapm_routes = ARRAY_SIZE(max98927_audio_map),
706         },
707 };
708 
709 static const struct regmap_config max98927_regmap = {
710         .reg_bits         = 16,
711         .val_bits         = 8,
712         .max_register     = MAX98927_R01FF_REV_ID,
713         .reg_defaults     = max98927_reg,
714         .num_reg_defaults = ARRAY_SIZE(max98927_reg),
715         .readable_reg     = max98927_readable_register,
716         .volatile_reg     = max98927_volatile_reg,
717         .cache_type       = REGCACHE_RBTREE,
718 };
719 
720 static void max98927_slot_config(struct i2c_client *i2c,
721         struct max98927_priv *max98927)
722 {
723         int value;
724 
725         if (!of_property_read_u32(i2c->dev.of_node,
726                 "vmon-slot-no", &value))
727                 max98927->v_l_slot = value & 0xF;
728         else
729                 max98927->v_l_slot = 0;
730         if (!of_property_read_u32(i2c->dev.of_node,
731                 "imon-slot-no", &value))
732                 max98927->i_l_slot = value & 0xF;
733         else
734                 max98927->i_l_slot = 1;
735 }
736 
737 static int max98927_i2c_probe(struct i2c_client *i2c,
738         const struct i2c_device_id *id)
739 {
740 
741         int ret = 0, value;
742         int reg = 0;
743         struct max98927_priv *max98927 = NULL;
744 
745         max98927 = devm_kzalloc(&i2c->dev,
746                 sizeof(*max98927), GFP_KERNEL);
747 
748         if (!max98927) {
749                 ret = -ENOMEM;
750                 return ret;
751         }
752         i2c_set_clientdata(i2c, max98927);
753 
754         /* update interleave mode info */
755         if (!of_property_read_u32(i2c->dev.of_node,
756                 "interleave_mode", &value)) {
757                 if (value > 0)
758                         max98927->interleave_mode = 1;
759                 else
760                         max98927->interleave_mode = 0;
761         } else
762                 max98927->interleave_mode = 0;
763 
764         /* regmap initialization */
765         max98927->regmap
766                 = devm_regmap_init_i2c(i2c, &max98927_regmap);
767         if (IS_ERR(max98927->regmap)) {
768                 ret = PTR_ERR(max98927->regmap);
769                 dev_err(&i2c->dev,
770                         "Failed to allocate regmap: %d\n", ret);
771                 return ret;
772         }
773 
774         /* Check Revision ID */
775         ret = regmap_read(max98927->regmap,
776                 MAX98927_R01FF_REV_ID, &reg);
777         if (ret < 0) {
778                 dev_err(&i2c->dev,
779                         "Failed to read: 0x%02X\n", MAX98927_R01FF_REV_ID);
780                 return ret;
781         }
782         dev_info(&i2c->dev, "MAX98927 revisionID: 0x%02X\n", reg);
783 
784         /* voltage/current slot configuration */
785         max98927_slot_config(i2c, max98927);
786 
787         /* codec registeration */
788         ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_max98927,
789                 max98927_dai, ARRAY_SIZE(max98927_dai));
790         if (ret < 0)
791                 dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
792 
793         return ret;
794 }
795 
796 static int max98927_i2c_remove(struct i2c_client *client)
797 {
798         snd_soc_unregister_codec(&client->dev);
799         return 0;
800 }
801 
802 static const struct i2c_device_id max98927_i2c_id[] = {
803         { "max98927", 0},
804         { },
805 };
806 
807 MODULE_DEVICE_TABLE(i2c, max98927_i2c_id);
808 
809 #if defined(CONFIG_OF)
810 static const struct of_device_id max98927_of_match[] = {
811         { .compatible = "maxim,max98927", },
812         { }
813 };
814 MODULE_DEVICE_TABLE(of, max98927_of_match);
815 #endif
816 
817 #ifdef CONFIG_ACPI
818 static const struct acpi_device_id max98927_acpi_match[] = {
819         { "MX98927", 0 },
820         {},
821 };
822 MODULE_DEVICE_TABLE(acpi, max98927_acpi_match);
823 #endif
824 
825 static struct i2c_driver max98927_i2c_driver = {
826         .driver = {
827                 .name = "max98927",
828                 .of_match_table = of_match_ptr(max98927_of_match),
829                 .acpi_match_table = ACPI_PTR(max98927_acpi_match),
830                 .pm = NULL,
831         },
832         .probe  = max98927_i2c_probe,
833         .remove = max98927_i2c_remove,
834         .id_table = max98927_i2c_id,
835 };
836 
837 module_i2c_driver(max98927_i2c_driver)
838 
839 MODULE_DESCRIPTION("ALSA SoC MAX98927 driver");
840 MODULE_AUTHOR("Ryan Lee <ryans.lee@maximintegrated.com>");
841 MODULE_LICENSE("GPL");
842 

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

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | 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.

osdn.jp