0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/acpi.h>
0010 #include <linux/i2c.h>
0011 #include <linux/module.h>
0012 #include <linux/regmap.h>
0013 #include <linux/slab.h>
0014 #include <linux/cdev.h>
0015 #include <sound/pcm.h>
0016 #include <sound/pcm_params.h>
0017 #include <sound/soc.h>
0018 #include <linux/gpio.h>
0019 #include <linux/gpio/consumer.h>
0020 #include <linux/of_gpio.h>
0021 #include <sound/tlv.h>
0022 #include "max98927.h"
0023
0024 static struct reg_default max98927_reg[] = {
0025 {MAX98927_R0001_INT_RAW1, 0x00},
0026 {MAX98927_R0002_INT_RAW2, 0x00},
0027 {MAX98927_R0003_INT_RAW3, 0x00},
0028 {MAX98927_R0004_INT_STATE1, 0x00},
0029 {MAX98927_R0005_INT_STATE2, 0x00},
0030 {MAX98927_R0006_INT_STATE3, 0x00},
0031 {MAX98927_R0007_INT_FLAG1, 0x00},
0032 {MAX98927_R0008_INT_FLAG2, 0x00},
0033 {MAX98927_R0009_INT_FLAG3, 0x00},
0034 {MAX98927_R000A_INT_EN1, 0x00},
0035 {MAX98927_R000B_INT_EN2, 0x00},
0036 {MAX98927_R000C_INT_EN3, 0x00},
0037 {MAX98927_R000D_INT_FLAG_CLR1, 0x00},
0038 {MAX98927_R000E_INT_FLAG_CLR2, 0x00},
0039 {MAX98927_R000F_INT_FLAG_CLR3, 0x00},
0040 {MAX98927_R0010_IRQ_CTRL, 0x00},
0041 {MAX98927_R0011_CLK_MON, 0x00},
0042 {MAX98927_R0012_WDOG_CTRL, 0x00},
0043 {MAX98927_R0013_WDOG_RST, 0x00},
0044 {MAX98927_R0014_MEAS_ADC_THERM_WARN_THRESH, 0x75},
0045 {MAX98927_R0015_MEAS_ADC_THERM_SHDN_THRESH, 0x8c},
0046 {MAX98927_R0016_MEAS_ADC_THERM_HYSTERESIS, 0x08},
0047 {MAX98927_R0017_PIN_CFG, 0x55},
0048 {MAX98927_R0018_PCM_RX_EN_A, 0x00},
0049 {MAX98927_R0019_PCM_RX_EN_B, 0x00},
0050 {MAX98927_R001A_PCM_TX_EN_A, 0x00},
0051 {MAX98927_R001B_PCM_TX_EN_B, 0x00},
0052 {MAX98927_R001C_PCM_TX_HIZ_CTRL_A, 0x00},
0053 {MAX98927_R001D_PCM_TX_HIZ_CTRL_B, 0x00},
0054 {MAX98927_R001E_PCM_TX_CH_SRC_A, 0x00},
0055 {MAX98927_R001F_PCM_TX_CH_SRC_B, 0x00},
0056 {MAX98927_R0020_PCM_MODE_CFG, 0x40},
0057 {MAX98927_R0021_PCM_MASTER_MODE, 0x00},
0058 {MAX98927_R0022_PCM_CLK_SETUP, 0x22},
0059 {MAX98927_R0023_PCM_SR_SETUP1, 0x00},
0060 {MAX98927_R0024_PCM_SR_SETUP2, 0x00},
0061 {MAX98927_R0025_PCM_TO_SPK_MONOMIX_A, 0x00},
0062 {MAX98927_R0026_PCM_TO_SPK_MONOMIX_B, 0x00},
0063 {MAX98927_R0027_ICC_RX_EN_A, 0x00},
0064 {MAX98927_R0028_ICC_RX_EN_B, 0x00},
0065 {MAX98927_R002B_ICC_TX_EN_A, 0x00},
0066 {MAX98927_R002C_ICC_TX_EN_B, 0x00},
0067 {MAX98927_R002E_ICC_HIZ_MANUAL_MODE, 0x00},
0068 {MAX98927_R002F_ICC_TX_HIZ_EN_A, 0x00},
0069 {MAX98927_R0030_ICC_TX_HIZ_EN_B, 0x00},
0070 {MAX98927_R0031_ICC_LNK_EN, 0x00},
0071 {MAX98927_R0032_PDM_TX_EN, 0x00},
0072 {MAX98927_R0033_PDM_TX_HIZ_CTRL, 0x00},
0073 {MAX98927_R0034_PDM_TX_CTRL, 0x00},
0074 {MAX98927_R0035_PDM_RX_CTRL, 0x00},
0075 {MAX98927_R0036_AMP_VOL_CTRL, 0x00},
0076 {MAX98927_R0037_AMP_DSP_CFG, 0x02},
0077 {MAX98927_R0038_TONE_GEN_DC_CFG, 0x00},
0078 {MAX98927_R0039_DRE_CTRL, 0x01},
0079 {MAX98927_R003A_AMP_EN, 0x00},
0080 {MAX98927_R003B_SPK_SRC_SEL, 0x00},
0081 {MAX98927_R003C_SPK_GAIN, 0x00},
0082 {MAX98927_R003D_SSM_CFG, 0x04},
0083 {MAX98927_R003E_MEAS_EN, 0x00},
0084 {MAX98927_R003F_MEAS_DSP_CFG, 0x04},
0085 {MAX98927_R0040_BOOST_CTRL0, 0x00},
0086 {MAX98927_R0041_BOOST_CTRL3, 0x00},
0087 {MAX98927_R0042_BOOST_CTRL1, 0x00},
0088 {MAX98927_R0043_MEAS_ADC_CFG, 0x00},
0089 {MAX98927_R0044_MEAS_ADC_BASE_MSB, 0x01},
0090 {MAX98927_R0045_MEAS_ADC_BASE_LSB, 0x00},
0091 {MAX98927_R0046_ADC_CH0_DIVIDE, 0x00},
0092 {MAX98927_R0047_ADC_CH1_DIVIDE, 0x00},
0093 {MAX98927_R0048_ADC_CH2_DIVIDE, 0x00},
0094 {MAX98927_R0049_ADC_CH0_FILT_CFG, 0x00},
0095 {MAX98927_R004A_ADC_CH1_FILT_CFG, 0x00},
0096 {MAX98927_R004B_ADC_CH2_FILT_CFG, 0x00},
0097 {MAX98927_R004C_MEAS_ADC_CH0_READ, 0x00},
0098 {MAX98927_R004D_MEAS_ADC_CH1_READ, 0x00},
0099 {MAX98927_R004E_MEAS_ADC_CH2_READ, 0x00},
0100 {MAX98927_R0051_BROWNOUT_STATUS, 0x00},
0101 {MAX98927_R0052_BROWNOUT_EN, 0x00},
0102 {MAX98927_R0053_BROWNOUT_INFINITE_HOLD, 0x00},
0103 {MAX98927_R0054_BROWNOUT_INFINITE_HOLD_CLR, 0x00},
0104 {MAX98927_R0055_BROWNOUT_LVL_HOLD, 0x00},
0105 {MAX98927_R005A_BROWNOUT_LVL1_THRESH, 0x00},
0106 {MAX98927_R005B_BROWNOUT_LVL2_THRESH, 0x00},
0107 {MAX98927_R005C_BROWNOUT_LVL3_THRESH, 0x00},
0108 {MAX98927_R005D_BROWNOUT_LVL4_THRESH, 0x00},
0109 {MAX98927_R005E_BROWNOUT_THRESH_HYSTERYSIS, 0x00},
0110 {MAX98927_R005F_BROWNOUT_AMP_LIMITER_ATK_REL, 0x00},
0111 {MAX98927_R0060_BROWNOUT_AMP_GAIN_ATK_REL, 0x00},
0112 {MAX98927_R0061_BROWNOUT_AMP1_CLIP_MODE, 0x00},
0113 {MAX98927_R0072_BROWNOUT_LVL1_CUR_LIMIT, 0x00},
0114 {MAX98927_R0073_BROWNOUT_LVL1_AMP1_CTRL1, 0x00},
0115 {MAX98927_R0074_BROWNOUT_LVL1_AMP1_CTRL2, 0x00},
0116 {MAX98927_R0075_BROWNOUT_LVL1_AMP1_CTRL3, 0x00},
0117 {MAX98927_R0076_BROWNOUT_LVL2_CUR_LIMIT, 0x00},
0118 {MAX98927_R0077_BROWNOUT_LVL2_AMP1_CTRL1, 0x00},
0119 {MAX98927_R0078_BROWNOUT_LVL2_AMP1_CTRL2, 0x00},
0120 {MAX98927_R0079_BROWNOUT_LVL2_AMP1_CTRL3, 0x00},
0121 {MAX98927_R007A_BROWNOUT_LVL3_CUR_LIMIT, 0x00},
0122 {MAX98927_R007B_BROWNOUT_LVL3_AMP1_CTRL1, 0x00},
0123 {MAX98927_R007C_BROWNOUT_LVL3_AMP1_CTRL2, 0x00},
0124 {MAX98927_R007D_BROWNOUT_LVL3_AMP1_CTRL3, 0x00},
0125 {MAX98927_R007E_BROWNOUT_LVL4_CUR_LIMIT, 0x00},
0126 {MAX98927_R007F_BROWNOUT_LVL4_AMP1_CTRL1, 0x00},
0127 {MAX98927_R0080_BROWNOUT_LVL4_AMP1_CTRL2, 0x00},
0128 {MAX98927_R0081_BROWNOUT_LVL4_AMP1_CTRL3, 0x00},
0129 {MAX98927_R0082_ENV_TRACK_VOUT_HEADROOM, 0x00},
0130 {MAX98927_R0083_ENV_TRACK_BOOST_VOUT_DELAY, 0x00},
0131 {MAX98927_R0084_ENV_TRACK_REL_RATE, 0x00},
0132 {MAX98927_R0085_ENV_TRACK_HOLD_RATE, 0x00},
0133 {MAX98927_R0086_ENV_TRACK_CTRL, 0x00},
0134 {MAX98927_R0087_ENV_TRACK_BOOST_VOUT_READ, 0x00},
0135 {MAX98927_R00FF_GLOBAL_SHDN, 0x00},
0136 {MAX98927_R0100_SOFT_RESET, 0x00},
0137 {MAX98927_R01FF_REV_ID, 0x40},
0138 };
0139
0140 static int max98927_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
0141 {
0142 struct snd_soc_component *component = codec_dai->component;
0143 struct max98927_priv *max98927 = snd_soc_component_get_drvdata(component);
0144 unsigned int mode = 0;
0145 unsigned int format = 0;
0146 bool use_pdm = false;
0147 unsigned int invert = 0;
0148
0149 dev_dbg(component->dev, "%s: fmt 0x%08X\n", __func__, fmt);
0150
0151 switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
0152 case SND_SOC_DAIFMT_CBC_CFC:
0153 max98927->provider = false;
0154 mode = MAX98927_PCM_MASTER_MODE_SLAVE;
0155 break;
0156 case SND_SOC_DAIFMT_CBP_CFP:
0157 max98927->provider = true;
0158 mode = MAX98927_PCM_MASTER_MODE_MASTER;
0159 break;
0160 default:
0161 dev_err(component->dev, "DAI clock mode unsupported\n");
0162 return -EINVAL;
0163 }
0164
0165 regmap_update_bits(max98927->regmap,
0166 MAX98927_R0021_PCM_MASTER_MODE,
0167 MAX98927_PCM_MASTER_MODE_MASK,
0168 mode);
0169
0170 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
0171 case SND_SOC_DAIFMT_NB_NF:
0172 break;
0173 case SND_SOC_DAIFMT_IB_NF:
0174 invert = MAX98927_PCM_MODE_CFG_PCM_BCLKEDGE;
0175 break;
0176 default:
0177 dev_err(component->dev, "DAI invert mode unsupported\n");
0178 return -EINVAL;
0179 }
0180
0181 regmap_update_bits(max98927->regmap,
0182 MAX98927_R0020_PCM_MODE_CFG,
0183 MAX98927_PCM_MODE_CFG_PCM_BCLKEDGE,
0184 invert);
0185
0186
0187 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
0188 case SND_SOC_DAIFMT_I2S:
0189 format = MAX98927_PCM_FORMAT_I2S;
0190 break;
0191 case SND_SOC_DAIFMT_LEFT_J:
0192 format = MAX98927_PCM_FORMAT_LJ;
0193 break;
0194 case SND_SOC_DAIFMT_DSP_A:
0195 format = MAX98927_PCM_FORMAT_TDM_MODE1;
0196 break;
0197 case SND_SOC_DAIFMT_DSP_B:
0198 format = MAX98927_PCM_FORMAT_TDM_MODE0;
0199 break;
0200 case SND_SOC_DAIFMT_PDM:
0201 use_pdm = true;
0202 break;
0203 default:
0204 return -EINVAL;
0205 }
0206 max98927->iface = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
0207
0208 if (!use_pdm) {
0209
0210 regmap_update_bits(max98927->regmap,
0211 MAX98927_R0018_PCM_RX_EN_A,
0212 MAX98927_PCM_RX_CH0_EN | MAX98927_PCM_RX_CH1_EN,
0213 MAX98927_PCM_RX_CH0_EN | MAX98927_PCM_RX_CH1_EN);
0214
0215 regmap_update_bits(max98927->regmap,
0216 MAX98927_R0020_PCM_MODE_CFG,
0217 MAX98927_PCM_MODE_CFG_FORMAT_MASK,
0218 format << MAX98927_PCM_MODE_CFG_FORMAT_SHIFT);
0219
0220 regmap_update_bits(max98927->regmap,
0221 MAX98927_R003B_SPK_SRC_SEL,
0222 MAX98927_SPK_SRC_MASK, 0);
0223
0224 regmap_update_bits(max98927->regmap,
0225 MAX98927_R0035_PDM_RX_CTRL,
0226 MAX98927_PDM_RX_EN_MASK, 0);
0227 } else {
0228
0229 regmap_update_bits(max98927->regmap,
0230 MAX98927_R0035_PDM_RX_CTRL,
0231 MAX98927_PDM_RX_EN_MASK, 1);
0232
0233 regmap_update_bits(max98927->regmap,
0234 MAX98927_R003B_SPK_SRC_SEL,
0235 MAX98927_SPK_SRC_MASK, 3);
0236
0237 regmap_update_bits(max98927->regmap,
0238 MAX98927_R0018_PCM_RX_EN_A,
0239 MAX98927_PCM_RX_CH0_EN | MAX98927_PCM_RX_CH1_EN, 0);
0240 }
0241 return 0;
0242 }
0243
0244
0245 static const int rate_table[] = {
0246 5644800, 6000000, 6144000, 6500000,
0247 9600000, 11289600, 12000000, 12288000,
0248 13000000, 19200000,
0249 };
0250
0251
0252 static const int bclk_sel_table[] = {
0253 32, 48, 64, 96, 128, 192, 256, 384, 512,
0254 };
0255
0256 static int max98927_get_bclk_sel(int bclk)
0257 {
0258 int i;
0259
0260 for (i = 0; i < ARRAY_SIZE(bclk_sel_table); i++) {
0261 if (bclk_sel_table[i] == bclk)
0262 return i + 2;
0263 }
0264 return 0;
0265 }
0266 static int max98927_set_clock(struct max98927_priv *max98927,
0267 struct snd_pcm_hw_params *params)
0268 {
0269 struct snd_soc_component *component = max98927->component;
0270
0271 int blr_clk_ratio = params_channels(params) * max98927->ch_size;
0272 int value;
0273
0274 if (max98927->provider) {
0275 int i;
0276
0277 for (i = 0; i < ARRAY_SIZE(rate_table); i++) {
0278 if (rate_table[i] >= max98927->sysclk)
0279 break;
0280 }
0281 if (i == ARRAY_SIZE(rate_table)) {
0282 dev_err(component->dev, "failed to find proper clock rate.\n");
0283 return -EINVAL;
0284 }
0285 regmap_update_bits(max98927->regmap,
0286 MAX98927_R0021_PCM_MASTER_MODE,
0287 MAX98927_PCM_MASTER_MODE_MCLK_MASK,
0288 i << MAX98927_PCM_MASTER_MODE_MCLK_RATE_SHIFT);
0289 }
0290
0291 if (!max98927->tdm_mode) {
0292
0293 value = max98927_get_bclk_sel(blr_clk_ratio);
0294 if (!value) {
0295 dev_err(component->dev, "format unsupported %d\n",
0296 params_format(params));
0297 return -EINVAL;
0298 }
0299
0300 regmap_update_bits(max98927->regmap,
0301 MAX98927_R0022_PCM_CLK_SETUP,
0302 MAX98927_PCM_CLK_SETUP_BSEL_MASK,
0303 value);
0304 }
0305 return 0;
0306 }
0307
0308 static int max98927_dai_hw_params(struct snd_pcm_substream *substream,
0309 struct snd_pcm_hw_params *params,
0310 struct snd_soc_dai *dai)
0311 {
0312 struct snd_soc_component *component = dai->component;
0313 struct max98927_priv *max98927 = snd_soc_component_get_drvdata(component);
0314 unsigned int sampling_rate = 0;
0315 unsigned int chan_sz = 0;
0316
0317
0318 switch (snd_pcm_format_width(params_format(params))) {
0319 case 16:
0320 chan_sz = MAX98927_PCM_MODE_CFG_CHANSZ_16;
0321 break;
0322 case 24:
0323 chan_sz = MAX98927_PCM_MODE_CFG_CHANSZ_24;
0324 break;
0325 case 32:
0326 chan_sz = MAX98927_PCM_MODE_CFG_CHANSZ_32;
0327 break;
0328 default:
0329 dev_err(component->dev, "format unsupported %d\n",
0330 params_format(params));
0331 goto err;
0332 }
0333
0334 max98927->ch_size = snd_pcm_format_width(params_format(params));
0335
0336 regmap_update_bits(max98927->regmap,
0337 MAX98927_R0020_PCM_MODE_CFG,
0338 MAX98927_PCM_MODE_CFG_CHANSZ_MASK, chan_sz);
0339
0340 dev_dbg(component->dev, "format supported %d",
0341 params_format(params));
0342
0343
0344 switch (params_rate(params)) {
0345 case 8000:
0346 sampling_rate = MAX98927_PCM_SR_SET1_SR_8000;
0347 break;
0348 case 11025:
0349 sampling_rate = MAX98927_PCM_SR_SET1_SR_11025;
0350 break;
0351 case 12000:
0352 sampling_rate = MAX98927_PCM_SR_SET1_SR_12000;
0353 break;
0354 case 16000:
0355 sampling_rate = MAX98927_PCM_SR_SET1_SR_16000;
0356 break;
0357 case 22050:
0358 sampling_rate = MAX98927_PCM_SR_SET1_SR_22050;
0359 break;
0360 case 24000:
0361 sampling_rate = MAX98927_PCM_SR_SET1_SR_24000;
0362 break;
0363 case 32000:
0364 sampling_rate = MAX98927_PCM_SR_SET1_SR_32000;
0365 break;
0366 case 44100:
0367 sampling_rate = MAX98927_PCM_SR_SET1_SR_44100;
0368 break;
0369 case 48000:
0370 sampling_rate = MAX98927_PCM_SR_SET1_SR_48000;
0371 break;
0372 default:
0373 dev_err(component->dev, "rate %d not supported\n",
0374 params_rate(params));
0375 goto err;
0376 }
0377
0378 regmap_update_bits(max98927->regmap,
0379 MAX98927_R0023_PCM_SR_SETUP1,
0380 MAX98927_PCM_SR_SET1_SR_MASK,
0381 sampling_rate);
0382 regmap_update_bits(max98927->regmap,
0383 MAX98927_R0024_PCM_SR_SETUP2,
0384 MAX98927_PCM_SR_SET2_SR_MASK,
0385 sampling_rate << MAX98927_PCM_SR_SET2_SR_SHIFT);
0386
0387
0388 if (max98927->interleave_mode &&
0389 sampling_rate > MAX98927_PCM_SR_SET1_SR_16000)
0390 regmap_update_bits(max98927->regmap,
0391 MAX98927_R0024_PCM_SR_SETUP2,
0392 MAX98927_PCM_SR_SET2_IVADC_SR_MASK,
0393 sampling_rate - 3);
0394 else
0395 regmap_update_bits(max98927->regmap,
0396 MAX98927_R0024_PCM_SR_SETUP2,
0397 MAX98927_PCM_SR_SET2_IVADC_SR_MASK,
0398 sampling_rate);
0399 return max98927_set_clock(max98927, params);
0400 err:
0401 return -EINVAL;
0402 }
0403
0404 static int max98927_dai_tdm_slot(struct snd_soc_dai *dai,
0405 unsigned int tx_mask, unsigned int rx_mask,
0406 int slots, int slot_width)
0407 {
0408 struct snd_soc_component *component = dai->component;
0409 struct max98927_priv *max98927 = snd_soc_component_get_drvdata(component);
0410 int bsel = 0;
0411 unsigned int chan_sz = 0;
0412
0413 max98927->tdm_mode = true;
0414
0415
0416 bsel = max98927_get_bclk_sel(slots * slot_width);
0417 if (bsel == 0) {
0418 dev_err(component->dev, "BCLK %d not supported\n",
0419 slots * slot_width);
0420 return -EINVAL;
0421 }
0422
0423 regmap_update_bits(max98927->regmap,
0424 MAX98927_R0022_PCM_CLK_SETUP,
0425 MAX98927_PCM_CLK_SETUP_BSEL_MASK,
0426 bsel);
0427
0428
0429 switch (slot_width) {
0430 case 16:
0431 chan_sz = MAX98927_PCM_MODE_CFG_CHANSZ_16;
0432 break;
0433 case 24:
0434 chan_sz = MAX98927_PCM_MODE_CFG_CHANSZ_24;
0435 break;
0436 case 32:
0437 chan_sz = MAX98927_PCM_MODE_CFG_CHANSZ_32;
0438 break;
0439 default:
0440 dev_err(component->dev, "format unsupported %d\n",
0441 slot_width);
0442 return -EINVAL;
0443 }
0444
0445 regmap_update_bits(max98927->regmap,
0446 MAX98927_R0020_PCM_MODE_CFG,
0447 MAX98927_PCM_MODE_CFG_CHANSZ_MASK, chan_sz);
0448
0449
0450 regmap_write(max98927->regmap,
0451 MAX98927_R0018_PCM_RX_EN_A,
0452 rx_mask & 0xFF);
0453 regmap_write(max98927->regmap,
0454 MAX98927_R0019_PCM_RX_EN_B,
0455 (rx_mask & 0xFF00) >> 8);
0456
0457
0458 regmap_write(max98927->regmap,
0459 MAX98927_R001A_PCM_TX_EN_A,
0460 tx_mask & 0xFF);
0461 regmap_write(max98927->regmap,
0462 MAX98927_R001B_PCM_TX_EN_B,
0463 (tx_mask & 0xFF00) >> 8);
0464
0465
0466 regmap_write(max98927->regmap,
0467 MAX98927_R001C_PCM_TX_HIZ_CTRL_A,
0468 ~tx_mask & 0xFF);
0469 regmap_write(max98927->regmap,
0470 MAX98927_R001D_PCM_TX_HIZ_CTRL_B,
0471 (~tx_mask & 0xFF00) >> 8);
0472
0473 return 0;
0474 }
0475
0476 #define MAX98927_RATES SNDRV_PCM_RATE_8000_48000
0477
0478 #define MAX98927_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
0479 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
0480
0481 static int max98927_dai_set_sysclk(struct snd_soc_dai *dai,
0482 int clk_id, unsigned int freq, int dir)
0483 {
0484 struct snd_soc_component *component = dai->component;
0485 struct max98927_priv *max98927 = snd_soc_component_get_drvdata(component);
0486
0487 max98927->sysclk = freq;
0488 return 0;
0489 }
0490
0491 static const struct snd_soc_dai_ops max98927_dai_ops = {
0492 .set_sysclk = max98927_dai_set_sysclk,
0493 .set_fmt = max98927_dai_set_fmt,
0494 .hw_params = max98927_dai_hw_params,
0495 .set_tdm_slot = max98927_dai_tdm_slot,
0496 };
0497
0498 static int max98927_dac_event(struct snd_soc_dapm_widget *w,
0499 struct snd_kcontrol *kcontrol, int event)
0500 {
0501 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
0502 struct max98927_priv *max98927 = snd_soc_component_get_drvdata(component);
0503
0504 switch (event) {
0505 case SND_SOC_DAPM_PRE_PMU:
0506 max98927->tdm_mode = false;
0507 break;
0508 case SND_SOC_DAPM_POST_PMU:
0509 regmap_update_bits(max98927->regmap,
0510 MAX98927_R003A_AMP_EN,
0511 MAX98927_AMP_EN_MASK, 1);
0512 regmap_update_bits(max98927->regmap,
0513 MAX98927_R00FF_GLOBAL_SHDN,
0514 MAX98927_GLOBAL_EN_MASK, 1);
0515 break;
0516 case SND_SOC_DAPM_POST_PMD:
0517 regmap_update_bits(max98927->regmap,
0518 MAX98927_R00FF_GLOBAL_SHDN,
0519 MAX98927_GLOBAL_EN_MASK, 0);
0520 regmap_update_bits(max98927->regmap,
0521 MAX98927_R003A_AMP_EN,
0522 MAX98927_AMP_EN_MASK, 0);
0523 break;
0524 default:
0525 return 0;
0526 }
0527 return 0;
0528 }
0529
0530 static const char * const max98927_switch_text[] = {
0531 "Left", "Right", "LeftRight"};
0532
0533 static const struct soc_enum dai_sel_enum =
0534 SOC_ENUM_SINGLE(MAX98927_R0025_PCM_TO_SPK_MONOMIX_A,
0535 MAX98927_PCM_TO_SPK_MONOMIX_CFG_SHIFT,
0536 3, max98927_switch_text);
0537
0538 static const struct snd_kcontrol_new max98927_dai_controls =
0539 SOC_DAPM_ENUM("DAI Sel", dai_sel_enum);
0540
0541 static const struct snd_kcontrol_new max98927_vi_control =
0542 SOC_DAPM_SINGLE("Switch", MAX98927_R003F_MEAS_DSP_CFG, 2, 1, 0);
0543
0544 static const struct snd_soc_dapm_widget max98927_dapm_widgets[] = {
0545 SND_SOC_DAPM_DAC_E("Amp Enable", "HiFi Playback", MAX98927_R003A_AMP_EN,
0546 0, 0, max98927_dac_event,
0547 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
0548 SND_SOC_DAPM_MUX("DAI Sel Mux", SND_SOC_NOPM, 0, 0,
0549 &max98927_dai_controls),
0550 SND_SOC_DAPM_OUTPUT("BE_OUT"),
0551 SND_SOC_DAPM_AIF_OUT("Voltage Sense", "HiFi Capture", 0,
0552 MAX98927_R003E_MEAS_EN, 0, 0),
0553 SND_SOC_DAPM_AIF_OUT("Current Sense", "HiFi Capture", 0,
0554 MAX98927_R003E_MEAS_EN, 1, 0),
0555 SND_SOC_DAPM_SWITCH("VI Sense", SND_SOC_NOPM, 0, 0,
0556 &max98927_vi_control),
0557 SND_SOC_DAPM_SIGGEN("VMON"),
0558 SND_SOC_DAPM_SIGGEN("IMON"),
0559 };
0560
0561 static DECLARE_TLV_DB_SCALE(max98927_spk_tlv, 300, 300, 0);
0562 static DECLARE_TLV_DB_SCALE(max98927_digital_tlv, -1600, 25, 0);
0563
0564 static bool max98927_readable_register(struct device *dev, unsigned int reg)
0565 {
0566 switch (reg) {
0567 case MAX98927_R0001_INT_RAW1 ... MAX98927_R0028_ICC_RX_EN_B:
0568 case MAX98927_R002B_ICC_TX_EN_A ... MAX98927_R002C_ICC_TX_EN_B:
0569 case MAX98927_R002E_ICC_HIZ_MANUAL_MODE
0570 ... MAX98927_R004E_MEAS_ADC_CH2_READ:
0571 case MAX98927_R0051_BROWNOUT_STATUS
0572 ... MAX98927_R0055_BROWNOUT_LVL_HOLD:
0573 case MAX98927_R005A_BROWNOUT_LVL1_THRESH
0574 ... MAX98927_R0061_BROWNOUT_AMP1_CLIP_MODE:
0575 case MAX98927_R0072_BROWNOUT_LVL1_CUR_LIMIT
0576 ... MAX98927_R0087_ENV_TRACK_BOOST_VOUT_READ:
0577 case MAX98927_R00FF_GLOBAL_SHDN:
0578 case MAX98927_R0100_SOFT_RESET:
0579 case MAX98927_R01FF_REV_ID:
0580 return true;
0581 default:
0582 return false;
0583 }
0584 };
0585
0586 static bool max98927_volatile_reg(struct device *dev, unsigned int reg)
0587 {
0588 switch (reg) {
0589 case MAX98927_R0001_INT_RAW1 ... MAX98927_R0009_INT_FLAG3:
0590 case MAX98927_R004C_MEAS_ADC_CH0_READ:
0591 case MAX98927_R004D_MEAS_ADC_CH1_READ:
0592 case MAX98927_R004E_MEAS_ADC_CH2_READ:
0593 case MAX98927_R0051_BROWNOUT_STATUS:
0594 case MAX98927_R0087_ENV_TRACK_BOOST_VOUT_READ:
0595 case MAX98927_R01FF_REV_ID:
0596 case MAX98927_R0100_SOFT_RESET:
0597 return true;
0598 default:
0599 return false;
0600 }
0601 }
0602
0603 static const char * const max98927_boost_voltage_text[] = {
0604 "6.5V", "6.625V", "6.75V", "6.875V", "7V", "7.125V", "7.25V", "7.375V",
0605 "7.5V", "7.625V", "7.75V", "7.875V", "8V", "8.125V", "8.25V", "8.375V",
0606 "8.5V", "8.625V", "8.75V", "8.875V", "9V", "9.125V", "9.25V", "9.375V",
0607 "9.5V", "9.625V", "9.75V", "9.875V", "10V"
0608 };
0609
0610 static SOC_ENUM_SINGLE_DECL(max98927_boost_voltage,
0611 MAX98927_R0040_BOOST_CTRL0, 0,
0612 max98927_boost_voltage_text);
0613
0614 static const char * const max98927_current_limit_text[] = {
0615 "1.00A", "1.10A", "1.20A", "1.30A", "1.40A", "1.50A", "1.60A", "1.70A",
0616 "1.80A", "1.90A", "2.00A", "2.10A", "2.20A", "2.30A", "2.40A", "2.50A",
0617 "2.60A", "2.70A", "2.80A", "2.90A", "3.00A", "3.10A", "3.20A", "3.30A",
0618 "3.40A", "3.50A", "3.60A", "3.70A", "3.80A", "3.90A", "4.00A", "4.10A"
0619 };
0620
0621 static SOC_ENUM_SINGLE_DECL(max98927_current_limit,
0622 MAX98927_R0042_BOOST_CTRL1, 1,
0623 max98927_current_limit_text);
0624
0625 static const struct snd_kcontrol_new max98927_snd_controls[] = {
0626 SOC_SINGLE_TLV("Speaker Volume", MAX98927_R003C_SPK_GAIN,
0627 0, 6, 0,
0628 max98927_spk_tlv),
0629 SOC_SINGLE_TLV("Digital Volume", MAX98927_R0036_AMP_VOL_CTRL,
0630 0, (1<<MAX98927_AMP_VOL_WIDTH)-1, 0,
0631 max98927_digital_tlv),
0632 SOC_SINGLE("Amp DSP Switch", MAX98927_R0052_BROWNOUT_EN,
0633 MAX98927_BROWNOUT_DSP_SHIFT, 1, 0),
0634 SOC_SINGLE("Ramp Switch", MAX98927_R0037_AMP_DSP_CFG,
0635 MAX98927_AMP_DSP_CFG_RMP_SHIFT, 1, 0),
0636 SOC_SINGLE("DRE Switch", MAX98927_R0039_DRE_CTRL,
0637 MAX98927_DRE_EN_SHIFT, 1, 0),
0638 SOC_SINGLE("Volume Location Switch", MAX98927_R0036_AMP_VOL_CTRL,
0639 MAX98927_AMP_VOL_SEL_SHIFT, 1, 0),
0640 SOC_ENUM("Boost Output Voltage", max98927_boost_voltage),
0641 SOC_ENUM("Current Limit", max98927_current_limit),
0642 };
0643
0644 static const struct snd_soc_dapm_route max98927_audio_map[] = {
0645
0646 {"DAI Sel Mux", "Left", "Amp Enable"},
0647 {"DAI Sel Mux", "Right", "Amp Enable"},
0648 {"DAI Sel Mux", "LeftRight", "Amp Enable"},
0649 {"BE_OUT", NULL, "DAI Sel Mux"},
0650
0651 { "VI Sense", "Switch", "VMON" },
0652 { "VI Sense", "Switch", "IMON" },
0653 { "Voltage Sense", NULL, "VI Sense" },
0654 { "Current Sense", NULL, "VI Sense" },
0655 };
0656
0657 static struct snd_soc_dai_driver max98927_dai[] = {
0658 {
0659 .name = "max98927-aif1",
0660 .playback = {
0661 .stream_name = "HiFi Playback",
0662 .channels_min = 1,
0663 .channels_max = 2,
0664 .rates = MAX98927_RATES,
0665 .formats = MAX98927_FORMATS,
0666 },
0667 .capture = {
0668 .stream_name = "HiFi Capture",
0669 .channels_min = 1,
0670 .channels_max = 2,
0671 .rates = MAX98927_RATES,
0672 .formats = MAX98927_FORMATS,
0673 },
0674 .ops = &max98927_dai_ops,
0675 }
0676 };
0677
0678 static int max98927_probe(struct snd_soc_component *component)
0679 {
0680 struct max98927_priv *max98927 = snd_soc_component_get_drvdata(component);
0681
0682 max98927->component = component;
0683
0684
0685 regmap_write(max98927->regmap,
0686 MAX98927_R0100_SOFT_RESET, MAX98927_SOFT_RESET);
0687
0688
0689 regmap_write(max98927->regmap,
0690 MAX98927_R001C_PCM_TX_HIZ_CTRL_A,
0691 0xFF);
0692 regmap_write(max98927->regmap,
0693 MAX98927_R001D_PCM_TX_HIZ_CTRL_B,
0694 0xFF);
0695 regmap_write(max98927->regmap,
0696 MAX98927_R0025_PCM_TO_SPK_MONOMIX_A,
0697 0x80);
0698 regmap_write(max98927->regmap,
0699 MAX98927_R0026_PCM_TO_SPK_MONOMIX_B,
0700 0x1);
0701
0702 regmap_write(max98927->regmap,
0703 MAX98927_R0036_AMP_VOL_CTRL,
0704 0x38);
0705 regmap_write(max98927->regmap,
0706 MAX98927_R003C_SPK_GAIN,
0707 0x05);
0708
0709 regmap_write(max98927->regmap,
0710 MAX98927_R0037_AMP_DSP_CFG,
0711 0x03);
0712
0713 regmap_write(max98927->regmap,
0714 MAX98927_R003F_MEAS_DSP_CFG,
0715 0xF7);
0716
0717 regmap_write(max98927->regmap,
0718 MAX98927_R0040_BOOST_CTRL0,
0719 0x1C);
0720 regmap_write(max98927->regmap,
0721 MAX98927_R0042_BOOST_CTRL1,
0722 0x3E);
0723
0724 regmap_write(max98927->regmap,
0725 MAX98927_R0043_MEAS_ADC_CFG,
0726 0x04);
0727 regmap_write(max98927->regmap,
0728 MAX98927_R0044_MEAS_ADC_BASE_MSB,
0729 0x00);
0730 regmap_write(max98927->regmap,
0731 MAX98927_R0045_MEAS_ADC_BASE_LSB,
0732 0x24);
0733
0734 regmap_write(max98927->regmap,
0735 MAX98927_R007F_BROWNOUT_LVL4_AMP1_CTRL1,
0736 0x06);
0737
0738 regmap_write(max98927->regmap,
0739 MAX98927_R0082_ENV_TRACK_VOUT_HEADROOM,
0740 0x08);
0741 regmap_write(max98927->regmap,
0742 MAX98927_R0086_ENV_TRACK_CTRL,
0743 0x01);
0744 regmap_write(max98927->regmap,
0745 MAX98927_R0087_ENV_TRACK_BOOST_VOUT_READ,
0746 0x10);
0747
0748
0749 regmap_write(max98927->regmap,
0750 MAX98927_R001E_PCM_TX_CH_SRC_A,
0751 (max98927->i_l_slot<<MAX98927_PCM_TX_CH_SRC_A_I_SHIFT|
0752 max98927->v_l_slot)&0xFF);
0753
0754 if (max98927->v_l_slot < 8) {
0755 regmap_update_bits(max98927->regmap,
0756 MAX98927_R001C_PCM_TX_HIZ_CTRL_A,
0757 1 << max98927->v_l_slot, 0);
0758 regmap_update_bits(max98927->regmap,
0759 MAX98927_R001A_PCM_TX_EN_A,
0760 1 << max98927->v_l_slot,
0761 1 << max98927->v_l_slot);
0762 } else {
0763 regmap_update_bits(max98927->regmap,
0764 MAX98927_R001D_PCM_TX_HIZ_CTRL_B,
0765 1 << (max98927->v_l_slot - 8), 0);
0766 regmap_update_bits(max98927->regmap,
0767 MAX98927_R001B_PCM_TX_EN_B,
0768 1 << (max98927->v_l_slot - 8),
0769 1 << (max98927->v_l_slot - 8));
0770 }
0771
0772 if (max98927->i_l_slot < 8) {
0773 regmap_update_bits(max98927->regmap,
0774 MAX98927_R001C_PCM_TX_HIZ_CTRL_A,
0775 1 << max98927->i_l_slot, 0);
0776 regmap_update_bits(max98927->regmap,
0777 MAX98927_R001A_PCM_TX_EN_A,
0778 1 << max98927->i_l_slot,
0779 1 << max98927->i_l_slot);
0780 } else {
0781 regmap_update_bits(max98927->regmap,
0782 MAX98927_R001D_PCM_TX_HIZ_CTRL_B,
0783 1 << (max98927->i_l_slot - 8), 0);
0784 regmap_update_bits(max98927->regmap,
0785 MAX98927_R001B_PCM_TX_EN_B,
0786 1 << (max98927->i_l_slot - 8),
0787 1 << (max98927->i_l_slot - 8));
0788 }
0789
0790
0791 if (max98927->interleave_mode)
0792 regmap_update_bits(max98927->regmap,
0793 MAX98927_R001F_PCM_TX_CH_SRC_B,
0794 MAX98927_PCM_TX_CH_INTERLEAVE_MASK,
0795 MAX98927_PCM_TX_CH_INTERLEAVE_MASK);
0796 return 0;
0797 }
0798
0799 #ifdef CONFIG_PM_SLEEP
0800 static int max98927_suspend(struct device *dev)
0801 {
0802 struct max98927_priv *max98927 = dev_get_drvdata(dev);
0803
0804 regcache_cache_only(max98927->regmap, true);
0805 regcache_mark_dirty(max98927->regmap);
0806 return 0;
0807 }
0808 static int max98927_resume(struct device *dev)
0809 {
0810 struct max98927_priv *max98927 = dev_get_drvdata(dev);
0811
0812 regmap_write(max98927->regmap,
0813 MAX98927_R0100_SOFT_RESET, MAX98927_SOFT_RESET);
0814 regcache_cache_only(max98927->regmap, false);
0815 regcache_sync(max98927->regmap);
0816 return 0;
0817 }
0818 #endif
0819
0820 static const struct dev_pm_ops max98927_pm = {
0821 SET_SYSTEM_SLEEP_PM_OPS(max98927_suspend, max98927_resume)
0822 };
0823
0824 static const struct snd_soc_component_driver soc_component_dev_max98927 = {
0825 .probe = max98927_probe,
0826 .controls = max98927_snd_controls,
0827 .num_controls = ARRAY_SIZE(max98927_snd_controls),
0828 .dapm_widgets = max98927_dapm_widgets,
0829 .num_dapm_widgets = ARRAY_SIZE(max98927_dapm_widgets),
0830 .dapm_routes = max98927_audio_map,
0831 .num_dapm_routes = ARRAY_SIZE(max98927_audio_map),
0832 .idle_bias_on = 1,
0833 .use_pmdown_time = 1,
0834 .endianness = 1,
0835 };
0836
0837 static const struct regmap_config max98927_regmap = {
0838 .reg_bits = 16,
0839 .val_bits = 8,
0840 .max_register = MAX98927_R01FF_REV_ID,
0841 .reg_defaults = max98927_reg,
0842 .num_reg_defaults = ARRAY_SIZE(max98927_reg),
0843 .readable_reg = max98927_readable_register,
0844 .volatile_reg = max98927_volatile_reg,
0845 .cache_type = REGCACHE_RBTREE,
0846 };
0847
0848 static void max98927_slot_config(struct i2c_client *i2c,
0849 struct max98927_priv *max98927)
0850 {
0851 int value;
0852 struct device *dev = &i2c->dev;
0853
0854 if (!device_property_read_u32(dev, "vmon-slot-no", &value))
0855 max98927->v_l_slot = value & 0xF;
0856 else
0857 max98927->v_l_slot = 0;
0858
0859 if (!device_property_read_u32(dev, "imon-slot-no", &value))
0860 max98927->i_l_slot = value & 0xF;
0861 else
0862 max98927->i_l_slot = 1;
0863 }
0864
0865 static int max98927_i2c_probe(struct i2c_client *i2c)
0866 {
0867
0868 int ret = 0, value;
0869 int reg = 0;
0870 struct max98927_priv *max98927 = NULL;
0871
0872 max98927 = devm_kzalloc(&i2c->dev,
0873 sizeof(*max98927), GFP_KERNEL);
0874
0875 if (!max98927) {
0876 ret = -ENOMEM;
0877 return ret;
0878 }
0879 i2c_set_clientdata(i2c, max98927);
0880
0881
0882 if (!of_property_read_u32(i2c->dev.of_node,
0883 "interleave_mode", &value)) {
0884 if (value > 0)
0885 max98927->interleave_mode = true;
0886 else
0887 max98927->interleave_mode = false;
0888 } else
0889 max98927->interleave_mode = false;
0890
0891
0892 max98927->regmap
0893 = devm_regmap_init_i2c(i2c, &max98927_regmap);
0894 if (IS_ERR(max98927->regmap)) {
0895 ret = PTR_ERR(max98927->regmap);
0896 dev_err(&i2c->dev,
0897 "Failed to allocate regmap: %d\n", ret);
0898 return ret;
0899 }
0900
0901 max98927->reset_gpio
0902 = devm_gpiod_get_optional(&i2c->dev, "reset", GPIOD_OUT_HIGH);
0903 if (IS_ERR(max98927->reset_gpio)) {
0904 ret = PTR_ERR(max98927->reset_gpio);
0905 return dev_err_probe(&i2c->dev, ret, "failed to request GPIO reset pin");
0906 }
0907
0908 if (max98927->reset_gpio) {
0909 gpiod_set_value_cansleep(max98927->reset_gpio, 0);
0910
0911 usleep_range(5000, 6000);
0912 }
0913
0914
0915 ret = regmap_read(max98927->regmap,
0916 MAX98927_R01FF_REV_ID, ®);
0917 if (ret < 0) {
0918 dev_err(&i2c->dev,
0919 "Failed to read: 0x%02X\n", MAX98927_R01FF_REV_ID);
0920 return ret;
0921 }
0922 dev_info(&i2c->dev, "MAX98927 revisionID: 0x%02X\n", reg);
0923
0924
0925 max98927_slot_config(i2c, max98927);
0926
0927
0928 ret = devm_snd_soc_register_component(&i2c->dev,
0929 &soc_component_dev_max98927,
0930 max98927_dai, ARRAY_SIZE(max98927_dai));
0931 if (ret < 0)
0932 dev_err(&i2c->dev, "Failed to register component: %d\n", ret);
0933
0934 return ret;
0935 }
0936
0937 static int max98927_i2c_remove(struct i2c_client *i2c)
0938 {
0939 struct max98927_priv *max98927 = i2c_get_clientdata(i2c);
0940
0941 if (max98927->reset_gpio) {
0942 gpiod_set_value_cansleep(max98927->reset_gpio, 1);
0943 }
0944
0945 return 0;
0946 }
0947
0948 static const struct i2c_device_id max98927_i2c_id[] = {
0949 { "max98927", 0},
0950 { },
0951 };
0952
0953 MODULE_DEVICE_TABLE(i2c, max98927_i2c_id);
0954
0955 #if defined(CONFIG_OF)
0956 static const struct of_device_id max98927_of_match[] = {
0957 { .compatible = "maxim,max98927", },
0958 { }
0959 };
0960 MODULE_DEVICE_TABLE(of, max98927_of_match);
0961 #endif
0962
0963 #ifdef CONFIG_ACPI
0964 static const struct acpi_device_id max98927_acpi_match[] = {
0965 { "MX98927", 0 },
0966 {},
0967 };
0968 MODULE_DEVICE_TABLE(acpi, max98927_acpi_match);
0969 #endif
0970
0971 static struct i2c_driver max98927_i2c_driver = {
0972 .driver = {
0973 .name = "max98927",
0974 .of_match_table = of_match_ptr(max98927_of_match),
0975 .acpi_match_table = ACPI_PTR(max98927_acpi_match),
0976 .pm = &max98927_pm,
0977 },
0978 .probe_new = max98927_i2c_probe,
0979 .remove = max98927_i2c_remove,
0980 .id_table = max98927_i2c_id,
0981 };
0982
0983 module_i2c_driver(max98927_i2c_driver)
0984
0985 MODULE_DESCRIPTION("ALSA SoC MAX98927 driver");
0986 MODULE_AUTHOR("Ryan Lee <ryans.lee@maximintegrated.com>");
0987 MODULE_LICENSE("GPL");