0001
0002
0003
0004 #include <linux/gpio/consumer.h>
0005 #include <linux/i2c.h>
0006 #include <linux/module.h>
0007 #include <sound/pcm_params.h>
0008 #include <linux/regulator/consumer.h>
0009 #include <sound/soc.h>
0010 #include <linux/gpio.h>
0011 #include <sound/tlv.h>
0012 #include "max98396.h"
0013
0014 static const char * const max98396_core_supplies[MAX98396_NUM_CORE_SUPPLIES] = {
0015 "avdd",
0016 "dvdd",
0017 "dvddio",
0018 };
0019
0020 static struct reg_default max98396_reg[] = {
0021 {MAX98396_R2000_SW_RESET, 0x00},
0022 {MAX98396_R2001_INT_RAW1, 0x00},
0023 {MAX98396_R2002_INT_RAW2, 0x00},
0024 {MAX98396_R2003_INT_RAW3, 0x00},
0025 {MAX98396_R2004_INT_RAW4, 0x00},
0026 {MAX98396_R2006_INT_STATE1, 0x00},
0027 {MAX98396_R2007_INT_STATE2, 0x00},
0028 {MAX98396_R2008_INT_STATE3, 0x00},
0029 {MAX98396_R2009_INT_STATE4, 0x00},
0030 {MAX98396_R200B_INT_FLAG1, 0x00},
0031 {MAX98396_R200C_INT_FLAG2, 0x00},
0032 {MAX98396_R200D_INT_FLAG3, 0x00},
0033 {MAX98396_R200E_INT_FLAG4, 0x00},
0034 {MAX98396_R2010_INT_EN1, 0x02},
0035 {MAX98396_R2011_INT_EN2, 0x00},
0036 {MAX98396_R2012_INT_EN3, 0x00},
0037 {MAX98396_R2013_INT_EN4, 0x00},
0038 {MAX98396_R2015_INT_FLAG_CLR1, 0x00},
0039 {MAX98396_R2016_INT_FLAG_CLR2, 0x00},
0040 {MAX98396_R2017_INT_FLAG_CLR3, 0x00},
0041 {MAX98396_R2018_INT_FLAG_CLR4, 0x00},
0042 {MAX98396_R201F_IRQ_CTRL, 0x00},
0043 {MAX98396_R2020_THERM_WARN_THRESH, 0x46},
0044 {MAX98396_R2021_THERM_WARN_THRESH2, 0x46},
0045 {MAX98396_R2022_THERM_SHDN_THRESH, 0x64},
0046 {MAX98396_R2023_THERM_HYSTERESIS, 0x02},
0047 {MAX98396_R2024_THERM_FOLDBACK_SET, 0xC5},
0048 {MAX98396_R2027_THERM_FOLDBACK_EN, 0x01},
0049 {MAX98396_R2030_NOISEGATE_MODE_CTRL, 0x32},
0050 {MAX98396_R2033_NOISEGATE_MODE_EN, 0x00},
0051 {MAX98396_R2038_CLK_MON_CTRL, 0x00},
0052 {MAX98396_R2039_DATA_MON_CTRL, 0x00},
0053 {MAX98396_R203F_ENABLE_CTRLS, 0x0F},
0054 {MAX98396_R2040_PIN_CFG, 0x55},
0055 {MAX98396_R2041_PCM_MODE_CFG, 0xC0},
0056 {MAX98396_R2042_PCM_CLK_SETUP, 0x04},
0057 {MAX98396_R2043_PCM_SR_SETUP, 0x88},
0058 {MAX98396_R2044_PCM_TX_CTRL_1, 0x00},
0059 {MAX98396_R2045_PCM_TX_CTRL_2, 0x00},
0060 {MAX98396_R2046_PCM_TX_CTRL_3, 0x00},
0061 {MAX98396_R2047_PCM_TX_CTRL_4, 0x00},
0062 {MAX98396_R2048_PCM_TX_CTRL_5, 0x00},
0063 {MAX98396_R2049_PCM_TX_CTRL_6, 0x00},
0064 {MAX98396_R204A_PCM_TX_CTRL_7, 0x00},
0065 {MAX98396_R204B_PCM_TX_CTRL_8, 0x00},
0066 {MAX98396_R204C_PCM_TX_HIZ_CTRL_1, 0xFF},
0067 {MAX98396_R204D_PCM_TX_HIZ_CTRL_2, 0xFF},
0068 {MAX98396_R204E_PCM_TX_HIZ_CTRL_3, 0xFF},
0069 {MAX98396_R204F_PCM_TX_HIZ_CTRL_4, 0xFF},
0070 {MAX98396_R2050_PCM_TX_HIZ_CTRL_5, 0xFF},
0071 {MAX98396_R2051_PCM_TX_HIZ_CTRL_6, 0xFF},
0072 {MAX98396_R2052_PCM_TX_HIZ_CTRL_7, 0xFF},
0073 {MAX98396_R2053_PCM_TX_HIZ_CTRL_8, 0xFF},
0074 {MAX98396_R2055_PCM_RX_SRC1, 0x00},
0075 {MAX98396_R2056_PCM_RX_SRC2, 0x00},
0076 {MAX98396_R2058_PCM_BYPASS_SRC, 0x00},
0077 {MAX98396_R205D_PCM_TX_SRC_EN, 0x00},
0078 {MAX98396_R205E_PCM_RX_EN, 0x00},
0079 {MAX98396_R205F_PCM_TX_EN, 0x00},
0080 {MAX98396_R2070_ICC_RX_EN_A, 0x00},
0081 {MAX98396_R2071_ICC_RX_EN_B, 0x00},
0082 {MAX98396_R2072_ICC_TX_CTRL, 0x00},
0083 {MAX98396_R207F_ICC_EN, 0x00},
0084 {MAX98396_R2083_TONE_GEN_DC_CFG, 0x04},
0085 {MAX98396_R2084_TONE_GEN_DC_LVL1, 0x00},
0086 {MAX98396_R2085_TONE_GEN_DC_LVL2, 0x00},
0087 {MAX98396_R2086_TONE_GEN_DC_LVL3, 0x00},
0088 {MAX98396_R208F_TONE_GEN_EN, 0x00},
0089 {MAX98396_R2090_AMP_VOL_CTRL, 0x00},
0090 {MAX98396_R2091_AMP_PATH_GAIN, 0x0B},
0091 {MAX98396_R2092_AMP_DSP_CFG, 0x23},
0092 {MAX98396_R2093_SSM_CFG, 0x0D},
0093 {MAX98396_R2094_SPK_CLS_DG_THRESH, 0x12},
0094 {MAX98396_R2095_SPK_CLS_DG_HDR, 0x17},
0095 {MAX98396_R2096_SPK_CLS_DG_HOLD_TIME, 0x17},
0096 {MAX98396_R2097_SPK_CLS_DG_DELAY, 0x00},
0097 {MAX98396_R2098_SPK_CLS_DG_MODE, 0x00},
0098 {MAX98396_R2099_SPK_CLS_DG_VBAT_LVL, 0x03},
0099 {MAX98396_R209A_SPK_EDGE_CTRL, 0x00},
0100 {MAX98396_R209C_SPK_EDGE_CTRL1, 0x0A},
0101 {MAX98396_R209D_SPK_EDGE_CTRL2, 0xAA},
0102 {MAX98396_R209E_AMP_CLIP_GAIN, 0x00},
0103 {MAX98396_R209F_BYPASS_PATH_CFG, 0x00},
0104 {MAX98396_R20A0_AMP_SUPPLY_CTL, 0x00},
0105 {MAX98396_R20AF_AMP_EN, 0x00},
0106 {MAX98396_R20B0_ADC_SR, 0x30},
0107 {MAX98396_R20B1_ADC_PVDD_CFG, 0x00},
0108 {MAX98396_R20B2_ADC_VBAT_CFG, 0x00},
0109 {MAX98396_R20B3_ADC_THERMAL_CFG, 0x00},
0110 {MAX98396_R20B4_ADC_READBACK_CTRL1, 0x00},
0111 {MAX98396_R20B5_ADC_READBACK_CTRL2, 0x00},
0112 {MAX98396_R20B6_ADC_PVDD_READBACK_MSB, 0x00},
0113 {MAX98396_R20B7_ADC_PVDD_READBACK_LSB, 0x00},
0114 {MAX98396_R20B8_ADC_VBAT_READBACK_MSB, 0x00},
0115 {MAX98396_R20B9_ADC_VBAT_READBACK_LSB, 0x00},
0116 {MAX98396_R20BA_ADC_TEMP_READBACK_MSB, 0x00},
0117 {MAX98396_R20BB_ADC_TEMP_READBACK_LSB, 0x00},
0118 {MAX98396_R20BC_ADC_LO_PVDD_READBACK_MSB, 0x00},
0119 {MAX98396_R20BD_ADC_LO_PVDD_READBACK_LSB, 0x00},
0120 {MAX98396_R20BE_ADC_LO_VBAT_READBACK_MSB, 0x00},
0121 {MAX98396_R20BF_ADC_LO_VBAT_READBACK_LSB, 0x00},
0122 {MAX98396_R20C7_ADC_CFG, 0x00},
0123 {MAX98396_R20D0_DHT_CFG1, 0x00},
0124 {MAX98396_R20D1_LIMITER_CFG1, 0x08},
0125 {MAX98396_R20D2_LIMITER_CFG2, 0x00},
0126 {MAX98396_R20D3_DHT_CFG2, 0x14},
0127 {MAX98396_R20D4_DHT_CFG3, 0x02},
0128 {MAX98396_R20D5_DHT_CFG4, 0x04},
0129 {MAX98396_R20D6_DHT_HYSTERESIS_CFG, 0x07},
0130 {MAX98396_R20DF_DHT_EN, 0x00},
0131 {MAX98396_R20E0_IV_SENSE_PATH_CFG, 0x04},
0132 {MAX98396_R20E4_IV_SENSE_PATH_EN, 0x00},
0133 {MAX98396_R20E5_BPE_STATE, 0x00},
0134 {MAX98396_R20E6_BPE_L3_THRESH_MSB, 0x00},
0135 {MAX98396_R20E7_BPE_L3_THRESH_LSB, 0x00},
0136 {MAX98396_R20E8_BPE_L2_THRESH_MSB, 0x00},
0137 {MAX98396_R20E9_BPE_L2_THRESH_LSB, 0x00},
0138 {MAX98396_R20EA_BPE_L1_THRESH_MSB, 0x00},
0139 {MAX98396_R20EB_BPE_L1_THRESH_LSB, 0x00},
0140 {MAX98396_R20EC_BPE_L0_THRESH_MSB, 0x00},
0141 {MAX98396_R20ED_BPE_L0_THRESH_LSB, 0x00},
0142 {MAX98396_R20EE_BPE_L3_DWELL_HOLD_TIME, 0x00},
0143 {MAX98396_R20EF_BPE_L2_DWELL_HOLD_TIME, 0x00},
0144 {MAX98396_R20F0_BPE_L1_DWELL_HOLD_TIME, 0x00},
0145 {MAX98396_R20F1_BPE_L0_HOLD_TIME, 0x00},
0146 {MAX98396_R20F2_BPE_L3_ATTACK_REL_STEP, 0x00},
0147 {MAX98396_R20F3_BPE_L2_ATTACK_REL_STEP, 0x00},
0148 {MAX98396_R20F4_BPE_L1_ATTACK_REL_STEP, 0x00},
0149 {MAX98396_R20F5_BPE_L0_ATTACK_REL_STEP, 0x00},
0150 {MAX98396_R20F6_BPE_L3_MAX_GAIN_ATTN, 0x00},
0151 {MAX98396_R20F7_BPE_L2_MAX_GAIN_ATTN, 0x00},
0152 {MAX98396_R20F8_BPE_L1_MAX_GAIN_ATTN, 0x00},
0153 {MAX98396_R20F9_BPE_L0_MAX_GAIN_ATTN, 0x00},
0154 {MAX98396_R20FA_BPE_L3_ATT_REL_RATE, 0x00},
0155 {MAX98396_R20FB_BPE_L2_ATT_REL_RATE, 0x00},
0156 {MAX98396_R20FC_BPE_L1_ATT_REL_RATE, 0x00},
0157 {MAX98396_R20FD_BPE_L0_ATT_REL_RATE, 0x00},
0158 {MAX98396_R20FE_BPE_L3_LIMITER_CFG, 0x00},
0159 {MAX98396_R20FF_BPE_L2_LIMITER_CFG, 0x00},
0160 {MAX98396_R2100_BPE_L1_LIMITER_CFG, 0x00},
0161 {MAX98396_R2101_BPE_L0_LIMITER_CFG, 0x00},
0162 {MAX98396_R2102_BPE_L3_LIM_ATT_REL_RATE, 0x00},
0163 {MAX98396_R2103_BPE_L2_LIM_ATT_REL_RATE, 0x00},
0164 {MAX98396_R2104_BPE_L1_LIM_ATT_REL_RATE, 0x00},
0165 {MAX98396_R2105_BPE_L0_LIM_ATT_REL_RATE, 0x00},
0166 {MAX98396_R2106_BPE_THRESH_HYSTERESIS, 0x00},
0167 {MAX98396_R2107_BPE_INFINITE_HOLD_CLR, 0x00},
0168 {MAX98396_R2108_BPE_SUPPLY_SRC, 0x00},
0169 {MAX98396_R2109_BPE_LOW_STATE, 0x00},
0170 {MAX98396_R210A_BPE_LOW_GAIN, 0x00},
0171 {MAX98396_R210B_BPE_LOW_LIMITER, 0x00},
0172 {MAX98396_R210D_BPE_EN, 0x00},
0173 {MAX98396_R210E_AUTO_RESTART, 0x00},
0174 {MAX98396_R210F_GLOBAL_EN, 0x00},
0175 {MAX98396_R21FF_REVISION_ID, 0x00},
0176 };
0177
0178 static struct reg_default max98397_reg[] = {
0179 {MAX98396_R2000_SW_RESET, 0x00},
0180 {MAX98396_R2001_INT_RAW1, 0x00},
0181 {MAX98396_R2002_INT_RAW2, 0x00},
0182 {MAX98396_R2003_INT_RAW3, 0x00},
0183 {MAX98396_R2004_INT_RAW4, 0x00},
0184 {MAX98396_R2006_INT_STATE1, 0x00},
0185 {MAX98396_R2007_INT_STATE2, 0x00},
0186 {MAX98396_R2008_INT_STATE3, 0x00},
0187 {MAX98396_R2009_INT_STATE4, 0x00},
0188 {MAX98396_R200B_INT_FLAG1, 0x00},
0189 {MAX98396_R200C_INT_FLAG2, 0x00},
0190 {MAX98396_R200D_INT_FLAG3, 0x00},
0191 {MAX98396_R200E_INT_FLAG4, 0x00},
0192 {MAX98396_R2010_INT_EN1, 0x02},
0193 {MAX98396_R2011_INT_EN2, 0x00},
0194 {MAX98396_R2012_INT_EN3, 0x00},
0195 {MAX98396_R2013_INT_EN4, 0x00},
0196 {MAX98396_R2015_INT_FLAG_CLR1, 0x00},
0197 {MAX98396_R2016_INT_FLAG_CLR2, 0x00},
0198 {MAX98396_R2017_INT_FLAG_CLR3, 0x00},
0199 {MAX98396_R2018_INT_FLAG_CLR4, 0x00},
0200 {MAX98396_R201F_IRQ_CTRL, 0x00},
0201 {MAX98396_R2020_THERM_WARN_THRESH, 0x46},
0202 {MAX98396_R2021_THERM_WARN_THRESH2, 0x46},
0203 {MAX98396_R2022_THERM_SHDN_THRESH, 0x64},
0204 {MAX98396_R2023_THERM_HYSTERESIS, 0x02},
0205 {MAX98396_R2024_THERM_FOLDBACK_SET, 0xC5},
0206 {MAX98396_R2027_THERM_FOLDBACK_EN, 0x01},
0207 {MAX98396_R2030_NOISEGATE_MODE_CTRL, 0x32},
0208 {MAX98396_R2033_NOISEGATE_MODE_EN, 0x00},
0209 {MAX98396_R2038_CLK_MON_CTRL, 0x00},
0210 {MAX98396_R2039_DATA_MON_CTRL, 0x00},
0211 {MAX98397_R203A_SPK_MON_THRESH, 0x03},
0212 {MAX98396_R203F_ENABLE_CTRLS, 0x0F},
0213 {MAX98396_R2040_PIN_CFG, 0x55},
0214 {MAX98396_R2041_PCM_MODE_CFG, 0xC0},
0215 {MAX98396_R2042_PCM_CLK_SETUP, 0x04},
0216 {MAX98396_R2043_PCM_SR_SETUP, 0x88},
0217 {MAX98396_R2044_PCM_TX_CTRL_1, 0x00},
0218 {MAX98396_R2045_PCM_TX_CTRL_2, 0x00},
0219 {MAX98396_R2046_PCM_TX_CTRL_3, 0x00},
0220 {MAX98396_R2047_PCM_TX_CTRL_4, 0x00},
0221 {MAX98396_R2048_PCM_TX_CTRL_5, 0x00},
0222 {MAX98396_R2049_PCM_TX_CTRL_6, 0x00},
0223 {MAX98396_R204A_PCM_TX_CTRL_7, 0x00},
0224 {MAX98396_R204B_PCM_TX_CTRL_8, 0x00},
0225 {MAX98397_R204C_PCM_TX_CTRL_9, 0x00},
0226 {MAX98397_R204D_PCM_TX_HIZ_CTRL_1, 0xFF},
0227 {MAX98397_R204E_PCM_TX_HIZ_CTRL_2, 0xFF},
0228 {MAX98397_R204F_PCM_TX_HIZ_CTRL_3, 0xFF},
0229 {MAX98397_R2050_PCM_TX_HIZ_CTRL_4, 0xFF},
0230 {MAX98397_R2051_PCM_TX_HIZ_CTRL_5, 0xFF},
0231 {MAX98397_R2052_PCM_TX_HIZ_CTRL_6, 0xFF},
0232 {MAX98397_R2053_PCM_TX_HIZ_CTRL_7, 0xFF},
0233 {MAX98397_R2054_PCM_TX_HIZ_CTRL_8, 0xFF},
0234 {MAX98397_R2056_PCM_RX_SRC1, 0x00},
0235 {MAX98397_R2057_PCM_RX_SRC2, 0x00},
0236 {MAX98396_R2058_PCM_BYPASS_SRC, 0x00},
0237 {MAX98396_R205D_PCM_TX_SRC_EN, 0x00},
0238 {MAX98396_R205E_PCM_RX_EN, 0x00},
0239 {MAX98396_R205F_PCM_TX_EN, 0x00},
0240 {MAX98397_R2060_PCM_TX_SUPPLY_SEL, 0x00},
0241 {MAX98396_R2070_ICC_RX_EN_A, 0x00},
0242 {MAX98396_R2071_ICC_RX_EN_B, 0x00},
0243 {MAX98396_R2072_ICC_TX_CTRL, 0x00},
0244 {MAX98396_R207F_ICC_EN, 0x00},
0245 {MAX98396_R2083_TONE_GEN_DC_CFG, 0x04},
0246 {MAX98396_R2084_TONE_GEN_DC_LVL1, 0x00},
0247 {MAX98396_R2085_TONE_GEN_DC_LVL2, 0x00},
0248 {MAX98396_R2086_TONE_GEN_DC_LVL3, 0x00},
0249 {MAX98396_R208F_TONE_GEN_EN, 0x00},
0250 {MAX98396_R2090_AMP_VOL_CTRL, 0x00},
0251 {MAX98396_R2091_AMP_PATH_GAIN, 0x12},
0252 {MAX98396_R2092_AMP_DSP_CFG, 0x22},
0253 {MAX98396_R2093_SSM_CFG, 0x08},
0254 {MAX98396_R2094_SPK_CLS_DG_THRESH, 0x12},
0255 {MAX98396_R2095_SPK_CLS_DG_HDR, 0x17},
0256 {MAX98396_R2096_SPK_CLS_DG_HOLD_TIME, 0x17},
0257 {MAX98396_R2097_SPK_CLS_DG_DELAY, 0x00},
0258 {MAX98396_R2098_SPK_CLS_DG_MODE, 0x00},
0259 {MAX98396_R2099_SPK_CLS_DG_VBAT_LVL, 0x03},
0260 {MAX98396_R209A_SPK_EDGE_CTRL, 0x00},
0261 {MAX98397_R209B_SPK_PATH_WB_ONLY, 0x00},
0262 {MAX98396_R209C_SPK_EDGE_CTRL1, 0x03},
0263 {MAX98396_R209D_SPK_EDGE_CTRL2, 0xFC},
0264 {MAX98396_R209E_AMP_CLIP_GAIN, 0x00},
0265 {MAX98396_R209F_BYPASS_PATH_CFG, 0x00},
0266 {MAX98396_R20AF_AMP_EN, 0x00},
0267 {MAX98396_R20B0_ADC_SR, 0x30},
0268 {MAX98396_R20B1_ADC_PVDD_CFG, 0x00},
0269 {MAX98396_R20B2_ADC_VBAT_CFG, 0x00},
0270 {MAX98396_R20B3_ADC_THERMAL_CFG, 0x00},
0271 {MAX98397_R20B4_ADC_VDDH_CFG, 0x00},
0272 {MAX98397_R20B5_ADC_READBACK_CTRL1, 0x00},
0273 {MAX98397_R20B6_ADC_READBACK_CTRL2, 0x00},
0274 {MAX98397_R20B7_ADC_PVDD_READBACK_MSB, 0x00},
0275 {MAX98397_R20B8_ADC_PVDD_READBACK_LSB, 0x00},
0276 {MAX98397_R20B9_ADC_VBAT_READBACK_MSB, 0x00},
0277 {MAX98397_R20BA_ADC_VBAT_READBACK_LSB, 0x00},
0278 {MAX98397_R20BB_ADC_TEMP_READBACK_MSB, 0x00},
0279 {MAX98397_R20BC_ADC_TEMP_READBACK_LSB, 0x00},
0280 {MAX98397_R20BD_ADC_VDDH__READBACK_MSB, 0x00},
0281 {MAX98397_R20BE_ADC_VDDH_READBACK_LSB, 0x00},
0282 {MAX98396_R20BF_ADC_LO_VBAT_READBACK_LSB, 0x00},
0283 {MAX98397_R20C3_ADC_LO_VDDH_READBACK_MSB, 0x00},
0284 {MAX98397_R20C4_ADC_LO_VDDH_READBACK_LSB, 0x00},
0285 {MAX98397_R20C5_MEAS_ADC_OPTIMAL_MODE, 0x04},
0286 {MAX98396_R20C7_ADC_CFG, 0x00},
0287 {MAX98396_R20D0_DHT_CFG1, 0x00},
0288 {MAX98396_R20D1_LIMITER_CFG1, 0x08},
0289 {MAX98396_R20D2_LIMITER_CFG2, 0x00},
0290 {MAX98396_R20D3_DHT_CFG2, 0x14},
0291 {MAX98396_R20D4_DHT_CFG3, 0x02},
0292 {MAX98396_R20D5_DHT_CFG4, 0x04},
0293 {MAX98396_R20D6_DHT_HYSTERESIS_CFG, 0x07},
0294 {MAX98396_R20DF_DHT_EN, 0x00},
0295 {MAX98396_R20E0_IV_SENSE_PATH_CFG, 0x04},
0296 {MAX98396_R20E4_IV_SENSE_PATH_EN, 0x00},
0297 {MAX98396_R20E5_BPE_STATE, 0x00},
0298 {MAX98396_R20E6_BPE_L3_THRESH_MSB, 0x00},
0299 {MAX98396_R20E7_BPE_L3_THRESH_LSB, 0x00},
0300 {MAX98396_R20E8_BPE_L2_THRESH_MSB, 0x00},
0301 {MAX98396_R20E9_BPE_L2_THRESH_LSB, 0x00},
0302 {MAX98396_R20EA_BPE_L1_THRESH_MSB, 0x00},
0303 {MAX98396_R20EB_BPE_L1_THRESH_LSB, 0x00},
0304 {MAX98396_R20EC_BPE_L0_THRESH_MSB, 0x00},
0305 {MAX98396_R20ED_BPE_L0_THRESH_LSB, 0x00},
0306 {MAX98396_R20EE_BPE_L3_DWELL_HOLD_TIME, 0x00},
0307 {MAX98396_R20EF_BPE_L2_DWELL_HOLD_TIME, 0x00},
0308 {MAX98396_R20F0_BPE_L1_DWELL_HOLD_TIME, 0x00},
0309 {MAX98396_R20F1_BPE_L0_HOLD_TIME, 0x00},
0310 {MAX98396_R20F2_BPE_L3_ATTACK_REL_STEP, 0x00},
0311 {MAX98396_R20F3_BPE_L2_ATTACK_REL_STEP, 0x00},
0312 {MAX98396_R20F4_BPE_L1_ATTACK_REL_STEP, 0x00},
0313 {MAX98396_R20F5_BPE_L0_ATTACK_REL_STEP, 0x00},
0314 {MAX98396_R20F6_BPE_L3_MAX_GAIN_ATTN, 0x00},
0315 {MAX98396_R20F7_BPE_L2_MAX_GAIN_ATTN, 0x00},
0316 {MAX98396_R20F8_BPE_L1_MAX_GAIN_ATTN, 0x00},
0317 {MAX98396_R20F9_BPE_L0_MAX_GAIN_ATTN, 0x00},
0318 {MAX98396_R20FA_BPE_L3_ATT_REL_RATE, 0x00},
0319 {MAX98396_R20FB_BPE_L2_ATT_REL_RATE, 0x00},
0320 {MAX98396_R20FC_BPE_L1_ATT_REL_RATE, 0x00},
0321 {MAX98396_R20FD_BPE_L0_ATT_REL_RATE, 0x00},
0322 {MAX98396_R20FE_BPE_L3_LIMITER_CFG, 0x00},
0323 {MAX98396_R20FF_BPE_L2_LIMITER_CFG, 0x00},
0324 {MAX98396_R2100_BPE_L1_LIMITER_CFG, 0x00},
0325 {MAX98396_R2101_BPE_L0_LIMITER_CFG, 0x00},
0326 {MAX98396_R2102_BPE_L3_LIM_ATT_REL_RATE, 0x00},
0327 {MAX98396_R2103_BPE_L2_LIM_ATT_REL_RATE, 0x00},
0328 {MAX98396_R2104_BPE_L1_LIM_ATT_REL_RATE, 0x00},
0329 {MAX98396_R2105_BPE_L0_LIM_ATT_REL_RATE, 0x00},
0330 {MAX98396_R2106_BPE_THRESH_HYSTERESIS, 0x00},
0331 {MAX98396_R2107_BPE_INFINITE_HOLD_CLR, 0x00},
0332 {MAX98396_R2108_BPE_SUPPLY_SRC, 0x00},
0333 {MAX98396_R2109_BPE_LOW_STATE, 0x00},
0334 {MAX98396_R210A_BPE_LOW_GAIN, 0x00},
0335 {MAX98396_R210B_BPE_LOW_LIMITER, 0x00},
0336 {MAX98396_R210D_BPE_EN, 0x00},
0337 {MAX98396_R210E_AUTO_RESTART, 0x00},
0338 {MAX98396_R210F_GLOBAL_EN, 0x00},
0339 {MAX98397_R22FF_REVISION_ID, 0x00},
0340 };
0341
0342 static void max98396_global_enable_onoff(struct regmap *regmap, bool onoff)
0343 {
0344 regmap_write(regmap, MAX98396_R210F_GLOBAL_EN, onoff ? 1 : 0);
0345 usleep_range(11000, 12000);
0346 }
0347
0348 static int max98396_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
0349 {
0350 struct snd_soc_component *component = codec_dai->component;
0351 struct max98396_priv *max98396 = snd_soc_component_get_drvdata(component);
0352 unsigned int format_mask, format = 0;
0353 unsigned int bclk_pol = 0;
0354 int ret, status;
0355 int reg;
0356 bool update = false;
0357
0358 format_mask = MAX98396_PCM_MODE_CFG_FORMAT_MASK |
0359 MAX98396_PCM_MODE_CFG_LRCLKEDGE;
0360
0361 dev_dbg(component->dev, "%s: fmt 0x%08X\n", __func__, fmt);
0362
0363 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
0364 case SND_SOC_DAIFMT_NB_NF:
0365 break;
0366 case SND_SOC_DAIFMT_NB_IF:
0367 format = MAX98396_PCM_MODE_CFG_LRCLKEDGE;
0368 break;
0369 case SND_SOC_DAIFMT_IB_NF:
0370 bclk_pol = MAX98396_PCM_MODE_CFG_BCLKEDGE;
0371 break;
0372 case SND_SOC_DAIFMT_IB_IF:
0373 bclk_pol = MAX98396_PCM_MODE_CFG_BCLKEDGE;
0374 format = MAX98396_PCM_MODE_CFG_LRCLKEDGE;
0375 break;
0376
0377 default:
0378 dev_err(component->dev, "DAI invert mode %d unsupported\n",
0379 fmt & SND_SOC_DAIFMT_INV_MASK);
0380 return -EINVAL;
0381 }
0382
0383
0384 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
0385 case SND_SOC_DAIFMT_I2S:
0386 format |= MAX98396_PCM_FORMAT_I2S;
0387 break;
0388 case SND_SOC_DAIFMT_LEFT_J:
0389 format |= MAX98396_PCM_FORMAT_LJ;
0390 break;
0391 case SND_SOC_DAIFMT_DSP_A:
0392 format |= MAX98396_PCM_FORMAT_TDM_MODE1;
0393 break;
0394 case SND_SOC_DAIFMT_DSP_B:
0395 format |= MAX98396_PCM_FORMAT_TDM_MODE0;
0396 break;
0397 default:
0398 dev_err(component->dev, "DAI format %d unsupported\n",
0399 fmt & SND_SOC_DAIFMT_FORMAT_MASK);
0400 return -EINVAL;
0401 }
0402
0403 ret = regmap_read(max98396->regmap, MAX98396_R210F_GLOBAL_EN, &status);
0404 if (ret < 0)
0405 return -EINVAL;
0406
0407 if (status) {
0408 ret = regmap_read(max98396->regmap, MAX98396_R2041_PCM_MODE_CFG, ®);
0409 if (ret < 0)
0410 return -EINVAL;
0411 if (format != (reg & format_mask)) {
0412 update = true;
0413 } else {
0414 ret = regmap_read(max98396->regmap,
0415 MAX98396_R2042_PCM_CLK_SETUP, ®);
0416 if (ret < 0)
0417 return -EINVAL;
0418 if (bclk_pol != (reg & MAX98396_PCM_MODE_CFG_BCLKEDGE))
0419 update = true;
0420 }
0421
0422 if (update)
0423 max98396_global_enable_onoff(max98396->regmap, false);
0424 }
0425
0426 regmap_update_bits(max98396->regmap,
0427 MAX98396_R2041_PCM_MODE_CFG,
0428 format_mask, format);
0429
0430 regmap_update_bits(max98396->regmap,
0431 MAX98396_R2042_PCM_CLK_SETUP,
0432 MAX98396_PCM_MODE_CFG_BCLKEDGE,
0433 bclk_pol);
0434
0435 if (status && update)
0436 max98396_global_enable_onoff(max98396->regmap, true);
0437
0438 return 0;
0439 }
0440
0441 #define MAX98396_BSEL_32 0x2
0442 #define MAX98396_BSEL_48 0x3
0443 #define MAX98396_BSEL_64 0x4
0444 #define MAX98396_BSEL_96 0x5
0445 #define MAX98396_BSEL_128 0x6
0446 #define MAX98396_BSEL_192 0x7
0447 #define MAX98396_BSEL_256 0x8
0448 #define MAX98396_BSEL_384 0x9
0449 #define MAX98396_BSEL_512 0xa
0450 #define MAX98396_BSEL_320 0xb
0451 #define MAX98396_BSEL_250 0xc
0452 #define MAX98396_BSEL_125 0xd
0453
0454
0455 static const struct max98396_pcm_config {
0456 int in, out, width, bsel, max_sr;
0457 } max98396_pcm_configs[] = {
0458 { .in = 2, .out = 4, .width = 16, .bsel = MAX98396_BSEL_32, .max_sr = 192000 },
0459 { .in = 2, .out = 6, .width = 24, .bsel = MAX98396_BSEL_48, .max_sr = 192000 },
0460 { .in = 2, .out = 8, .width = 32, .bsel = MAX98396_BSEL_64, .max_sr = 192000 },
0461 { .in = 3, .out = 15, .width = 32, .bsel = MAX98396_BSEL_125, .max_sr = 192000 },
0462 { .in = 4, .out = 8, .width = 16, .bsel = MAX98396_BSEL_64, .max_sr = 192000 },
0463 { .in = 4, .out = 12, .width = 24, .bsel = MAX98396_BSEL_96, .max_sr = 192000 },
0464 { .in = 4, .out = 16, .width = 32, .bsel = MAX98396_BSEL_128, .max_sr = 192000 },
0465 { .in = 5, .out = 15, .width = 24, .bsel = MAX98396_BSEL_125, .max_sr = 192000 },
0466 { .in = 7, .out = 15, .width = 16, .bsel = MAX98396_BSEL_125, .max_sr = 192000 },
0467 { .in = 2, .out = 4, .width = 16, .bsel = MAX98396_BSEL_32, .max_sr = 96000 },
0468 { .in = 2, .out = 6, .width = 24, .bsel = MAX98396_BSEL_48, .max_sr = 96000 },
0469 { .in = 2, .out = 8, .width = 32, .bsel = MAX98396_BSEL_64, .max_sr = 96000 },
0470 { .in = 3, .out = 15, .width = 32, .bsel = MAX98396_BSEL_125, .max_sr = 96000 },
0471 { .in = 4, .out = 8, .width = 16, .bsel = MAX98396_BSEL_64, .max_sr = 96000 },
0472 { .in = 4, .out = 12, .width = 24, .bsel = MAX98396_BSEL_96, .max_sr = 96000 },
0473 { .in = 4, .out = 16, .width = 32, .bsel = MAX98396_BSEL_128, .max_sr = 96000 },
0474 { .in = 5, .out = 15, .width = 24, .bsel = MAX98396_BSEL_125, .max_sr = 96000 },
0475 { .in = 7, .out = 15, .width = 16, .bsel = MAX98396_BSEL_125, .max_sr = 96000 },
0476 { .in = 7, .out = 31, .width = 32, .bsel = MAX98396_BSEL_250, .max_sr = 96000 },
0477 { .in = 8, .out = 16, .width = 16, .bsel = MAX98396_BSEL_128, .max_sr = 96000 },
0478 { .in = 8, .out = 24, .width = 24, .bsel = MAX98396_BSEL_192, .max_sr = 96000 },
0479 { .in = 8, .out = 32, .width = 32, .bsel = MAX98396_BSEL_256, .max_sr = 96000 },
0480 { .in = 10, .out = 31, .width = 24, .bsel = MAX98396_BSEL_250, .max_sr = 96000 },
0481 { .in = 15, .out = 31, .width = 16, .bsel = MAX98396_BSEL_250, .max_sr = 96000 },
0482 { .in = 16, .out = 32, .width = 16, .bsel = MAX98396_BSEL_256, .max_sr = 96000 },
0483 { .in = 7, .out = 31, .width = 32, .bsel = MAX98396_BSEL_250, .max_sr = 48000 },
0484 { .in = 10, .out = 31, .width = 24, .bsel = MAX98396_BSEL_250, .max_sr = 48000 },
0485 { .in = 10, .out = 40, .width = 32, .bsel = MAX98396_BSEL_320, .max_sr = 48000 },
0486 { .in = 15, .out = 31, .width = 16, .bsel = MAX98396_BSEL_250, .max_sr = 48000 },
0487 { .in = 16, .out = 48, .width = 24, .bsel = MAX98396_BSEL_384, .max_sr = 48000 },
0488 { .in = 16, .out = 64, .width = 32, .bsel = MAX98396_BSEL_512, .max_sr = 48000 },
0489 };
0490
0491 static int max98396_pcm_config_index(int in_slots, int out_slots, int width)
0492 {
0493 int i;
0494
0495 for (i = 0; i < ARRAY_SIZE(max98396_pcm_configs); i++) {
0496 const struct max98396_pcm_config *c = &max98396_pcm_configs[i];
0497
0498 if (in_slots == c->in && out_slots <= c->out && width == c->width)
0499 return i;
0500 }
0501
0502 return -1;
0503 }
0504
0505 static int max98396_dai_hw_params(struct snd_pcm_substream *substream,
0506 struct snd_pcm_hw_params *params,
0507 struct snd_soc_dai *dai)
0508 {
0509 struct snd_soc_component *component = dai->component;
0510 struct max98396_priv *max98396 = snd_soc_component_get_drvdata(component);
0511 unsigned int sampling_rate = 0;
0512 unsigned int chan_sz = 0;
0513 int ret, reg, status, bsel = 0;
0514 bool update = false;
0515
0516
0517 switch (snd_pcm_format_width(params_format(params))) {
0518 case 16:
0519 chan_sz = MAX98396_PCM_MODE_CFG_CHANSZ_16;
0520 break;
0521 case 24:
0522 chan_sz = MAX98396_PCM_MODE_CFG_CHANSZ_24;
0523 break;
0524 case 32:
0525 chan_sz = MAX98396_PCM_MODE_CFG_CHANSZ_32;
0526 break;
0527 default:
0528 dev_err(component->dev, "format unsupported %d\n",
0529 params_format(params));
0530 goto err;
0531 }
0532
0533 dev_dbg(component->dev, "format supported %d",
0534 params_format(params));
0535
0536
0537 switch (params_rate(params)) {
0538 case 8000:
0539 sampling_rate = MAX98396_PCM_SR_8000;
0540 break;
0541 case 11025:
0542 sampling_rate = MAX98396_PCM_SR_11025;
0543 break;
0544 case 12000:
0545 sampling_rate = MAX98396_PCM_SR_12000;
0546 break;
0547 case 16000:
0548 sampling_rate = MAX98396_PCM_SR_16000;
0549 break;
0550 case 22050:
0551 sampling_rate = MAX98396_PCM_SR_22050;
0552 break;
0553 case 24000:
0554 sampling_rate = MAX98396_PCM_SR_24000;
0555 break;
0556 case 32000:
0557 sampling_rate = MAX98396_PCM_SR_32000;
0558 break;
0559 case 44100:
0560 sampling_rate = MAX98396_PCM_SR_44100;
0561 break;
0562 case 48000:
0563 sampling_rate = MAX98396_PCM_SR_48000;
0564 break;
0565 case 88200:
0566 sampling_rate = MAX98396_PCM_SR_88200;
0567 break;
0568 case 96000:
0569 sampling_rate = MAX98396_PCM_SR_96000;
0570 break;
0571 case 192000:
0572 sampling_rate = MAX98396_PCM_SR_192000;
0573 break;
0574 default:
0575 dev_err(component->dev, "rate %d not supported\n",
0576 params_rate(params));
0577 goto err;
0578 }
0579
0580 if (max98396->tdm_mode) {
0581 if (params_rate(params) > max98396->tdm_max_samplerate) {
0582 dev_err(component->dev, "TDM sample rate %d too high",
0583 params_rate(params));
0584 goto err;
0585 }
0586 } else {
0587
0588 ret = max98396_pcm_config_index(params_channels(params),
0589 params_channels(params),
0590 snd_pcm_format_width(params_format(params)));
0591 if (ret < 0) {
0592 dev_err(component->dev,
0593 "no PCM config for %d channels, format %d\n",
0594 params_channels(params), params_format(params));
0595 goto err;
0596 }
0597
0598 bsel = max98396_pcm_configs[ret].bsel;
0599
0600 if (params_rate(params) > max98396_pcm_configs[ret].max_sr) {
0601 dev_err(component->dev, "sample rate %d too high",
0602 params_rate(params));
0603 goto err;
0604 }
0605 }
0606
0607 ret = regmap_read(max98396->regmap, MAX98396_R210F_GLOBAL_EN, &status);
0608 if (ret < 0)
0609 goto err;
0610
0611 if (status) {
0612 ret = regmap_read(max98396->regmap, MAX98396_R2041_PCM_MODE_CFG, ®);
0613 if (ret < 0)
0614 goto err;
0615 if (chan_sz != (reg & MAX98396_PCM_MODE_CFG_CHANSZ_MASK)) {
0616 update = true;
0617 } else {
0618 ret = regmap_read(max98396->regmap, MAX98396_R2043_PCM_SR_SETUP, ®);
0619 if (ret < 0)
0620 goto err;
0621 if (sampling_rate != (reg & MAX98396_PCM_SR_MASK))
0622 update = true;
0623 }
0624
0625
0626 if (update)
0627 max98396_global_enable_onoff(max98396->regmap, false);
0628 }
0629
0630
0631 regmap_update_bits(max98396->regmap, MAX98396_R2041_PCM_MODE_CFG,
0632 MAX98396_PCM_MODE_CFG_CHANSZ_MASK, chan_sz);
0633
0634
0635 regmap_update_bits(max98396->regmap, MAX98396_R2043_PCM_SR_SETUP,
0636 MAX98396_PCM_SR_MASK, sampling_rate);
0637
0638
0639 if (max98396->interleave_mode &&
0640 sampling_rate > MAX98396_PCM_SR_16000)
0641 regmap_update_bits(max98396->regmap,
0642 MAX98396_R2043_PCM_SR_SETUP,
0643 MAX98396_IVADC_SR_MASK,
0644 (sampling_rate - 3)
0645 << MAX98396_IVADC_SR_SHIFT);
0646 else
0647 regmap_update_bits(max98396->regmap,
0648 MAX98396_R2043_PCM_SR_SETUP,
0649 MAX98396_IVADC_SR_MASK,
0650 sampling_rate << MAX98396_IVADC_SR_SHIFT);
0651
0652 if (bsel)
0653 regmap_update_bits(max98396->regmap,
0654 MAX98396_R2042_PCM_CLK_SETUP,
0655 MAX98396_PCM_CLK_SETUP_BSEL_MASK,
0656 bsel);
0657
0658 if (status && update)
0659 max98396_global_enable_onoff(max98396->regmap, true);
0660
0661 return 0;
0662
0663 err:
0664 return -EINVAL;
0665 }
0666
0667 static int max98396_dai_tdm_slot(struct snd_soc_dai *dai,
0668 unsigned int tx_mask, unsigned int rx_mask,
0669 int slots, int slot_width)
0670 {
0671 struct snd_soc_component *component = dai->component;
0672 struct max98396_priv *max98396 =
0673 snd_soc_component_get_drvdata(component);
0674 int bsel;
0675 unsigned int chan_sz = 0;
0676 int ret, status;
0677 int reg;
0678 bool update = false;
0679
0680 if (!tx_mask && !rx_mask && !slots && !slot_width)
0681 max98396->tdm_mode = false;
0682 else
0683 max98396->tdm_mode = true;
0684
0685
0686 ret = max98396_pcm_config_index(slots, slots, slot_width);
0687 if (ret < 0) {
0688 dev_err(component->dev, "no TDM config for %d slots %d bits\n",
0689 slots, slot_width);
0690 return -EINVAL;
0691 }
0692
0693 bsel = max98396_pcm_configs[ret].bsel;
0694 max98396->tdm_max_samplerate = max98396_pcm_configs[ret].max_sr;
0695
0696
0697 switch (slot_width) {
0698 case 16:
0699 chan_sz = MAX98396_PCM_MODE_CFG_CHANSZ_16;
0700 break;
0701 case 24:
0702 chan_sz = MAX98396_PCM_MODE_CFG_CHANSZ_24;
0703 break;
0704 case 32:
0705 chan_sz = MAX98396_PCM_MODE_CFG_CHANSZ_32;
0706 break;
0707 default:
0708 dev_err(component->dev, "slot width %d unsupported\n",
0709 slot_width);
0710 return -EINVAL;
0711 }
0712
0713 ret = regmap_read(max98396->regmap, MAX98396_R210F_GLOBAL_EN, &status);
0714 if (ret < 0)
0715 return -EINVAL;
0716
0717 if (status) {
0718 ret = regmap_read(max98396->regmap, MAX98396_R2042_PCM_CLK_SETUP, ®);
0719 if (ret < 0)
0720 return -EINVAL;
0721 if (bsel != (reg & MAX98396_PCM_CLK_SETUP_BSEL_MASK)) {
0722 update = true;
0723 } else {
0724 ret = regmap_read(max98396->regmap, MAX98396_R2041_PCM_MODE_CFG, ®);
0725 if (ret < 0)
0726 return -EINVAL;
0727 if (chan_sz != (reg & MAX98396_PCM_MODE_CFG_CHANSZ_MASK))
0728 update = true;
0729 }
0730
0731
0732 if (update)
0733 max98396_global_enable_onoff(max98396->regmap, false);
0734 }
0735
0736 regmap_update_bits(max98396->regmap,
0737 MAX98396_R2042_PCM_CLK_SETUP,
0738 MAX98396_PCM_CLK_SETUP_BSEL_MASK,
0739 bsel);
0740
0741 regmap_update_bits(max98396->regmap,
0742 MAX98396_R2041_PCM_MODE_CFG,
0743 MAX98396_PCM_MODE_CFG_CHANSZ_MASK, chan_sz);
0744
0745
0746 if (max98396->device_id == CODEC_TYPE_MAX98396) {
0747 regmap_update_bits(max98396->regmap,
0748 MAX98396_R2056_PCM_RX_SRC2,
0749 MAX98396_PCM_DMIX_CH0_SRC_MASK,
0750 rx_mask);
0751 regmap_update_bits(max98396->regmap,
0752 MAX98396_R2056_PCM_RX_SRC2,
0753 MAX98396_PCM_DMIX_CH1_SRC_MASK,
0754 rx_mask << MAX98396_PCM_DMIX_CH1_SHIFT);
0755 } else {
0756 regmap_update_bits(max98396->regmap,
0757 MAX98397_R2057_PCM_RX_SRC2,
0758 MAX98396_PCM_DMIX_CH0_SRC_MASK,
0759 rx_mask);
0760 regmap_update_bits(max98396->regmap,
0761 MAX98397_R2057_PCM_RX_SRC2,
0762 MAX98396_PCM_DMIX_CH1_SRC_MASK,
0763 rx_mask << MAX98396_PCM_DMIX_CH1_SHIFT);
0764 }
0765
0766
0767 if (max98396->device_id == CODEC_TYPE_MAX98396) {
0768 regmap_write(max98396->regmap,
0769 MAX98396_R2053_PCM_TX_HIZ_CTRL_8,
0770 ~tx_mask & 0xFF);
0771 regmap_write(max98396->regmap,
0772 MAX98396_R2052_PCM_TX_HIZ_CTRL_7,
0773 (~tx_mask & 0xFF00) >> 8);
0774 } else {
0775 regmap_write(max98396->regmap,
0776 MAX98397_R2054_PCM_TX_HIZ_CTRL_8,
0777 ~tx_mask & 0xFF);
0778 regmap_write(max98396->regmap,
0779 MAX98397_R2053_PCM_TX_HIZ_CTRL_7,
0780 (~tx_mask & 0xFF00) >> 8);
0781 }
0782
0783 if (status && update)
0784 max98396_global_enable_onoff(max98396->regmap, true);
0785
0786 return 0;
0787 }
0788
0789 #define MAX98396_RATES SNDRV_PCM_RATE_8000_192000
0790
0791 #define MAX98396_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
0792 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
0793
0794 static const struct snd_soc_dai_ops max98396_dai_ops = {
0795 .set_fmt = max98396_dai_set_fmt,
0796 .hw_params = max98396_dai_hw_params,
0797 .set_tdm_slot = max98396_dai_tdm_slot,
0798 };
0799
0800 static int max98396_dac_event(struct snd_soc_dapm_widget *w,
0801 struct snd_kcontrol *kcontrol, int event)
0802 {
0803 struct snd_soc_component *component =
0804 snd_soc_dapm_to_component(w->dapm);
0805 struct max98396_priv *max98396 =
0806 snd_soc_component_get_drvdata(component);
0807
0808 switch (event) {
0809 case SND_SOC_DAPM_POST_PMU:
0810 max98396_global_enable_onoff(max98396->regmap, true);
0811 break;
0812 case SND_SOC_DAPM_PRE_PMD:
0813 max98396_global_enable_onoff(max98396->regmap, false);
0814
0815 max98396->tdm_mode = false;
0816 break;
0817 default:
0818 return 0;
0819 }
0820 return 0;
0821 }
0822
0823 static bool max98396_readable_register(struct device *dev, unsigned int reg)
0824 {
0825 switch (reg) {
0826 case MAX98396_R2001_INT_RAW1 ... MAX98396_R2004_INT_RAW4:
0827 case MAX98396_R2006_INT_STATE1 ... MAX98396_R2009_INT_STATE4:
0828 case MAX98396_R200B_INT_FLAG1 ... MAX98396_R200E_INT_FLAG4:
0829 case MAX98396_R2010_INT_EN1 ... MAX98396_R2013_INT_EN4:
0830 case MAX98396_R2015_INT_FLAG_CLR1 ... MAX98396_R2018_INT_FLAG_CLR4:
0831 case MAX98396_R201F_IRQ_CTRL ... MAX98396_R2024_THERM_FOLDBACK_SET:
0832 case MAX98396_R2027_THERM_FOLDBACK_EN:
0833 case MAX98396_R2030_NOISEGATE_MODE_CTRL:
0834 case MAX98396_R2033_NOISEGATE_MODE_EN:
0835 case MAX98396_R2038_CLK_MON_CTRL ... MAX98396_R2039_DATA_MON_CTRL:
0836 case MAX98396_R203F_ENABLE_CTRLS ... MAX98396_R2053_PCM_TX_HIZ_CTRL_8:
0837 case MAX98396_R2055_PCM_RX_SRC1 ... MAX98396_R2056_PCM_RX_SRC2:
0838 case MAX98396_R2058_PCM_BYPASS_SRC:
0839 case MAX98396_R205D_PCM_TX_SRC_EN ... MAX98396_R205F_PCM_TX_EN:
0840 case MAX98396_R2070_ICC_RX_EN_A... MAX98396_R2072_ICC_TX_CTRL:
0841 case MAX98396_R207F_ICC_EN:
0842 case MAX98396_R2083_TONE_GEN_DC_CFG ... MAX98396_R2086_TONE_GEN_DC_LVL3:
0843 case MAX98396_R208F_TONE_GEN_EN ... MAX98396_R209A_SPK_EDGE_CTRL:
0844 case MAX98396_R209C_SPK_EDGE_CTRL1 ... MAX98396_R20A0_AMP_SUPPLY_CTL:
0845 case MAX98396_R20AF_AMP_EN ... MAX98396_R20BF_ADC_LO_VBAT_READBACK_LSB:
0846 case MAX98396_R20C7_ADC_CFG:
0847 case MAX98396_R20D0_DHT_CFG1 ... MAX98396_R20D6_DHT_HYSTERESIS_CFG:
0848 case MAX98396_R20DF_DHT_EN:
0849 case MAX98396_R20E0_IV_SENSE_PATH_CFG:
0850 case MAX98396_R20E4_IV_SENSE_PATH_EN
0851 ... MAX98396_R2106_BPE_THRESH_HYSTERESIS:
0852 case MAX98396_R2108_BPE_SUPPLY_SRC ... MAX98396_R210B_BPE_LOW_LIMITER:
0853 case MAX98396_R210D_BPE_EN ... MAX98396_R210F_GLOBAL_EN:
0854 case MAX98396_R21FF_REVISION_ID:
0855 return true;
0856 default:
0857 return false;
0858 }
0859 };
0860
0861 static bool max98396_volatile_reg(struct device *dev, unsigned int reg)
0862 {
0863 switch (reg) {
0864 case MAX98396_R2000_SW_RESET:
0865 case MAX98396_R2001_INT_RAW1 ... MAX98396_R200E_INT_FLAG4:
0866 case MAX98396_R2041_PCM_MODE_CFG:
0867 case MAX98396_R20B6_ADC_PVDD_READBACK_MSB
0868 ... MAX98396_R20BF_ADC_LO_VBAT_READBACK_LSB:
0869 case MAX98396_R20E5_BPE_STATE:
0870 case MAX98396_R2109_BPE_LOW_STATE
0871 ... MAX98396_R210B_BPE_LOW_LIMITER:
0872 case MAX98396_R210F_GLOBAL_EN:
0873 case MAX98396_R21FF_REVISION_ID:
0874 return true;
0875 default:
0876 return false;
0877 }
0878 }
0879
0880 static bool max98397_readable_register(struct device *dev, unsigned int reg)
0881 {
0882 switch (reg) {
0883 case MAX98396_R2001_INT_RAW1 ... MAX98396_R2004_INT_RAW4:
0884 case MAX98396_R2006_INT_STATE1 ... MAX98396_R2009_INT_STATE4:
0885 case MAX98396_R200B_INT_FLAG1 ... MAX98396_R200E_INT_FLAG4:
0886 case MAX98396_R2010_INT_EN1 ... MAX98396_R2013_INT_EN4:
0887 case MAX98396_R2015_INT_FLAG_CLR1 ... MAX98396_R2018_INT_FLAG_CLR4:
0888 case MAX98396_R201F_IRQ_CTRL ... MAX98396_R2024_THERM_FOLDBACK_SET:
0889 case MAX98396_R2027_THERM_FOLDBACK_EN:
0890 case MAX98396_R2030_NOISEGATE_MODE_CTRL:
0891 case MAX98396_R2033_NOISEGATE_MODE_EN:
0892 case MAX98396_R2038_CLK_MON_CTRL ... MAX98397_R203A_SPK_MON_THRESH:
0893 case MAX98396_R203F_ENABLE_CTRLS ... MAX98397_R2054_PCM_TX_HIZ_CTRL_8:
0894 case MAX98397_R2056_PCM_RX_SRC1... MAX98396_R2058_PCM_BYPASS_SRC:
0895 case MAX98396_R205D_PCM_TX_SRC_EN ... MAX98397_R2060_PCM_TX_SUPPLY_SEL:
0896 case MAX98396_R2070_ICC_RX_EN_A... MAX98396_R2072_ICC_TX_CTRL:
0897 case MAX98396_R207F_ICC_EN:
0898 case MAX98396_R2083_TONE_GEN_DC_CFG ... MAX98396_R2086_TONE_GEN_DC_LVL3:
0899 case MAX98396_R208F_TONE_GEN_EN ... MAX98396_R209F_BYPASS_PATH_CFG:
0900 case MAX98396_R20AF_AMP_EN ... MAX98397_R20C5_MEAS_ADC_OPTIMAL_MODE:
0901 case MAX98396_R20C7_ADC_CFG:
0902 case MAX98396_R20D0_DHT_CFG1 ... MAX98396_R20D6_DHT_HYSTERESIS_CFG:
0903 case MAX98396_R20DF_DHT_EN:
0904 case MAX98396_R20E0_IV_SENSE_PATH_CFG:
0905 case MAX98396_R20E4_IV_SENSE_PATH_EN
0906 ... MAX98396_R2106_BPE_THRESH_HYSTERESIS:
0907 case MAX98396_R2108_BPE_SUPPLY_SRC ... MAX98396_R210B_BPE_LOW_LIMITER:
0908 case MAX98396_R210D_BPE_EN ... MAX98396_R210F_GLOBAL_EN:
0909 case MAX98397_R22FF_REVISION_ID:
0910 return true;
0911 default:
0912 return false;
0913 }
0914 };
0915
0916 static bool max98397_volatile_reg(struct device *dev, unsigned int reg)
0917 {
0918 switch (reg) {
0919 case MAX98396_R2001_INT_RAW1 ... MAX98396_R200E_INT_FLAG4:
0920 case MAX98396_R2041_PCM_MODE_CFG:
0921 case MAX98397_R20B7_ADC_PVDD_READBACK_MSB
0922 ... MAX98397_R20C4_ADC_LO_VDDH_READBACK_LSB:
0923 case MAX98396_R20E5_BPE_STATE:
0924 case MAX98396_R2109_BPE_LOW_STATE
0925 ... MAX98396_R210B_BPE_LOW_LIMITER:
0926 case MAX98396_R210F_GLOBAL_EN:
0927 case MAX98397_R22FF_REVISION_ID:
0928 return true;
0929 default:
0930 return false;
0931 }
0932 }
0933
0934 static const char * const max98396_op_mod_text[] = {
0935 "DG", "PVDD", "VBAT",
0936 };
0937
0938 static SOC_ENUM_SINGLE_DECL(max98396_op_mod_enum,
0939 MAX98396_R2098_SPK_CLS_DG_MODE,
0940 0, max98396_op_mod_text);
0941
0942 static DECLARE_TLV_DB_SCALE(max98396_digital_tlv, -6350, 50, 1);
0943 static const DECLARE_TLV_DB_RANGE(max98396_spk_tlv,
0944 0, 0x11, TLV_DB_SCALE_ITEM(400, 100, 0),
0945 );
0946 static DECLARE_TLV_DB_RANGE(max98397_digital_tlv,
0947 0, 0x4A, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1),
0948 0x4B, 0xFF, TLV_DB_SCALE_ITEM(-9000, 50, 0),
0949 );
0950 static const DECLARE_TLV_DB_RANGE(max98397_spk_tlv,
0951 0, 0x15, TLV_DB_SCALE_ITEM(600, 100, 0),
0952 );
0953
0954 static int max98396_mux_get(struct snd_kcontrol *kcontrol,
0955 struct snd_ctl_elem_value *ucontrol)
0956 {
0957 struct snd_soc_component *component =
0958 snd_soc_dapm_kcontrol_component(kcontrol);
0959 struct max98396_priv *max98396 = snd_soc_component_get_drvdata(component);
0960 int reg, val;
0961
0962 if (max98396->device_id == CODEC_TYPE_MAX98396)
0963 reg = MAX98396_R2055_PCM_RX_SRC1;
0964 else
0965 reg = MAX98397_R2056_PCM_RX_SRC1;
0966
0967 regmap_read(max98396->regmap, reg, &val);
0968
0969 ucontrol->value.enumerated.item[0] = val;
0970
0971 return 0;
0972 }
0973
0974 static int max98396_mux_put(struct snd_kcontrol *kcontrol,
0975 struct snd_ctl_elem_value *ucontrol)
0976 {
0977 struct snd_soc_component *component =
0978 snd_soc_dapm_kcontrol_component(kcontrol);
0979 struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol);
0980 struct max98396_priv *max98396 = snd_soc_component_get_drvdata(component);
0981 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
0982 unsigned int *item = ucontrol->value.enumerated.item;
0983 int reg, val;
0984 int change;
0985
0986 if (item[0] >= e->items)
0987 return -EINVAL;
0988
0989 val = snd_soc_enum_item_to_val(e, item[0]) << e->shift_l;
0990
0991 if (max98396->device_id == CODEC_TYPE_MAX98396)
0992 reg = MAX98396_R2055_PCM_RX_SRC1;
0993 else
0994 reg = MAX98397_R2056_PCM_RX_SRC1;
0995
0996 change = snd_soc_component_test_bits(component, reg,
0997 MAX98396_PCM_RX_MASK, val);
0998
0999 if (change)
1000 regmap_update_bits(max98396->regmap, reg,
1001 MAX98396_PCM_RX_MASK, val);
1002
1003 snd_soc_dapm_mux_update_power(dapm, kcontrol, item[0], e, NULL);
1004
1005 return change;
1006 }
1007
1008 static const char * const max98396_switch_text[] = {
1009 "Left", "Right", "LeftRight"};
1010
1011 static SOC_ENUM_SINGLE_DECL(dai_sel_enum, SND_SOC_NOPM, 0,
1012 max98396_switch_text);
1013
1014 static const struct snd_kcontrol_new max98396_dai_mux =
1015 SOC_DAPM_ENUM_EXT("DAI Sel Mux", dai_sel_enum,
1016 max98396_mux_get, max98396_mux_put);
1017
1018 static const struct snd_kcontrol_new max98396_vi_control =
1019 SOC_DAPM_SINGLE("Switch", MAX98396_R205F_PCM_TX_EN, 0, 1, 0);
1020
1021 static const struct snd_soc_dapm_widget max98396_dapm_widgets[] = {
1022 SND_SOC_DAPM_DAC_E("Amp Enable", "HiFi Playback",
1023 MAX98396_R20AF_AMP_EN, 0, 0, max98396_dac_event,
1024 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1025 SND_SOC_DAPM_MUX("DAI Sel Mux", SND_SOC_NOPM, 0, 0,
1026 &max98396_dai_mux),
1027 SND_SOC_DAPM_OUTPUT("BE_OUT"),
1028 SND_SOC_DAPM_AIF_OUT("Voltage Sense", "HiFi Capture", 0,
1029 MAX98396_R20E4_IV_SENSE_PATH_EN, 0, 0),
1030 SND_SOC_DAPM_AIF_OUT("Current Sense", "HiFi Capture", 0,
1031 MAX98396_R20E4_IV_SENSE_PATH_EN, 1, 0),
1032 SND_SOC_DAPM_SWITCH("VI Sense", SND_SOC_NOPM, 0, 0,
1033 &max98396_vi_control),
1034 SND_SOC_DAPM_SIGGEN("VMON"),
1035 SND_SOC_DAPM_SIGGEN("IMON"),
1036 SND_SOC_DAPM_SIGGEN("FBMON"),
1037 };
1038
1039 static const char * const max98396_thermal_thresh_text[] = {
1040 "50C", "51C", "52C", "53C", "54C", "55C", "56C", "57C",
1041 "58C", "59C", "60C", "61C", "62C", "63C", "64C", "65C",
1042 "66C", "67C", "68C", "69C", "70C", "71C", "72C", "73C",
1043 "74C", "75C", "76C", "77C", "78C", "79C", "80C", "81C",
1044 "82C", "83C", "84C", "85C", "86C", "87C", "88C", "89C",
1045 "90C", "91C", "92C", "93C", "94C", "95C", "96C", "97C",
1046 "98C", "99C", "100C", "101C", "102C", "103C", "104C", "105C",
1047 "106C", "107C", "108C", "109C", "110C", "111C", "112C", "113C",
1048 "114C", "115C", "116C", "117C", "118C", "119C", "120C", "121C",
1049 "122C", "123C", "124C", "125C", "126C", "127C", "128C", "129C",
1050 "130C", "131C", "132C", "133C", "134C", "135C", "136C", "137C",
1051 "138C", "139C", "140C", "141C", "142C", "143C", "144C", "145C",
1052 "146C", "147C", "148C", "149C", "150C"
1053 };
1054
1055 static SOC_ENUM_SINGLE_DECL(max98396_thermal_warn_thresh1_enum,
1056 MAX98396_R2020_THERM_WARN_THRESH, 0,
1057 max98396_thermal_thresh_text);
1058
1059 static SOC_ENUM_SINGLE_DECL(max98396_thermal_warn_thresh2_enum,
1060 MAX98396_R2021_THERM_WARN_THRESH2, 0,
1061 max98396_thermal_thresh_text);
1062
1063 static SOC_ENUM_SINGLE_DECL(max98396_thermal_shdn_thresh_enum,
1064 MAX98396_R2022_THERM_SHDN_THRESH, 0,
1065 max98396_thermal_thresh_text);
1066
1067 static const char * const max98396_thermal_hyteresis_text[] = {
1068 "2C", "5C", "7C", "10C"
1069 };
1070
1071 static SOC_ENUM_SINGLE_DECL(max98396_thermal_hysteresis_enum,
1072 MAX98396_R2023_THERM_HYSTERESIS, 0,
1073 max98396_thermal_hyteresis_text);
1074
1075 static const char * const max98396_foldback_slope_text[] = {
1076 "0.25", "0.5", "1.0", "2.0"
1077 };
1078
1079 static SOC_ENUM_SINGLE_DECL(max98396_thermal_fb_slope1_enum,
1080 MAX98396_R2024_THERM_FOLDBACK_SET,
1081 MAX98396_THERM_FB_SLOPE1_SHIFT,
1082 max98396_foldback_slope_text);
1083
1084 static SOC_ENUM_SINGLE_DECL(max98396_thermal_fb_slope2_enum,
1085 MAX98396_R2024_THERM_FOLDBACK_SET,
1086 MAX98396_THERM_FB_SLOPE2_SHIFT,
1087 max98396_foldback_slope_text);
1088
1089 static const char * const max98396_foldback_reltime_text[] = {
1090 "3ms", "10ms", "100ms", "300ms"
1091 };
1092
1093 static SOC_ENUM_SINGLE_DECL(max98396_thermal_fb_reltime_enum,
1094 MAX98396_R2024_THERM_FOLDBACK_SET,
1095 MAX98396_THERM_FB_REL_SHIFT,
1096 max98396_foldback_reltime_text);
1097
1098 static const char * const max98396_foldback_holdtime_text[] = {
1099 "0ms", "20ms", "40ms", "80ms"
1100 };
1101
1102 static SOC_ENUM_SINGLE_DECL(max98396_thermal_fb_holdtime_enum,
1103 MAX98396_R2024_THERM_FOLDBACK_SET,
1104 MAX98396_THERM_FB_HOLD_SHIFT,
1105 max98396_foldback_holdtime_text);
1106
1107 static int max98396_adc_value_get(struct snd_kcontrol *kcontrol,
1108 struct snd_ctl_elem_value *ucontrol)
1109 {
1110 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
1111 struct soc_mixer_control *mc =
1112 (struct soc_mixer_control *)kcontrol->private_value;
1113 struct max98396_priv *max98396 = snd_soc_component_get_drvdata(component);
1114 int ret;
1115 u8 val[2];
1116 int reg = mc->reg;
1117
1118
1119 if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)
1120 goto exit;
1121
1122 if (max98396->device_id == CODEC_TYPE_MAX98397) {
1123 switch (mc->reg) {
1124 case MAX98396_R20B6_ADC_PVDD_READBACK_MSB:
1125 reg = MAX98397_R20B7_ADC_PVDD_READBACK_MSB;
1126 break;
1127 case MAX98396_R20B8_ADC_VBAT_READBACK_MSB:
1128 reg = MAX98397_R20B9_ADC_VBAT_READBACK_MSB;
1129 break;
1130 case MAX98396_R20BA_ADC_TEMP_READBACK_MSB:
1131 reg = MAX98397_R20BB_ADC_TEMP_READBACK_MSB;
1132 break;
1133 default:
1134 goto exit;
1135 }
1136 }
1137
1138 ret = regmap_raw_read(max98396->regmap, reg, &val, 2);
1139 if (ret)
1140 goto exit;
1141
1142
1143 ucontrol->value.integer.value[0] = (val[0] << 1) | (val[1] & 1);
1144 return 0;
1145
1146 exit:
1147 ucontrol->value.integer.value[0] = 0;
1148 return 0;
1149 }
1150
1151 static const struct snd_kcontrol_new max98396_snd_controls[] = {
1152
1153 SOC_SINGLE_TLV("Digital Volume", MAX98396_R2090_AMP_VOL_CTRL,
1154 0, 0x7F, 1, max98396_digital_tlv),
1155 SOC_SINGLE_TLV("Speaker Volume", MAX98396_R2091_AMP_PATH_GAIN,
1156 0, 0x11, 0, max98396_spk_tlv),
1157
1158 SOC_SINGLE("Ramp Up Switch", MAX98396_R2092_AMP_DSP_CFG,
1159 MAX98396_DSP_SPK_VOL_RMPUP_SHIFT, 1, 0),
1160 SOC_SINGLE("Ramp Down Switch", MAX98396_R2092_AMP_DSP_CFG,
1161 MAX98396_DSP_SPK_VOL_RMPDN_SHIFT, 1, 0),
1162
1163 SOC_SINGLE("CLK Monitor Switch", MAX98396_R203F_ENABLE_CTRLS,
1164 MAX98396_CTRL_CMON_EN_SHIFT, 1, 0),
1165
1166 SOC_SINGLE("Dither Switch", MAX98396_R2092_AMP_DSP_CFG,
1167 MAX98396_DSP_SPK_DITH_EN_SHIFT, 1, 0),
1168 SOC_SINGLE("IV Dither Switch", MAX98396_R20E0_IV_SENSE_PATH_CFG,
1169 MAX98396_IV_SENSE_DITH_EN_SHIFT, 1, 0),
1170
1171 SOC_SINGLE("DC Blocker Switch", MAX98396_R2092_AMP_DSP_CFG,
1172 MAX98396_DSP_SPK_DCBLK_EN_SHIFT, 1, 0),
1173 SOC_SINGLE("IV DC Blocker Switch", MAX98396_R20E0_IV_SENSE_PATH_CFG,
1174 MAX98396_IV_SENSE_DCBLK_EN_SHIFT, 3, 0),
1175
1176 SOC_SINGLE("Safe Mode Switch", MAX98396_R2092_AMP_DSP_CFG,
1177 MAX98396_DSP_SPK_SAFE_EN_SHIFT, 1, 0),
1178
1179 SOC_SINGLE("WB Filter Switch", MAX98396_R2092_AMP_DSP_CFG,
1180 MAX98396_DSP_SPK_WB_FLT_EN_SHIFT, 1, 0),
1181 SOC_SINGLE("IV WB Filter Switch", MAX98396_R20E0_IV_SENSE_PATH_CFG,
1182 MAX98396_IV_SENSE_WB_FLT_EN_SHIFT, 1, 0),
1183
1184 SOC_SINGLE("DHT Switch", MAX98396_R20DF_DHT_EN, 0, 1, 0),
1185
1186 SOC_SINGLE("BPE Switch", MAX98396_R210D_BPE_EN, 0, 1, 0),
1187 SOC_SINGLE("BPE Limiter Switch", MAX98396_R210D_BPE_EN, 1, 1, 0),
1188
1189 SOC_SINGLE("Bypass Path Switch",
1190 MAX98396_R205E_PCM_RX_EN, 1, 1, 0),
1191
1192 SOC_ENUM("OP Mode", max98396_op_mod_enum),
1193
1194 SOC_SINGLE("CMON Auto Restart Switch", MAX98396_R2038_CLK_MON_CTRL,
1195 MAX98396_CLK_MON_AUTO_RESTART_SHIFT, 1, 0),
1196 SOC_SINGLE("PVDD Auto Restart Switch", MAX98396_R210E_AUTO_RESTART,
1197 MAX98396_PVDD_UVLO_RESTART_SHFT, 1, 0),
1198 SOC_SINGLE("VBAT Auto Restart Switch", MAX98396_R210E_AUTO_RESTART,
1199 MAX98396_VBAT_UVLO_RESTART_SHFT, 1, 0),
1200 SOC_SINGLE("THERM Auto Restart Switch", MAX98396_R210E_AUTO_RESTART,
1201 MAX98396_THEM_SHDN_RESTART_SHFT, 1, 0),
1202 SOC_SINGLE("OVC Auto Restart Switch", MAX98396_R210E_AUTO_RESTART,
1203 MAX98396_OVC_RESTART_SHFT, 1, 0),
1204
1205 SOC_ENUM("THERM Thresh1", max98396_thermal_warn_thresh1_enum),
1206 SOC_ENUM("THERM Thresh2", max98396_thermal_warn_thresh2_enum),
1207 SOC_ENUM("THERM SHDN Thresh", max98396_thermal_shdn_thresh_enum),
1208 SOC_ENUM("THERM Hysteresis", max98396_thermal_hysteresis_enum),
1209 SOC_SINGLE("THERM Foldback Switch",
1210 MAX98396_R2027_THERM_FOLDBACK_EN, 0, 1, 0),
1211 SOC_ENUM("THERM Slope1", max98396_thermal_fb_slope1_enum),
1212 SOC_ENUM("THERM Slope2", max98396_thermal_fb_slope2_enum),
1213 SOC_ENUM("THERM Release", max98396_thermal_fb_reltime_enum),
1214 SOC_ENUM("THERM Hold", max98396_thermal_fb_holdtime_enum),
1215
1216 SOC_SINGLE_EXT("ADC PVDD", MAX98396_R20B6_ADC_PVDD_READBACK_MSB, 0, 0x1FF, 0,
1217 max98396_adc_value_get, NULL),
1218 SOC_SINGLE_EXT("ADC VBAT", MAX98396_R20B8_ADC_VBAT_READBACK_MSB, 0, 0x1FF, 0,
1219 max98396_adc_value_get, NULL),
1220 SOC_SINGLE_EXT("ADC TEMP", MAX98396_R20BA_ADC_TEMP_READBACK_MSB, 0, 0x1FF, 0,
1221 max98396_adc_value_get, NULL),
1222 };
1223
1224 static const struct snd_kcontrol_new max98397_snd_controls[] = {
1225
1226 SOC_SINGLE_TLV("Digital Volume", MAX98396_R2090_AMP_VOL_CTRL,
1227 0, 0xFF, 1, max98397_digital_tlv),
1228 SOC_SINGLE_TLV("Speaker Volume", MAX98396_R2091_AMP_PATH_GAIN,
1229 0, 0x15, 0, max98397_spk_tlv),
1230
1231 SOC_SINGLE("Ramp Up Switch", MAX98396_R2092_AMP_DSP_CFG,
1232 MAX98396_DSP_SPK_VOL_RMPUP_SHIFT, 1, 0),
1233 SOC_SINGLE("Ramp Down Switch", MAX98396_R2092_AMP_DSP_CFG,
1234 MAX98396_DSP_SPK_VOL_RMPDN_SHIFT, 1, 0),
1235
1236 SOC_SINGLE("CLK Monitor Switch", MAX98396_R203F_ENABLE_CTRLS,
1237 MAX98396_CTRL_CMON_EN_SHIFT, 1, 0),
1238
1239 SOC_SINGLE("Dither Switch", MAX98396_R2092_AMP_DSP_CFG,
1240 MAX98396_DSP_SPK_DITH_EN_SHIFT, 1, 0),
1241 SOC_SINGLE("IV Dither Switch", MAX98396_R20E0_IV_SENSE_PATH_CFG,
1242 MAX98396_IV_SENSE_DITH_EN_SHIFT, 1, 0),
1243
1244 SOC_SINGLE("DC Blocker Switch", MAX98396_R2092_AMP_DSP_CFG,
1245 MAX98396_DSP_SPK_DCBLK_EN_SHIFT, 1, 0),
1246 SOC_SINGLE("IV DC Blocker Switch", MAX98396_R20E0_IV_SENSE_PATH_CFG,
1247 MAX98396_IV_SENSE_DCBLK_EN_SHIFT, 3, 0),
1248
1249 SOC_SINGLE("Safe Mode Switch", MAX98396_R2092_AMP_DSP_CFG,
1250 MAX98396_DSP_SPK_SAFE_EN_SHIFT, 1, 0),
1251
1252 SOC_SINGLE("WB Filter Switch", MAX98396_R2092_AMP_DSP_CFG,
1253 MAX98396_DSP_SPK_WB_FLT_EN_SHIFT, 1, 0),
1254 SOC_SINGLE("IV WB Filter Switch", MAX98396_R20E0_IV_SENSE_PATH_CFG,
1255 MAX98396_IV_SENSE_WB_FLT_EN_SHIFT, 1, 0),
1256
1257 SOC_SINGLE("DHT Switch", MAX98396_R20DF_DHT_EN, 0, 1, 0),
1258
1259 SOC_SINGLE("BPE Switch", MAX98396_R210D_BPE_EN, 0, 1, 0),
1260 SOC_SINGLE("BPE Limiter Switch", MAX98396_R210D_BPE_EN, 1, 1, 0),
1261
1262 SOC_SINGLE("Bypass Path Switch",
1263 MAX98396_R205E_PCM_RX_EN, 1, 1, 0),
1264
1265 SOC_ENUM("OP Mode", max98396_op_mod_enum),
1266
1267 SOC_SINGLE("CMON Auto Restart Switch", MAX98396_R2038_CLK_MON_CTRL,
1268 MAX98396_CLK_MON_AUTO_RESTART_SHIFT, 1, 0),
1269 SOC_SINGLE("PVDD Auto Restart Switch", MAX98396_R210E_AUTO_RESTART,
1270 MAX98396_PVDD_UVLO_RESTART_SHFT, 1, 0),
1271 SOC_SINGLE("VBAT Auto Restart Switch", MAX98396_R210E_AUTO_RESTART,
1272 MAX98396_VBAT_UVLO_RESTART_SHFT, 1, 0),
1273 SOC_SINGLE("THERM Auto Restart Switch", MAX98396_R210E_AUTO_RESTART,
1274 MAX98396_THEM_SHDN_RESTART_SHFT, 1, 0),
1275 SOC_SINGLE("OVC Auto Restart Switch", MAX98396_R210E_AUTO_RESTART,
1276 MAX98396_OVC_RESTART_SHFT, 1, 0),
1277
1278 SOC_ENUM("THERM Thresh1", max98396_thermal_warn_thresh1_enum),
1279 SOC_ENUM("THERM Thresh2", max98396_thermal_warn_thresh2_enum),
1280 SOC_ENUM("THERM SHDN Thresh", max98396_thermal_shdn_thresh_enum),
1281 SOC_ENUM("THERM Hysteresis", max98396_thermal_hysteresis_enum),
1282 SOC_SINGLE("THERM Foldback Switch",
1283 MAX98396_R2027_THERM_FOLDBACK_EN, 0, 1, 0),
1284 SOC_ENUM("THERM Slope1", max98396_thermal_fb_slope1_enum),
1285 SOC_ENUM("THERM Slope2", max98396_thermal_fb_slope2_enum),
1286 SOC_ENUM("THERM Release", max98396_thermal_fb_reltime_enum),
1287 SOC_ENUM("THERM Hold", max98396_thermal_fb_holdtime_enum),
1288
1289 SOC_SINGLE_EXT("ADC PVDD", MAX98396_R20B6_ADC_PVDD_READBACK_MSB, 0, 0x1FF, 0,
1290 max98396_adc_value_get, NULL),
1291 SOC_SINGLE_EXT("ADC VBAT", MAX98396_R20B8_ADC_VBAT_READBACK_MSB, 0, 0x1FF, 0,
1292 max98396_adc_value_get, NULL),
1293 SOC_SINGLE_EXT("ADC TEMP", MAX98396_R20BA_ADC_TEMP_READBACK_MSB, 0, 0x1FF, 0,
1294 max98396_adc_value_get, NULL),
1295 };
1296
1297 static const struct snd_soc_dapm_route max98396_audio_map[] = {
1298
1299 {"DAI Sel Mux", "Left", "Amp Enable"},
1300 {"DAI Sel Mux", "Right", "Amp Enable"},
1301 {"DAI Sel Mux", "LeftRight", "Amp Enable"},
1302 {"BE_OUT", NULL, "DAI Sel Mux"},
1303
1304 { "VI Sense", "Switch", "VMON" },
1305 { "VI Sense", "Switch", "IMON" },
1306 { "Voltage Sense", NULL, "VI Sense" },
1307 { "Current Sense", NULL, "VI Sense" },
1308 };
1309
1310 static struct snd_soc_dai_driver max98396_dai[] = {
1311 {
1312 .name = "max98396-aif1",
1313 .playback = {
1314 .stream_name = "HiFi Playback",
1315 .channels_min = 1,
1316 .channels_max = 2,
1317 .rates = MAX98396_RATES,
1318 .formats = MAX98396_FORMATS,
1319 },
1320 .capture = {
1321 .stream_name = "HiFi Capture",
1322 .channels_min = 1,
1323 .channels_max = 2,
1324 .rates = MAX98396_RATES,
1325 .formats = MAX98396_FORMATS,
1326 },
1327 .ops = &max98396_dai_ops,
1328 }
1329 };
1330
1331 static struct snd_soc_dai_driver max98397_dai[] = {
1332 {
1333 .name = "max98397-aif1",
1334 .playback = {
1335 .stream_name = "HiFi Playback",
1336 .channels_min = 1,
1337 .channels_max = 2,
1338 .rates = MAX98396_RATES,
1339 .formats = MAX98396_FORMATS,
1340 },
1341 .capture = {
1342 .stream_name = "HiFi Capture",
1343 .channels_min = 1,
1344 .channels_max = 2,
1345 .rates = MAX98396_RATES,
1346 .formats = MAX98396_FORMATS,
1347 },
1348 .ops = &max98396_dai_ops,
1349 }
1350 };
1351
1352 static void max98396_reset(struct max98396_priv *max98396, struct device *dev)
1353 {
1354 int ret, reg, count;
1355
1356
1357 ret = regmap_write(max98396->regmap,
1358 MAX98396_R2000_SW_RESET, 1);
1359 if (ret)
1360 dev_err(dev, "Reset command failed. (ret:%d)\n", ret);
1361
1362 count = 0;
1363 while (count < 3) {
1364 usleep_range(5000, 6000);
1365
1366 ret = regmap_read(max98396->regmap,
1367 GET_REG_ADDR_REV_ID(max98396->device_id), ®);
1368 if (!ret) {
1369 dev_info(dev, "Reset completed (retry:%d)\n", count);
1370 return;
1371 }
1372 count++;
1373 }
1374 dev_err(dev, "Reset failed. (ret:%d)\n", ret);
1375 }
1376
1377 static int max98396_probe(struct snd_soc_component *component)
1378 {
1379 struct max98396_priv *max98396 =
1380 snd_soc_component_get_drvdata(component);
1381
1382
1383 max98396_reset(max98396, component->dev);
1384
1385
1386 if (max98396->device_id == CODEC_TYPE_MAX98396) {
1387 regmap_write(max98396->regmap,
1388 MAX98396_R2055_PCM_RX_SRC1, 0x02);
1389 regmap_write(max98396->regmap,
1390 MAX98396_R2056_PCM_RX_SRC2, 0x10);
1391 } else {
1392 regmap_write(max98396->regmap,
1393 MAX98397_R2056_PCM_RX_SRC1, 0x02);
1394 regmap_write(max98396->regmap,
1395 MAX98397_R2057_PCM_RX_SRC2, 0x10);
1396 }
1397
1398 regmap_update_bits(max98396->regmap,
1399 MAX98396_R20A0_AMP_SUPPLY_CTL,
1400 MAX98396_AMP_SUPPLY_NOVBAT,
1401 (max98396->vbat == NULL) ?
1402 MAX98396_AMP_SUPPLY_NOVBAT : 0);
1403
1404 regmap_update_bits(max98396->regmap,
1405 MAX98396_R2092_AMP_DSP_CFG, 1, 1);
1406
1407 regmap_update_bits(max98396->regmap,
1408 MAX98396_R20E0_IV_SENSE_PATH_CFG,
1409 MAX98396_IV_SENSE_DCBLK_EN_MASK,
1410 MAX98396_IV_SENSE_DCBLK_EN_MASK);
1411
1412 regmap_write(max98396->regmap,
1413 MAX98396_R205D_PCM_TX_SRC_EN, 3);
1414
1415 regmap_update_bits(max98396->regmap,
1416 MAX98396_R2092_AMP_DSP_CFG, 0x40, 0x40);
1417
1418 regmap_update_bits(max98396->regmap,
1419 MAX98396_R20E0_IV_SENSE_PATH_CFG, 8, 8);
1420
1421
1422 regmap_write(max98396->regmap,
1423 MAX98396_R2058_PCM_BYPASS_SRC,
1424 max98396->bypass_slot);
1425
1426 regmap_write(max98396->regmap,
1427 MAX98396_R2044_PCM_TX_CTRL_1,
1428 max98396->v_slot);
1429 regmap_write(max98396->regmap,
1430 MAX98396_R2045_PCM_TX_CTRL_2,
1431 max98396->i_slot);
1432 regmap_write(max98396->regmap,
1433 MAX98396_R204A_PCM_TX_CTRL_7,
1434 max98396->spkfb_slot);
1435
1436 if (max98396->v_slot < 8)
1437 if (max98396->device_id == CODEC_TYPE_MAX98396)
1438 regmap_update_bits(max98396->regmap,
1439 MAX98396_R2053_PCM_TX_HIZ_CTRL_8,
1440 1 << max98396->v_slot, 0);
1441 else
1442 regmap_update_bits(max98396->regmap,
1443 MAX98397_R2054_PCM_TX_HIZ_CTRL_8,
1444 1 << max98396->v_slot, 0);
1445 else
1446 if (max98396->device_id == CODEC_TYPE_MAX98396)
1447 regmap_update_bits(max98396->regmap,
1448 MAX98396_R2052_PCM_TX_HIZ_CTRL_7,
1449 1 << (max98396->v_slot - 8), 0);
1450 else
1451 regmap_update_bits(max98396->regmap,
1452 MAX98397_R2053_PCM_TX_HIZ_CTRL_7,
1453 1 << (max98396->v_slot - 8), 0);
1454
1455 if (max98396->i_slot < 8)
1456 if (max98396->device_id == CODEC_TYPE_MAX98396)
1457 regmap_update_bits(max98396->regmap,
1458 MAX98396_R2053_PCM_TX_HIZ_CTRL_8,
1459 1 << max98396->i_slot, 0);
1460 else
1461 regmap_update_bits(max98396->regmap,
1462 MAX98397_R2054_PCM_TX_HIZ_CTRL_8,
1463 1 << max98396->i_slot, 0);
1464 else
1465 if (max98396->device_id == CODEC_TYPE_MAX98396)
1466 regmap_update_bits(max98396->regmap,
1467 MAX98396_R2052_PCM_TX_HIZ_CTRL_7,
1468 1 << (max98396->i_slot - 8), 0);
1469 else
1470 regmap_update_bits(max98396->regmap,
1471 MAX98397_R2053_PCM_TX_HIZ_CTRL_7,
1472 1 << (max98396->i_slot - 8), 0);
1473
1474
1475 if (max98396->interleave_mode)
1476 regmap_update_bits(max98396->regmap,
1477 MAX98396_R2041_PCM_MODE_CFG,
1478 MAX98396_PCM_TX_CH_INTERLEAVE_MASK,
1479 MAX98396_PCM_TX_CH_INTERLEAVE_MASK);
1480
1481 regmap_update_bits(max98396->regmap,
1482 MAX98396_R2038_CLK_MON_CTRL,
1483 MAX98396_CLK_MON_AUTO_RESTART_MASK,
1484 MAX98396_CLK_MON_AUTO_RESTART_MASK);
1485
1486
1487 regmap_update_bits(max98396->regmap,
1488 MAX98396_R205E_PCM_RX_EN,
1489 MAX98396_PCM_RX_EN_MASK, 1);
1490
1491 return 0;
1492 }
1493
1494 #ifdef CONFIG_PM_SLEEP
1495 static int max98396_suspend(struct device *dev)
1496 {
1497 struct max98396_priv *max98396 = dev_get_drvdata(dev);
1498
1499 regcache_cache_only(max98396->regmap, true);
1500 regcache_mark_dirty(max98396->regmap);
1501 regulator_bulk_disable(MAX98396_NUM_CORE_SUPPLIES,
1502 max98396->core_supplies);
1503 if (max98396->pvdd)
1504 regulator_disable(max98396->pvdd);
1505
1506 if (max98396->vbat)
1507 regulator_disable(max98396->vbat);
1508
1509 return 0;
1510 }
1511
1512 static int max98396_resume(struct device *dev)
1513 {
1514 struct max98396_priv *max98396 = dev_get_drvdata(dev);
1515 int ret;
1516
1517 ret = regulator_bulk_enable(MAX98396_NUM_CORE_SUPPLIES,
1518 max98396->core_supplies);
1519 if (ret < 0)
1520 return ret;
1521
1522 if (max98396->pvdd) {
1523 ret = regulator_enable(max98396->pvdd);
1524 if (ret < 0)
1525 return ret;
1526 }
1527
1528 if (max98396->vbat) {
1529 ret = regulator_enable(max98396->vbat);
1530 if (ret < 0)
1531 return ret;
1532 }
1533
1534 regcache_cache_only(max98396->regmap, false);
1535 max98396_reset(max98396, dev);
1536 regcache_sync(max98396->regmap);
1537 return 0;
1538 }
1539 #endif
1540
1541 static const struct dev_pm_ops max98396_pm = {
1542 SET_SYSTEM_SLEEP_PM_OPS(max98396_suspend, max98396_resume)
1543 };
1544
1545 static const struct snd_soc_component_driver soc_codec_dev_max98396 = {
1546 .probe = max98396_probe,
1547 .controls = max98396_snd_controls,
1548 .num_controls = ARRAY_SIZE(max98396_snd_controls),
1549 .dapm_widgets = max98396_dapm_widgets,
1550 .num_dapm_widgets = ARRAY_SIZE(max98396_dapm_widgets),
1551 .dapm_routes = max98396_audio_map,
1552 .num_dapm_routes = ARRAY_SIZE(max98396_audio_map),
1553 .idle_bias_on = 1,
1554 .use_pmdown_time = 1,
1555 .endianness = 1,
1556 };
1557
1558 static const struct snd_soc_component_driver soc_codec_dev_max98397 = {
1559 .probe = max98396_probe,
1560 .controls = max98397_snd_controls,
1561 .num_controls = ARRAY_SIZE(max98397_snd_controls),
1562 .dapm_widgets = max98396_dapm_widgets,
1563 .num_dapm_widgets = ARRAY_SIZE(max98396_dapm_widgets),
1564 .dapm_routes = max98396_audio_map,
1565 .num_dapm_routes = ARRAY_SIZE(max98396_audio_map),
1566 .idle_bias_on = 1,
1567 .use_pmdown_time = 1,
1568 .endianness = 1,
1569 };
1570
1571 static const struct regmap_config max98396_regmap = {
1572 .reg_bits = 16,
1573 .val_bits = 8,
1574 .max_register = MAX98396_R21FF_REVISION_ID,
1575 .reg_defaults = max98396_reg,
1576 .num_reg_defaults = ARRAY_SIZE(max98396_reg),
1577 .readable_reg = max98396_readable_register,
1578 .volatile_reg = max98396_volatile_reg,
1579 .cache_type = REGCACHE_RBTREE,
1580 };
1581
1582 static const struct regmap_config max98397_regmap = {
1583 .reg_bits = 16,
1584 .val_bits = 8,
1585 .max_register = MAX98397_R22FF_REVISION_ID,
1586 .reg_defaults = max98397_reg,
1587 .num_reg_defaults = ARRAY_SIZE(max98397_reg),
1588 .readable_reg = max98397_readable_register,
1589 .volatile_reg = max98397_volatile_reg,
1590 .cache_type = REGCACHE_RBTREE,
1591 };
1592
1593 static void max98396_read_device_property(struct device *dev,
1594 struct max98396_priv *max98396)
1595 {
1596 int value;
1597
1598 if (!device_property_read_u32(dev, "adi,vmon-slot-no", &value))
1599 max98396->v_slot = value & 0xF;
1600 else
1601 max98396->v_slot = 0;
1602
1603 if (!device_property_read_u32(dev, "adi,imon-slot-no", &value))
1604 max98396->i_slot = value & 0xF;
1605 else
1606 max98396->i_slot = 1;
1607
1608 if (!device_property_read_u32(dev, "adi,spkfb-slot-no", &value))
1609 max98396->spkfb_slot = value & 0xF;
1610 else
1611 max98396->spkfb_slot = 2;
1612
1613 if (!device_property_read_u32(dev, "adi,bypass-slot-no", &value))
1614 max98396->bypass_slot = value & 0xF;
1615 else
1616 max98396->bypass_slot = 0;
1617 }
1618
1619 static void max98396_core_supplies_disable(void *priv)
1620 {
1621 struct max98396_priv *max98396 = priv;
1622
1623 regulator_bulk_disable(MAX98396_NUM_CORE_SUPPLIES,
1624 max98396->core_supplies);
1625 }
1626
1627 static void max98396_supply_disable(void *r)
1628 {
1629 regulator_disable((struct regulator *) r);
1630 }
1631
1632 static int max98396_i2c_probe(struct i2c_client *i2c,
1633 const struct i2c_device_id *id)
1634 {
1635 struct max98396_priv *max98396 = NULL;
1636 int i, ret, reg;
1637
1638 max98396 = devm_kzalloc(&i2c->dev, sizeof(*max98396), GFP_KERNEL);
1639
1640 if (!max98396) {
1641 ret = -ENOMEM;
1642 return ret;
1643 }
1644 i2c_set_clientdata(i2c, max98396);
1645
1646 max98396->device_id = id->driver_data;
1647
1648
1649 if (max98396->device_id == CODEC_TYPE_MAX98396)
1650 max98396->regmap = devm_regmap_init_i2c(i2c, &max98396_regmap);
1651
1652 else
1653 max98396->regmap = devm_regmap_init_i2c(i2c, &max98397_regmap);
1654
1655 if (IS_ERR(max98396->regmap)) {
1656 ret = PTR_ERR(max98396->regmap);
1657 dev_err(&i2c->dev,
1658 "Failed to allocate regmap: %d\n", ret);
1659 return ret;
1660 }
1661
1662
1663 for (i = 0; i < MAX98396_NUM_CORE_SUPPLIES; i++)
1664 max98396->core_supplies[i].supply = max98396_core_supplies[i];
1665
1666 ret = devm_regulator_bulk_get(&i2c->dev, MAX98396_NUM_CORE_SUPPLIES,
1667 max98396->core_supplies);
1668 if (ret < 0) {
1669 dev_err(&i2c->dev, "Failed to request core supplies: %d\n", ret);
1670 return ret;
1671 }
1672
1673 max98396->vbat = devm_regulator_get_optional(&i2c->dev, "vbat");
1674 if (IS_ERR(max98396->vbat)) {
1675 if (PTR_ERR(max98396->vbat) == -EPROBE_DEFER)
1676 return -EPROBE_DEFER;
1677
1678 max98396->vbat = NULL;
1679 }
1680
1681 max98396->pvdd = devm_regulator_get_optional(&i2c->dev, "pvdd");
1682 if (IS_ERR(max98396->pvdd)) {
1683 if (PTR_ERR(max98396->pvdd) == -EPROBE_DEFER)
1684 return -EPROBE_DEFER;
1685
1686 max98396->pvdd = NULL;
1687 }
1688
1689 ret = regulator_bulk_enable(MAX98396_NUM_CORE_SUPPLIES,
1690 max98396->core_supplies);
1691 if (ret < 0) {
1692 dev_err(&i2c->dev, "Unable to enable core supplies: %d", ret);
1693 return ret;
1694 }
1695
1696 ret = devm_add_action_or_reset(&i2c->dev, max98396_core_supplies_disable,
1697 max98396);
1698 if (ret < 0)
1699 return ret;
1700
1701 if (max98396->pvdd) {
1702 ret = regulator_enable(max98396->pvdd);
1703 if (ret < 0)
1704 return ret;
1705
1706 ret = devm_add_action_or_reset(&i2c->dev,
1707 max98396_supply_disable,
1708 max98396->pvdd);
1709 if (ret < 0)
1710 return ret;
1711 }
1712
1713 if (max98396->vbat) {
1714 ret = regulator_enable(max98396->vbat);
1715 if (ret < 0)
1716 return ret;
1717
1718 ret = devm_add_action_or_reset(&i2c->dev,
1719 max98396_supply_disable,
1720 max98396->vbat);
1721 if (ret < 0)
1722 return ret;
1723 }
1724
1725
1726 if (device_property_read_bool(&i2c->dev, "adi,interleave_mode"))
1727 max98396->interleave_mode = true;
1728 else
1729 max98396->interleave_mode = false;
1730
1731
1732 max98396_read_device_property(&i2c->dev, max98396);
1733
1734
1735 max98396->reset_gpio = devm_gpiod_get_optional(&i2c->dev,
1736 "reset", GPIOD_OUT_HIGH);
1737 if (IS_ERR(max98396->reset_gpio)) {
1738 ret = PTR_ERR(max98396->reset_gpio);
1739 dev_err(&i2c->dev, "Unable to request GPIO pin: %d.\n", ret);
1740 return ret;
1741 }
1742
1743 if (max98396->reset_gpio) {
1744 usleep_range(5000, 6000);
1745 gpiod_set_value_cansleep(max98396->reset_gpio, 0);
1746
1747 usleep_range(5000, 6000);
1748 }
1749
1750 ret = regmap_read(max98396->regmap,
1751 GET_REG_ADDR_REV_ID(max98396->device_id), ®);
1752 if (ret < 0) {
1753 dev_err(&i2c->dev, "%s: failed to read revision of the device.\n", id->name);
1754 return ret;
1755 }
1756 dev_info(&i2c->dev, "%s revision ID: 0x%02X\n", id->name, reg);
1757
1758
1759 if (max98396->device_id == CODEC_TYPE_MAX98396)
1760 ret = devm_snd_soc_register_component(&i2c->dev,
1761 &soc_codec_dev_max98396,
1762 max98396_dai,
1763 ARRAY_SIZE(max98396_dai));
1764 else
1765 ret = devm_snd_soc_register_component(&i2c->dev,
1766 &soc_codec_dev_max98397,
1767 max98397_dai,
1768 ARRAY_SIZE(max98397_dai));
1769 if (ret < 0)
1770 dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
1771
1772 return ret;
1773 }
1774
1775 static const struct i2c_device_id max98396_i2c_id[] = {
1776 { "max98396", CODEC_TYPE_MAX98396},
1777 { "max98397", CODEC_TYPE_MAX98397},
1778 { },
1779 };
1780
1781 MODULE_DEVICE_TABLE(i2c, max98396_i2c_id);
1782
1783 #if defined(CONFIG_OF)
1784 static const struct of_device_id max98396_of_match[] = {
1785 { .compatible = "adi,max98396", },
1786 { .compatible = "adi,max98397", },
1787 { }
1788 };
1789 MODULE_DEVICE_TABLE(of, max98396_of_match);
1790 #endif
1791
1792 #ifdef CONFIG_ACPI
1793 static const struct acpi_device_id max98396_acpi_match[] = {
1794 { "ADS8396", 0 },
1795 { "ADS8397", 0 },
1796 {},
1797 };
1798 MODULE_DEVICE_TABLE(acpi, max98396_acpi_match);
1799 #endif
1800
1801 static struct i2c_driver max98396_i2c_driver = {
1802 .driver = {
1803 .name = "max98396",
1804 .of_match_table = of_match_ptr(max98396_of_match),
1805 .acpi_match_table = ACPI_PTR(max98396_acpi_match),
1806 .pm = &max98396_pm,
1807 },
1808 .probe = max98396_i2c_probe,
1809 .id_table = max98396_i2c_id,
1810 };
1811
1812 module_i2c_driver(max98396_i2c_driver)
1813
1814 MODULE_DESCRIPTION("ALSA SoC MAX98396 driver");
1815 MODULE_AUTHOR("Ryan Lee <ryans.lee@analog.com>");
1816 MODULE_LICENSE("GPL");