diff --git a/asoc/codecs/aqt1000/aqt1000-clsh.c b/asoc/codecs/aqt1000/aqt1000-clsh.c new file mode 100644 index 0000000000..640795dc79 --- /dev/null +++ b/asoc/codecs/aqt1000/aqt1000-clsh.c @@ -0,0 +1,805 @@ +/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include "aqt1000-registers.h" +#include "aqt1000-clsh.h" + +#define AQT_USLEEP_RANGE 50 +#define MAX_IMPED_PARAMS 6 + +enum aqt_vref_dac_sel { + VREF_N1P9V = 0, + VREF_N1P86V, + VREF_N181V, + VREF_N1P74V, + VREF_N1P7V, + VREF_N0P9V, + VREF_N1P576V, + VREF_N1P827V, +}; + +enum aqt_vref_ctl { + CONTROLLER = 0, + I2C, +}; + +enum aqt_hd2_res_div_ctl { + DISCONNECT = 0, + P5_0P35, + P75_0P68, + P82_0P77, + P9_0P87, +}; + +enum aqt_curr_bias_err_amp { + I_0P25UA = 0, + I_0P5UA, + I_0P75UA, + I_1UA, + I_1P25UA, + I_1P5UA, + I_1P75UA, + I_2UA, +}; + +static const struct aqt_reg_mask_val imped_table_aqt[][MAX_IMPED_PARAMS] = { + { + {AQT1000_CDC_RX1_RX_VOL_CTL, 0xff, 0xf2}, + {AQT1000_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xf2}, + {AQT1000_CDC_RX1_RX_PATH_SEC1, 0x01, 0x00}, + {AQT1000_CDC_RX2_RX_VOL_CTL, 0xff, 0xf2}, + {AQT1000_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xf2}, + {AQT1000_CDC_RX2_RX_PATH_SEC1, 0x01, 0x00}, + }, + { + {AQT1000_CDC_RX1_RX_VOL_CTL, 0xff, 0xf4}, + {AQT1000_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xf4}, + {AQT1000_CDC_RX1_RX_PATH_SEC1, 0x01, 0x00}, + {AQT1000_CDC_RX2_RX_VOL_CTL, 0xff, 0xf4}, + {AQT1000_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xf4}, + {AQT1000_CDC_RX2_RX_PATH_SEC1, 0x01, 0x00}, + }, + { + {AQT1000_CDC_RX1_RX_VOL_CTL, 0xff, 0xf7}, + {AQT1000_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xf7}, + {AQT1000_CDC_RX1_RX_PATH_SEC1, 0x01, 0x01}, + {AQT1000_CDC_RX2_RX_VOL_CTL, 0xff, 0xf7}, + {AQT1000_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xf7}, + {AQT1000_CDC_RX2_RX_PATH_SEC1, 0x01, 0x01}, + }, + { + {AQT1000_CDC_RX1_RX_VOL_CTL, 0xff, 0xf9}, + {AQT1000_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xf9}, + {AQT1000_CDC_RX1_RX_PATH_SEC1, 0x01, 0x00}, + {AQT1000_CDC_RX2_RX_VOL_CTL, 0xff, 0xf9}, + {AQT1000_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xf9}, + {AQT1000_CDC_RX2_RX_PATH_SEC1, 0x01, 0x00}, + }, + { + {AQT1000_CDC_RX1_RX_VOL_CTL, 0xff, 0xfa}, + {AQT1000_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xfa}, + {AQT1000_CDC_RX1_RX_PATH_SEC1, 0x01, 0x00}, + {AQT1000_CDC_RX2_RX_VOL_CTL, 0xff, 0xfa}, + {AQT1000_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xfa}, + {AQT1000_CDC_RX2_RX_PATH_SEC1, 0x01, 0x00}, + }, + { + {AQT1000_CDC_RX1_RX_VOL_CTL, 0xff, 0xfb}, + {AQT1000_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xfb}, + {AQT1000_CDC_RX1_RX_PATH_SEC1, 0x01, 0x00}, + {AQT1000_CDC_RX2_RX_VOL_CTL, 0xff, 0xfb}, + {AQT1000_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xfb}, + {AQT1000_CDC_RX2_RX_PATH_SEC1, 0x01, 0x00}, + }, + { + {AQT1000_CDC_RX1_RX_VOL_CTL, 0xff, 0xfc}, + {AQT1000_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xfc}, + {AQT1000_CDC_RX1_RX_PATH_SEC1, 0x01, 0x00}, + {AQT1000_CDC_RX2_RX_VOL_CTL, 0xff, 0xfc}, + {AQT1000_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xfc}, + {AQT1000_CDC_RX2_RX_PATH_SEC1, 0x01, 0x00}, + }, + { + {AQT1000_CDC_RX1_RX_VOL_CTL, 0xff, 0xfd}, + {AQT1000_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xfd}, + {AQT1000_CDC_RX1_RX_PATH_SEC1, 0x01, 0x00}, + {AQT1000_CDC_RX2_RX_VOL_CTL, 0xff, 0xfd}, + {AQT1000_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xfd}, + {AQT1000_CDC_RX2_RX_PATH_SEC1, 0x01, 0x00}, + }, + { + {AQT1000_CDC_RX1_RX_VOL_CTL, 0xff, 0xfd}, + {AQT1000_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xfd}, + {AQT1000_CDC_RX1_RX_PATH_SEC1, 0x01, 0x01}, + {AQT1000_CDC_RX2_RX_VOL_CTL, 0xff, 0xfd}, + {AQT1000_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xfd}, + {AQT1000_CDC_RX2_RX_PATH_SEC1, 0x01, 0x01}, + }, +}; + +static const struct aqt_imped_val imped_index[] = { + {4, 0}, + {5, 1}, + {6, 2}, + {7, 3}, + {8, 4}, + {9, 5}, + {10, 6}, + {11, 7}, + {12, 8}, + {13, 9}, +}; + +static void (*clsh_state_fp[NUM_CLSH_STATES])(struct snd_soc_codec *, + struct aqt_clsh_cdc_data *, + u8 req_state, bool en, int mode); + +static int get_impedance_index(int imped) +{ + int i = 0; + + if (imped < imped_index[i].imped_val) { + pr_debug("%s, detected impedance is less than 4 Ohm\n", + __func__); + i = 0; + goto ret; + } + if (imped >= imped_index[ARRAY_SIZE(imped_index) - 1].imped_val) { + pr_debug("%s, detected impedance is greater than 12 Ohm\n", + __func__); + i = ARRAY_SIZE(imped_index) - 1; + goto ret; + } + for (i = 0; i < ARRAY_SIZE(imped_index) - 1; i++) { + if (imped >= imped_index[i].imped_val && + imped < imped_index[i + 1].imped_val) + break; + } +ret: + pr_debug("%s: selected impedance index = %d\n", + __func__, imped_index[i].index); + return imped_index[i].index; +} + +/* + * Function: aqt_clsh_imped_config + * Params: codec, imped, reset + * Description: + * This function updates HPHL and HPHR gain settings + * according to the impedance value. + */ +void aqt_clsh_imped_config(struct snd_soc_codec *codec, int imped, bool reset) +{ + int i; + int index = 0; + int table_size; + + static const struct aqt_reg_mask_val + (*imped_table_ptr)[MAX_IMPED_PARAMS]; + + table_size = ARRAY_SIZE(imped_table_aqt); + imped_table_ptr = imped_table_aqt; + + /* reset = 1, which means request is to reset the register values */ + if (reset) { + for (i = 0; i < MAX_IMPED_PARAMS; i++) + snd_soc_update_bits(codec, + imped_table_ptr[index][i].reg, + imped_table_ptr[index][i].mask, 0); + return; + } + index = get_impedance_index(imped); + if (index >= (ARRAY_SIZE(imped_index) - 1)) { + pr_debug("%s, impedance not in range = %d\n", __func__, imped); + return; + } + if (index >= table_size) { + pr_debug("%s, impedance index not in range = %d\n", __func__, + index); + return; + } + for (i = 0; i < MAX_IMPED_PARAMS; i++) + snd_soc_update_bits(codec, + imped_table_ptr[index][i].reg, + imped_table_ptr[index][i].mask, + imped_table_ptr[index][i].val); +} +EXPORT_SYMBOL(aqt_clsh_imped_config); + +static const char *mode_to_str(int mode) +{ + switch (mode) { + case CLS_H_NORMAL: + return "CLS_H_NORMAL"; + case CLS_H_HIFI: + return "CLS_H_HIFI"; + case CLS_H_LOHIFI: + return "CLS_H_LOHIFI"; + case CLS_H_LP: + return "CLS_H_LP"; + case CLS_H_ULP: + return "CLS_H_ULP"; + case CLS_AB: + return "CLS_AB"; + case CLS_AB_HIFI: + return "CLS_AB_HIFI"; + default: + return "CLS_H_INVALID"; + }; +} + +static const char *const state_to_str[] = { + [AQT_CLSH_STATE_IDLE] = "STATE_IDLE", + [AQT_CLSH_STATE_HPHL] = "STATE_HPH_L", + [AQT_CLSH_STATE_HPHR] = "STATE_HPH_R", + [AQT_CLSH_STATE_HPH_ST] = "STATE_HPH_ST", +}; + +static inline void +aqt_enable_clsh_block(struct snd_soc_codec *codec, + struct aqt_clsh_cdc_data *clsh_d, bool enable) +{ + if ((enable && ++clsh_d->clsh_users == 1) || + (!enable && --clsh_d->clsh_users == 0)) + snd_soc_update_bits(codec, AQT1000_CDC_CLSH_CRC, 0x01, + (u8) enable); + if (clsh_d->clsh_users < 0) + clsh_d->clsh_users = 0; + dev_dbg(codec->dev, "%s: clsh_users %d, enable %d", __func__, + clsh_d->clsh_users, enable); +} + +static inline bool aqt_clsh_enable_status(struct snd_soc_codec *codec) +{ + return snd_soc_read(codec, AQT1000_CDC_CLSH_CRC) & 0x01; +} + +static inline int aqt_clsh_get_int_mode(struct aqt_clsh_cdc_data *clsh_d, + int clsh_state) +{ + int mode; + + if ((clsh_state != AQT_CLSH_STATE_HPHL) && + (clsh_state != AQT_CLSH_STATE_HPHR)) + mode = CLS_NONE; + else + mode = clsh_d->interpolator_modes[ffs(clsh_state)]; + + return mode; +} + +static inline void aqt_clsh_set_int_mode(struct aqt_clsh_cdc_data *clsh_d, + int clsh_state, int mode) +{ + if ((clsh_state != AQT_CLSH_STATE_HPHL) && + (clsh_state != AQT_CLSH_STATE_HPHR)) + return; + + clsh_d->interpolator_modes[ffs(clsh_state)] = mode; +} + +static inline void aqt_clsh_set_buck_mode(struct snd_soc_codec *codec, + int mode) +{ + if (mode == CLS_H_HIFI || mode == CLS_H_LOHIFI || + mode == CLS_AB_HIFI || mode == CLS_AB) + snd_soc_update_bits(codec, AQT1000_ANA_RX_SUPPLIES, + 0x08, 0x08); /* set to HIFI */ + else + snd_soc_update_bits(codec, AQT1000_ANA_RX_SUPPLIES, + 0x08, 0x00); /* set to default */ +} + +static inline void aqt_clsh_set_flyback_mode(struct snd_soc_codec *codec, + int mode) +{ + if (mode == CLS_H_HIFI || mode == CLS_H_LOHIFI || + mode == CLS_AB_HIFI || mode == CLS_AB) + snd_soc_update_bits(codec, AQT1000_ANA_RX_SUPPLIES, + 0x04, 0x04); /* set to HIFI */ + else + snd_soc_update_bits(codec, AQT1000_ANA_RX_SUPPLIES, + 0x04, 0x00); /* set to Default */ +} + +static inline void aqt_clsh_gm3_boost_disable(struct snd_soc_codec *codec, + int mode) +{ + if (mode == CLS_H_HIFI || mode == CLS_H_LOHIFI || + mode == CLS_AB_HIFI || mode == CLS_AB) { + snd_soc_update_bits(codec, AQT1000_HPH_CNP_WG_CTL, + 0x80, 0x0); /* disable GM3 Boost */ + snd_soc_update_bits(codec, AQT1000_FLYBACK_VNEG_CTRL_4, + 0xF0, 0x80); + } else { + snd_soc_update_bits(codec, AQT1000_HPH_CNP_WG_CTL, + 0x80, 0x80); /* set to Default */ + snd_soc_update_bits(codec, AQT1000_FLYBACK_VNEG_CTRL_4, + 0xF0, 0x70); + } +} + +static inline void aqt_clsh_flyback_dac_ctl(struct snd_soc_codec *codec, + int vref) +{ + snd_soc_update_bits(codec, AQT1000_FLYBACK_VNEGDAC_CTRL_2, + 0xE0, (vref << 5)); +} + +static inline void aqt_clsh_mode_vref_ctl(struct snd_soc_codec *codec, + int vref_ctl) +{ + if (vref_ctl == I2C) { + snd_soc_update_bits(codec, AQT1000_CLASSH_MODE_3, 0x02, 0x02); + snd_soc_update_bits(codec, AQT1000_CLASSH_MODE_2, 0xFF, 0x1C); + } else { + snd_soc_update_bits(codec, AQT1000_CLASSH_MODE_2, 0xFF, 0x3A); + snd_soc_update_bits(codec, AQT1000_CLASSH_MODE_3, 0x02, 0x00); + } +} + +static inline void aqt_clsh_buck_current_bias_ctl(struct snd_soc_codec *codec, + bool enable) +{ + if (enable) { + snd_soc_update_bits(codec, AQT1000_BUCK_5V_IBIAS_CTL_4, + 0x70, (I_2UA << 4)); + snd_soc_update_bits(codec, AQT1000_BUCK_5V_IBIAS_CTL_4, + 0x07, I_0P25UA); + snd_soc_update_bits(codec, AQT1000_BUCK_5V_CTRL_CCL_2, + 0x3F, 0x3F); + } else { + snd_soc_update_bits(codec, AQT1000_BUCK_5V_IBIAS_CTL_4, + 0x70, (I_1UA << 4)); + snd_soc_update_bits(codec, AQT1000_BUCK_5V_IBIAS_CTL_4, + 0x07, I_1UA); + snd_soc_update_bits(codec, AQT1000_BUCK_5V_CTRL_CCL_2, + 0x3F, 0x20); + } +} + +static inline void aqt_clsh_rdac_hd2_ctl(struct snd_soc_codec *codec, + u8 hd2_div_ctl, u8 state) +{ + u16 reg = 0; + + if (state == AQT_CLSH_STATE_HPHL) + reg = AQT1000_HPH_NEW_INT_RDAC_HD2_CTL_L; + else if (state == AQT_CLSH_STATE_HPHR) + reg = AQT1000_HPH_NEW_INT_RDAC_HD2_CTL_R; + else + dev_err(codec->dev, "%s: Invalid state: %d\n", + __func__, state); + if (!reg) + snd_soc_update_bits(codec, reg, 0x0F, hd2_div_ctl); +} + +static inline void aqt_clsh_force_iq_ctl(struct snd_soc_codec *codec, + int mode) +{ + if (mode == CLS_H_LOHIFI || mode == CLS_AB) { + snd_soc_update_bits(codec, AQT1000_HPH_NEW_INT_PA_MISC2, + 0x20, 0x20); + snd_soc_update_bits(codec, AQT1000_RX_BIAS_HPH_LOWPOWER, + 0xF0, 0xC0); + snd_soc_update_bits(codec, AQT1000_HPH_PA_CTL1, + 0x0E, 0x02); + } else { + + snd_soc_update_bits(codec, AQT1000_HPH_NEW_INT_PA_MISC2, + 0x20, 0x0); + snd_soc_update_bits(codec, AQT1000_RX_BIAS_HPH_LOWPOWER, + 0xF0, 0x80); + snd_soc_update_bits(codec, AQT1000_HPH_PA_CTL1, + 0x0E, 0x06); + } +} + +static void aqt_clsh_buck_ctrl(struct snd_soc_codec *codec, + struct aqt_clsh_cdc_data *clsh_d, + int mode, + bool enable) +{ + /* enable/disable buck */ + if ((enable && (++clsh_d->buck_users == 1)) || + (!enable && (--clsh_d->buck_users == 0))) + snd_soc_update_bits(codec, AQT1000_ANA_RX_SUPPLIES, + (1 << 7), (enable << 7)); + dev_dbg(codec->dev, "%s: buck_users %d, enable %d, mode: %s", + __func__, clsh_d->buck_users, enable, mode_to_str(mode)); + /* + * 500us sleep is required after buck enable/disable + * as per HW requirement + */ + usleep_range(500, 500 + AQT_USLEEP_RANGE); +} + +static void aqt_clsh_flyback_ctrl(struct snd_soc_codec *codec, + struct aqt_clsh_cdc_data *clsh_d, + int mode, + bool enable) +{ + /* enable/disable flyback */ + if ((enable && (++clsh_d->flyback_users == 1)) || + (!enable && (--clsh_d->flyback_users == 0))) { + snd_soc_update_bits(codec, AQT1000_ANA_RX_SUPPLIES, + (1 << 6), (enable << 6)); + /* 100usec delay is needed as per HW requirement */ + usleep_range(100, 110); + } + dev_dbg(codec->dev, "%s: flyback_users %d, enable %d, mode: %s", + __func__, clsh_d->flyback_users, enable, mode_to_str(mode)); + /* + * 500us sleep is required after flyback enable/disable + * as per HW requirement + */ + usleep_range(500, 500 + AQT_USLEEP_RANGE); +} + +static void aqt_clsh_set_hph_mode(struct snd_soc_codec *codec, + int mode) +{ + u8 val = 0; + u8 gain = 0; + u8 res_val = VREF_FILT_R_0OHM; + u8 ipeak = DELTA_I_50MA; + + switch (mode) { + case CLS_H_NORMAL: + res_val = VREF_FILT_R_50KOHM; + val = 0x00; + gain = DAC_GAIN_0DB; + ipeak = DELTA_I_50MA; + break; + case CLS_AB: + val = 0x00; + gain = DAC_GAIN_0DB; + ipeak = DELTA_I_50MA; + break; + case CLS_AB_HIFI: + val = 0x08; + break; + case CLS_H_HIFI: + val = 0x08; + gain = DAC_GAIN_M0P2DB; + ipeak = DELTA_I_50MA; + break; + case CLS_H_LOHIFI: + val = 0x00; + break; + case CLS_H_ULP: + val = 0x0C; + break; + case CLS_H_LP: + val = 0x04; + ipeak = DELTA_I_30MA; + break; + default: + return; + }; + + if (mode == CLS_H_LOHIFI || mode == CLS_AB) + val = 0x04; + + snd_soc_update_bits(codec, AQT1000_ANA_HPH, 0x0C, val); +} + +static void aqt_clsh_set_buck_regulator_mode(struct snd_soc_codec *codec, + int mode) +{ + snd_soc_update_bits(codec, AQT1000_ANA_RX_SUPPLIES, + 0x02, 0x00); +} + +static void aqt_clsh_state_hph_st(struct snd_soc_codec *codec, + struct aqt_clsh_cdc_data *clsh_d, + u8 req_state, bool is_enable, int mode) +{ + dev_dbg(codec->dev, "%s: mode: %s, %s\n", __func__, mode_to_str(mode), + is_enable ? "enable" : "disable"); + + if (mode == CLS_AB || mode == CLS_AB_HIFI) + return; + + if (is_enable) { + if (req_state == AQT_CLSH_STATE_HPHL) + snd_soc_update_bits(codec, + AQT1000_CDC_RX1_RX_PATH_CFG0, + 0x40, 0x40); + if (req_state == AQT_CLSH_STATE_HPHR) + snd_soc_update_bits(codec, + AQT1000_CDC_RX2_RX_PATH_CFG0, + 0x40, 0x40); + } else { + if (req_state == AQT_CLSH_STATE_HPHL) + snd_soc_update_bits(codec, + AQT1000_CDC_RX1_RX_PATH_CFG0, + 0x40, 0x00); + if (req_state == AQT_CLSH_STATE_HPHR) + snd_soc_update_bits(codec, + AQT1000_CDC_RX2_RX_PATH_CFG0, + 0x40, 0x00); + } +} + +static void aqt_clsh_state_hph_r(struct snd_soc_codec *codec, + struct aqt_clsh_cdc_data *clsh_d, + u8 req_state, bool is_enable, int mode) +{ + dev_dbg(codec->dev, "%s: mode: %s, %s\n", __func__, mode_to_str(mode), + is_enable ? "enable" : "disable"); + + if (mode == CLS_H_NORMAL) { + dev_err(codec->dev, "%s: Normal mode not applicable for hph_r\n", + __func__); + return; + } + + if (is_enable) { + if (mode != CLS_AB && mode != CLS_AB_HIFI) { + aqt_enable_clsh_block(codec, clsh_d, true); + /* + * These K1 values depend on the Headphone Impedance + * For now it is assumed to be 16 ohm + */ + snd_soc_update_bits(codec, AQT1000_CDC_CLSH_K1_MSB, + 0x0F, 0x00); + snd_soc_update_bits(codec, AQT1000_CDC_CLSH_K1_LSB, + 0xFF, 0xC0); + snd_soc_update_bits(codec, + AQT1000_CDC_RX2_RX_PATH_CFG0, + 0x40, 0x40); + } + aqt_clsh_set_buck_regulator_mode(codec, mode); + aqt_clsh_set_flyback_mode(codec, mode); + aqt_clsh_gm3_boost_disable(codec, mode); + aqt_clsh_flyback_dac_ctl(codec, VREF_N0P9V); + aqt_clsh_mode_vref_ctl(codec, I2C); + aqt_clsh_force_iq_ctl(codec, mode); + aqt_clsh_rdac_hd2_ctl(codec, P82_0P77, req_state); + aqt_clsh_flyback_ctrl(codec, clsh_d, mode, true); + aqt_clsh_flyback_dac_ctl(codec, VREF_N1P827V); + aqt_clsh_set_buck_mode(codec, mode); + aqt_clsh_buck_ctrl(codec, clsh_d, mode, true); + aqt_clsh_mode_vref_ctl(codec, CONTROLLER); + aqt_clsh_buck_current_bias_ctl(codec, true); + aqt_clsh_set_hph_mode(codec, mode); + } else { + aqt_clsh_set_hph_mode(codec, CLS_H_NORMAL); + aqt_clsh_buck_current_bias_ctl(codec, false); + + if (mode != CLS_AB && mode != CLS_AB_HIFI) { + snd_soc_update_bits(codec, + AQT1000_CDC_RX2_RX_PATH_CFG0, + 0x40, 0x00); + aqt_enable_clsh_block(codec, clsh_d, false); + } + /* buck and flyback set to default mode and disable */ + aqt_clsh_buck_ctrl(codec, clsh_d, CLS_H_NORMAL, false); + aqt_clsh_flyback_ctrl(codec, clsh_d, CLS_H_NORMAL, false); + aqt_clsh_rdac_hd2_ctl(codec, P5_0P35, req_state); + aqt_clsh_force_iq_ctl(codec, CLS_H_NORMAL); + aqt_clsh_gm3_boost_disable(codec, CLS_H_NORMAL); + aqt_clsh_set_flyback_mode(codec, CLS_H_NORMAL); + aqt_clsh_set_buck_mode(codec, CLS_H_NORMAL); + aqt_clsh_set_buck_regulator_mode(codec, CLS_H_NORMAL); + } +} + +static void aqt_clsh_state_hph_l(struct snd_soc_codec *codec, + struct aqt_clsh_cdc_data *clsh_d, + u8 req_state, bool is_enable, int mode) +{ + dev_dbg(codec->dev, "%s: mode: %s, %s\n", __func__, mode_to_str(mode), + is_enable ? "enable" : "disable"); + + if (mode == CLS_H_NORMAL) { + dev_err(codec->dev, "%s: Normal mode not applicable for hph_l\n", + __func__); + return; + } + + if (is_enable) { + if (mode != CLS_AB && mode != CLS_AB_HIFI) { + aqt_enable_clsh_block(codec, clsh_d, true); + /* + * These K1 values depend on the Headphone Impedance + * For now it is assumed to be 16 ohm + */ + snd_soc_update_bits(codec, AQT1000_CDC_CLSH_K1_MSB, + 0x0F, 0x00); + snd_soc_update_bits(codec, AQT1000_CDC_CLSH_K1_LSB, + 0xFF, 0xC0); + snd_soc_update_bits(codec, + AQT1000_CDC_RX1_RX_PATH_CFG0, + 0x40, 0x40); + } + aqt_clsh_set_buck_regulator_mode(codec, mode); + aqt_clsh_set_flyback_mode(codec, mode); + aqt_clsh_gm3_boost_disable(codec, mode); + aqt_clsh_flyback_dac_ctl(codec, VREF_N0P9V); + aqt_clsh_mode_vref_ctl(codec, I2C); + aqt_clsh_force_iq_ctl(codec, mode); + aqt_clsh_rdac_hd2_ctl(codec, P82_0P77, req_state); + aqt_clsh_flyback_ctrl(codec, clsh_d, mode, true); + aqt_clsh_flyback_dac_ctl(codec, VREF_N1P827V); + aqt_clsh_set_buck_mode(codec, mode); + aqt_clsh_buck_ctrl(codec, clsh_d, mode, true); + aqt_clsh_mode_vref_ctl(codec, CONTROLLER); + aqt_clsh_buck_current_bias_ctl(codec, true); + aqt_clsh_set_hph_mode(codec, mode); + } else { + aqt_clsh_set_hph_mode(codec, CLS_H_NORMAL); + aqt_clsh_buck_current_bias_ctl(codec, false); + + if (mode != CLS_AB && mode != CLS_AB_HIFI) { + snd_soc_update_bits(codec, + AQT1000_CDC_RX1_RX_PATH_CFG0, + 0x40, 0x00); + aqt_enable_clsh_block(codec, clsh_d, false); + } + /* set buck and flyback to Default Mode */ + aqt_clsh_buck_ctrl(codec, clsh_d, CLS_H_NORMAL, false); + aqt_clsh_flyback_ctrl(codec, clsh_d, CLS_H_NORMAL, false); + aqt_clsh_rdac_hd2_ctl(codec, P5_0P35, req_state); + aqt_clsh_force_iq_ctl(codec, CLS_H_NORMAL); + aqt_clsh_gm3_boost_disable(codec, CLS_H_NORMAL); + aqt_clsh_set_flyback_mode(codec, CLS_H_NORMAL); + aqt_clsh_set_buck_mode(codec, CLS_H_NORMAL); + aqt_clsh_set_buck_regulator_mode(codec, CLS_H_NORMAL); + } +} + +static void aqt_clsh_state_err(struct snd_soc_codec *codec, + struct aqt_clsh_cdc_data *clsh_d, + u8 req_state, bool is_enable, int mode) +{ + dev_err(codec->dev, + "%s Wrong request for class H state machine requested to %s %s", + __func__, is_enable ? "enable" : "disable", + state_to_str[req_state]); +} + +/* + * Function: aqt_clsh_is_state_valid + * Params: state + * Description: + * Provides information on valid states of Class H configuration + */ +static bool aqt_clsh_is_state_valid(u8 state) +{ + switch (state) { + case AQT_CLSH_STATE_IDLE: + case AQT_CLSH_STATE_HPHL: + case AQT_CLSH_STATE_HPHR: + case AQT_CLSH_STATE_HPH_ST: + return true; + default: + return false; + }; +} + +/* + * Function: aqt_clsh_fsm + * Params: codec, cdc_clsh_d, req_state, req_type, clsh_event + * Description: + * This function handles PRE DAC and POST DAC conditions of different devices + * and updates class H configuration of different combination of devices + * based on validity of their states. cdc_clsh_d will contain current + * class h state information + */ +void aqt_clsh_fsm(struct snd_soc_codec *codec, + struct aqt_clsh_cdc_data *cdc_clsh_d, + u8 clsh_event, u8 req_state, + int int_mode) +{ + u8 old_state, new_state; + + switch (clsh_event) { + case AQT_CLSH_EVENT_PRE_DAC: + old_state = cdc_clsh_d->state; + new_state = old_state | req_state; + + if (!aqt_clsh_is_state_valid(new_state)) { + dev_err(codec->dev, + "%s: Class-H not a valid new state: %s\n", + __func__, state_to_str[new_state]); + return; + } + if (new_state == old_state) { + dev_err(codec->dev, + "%s: Class-H already in requested state: %s\n", + __func__, state_to_str[new_state]); + return; + } + cdc_clsh_d->state = new_state; + aqt_clsh_set_int_mode(cdc_clsh_d, req_state, int_mode); + (*clsh_state_fp[new_state]) (codec, cdc_clsh_d, req_state, + CLSH_REQ_ENABLE, int_mode); + dev_dbg(codec->dev, + "%s: ClassH state transition from %s to %s\n", + __func__, state_to_str[old_state], + state_to_str[cdc_clsh_d->state]); + break; + case AQT_CLSH_EVENT_POST_PA: + old_state = cdc_clsh_d->state; + new_state = old_state & (~req_state); + if (new_state < NUM_CLSH_STATES) { + if (!aqt_clsh_is_state_valid(old_state)) { + dev_err(codec->dev, + "%s:Invalid old state:%s\n", + __func__, state_to_str[old_state]); + return; + } + if (new_state == old_state) { + dev_err(codec->dev, + "%s: Class-H already in requested state: %s\n", + __func__,state_to_str[new_state]); + return; + } + (*clsh_state_fp[old_state]) (codec, cdc_clsh_d, + req_state, CLSH_REQ_DISABLE, + int_mode); + cdc_clsh_d->state = new_state; + aqt_clsh_set_int_mode(cdc_clsh_d, req_state, CLS_NONE); + dev_dbg(codec->dev, "%s: ClassH state transition from %s to %s\n", + __func__, state_to_str[old_state], + state_to_str[cdc_clsh_d->state]); + } + break; + }; +} +EXPORT_SYMBOL(aqt_clsh_fsm); + +/* + * Function: aqt_clsh_get_clsh_state + * Params: clsh + * Description: + * This function returns the state of the class H controller + */ +int aqt_clsh_get_clsh_state(struct aqt_clsh_cdc_data *clsh) +{ + return clsh->state; +} +EXPORT_SYMBOL(aqt_clsh_get_clsh_state); + +/* + * Function: aqt_clsh_init + * Params: clsh + * Description: + * This function initializes the class H controller + */ +void aqt_clsh_init(struct aqt_clsh_cdc_data *clsh) +{ + int i; + + clsh->state = AQT_CLSH_STATE_IDLE; + + for (i = 0; i < NUM_CLSH_STATES; i++) + clsh_state_fp[i] = aqt_clsh_state_err; + + clsh_state_fp[AQT_CLSH_STATE_HPHL] = aqt_clsh_state_hph_l; + clsh_state_fp[AQT_CLSH_STATE_HPHR] = aqt_clsh_state_hph_r; + clsh_state_fp[AQT_CLSH_STATE_HPH_ST] = aqt_clsh_state_hph_st; + /* Set interpolator modes to NONE */ + aqt_clsh_set_int_mode(clsh, AQT_CLSH_STATE_HPHL, CLS_NONE); + aqt_clsh_set_int_mode(clsh, AQT_CLSH_STATE_HPHR, CLS_NONE); + clsh->flyback_users = 0; + clsh->buck_users = 0; + clsh->clsh_users = 0; +} +EXPORT_SYMBOL(aqt_clsh_init); diff --git a/asoc/codecs/aqt1000/aqt1000-clsh.h b/asoc/codecs/aqt1000/aqt1000-clsh.h new file mode 100644 index 0000000000..4a829b0c69 --- /dev/null +++ b/asoc/codecs/aqt1000/aqt1000-clsh.h @@ -0,0 +1,115 @@ +/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _AQT1000_CLSH_H +#define _AQT1000_CLSH_H + +#include +#include +#include +#include + +#define CLSH_REQ_ENABLE true +#define CLSH_REQ_DISABLE false + +#define AQT_CLSH_EVENT_PRE_DAC 0x01 +#define AQT_CLSH_EVENT_POST_PA 0x02 +/* + * Basic states for Class H state machine. + * represented as a bit mask within a u8 data type + * bit 0: HPH Left mode + * bit 1: HPH Right mode + */ +#define AQT_CLSH_STATE_IDLE 0x00 +#define AQT_CLSH_STATE_HPHL (0x01 << 0) +#define AQT_CLSH_STATE_HPHR (0x01 << 1) + +/* + * Though number of CLSH states are 2, max state shoulbe be 3 + * because state array index starts from 1. + */ +#define AQT_CLSH_STATE_MAX 3 +#define NUM_CLSH_STATES (0x01 << AQT_CLSH_STATE_MAX) + + +/* Derived State: Bits 1 and 2 should be set for Headphone stereo */ +#define AQT_CLSH_STATE_HPH_ST (AQT_CLSH_STATE_HPHL | \ + AQT_CLSH_STATE_HPHR) + +enum { + CLS_H_NORMAL = 0, /* Class-H Default */ + CLS_H_HIFI, /* Class-H HiFi */ + CLS_H_LP, /* Class-H Low Power */ + CLS_AB, /* Class-AB Low HIFI*/ + CLS_H_LOHIFI, /* LoHIFI */ + CLS_H_ULP, /* Ultra Low power */ + CLS_AB_HIFI, /* Class-AB */ + CLS_NONE, /* None of the above modes */ +}; + +enum { + DAC_GAIN_0DB = 0, + DAC_GAIN_0P2DB, + DAC_GAIN_0P4DB, + DAC_GAIN_0P6DB, + DAC_GAIN_0P8DB, + DAC_GAIN_M0P2DB, + DAC_GAIN_M0P4DB, + DAC_GAIN_M0P6DB, +}; + +enum { + VREF_FILT_R_0OHM = 0, + VREF_FILT_R_25KOHM, + VREF_FILT_R_50KOHM, + VREF_FILT_R_100KOHM, +}; + +enum { + DELTA_I_0MA, + DELTA_I_10MA, + DELTA_I_20MA, + DELTA_I_30MA, + DELTA_I_40MA, + DELTA_I_50MA, +}; + +struct aqt_imped_val { + u32 imped_val; + u8 index; +}; + +struct aqt_clsh_cdc_data { + u8 state; + int flyback_users; + int buck_users; + int clsh_users; + int interpolator_modes[AQT_CLSH_STATE_MAX]; +}; + +struct aqt_reg_mask_val { + u16 reg; + u8 mask; + u8 val; +}; + +extern void aqt_clsh_fsm(struct snd_soc_codec *codec, + struct aqt_clsh_cdc_data *cdc_clsh_d, + u8 clsh_event, u8 req_state, + int int_mode); + +extern void aqt_clsh_init(struct aqt_clsh_cdc_data *clsh); +extern int aqt_clsh_get_clsh_state(struct aqt_clsh_cdc_data *clsh); +extern void aqt_clsh_imped_config(struct snd_soc_codec *codec, int imped, + bool reset); + +#endif /* _AQT1000_CLSH_H */ diff --git a/asoc/codecs/aqt1000/aqt1000-core.c b/asoc/codecs/aqt1000/aqt1000-core.c new file mode 100644 index 0000000000..2306a2acfd --- /dev/null +++ b/asoc/codecs/aqt1000/aqt1000-core.c @@ -0,0 +1,589 @@ +/* Copyright (c) 2011-2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../msm-cdc-pinctrl.h" +#include "../msm-cdc-supply.h" +#include "aqt1000-registers.h" +#include "aqt1000-internal.h" +#include "aqt1000.h" +#include "aqt1000-utils.h" + +static int aqt1000_bringup(struct aqt1000 *aqt) +{ + struct aqt1000_pdata *pdata; + u8 clk_div = 0, mclk = 1; + + if (!aqt->regmap) { + dev_err(aqt->dev, "%s: aqt regmap is NULL\n", __func__); + return -EINVAL; + } + + /* Bringup register write sequence */ + regmap_update_bits(aqt->regmap, AQT1000_BUCK_5V_CTRL_CCL_1, 0xF0, 0xF0); + regmap_update_bits(aqt->regmap, AQT1000_BIAS_CCOMP_FINE_ADJ, + 0xF0, 0x90); + regmap_update_bits(aqt->regmap, AQT1000_ANA_BIAS, 0x80, 0x80); + regmap_update_bits(aqt->regmap, AQT1000_ANA_BIAS, 0x40, 0x40); + + /* Added 1msec sleep as per HW requirement */ + usleep_range(1000, 1010); + + regmap_update_bits(aqt->regmap, AQT1000_ANA_BIAS, 0x40, 0x00); + + clk_div = 0x04; /* Assumption is CLK DIV 2 */ + pdata = dev_get_platdata(aqt->dev); + if (pdata) { + if (pdata->mclk_rate == AQT1000_CLK_12P288MHZ) + mclk = 0; + clk_div = (((pdata->ext_clk_rate / pdata->mclk_rate) >> 1) + << 2); + } + regmap_update_bits(aqt->regmap, AQT1000_CHIP_CFG0_CLK_CFG_MCLK, + 0x03, mclk); + + regmap_update_bits(aqt->regmap, AQT1000_CLK_SYS_MCLK1_PRG, + 0x0C, clk_div); + + /* Source clock enable */ + regmap_update_bits(aqt->regmap, AQT1000_CLK_SYS_MCLK1_PRG, 0x02, 0x02); + + /* Ungate the source clock */ + regmap_update_bits(aqt->regmap, AQT1000_CLK_SYS_MCLK1_PRG, 0x10, 0x10); + + /* Set the I2S_HS_CLK reference to CLK DIV 2 */ + regmap_update_bits(aqt->regmap, AQT1000_CLK_SYS_MCLK2_I2S_HS_CLK_PRG, + 0x60, 0x20); + + /* Set the PLL preset to CLK9P6M_IN_12P288M_OUT */ + regmap_update_bits(aqt->regmap, AQT1000_CLK_SYS_PLL_PRESET, 0x0F, 0x02); + + /* Enable clock PLL */ + regmap_update_bits(aqt->regmap, AQT1000_CLK_SYS_PLL_ENABLES, + 0x01, 0x01); + + /* Add 100usec delay as per HW requirement */ + usleep_range(100, 110); + + /* Set AQT to I2S Master */ + regmap_update_bits(aqt->regmap, AQT1000_I2S_I2S_0_CTL, 0x02, 0x02); + + /* Enable I2S HS clock */ + regmap_update_bits(aqt->regmap, AQT1000_CLK_SYS_MCLK2_I2S_HS_CLK_PRG, + 0x01, 0x01); + + /* Codec digital reset */ + regmap_update_bits(aqt->regmap, AQT1000_CHIP_CFG0_RST_CTL, 0x01, 0x01); + + return 0; +} + +static int aqt1000_device_init(struct aqt1000 *aqt) +{ + int ret = 0; + + mutex_init(&aqt->io_lock); + mutex_init(&aqt->xfer_lock); + mutex_init(&aqt->cdc_bg_clk_lock); + mutex_init(&aqt->master_bias_lock); + + ret = aqt1000_bringup(aqt); + if (ret) { + ret = -EPROBE_DEFER; + goto done; + } + +done: + mutex_destroy(&aqt->io_lock); + mutex_destroy(&aqt->xfer_lock); + mutex_destroy(&aqt->cdc_bg_clk_lock); + mutex_destroy(&aqt->master_bias_lock); + return ret; +} + +static int aqt1000_i2c_write(struct aqt1000 *aqt1000, unsigned short reg, + void *val, int bytes) +{ + struct i2c_msg *msg; + int ret = 0; + u8 reg_addr = 0; + u8 data[bytes + 1]; + struct aqt1000_i2c *aqt1000_i2c; + u8 *value = (u8 *)val; + + aqt1000_i2c = &aqt1000->i2c_dev; + if (aqt1000_i2c == NULL || aqt1000_i2c->client == NULL) { + pr_err("%s: Failed to get device info\n", __func__); + return -ENODEV; + } + reg_addr = (u8)reg; + msg = &aqt1000_i2c->xfer_msg[0]; + msg->addr = aqt1000_i2c->client->addr; + msg->len = bytes + 1; + msg->flags = 0; + data[0] = reg; + data[1] = *value; + msg->buf = data; + ret = i2c_transfer(aqt1000_i2c->client->adapter, + aqt1000_i2c->xfer_msg, 1); + /* Try again if the write fails */ + if (ret != 1) { + ret = i2c_transfer(aqt1000_i2c->client->adapter, + aqt1000_i2c->xfer_msg, 1); + if (ret != 1) { + dev_err(aqt1000->dev, + "%s: I2C write failed, reg: 0x%x ret: %d\n", + __func__, reg, ret); + return ret; + } + } + dev_dbg(aqt1000->dev, "%s: write success register = %x val = %x\n", + __func__, reg, data[1]); + return 0; +} + +static int aqt1000_i2c_read(struct aqt1000 *aqt1000, unsigned short reg, + void *dst, int bytes) +{ + struct i2c_msg *msg; + int ret = 0; + u8 reg_addr = 0; + struct aqt1000_i2c *aqt1000_i2c; + u8 i = 0; + unsigned char *dest = (unsigned char *)dst; + + aqt1000_i2c = &aqt1000->i2c_dev; + if (aqt1000_i2c == NULL || aqt1000_i2c->client == NULL) { + pr_err("%s: Failed to get device info\n", __func__); + return -ENODEV; + } + for (i = 0; i < bytes; i++) { + reg_addr = (u8)reg++; + msg = &aqt1000_i2c->xfer_msg[0]; + msg->addr = aqt1000_i2c->client->addr; + msg->len = 1; + msg->flags = 0; + msg->buf = ®_addr; + + msg = &aqt1000_i2c->xfer_msg[1]; + msg->addr = aqt1000_i2c->client->addr; + msg->len = 1; + msg->flags = I2C_M_RD; + msg->buf = dest++; + ret = i2c_transfer(aqt1000_i2c->client->adapter, + aqt1000_i2c->xfer_msg, 2); + + /* Try again if read fails first time */ + if (ret != 2) { + ret = i2c_transfer(aqt1000_i2c->client->adapter, + aqt1000_i2c->xfer_msg, 2); + if (ret != 2) { + dev_err(aqt1000->dev, + "%s: I2C read failed, reg: 0x%x\n", + __func__, reg); + return ret; + } + } + } + return 0; +} + +static int aqt1000_reset(struct device *dev) +{ + struct aqt1000 *aqt1000; + int rc = 0; + + if (!dev) + return -ENODEV; + + aqt1000 = dev_get_drvdata(dev); + if (!aqt1000) + return -EINVAL; + + if (!aqt1000->aqt_rst_np) { + dev_err(dev, "%s: reset gpio device node not specified\n", + __func__); + return -EINVAL; + } + + if (!msm_cdc_pinctrl_get_state(aqt1000->aqt_rst_np)) { + rc = msm_cdc_pinctrl_select_sleep_state(aqt1000->aqt_rst_np); + if (rc) { + dev_err(dev, "%s: aqt sleep state request fail!\n", + __func__); + return rc; + } + + /* 20ms sleep required after pulling the reset gpio to LOW */ + msleep(20); + + rc = msm_cdc_pinctrl_select_active_state(aqt1000->aqt_rst_np); + if (rc) { + dev_err(dev, + "%s: aqt active state request fail, ret: %d\n", + __func__, rc); + return rc; + } + /* 20ms sleep required after pulling the reset gpio to HIGH */ + msleep(20); + } + + return rc; +} + +static int aqt1000_read_of_property_u32(struct device *dev, const char *name, + u32 *val) +{ + int rc = 0; + + rc = of_property_read_u32(dev->of_node, name, val); + if (rc) + dev_err(dev, "%s: Looking up %s property in node %s failed", + __func__, name, dev->of_node->full_name); + + return rc; +} + +static void aqt1000_dt_parse_micbias_info(struct device *dev, + struct aqt1000_micbias_setting *mb) +{ + u32 prop_val; + int rc; + + if (of_find_property(dev->of_node, "qcom,cdc-micbias-ldoh-v", NULL)) { + rc = aqt1000_read_of_property_u32(dev, + "qcom,cdc-micbias-ldoh-v", + &prop_val); + if (!rc) + mb->ldoh_v = (u8)prop_val; + } + + /* MB1 */ + if (of_find_property(dev->of_node, "qcom,cdc-micbias-cfilt1-mv", + NULL)) { + rc = aqt1000_read_of_property_u32(dev, + "qcom,cdc-micbias-cfilt1-mv", + &prop_val); + if (!rc) + mb->cfilt1_mv = prop_val; + + rc = aqt1000_read_of_property_u32(dev, + "qcom,cdc-micbias1-cfilt-sel", + &prop_val); + if (!rc) + mb->bias1_cfilt_sel = (u8)prop_val; + + } else if (of_find_property(dev->of_node, "qcom,cdc-micbias1-mv", + NULL)) { + rc = aqt1000_read_of_property_u32(dev, + "qcom,cdc-micbias1-mv", + &prop_val); + if (!rc) + mb->micb1_mv = prop_val; + } else { + dev_info(dev, "%s: Micbias1 DT property not found\n", + __func__); + } + + /* Print micbias info */ + dev_dbg(dev, "%s: ldoh_v %u cfilt1_mv %u micb1_mv %u \n", __func__, + (u32)mb->ldoh_v, (u32)mb->cfilt1_mv, (u32)mb->micb1_mv); +} + +static struct aqt1000_pdata *aqt1000_populate_dt_data(struct device *dev) +{ + struct aqt1000_pdata *pdata; + u32 prop_val; + + if (!dev || !dev->of_node) + return NULL; + + pdata = devm_kzalloc(dev, sizeof(struct aqt1000_pdata), + GFP_KERNEL); + if (!pdata) + return NULL; + + /* Parse power supplies */ + msm_cdc_get_power_supplies(dev, &pdata->regulator, + &pdata->num_supplies); + if (!pdata->regulator || (pdata->num_supplies <= 0)) { + dev_err(dev, "%s: no power supplies defined for codec\n", + __func__); + goto err_power_sup; + } + + /* Parse micbias info */ + aqt1000_dt_parse_micbias_info(dev, &pdata->micbias); + + pdata->aqt_rst_np = of_parse_phandle(dev->of_node, + "qcom,aqt-rst-gpio-node", 0); + if (!pdata->aqt_rst_np) { + dev_err(dev, "%s: Looking up %s property in node %s failed\n", + __func__, "qcom,aqt-rst-gpio-node", + dev->of_node->full_name); + goto err_parse_dt_prop; + } + + if (!(aqt1000_read_of_property_u32(dev, "qcom,cdc-ext-clk-rate", + &prop_val))) + pdata->ext_clk_rate = prop_val; + if (pdata->ext_clk_rate != AQT1000_CLK_24P576MHZ && + pdata->ext_clk_rate != AQT1000_CLK_19P2MHZ && + pdata->ext_clk_rate != AQT1000_CLK_12P288MHZ) { + /* Use the default ext_clk_rate if the DT value is wrong */ + pdata->ext_clk_rate = AQT1000_CLK_9P6MHZ; + } + + prop_val = 0; + if (!(aqt1000_read_of_property_u32(dev, "qcom,cdc-mclk-clk-rate", + &prop_val))) + pdata->mclk_rate = prop_val; + + if (pdata->mclk_rate != AQT1000_CLK_9P6MHZ && + pdata->mclk_rate != AQT1000_CLK_12P288MHZ) { + dev_err(dev, "%s: Invalid mclk_rate = %u\n", __func__, + pdata->mclk_rate); + goto err_parse_dt_prop; + } + if (pdata->ext_clk_rate % pdata->mclk_rate) { + dev_err(dev, + "%s: Invalid clock group, ext_clk = %d mclk = %d\n", + __func__, pdata->ext_clk_rate, pdata->mclk_rate); + goto err_parse_dt_prop; + } + + return pdata; + +err_parse_dt_prop: + devm_kfree(dev, pdata->regulator); + pdata->regulator = NULL; + pdata->num_supplies = 0; +err_power_sup: + devm_kfree(dev, pdata); + return NULL; +} + +static int aqt1000_bringdown(struct device *dev) +{ + /* No sequence for teardown */ + + return 0; +} + +static void aqt1000_device_exit(struct aqt1000 *aqt) +{ + aqt1000_bringdown(aqt->dev); + mutex_destroy(&aqt->io_lock); + mutex_destroy(&aqt->xfer_lock); + mutex_destroy(&aqt->cdc_bg_clk_lock); + mutex_destroy(&aqt->master_bias_lock); +} + +static int aqt1000_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct aqt1000 *aqt1000 = NULL; + struct aqt1000_pdata *pdata = NULL; + int ret = 0; + + pdata = aqt1000_populate_dt_data(&client->dev); + if (!pdata) { + dev_err(&client->dev, + "%s: Fail to obtain pdata from device tree\n", + __func__); + ret = -EINVAL; + goto fail; + } + client->dev.platform_data = pdata; + + aqt1000 = devm_kzalloc(&client->dev, sizeof(struct aqt1000), + GFP_KERNEL); + if (!aqt1000) { + ret = -ENOMEM; + goto fail; + } + + aqt1000->regmap = aqt1000_regmap_init(&client->dev, + &aqt1000_regmap_config); + if (IS_ERR(aqt1000->regmap)) { + ret = PTR_ERR(aqt1000->regmap); + dev_err(&client->dev, + "%s: Failed to init register map: %d\n", + __func__, ret); + goto fail; + } + aqt1000->aqt_rst_np = pdata->aqt_rst_np; + if (!aqt1000->aqt_rst_np) { + dev_err(&client->dev, "%s: pinctrl not used for rst_n\n", + __func__); + ret = -EINVAL; + goto fail; + } + + if (i2c_check_functionality(client->adapter, + I2C_FUNC_I2C) == 0) { + dev_dbg(&client->dev, "%s: can't talk I2C?\n", __func__); + ret = -EIO; + goto fail; + } + dev_set_drvdata(&client->dev, aqt1000); + aqt1000->dev = &client->dev; + aqt1000->dev_up = true; + aqt1000->mclk_rate = pdata->mclk_rate; + + aqt1000->num_of_supplies = pdata->num_supplies; + ret = msm_cdc_init_supplies(aqt1000->dev, &aqt1000->supplies, + pdata->regulator, + pdata->num_supplies); + if (!aqt1000->supplies) { + dev_err(aqt1000->dev, "%s: Cannot init aqt supplies\n", + __func__); + goto err_codec; + } + ret = msm_cdc_enable_static_supplies(aqt1000->dev, + aqt1000->supplies, + pdata->regulator, + pdata->num_supplies); + if (ret) { + dev_err(aqt1000->dev, "%s: aqt static supply enable failed!\n", + __func__); + goto err_codec; + } + /* 5 usec sleep is needed as per HW requirement */ + usleep_range(5, 10); + + ret = aqt1000_reset(aqt1000->dev); + if (ret) { + dev_err(aqt1000->dev, "%s: Codec reset failed\n", __func__); + goto err_supplies; + } + + aqt1000->i2c_dev.client = client; + aqt1000->read_dev = aqt1000_i2c_read; + aqt1000->write_dev = aqt1000_i2c_write; + + ret = aqt1000_device_init(aqt1000); + if (ret) { + pr_err("%s: error, initializing device failed (%d)\n", + __func__, ret); + goto err_supplies; + } + + ret = aqt_register_codec(&client->dev); + if (ret) { + dev_err(aqt1000->dev, "%s: Codec registration failed\n", + __func__); + goto err_cdc_register; + } + + return ret; + +err_cdc_register: + aqt1000_device_exit(aqt1000); +err_supplies: + msm_cdc_release_supplies(aqt1000->dev, aqt1000->supplies, + pdata->regulator, + pdata->num_supplies); + pdata->regulator = NULL; + pdata->num_supplies = 0; +err_codec: + devm_kfree(&client->dev, aqt1000); + dev_set_drvdata(&client->dev, NULL); +fail: + return ret; +} + +static int aqt1000_i2c_remove(struct i2c_client *client) +{ + struct aqt1000 *aqt; + struct aqt1000_pdata *pdata = client->dev.platform_data; + + aqt = dev_get_drvdata(&client->dev); + + msm_cdc_release_supplies(aqt->dev, aqt->supplies, + pdata->regulator, + pdata->num_supplies); + aqt1000_device_exit(aqt); + dev_set_drvdata(&client->dev, NULL); + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int aqt1000_i2c_resume(struct device *dev) +{ + pr_debug("%s system resume\n", __func__); + return 0; +} + +static int aqt1000_i2c_suspend(struct device *dev) +{ + pr_debug("%s system suspend\n", __func__); + return 0; +} +#endif + +static struct i2c_device_id aqt1000_id_table[] = { + {"aqt1000-i2c", 0}, + {} +}; +MODULE_DEVICE_TABLE(i2c, aqt1000_id_table); + +static const struct dev_pm_ops aqt1000_i2c_pm_ops = { + .suspend = aqt1000_i2c_suspend, + .resume = aqt1000_i2c_resume, +}; + +static const struct of_device_id aqt_match_table[] = { + {.compatible = "qcom,aqt1000-i2c-codec"}, + {} +}; +MODULE_DEVICE_TABLE(of, aqt_match_table); + +static struct i2c_driver aqt1000_i2c_driver = { + .driver = { + .owner = THIS_MODULE, + .name = "aqt1000-i2c-codec", +#ifdef CONFIG_PM_SLEEP + .pm = &aqt1000_i2c_pm_ops, +#endif + .of_match_table = aqt_match_table, + }, + .id_table = aqt1000_id_table, + .probe = aqt1000_i2c_probe, + .remove = aqt1000_i2c_remove, +}; + +static int __init aqt1000_init(void) +{ + return i2c_add_driver(&aqt1000_i2c_driver); +} +module_init(aqt1000_init); + +static void __exit aqt1000_exit(void) +{ + i2c_del_driver(&aqt1000_i2c_driver); +} +module_exit(aqt1000_exit); + +MODULE_DESCRIPTION("AQT1000 Codec driver"); +MODULE_LICENSE("GPL v2"); diff --git a/asoc/codecs/aqt1000/aqt1000-internal.h b/asoc/codecs/aqt1000/aqt1000-internal.h new file mode 100644 index 0000000000..1ce0005fc6 --- /dev/null +++ b/asoc/codecs/aqt1000/aqt1000-internal.h @@ -0,0 +1,181 @@ +/* Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _AQT1000_INTERNAL_H +#define _AQT1000_INTERNAL_H + +#include +#include +#include + +#define AQT1000_RATES_MASK (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\ + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000 |\ + SNDRV_PCM_RATE_384000) +/* Fractional Rates */ +#define AQT1000_FRAC_RATES_MASK (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_88200 |\ + SNDRV_PCM_RATE_176400) + +#define AQT1000_FORMATS_S16_S24_LE (SNDRV_PCM_FMTBIT_S16_LE | \ + SNDRV_PCM_FMTBIT_S24_LE) + +#define AQT1000_FORMATS_S16_S24_S32_LE (SNDRV_PCM_FMTBIT_S16_LE | \ + SNDRV_PCM_FMTBIT_S24_LE | \ + SNDRV_PCM_FMTBIT_S32_LE) + +#define AQT1000_FORMATS_S16_LE (SNDRV_PCM_FMTBIT_S16_LE) + +/* Macros for packing register writes into a U32 */ +#define AQT1000_PACKED_REG_SIZE sizeof(u32) +#define AQT1000_CODEC_UNPACK_ENTRY(packed, reg, mask, val) \ + do { \ + ((reg) = ((packed >> 16) & (0xffff))); \ + ((mask) = ((packed >> 8) & (0xff))); \ + ((val) = ((packed) & (0xff))); \ + } while (0) + +#define STRING(name) #name +#define AQT_DAPM_ENUM(name, reg, offset, text) \ +static SOC_ENUM_SINGLE_DECL(name##_enum, reg, offset, text); \ +static const struct snd_kcontrol_new name##_mux = \ + SOC_DAPM_ENUM(STRING(name), name##_enum) + +#define AQT_DAPM_ENUM_EXT(name, reg, offset, text, getname, putname) \ +static SOC_ENUM_SINGLE_DECL(name##_enum, reg, offset, text); \ +static const struct snd_kcontrol_new name##_mux = \ + SOC_DAPM_ENUM_EXT(STRING(name), name##_enum, getname, putname) + +#define AQT_DAPM_MUX(name, shift, kctl) \ + SND_SOC_DAPM_MUX(name, SND_SOC_NOPM, shift, 0, &kctl##_mux) + + +#define AQT1000_INTERP_MUX_NUM_INPUTS 3 +#define AQT1000_RX_PATH_CTL_OFFSET 20 + +#define BYTE_BIT_MASK(nr) (1 << ((nr) % BITS_PER_BYTE)) + +#define AQT1000_REG_BITS 8 +#define AQT1000_MAX_VALID_ADC_MUX 3 + +#define AQT1000_AMIC_PWR_LEVEL_LP 0 +#define AQT1000_AMIC_PWR_LEVEL_DEFAULT 1 +#define AQT1000_AMIC_PWR_LEVEL_HP 2 +#define AQT1000_AMIC_PWR_LVL_MASK 0x60 +#define AQT1000_AMIC_PWR_LVL_SHIFT 0x5 + +#define AQT1000_DEC_PWR_LVL_MASK 0x06 +#define AQT1000_DEC_PWR_LVL_DF 0x00 +#define AQT1000_DEC_PWR_LVL_LP 0x02 +#define AQT1000_DEC_PWR_LVL_HP 0x04 +#define AQT1000_STRING_LEN 100 + +#define AQT1000_CDC_SIDETONE_IIR_COEFF_MAX 5 + +#define AQT1000_MAX_MICBIAS 1 +#define DAPM_MICBIAS1_STANDALONE "MIC BIAS1 Standalone" + +#define TX_HPF_CUT_OFF_FREQ_MASK 0x60 +#define CF_MIN_3DB_4HZ 0x0 +#define CF_MIN_3DB_75HZ 0x1 +#define CF_MIN_3DB_150HZ 0x2 + +enum { + AUDIO_NOMINAL, + HPH_PA_DELAY, + CLSH_Z_CONFIG, + ANC_MIC_AMIC1, + ANC_MIC_AMIC2, + ANC_MIC_AMIC3, +}; + +enum { + MIC_BIAS_1 = 1, +}; + +enum { + MICB_PULLUP_ENABLE, + MICB_PULLUP_DISABLE, + MICB_ENABLE, + MICB_DISABLE, +}; + +enum { + INTn_1_INP_SEL_ZERO = 0, + INTn_1_INP_SEL_DEC0, + INTn_1_INP_SEL_DEC1, + INTn_1_INP_SEL_IIR0, + INTn_1_INP_SEL_IIR1, + INTn_1_INP_SEL_RX0, + INTn_1_INP_SEL_RX1, +}; + +enum { + INTn_2_INP_SEL_ZERO = 0, + INTn_2_INP_SEL_RX0, + INTn_2_INP_SEL_RX1, + INTn_2_INP_SEL_PROXIMITY, +}; + +/* Codec supports 2 IIR filters */ +enum { + IIR0 = 0, + IIR1, + IIR_MAX, +}; + +enum { + ASRC_IN_HPHL, + ASRC_IN_HPHR, + ASRC_INVALID, +}; + +enum { + CONV_88P2K_TO_384K, + CONV_96K_TO_352P8K, + CONV_352P8K_TO_384K, + CONV_384K_TO_352P8K, + CONV_384K_TO_384K, + CONV_96K_TO_384K, +}; + +enum aqt_notify_event { + AQT_EVENT_INVALID, + /* events for micbias ON and OFF */ + AQT_EVENT_PRE_MICBIAS_1_OFF, + AQT_EVENT_POST_MICBIAS_1_OFF, + AQT_EVENT_PRE_MICBIAS_1_ON, + AQT_EVENT_POST_MICBIAS_1_ON, + AQT_EVENT_PRE_DAPM_MICBIAS_1_OFF, + AQT_EVENT_POST_DAPM_MICBIAS_1_OFF, + AQT_EVENT_PRE_DAPM_MICBIAS_1_ON, + AQT_EVENT_POST_DAPM_MICBIAS_1_ON, + /* events for PA ON and OFF */ + AQT_EVENT_PRE_HPHL_PA_ON, + AQT_EVENT_POST_HPHL_PA_OFF, + AQT_EVENT_PRE_HPHR_PA_ON, + AQT_EVENT_POST_HPHR_PA_OFF, + AQT_EVENT_PRE_HPHL_PA_OFF, + AQT_EVENT_PRE_HPHR_PA_OFF, + AQT_EVENT_OCP_OFF, + AQT_EVENT_OCP_ON, + AQT_EVENT_LAST, +}; + +struct interp_sample_rate { + int sample_rate; + int rate_val; +}; + +extern struct regmap_config aqt1000_regmap_config; +extern int aqt_register_codec(struct device *dev); + +#endif /* _AQT1000_INTERNAL_H */ diff --git a/asoc/codecs/aqt1000/aqt1000-irq.c b/asoc/codecs/aqt1000/aqt1000-irq.c new file mode 100644 index 0000000000..e01dc46023 --- /dev/null +++ b/asoc/codecs/aqt1000/aqt1000-irq.c @@ -0,0 +1,185 @@ +/* Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "aqt1000-registers.h" +#include "aqt1000-irq.h" + + +static int aqt_irq_init(struct aqt1000_irq *aqt_irq) +{ + int i, ret; + + if (aqt_irq == NULL) { + pr_err("%s: aqt_irq is NULL\n", __func__); + return -EINVAL; + } + mutex_init(&aqt_irq->irq_lock); + mutex_init(&aqt_irq->nested_irq_lock); + + aqt_irq->irq = aqt_irq_get_upstream_irq(aqt_irq); + if (!aqt_irq->irq) { + pr_warn("%s: irq driver is not yet initialized\n", __func__); + mutex_destroy(&aqt_irq->irq_lock); + mutex_destroy(&aqt_irq->nested_irq_lock); + return -EPROBE_DEFER; + } + pr_debug("%s: probed irq %d\n", __func__, aqt_irq->irq); + + /* Setup downstream IRQs */ + ret = aqt_irq_setup_downstream_irq(aqt_irq); + if (ret) { + pr_err("%s: Failed to setup downstream IRQ\n", __func__); + goto fail_irq_init; + } + + /* mask all the interrupts */ + for (i = 0; i < aqt_irq->num_irqs; i++) { + aqt_irq->irq_masks_cur |= BYTE_BIT_MASK(i); + aqt_irq->irq_masks_cache |= BYTE_BIT_MASK(i); + } + + ret = request_threaded_irq(aqt_irq->irq, NULL, aqt_irq_thread, + IRQF_TRIGGER_HIGH | IRQF_ONESHOT, + "aqt", aqt_irq); + if (ret != 0) { + dev_err(aqt_irq->dev, "Failed to request IRQ %d: %d\n", + aqt_irq->irq, ret); + } else { + ret = enable_irq_wake(aqt_irq->irq); + if (ret) { + dev_err(aqt_irq->dev, + "Failed to set wake interrupt on IRQ %d: %d\n", + aqt_irq->irq, ret); + free_irq(aqt_irq->irq, aqt_irq); + } + } + + if (ret) + goto fail_irq_init; + + return ret; + +fail_irq_init: + dev_err(aqt_irq->dev, + "%s: Failed to init aqt irq\n", __func__); + aqt_irq_put_upstream_irq(aqt_irq); + mutex_destroy(&aqt_irq->irq_lock); + mutex_destroy(&aqt_irq->nested_irq_lock); + return ret; +} + +static int aqt_irq_probe(struct platform_device *pdev) +{ + int irq; + struct aqt1000_irq *aqt_irq = NULL; + int ret = -EINVAL; + + irq = platform_get_irq_byname(pdev, "aqt-int"); + if (irq < 0) { + dev_err(&pdev->dev, "%s: Couldn't find aqt-int node(%d)\n", + __func__, irq); + return -EINVAL; + } + aqt_irq = kzalloc(sizeof(*aqt_irq), GFP_KERNEL); + if (!aqt_irq) + return -ENOMEM; + /* + * AQT interrupt controller supports N to N irq mapping with + * single cell binding with irq numbers(offsets) only. + * Use irq_domain_simple_ops that has irq_domain_simple_map and + * irq_domain_xlate_onetwocell. + */ + aqt_irq->dev = &pdev->dev; + aqt_irq->domain = irq_domain_add_linear(aqt_irq->dev->of_node, + WSA_NUM_IRQS, &irq_domain_simple_ops, + aqt_irq); + if (!aqt_irq->domain) { + dev_err(&pdev->dev, "%s: domain is NULL\n", __func__); + ret = -ENOMEM; + goto err; + } + aqt_irq->dev = &pdev->dev; + + dev_dbg(&pdev->dev, "%s: virq = %d\n", __func__, irq); + aqt_irq->irq = irq; + aqt_irq->num_irq_regs = 2; + aqt_irq->num_irqs = WSA_NUM_IRQS; + ret = aqt_irq_init(aqt_irq); + if (ret < 0) { + dev_err(&pdev->dev, "%s: failed to do irq init %d\n", + __func__, ret); + goto err; + } + + return ret; +err: + kfree(aqt_irq); + return ret; +} + +static int aqt_irq_remove(struct platform_device *pdev) +{ + struct irq_domain *domain; + struct aqt1000_irq *data; + + domain = irq_find_host(pdev->dev.of_node); + if (unlikely(!domain)) { + pr_err("%s: domain is NULL\n", __func__); + return -EINVAL; + } + data = (struct aqt_irq *)domain->host_data; + data->irq = 0; + + return 0; +} + +static const struct of_device_id of_match[] = { + { .compatible = "qcom,aqt-irq" }, + { } +}; + +static struct platform_driver aqt_irq_driver = { + .probe = aqt_irq_probe, + .remove = aqt_irq_remove, + .driver = { + .name = "aqt_intc", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(of_match), + }, +}; + +static int aqt_irq_drv_init(void) +{ + return platform_driver_register(&aqt_irq_driver); +} +subsys_initcall(aqt_irq_drv_init); + +static void aqt_irq_drv_exit(void) +{ + platform_driver_unregister(&aqt_irq_driver); +} +module_exit(aqt_irq_drv_exit); + +MODULE_DESCRIPTION("AQT1000 IRQ driver"); +MODULE_LICENSE("GPL v2"); diff --git a/asoc/codecs/aqt1000/aqt1000-irq.h b/asoc/codecs/aqt1000/aqt1000-irq.h new file mode 100644 index 0000000000..dd5b1166a1 --- /dev/null +++ b/asoc/codecs/aqt1000/aqt1000-irq.h @@ -0,0 +1,73 @@ +/* Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __AQT1000_IRQ_H_ +#define __AQT1000_IRQ_H_ + +#include +#include + +enum { + /* INTR_CTRL_INT_MASK_2 */ + AQT1000_IRQ_MBHC_BUTTON_RELEASE_DET = 0, + AQT1000_IRQ_MBHC_BUTTON_PRESS_DET, + AQT1000_IRQ_MBHC_ELECT_INS_REM_DET, + AQT1000_IRQ_MBHC_ELECT_INS_REM_LEG_DET, + AQT1000_IRQ_MBHC_SW_DET, + AQT1000_IRQ_HPH_PA_OCPL_FAULT, + AQT1000_IRQ_HPH_PA_OCPR_FAULT, + AQT1000_IRQ_HPH_PA_CNPL_COMPLETE, + + /* INTR_CTRL_INT_MASK_3 */ + AQT1000_IRQ_HPH_PA_CNPR_COMPLETE, + AQT1000_CDC_HPHL_SURGE, + AQT1000_CDC_HPHR_SURGE, + AQT1000_PLL_LOCK_LOSS, + AQT1000_FLL_LOCK_LOSS, + AQT1000_DSD_INT, + AQT1000_NUM_IRQS, +}; + +/** + * struct aqt_irq - AQT IRQ resource structure + * @irq_lock: lock used by irq_chip functions. + * @nested_irq_lock: lock used while handling nested interrupts. + * @irq: interrupt number. + * @irq_masks_cur: current mask value to be written to mask registers. + * @irq_masks_cache: cached mask value. + * @num_irqs: number of supported interrupts. + * @num_irq_regs: number of irq registers. + * @parent: parent pointer. + * @dev: device pointer. + * @domain: irq domain pointer. + * + * Contains required members used in wsa irq driver. + */ + +struct aqt1000_irq { + struct mutex irq_lock; + struct mutex nested_irq_lock; + unsigned int irq; + u8 irq_masks_cur; + u8 irq_masks_cache; + bool irq_level_high[8]; + int num_irqs; + int num_irq_regs; + void *parent; + struct device *dev; + struct irq_domain *domain; +}; + +int aqt_irq_init(void); +void aqt_irq_exit(void); + +#endif /* __AQT1000_IRQ_H_ */ diff --git a/asoc/codecs/aqt1000/aqt1000-mbhc.c b/asoc/codecs/aqt1000/aqt1000-mbhc.c new file mode 100644 index 0000000000..2f7e470649 --- /dev/null +++ b/asoc/codecs/aqt1000/aqt1000-mbhc.c @@ -0,0 +1,1133 @@ +/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "aqt.h" +#include "aqt-mbhc.h" +#include +#include "aqt_irq.h" +#include "pdata.h" +#include "../wcd9xxx-irq.h" +#include "../wcdcal-hwdep.h" +#include "../wcd-mbhc-v2-api.h" + +#define AQT_ZDET_SUPPORTED true +/* Z value defined in milliohm */ +#define AQT_ZDET_VAL_32 32000 +#define AQT_ZDET_VAL_400 400000 +#define AQT_ZDET_VAL_1200 1200000 +#define AQT_ZDET_VAL_100K 100000000 +/* Z floating defined in ohms */ +#define AQT_ZDET_FLOATING_IMPEDANCE 0x0FFFFFFE + +#define AQT_ZDET_NUM_MEASUREMENTS 900 +#define AQT_MBHC_GET_C1(c) ((c & 0xC000) >> 14) +#define AQT_MBHC_GET_X1(x) (x & 0x3FFF) +/* Z value compared in milliOhm */ +#define AQT_MBHC_IS_SECOND_RAMP_REQUIRED(z) ((z > 400000) || (z < 32000)) +#define AQT_MBHC_ZDET_CONST (86 * 16384) +#define AQT_MBHC_MOISTURE_RREF R_24_KOHM + +static struct wcd_mbhc_register + wcd_mbhc_registers[WCD_MBHC_REG_FUNC_MAX] = { + WCD_MBHC_REGISTER("WCD_MBHC_L_DET_EN", + AQT_ANA_MBHC_MECH, 0x80, 7, 0), + WCD_MBHC_REGISTER("WCD_MBHC_GND_DET_EN", + AQT_ANA_MBHC_MECH, 0x40, 6, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MECH_DETECTION_TYPE", + AQT_ANA_MBHC_MECH, 0x20, 5, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MIC_CLAMP_CTL", + AQT_MBHC_NEW_PLUG_DETECT_CTL, 0x30, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ELECT_DETECTION_TYPE", + AQT_ANA_MBHC_ELECT, 0x08, 3, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HS_L_DET_PULL_UP_CTRL", + AQT_MBHC_NEW_PLUG_DETECT_CTL, 0xC0, 6, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HS_L_DET_PULL_UP_COMP_CTRL", + AQT_ANA_MBHC_MECH, 0x04, 2, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHL_PLUG_TYPE", + AQT_ANA_MBHC_MECH, 0x10, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_GND_PLUG_TYPE", + AQT_ANA_MBHC_MECH, 0x08, 3, 0), + WCD_MBHC_REGISTER("WCD_MBHC_SW_HPH_LP_100K_TO_GND", + AQT_ANA_MBHC_MECH, 0x01, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ELECT_SCHMT_ISRC", + AQT_ANA_MBHC_ELECT, 0x06, 1, 0), + WCD_MBHC_REGISTER("WCD_MBHC_FSM_EN", + AQT_ANA_MBHC_ELECT, 0x80, 7, 0), + WCD_MBHC_REGISTER("WCD_MBHC_INSREM_DBNC", + AQT_MBHC_NEW_PLUG_DETECT_CTL, 0x0F, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_BTN_DBNC", + AQT_MBHC_NEW_CTL_1, 0x03, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HS_VREF", + AQT_MBHC_NEW_CTL_2, 0x03, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HS_COMP_RESULT", + AQT_ANA_MBHC_RESULT_3, 0x08, 3, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MIC_SCHMT_RESULT", + AQT_ANA_MBHC_RESULT_3, 0x20, 5, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHL_SCHMT_RESULT", + AQT_ANA_MBHC_RESULT_3, 0x80, 7, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHR_SCHMT_RESULT", + AQT_ANA_MBHC_RESULT_3, 0x40, 6, 0), + WCD_MBHC_REGISTER("WCD_MBHC_OCP_FSM_EN", + AQT_HPH_OCP_CTL, 0x10, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_BTN_RESULT", + AQT_ANA_MBHC_RESULT_3, 0x07, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_BTN_ISRC_CTL", + AQT_ANA_MBHC_ELECT, 0x70, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ELECT_RESULT", + AQT_ANA_MBHC_RESULT_3, 0xFF, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MICB_CTRL", + AQT_ANA_MICB2, 0xC0, 6, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPH_CNP_WG_TIME", + AQT_HPH_CNP_WG_TIME, 0xFF, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHR_PA_EN", + AQT_ANA_HPH, 0x40, 6, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHL_PA_EN", + AQT_ANA_HPH, 0x80, 7, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPH_PA_EN", + AQT_ANA_HPH, 0xC0, 6, 0), + WCD_MBHC_REGISTER("WCD_MBHC_SWCH_LEVEL_REMOVE", + AQT_ANA_MBHC_RESULT_3, 0x10, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_PULLDOWN_CTRL", + 0, 0, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ANC_DET_EN", + AQT_MBHC_CTL_BCS, 0x02, 1, 0), + WCD_MBHC_REGISTER("WCD_MBHC_FSM_STATUS", + AQT_MBHC_STATUS_SPARE_1, 0x01, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MUX_CTL", + AQT_MBHC_NEW_CTL_2, 0x70, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHL_OCP_DET_EN", + AQT_HPH_L_TEST, 0x01, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHR_OCP_DET_EN", + AQT_HPH_R_TEST, 0x01, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHL_OCP_STATUS", + AQT_INTR_PIN1_STATUS0, 0x04, 2, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHR_OCP_STATUS", + AQT_INTR_PIN1_STATUS0, 0x08, 3, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ADC_EN", + AQT_MBHC_NEW_CTL_1, 0x08, 3, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ADC_COMPLETE", AQT_MBHC_NEW_FSM_STATUS, + 0x40, 6, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ADC_TIMEOUT", AQT_MBHC_NEW_FSM_STATUS, + 0x80, 7, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ADC_RESULT", AQT_MBHC_NEW_ADC_RESULT, + 0xFF, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MICB2_VOUT", AQT_ANA_MICB2, 0x3F, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ADC_MODE", + AQT_MBHC_NEW_CTL_1, 0x10, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_DETECTION_DONE", + AQT_MBHC_NEW_CTL_1, 0x04, 2, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ELECT_ISRC_EN", + AQT_ANA_MBHC_ZDET, 0x02, 1, 0), +}; + +static const struct wcd_mbhc_intr intr_ids = { + .mbhc_sw_intr = AQT_IRQ_MBHC_SW_DET, + .mbhc_btn_press_intr = AQT_IRQ_MBHC_BUTTON_PRESS_DET, + .mbhc_btn_release_intr = AQT_IRQ_MBHC_BUTTON_RELEASE_DET, + .mbhc_hs_ins_intr = AQT_IRQ_MBHC_ELECT_INS_REM_LEG_DET, + .mbhc_hs_rem_intr = AQT_IRQ_MBHC_ELECT_INS_REM_DET, + .hph_left_ocp = AQT_IRQ_HPH_PA_OCPL_FAULT, + .hph_right_ocp = AQT_IRQ_HPH_PA_OCPR_FAULT, +}; + + +static char on_demand_supply_name[][MAX_ON_DEMAND_SUPPLY_NAME_LENGTH] = { + "cdc-vdd-mic-bias", +}; + +struct aqt_mbhc_zdet_param { + u16 ldo_ctl; + u16 noff; + u16 nshift; + u16 btn5; + u16 btn6; + u16 btn7; +}; + +static int aqt_mbhc_request_irq(struct snd_soc_codec *codec, + int irq, irq_handler_t handler, + const char *name, void *data) +{ + struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + struct wcd9xxx_core_resource *core_res = + &wcd9xxx->core_res; + + return wcd9xxx_request_irq(core_res, irq, handler, name, data); +} + +static void aqt_mbhc_irq_control(struct snd_soc_codec *codec, + int irq, bool enable) +{ + struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + struct wcd9xxx_core_resource *core_res = + &wcd9xxx->core_res; + if (enable) + wcd9xxx_enable_irq(core_res, irq); + else + wcd9xxx_disable_irq(core_res, irq); +} + +static int aqt_mbhc_free_irq(struct snd_soc_codec *codec, + int irq, void *data) +{ + struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + struct wcd9xxx_core_resource *core_res = + &wcd9xxx->core_res; + + wcd9xxx_free_irq(core_res, irq, data); + return 0; +} + +static void aqt_mbhc_clk_setup(struct snd_soc_codec *codec, + bool enable) +{ + if (enable) + snd_soc_update_bits(codec, AQT_MBHC_NEW_CTL_1, + 0x80, 0x80); + else + snd_soc_update_bits(codec, AQT_MBHC_NEW_CTL_1, + 0x80, 0x00); +} + +static int aqt_mbhc_btn_to_num(struct snd_soc_codec *codec) +{ + return snd_soc_read(codec, AQT_ANA_MBHC_RESULT_3) & 0x7; +} + +static int aqt_enable_ext_mb_source(struct wcd_mbhc *mbhc, + bool turn_on) +{ + struct aqt_mbhc *aqt_mbhc; + struct snd_soc_codec *codec = mbhc->codec; + struct aqt_on_demand_supply *supply; + int ret = 0; + + aqt_mbhc = container_of(mbhc, struct aqt_mbhc, wcd_mbhc); + + supply = &aqt_mbhc->on_demand_list[AQT_ON_DEMAND_MICBIAS]; + if (!supply->supply) { + dev_dbg(codec->dev, "%s: warning supply not present ond for %s\n", + __func__, "onDemand Micbias"); + return ret; + } + + dev_dbg(codec->dev, "%s turn_on: %d count: %d\n", __func__, turn_on, + supply->ondemand_supply_count); + + if (turn_on) { + if (!(supply->ondemand_supply_count)) { + ret = snd_soc_dapm_force_enable_pin( + snd_soc_codec_get_dapm(codec), + "MICBIAS_REGULATOR"); + snd_soc_dapm_sync(snd_soc_codec_get_dapm(codec)); + } + supply->ondemand_supply_count++; + } else { + if (supply->ondemand_supply_count > 0) + supply->ondemand_supply_count--; + if (!(supply->ondemand_supply_count)) { + ret = snd_soc_dapm_disable_pin( + snd_soc_codec_get_dapm(codec), + "MICBIAS_REGULATOR"); + snd_soc_dapm_sync(snd_soc_codec_get_dapm(codec)); + } + } + + if (ret) + dev_err(codec->dev, "%s: Failed to %s external micbias source\n", + __func__, turn_on ? "enable" : "disabled"); + else + dev_dbg(codec->dev, "%s: %s external micbias source\n", + __func__, turn_on ? "Enabled" : "Disabled"); + + return ret; +} + +static void aqt_mbhc_mbhc_bias_control(struct snd_soc_codec *codec, + bool enable) +{ + if (enable) + snd_soc_update_bits(codec, AQT_ANA_MBHC_ELECT, + 0x01, 0x01); + else + snd_soc_update_bits(codec, AQT_ANA_MBHC_ELECT, + 0x01, 0x00); +} + +static void aqt_mbhc_program_btn_thr(struct snd_soc_codec *codec, + s16 *btn_low, s16 *btn_high, + int num_btn, bool is_micbias) +{ + int i; + int vth; + + if (num_btn > WCD_MBHC_DEF_BUTTONS) { + dev_err(codec->dev, "%s: invalid number of buttons: %d\n", + __func__, num_btn); + return; + } + /* + * Tavil just needs one set of thresholds for button detection + * due to micbias voltage ramp to pullup upon button press. So + * btn_low and is_micbias are ignored and always program button + * thresholds using btn_high. + */ + for (i = 0; i < num_btn; i++) { + vth = ((btn_high[i] * 2) / 25) & 0x3F; + snd_soc_update_bits(codec, AQT_ANA_MBHC_BTN0 + i, + 0xFC, vth << 2); + dev_dbg(codec->dev, "%s: btn_high[%d]: %d, vth: %d\n", + __func__, i, btn_high[i], vth); + } +} + +static bool aqt_mbhc_lock_sleep(struct wcd_mbhc *mbhc, bool lock) +{ + struct snd_soc_codec *codec = mbhc->codec; + struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + struct wcd9xxx_core_resource *core_res = + &wcd9xxx->core_res; + bool ret = 0; + + if (lock) + ret = wcd9xxx_lock_sleep(core_res); + else + wcd9xxx_unlock_sleep(core_res); + + return ret; +} + +static int aqt_mbhc_register_notifier(struct wcd_mbhc *mbhc, + struct notifier_block *nblock, + bool enable) +{ + struct aqt_mbhc *aqt_mbhc; + + aqt_mbhc = container_of(mbhc, struct aqt_mbhc, wcd_mbhc); + + if (enable) + return blocking_notifier_chain_register(&aqt_mbhc->notifier, + nblock); + else + return blocking_notifier_chain_unregister( + &aqt_mbhc->notifier, nblock); +} + +static bool aqt_mbhc_micb_en_status(struct wcd_mbhc *mbhc, int micb_num) +{ + u8 val; + + if (micb_num == MIC_BIAS_2) { + val = (snd_soc_read(mbhc->codec, AQT_ANA_MICB2) >> 6); + if (val == 0x01) + return true; + } + return false; +} + +static bool aqt_mbhc_hph_pa_on_status(struct snd_soc_codec *codec) +{ + return (snd_soc_read(codec, AQT_ANA_HPH) & 0xC0) ? true : false; +} + +static void aqt_mbhc_hph_l_pull_up_control( + struct snd_soc_codec *codec, + enum mbhc_hs_pullup_iref pull_up_cur) +{ + /* Default pull up current to 2uA */ + if (pull_up_cur < I_OFF || pull_up_cur > I_3P0_UA || + pull_up_cur == I_DEFAULT) + pull_up_cur = I_2P0_UA; + + dev_dbg(codec->dev, "%s: HS pull up current:%d\n", + __func__, pull_up_cur); + + snd_soc_update_bits(codec, AQT_MBHC_NEW_PLUG_DETECT_CTL, + 0xC0, pull_up_cur << 6); +} + +static int aqt_mbhc_request_micbias(struct snd_soc_codec *codec, + int micb_num, int req) +{ + int ret; + + /* + * If micbias is requested, make sure that there + * is vote to enable mclk + */ + if (req == MICB_ENABLE) + aqt_cdc_mclk_enable(codec, true); + + ret = aqt_micbias_control(codec, micb_num, req, false); + + /* + * Release vote for mclk while requesting for + * micbias disable + */ + if (req == MICB_DISABLE) + aqt_cdc_mclk_enable(codec, false); + + return ret; +} + +static void aqt_mbhc_micb_ramp_control(struct snd_soc_codec *codec, + bool enable) +{ + if (enable) { + snd_soc_update_bits(codec, AQT_ANA_MICB2_RAMP, + 0x1C, 0x0C); + snd_soc_update_bits(codec, AQT_ANA_MICB2_RAMP, + 0x80, 0x80); + } else { + snd_soc_update_bits(codec, AQT_ANA_MICB2_RAMP, + 0x80, 0x00); + snd_soc_update_bits(codec, AQT_ANA_MICB2_RAMP, + 0x1C, 0x00); + } +} + +static struct firmware_cal *aqt_get_hwdep_fw_cal(struct wcd_mbhc *mbhc, + enum wcd_cal_type type) +{ + struct aqt_mbhc *aqt_mbhc; + struct firmware_cal *hwdep_cal; + struct snd_soc_codec *codec = mbhc->codec; + + aqt_mbhc = container_of(mbhc, struct aqt_mbhc, wcd_mbhc); + + if (!codec) { + pr_err("%s: NULL codec pointer\n", __func__); + return NULL; + } + hwdep_cal = wcdcal_get_fw_cal(aqt_mbhc->fw_data, type); + if (!hwdep_cal) + dev_err(codec->dev, "%s: cal not sent by %d\n", + __func__, type); + + return hwdep_cal; +} + +static int aqt_mbhc_micb_ctrl_threshold_mic(struct snd_soc_codec *codec, + int micb_num, bool req_en) +{ + struct wcd9xxx_pdata *pdata = dev_get_platdata(codec->dev->parent); + int rc, micb_mv; + + if (micb_num != MIC_BIAS_2) + return -EINVAL; + + /* + * If device tree micbias level is already above the minimum + * voltage needed to detect threshold microphone, then do + * not change the micbias, just return. + */ + if (pdata->micbias.micb2_mv >= WCD_MBHC_THR_HS_MICB_MV) + return 0; + + micb_mv = req_en ? WCD_MBHC_THR_HS_MICB_MV : pdata->micbias.micb2_mv; + + rc = aqt_mbhc_micb_adjust_voltage(codec, micb_mv, MIC_BIAS_2); + + return rc; +} + +static inline void aqt_mbhc_get_result_params(struct wcd9xxx *wcd9xxx, + s16 *d1_a, u16 noff, + int32_t *zdet) +{ + int i; + int val, val1; + s16 c1; + s32 x1, d1; + int32_t denom; + int minCode_param[] = { + 3277, 1639, 820, 410, 205, 103, 52, 26 + }; + + regmap_update_bits(wcd9xxx->regmap, AQT_ANA_MBHC_ZDET, 0x20, 0x20); + for (i = 0; i < AQT_ZDET_NUM_MEASUREMENTS; i++) { + regmap_read(wcd9xxx->regmap, AQT_ANA_MBHC_RESULT_2, &val); + if (val & 0x80) + break; + } + val = val << 0x8; + regmap_read(wcd9xxx->regmap, AQT_ANA_MBHC_RESULT_1, &val1); + val |= val1; + regmap_update_bits(wcd9xxx->regmap, AQT_ANA_MBHC_ZDET, 0x20, 0x00); + x1 = AQT_MBHC_GET_X1(val); + c1 = AQT_MBHC_GET_C1(val); + /* If ramp is not complete, give additional 5ms */ + if ((c1 < 2) && x1) + usleep_range(5000, 5050); + + if (!c1 || !x1) { + dev_dbg(wcd9xxx->dev, + "%s: Impedance detect ramp error, c1=%d, x1=0x%x\n", + __func__, c1, x1); + goto ramp_down; + } + d1 = d1_a[c1]; + denom = (x1 * d1) - (1 << (14 - noff)); + if (denom > 0) + *zdet = (AQT_MBHC_ZDET_CONST * 1000) / denom; + else if (x1 < minCode_param[noff]) + *zdet = AQT_ZDET_FLOATING_IMPEDANCE; + + dev_dbg(wcd9xxx->dev, "%s: d1=%d, c1=%d, x1=0x%x, z_val=%d(milliOhm)\n", + __func__, d1, c1, x1, *zdet); +ramp_down: + i = 0; + while (x1) { + regmap_bulk_read(wcd9xxx->regmap, + AQT_ANA_MBHC_RESULT_1, (u8 *)&val, 2); + x1 = AQT_MBHC_GET_X1(val); + i++; + if (i == AQT_ZDET_NUM_MEASUREMENTS) + break; + } +} + +static void aqt_mbhc_zdet_ramp(struct snd_soc_codec *codec, + struct aqt_mbhc_zdet_param *zdet_param, + int32_t *zl, int32_t *zr, s16 *d1_a) +{ + struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + int32_t zdet = 0; + + snd_soc_update_bits(codec, AQT_MBHC_NEW_ZDET_ANA_CTL, 0x70, + zdet_param->ldo_ctl << 4); + snd_soc_update_bits(codec, AQT_ANA_MBHC_BTN5, 0xFC, + zdet_param->btn5); + snd_soc_update_bits(codec, AQT_ANA_MBHC_BTN6, 0xFC, + zdet_param->btn6); + snd_soc_update_bits(codec, AQT_ANA_MBHC_BTN7, 0xFC, + zdet_param->btn7); + snd_soc_update_bits(codec, AQT_MBHC_NEW_ZDET_ANA_CTL, 0x0F, + zdet_param->noff); + snd_soc_update_bits(codec, AQT_MBHC_NEW_ZDET_RAMP_CTL, 0x0F, + zdet_param->nshift); + + if (!zl) + goto z_right; + /* Start impedance measurement for HPH_L */ + regmap_update_bits(wcd9xxx->regmap, + AQT_ANA_MBHC_ZDET, 0x80, 0x80); + dev_dbg(wcd9xxx->dev, "%s: ramp for HPH_L, noff = %d\n", + __func__, zdet_param->noff); + aqt_mbhc_get_result_params(wcd9xxx, d1_a, zdet_param->noff, &zdet); + regmap_update_bits(wcd9xxx->regmap, + AQT_ANA_MBHC_ZDET, 0x80, 0x00); + + *zl = zdet; + +z_right: + if (!zr) + return; + /* Start impedance measurement for HPH_R */ + regmap_update_bits(wcd9xxx->regmap, + AQT_ANA_MBHC_ZDET, 0x40, 0x40); + dev_dbg(wcd9xxx->dev, "%s: ramp for HPH_R, noff = %d\n", + __func__, zdet_param->noff); + aqt_mbhc_get_result_params(wcd9xxx, d1_a, zdet_param->noff, &zdet); + regmap_update_bits(wcd9xxx->regmap, + AQT_ANA_MBHC_ZDET, 0x40, 0x00); + + *zr = zdet; +} + +static inline void aqt_wcd_mbhc_qfuse_cal(struct snd_soc_codec *codec, + int32_t *z_val, int flag_l_r) +{ + s16 q1; + int q1_cal; + + if (*z_val < (AQT_ZDET_VAL_400/1000)) + q1 = snd_soc_read(codec, + AQT_CHIP_TIER_CTRL_EFUSE_VAL_OUT1 + (2 * flag_l_r)); + else + q1 = snd_soc_read(codec, + AQT_CHIP_TIER_CTRL_EFUSE_VAL_OUT2 + (2 * flag_l_r)); + if (q1 & 0x80) + q1_cal = (10000 - ((q1 & 0x7F) * 25)); + else + q1_cal = (10000 + (q1 * 25)); + if (q1_cal > 0) + *z_val = ((*z_val) * 10000) / q1_cal; +} + +static void aqt_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, + uint32_t *zr) +{ + struct snd_soc_codec *codec = mbhc->codec; + struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + s16 reg0, reg1, reg2, reg3, reg4; + int32_t z1L, z1R, z1Ls; + int zMono, z_diff1, z_diff2; + bool is_fsm_disable = false; + struct aqt_mbhc_zdet_param zdet_param[] = { + {4, 0, 4, 0x08, 0x14, 0x18}, /* < 32ohm */ + {2, 0, 3, 0x18, 0x7C, 0x90}, /* 32ohm < Z < 400ohm */ + {1, 4, 5, 0x18, 0x7C, 0x90}, /* 400ohm < Z < 1200ohm */ + {1, 6, 7, 0x18, 0x7C, 0x90}, /* >1200ohm */ + }; + struct aqt_mbhc_zdet_param *zdet_param_ptr = NULL; + s16 d1_a[][4] = { + {0, 30, 90, 30}, + {0, 30, 30, 5}, + {0, 30, 30, 5}, + {0, 30, 30, 5}, + }; + s16 *d1 = NULL; + + WCD_MBHC_RSC_ASSERT_LOCKED(mbhc); + + reg0 = snd_soc_read(codec, AQT_ANA_MBHC_BTN5); + reg1 = snd_soc_read(codec, AQT_ANA_MBHC_BTN6); + reg2 = snd_soc_read(codec, AQT_ANA_MBHC_BTN7); + reg3 = snd_soc_read(codec, AQT_MBHC_CTL_CLK); + reg4 = snd_soc_read(codec, AQT_MBHC_NEW_ZDET_ANA_CTL); + + if (snd_soc_read(codec, AQT_ANA_MBHC_ELECT) & 0x80) { + is_fsm_disable = true; + regmap_update_bits(wcd9xxx->regmap, + AQT_ANA_MBHC_ELECT, 0x80, 0x00); + } + + /* For NO-jack, disable L_DET_EN before Z-det measurements */ + if (mbhc->hphl_swh) + regmap_update_bits(wcd9xxx->regmap, + AQT_ANA_MBHC_MECH, 0x80, 0x00); + + /* Turn off 100k pull down on HPHL */ + regmap_update_bits(wcd9xxx->regmap, + AQT_ANA_MBHC_MECH, 0x01, 0x00); + + /* First get impedance on Left */ + d1 = d1_a[1]; + zdet_param_ptr = &zdet_param[1]; + aqt_mbhc_zdet_ramp(codec, zdet_param_ptr, &z1L, NULL, d1); + + if (!AQT_MBHC_IS_SECOND_RAMP_REQUIRED(z1L)) + goto left_ch_impedance; + + /* Second ramp for left ch */ + if (z1L < AQT_ZDET_VAL_32) { + zdet_param_ptr = &zdet_param[0]; + d1 = d1_a[0]; + } else if ((z1L > AQT_ZDET_VAL_400) && (z1L <= AQT_ZDET_VAL_1200)) { + zdet_param_ptr = &zdet_param[2]; + d1 = d1_a[2]; + } else if (z1L > AQT_ZDET_VAL_1200) { + zdet_param_ptr = &zdet_param[3]; + d1 = d1_a[3]; + } + aqt_mbhc_zdet_ramp(codec, zdet_param_ptr, &z1L, NULL, d1); + +left_ch_impedance: + if ((z1L == AQT_ZDET_FLOATING_IMPEDANCE) || + (z1L > AQT_ZDET_VAL_100K)) { + *zl = AQT_ZDET_FLOATING_IMPEDANCE; + zdet_param_ptr = &zdet_param[1]; + d1 = d1_a[1]; + } else { + *zl = z1L/1000; + aqt_wcd_mbhc_qfuse_cal(codec, zl, 0); + } + dev_dbg(codec->dev, "%s: impedance on HPH_L = %d(ohms)\n", + __func__, *zl); + + /* Start of right impedance ramp and calculation */ + aqt_mbhc_zdet_ramp(codec, zdet_param_ptr, NULL, &z1R, d1); + if (AQT_MBHC_IS_SECOND_RAMP_REQUIRED(z1R)) { + if (((z1R > AQT_ZDET_VAL_1200) && + (zdet_param_ptr->noff == 0x6)) || + ((*zl) != AQT_ZDET_FLOATING_IMPEDANCE)) + goto right_ch_impedance; + /* Second ramp for right ch */ + if (z1R < AQT_ZDET_VAL_32) { + zdet_param_ptr = &zdet_param[0]; + d1 = d1_a[0]; + } else if ((z1R > AQT_ZDET_VAL_400) && + (z1R <= AQT_ZDET_VAL_1200)) { + zdet_param_ptr = &zdet_param[2]; + d1 = d1_a[2]; + } else if (z1R > AQT_ZDET_VAL_1200) { + zdet_param_ptr = &zdet_param[3]; + d1 = d1_a[3]; + } + aqt_mbhc_zdet_ramp(codec, zdet_param_ptr, NULL, &z1R, d1); + } +right_ch_impedance: + if ((z1R == AQT_ZDET_FLOATING_IMPEDANCE) || + (z1R > AQT_ZDET_VAL_100K)) { + *zr = AQT_ZDET_FLOATING_IMPEDANCE; + } else { + *zr = z1R/1000; + aqt_wcd_mbhc_qfuse_cal(codec, zr, 1); + } + dev_dbg(codec->dev, "%s: impedance on HPH_R = %d(ohms)\n", + __func__, *zr); + + /* Mono/stereo detection */ + if ((*zl == AQT_ZDET_FLOATING_IMPEDANCE) && + (*zr == AQT_ZDET_FLOATING_IMPEDANCE)) { + dev_dbg(codec->dev, + "%s: plug type is invalid or extension cable\n", + __func__); + goto zdet_complete; + } + if ((*zl == AQT_ZDET_FLOATING_IMPEDANCE) || + (*zr == AQT_ZDET_FLOATING_IMPEDANCE) || + ((*zl < WCD_MONO_HS_MIN_THR) && (*zr > WCD_MONO_HS_MIN_THR)) || + ((*zl > WCD_MONO_HS_MIN_THR) && (*zr < WCD_MONO_HS_MIN_THR))) { + dev_dbg(codec->dev, + "%s: Mono plug type with one ch floating or shorted to GND\n", + __func__); + mbhc->hph_type = WCD_MBHC_HPH_MONO; + goto zdet_complete; + } + snd_soc_update_bits(codec, AQT_HPH_R_ATEST, 0x02, 0x02); + snd_soc_update_bits(codec, AQT_HPH_PA_CTL2, 0x40, 0x01); + if (*zl < (AQT_ZDET_VAL_32/1000)) + aqt_mbhc_zdet_ramp(codec, &zdet_param[0], &z1Ls, NULL, d1); + else + aqt_mbhc_zdet_ramp(codec, &zdet_param[1], &z1Ls, NULL, d1); + snd_soc_update_bits(codec, AQT_HPH_PA_CTL2, 0x40, 0x00); + snd_soc_update_bits(codec, AQT_HPH_R_ATEST, 0x02, 0x00); + z1Ls /= 1000; + aqt_wcd_mbhc_qfuse_cal(codec, &z1Ls, 0); + /* Parallel of left Z and 9 ohm pull down resistor */ + zMono = ((*zl) * 9) / ((*zl) + 9); + z_diff1 = (z1Ls > zMono) ? (z1Ls - zMono) : (zMono - z1Ls); + z_diff2 = ((*zl) > z1Ls) ? ((*zl) - z1Ls) : (z1Ls - (*zl)); + if ((z_diff1 * (*zl + z1Ls)) > (z_diff2 * (z1Ls + zMono))) { + dev_dbg(codec->dev, "%s: stereo plug type detected\n", + __func__); + mbhc->hph_type = WCD_MBHC_HPH_STEREO; + } else { + dev_dbg(codec->dev, "%s: MONO plug type detected\n", + __func__); + mbhc->hph_type = WCD_MBHC_HPH_MONO; + } + +zdet_complete: + snd_soc_write(codec, AQT_ANA_MBHC_BTN5, reg0); + snd_soc_write(codec, AQT_ANA_MBHC_BTN6, reg1); + snd_soc_write(codec, AQT_ANA_MBHC_BTN7, reg2); + /* Turn on 100k pull down on HPHL */ + regmap_update_bits(wcd9xxx->regmap, + AQT_ANA_MBHC_MECH, 0x01, 0x01); + + /* For NO-jack, re-enable L_DET_EN after Z-det measurements */ + if (mbhc->hphl_swh) + regmap_update_bits(wcd9xxx->regmap, + AQT_ANA_MBHC_MECH, 0x80, 0x80); + + snd_soc_write(codec, AQT_MBHC_NEW_ZDET_ANA_CTL, reg4); + snd_soc_write(codec, AQT_MBHC_CTL_CLK, reg3); + if (is_fsm_disable) + regmap_update_bits(wcd9xxx->regmap, + AQT_ANA_MBHC_ELECT, 0x80, 0x80); +} + +static void aqt_mbhc_gnd_det_ctrl(struct snd_soc_codec *codec, bool enable) +{ + if (enable) { + snd_soc_update_bits(codec, AQT_ANA_MBHC_MECH, + 0x02, 0x02); + snd_soc_update_bits(codec, AQT_ANA_MBHC_MECH, + 0x40, 0x40); + } else { + snd_soc_update_bits(codec, AQT_ANA_MBHC_MECH, + 0x40, 0x00); + snd_soc_update_bits(codec, AQT_ANA_MBHC_MECH, + 0x02, 0x00); + } +} + +static void aqt_mbhc_hph_pull_down_ctrl(struct snd_soc_codec *codec, + bool enable) +{ + if (enable) { + snd_soc_update_bits(codec, AQT_HPH_PA_CTL2, + 0x40, 0x40); + snd_soc_update_bits(codec, AQT_HPH_PA_CTL2, + 0x10, 0x10); + } else { + snd_soc_update_bits(codec, AQT_HPH_PA_CTL2, + 0x40, 0x00); + snd_soc_update_bits(codec, AQT_HPH_PA_CTL2, + 0x10, 0x00); + } +} +static void aqt_mbhc_moisture_config(struct wcd_mbhc *mbhc) +{ + struct snd_soc_codec *codec = mbhc->codec; + + if ((mbhc->moist_rref == R_OFF) || + (mbhc->mbhc_cfg->enable_usbc_analog)) { + snd_soc_update_bits(codec, AQT_MBHC_NEW_CTL_2, + 0x0C, R_OFF << 2); + return; + } + + /* Donot enable moisture detection if jack type is NC */ + if (!mbhc->hphl_swh) { + dev_dbg(codec->dev, "%s: disable moisture detection for NC\n", + __func__); + snd_soc_update_bits(codec, AQT_MBHC_NEW_CTL_2, + 0x0C, R_OFF << 2); + return; + } + + snd_soc_update_bits(codec, AQT_MBHC_NEW_CTL_2, + 0x0C, mbhc->moist_rref << 2); +} + +static bool aqt_hph_register_recovery(struct wcd_mbhc *mbhc) +{ + struct snd_soc_codec *codec = mbhc->codec; + struct aqt_mbhc *aqt_mbhc = aqt_soc_get_mbhc(codec); + + if (!aqt_mbhc) + return false; + + aqt_mbhc->is_hph_recover = false; + snd_soc_dapm_force_enable_pin(snd_soc_codec_get_dapm(codec), + "RESET_HPH_REGISTERS"); + snd_soc_dapm_sync(snd_soc_codec_get_dapm(codec)); + + snd_soc_dapm_disable_pin(snd_soc_codec_get_dapm(codec), + "RESET_HPH_REGISTERS"); + snd_soc_dapm_sync(snd_soc_codec_get_dapm(codec)); + + return aqt_mbhc->is_hph_recover; +} + +static void aqt_update_anc_state(struct snd_soc_codec *codec, bool enable, + int anc_num) +{ + if (enable) + snd_soc_update_bits(codec, AQT_CDC_RX1_RX_PATH_CFG0 + + (20 * anc_num), 0x10, 0x10); + else + snd_soc_update_bits(codec, AQT_CDC_RX1_RX_PATH_CFG0 + + (20 * anc_num), 0x10, 0x00); +} + +static bool aqt_is_anc_on(struct wcd_mbhc *mbhc) +{ + bool anc_on = false; + u16 ancl, ancr; + + ancl = + (snd_soc_read(mbhc->codec, AQT_CDC_RX1_RX_PATH_CFG0)) & 0x10; + ancr = + (snd_soc_read(mbhc->codec, AQT_CDC_RX2_RX_PATH_CFG0)) & 0x10; + + anc_on = !!(ancl | ancr); + + return anc_on; +} + +static const struct wcd_mbhc_cb mbhc_cb = { + .request_irq = aqt_mbhc_request_irq, + .irq_control = aqt_mbhc_irq_control, + .free_irq = aqt_mbhc_free_irq, + .clk_setup = aqt_mbhc_clk_setup, + .map_btn_code_to_num = aqt_mbhc_btn_to_num, + .enable_mb_source = aqt_enable_ext_mb_source, + .mbhc_bias = aqt_mbhc_mbhc_bias_control, + .set_btn_thr = aqt_mbhc_program_btn_thr, + .lock_sleep = aqt_mbhc_lock_sleep, + .register_notifier = aqt_mbhc_register_notifier, + .micbias_enable_status = aqt_mbhc_micb_en_status, + .hph_pa_on_status = aqt_mbhc_hph_pa_on_status, + .hph_pull_up_control = aqt_mbhc_hph_l_pull_up_control, + .mbhc_micbias_control = aqt_mbhc_request_micbias, + .mbhc_micb_ramp_control = aqt_mbhc_micb_ramp_control, + .get_hwdep_fw_cal = aqt_get_hwdep_fw_cal, + .mbhc_micb_ctrl_thr_mic = aqt_mbhc_micb_ctrl_threshold_mic, + .compute_impedance = aqt_wcd_mbhc_calc_impedance, + .mbhc_gnd_det_ctrl = aqt_mbhc_gnd_det_ctrl, + .hph_pull_down_ctrl = aqt_mbhc_hph_pull_down_ctrl, + .mbhc_moisture_config = aqt_mbhc_moisture_config, + .hph_register_recovery = aqt_hph_register_recovery, + .update_anc_state = aqt_update_anc_state, + .is_anc_on = aqt_is_anc_on, +}; + +static struct regulator *aqt_codec_find_ondemand_regulator( + struct snd_soc_codec *codec, const char *name) +{ + int i; + struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + struct wcd9xxx_pdata *pdata = dev_get_platdata(codec->dev->parent); + + for (i = 0; i < wcd9xxx->num_of_supplies; ++i) { + if (pdata->regulator[i].ondemand && + wcd9xxx->supplies[i].supply && + !strcmp(wcd9xxx->supplies[i].supply, name)) + return wcd9xxx->supplies[i].consumer; + } + + dev_dbg(codec->dev, "Warning: regulator not found:%s\n", + name); + return NULL; +} + +static int aqt_get_hph_type(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct aqt_mbhc *aqt_mbhc = aqt_soc_get_mbhc(codec); + struct wcd_mbhc *mbhc; + + if (!aqt_mbhc) { + dev_err(codec->dev, "%s: mbhc not initialized!\n", __func__); + return -EINVAL; + } + + mbhc = &aqt_mbhc->wcd_mbhc; + + ucontrol->value.integer.value[0] = (u32) mbhc->hph_type; + dev_dbg(codec->dev, "%s: hph_type = %u\n", __func__, mbhc->hph_type); + + return 0; +} + +static int aqt_hph_impedance_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + uint32_t zl, zr; + bool hphr; + struct soc_multi_mixer_control *mc; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct aqt_mbhc *aqt_mbhc = aqt_soc_get_mbhc(codec); + + if (!aqt_mbhc) { + dev_err(codec->dev, "%s: mbhc not initialized!\n", __func__); + return -EINVAL; + } + + mc = (struct soc_multi_mixer_control *)(kcontrol->private_value); + hphr = mc->shift; + wcd_mbhc_get_impedance(&aqt_mbhc->wcd_mbhc, &zl, &zr); + dev_dbg(codec->dev, "%s: zl=%u(ohms), zr=%u(ohms)\n", __func__, zl, zr); + ucontrol->value.integer.value[0] = hphr ? zr : zl; + + return 0; +} + +static const struct snd_kcontrol_new hph_type_detect_controls[] = { + SOC_SINGLE_EXT("HPH Type", 0, 0, UINT_MAX, 0, + aqt_get_hph_type, NULL), +}; + +static const struct snd_kcontrol_new impedance_detect_controls[] = { + SOC_SINGLE_EXT("HPHL Impedance", 0, 0, UINT_MAX, 0, + aqt_hph_impedance_get, NULL), + SOC_SINGLE_EXT("HPHR Impedance", 0, 1, UINT_MAX, 0, + aqt_hph_impedance_get, NULL), +}; + +/* + * aqt_mbhc_get_impedance: get impedance of headphone left and right channels + * @aqt_mbhc: handle to struct aqt_mbhc * + * @zl: handle to left-ch impedance + * @zr: handle to right-ch impedance + * return 0 for success or error code in case of failure + */ +int aqt_mbhc_get_impedance(struct aqt_mbhc *aqt_mbhc, + uint32_t *zl, uint32_t *zr) +{ + if (!aqt_mbhc) { + pr_err("%s: mbhc not initialized!\n", __func__); + return -EINVAL; + } + if (!zl || !zr) { + pr_err("%s: zl or zr null!\n", __func__); + return -EINVAL; + } + + return wcd_mbhc_get_impedance(&aqt_mbhc->wcd_mbhc, zl, zr); +} +EXPORT_SYMBOL(aqt_mbhc_get_impedance); + +/* + * aqt_mbhc_hs_detect: starts mbhc insertion/removal functionality + * @codec: handle to snd_soc_codec * + * @mbhc_cfg: handle to mbhc configuration structure + * return 0 if mbhc_start is success or error code in case of failure + */ +int aqt_mbhc_hs_detect(struct snd_soc_codec *codec, + struct wcd_mbhc_config *mbhc_cfg) +{ + struct aqt_mbhc *aqt_mbhc = aqt_soc_get_mbhc(codec); + + if (!aqt_mbhc) { + dev_err(codec->dev, "%s: mbhc not initialized!\n", __func__); + return -EINVAL; + } + + return wcd_mbhc_start(&aqt_mbhc->wcd_mbhc, mbhc_cfg); +} +EXPORT_SYMBOL(aqt_mbhc_hs_detect); + +/* + * aqt_mbhc_hs_detect_exit: stop mbhc insertion/removal functionality + * @codec: handle to snd_soc_codec * + */ +void aqt_mbhc_hs_detect_exit(struct snd_soc_codec *codec) +{ + struct aqt_mbhc *aqt_mbhc = aqt_soc_get_mbhc(codec); + + if (!aqt_mbhc) { + dev_err(codec->dev, "%s: mbhc not initialized!\n", __func__); + return; + } + wcd_mbhc_stop(&aqt_mbhc->wcd_mbhc); +} +EXPORT_SYMBOL(aqt_mbhc_hs_detect_exit); + +/* + * aqt_mbhc_post_ssr_init: initialize mbhc for aqt post subsystem restart + * @mbhc: poniter to aqt_mbhc structure + * @codec: handle to snd_soc_codec * + * + * return 0 if mbhc_init is success or error code in case of failure + */ +int aqt_mbhc_post_ssr_init(struct aqt_mbhc *mbhc, + struct snd_soc_codec *codec) +{ + int ret; + struct wcd_mbhc *wcd_mbhc; + + if (!mbhc || !codec) + return -EINVAL; + + wcd_mbhc = &mbhc->wcd_mbhc; + if (wcd_mbhc == NULL) { + pr_err("%s: wcd_mbhc is NULL\n", __func__); + return -EINVAL; + } + + wcd_mbhc_deinit(wcd_mbhc); + ret = wcd_mbhc_init(wcd_mbhc, codec, &mbhc_cb, &intr_ids, + wcd_mbhc_registers, AQT_ZDET_SUPPORTED); + if (ret) { + dev_err(codec->dev, "%s: mbhc initialization failed\n", + __func__); + goto done; + } + +done: + return ret; +} +EXPORT_SYMBOL(aqt_mbhc_post_ssr_init); + +/* + * aqt_mbhc_init: initialize mbhc for aqt + * @mbhc: poniter to aqt_mbhc struct pointer to store the configs + * @codec: handle to snd_soc_codec * + * @fw_data: handle to firmware data + * + * return 0 if mbhc_init is success or error code in case of failure + */ +int aqt_mbhc_init(struct aqt_mbhc **mbhc, struct snd_soc_codec *codec, + struct fw_info *fw_data) +{ + struct regulator *supply; + struct aqt_mbhc *aqt_mbhc; + struct wcd_mbhc *wcd_mbhc; + int ret; + + aqt_mbhc = devm_kzalloc(codec->dev, sizeof(struct aqt_mbhc), + GFP_KERNEL); + if (!aqt_mbhc) + return -ENOMEM; + + aqt_mbhc->wcd9xxx = dev_get_drvdata(codec->dev->parent); + aqt_mbhc->fw_data = fw_data; + BLOCKING_INIT_NOTIFIER_HEAD(&aqt_mbhc->notifier); + wcd_mbhc = &aqt_mbhc->wcd_mbhc; + if (wcd_mbhc == NULL) { + pr_err("%s: wcd_mbhc is NULL\n", __func__); + ret = -EINVAL; + goto err; + } + + + /* Setting default mbhc detection logic to ADC */ + wcd_mbhc->mbhc_detection_logic = WCD_DETECTION_ADC; + + ret = wcd_mbhc_init(wcd_mbhc, codec, &mbhc_cb, + &intr_ids, wcd_mbhc_registers, + AQT_ZDET_SUPPORTED); + if (ret) { + dev_err(codec->dev, "%s: mbhc initialization failed\n", + __func__); + goto err; + } + + supply = aqt_codec_find_ondemand_regulator(codec, + on_demand_supply_name[AQT_ON_DEMAND_MICBIAS]); + if (supply) { + aqt_mbhc->on_demand_list[ + AQT_ON_DEMAND_MICBIAS].supply = + supply; + aqt_mbhc->on_demand_list[ + AQT_ON_DEMAND_MICBIAS].ondemand_supply_count = + 0; + } + + (*mbhc) = aqt_mbhc; + snd_soc_add_codec_controls(codec, impedance_detect_controls, + ARRAY_SIZE(impedance_detect_controls)); + snd_soc_add_codec_controls(codec, hph_type_detect_controls, + ARRAY_SIZE(hph_type_detect_controls)); + + return 0; +err: + devm_kfree(codec->dev, aqt_mbhc); + return ret; +} +EXPORT_SYMBOL(aqt_mbhc_init); + +/* + * aqt_mbhc_deinit: deinitialize mbhc for aqt + * @codec: handle to snd_soc_codec * + */ +void aqt_mbhc_deinit(struct snd_soc_codec *codec) +{ + struct aqt_mbhc *aqt_mbhc = aqt_soc_get_mbhc(codec); + + if (aqt_mbhc) { + wcd_mbhc_deinit(&aqt_mbhc->wcd_mbhc); + devm_kfree(codec->dev, aqt_mbhc); + } +} +EXPORT_SYMBOL(aqt_mbhc_deinit); diff --git a/asoc/codecs/aqt1000/aqt1000-mbhc.h b/asoc/codecs/aqt1000/aqt1000-mbhc.h new file mode 100644 index 0000000000..848cb07d7e --- /dev/null +++ b/asoc/codecs/aqt1000/aqt1000-mbhc.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef __AQT_MBHC_H__ +#define __AQT_MBHC_H__ +#include "../wcd-mbhc-v2.h" + +enum aqt_on_demand_supply_name { + AQT_ON_DEMAND_MICBIAS = 0, + AQT_ON_DEMAND_SUPPLIES_MAX, +}; + +struct aqt_on_demand_supply { + struct regulator *supply; + int ondemand_supply_count; +}; + +struct aqt_mbhc { + struct wcd_mbhc wcd_mbhc; + struct blocking_notifier_head notifier; + struct aqt_on_demand_supply on_demand_list[ + AQT_ON_DEMAND_SUPPLIES_MAX]; + struct aqt1000 *aqt; + struct fw_info *fw_data; + bool mbhc_started; + bool is_hph_recover; +}; + +#if IS_ENABLED(CONFIG_SND_SOC_AQT_MBHC) +extern int aqt_mbhc_init(struct aqt_mbhc **mbhc, + struct snd_soc_codec *codec, + struct fw_info *fw_data); +extern void aqt_mbhc_hs_detect_exit(struct snd_soc_codec *codec); +extern int aqt_mbhc_hs_detect(struct snd_soc_codec *codec, + struct wcd_mbhc_config *mbhc_cfg); +extern void aqt_mbhc_deinit(struct snd_soc_codec *codec); +extern int aqt_mbhc_post_ssr_init(struct aqt_mbhc *mbhc, + struct snd_soc_codec *codec); +extern int aqt_mbhc_get_impedance(struct aqt_mbhc *aqt_mbhc, + uint32_t *zl, uint32_t *zr); +#else +static inline int aqt_mbhc_init(struct aqt_mbhc **mbhc, + struct snd_soc_codec *codec, + struct fw_info *fw_data) +{ + return 0; +} +static inline void aqt_mbhc_hs_detect_exit(struct snd_soc_codec *codec) +{ +} +static inline int aqt_mbhc_hs_detect(struct snd_soc_codec *codec, + struct wcd_mbhc_config *mbhc_cfg) +{ + return 0; +} +static inline void aqt_mbhc_deinit(struct snd_soc_codec *codec) +{ +} +static inline int aqt_mbhc_post_ssr_init(struct aqt_mbhc *mbhc, + struct snd_soc_codec *codec) +{ + return 0; +} +static inline int aqt_mbhc_get_impedance(struct aqt_mbhc *aqt_mbhc, + uint32_t *zl, uint32_t *zr) +{ + if (zl) + *zl = 0; + if (zr) + *zr = 0; + return -EINVAL; +} +#endif + +#endif /* __AQT_MBHC_H__ */ diff --git a/asoc/codecs/aqt1000/aqt1000-reg-defaults.h b/asoc/codecs/aqt1000/aqt1000-reg-defaults.h new file mode 100644 index 0000000000..5a5da25fa7 --- /dev/null +++ b/asoc/codecs/aqt1000/aqt1000-reg-defaults.h @@ -0,0 +1,1616 @@ +/* Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _AQT1000_REG_DEFAULTS_H +#define _AQT1000_REG_DEFAULTS_H + +#include +#include "aqt1000-registers.h" + +#define AQT1000_REG(reg) ((reg) & 0xFF) +#define AQT1000_PAGE_SIZE 256 + +enum { + AQT1000_PAGE_0 = 0, + AQT1000_PAGE_1, + AQT1000_PAGE_2, + AQT1000_PAGE_5 = 5, + AQT1000_PAGE_6, + AQT1000_PAGE_7, + AQT1000_PAGE_10 = 0xA, + AQT1000_PAGE_11, + AQT1000_PAGE_12, + AQT1000_PAGE_13, + AQT1000_PAGE_15 = 0xF, + AQT1000_PAGE_128, + AQT1000_PAGE_MAX, +}; + +enum { + AQT1000_WO = 0, + AQT1000_RO, + AQT1000_RW, +}; + +static const struct reg_default aqt1000_defaults[] = { + {AQT1000_CHIP_CFG1_PWR_MEM_SD, 0x07}, + {AQT1000_CHIP_CFG1_PWR_SYS_MEM_SD_RAM, 0x00}, + {AQT1000_CHIP_CFG1_PWR_SYS_MEM_SD_ROM, 0x00}, + {AQT1000_CHIP_CFG1_PWR_SYS_MEM_FORCE_DS_RAM, 0x00}, + {AQT1000_CHIP_CFG1_PWR_SYS_MEM_FORCE_DS_ROM, 0x00}, + {AQT1000_CHIP_CFG1_CLK_CFG_FLL, 0x20}, + {AQT1000_CHIP_CFG1_CLK_CFG_SPI_M, 0x01}, + {AQT1000_CHIP_CFG1_CLK_CFG_I2C_M, 0x01}, + {AQT1000_CHIP_CFG1_CLK_CFG_UART, 0x01}, + {AQT1000_CHIP_CFG1_RST_USB_SS, 0x0E}, + {AQT1000_CHIP_CFG1_RST_BLSP, 0x0F}, + {AQT1000_CHIP_CFG1_RST_BUS_MTRX, 0x00}, + {AQT1000_CHIP_CFG1_RST_MISC, 0x00}, + {AQT1000_CHIP_CFG1_ANA_WAIT_STATE_CTL, 0xCC}, + {AQT1000_PAGE1_PAGE_REGISTER, 0x00}, + {AQT1000_FLL_USER_CTL_0, 0x71}, + {AQT1000_FLL_USER_CTL_1, 0x34}, + {AQT1000_FLL_USER_CTL_2, 0x0B}, + {AQT1000_FLL_USER_CTL_3, 0x02}, + {AQT1000_FLL_USER_CTL_4, 0x04}, + {AQT1000_FLL_USER_CTL_5, 0x02}, + {AQT1000_FLL_USER_CTL_6, 0x6E}, + {AQT1000_FLL_USER_CTL_7, 0x00}, + {AQT1000_FLL_USER_CTL_8, 0x94}, + {AQT1000_FLL_USER_CTL_9, 0x70}, + {AQT1000_FLL_L_VAL_CTL_0, 0x34}, + {AQT1000_FLL_L_VAL_CTL_1, 0x00}, + {AQT1000_FLL_DSM_FRAC_CTL_0, 0x00}, + {AQT1000_FLL_DSM_FRAC_CTL_1, 0xFF}, + {AQT1000_FLL_CONFIG_CTL_0, 0x6B}, + {AQT1000_FLL_CONFIG_CTL_1, 0x05}, + {AQT1000_FLL_CONFIG_CTL_2, 0x08}, + {AQT1000_FLL_CONFIG_CTL_3, 0x00}, + {AQT1000_FLL_CONFIG_CTL_4, 0x10}, + {AQT1000_FLL_TEST_CTL_0, 0x80}, + {AQT1000_FLL_TEST_CTL_1, 0x00}, + {AQT1000_FLL_TEST_CTL_2, 0x00}, + {AQT1000_FLL_TEST_CTL_3, 0x00}, + {AQT1000_FLL_TEST_CTL_4, 0x00}, + {AQT1000_FLL_TEST_CTL_5, 0x00}, + {AQT1000_FLL_TEST_CTL_6, 0x04}, + {AQT1000_FLL_TEST_CTL_7, 0x33}, + {AQT1000_FLL_FREQ_CTL_0, 0x00}, + {AQT1000_FLL_FREQ_CTL_1, 0x00}, + {AQT1000_FLL_FREQ_CTL_2, 0x00}, + {AQT1000_FLL_FREQ_CTL_3, 0x00}, + {AQT1000_FLL_SSC_CTL_0, 0x00}, + {AQT1000_FLL_SSC_CTL_1, 0x00}, + {AQT1000_FLL_SSC_CTL_2, 0x00}, + {AQT1000_FLL_SSC_CTL_3, 0x00}, + {AQT1000_FLL_FLL_MODE, 0xA0}, + {AQT1000_FLL_STATUS_0, 0x00}, + {AQT1000_FLL_STATUS_1, 0x00}, + {AQT1000_FLL_STATUS_2, 0x00}, + {AQT1000_FLL_STATUS_3, 0x00}, + {AQT1000_PAGE2_PAGE_REGISTER, 0x00}, + {AQT1000_I2S_I2S_0_TX_CFG, 0x00}, + {AQT1000_I2S_I2S_0_RX_CFG, 0x00}, + {AQT1000_I2S_I2S_0_CTL, 0x0C}, + {AQT1000_I2S_I2S_CLKSRC_CTL, 0x01}, + {AQT1000_I2S_I2S_HS_CLK_CTL, 0x00}, + {AQT1000_I2S_I2S_0_RST, 0x00}, + {AQT1000_I2S_SHADOW_I2S_0_CTL, 0x00}, + {AQT1000_I2S_SHADOW_I2S_0_RX_CFG, 0x09}, + {AQT1000_PAGE5_PAGE_REGISTER, 0x00}, + {AQT1000_INTR_CTRL_MCU_INT_POLARITY, 0x00}, + {AQT1000_INTR_CTRL_INT_MASK_0, 0xFE}, + {AQT1000_INTR_CTRL_INT_MASK_1, 0xFF}, + {AQT1000_INTR_CTRL_INT_MASK_2, 0xFF}, + {AQT1000_INTR_CTRL_INT_MASK_3, 0xEF}, + {AQT1000_INTR_CTRL_INT_MASK_4, 0x3B}, + {AQT1000_INTR_CTRL_INT_MASK_5, 0xFF}, + {AQT1000_INTR_CTRL_INT_MASK_6, 0x3F}, + {AQT1000_INTR_CTRL_INT_STATUS_0, 0x00}, + {AQT1000_INTR_CTRL_INT_STATUS_1, 0x00}, + {AQT1000_INTR_CTRL_INT_STATUS_2, 0x00}, + {AQT1000_INTR_CTRL_INT_STATUS_3, 0x00}, + {AQT1000_INTR_CTRL_INT_STATUS_4, 0x00}, + {AQT1000_INTR_CTRL_INT_STATUS_5, 0x00}, + {AQT1000_INTR_CTRL_INT_STATUS_6, 0x00}, + {AQT1000_INTR_CTRL_INT_CLEAR_0, 0x00}, + {AQT1000_INTR_CTRL_INT_CLEAR_1, 0x00}, + {AQT1000_INTR_CTRL_INT_CLEAR_2, 0x00}, + {AQT1000_INTR_CTRL_INT_CLEAR_3, 0x00}, + {AQT1000_INTR_CTRL_INT_CLEAR_4, 0x00}, + {AQT1000_INTR_CTRL_INT_CLEAR_5, 0x00}, + {AQT1000_INTR_CTRL_INT_CLEAR_6, 0x00}, + {AQT1000_INTR_CTRL_INT_TYPE_0, 0xEF}, + {AQT1000_INTR_CTRL_INT_TYPE_1, 0x03}, + {AQT1000_INTR_CTRL_INT_TYPE_2, 0x00}, + {AQT1000_INTR_CTRL_INT_TYPE_3, 0x20}, + {AQT1000_INTR_CTRL_INT_TYPE_4, 0x44}, + {AQT1000_INTR_CTRL_INT_TYPE_5, 0x00}, + {AQT1000_INTR_CTRL_INT_TYPE_6, 0x00}, + {AQT1000_INTR_CTRL_INT_TEST_EN_0, 0x00}, + {AQT1000_INTR_CTRL_INT_TEST_EN_1, 0x00}, + {AQT1000_INTR_CTRL_INT_TEST_EN_2, 0x00}, + {AQT1000_INTR_CTRL_INT_TEST_EN_3, 0x00}, + {AQT1000_INTR_CTRL_INT_TEST_EN_4, 0x00}, + {AQT1000_INTR_CTRL_INT_TEST_EN_5, 0x00}, + {AQT1000_INTR_CTRL_INT_TEST_EN_6, 0x00}, + {AQT1000_INTR_CTRL_INT_TEST_VAL_0, 0x00}, + {AQT1000_INTR_CTRL_INT_TEST_VAL_1, 0x00}, + {AQT1000_INTR_CTRL_INT_TEST_VAL_2, 0x00}, + {AQT1000_INTR_CTRL_INT_TEST_VAL_3, 0x00}, + {AQT1000_INTR_CTRL_INT_TEST_VAL_4, 0x00}, + {AQT1000_INTR_CTRL_INT_TEST_VAL_5, 0x00}, + {AQT1000_INTR_CTRL_INT_TEST_VAL_6, 0x00}, + {AQT1000_INTR_CTRL_INT_DEST_0, 0x02}, + {AQT1000_INTR_CTRL_INT_DEST_1, 0x00}, + {AQT1000_INTR_CTRL_INT_DEST_2, 0x00}, + {AQT1000_INTR_CTRL_INT_DEST_3, 0x00}, + {AQT1000_INTR_CTRL_INT_DEST_4, 0x00}, + {AQT1000_INTR_CTRL_INT_DEST_5, 0x00}, + {AQT1000_INTR_CTRL_INT_DEST_6, 0x00}, + {AQT1000_INTR_CTRL_INT_DEST_7, 0x00}, + {AQT1000_INTR_CTRL_INT_DEST_8, 0x00}, + {AQT1000_INTR_CTRL_INT_DEST_9, 0x00}, + {AQT1000_INTR_CTRL_INT_DEST_10, 0x00}, + {AQT1000_INTR_CTRL_INT_DEST_11, 0x00}, + {AQT1000_INTR_CTRL_INT_DEST_12, 0x00}, + {AQT1000_INTR_CTRL_INT_DEST_13, 0x00}, + {AQT1000_INTR_CTRL_CLR_COMMIT, 0x00}, + {AQT1000_ANA_PAGE_REGISTER, 0x00}, + {AQT1000_ANA_BIAS, 0x00}, + {AQT1000_ANA_RX_SUPPLIES, 0x00}, + {AQT1000_ANA_HPH, 0x0C}, + {AQT1000_ANA_AMIC1, 0x20}, + {AQT1000_ANA_AMIC2, 0x00}, + {AQT1000_ANA_AMIC3, 0x20}, + {AQT1000_ANA_AMIC3_HPF, 0x00}, + {AQT1000_ANA_MBHC_MECH, 0x39}, + {AQT1000_ANA_MBHC_ELECT, 0x08}, + {AQT1000_ANA_MBHC_ZDET, 0x00}, + {AQT1000_ANA_MBHC_RESULT_1, 0x00}, + {AQT1000_ANA_MBHC_RESULT_2, 0x00}, + {AQT1000_ANA_MBHC_RESULT_3, 0x00}, + {AQT1000_ANA_MBHC_BTN0, 0x00}, + {AQT1000_ANA_MBHC_BTN1, 0x10}, + {AQT1000_ANA_MBHC_BTN2, 0x20}, + {AQT1000_ANA_MBHC_BTN3, 0x30}, + {AQT1000_ANA_MBHC_BTN4, 0x40}, + {AQT1000_ANA_MBHC_BTN5, 0x50}, + {AQT1000_ANA_MBHC_BTN6, 0x60}, + {AQT1000_ANA_MBHC_BTN7, 0x70}, + {AQT1000_ANA_MICB1, 0x10}, + {AQT1000_ANA_MICB1_RAMP, 0x00}, + {AQT1000_BIAS_CTL, 0x28}, + {AQT1000_BIAS_CCOMP_FINE_ADJ, 0x75}, + {AQT1000_LED_LED_MODE_SEL_R, 0x00}, + {AQT1000_LED_LED_MISC_R, 0x00}, + {AQT1000_LED_LED_MODE_SEL_G, 0x00}, + {AQT1000_LED_LED_MISC_G, 0x00}, + {AQT1000_LED_LED_MODE_SEL_B, 0x00}, + {AQT1000_LED_LED_MISC_B, 0x00}, + {AQT1000_LDOH_MODE, 0x1D}, + {AQT1000_LDOH_BIAS, 0x00}, + {AQT1000_LDOH_STB_LOADS, 0x00}, + {AQT1000_LDOH_MISC1, 0x00}, + {AQT1000_LDOL_VDDCX_ADJUST, 0x01}, + {AQT1000_LDOL_DISABLE_LDOL, 0x00}, + {AQT1000_BUCK_5V_EN_CTL, 0x03}, + {AQT1000_BUCK_5V_VOUT_SEL, 0x03}, + {AQT1000_BUCK_5V_CTRL_VCL_1, 0x03}, + {AQT1000_BUCK_5V_CTRL_VCL_2, 0x21}, + {AQT1000_BUCK_5V_CTRL_CCL_2, 0x20}, + {AQT1000_BUCK_5V_CTRL_CCL_1, 0xA1}, + {AQT1000_BUCK_5V_CTRL_CCL_3, 0x02}, + {AQT1000_BUCK_5V_CTRL_CCL_4, 0x05}, + {AQT1000_BUCK_5V_CTRL_CCL_5, 0x00}, + {AQT1000_BUCK_5V_IBIAS_CTL_1, 0x37}, + {AQT1000_BUCK_5V_IBIAS_CTL_2, 0x00}, + {AQT1000_BUCK_5V_IBIAS_CTL_3, 0x33}, + {AQT1000_BUCK_5V_IBIAS_CTL_4, 0x33}, + {AQT1000_BUCK_5V_IBIAS_CTL_5, 0x00}, + {AQT1000_BUCK_5V_ATEST_DTEST_CTL, 0x00}, + {AQT1000_PON_BG_CTRL, 0x80}, + {AQT1000_PON_TEST_CTRL, 0x00}, + {AQT1000_MBHC_CTL_CLK, 0x30}, + {AQT1000_MBHC_CTL_ANA, 0x00}, + {AQT1000_MBHC_CTL_SPARE_1, 0x00}, + {AQT1000_MBHC_CTL_SPARE_2, 0x00}, + {AQT1000_MBHC_CTL_BCS, 0x00}, + {AQT1000_MBHC_MOISTURE_DET_FSM_STATUS, 0x00}, + {AQT1000_MBHC_TEST_CTL, 0x00}, + {AQT1000_MICB1_TEST_CTL_1, 0x1A}, + {AQT1000_MICB1_TEST_CTL_2, 0x18}, + {AQT1000_MICB1_TEST_CTL_3, 0xA4}, + {AQT1000_MICB1_MISC_MICB1_INM_RES_BIAS, 0x00}, + {AQT1000_MICB1_MISC_MICB_MISC1, 0x00}, + {AQT1000_MICB1_MISC_MICB_MISC2, 0x00}, + {AQT1000_TX_COM_ADC_VCM, 0x39}, + {AQT1000_TX_COM_BIAS_ATEST, 0xC0}, + {AQT1000_TX_COM_ADC_INT1_IB, 0x6F}, + {AQT1000_TX_COM_ADC_INT2_IB, 0x4F}, + {AQT1000_TX_COM_TXFE_DIV_CTL, 0x2E}, + {AQT1000_TX_COM_TXFE_DIV_START, 0x00}, + {AQT1000_TX_COM_TXFE_DIV_STOP_9P6M, 0xC7}, + {AQT1000_TX_COM_TXFE_DIV_STOP_12P288M, 0xFF}, + {AQT1000_TX_1_2_TEST_EN, 0xCC}, + {AQT1000_TX_1_2_ADC_IB, 0x09}, + {AQT1000_TX_1_2_ATEST_REFCTL, 0x0A}, + {AQT1000_TX_1_2_TEST_CTL, 0x38}, + {AQT1000_TX_1_2_TEST_BLK_EN, 0xFF}, + {AQT1000_TX_1_2_TXFE_CLKDIV, 0x00}, + {AQT1000_TX_1_2_SAR1_ERR, 0x00}, + {AQT1000_TX_1_2_SAR2_ERR, 0x00}, + {AQT1000_TX_3_TEST_EN, 0xC0}, + {AQT1000_TX_3_ADC_IB, 0x09}, + {AQT1000_TX_3_ATEST_REFCTL, 0x0A}, + {AQT1000_TX_3_TEST_CTL, 0x38}, + {AQT1000_TX_3_TEST_BLK_EN, 0xFE}, + {AQT1000_TX_3_TXFE_CLKDIV, 0x00}, + {AQT1000_TX_3_SAR1_ERR, 0x00}, + {AQT1000_TX_3_SAR2_ERR, 0x00}, + {AQT1000_TX_ATEST1_2_SEL, 0x60}, + {AQT1000_CLASSH_MODE_1, 0x40}, + {AQT1000_CLASSH_MODE_2, 0x3A}, + {AQT1000_CLASSH_MODE_3, 0x00}, + {AQT1000_CLASSH_CTRL_VCL_1, 0x70}, + {AQT1000_CLASSH_CTRL_VCL_2, 0x82}, + {AQT1000_CLASSH_CTRL_CCL_1, 0x31}, + {AQT1000_CLASSH_CTRL_CCL_2, 0x80}, + {AQT1000_CLASSH_CTRL_CCL_3, 0x80}, + {AQT1000_CLASSH_CTRL_CCL_4, 0x51}, + {AQT1000_CLASSH_CTRL_CCL_5, 0x00}, + {AQT1000_CLASSH_BUCK_TMUX_A_D, 0x00}, + {AQT1000_CLASSH_BUCK_SW_DRV_CNTL, 0x77}, + {AQT1000_CLASSH_SPARE, 0x00}, + {AQT1000_FLYBACK_EN, 0x4E}, + {AQT1000_FLYBACK_VNEG_CTRL_1, 0x0B}, + {AQT1000_FLYBACK_VNEG_CTRL_2, 0x45}, + {AQT1000_FLYBACK_VNEG_CTRL_3, 0x74}, + {AQT1000_FLYBACK_VNEG_CTRL_4, 0x7F}, + {AQT1000_FLYBACK_VNEG_CTRL_5, 0x83}, + {AQT1000_FLYBACK_VNEG_CTRL_6, 0x98}, + {AQT1000_FLYBACK_VNEG_CTRL_7, 0xA9}, + {AQT1000_FLYBACK_VNEG_CTRL_8, 0x68}, + {AQT1000_FLYBACK_VNEG_CTRL_9, 0x64}, + {AQT1000_FLYBACK_VNEGDAC_CTRL_1, 0xED}, + {AQT1000_FLYBACK_VNEGDAC_CTRL_2, 0xF0}, + {AQT1000_FLYBACK_VNEGDAC_CTRL_3, 0xA6}, + {AQT1000_FLYBACK_CTRL_1, 0x65}, + {AQT1000_FLYBACK_TEST_CTL, 0x00}, + {AQT1000_RX_AUX_SW_CTL, 0x00}, + {AQT1000_RX_PA_AUX_IN_CONN, 0x00}, + {AQT1000_RX_TIMER_DIV, 0x32}, + {AQT1000_RX_OCP_CTL, 0x1F}, + {AQT1000_RX_OCP_COUNT, 0x77}, + {AQT1000_RX_BIAS_ATEST, 0x00}, + {AQT1000_RX_BIAS_MISC1, 0xAA}, + {AQT1000_RX_BIAS_HPH_LDO, 0xA9}, + {AQT1000_RX_BIAS_HPH_PA, 0xAA}, + {AQT1000_RX_BIAS_HPH_RDACBUFF_CNP2, 0x8A}, + {AQT1000_RX_BIAS_HPH_RDAC_LDO, 0x88}, + {AQT1000_RX_BIAS_HPH_CNP1, 0x82}, + {AQT1000_RX_BIAS_HPH_LOWPOWER, 0x82}, + {AQT1000_RX_BIAS_MISC2, 0x80}, + {AQT1000_RX_BIAS_MISC3, 0x88}, + {AQT1000_RX_BIAS_MISC4, 0x88}, + {AQT1000_RX_BIAS_MISC5, 0xA8}, + {AQT1000_RX_BIAS_BUCK_RST, 0x08}, + {AQT1000_RX_BIAS_BUCK_VREF_ERRAMP, 0x44}, + {AQT1000_RX_BIAS_FLYB_ERRAMP, 0x40}, + {AQT1000_RX_BIAS_FLYB_BUFF, 0xAA}, + {AQT1000_RX_BIAS_FLYB_MID_RST, 0x14}, + {AQT1000_HPH_L_STATUS, 0x04}, + {AQT1000_HPH_R_STATUS, 0x04}, + {AQT1000_HPH_CNP_EN, 0x80}, + {AQT1000_HPH_CNP_WG_CTL, 0x9A}, + {AQT1000_HPH_CNP_WG_TIME, 0x14}, + {AQT1000_HPH_OCP_CTL, 0x28}, + {AQT1000_HPH_AUTO_CHOP, 0x16}, + {AQT1000_HPH_CHOP_CTL, 0x83}, + {AQT1000_HPH_PA_CTL1, 0x46}, + {AQT1000_HPH_PA_CTL2, 0x50}, + {AQT1000_HPH_L_EN, 0x80}, + {AQT1000_HPH_L_TEST, 0xE0}, + {AQT1000_HPH_L_ATEST, 0x50}, + {AQT1000_HPH_R_EN, 0x80}, + {AQT1000_HPH_R_TEST, 0xE0}, + {AQT1000_HPH_R_ATEST, 0x54}, + {AQT1000_HPH_RDAC_CLK_CTL1, 0x99}, + {AQT1000_HPH_RDAC_CLK_CTL2, 0x9B}, + {AQT1000_HPH_RDAC_LDO_CTL, 0x33}, + {AQT1000_HPH_RDAC_CHOP_CLK_LP_CTL, 0x00}, + {AQT1000_HPH_REFBUFF_UHQA_CTL, 0xA8}, + {AQT1000_HPH_REFBUFF_LP_CTL, 0x0E}, + {AQT1000_HPH_L_DAC_CTL, 0x00}, + {AQT1000_HPH_R_DAC_CTL, 0x00}, + {AQT1000_HPHLR_SURGE_COMP_SEL, 0x55}, + {AQT1000_HPHLR_SURGE_EN, 0x1D}, + {AQT1000_HPHLR_SURGE_MISC1, 0xA0}, + {AQT1000_HPHLR_SURGE_STATUS, 0x00}, + {AQT1000_ANA_NEW_PAGE_REGISTER, 0x00}, + {AQT1000_HPH_NEW_ANA_HPH2, 0x00}, + {AQT1000_HPH_NEW_ANA_HPH3, 0x00}, + {AQT1000_CLK_SYS_MCLK1_PRG, 0x09}, + {AQT1000_CLK_SYS_MCLK2_I2S_HS_CLK_PRG, 0x20}, + {AQT1000_CLK_SYS_XO_CAP_XTP, 0x3F}, + {AQT1000_CLK_SYS_XO_CAP_XTM, 0x3F}, + {AQT1000_CLK_SYS_PLL_ENABLES, 0x00}, + {AQT1000_CLK_SYS_PLL_PRESET, 0x00}, + {AQT1000_CLK_SYS_PLL_STATUS, 0x00}, + {AQT1000_MBHC_NEW_ELECT_REM_CLAMP_CTL, 0x00}, + {AQT1000_MBHC_NEW_CTL_1, 0x02}, + {AQT1000_MBHC_NEW_CTL_2, 0x05}, + {AQT1000_MBHC_NEW_PLUG_DETECT_CTL, 0x29}, + {AQT1000_MBHC_NEW_ZDET_ANA_CTL, 0x0F}, + {AQT1000_MBHC_NEW_ZDET_RAMP_CTL, 0x00}, + {AQT1000_MBHC_NEW_FSM_STATUS, 0x00}, + {AQT1000_MBHC_NEW_ADC_RESULT, 0x00}, + {AQT1000_HPH_NEW_INT_RDAC_GAIN_CTL, 0x40}, + {AQT1000_HPH_NEW_INT_RDAC_HD2_CTL_L, 0x81}, + {AQT1000_HPH_NEW_INT_RDAC_VREF_CTL, 0x10}, + {AQT1000_HPH_NEW_INT_RDAC_OVERRIDE_CTL, 0x00}, + {AQT1000_HPH_NEW_INT_RDAC_HD2_CTL_R, 0x81}, + {AQT1000_HPH_NEW_INT_PA_MISC1, 0x22}, + {AQT1000_HPH_NEW_INT_PA_MISC2, 0x00}, + {AQT1000_HPH_NEW_INT_PA_RDAC_MISC, 0x00}, + {AQT1000_HPH_NEW_INT_HPH_TIMER1, 0xFE}, + {AQT1000_HPH_NEW_INT_HPH_TIMER2, 0x02}, + {AQT1000_HPH_NEW_INT_HPH_TIMER3, 0x4E}, + {AQT1000_HPH_NEW_INT_HPH_TIMER4, 0x54}, + {AQT1000_HPH_NEW_INT_PA_RDAC_MISC2, 0x80}, + {AQT1000_HPH_NEW_INT_PA_RDAC_MISC3, 0x00}, + {AQT1000_RX_NEW_INT_HPH_RDAC_BIAS_LOHIFI, 0x62}, + {AQT1000_RX_NEW_INT_HPH_RDAC_BIAS_ULP, 0x01}, + {AQT1000_RX_NEW_INT_HPH_RDAC_LDO_LP, 0x11}, + {AQT1000_CLK_SYS_INT_CLK_TEST1, 0x00}, + {AQT1000_CLK_SYS_INT_XO_TEST1, 0x98}, + {AQT1000_CLK_SYS_INT_XO_TEST2, 0x00}, + {AQT1000_CLK_SYS_INT_POST_DIV_REG0, 0x00}, + {AQT1000_CLK_SYS_INT_POST_DIV_REG1, 0x00}, + {AQT1000_CLK_SYS_INT_REF_DIV_REG0, 0x00}, + {AQT1000_CLK_SYS_INT_REF_DIV_REG1, 0x00}, + {AQT1000_CLK_SYS_INT_FILTER_REG0, 0x00}, + {AQT1000_CLK_SYS_INT_FILTER_REG1, 0x00}, + {AQT1000_CLK_SYS_INT_PLL_L_VAL, 0x00}, + {AQT1000_CLK_SYS_INT_PLL_M_VAL, 0x00}, + {AQT1000_CLK_SYS_INT_PLL_N_VAL, 0x00}, + {AQT1000_CLK_SYS_INT_TEST_REG0, 0x00}, + {AQT1000_CLK_SYS_INT_PFD_CP_DSM_PROG, 0x00}, + {AQT1000_CLK_SYS_INT_VCO_PROG, 0x00}, + {AQT1000_CLK_SYS_INT_TEST_REG1, 0x00}, + {AQT1000_CLK_SYS_INT_LDO_LOCK_CFG, 0x00}, + {AQT1000_CLK_SYS_INT_DIG_LOCK_DET_CFG, 0x00}, + {AQT1000_MBHC_NEW_INT_MOISTURE_DET_DC_CTRL, 0x57}, + {AQT1000_MBHC_NEW_INT_MOISTURE_DET_POLLING_CTRL, 0x01}, + {AQT1000_MBHC_NEW_INT_MECH_DET_CURRENT, 0x00}, + {AQT1000_MBHC_NEW_INT_SPARE_2, 0x00}, + {AQT1000_PAGE10_PAGE_REGISTER, 0x00}, + {AQT1000_CDC_ANC0_CLK_RESET_CTL, 0x00}, + {AQT1000_CDC_ANC0_MODE_1_CTL, 0x00}, + {AQT1000_CDC_ANC0_MODE_2_CTL, 0x00}, + {AQT1000_CDC_ANC0_FF_SHIFT, 0x00}, + {AQT1000_CDC_ANC0_FB_SHIFT, 0x00}, + {AQT1000_CDC_ANC0_LPF_FF_A_CTL, 0x00}, + {AQT1000_CDC_ANC0_LPF_FF_B_CTL, 0x00}, + {AQT1000_CDC_ANC0_LPF_FB_CTL, 0x00}, + {AQT1000_CDC_ANC0_SMLPF_CTL, 0x00}, + {AQT1000_CDC_ANC0_DCFLT_SHIFT_CTL, 0x00}, + {AQT1000_CDC_ANC0_IIR_ADAPT_CTL, 0x00}, + {AQT1000_CDC_ANC0_IIR_COEFF_1_CTL, 0x00}, + {AQT1000_CDC_ANC0_IIR_COEFF_2_CTL, 0x00}, + {AQT1000_CDC_ANC0_FF_A_GAIN_CTL, 0x00}, + {AQT1000_CDC_ANC0_FF_B_GAIN_CTL, 0x00}, + {AQT1000_CDC_ANC0_FB_GAIN_CTL, 0x00}, + {AQT1000_CDC_ANC0_RC_COMMON_CTL, 0x00}, + {AQT1000_CDC_ANC0_FIFO_COMMON_CTL, 0x88}, + {AQT1000_CDC_ANC0_RC0_STATUS_FMIN_CNTR, 0x00}, + {AQT1000_CDC_ANC0_RC1_STATUS_FMIN_CNTR, 0x00}, + {AQT1000_CDC_ANC0_RC0_STATUS_FMAX_CNTR, 0x00}, + {AQT1000_CDC_ANC0_RC1_STATUS_FMAX_CNTR, 0x00}, + {AQT1000_CDC_ANC0_STATUS_FIFO, 0x00}, + {AQT1000_CDC_ANC1_CLK_RESET_CTL, 0x00}, + {AQT1000_CDC_ANC1_MODE_1_CTL, 0x00}, + {AQT1000_CDC_ANC1_MODE_2_CTL, 0x00}, + {AQT1000_CDC_ANC1_FF_SHIFT, 0x00}, + {AQT1000_CDC_ANC1_FB_SHIFT, 0x00}, + {AQT1000_CDC_ANC1_LPF_FF_A_CTL, 0x00}, + {AQT1000_CDC_ANC1_LPF_FF_B_CTL, 0x00}, + {AQT1000_CDC_ANC1_LPF_FB_CTL, 0x00}, + {AQT1000_CDC_ANC1_SMLPF_CTL, 0x00}, + {AQT1000_CDC_ANC1_DCFLT_SHIFT_CTL, 0x00}, + {AQT1000_CDC_ANC1_IIR_ADAPT_CTL, 0x00}, + {AQT1000_CDC_ANC1_IIR_COEFF_1_CTL, 0x00}, + {AQT1000_CDC_ANC1_IIR_COEFF_2_CTL, 0x00}, + {AQT1000_CDC_ANC1_FF_A_GAIN_CTL, 0x00}, + {AQT1000_CDC_ANC1_FF_B_GAIN_CTL, 0x00}, + {AQT1000_CDC_ANC1_FB_GAIN_CTL, 0x00}, + {AQT1000_CDC_ANC1_RC_COMMON_CTL, 0x00}, + {AQT1000_CDC_ANC1_FIFO_COMMON_CTL, 0x88}, + {AQT1000_CDC_ANC1_RC0_STATUS_FMIN_CNTR, 0x00}, + {AQT1000_CDC_ANC1_RC1_STATUS_FMIN_CNTR, 0x00}, + {AQT1000_CDC_ANC1_RC0_STATUS_FMAX_CNTR, 0x00}, + {AQT1000_CDC_ANC1_RC1_STATUS_FMAX_CNTR, 0x00}, + {AQT1000_CDC_ANC1_STATUS_FIFO, 0x00}, + {AQT1000_CDC_TX0_TX_PATH_CTL, 0x04}, + {AQT1000_CDC_TX0_TX_PATH_CFG0, 0x10}, + {AQT1000_CDC_TX0_TX_PATH_CFG1, 0x03}, + {AQT1000_CDC_TX0_TX_VOL_CTL, 0x00}, + {AQT1000_CDC_TX0_TX_PATH_SEC0, 0x00}, + {AQT1000_CDC_TX0_TX_PATH_SEC1, 0x00}, + {AQT1000_CDC_TX0_TX_PATH_SEC2, 0x01}, + {AQT1000_CDC_TX0_TX_PATH_SEC3, 0x3C}, + {AQT1000_CDC_TX0_TX_PATH_SEC4, 0x20}, + {AQT1000_CDC_TX0_TX_PATH_SEC5, 0x00}, + {AQT1000_CDC_TX0_TX_PATH_SEC6, 0x00}, + {AQT1000_CDC_TX1_TX_PATH_CTL, 0x04}, + {AQT1000_CDC_TX1_TX_PATH_CFG0, 0x10}, + {AQT1000_CDC_TX1_TX_PATH_CFG1, 0x03}, + {AQT1000_CDC_TX1_TX_VOL_CTL, 0x00}, + {AQT1000_CDC_TX1_TX_PATH_SEC0, 0x00}, + {AQT1000_CDC_TX1_TX_PATH_SEC1, 0x00}, + {AQT1000_CDC_TX1_TX_PATH_SEC2, 0x01}, + {AQT1000_CDC_TX1_TX_PATH_SEC3, 0x3C}, + {AQT1000_CDC_TX1_TX_PATH_SEC4, 0x20}, + {AQT1000_CDC_TX1_TX_PATH_SEC5, 0x00}, + {AQT1000_CDC_TX1_TX_PATH_SEC6, 0x00}, + {AQT1000_CDC_TX2_TX_PATH_CTL, 0x04}, + {AQT1000_CDC_TX2_TX_PATH_CFG0, 0x10}, + {AQT1000_CDC_TX2_TX_PATH_CFG1, 0x03}, + {AQT1000_CDC_TX2_TX_VOL_CTL, 0x00}, + {AQT1000_CDC_TX2_TX_PATH_SEC0, 0x00}, + {AQT1000_CDC_TX2_TX_PATH_SEC1, 0x00}, + {AQT1000_CDC_TX2_TX_PATH_SEC2, 0x01}, + {AQT1000_CDC_TX2_TX_PATH_SEC3, 0x3C}, + {AQT1000_CDC_TX2_TX_PATH_SEC4, 0x20}, + {AQT1000_CDC_TX2_TX_PATH_SEC5, 0x00}, + {AQT1000_CDC_TX2_TX_PATH_SEC6, 0x00}, + {AQT1000_CDC_TX2_TX_PATH_SEC7, 0x25}, + {AQT1000_PAGE11_PAGE_REGISTER, 0x00}, + {AQT1000_CDC_COMPANDER1_CTL0, 0x60}, + {AQT1000_CDC_COMPANDER1_CTL1, 0xDB}, + {AQT1000_CDC_COMPANDER1_CTL2, 0xFF}, + {AQT1000_CDC_COMPANDER1_CTL3, 0x35}, + {AQT1000_CDC_COMPANDER1_CTL4, 0xFF}, + {AQT1000_CDC_COMPANDER1_CTL5, 0x00}, + {AQT1000_CDC_COMPANDER1_CTL6, 0x01}, + {AQT1000_CDC_COMPANDER1_CTL7, 0x26}, + {AQT1000_CDC_COMPANDER2_CTL0, 0x60}, + {AQT1000_CDC_COMPANDER2_CTL1, 0xDB}, + {AQT1000_CDC_COMPANDER2_CTL2, 0xFF}, + {AQT1000_CDC_COMPANDER2_CTL3, 0x35}, + {AQT1000_CDC_COMPANDER2_CTL4, 0xFF}, + {AQT1000_CDC_COMPANDER2_CTL5, 0x00}, + {AQT1000_CDC_COMPANDER2_CTL6, 0x01}, + {AQT1000_CDC_COMPANDER2_CTL7, 0x26}, + {AQT1000_CDC_RX1_RX_PATH_CTL, 0x04}, + {AQT1000_CDC_RX1_RX_PATH_CFG0, 0x00}, + {AQT1000_CDC_RX1_RX_PATH_CFG1, 0x64}, + {AQT1000_CDC_RX1_RX_PATH_CFG2, 0x8F}, + {AQT1000_CDC_RX1_RX_VOL_CTL, 0x00}, + {AQT1000_CDC_RX1_RX_PATH_MIX_CTL, 0x04}, + {AQT1000_CDC_RX1_RX_PATH_MIX_CFG, 0x7E}, + {AQT1000_CDC_RX1_RX_VOL_MIX_CTL, 0x00}, + {AQT1000_CDC_RX1_RX_PATH_SEC0, 0xFC}, + {AQT1000_CDC_RX1_RX_PATH_SEC1, 0x08}, + {AQT1000_CDC_RX1_RX_PATH_SEC2, 0x00}, + {AQT1000_CDC_RX1_RX_PATH_SEC3, 0x00}, + {AQT1000_CDC_RX1_RX_PATH_SEC4, 0x00}, + {AQT1000_CDC_RX1_RX_PATH_SEC5, 0x00}, + {AQT1000_CDC_RX1_RX_PATH_SEC6, 0x00}, + {AQT1000_CDC_RX1_RX_PATH_SEC7, 0x00}, + {AQT1000_CDC_RX1_RX_PATH_MIX_SEC0, 0x08}, + {AQT1000_CDC_RX1_RX_PATH_MIX_SEC1, 0x00}, + {AQT1000_CDC_RX1_RX_PATH_DSMDEM_CTL, 0x00}, + {AQT1000_CDC_RX2_RX_PATH_CTL, 0x04}, + {AQT1000_CDC_RX2_RX_PATH_CFG0, 0x00}, + {AQT1000_CDC_RX2_RX_PATH_CFG1, 0x64}, + {AQT1000_CDC_RX2_RX_PATH_CFG2, 0x8F}, + {AQT1000_CDC_RX2_RX_VOL_CTL, 0x00}, + {AQT1000_CDC_RX2_RX_PATH_MIX_CTL, 0x04}, + {AQT1000_CDC_RX2_RX_PATH_MIX_CFG, 0x7E}, + {AQT1000_CDC_RX2_RX_VOL_MIX_CTL, 0x00}, + {AQT1000_CDC_RX2_RX_PATH_SEC0, 0xFC}, + {AQT1000_CDC_RX2_RX_PATH_SEC1, 0x08}, + {AQT1000_CDC_RX2_RX_PATH_SEC2, 0x00}, + {AQT1000_CDC_RX2_RX_PATH_SEC3, 0x00}, + {AQT1000_CDC_RX2_RX_PATH_SEC4, 0x00}, + {AQT1000_CDC_RX2_RX_PATH_SEC5, 0x00}, + {AQT1000_CDC_RX2_RX_PATH_SEC6, 0x00}, + {AQT1000_CDC_RX2_RX_PATH_SEC7, 0x00}, + {AQT1000_CDC_RX2_RX_PATH_MIX_SEC0, 0x08}, + {AQT1000_CDC_RX2_RX_PATH_MIX_SEC1, 0x00}, + {AQT1000_CDC_RX2_RX_PATH_DSMDEM_CTL, 0x00}, + {AQT1000_CDC_EQ_IIR0_PATH_CTL, 0x00}, + {AQT1000_CDC_EQ_IIR0_PATH_CFG0, 0x1F}, + {AQT1000_CDC_EQ_IIR0_PATH_CFG1, 0x00}, + {AQT1000_CDC_EQ_IIR0_PATH_CFG2, 0x00}, + {AQT1000_CDC_EQ_IIR0_PATH_CFG3, 0x00}, + {AQT1000_CDC_EQ_IIR0_COEF_CFG0, 0x00}, + {AQT1000_CDC_EQ_IIR0_COEF_CFG1, 0x00}, + {AQT1000_CDC_EQ_IIR1_PATH_CTL, 0x00}, + {AQT1000_CDC_EQ_IIR1_PATH_CFG0, 0x1F}, + {AQT1000_CDC_EQ_IIR1_PATH_CFG1, 0x00}, + {AQT1000_CDC_EQ_IIR1_PATH_CFG2, 0x00}, + {AQT1000_CDC_EQ_IIR1_PATH_CFG3, 0x00}, + {AQT1000_CDC_EQ_IIR1_COEF_CFG0, 0x00}, + {AQT1000_CDC_EQ_IIR1_COEF_CFG1, 0x00}, + {AQT1000_PAGE12_PAGE_REGISTER, 0x00}, + {AQT1000_CDC_CLSH_CRC, 0x00}, + {AQT1000_CDC_CLSH_DLY_CTRL, 0x03}, + {AQT1000_CDC_CLSH_DECAY_CTRL, 0x02}, + {AQT1000_CDC_CLSH_HPH_V_PA, 0x1C}, + {AQT1000_CDC_CLSH_EAR_V_PA, 0x39}, + {AQT1000_CDC_CLSH_HPH_V_HD, 0x0C}, + {AQT1000_CDC_CLSH_EAR_V_HD, 0x0C}, + {AQT1000_CDC_CLSH_K1_MSB, 0x01}, + {AQT1000_CDC_CLSH_K1_LSB, 0x00}, + {AQT1000_CDC_CLSH_K2_MSB, 0x00}, + {AQT1000_CDC_CLSH_K2_LSB, 0x80}, + {AQT1000_CDC_CLSH_IDLE_CTRL, 0x00}, + {AQT1000_CDC_CLSH_IDLE_HPH, 0x00}, + {AQT1000_CDC_CLSH_IDLE_EAR, 0x00}, + {AQT1000_CDC_CLSH_TEST0, 0x07}, + {AQT1000_CDC_CLSH_TEST1, 0x00}, + {AQT1000_CDC_CLSH_OVR_VREF, 0x00}, + {AQT1000_MIXING_ASRC0_CLK_RST_CTL, 0x00}, + {AQT1000_MIXING_ASRC0_CTL0, 0x00}, + {AQT1000_MIXING_ASRC0_CTL1, 0x00}, + {AQT1000_MIXING_ASRC0_FIFO_CTL, 0xA8}, + {AQT1000_MIXING_ASRC0_STATUS_FMIN_CNTR_LSB, 0x00}, + {AQT1000_MIXING_ASRC0_STATUS_FMIN_CNTR_MSB, 0x00}, + {AQT1000_MIXING_ASRC0_STATUS_FMAX_CNTR_LSB, 0x00}, + {AQT1000_MIXING_ASRC0_STATUS_FMAX_CNTR_MSB, 0x00}, + {AQT1000_MIXING_ASRC0_STATUS_FIFO, 0x00}, + {AQT1000_MIXING_ASRC1_CLK_RST_CTL, 0x00}, + {AQT1000_MIXING_ASRC1_CTL0, 0x00}, + {AQT1000_MIXING_ASRC1_CTL1, 0x00}, + {AQT1000_MIXING_ASRC1_FIFO_CTL, 0xA8}, + {AQT1000_MIXING_ASRC1_STATUS_FMIN_CNTR_LSB, 0x00}, + {AQT1000_MIXING_ASRC1_STATUS_FMIN_CNTR_MSB, 0x00}, + {AQT1000_MIXING_ASRC1_STATUS_FMAX_CNTR_LSB, 0x00}, + {AQT1000_MIXING_ASRC1_STATUS_FMAX_CNTR_MSB, 0x00}, + {AQT1000_MIXING_ASRC1_STATUS_FIFO, 0x00}, + {AQT1000_CDC_SIDETONE_SRC0_ST_SRC_PATH_CTL, 0x04}, + {AQT1000_CDC_SIDETONE_SRC0_ST_SRC_PATH_CFG1, 0x00}, + {AQT1000_SIDETONE_ASRC0_CLK_RST_CTL, 0x00}, + {AQT1000_SIDETONE_ASRC0_CTL0, 0x00}, + {AQT1000_SIDETONE_ASRC0_CTL1, 0x00}, + {AQT1000_SIDETONE_ASRC0_FIFO_CTL, 0xA8}, + {AQT1000_SIDETONE_ASRC0_STATUS_FMIN_CNTR_LSB, 0x00}, + {AQT1000_SIDETONE_ASRC0_STATUS_FMIN_CNTR_MSB, 0x00}, + {AQT1000_SIDETONE_ASRC0_STATUS_FMAX_CNTR_LSB, 0x00}, + {AQT1000_SIDETONE_ASRC0_STATUS_FMAX_CNTR_MSB, 0x00}, + {AQT1000_SIDETONE_ASRC0_STATUS_FIFO, 0x00}, + {AQT1000_EC_REF_HQ0_EC_REF_HQ_PATH_CTL, 0x00}, + {AQT1000_EC_REF_HQ0_EC_REF_HQ_CFG0, 0x01}, + {AQT1000_EC_REF_HQ1_EC_REF_HQ_PATH_CTL, 0x00}, + {AQT1000_EC_REF_HQ1_EC_REF_HQ_CFG0, 0x01}, + {AQT1000_EC_ASRC0_CLK_RST_CTL, 0x00}, + {AQT1000_EC_ASRC0_CTL0, 0x00}, + {AQT1000_EC_ASRC0_CTL1, 0x00}, + {AQT1000_EC_ASRC0_FIFO_CTL, 0xA8}, + {AQT1000_EC_ASRC0_STATUS_FMIN_CNTR_LSB, 0x00}, + {AQT1000_EC_ASRC0_STATUS_FMIN_CNTR_MSB, 0x00}, + {AQT1000_EC_ASRC0_STATUS_FMAX_CNTR_LSB, 0x00}, + {AQT1000_EC_ASRC0_STATUS_FMAX_CNTR_MSB, 0x00}, + {AQT1000_EC_ASRC0_STATUS_FIFO, 0x00}, + {AQT1000_EC_ASRC1_CLK_RST_CTL, 0x00}, + {AQT1000_EC_ASRC1_CTL0, 0x00}, + {AQT1000_EC_ASRC1_CTL1, 0x00}, + {AQT1000_EC_ASRC1_FIFO_CTL, 0xA8}, + {AQT1000_EC_ASRC1_STATUS_FMIN_CNTR_LSB, 0x00}, + {AQT1000_EC_ASRC1_STATUS_FMIN_CNTR_MSB, 0x00}, + {AQT1000_EC_ASRC1_STATUS_FMAX_CNTR_LSB, 0x00}, + {AQT1000_EC_ASRC1_STATUS_FMAX_CNTR_MSB, 0x00}, + {AQT1000_EC_ASRC1_STATUS_FIFO, 0x00}, + {AQT1000_PAGE13_PAGE_REGISTER, 0x00}, + {AQT1000_CDC_RX_INP_MUX_RX_INT1_CFG0, 0x00}, + {AQT1000_CDC_RX_INP_MUX_RX_INT1_CFG1, 0x00}, + {AQT1000_CDC_RX_INP_MUX_RX_INT2_CFG0, 0x00}, + {AQT1000_CDC_RX_INP_MUX_RX_INT2_CFG1, 0x00}, + {AQT1000_CDC_RX_INP_MUX_EQ_IIR_CFG0, 0x00}, + {AQT1000_CDC_RX_INP_MUX_DSD_CFG0, 0x00}, + {AQT1000_CDC_RX_INP_MUX_RX_MIX_CFG0, 0x00}, + {AQT1000_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 0x00}, + {AQT1000_CDC_RX_INP_MUX_ANC_CFG0, 0x00}, + {AQT1000_CDC_RX_INP_MUX_SPLINE_ASRC_CFG0, 0x00}, + {AQT1000_CDC_RX_INP_MUX_EC_REF_HQ_CFG0, 0x00}, + {AQT1000_CDC_TX_INP_MUX_ADC_MUX0_CFG0, 0x00}, + {AQT1000_CDC_TX_INP_MUX_ADC_MUX0_CFG1, 0x00}, + {AQT1000_CDC_TX_INP_MUX_ADC_MUX1_CFG0, 0x00}, + {AQT1000_CDC_TX_INP_MUX_ADC_MUX1_CFG1, 0x00}, + {AQT1000_CDC_TX_INP_MUX_ADC_MUX2_CFG0, 0x00}, + {AQT1000_CDC_TX_INP_MUX_ADC_MUX2_CFG1, 0x00}, + {AQT1000_CDC_TX_INP_MUX_ADC_MUX10_CFG0, 0x00}, + {AQT1000_CDC_TX_INP_MUX_ADC_MUX10_CFG1, 0x00}, + {AQT1000_CDC_TX_INP_MUX_ADC_MUX11_CFG0, 0x00}, + {AQT1000_CDC_TX_INP_MUX_ADC_MUX11_CFG1, 0x00}, + {AQT1000_CDC_TX_INP_MUX_ADC_MUX12_CFG0, 0x00}, + {AQT1000_CDC_TX_INP_MUX_ADC_MUX12_CFG1, 0x00}, + {AQT1000_CDC_TX_INP_MUX_ADC_MUX13_CFG0, 0x00}, + {AQT1000_CDC_TX_INP_MUX_ADC_MUX13_CFG1, 0x00}, + {AQT1000_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG0, 0x00}, + {AQT1000_CDC_IF_ROUTER_TX_MUX_CFG0, 0x00}, + {AQT1000_CDC_CLK_RST_CTRL_MCLK_CONTROL, 0x00}, + {AQT1000_CDC_CLK_RST_CTRL_FS_CNT_CONTROL, 0x00}, + {AQT1000_CDC_CLK_RST_CTRL_DSD_CONTROL, 0x00}, + {AQT1000_CDC_CLK_RST_CTRL_ASRC_SHARE_CONTROL, 0x0F}, + {AQT1000_CDC_CLK_RST_CTRL_GFM_CONTROL, 0x00}, + {AQT1000_CDC_CLK_RST_CTRL_I2S_CONTROL, 0x00}, + {AQT1000_CDC_SIDETONE_IIR0_IIR_PATH_CTL, 0x00}, + {AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL, 0x00}, + {AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL, 0x00}, + {AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL, 0x00}, + {AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL, 0x00}, + {AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B5_CTL, 0x00}, + {AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B6_CTL, 0x00}, + {AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B7_CTL, 0x00}, + {AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B8_CTL, 0x00}, + {AQT1000_CDC_SIDETONE_IIR0_IIR_CTL, 0x40}, + {AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_TIMER_CTL, 0x00}, + {AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL, 0x00}, + {AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL, 0x00}, + {AQT1000_CDC_TOP_TOP_CFG0, 0x00}, + {AQT1000_CDC_TOP_HPHL_COMP_WR_LSB, 0x00}, + {AQT1000_CDC_TOP_HPHL_COMP_WR_MSB, 0x00}, + {AQT1000_CDC_TOP_HPHL_COMP_LUT, 0x00}, + {AQT1000_CDC_TOP_HPHL_COMP_RD_LSB, 0x00}, + {AQT1000_CDC_TOP_HPHL_COMP_RD_MSB, 0x00}, + {AQT1000_CDC_TOP_HPHR_COMP_WR_LSB, 0x00}, + {AQT1000_CDC_TOP_HPHR_COMP_WR_MSB, 0x00}, + {AQT1000_CDC_TOP_HPHR_COMP_LUT, 0x00}, + {AQT1000_CDC_TOP_HPHR_COMP_RD_LSB, 0x00}, + {AQT1000_CDC_TOP_HPHR_COMP_RD_MSB, 0x00}, + {AQT1000_CDC_DSD0_PATH_CTL, 0x00}, + {AQT1000_CDC_DSD0_CFG0, 0x00}, + {AQT1000_CDC_DSD0_CFG1, 0x00}, + {AQT1000_CDC_DSD0_CFG2, 0x42}, + {AQT1000_CDC_DSD0_CFG3, 0x00}, + {AQT1000_CDC_DSD0_CFG4, 0x02}, + {AQT1000_CDC_DSD0_CFG5, 0x00}, + {AQT1000_CDC_DSD1_PATH_CTL, 0x00}, + {AQT1000_CDC_DSD1_CFG0, 0x00}, + {AQT1000_CDC_DSD1_CFG1, 0x00}, + {AQT1000_CDC_DSD1_CFG2, 0x42}, + {AQT1000_CDC_DSD1_CFG3, 0x00}, + {AQT1000_CDC_DSD1_CFG4, 0x02}, + {AQT1000_CDC_DSD1_CFG5, 0x00}, + {AQT1000_CDC_RX_IDLE_DET_PATH_CTL, 0x00}, + {AQT1000_CDC_RX_IDLE_DET_CFG0, 0x07}, + {AQT1000_CDC_RX_IDLE_DET_CFG1, 0x3C}, + {AQT1000_CDC_RX_IDLE_DET_CFG2, 0x00}, + {AQT1000_CDC_RX_IDLE_DET_CFG3, 0x00}, + {AQT1000_CDC_DOP_DET_CTL, 0x00}, + {AQT1000_CDC_DOP_DET_CFG0, 0xFA}, + {AQT1000_CDC_DOP_DET_CFG1, 0x05}, + {AQT1000_CDC_DOP_DET_CFG2, 0x00}, + {AQT1000_CDC_DOP_DET_CFG3, 0x33}, + {AQT1000_CDC_DOP_DET_CFG4, 0x20}, + {AQT1000_CDC_DOP_DET_STATUS0, 0x00}, + {AQT1000_PAGE15_PAGE_REGISTER, 0x00}, + {AQT1000_CDC_DEBUG_DSD0_DEBUG_CFG0, 0x1B}, + {AQT1000_CDC_DEBUG_DSD0_DEBUG_CFG1, 0x24}, + {AQT1000_CDC_DEBUG_DSD0_DEBUG_CFG2, 0x00}, + {AQT1000_CDC_DEBUG_DSD0_DEBUG_CFG3, 0x08}, + {AQT1000_CDC_DEBUG_DSD1_DEBUG_CFG0, 0x1B}, + {AQT1000_CDC_DEBUG_DSD1_DEBUG_CFG1, 0x24}, + {AQT1000_CDC_DEBUG_DSD1_DEBUG_CFG2, 0x00}, + {AQT1000_CDC_DEBUG_DSD1_DEBUG_CFG3, 0x08}, + {AQT1000_CDC_DEBUG_RC_RE_ASRC_DEBUG_CFG0, 0x00}, + {AQT1000_CDC_DEBUG_ANC0_RC0_FIFO_CTL, 0x4C}, + {AQT1000_CDC_DEBUG_ANC0_RC1_FIFO_CTL, 0x4C}, + {AQT1000_CDC_DEBUG_ANC1_RC0_FIFO_CTL, 0x4C}, + {AQT1000_CDC_DEBUG_ANC1_RC1_FIFO_CTL, 0x4C}, + {AQT1000_CDC_DEBUG_ANC_RC_RST_DBG_CNTR, 0x00}, + {AQT1000_PAGE128_PAGE_REGISTER, 0x00}, + {AQT1000_TLMM_SPI_CLK_PINCFG, 0x00}, + {AQT1000_TLMM_SPI_MOSI_PINCFG, 0x00}, + {AQT1000_TLMM_SPI_MISO_PINCFG, 0x00}, + {AQT1000_TLMM_SPI_CS_N_PINCFG, 0x00}, + {AQT1000_TLMM_GPIO1_PINCFG, 0x00}, + {AQT1000_TLMM_GPIO2_PINCFG, 0x00}, + {AQT1000_TLMM_GPIO3_PINCFG, 0x00}, + {AQT1000_TLMM_GPIO4_PINCFG, 0x00}, + {AQT1000_TLMM_GPIO5_PINCFG, 0x00}, + {AQT1000_TLMM_GPIO6_PINCFG, 0x00}, + {AQT1000_TLMM_GPIO7_PINCFG, 0x00}, + {AQT1000_TLMM_GPIO8_PINCFG, 0x00}, + {AQT1000_TLMM_GPIO9_PINCFG, 0x00}, + {AQT1000_TLMM_GPIO10_PINCFG, 0x00}, + {AQT1000_PAD_CTRL_PAD_PDN_CTRL_0, 0x00}, + {AQT1000_PAD_CTRL_PAD_PDN_CTRL_1, 0x00}, + {AQT1000_PAD_CTRL_PAD_PU_CTRL_0, 0x00}, + {AQT1000_PAD_CTRL_PAD_PU_CTRL_1, 0x00}, + {AQT1000_PAD_CTRL_GPIO_CTL_0_OE, 0x00}, + {AQT1000_PAD_CTRL_GPIO_CTL_1_OE, 0x00}, + {AQT1000_PAD_CTRL_GPIO_CTL_0_DATA, 0x00}, + {AQT1000_PAD_CTRL_GPIO_CTL_1_DATA, 0x00}, + {AQT1000_PAD_CTRL_PAD_DRVCTL, 0x00}, + {AQT1000_PAD_CTRL_PIN_STATUS, 0x00}, + {AQT1000_PAD_CTRL_MEM_CTRL, 0x00}, + {AQT1000_PAD_CTRL_PAD_INP_DISABLE_0, 0x00}, + {AQT1000_PAD_CTRL_PAD_INP_DISABLE_1, 0x00}, + {AQT1000_PAD_CTRL_PIN_CTL_OE_0, 0x00}, + {AQT1000_PAD_CTRL_PIN_CTL_OE_1, 0x00}, + {AQT1000_PAD_CTRL_PIN_CTL_DATA_0, 0x00}, + {AQT1000_PAD_CTRL_PIN_CTL_DATA_1, 0x00}, + {AQT1000_PAD_CTRL_USB_PHY_CLK_DIV, 0x0F}, + {AQT1000_PAD_CTRL_DEBUG_BUS_CDC, 0x00}, + {AQT1000_PAD_CTRL_DEBUG_BUS_SEL, 0x00}, + {AQT1000_PAD_CTRL_DEBUG_EN_1, 0x00}, + {AQT1000_PAD_CTRL_DEBUG_EN_2, 0x00}, + {AQT1000_PAD_CTRL_DEBUG_EN_3, 0x00}, + {AQT1000_PAD_CTRL_DEBUG_EN_4, 0x00}, + {AQT1000_PAD_CTRL_DEBUG_EN_5, 0x00}, + {AQT1000_PAD_CTRL_DEBUG_MUX_BIT_0, 0x00}, + {AQT1000_PAD_CTRL_DEBUG_MUX_BIT_1, 0x01}, + {AQT1000_PAD_CTRL_DEBUG_MUX_BIT_2, 0x02}, + {AQT1000_PAD_CTRL_DEBUG_MUX_BIT_3, 0x03}, + {AQT1000_PAD_CTRL_DEBUG_MUX_BIT_4, 0x04}, + {AQT1000_PAD_CTRL_DEBUG_MUX_BIT_5, 0x05}, + {AQT1000_PAD_CTRL_DEBUG_MUX_BIT_6, 0x06}, + {AQT1000_PAD_CTRL_DEBUG_MUX_BIT_7, 0x07}, + {AQT1000_PAD_CTRL_DEBUG_MUX_BIT_8, 0x08}, + {AQT1000_PAD_CTRL_DEBUG_MUX_BIT_9, 0x09}, + {AQT1000_PAD_CTRL_DEBUG_MUX_BIT_10, 0x0A}, + {AQT1000_PAD_CTRL_DEBUG_MUX_BIT_11, 0x0B}, + {AQT1000_PAD_CTRL_DEBUG_MUX_BIT_12, 0x0C}, + {AQT1000_PAD_CTRL_DEBUG_MUX_BIT_13, 0x0D}, + {AQT1000_PAD_CTRL_DEBUG_READ_0, 0x0D}, + {AQT1000_PAD_CTRL_DEBUG_READ_1, 0x0D}, + {AQT1000_PAD_CTRL_DEBUG_READ_2, 0x0D}, + {AQT1000_PAD_CTRL_DEBUG_READ_3, 0x0D}, + {AQT1000_PAD_CTRL_FPGA_CTL, 0x00}, +}; + +const u8 aqt1000_page0_reg_access[AQT1000_PAGE_SIZE] = { + [AQT1000_REG(AQT1000_PAGE0_PAGE_REGISTER)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG0_CHIP_ID_BYTE0)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_CHIP_ID_BYTE1)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_CHIP_ID_BYTE2)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_CHIP_ID_BYTE3)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_TEST0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_TEST1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_VAL_OUT0)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_VAL_OUT1)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_VAL_OUT2)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_VAL_OUT3)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_VAL_OUT4)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_VAL_OUT5)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_VAL_OUT6)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_VAL_OUT7)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_VAL_OUT8)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_VAL_OUT9)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_VAL_OUT10)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_VAL_OUT11)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_VAL_OUT12)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_VAL_OUT13)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_VAL_OUT14)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_VAL_OUT15)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_STATUS)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_I2C_SLAVE_ID_NONNEGO)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_I2C_SLAVE_ID_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG0_I2C_SLAVE_ID_2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG0_I2C_SLAVE_ID_3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG0_I2C_ACTIVE)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG0_CLK_CFG_MCLK)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG0_CLK_CFG_MCLK2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG0_CLK_CTL_CDC_DIG)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG0_RST_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_TEST0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_TEST1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT0)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT1)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT2)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT3)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT4)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT5)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT6)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT7)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT8)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT9)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT10)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT11)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT12)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT13)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT14)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT15)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_STATUS)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG1_PWR_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG1_BUS_MTRX_CFG)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG1_DMA_BUS_VOTE)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG1_USB_BUS_VOTE)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG1_BLSP_BUS_VOTE)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG1_PWR_MEM_SD)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG1_PWR_SYS_MEM_SD_RAM)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG1_PWR_SYS_MEM_SD_ROM)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG1_PWR_SYS_MEM_FORCE_DS_RAM)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG1_PWR_SYS_MEM_FORCE_DS_ROM)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG1_CLK_CFG_FLL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG1_CLK_CFG_SPI_M)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG1_CLK_CFG_I2C_M)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG1_CLK_CFG_UART)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG1_RST_USB_SS)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG1_RST_BLSP)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG1_RST_BUS_MTRX)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG1_RST_MISC)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG1_ANA_WAIT_STATE_CTL)] = AQT1000_RW, +}; + +const u8 aqt1000_page1_reg_access[AQT1000_PAGE_SIZE] = { + [AQT1000_REG(AQT1000_PAGE1_PAGE_REGISTER)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_USER_CTL_0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_USER_CTL_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_USER_CTL_2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_USER_CTL_3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_USER_CTL_4)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_USER_CTL_5)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_USER_CTL_6)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_USER_CTL_7)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_USER_CTL_8)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_USER_CTL_9)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_L_VAL_CTL_0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_L_VAL_CTL_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_DSM_FRAC_CTL_0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_DSM_FRAC_CTL_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_CONFIG_CTL_0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_CONFIG_CTL_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_CONFIG_CTL_2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_CONFIG_CTL_3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_CONFIG_CTL_4)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_TEST_CTL_0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_TEST_CTL_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_TEST_CTL_2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_TEST_CTL_3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_TEST_CTL_4)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_TEST_CTL_5)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_TEST_CTL_6)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_TEST_CTL_7)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_FREQ_CTL_0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_FREQ_CTL_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_FREQ_CTL_2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_FREQ_CTL_3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_SSC_CTL_0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_SSC_CTL_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_SSC_CTL_2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_SSC_CTL_3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_FLL_MODE)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_STATUS_0)] = AQT1000_RO, + [AQT1000_REG(AQT1000_FLL_STATUS_1)] = AQT1000_RO, + [AQT1000_REG(AQT1000_FLL_STATUS_2)] = AQT1000_RO, + [AQT1000_REG(AQT1000_FLL_STATUS_3)] = AQT1000_RO, +}; + +const u8 aqt1000_page2_reg_access[AQT1000_PAGE_SIZE] = { + [AQT1000_REG(AQT1000_PAGE2_PAGE_REGISTER)] = AQT1000_RW, + [AQT1000_REG(AQT1000_I2S_I2S_0_TX_CFG)] = AQT1000_RW, + [AQT1000_REG(AQT1000_I2S_I2S_0_RX_CFG)] = AQT1000_RW, + [AQT1000_REG(AQT1000_I2S_I2S_0_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_I2S_I2S_CLKSRC_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_I2S_I2S_HS_CLK_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_I2S_I2S_0_RST)] = AQT1000_RW, + [AQT1000_REG(AQT1000_I2S_SHADOW_I2S_0_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_I2S_SHADOW_I2S_0_RX_CFG)] = AQT1000_RW, +}; + +const u8 aqt1000_page5_reg_access[AQT1000_PAGE_SIZE] = { + [AQT1000_REG(AQT1000_PAGE5_PAGE_REGISTER)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_MCU_INT_POLARITY)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_MASK_0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_MASK_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_MASK_2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_MASK_3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_MASK_4)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_MASK_5)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_MASK_6)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_STATUS_0)] = AQT1000_RO, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_STATUS_1)] = AQT1000_RO, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_STATUS_2)] = AQT1000_RO, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_STATUS_3)] = AQT1000_RO, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_STATUS_4)] = AQT1000_RO, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_STATUS_5)] = AQT1000_RO, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_STATUS_6)] = AQT1000_RO, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_CLEAR_0)] = AQT1000_WO, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_CLEAR_1)] = AQT1000_WO, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_CLEAR_2)] = AQT1000_WO, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_CLEAR_3)] = AQT1000_WO, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_CLEAR_4)] = AQT1000_WO, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_CLEAR_5)] = AQT1000_WO, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_CLEAR_6)] = AQT1000_WO, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_TYPE_0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_TYPE_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_TYPE_2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_TYPE_3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_TYPE_4)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_TYPE_5)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_TYPE_6)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_TEST_EN_0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_TEST_EN_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_TEST_EN_2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_TEST_EN_3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_TEST_EN_4)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_TEST_EN_5)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_TEST_EN_6)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_TEST_VAL_0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_TEST_VAL_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_TEST_VAL_2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_TEST_VAL_3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_TEST_VAL_4)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_TEST_VAL_5)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_TEST_VAL_6)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_DEST_0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_DEST_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_DEST_2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_DEST_3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_DEST_4)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_DEST_5)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_DEST_6)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_DEST_7)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_DEST_8)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_DEST_9)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_DEST_10)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_DEST_11)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_DEST_12)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_DEST_13)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_CLR_COMMIT)] = AQT1000_WO, +}; + +const u8 aqt1000_page6_reg_access[AQT1000_PAGE_SIZE] = { + [AQT1000_REG(AQT1000_ANA_PAGE_REGISTER)] = AQT1000_RW, + [AQT1000_REG(AQT1000_ANA_BIAS)] = AQT1000_RW, + [AQT1000_REG(AQT1000_ANA_RX_SUPPLIES)] = AQT1000_RW, + [AQT1000_REG(AQT1000_ANA_HPH)] = AQT1000_RW, + [AQT1000_REG(AQT1000_ANA_AMIC1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_ANA_AMIC2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_ANA_AMIC3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_ANA_AMIC3_HPF)] = AQT1000_RW, + [AQT1000_REG(AQT1000_ANA_MBHC_MECH)] = AQT1000_RW, + [AQT1000_REG(AQT1000_ANA_MBHC_ELECT)] = AQT1000_RW, + [AQT1000_REG(AQT1000_ANA_MBHC_ZDET)] = AQT1000_RW, + [AQT1000_REG(AQT1000_ANA_MBHC_RESULT_1)] = AQT1000_RO, + [AQT1000_REG(AQT1000_ANA_MBHC_RESULT_2)] = AQT1000_RO, + [AQT1000_REG(AQT1000_ANA_MBHC_RESULT_3)] = AQT1000_RO, + [AQT1000_REG(AQT1000_ANA_MBHC_BTN0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_ANA_MBHC_BTN1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_ANA_MBHC_BTN2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_ANA_MBHC_BTN3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_ANA_MBHC_BTN4)] = AQT1000_RW, + [AQT1000_REG(AQT1000_ANA_MBHC_BTN5)] = AQT1000_RW, + [AQT1000_REG(AQT1000_ANA_MBHC_BTN6)] = AQT1000_RW, + [AQT1000_REG(AQT1000_ANA_MBHC_BTN7)] = AQT1000_RW, + [AQT1000_REG(AQT1000_ANA_MICB1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_ANA_MICB1_RAMP)] = AQT1000_RW, + [AQT1000_REG(AQT1000_BIAS_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_BIAS_CCOMP_FINE_ADJ)] = AQT1000_RW, + [AQT1000_REG(AQT1000_LED_LED_MODE_SEL_R)] = AQT1000_RW, + [AQT1000_REG(AQT1000_LED_LED_MISC_R)] = AQT1000_RW, + [AQT1000_REG(AQT1000_LED_LED_MODE_SEL_G)] = AQT1000_RW, + [AQT1000_REG(AQT1000_LED_LED_MISC_G)] = AQT1000_RW, + [AQT1000_REG(AQT1000_LED_LED_MODE_SEL_B)] = AQT1000_RW, + [AQT1000_REG(AQT1000_LED_LED_MISC_B)] = AQT1000_RW, + [AQT1000_REG(AQT1000_LDOH_MODE)] = AQT1000_RW, + [AQT1000_REG(AQT1000_LDOH_BIAS)] = AQT1000_RW, + [AQT1000_REG(AQT1000_LDOH_STB_LOADS)] = AQT1000_RW, + [AQT1000_REG(AQT1000_LDOH_MISC1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_LDOL_VDDCX_ADJUST)] = AQT1000_RW, + [AQT1000_REG(AQT1000_LDOL_DISABLE_LDOL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_BUCK_5V_EN_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_BUCK_5V_VOUT_SEL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_BUCK_5V_CTRL_VCL_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_BUCK_5V_CTRL_VCL_2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_BUCK_5V_CTRL_CCL_2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_BUCK_5V_CTRL_CCL_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_BUCK_5V_CTRL_CCL_3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_BUCK_5V_CTRL_CCL_4)] = AQT1000_RW, + [AQT1000_REG(AQT1000_BUCK_5V_CTRL_CCL_5)] = AQT1000_RW, + [AQT1000_REG(AQT1000_BUCK_5V_IBIAS_CTL_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_BUCK_5V_IBIAS_CTL_2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_BUCK_5V_IBIAS_CTL_3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_BUCK_5V_IBIAS_CTL_4)] = AQT1000_RW, + [AQT1000_REG(AQT1000_BUCK_5V_IBIAS_CTL_5)] = AQT1000_RW, + [AQT1000_REG(AQT1000_BUCK_5V_ATEST_DTEST_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PON_BG_CTRL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PON_TEST_CTRL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MBHC_CTL_CLK)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MBHC_CTL_ANA)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MBHC_CTL_SPARE_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MBHC_CTL_SPARE_2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MBHC_CTL_BCS)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MBHC_MOISTURE_DET_FSM_STATUS)] = AQT1000_RO, + [AQT1000_REG(AQT1000_MBHC_TEST_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MICB1_TEST_CTL_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MICB1_TEST_CTL_2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MICB1_TEST_CTL_3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MICB1_MISC_MICB1_INM_RES_BIAS)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MICB1_MISC_MICB_MISC1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MICB1_MISC_MICB_MISC2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TX_COM_ADC_VCM)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TX_COM_BIAS_ATEST)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TX_COM_ADC_INT1_IB)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TX_COM_ADC_INT2_IB)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TX_COM_TXFE_DIV_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TX_COM_TXFE_DIV_START)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TX_COM_TXFE_DIV_STOP_9P6M)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TX_COM_TXFE_DIV_STOP_12P288M)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TX_1_2_TEST_EN)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TX_1_2_ADC_IB)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TX_1_2_ATEST_REFCTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TX_1_2_TEST_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TX_1_2_TEST_BLK_EN)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TX_1_2_TXFE_CLKDIV)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TX_1_2_SAR1_ERR)] = AQT1000_RO, + [AQT1000_REG(AQT1000_TX_1_2_SAR2_ERR)] = AQT1000_RO, + [AQT1000_REG(AQT1000_TX_3_TEST_EN)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TX_3_ADC_IB)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TX_3_ATEST_REFCTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TX_3_TEST_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TX_3_TEST_BLK_EN)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TX_3_TXFE_CLKDIV)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TX_3_SAR1_ERR)] = AQT1000_RO, + [AQT1000_REG(AQT1000_TX_3_SAR2_ERR)] = AQT1000_RO, + [AQT1000_REG(AQT1000_TX_ATEST1_2_SEL)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CLASSH_MODE_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLASSH_MODE_2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLASSH_MODE_3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLASSH_CTRL_VCL_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLASSH_CTRL_VCL_2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLASSH_CTRL_CCL_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLASSH_CTRL_CCL_2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLASSH_CTRL_CCL_3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLASSH_CTRL_CCL_4)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLASSH_CTRL_CCL_5)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLASSH_BUCK_TMUX_A_D)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLASSH_BUCK_SW_DRV_CNTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLASSH_SPARE)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLYBACK_EN)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLYBACK_VNEG_CTRL_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLYBACK_VNEG_CTRL_2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLYBACK_VNEG_CTRL_3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLYBACK_VNEG_CTRL_4)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLYBACK_VNEG_CTRL_5)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLYBACK_VNEG_CTRL_6)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLYBACK_VNEG_CTRL_7)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLYBACK_VNEG_CTRL_8)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLYBACK_VNEG_CTRL_9)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLYBACK_VNEGDAC_CTRL_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLYBACK_VNEGDAC_CTRL_2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLYBACK_VNEGDAC_CTRL_3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLYBACK_CTRL_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLYBACK_TEST_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_RX_AUX_SW_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_RX_PA_AUX_IN_CONN)] = AQT1000_RW, + [AQT1000_REG(AQT1000_RX_TIMER_DIV)] = AQT1000_RW, + [AQT1000_REG(AQT1000_RX_OCP_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_RX_OCP_COUNT)] = AQT1000_RW, + [AQT1000_REG(AQT1000_RX_BIAS_ATEST)] = AQT1000_RW, + [AQT1000_REG(AQT1000_RX_BIAS_MISC1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_RX_BIAS_HPH_LDO)] = AQT1000_RW, + [AQT1000_REG(AQT1000_RX_BIAS_HPH_PA)] = AQT1000_RW, + [AQT1000_REG(AQT1000_RX_BIAS_HPH_RDACBUFF_CNP2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_RX_BIAS_HPH_RDAC_LDO)] = AQT1000_RW, + [AQT1000_REG(AQT1000_RX_BIAS_HPH_CNP1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_RX_BIAS_HPH_LOWPOWER)] = AQT1000_RW, + [AQT1000_REG(AQT1000_RX_BIAS_MISC2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_RX_BIAS_MISC3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_RX_BIAS_MISC4)] = AQT1000_RW, + [AQT1000_REG(AQT1000_RX_BIAS_MISC5)] = AQT1000_RW, + [AQT1000_REG(AQT1000_RX_BIAS_BUCK_RST)] = AQT1000_RW, + [AQT1000_REG(AQT1000_RX_BIAS_BUCK_VREF_ERRAMP)] = AQT1000_RW, + [AQT1000_REG(AQT1000_RX_BIAS_FLYB_ERRAMP)] = AQT1000_RW, + [AQT1000_REG(AQT1000_RX_BIAS_FLYB_BUFF)] = AQT1000_RW, + [AQT1000_REG(AQT1000_RX_BIAS_FLYB_MID_RST)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_L_STATUS)] = AQT1000_RO, + [AQT1000_REG(AQT1000_HPH_R_STATUS)] = AQT1000_RO, + [AQT1000_REG(AQT1000_HPH_CNP_EN)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_CNP_WG_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_CNP_WG_TIME)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_OCP_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_AUTO_CHOP)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_CHOP_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_PA_CTL1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_PA_CTL2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_L_EN)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_L_TEST)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_L_ATEST)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_R_EN)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_R_TEST)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_R_ATEST)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_RDAC_CLK_CTL1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_RDAC_CLK_CTL2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_RDAC_LDO_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_RDAC_CHOP_CLK_LP_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_REFBUFF_UHQA_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_REFBUFF_LP_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_L_DAC_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_R_DAC_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPHLR_SURGE_COMP_SEL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPHLR_SURGE_EN)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPHLR_SURGE_MISC1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPHLR_SURGE_STATUS)] = AQT1000_RO, +}; + +const u8 aqt1000_page7_reg_access[AQT1000_PAGE_SIZE] = { + [AQT1000_REG(AQT1000_ANA_NEW_PAGE_REGISTER)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_NEW_ANA_HPH2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_NEW_ANA_HPH3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLK_SYS_MCLK1_PRG)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLK_SYS_MCLK2_I2S_HS_CLK_PRG)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLK_SYS_XO_CAP_XTP)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLK_SYS_XO_CAP_XTM)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLK_SYS_PLL_ENABLES)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLK_SYS_PLL_PRESET)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLK_SYS_PLL_STATUS)] = AQT1000_RO, + [AQT1000_REG(AQT1000_MBHC_NEW_ELECT_REM_CLAMP_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MBHC_NEW_CTL_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MBHC_NEW_CTL_2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MBHC_NEW_PLUG_DETECT_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MBHC_NEW_ZDET_ANA_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MBHC_NEW_ZDET_RAMP_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MBHC_NEW_FSM_STATUS)] = AQT1000_RO, + [AQT1000_REG(AQT1000_MBHC_NEW_ADC_RESULT)] = AQT1000_RO, + [AQT1000_REG(AQT1000_HPH_NEW_INT_RDAC_GAIN_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_NEW_INT_RDAC_HD2_CTL_L)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_NEW_INT_RDAC_VREF_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_NEW_INT_RDAC_OVERRIDE_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_NEW_INT_RDAC_HD2_CTL_R)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_NEW_INT_PA_MISC1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_NEW_INT_PA_MISC2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_NEW_INT_PA_RDAC_MISC)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_NEW_INT_HPH_TIMER1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_NEW_INT_HPH_TIMER2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_NEW_INT_HPH_TIMER3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_NEW_INT_HPH_TIMER4)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_NEW_INT_PA_RDAC_MISC2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_NEW_INT_PA_RDAC_MISC3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_RX_NEW_INT_HPH_RDAC_BIAS_LOHIFI)] = AQT1000_RW, + [AQT1000_REG(AQT1000_RX_NEW_INT_HPH_RDAC_BIAS_ULP)] = AQT1000_RW, + [AQT1000_REG(AQT1000_RX_NEW_INT_HPH_RDAC_LDO_LP)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLK_SYS_INT_CLK_TEST1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLK_SYS_INT_XO_TEST1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLK_SYS_INT_XO_TEST2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLK_SYS_INT_POST_DIV_REG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLK_SYS_INT_POST_DIV_REG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLK_SYS_INT_REF_DIV_REG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLK_SYS_INT_REF_DIV_REG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLK_SYS_INT_FILTER_REG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLK_SYS_INT_FILTER_REG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLK_SYS_INT_PLL_L_VAL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLK_SYS_INT_PLL_M_VAL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLK_SYS_INT_PLL_N_VAL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLK_SYS_INT_TEST_REG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLK_SYS_INT_PFD_CP_DSM_PROG)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLK_SYS_INT_VCO_PROG)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLK_SYS_INT_TEST_REG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLK_SYS_INT_LDO_LOCK_CFG)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLK_SYS_INT_DIG_LOCK_DET_CFG)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MBHC_NEW_INT_MOISTURE_DET_DC_CTRL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MBHC_NEW_INT_MOISTURE_DET_POLLING_CTRL)] = + AQT1000_RW, + [AQT1000_REG(AQT1000_MBHC_NEW_INT_MECH_DET_CURRENT)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MBHC_NEW_INT_SPARE_2)] = AQT1000_RW, +}; + +const u8 aqt1000_page10_reg_access[AQT1000_PAGE_SIZE] = { + [AQT1000_REG(AQT1000_PAGE10_PAGE_REGISTER)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC0_CLK_RESET_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC0_MODE_1_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC0_MODE_2_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC0_FF_SHIFT)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC0_FB_SHIFT)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC0_LPF_FF_A_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC0_LPF_FF_B_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC0_LPF_FB_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC0_SMLPF_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC0_DCFLT_SHIFT_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC0_IIR_ADAPT_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC0_IIR_COEFF_1_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC0_IIR_COEFF_2_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC0_FF_A_GAIN_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC0_FF_B_GAIN_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC0_FB_GAIN_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC0_RC_COMMON_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC0_FIFO_COMMON_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC0_RC0_STATUS_FMIN_CNTR)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CDC_ANC0_RC1_STATUS_FMIN_CNTR)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CDC_ANC0_RC0_STATUS_FMAX_CNTR)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CDC_ANC0_RC1_STATUS_FMAX_CNTR)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CDC_ANC0_STATUS_FIFO)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CDC_ANC1_CLK_RESET_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC1_MODE_1_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC1_MODE_2_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC1_FF_SHIFT)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC1_FB_SHIFT)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC1_LPF_FF_A_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC1_LPF_FF_B_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC1_LPF_FB_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC1_SMLPF_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC1_DCFLT_SHIFT_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC1_IIR_ADAPT_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC1_IIR_COEFF_1_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC1_IIR_COEFF_2_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC1_FF_A_GAIN_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC1_FF_B_GAIN_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC1_FB_GAIN_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC1_RC_COMMON_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC1_FIFO_COMMON_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC1_RC0_STATUS_FMIN_CNTR)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CDC_ANC1_RC1_STATUS_FMIN_CNTR)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CDC_ANC1_RC0_STATUS_FMAX_CNTR)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CDC_ANC1_RC1_STATUS_FMAX_CNTR)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CDC_ANC1_STATUS_FIFO)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CDC_TX0_TX_PATH_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX0_TX_PATH_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX0_TX_PATH_CFG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX0_TX_VOL_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX0_TX_PATH_SEC0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX0_TX_PATH_SEC1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX0_TX_PATH_SEC2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX0_TX_PATH_SEC3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX0_TX_PATH_SEC4)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX0_TX_PATH_SEC5)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX0_TX_PATH_SEC6)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX1_TX_PATH_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX1_TX_PATH_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX1_TX_PATH_CFG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX1_TX_VOL_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX1_TX_PATH_SEC0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX1_TX_PATH_SEC1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX1_TX_PATH_SEC2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX1_TX_PATH_SEC3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX1_TX_PATH_SEC4)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX1_TX_PATH_SEC5)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX1_TX_PATH_SEC6)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX2_TX_PATH_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX2_TX_PATH_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX2_TX_PATH_CFG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX2_TX_VOL_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX2_TX_PATH_SEC0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX2_TX_PATH_SEC1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX2_TX_PATH_SEC2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX2_TX_PATH_SEC3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX2_TX_PATH_SEC4)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX2_TX_PATH_SEC5)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX2_TX_PATH_SEC6)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX2_TX_PATH_SEC7)] = AQT1000_RW, +}; + +const u8 aqt1000_page11_reg_access[AQT1000_PAGE_SIZE] = { + [AQT1000_REG(AQT1000_PAGE11_PAGE_REGISTER)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_COMPANDER1_CTL0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_COMPANDER1_CTL1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_COMPANDER1_CTL2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_COMPANDER1_CTL3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_COMPANDER1_CTL4)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_COMPANDER1_CTL5)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_COMPANDER1_CTL6)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CDC_COMPANDER1_CTL7)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_COMPANDER2_CTL0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_COMPANDER2_CTL1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_COMPANDER2_CTL2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_COMPANDER2_CTL3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_COMPANDER2_CTL4)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_COMPANDER2_CTL5)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_COMPANDER2_CTL6)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CDC_COMPANDER2_CTL7)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX1_RX_PATH_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX1_RX_PATH_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX1_RX_PATH_CFG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX1_RX_PATH_CFG2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX1_RX_VOL_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX1_RX_PATH_MIX_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX1_RX_PATH_MIX_CFG)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX1_RX_VOL_MIX_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX1_RX_PATH_SEC0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX1_RX_PATH_SEC1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX1_RX_PATH_SEC2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX1_RX_PATH_SEC3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX1_RX_PATH_SEC4)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX1_RX_PATH_SEC5)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX1_RX_PATH_SEC6)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX1_RX_PATH_SEC7)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX1_RX_PATH_MIX_SEC0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX1_RX_PATH_MIX_SEC1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX1_RX_PATH_DSMDEM_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX2_RX_PATH_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX2_RX_PATH_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX2_RX_PATH_CFG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX2_RX_PATH_CFG2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX2_RX_VOL_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX2_RX_PATH_MIX_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX2_RX_PATH_MIX_CFG)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX2_RX_VOL_MIX_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX2_RX_PATH_SEC0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX2_RX_PATH_SEC1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX2_RX_PATH_SEC2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX2_RX_PATH_SEC3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX2_RX_PATH_SEC4)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX2_RX_PATH_SEC5)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX2_RX_PATH_SEC6)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX2_RX_PATH_SEC7)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX2_RX_PATH_MIX_SEC0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX2_RX_PATH_MIX_SEC1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX2_RX_PATH_DSMDEM_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_EQ_IIR0_PATH_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_EQ_IIR0_PATH_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_EQ_IIR0_PATH_CFG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_EQ_IIR0_PATH_CFG2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_EQ_IIR0_PATH_CFG3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_EQ_IIR0_COEF_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_EQ_IIR0_COEF_CFG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_EQ_IIR1_PATH_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_EQ_IIR1_PATH_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_EQ_IIR1_PATH_CFG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_EQ_IIR1_PATH_CFG2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_EQ_IIR1_PATH_CFG3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_EQ_IIR1_COEF_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_EQ_IIR1_COEF_CFG1)] = AQT1000_RW, +}; + +const u8 aqt1000_page12_reg_access[AQT1000_PAGE_SIZE] = { + [AQT1000_REG(AQT1000_PAGE12_PAGE_REGISTER)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_CLSH_CRC)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_CLSH_DLY_CTRL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_CLSH_DECAY_CTRL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_CLSH_HPH_V_PA)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_CLSH_EAR_V_PA)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_CLSH_HPH_V_HD)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_CLSH_EAR_V_HD)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_CLSH_K1_MSB)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_CLSH_K1_LSB)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_CLSH_K2_MSB)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_CLSH_K2_LSB)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_CLSH_IDLE_CTRL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_CLSH_IDLE_HPH)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_CLSH_IDLE_EAR)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_CLSH_TEST0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_CLSH_TEST1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_CLSH_OVR_VREF)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MIXING_ASRC0_CLK_RST_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MIXING_ASRC0_CTL0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MIXING_ASRC0_CTL1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MIXING_ASRC0_FIFO_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MIXING_ASRC0_STATUS_FMIN_CNTR_LSB)] = AQT1000_RO, + [AQT1000_REG(AQT1000_MIXING_ASRC0_STATUS_FMIN_CNTR_MSB)] = AQT1000_RO, + [AQT1000_REG(AQT1000_MIXING_ASRC0_STATUS_FMAX_CNTR_LSB)] = AQT1000_RO, + [AQT1000_REG(AQT1000_MIXING_ASRC0_STATUS_FMAX_CNTR_MSB)] = AQT1000_RO, + [AQT1000_REG(AQT1000_MIXING_ASRC0_STATUS_FIFO)] = AQT1000_RO, + [AQT1000_REG(AQT1000_MIXING_ASRC1_CLK_RST_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MIXING_ASRC1_CTL0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MIXING_ASRC1_CTL1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MIXING_ASRC1_FIFO_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MIXING_ASRC1_STATUS_FMIN_CNTR_LSB)] = AQT1000_RO, + [AQT1000_REG(AQT1000_MIXING_ASRC1_STATUS_FMIN_CNTR_MSB)] = AQT1000_RO, + [AQT1000_REG(AQT1000_MIXING_ASRC1_STATUS_FMAX_CNTR_LSB)] = AQT1000_RO, + [AQT1000_REG(AQT1000_MIXING_ASRC1_STATUS_FMAX_CNTR_MSB)] = AQT1000_RO, + [AQT1000_REG(AQT1000_MIXING_ASRC1_STATUS_FIFO)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CDC_SIDETONE_SRC0_ST_SRC_PATH_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_SIDETONE_SRC0_ST_SRC_PATH_CFG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_SIDETONE_ASRC0_CLK_RST_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_SIDETONE_ASRC0_CTL0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_SIDETONE_ASRC0_CTL1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_SIDETONE_ASRC0_FIFO_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_SIDETONE_ASRC0_STATUS_FMIN_CNTR_LSB)] = AQT1000_RO, + [AQT1000_REG(AQT1000_SIDETONE_ASRC0_STATUS_FMIN_CNTR_MSB)] = AQT1000_RO, + [AQT1000_REG(AQT1000_SIDETONE_ASRC0_STATUS_FMAX_CNTR_LSB)] = AQT1000_RO, + [AQT1000_REG(AQT1000_SIDETONE_ASRC0_STATUS_FMAX_CNTR_MSB)] = AQT1000_RO, + [AQT1000_REG(AQT1000_SIDETONE_ASRC0_STATUS_FIFO)] = AQT1000_RO, + [AQT1000_REG(AQT1000_EC_REF_HQ0_EC_REF_HQ_PATH_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_EC_REF_HQ0_EC_REF_HQ_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_EC_REF_HQ1_EC_REF_HQ_PATH_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_EC_REF_HQ1_EC_REF_HQ_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_EC_ASRC0_CLK_RST_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_EC_ASRC0_CTL0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_EC_ASRC0_CTL1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_EC_ASRC0_FIFO_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_EC_ASRC0_STATUS_FMIN_CNTR_LSB)] = AQT1000_RO, + [AQT1000_REG(AQT1000_EC_ASRC0_STATUS_FMIN_CNTR_MSB)] = AQT1000_RO, + [AQT1000_REG(AQT1000_EC_ASRC0_STATUS_FMAX_CNTR_LSB)] = AQT1000_RO, + [AQT1000_REG(AQT1000_EC_ASRC0_STATUS_FMAX_CNTR_MSB)] = AQT1000_RO, + [AQT1000_REG(AQT1000_EC_ASRC0_STATUS_FIFO)] = AQT1000_RO, + [AQT1000_REG(AQT1000_EC_ASRC1_CLK_RST_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_EC_ASRC1_CTL0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_EC_ASRC1_CTL1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_EC_ASRC1_FIFO_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_EC_ASRC1_STATUS_FMIN_CNTR_LSB)] = AQT1000_RO, + [AQT1000_REG(AQT1000_EC_ASRC1_STATUS_FMIN_CNTR_MSB)] = AQT1000_RO, + [AQT1000_REG(AQT1000_EC_ASRC1_STATUS_FMAX_CNTR_LSB)] = AQT1000_RO, + [AQT1000_REG(AQT1000_EC_ASRC1_STATUS_FMAX_CNTR_MSB)] = AQT1000_RO, + [AQT1000_REG(AQT1000_EC_ASRC1_STATUS_FIFO)] = AQT1000_RO, +}; + +const u8 aqt1000_page13_reg_access[AQT1000_PAGE_SIZE] = { + [AQT1000_REG(AQT1000_PAGE13_PAGE_REGISTER)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX_INP_MUX_RX_INT1_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX_INP_MUX_RX_INT1_CFG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX_INP_MUX_RX_INT2_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX_INP_MUX_RX_INT2_CFG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX_INP_MUX_EQ_IIR_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX_INP_MUX_DSD_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX_INP_MUX_RX_MIX_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX_INP_MUX_ANC_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX_INP_MUX_SPLINE_ASRC_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX_INP_MUX_EC_REF_HQ_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX_INP_MUX_ADC_MUX0_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX_INP_MUX_ADC_MUX0_CFG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX_INP_MUX_ADC_MUX1_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX_INP_MUX_ADC_MUX1_CFG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX_INP_MUX_ADC_MUX2_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX_INP_MUX_ADC_MUX2_CFG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX_INP_MUX_ADC_MUX10_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX_INP_MUX_ADC_MUX10_CFG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX_INP_MUX_ADC_MUX11_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX_INP_MUX_ADC_MUX11_CFG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX_INP_MUX_ADC_MUX12_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX_INP_MUX_ADC_MUX12_CFG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX_INP_MUX_ADC_MUX13_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX_INP_MUX_ADC_MUX13_CFG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG0)] = + AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_IF_ROUTER_TX_MUX_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_CLK_RST_CTRL_MCLK_CONTROL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_CLK_RST_CTRL_FS_CNT_CONTROL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_CLK_RST_CTRL_DSD_CONTROL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_CLK_RST_CTRL_ASRC_SHARE_CONTROL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_CLK_RST_CTRL_GFM_CONTROL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_CLK_RST_CTRL_I2S_CONTROL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_SIDETONE_IIR0_IIR_PATH_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B5_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B6_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B7_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B8_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_SIDETONE_IIR0_IIR_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_TIMER_CTL)] = + AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TOP_TOP_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TOP_HPHL_COMP_WR_LSB)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TOP_HPHL_COMP_WR_MSB)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TOP_HPHL_COMP_LUT)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TOP_HPHL_COMP_RD_LSB)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CDC_TOP_HPHL_COMP_RD_MSB)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CDC_TOP_HPHR_COMP_WR_LSB)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TOP_HPHR_COMP_WR_MSB)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TOP_HPHR_COMP_LUT)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TOP_HPHR_COMP_RD_LSB)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CDC_TOP_HPHR_COMP_RD_MSB)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CDC_DSD0_PATH_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DSD0_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DSD0_CFG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DSD0_CFG2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DSD0_CFG3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DSD0_CFG4)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DSD0_CFG5)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DSD1_PATH_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DSD1_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DSD1_CFG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DSD1_CFG2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DSD1_CFG3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DSD1_CFG4)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DSD1_CFG5)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX_IDLE_DET_PATH_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX_IDLE_DET_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX_IDLE_DET_CFG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX_IDLE_DET_CFG2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX_IDLE_DET_CFG3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DOP_DET_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DOP_DET_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DOP_DET_CFG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DOP_DET_CFG2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DOP_DET_CFG3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DOP_DET_CFG4)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DOP_DET_STATUS0)] = AQT1000_RO, +}; + +const u8 aqt1000_page15_reg_access[AQT1000_PAGE_SIZE] = { + [AQT1000_REG(AQT1000_PAGE15_PAGE_REGISTER)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DEBUG_DSD0_DEBUG_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DEBUG_DSD0_DEBUG_CFG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DEBUG_DSD0_DEBUG_CFG2)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CDC_DEBUG_DSD0_DEBUG_CFG3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DEBUG_DSD1_DEBUG_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DEBUG_DSD1_DEBUG_CFG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DEBUG_DSD1_DEBUG_CFG2)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CDC_DEBUG_DSD1_DEBUG_CFG3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DEBUG_RC_RE_ASRC_DEBUG_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DEBUG_ANC0_RC0_FIFO_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DEBUG_ANC0_RC1_FIFO_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DEBUG_ANC1_RC0_FIFO_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DEBUG_ANC1_RC1_FIFO_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DEBUG_ANC_RC_RST_DBG_CNTR)] = AQT1000_RW, +}; + +const u8 aqt1000_page128_reg_access[AQT1000_PAGE_SIZE] = { + [AQT1000_REG(AQT1000_PAGE128_PAGE_REGISTER)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TLMM_SPI_CLK_PINCFG)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TLMM_SPI_MOSI_PINCFG)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TLMM_SPI_MISO_PINCFG)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TLMM_SPI_CS_N_PINCFG)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TLMM_GPIO1_PINCFG)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TLMM_GPIO2_PINCFG)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TLMM_GPIO3_PINCFG)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TLMM_GPIO4_PINCFG)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TLMM_GPIO5_PINCFG)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TLMM_GPIO6_PINCFG)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TLMM_GPIO7_PINCFG)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TLMM_GPIO8_PINCFG)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TLMM_GPIO9_PINCFG)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TLMM_GPIO10_PINCFG)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_PAD_PDN_CTRL_0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_PAD_PDN_CTRL_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_PAD_PU_CTRL_0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_PAD_PU_CTRL_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_GPIO_CTL_0_OE)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_GPIO_CTL_1_OE)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_GPIO_CTL_0_DATA)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_GPIO_CTL_1_DATA)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_PAD_DRVCTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_PIN_STATUS)] = AQT1000_RO, + [AQT1000_REG(AQT1000_PAD_CTRL_MEM_CTRL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_PAD_INP_DISABLE_0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_PAD_INP_DISABLE_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_PIN_CTL_OE_0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_PIN_CTL_OE_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_PIN_CTL_DATA_0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_PIN_CTL_DATA_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_USB_PHY_CLK_DIV)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_BUS_CDC)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_BUS_SEL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_EN_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_EN_2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_EN_3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_EN_4)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_EN_5)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_MUX_BIT_0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_MUX_BIT_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_MUX_BIT_2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_MUX_BIT_3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_MUX_BIT_4)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_MUX_BIT_5)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_MUX_BIT_6)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_MUX_BIT_7)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_MUX_BIT_8)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_MUX_BIT_9)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_MUX_BIT_10)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_MUX_BIT_11)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_MUX_BIT_12)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_MUX_BIT_13)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_READ_0)] = AQT1000_RO, + [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_READ_1)] = AQT1000_RO, + [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_READ_2)] = AQT1000_RO, + [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_READ_3)] = AQT1000_RO, + [AQT1000_REG(AQT1000_PAD_CTRL_FPGA_CTL)] = AQT1000_RW, +}; + +const u8 * const aqt1000_reg[AQT1000_PAGE_MAX] = { + [AQT1000_PAGE_0] = aqt1000_page0_reg_access, + [AQT1000_PAGE_1] = aqt1000_page1_reg_access, + [AQT1000_PAGE_2] = aqt1000_page2_reg_access, + [AQT1000_PAGE_5] = aqt1000_page5_reg_access, + [AQT1000_PAGE_6] = aqt1000_page6_reg_access, + [AQT1000_PAGE_7] = aqt1000_page7_reg_access, + [AQT1000_PAGE_10] = aqt1000_page10_reg_access, + [AQT1000_PAGE_11] = aqt1000_page11_reg_access, + [AQT1000_PAGE_12] = aqt1000_page12_reg_access, + [AQT1000_PAGE_13] = aqt1000_page13_reg_access, + [AQT1000_PAGE_15] = aqt1000_page15_reg_access, + [AQT1000_PAGE_128] = aqt1000_page128_reg_access, +}; + +#endif /* _AQT1000_REG_DEFAULTS_H */ diff --git a/asoc/codecs/aqt1000/aqt1000-registers.h b/asoc/codecs/aqt1000/aqt1000-registers.h new file mode 100644 index 0000000000..9033466656 --- /dev/null +++ b/asoc/codecs/aqt1000/aqt1000-registers.h @@ -0,0 +1,881 @@ +/* Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _AQT1000_REGISTERS_H +#define _AQT1000_REGISTERS_H + +#define AQT1000_PAGE0_BASE (0x00000000) +#define AQT1000_PAGE0_PAGE_REGISTER (0x00000000) +#define AQT1000_CHIP_CFG0_BASE (0x00000001) +#define AQT1000_CHIP_CFG0_CHIP_ID_BYTE0 (0x00000001) +#define AQT1000_CHIP_CFG0_CHIP_ID_BYTE1 (0x00000002) +#define AQT1000_CHIP_CFG0_CHIP_ID_BYTE2 (0x00000003) +#define AQT1000_CHIP_CFG0_CHIP_ID_BYTE3 (0x00000004) +#define AQT1000_CHIP_CFG0_EFUSE_CTL (0x00000005) +#define AQT1000_CHIP_CFG0_EFUSE_TEST0 (0x00000006) +#define AQT1000_CHIP_CFG0_EFUSE_TEST1 (0x00000007) +#define AQT1000_CHIP_CFG0_EFUSE_VAL_OUT0 (0x00000009) +#define AQT1000_CHIP_CFG0_EFUSE_VAL_OUT1 (0x0000000A) +#define AQT1000_CHIP_CFG0_EFUSE_VAL_OUT2 (0x0000000B) +#define AQT1000_CHIP_CFG0_EFUSE_VAL_OUT3 (0x0000000C) +#define AQT1000_CHIP_CFG0_EFUSE_VAL_OUT4 (0x0000000D) +#define AQT1000_CHIP_CFG0_EFUSE_VAL_OUT5 (0x0000000E) +#define AQT1000_CHIP_CFG0_EFUSE_VAL_OUT6 (0x0000000F) +#define AQT1000_CHIP_CFG0_EFUSE_VAL_OUT7 (0x00000010) +#define AQT1000_CHIP_CFG0_EFUSE_VAL_OUT8 (0x00000011) +#define AQT1000_CHIP_CFG0_EFUSE_VAL_OUT9 (0x00000012) +#define AQT1000_CHIP_CFG0_EFUSE_VAL_OUT10 (0x00000013) +#define AQT1000_CHIP_CFG0_EFUSE_VAL_OUT11 (0x00000014) +#define AQT1000_CHIP_CFG0_EFUSE_VAL_OUT12 (0x00000015) +#define AQT1000_CHIP_CFG0_EFUSE_VAL_OUT13 (0x00000016) +#define AQT1000_CHIP_CFG0_EFUSE_VAL_OUT14 (0x00000017) +#define AQT1000_CHIP_CFG0_EFUSE_VAL_OUT15 (0x00000018) +#define AQT1000_CHIP_CFG0_EFUSE_STATUS (0x00000019) +#define AQT1000_CHIP_CFG0_I2C_SLAVE_ID_NONNEGO (0x0000001A) +#define AQT1000_CHIP_CFG0_I2C_SLAVE_ID_1 (0x0000001B) +#define AQT1000_CHIP_CFG0_I2C_SLAVE_ID_2 (0x0000001C) +#define AQT1000_CHIP_CFG0_I2C_SLAVE_ID_3 (0x0000001D) +#define AQT1000_CHIP_CFG0_I2C_ACTIVE (0x00000020) +#define AQT1000_CHIP_CFG0_CLK_CFG_MCLK (0x00000021) +#define AQT1000_CHIP_CFG0_CLK_CFG_MCLK2 (0x00000022) +#define AQT1000_CHIP_CFG0_CLK_CTL_CDC_DIG (0x00000023) +#define AQT1000_CHIP_CFG0_RST_CTL (0x00000032) +#define AQT1000_CHIP_CFG0_EFUSE2_CTL (0x0000003D) +#define AQT1000_CHIP_CFG0_EFUSE2_TEST0 (0x0000003E) +#define AQT1000_CHIP_CFG0_EFUSE2_TEST1 (0x0000003F) +#define AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT0 (0x00000040) +#define AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT1 (0x00000041) +#define AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT2 (0x00000042) +#define AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT3 (0x00000043) +#define AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT4 (0x00000044) +#define AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT5 (0x00000045) +#define AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT6 (0x00000046) +#define AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT7 (0x00000047) +#define AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT8 (0x00000048) +#define AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT9 (0x00000049) +#define AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT10 (0x0000004A) +#define AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT11 (0x0000004B) +#define AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT12 (0x0000004C) +#define AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT13 (0x0000004D) +#define AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT14 (0x0000004E) +#define AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT15 (0x0000004F) +#define AQT1000_CHIP_CFG0_EFUSE2_STATUS (0x00000050) +#define AQT1000_CHIP_CFG1_BASE (0x00000051) +#define AQT1000_CHIP_CFG1_PWR_CTL (0x00000051) +#define AQT1000_CHIP_CFG1_BUS_MTRX_CFG (0x00000052) +#define AQT1000_CHIP_CFG1_DMA_BUS_VOTE (0x00000053) +#define AQT1000_CHIP_CFG1_USB_BUS_VOTE (0x00000054) +#define AQT1000_CHIP_CFG1_BLSP_BUS_VOTE (0x00000055) +#define AQT1000_CHIP_CFG1_PWR_MEM_SD (0x00000059) +#define AQT1000_CHIP_CFG1_PWR_SYS_MEM_SD_RAM (0x0000005C) +#define AQT1000_CHIP_CFG1_PWR_SYS_MEM_SD_ROM (0x0000005D) +#define AQT1000_CHIP_CFG1_PWR_SYS_MEM_FORCE_DS_RAM (0x0000005E) +#define AQT1000_CHIP_CFG1_PWR_SYS_MEM_FORCE_DS_ROM (0x0000005F) +#define AQT1000_CHIP_CFG1_CLK_CFG_FLL (0x00000061) +#define AQT1000_CHIP_CFG1_CLK_CFG_SPI_M (0x00000062) +#define AQT1000_CHIP_CFG1_CLK_CFG_I2C_M (0x00000063) +#define AQT1000_CHIP_CFG1_CLK_CFG_UART (0x00000064) +#define AQT1000_CHIP_CFG1_RST_USB_SS (0x00000071) +#define AQT1000_CHIP_CFG1_RST_BLSP (0x00000072) +#define AQT1000_CHIP_CFG1_RST_BUS_MTRX (0x00000073) +#define AQT1000_CHIP_CFG1_RST_MISC (0x00000074) +#define AQT1000_CHIP_CFG1_ANA_WAIT_STATE_CTL (0x00000081) +#define AQT1000_PAGE1_BASE (0x00000100) +#define AQT1000_PAGE1_PAGE_REGISTER (0x00000100) +#define AQT1000_FLL_BASE (0x00000101) +#define AQT1000_FLL_USER_CTL_0 (0x00000101) +#define AQT1000_FLL_USER_CTL_1 (0x00000102) +#define AQT1000_FLL_USER_CTL_2 (0x00000103) +#define AQT1000_FLL_USER_CTL_3 (0x00000104) +#define AQT1000_FLL_USER_CTL_4 (0x00000105) +#define AQT1000_FLL_USER_CTL_5 (0x00000106) +#define AQT1000_FLL_USER_CTL_6 (0x00000107) +#define AQT1000_FLL_USER_CTL_7 (0x00000108) +#define AQT1000_FLL_USER_CTL_8 (0x00000109) +#define AQT1000_FLL_USER_CTL_9 (0x0000010A) +#define AQT1000_FLL_L_VAL_CTL_0 (0x0000010B) +#define AQT1000_FLL_L_VAL_CTL_1 (0x0000010C) +#define AQT1000_FLL_DSM_FRAC_CTL_0 (0x0000010D) +#define AQT1000_FLL_DSM_FRAC_CTL_1 (0x0000010E) +#define AQT1000_FLL_CONFIG_CTL_0 (0x0000010F) +#define AQT1000_FLL_CONFIG_CTL_1 (0x00000110) +#define AQT1000_FLL_CONFIG_CTL_2 (0x00000111) +#define AQT1000_FLL_CONFIG_CTL_3 (0x00000112) +#define AQT1000_FLL_CONFIG_CTL_4 (0x00000113) +#define AQT1000_FLL_TEST_CTL_0 (0x00000114) +#define AQT1000_FLL_TEST_CTL_1 (0x00000115) +#define AQT1000_FLL_TEST_CTL_2 (0x00000116) +#define AQT1000_FLL_TEST_CTL_3 (0x00000117) +#define AQT1000_FLL_TEST_CTL_4 (0x00000118) +#define AQT1000_FLL_TEST_CTL_5 (0x00000119) +#define AQT1000_FLL_TEST_CTL_6 (0x0000011A) +#define AQT1000_FLL_TEST_CTL_7 (0x0000011B) +#define AQT1000_FLL_FREQ_CTL_0 (0x0000011C) +#define AQT1000_FLL_FREQ_CTL_1 (0x0000011D) +#define AQT1000_FLL_FREQ_CTL_2 (0x0000011E) +#define AQT1000_FLL_FREQ_CTL_3 (0x0000011F) +#define AQT1000_FLL_SSC_CTL_0 (0x00000120) +#define AQT1000_FLL_SSC_CTL_1 (0x00000121) +#define AQT1000_FLL_SSC_CTL_2 (0x00000122) +#define AQT1000_FLL_SSC_CTL_3 (0x00000123) +#define AQT1000_FLL_FLL_MODE (0x00000124) +#define AQT1000_FLL_STATUS_0 (0x00000125) +#define AQT1000_FLL_STATUS_1 (0x00000126) +#define AQT1000_FLL_STATUS_2 (0x00000127) +#define AQT1000_FLL_STATUS_3 (0x00000128) +#define AQT1000_PAGE2_BASE (0x00000200) +#define AQT1000_PAGE2_PAGE_REGISTER (0x00000200) +#define AQT1000_I2S_BASE (0x00000201) +#define AQT1000_I2S_I2S_0_TX_CFG (0x00000201) +#define AQT1000_I2S_I2S_0_RX_CFG (0x00000202) +#define AQT1000_I2S_I2S_0_CTL (0x00000203) +#define AQT1000_I2S_I2S_CLKSRC_CTL (0x00000204) +#define AQT1000_I2S_I2S_HS_CLK_CTL (0x00000205) +#define AQT1000_I2S_I2S_0_RST (0x00000206) +#define AQT1000_I2S_SHADOW_I2S_0_CTL (0x00000207) +#define AQT1000_I2S_SHADOW_I2S_0_RX_CFG (0x00000208) +#define AQT1000_PAGE5_BASE (0x00000500) +#define AQT1000_PAGE5_PAGE_REGISTER (0x00000500) +#define AQT1000_INTR_CTRL_INTR_CTRL_BASE (0x00000501) +#define AQT1000_INTR_CTRL_MCU_INT_POLARITY (0x00000501) +#define AQT1000_INTR_CTRL_INT_MASK_0 (0x00000502) +#define AQT1000_INTR_CTRL_INT_MASK_1 (0x00000503) +#define AQT1000_INTR_CTRL_INT_MASK_2 (0x00000504) +#define AQT1000_INTR_CTRL_INT_MASK_3 (0x00000505) +#define AQT1000_INTR_CTRL_INT_MASK_4 (0x00000506) +#define AQT1000_INTR_CTRL_INT_MASK_5 (0x00000507) +#define AQT1000_INTR_CTRL_INT_MASK_6 (0x00000508) +#define AQT1000_INTR_CTRL_INT_STATUS_0 (0x00000509) +#define AQT1000_INTR_CTRL_INT_STATUS_1 (0x0000050A) +#define AQT1000_INTR_CTRL_INT_STATUS_2 (0x0000050B) +#define AQT1000_INTR_CTRL_INT_STATUS_3 (0x0000050C) +#define AQT1000_INTR_CTRL_INT_STATUS_4 (0x0000050D) +#define AQT1000_INTR_CTRL_INT_STATUS_5 (0x0000050E) +#define AQT1000_INTR_CTRL_INT_STATUS_6 (0x0000050F) +#define AQT1000_INTR_CTRL_INT_CLEAR_0 (0x00000510) +#define AQT1000_INTR_CTRL_INT_CLEAR_1 (0x00000511) +#define AQT1000_INTR_CTRL_INT_CLEAR_2 (0x00000512) +#define AQT1000_INTR_CTRL_INT_CLEAR_3 (0x00000513) +#define AQT1000_INTR_CTRL_INT_CLEAR_4 (0x00000514) +#define AQT1000_INTR_CTRL_INT_CLEAR_5 (0x00000515) +#define AQT1000_INTR_CTRL_INT_CLEAR_6 (0x00000516) +#define AQT1000_INTR_CTRL_INT_TYPE_0 (0x00000517) +#define AQT1000_INTR_CTRL_INT_TYPE_1 (0x00000518) +#define AQT1000_INTR_CTRL_INT_TYPE_2 (0x00000519) +#define AQT1000_INTR_CTRL_INT_TYPE_3 (0x0000051A) +#define AQT1000_INTR_CTRL_INT_TYPE_4 (0x0000051B) +#define AQT1000_INTR_CTRL_INT_TYPE_5 (0x0000051C) +#define AQT1000_INTR_CTRL_INT_TYPE_6 (0x0000051D) +#define AQT1000_INTR_CTRL_INT_TEST_EN_0 (0x0000051E) +#define AQT1000_INTR_CTRL_INT_TEST_EN_1 (0x0000051F) +#define AQT1000_INTR_CTRL_INT_TEST_EN_2 (0x00000520) +#define AQT1000_INTR_CTRL_INT_TEST_EN_3 (0x00000521) +#define AQT1000_INTR_CTRL_INT_TEST_EN_4 (0x00000522) +#define AQT1000_INTR_CTRL_INT_TEST_EN_5 (0x00000523) +#define AQT1000_INTR_CTRL_INT_TEST_EN_6 (0x00000524) +#define AQT1000_INTR_CTRL_INT_TEST_VAL_0 (0x00000525) +#define AQT1000_INTR_CTRL_INT_TEST_VAL_1 (0x00000526) +#define AQT1000_INTR_CTRL_INT_TEST_VAL_2 (0x00000527) +#define AQT1000_INTR_CTRL_INT_TEST_VAL_3 (0x00000528) +#define AQT1000_INTR_CTRL_INT_TEST_VAL_4 (0x00000529) +#define AQT1000_INTR_CTRL_INT_TEST_VAL_5 (0x0000052A) +#define AQT1000_INTR_CTRL_INT_TEST_VAL_6 (0x0000052B) +#define AQT1000_INTR_CTRL_INT_DEST_0 (0x0000052C) +#define AQT1000_INTR_CTRL_INT_DEST_1 (0x0000052D) +#define AQT1000_INTR_CTRL_INT_DEST_2 (0x0000052E) +#define AQT1000_INTR_CTRL_INT_DEST_3 (0x0000052F) +#define AQT1000_INTR_CTRL_INT_DEST_4 (0x00000530) +#define AQT1000_INTR_CTRL_INT_DEST_5 (0x00000531) +#define AQT1000_INTR_CTRL_INT_DEST_6 (0x00000532) +#define AQT1000_INTR_CTRL_INT_DEST_7 (0x00000533) +#define AQT1000_INTR_CTRL_INT_DEST_8 (0x00000534) +#define AQT1000_INTR_CTRL_INT_DEST_9 (0x00000535) +#define AQT1000_INTR_CTRL_INT_DEST_10 (0x00000536) +#define AQT1000_INTR_CTRL_INT_DEST_11 (0x00000537) +#define AQT1000_INTR_CTRL_INT_DEST_12 (0x00000538) +#define AQT1000_INTR_CTRL_INT_DEST_13 (0x00000539) +#define AQT1000_INTR_CTRL_CLR_COMMIT (0x000005E1) +#define AQT1000_ANA_BASE (0x00000600) +#define AQT1000_ANA_PAGE_REGISTER (0x00000600) +#define AQT1000_ANA_BIAS (0x00000601) +#define AQT1000_ANA_RX_SUPPLIES (0x00000608) +#define AQT1000_ANA_HPH (0x00000609) +#define AQT1000_ANA_AMIC1 (0x0000060E) +#define AQT1000_ANA_AMIC2 (0x0000060F) +#define AQT1000_ANA_AMIC3 (0x00000610) +#define AQT1000_ANA_AMIC3_HPF (0x00000611) +#define AQT1000_ANA_MBHC_MECH (0x00000614) +#define AQT1000_ANA_MBHC_ELECT (0x00000615) +#define AQT1000_ANA_MBHC_ZDET (0x00000616) +#define AQT1000_ANA_MBHC_RESULT_1 (0x00000617) +#define AQT1000_ANA_MBHC_RESULT_2 (0x00000618) +#define AQT1000_ANA_MBHC_RESULT_3 (0x00000619) +#define AQT1000_ANA_MBHC_BTN0 (0x0000061A) +#define AQT1000_ANA_MBHC_BTN1 (0x0000061B) +#define AQT1000_ANA_MBHC_BTN2 (0x0000061C) +#define AQT1000_ANA_MBHC_BTN3 (0x0000061D) +#define AQT1000_ANA_MBHC_BTN4 (0x0000061E) +#define AQT1000_ANA_MBHC_BTN5 (0x0000061F) +#define AQT1000_ANA_MBHC_BTN6 (0x00000620) +#define AQT1000_ANA_MBHC_BTN7 (0x00000621) +#define AQT1000_ANA_MICB1 (0x00000622) +#define AQT1000_ANA_MICB1_RAMP (0x00000624) +#define AQT1000_BIAS_BASE (0x00000628) +#define AQT1000_BIAS_CTL (0x00000628) +#define AQT1000_BIAS_CCOMP_FINE_ADJ (0x00000629) +#define AQT1000_LED_BASE (0x0000062E) +#define AQT1000_LED_LED_MODE_SEL_R (0x0000062E) +#define AQT1000_LED_LED_MISC_R (0x0000062F) +#define AQT1000_LED_LED_MODE_SEL_G (0x00000630) +#define AQT1000_LED_LED_MISC_G (0x00000631) +#define AQT1000_LED_LED_MODE_SEL_B (0x00000632) +#define AQT1000_LED_LED_MISC_B (0x00000633) +#define AQT1000_LDOH_BASE (0x0000063A) +#define AQT1000_LDOH_MODE (0x0000063A) +#define AQT1000_LDOH_BIAS (0x0000063B) +#define AQT1000_LDOH_STB_LOADS (0x0000063C) +#define AQT1000_LDOH_MISC1 (0x0000063D) +#define AQT1000_LDOL_BASE (0x00000640) +#define AQT1000_LDOL_VDDCX_ADJUST (0x00000640) +#define AQT1000_LDOL_DISABLE_LDOL (0x00000641) +#define AQT1000_BUCK_5V_BASE (0x00000644) +#define AQT1000_BUCK_5V_EN_CTL (0x00000644) +#define AQT1000_BUCK_5V_VOUT_SEL (0x00000645) +#define AQT1000_BUCK_5V_CTRL_VCL_1 (0x00000646) +#define AQT1000_BUCK_5V_CTRL_VCL_2 (0x00000647) +#define AQT1000_BUCK_5V_CTRL_CCL_2 (0x00000648) +#define AQT1000_BUCK_5V_CTRL_CCL_1 (0x00000649) +#define AQT1000_BUCK_5V_CTRL_CCL_3 (0x0000064A) +#define AQT1000_BUCK_5V_CTRL_CCL_4 (0x0000064B) +#define AQT1000_BUCK_5V_CTRL_CCL_5 (0x0000064C) +#define AQT1000_BUCK_5V_IBIAS_CTL_1 (0x0000064D) +#define AQT1000_BUCK_5V_IBIAS_CTL_2 (0x0000064E) +#define AQT1000_BUCK_5V_IBIAS_CTL_3 (0x0000064F) +#define AQT1000_BUCK_5V_IBIAS_CTL_4 (0x00000650) +#define AQT1000_BUCK_5V_IBIAS_CTL_5 (0x00000651) +#define AQT1000_BUCK_5V_ATEST_DTEST_CTL (0x00000652) +#define AQT1000_PON_BASE (0x00000653) +#define AQT1000_PON_BG_CTRL (0x00000653) +#define AQT1000_PON_TEST_CTRL (0x00000654) +#define AQT1000_MBHC_BASE (0x00000656) +#define AQT1000_MBHC_CTL_CLK (0x00000656) +#define AQT1000_MBHC_CTL_ANA (0x00000657) +#define AQT1000_MBHC_CTL_SPARE_1 (0x00000658) +#define AQT1000_MBHC_CTL_SPARE_2 (0x00000659) +#define AQT1000_MBHC_CTL_BCS (0x0000065A) +#define AQT1000_MBHC_MOISTURE_DET_FSM_STATUS (0x0000065B) +#define AQT1000_MBHC_TEST_CTL (0x0000065C) +#define AQT1000_MICB1_BASE (0x0000066B) +#define AQT1000_MICB1_TEST_CTL_1 (0x0000066B) +#define AQT1000_MICB1_TEST_CTL_2 (0x0000066C) +#define AQT1000_MICB1_TEST_CTL_3 (0x0000066D) +#define AQT1000_MICB1_MISC_BASE (0x0000066E) +#define AQT1000_MICB1_MISC_MICB1_INM_RES_BIAS (0x0000066E) +#define AQT1000_MICB1_MISC_MICB_MISC1 (0x0000066F) +#define AQT1000_MICB1_MISC_MICB_MISC2 (0x00000670) +#define AQT1000_TX_COM_BASE (0x00000677) +#define AQT1000_TX_COM_ADC_VCM (0x00000677) +#define AQT1000_TX_COM_BIAS_ATEST (0x00000678) +#define AQT1000_TX_COM_ADC_INT1_IB (0x00000679) +#define AQT1000_TX_COM_ADC_INT2_IB (0x0000067A) +#define AQT1000_TX_COM_TXFE_DIV_CTL (0x0000067B) +#define AQT1000_TX_COM_TXFE_DIV_START (0x0000067C) +#define AQT1000_TX_COM_TXFE_DIV_STOP_9P6M (0x0000067D) +#define AQT1000_TX_COM_TXFE_DIV_STOP_12P288M (0x0000067E) +#define AQT1000_TX_1_2_BASE (0x0000067F) +#define AQT1000_TX_1_2_TEST_EN (0x0000067F) +#define AQT1000_TX_1_2_ADC_IB (0x00000680) +#define AQT1000_TX_1_2_ATEST_REFCTL (0x00000681) +#define AQT1000_TX_1_2_TEST_CTL (0x00000682) +#define AQT1000_TX_1_2_TEST_BLK_EN (0x00000683) +#define AQT1000_TX_1_2_TXFE_CLKDIV (0x00000684) +#define AQT1000_TX_1_2_SAR1_ERR (0x00000685) +#define AQT1000_TX_1_2_SAR2_ERR (0x00000686) +#define AQT1000_TX_3_BASE (0x00000687) +#define AQT1000_TX_3_TEST_EN (0x00000687) +#define AQT1000_TX_3_ADC_IB (0x00000688) +#define AQT1000_TX_3_ATEST_REFCTL (0x00000689) +#define AQT1000_TX_3_TEST_CTL (0x0000068A) +#define AQT1000_TX_3_TEST_BLK_EN (0x0000068B) +#define AQT1000_TX_3_TXFE_CLKDIV (0x0000068C) +#define AQT1000_TX_3_SAR1_ERR (0x0000068D) +#define AQT1000_TX_3_SAR2_ERR (0x0000068E) +#define AQT1000_TX_BASE (0x0000068F) +#define AQT1000_TX_ATEST1_2_SEL (0x0000068F) +#define AQT1000_CLASSH_BASE (0x00000697) +#define AQT1000_CLASSH_MODE_1 (0x00000697) +#define AQT1000_CLASSH_MODE_2 (0x00000698) +#define AQT1000_CLASSH_MODE_3 (0x00000699) +#define AQT1000_CLASSH_CTRL_VCL_1 (0x0000069A) +#define AQT1000_CLASSH_CTRL_VCL_2 (0x0000069B) +#define AQT1000_CLASSH_CTRL_CCL_1 (0x0000069C) +#define AQT1000_CLASSH_CTRL_CCL_2 (0x0000069D) +#define AQT1000_CLASSH_CTRL_CCL_3 (0x0000069E) +#define AQT1000_CLASSH_CTRL_CCL_4 (0x0000069F) +#define AQT1000_CLASSH_CTRL_CCL_5 (0x000006A0) +#define AQT1000_CLASSH_BUCK_TMUX_A_D (0x000006A1) +#define AQT1000_CLASSH_BUCK_SW_DRV_CNTL (0x000006A2) +#define AQT1000_CLASSH_SPARE (0x000006A3) +#define AQT1000_FLYBACK_BASE (0x000006A4) +#define AQT1000_FLYBACK_EN (0x000006A4) +#define AQT1000_FLYBACK_VNEG_CTRL_1 (0x000006A5) +#define AQT1000_FLYBACK_VNEG_CTRL_2 (0x000006A6) +#define AQT1000_FLYBACK_VNEG_CTRL_3 (0x000006A7) +#define AQT1000_FLYBACK_VNEG_CTRL_4 (0x000006A8) +#define AQT1000_FLYBACK_VNEG_CTRL_5 (0x000006A9) +#define AQT1000_FLYBACK_VNEG_CTRL_6 (0x000006AA) +#define AQT1000_FLYBACK_VNEG_CTRL_7 (0x000006AB) +#define AQT1000_FLYBACK_VNEG_CTRL_8 (0x000006AC) +#define AQT1000_FLYBACK_VNEG_CTRL_9 (0x000006AD) +#define AQT1000_FLYBACK_VNEGDAC_CTRL_1 (0x000006AE) +#define AQT1000_FLYBACK_VNEGDAC_CTRL_2 (0x000006AF) +#define AQT1000_FLYBACK_VNEGDAC_CTRL_3 (0x000006B0) +#define AQT1000_FLYBACK_CTRL_1 (0x000006B1) +#define AQT1000_FLYBACK_TEST_CTL (0x000006B2) +#define AQT1000_RX_BASE (0x000006B3) +#define AQT1000_RX_AUX_SW_CTL (0x000006B3) +#define AQT1000_RX_PA_AUX_IN_CONN (0x000006B4) +#define AQT1000_RX_TIMER_DIV (0x000006B5) +#define AQT1000_RX_OCP_CTL (0x000006B6) +#define AQT1000_RX_OCP_COUNT (0x000006B7) +#define AQT1000_RX_BIAS_ATEST (0x000006B8) +#define AQT1000_RX_BIAS_MISC1 (0x000006B9) +#define AQT1000_RX_BIAS_HPH_LDO (0x000006BA) +#define AQT1000_RX_BIAS_HPH_PA (0x000006BB) +#define AQT1000_RX_BIAS_HPH_RDACBUFF_CNP2 (0x000006BC) +#define AQT1000_RX_BIAS_HPH_RDAC_LDO (0x000006BD) +#define AQT1000_RX_BIAS_HPH_CNP1 (0x000006BE) +#define AQT1000_RX_BIAS_HPH_LOWPOWER (0x000006BF) +#define AQT1000_RX_BIAS_MISC2 (0x000006C0) +#define AQT1000_RX_BIAS_MISC3 (0x000006C1) +#define AQT1000_RX_BIAS_MISC4 (0x000006C2) +#define AQT1000_RX_BIAS_MISC5 (0x000006C3) +#define AQT1000_RX_BIAS_BUCK_RST (0x000006C4) +#define AQT1000_RX_BIAS_BUCK_VREF_ERRAMP (0x000006C5) +#define AQT1000_RX_BIAS_FLYB_ERRAMP (0x000006C6) +#define AQT1000_RX_BIAS_FLYB_BUFF (0x000006C7) +#define AQT1000_RX_BIAS_FLYB_MID_RST (0x000006C8) +#define AQT1000_HPH_BASE (0x000006C9) +#define AQT1000_HPH_L_STATUS (0x000006C9) +#define AQT1000_HPH_R_STATUS (0x000006CA) +#define AQT1000_HPH_CNP_EN (0x000006CB) +#define AQT1000_HPH_CNP_WG_CTL (0x000006CC) +#define AQT1000_HPH_CNP_WG_TIME (0x000006CD) +#define AQT1000_HPH_OCP_CTL (0x000006CE) +#define AQT1000_HPH_AUTO_CHOP (0x000006CF) +#define AQT1000_HPH_CHOP_CTL (0x000006D0) +#define AQT1000_HPH_PA_CTL1 (0x000006D1) +#define AQT1000_HPH_PA_CTL2 (0x000006D2) +#define AQT1000_HPH_L_EN (0x000006D3) +#define AQT1000_HPH_L_TEST (0x000006D4) +#define AQT1000_HPH_L_ATEST (0x000006D5) +#define AQT1000_HPH_R_EN (0x000006D6) +#define AQT1000_HPH_R_TEST (0x000006D7) +#define AQT1000_HPH_R_ATEST (0x000006D8) +#define AQT1000_HPH_RDAC_CLK_CTL1 (0x000006D9) +#define AQT1000_HPH_RDAC_CLK_CTL2 (0x000006DA) +#define AQT1000_HPH_RDAC_LDO_CTL (0x000006DB) +#define AQT1000_HPH_RDAC_CHOP_CLK_LP_CTL (0x000006DC) +#define AQT1000_HPH_REFBUFF_UHQA_CTL (0x000006DD) +#define AQT1000_HPH_REFBUFF_LP_CTL (0x000006DE) +#define AQT1000_HPH_L_DAC_CTL (0x000006DF) +#define AQT1000_HPH_R_DAC_CTL (0x000006E0) +#define AQT1000_HPHLR_BASE (0x000006E1) +#define AQT1000_HPHLR_SURGE_COMP_SEL (0x000006E1) +#define AQT1000_HPHLR_SURGE_EN (0x000006E2) +#define AQT1000_HPHLR_SURGE_MISC1 (0x000006E3) +#define AQT1000_HPHLR_SURGE_STATUS (0x000006E4) +#define AQT1000_ANA_NEW_BASE (0x00000700) +#define AQT1000_ANA_NEW_PAGE_REGISTER (0x00000700) +#define AQT1000_HPH_NEW_BASE (0x00000701) +#define AQT1000_HPH_NEW_ANA_HPH2 (0x00000701) +#define AQT1000_HPH_NEW_ANA_HPH3 (0x00000702) +#define AQT1000_CLK_SYS_BASE (0x0000070E) +#define AQT1000_CLK_SYS_MCLK1_PRG (0x0000070E) +#define AQT1000_CLK_SYS_MCLK2_I2S_HS_CLK_PRG (0x0000070F) +#define AQT1000_CLK_SYS_XO_CAP_XTP (0x00000710) +#define AQT1000_CLK_SYS_XO_CAP_XTM (0x00000711) +#define AQT1000_CLK_SYS_PLL_ENABLES (0x00000712) +#define AQT1000_CLK_SYS_PLL_PRESET (0x00000713) +#define AQT1000_CLK_SYS_PLL_STATUS (0x00000714) +#define AQT1000_MBHC_NEW_BASE (0x0000071F) +#define AQT1000_MBHC_NEW_ELECT_REM_CLAMP_CTL (0x0000071F) +#define AQT1000_MBHC_NEW_CTL_1 (0x00000720) +#define AQT1000_MBHC_NEW_CTL_2 (0x00000721) +#define AQT1000_MBHC_NEW_PLUG_DETECT_CTL (0x00000722) +#define AQT1000_MBHC_NEW_ZDET_ANA_CTL (0x00000723) +#define AQT1000_MBHC_NEW_ZDET_RAMP_CTL (0x00000724) +#define AQT1000_MBHC_NEW_FSM_STATUS (0x00000725) +#define AQT1000_MBHC_NEW_ADC_RESULT (0x00000726) +#define AQT1000_HPH_NEW_INT_BASE (0x00000732) +#define AQT1000_HPH_NEW_INT_RDAC_GAIN_CTL (0x00000732) +#define AQT1000_HPH_NEW_INT_RDAC_HD2_CTL_L (0x00000733) +#define AQT1000_HPH_NEW_INT_RDAC_VREF_CTL (0x00000734) +#define AQT1000_HPH_NEW_INT_RDAC_OVERRIDE_CTL (0x00000735) +#define AQT1000_HPH_NEW_INT_RDAC_HD2_CTL_R (0x00000736) +#define AQT1000_HPH_NEW_INT_PA_MISC1 (0x00000737) +#define AQT1000_HPH_NEW_INT_PA_MISC2 (0x00000738) +#define AQT1000_HPH_NEW_INT_PA_RDAC_MISC (0x00000739) +#define AQT1000_HPH_NEW_INT_HPH_TIMER1 (0x0000073A) +#define AQT1000_HPH_NEW_INT_HPH_TIMER2 (0x0000073B) +#define AQT1000_HPH_NEW_INT_HPH_TIMER3 (0x0000073C) +#define AQT1000_HPH_NEW_INT_HPH_TIMER4 (0x0000073D) +#define AQT1000_HPH_NEW_INT_PA_RDAC_MISC2 (0x0000073E) +#define AQT1000_HPH_NEW_INT_PA_RDAC_MISC3 (0x0000073F) +#define AQT1000_RX_NEW_INT_BASE (0x00000745) +#define AQT1000_RX_NEW_INT_HPH_RDAC_BIAS_LOHIFI (0x00000745) +#define AQT1000_RX_NEW_INT_HPH_RDAC_BIAS_ULP (0x00000746) +#define AQT1000_RX_NEW_INT_HPH_RDAC_LDO_LP (0x00000747) +#define AQT1000_CLK_SYS_INT_BASE (0x0000076C) +#define AQT1000_CLK_SYS_INT_CLK_TEST1 (0x0000076C) +#define AQT1000_CLK_SYS_INT_XO_TEST1 (0x0000076D) +#define AQT1000_CLK_SYS_INT_XO_TEST2 (0x0000076E) +#define AQT1000_CLK_SYS_INT_POST_DIV_REG0 (0x0000076F) +#define AQT1000_CLK_SYS_INT_POST_DIV_REG1 (0x00000770) +#define AQT1000_CLK_SYS_INT_REF_DIV_REG0 (0x00000771) +#define AQT1000_CLK_SYS_INT_REF_DIV_REG1 (0x00000772) +#define AQT1000_CLK_SYS_INT_FILTER_REG0 (0x00000773) +#define AQT1000_CLK_SYS_INT_FILTER_REG1 (0x00000774) +#define AQT1000_CLK_SYS_INT_PLL_L_VAL (0x00000775) +#define AQT1000_CLK_SYS_INT_PLL_M_VAL (0x00000776) +#define AQT1000_CLK_SYS_INT_PLL_N_VAL (0x00000777) +#define AQT1000_CLK_SYS_INT_TEST_REG0 (0x00000778) +#define AQT1000_CLK_SYS_INT_PFD_CP_DSM_PROG (0x00000779) +#define AQT1000_CLK_SYS_INT_VCO_PROG (0x0000077A) +#define AQT1000_CLK_SYS_INT_TEST_REG1 (0x0000077B) +#define AQT1000_CLK_SYS_INT_LDO_LOCK_CFG (0x0000077C) +#define AQT1000_CLK_SYS_INT_DIG_LOCK_DET_CFG (0x0000077D) +#define AQT1000_MBHC_NEW_INT_BASE (0x000007AF) +#define AQT1000_MBHC_NEW_INT_MOISTURE_DET_DC_CTRL (0x000007AF) +#define AQT1000_MBHC_NEW_INT_MOISTURE_DET_POLLING_CTRL (0x000007B0) +#define AQT1000_MBHC_NEW_INT_MECH_DET_CURRENT (0x000007B1) +#define AQT1000_MBHC_NEW_INT_SPARE_2 (0x000007B2) +#define AQT1000_PAGE10_BASE (0x00000A00) +#define AQT1000_PAGE10_PAGE_REGISTER (0x00000A00) +#define AQT1000_CDC_ANC0_BASE (0x00000A01) +#define AQT1000_CDC_ANC0_CLK_RESET_CTL (0x00000A01) +#define AQT1000_CDC_ANC0_MODE_1_CTL (0x00000A02) +#define AQT1000_CDC_ANC0_MODE_2_CTL (0x00000A03) +#define AQT1000_CDC_ANC0_FF_SHIFT (0x00000A04) +#define AQT1000_CDC_ANC0_FB_SHIFT (0x00000A05) +#define AQT1000_CDC_ANC0_LPF_FF_A_CTL (0x00000A06) +#define AQT1000_CDC_ANC0_LPF_FF_B_CTL (0x00000A07) +#define AQT1000_CDC_ANC0_LPF_FB_CTL (0x00000A08) +#define AQT1000_CDC_ANC0_SMLPF_CTL (0x00000A09) +#define AQT1000_CDC_ANC0_DCFLT_SHIFT_CTL (0x00000A0A) +#define AQT1000_CDC_ANC0_IIR_ADAPT_CTL (0x00000A0B) +#define AQT1000_CDC_ANC0_IIR_COEFF_1_CTL (0x00000A0C) +#define AQT1000_CDC_ANC0_IIR_COEFF_2_CTL (0x00000A0D) +#define AQT1000_CDC_ANC0_FF_A_GAIN_CTL (0x00000A0E) +#define AQT1000_CDC_ANC0_FF_B_GAIN_CTL (0x00000A0F) +#define AQT1000_CDC_ANC0_FB_GAIN_CTL (0x00000A10) +#define AQT1000_CDC_ANC0_RC_COMMON_CTL (0x00000A11) +#define AQT1000_CDC_ANC0_FIFO_COMMON_CTL (0x00000A13) +#define AQT1000_CDC_ANC0_RC0_STATUS_FMIN_CNTR (0x00000A14) +#define AQT1000_CDC_ANC0_RC1_STATUS_FMIN_CNTR (0x00000A15) +#define AQT1000_CDC_ANC0_RC0_STATUS_FMAX_CNTR (0x00000A16) +#define AQT1000_CDC_ANC0_RC1_STATUS_FMAX_CNTR (0x00000A17) +#define AQT1000_CDC_ANC0_STATUS_FIFO (0x00000A18) +#define AQT1000_CDC_ANC1_BASE (0x00000A19) +#define AQT1000_CDC_ANC1_CLK_RESET_CTL (0x00000A19) +#define AQT1000_CDC_ANC1_MODE_1_CTL (0x00000A1A) +#define AQT1000_CDC_ANC1_MODE_2_CTL (0x00000A1B) +#define AQT1000_CDC_ANC1_FF_SHIFT (0x00000A1C) +#define AQT1000_CDC_ANC1_FB_SHIFT (0x00000A1D) +#define AQT1000_CDC_ANC1_LPF_FF_A_CTL (0x00000A1E) +#define AQT1000_CDC_ANC1_LPF_FF_B_CTL (0x00000A1F) +#define AQT1000_CDC_ANC1_LPF_FB_CTL (0x00000A20) +#define AQT1000_CDC_ANC1_SMLPF_CTL (0x00000A21) +#define AQT1000_CDC_ANC1_DCFLT_SHIFT_CTL (0x00000A22) +#define AQT1000_CDC_ANC1_IIR_ADAPT_CTL (0x00000A23) +#define AQT1000_CDC_ANC1_IIR_COEFF_1_CTL (0x00000A24) +#define AQT1000_CDC_ANC1_IIR_COEFF_2_CTL (0x00000A25) +#define AQT1000_CDC_ANC1_FF_A_GAIN_CTL (0x00000A26) +#define AQT1000_CDC_ANC1_FF_B_GAIN_CTL (0x00000A27) +#define AQT1000_CDC_ANC1_FB_GAIN_CTL (0x00000A28) +#define AQT1000_CDC_ANC1_RC_COMMON_CTL (0x00000A29) +#define AQT1000_CDC_ANC1_FIFO_COMMON_CTL (0x00000A2B) +#define AQT1000_CDC_ANC1_RC0_STATUS_FMIN_CNTR (0x00000A2C) +#define AQT1000_CDC_ANC1_RC1_STATUS_FMIN_CNTR (0x00000A2D) +#define AQT1000_CDC_ANC1_RC0_STATUS_FMAX_CNTR (0x00000A2E) +#define AQT1000_CDC_ANC1_RC1_STATUS_FMAX_CNTR (0x00000A2F) +#define AQT1000_CDC_ANC1_STATUS_FIFO (0x00000A30) +#define AQT1000_CDC_TX0_BASE (0x00000A31) +#define AQT1000_CDC_TX0_TX_PATH_CTL (0x00000A31) +#define AQT1000_CDC_TX0_TX_PATH_CFG0 (0x00000A32) +#define AQT1000_CDC_TX0_TX_PATH_CFG1 (0x00000A33) +#define AQT1000_CDC_TX0_TX_VOL_CTL (0x00000A34) +#define AQT1000_CDC_TX0_TX_PATH_SEC0 (0x00000A37) +#define AQT1000_CDC_TX0_TX_PATH_SEC1 (0x00000A38) +#define AQT1000_CDC_TX0_TX_PATH_SEC2 (0x00000A39) +#define AQT1000_CDC_TX0_TX_PATH_SEC3 (0x00000A3A) +#define AQT1000_CDC_TX0_TX_PATH_SEC4 (0x00000A3B) +#define AQT1000_CDC_TX0_TX_PATH_SEC5 (0x00000A3C) +#define AQT1000_CDC_TX0_TX_PATH_SEC6 (0x00000A3D) +#define AQT1000_CDC_TX1_BASE (0x00000A41) +#define AQT1000_CDC_TX1_TX_PATH_CTL (0x00000A41) +#define AQT1000_CDC_TX1_TX_PATH_CFG0 (0x00000A42) +#define AQT1000_CDC_TX1_TX_PATH_CFG1 (0x00000A43) +#define AQT1000_CDC_TX1_TX_VOL_CTL (0x00000A44) +#define AQT1000_CDC_TX1_TX_PATH_SEC0 (0x00000A47) +#define AQT1000_CDC_TX1_TX_PATH_SEC1 (0x00000A48) +#define AQT1000_CDC_TX1_TX_PATH_SEC2 (0x00000A49) +#define AQT1000_CDC_TX1_TX_PATH_SEC3 (0x00000A4A) +#define AQT1000_CDC_TX1_TX_PATH_SEC4 (0x00000A4B) +#define AQT1000_CDC_TX1_TX_PATH_SEC5 (0x00000A4C) +#define AQT1000_CDC_TX1_TX_PATH_SEC6 (0x00000A4D) +#define AQT1000_CDC_TX2_BASE (0x00000A51) +#define AQT1000_CDC_TX2_TX_PATH_CTL (0x00000A51) +#define AQT1000_CDC_TX2_TX_PATH_CFG0 (0x00000A52) +#define AQT1000_CDC_TX2_TX_PATH_CFG1 (0x00000A53) +#define AQT1000_CDC_TX2_TX_VOL_CTL (0x00000A54) +#define AQT1000_CDC_TX2_TX_PATH_SEC0 (0x00000A57) +#define AQT1000_CDC_TX2_TX_PATH_SEC1 (0x00000A58) +#define AQT1000_CDC_TX2_TX_PATH_SEC2 (0x00000A59) +#define AQT1000_CDC_TX2_TX_PATH_SEC3 (0x00000A5A) +#define AQT1000_CDC_TX2_TX_PATH_SEC4 (0x00000A5B) +#define AQT1000_CDC_TX2_TX_PATH_SEC5 (0x00000A5C) +#define AQT1000_CDC_TX2_TX_PATH_SEC6 (0x00000A5D) +#define AQT1000_CDC_TX2_TX_PATH_SEC7 (0x00000A5E) +#define AQT1000_PAGE11_BASE (0x00000B00) +#define AQT1000_PAGE11_PAGE_REGISTER (0x00000B00) +#define AQT1000_CDC_COMPANDER1_BASE (0x00000B01) +#define AQT1000_CDC_COMPANDER1_CTL0 (0x00000B01) +#define AQT1000_CDC_COMPANDER1_CTL1 (0x00000B02) +#define AQT1000_CDC_COMPANDER1_CTL2 (0x00000B03) +#define AQT1000_CDC_COMPANDER1_CTL3 (0x00000B04) +#define AQT1000_CDC_COMPANDER1_CTL4 (0x00000B05) +#define AQT1000_CDC_COMPANDER1_CTL5 (0x00000B06) +#define AQT1000_CDC_COMPANDER1_CTL6 (0x00000B07) +#define AQT1000_CDC_COMPANDER1_CTL7 (0x00000B08) +#define AQT1000_CDC_COMPANDER2_BASE (0x00000B09) +#define AQT1000_CDC_COMPANDER2_CTL0 (0x00000B09) +#define AQT1000_CDC_COMPANDER2_CTL1 (0x00000B0A) +#define AQT1000_CDC_COMPANDER2_CTL2 (0x00000B0B) +#define AQT1000_CDC_COMPANDER2_CTL3 (0x00000B0C) +#define AQT1000_CDC_COMPANDER2_CTL4 (0x00000B0D) +#define AQT1000_CDC_COMPANDER2_CTL5 (0x00000B0E) +#define AQT1000_CDC_COMPANDER2_CTL6 (0x00000B0F) +#define AQT1000_CDC_COMPANDER2_CTL7 (0x00000B10) +#define AQT1000_CDC_RX1_BASE (0x00000B55) +#define AQT1000_CDC_RX1_RX_PATH_CTL (0x00000B55) +#define AQT1000_CDC_RX1_RX_PATH_CFG0 (0x00000B56) +#define AQT1000_CDC_RX1_RX_PATH_CFG1 (0x00000B57) +#define AQT1000_CDC_RX1_RX_PATH_CFG2 (0x00000B58) +#define AQT1000_CDC_RX1_RX_VOL_CTL (0x00000B59) +#define AQT1000_CDC_RX1_RX_PATH_MIX_CTL (0x00000B5A) +#define AQT1000_CDC_RX1_RX_PATH_MIX_CFG (0x00000B5B) +#define AQT1000_CDC_RX1_RX_VOL_MIX_CTL (0x00000B5C) +#define AQT1000_CDC_RX1_RX_PATH_SEC0 (0x00000B5D) +#define AQT1000_CDC_RX1_RX_PATH_SEC1 (0x00000B5E) +#define AQT1000_CDC_RX1_RX_PATH_SEC2 (0x00000B5F) +#define AQT1000_CDC_RX1_RX_PATH_SEC3 (0x00000B60) +#define AQT1000_CDC_RX1_RX_PATH_SEC4 (0x00000B61) +#define AQT1000_CDC_RX1_RX_PATH_SEC5 (0x00000B62) +#define AQT1000_CDC_RX1_RX_PATH_SEC6 (0x00000B63) +#define AQT1000_CDC_RX1_RX_PATH_SEC7 (0x00000B64) +#define AQT1000_CDC_RX1_RX_PATH_MIX_SEC0 (0x00000B65) +#define AQT1000_CDC_RX1_RX_PATH_MIX_SEC1 (0x00000B66) +#define AQT1000_CDC_RX1_RX_PATH_DSMDEM_CTL (0x00000B67) +#define AQT1000_CDC_RX2_BASE (0x00000B69) +#define AQT1000_CDC_RX2_RX_PATH_CTL (0x00000B69) +#define AQT1000_CDC_RX2_RX_PATH_CFG0 (0x00000B6A) +#define AQT1000_CDC_RX2_RX_PATH_CFG1 (0x00000B6B) +#define AQT1000_CDC_RX2_RX_PATH_CFG2 (0x00000B6C) +#define AQT1000_CDC_RX2_RX_VOL_CTL (0x00000B6D) +#define AQT1000_CDC_RX2_RX_PATH_MIX_CTL (0x00000B6E) +#define AQT1000_CDC_RX2_RX_PATH_MIX_CFG (0x00000B6F) +#define AQT1000_CDC_RX2_RX_VOL_MIX_CTL (0x00000B70) +#define AQT1000_CDC_RX2_RX_PATH_SEC0 (0x00000B71) +#define AQT1000_CDC_RX2_RX_PATH_SEC1 (0x00000B72) +#define AQT1000_CDC_RX2_RX_PATH_SEC2 (0x00000B73) +#define AQT1000_CDC_RX2_RX_PATH_SEC3 (0x00000B74) +#define AQT1000_CDC_RX2_RX_PATH_SEC4 (0x00000B75) +#define AQT1000_CDC_RX2_RX_PATH_SEC5 (0x00000B76) +#define AQT1000_CDC_RX2_RX_PATH_SEC6 (0x00000B77) +#define AQT1000_CDC_RX2_RX_PATH_SEC7 (0x00000B78) +#define AQT1000_CDC_RX2_RX_PATH_MIX_SEC0 (0x00000B79) +#define AQT1000_CDC_RX2_RX_PATH_MIX_SEC1 (0x00000B7A) +#define AQT1000_CDC_RX2_RX_PATH_DSMDEM_CTL (0x00000B7B) +#define AQT1000_CDC_EQ_IIR0_BASE (0x00000BD1) +#define AQT1000_CDC_EQ_IIR0_PATH_CTL (0x00000BD1) +#define AQT1000_CDC_EQ_IIR0_PATH_CFG0 (0x00000BD2) +#define AQT1000_CDC_EQ_IIR0_PATH_CFG1 (0x00000BD3) +#define AQT1000_CDC_EQ_IIR0_PATH_CFG2 (0x00000BD4) +#define AQT1000_CDC_EQ_IIR0_PATH_CFG3 (0x00000BD5) +#define AQT1000_CDC_EQ_IIR0_COEF_CFG0 (0x00000BD6) +#define AQT1000_CDC_EQ_IIR0_COEF_CFG1 (0x00000BD7) +#define AQT1000_CDC_EQ_IIR1_BASE (0x00000BE1) +#define AQT1000_CDC_EQ_IIR1_PATH_CTL (0x00000BE1) +#define AQT1000_CDC_EQ_IIR1_PATH_CFG0 (0x00000BE2) +#define AQT1000_CDC_EQ_IIR1_PATH_CFG1 (0x00000BE3) +#define AQT1000_CDC_EQ_IIR1_PATH_CFG2 (0x00000BE4) +#define AQT1000_CDC_EQ_IIR1_PATH_CFG3 (0x00000BE5) +#define AQT1000_CDC_EQ_IIR1_COEF_CFG0 (0x00000BE6) +#define AQT1000_CDC_EQ_IIR1_COEF_CFG1 (0x00000BE7) +#define AQT1000_PAGE12_BASE (0x00000C00) +#define AQT1000_PAGE12_PAGE_REGISTER (0x00000C00) +#define AQT1000_CDC_CLSH_CDC_CLSH_BASE (0x00000C01) +#define AQT1000_CDC_CLSH_CRC (0x00000C01) +#define AQT1000_CDC_CLSH_DLY_CTRL (0x00000C02) +#define AQT1000_CDC_CLSH_DECAY_CTRL (0x00000C03) +#define AQT1000_CDC_CLSH_HPH_V_PA (0x00000C04) +#define AQT1000_CDC_CLSH_EAR_V_PA (0x00000C05) +#define AQT1000_CDC_CLSH_HPH_V_HD (0x00000C06) +#define AQT1000_CDC_CLSH_EAR_V_HD (0x00000C07) +#define AQT1000_CDC_CLSH_K1_MSB (0x00000C08) +#define AQT1000_CDC_CLSH_K1_LSB (0x00000C09) +#define AQT1000_CDC_CLSH_K2_MSB (0x00000C0A) +#define AQT1000_CDC_CLSH_K2_LSB (0x00000C0B) +#define AQT1000_CDC_CLSH_IDLE_CTRL (0x00000C0C) +#define AQT1000_CDC_CLSH_IDLE_HPH (0x00000C0D) +#define AQT1000_CDC_CLSH_IDLE_EAR (0x00000C0E) +#define AQT1000_CDC_CLSH_TEST0 (0x00000C0F) +#define AQT1000_CDC_CLSH_TEST1 (0x00000C10) +#define AQT1000_CDC_CLSH_OVR_VREF (0x00000C11) +#define AQT1000_MIXING_ASRC0_BASE (0x00000C55) +#define AQT1000_MIXING_ASRC0_CLK_RST_CTL (0x00000C55) +#define AQT1000_MIXING_ASRC0_CTL0 (0x00000C56) +#define AQT1000_MIXING_ASRC0_CTL1 (0x00000C57) +#define AQT1000_MIXING_ASRC0_FIFO_CTL (0x00000C58) +#define AQT1000_MIXING_ASRC0_STATUS_FMIN_CNTR_LSB (0x00000C59) +#define AQT1000_MIXING_ASRC0_STATUS_FMIN_CNTR_MSB (0x00000C5A) +#define AQT1000_MIXING_ASRC0_STATUS_FMAX_CNTR_LSB (0x00000C5B) +#define AQT1000_MIXING_ASRC0_STATUS_FMAX_CNTR_MSB (0x00000C5C) +#define AQT1000_MIXING_ASRC0_STATUS_FIFO (0x00000C5D) +#define AQT1000_MIXING_ASRC1_BASE (0x00000C61) +#define AQT1000_MIXING_ASRC1_CLK_RST_CTL (0x00000C61) +#define AQT1000_MIXING_ASRC1_CTL0 (0x00000C62) +#define AQT1000_MIXING_ASRC1_CTL1 (0x00000C63) +#define AQT1000_MIXING_ASRC1_FIFO_CTL (0x00000C64) +#define AQT1000_MIXING_ASRC1_STATUS_FMIN_CNTR_LSB (0x00000C65) +#define AQT1000_MIXING_ASRC1_STATUS_FMIN_CNTR_MSB (0x00000C66) +#define AQT1000_MIXING_ASRC1_STATUS_FMAX_CNTR_LSB (0x00000C67) +#define AQT1000_MIXING_ASRC1_STATUS_FMAX_CNTR_MSB (0x00000C68) +#define AQT1000_MIXING_ASRC1_STATUS_FIFO (0x00000C69) +#define AQT1000_CDC_SIDETONE_SRC0_BASE (0x00000CB5) +#define AQT1000_CDC_SIDETONE_SRC0_ST_SRC_PATH_CTL (0x00000CB5) +#define AQT1000_CDC_SIDETONE_SRC0_ST_SRC_PATH_CFG1 (0x00000CB6) +#define AQT1000_SIDETONE_ASRC0_BASE (0x00000CBD) +#define AQT1000_SIDETONE_ASRC0_CLK_RST_CTL (0x00000CBD) +#define AQT1000_SIDETONE_ASRC0_CTL0 (0x00000CBE) +#define AQT1000_SIDETONE_ASRC0_CTL1 (0x00000CBF) +#define AQT1000_SIDETONE_ASRC0_FIFO_CTL (0x00000CC0) +#define AQT1000_SIDETONE_ASRC0_STATUS_FMIN_CNTR_LSB (0x00000CC1) +#define AQT1000_SIDETONE_ASRC0_STATUS_FMIN_CNTR_MSB (0x00000CC2) +#define AQT1000_SIDETONE_ASRC0_STATUS_FMAX_CNTR_LSB (0x00000CC3) +#define AQT1000_SIDETONE_ASRC0_STATUS_FMAX_CNTR_MSB (0x00000CC4) +#define AQT1000_SIDETONE_ASRC0_STATUS_FIFO (0x00000CC5) +#define AQT1000_EC_REF_HQ0_BASE (0x00000CD5) +#define AQT1000_EC_REF_HQ0_EC_REF_HQ_PATH_CTL (0x00000CD5) +#define AQT1000_EC_REF_HQ0_EC_REF_HQ_CFG0 (0x00000CD6) +#define AQT1000_EC_REF_HQ1_BASE (0x00000CDD) +#define AQT1000_EC_REF_HQ1_EC_REF_HQ_PATH_CTL (0x00000CDD) +#define AQT1000_EC_REF_HQ1_EC_REF_HQ_CFG0 (0x00000CDE) +#define AQT1000_EC_ASRC0_BASE (0x00000CE5) +#define AQT1000_EC_ASRC0_CLK_RST_CTL (0x00000CE5) +#define AQT1000_EC_ASRC0_CTL0 (0x00000CE6) +#define AQT1000_EC_ASRC0_CTL1 (0x00000CE7) +#define AQT1000_EC_ASRC0_FIFO_CTL (0x00000CE8) +#define AQT1000_EC_ASRC0_STATUS_FMIN_CNTR_LSB (0x00000CE9) +#define AQT1000_EC_ASRC0_STATUS_FMIN_CNTR_MSB (0x00000CEA) +#define AQT1000_EC_ASRC0_STATUS_FMAX_CNTR_LSB (0x00000CEB) +#define AQT1000_EC_ASRC0_STATUS_FMAX_CNTR_MSB (0x00000CEC) +#define AQT1000_EC_ASRC0_STATUS_FIFO (0x00000CED) +#define AQT1000_EC_ASRC1_BASE (0x00000CF1) +#define AQT1000_EC_ASRC1_CLK_RST_CTL (0x00000CF1) +#define AQT1000_EC_ASRC1_CTL0 (0x00000CF2) +#define AQT1000_EC_ASRC1_CTL1 (0x00000CF3) +#define AQT1000_EC_ASRC1_FIFO_CTL (0x00000CF4) +#define AQT1000_EC_ASRC1_STATUS_FMIN_CNTR_LSB (0x00000CF5) +#define AQT1000_EC_ASRC1_STATUS_FMIN_CNTR_MSB (0x00000CF6) +#define AQT1000_EC_ASRC1_STATUS_FMAX_CNTR_LSB (0x00000CF7) +#define AQT1000_EC_ASRC1_STATUS_FMAX_CNTR_MSB (0x00000CF8) +#define AQT1000_EC_ASRC1_STATUS_FIFO (0x00000CF9) +#define AQT1000_PAGE13_BASE (0x00000D00) +#define AQT1000_PAGE13_PAGE_REGISTER (0x00000D00) +#define AQT1000_CDC_RX_INP_MUX_CDC_RX_INP_MUX_BASE (0x00000D01) +#define AQT1000_CDC_RX_INP_MUX_RX_INT1_CFG0 (0x00000D03) +#define AQT1000_CDC_RX_INP_MUX_RX_INT1_CFG1 (0x00000D04) +#define AQT1000_CDC_RX_INP_MUX_RX_INT2_CFG0 (0x00000D05) +#define AQT1000_CDC_RX_INP_MUX_RX_INT2_CFG1 (0x00000D06) +#define AQT1000_CDC_RX_INP_MUX_EQ_IIR_CFG0 (0x00000D11) +#define AQT1000_CDC_RX_INP_MUX_DSD_CFG0 (0x00000D12) +#define AQT1000_CDC_RX_INP_MUX_RX_MIX_CFG0 (0x00000D13) +#define AQT1000_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0 (0x00000D18) +#define AQT1000_CDC_RX_INP_MUX_ANC_CFG0 (0x00000D1A) +#define AQT1000_CDC_RX_INP_MUX_SPLINE_ASRC_CFG0 (0x00000D1B) +#define AQT1000_CDC_RX_INP_MUX_EC_REF_HQ_CFG0 (0x00000D1C) +#define AQT1000_CDC_TX_INP_MUX_CDC_TX_INP_MUX_BASE (0x00000D1D) +#define AQT1000_CDC_TX_INP_MUX_ADC_MUX0_CFG0 (0x00000D1D) +#define AQT1000_CDC_TX_INP_MUX_ADC_MUX0_CFG1 (0x00000D1E) +#define AQT1000_CDC_TX_INP_MUX_ADC_MUX1_CFG0 (0x00000D1F) +#define AQT1000_CDC_TX_INP_MUX_ADC_MUX1_CFG1 (0x00000D20) +#define AQT1000_CDC_TX_INP_MUX_ADC_MUX2_CFG0 (0x00000D21) +#define AQT1000_CDC_TX_INP_MUX_ADC_MUX2_CFG1 (0x00000D22) +#define AQT1000_CDC_TX_INP_MUX_ADC_MUX10_CFG0 (0x00000D29) +#define AQT1000_CDC_TX_INP_MUX_ADC_MUX10_CFG1 (0x00000D2A) +#define AQT1000_CDC_TX_INP_MUX_ADC_MUX11_CFG0 (0x00000D2B) +#define AQT1000_CDC_TX_INP_MUX_ADC_MUX11_CFG1 (0x00000D2C) +#define AQT1000_CDC_TX_INP_MUX_ADC_MUX12_CFG0 (0x00000D2D) +#define AQT1000_CDC_TX_INP_MUX_ADC_MUX12_CFG1 (0x00000D2E) +#define AQT1000_CDC_TX_INP_MUX_ADC_MUX13_CFG0 (0x00000D2F) +#define AQT1000_CDC_TX_INP_MUX_ADC_MUX13_CFG1 (0x00000D30) +#define AQT1000_CDC_SIDETONE_IIR_INP_MUX_CDC_SIDETONE_IIR_INP_MUX_BASE (0xD31) +#define AQT1000_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG0 (0x00000D31) +#define AQT1000_CDC_IF_ROUTER_CDC_IF_ROUTER_BASE (0x00000D3D) +#define AQT1000_CDC_IF_ROUTER_TX_MUX_CFG0 (0x00000D3D) +#define AQT1000_CDC_CLK_RST_CTRL_CDC_CLK_RST_CTRL_BASE (0x00000D41) +#define AQT1000_CDC_CLK_RST_CTRL_MCLK_CONTROL (0x00000D41) +#define AQT1000_CDC_CLK_RST_CTRL_FS_CNT_CONTROL (0x00000D42) +#define AQT1000_CDC_CLK_RST_CTRL_DSD_CONTROL (0x00000D44) +#define AQT1000_CDC_CLK_RST_CTRL_ASRC_SHARE_CONTROL (0x00000D45) +#define AQT1000_CDC_CLK_RST_CTRL_GFM_CONTROL (0x00000D46) +#define AQT1000_CDC_CLK_RST_CTRL_I2S_CONTROL (0x00000D47) +#define AQT1000_CDC_SIDETONE_IIR0_BASE (0x00000D55) +#define AQT1000_CDC_SIDETONE_IIR0_IIR_PATH_CTL (0x00000D55) +#define AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL (0x00000D56) +#define AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL (0x00000D57) +#define AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL (0x00000D58) +#define AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL (0x00000D59) +#define AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B5_CTL (0x00000D5A) +#define AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B6_CTL (0x00000D5B) +#define AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B7_CTL (0x00000D5C) +#define AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B8_CTL (0x00000D5D) +#define AQT1000_CDC_SIDETONE_IIR0_IIR_CTL (0x00000D5E) +#define AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_TIMER_CTL (0x00000D5F) +#define AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL (0x00000D60) +#define AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL (0x00000D61) +#define AQT1000_CDC_TOP_CDC_TOP_BASE (0x00000D81) +#define AQT1000_CDC_TOP_TOP_CFG0 (0x00000D81) +#define AQT1000_CDC_TOP_HPHL_COMP_WR_LSB (0x00000D89) +#define AQT1000_CDC_TOP_HPHL_COMP_WR_MSB (0x00000D8A) +#define AQT1000_CDC_TOP_HPHL_COMP_LUT (0x00000D8B) +#define AQT1000_CDC_TOP_HPHL_COMP_RD_LSB (0x00000D8C) +#define AQT1000_CDC_TOP_HPHL_COMP_RD_MSB (0x00000D8D) +#define AQT1000_CDC_TOP_HPHR_COMP_WR_LSB (0x00000D8E) +#define AQT1000_CDC_TOP_HPHR_COMP_WR_MSB (0x00000D8F) +#define AQT1000_CDC_TOP_HPHR_COMP_LUT (0x00000D90) +#define AQT1000_CDC_TOP_HPHR_COMP_RD_LSB (0x00000D91) +#define AQT1000_CDC_TOP_HPHR_COMP_RD_MSB (0x00000D92) +#define AQT1000_CDC_DSD0_BASE (0x00000DB1) +#define AQT1000_CDC_DSD0_PATH_CTL (0x00000DB1) +#define AQT1000_CDC_DSD0_CFG0 (0x00000DB2) +#define AQT1000_CDC_DSD0_CFG1 (0x00000DB3) +#define AQT1000_CDC_DSD0_CFG2 (0x00000DB4) +#define AQT1000_CDC_DSD0_CFG3 (0x00000DB5) +#define AQT1000_CDC_DSD0_CFG4 (0x00000DB6) +#define AQT1000_CDC_DSD0_CFG5 (0x00000DB7) +#define AQT1000_CDC_DSD1_BASE (0x00000DC1) +#define AQT1000_CDC_DSD1_PATH_CTL (0x00000DC1) +#define AQT1000_CDC_DSD1_CFG0 (0x00000DC2) +#define AQT1000_CDC_DSD1_CFG1 (0x00000DC3) +#define AQT1000_CDC_DSD1_CFG2 (0x00000DC4) +#define AQT1000_CDC_DSD1_CFG3 (0x00000DC5) +#define AQT1000_CDC_DSD1_CFG4 (0x00000DC6) +#define AQT1000_CDC_DSD1_CFG5 (0x00000DC7) +#define AQT1000_CDC_RX_IDLE_DET_CDC_RX_IDLE_DET_BASE (0x00000DD1) +#define AQT1000_CDC_RX_IDLE_DET_PATH_CTL (0x00000DD1) +#define AQT1000_CDC_RX_IDLE_DET_CFG0 (0x00000DD2) +#define AQT1000_CDC_RX_IDLE_DET_CFG1 (0x00000DD3) +#define AQT1000_CDC_RX_IDLE_DET_CFG2 (0x00000DD4) +#define AQT1000_CDC_RX_IDLE_DET_CFG3 (0x00000DD5) +#define AQT1000_CDC_DOP_DET_CDC_DOP_DET_BASE (0x00000DD9) +#define AQT1000_CDC_DOP_DET_CTL (0x00000DD9) +#define AQT1000_CDC_DOP_DET_CFG0 (0x00000DDA) +#define AQT1000_CDC_DOP_DET_CFG1 (0x00000DDB) +#define AQT1000_CDC_DOP_DET_CFG2 (0x00000DDC) +#define AQT1000_CDC_DOP_DET_CFG3 (0x00000DDD) +#define AQT1000_CDC_DOP_DET_CFG4 (0x00000DDE) +#define AQT1000_CDC_DOP_DET_STATUS0 (0x00000DE1) +#define AQT1000_PAGE15_BASE (0x00000F00) +#define AQT1000_PAGE15_PAGE_REGISTER (0x00000F00) +#define AQT1000_CDC_DEBUG_CDC_DEBUG_BASE (0x00000FA1) +#define AQT1000_CDC_DEBUG_DSD0_DEBUG_CFG0 (0x00000FA1) +#define AQT1000_CDC_DEBUG_DSD0_DEBUG_CFG1 (0x00000FA2) +#define AQT1000_CDC_DEBUG_DSD0_DEBUG_CFG2 (0x00000FA3) +#define AQT1000_CDC_DEBUG_DSD0_DEBUG_CFG3 (0x00000FA4) +#define AQT1000_CDC_DEBUG_DSD1_DEBUG_CFG0 (0x00000FA5) +#define AQT1000_CDC_DEBUG_DSD1_DEBUG_CFG1 (0x00000FA6) +#define AQT1000_CDC_DEBUG_DSD1_DEBUG_CFG2 (0x00000FA7) +#define AQT1000_CDC_DEBUG_DSD1_DEBUG_CFG3 (0x00000FA8) +#define AQT1000_CDC_DEBUG_RC_RE_ASRC_DEBUG_CFG0 (0x00000FAB) +#define AQT1000_CDC_DEBUG_ANC0_RC0_FIFO_CTL (0x00000FAC) +#define AQT1000_CDC_DEBUG_ANC0_RC1_FIFO_CTL (0x00000FAD) +#define AQT1000_CDC_DEBUG_ANC1_RC0_FIFO_CTL (0x00000FAE) +#define AQT1000_CDC_DEBUG_ANC1_RC1_FIFO_CTL (0x00000FAF) +#define AQT1000_CDC_DEBUG_ANC_RC_RST_DBG_CNTR (0x00000FB0) +#define AQT1000_PAGE128_BASE (0x00008000) +#define AQT1000_PAGE128_PAGE_REGISTER (0x00008000) +#define AQT1000_TLMM_TLMM_BASE (0x00008001) +#define AQT1000_TLMM_SPI_CLK_PINCFG (0x00008001) +#define AQT1000_TLMM_SPI_MOSI_PINCFG (0x00008002) +#define AQT1000_TLMM_SPI_MISO_PINCFG (0x00008003) +#define AQT1000_TLMM_SPI_CS_N_PINCFG (0x00008004) +#define AQT1000_TLMM_GPIO1_PINCFG (0x00008005) +#define AQT1000_TLMM_GPIO2_PINCFG (0x00008006) +#define AQT1000_TLMM_GPIO3_PINCFG (0x00008007) +#define AQT1000_TLMM_GPIO4_PINCFG (0x00008008) +#define AQT1000_TLMM_GPIO5_PINCFG (0x00008009) +#define AQT1000_TLMM_GPIO6_PINCFG (0x0000800A) +#define AQT1000_TLMM_GPIO7_PINCFG (0x0000800B) +#define AQT1000_TLMM_GPIO8_PINCFG (0x0000800C) +#define AQT1000_TLMM_GPIO9_PINCFG (0x0000800D) +#define AQT1000_TLMM_GPIO10_PINCFG (0x0000800E) +#define AQT1000_PAD_CTRL_PAD_CTRL_BASE (0x00008031) +#define AQT1000_PAD_CTRL_PAD_PDN_CTRL_0 (0x00008031) +#define AQT1000_PAD_CTRL_PAD_PDN_CTRL_1 (0x00008032) +#define AQT1000_PAD_CTRL_PAD_PU_CTRL_0 (0x00008033) +#define AQT1000_PAD_CTRL_PAD_PU_CTRL_1 (0x00008034) +#define AQT1000_PAD_CTRL_GPIO_CTL_0_OE (0x00008036) +#define AQT1000_PAD_CTRL_GPIO_CTL_1_OE (0x00008037) +#define AQT1000_PAD_CTRL_GPIO_CTL_0_DATA (0x00008038) +#define AQT1000_PAD_CTRL_GPIO_CTL_1_DATA (0x00008039) +#define AQT1000_PAD_CTRL_PAD_DRVCTL (0x0000803A) +#define AQT1000_PAD_CTRL_PIN_STATUS (0x0000803B) +#define AQT1000_PAD_CTRL_MEM_CTRL (0x0000803C) +#define AQT1000_PAD_CTRL_PAD_INP_DISABLE_0 (0x0000803E) +#define AQT1000_PAD_CTRL_PAD_INP_DISABLE_1 (0x0000803F) +#define AQT1000_PAD_CTRL_PIN_CTL_OE_0 (0x00008040) +#define AQT1000_PAD_CTRL_PIN_CTL_OE_1 (0x00008041) +#define AQT1000_PAD_CTRL_PIN_CTL_DATA_0 (0x00008042) +#define AQT1000_PAD_CTRL_PIN_CTL_DATA_1 (0x00008043) +#define AQT1000_PAD_CTRL_USB_PHY_CLK_DIV (0x00008044) +#define AQT1000_PAD_CTRL_DEBUG_BUS_CDC (0x00008045) +#define AQT1000_PAD_CTRL_DEBUG_BUS_SEL (0x00008046) +#define AQT1000_PAD_CTRL_DEBUG_EN_1 (0x00008047) +#define AQT1000_PAD_CTRL_DEBUG_EN_2 (0x00008048) +#define AQT1000_PAD_CTRL_DEBUG_EN_3 (0x00008049) +#define AQT1000_PAD_CTRL_DEBUG_EN_4 (0x0000804A) +#define AQT1000_PAD_CTRL_DEBUG_EN_5 (0x0000804B) +#define AQT1000_PAD_CTRL_DEBUG_MUX_BIT_0 (0x0000804C) +#define AQT1000_PAD_CTRL_DEBUG_MUX_BIT_1 (0x0000804D) +#define AQT1000_PAD_CTRL_DEBUG_MUX_BIT_2 (0x0000804E) +#define AQT1000_PAD_CTRL_DEBUG_MUX_BIT_3 (0x0000804F) +#define AQT1000_PAD_CTRL_DEBUG_MUX_BIT_4 (0x00008050) +#define AQT1000_PAD_CTRL_DEBUG_MUX_BIT_5 (0x00008051) +#define AQT1000_PAD_CTRL_DEBUG_MUX_BIT_6 (0x00008052) +#define AQT1000_PAD_CTRL_DEBUG_MUX_BIT_7 (0x00008053) +#define AQT1000_PAD_CTRL_DEBUG_MUX_BIT_8 (0x00008054) +#define AQT1000_PAD_CTRL_DEBUG_MUX_BIT_9 (0x00008055) +#define AQT1000_PAD_CTRL_DEBUG_MUX_BIT_10 (0x00008056) +#define AQT1000_PAD_CTRL_DEBUG_MUX_BIT_11 (0x00008057) +#define AQT1000_PAD_CTRL_DEBUG_MUX_BIT_12 (0x00008058) +#define AQT1000_PAD_CTRL_DEBUG_MUX_BIT_13 (0x00008059) +#define AQT1000_PAD_CTRL_DEBUG_READ_0 (0x0000805A) +#define AQT1000_PAD_CTRL_DEBUG_READ_1 (0x0000805B) +#define AQT1000_PAD_CTRL_DEBUG_READ_2 (0x0000805C) +#define AQT1000_PAD_CTRL_DEBUG_READ_3 (0x0000805D) +#define AQT1000_PAD_CTRL_FPGA_CTL (0x00008061) +#define AQT1000_MAX_REGISTER (0x000080FF) + +#endif /*_AQT_REGISTERS_H*/ diff --git a/asoc/codecs/aqt1000/aqt1000-regmap.c b/asoc/codecs/aqt1000/aqt1000-regmap.c new file mode 100644 index 0000000000..e38c32748f --- /dev/null +++ b/asoc/codecs/aqt1000/aqt1000-regmap.c @@ -0,0 +1,110 @@ +/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include "aqt1000-registers.h" +#include "aqt1000-reg-defaults.h" +#include "aqt1000-internal.h" + +static bool aqt1000_is_readable_register(struct device *dev, unsigned int reg) +{ + u8 pg_num, reg_offset; + const u8 *reg_tbl = NULL; + + /* + * Get the page number from MSB of codec register. If its 0x80, assign + * the corresponding page index PAGE_0x80. + */ + pg_num = reg >> 0x8; + if (pg_num == 0x80) + pg_num = AQT1000_PAGE_128; + else if (pg_num > 15) + return false; + + reg_tbl = aqt1000_reg[pg_num]; + reg_offset = reg & 0xFF; + + if (reg_tbl && reg_tbl[reg_offset]) + return true; + else + return false; +} + +static bool aqt1000_is_volatile_register(struct device *dev, unsigned int reg) +{ + u8 pg_num, reg_offset; + const u8 *reg_tbl = NULL; + + pg_num = reg >> 0x8; + if (pg_num == 0x80) + pg_num = AQT1000_PAGE_128; + else if (pg_num > 15) + return false; + + reg_tbl = aqt1000_reg[pg_num]; + reg_offset = reg & 0xFF; + + if (reg_tbl && reg_tbl[reg_offset] == AQT1000_RO) + return true; + + /* IIR Coeff registers are not cacheable */ + if ((reg >= AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL) && + (reg <= AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL)) + return true; + + if ((reg >= AQT1000_CDC_ANC0_IIR_COEFF_1_CTL) && + (reg <= AQT1000_CDC_ANC0_FB_GAIN_CTL)) + return true; + + if ((reg >= AQT1000_CDC_ANC1_IIR_COEFF_1_CTL) && + (reg <= AQT1000_CDC_ANC1_FB_GAIN_CTL)) + return true; + + /* + * Need to mark volatile for registers that are writable but + * only few bits are read-only + */ + switch (reg) { + case AQT1000_BUCK_5V_CTRL_CCL_1: + case AQT1000_BIAS_CCOMP_FINE_ADJ: + case AQT1000_ANA_BIAS: + case AQT1000_BUCK_5V_IBIAS_CTL_4: + case AQT1000_BUCK_5V_CTRL_CCL_2: + case AQT1000_CHIP_CFG0_RST_CTL: + case AQT1000_CHIP_CFG0_CLK_CTL_CDC_DIG: + case AQT1000_CHIP_CFG0_CLK_CFG_MCLK: + case AQT1000_CHIP_CFG0_EFUSE_CTL: + case AQT1000_CDC_CLK_RST_CTRL_FS_CNT_CONTROL: + case AQT1000_CDC_CLK_RST_CTRL_MCLK_CONTROL: + case AQT1000_ANA_RX_SUPPLIES: + case AQT1000_ANA_MBHC_MECH: + case AQT1000_ANA_MBHC_ELECT: + case AQT1000_ANA_MBHC_ZDET: + case AQT1000_ANA_MICB1: + case AQT1000_BUCK_5V_EN_CTL: + return true; + } + + return false; +} + +struct regmap_config aqt1000_regmap_config = { + .reg_bits = 16, + .val_bits = 8, + .cache_type = REGCACHE_RBTREE, + .reg_defaults = aqt1000_defaults, + .num_reg_defaults = ARRAY_SIZE(aqt1000_defaults), + .max_register = AQT1000_MAX_REGISTER, + .volatile_reg = aqt1000_is_volatile_register, + .readable_reg = aqt1000_is_readable_register, +}; diff --git a/asoc/codecs/aqt1000/aqt1000-routing.h b/asoc/codecs/aqt1000/aqt1000-routing.h new file mode 100644 index 0000000000..9dc74a425a --- /dev/null +++ b/asoc/codecs/aqt1000/aqt1000-routing.h @@ -0,0 +1,170 @@ +/* Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef AQT1000_ROUTING_H +#define AQT1000_ROUTING_H + +#include + +const struct snd_soc_dapm_route aqt_audio_map[] = { + + /* CDC Tx interface */ + + {"AQT AIF1 CAP", NULL, "AQT AIF1 CAP Mixer"}, + {"AQT AIF1 CAP Mixer", "TX0", "AQT TX0_MUX"}, + {"AQT AIF1 CAP Mixer", "TX1", "AQT TX1_MUX"}, + + {"AQT TX0_MUX", "DEC_L", "AQT ADC0 MUX"}, + {"AQT TX0_MUX", "DEC_R", "AQT ADC1 MUX"}, + {"AQT TX0_MUX", "DEC_V", "AQT ADC2 MUX"}, + + {"AQT TX1_MUX", "DEC_L", "AQT ADC0 MUX"}, + {"AQT TX1_MUX", "DEC_R", "AQT ADC1 MUX"}, + {"AQT TX1_MUX", "DEC_V", "AQT ADC2 MUX"}, + + {"AQT ADC0 MUX", "AMIC", "AQT AMIC0_MUX"}, + {"AQT ADC0 MUX", "ANC_FB0", "AQT ANC_FB_TUNE0"}, + {"AQT ADC0 MUX", "ANC_FB1", "AQT ANC_FB_TUNE1"}, + + {"AQT ADC1 MUX", "AMIC", "AQT AMIC1_MUX"}, + {"AQT ADC1 MUX", "ANC_FB0", "AQT ANC_FB_TUNE0"}, + {"AQT ADC1 MUX", "ANC_FB1", "AQT ANC_FB_TUNE1"}, + + {"AQT ADC2 MUX", "AMIC", "AQT AMIC2_MUX"}, + {"AQT ADC2 MUX", "ANC_FB0", "AQT ANC_FB_TUNE0"}, + {"AQT ADC2 MUX", "ANC_FB1", "AQT ANC_FB_TUNE1"}, + + {"AQT AMIC0_MUX", "ADC_L", "AQT ADC_L"}, + {"AQT AMIC0_MUX", "ADC_R", "AQT ADC_R"}, + {"AQT AMIC0_MUX", "ADC_V", "AQT ADC_V"}, + + {"AQT AMIC1_MUX", "ADC_L", "AQT ADC_L"}, + {"AQT AMIC1_MUX", "ADC_R", "AQT ADC_R"}, + {"AQT AMIC1_MUX", "ADC_V", "AQT ADC_V"}, + + {"AQT AMIC2_MUX", "ADC_L", "AQT ADC_L"}, + {"AQT AMIC2_MUX", "ADC_R", "AQT ADC_R"}, + {"AQT AMIC2_MUX", "ADC_V", "AQT ADC_V"}, + + {"AQT ADC_L", NULL, "AQT AMIC1"}, + {"AQT ADC_R", NULL, "AQT AMIC2"}, + {"AQT ADC_V", NULL, "AQT AMIC3"}, + + {"AQT AMIC10_MUX", "ADC_L", "AQT ADC_L"}, + {"AQT AMIC10_MUX", "ADC_R", "AQT ADC_R"}, + {"AQT AMIC10_MUX", "ADC_V", "AQT ADC_V"}, + + {"AQT AMIC11_MUX", "ADC_L", "AQT ADC_L"}, + {"AQT AMIC11_MUX", "ADC_R", "AQT ADC_R"}, + {"AQT AMIC11_MUX", "ADC_V", "AQT ADC_V"}, + + {"AQT AMIC12_MUX", "ADC_L", "AQT ADC_L"}, + {"AQT AMIC12_MUX", "ADC_R", "AQT ADC_R"}, + {"AQT AMIC12_MUX", "ADC_V", "AQT ADC_V"}, + + {"AQT AMIC13_MUX", "ADC_L", "AQT ADC_L"}, + {"AQT AMIC13_MUX", "ADC_R", "AQT ADC_R"}, + {"AQT AMIC13_MUX", "ADC_V", "AQT ADC_V"}, + + {"AQT ANC OUT HPHL Enable", "Switch", "AQT AMIC10_MUX"}, + {"AQT ANC OUT HPHL Enable", "Switch", "AQT AMIC11_MUX"}, + {"AQT ANC OUT HPHR Enable", "Switch", "AQT AMIC12_MUX"}, + {"AQT ANC OUT HPHR Enable", "Switch", "AQT AMIC13_MUX"}, + + {"AQT RX INT1 MIX2", NULL, "AQT ANC OUT HPHL Enable"}, + {"AQT RX INT2 MIX2", NULL, "AQT ANC OUT HPHR Enable"}, + + {"AQT ANC0 FB MUX", "ANC_IN_HPHL", "AQT RX INT1 MIX2"}, + {"AQT ANC1 FB MUX", "ANC_IN_HPHR", "AQT RX INT2 MIX2"}, + + {"AQT I2S_L RX", "AIF1_PB", "AQT AIF1 PB"}, + {"AQT I2S_R RX", "AIF1_PB", "AQT AIF1 PB"}, + + {"AQT RX INT1_1 MUX", "I2S_L", "AQT I2S_L RX"}, + {"AQT RX INT1_1 MUX", "I2S_R", "AQT I2S_R RX"}, + {"AQT RX INT1_1 MUX", "DEC_L", "AQT ADC0 MUX"}, + {"AQT RX INT1_1 MUX", "DEC_R", "AQT ADC1 MUX"}, + {"AQT RX INT1_1 MUX", "DEC_V", "AQT ADC2 MUX"}, + + {"AQT RX INT2_1 MUX", "I2S_L", "AQT I2S_L RX"}, + {"AQT RX INT2_1 MUX", "I2S_R", "AQT I2S_R RX"}, + {"AQT RX INT2_1 MUX", "DEC_L", "AQT ADC0 MUX"}, + {"AQT RX INT2_1 MUX", "DEC_R", "AQT ADC1 MUX"}, + {"AQT RX INT2_1 MUX", "DEC_V", "AQT ADC2 MUX"}, + + {"AQT RX INT1_2 MUX", "I2S_L", "AQT I2S_L RX"}, + {"AQT RX INT1_2 MUX", "I2S_R", "AQT I2S_R RX"}, + {"AQT RX INT1_2 MUX", "DEC_L", "AQT ADC0 MUX"}, + {"AQT RX INT1_2 MUX", "DEC_R", "AQT ADC1 MUX"}, + {"AQT RX INT1_2 MUX", "DEC_V", "AQT ADC2 MUX"}, + {"AQT RX INT1_2 MUX", "IIR0", "AQT IIR0"}, + + {"AQT RX INT2_2 MUX", "I2S_L", "AQT I2S_L RX"}, + {"AQT RX INT2_2 MUX", "I2S_R", "AQT I2S_R RX"}, + {"AQT RX INT2_2 MUX", "DEC_L", "AQT ADC0 MUX"}, + {"AQT RX INT2_2 MUX", "DEC_R", "AQT ADC1 MUX"}, + {"AQT RX INT2_2 MUX", "DEC_V", "AQT ADC2 MUX"}, + {"AQT RX INT2_2 MUX", "IIR0", "AQT IIR0"}, + + {"AQT RX INT1_1 INTERP", NULL, "AQT RX INT1_1 MUX"}, + {"AQT RX INT1 MIX1", NULL, "AQT RX INT1_1 INTERP"}, + {"AQT RX INT1 MIX2", NULL, "AQT RX INT1 MIX1"}, + + {"AQT RX INT1_2 INTERP", NULL, "AQT RX INT1_2 MUX"}, + {"AQT RX INT1 MIX1", NULL, "AQT RX INT1_2 INTERP"}, + + {"AQT ASRC0 MUX", "ASRC_IN_HPHL", "AQT RX INT1_2 INTERP"}, + {"AQT RX INT1 MIX1", "HPHL Switch", "AQT ASRC0 MUX"}, + + {"AQT RX INT2_1 INTERP", NULL, "AQT RX INT2_1 MUX"}, + {"AQT RX INT2 MIX1", NULL, "AQT RX INT2_1 INTERP"}, + {"AQT RX INT2 MIX2", NULL, "AQT RX INT2 MIX1"}, + + {"AQT RX INT2_2 INTERP", NULL, "AQT RX INT2_2 MUX"}, + {"AQT RX INT2 MIX1", NULL, "AQT RX INT2_2 INTERP"}, + + {"AQT ASRC1 MUX", "ASRC_IN_HPHR", "AQT RX INT2_2 INTERP"}, + {"AQT RX INT2 MIX1", "HPHR Switch", "AQT ASRC1 MUX"}, + + {"AQT RX INT1 DEM MUX", "CLSH_DSM_OUT", "AQT RX INT1 MIX2"}, + {"AQT RX INT1 DAC", NULL, "AQT RX INT1 DEM MUX"}, + {"AQT RX INT1 DAC", NULL, "AQT RX_BIAS"}, + {"AQT HPHL PA", NULL, "AQT RX INT1 DAC"}, + {"AQT HPHL", NULL, "AQT HPHL PA"}, + + {"AQT RX INT2 DEM MUX", "CLSH_DSM_OUT", "AQT RX INT2 MIX2"}, + {"AQT RX INT2 DAC", NULL, "AQT RX INT2 DEM MUX"}, + {"AQT RX INT2 DAC", NULL, "AQT RX_BIAS"}, + {"AQT HPHR PA", NULL, "AQT RX INT2 DAC"}, + {"AQT HPHR", NULL, "AQT HPHR PA"}, + + {"AQT ANC HPHL PA", NULL, "AQT RX INT1 DAC"}, + {"AQT ANC HPHL", NULL, "AQT ANC HPHL PA"}, + + {"AQT ANC HPHR PA", NULL, "AQT RX INT2 DAC"}, + {"AQT ANC HPHR", NULL, "AQT ANC HPHR PA"}, + + {"AQT IIR0", NULL, "AQT TX_PATH2"}, + {"AQT SRC0", NULL, "AQT IIR0"}, + {"AQT RX INT1 MIX2", "SRC0", "AQT SRC0"}, + {"AQT RX INT2 MIX2", "SRC0", "AQT SRC0"}, + + /* Native clk main path routing */ + {"AQT RX INT1_1 NATIVE MUX", "ON", "AQT RX INT1_1 MUX"}, + {"AQT RX INT1_1 INTERP", NULL, "AQT RX INT1_1 NATIVE MUX"}, + {"AQT RX INT1_1 NATIVE MUX", NULL, "AQT RX INT1 NATIVE SUPPLY"}, + + {"AQT RX INT2_1 NATIVE MUX", "ON", "AQT RX INT2_1 MUX"}, + {"AQT RX INT2_1 INTERP", NULL, "AQT RX INT2_1 NATIVE MUX"}, + {"AQT RX INT2_1 NATIVE MUX", NULL, "AQT RX INT2 NATIVE SUPPLY"}, +}; + +#endif diff --git a/asoc/codecs/aqt1000/aqt1000-utils.c b/asoc/codecs/aqt1000/aqt1000-utils.c new file mode 100644 index 0000000000..f1c16de8a6 --- /dev/null +++ b/asoc/codecs/aqt1000/aqt1000-utils.c @@ -0,0 +1,199 @@ +/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include "aqt1000.h" +#include "aqt1000-utils.h" + +#define REG_BYTES 2 +#define VAL_BYTES 1 +/* + * Page Register Address that APP Proc uses to + * access codec registers is identified as 0x00 + */ +#define PAGE_REG_ADDR 0x00 + +static int aqt_page_write(struct aqt1000 *aqt, unsigned short *reg) +{ + int ret = 0; + unsigned short c_reg, reg_addr; + u8 pg_num, prev_pg_num; + + c_reg = *reg; + pg_num = c_reg >> 8; + reg_addr = c_reg & 0xff; + if (aqt->prev_pg_valid) { + prev_pg_num = aqt->prev_pg; + if (prev_pg_num != pg_num) { + ret = aqt->write_dev( + aqt, PAGE_REG_ADDR, + (void *) &pg_num, 1); + if (ret < 0) + dev_err(aqt->dev, + "%s: page write error, pg_num: 0x%x\n", + __func__, pg_num); + else { + aqt->prev_pg = pg_num; + dev_dbg(aqt->dev, "%s: Page 0x%x Write to 0x00\n", + __func__, pg_num); + } + } + } else { + ret = aqt->write_dev( + aqt, PAGE_REG_ADDR, (void *) &pg_num, 1); + if (ret < 0) + dev_err(aqt->dev, + "%s: page write error, pg_num: 0x%x\n", + __func__, pg_num); + else { + aqt->prev_pg = pg_num; + aqt->prev_pg_valid = true; + dev_dbg(aqt->dev, "%s: Page 0x%x Write to 0x00\n", + __func__, pg_num); + } + } + *reg = reg_addr; + return ret; +} + +static int regmap_bus_read(void *context, const void *reg, size_t reg_size, + void *val, size_t val_size) +{ + struct device *dev = context; + struct aqt1000 *aqt = dev_get_drvdata(dev); + unsigned short c_reg, rreg; + int ret, i; + + if (!aqt) { + dev_err(dev, "%s: aqt is NULL\n", __func__); + return -EINVAL; + } + if (!reg || !val) { + dev_err(dev, "%s: reg or val is NULL\n", __func__); + return -EINVAL; + } + + if (reg_size != REG_BYTES) { + dev_err(dev, "%s: register size %zd bytes, not supported\n", + __func__, reg_size); + return -EINVAL; + } + + mutex_lock(&aqt->io_lock); + c_reg = *(u16 *)reg; + rreg = c_reg; + + ret = aqt_page_write(aqt, &c_reg); + if (ret) + goto err; + ret = aqt->read_dev(aqt, c_reg, val, val_size); + if (ret < 0) + dev_err(dev, "%s: Codec read failed (%d), reg: 0x%x, size:%zd\n", + __func__, ret, rreg, val_size); + else { + for (i = 0; i < val_size; i++) + dev_dbg(dev, "%s: Read 0x%02x from 0x%x\n", + __func__, ((u8 *)val)[i], rreg + i); + } +err: + mutex_unlock(&aqt->io_lock); + return ret; +} + +static int regmap_bus_gather_write(void *context, + const void *reg, size_t reg_size, + const void *val, size_t val_size) +{ + struct device *dev = context; + struct aqt1000 *aqt = dev_get_drvdata(dev); + unsigned short c_reg, rreg; + int ret, i; + + if (!aqt) { + dev_err(dev, "%s: aqt is NULL\n", __func__); + return -EINVAL; + } + if (!reg || !val) { + dev_err(dev, "%s: reg or val is NULL\n", __func__); + return -EINVAL; + } + if (reg_size != REG_BYTES) { + dev_err(dev, "%s: register size %zd bytes, not supported\n", + __func__, reg_size); + return -EINVAL; + } + mutex_lock(&aqt->io_lock); + c_reg = *(u16 *)reg; + rreg = c_reg; + + ret = aqt_page_write(aqt, &c_reg); + if (ret) + goto err; + + for (i = 0; i < val_size; i++) + dev_dbg(dev, "Write %02x to 0x%x\n", ((u8 *)val)[i], + rreg + i); + + ret = aqt->write_dev(aqt, c_reg, (void *) val, val_size); + if (ret < 0) + dev_err(dev, "%s: Codec write failed (%d), reg:0x%x, size:%zd\n", + __func__, ret, rreg, val_size); + +err: + mutex_unlock(&aqt->io_lock); + return ret; +} + +static int regmap_bus_write(void *context, const void *data, size_t count) +{ + struct device *dev = context; + struct aqt1000 *aqt = dev_get_drvdata(dev); + + if (!aqt) + return -EINVAL; + + WARN_ON(count < REG_BYTES); + + return regmap_bus_gather_write(context, data, REG_BYTES, + data + REG_BYTES, + count - REG_BYTES); +} + +static struct regmap_bus regmap_bus_config = { + .write = regmap_bus_write, + .gather_write = regmap_bus_gather_write, + .read = regmap_bus_read, + .reg_format_endian_default = REGMAP_ENDIAN_NATIVE, + .val_format_endian_default = REGMAP_ENDIAN_NATIVE, +}; + +/* + * aqt1000_regmap_init: + * Initialize aqt1000 register map + * + * @dev: pointer to wcd device + * @config: pointer to register map config + * + * Returns pointer to regmap structure for success + * or NULL in case of failure. + */ +struct regmap *aqt1000_regmap_init(struct device *dev, + const struct regmap_config *config) +{ + return devm_regmap_init(dev, ®map_bus_config, dev, config); +} +EXPORT_SYMBOL(aqt1000_regmap_init); diff --git a/asoc/codecs/aqt1000/aqt1000-utils.h b/asoc/codecs/aqt1000/aqt1000-utils.h new file mode 100644 index 0000000000..9f68cf12b0 --- /dev/null +++ b/asoc/codecs/aqt1000/aqt1000-utils.h @@ -0,0 +1,22 @@ +/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __WCD9XXX_UTILS_H__ +#define __WCD9XXX_UTILS_H__ + +#include +#include +#include + +struct regmap *aqt1000_regmap_init(struct device *dev, + const struct regmap_config *config); +#endif diff --git a/asoc/codecs/aqt1000/aqt1000.c b/asoc/codecs/aqt1000/aqt1000.c new file mode 100644 index 0000000000..aff8976e84 --- /dev/null +++ b/asoc/codecs/aqt1000/aqt1000.c @@ -0,0 +1,3216 @@ +/* Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "aqt1000-registers.h" +#include "aqt1000.h" +#include "aqt1000-routing.h" +#include "../wcdcal-hwdep.h" +#include "aqt1000-internal.h" + +#define AQT1000_CODEC_HWDEP_NODE 1001 +#define AQT1000_TX_UNMUTE_DELAY_MS 40 +#define TX_HPF_CUT_OFF_FREQ_MASK 0x60 +#define CF_MIN_3DB_4HZ 0x0 +#define CF_MIN_3DB_75HZ 0x1 +#define CF_MIN_3DB_150HZ 0x2 + +static struct interp_sample_rate sr_val_tbl[] = { + {8000, 0x0}, {16000, 0x1}, {32000, 0x3}, {48000, 0x4}, {96000, 0x5}, + {192000, 0x6}, {384000, 0x7}, {44100, 0x9}, {88200, 0xA}, + {176400, 0xB}, {352800, 0xC}, +}; + +static int tx_unmute_delay = AQT1000_TX_UNMUTE_DELAY_MS; +module_param(tx_unmute_delay, int, 0664); +MODULE_PARM_DESC(tx_unmute_delay, "delay to unmute the tx path"); + +static void aqt_codec_set_tx_hold(struct snd_soc_codec *, u16, bool); + +/* Cutoff frequency for high pass filter */ +static const char * const cf_text[] = { + "CF_NEG_3DB_4HZ", "CF_NEG_3DB_75HZ", "CF_NEG_3DB_150HZ" +}; + +static const char * const rx_cf_text[] = { + "CF_NEG_3DB_4HZ", "CF_NEG_3DB_75HZ", "CF_NEG_3DB_150HZ", + "CF_NEG_3DB_0P48HZ" +}; + +struct aqt1000_anc_header { + u32 reserved[3]; + u32 num_anc_slots; +}; + +static SOC_ENUM_SINGLE_DECL(cf_dec0_enum, AQT1000_CDC_TX0_TX_PATH_CFG0, 5, + cf_text); +static SOC_ENUM_SINGLE_DECL(cf_dec1_enum, AQT1000_CDC_TX1_TX_PATH_CFG0, 5, + cf_text); +static SOC_ENUM_SINGLE_DECL(cf_dec2_enum, AQT1000_CDC_TX2_TX_PATH_CFG0, 5, + cf_text); +static SOC_ENUM_SINGLE_DECL(cf_int1_1_enum, AQT1000_CDC_RX1_RX_PATH_CFG2, 0, + rx_cf_text); +static SOC_ENUM_SINGLE_DECL(cf_int1_2_enum, AQT1000_CDC_RX1_RX_PATH_MIX_CFG, 2, + rx_cf_text); +static SOC_ENUM_SINGLE_DECL(cf_int2_1_enum, AQT1000_CDC_RX2_RX_PATH_CFG2, 0, + rx_cf_text); +static SOC_ENUM_SINGLE_DECL(cf_int2_2_enum, AQT1000_CDC_RX2_RX_PATH_MIX_CFG, 2, + rx_cf_text); + +static const DECLARE_TLV_DB_SCALE(hph_gain, -3000, 150, 0); +static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 150, 0); +static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0); + +static int aqt_get_anc_slot(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = aqt->anc_slot; + return 0; +} + +static int aqt_put_anc_slot(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + + aqt->anc_slot = ucontrol->value.integer.value[0]; + return 0; +} + +static int aqt_get_anc_func(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = (aqt->anc_func == true ? 1 : 0); + return 0; +} + +static int aqt_put_anc_func(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + + mutex_lock(&aqt->codec_mutex); + aqt->anc_func = (!ucontrol->value.integer.value[0] ? false : true); + dev_dbg(codec->dev, "%s: anc_func %x", __func__, aqt->anc_func); + + if (aqt->anc_func == true) { + snd_soc_dapm_enable_pin(dapm, "ANC HPHL PA"); + snd_soc_dapm_enable_pin(dapm, "ANC HPHR PA"); + snd_soc_dapm_enable_pin(dapm, "ANC HPHL"); + snd_soc_dapm_enable_pin(dapm, "ANC HPHR"); + snd_soc_dapm_disable_pin(dapm, "HPHL PA"); + snd_soc_dapm_disable_pin(dapm, "HPHR PA"); + snd_soc_dapm_disable_pin(dapm, "HPHL"); + snd_soc_dapm_disable_pin(dapm, "HPHR"); + } else { + snd_soc_dapm_disable_pin(dapm, "ANC HPHL PA"); + snd_soc_dapm_disable_pin(dapm, "ANC HPHR PA"); + snd_soc_dapm_disable_pin(dapm, "ANC HPHL"); + snd_soc_dapm_disable_pin(dapm, "ANC HPHR"); + snd_soc_dapm_enable_pin(dapm, "HPHL"); + snd_soc_dapm_enable_pin(dapm, "HPHR"); + snd_soc_dapm_enable_pin(dapm, "HPHL PA"); + snd_soc_dapm_enable_pin(dapm, "HPHR PA"); + } + mutex_unlock(&aqt->codec_mutex); + + snd_soc_dapm_sync(dapm); + return 0; +} + +static const char *const aqt_anc_func_text[] = {"OFF", "ON"}; +static const struct soc_enum aqt_anc_func_enum = + SOC_ENUM_SINGLE_EXT(2, aqt_anc_func_text); + +static int aqt_rx_hph_mode_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = aqt->hph_mode; + return 0; +} + +static int aqt_rx_hph_mode_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + u32 mode_val; + + mode_val = ucontrol->value.enumerated.item[0]; + + dev_dbg(codec->dev, "%s: mode: %d\n", __func__, mode_val); + + if (mode_val == 0) { + dev_warn(codec->dev, "%s:Invalid HPH Mode, default to Cls-H LOHiFi\n", + __func__); + mode_val = CLS_H_LOHIFI; + } + aqt->hph_mode = mode_val; + return 0; +} + +static const char * const rx_hph_mode_mux_text[] = { + "CLS_H_INVALID", "CLS_H_HIFI", "CLS_H_LP", "CLS_AB", "CLS_H_LOHIFI", + "CLS_H_ULP", "CLS_AB_HIFI", +}; + +static const struct soc_enum rx_hph_mode_mux_enum = + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_hph_mode_mux_text), + rx_hph_mode_mux_text); + +static int aqt_iir_enable_audio_mixer_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + int band_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + + ucontrol->value.integer.value[0] = (snd_soc_read(codec, + AQT1000_CDC_SIDETONE_IIR0_IIR_CTL) & + (1 << band_idx)) != 0; + + dev_dbg(codec->dev, "%s: IIR0 band #%d enable %d\n", __func__, + band_idx, (uint32_t)ucontrol->value.integer.value[0]); + + return 0; +} + +static int aqt_iir_enable_audio_mixer_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + int band_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + bool iir_band_en_status; + int value = ucontrol->value.integer.value[0]; + + /* Mask first 5 bits, 6-8 are reserved */ + snd_soc_update_bits(codec, AQT1000_CDC_SIDETONE_IIR0_IIR_CTL, + (1 << band_idx), (value << band_idx)); + + iir_band_en_status = ((snd_soc_read(codec, + AQT1000_CDC_SIDETONE_IIR0_IIR_CTL) & + (1 << band_idx)) != 0); + dev_dbg(codec->dev, "%s: IIR0 band #%d enable %d\n", __func__, + band_idx, iir_band_en_status); + + return 0; +} + +static uint32_t aqt_get_iir_band_coeff(struct snd_soc_codec *codec, + int band_idx, int coeff_idx) +{ + uint32_t value = 0; + + /* Address does not automatically update if reading */ + snd_soc_write(codec, + AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL, + ((band_idx * BAND_MAX + coeff_idx) + * sizeof(uint32_t)) & 0x7F); + + value |= snd_soc_read(codec, AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL); + + snd_soc_write(codec, AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL, + ((band_idx * BAND_MAX + coeff_idx) + * sizeof(uint32_t) + 1) & 0x7F); + + value |= (snd_soc_read(codec, + AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL) << 8); + + snd_soc_write(codec, + AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL, + ((band_idx * BAND_MAX + coeff_idx) + * sizeof(uint32_t) + 2) & 0x7F); + + value |= (snd_soc_read(codec, + AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL) << 16); + + snd_soc_write(codec, + AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL, + ((band_idx * BAND_MAX + coeff_idx) + * sizeof(uint32_t) + 3) & 0x7F); + + /* Mask bits top 2 bits since they are reserved */ + value |= ((snd_soc_read(codec, + AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL) + & 0x3F) << 24); + + return value; +} + +static int aqt_iir_band_audio_mixer_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + int band_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + + ucontrol->value.integer.value[0] = + aqt_get_iir_band_coeff(codec, band_idx, 0); + ucontrol->value.integer.value[1] = + aqt_get_iir_band_coeff(codec, band_idx, 1); + ucontrol->value.integer.value[2] = + aqt_get_iir_band_coeff(codec, band_idx, 2); + ucontrol->value.integer.value[3] = + aqt_get_iir_band_coeff(codec, band_idx, 3); + ucontrol->value.integer.value[4] = + aqt_get_iir_band_coeff(codec, band_idx, 4); + + dev_dbg(codec->dev, "%s: IIR band #%d b0 = 0x%x\n" + "%s: IIR band #%d b1 = 0x%x\n" + "%s: IIR band #%d b2 = 0x%x\n" + "%s: IIR band #%d a1 = 0x%x\n" + "%s: IIR band #%d a2 = 0x%x\n", + __func__, band_idx, + (uint32_t)ucontrol->value.integer.value[0], + __func__, band_idx, + (uint32_t)ucontrol->value.integer.value[1], + __func__, band_idx, + (uint32_t)ucontrol->value.integer.value[2], + __func__, band_idx, + (uint32_t)ucontrol->value.integer.value[3], + __func__, band_idx, + (uint32_t)ucontrol->value.integer.value[4]); + + return 0; +} + +static void aqt_set_iir_band_coeff(struct snd_soc_codec *codec, + int band_idx, uint32_t value) +{ + snd_soc_write(codec, + (AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL), + (value & 0xFF)); + + snd_soc_write(codec, + (AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL), + (value >> 8) & 0xFF); + + snd_soc_write(codec, + (AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL), + (value >> 16) & 0xFF); + + /* Mask top 2 bits, 7-8 are reserved */ + snd_soc_write(codec, + (AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL), + (value >> 24) & 0x3F); +} + +static int aqt_iir_band_audio_mixer_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + int band_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + int coeff_idx; + + /* + * Mask top bit it is reserved + * Updates addr automatically for each B2 write + */ + snd_soc_write(codec, + (AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL), + (band_idx * BAND_MAX * sizeof(uint32_t)) & 0x7F); + + for (coeff_idx = 0; coeff_idx < AQT1000_CDC_SIDETONE_IIR_COEFF_MAX; + coeff_idx++) { + aqt_set_iir_band_coeff(codec, band_idx, + ucontrol->value.integer.value[coeff_idx]); + } + + dev_dbg(codec->dev, "%s: IIR band #%d b0 = 0x%x\n" + "%s: IIR band #%d b1 = 0x%x\n" + "%s: IIR band #%d b2 = 0x%x\n" + "%s: IIR band #%d a1 = 0x%x\n" + "%s: IIR band #%d a2 = 0x%x\n", + __func__, band_idx, + aqt_get_iir_band_coeff(codec, band_idx, 0), + __func__, band_idx, + aqt_get_iir_band_coeff(codec, band_idx, 1), + __func__, band_idx, + aqt_get_iir_band_coeff(codec, band_idx, 2), + __func__, band_idx, + aqt_get_iir_band_coeff(codec, band_idx, 3), + __func__, band_idx, + aqt_get_iir_band_coeff(codec, band_idx, 4)); + + return 0; +} + +static int aqt_compander_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + int comp = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = aqt->comp_enabled[comp]; + return 0; +} + +static int aqt_compander_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + int comp = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + int value = ucontrol->value.integer.value[0]; + + dev_dbg(codec->dev, "%s: Compander %d enable current %d, new %d\n", + __func__, comp + 1, aqt->comp_enabled[comp], value); + aqt->comp_enabled[comp] = value; + + /* Any specific register configuration for compander */ + switch (comp) { + case COMPANDER_1: + /* Set Gain Source Select based on compander enable/disable */ + snd_soc_update_bits(codec, AQT1000_HPH_L_EN, 0x20, + (value ? 0x00:0x20)); + break; + case COMPANDER_2: + snd_soc_update_bits(codec, AQT1000_HPH_R_EN, 0x20, + (value ? 0x00:0x20)); + break; + default: + /* + * if compander is not enabled for any interpolator, + * it does not cause any audio failure, so do not + * return error in this case, but just print a log + */ + dev_warn(codec->dev, "%s: unknown compander: %d\n", + __func__, comp); + }; + return 0; +} + +static int aqt_hph_asrc_mode_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + int index = -EINVAL; + + if (!strcmp(kcontrol->id.name, "AQT ASRC0 Output Mode")) + index = ASRC0; + if (!strcmp(kcontrol->id.name, "AQT ASRC1 Output Mode")) + index = ASRC1; + + if (aqt && (index >= 0) && (index < ASRC_MAX)) + aqt->asrc_output_mode[index] = + ucontrol->value.integer.value[0]; + + return 0; +} + +static int aqt_hph_asrc_mode_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + int val = 0; + int index = -EINVAL; + + if (!strcmp(kcontrol->id.name, "AQT ASRC0 Output Mode")) + index = ASRC0; + if (!strcmp(kcontrol->id.name, "AQT ASRC1 Output Mode")) + index = ASRC1; + + if (aqt && (index >= 0) && (index < ASRC_MAX)) + val = aqt->asrc_output_mode[index]; + + ucontrol->value.integer.value[0] = val; + + return 0; +} + +static const char * const asrc_mode_text[] = { + "INT", "FRAC" +}; +static SOC_ENUM_SINGLE_EXT_DECL(asrc_mode_enum, asrc_mode_text); + +static int aqt_hph_idle_detect_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + int val = 0; + + if (aqt) + val = aqt->idle_det_cfg.hph_idle_detect_en; + + ucontrol->value.integer.value[0] = val; + + return 0; +} + +static int aqt_hph_idle_detect_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + + if (aqt) + aqt->idle_det_cfg.hph_idle_detect_en = + ucontrol->value.integer.value[0]; + + return 0; +} + +static const char * const hph_idle_detect_text[] = { + "OFF", "ON" +}; + +static SOC_ENUM_SINGLE_EXT_DECL(hph_idle_detect_enum, hph_idle_detect_text); + +static int aqt_amic_pwr_lvl_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + u16 amic_reg = 0; + + if (!strcmp(kcontrol->id.name, "AQT AMIC_1_2 PWR MODE")) + amic_reg = AQT1000_ANA_AMIC1; + if (!strcmp(kcontrol->id.name, "AQT AMIC_3 PWR MODE")) + amic_reg = AQT1000_ANA_AMIC3; + + if (amic_reg) + ucontrol->value.integer.value[0] = + (snd_soc_read(codec, amic_reg) & + AQT1000_AMIC_PWR_LVL_MASK) >> + AQT1000_AMIC_PWR_LVL_SHIFT; + return 0; +} + +static int aqt_amic_pwr_lvl_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + u32 mode_val; + u16 amic_reg = 0; + + mode_val = ucontrol->value.enumerated.item[0]; + + dev_dbg(codec->dev, "%s: mode: %d\n", __func__, mode_val); + + if (!strcmp(kcontrol->id.name, "AQT AMIC_1_2 PWR MODE")) + amic_reg = AQT1000_ANA_AMIC1; + if (!strcmp(kcontrol->id.name, "AQT AMIC_3 PWR MODE")) + amic_reg = AQT1000_ANA_AMIC3; + + if (amic_reg) + snd_soc_update_bits(codec, amic_reg, AQT1000_AMIC_PWR_LVL_MASK, + mode_val << AQT1000_AMIC_PWR_LVL_SHIFT); + return 0; +} + +static const char * const amic_pwr_lvl_text[] = { + "LOW_PWR", "DEFAULT", "HIGH_PERF", "HYBRID" +}; + +static SOC_ENUM_SINGLE_EXT_DECL(amic_pwr_lvl_enum, amic_pwr_lvl_text); + +static const struct snd_kcontrol_new aqt_snd_controls[] = { + SOC_SINGLE_TLV("AQT HPHL Volume", AQT1000_HPH_L_EN, 0, 24, 1, hph_gain), + SOC_SINGLE_TLV("AQT HPHR Volume", AQT1000_HPH_R_EN, 0, 24, 1, hph_gain), + SOC_SINGLE_TLV("AQT ADC1 Volume", AQT1000_ANA_AMIC1, 0, 20, 0, + analog_gain), + SOC_SINGLE_TLV("AQT ADC2 Volume", AQT1000_ANA_AMIC2, 0, 20, 0, + analog_gain), + SOC_SINGLE_TLV("AQT ADC3 Volume", AQT1000_ANA_AMIC3, 0, 20, 0, + analog_gain), + + SOC_SINGLE_SX_TLV("AQT RX1 Digital Volume", AQT1000_CDC_RX1_RX_VOL_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("AQT RX2 Digital Volume", AQT1000_CDC_RX2_RX_VOL_CTL, + 0, -84, 40, digital_gain), + + SOC_SINGLE_SX_TLV("AQT DEC0 Volume", AQT1000_CDC_TX0_TX_VOL_CTL, 0, + -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("AQT DEC1 Volume", AQT1000_CDC_TX1_TX_VOL_CTL, 0, + -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("AQT DEC2 Volume", AQT1000_CDC_TX2_TX_VOL_CTL, 0, + -84, 40, digital_gain), + + SOC_SINGLE_SX_TLV("AQT IIR0 INP0 Volume", + AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL, 0, -84, 40, + digital_gain), + SOC_SINGLE_SX_TLV("AQT IIR0 INP1 Volume", + AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL, 0, -84, 40, + digital_gain), + SOC_SINGLE_SX_TLV("AQT IIR0 INP2 Volume", + AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL, 0, -84, 40, + digital_gain), + SOC_SINGLE_SX_TLV("AQT IIR0 INP3 Volume", + AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL, 0, -84, 40, + digital_gain), + SOC_SINGLE_EXT("AQT ANC Slot", SND_SOC_NOPM, 0, 100, 0, + aqt_get_anc_slot, aqt_put_anc_slot), + SOC_ENUM_EXT("AQT ANC Function", aqt_anc_func_enum, aqt_get_anc_func, + aqt_put_anc_func), + + SOC_ENUM("AQT TX0 HPF cut off", cf_dec0_enum), + SOC_ENUM("AQT TX1 HPF cut off", cf_dec1_enum), + SOC_ENUM("AQT TX2 HPF cut off", cf_dec2_enum), + + SOC_ENUM("AQT RX INT1_1 HPF cut off", cf_int1_1_enum), + SOC_ENUM("AQT RX INT1_2 HPF cut off", cf_int1_2_enum), + SOC_ENUM("AQT RX INT2_1 HPF cut off", cf_int2_1_enum), + SOC_ENUM("AQT RX INT2_2 HPF cut off", cf_int2_2_enum), + + SOC_ENUM_EXT("AQT RX HPH Mode", rx_hph_mode_mux_enum, + aqt_rx_hph_mode_get, aqt_rx_hph_mode_put), + + SOC_SINGLE_EXT("AQT IIR0 Enable Band1", IIR0, BAND1, 1, 0, + aqt_iir_enable_audio_mixer_get, + aqt_iir_enable_audio_mixer_put), + SOC_SINGLE_EXT("AQT IIR0 Enable Band2", IIR0, BAND2, 1, 0, + aqt_iir_enable_audio_mixer_get, + aqt_iir_enable_audio_mixer_put), + SOC_SINGLE_EXT("AQT IIR0 Enable Band3", IIR0, BAND3, 1, 0, + aqt_iir_enable_audio_mixer_get, + aqt_iir_enable_audio_mixer_put), + SOC_SINGLE_EXT("AQT IIR0 Enable Band4", IIR0, BAND4, 1, 0, + aqt_iir_enable_audio_mixer_get, + aqt_iir_enable_audio_mixer_put), + SOC_SINGLE_EXT("AQT IIR0 Enable Band5", IIR0, BAND5, 1, 0, + aqt_iir_enable_audio_mixer_get, + aqt_iir_enable_audio_mixer_put), + + SOC_SINGLE_MULTI_EXT("AQT IIR0 Band1", IIR0, BAND1, 255, 0, 5, + aqt_iir_band_audio_mixer_get, aqt_iir_band_audio_mixer_put), + SOC_SINGLE_MULTI_EXT("AQT IIR0 Band2", IIR0, BAND2, 255, 0, 5, + aqt_iir_band_audio_mixer_get, aqt_iir_band_audio_mixer_put), + SOC_SINGLE_MULTI_EXT("AQT IIR0 Band3", IIR0, BAND3, 255, 0, 5, + aqt_iir_band_audio_mixer_get, aqt_iir_band_audio_mixer_put), + SOC_SINGLE_MULTI_EXT("AQT IIR0 Band4", IIR0, BAND4, 255, 0, 5, + aqt_iir_band_audio_mixer_get, aqt_iir_band_audio_mixer_put), + SOC_SINGLE_MULTI_EXT("AQT IIR0 Band5", IIR0, BAND5, 255, 0, 5, + aqt_iir_band_audio_mixer_get, aqt_iir_band_audio_mixer_put), + + SOC_SINGLE_EXT("AQT COMP1 Switch", SND_SOC_NOPM, COMPANDER_1, 1, 0, + aqt_compander_get, aqt_compander_put), + SOC_SINGLE_EXT("AQT COMP2 Switch", SND_SOC_NOPM, COMPANDER_2, 1, 0, + aqt_compander_get, aqt_compander_put), + + SOC_ENUM_EXT("AQT ASRC0 Output Mode", asrc_mode_enum, + aqt_hph_asrc_mode_get, aqt_hph_asrc_mode_put), + SOC_ENUM_EXT("AQT ASRC1 Output Mode", asrc_mode_enum, + aqt_hph_asrc_mode_get, aqt_hph_asrc_mode_put), + + SOC_ENUM_EXT("AQT HPH Idle Detect", hph_idle_detect_enum, + aqt_hph_idle_detect_get, aqt_hph_idle_detect_put), + + SOC_ENUM_EXT("AQT AMIC_1_2 PWR MODE", amic_pwr_lvl_enum, + aqt_amic_pwr_lvl_get, aqt_amic_pwr_lvl_put), + SOC_ENUM_EXT("AQT AMIC_3 PWR MODE", amic_pwr_lvl_enum, + aqt_amic_pwr_lvl_get, aqt_amic_pwr_lvl_put), +}; + +static int aqt_codec_enable_rx_bias(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + + dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + aqt->rx_bias_count++; + if (aqt->rx_bias_count == 1) { + snd_soc_update_bits(codec, AQT1000_ANA_RX_SUPPLIES, + 0x01, 0x01); + } + break; + case SND_SOC_DAPM_POST_PMD: + aqt->rx_bias_count--; + if (!aqt->rx_bias_count) + snd_soc_update_bits(codec, AQT1000_ANA_RX_SUPPLIES, + 0x01, 0x00); + break; + }; + dev_dbg(codec->dev, "%s: Current RX BIAS user count: %d\n", __func__, + aqt->rx_bias_count); + + return 0; +} + +/* + * aqt_micbias_control: enable/disable micbias + * @codec: handle to snd_soc_codec * + * @micb_num: micbias to be enabled/disabled, e.g. micbias1 or micbias2 + * @req: control requested, enable/disable or pullup enable/disable + * @is_dapm: triggered by dapm or not + * + * return 0 if control is success or error code in case of failure + */ +int aqt_micbias_control(struct snd_soc_codec *codec, + int micb_num, int req, bool is_dapm) +{ + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + u16 micb_reg; + int pre_off_event = 0, post_off_event = 0; + int post_on_event = 0, post_dapm_off = 0; + int post_dapm_on = 0; + int ret = 0; + + switch (micb_num) { + case MIC_BIAS_1: + micb_reg = AQT1000_ANA_MICB1; + pre_off_event = AQT_EVENT_PRE_MICBIAS_1_OFF; + post_off_event = AQT_EVENT_POST_MICBIAS_1_OFF; + post_on_event = AQT_EVENT_POST_MICBIAS_1_ON; + post_dapm_on = AQT_EVENT_POST_DAPM_MICBIAS_1_ON; + post_dapm_off = AQT_EVENT_POST_DAPM_MICBIAS_1_OFF; + break; + default: + dev_err(codec->dev, "%s: Invalid micbias number: %d\n", + __func__, micb_num); + return -EINVAL; + } + mutex_lock(&aqt->micb_lock); + + switch (req) { + case MICB_PULLUP_ENABLE: + aqt->pullup_ref++; + if ((aqt->pullup_ref == 1) && + (aqt->micb_ref == 0)) + snd_soc_update_bits(codec, micb_reg, 0xC0, 0x80); + break; + case MICB_PULLUP_DISABLE: + if (aqt->pullup_ref > 0) + aqt->pullup_ref--; + if ((aqt->pullup_ref == 0) && + (aqt->micb_ref == 0)) + snd_soc_update_bits(codec, micb_reg, 0xC0, 0x00); + break; + case MICB_ENABLE: + aqt->micb_ref++; + if (aqt->micb_ref == 1) { + snd_soc_update_bits(codec, micb_reg, 0xC0, 0x40); + } + break; + case MICB_DISABLE: + if (aqt->micb_ref > 0) + aqt->micb_ref--; + if ((aqt->micb_ref == 0) && + (aqt->pullup_ref > 0)) + snd_soc_update_bits(codec, micb_reg, 0xC0, 0x80); + else if ((aqt->micb_ref == 0) && + (aqt->pullup_ref == 0)) { + snd_soc_update_bits(codec, micb_reg, 0xC0, 0x00); + } + break; + default: + dev_err(codec->dev, "%s: Invalid micbias request: %d\n", + __func__, req); + ret = -EINVAL; + break; + }; + + if (!ret) + dev_dbg(codec->dev, + "%s: micb_num:%d, micb_ref: %d, pullup_ref: %d\n", + __func__, micb_num, aqt->micb_ref, aqt->pullup_ref); + + mutex_unlock(&aqt->micb_lock); + + return ret; +} +EXPORT_SYMBOL(aqt_micbias_control); + +static int __aqt_codec_enable_micbias(struct snd_soc_dapm_widget *w, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + int micb_num; + + dev_dbg(codec->dev, "%s: wname: %s, event: %d\n", + __func__, w->name, event); + + if (strnstr(w->name, "AQT MIC BIAS1", sizeof("AQT MIC BIAS1"))) + micb_num = MIC_BIAS_1; + else + return -EINVAL; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + /* + * MIC BIAS can also be requested by MBHC, + * so use ref count to handle micbias pullup + * and enable requests + */ + aqt_micbias_control(codec, micb_num, MICB_ENABLE, true); + break; + case SND_SOC_DAPM_POST_PMU: + /* wait for cnp time */ + usleep_range(1000, 1100); + break; + case SND_SOC_DAPM_POST_PMD: + aqt_micbias_control(codec, micb_num, MICB_DISABLE, true); + break; + }; + + return 0; +} + +static int aqt_codec_enable_micbias(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + return __aqt_codec_enable_micbias(w, event); +} + +static int aqt_codec_enable_i2s_block(struct snd_soc_codec *codec) +{ + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + + mutex_lock(&aqt->i2s_lock); + if (++aqt->i2s_users == 1) + snd_soc_update_bits(codec, AQT1000_I2S_I2S_0_CTL, 0x01, 0x01); + mutex_unlock(&aqt->i2s_lock); + + return 0; +} + +static int aqt_codec_disable_i2s_block(struct snd_soc_codec *codec) +{ + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + + mutex_lock(&aqt->i2s_lock); + if (--aqt->i2s_users == 0) + snd_soc_update_bits(codec, AQT1000_I2S_I2S_0_CTL, 0x01, 0x00); + + if (aqt->i2s_users < 0) + dev_warn(codec->dev, "%s: i2s_users count (%d) < 0\n", + __func__, aqt->i2s_users); + mutex_unlock(&aqt->i2s_lock); + + return 0; +} + +static int aqt_codec_enable_i2s_tx(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + aqt_codec_enable_i2s_block(codec); + break; + case SND_SOC_DAPM_POST_PMD: + aqt_codec_disable_i2s_block(codec); + break; + } + dev_dbg(codec->dev, "%s: event: %d\n", __func__, event); + + return 0; +} + +static int aqt_codec_enable_i2s_rx(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + aqt_codec_enable_i2s_block(codec); + break; + case SND_SOC_DAPM_POST_PMD: + aqt_codec_disable_i2s_block(codec); + break; + } + dev_dbg(codec->dev, "%s: event: %d\n", __func__, event); + + return 0; +} + +static const char * const tx_mux_text[] = { + "ZERO", "DEC_L", "DEC_R", "DEC_V", +}; +AQT_DAPM_ENUM(tx0, AQT1000_CDC_IF_ROUTER_TX_MUX_CFG0, 0, tx_mux_text); +AQT_DAPM_ENUM(tx1, AQT1000_CDC_IF_ROUTER_TX_MUX_CFG0, 2, tx_mux_text); + +static const char * const tx_adc_mux_text[] = { + "AMIC", "ANC_FB0", "ANC_FB1", +}; +AQT_DAPM_ENUM(tx_adc0, AQT1000_CDC_TX_INP_MUX_ADC_MUX0_CFG1, 0, + tx_adc_mux_text); +AQT_DAPM_ENUM(tx_adc1, AQT1000_CDC_TX_INP_MUX_ADC_MUX1_CFG1, 0, + tx_adc_mux_text); +AQT_DAPM_ENUM(tx_adc2, AQT1000_CDC_TX_INP_MUX_ADC_MUX2_CFG1, 0, + tx_adc_mux_text); + +static int aqt_find_amic_input(struct snd_soc_codec *codec, int adc_mux_n) +{ + u8 mask; + u16 adc_mux_in_reg = 0, amic_mux_sel_reg = 0; + bool is_amic; + + if (adc_mux_n > 2) + return 0; + + if (adc_mux_n < 3) { + adc_mux_in_reg = AQT1000_CDC_TX_INP_MUX_ADC_MUX0_CFG1 + + adc_mux_n; + mask = 0x03; + amic_mux_sel_reg = AQT1000_CDC_TX_INP_MUX_ADC_MUX0_CFG0 + + 2 * adc_mux_n; + } + is_amic = (((snd_soc_read(codec, adc_mux_in_reg) & mask)) == 0); + if (!is_amic) + return 0; + + return snd_soc_read(codec, amic_mux_sel_reg) & 0x07; +} + +static u16 aqt_codec_get_amic_pwlvl_reg(struct snd_soc_codec *codec, int amic) +{ + u16 pwr_level_reg = 0; + + switch (amic) { + case 1: + case 2: + pwr_level_reg = AQT1000_ANA_AMIC1; + break; + case 3: + pwr_level_reg = AQT1000_ANA_AMIC3; + break; + default: + dev_dbg(codec->dev, "%s: invalid amic: %d\n", + __func__, amic); + break; + } + + return pwr_level_reg; +} + +static void aqt_tx_hpf_corner_freq_callback(struct work_struct *work) +{ + struct delayed_work *hpf_delayed_work; + struct hpf_work *hpf_work; + struct aqt1000 *aqt; + struct snd_soc_codec *codec; + u16 dec_cfg_reg, amic_reg, go_bit_reg; + u8 hpf_cut_off_freq; + int amic_n; + + hpf_delayed_work = to_delayed_work(work); + hpf_work = container_of(hpf_delayed_work, struct hpf_work, dwork); + aqt = hpf_work->aqt; + codec = aqt->codec; + hpf_cut_off_freq = hpf_work->hpf_cut_off_freq; + + dec_cfg_reg = AQT1000_CDC_TX0_TX_PATH_CFG0 + 16 * hpf_work->decimator; + go_bit_reg = dec_cfg_reg + 7; + + dev_dbg(codec->dev, "%s: decimator %u hpf_cut_of_freq 0x%x\n", + __func__, hpf_work->decimator, hpf_cut_off_freq); + + amic_n = aqt_find_amic_input(codec, hpf_work->decimator); + if (amic_n) { + amic_reg = AQT1000_ANA_AMIC1 + amic_n - 1; + aqt_codec_set_tx_hold(codec, amic_reg, false); + } + snd_soc_update_bits(codec, dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK, + hpf_cut_off_freq << 5); + snd_soc_update_bits(codec, go_bit_reg, 0x02, 0x02); + /* Minimum 1 clk cycle delay is required as per HW spec */ + usleep_range(1000, 1010); + snd_soc_update_bits(codec, go_bit_reg, 0x02, 0x00); +} + +static void aqt_tx_mute_update_callback(struct work_struct *work) +{ + struct tx_mute_work *tx_mute_dwork; + struct aqt1000 *aqt; + struct delayed_work *delayed_work; + struct snd_soc_codec *codec; + u16 tx_vol_ctl_reg, hpf_gate_reg; + + delayed_work = to_delayed_work(work); + tx_mute_dwork = container_of(delayed_work, struct tx_mute_work, dwork); + aqt = tx_mute_dwork->aqt; + codec = aqt->codec; + + tx_vol_ctl_reg = AQT1000_CDC_TX0_TX_PATH_CTL + + 16 * tx_mute_dwork->decimator; + hpf_gate_reg = AQT1000_CDC_TX0_TX_PATH_SEC2 + + 16 * tx_mute_dwork->decimator; + snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x00); +} + +static int aqt_codec_enable_dec(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + char *widget_name = NULL; + char *dec = NULL; + unsigned int decimator = 0; + u8 amic_n = 0; + u16 tx_vol_ctl_reg, pwr_level_reg = 0, dec_cfg_reg, hpf_gate_reg; + u16 tx_gain_ctl_reg; + int ret = 0; + u8 hpf_cut_off_freq; + + dev_dbg(codec->dev, "%s: event: %d\n", __func__, event); + widget_name = kstrndup(w->name, 15, GFP_KERNEL); + if (!widget_name) + return -ENOMEM; + + dec = strpbrk(widget_name, "012"); + if (!dec) { + dev_err(codec->dev, "%s: decimator index not found\n", + __func__); + ret = -EINVAL; + goto out; + } + + ret = kstrtouint(dec, 10, &decimator); + if (ret < 0) { + dev_err(codec->dev, "%s: Invalid decimator = %s\n", + __func__, widget_name); + ret = -EINVAL; + goto out; + } + dev_dbg(codec->dev, "%s(): widget = %s decimator = %u\n", __func__, + w->name, decimator); + + tx_vol_ctl_reg = AQT1000_CDC_TX0_TX_PATH_CTL + 16 * decimator; + hpf_gate_reg = AQT1000_CDC_TX0_TX_PATH_SEC2 + 16 * decimator; + dec_cfg_reg = AQT1000_CDC_TX0_TX_PATH_CFG0 + 16 * decimator; + tx_gain_ctl_reg = AQT1000_CDC_TX0_TX_VOL_CTL + 16 * decimator; + + amic_n = aqt_find_amic_input(codec, decimator); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (amic_n) + pwr_level_reg = aqt_codec_get_amic_pwlvl_reg(codec, + amic_n); + if (pwr_level_reg) { + switch ((snd_soc_read(codec, pwr_level_reg) & + AQT1000_AMIC_PWR_LVL_MASK) >> + AQT1000_AMIC_PWR_LVL_SHIFT) { + case AQT1000_AMIC_PWR_LEVEL_LP: + snd_soc_update_bits(codec, dec_cfg_reg, + AQT1000_DEC_PWR_LVL_MASK, + AQT1000_DEC_PWR_LVL_LP); + break; + + case AQT1000_AMIC_PWR_LEVEL_HP: + snd_soc_update_bits(codec, dec_cfg_reg, + AQT1000_DEC_PWR_LVL_MASK, + AQT1000_DEC_PWR_LVL_HP); + break; + case AQT1000_AMIC_PWR_LEVEL_DEFAULT: + default: + snd_soc_update_bits(codec, dec_cfg_reg, + AQT1000_DEC_PWR_LVL_MASK, + AQT1000_DEC_PWR_LVL_DF); + break; + } + } + /* Enable TX PGA Mute */ + snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x10); + break; + case SND_SOC_DAPM_POST_PMU: + hpf_cut_off_freq = (snd_soc_read(codec, dec_cfg_reg) & + TX_HPF_CUT_OFF_FREQ_MASK) >> 5; + + aqt->tx_hpf_work[decimator].hpf_cut_off_freq = + hpf_cut_off_freq; + if (hpf_cut_off_freq != CF_MIN_3DB_150HZ) { + snd_soc_update_bits(codec, dec_cfg_reg, + TX_HPF_CUT_OFF_FREQ_MASK, + CF_MIN_3DB_150HZ << 5); + snd_soc_update_bits(codec, hpf_gate_reg, 0x02, 0x02); + /* + * Minimum 1 clk cycle delay is required as per + * HW spec. + */ + usleep_range(1000, 1010); + snd_soc_update_bits(codec, hpf_gate_reg, 0x02, 0x00); + } + /* schedule work queue to Remove Mute */ + schedule_delayed_work(&aqt->tx_mute_dwork[decimator].dwork, + msecs_to_jiffies(tx_unmute_delay)); + if (aqt->tx_hpf_work[decimator].hpf_cut_off_freq != + CF_MIN_3DB_150HZ) + schedule_delayed_work( + &aqt->tx_hpf_work[decimator].dwork, + msecs_to_jiffies(300)); + /* apply gain after decimator is enabled */ + snd_soc_write(codec, tx_gain_ctl_reg, + snd_soc_read(codec, tx_gain_ctl_reg)); + break; + case SND_SOC_DAPM_PRE_PMD: + hpf_cut_off_freq = + aqt->tx_hpf_work[decimator].hpf_cut_off_freq; + snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x10); + if (cancel_delayed_work_sync( + &aqt->tx_hpf_work[decimator].dwork)) { + if (hpf_cut_off_freq != CF_MIN_3DB_150HZ) { + snd_soc_update_bits(codec, dec_cfg_reg, + TX_HPF_CUT_OFF_FREQ_MASK, + hpf_cut_off_freq << 5); + snd_soc_update_bits(codec, hpf_gate_reg, + 0x02, 0x02); + /* + * Minimum 1 clk cycle delay is required as per + * HW spec. + */ + usleep_range(1000, 1010); + snd_soc_update_bits(codec, hpf_gate_reg, + 0x02, 0x00); + } + } + cancel_delayed_work_sync( + &aqt->tx_mute_dwork[decimator].dwork); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x00); + snd_soc_update_bits(codec, dec_cfg_reg, + AQT1000_DEC_PWR_LVL_MASK, + AQT1000_DEC_PWR_LVL_DF); + break; + } + +out: + kfree(widget_name); + return ret; +} + +static const char * const tx_amic_text[] = { + "ZERO", "ADC_L", "ADC_R", "ADC_V", +}; +AQT_DAPM_ENUM(tx_amic0, AQT1000_CDC_TX_INP_MUX_ADC_MUX0_CFG0, 0, tx_amic_text); +AQT_DAPM_ENUM(tx_amic1, AQT1000_CDC_TX_INP_MUX_ADC_MUX1_CFG0, 0, tx_amic_text); +AQT_DAPM_ENUM(tx_amic2, AQT1000_CDC_TX_INP_MUX_ADC_MUX2_CFG0, 0, tx_amic_text); + +AQT_DAPM_ENUM(tx_amic10, AQT1000_CDC_TX_INP_MUX_ADC_MUX10_CFG0, 0, + tx_amic_text); +AQT_DAPM_ENUM(tx_amic11, AQT1000_CDC_TX_INP_MUX_ADC_MUX11_CFG0, 0, + tx_amic_text); +AQT_DAPM_ENUM(tx_amic12, AQT1000_CDC_TX_INP_MUX_ADC_MUX12_CFG0, 0, + tx_amic_text); +AQT_DAPM_ENUM(tx_amic13, AQT1000_CDC_TX_INP_MUX_ADC_MUX13_CFG0, 0, + tx_amic_text); + +static int aqt_codec_enable_adc(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + aqt_codec_set_tx_hold(codec, w->reg, true); + break; + default: + break; + } + + return 0; +} + +static const struct snd_kcontrol_new anc_hphl_pa_switch = + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0); + +static const struct snd_kcontrol_new anc_hphr_pa_switch = + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0); + +static int aqt_config_compander(struct snd_soc_codec *codec, int interp_n, + int event) +{ + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + int comp; + u16 comp_ctl0_reg, rx_path_cfg0_reg; + + comp = interp_n; + dev_dbg(codec->dev, "%s: event %d compander %d, enabled %d\n", + __func__, event, comp, aqt->comp_enabled[comp]); + + if (!aqt->comp_enabled[comp]) + return 0; + + comp_ctl0_reg = AQT1000_CDC_COMPANDER1_CTL0 + (comp * 8); + rx_path_cfg0_reg = AQT1000_CDC_RX1_RX_PATH_CFG0 + (comp * 20); + + if (SND_SOC_DAPM_EVENT_ON(event)) { + /* Enable Compander Clock */ + snd_soc_update_bits(codec, comp_ctl0_reg, 0x01, 0x01); + snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x02); + snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x00); + snd_soc_update_bits(codec, rx_path_cfg0_reg, 0x02, 0x02); + } + + if (SND_SOC_DAPM_EVENT_OFF(event)) { + snd_soc_update_bits(codec, rx_path_cfg0_reg, 0x02, 0x00); + snd_soc_update_bits(codec, comp_ctl0_reg, 0x04, 0x04); + snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x02); + snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x00); + snd_soc_update_bits(codec, comp_ctl0_reg, 0x01, 0x00); + snd_soc_update_bits(codec, comp_ctl0_reg, 0x04, 0x00); + } + + return 0; +} + +static void aqt_codec_idle_detect_control(struct snd_soc_codec *codec, + int interp, int event) +{ + int reg = 0, mask, val; + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + + if (!aqt->idle_det_cfg.hph_idle_detect_en) + return; + + if (interp == INTERP_HPHL) { + reg = AQT1000_CDC_RX_IDLE_DET_PATH_CTL; + mask = 0x01; + val = 0x01; + } + if (interp == INTERP_HPHR) { + reg = AQT1000_CDC_RX_IDLE_DET_PATH_CTL; + mask = 0x02; + val = 0x02; + } + + if (reg && SND_SOC_DAPM_EVENT_ON(event)) + snd_soc_update_bits(codec, reg, mask, val); + + if (reg && SND_SOC_DAPM_EVENT_OFF(event)) { + snd_soc_update_bits(codec, reg, mask, 0x00); + aqt->idle_det_cfg.hph_idle_thr = 0; + snd_soc_write(codec, AQT1000_CDC_RX_IDLE_DET_CFG3, 0x0); + } +} + +static void aqt_codec_hphdelay_lutbypass(struct snd_soc_codec *codec, + u16 interp_idx, int event) +{ + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + u8 hph_dly_mask; + u16 hph_lut_bypass_reg = 0; + u16 hph_comp_ctrl7 = 0; + + + switch (interp_idx) { + case INTERP_HPHL: + hph_dly_mask = 1; + hph_lut_bypass_reg = AQT1000_CDC_TOP_HPHL_COMP_LUT; + hph_comp_ctrl7 = AQT1000_CDC_COMPANDER1_CTL7; + break; + case INTERP_HPHR: + hph_dly_mask = 2; + hph_lut_bypass_reg = AQT1000_CDC_TOP_HPHR_COMP_LUT; + hph_comp_ctrl7 = AQT1000_CDC_COMPANDER2_CTL7; + break; + default: + break; + } + + if (hph_lut_bypass_reg && SND_SOC_DAPM_EVENT_ON(event)) { + snd_soc_update_bits(codec, AQT1000_CDC_CLSH_TEST0, + hph_dly_mask, 0x0); + snd_soc_update_bits(codec, hph_lut_bypass_reg, 0x80, 0x80); + if (aqt->hph_mode == CLS_H_ULP) + snd_soc_update_bits(codec, hph_comp_ctrl7, 0x20, 0x20); + } + + if (hph_lut_bypass_reg && SND_SOC_DAPM_EVENT_OFF(event)) { + snd_soc_update_bits(codec, AQT1000_CDC_CLSH_TEST0, + hph_dly_mask, hph_dly_mask); + snd_soc_update_bits(codec, hph_lut_bypass_reg, 0x80, 0x00); + snd_soc_update_bits(codec, hph_comp_ctrl7, 0x20, 0x0); + } +} + +static int aqt_codec_enable_interp_clk(struct snd_soc_codec *codec, + int event, int interp_idx) +{ + struct aqt1000 *aqt; + u16 main_reg, dsm_reg; + + if (!codec) { + pr_err("%s: codec is NULL\n", __func__); + return -EINVAL; + } + + aqt = snd_soc_codec_get_drvdata(codec); + main_reg = AQT1000_CDC_RX1_RX_PATH_CTL + (interp_idx * 20); + dsm_reg = AQT1000_CDC_RX1_RX_PATH_DSMDEM_CTL + (interp_idx * 20); + + if (SND_SOC_DAPM_EVENT_ON(event)) { + if (aqt->main_clk_users[interp_idx] == 0) { + /* Main path PGA mute enable */ + snd_soc_update_bits(codec, main_reg, 0x10, 0x10); + /* Clk enable */ + snd_soc_update_bits(codec, dsm_reg, 0x01, 0x01); + snd_soc_update_bits(codec, main_reg, 0x20, 0x20); + aqt_codec_idle_detect_control(codec, interp_idx, + event); + aqt_codec_hphdelay_lutbypass(codec, interp_idx, + event); + aqt_config_compander(codec, interp_idx, event); + } + aqt->main_clk_users[interp_idx]++; + } + + if (SND_SOC_DAPM_EVENT_OFF(event)) { + aqt->main_clk_users[interp_idx]--; + if (aqt->main_clk_users[interp_idx] <= 0) { + aqt->main_clk_users[interp_idx] = 0; + aqt_config_compander(codec, interp_idx, event); + aqt_codec_hphdelay_lutbypass(codec, interp_idx, + event); + aqt_codec_idle_detect_control(codec, interp_idx, + event); + /* Clk Disable */ + snd_soc_update_bits(codec, main_reg, 0x20, 0x00); + snd_soc_update_bits(codec, dsm_reg, 0x01, 0x00); + /* Reset enable and disable */ + snd_soc_update_bits(codec, main_reg, 0x40, 0x40); + snd_soc_update_bits(codec, main_reg, 0x40, 0x00); + /* Reset rate to 48K*/ + snd_soc_update_bits(codec, main_reg, 0x0F, 0x04); + } + } + + dev_dbg(codec->dev, "%s event %d main_clk_users %d\n", + __func__, event, aqt->main_clk_users[interp_idx]); + + return aqt->main_clk_users[interp_idx]; +} + +static int aqt_anc_out_switch_cb(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + aqt_codec_enable_interp_clk(codec, event, w->shift); + + return 0; +} + +static const char * const anc0_fb_mux_text[] = { + "ZERO", "ANC_IN_HPHL", +}; + +static const char * const anc1_fb_mux_text[] = { + "ZERO", "ANC_IN_HPHR", +}; + +AQT_DAPM_ENUM(anc0_fb, AQT1000_CDC_RX_INP_MUX_ANC_CFG0, 0, anc0_fb_mux_text); +AQT_DAPM_ENUM(anc1_fb, AQT1000_CDC_RX_INP_MUX_ANC_CFG0, 3, anc1_fb_mux_text); + +static const char *const rx_int1_1_mux_text[] = { + "ZERO", "MAIN_DMA_L", "I2S0_L", "I2S0_R", "DEC_L", "DEC_R", "DEC_V", + "SHADOW_I2S0_L", "MAIN_DMA_R" +}; + +static const char *const rx_int1_2_mux_text[] = { + "ZERO", "MIX_DMA_L", "I2S0_L", "I2S0_R", "DEC_L", "DEC_R", "DEC_V", + "IIR0", "MIX_DMA_R" +}; + +static const char *const rx_int2_1_mux_text[] = { + "ZERO", "MAIN_DMA_R", "I2S0_L", "I2S0_R", "DEC_L", "DEC_R", "DEC_V", + "SHADOW_I2S0_R", "MAIN_DMA_L" +}; + +static const char *const rx_int2_2_mux_text[] = { + "ZERO", "MIX_DMA_R", "I2S0_L", "I2S0_R", "DEC_L", "DEC_R", "DEC_V", + "IIR0", "MIX_DMA_L" +}; + +AQT_DAPM_ENUM(rx_int1_1, AQT1000_CDC_RX_INP_MUX_RX_INT1_CFG0, 0, + rx_int1_1_mux_text); +AQT_DAPM_ENUM(rx_int1_2, AQT1000_CDC_RX_INP_MUX_RX_INT1_CFG1, 0, + rx_int1_2_mux_text); +AQT_DAPM_ENUM(rx_int2_1, AQT1000_CDC_RX_INP_MUX_RX_INT2_CFG0, 0, + rx_int2_1_mux_text); +AQT_DAPM_ENUM(rx_int2_2, AQT1000_CDC_RX_INP_MUX_RX_INT2_CFG1, 0, + rx_int2_2_mux_text); + +static int aqt_codec_set_idle_detect_thr(struct snd_soc_codec *codec, + int interp, int path_type) +{ + int port_id[4] = { 0, 0, 0, 0 }; + int *port_ptr, num_ports; + int bit_width = 0; + int mux_reg = 0, mux_reg_val = 0; + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + int idle_thr; + + if ((interp != INTERP_HPHL) && (interp != INTERP_HPHR)) + return 0; + + if (!aqt->idle_det_cfg.hph_idle_detect_en) + return 0; + + port_ptr = &port_id[0]; + num_ports = 0; + + if (path_type == INTERP_MIX_PATH) { + if (interp == INTERP_HPHL) + mux_reg = AQT1000_CDC_RX_INP_MUX_RX_INT1_CFG1; + else + mux_reg = AQT1000_CDC_RX_INP_MUX_RX_INT2_CFG1; + } + + if (path_type == INTERP_MAIN_PATH) { + if (interp == INTERP_HPHL) + mux_reg = AQT1000_CDC_RX_INP_MUX_RX_INT1_CFG0; + else + mux_reg = AQT1000_CDC_RX_INP_MUX_RX_INT2_CFG0; + } + mux_reg_val = snd_soc_read(codec, mux_reg); + + /* Read bit width from I2S reg if mux is set to I2S0_L or I2S0_R */ + if (mux_reg_val == 0x02 || mux_reg_val == 0x03) + bit_width = ((snd_soc_read(codec, AQT1000_I2S_I2S_0_CTL) & + 0x40) >> 6); + + switch (bit_width) { + case 1: /* 16 bit */ + idle_thr = 0xff; /* F16 */ + break; + case 0: /* 32 bit */ + default: + idle_thr = 0x03; /* F22 */ + break; + } + + dev_dbg(codec->dev, "%s: (new) idle_thr: %d, (cur) idle_thr: %d\n", + __func__, idle_thr, aqt->idle_det_cfg.hph_idle_thr); + + if ((aqt->idle_det_cfg.hph_idle_thr == 0) || + (idle_thr < aqt->idle_det_cfg.hph_idle_thr)) { + snd_soc_write(codec, AQT1000_CDC_RX_IDLE_DET_CFG3, idle_thr); + aqt->idle_det_cfg.hph_idle_thr = idle_thr; + } + + return 0; +} + +static int aqt_codec_enable_main_path(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + u16 gain_reg = 0; + int val = 0; + + dev_dbg(codec->dev, "%s %d %s\n", __func__, event, w->name); + + if (w->shift >= AQT1000_NUM_INTERPOLATORS) { + dev_err(codec->dev, "%s: Invalid Interpolator value %d for name %s\n", + __func__, w->shift, w->name); + return -EINVAL; + }; + + gain_reg = AQT1000_CDC_RX1_RX_VOL_CTL + (w->shift * + AQT1000_RX_PATH_CTL_OFFSET); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + aqt_codec_enable_interp_clk(codec, event, w->shift); + break; + case SND_SOC_DAPM_POST_PMU: + aqt_codec_set_idle_detect_thr(codec, w->shift, + INTERP_MAIN_PATH); + /* apply gain after int clk is enabled */ + val = snd_soc_read(codec, gain_reg); + snd_soc_write(codec, gain_reg, val); + break; + case SND_SOC_DAPM_POST_PMD: + aqt_codec_enable_interp_clk(codec, event, w->shift); + break; + }; + + return 0; +} + +static int aqt_codec_enable_mix_path(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + u16 gain_reg = 0; + u16 mix_reg = 0; + + if (w->shift >= AQT1000_NUM_INTERPOLATORS) { + dev_err(codec->dev, "%s: Invalid Interpolator value %d for name %s\n", + __func__, w->shift, w->name); + return -EINVAL; + }; + gain_reg = AQT1000_CDC_RX1_RX_VOL_MIX_CTL + + (w->shift * AQT1000_RX_PATH_CTL_OFFSET); + mix_reg = AQT1000_CDC_RX1_RX_PATH_MIX_CTL + + (w->shift * AQT1000_RX_PATH_CTL_OFFSET); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + aqt_codec_enable_interp_clk(codec, event, w->shift); + /* Clk enable */ + snd_soc_update_bits(codec, mix_reg, 0x20, 0x20); + break; + case SND_SOC_DAPM_POST_PMU: + aqt_codec_set_idle_detect_thr(codec, w->shift, + INTERP_MIX_PATH); + break; + case SND_SOC_DAPM_POST_PMD: + /* Clk Disable */ + snd_soc_update_bits(codec, mix_reg, 0x20, 0x00); + aqt_codec_enable_interp_clk(codec, event, w->shift); + /* Reset enable and disable */ + snd_soc_update_bits(codec, mix_reg, 0x40, 0x40); + snd_soc_update_bits(codec, mix_reg, 0x40, 0x00); + + break; + }; + dev_dbg(codec->dev, "%s event %d name %s\n", __func__, event, w->name); + + return 0; +} + +static const char * const rx_int1_1_interp_mux_text[] = { + "ZERO", "RX INT1_1 MUX", +}; + +static const char * const rx_int2_1_interp_mux_text[] = { + "ZERO", "RX INT2_1 MUX", +}; + +static const char * const rx_int1_2_interp_mux_text[] = { + "ZERO", "RX INT1_2 MUX", +}; + +static const char * const rx_int2_2_interp_mux_text[] = { + "ZERO", "RX INT2_2 MUX", +}; + +AQT_DAPM_ENUM(rx_int1_1_interp, SND_SOC_NOPM, 0, rx_int1_1_interp_mux_text); +AQT_DAPM_ENUM(rx_int2_1_interp, SND_SOC_NOPM, 0, rx_int2_1_interp_mux_text); + +AQT_DAPM_ENUM(rx_int1_2_interp, SND_SOC_NOPM, 0, rx_int1_2_interp_mux_text); +AQT_DAPM_ENUM(rx_int2_2_interp, SND_SOC_NOPM, 0, rx_int2_2_interp_mux_text); + +static const char * const asrc0_mux_text[] = { + "ZERO", "ASRC_IN_HPHL", +}; + +static const char * const asrc1_mux_text[] = { + "ZERO", "ASRC_IN_HPHR", +}; + +AQT_DAPM_ENUM(asrc0, AQT1000_CDC_RX_INP_MUX_SPLINE_ASRC_CFG0, 0, + asrc0_mux_text); +AQT_DAPM_ENUM(asrc1, AQT1000_CDC_RX_INP_MUX_SPLINE_ASRC_CFG0, 2, + asrc1_mux_text); + +static int aqt_get_asrc_mode(struct aqt1000 *aqt, int asrc, + u8 main_sr, u8 mix_sr) +{ + u8 asrc_output_mode; + int asrc_mode = CONV_88P2K_TO_384K; + + if ((asrc < 0) || (asrc >= ASRC_MAX)) + return 0; + + asrc_output_mode = aqt->asrc_output_mode[asrc]; + + if (asrc_output_mode) { + /* + * If Mix sample rate is < 96KHz, use 96K to 352.8K + * conversion, or else use 384K to 352.8K conversion + */ + if (mix_sr < 5) + asrc_mode = CONV_96K_TO_352P8K; + else + asrc_mode = CONV_384K_TO_352P8K; + } else { + /* Integer main and Fractional mix path */ + if (main_sr < 8 && mix_sr > 9) { + asrc_mode = CONV_352P8K_TO_384K; + } else if (main_sr > 8 && mix_sr < 8) { + /* Fractional main and Integer mix path */ + if (mix_sr < 5) + asrc_mode = CONV_96K_TO_352P8K; + else + asrc_mode = CONV_384K_TO_352P8K; + } else if (main_sr < 8 && mix_sr < 8) { + /* Integer main and Integer mix path */ + asrc_mode = CONV_96K_TO_384K; + } + } + + return asrc_mode; +} + +static int aqt_codec_enable_asrc_resampler(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + int asrc = 0, ret = 0; + u8 cfg; + u16 cfg_reg = 0; + u16 ctl_reg = 0; + u16 clk_reg = 0; + u16 asrc_ctl = 0; + u16 mix_ctl_reg = 0; + u16 paired_reg = 0; + u8 main_sr, mix_sr, asrc_mode = 0; + + cfg = snd_soc_read(codec, AQT1000_CDC_RX_INP_MUX_SPLINE_ASRC_CFG0); + if (!(cfg & 0xFF)) { + dev_err(codec->dev, "%s: ASRC%u input not selected\n", + __func__, w->shift); + return -EINVAL; + } + + switch (w->shift) { + case ASRC0: + if ((cfg & 0x03) == 0x01) { + cfg_reg = AQT1000_CDC_RX1_RX_PATH_CFG0; + ctl_reg = AQT1000_CDC_RX1_RX_PATH_CTL; + clk_reg = AQT1000_MIXING_ASRC0_CLK_RST_CTL; + paired_reg = AQT1000_MIXING_ASRC1_CLK_RST_CTL; + asrc_ctl = AQT1000_MIXING_ASRC0_CTL1; + } + break; + case ASRC1: + if ((cfg & 0x0C) == 0x4) { + cfg_reg = AQT1000_CDC_RX2_RX_PATH_CFG0; + ctl_reg = AQT1000_CDC_RX2_RX_PATH_CTL; + clk_reg = AQT1000_MIXING_ASRC1_CLK_RST_CTL; + paired_reg = AQT1000_MIXING_ASRC0_CLK_RST_CTL; + asrc_ctl = AQT1000_MIXING_ASRC1_CTL1; + } + break; + default: + dev_err(codec->dev, "%s: Invalid asrc:%u\n", __func__, + w->shift); + ret = -EINVAL; + break; + }; + + if ((cfg_reg == 0) || (ctl_reg == 0) || (clk_reg == 0) || + (asrc_ctl == 0) || ret) + goto done; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if ((snd_soc_read(codec, clk_reg) & 0x02) || + (snd_soc_read(codec, paired_reg) & 0x02)) { + snd_soc_update_bits(codec, clk_reg, 0x02, 0x00); + snd_soc_update_bits(codec, paired_reg, 0x02, 0x00); + } + snd_soc_update_bits(codec, cfg_reg, 0x80, 0x80); + snd_soc_update_bits(codec, clk_reg, 0x01, 0x01); + main_sr = snd_soc_read(codec, ctl_reg) & 0x0F; + mix_ctl_reg = ctl_reg + 5; + mix_sr = snd_soc_read(codec, mix_ctl_reg) & 0x0F; + asrc_mode = aqt_get_asrc_mode(aqt, asrc, + main_sr, mix_sr); + dev_dbg(codec->dev, "%s: main_sr:%d mix_sr:%d asrc_mode %d\n", + __func__, main_sr, mix_sr, asrc_mode); + snd_soc_update_bits(codec, asrc_ctl, 0x07, asrc_mode); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_update_bits(codec, asrc_ctl, 0x07, 0x00); + snd_soc_update_bits(codec, cfg_reg, 0x80, 0x00); + snd_soc_update_bits(codec, clk_reg, 0x03, 0x02); + break; + }; + +done: + return ret; +} + +static int aqt_codec_enable_anc(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + const char *filename; + const struct firmware *fw; + int i; + int ret = 0; + int num_anc_slots; + struct aqt1000_anc_header *anc_head; + struct firmware_cal *hwdep_cal = NULL; + u32 anc_writes_size = 0; + u32 anc_cal_size = 0; + int anc_size_remaining; + u32 *anc_ptr; + u16 reg; + u8 mask, val; + size_t cal_size; + const void *data; + + if (!aqt->anc_func) + return 0; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + hwdep_cal = wcdcal_get_fw_cal(aqt->fw_data, WCD9XXX_ANC_CAL); + if (hwdep_cal) { + data = hwdep_cal->data; + cal_size = hwdep_cal->size; + dev_dbg(codec->dev, "%s: using hwdep calibration, cal_size %zd", + __func__, cal_size); + } else { + filename = "AQT1000/AQT1000_anc.bin"; + ret = request_firmware(&fw, filename, codec->dev); + if (ret < 0) { + dev_err(codec->dev, "%s: Failed to acquire ANC data: %d\n", + __func__, ret); + return ret; + } + if (!fw) { + dev_err(codec->dev, "%s: Failed to get anc fw\n", + __func__); + return -ENODEV; + } + data = fw->data; + cal_size = fw->size; + dev_dbg(codec->dev, "%s: using request_firmware calibration\n", + __func__); + } + if (cal_size < sizeof(struct aqt1000_anc_header)) { + dev_err(codec->dev, "%s: Invalid cal_size %zd\n", + __func__, cal_size); + ret = -EINVAL; + goto err; + } + /* First number is the number of register writes */ + anc_head = (struct aqt1000_anc_header *)(data); + anc_ptr = (u32 *)(data + sizeof(struct aqt1000_anc_header)); + anc_size_remaining = cal_size - + sizeof(struct aqt1000_anc_header); + num_anc_slots = anc_head->num_anc_slots; + + if (aqt->anc_slot >= num_anc_slots) { + dev_err(codec->dev, "%s: Invalid ANC slot selected\n", + __func__); + ret = -EINVAL; + goto err; + } + for (i = 0; i < num_anc_slots; i++) { + if (anc_size_remaining < AQT1000_PACKED_REG_SIZE) { + dev_err(codec->dev, "%s: Invalid register format\n", + __func__); + ret = -EINVAL; + goto err; + } + anc_writes_size = (u32)(*anc_ptr); + anc_size_remaining -= sizeof(u32); + anc_ptr += 1; + + if ((anc_writes_size * AQT1000_PACKED_REG_SIZE) > + anc_size_remaining) { + dev_err(codec->dev, "%s: Invalid register format\n", + __func__); + ret = -EINVAL; + goto err; + } + + if (aqt->anc_slot == i) + break; + + anc_size_remaining -= (anc_writes_size * + AQT1000_PACKED_REG_SIZE); + anc_ptr += anc_writes_size; + } + if (i == num_anc_slots) { + dev_err(codec->dev, "%s: Selected ANC slot not present\n", + __func__); + ret = -EINVAL; + goto err; + } + + i = 0; + anc_cal_size = anc_writes_size; + /* Rate converter clk enable and set bypass mode */ + if (!strcmp(w->name, "AQT RX INT1 DAC")) { + snd_soc_update_bits(codec, + AQT1000_CDC_ANC0_RC_COMMON_CTL, + 0x05, 0x05); + snd_soc_update_bits(codec, + AQT1000_CDC_ANC0_FIFO_COMMON_CTL, + 0x66, 0x66); + anc_writes_size = anc_cal_size / 2; + snd_soc_update_bits(codec, + AQT1000_CDC_ANC0_CLK_RESET_CTL, 0x39, 0x39); + } else if (!strcmp(w->name, "AQT RX INT2 DAC")) { + snd_soc_update_bits(codec, + AQT1000_CDC_ANC1_RC_COMMON_CTL, + 0x05, 0x05); + snd_soc_update_bits(codec, + AQT1000_CDC_ANC1_FIFO_COMMON_CTL, + 0x66, 0x66); + i = anc_cal_size / 2; + snd_soc_update_bits(codec, + AQT1000_CDC_ANC1_CLK_RESET_CTL, 0x39, 0x39); + } + + for (; i < anc_writes_size; i++) { + AQT1000_CODEC_UNPACK_ENTRY(anc_ptr[i], reg, mask, val); + snd_soc_write(codec, reg, (val & mask)); + } + if (!strcmp(w->name, "AQT RX INT1 DAC")) + snd_soc_update_bits(codec, + AQT1000_CDC_ANC0_CLK_RESET_CTL, 0x08, 0x08); + else if (!strcmp(w->name, "AQT RX INT2 DAC")) + snd_soc_update_bits(codec, + AQT1000_CDC_ANC1_CLK_RESET_CTL, 0x08, 0x08); + + if (!hwdep_cal) + release_firmware(fw); + break; + + case SND_SOC_DAPM_POST_PMU: + /* Remove ANC Rx from reset */ + snd_soc_update_bits(codec, + AQT1000_CDC_ANC0_CLK_RESET_CTL, + 0x08, 0x00); + snd_soc_update_bits(codec, + AQT1000_CDC_ANC1_CLK_RESET_CTL, + 0x08, 0x00); + break; + + case SND_SOC_DAPM_POST_PMD: + snd_soc_update_bits(codec, AQT1000_CDC_ANC0_RC_COMMON_CTL, + 0x05, 0x00); + if (!strcmp(w->name, "AQT ANC HPHL PA")) { + snd_soc_update_bits(codec, AQT1000_CDC_ANC0_MODE_1_CTL, + 0x30, 0x00); + /* 50 msec sleep is needed to avoid click and pop as + * per HW requirement + */ + msleep(50); + snd_soc_update_bits(codec, AQT1000_CDC_ANC0_MODE_1_CTL, + 0x01, 0x00); + snd_soc_update_bits(codec, + AQT1000_CDC_ANC0_CLK_RESET_CTL, + 0x38, 0x38); + snd_soc_update_bits(codec, + AQT1000_CDC_ANC0_CLK_RESET_CTL, + 0x07, 0x00); + snd_soc_update_bits(codec, + AQT1000_CDC_ANC0_CLK_RESET_CTL, + 0x38, 0x00); + } else if (!strcmp(w->name, "AQT ANC HPHR PA")) { + snd_soc_update_bits(codec, AQT1000_CDC_ANC1_MODE_1_CTL, + 0x30, 0x00); + /* 50 msec sleep is needed to avoid click and pop as + * per HW requirement + */ + msleep(50); + snd_soc_update_bits(codec, AQT1000_CDC_ANC1_MODE_1_CTL, + 0x01, 0x00); + snd_soc_update_bits(codec, + AQT1000_CDC_ANC1_CLK_RESET_CTL, + 0x38, 0x38); + snd_soc_update_bits(codec, + AQT1000_CDC_ANC1_CLK_RESET_CTL, + 0x07, 0x00); + snd_soc_update_bits(codec, + AQT1000_CDC_ANC1_CLK_RESET_CTL, + 0x38, 0x00); + } + break; + } + + return 0; +err: + if (!hwdep_cal) + release_firmware(fw); + return ret; +} + +static void aqt_codec_override(struct snd_soc_codec *codec, int mode, + int event) +{ + if (mode == CLS_AB || mode == CLS_AB_HIFI) { + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + case SND_SOC_DAPM_POST_PMU: + snd_soc_update_bits(codec, + AQT1000_ANA_RX_SUPPLIES, 0x02, 0x02); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_update_bits(codec, + AQT1000_ANA_RX_SUPPLIES, 0x02, 0x00); + break; + } + } +} + +static void aqt_codec_set_tx_hold(struct snd_soc_codec *codec, + u16 amic_reg, bool set) +{ + u8 mask = 0x20; + u8 val; + + if (amic_reg == AQT1000_ANA_AMIC1 || + amic_reg == AQT1000_ANA_AMIC3) + mask = 0x40; + + val = set ? mask : 0x00; + + switch (amic_reg) { + case AQT1000_ANA_AMIC1: + case AQT1000_ANA_AMIC2: + snd_soc_update_bits(codec, AQT1000_ANA_AMIC2, mask, val); + break; + case AQT1000_ANA_AMIC3: + snd_soc_update_bits(codec, AQT1000_ANA_AMIC3_HPF, mask, val); + break; + default: + dev_dbg(codec->dev, "%s: invalid amic: %d\n", + __func__, amic_reg); + break; + } +} + +static void aqt_codec_clear_anc_tx_hold(struct aqt1000 *aqt) +{ + if (test_and_clear_bit(ANC_MIC_AMIC1, &aqt->status_mask)) + aqt_codec_set_tx_hold(aqt->codec, AQT1000_ANA_AMIC1, false); + if (test_and_clear_bit(ANC_MIC_AMIC2, &aqt->status_mask)) + aqt_codec_set_tx_hold(aqt->codec, AQT1000_ANA_AMIC2, false); + if (test_and_clear_bit(ANC_MIC_AMIC3, &aqt->status_mask)) + aqt_codec_set_tx_hold(aqt->codec, AQT1000_ANA_AMIC3, false); +} + +static const char * const rx_int_dem_inp_mux_text[] = { + "NORMAL_DSM_OUT", "CLSH_DSM_OUT", +}; + +static int aqt_int_dem_inp_mux_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + unsigned int val; + unsigned short look_ahead_dly_reg = AQT1000_CDC_RX1_RX_PATH_CFG0; + + val = ucontrol->value.enumerated.item[0]; + if (val >= e->items) + return -EINVAL; + + dev_dbg(codec->dev, "%s: wname: %s, val: 0x%x\n", __func__, + widget->name, val); + + if (e->reg == AQT1000_CDC_RX1_RX_PATH_SEC0) + look_ahead_dly_reg = AQT1000_CDC_RX1_RX_PATH_CFG0; + else if (e->reg == AQT1000_CDC_RX2_RX_PATH_SEC0) + look_ahead_dly_reg = AQT1000_CDC_RX2_RX_PATH_CFG0; + + /* Set Look Ahead Delay */ + snd_soc_update_bits(codec, look_ahead_dly_reg, + 0x08, (val ? 0x08 : 0x00)); + /* Set DEM INP Select */ + return snd_soc_dapm_put_enum_double(kcontrol, ucontrol); +} + +AQT_DAPM_ENUM_EXT(rx_int1_dem, AQT1000_CDC_RX1_RX_PATH_SEC0, 0, + rx_int_dem_inp_mux_text, snd_soc_dapm_get_enum_double, + aqt_int_dem_inp_mux_put); +AQT_DAPM_ENUM_EXT(rx_int2_dem, AQT1000_CDC_RX2_RX_PATH_SEC0, 0, + rx_int_dem_inp_mux_text, snd_soc_dapm_get_enum_double, + aqt_int_dem_inp_mux_put); + +static int aqt_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + int hph_mode = aqt->hph_mode; + u8 dem_inp; + int ret = 0; + + dev_dbg(codec->dev, "%s wname: %s event: %d hph_mode: %d\n", __func__, + w->name, event, hph_mode); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (aqt->anc_func) { + ret = aqt_codec_enable_anc(w, kcontrol, event); + /* 40 msec delay is needed to avoid click and pop */ + msleep(40); + } + /* Read DEM INP Select */ + dem_inp = snd_soc_read(codec, AQT1000_CDC_RX1_RX_PATH_SEC0) & + 0x03; + if (((hph_mode == CLS_H_HIFI) || (hph_mode == CLS_H_LOHIFI) || + (hph_mode == CLS_H_LP)) && (dem_inp != 0x01)) { + dev_err(codec->dev, "%s: DEM Input not set correctly, hph_mode: %d\n", + __func__, hph_mode); + return -EINVAL; + } + /* Disable AutoChop timer during power up */ + snd_soc_update_bits(codec, AQT1000_HPH_NEW_INT_HPH_TIMER1, + 0x02, 0x00); + + aqt_clsh_fsm(codec, &aqt->clsh_d, + AQT_CLSH_EVENT_PRE_DAC, + AQT_CLSH_STATE_HPHL, + hph_mode); + + if (aqt->anc_func) + snd_soc_update_bits(codec, + AQT1000_CDC_RX1_RX_PATH_CFG0, + 0x10, 0x10); + break; + case SND_SOC_DAPM_POST_PMD: + /* 1000us required as per HW requirement */ + usleep_range(1000, 1100); + aqt_clsh_fsm(codec, &aqt->clsh_d, + AQT_CLSH_EVENT_POST_PA, + AQT_CLSH_STATE_HPHL, + hph_mode); + break; + default: + break; + }; + + return ret; +} + +static int aqt_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + int hph_mode = aqt->hph_mode; + u8 dem_inp; + int ret = 0; + + dev_dbg(codec->dev, "%s wname: %s event: %d hph_mode: %d\n", __func__, + w->name, event, hph_mode); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (aqt->anc_func) { + ret = aqt_codec_enable_anc(w, kcontrol, event); + /* 40 msec delay is needed to avoid click and pop */ + msleep(40); + } + /* Read DEM INP Select */ + dem_inp = snd_soc_read(codec, AQT1000_CDC_RX2_RX_PATH_SEC0) & + 0x03; + if (((hph_mode == CLS_H_HIFI) || (hph_mode == CLS_H_LOHIFI) || + (hph_mode == CLS_H_LP)) && (dem_inp != 0x01)) { + dev_err(codec->dev, "%s: DEM Input not set correctly, hph_mode: %d\n", + __func__, hph_mode); + return -EINVAL; + } + /* Disable AutoChop timer during power up */ + snd_soc_update_bits(codec, AQT1000_HPH_NEW_INT_HPH_TIMER1, + 0x02, 0x00); + aqt_clsh_fsm(codec, &aqt->clsh_d, + AQT_CLSH_EVENT_PRE_DAC, + AQT_CLSH_STATE_HPHR, + hph_mode); + if (aqt->anc_func) + snd_soc_update_bits(codec, + AQT1000_CDC_RX2_RX_PATH_CFG0, + 0x10, 0x10); + break; + case SND_SOC_DAPM_POST_PMD: + /* 1000us required as per HW requirement */ + usleep_range(1000, 1100); + aqt_clsh_fsm(codec, &aqt->clsh_d, + AQT_CLSH_EVENT_POST_PA, + AQT_CLSH_STATE_HPHR, + hph_mode); + break; + default: + break; + }; + + return 0; +} + +static int aqt_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + int ret = 0; + + dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if ((!(strcmp(w->name, "AQT ANC HPHR PA"))) && + (test_bit(HPH_PA_DELAY, &aqt->status_mask))) + snd_soc_update_bits(codec, AQT1000_ANA_HPH, 0xC0, 0xC0); + + set_bit(HPH_PA_DELAY, &aqt->status_mask); + break; + case SND_SOC_DAPM_POST_PMU: + if ((!(strcmp(w->name, "AQT ANC HPHR PA")))) { + if ((snd_soc_read(codec, AQT1000_ANA_HPH) & 0xC0) + != 0xC0) + /* + * If PA_EN is not set (potentially in ANC case) + * then do nothing for POST_PMU and let left + * channel handle everything. + */ + break; + } + /* + * 7ms sleep is required after PA is enabled as per + * HW requirement. If compander is disabled, then + * 20ms delay is needed. + */ + if (test_bit(HPH_PA_DELAY, &aqt->status_mask)) { + if (!aqt->comp_enabled[COMPANDER_2]) + usleep_range(20000, 20100); + else + usleep_range(7000, 7100); + clear_bit(HPH_PA_DELAY, &aqt->status_mask); + } + if (aqt->anc_func) { + /* Clear Tx FE HOLD if both PAs are enabled */ + if ((snd_soc_read(aqt->codec, AQT1000_ANA_HPH) & + 0xC0) == 0xC0) + aqt_codec_clear_anc_tx_hold(aqt); + } + + snd_soc_update_bits(codec, AQT1000_HPH_R_TEST, 0x01, 0x01); + + /* Remove mute */ + snd_soc_update_bits(codec, AQT1000_CDC_RX2_RX_PATH_CTL, + 0x10, 0x00); + /* Enable GM3 boost */ + snd_soc_update_bits(codec, AQT1000_HPH_CNP_WG_CTL, + 0x80, 0x80); + /* Enable AutoChop timer at the end of power up */ + snd_soc_update_bits(codec, AQT1000_HPH_NEW_INT_HPH_TIMER1, + 0x02, 0x02); + /* Remove mix path mute if it is enabled */ + if ((snd_soc_read(codec, AQT1000_CDC_RX2_RX_PATH_MIX_CTL)) & + 0x10) + snd_soc_update_bits(codec, + AQT1000_CDC_RX2_RX_PATH_MIX_CTL, + 0x10, 0x00); + if (!(strcmp(w->name, "AQT ANC HPHR PA"))) { + dev_dbg(codec->dev, + "%s:Do everything needed for left channel\n", + __func__); + /* Do everything needed for left channel */ + snd_soc_update_bits(codec, AQT1000_HPH_L_TEST, + 0x01, 0x01); + + /* Remove mute */ + snd_soc_update_bits(codec, AQT1000_CDC_RX1_RX_PATH_CTL, + 0x10, 0x00); + + /* Remove mix path mute if it is enabled */ + if ((snd_soc_read(codec, + AQT1000_CDC_RX1_RX_PATH_MIX_CTL)) & + 0x10) + snd_soc_update_bits(codec, + AQT1000_CDC_RX1_RX_PATH_MIX_CTL, + 0x10, 0x00); + + /* Remove ANC Rx from reset */ + ret = aqt_codec_enable_anc(w, kcontrol, event); + } + aqt_codec_override(codec, aqt->hph_mode, event); + break; + case SND_SOC_DAPM_PRE_PMD: + snd_soc_update_bits(codec, AQT1000_HPH_R_TEST, 0x01, 0x00); + snd_soc_update_bits(codec, AQT1000_CDC_RX2_RX_PATH_CTL, + 0x10, 0x10); + snd_soc_update_bits(codec, AQT1000_CDC_RX2_RX_PATH_MIX_CTL, + 0x10, 0x10); + if (!(strcmp(w->name, "AQT ANC HPHR PA"))) + snd_soc_update_bits(codec, AQT1000_ANA_HPH, 0x40, 0x00); + break; + case SND_SOC_DAPM_POST_PMD: + /* + * 5ms sleep is required after PA disable. If compander is + * disabled, then 20ms delay is needed after PA disable. + */ + if (!aqt->comp_enabled[COMPANDER_2]) + usleep_range(20000, 20100); + else + usleep_range(5000, 5100); + aqt_codec_override(codec, aqt->hph_mode, event); + if (!(strcmp(w->name, "AQT ANC HPHR PA"))) { + ret = aqt_codec_enable_anc(w, kcontrol, event); + snd_soc_update_bits(codec, + AQT1000_CDC_RX2_RX_PATH_CFG0, + 0x10, 0x00); + } + break; + }; + + return ret; +} + +static int aqt_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + int ret = 0; + + dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if ((!(strcmp(w->name, "AQT ANC HPHL PA"))) && + (test_bit(HPH_PA_DELAY, &aqt->status_mask))) + snd_soc_update_bits(codec, AQT1000_ANA_HPH, + 0xC0, 0xC0); + set_bit(HPH_PA_DELAY, &aqt->status_mask); + break; + case SND_SOC_DAPM_POST_PMU: + if (!(strcmp(w->name, "AQT ANC HPHL PA"))) { + if ((snd_soc_read(codec, AQT1000_ANA_HPH) & 0xC0) + != 0xC0) + /* + * If PA_EN is not set (potentially in ANC + * case) then do nothing for POST_PMU and + * let right channel handle everything. + */ + break; + } + /* + * 7ms sleep is required after PA is enabled as per + * HW requirement. If compander is disabled, then + * 20ms delay is needed. + */ + if (test_bit(HPH_PA_DELAY, &aqt->status_mask)) { + if (!aqt->comp_enabled[COMPANDER_1]) + usleep_range(20000, 20100); + else + usleep_range(7000, 7100); + clear_bit(HPH_PA_DELAY, &aqt->status_mask); + } + if (aqt->anc_func) { + /* Clear Tx FE HOLD if both PAs are enabled */ + if ((snd_soc_read(aqt->codec, AQT1000_ANA_HPH) & + 0xC0) == 0xC0) + aqt_codec_clear_anc_tx_hold(aqt); + } + + snd_soc_update_bits(codec, AQT1000_HPH_L_TEST, 0x01, 0x01); + /* Remove Mute on primary path */ + snd_soc_update_bits(codec, AQT1000_CDC_RX1_RX_PATH_CTL, + 0x10, 0x00); + /* Enable GM3 boost */ + snd_soc_update_bits(codec, AQT1000_HPH_CNP_WG_CTL, + 0x80, 0x80); + /* Enable AutoChop timer at the end of power up */ + snd_soc_update_bits(codec, AQT1000_HPH_NEW_INT_HPH_TIMER1, + 0x02, 0x02); + /* Remove mix path mute if it is enabled */ + if ((snd_soc_read(codec, AQT1000_CDC_RX1_RX_PATH_MIX_CTL)) & + 0x10) + snd_soc_update_bits(codec, + AQT1000_CDC_RX1_RX_PATH_MIX_CTL, + 0x10, 0x00); + if (!(strcmp(w->name, "AQT ANC HPHL PA"))) { + dev_dbg(codec->dev, + "%s:Do everything needed for right channel\n", + __func__); + + /* Do everything needed for right channel */ + snd_soc_update_bits(codec, AQT1000_HPH_R_TEST, + 0x01, 0x01); + + /* Remove mute */ + snd_soc_update_bits(codec, AQT1000_CDC_RX2_RX_PATH_CTL, + 0x10, 0x00); + + /* Remove mix path mute if it is enabled */ + if ((snd_soc_read(codec, + AQT1000_CDC_RX2_RX_PATH_MIX_CTL)) & + 0x10) + snd_soc_update_bits(codec, + AQT1000_CDC_RX2_RX_PATH_MIX_CTL, + 0x10, 0x00); + /* Remove ANC Rx from reset */ + ret = aqt_codec_enable_anc(w, kcontrol, event); + } + aqt_codec_override(codec, aqt->hph_mode, event); + break; + case SND_SOC_DAPM_PRE_PMD: + snd_soc_update_bits(codec, AQT1000_HPH_L_TEST, 0x01, 0x00); + snd_soc_update_bits(codec, AQT1000_CDC_RX1_RX_PATH_CTL, + 0x10, 0x10); + snd_soc_update_bits(codec, AQT1000_CDC_RX1_RX_PATH_MIX_CTL, + 0x10, 0x10); + if (!(strcmp(w->name, "AQT ANC HPHL PA"))) + snd_soc_update_bits(codec, AQT1000_ANA_HPH, + 0x80, 0x00); + break; + case SND_SOC_DAPM_POST_PMD: + /* + * 5ms sleep is required after PA disable. If compander is + * disabled, then 20ms delay is needed after PA disable. + */ + if (!aqt->comp_enabled[COMPANDER_1]) + usleep_range(20000, 20100); + else + usleep_range(5000, 5100); + aqt_codec_override(codec, aqt->hph_mode, event); + if (!(strcmp(w->name, "AQT ANC HPHL PA"))) { + ret = aqt_codec_enable_anc(w, kcontrol, event); + snd_soc_update_bits(codec, + AQT1000_CDC_RX1_RX_PATH_CFG0, 0x10, 0x00); + } + break; + }; + + return ret; +} + +static int aqt_codec_set_iir_gain(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + dev_dbg(codec->dev, "%s: event = %d\n", __func__, event); + + switch (event) { + case SND_SOC_DAPM_POST_PMU: /* fall through */ + case SND_SOC_DAPM_PRE_PMD: + if (strnstr(w->name, "AQT IIR0", sizeof("AQT IIR0"))) { + snd_soc_write(codec, + AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL, + snd_soc_read(codec, + AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL)); + snd_soc_write(codec, + AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL, + snd_soc_read(codec, + AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL)); + snd_soc_write(codec, + AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL, + snd_soc_read(codec, + AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL)); + snd_soc_write(codec, + AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL, + snd_soc_read(codec, + AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL)); + } + break; + } + return 0; +} + +static int aqt_enable_native_supply(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (++aqt->native_clk_users == 1) { + snd_soc_update_bits(codec, AQT1000_CLK_SYS_PLL_ENABLES, + 0x01, 0x01); + /* 100usec is needed as per HW requirement */ + usleep_range(100, 120); + snd_soc_update_bits(codec, + AQT1000_CDC_CLK_RST_CTRL_MCLK_CONTROL, + 0x02, 0x02); + snd_soc_update_bits(codec, + AQT1000_CDC_CLK_RST_CTRL_FS_CNT_CONTROL, + 0x10, 0x10); + } + break; + case SND_SOC_DAPM_PRE_PMD: + if (aqt->native_clk_users && + (--aqt->native_clk_users == 0)) { + snd_soc_update_bits(codec, + AQT1000_CDC_CLK_RST_CTRL_FS_CNT_CONTROL, + 0x10, 0x00); + snd_soc_update_bits(codec, + AQT1000_CDC_CLK_RST_CTRL_MCLK_CONTROL, + 0x02, 0x00); + snd_soc_update_bits(codec, AQT1000_CLK_SYS_PLL_ENABLES, + 0x01, 0x00); + } + break; + } + + dev_dbg(codec->dev, "%s: native_clk_users: %d, event: %d\n", + __func__, aqt->native_clk_users, event); + + return 0; +} + +static const char * const native_mux_text[] = { + "OFF", "ON", +}; + +AQT_DAPM_ENUM(int1_1_native, SND_SOC_NOPM, 0, native_mux_text); +AQT_DAPM_ENUM(int2_1_native, SND_SOC_NOPM, 0, native_mux_text); + +static int aif_cap_mixer_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + return 0; +} + +static int aif_cap_mixer_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + return 0; +} + +static const struct snd_kcontrol_new aif1_cap_mixer[] = { + SOC_SINGLE_EXT("TX0", SND_SOC_NOPM, AQT_TX0, 1, 0, + aif_cap_mixer_get, aif_cap_mixer_put), + SOC_SINGLE_EXT("TX1", SND_SOC_NOPM, AQT_TX1, 1, 0, + aif_cap_mixer_get, aif_cap_mixer_put), +}; + +static const struct snd_soc_dapm_widget aqt_dapm_widgets[] = { + + SND_SOC_DAPM_AIF_OUT_E("AQT AIF1 CAP", "AQT AIF1 Capture", 0, + SND_SOC_NOPM, AIF1_CAP, 0, aqt_codec_enable_i2s_tx, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MIXER("AQT AIF1 CAP Mixer", SND_SOC_NOPM, AIF1_CAP, 0, + aif1_cap_mixer, ARRAY_SIZE(aif1_cap_mixer)), + + AQT_DAPM_MUX("AQT TX0_MUX", 0, tx0), + AQT_DAPM_MUX("AQT TX1_MUX", 0, tx1), + + SND_SOC_DAPM_MUX_E("AQT ADC0 MUX", AQT1000_CDC_TX0_TX_PATH_CTL, 5, 0, + &tx_adc0_mux, aqt_codec_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("AQT ADC1 MUX", AQT1000_CDC_TX1_TX_PATH_CTL, 5, 0, + &tx_adc1_mux, aqt_codec_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("AQT ADC2 MUX", AQT1000_CDC_TX2_TX_PATH_CTL, 5, 0, + &tx_adc2_mux, aqt_codec_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + AQT_DAPM_MUX("AQT AMIC0_MUX", 0, tx_amic0), + AQT_DAPM_MUX("AQT AMIC1_MUX", 0, tx_amic1), + AQT_DAPM_MUX("AQT AMIC2_MUX", 0, tx_amic2), + + SND_SOC_DAPM_ADC_E("AQT ADC_L", NULL, AQT1000_ANA_AMIC1, 7, 0, + aqt_codec_enable_adc, SND_SOC_DAPM_PRE_PMU), + SND_SOC_DAPM_ADC_E("AQT ADC_R", NULL, AQT1000_ANA_AMIC2, 7, 0, + aqt_codec_enable_adc, SND_SOC_DAPM_PRE_PMU), + SND_SOC_DAPM_ADC_E("AQT ADC_V", NULL, AQT1000_ANA_AMIC3, 7, 0, + aqt_codec_enable_adc, SND_SOC_DAPM_PRE_PMU), + + AQT_DAPM_MUX("AQT AMIC10_MUX", 0, tx_amic10), + AQT_DAPM_MUX("AQT AMIC11_MUX", 0, tx_amic11), + AQT_DAPM_MUX("AQT AMIC12_MUX", 0, tx_amic12), + AQT_DAPM_MUX("AQT AMIC13_MUX", 0, tx_amic13), + + SND_SOC_DAPM_SWITCH_E("AQT ANC OUT HPHL Enable", SND_SOC_NOPM, + INTERP_HPHL, 0, &anc_hphl_pa_switch, aqt_anc_out_switch_cb, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_SWITCH_E("AQT ANC OUT HPHR Enable", SND_SOC_NOPM, + INTERP_HPHR, 0, &anc_hphr_pa_switch, aqt_anc_out_switch_cb, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), + + SND_SOC_DAPM_MIXER("AQT RX INT1 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("AQT RX INT2 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), + + AQT_DAPM_MUX("AQT ANC0 FB MUX", 0, anc0_fb), + AQT_DAPM_MUX("AQT ANC1 FB MUX", 0, anc1_fb), + + SND_SOC_DAPM_INPUT("AQT AMIC1"), + SND_SOC_DAPM_INPUT("AQT AMIC2"), + SND_SOC_DAPM_INPUT("AQT AMIC3"), + + SND_SOC_DAPM_MIXER("AQT I2S_L RX", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("AQT I2S_R RX", SND_SOC_NOPM, 0, 0, NULL, 0), + + SND_SOC_DAPM_AIF_IN_E("AQT AIF1 PB", "AQT AIF1 Playback", 0, + SND_SOC_NOPM, AIF1_PB, 0, aqt_codec_enable_i2s_rx, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("AQT RX INT1_1 MUX", SND_SOC_NOPM, INTERP_HPHL, 0, + &rx_int1_1_mux, aqt_codec_enable_main_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("AQT RX INT2_1 MUX", SND_SOC_NOPM, INTERP_HPHR, 0, + &rx_int2_1_mux, aqt_codec_enable_main_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("AQT RX INT1_2 MUX", SND_SOC_NOPM, INTERP_HPHL, 0, + &rx_int1_2_mux, aqt_codec_enable_mix_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("AQT RX INT2_2 MUX", SND_SOC_NOPM, INTERP_HPHR, 0, + &rx_int2_2_mux, aqt_codec_enable_mix_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + + AQT_DAPM_MUX("AQT RX INT1_1 INTERP", 0, rx_int1_1_interp), + AQT_DAPM_MUX("AQT RX INT1_2 INTERP", 0, rx_int1_2_interp), + AQT_DAPM_MUX("AQT RX INT2_1 INTERP", 0, rx_int2_1_interp), + AQT_DAPM_MUX("AQT RX INT2_2 INTERP", 0, rx_int2_2_interp), + + SND_SOC_DAPM_MIXER("AQT RX INT1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("AQT RX INT2 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), + + SND_SOC_DAPM_MUX_E("AQT ASRC0 MUX", SND_SOC_NOPM, ASRC0, 0, + &asrc0_mux, aqt_codec_enable_asrc_resampler, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("AQT ASRC1 MUX", SND_SOC_NOPM, ASRC1, 0, + &asrc1_mux, aqt_codec_enable_asrc_resampler, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + AQT_DAPM_MUX("AQT RX INT1 DEM MUX", 0, rx_int1_dem), + AQT_DAPM_MUX("AQT RX INT2 DEM MUX", 0, rx_int2_dem), + + SND_SOC_DAPM_DAC_E("AQT RX INT1 DAC", NULL, AQT1000_ANA_HPH, + 5, 0, aqt_codec_hphl_dac_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_DAC_E("AQT RX INT2 DAC", NULL, AQT1000_ANA_HPH, + 4, 0, aqt_codec_hphr_dac_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_PGA_E("AQT HPHL PA", AQT1000_ANA_HPH, 7, 0, NULL, 0, + aqt_codec_enable_hphl_pa, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA_E("AQT HPHR PA", AQT1000_ANA_HPH, 6, 0, NULL, 0, + aqt_codec_enable_hphr_pa, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA_E("AQT ANC HPHL PA", SND_SOC_NOPM, 0, 0, NULL, 0, + aqt_codec_enable_hphl_pa, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA_E("AQT ANC HPHR PA", SND_SOC_NOPM, 0, 0, NULL, 0, + aqt_codec_enable_hphr_pa, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_OUTPUT("AQT HPHL"), + SND_SOC_DAPM_OUTPUT("AQT HPHR"), + SND_SOC_DAPM_OUTPUT("AQT ANC HPHL"), + SND_SOC_DAPM_OUTPUT("AQT ANC HPHR"), + + SND_SOC_DAPM_MIXER_E("AQT IIR0", AQT1000_CDC_SIDETONE_IIR0_IIR_PATH_CTL, + 4, 0, NULL, 0, aqt_codec_set_iir_gain, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + + SND_SOC_DAPM_MIXER("AQT SRC0", + AQT1000_CDC_SIDETONE_SRC0_ST_SRC_PATH_CTL, + 4, 0, NULL, 0), + + SND_SOC_DAPM_MICBIAS_E("AQT MIC BIAS1", SND_SOC_NOPM, 0, 0, + aqt_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY("AQT RX_BIAS", SND_SOC_NOPM, 0, 0, + aqt_codec_enable_rx_bias, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY("AQT RX INT1 NATIVE SUPPLY", SND_SOC_NOPM, + INTERP_HPHL, 0, aqt_enable_native_supply, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_SUPPLY("AQT RX INT2 NATIVE SUPPLY", SND_SOC_NOPM, + INTERP_HPHR, 0, aqt_enable_native_supply, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), + + AQT_DAPM_MUX("AQT RX INT1_1 NATIVE MUX", 0, int1_1_native), + AQT_DAPM_MUX("AQT RX INT2_1 NATIVE MUX", 0, int2_1_native), +}; + +static int aqt_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + pr_debug("%s(): substream = %s stream = %d\n", __func__, + substream->name, substream->stream); + + return 0; +} + +static void aqt_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + pr_debug("%s(): substream = %s stream = %d\n", __func__, + substream->name, substream->stream); +} + +static int aqt_set_decimator_rate(struct snd_soc_dai *dai, + u32 sample_rate) +{ + struct snd_soc_codec *codec = dai->codec; + u8 tx_fs_rate = 0; + u8 tx_mux_sel = 0, tx0_mux_sel = 0, tx1_mux_sel = 0; + u16 tx_path_ctl_reg = 0; + + switch (sample_rate) { + case 8000: + tx_fs_rate = 0; + break; + case 16000: + tx_fs_rate = 1; + break; + case 32000: + tx_fs_rate = 3; + break; + case 48000: + tx_fs_rate = 4; + break; + case 96000: + tx_fs_rate = 5; + break; + case 192000: + tx_fs_rate = 6; + break; + default: + dev_err(codec->dev, "%s: Invalid TX sample rate: %d\n", + __func__, sample_rate); + return -EINVAL; + + }; + + /* Find which decimator path is enabled */ + tx_mux_sel = snd_soc_read(codec, AQT1000_CDC_IF_ROUTER_TX_MUX_CFG0); + tx0_mux_sel = (tx_mux_sel & 0x03); + tx1_mux_sel = (tx_mux_sel & 0xC0); + + if (tx0_mux_sel) { + tx_path_ctl_reg = AQT1000_CDC_TX0_TX_PATH_CTL + + ((tx0_mux_sel - 1) * 16); + snd_soc_update_bits(codec, tx_path_ctl_reg, 0x0F, tx_fs_rate); + } + + if (tx1_mux_sel) { + tx_path_ctl_reg = AQT1000_CDC_TX0_TX_PATH_CTL + + ((tx1_mux_sel - 1) * 16); + snd_soc_update_bits(codec, tx_path_ctl_reg, 0x0F, tx_fs_rate); + } + + return 0; +} + +static int aqt_set_interpolator_rate(struct snd_soc_dai *dai, + u32 sample_rate) +{ + struct snd_soc_codec *codec = dai->codec; + int rate_val = 0; + int i; + + for (i = 0; i < ARRAY_SIZE(sr_val_tbl); i++) { + if (sample_rate == sr_val_tbl[i].sample_rate) { + rate_val = sr_val_tbl[i].rate_val; + break; + } + } + if ((i == ARRAY_SIZE(sr_val_tbl)) || (rate_val < 0)) { + dev_err(codec->dev, "%s: Unsupported sample rate: %d\n", + __func__, sample_rate); + return -EINVAL; + } + + /* TODO - Set the rate only to enabled path */ + /* Set Primary interpolator rate */ + snd_soc_update_bits(codec, AQT1000_CDC_RX1_RX_PATH_CTL, + 0x0F, (u8)rate_val); + snd_soc_update_bits(codec, AQT1000_CDC_RX2_RX_PATH_CTL, + 0x0F, (u8)rate_val); + + /* Set mixing path interpolator rate */ + snd_soc_update_bits(codec, AQT1000_CDC_RX1_RX_PATH_MIX_CTL, + 0x0F, (u8)rate_val); + snd_soc_update_bits(codec, AQT1000_CDC_RX2_RX_PATH_MIX_CTL, + 0x0F, (u8)rate_val); + + return 0; +} + +static int aqt_prepare(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + pr_debug("%s(): substream = %s stream = %d\n", __func__, + substream->name, substream->stream); + return 0; +} + +static int aqt_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(dai->codec); + int ret = 0; + + dev_dbg(aqt->dev, "%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", + __func__, dai->name, dai->id, params_rate(params), + params_channels(params)); + + switch (substream->stream) { + case SNDRV_PCM_STREAM_PLAYBACK: + ret = aqt_set_interpolator_rate(dai, params_rate(params)); + if (ret) { + dev_err(aqt->dev, "%s: cannot set sample rate: %u\n", + __func__, params_rate(params)); + return ret; + } + switch (params_width(params)) { + case 16: + aqt->dai[dai->id].bit_width = 16; + break; + case 24: + aqt->dai[dai->id].bit_width = 24; + break; + case 32: + aqt->dai[dai->id].bit_width = 32; + break; + default: + return -EINVAL; + } + aqt->dai[dai->id].rate = params_rate(params); + break; + case SNDRV_PCM_STREAM_CAPTURE: + ret = aqt_set_decimator_rate(dai, params_rate(params)); + if (ret) { + dev_err(aqt->dev, + "%s: cannot set TX Decimator rate: %d\n", + __func__, ret); + return ret; + } + switch (params_width(params)) { + case 16: + aqt->dai[dai->id].bit_width = 16; + break; + case 24: + aqt->dai[dai->id].bit_width = 24; + break; + default: + dev_err(aqt->dev, "%s: Invalid format 0x%x\n", + __func__, params_width(params)); + return -EINVAL; + }; + aqt->dai[dai->id].rate = params_rate(params); + break; + default: + dev_err(aqt->dev, "%s: Invalid stream type %d\n", __func__, + substream->stream); + return -EINVAL; + }; + + return 0; +} + +static struct snd_soc_dai_ops aqt_dai_ops = { + .startup = aqt_startup, + .shutdown = aqt_shutdown, + .hw_params = aqt_hw_params, + .prepare = aqt_prepare, +}; + +struct snd_soc_dai_driver aqt_dai[] = { + { + .name = "aqt_rx1", + .id = AIF1_PB, + .playback = { + .stream_name = "AQT AIF1 Playback", + .rates = AQT1000_RATES_MASK | AQT1000_FRAC_RATES_MASK, + .formats = AQT1000_FORMATS_S16_S24_S32_LE, + .rate_min = 8000, + .rate_max = 384000, + .channels_min = 1, + .channels_max = 2, + }, + .ops = &aqt_dai_ops, + }, + { + .name = "aqt_tx1", + .id = AIF1_CAP, + .capture = { + .stream_name = "AQT AIF1 Capture", + .rates = AQT1000_RATES_MASK, + .formats = AQT1000_FORMATS_S16_S24_LE, + .rate_min = 8000, + .rate_max = 192000, + .channels_min = 1, + .channels_max = 2, + }, + .ops = &aqt_dai_ops, + }, +}; + +static int aqt_enable_mclk(struct aqt1000 *aqt) +{ + struct snd_soc_codec *codec = aqt->codec; + + /* Enable mclk requires master bias to be enabled first */ + if (aqt->master_bias_users <= 0) { + dev_err(aqt->dev, + "%s: Cannot turn on MCLK, BG is not enabled\n", + __func__); + return -EINVAL; + } + + if (++aqt->mclk_users == 1) { + /* Set clock div 2 */ + snd_soc_update_bits(codec, + AQT1000_CLK_SYS_MCLK1_PRG, 0x0C, 0x04); + snd_soc_update_bits(codec, + AQT1000_CLK_SYS_MCLK1_PRG, 0x10, 0x10); + snd_soc_update_bits(codec, + AQT1000_CDC_CLK_RST_CTRL_FS_CNT_CONTROL, + 0x01, 0x01); + snd_soc_update_bits(codec, + AQT1000_CDC_CLK_RST_CTRL_MCLK_CONTROL, + 0x01, 0x01); + /* + * 10us sleep is required after clock is enabled + * as per HW requirement + */ + usleep_range(10, 15); + } + + dev_dbg(aqt->dev, "%s: mclk_users: %d\n", __func__, aqt->mclk_users); + + return 0; +} + +static int aqt_disable_mclk(struct aqt1000 *aqt) +{ + struct snd_soc_codec *codec = aqt->codec; + + if (aqt->mclk_users <= 0) { + dev_err(aqt->dev, "%s: No mclk users, cannot disable mclk\n", + __func__); + return -EINVAL; + } + + if (--aqt->mclk_users == 0) { + snd_soc_update_bits(codec, + AQT1000_CDC_CLK_RST_CTRL_MCLK_CONTROL, + 0x01, 0x00); + snd_soc_update_bits(codec, + AQT1000_CDC_CLK_RST_CTRL_FS_CNT_CONTROL, + 0x01, 0x00); + snd_soc_update_bits(codec, + AQT1000_CLK_SYS_MCLK1_PRG, 0x10, 0x00); + } + + dev_dbg(codec->dev, "%s: mclk_users: %d\n", __func__, aqt->mclk_users); + + return 0; +} + +static int aqt_enable_master_bias(struct aqt1000 *aqt) +{ + struct snd_soc_codec *codec = aqt->codec; + + mutex_lock(&aqt->master_bias_lock); + + aqt->master_bias_users++; + if (aqt->master_bias_users == 1) { + snd_soc_update_bits(codec, AQT1000_ANA_BIAS, 0x80, 0x80); + snd_soc_update_bits(codec, AQT1000_ANA_BIAS, 0x40, 0x40); + /* + * 1ms delay is required after pre-charge is enabled + * as per HW requirement + */ + usleep_range(1000, 1100); + snd_soc_update_bits(codec, AQT1000_ANA_BIAS, 0x40, 0x00); + } + + mutex_unlock(&aqt->master_bias_lock); + + return 0; +} + +static int aqt_disable_master_bias(struct aqt1000 *aqt) +{ + struct snd_soc_codec *codec = aqt->codec; + + mutex_lock(&aqt->master_bias_lock); + if (aqt->master_bias_users <= 0) { + mutex_unlock(&aqt->master_bias_lock); + return -EINVAL; + } + + aqt->master_bias_users--; + if (aqt->master_bias_users == 0) + snd_soc_update_bits(codec, AQT1000_ANA_BIAS, 0x80, 0x00); + mutex_unlock(&aqt->master_bias_lock); + + return 0; +} + +static int aqt_cdc_req_mclk_enable(struct aqt1000 *aqt, + bool enable) +{ + int ret = 0; + + if (enable) { + ret = clk_prepare_enable(aqt->ext_clk); + if (ret) { + dev_err(aqt->dev, "%s: ext clk enable failed\n", + __func__); + goto done; + } + /* Get BG */ + aqt_enable_master_bias(aqt); + /* Get MCLK */ + aqt_enable_mclk(aqt); + } else { + /* put MCLK */ + aqt_disable_mclk(aqt); + /* put BG */ + if (aqt_disable_master_bias(aqt)) + dev_err(aqt->dev, "%s: master bias disable failed\n", + __func__); + clk_disable_unprepare(aqt->ext_clk); + } + +done: + return ret; +} + +static int __aqt_cdc_mclk_enable_locked(struct aqt1000 *aqt, + bool enable) +{ + int ret = 0; + + dev_dbg(aqt->dev, "%s: mclk_enable = %u\n", __func__, enable); + + if (enable) + ret = aqt_cdc_req_mclk_enable(aqt, true); + else + aqt_cdc_req_mclk_enable(aqt, false); + + return ret; +} + +static int __aqt_cdc_mclk_enable(struct aqt1000 *aqt, + bool enable) +{ + int ret; + + mutex_lock(&aqt->cdc_bg_clk_lock); + ret = __aqt_cdc_mclk_enable_locked(aqt, enable); + mutex_unlock(&aqt->cdc_bg_clk_lock); + + return ret; +} + +/** + * aqt_cdc_mclk_enable - Enable/disable codec mclk + * + * @codec: codec instance + * @enable: Indicates clk enable or disable + * + * Returns 0 on Success and error on failure + */ +int aqt_cdc_mclk_enable(struct snd_soc_codec *codec, bool enable) +{ + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + + return __aqt_cdc_mclk_enable(aqt, enable); +} +EXPORT_SYMBOL(aqt_cdc_mclk_enable); + +/* + * aqt_get_micb_vout_ctl_val: converts micbias from volts to register value + * @micb_mv: micbias in mv + * + * return register value converted + */ +int aqt_get_micb_vout_ctl_val(u32 micb_mv) +{ + /* min micbias voltage is 1V and maximum is 2.85V */ + if (micb_mv < 1000 || micb_mv > 2850) { + pr_err("%s: unsupported micbias voltage\n", __func__); + return -EINVAL; + } + + return (micb_mv - 1000) / 50; +} +EXPORT_SYMBOL(aqt_get_micb_vout_ctl_val); + +static int aqt_set_micbias(struct aqt1000 *aqt, + struct aqt1000_pdata *pdata) +{ + struct snd_soc_codec *codec = aqt->codec; + int vout_ctl_1; + + if (!pdata) { + dev_err(codec->dev, "%s: NULL pdata\n", __func__); + return -ENODEV; + } + + /* set micbias voltage */ + vout_ctl_1 = aqt_get_micb_vout_ctl_val(pdata->micbias.micb1_mv); + if (vout_ctl_1 < 0) + return -EINVAL; + + snd_soc_update_bits(codec, AQT1000_ANA_MICB1, 0x3F, vout_ctl_1); + + return 0; +} + +static const struct aqt_reg_mask_val aqt_codec_reg_init[] = { + {AQT1000_CHIP_CFG0_CLK_CFG_MCLK, 0x04, 0x00}, + {AQT1000_CHIP_CFG0_EFUSE_CTL, 0x01, 0x01}, +}; + +static const struct aqt_reg_mask_val aqt_codec_reg_update[] = { + {AQT1000_CDC_CLK_RST_CTRL_MCLK_CONTROL, 0x01, 0x01}, + {AQT1000_CDC_CLK_RST_CTRL_FS_CNT_CONTROL, 0x01, 0x01}, + {AQT1000_CHIP_CFG0_CLK_CTL_CDC_DIG, 0x01, 0x01}, + {AQT1000_LDOH_MODE, 0x1F, 0x0B}, + {AQT1000_MICB1_TEST_CTL_2, 0x07, 0x01}, + {AQT1000_MICB1_MISC_MICB1_INM_RES_BIAS, 0x03, 0x02}, + {AQT1000_MICB1_MISC_MICB1_INM_RES_BIAS, 0x0C, 0x08}, + {AQT1000_MICB1_MISC_MICB1_INM_RES_BIAS, 0x30, 0x20}, + {AQT1000_CDC_TX0_TX_PATH_CFG1, 0x01, 0x00}, + {AQT1000_CDC_TX1_TX_PATH_CFG1, 0x01, 0x00}, + {AQT1000_CDC_TX2_TX_PATH_CFG1, 0x01, 0x00}, +}; + +static void aqt_codec_init_reg(struct aqt1000 *priv) +{ + struct snd_soc_codec *codec = priv->codec; + u32 i; + + for (i = 0; i < ARRAY_SIZE(aqt_codec_reg_init); i++) + snd_soc_update_bits(codec, + aqt_codec_reg_init[i].reg, + aqt_codec_reg_init[i].mask, + aqt_codec_reg_init[i].val); +} + +static void aqt_codec_update_reg(struct aqt1000 *priv) +{ + struct snd_soc_codec *codec = priv->codec; + u32 i; + + for (i = 0; i < ARRAY_SIZE(aqt_codec_reg_update); i++) + snd_soc_update_bits(codec, + aqt_codec_reg_update[i].reg, + aqt_codec_reg_update[i].mask, + aqt_codec_reg_update[i].val); + +} + +static int aqt_soc_codec_probe(struct snd_soc_codec *codec) +{ + struct aqt1000 *aqt; + struct aqt1000_pdata *pdata; + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + int i, ret = 0; + + dev_dbg(codec->dev, "%s()\n", __func__); + aqt = snd_soc_codec_get_drvdata(codec); + + mutex_init(&aqt->codec_mutex); + mutex_init(&aqt->i2s_lock); + /* Class-H Init */ + aqt_clsh_init(&aqt->clsh_d); + /* Default HPH Mode to Class-H Low HiFi */ + aqt->hph_mode = CLS_H_LOHIFI; + + aqt->fw_data = devm_kzalloc(codec->dev, sizeof(*(aqt->fw_data)), + GFP_KERNEL); + if (!aqt->fw_data) + goto err; + + set_bit(WCD9XXX_ANC_CAL, aqt->fw_data->cal_bit); + set_bit(WCD9XXX_MBHC_CAL, aqt->fw_data->cal_bit); + + ret = wcd_cal_create_hwdep(aqt->fw_data, + AQT1000_CODEC_HWDEP_NODE, codec); + if (ret < 0) { + dev_err(codec->dev, "%s hwdep failed %d\n", __func__, ret); + goto err_hwdep; + } + + aqt->codec = codec; + for (i = 0; i < COMPANDER_MAX; i++) + aqt->comp_enabled[i] = 0; + + aqt_cdc_mclk_enable(codec, true); + aqt_codec_init_reg(aqt); + aqt_cdc_mclk_enable(codec, false); + + /* Add 100usec delay as per HW requirement */ + usleep_range(100, 110); + + aqt_codec_update_reg(aqt); + + pdata = dev_get_platdata(codec->dev); + + /* If 1.8v is supplied externally, then disable internal 1.8v supply */ + for (i = 0; i < pdata->num_supplies; i++) { + if (!strcmp(pdata->regulator->name, "aqt_vdd1p8")) { + snd_soc_update_bits(codec, AQT1000_BUCK_5V_EN_CTL, + 0x03, 0x00); + dev_dbg(codec->dev, "%s: Disabled internal supply\n", + __func__); + break; + } + } + + aqt_set_micbias(aqt, pdata); + + snd_soc_dapm_add_routes(dapm, aqt_audio_map, + ARRAY_SIZE(aqt_audio_map)); + + for (i = 0; i < NUM_CODEC_DAIS; i++) { + INIT_LIST_HEAD(&aqt->dai[i].ch_list); + init_waitqueue_head(&aqt->dai[i].dai_wait); + } + + for (i = 0; i < AQT1000_NUM_DECIMATORS; i++) { + aqt->tx_hpf_work[i].aqt = aqt; + aqt->tx_hpf_work[i].decimator = i; + INIT_DELAYED_WORK(&aqt->tx_hpf_work[i].dwork, + aqt_tx_hpf_corner_freq_callback); + + aqt->tx_mute_dwork[i].aqt = aqt; + aqt->tx_mute_dwork[i].decimator = i; + INIT_DELAYED_WORK(&aqt->tx_mute_dwork[i].dwork, + aqt_tx_mute_update_callback); + } + + mutex_lock(&aqt->codec_mutex); + snd_soc_dapm_disable_pin(dapm, "AQT ANC HPHL PA"); + snd_soc_dapm_disable_pin(dapm, "AQT ANC HPHR PA"); + snd_soc_dapm_disable_pin(dapm, "AQT ANC HPHL"); + snd_soc_dapm_disable_pin(dapm, "AQT ANC HPHR"); + mutex_unlock(&aqt->codec_mutex); + + snd_soc_dapm_ignore_suspend(dapm, "AQT AIF1 Playback"); + snd_soc_dapm_ignore_suspend(dapm, "AQT AIF1 Capture"); + + snd_soc_dapm_sync(dapm); + + return ret; + +err_hwdep: + devm_kfree(codec->dev, aqt->fw_data); + aqt->fw_data = NULL; +err: + mutex_destroy(&aqt->i2s_lock); + mutex_destroy(&aqt->codec_mutex); + return ret; +} + +static int aqt_soc_codec_remove(struct snd_soc_codec *codec) +{ + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + + mutex_destroy(&aqt->i2s_lock); + mutex_destroy(&aqt->codec_mutex); + + return 0; +} + +static struct regmap *aqt_get_regmap(struct device *dev) +{ + struct aqt1000 *control = dev_get_drvdata(dev); + + return control->regmap; +} + +struct snd_soc_codec_driver snd_cdc_dev_aqt = { + .probe = aqt_soc_codec_probe, + .remove = aqt_soc_codec_remove, + .get_regmap = aqt_get_regmap, + .component_driver = { + .controls = aqt_snd_controls, + .num_controls = ARRAY_SIZE(aqt_snd_controls), + .dapm_widgets = aqt_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(aqt_dapm_widgets), + .dapm_routes = aqt_audio_map, + .num_dapm_routes = ARRAY_SIZE(aqt_audio_map), + }, +}; + +/* + * aqt_register_codec: Register the device to ASoC + * @dev: device + * + * return 0 success or error code in case of failure + */ +int aqt_register_codec(struct device *dev) +{ + return snd_soc_register_codec(dev, &snd_cdc_dev_aqt, aqt_dai, + ARRAY_SIZE(aqt_dai)); +} +EXPORT_SYMBOL(aqt_register_codec); diff --git a/asoc/codecs/aqt1000/aqt1000.h b/asoc/codecs/aqt1000/aqt1000.h new file mode 100644 index 0000000000..4267e6f552 --- /dev/null +++ b/asoc/codecs/aqt1000/aqt1000.h @@ -0,0 +1,225 @@ +/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef AQT1000_H +#define AQT1000_H + +#include +#include +#include +#include +#include "pdata.h" +#include "aqt1000-clsh.h" + +#define AQT1000_MAX_MICBIAS 1 +#define AQT1000_NUM_INTERPOLATORS 2 +#define AQT1000_NUM_DECIMATORS 3 +#define AQT1000_VOUT_CTL_TO_MICB(v) (1000 + v * 50) +#define AQT1000_RX_PATH_CTL_OFFSET 20 + +#define AQT1000_CLK_24P576MHZ 24576000 +#define AQT1000_CLK_19P2MHZ 19200000 +#define AQT1000_CLK_12P288MHZ 12288000 +#define AQT1000_CLK_9P6MHZ 9600000 + +#define AQT1000_ST_IIR_COEFF_MAX 5 + +enum { + AQT1000_RX0 = 0, + AQT1000_RX1, + AQT1000_RX_MAX, +}; + +enum { + AQT_NONE, + AQT_MCLK, + AQT_RCO, +}; + +enum { + AQT_TX0 = 0, + AQT_TX1, +}; + +enum { + ASRC0, + ASRC1, + ASRC_MAX, +}; + +/* Each IIR has 5 Filter Stages */ +enum { + BAND1 = 0, + BAND2, + BAND3, + BAND4, + BAND5, + BAND_MAX, +}; + +enum { + AQT1000_TX0 = 0, + AQT1000_TX1, + AQT1000_TX2, + AQT1000_TX_MAX, +}; + +enum { + INTERP_HPHL, + INTERP_HPHR, + INTERP_MAX, +}; + +enum { + INTERP_MAIN_PATH, + INTERP_MIX_PATH, +}; + +enum { + COMPANDER_1, /* HPH_L */ + COMPANDER_2, /* HPH_R */ + COMPANDER_MAX, +}; + +enum { + AIF1_PB = 0, + AIF1_CAP, + NUM_CODEC_DAIS, +}; + +struct aqt_codec_dai_data { + u32 rate; + u32 *ch_num; + u32 ch_act; + u32 ch_tot; +}; + +struct aqt_idle_detect_config { + u8 hph_idle_thr; + u8 hph_idle_detect_en; +}; + +struct aqt1000_i2c { + struct i2c_client *client; + struct i2c_msg xfer_msg[2]; + struct mutex xfer_lock; + int mod_id; +}; + +struct aqt1000_cdc_dai_data { + u32 rate; /* sample rate */ + u32 bit_width; /* sit width 16,24,32 */ + struct list_head ch_list; + wait_queue_head_t dai_wait; +}; + +struct tx_mute_work { + struct aqt1000 *aqt; + u8 decimator; + struct delayed_work dwork; +}; + +struct hpf_work { + struct aqt1000 *aqt; + u8 decimator; + u8 hpf_cut_off_freq; + struct delayed_work dwork; +}; + +struct aqt1000 { + struct device *dev; + struct mutex io_lock; + struct mutex xfer_lock; + struct mutex reset_lock; + + struct device_node *aqt_rst_np; + + int (*read_dev)(struct aqt1000 *aqt, unsigned short reg, + void *dest, int bytes); + int (*write_dev)(struct aqt1000 *aqt, unsigned short reg, + void *src, int bytes); + + u32 num_of_supplies; + struct regulator_bulk_data *supplies; + + u32 mclk_rate; + struct regmap *regmap; + struct snd_soc_codec *codec; + bool dev_up; + bool prev_pg_valid; + u8 prev_pg; + + struct aqt1000_i2c i2c_dev; + + /* Codec params */ + + /* ANC related */ + u32 anc_slot; + bool anc_func; + + /* compander */ + int comp_enabled[COMPANDER_MAX]; + + /* class h specific data */ + struct aqt_clsh_cdc_data clsh_d; + + /* Interpolator Mode Select for HPH_L and HPH_R */ + u32 hph_mode; + + unsigned long status_mask; + + struct aqt1000_cdc_dai_data dai[NUM_CODEC_DAIS]; + + struct mutex micb_lock; + + struct clk *ext_clk; + + /* mbhc module */ + struct aqt1000_mbhc *mbhc; + + struct mutex codec_mutex; + + /* cal info for codec */ + struct fw_info *fw_data; + + int native_clk_users; + /* ASRC users count */ + int asrc_users[ASRC_MAX]; + int asrc_output_mode[ASRC_MAX]; + /* Main path clock users count */ + int main_clk_users[AQT1000_NUM_INTERPOLATORS]; + + struct aqt_idle_detect_config idle_det_cfg; + u32 rx_bias_count; + + s32 micb_ref; + s32 pullup_ref; + int master_bias_users; + int mclk_users; + int i2s_users; + + struct hpf_work tx_hpf_work[AQT1000_NUM_DECIMATORS]; + struct tx_mute_work tx_mute_dwork[AQT1000_NUM_DECIMATORS]; + + struct mutex master_bias_lock; + struct mutex cdc_bg_clk_lock; + struct mutex i2s_lock; + + /* Interrupt */ + struct regmap_irq_chip_data *irq_chip; + int num_irq_regs; + struct irq_domain *virq; + int irq; + int irq_base; +}; + +#endif /* AQT1000_H */ diff --git a/asoc/codecs/aqt1000/pdata.h b/asoc/codecs/aqt1000/pdata.h new file mode 100644 index 0000000000..2c29848d79 --- /dev/null +++ b/asoc/codecs/aqt1000/pdata.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _AQT1000_PDATA_H_ +#define _AQT1000_PDATA_H_ + +#include +#include +#include "../msm-cdc-supply.h" + +struct aqt1000_micbias_setting { + u8 ldoh_v; + u32 cfilt1_mv; + u32 micb1_mv; + u8 bias1_cfilt_sel; +}; + +struct aqt1000_pdata { + unsigned int irq_gpio; + unsigned int irq_flags; + struct cdc_regulator *regulator; + int num_supplies; + struct aqt1000_micbias_setting micbias; + struct device_node *aqt_rst_np; + u32 mclk_rate; + u32 ext_clk_rate; + u32 ext_1p8v_supply; +}; + +#endif /* _AQT1000_PDATA_H_ */