cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

max98396.c (53931B)


      1// SPDX-License-Identifier: GPL-2.0
      2// Copyright (c) 2022, Analog Devices Inc.
      3
      4#include <linux/gpio/consumer.h>
      5#include <linux/i2c.h>
      6#include <linux/module.h>
      7#include <sound/pcm_params.h>
      8#include <sound/soc.h>
      9#include <linux/gpio.h>
     10#include <sound/tlv.h>
     11#include "max98396.h"
     12
     13static struct reg_default max98396_reg[] = {
     14	{MAX98396_R2000_SW_RESET, 0x00},
     15	{MAX98396_R2001_INT_RAW1, 0x00},
     16	{MAX98396_R2002_INT_RAW2, 0x00},
     17	{MAX98396_R2003_INT_RAW3, 0x00},
     18	{MAX98396_R2004_INT_RAW4, 0x00},
     19	{MAX98396_R2006_INT_STATE1, 0x00},
     20	{MAX98396_R2007_INT_STATE2, 0x00},
     21	{MAX98396_R2008_INT_STATE3, 0x00},
     22	{MAX98396_R2009_INT_STATE4, 0x00},
     23	{MAX98396_R200B_INT_FLAG1, 0x00},
     24	{MAX98396_R200C_INT_FLAG2, 0x00},
     25	{MAX98396_R200D_INT_FLAG3, 0x00},
     26	{MAX98396_R200E_INT_FLAG4, 0x00},
     27	{MAX98396_R2010_INT_EN1, 0x02},
     28	{MAX98396_R2011_INT_EN2, 0x00},
     29	{MAX98396_R2012_INT_EN3, 0x00},
     30	{MAX98396_R2013_INT_EN4, 0x00},
     31	{MAX98396_R2015_INT_FLAG_CLR1, 0x00},
     32	{MAX98396_R2016_INT_FLAG_CLR2, 0x00},
     33	{MAX98396_R2017_INT_FLAG_CLR3, 0x00},
     34	{MAX98396_R2018_INT_FLAG_CLR4, 0x00},
     35	{MAX98396_R201F_IRQ_CTRL, 0x00},
     36	{MAX98396_R2020_THERM_WARN_THRESH, 0x46},
     37	{MAX98396_R2021_THERM_WARN_THRESH2, 0x46},
     38	{MAX98396_R2022_THERM_SHDN_THRESH, 0x64},
     39	{MAX98396_R2023_THERM_HYSTERESIS, 0x02},
     40	{MAX98396_R2024_THERM_FOLDBACK_SET, 0xC5},
     41	{MAX98396_R2027_THERM_FOLDBACK_EN, 0x01},
     42	{MAX98396_R2030_NOISEGATE_MODE_CTRL, 0x32},
     43	{MAX98396_R2033_NOISEGATE_MODE_EN, 0x00},
     44	{MAX98396_R2038_CLK_MON_CTRL, 0x00},
     45	{MAX98396_R2039_DATA_MON_CTRL, 0x00},
     46	{MAX98396_R203F_ENABLE_CTRLS, 0x0F},
     47	{MAX98396_R2040_PIN_CFG, 0x55},
     48	{MAX98396_R2041_PCM_MODE_CFG, 0xC0},
     49	{MAX98396_R2042_PCM_CLK_SETUP, 0x04},
     50	{MAX98396_R2043_PCM_SR_SETUP, 0x88},
     51	{MAX98396_R2044_PCM_TX_CTRL_1, 0x00},
     52	{MAX98396_R2045_PCM_TX_CTRL_2, 0x00},
     53	{MAX98396_R2046_PCM_TX_CTRL_3, 0x00},
     54	{MAX98396_R2047_PCM_TX_CTRL_4, 0x00},
     55	{MAX98396_R2048_PCM_TX_CTRL_5, 0x00},
     56	{MAX98396_R2049_PCM_TX_CTRL_6, 0x00},
     57	{MAX98396_R204A_PCM_TX_CTRL_7, 0x00},
     58	{MAX98396_R204B_PCM_TX_CTRL_8, 0x00},
     59	{MAX98396_R204C_PCM_TX_HIZ_CTRL_1, 0xFF},
     60	{MAX98396_R204D_PCM_TX_HIZ_CTRL_2, 0xFF},
     61	{MAX98396_R204E_PCM_TX_HIZ_CTRL_3, 0xFF},
     62	{MAX98396_R204F_PCM_TX_HIZ_CTRL_4, 0xFF},
     63	{MAX98396_R2050_PCM_TX_HIZ_CTRL_5, 0xFF},
     64	{MAX98396_R2051_PCM_TX_HIZ_CTRL_6, 0xFF},
     65	{MAX98396_R2052_PCM_TX_HIZ_CTRL_7, 0xFF},
     66	{MAX98396_R2053_PCM_TX_HIZ_CTRL_8, 0xFF},
     67	{MAX98396_R2055_PCM_RX_SRC1, 0x00},
     68	{MAX98396_R2056_PCM_RX_SRC2, 0x00},
     69	{MAX98396_R2058_PCM_BYPASS_SRC, 0x00},
     70	{MAX98396_R205D_PCM_TX_SRC_EN, 0x00},
     71	{MAX98396_R205E_PCM_RX_EN, 0x00},
     72	{MAX98396_R205F_PCM_TX_EN, 0x00},
     73	{MAX98396_R2070_ICC_RX_EN_A, 0x00},
     74	{MAX98396_R2071_ICC_RX_EN_B, 0x00},
     75	{MAX98396_R2072_ICC_TX_CTRL, 0x00},
     76	{MAX98396_R207F_ICC_EN, 0x00},
     77	{MAX98396_R2083_TONE_GEN_DC_CFG, 0x04},
     78	{MAX98396_R2084_TONE_GEN_DC_LVL1, 0x00},
     79	{MAX98396_R2085_TONE_GEN_DC_LVL2, 0x00},
     80	{MAX98396_R2086_TONE_GEN_DC_LVL3, 0x00},
     81	{MAX98396_R208F_TONE_GEN_EN, 0x00},
     82	{MAX98396_R2090_AMP_VOL_CTRL, 0x00},
     83	{MAX98396_R2091_AMP_PATH_GAIN, 0x0B},
     84	{MAX98396_R2092_AMP_DSP_CFG, 0x23},
     85	{MAX98396_R2093_SSM_CFG, 0x0D},
     86	{MAX98396_R2094_SPK_CLS_DG_THRESH, 0x12},
     87	{MAX98396_R2095_SPK_CLS_DG_HDR, 0x17},
     88	{MAX98396_R2096_SPK_CLS_DG_HOLD_TIME, 0x17},
     89	{MAX98396_R2097_SPK_CLS_DG_DELAY, 0x00},
     90	{MAX98396_R2098_SPK_CLS_DG_MODE, 0x00},
     91	{MAX98396_R2099_SPK_CLS_DG_VBAT_LVL, 0x03},
     92	{MAX98396_R209A_SPK_EDGE_CTRL, 0x00},
     93	{MAX98396_R209C_SPK_EDGE_CTRL1, 0x0A},
     94	{MAX98396_R209D_SPK_EDGE_CTRL2, 0xAA},
     95	{MAX98396_R209E_AMP_CLIP_GAIN, 0x00},
     96	{MAX98396_R209F_BYPASS_PATH_CFG, 0x00},
     97	{MAX98396_R20A0_AMP_SUPPLY_CTL, 0x00},
     98	{MAX98396_R20AF_AMP_EN, 0x00},
     99	{MAX98396_R20B0_ADC_SR, 0x30},
    100	{MAX98396_R20B1_ADC_PVDD_CFG, 0x00},
    101	{MAX98396_R20B2_ADC_VBAT_CFG, 0x00},
    102	{MAX98396_R20B3_ADC_THERMAL_CFG, 0x00},
    103	{MAX98396_R20B4_ADC_READBACK_CTRL1, 0x00},
    104	{MAX98396_R20B5_ADC_READBACK_CTRL2, 0x00},
    105	{MAX98396_R20B6_ADC_PVDD_READBACK_MSB, 0x00},
    106	{MAX98396_R20B7_ADC_PVDD_READBACK_LSB, 0x00},
    107	{MAX98396_R20B8_ADC_VBAT_READBACK_MSB, 0x00},
    108	{MAX98396_R20B9_ADC_VBAT_READBACK_LSB, 0x00},
    109	{MAX98396_R20BA_ADC_TEMP_READBACK_MSB, 0x00},
    110	{MAX98396_R20BB_ADC_TEMP_READBACK_LSB, 0x00},
    111	{MAX98396_R20BC_ADC_LO_PVDD_READBACK_MSB, 0x00},
    112	{MAX98396_R20BD_ADC_LO_PVDD_READBACK_LSB, 0x00},
    113	{MAX98396_R20BE_ADC_LO_VBAT_READBACK_MSB, 0x00},
    114	{MAX98396_R20BF_ADC_LO_VBAT_READBACK_LSB, 0x00},
    115	{MAX98396_R20C7_ADC_CFG, 0x00},
    116	{MAX98396_R20D0_DHT_CFG1, 0x00},
    117	{MAX98396_R20D1_LIMITER_CFG1, 0x08},
    118	{MAX98396_R20D2_LIMITER_CFG2, 0x00},
    119	{MAX98396_R20D3_DHT_CFG2, 0x14},
    120	{MAX98396_R20D4_DHT_CFG3, 0x02},
    121	{MAX98396_R20D5_DHT_CFG4, 0x04},
    122	{MAX98396_R20D6_DHT_HYSTERESIS_CFG, 0x07},
    123	{MAX98396_R20DF_DHT_EN, 0x00},
    124	{MAX98396_R20E0_IV_SENSE_PATH_CFG, 0x04},
    125	{MAX98396_R20E4_IV_SENSE_PATH_EN, 0x00},
    126	{MAX98396_R20E5_BPE_STATE, 0x00},
    127	{MAX98396_R20E6_BPE_L3_THRESH_MSB, 0x00},
    128	{MAX98396_R20E7_BPE_L3_THRESH_LSB, 0x00},
    129	{MAX98396_R20E8_BPE_L2_THRESH_MSB, 0x00},
    130	{MAX98396_R20E9_BPE_L2_THRESH_LSB, 0x00},
    131	{MAX98396_R20EA_BPE_L1_THRESH_MSB, 0x00},
    132	{MAX98396_R20EB_BPE_L1_THRESH_LSB, 0x00},
    133	{MAX98396_R20EC_BPE_L0_THRESH_MSB, 0x00},
    134	{MAX98396_R20ED_BPE_L0_THRESH_LSB, 0x00},
    135	{MAX98396_R20EE_BPE_L3_DWELL_HOLD_TIME, 0x00},
    136	{MAX98396_R20EF_BPE_L2_DWELL_HOLD_TIME, 0x00},
    137	{MAX98396_R20F0_BPE_L1_DWELL_HOLD_TIME, 0x00},
    138	{MAX98396_R20F1_BPE_L0_HOLD_TIME, 0x00},
    139	{MAX98396_R20F2_BPE_L3_ATTACK_REL_STEP, 0x00},
    140	{MAX98396_R20F3_BPE_L2_ATTACK_REL_STEP, 0x00},
    141	{MAX98396_R20F4_BPE_L1_ATTACK_REL_STEP, 0x00},
    142	{MAX98396_R20F5_BPE_L0_ATTACK_REL_STEP, 0x00},
    143	{MAX98396_R20F6_BPE_L3_MAX_GAIN_ATTN, 0x00},
    144	{MAX98396_R20F7_BPE_L2_MAX_GAIN_ATTN, 0x00},
    145	{MAX98396_R20F8_BPE_L1_MAX_GAIN_ATTN, 0x00},
    146	{MAX98396_R20F9_BPE_L0_MAX_GAIN_ATTN, 0x00},
    147	{MAX98396_R20FA_BPE_L3_ATT_REL_RATE, 0x00},
    148	{MAX98396_R20FB_BPE_L2_ATT_REL_RATE, 0x00},
    149	{MAX98396_R20FC_BPE_L1_ATT_REL_RATE, 0x00},
    150	{MAX98396_R20FD_BPE_L0_ATT_REL_RATE, 0x00},
    151	{MAX98396_R20FE_BPE_L3_LIMITER_CFG, 0x00},
    152	{MAX98396_R20FF_BPE_L2_LIMITER_CFG, 0x00},
    153	{MAX98396_R2100_BPE_L1_LIMITER_CFG, 0x00},
    154	{MAX98396_R2101_BPE_L0_LIMITER_CFG, 0x00},
    155	{MAX98396_R2102_BPE_L3_LIM_ATT_REL_RATE, 0x00},
    156	{MAX98396_R2103_BPE_L2_LIM_ATT_REL_RATE, 0x00},
    157	{MAX98396_R2104_BPE_L1_LIM_ATT_REL_RATE, 0x00},
    158	{MAX98396_R2105_BPE_L0_LIM_ATT_REL_RATE, 0x00},
    159	{MAX98396_R2106_BPE_THRESH_HYSTERESIS, 0x00},
    160	{MAX98396_R2107_BPE_INFINITE_HOLD_CLR, 0x00},
    161	{MAX98396_R2108_BPE_SUPPLY_SRC, 0x00},
    162	{MAX98396_R2109_BPE_LOW_STATE, 0x00},
    163	{MAX98396_R210A_BPE_LOW_GAIN, 0x00},
    164	{MAX98396_R210B_BPE_LOW_LIMITER, 0x00},
    165	{MAX98396_R210D_BPE_EN, 0x00},
    166	{MAX98396_R210E_AUTO_RESTART, 0x00},
    167	{MAX98396_R210F_GLOBAL_EN, 0x00},
    168	{MAX98396_R21FF_REVISION_ID, 0x00},
    169};
    170
    171static struct reg_default max98397_reg[] = {
    172	{MAX98396_R2000_SW_RESET, 0x00},
    173	{MAX98396_R2001_INT_RAW1, 0x00},
    174	{MAX98396_R2002_INT_RAW2, 0x00},
    175	{MAX98396_R2003_INT_RAW3, 0x00},
    176	{MAX98396_R2004_INT_RAW4, 0x00},
    177	{MAX98396_R2006_INT_STATE1, 0x00},
    178	{MAX98396_R2007_INT_STATE2, 0x00},
    179	{MAX98396_R2008_INT_STATE3, 0x00},
    180	{MAX98396_R2009_INT_STATE4, 0x00},
    181	{MAX98396_R200B_INT_FLAG1, 0x00},
    182	{MAX98396_R200C_INT_FLAG2, 0x00},
    183	{MAX98396_R200D_INT_FLAG3, 0x00},
    184	{MAX98396_R200E_INT_FLAG4, 0x00},
    185	{MAX98396_R2010_INT_EN1, 0x02},
    186	{MAX98396_R2011_INT_EN2, 0x00},
    187	{MAX98396_R2012_INT_EN3, 0x00},
    188	{MAX98396_R2013_INT_EN4, 0x00},
    189	{MAX98396_R2015_INT_FLAG_CLR1, 0x00},
    190	{MAX98396_R2016_INT_FLAG_CLR2, 0x00},
    191	{MAX98396_R2017_INT_FLAG_CLR3, 0x00},
    192	{MAX98396_R2018_INT_FLAG_CLR4, 0x00},
    193	{MAX98396_R201F_IRQ_CTRL, 0x00},
    194	{MAX98396_R2020_THERM_WARN_THRESH, 0x46},
    195	{MAX98396_R2021_THERM_WARN_THRESH2, 0x46},
    196	{MAX98396_R2022_THERM_SHDN_THRESH, 0x64},
    197	{MAX98396_R2023_THERM_HYSTERESIS, 0x02},
    198	{MAX98396_R2024_THERM_FOLDBACK_SET, 0xC5},
    199	{MAX98396_R2027_THERM_FOLDBACK_EN, 0x01},
    200	{MAX98396_R2030_NOISEGATE_MODE_CTRL, 0x32},
    201	{MAX98396_R2033_NOISEGATE_MODE_EN, 0x00},
    202	{MAX98396_R2038_CLK_MON_CTRL, 0x00},
    203	{MAX98396_R2039_DATA_MON_CTRL, 0x00},
    204	{MAX98397_R203A_SPK_MON_THRESH, 0x03},
    205	{MAX98396_R203F_ENABLE_CTRLS, 0x0F},
    206	{MAX98396_R2040_PIN_CFG, 0x55},
    207	{MAX98396_R2041_PCM_MODE_CFG, 0xC0},
    208	{MAX98396_R2042_PCM_CLK_SETUP, 0x04},
    209	{MAX98396_R2043_PCM_SR_SETUP, 0x88},
    210	{MAX98396_R2044_PCM_TX_CTRL_1, 0x00},
    211	{MAX98396_R2045_PCM_TX_CTRL_2, 0x00},
    212	{MAX98396_R2046_PCM_TX_CTRL_3, 0x00},
    213	{MAX98396_R2047_PCM_TX_CTRL_4, 0x00},
    214	{MAX98396_R2048_PCM_TX_CTRL_5, 0x00},
    215	{MAX98396_R2049_PCM_TX_CTRL_6, 0x00},
    216	{MAX98396_R204A_PCM_TX_CTRL_7, 0x00},
    217	{MAX98396_R204B_PCM_TX_CTRL_8, 0x00},
    218	{MAX98397_R204C_PCM_TX_CTRL_9, 0x00},
    219	{MAX98397_R204D_PCM_TX_HIZ_CTRL_1, 0xFF},
    220	{MAX98397_R204E_PCM_TX_HIZ_CTRL_2, 0xFF},
    221	{MAX98397_R204F_PCM_TX_HIZ_CTRL_3, 0xFF},
    222	{MAX98397_R2050_PCM_TX_HIZ_CTRL_4, 0xFF},
    223	{MAX98397_R2051_PCM_TX_HIZ_CTRL_5, 0xFF},
    224	{MAX98397_R2052_PCM_TX_HIZ_CTRL_6, 0xFF},
    225	{MAX98397_R2053_PCM_TX_HIZ_CTRL_7, 0xFF},
    226	{MAX98397_R2054_PCM_TX_HIZ_CTRL_8, 0xFF},
    227	{MAX98397_R2056_PCM_RX_SRC1, 0x00},
    228	{MAX98397_R2057_PCM_RX_SRC2, 0x00},
    229	{MAX98396_R2058_PCM_BYPASS_SRC, 0x00},
    230	{MAX98396_R205D_PCM_TX_SRC_EN, 0x00},
    231	{MAX98396_R205E_PCM_RX_EN, 0x00},
    232	{MAX98396_R205F_PCM_TX_EN, 0x00},
    233	{MAX98397_R2060_PCM_TX_SUPPLY_SEL, 0x00},
    234	{MAX98396_R2070_ICC_RX_EN_A, 0x00},
    235	{MAX98396_R2071_ICC_RX_EN_B, 0x00},
    236	{MAX98396_R2072_ICC_TX_CTRL, 0x00},
    237	{MAX98396_R207F_ICC_EN, 0x00},
    238	{MAX98396_R2083_TONE_GEN_DC_CFG, 0x04},
    239	{MAX98396_R2084_TONE_GEN_DC_LVL1, 0x00},
    240	{MAX98396_R2085_TONE_GEN_DC_LVL2, 0x00},
    241	{MAX98396_R2086_TONE_GEN_DC_LVL3, 0x00},
    242	{MAX98396_R208F_TONE_GEN_EN, 0x00},
    243	{MAX98396_R2090_AMP_VOL_CTRL, 0x00},
    244	{MAX98396_R2091_AMP_PATH_GAIN, 0x12},
    245	{MAX98396_R2092_AMP_DSP_CFG, 0x22},
    246	{MAX98396_R2093_SSM_CFG, 0x08},
    247	{MAX98396_R2094_SPK_CLS_DG_THRESH, 0x12},
    248	{MAX98396_R2095_SPK_CLS_DG_HDR, 0x17},
    249	{MAX98396_R2096_SPK_CLS_DG_HOLD_TIME, 0x17},
    250	{MAX98396_R2097_SPK_CLS_DG_DELAY, 0x00},
    251	{MAX98396_R2098_SPK_CLS_DG_MODE, 0x00},
    252	{MAX98396_R2099_SPK_CLS_DG_VBAT_LVL, 0x03},
    253	{MAX98396_R209A_SPK_EDGE_CTRL, 0x00},
    254	{MAX98397_R209B_SPK_PATH_WB_ONLY, 0x00},
    255	{MAX98396_R209C_SPK_EDGE_CTRL1, 0x03},
    256	{MAX98396_R209D_SPK_EDGE_CTRL2, 0xFC},
    257	{MAX98396_R209E_AMP_CLIP_GAIN, 0x00},
    258	{MAX98396_R209F_BYPASS_PATH_CFG, 0x00},
    259	{MAX98396_R20AF_AMP_EN, 0x00},
    260	{MAX98396_R20B0_ADC_SR, 0x30},
    261	{MAX98396_R20B1_ADC_PVDD_CFG, 0x00},
    262	{MAX98396_R20B2_ADC_VBAT_CFG, 0x00},
    263	{MAX98396_R20B3_ADC_THERMAL_CFG, 0x00},
    264	{MAX98397_R20B4_ADC_VDDH_CFG, 0x00},
    265	{MAX98397_R20B5_ADC_READBACK_CTRL1, 0x00},
    266	{MAX98397_R20B6_ADC_READBACK_CTRL2, 0x00},
    267	{MAX98397_R20B7_ADC_PVDD_READBACK_MSB, 0x00},
    268	{MAX98397_R20B8_ADC_PVDD_READBACK_LSB, 0x00},
    269	{MAX98397_R20B9_ADC_VBAT_READBACK_MSB, 0x00},
    270	{MAX98397_R20BA_ADC_VBAT_READBACK_LSB, 0x00},
    271	{MAX98397_R20BB_ADC_TEMP_READBACK_MSB, 0x00},
    272	{MAX98397_R20BC_ADC_TEMP_READBACK_LSB, 0x00},
    273	{MAX98397_R20BD_ADC_VDDH__READBACK_MSB, 0x00},
    274	{MAX98397_R20BE_ADC_VDDH_READBACK_LSB, 0x00},
    275	{MAX98396_R20BF_ADC_LO_VBAT_READBACK_LSB, 0x00},
    276	{MAX98397_R20C3_ADC_LO_VDDH_READBACK_MSB, 0x00},
    277	{MAX98397_R20C4_ADC_LO_VDDH_READBACK_LSB, 0x00},
    278	{MAX98397_R20C5_MEAS_ADC_OPTIMAL_MODE, 0x04},
    279	{MAX98396_R20C7_ADC_CFG, 0x00},
    280	{MAX98396_R20D0_DHT_CFG1, 0x00},
    281	{MAX98396_R20D1_LIMITER_CFG1, 0x08},
    282	{MAX98396_R20D2_LIMITER_CFG2, 0x00},
    283	{MAX98396_R20D3_DHT_CFG2, 0x14},
    284	{MAX98396_R20D4_DHT_CFG3, 0x02},
    285	{MAX98396_R20D5_DHT_CFG4, 0x04},
    286	{MAX98396_R20D6_DHT_HYSTERESIS_CFG, 0x07},
    287	{MAX98396_R20DF_DHT_EN, 0x00},
    288	{MAX98396_R20E0_IV_SENSE_PATH_CFG, 0x04},
    289	{MAX98396_R20E4_IV_SENSE_PATH_EN, 0x00},
    290	{MAX98396_R20E5_BPE_STATE, 0x00},
    291	{MAX98396_R20E6_BPE_L3_THRESH_MSB, 0x00},
    292	{MAX98396_R20E7_BPE_L3_THRESH_LSB, 0x00},
    293	{MAX98396_R20E8_BPE_L2_THRESH_MSB, 0x00},
    294	{MAX98396_R20E9_BPE_L2_THRESH_LSB, 0x00},
    295	{MAX98396_R20EA_BPE_L1_THRESH_MSB, 0x00},
    296	{MAX98396_R20EB_BPE_L1_THRESH_LSB, 0x00},
    297	{MAX98396_R20EC_BPE_L0_THRESH_MSB, 0x00},
    298	{MAX98396_R20ED_BPE_L0_THRESH_LSB, 0x00},
    299	{MAX98396_R20EE_BPE_L3_DWELL_HOLD_TIME, 0x00},
    300	{MAX98396_R20EF_BPE_L2_DWELL_HOLD_TIME, 0x00},
    301	{MAX98396_R20F0_BPE_L1_DWELL_HOLD_TIME, 0x00},
    302	{MAX98396_R20F1_BPE_L0_HOLD_TIME, 0x00},
    303	{MAX98396_R20F2_BPE_L3_ATTACK_REL_STEP, 0x00},
    304	{MAX98396_R20F3_BPE_L2_ATTACK_REL_STEP, 0x00},
    305	{MAX98396_R20F4_BPE_L1_ATTACK_REL_STEP, 0x00},
    306	{MAX98396_R20F5_BPE_L0_ATTACK_REL_STEP, 0x00},
    307	{MAX98396_R20F6_BPE_L3_MAX_GAIN_ATTN, 0x00},
    308	{MAX98396_R20F7_BPE_L2_MAX_GAIN_ATTN, 0x00},
    309	{MAX98396_R20F8_BPE_L1_MAX_GAIN_ATTN, 0x00},
    310	{MAX98396_R20F9_BPE_L0_MAX_GAIN_ATTN, 0x00},
    311	{MAX98396_R20FA_BPE_L3_ATT_REL_RATE, 0x00},
    312	{MAX98396_R20FB_BPE_L2_ATT_REL_RATE, 0x00},
    313	{MAX98396_R20FC_BPE_L1_ATT_REL_RATE, 0x00},
    314	{MAX98396_R20FD_BPE_L0_ATT_REL_RATE, 0x00},
    315	{MAX98396_R20FE_BPE_L3_LIMITER_CFG, 0x00},
    316	{MAX98396_R20FF_BPE_L2_LIMITER_CFG, 0x00},
    317	{MAX98396_R2100_BPE_L1_LIMITER_CFG, 0x00},
    318	{MAX98396_R2101_BPE_L0_LIMITER_CFG, 0x00},
    319	{MAX98396_R2102_BPE_L3_LIM_ATT_REL_RATE, 0x00},
    320	{MAX98396_R2103_BPE_L2_LIM_ATT_REL_RATE, 0x00},
    321	{MAX98396_R2104_BPE_L1_LIM_ATT_REL_RATE, 0x00},
    322	{MAX98396_R2105_BPE_L0_LIM_ATT_REL_RATE, 0x00},
    323	{MAX98396_R2106_BPE_THRESH_HYSTERESIS, 0x00},
    324	{MAX98396_R2107_BPE_INFINITE_HOLD_CLR, 0x00},
    325	{MAX98396_R2108_BPE_SUPPLY_SRC, 0x00},
    326	{MAX98396_R2109_BPE_LOW_STATE, 0x00},
    327	{MAX98396_R210A_BPE_LOW_GAIN, 0x00},
    328	{MAX98396_R210B_BPE_LOW_LIMITER, 0x00},
    329	{MAX98396_R210D_BPE_EN, 0x00},
    330	{MAX98396_R210E_AUTO_RESTART, 0x00},
    331	{MAX98396_R210F_GLOBAL_EN, 0x00},
    332	{MAX98397_R22FF_REVISION_ID, 0x00},
    333};
    334
    335static void max98396_global_enable_onoff(struct regmap *regmap, bool onoff)
    336{
    337	regmap_write(regmap, MAX98396_R210F_GLOBAL_EN, onoff ? 1 : 0);
    338	usleep_range(11000, 12000);
    339}
    340
    341static int max98396_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
    342{
    343	struct snd_soc_component *component = codec_dai->component;
    344	struct max98396_priv *max98396 = snd_soc_component_get_drvdata(component);
    345	unsigned int format = 0;
    346	unsigned int bclk_pol = 0;
    347	int ret, status;
    348	int reg;
    349	bool update = false;
    350
    351	dev_dbg(component->dev, "%s: fmt 0x%08X\n", __func__, fmt);
    352
    353	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
    354	case SND_SOC_DAIFMT_NB_NF:
    355		break;
    356	case SND_SOC_DAIFMT_NB_IF:
    357		format = MAX98396_PCM_MODE_CFG_LRCLKEDGE;
    358		break;
    359	case SND_SOC_DAIFMT_IB_NF:
    360		bclk_pol = MAX98396_PCM_MODE_CFG_BCLKEDGE;
    361		break;
    362	case SND_SOC_DAIFMT_IB_IF:
    363		bclk_pol = MAX98396_PCM_MODE_CFG_BCLKEDGE;
    364		format = MAX98396_PCM_MODE_CFG_LRCLKEDGE;
    365		break;
    366
    367	default:
    368		dev_err(component->dev, "DAI invert mode unsupported\n");
    369		return -EINVAL;
    370	}
    371
    372	/* interface format */
    373	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
    374	case SND_SOC_DAIFMT_I2S:
    375		format |= MAX98396_PCM_FORMAT_I2S;
    376		break;
    377	case SND_SOC_DAIFMT_LEFT_J:
    378		format |= MAX98396_PCM_FORMAT_LJ;
    379		break;
    380	case SND_SOC_DAIFMT_DSP_A:
    381		format |= MAX98396_PCM_FORMAT_TDM_MODE1;
    382		break;
    383	case SND_SOC_DAIFMT_DSP_B:
    384		format |= MAX98396_PCM_FORMAT_TDM_MODE0;
    385		break;
    386	default:
    387		return -EINVAL;
    388	}
    389
    390	ret = regmap_read(max98396->regmap, MAX98396_R210F_GLOBAL_EN, &status);
    391	if (ret < 0)
    392		return -EINVAL;
    393
    394	if (status) {
    395		ret = regmap_read(max98396->regmap, MAX98396_R2041_PCM_MODE_CFG, &reg);
    396		if (ret < 0)
    397			return -EINVAL;
    398		if (format != (reg & MAX98396_PCM_BCLKEDGE_BSEL_MASK)) {
    399			update = true;
    400		} else {
    401			ret = regmap_read(max98396->regmap,
    402					  MAX98396_R2042_PCM_CLK_SETUP, &reg);
    403			if (ret < 0)
    404				return -EINVAL;
    405			if (bclk_pol != (reg & MAX98396_PCM_MODE_CFG_BCLKEDGE))
    406				update = true;
    407		}
    408		/* GLOBAL_EN OFF prior to pcm mode, clock configuration change */
    409		if (update)
    410			max98396_global_enable_onoff(max98396->regmap, false);
    411	}
    412
    413	regmap_update_bits(max98396->regmap,
    414			   MAX98396_R2041_PCM_MODE_CFG,
    415			   MAX98396_PCM_BCLKEDGE_BSEL_MASK,
    416			   format);
    417
    418	regmap_update_bits(max98396->regmap,
    419			   MAX98396_R2042_PCM_CLK_SETUP,
    420			   MAX98396_PCM_MODE_CFG_BCLKEDGE,
    421			   bclk_pol);
    422
    423	if (status && update)
    424		max98396_global_enable_onoff(max98396->regmap, true);
    425
    426	return 0;
    427}
    428
    429/* BCLKs per LRCLK */
    430static const int bclk_sel_table[] = {
    431	32, 48, 64, 96, 128, 192, 256, 384, 512, 320,
    432};
    433
    434static int max98396_get_bclk_sel(int bclk)
    435{
    436	int i;
    437	/* match BCLKs per LRCLK */
    438	for (i = 0; i < ARRAY_SIZE(bclk_sel_table); i++) {
    439		if (bclk_sel_table[i] == bclk)
    440			return i + 2;
    441	}
    442	return 0;
    443}
    444
    445static int max98396_set_clock(struct snd_soc_component *component,
    446			      struct snd_pcm_hw_params *params)
    447{
    448	struct max98396_priv *max98396 = snd_soc_component_get_drvdata(component);
    449	/* BCLK/LRCLK ratio calculation */
    450	int blr_clk_ratio = params_channels(params) * max98396->ch_size;
    451	int value;
    452
    453	if (!max98396->tdm_mode) {
    454		/* BCLK configuration */
    455		value = max98396_get_bclk_sel(blr_clk_ratio);
    456		if (!value) {
    457			dev_err(component->dev, "format unsupported %d\n",
    458				params_format(params));
    459			return -EINVAL;
    460		}
    461
    462		regmap_update_bits(max98396->regmap,
    463				   MAX98396_R2042_PCM_CLK_SETUP,
    464				   MAX98396_PCM_CLK_SETUP_BSEL_MASK,
    465				   value);
    466	}
    467
    468	return 0;
    469}
    470
    471static int max98396_dai_hw_params(struct snd_pcm_substream *substream,
    472				  struct snd_pcm_hw_params *params,
    473				  struct snd_soc_dai *dai)
    474{
    475	struct snd_soc_component *component = dai->component;
    476	struct max98396_priv *max98396 = snd_soc_component_get_drvdata(component);
    477	unsigned int sampling_rate = 0;
    478	unsigned int chan_sz = 0;
    479	int ret, reg;
    480	int status;
    481	bool update = false;
    482
    483	/* pcm mode configuration */
    484	switch (snd_pcm_format_width(params_format(params))) {
    485	case 16:
    486		chan_sz = MAX98396_PCM_MODE_CFG_CHANSZ_16;
    487		break;
    488	case 24:
    489		chan_sz = MAX98396_PCM_MODE_CFG_CHANSZ_24;
    490		break;
    491	case 32:
    492		chan_sz = MAX98396_PCM_MODE_CFG_CHANSZ_32;
    493		break;
    494	default:
    495		dev_err(component->dev, "format unsupported %d\n",
    496			params_format(params));
    497		goto err;
    498	}
    499
    500	max98396->ch_size = snd_pcm_format_width(params_format(params));
    501
    502	dev_dbg(component->dev, "format supported %d",
    503		params_format(params));
    504
    505	/* sampling rate configuration */
    506	switch (params_rate(params)) {
    507	case 8000:
    508		sampling_rate = MAX98396_PCM_SR_8000;
    509		break;
    510	case 11025:
    511		sampling_rate = MAX98396_PCM_SR_11025;
    512		break;
    513	case 12000:
    514		sampling_rate = MAX98396_PCM_SR_12000;
    515		break;
    516	case 16000:
    517		sampling_rate = MAX98396_PCM_SR_16000;
    518		break;
    519	case 22050:
    520		sampling_rate = MAX98396_PCM_SR_22050;
    521		break;
    522	case 24000:
    523		sampling_rate = MAX98396_PCM_SR_24000;
    524		break;
    525	case 32000:
    526		sampling_rate = MAX98396_PCM_SR_32000;
    527		break;
    528	case 44100:
    529		sampling_rate = MAX98396_PCM_SR_44100;
    530		break;
    531	case 48000:
    532		sampling_rate = MAX98396_PCM_SR_48000;
    533		break;
    534	case 88200:
    535		sampling_rate = MAX98396_PCM_SR_88200;
    536		break;
    537	case 96000:
    538		sampling_rate = MAX98396_PCM_SR_96000;
    539		break;
    540	case 192000:
    541		sampling_rate = MAX98396_PCM_SR_192000;
    542		break;
    543	default:
    544		dev_err(component->dev, "rate %d not supported\n",
    545			params_rate(params));
    546		goto err;
    547	}
    548
    549	ret = regmap_read(max98396->regmap, MAX98396_R210F_GLOBAL_EN, &status);
    550	if (ret < 0)
    551		goto err;
    552
    553	if (status) {
    554		ret = regmap_read(max98396->regmap, MAX98396_R2041_PCM_MODE_CFG, &reg);
    555		if (ret < 0)
    556			goto err;
    557		if (chan_sz != (reg & MAX98396_PCM_MODE_CFG_CHANSZ_MASK)) {
    558			update = true;
    559		} else {
    560			ret = regmap_read(max98396->regmap, MAX98396_R2043_PCM_SR_SETUP, &reg);
    561			if (ret < 0)
    562				goto err;
    563			if (sampling_rate != (reg & MAX98396_PCM_SR_MASK))
    564				update = true;
    565		}
    566
    567		/* GLOBAL_EN OFF prior to channel size and sampling rate change */
    568		if (update)
    569			max98396_global_enable_onoff(max98396->regmap, false);
    570	}
    571
    572	/* set channel size */
    573	regmap_update_bits(max98396->regmap, MAX98396_R2041_PCM_MODE_CFG,
    574			   MAX98396_PCM_MODE_CFG_CHANSZ_MASK, chan_sz);
    575
    576	/* set DAI_SR to correct LRCLK frequency */
    577	regmap_update_bits(max98396->regmap, MAX98396_R2043_PCM_SR_SETUP,
    578			   MAX98396_PCM_SR_MASK, sampling_rate);
    579
    580	/* set sampling rate of IV */
    581	if (max98396->interleave_mode &&
    582	    sampling_rate > MAX98396_PCM_SR_16000)
    583		regmap_update_bits(max98396->regmap,
    584				   MAX98396_R2043_PCM_SR_SETUP,
    585				   MAX98396_IVADC_SR_MASK,
    586				   (sampling_rate - 3)
    587				   << MAX98396_IVADC_SR_SHIFT);
    588	else
    589		regmap_update_bits(max98396->regmap,
    590				   MAX98396_R2043_PCM_SR_SETUP,
    591				   MAX98396_IVADC_SR_MASK,
    592				   sampling_rate << MAX98396_IVADC_SR_SHIFT);
    593
    594	ret = max98396_set_clock(component, params);
    595
    596	if (status && update)
    597		max98396_global_enable_onoff(max98396->regmap, true);
    598
    599	return ret;
    600
    601err:
    602	return -EINVAL;
    603}
    604
    605static int max98396_dai_tdm_slot(struct snd_soc_dai *dai,
    606				 unsigned int tx_mask, unsigned int rx_mask,
    607				 int slots, int slot_width)
    608{
    609	struct snd_soc_component *component = dai->component;
    610	struct max98396_priv *max98396 =
    611		snd_soc_component_get_drvdata(component);
    612	int bsel;
    613	unsigned int chan_sz = 0;
    614	int ret, status;
    615	int reg;
    616	bool update = false;
    617
    618	if (!tx_mask && !rx_mask && !slots && !slot_width)
    619		max98396->tdm_mode = false;
    620	else
    621		max98396->tdm_mode = true;
    622
    623	/* BCLK configuration */
    624	bsel = max98396_get_bclk_sel(slots * slot_width);
    625	if (bsel == 0) {
    626		dev_err(component->dev, "BCLK %d not supported\n",
    627			slots * slot_width);
    628		return -EINVAL;
    629	}
    630
    631	/* Channel size configuration */
    632	switch (slot_width) {
    633	case 16:
    634		chan_sz = MAX98396_PCM_MODE_CFG_CHANSZ_16;
    635		break;
    636	case 24:
    637		chan_sz = MAX98396_PCM_MODE_CFG_CHANSZ_24;
    638		break;
    639	case 32:
    640		chan_sz = MAX98396_PCM_MODE_CFG_CHANSZ_32;
    641		break;
    642	default:
    643		dev_err(component->dev, "format unsupported %d\n",
    644			slot_width);
    645		return -EINVAL;
    646	}
    647
    648	ret = regmap_read(max98396->regmap, MAX98396_R210F_GLOBAL_EN, &status);
    649	if (ret < 0)
    650		return -EINVAL;
    651
    652	if (status) {
    653		ret = regmap_read(max98396->regmap, MAX98396_R2042_PCM_CLK_SETUP, &reg);
    654		if (ret < 0)
    655			return -EINVAL;
    656		if (bsel != (reg & MAX98396_PCM_CLK_SETUP_BSEL_MASK)) {
    657			update = true;
    658		} else {
    659			ret = regmap_read(max98396->regmap, MAX98396_R2041_PCM_MODE_CFG, &reg);
    660			if (ret < 0)
    661				return -EINVAL;
    662			if (chan_sz != (reg & MAX98396_PCM_MODE_CFG_CHANSZ_MASK))
    663				update = true;
    664		}
    665
    666		/* GLOBAL_EN OFF prior to channel size and BCLK per LRCLK change */
    667		if (update)
    668			max98396_global_enable_onoff(max98396->regmap, false);
    669	}
    670
    671	regmap_update_bits(max98396->regmap,
    672			   MAX98396_R2042_PCM_CLK_SETUP,
    673			   MAX98396_PCM_CLK_SETUP_BSEL_MASK,
    674			   bsel);
    675
    676	regmap_update_bits(max98396->regmap,
    677			   MAX98396_R2041_PCM_MODE_CFG,
    678			   MAX98396_PCM_MODE_CFG_CHANSZ_MASK, chan_sz);
    679
    680	/* Rx slot configuration */
    681	if (max98396->device_id == CODEC_TYPE_MAX98396) {
    682		regmap_update_bits(max98396->regmap,
    683				   MAX98396_R2056_PCM_RX_SRC2,
    684				   MAX98396_PCM_DMIX_CH0_SRC_MASK,
    685				   rx_mask);
    686		regmap_update_bits(max98396->regmap,
    687				   MAX98396_R2056_PCM_RX_SRC2,
    688				   MAX98396_PCM_DMIX_CH1_SRC_MASK,
    689				   rx_mask << MAX98396_PCM_DMIX_CH1_SHIFT);
    690	} else {
    691		regmap_update_bits(max98396->regmap,
    692				   MAX98397_R2057_PCM_RX_SRC2,
    693				   MAX98396_PCM_DMIX_CH0_SRC_MASK,
    694				   rx_mask);
    695		regmap_update_bits(max98396->regmap,
    696				   MAX98397_R2057_PCM_RX_SRC2,
    697				   MAX98396_PCM_DMIX_CH1_SRC_MASK,
    698				   rx_mask << MAX98396_PCM_DMIX_CH1_SHIFT);
    699	}
    700
    701	/* Tx slot Hi-Z configuration */
    702	if (max98396->device_id == CODEC_TYPE_MAX98396) {
    703		regmap_write(max98396->regmap,
    704			     MAX98396_R2053_PCM_TX_HIZ_CTRL_8,
    705			     ~tx_mask & 0xFF);
    706		regmap_write(max98396->regmap,
    707			     MAX98396_R2052_PCM_TX_HIZ_CTRL_7,
    708			     (~tx_mask & 0xFF00) >> 8);
    709	} else {
    710		regmap_write(max98396->regmap,
    711			     MAX98397_R2054_PCM_TX_HIZ_CTRL_8,
    712			     ~tx_mask & 0xFF);
    713		regmap_write(max98396->regmap,
    714			     MAX98397_R2053_PCM_TX_HIZ_CTRL_7,
    715			     (~tx_mask & 0xFF00) >> 8);
    716	}
    717
    718	if (status && update)
    719		max98396_global_enable_onoff(max98396->regmap, true);
    720
    721	return 0;
    722}
    723
    724#define MAX98396_RATES SNDRV_PCM_RATE_8000_192000
    725
    726#define MAX98396_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
    727	SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
    728
    729static const struct snd_soc_dai_ops max98396_dai_ops = {
    730	.set_fmt = max98396_dai_set_fmt,
    731	.hw_params = max98396_dai_hw_params,
    732	.set_tdm_slot = max98396_dai_tdm_slot,
    733};
    734
    735static int max98396_dac_event(struct snd_soc_dapm_widget *w,
    736			      struct snd_kcontrol *kcontrol, int event)
    737{
    738	struct snd_soc_component *component =
    739		snd_soc_dapm_to_component(w->dapm);
    740	struct max98396_priv *max98396 =
    741		snd_soc_component_get_drvdata(component);
    742
    743	switch (event) {
    744	case SND_SOC_DAPM_POST_PMU:
    745		max98396_global_enable_onoff(max98396->regmap, true);
    746		break;
    747	case SND_SOC_DAPM_PRE_PMD:
    748		max98396_global_enable_onoff(max98396->regmap, false);
    749
    750		max98396->tdm_mode = false;
    751		break;
    752	default:
    753		return 0;
    754	}
    755	return 0;
    756}
    757
    758static bool max98396_readable_register(struct device *dev, unsigned int reg)
    759{
    760	switch (reg) {
    761	case MAX98396_R2001_INT_RAW1 ... MAX98396_R2004_INT_RAW4:
    762	case MAX98396_R2006_INT_STATE1 ... MAX98396_R2009_INT_STATE4:
    763	case MAX98396_R200B_INT_FLAG1 ... MAX98396_R200E_INT_FLAG4:
    764	case MAX98396_R2010_INT_EN1 ... MAX98396_R2013_INT_EN4:
    765	case MAX98396_R2015_INT_FLAG_CLR1 ... MAX98396_R2018_INT_FLAG_CLR4:
    766	case MAX98396_R201F_IRQ_CTRL ... MAX98396_R2024_THERM_FOLDBACK_SET:
    767	case MAX98396_R2027_THERM_FOLDBACK_EN:
    768	case MAX98396_R2030_NOISEGATE_MODE_CTRL:
    769	case MAX98396_R2033_NOISEGATE_MODE_EN:
    770	case MAX98396_R2038_CLK_MON_CTRL ... MAX98396_R2039_DATA_MON_CTRL:
    771	case MAX98396_R203F_ENABLE_CTRLS ... MAX98396_R2053_PCM_TX_HIZ_CTRL_8:
    772	case MAX98396_R2055_PCM_RX_SRC1 ... MAX98396_R2056_PCM_RX_SRC2:
    773	case MAX98396_R2058_PCM_BYPASS_SRC:
    774	case MAX98396_R205D_PCM_TX_SRC_EN ... MAX98396_R205F_PCM_TX_EN:
    775	case MAX98396_R2070_ICC_RX_EN_A... MAX98396_R2072_ICC_TX_CTRL:
    776	case MAX98396_R207F_ICC_EN:
    777	case MAX98396_R2083_TONE_GEN_DC_CFG ... MAX98396_R2086_TONE_GEN_DC_LVL3:
    778	case MAX98396_R208F_TONE_GEN_EN ... MAX98396_R209A_SPK_EDGE_CTRL:
    779	case MAX98396_R209C_SPK_EDGE_CTRL1 ... MAX98396_R20A0_AMP_SUPPLY_CTL:
    780	case MAX98396_R20AF_AMP_EN ... MAX98396_R20BF_ADC_LO_VBAT_READBACK_LSB:
    781	case MAX98396_R20C7_ADC_CFG:
    782	case MAX98396_R20D0_DHT_CFG1 ... MAX98396_R20D6_DHT_HYSTERESIS_CFG:
    783	case MAX98396_R20DF_DHT_EN:
    784	case MAX98396_R20E0_IV_SENSE_PATH_CFG:
    785	case MAX98396_R20E4_IV_SENSE_PATH_EN
    786		... MAX98396_R2106_BPE_THRESH_HYSTERESIS:
    787	case MAX98396_R2108_BPE_SUPPLY_SRC ... MAX98396_R210B_BPE_LOW_LIMITER:
    788	case MAX98396_R210D_BPE_EN ... MAX98396_R210F_GLOBAL_EN:
    789	case MAX98396_R21FF_REVISION_ID:
    790		return true;
    791	default:
    792		return false;
    793	}
    794};
    795
    796static bool max98396_volatile_reg(struct device *dev, unsigned int reg)
    797{
    798	switch (reg) {
    799	case MAX98396_R2000_SW_RESET:
    800	case MAX98396_R2001_INT_RAW1 ... MAX98396_R200E_INT_FLAG4:
    801	case MAX98396_R2041_PCM_MODE_CFG:
    802	case MAX98396_R20B6_ADC_PVDD_READBACK_MSB
    803		... MAX98396_R20BF_ADC_LO_VBAT_READBACK_LSB:
    804	case MAX98396_R20E5_BPE_STATE:
    805	case MAX98396_R2109_BPE_LOW_STATE
    806		... MAX98396_R210B_BPE_LOW_LIMITER:
    807	case MAX98396_R210F_GLOBAL_EN:
    808	case MAX98396_R21FF_REVISION_ID:
    809		return true;
    810	default:
    811		return false;
    812	}
    813}
    814
    815static bool max98397_readable_register(struct device *dev, unsigned int reg)
    816{
    817	switch (reg) {
    818	case MAX98396_R2001_INT_RAW1 ... MAX98396_R2004_INT_RAW4:
    819	case MAX98396_R2006_INT_STATE1 ... MAX98396_R2009_INT_STATE4:
    820	case MAX98396_R200B_INT_FLAG1 ... MAX98396_R200E_INT_FLAG4:
    821	case MAX98396_R2010_INT_EN1 ... MAX98396_R2013_INT_EN4:
    822	case MAX98396_R2015_INT_FLAG_CLR1 ... MAX98396_R2018_INT_FLAG_CLR4:
    823	case MAX98396_R201F_IRQ_CTRL ... MAX98396_R2024_THERM_FOLDBACK_SET:
    824	case MAX98396_R2027_THERM_FOLDBACK_EN:
    825	case MAX98396_R2030_NOISEGATE_MODE_CTRL:
    826	case MAX98396_R2033_NOISEGATE_MODE_EN:
    827	case MAX98396_R2038_CLK_MON_CTRL ... MAX98397_R203A_SPK_MON_THRESH:
    828	case MAX98396_R203F_ENABLE_CTRLS ... MAX98397_R2054_PCM_TX_HIZ_CTRL_8:
    829	case MAX98397_R2056_PCM_RX_SRC1... MAX98396_R2058_PCM_BYPASS_SRC:
    830	case MAX98396_R205D_PCM_TX_SRC_EN ... MAX98397_R2060_PCM_TX_SUPPLY_SEL:
    831	case MAX98396_R2070_ICC_RX_EN_A... MAX98396_R2072_ICC_TX_CTRL:
    832	case MAX98396_R207F_ICC_EN:
    833	case MAX98396_R2083_TONE_GEN_DC_CFG ... MAX98396_R2086_TONE_GEN_DC_LVL3:
    834	case MAX98396_R208F_TONE_GEN_EN ... MAX98396_R209F_BYPASS_PATH_CFG:
    835	case MAX98396_R20AF_AMP_EN ... MAX98397_R20C5_MEAS_ADC_OPTIMAL_MODE:
    836	case MAX98396_R20C7_ADC_CFG:
    837	case MAX98396_R20D0_DHT_CFG1 ... MAX98396_R20D6_DHT_HYSTERESIS_CFG:
    838	case MAX98396_R20DF_DHT_EN:
    839	case MAX98396_R20E0_IV_SENSE_PATH_CFG:
    840	case MAX98396_R20E4_IV_SENSE_PATH_EN
    841		... MAX98396_R2106_BPE_THRESH_HYSTERESIS:
    842	case MAX98396_R2108_BPE_SUPPLY_SRC ... MAX98396_R210B_BPE_LOW_LIMITER:
    843	case MAX98396_R210D_BPE_EN ... MAX98396_R210F_GLOBAL_EN:
    844	case MAX98397_R22FF_REVISION_ID:
    845		return true;
    846	default:
    847		return false;
    848	}
    849};
    850
    851static bool max98397_volatile_reg(struct device *dev, unsigned int reg)
    852{
    853	switch (reg) {
    854	case MAX98396_R2001_INT_RAW1 ... MAX98396_R200E_INT_FLAG4:
    855	case MAX98396_R2041_PCM_MODE_CFG:
    856	case MAX98397_R20B7_ADC_PVDD_READBACK_MSB
    857		... MAX98397_R20C4_ADC_LO_VDDH_READBACK_LSB:
    858	case MAX98396_R20E5_BPE_STATE:
    859	case MAX98396_R2109_BPE_LOW_STATE
    860		... MAX98396_R210B_BPE_LOW_LIMITER:
    861	case MAX98396_R210F_GLOBAL_EN:
    862	case MAX98397_R22FF_REVISION_ID:
    863		return true;
    864	default:
    865		return false;
    866	}
    867}
    868
    869static const char * const max98396_op_mod_text[] = {
    870	"DG", "PVDD", "VBAT",
    871};
    872
    873static SOC_ENUM_SINGLE_DECL(max98396_op_mod_enum,
    874			    MAX98396_R2098_SPK_CLS_DG_MODE,
    875			    0, max98396_op_mod_text);
    876
    877static DECLARE_TLV_DB_SCALE(max98396_digital_tlv, -6350, 50, 1);
    878static const DECLARE_TLV_DB_RANGE(max98396_spk_tlv,
    879	0, 0x11, TLV_DB_SCALE_ITEM(400, 100, 0),
    880);
    881static DECLARE_TLV_DB_RANGE(max98397_digital_tlv,
    882	0, 0x4A, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1),
    883	0x4B, 0xFF, TLV_DB_SCALE_ITEM(-9000, 50, 0),
    884);
    885static const DECLARE_TLV_DB_RANGE(max98397_spk_tlv,
    886	0, 0x15, TLV_DB_SCALE_ITEM(600, 100, 0),
    887);
    888
    889static int max98396_mux_get(struct snd_kcontrol *kcontrol,
    890			    struct snd_ctl_elem_value *ucontrol)
    891{
    892	struct snd_soc_component *component =
    893		snd_soc_dapm_kcontrol_component(kcontrol);
    894	struct max98396_priv *max98396 = snd_soc_component_get_drvdata(component);
    895	int reg, val;
    896
    897	if (max98396->device_id == CODEC_TYPE_MAX98396)
    898		reg = MAX98396_R2055_PCM_RX_SRC1;
    899	else
    900		reg = MAX98397_R2056_PCM_RX_SRC1;
    901
    902	regmap_read(max98396->regmap, reg, &val);
    903
    904	ucontrol->value.enumerated.item[0] = val;
    905
    906	return 0;
    907}
    908
    909static int max98396_mux_put(struct snd_kcontrol *kcontrol,
    910			    struct snd_ctl_elem_value *ucontrol)
    911{
    912	struct snd_soc_component *component =
    913		snd_soc_dapm_kcontrol_component(kcontrol);
    914	struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol);
    915	struct max98396_priv *max98396 = snd_soc_component_get_drvdata(component);
    916	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
    917	unsigned int *item = ucontrol->value.enumerated.item;
    918	int reg, val;
    919	int change;
    920
    921	if (item[0] >= e->items)
    922		return -EINVAL;
    923
    924	val = snd_soc_enum_item_to_val(e, item[0]) << e->shift_l;
    925
    926	if (max98396->device_id == CODEC_TYPE_MAX98396)
    927		reg = MAX98396_R2055_PCM_RX_SRC1;
    928	else
    929		reg = MAX98397_R2056_PCM_RX_SRC1;
    930
    931	change = snd_soc_component_test_bits(component, reg,
    932					     MAX98396_PCM_RX_MASK, val);
    933
    934	if (change)
    935		regmap_update_bits(max98396->regmap, reg,
    936				   MAX98396_PCM_RX_MASK, val);
    937
    938	snd_soc_dapm_mux_update_power(dapm, kcontrol, item[0], e, NULL);
    939
    940	return change;
    941}
    942
    943static const char * const max98396_switch_text[] = {
    944	"Left", "Right", "LeftRight"};
    945
    946static SOC_ENUM_SINGLE_DECL(dai_sel_enum, SND_SOC_NOPM, 0,
    947			    max98396_switch_text);
    948
    949static const struct snd_kcontrol_new max98396_dai_mux =
    950	SOC_DAPM_ENUM_EXT("DAI Sel Mux", dai_sel_enum,
    951			  max98396_mux_get, max98396_mux_put);
    952
    953static const struct snd_kcontrol_new max98396_vi_control =
    954	SOC_DAPM_SINGLE("Switch", MAX98396_R205F_PCM_TX_EN, 0, 1, 0);
    955
    956static const struct snd_soc_dapm_widget max98396_dapm_widgets[] = {
    957	SND_SOC_DAPM_DAC_E("Amp Enable", "HiFi Playback",
    958			   MAX98396_R20AF_AMP_EN, 0, 0, max98396_dac_event,
    959			   SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
    960	SND_SOC_DAPM_MUX("DAI Sel Mux", SND_SOC_NOPM, 0, 0,
    961			 &max98396_dai_mux),
    962	SND_SOC_DAPM_OUTPUT("BE_OUT"),
    963	SND_SOC_DAPM_AIF_OUT("Voltage Sense", "HiFi Capture", 0,
    964			     MAX98396_R20E4_IV_SENSE_PATH_EN, 0, 0),
    965	SND_SOC_DAPM_AIF_OUT("Current Sense", "HiFi Capture", 0,
    966			     MAX98396_R20E4_IV_SENSE_PATH_EN, 1, 0),
    967	SND_SOC_DAPM_SWITCH("VI Sense", SND_SOC_NOPM, 0, 0,
    968			    &max98396_vi_control),
    969	SND_SOC_DAPM_SIGGEN("VMON"),
    970	SND_SOC_DAPM_SIGGEN("IMON"),
    971	SND_SOC_DAPM_SIGGEN("FBMON"),
    972};
    973
    974static const char * const max98396_thermal_thresh_text[] = {
    975	"50C", "51C", "52C", "53C", "54C", "55C", "56C", "57C",
    976	"58C", "59C", "60C", "61C", "62C", "63C", "64C", "65C",
    977	"66C", "67C", "68C", "69C", "70C", "71C", "72C", "73C",
    978	"74C", "75C", "76C", "77C", "78C", "79C", "80C", "81C",
    979	"82C", "83C", "84C", "85C", "86C", "87C", "88C", "89C",
    980	"90C", "91C", "92C", "93C", "94C", "95C", "96C", "97C",
    981	"98C", "99C", "100C", "101C", "102C", "103C", "104C", "105C",
    982	"106C", "107C", "108C", "109C", "110C", "111C", "112C", "113C",
    983	"114C", "115C", "116C", "117C", "118C", "119C", "120C", "121C",
    984	"122C", "123C", "124C", "125C", "126C", "127C", "128C", "129C",
    985	"130C", "131C", "132C", "133C", "134C", "135C", "136C", "137C",
    986	"138C", "139C", "140C", "141C", "142C", "143C", "144C", "145C",
    987	"146C", "147C", "148C", "149C", "150C"
    988};
    989
    990static SOC_ENUM_SINGLE_DECL(max98396_thermal_warn_thresh1_enum,
    991			    MAX98396_R2020_THERM_WARN_THRESH, 0,
    992			    max98396_thermal_thresh_text);
    993
    994static SOC_ENUM_SINGLE_DECL(max98396_thermal_warn_thresh2_enum,
    995			    MAX98396_R2021_THERM_WARN_THRESH2, 0,
    996			    max98396_thermal_thresh_text);
    997
    998static SOC_ENUM_SINGLE_DECL(max98396_thermal_shdn_thresh_enum,
    999			    MAX98396_R2022_THERM_SHDN_THRESH, 0,
   1000			    max98396_thermal_thresh_text);
   1001
   1002static const char * const max98396_thermal_hyteresis_text[] = {
   1003	"2C", "5C", "7C", "10C"
   1004};
   1005
   1006static SOC_ENUM_SINGLE_DECL(max98396_thermal_hysteresis_enum,
   1007			    MAX98396_R2023_THERM_HYSTERESIS, 0,
   1008			    max98396_thermal_hyteresis_text);
   1009
   1010static const char * const max98396_foldback_slope_text[] = {
   1011	"0.25", "0.5", "1.0", "2.0"
   1012};
   1013
   1014static SOC_ENUM_SINGLE_DECL(max98396_thermal_fb_slope1_enum,
   1015			    MAX98396_R2024_THERM_FOLDBACK_SET,
   1016			    MAX98396_THERM_FB_SLOPE1_SHIFT,
   1017			    max98396_foldback_slope_text);
   1018
   1019static SOC_ENUM_SINGLE_DECL(max98396_thermal_fb_slope2_enum,
   1020			    MAX98396_R2024_THERM_FOLDBACK_SET,
   1021			    MAX98396_THERM_FB_SLOPE2_SHIFT,
   1022			    max98396_foldback_slope_text);
   1023
   1024static const char * const max98396_foldback_reltime_text[] = {
   1025	"3ms", "10ms", "100ms", "300ms"
   1026};
   1027
   1028static SOC_ENUM_SINGLE_DECL(max98396_thermal_fb_reltime_enum,
   1029			    MAX98396_R2024_THERM_FOLDBACK_SET,
   1030			    MAX98396_THERM_FB_REL_SHIFT,
   1031			    max98396_foldback_reltime_text);
   1032
   1033static const char * const max98396_foldback_holdtime_text[] = {
   1034	"0ms", "20ms", "40ms", "80ms"
   1035};
   1036
   1037static SOC_ENUM_SINGLE_DECL(max98396_thermal_fb_holdtime_enum,
   1038			    MAX98396_R2024_THERM_FOLDBACK_SET,
   1039			    MAX98396_THERM_FB_HOLD_SHIFT,
   1040			    max98396_foldback_holdtime_text);
   1041
   1042static int max98396_adc_value_get(struct snd_kcontrol *kcontrol,
   1043				  struct snd_ctl_elem_value *ucontrol)
   1044{
   1045	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
   1046	struct soc_mixer_control *mc =
   1047		(struct soc_mixer_control *)kcontrol->private_value;
   1048	struct max98396_priv *max98396 = snd_soc_component_get_drvdata(component);
   1049	int ret;
   1050	u8 val[2];
   1051	int reg = mc->reg;
   1052
   1053	/* ADC value is not available if the device is powered down */
   1054	if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)
   1055		goto exit;
   1056
   1057	if (max98396->device_id == CODEC_TYPE_MAX98397) {
   1058		switch (mc->reg) {
   1059		case MAX98396_R20B6_ADC_PVDD_READBACK_MSB:
   1060			reg = MAX98397_R20B7_ADC_PVDD_READBACK_MSB;
   1061			break;
   1062		case MAX98396_R20B8_ADC_VBAT_READBACK_MSB:
   1063			reg = MAX98397_R20B9_ADC_VBAT_READBACK_MSB;
   1064			break;
   1065		case MAX98396_R20BA_ADC_TEMP_READBACK_MSB:
   1066			reg = MAX98397_R20BB_ADC_TEMP_READBACK_MSB;
   1067			break;
   1068		default:
   1069			goto exit;
   1070		}
   1071	}
   1072
   1073	ret = regmap_raw_read(max98396->regmap, reg, &val, 2);
   1074	if (ret)
   1075		goto exit;
   1076
   1077	/* ADC readback bits[8:0] rearrangement */
   1078	ucontrol->value.integer.value[0] = (val[0] << 1) | (val[1] & 1);
   1079	return 0;
   1080
   1081exit:
   1082	ucontrol->value.integer.value[0] = 0;
   1083	return 0;
   1084}
   1085
   1086static const struct snd_kcontrol_new max98396_snd_controls[] = {
   1087	/* Volume */
   1088	SOC_SINGLE_TLV("Digital Volume", MAX98396_R2090_AMP_VOL_CTRL,
   1089		       0, 0x7F, 1, max98396_digital_tlv),
   1090	SOC_SINGLE_TLV("Speaker Volume", MAX98396_R2091_AMP_PATH_GAIN,
   1091		       0, 0x11, 0, max98396_spk_tlv),
   1092	/* Volume Ramp Up/Down Enable*/
   1093	SOC_SINGLE("Ramp Up Switch", MAX98396_R2092_AMP_DSP_CFG,
   1094		   MAX98396_DSP_SPK_VOL_RMPUP_SHIFT, 1, 0),
   1095	SOC_SINGLE("Ramp Down Switch", MAX98396_R2092_AMP_DSP_CFG,
   1096		   MAX98396_DSP_SPK_VOL_RMPDN_SHIFT, 1, 0),
   1097	/* Clock Monitor Enable */
   1098	SOC_SINGLE("CLK Monitor Switch", MAX98396_R203F_ENABLE_CTRLS,
   1099		   MAX98396_CTRL_CMON_EN_SHIFT, 1, 0),
   1100	/* Dither Enable */
   1101	SOC_SINGLE("Dither Switch", MAX98396_R2092_AMP_DSP_CFG,
   1102		   MAX98396_DSP_SPK_DITH_EN_SHIFT, 1, 0),
   1103	SOC_SINGLE("IV Dither Switch", MAX98396_R20E0_IV_SENSE_PATH_CFG,
   1104		   MAX98396_IV_SENSE_DITH_EN_SHIFT, 1, 0),
   1105	/* DC Blocker Enable */
   1106	SOC_SINGLE("DC Blocker Switch", MAX98396_R2092_AMP_DSP_CFG,
   1107		   MAX98396_DSP_SPK_DCBLK_EN_SHIFT, 1, 0),
   1108	SOC_SINGLE("IV DC Blocker Switch", MAX98396_R20E0_IV_SENSE_PATH_CFG,
   1109		   MAX98396_IV_SENSE_DCBLK_EN_SHIFT, 3, 0),
   1110	/* Speaker Safe Mode Enable */
   1111	SOC_SINGLE("Safe Mode Switch", MAX98396_R2092_AMP_DSP_CFG,
   1112		   MAX98396_DSP_SPK_SAFE_EN_SHIFT, 1, 0),
   1113	/* Wideband Filter Enable */
   1114	SOC_SINGLE("WB Filter Switch", MAX98396_R2092_AMP_DSP_CFG,
   1115		   MAX98396_DSP_SPK_WB_FLT_EN_SHIFT, 1, 0),
   1116	SOC_SINGLE("IV WB Filter Switch", MAX98396_R20E0_IV_SENSE_PATH_CFG,
   1117		   MAX98396_IV_SENSE_WB_FLT_EN_SHIFT, 1, 0),
   1118	/* Dynamic Headroom Tracking */
   1119	SOC_SINGLE("DHT Switch", MAX98396_R20DF_DHT_EN, 0, 1, 0),
   1120	/* Brownout Protection Engine */
   1121	SOC_SINGLE("BPE Switch", MAX98396_R210D_BPE_EN, 0, 1, 0),
   1122	SOC_SINGLE("BPE Limiter Switch", MAX98396_R210D_BPE_EN, 1, 1, 0),
   1123	/* Bypass Path Enable */
   1124	SOC_SINGLE("Bypass Path Switch",
   1125		   MAX98396_R205E_PCM_RX_EN, 1, 1, 0),
   1126	/* Speaker Operation Mode */
   1127	SOC_ENUM("OP Mode", max98396_op_mod_enum),
   1128	/* Auto Restart functions */
   1129	SOC_SINGLE("CMON Auto Restart Switch", MAX98396_R2038_CLK_MON_CTRL,
   1130		   MAX98396_CLK_MON_AUTO_RESTART_SHIFT, 1, 0),
   1131	SOC_SINGLE("PVDD Auto Restart Switch", MAX98396_R210E_AUTO_RESTART,
   1132		   MAX98396_PVDD_UVLO_RESTART_SHFT, 1, 0),
   1133	SOC_SINGLE("VBAT Auto Restart Switch", MAX98396_R210E_AUTO_RESTART,
   1134		   MAX98396_VBAT_UVLO_RESTART_SHFT, 1, 0),
   1135	SOC_SINGLE("THERM Auto Restart Switch", MAX98396_R210E_AUTO_RESTART,
   1136		   MAX98396_THEM_SHDN_RESTART_SHFT, 1, 0),
   1137	SOC_SINGLE("OVC Auto Restart Switch", MAX98396_R210E_AUTO_RESTART,
   1138		   MAX98396_OVC_RESTART_SHFT, 1, 0),
   1139	/* Thermal Threshold */
   1140	SOC_ENUM("THERM Thresh1", max98396_thermal_warn_thresh1_enum),
   1141	SOC_ENUM("THERM Thresh2", max98396_thermal_warn_thresh2_enum),
   1142	SOC_ENUM("THERM SHDN Thresh", max98396_thermal_shdn_thresh_enum),
   1143	SOC_ENUM("THERM Hysteresis", max98396_thermal_hysteresis_enum),
   1144	SOC_SINGLE("THERM Foldback Switch",
   1145		   MAX98396_R2027_THERM_FOLDBACK_EN, 0, 1, 0),
   1146	SOC_ENUM("THERM Slope1", max98396_thermal_fb_slope1_enum),
   1147	SOC_ENUM("THERM Slope2", max98396_thermal_fb_slope2_enum),
   1148	SOC_ENUM("THERM Release", max98396_thermal_fb_reltime_enum),
   1149	SOC_ENUM("THERM Hold", max98396_thermal_fb_holdtime_enum),
   1150	/* ADC */
   1151	SOC_SINGLE_EXT("ADC PVDD", MAX98396_R20B6_ADC_PVDD_READBACK_MSB, 0, 0x1FF, 0,
   1152		       max98396_adc_value_get, NULL),
   1153	SOC_SINGLE_EXT("ADC VBAT", MAX98396_R20B8_ADC_VBAT_READBACK_MSB, 0, 0x1FF, 0,
   1154		       max98396_adc_value_get, NULL),
   1155	SOC_SINGLE_EXT("ADC TEMP", MAX98396_R20BA_ADC_TEMP_READBACK_MSB, 0, 0x1FF, 0,
   1156		       max98396_adc_value_get, NULL),
   1157};
   1158
   1159static const struct snd_kcontrol_new max98397_snd_controls[] = {
   1160	/* Volume */
   1161	SOC_SINGLE_TLV("Digital Volume", MAX98396_R2090_AMP_VOL_CTRL,
   1162		       0, 0xFF, 1, max98397_digital_tlv),
   1163	SOC_SINGLE_TLV("Speaker Volume", MAX98396_R2091_AMP_PATH_GAIN,
   1164		       0, 0x15, 0, max98397_spk_tlv),
   1165	/* Volume Ramp Up/Down Enable*/
   1166	SOC_SINGLE("Ramp Up Switch", MAX98396_R2092_AMP_DSP_CFG,
   1167		   MAX98396_DSP_SPK_VOL_RMPUP_SHIFT, 1, 0),
   1168	SOC_SINGLE("Ramp Down Switch", MAX98396_R2092_AMP_DSP_CFG,
   1169		   MAX98396_DSP_SPK_VOL_RMPDN_SHIFT, 1, 0),
   1170	/* Clock Monitor Enable */
   1171	SOC_SINGLE("CLK Monitor Switch", MAX98396_R203F_ENABLE_CTRLS,
   1172		   MAX98396_CTRL_CMON_EN_SHIFT, 1, 0),
   1173	/* Dither Enable */
   1174	SOC_SINGLE("Dither Switch", MAX98396_R2092_AMP_DSP_CFG,
   1175		   MAX98396_DSP_SPK_DITH_EN_SHIFT, 1, 0),
   1176	SOC_SINGLE("IV Dither Switch", MAX98396_R20E0_IV_SENSE_PATH_CFG,
   1177		   MAX98396_IV_SENSE_DITH_EN_SHIFT, 1, 0),
   1178	/* DC Blocker Enable */
   1179	SOC_SINGLE("DC Blocker Switch", MAX98396_R2092_AMP_DSP_CFG,
   1180		   MAX98396_DSP_SPK_DCBLK_EN_SHIFT, 1, 0),
   1181	SOC_SINGLE("IV DC Blocker Switch", MAX98396_R20E0_IV_SENSE_PATH_CFG,
   1182		   MAX98396_IV_SENSE_DCBLK_EN_SHIFT, 3, 0),
   1183	/* Speaker Safe Mode Enable */
   1184	SOC_SINGLE("Safe Mode Switch", MAX98396_R2092_AMP_DSP_CFG,
   1185		   MAX98396_DSP_SPK_SAFE_EN_SHIFT, 1, 0),
   1186	/* Wideband Filter Enable */
   1187	SOC_SINGLE("WB Filter Switch", MAX98396_R2092_AMP_DSP_CFG,
   1188		   MAX98396_DSP_SPK_WB_FLT_EN_SHIFT, 1, 0),
   1189	SOC_SINGLE("IV WB Filter Switch", MAX98396_R20E0_IV_SENSE_PATH_CFG,
   1190		   MAX98396_IV_SENSE_WB_FLT_EN_SHIFT, 1, 0),
   1191	/* Dynamic Headroom Tracking */
   1192	SOC_SINGLE("DHT Switch", MAX98396_R20DF_DHT_EN, 0, 1, 0),
   1193	/* Brownout Protection Engine */
   1194	SOC_SINGLE("BPE Switch", MAX98396_R210D_BPE_EN, 0, 1, 0),
   1195	SOC_SINGLE("BPE Limiter Switch", MAX98396_R210D_BPE_EN, 1, 1, 0),
   1196	/* Bypass Path Enable */
   1197	SOC_SINGLE("Bypass Path Switch",
   1198		   MAX98396_R205E_PCM_RX_EN, 1, 1, 0),
   1199	/* Speaker Operation Mode */
   1200	SOC_ENUM("OP Mode", max98396_op_mod_enum),
   1201	/* Auto Restart functions */
   1202	SOC_SINGLE("CMON Auto Restart Switch", MAX98396_R2038_CLK_MON_CTRL,
   1203		   MAX98396_CLK_MON_AUTO_RESTART_SHIFT, 1, 0),
   1204	SOC_SINGLE("PVDD Auto Restart Switch", MAX98396_R210E_AUTO_RESTART,
   1205		   MAX98396_PVDD_UVLO_RESTART_SHFT, 1, 0),
   1206	SOC_SINGLE("VBAT Auto Restart Switch", MAX98396_R210E_AUTO_RESTART,
   1207		   MAX98396_VBAT_UVLO_RESTART_SHFT, 1, 0),
   1208	SOC_SINGLE("THERM Auto Restart Switch", MAX98396_R210E_AUTO_RESTART,
   1209		   MAX98396_THEM_SHDN_RESTART_SHFT, 1, 0),
   1210	SOC_SINGLE("OVC Auto Restart Switch", MAX98396_R210E_AUTO_RESTART,
   1211		   MAX98396_OVC_RESTART_SHFT, 1, 0),
   1212	/* Thermal Threshold */
   1213	SOC_ENUM("THERM Thresh1", max98396_thermal_warn_thresh1_enum),
   1214	SOC_ENUM("THERM Thresh2", max98396_thermal_warn_thresh2_enum),
   1215	SOC_ENUM("THERM SHDN Thresh", max98396_thermal_shdn_thresh_enum),
   1216	SOC_ENUM("THERM Hysteresis", max98396_thermal_hysteresis_enum),
   1217	SOC_SINGLE("THERM Foldback Switch",
   1218		   MAX98396_R2027_THERM_FOLDBACK_EN, 0, 1, 0),
   1219	SOC_ENUM("THERM Slope1", max98396_thermal_fb_slope1_enum),
   1220	SOC_ENUM("THERM Slope2", max98396_thermal_fb_slope2_enum),
   1221	SOC_ENUM("THERM Release", max98396_thermal_fb_reltime_enum),
   1222	SOC_ENUM("THERM Hold", max98396_thermal_fb_holdtime_enum),
   1223	/* ADC */
   1224	SOC_SINGLE_EXT("ADC PVDD", MAX98396_R20B6_ADC_PVDD_READBACK_MSB, 0, 0x1FF, 0,
   1225		       max98396_adc_value_get, NULL),
   1226	SOC_SINGLE_EXT("ADC VBAT", MAX98396_R20B8_ADC_VBAT_READBACK_MSB, 0, 0x1FF, 0,
   1227		       max98396_adc_value_get, NULL),
   1228	SOC_SINGLE_EXT("ADC TEMP", MAX98396_R20BA_ADC_TEMP_READBACK_MSB, 0, 0x1FF, 0,
   1229		       max98396_adc_value_get, NULL),
   1230};
   1231
   1232static const struct snd_soc_dapm_route max98396_audio_map[] = {
   1233	/* Plabyack */
   1234	{"DAI Sel Mux", "Left", "Amp Enable"},
   1235	{"DAI Sel Mux", "Right", "Amp Enable"},
   1236	{"DAI Sel Mux", "LeftRight", "Amp Enable"},
   1237	{"BE_OUT", NULL, "DAI Sel Mux"},
   1238	/* Capture */
   1239	{ "VI Sense", "Switch", "VMON" },
   1240	{ "VI Sense", "Switch", "IMON" },
   1241	{ "Voltage Sense", NULL, "VI Sense" },
   1242	{ "Current Sense", NULL, "VI Sense" },
   1243};
   1244
   1245static struct snd_soc_dai_driver max98396_dai[] = {
   1246	{
   1247		.name = "max98396-aif1",
   1248		.playback = {
   1249			.stream_name = "HiFi Playback",
   1250			.channels_min = 1,
   1251			.channels_max = 2,
   1252			.rates = MAX98396_RATES,
   1253			.formats = MAX98396_FORMATS,
   1254		},
   1255		.capture = {
   1256			.stream_name = "HiFi Capture",
   1257			.channels_min = 1,
   1258			.channels_max = 2,
   1259			.rates = MAX98396_RATES,
   1260			.formats = MAX98396_FORMATS,
   1261		},
   1262		.ops = &max98396_dai_ops,
   1263	}
   1264};
   1265
   1266static struct snd_soc_dai_driver max98397_dai[] = {
   1267	{
   1268		.name = "max98397-aif1",
   1269		.playback = {
   1270			.stream_name = "HiFi Playback",
   1271			.channels_min = 1,
   1272			.channels_max = 2,
   1273			.rates = MAX98396_RATES,
   1274			.formats = MAX98396_FORMATS,
   1275		},
   1276		.capture = {
   1277			.stream_name = "HiFi Capture",
   1278			.channels_min = 1,
   1279			.channels_max = 2,
   1280			.rates = MAX98396_RATES,
   1281			.formats = MAX98396_FORMATS,
   1282		},
   1283		.ops = &max98396_dai_ops,
   1284	}
   1285};
   1286
   1287static void max98396_reset(struct max98396_priv *max98396, struct device *dev)
   1288{
   1289	int ret, reg, count;
   1290
   1291	/* Software Reset */
   1292	ret = regmap_write(max98396->regmap,
   1293			   MAX98396_R2000_SW_RESET, 1);
   1294	if (ret)
   1295		dev_err(dev, "Reset command failed. (ret:%d)\n", ret);
   1296
   1297	count = 0;
   1298	while (count < 3) {
   1299		usleep_range(5000, 6000);
   1300		/* Software Reset Verification */
   1301		ret = regmap_read(max98396->regmap,
   1302				  GET_REG_ADDR_REV_ID(max98396->device_id), &reg);
   1303		if (!ret) {
   1304			dev_info(dev, "Reset completed (retry:%d)\n", count);
   1305			return;
   1306		}
   1307		count++;
   1308	}
   1309	dev_err(dev, "Reset failed. (ret:%d)\n", ret);
   1310}
   1311
   1312static int max98396_probe(struct snd_soc_component *component)
   1313{
   1314	struct max98396_priv *max98396 =
   1315		snd_soc_component_get_drvdata(component);
   1316
   1317	/* Software Reset */
   1318	max98396_reset(max98396, component->dev);
   1319
   1320	/* L/R mix configuration */
   1321	if (max98396->device_id == CODEC_TYPE_MAX98396) {
   1322		regmap_write(max98396->regmap,
   1323			     MAX98396_R2055_PCM_RX_SRC1, 0x02);
   1324		regmap_write(max98396->regmap,
   1325			     MAX98396_R2056_PCM_RX_SRC2, 0x10);
   1326	} else {
   1327		regmap_write(max98396->regmap,
   1328			     MAX98397_R2056_PCM_RX_SRC1, 0x02);
   1329		regmap_write(max98396->regmap,
   1330			     MAX98397_R2057_PCM_RX_SRC2, 0x10);
   1331	}
   1332	/* Enable DC blocker */
   1333	regmap_update_bits(max98396->regmap,
   1334			   MAX98396_R2092_AMP_DSP_CFG, 1, 1);
   1335	/* Enable IV Monitor DC blocker */
   1336	regmap_update_bits(max98396->regmap,
   1337			   MAX98396_R20E0_IV_SENSE_PATH_CFG,
   1338			   MAX98396_IV_SENSE_DCBLK_EN_MASK,
   1339			   MAX98396_IV_SENSE_DCBLK_EN_MASK);
   1340	/* Configure default data output sources */
   1341	regmap_write(max98396->regmap,
   1342		     MAX98396_R205D_PCM_TX_SRC_EN, 3);
   1343	/* Enable Wideband Filter */
   1344	regmap_update_bits(max98396->regmap,
   1345			   MAX98396_R2092_AMP_DSP_CFG, 0x40, 0x40);
   1346	/* Enable IV Wideband Filter */
   1347	regmap_update_bits(max98396->regmap,
   1348			   MAX98396_R20E0_IV_SENSE_PATH_CFG, 8, 8);
   1349
   1350	/* Enable Bypass Source */
   1351	regmap_write(max98396->regmap,
   1352		     MAX98396_R2058_PCM_BYPASS_SRC,
   1353		     max98396->bypass_slot);
   1354	/* Voltage, current slot configuration */
   1355	regmap_write(max98396->regmap,
   1356		     MAX98396_R2044_PCM_TX_CTRL_1,
   1357		     max98396->v_slot);
   1358	regmap_write(max98396->regmap,
   1359		     MAX98396_R2045_PCM_TX_CTRL_2,
   1360		     max98396->i_slot);
   1361
   1362	if (max98396->v_slot < 8)
   1363		if (max98396->device_id == CODEC_TYPE_MAX98396)
   1364			regmap_update_bits(max98396->regmap,
   1365					   MAX98396_R2053_PCM_TX_HIZ_CTRL_8,
   1366					   1 << max98396->v_slot, 0);
   1367		else
   1368			regmap_update_bits(max98396->regmap,
   1369					   MAX98397_R2054_PCM_TX_HIZ_CTRL_8,
   1370					   1 << max98396->v_slot, 0);
   1371	else
   1372		if (max98396->device_id == CODEC_TYPE_MAX98396)
   1373			regmap_update_bits(max98396->regmap,
   1374					   MAX98396_R2052_PCM_TX_HIZ_CTRL_7,
   1375					   1 << (max98396->v_slot - 8), 0);
   1376		else
   1377			regmap_update_bits(max98396->regmap,
   1378					   MAX98397_R2053_PCM_TX_HIZ_CTRL_7,
   1379					   1 << (max98396->v_slot - 8), 0);
   1380
   1381	if (max98396->i_slot < 8)
   1382		if (max98396->device_id == CODEC_TYPE_MAX98396)
   1383			regmap_update_bits(max98396->regmap,
   1384					   MAX98396_R2053_PCM_TX_HIZ_CTRL_8,
   1385					   1 << max98396->i_slot, 0);
   1386		else
   1387			regmap_update_bits(max98396->regmap,
   1388					   MAX98397_R2054_PCM_TX_HIZ_CTRL_8,
   1389					   1 << max98396->i_slot, 0);
   1390	else
   1391		if (max98396->device_id == CODEC_TYPE_MAX98396)
   1392			regmap_update_bits(max98396->regmap,
   1393					   MAX98396_R2052_PCM_TX_HIZ_CTRL_7,
   1394					   1 << (max98396->i_slot - 8), 0);
   1395		else
   1396			regmap_update_bits(max98396->regmap,
   1397					   MAX98397_R2053_PCM_TX_HIZ_CTRL_7,
   1398					   1 << (max98396->i_slot - 8), 0);
   1399
   1400	/* Set interleave mode */
   1401	if (max98396->interleave_mode)
   1402		regmap_update_bits(max98396->regmap,
   1403				   MAX98396_R2041_PCM_MODE_CFG,
   1404				   MAX98396_PCM_TX_CH_INTERLEAVE_MASK,
   1405				   MAX98396_PCM_TX_CH_INTERLEAVE_MASK);
   1406
   1407	regmap_update_bits(max98396->regmap,
   1408			   MAX98396_R2038_CLK_MON_CTRL,
   1409			   MAX98396_CLK_MON_AUTO_RESTART_MASK,
   1410			   MAX98396_CLK_MON_AUTO_RESTART_MASK);
   1411
   1412	/* Speaker Amplifier PCM RX Enable by default */
   1413	regmap_update_bits(max98396->regmap,
   1414			   MAX98396_R205E_PCM_RX_EN,
   1415			   MAX98396_PCM_RX_EN_MASK, 1);
   1416
   1417	return 0;
   1418}
   1419
   1420#ifdef CONFIG_PM_SLEEP
   1421static int max98396_suspend(struct device *dev)
   1422{
   1423	struct max98396_priv *max98396 = dev_get_drvdata(dev);
   1424
   1425	regcache_cache_only(max98396->regmap, true);
   1426	regcache_mark_dirty(max98396->regmap);
   1427	return 0;
   1428}
   1429
   1430static int max98396_resume(struct device *dev)
   1431{
   1432	struct max98396_priv *max98396 = dev_get_drvdata(dev);
   1433
   1434	regcache_cache_only(max98396->regmap, false);
   1435	max98396_reset(max98396, dev);
   1436	regcache_sync(max98396->regmap);
   1437	return 0;
   1438}
   1439#endif
   1440
   1441static const struct dev_pm_ops max98396_pm = {
   1442	SET_SYSTEM_SLEEP_PM_OPS(max98396_suspend, max98396_resume)
   1443};
   1444
   1445static const struct snd_soc_component_driver soc_codec_dev_max98396 = {
   1446	.probe			= max98396_probe,
   1447	.controls		= max98396_snd_controls,
   1448	.num_controls		= ARRAY_SIZE(max98396_snd_controls),
   1449	.dapm_widgets		= max98396_dapm_widgets,
   1450	.num_dapm_widgets	= ARRAY_SIZE(max98396_dapm_widgets),
   1451	.dapm_routes		= max98396_audio_map,
   1452	.num_dapm_routes	= ARRAY_SIZE(max98396_audio_map),
   1453	.idle_bias_on		= 1,
   1454	.use_pmdown_time	= 1,
   1455	.endianness		= 1,
   1456	.non_legacy_dai_naming	= 1,
   1457};
   1458
   1459static const struct snd_soc_component_driver soc_codec_dev_max98397 = {
   1460	.probe			= max98396_probe,
   1461	.controls		= max98397_snd_controls,
   1462	.num_controls		= ARRAY_SIZE(max98397_snd_controls),
   1463	.dapm_widgets		= max98396_dapm_widgets,
   1464	.num_dapm_widgets	= ARRAY_SIZE(max98396_dapm_widgets),
   1465	.dapm_routes		= max98396_audio_map,
   1466	.num_dapm_routes	= ARRAY_SIZE(max98396_audio_map),
   1467	.idle_bias_on		= 1,
   1468	.use_pmdown_time	= 1,
   1469	.endianness		= 1,
   1470	.non_legacy_dai_naming	= 1,
   1471};
   1472
   1473static const struct regmap_config max98396_regmap = {
   1474	.reg_bits = 16,
   1475	.val_bits = 8,
   1476	.max_register = MAX98396_R21FF_REVISION_ID,
   1477	.reg_defaults  = max98396_reg,
   1478	.num_reg_defaults = ARRAY_SIZE(max98396_reg),
   1479	.readable_reg = max98396_readable_register,
   1480	.volatile_reg = max98396_volatile_reg,
   1481	.cache_type = REGCACHE_RBTREE,
   1482};
   1483
   1484static const struct regmap_config max98397_regmap = {
   1485	.reg_bits = 16,
   1486	.val_bits = 8,
   1487	.max_register = MAX98397_R22FF_REVISION_ID,
   1488	.reg_defaults  = max98397_reg,
   1489	.num_reg_defaults = ARRAY_SIZE(max98397_reg),
   1490	.readable_reg = max98397_readable_register,
   1491	.volatile_reg = max98397_volatile_reg,
   1492	.cache_type = REGCACHE_RBTREE,
   1493};
   1494
   1495static void max98396_read_device_property(struct device *dev,
   1496					  struct max98396_priv *max98396)
   1497{
   1498	int value;
   1499
   1500	if (!device_property_read_u32(dev, "adi,vmon-slot-no", &value))
   1501		max98396->v_slot = value & 0xF;
   1502	else
   1503		max98396->v_slot = 0;
   1504
   1505	if (!device_property_read_u32(dev, "adi,imon-slot-no", &value))
   1506		max98396->i_slot = value & 0xF;
   1507	else
   1508		max98396->i_slot = 1;
   1509
   1510	if (!device_property_read_u32(dev, "adi,bypass-slot-no", &value))
   1511		max98396->bypass_slot = value & 0xF;
   1512	else
   1513		max98396->bypass_slot = 0;
   1514}
   1515
   1516static int max98396_i2c_probe(struct i2c_client *i2c,
   1517			      const struct i2c_device_id *id)
   1518{
   1519	struct max98396_priv *max98396 = NULL;
   1520	int ret, reg;
   1521
   1522	max98396 = devm_kzalloc(&i2c->dev, sizeof(*max98396), GFP_KERNEL);
   1523
   1524	if (!max98396) {
   1525		ret = -ENOMEM;
   1526		return ret;
   1527	}
   1528	i2c_set_clientdata(i2c, max98396);
   1529
   1530	max98396->device_id =  id->driver_data;
   1531
   1532	/* regmap initialization */
   1533	if (max98396->device_id == CODEC_TYPE_MAX98396)
   1534		max98396->regmap = devm_regmap_init_i2c(i2c, &max98396_regmap);
   1535
   1536	else
   1537		max98396->regmap = devm_regmap_init_i2c(i2c, &max98397_regmap);
   1538
   1539	if (IS_ERR(max98396->regmap)) {
   1540		ret = PTR_ERR(max98396->regmap);
   1541		dev_err(&i2c->dev,
   1542			"Failed to allocate regmap: %d\n", ret);
   1543		return ret;
   1544	}
   1545
   1546	/* update interleave mode info */
   1547	if (device_property_read_bool(&i2c->dev, "adi,interleave_mode"))
   1548		max98396->interleave_mode = true;
   1549	else
   1550		max98396->interleave_mode = false;
   1551
   1552	/* voltage/current slot & gpio configuration */
   1553	max98396_read_device_property(&i2c->dev, max98396);
   1554
   1555	/* Reset the Device */
   1556	max98396->reset_gpio = devm_gpiod_get_optional(&i2c->dev,
   1557						       "reset", GPIOD_OUT_HIGH);
   1558	if (IS_ERR(max98396->reset_gpio)) {
   1559		ret = PTR_ERR(max98396->reset_gpio);
   1560		dev_err(&i2c->dev, "Unable to request GPIO pin: %d.\n", ret);
   1561		return ret;
   1562	}
   1563
   1564	if (max98396->reset_gpio) {
   1565		usleep_range(5000, 6000);
   1566		gpiod_set_value_cansleep(max98396->reset_gpio, 0);
   1567		/* Wait for the hw reset done */
   1568		usleep_range(5000, 6000);
   1569	}
   1570
   1571	ret = regmap_read(max98396->regmap,
   1572			  GET_REG_ADDR_REV_ID(max98396->device_id), &reg);
   1573	if (ret < 0) {
   1574		dev_err(&i2c->dev, "%s: failed to read revision of the device.\n",  id->name);
   1575		return ret;
   1576	}
   1577	dev_info(&i2c->dev, "%s revision ID: 0x%02X\n", id->name, reg);
   1578
   1579	/* codec registration */
   1580	if (max98396->device_id == CODEC_TYPE_MAX98396)
   1581		ret = devm_snd_soc_register_component(&i2c->dev,
   1582						      &soc_codec_dev_max98396,
   1583						      max98396_dai,
   1584						      ARRAY_SIZE(max98396_dai));
   1585	else
   1586		ret = devm_snd_soc_register_component(&i2c->dev,
   1587						      &soc_codec_dev_max98397,
   1588						      max98397_dai,
   1589						      ARRAY_SIZE(max98397_dai));
   1590	if (ret < 0)
   1591		dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
   1592
   1593	return ret;
   1594}
   1595
   1596static const struct i2c_device_id max98396_i2c_id[] = {
   1597	{ "max98396", CODEC_TYPE_MAX98396},
   1598	{ "max98397", CODEC_TYPE_MAX98397},
   1599	{ },
   1600};
   1601
   1602MODULE_DEVICE_TABLE(i2c, max98396_i2c_id);
   1603
   1604#if defined(CONFIG_OF)
   1605static const struct of_device_id max98396_of_match[] = {
   1606	{ .compatible = "adi,max98396", },
   1607	{ .compatible = "adi,max98397", },
   1608	{ }
   1609};
   1610MODULE_DEVICE_TABLE(of, max98396_of_match);
   1611#endif
   1612
   1613#ifdef CONFIG_ACPI
   1614static const struct acpi_device_id max98396_acpi_match[] = {
   1615	{ "ADS8396", 0 },
   1616	{ "ADS8397", 0 },
   1617	{},
   1618};
   1619MODULE_DEVICE_TABLE(acpi, max98396_acpi_match);
   1620#endif
   1621
   1622static struct i2c_driver max98396_i2c_driver = {
   1623	.driver = {
   1624		.name = "max98396",
   1625		.of_match_table = of_match_ptr(max98396_of_match),
   1626		.acpi_match_table = ACPI_PTR(max98396_acpi_match),
   1627		.pm = &max98396_pm,
   1628	},
   1629	.probe = max98396_i2c_probe,
   1630	.id_table = max98396_i2c_id,
   1631};
   1632
   1633module_i2c_driver(max98396_i2c_driver)
   1634
   1635MODULE_DESCRIPTION("ALSA SoC MAX98396 driver");
   1636MODULE_AUTHOR("Ryan Lee <ryans.lee@analog.com>");
   1637MODULE_LICENSE("GPL");