blob: caf5340ca6bbc3f31c47f02a5f7818e418f4ed4f [file] [log] [blame]
Ryan Lee7c0c2002017-04-04 02:23:08 +09001/*
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
27static 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},
Ryan Lee848844b2017-08-28 16:30:58 -070047 {MAX98927_R0014_MEAS_ADC_THERM_WARN_THRESH, 0x75},
48 {MAX98927_R0015_MEAS_ADC_THERM_SHDN_THRESH, 0x8c},
49 {MAX98927_R0016_MEAS_ADC_THERM_HYSTERESIS, 0x08},
Ryan Lee7c0c2002017-04-04 02:23:08 +090050 {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},
Ryan Lee848844b2017-08-28 16:30:58 -070085 {MAX98927_R003D_SSM_CFG, 0x04},
Ryan Lee7c0c2002017-04-04 02:23:08 +090086 {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},
Ryan Lee848844b2017-08-28 16:30:58 -070092 {MAX98927_R0044_MEAS_ADC_BASE_MSB, 0x01},
Ryan Lee7c0c2002017-04-04 02:23:08 +090093 {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
143static 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:
Ryan Lee01c6f1b2017-08-28 16:30:56 -0700162 dev_err(codec->dev, "DAI clock mode unsupported\n");
Ryan Lee7c0c2002017-04-04 02:23:08 +0900163 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:
Ryan Lee01c6f1b2017-08-28 16:30:56 -0700178 dev_err(codec->dev, "DAI invert mode unsupported\n");
Ryan Lee7c0c2002017-04-04 02:23:08 +0900179 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 */
242static const int rate_table[] = {
243 5644800, 6000000, 6144000, 6500000,
244 9600000, 11289600, 12000000, 12288000,
245 13000000, 19200000,
246};
247
248static 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
293static 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:
Ryan Lee01c6f1b2017-08-28 16:30:56 -0700314 dev_err(codec->dev, "format unsupported %d\n",
Ryan Lee7c0c2002017-04-04 02:23:08 +0900315 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);
385err:
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
394static 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
404static 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
410static 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
448static const char * const max98927_switch_text[] = {
449 "Left", "Right", "LeftRight"};
450
451static 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
456static const struct snd_kcontrol_new max98927_dai_controls =
457 SOC_DAPM_ENUM("DAI Sel", dai_sel_enum);
458
459static 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
469static DECLARE_TLV_DB_SCALE(max98927_spk_tlv, 300, 300, 0);
470static DECLARE_TLV_DB_SCALE(max98927_digital_tlv, -1600, 25, 0);
471
472static 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
494static bool max98927_volatile_reg(struct device *dev, unsigned int reg)
495{
496 switch (reg) {
497 case MAX98927_R0001_INT_RAW1 ... MAX98927_R0009_INT_FLAG3:
Ryan Lee9c1743e2017-08-28 16:30:55 -0700498 case MAX98927_R004C_MEAS_ADC_CH0_READ:
499 case MAX98927_R004D_MEAS_ADC_CH1_READ:
500 case MAX98927_R004E_MEAS_ADC_CH2_READ:
501 case MAX98927_R0051_BROWNOUT_STATUS:
502 case MAX98927_R0087_ENV_TRACK_BOOST_VOUT_READ:
503 case MAX98927_R01FF_REV_ID:
504 case MAX98927_R0100_SOFT_RESET:
Ryan Lee7c0c2002017-04-04 02:23:08 +0900505 return true;
506 default:
507 return false;
508 }
509}
510
511static const char * const max98927_boost_voltage_text[] = {
512 "6.5V", "6.625V", "6.75V", "6.875V", "7V", "7.125V", "7.25V", "7.375V",
513 "7.5V", "7.625V", "7.75V", "7.875V", "8V", "8.125V", "8.25V", "8.375V",
514 "8.5V", "8.625V", "8.75V", "8.875V", "9V", "9.125V", "9.25V", "9.375V",
515 "9.5V", "9.625V", "9.75V", "9.875V", "10V"
516};
517
518static SOC_ENUM_SINGLE_DECL(max98927_boost_voltage,
519 MAX98927_R0040_BOOST_CTRL0, 0,
520 max98927_boost_voltage_text);
521
522static const char * const max98927_current_limit_text[] = {
523 "1.00A", "1.10A", "1.20A", "1.30A", "1.40A", "1.50A", "1.60A", "1.70A",
524 "1.80A", "1.90A", "2.00A", "2.10A", "2.20A", "2.30A", "2.40A", "2.50A",
525 "2.60A", "2.70A", "2.80A", "2.90A", "3.00A", "3.10A", "3.20A", "3.30A",
526 "3.40A", "3.50A", "3.60A", "3.70A", "3.80A", "3.90A", "4.00A", "4.10A"
527};
528
529static SOC_ENUM_SINGLE_DECL(max98927_current_limit,
530 MAX98927_R0042_BOOST_CTRL1, 1,
531 max98927_current_limit_text);
532
533static const struct snd_kcontrol_new max98927_snd_controls[] = {
534 SOC_SINGLE_TLV("Speaker Volume", MAX98927_R003C_SPK_GAIN,
535 0, 6, 0,
536 max98927_spk_tlv),
537 SOC_SINGLE_TLV("Digital Volume", MAX98927_R0036_AMP_VOL_CTRL,
538 0, (1<<MAX98927_AMP_VOL_WIDTH)-1, 0,
539 max98927_digital_tlv),
540 SOC_SINGLE("Amp DSP Switch", MAX98927_R0052_BROWNOUT_EN,
541 MAX98927_BROWNOUT_DSP_SHIFT, 1, 0),
542 SOC_SINGLE("Ramp Switch", MAX98927_R0037_AMP_DSP_CFG,
543 MAX98927_AMP_DSP_CFG_RMP_SHIFT, 1, 0),
544 SOC_SINGLE("DRE Switch", MAX98927_R0039_DRE_CTRL,
545 MAX98927_DRE_EN_SHIFT, 1, 0),
546 SOC_SINGLE("Volume Location Switch", MAX98927_R0036_AMP_VOL_CTRL,
547 MAX98927_AMP_VOL_SEL_SHIFT, 1, 0),
548 SOC_ENUM("Boost Output Voltage", max98927_boost_voltage),
549 SOC_ENUM("Current Limit", max98927_current_limit),
550};
551
552static const struct snd_soc_dapm_route max98927_audio_map[] = {
553 {"Amp Enable", NULL, "DAI_OUT"},
554 {"DAI Sel Mux", "Left", "Amp Enable"},
555 {"DAI Sel Mux", "Right", "Amp Enable"},
556 {"DAI Sel Mux", "LeftRight", "Amp Enable"},
557 {"BE_OUT", NULL, "DAI Sel Mux"},
558};
559
560static struct snd_soc_dai_driver max98927_dai[] = {
561 {
562 .name = "max98927-aif1",
563 .playback = {
564 .stream_name = "HiFi Playback",
565 .channels_min = 1,
566 .channels_max = 2,
567 .rates = MAX98927_RATES,
568 .formats = MAX98927_FORMATS,
569 },
570 .capture = {
571 .stream_name = "HiFi Capture",
572 .channels_min = 1,
573 .channels_max = 2,
574 .rates = MAX98927_RATES,
575 .formats = MAX98927_FORMATS,
576 },
577 .ops = &max98927_dai_ops,
578 }
579};
580
581static int max98927_probe(struct snd_soc_codec *codec)
582{
583 struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
584
585 max98927->codec = codec;
586 codec->control_data = max98927->regmap;
587 codec->cache_bypass = 1;
588
589 /* Software Reset */
590 regmap_write(max98927->regmap,
591 MAX98927_R0100_SOFT_RESET, MAX98927_SOFT_RESET);
592
593 /* IV default slot configuration */
594 regmap_write(max98927->regmap,
595 MAX98927_R001C_PCM_TX_HIZ_CTRL_A,
596 0xFF);
597 regmap_write(max98927->regmap,
598 MAX98927_R001D_PCM_TX_HIZ_CTRL_B,
599 0xFF);
600 regmap_write(max98927->regmap,
601 MAX98927_R0025_PCM_TO_SPK_MONOMIX_A,
602 0x80);
603 regmap_write(max98927->regmap,
604 MAX98927_R0026_PCM_TO_SPK_MONOMIX_B,
605 0x1);
606 /* Set inital volume (+13dB) */
607 regmap_write(max98927->regmap,
608 MAX98927_R0036_AMP_VOL_CTRL,
609 0x38);
610 regmap_write(max98927->regmap,
611 MAX98927_R003C_SPK_GAIN,
612 0x05);
613 /* Enable DC blocker */
614 regmap_write(max98927->regmap,
615 MAX98927_R0037_AMP_DSP_CFG,
616 0x03);
617 /* Enable IMON VMON DC blocker */
618 regmap_write(max98927->regmap,
619 MAX98927_R003F_MEAS_DSP_CFG,
620 0xF7);
621 /* Boost Output Voltage & Current limit */
622 regmap_write(max98927->regmap,
623 MAX98927_R0040_BOOST_CTRL0,
624 0x1C);
625 regmap_write(max98927->regmap,
626 MAX98927_R0042_BOOST_CTRL1,
627 0x3E);
628 /* Measurement ADC config */
629 regmap_write(max98927->regmap,
630 MAX98927_R0043_MEAS_ADC_CFG,
631 0x04);
632 regmap_write(max98927->regmap,
633 MAX98927_R0044_MEAS_ADC_BASE_MSB,
634 0x00);
635 regmap_write(max98927->regmap,
636 MAX98927_R0045_MEAS_ADC_BASE_LSB,
637 0x24);
638 /* Brownout Level */
639 regmap_write(max98927->regmap,
640 MAX98927_R007F_BROWNOUT_LVL4_AMP1_CTRL1,
641 0x06);
642 /* Envelope Tracking configuration */
643 regmap_write(max98927->regmap,
644 MAX98927_R0082_ENV_TRACK_VOUT_HEADROOM,
645 0x08);
646 regmap_write(max98927->regmap,
647 MAX98927_R0086_ENV_TRACK_CTRL,
648 0x01);
649 regmap_write(max98927->regmap,
650 MAX98927_R0087_ENV_TRACK_BOOST_VOUT_READ,
651 0x10);
652
653 /* voltage, current slot configuration */
654 regmap_write(max98927->regmap,
655 MAX98927_R001E_PCM_TX_CH_SRC_A,
656 (max98927->i_l_slot<<MAX98927_PCM_TX_CH_SRC_A_I_SHIFT|
657 max98927->v_l_slot)&0xFF);
658
659 if (max98927->v_l_slot < 8) {
660 regmap_update_bits(max98927->regmap,
661 MAX98927_R001C_PCM_TX_HIZ_CTRL_A,
662 1 << max98927->v_l_slot, 0);
663 regmap_update_bits(max98927->regmap,
664 MAX98927_R001A_PCM_TX_EN_A,
665 1 << max98927->v_l_slot,
666 1 << max98927->v_l_slot);
667 } else {
668 regmap_update_bits(max98927->regmap,
669 MAX98927_R001D_PCM_TX_HIZ_CTRL_B,
670 1 << (max98927->v_l_slot - 8), 0);
671 regmap_update_bits(max98927->regmap,
672 MAX98927_R001B_PCM_TX_EN_B,
673 1 << (max98927->v_l_slot - 8),
674 1 << (max98927->v_l_slot - 8));
675 }
676
677 if (max98927->i_l_slot < 8) {
678 regmap_update_bits(max98927->regmap,
679 MAX98927_R001C_PCM_TX_HIZ_CTRL_A,
680 1 << max98927->i_l_slot, 0);
681 regmap_update_bits(max98927->regmap,
682 MAX98927_R001A_PCM_TX_EN_A,
683 1 << max98927->i_l_slot,
684 1 << max98927->i_l_slot);
685 } else {
686 regmap_update_bits(max98927->regmap,
687 MAX98927_R001D_PCM_TX_HIZ_CTRL_B,
688 1 << (max98927->i_l_slot - 8), 0);
689 regmap_update_bits(max98927->regmap,
690 MAX98927_R001B_PCM_TX_EN_B,
691 1 << (max98927->i_l_slot - 8),
692 1 << (max98927->i_l_slot - 8));
693 }
694
695 /* Set interleave mode */
696 if (max98927->interleave_mode)
697 regmap_update_bits(max98927->regmap,
698 MAX98927_R001F_PCM_TX_CH_SRC_B,
699 MAX98927_PCM_TX_CH_INTERLEAVE_MASK,
700 MAX98927_PCM_TX_CH_INTERLEAVE_MASK);
701 return 0;
702}
703
Ryan Leef81991d2017-08-28 16:30:59 -0700704#ifdef CONFIG_PM_SLEEP
705static int max98927_suspend(struct device *dev)
706{
707 struct max98927_priv *max98927 = dev_get_drvdata(dev);
708
709 regcache_cache_only(max98927->regmap, true);
710 regcache_mark_dirty(max98927->regmap);
711 return 0;
712}
713static int max98927_resume(struct device *dev)
714{
715 struct max98927_priv *max98927 = dev_get_drvdata(dev);
716
717 regmap_write(max98927->regmap,
718 MAX98927_R0100_SOFT_RESET, MAX98927_SOFT_RESET);
719 regcache_cache_only(max98927->regmap, false);
720 regcache_sync(max98927->regmap);
721 return 0;
722}
723#endif
724
725static const struct dev_pm_ops max98927_pm = {
726 SET_SYSTEM_SLEEP_PM_OPS(max98927_suspend, max98927_resume)
727};
728
Ryan Lee7c0c2002017-04-04 02:23:08 +0900729static const struct snd_soc_codec_driver soc_codec_dev_max98927 = {
730 .probe = max98927_probe,
731 .component_driver = {
732 .controls = max98927_snd_controls,
733 .num_controls = ARRAY_SIZE(max98927_snd_controls),
734 .dapm_widgets = max98927_dapm_widgets,
735 .num_dapm_widgets = ARRAY_SIZE(max98927_dapm_widgets),
736 .dapm_routes = max98927_audio_map,
737 .num_dapm_routes = ARRAY_SIZE(max98927_audio_map),
738 },
739};
740
741static const struct regmap_config max98927_regmap = {
742 .reg_bits = 16,
743 .val_bits = 8,
744 .max_register = MAX98927_R01FF_REV_ID,
745 .reg_defaults = max98927_reg,
746 .num_reg_defaults = ARRAY_SIZE(max98927_reg),
747 .readable_reg = max98927_readable_register,
748 .volatile_reg = max98927_volatile_reg,
749 .cache_type = REGCACHE_RBTREE,
750};
751
752static void max98927_slot_config(struct i2c_client *i2c,
753 struct max98927_priv *max98927)
754{
755 int value;
756
757 if (!of_property_read_u32(i2c->dev.of_node,
758 "vmon-slot-no", &value))
759 max98927->v_l_slot = value & 0xF;
760 else
761 max98927->v_l_slot = 0;
762 if (!of_property_read_u32(i2c->dev.of_node,
763 "imon-slot-no", &value))
764 max98927->i_l_slot = value & 0xF;
765 else
766 max98927->i_l_slot = 1;
767}
768
769static int max98927_i2c_probe(struct i2c_client *i2c,
770 const struct i2c_device_id *id)
771{
772
773 int ret = 0, value;
774 int reg = 0;
775 struct max98927_priv *max98927 = NULL;
776
777 max98927 = devm_kzalloc(&i2c->dev,
778 sizeof(*max98927), GFP_KERNEL);
779
780 if (!max98927) {
781 ret = -ENOMEM;
782 return ret;
783 }
784 i2c_set_clientdata(i2c, max98927);
785
786 /* update interleave mode info */
787 if (!of_property_read_u32(i2c->dev.of_node,
788 "interleave_mode", &value)) {
789 if (value > 0)
790 max98927->interleave_mode = 1;
791 else
792 max98927->interleave_mode = 0;
793 } else
794 max98927->interleave_mode = 0;
795
796 /* regmap initialization */
797 max98927->regmap
798 = devm_regmap_init_i2c(i2c, &max98927_regmap);
799 if (IS_ERR(max98927->regmap)) {
800 ret = PTR_ERR(max98927->regmap);
801 dev_err(&i2c->dev,
802 "Failed to allocate regmap: %d\n", ret);
803 return ret;
804 }
805
806 /* Check Revision ID */
807 ret = regmap_read(max98927->regmap,
808 MAX98927_R01FF_REV_ID, &reg);
809 if (ret < 0) {
810 dev_err(&i2c->dev,
811 "Failed to read: 0x%02X\n", MAX98927_R01FF_REV_ID);
812 return ret;
813 }
814 dev_info(&i2c->dev, "MAX98927 revisionID: 0x%02X\n", reg);
815
816 /* voltage/current slot configuration */
817 max98927_slot_config(i2c, max98927);
818
819 /* codec registeration */
820 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_max98927,
821 max98927_dai, ARRAY_SIZE(max98927_dai));
822 if (ret < 0)
823 dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
824
825 return ret;
826}
827
828static int max98927_i2c_remove(struct i2c_client *client)
829{
830 snd_soc_unregister_codec(&client->dev);
831 return 0;
832}
833
834static const struct i2c_device_id max98927_i2c_id[] = {
835 { "max98927", 0},
836 { },
837};
838
839MODULE_DEVICE_TABLE(i2c, max98927_i2c_id);
840
841#if defined(CONFIG_OF)
842static const struct of_device_id max98927_of_match[] = {
843 { .compatible = "maxim,max98927", },
844 { }
845};
846MODULE_DEVICE_TABLE(of, max98927_of_match);
847#endif
848
849#ifdef CONFIG_ACPI
850static const struct acpi_device_id max98927_acpi_match[] = {
851 { "MX98927", 0 },
852 {},
853};
854MODULE_DEVICE_TABLE(acpi, max98927_acpi_match);
855#endif
856
857static struct i2c_driver max98927_i2c_driver = {
858 .driver = {
859 .name = "max98927",
860 .of_match_table = of_match_ptr(max98927_of_match),
861 .acpi_match_table = ACPI_PTR(max98927_acpi_match),
Ryan Leef81991d2017-08-28 16:30:59 -0700862 .pm = &max98927_pm,
Ryan Lee7c0c2002017-04-04 02:23:08 +0900863 },
864 .probe = max98927_i2c_probe,
865 .remove = max98927_i2c_remove,
866 .id_table = max98927_i2c_id,
867};
868
869module_i2c_driver(max98927_i2c_driver)
870
871MODULE_DESCRIPTION("ALSA SoC MAX98927 driver");
872MODULE_AUTHOR("Ryan Lee <ryans.lee@maximintegrated.com>");
873MODULE_LICENSE("GPL");