From ec950eb97e38dcc7ed23083009996ce841c12c17 Mon Sep 17 00:00:00 2001 From: Shunhua Lan Date: Wed, 10 Jul 2024 12:16:14 +0800 Subject: [PATCH] ASoC: codecs: rk730: fixed and update something for driver This version has made a lot of updates to the rk730 codec driver. Including: - Fixed dapm routing path and definition description - The capturing and playbacking functions work normally - Corrected the final description of registers according to the manual Aims to make the rk730 codec driver more convenient and easy to use on general platforms. Signed-off-by: Shunhua Lan Change-Id: Ia9fb477681433dc5ec5e2ca8c6b526a9dc1d5cb2 --- sound/soc/codecs/rk730.c | 1227 ++++++++++++++++++++------------------ sound/soc/codecs/rk730.h | 346 +++++++---- 2 files changed, 886 insertions(+), 687 deletions(-) diff --git a/sound/soc/codecs/rk730.c b/sound/soc/codecs/rk730.c index 3c24ec136716..d36ab6fd7b57 100644 --- a/sound/soc/codecs/rk730.c +++ b/sound/soc/codecs/rk730.c @@ -19,9 +19,24 @@ #include #include #include - #include "rk730.h" +/* Output diagram + * FOR current evb, LOUT2 to speaker and LOUT2 to headphone + * DAC0(DAC_L_N/DAC_R_N)->HP_0 -> LOUT2 + * DAC1(DAC_L_P/DAC_R_P)->SP_0 -> LOUT1 + * + * FOR HP differential mode + *- DAC_L_N(DAC0) -> HP Driver -> LOUT2 ---------- + *- DAC_R_N(DAC0) -> HP Driver -> ROUT2 ---- | + * | | + * | R + * R | + * | | + *- DAC_L_P(DAC1) -> SPK Driver -> LOUT1 ---|----- + *- DAC_R_P(DAC1) -> SPK Driver -> ROUT1 --- + */ + enum rk730_mix_mode { RK730_MIX_MODE_1_PATH, RK730_MIX_MODE_2_PATHS, @@ -42,565 +57,554 @@ struct rk730_priv { }; /* ADC Digital Volume */ -static const DECLARE_TLV_DB_SCALE(adc_dig_tlv, -95625, 375, 0); +static const DECLARE_TLV_DB_MINMAX(adc_dig_tlv, -9600, 0); /* DAC Digital Volume */ -static const DECLARE_TLV_DB_SCALE(dac_dig_tlv, -95625, 375, 0); -/* D2S Volume */ -static const DECLARE_TLV_DB_SCALE(d2s_tlv, -1800, 300, 0); +static const DECLARE_TLV_DB_MINMAX(dac_dig_tlv, -9600, 0); /* ADC Volume */ -static const DECLARE_TLV_DB_SCALE(adc_tlv, -1200, 300, 0); -/* MUX Volume */ -static const DECLARE_TLV_DB_SCALE(mux_tlv, -600, 600, 0); -/* MIX Buf Volume */ -static const DECLARE_TLV_DB_SCALE(mix_buf_tlv, -1800, 300, 0); -/* HP Volume */ -static const DECLARE_TLV_DB_SCALE(hp_tlv, 0, 300, 0); -/* LINEOUT Volume */ -static const DECLARE_TLV_DB_SCALE(lineout_tlv, 0, 300, 0); +static const DECLARE_TLV_DB_MINMAX(adc_tlv, -1050, 0); /* MIC Boost Volume */ static const DECLARE_TLV_DB_RANGE(micboost_tlv, 0, 2, TLV_DB_SCALE_ITEM(0, 600, 0), 3, 4, TLV_DB_SCALE_ITEM(2400, 1200, 0), 5, 7, TLV_DB_SCALE_ITEM(4200, 600, 0), - 8, 8, TLV_DB_SCALE_ITEM(-300, 0, 0), - 16, 16, TLV_DB_SCALE_ITEM(-600, 0, 0), - 24, 24, TLV_DB_SCALE_ITEM(-900, 0, 0) ); -static const char * const mux_out_l_text[] = { "DIFF", "MIC1N", "MIC2N" }; -static const char * const mux_out_r_text[] = { "DIFF", "MIC2P", "MIC1P" }; -static const char * const mux_input_l_text[] = { "DIFF", "VINP1", "VINN1" }; -static const char * const mux_input_r_text[] = { "DIFF", "VINP2", "VINN2" }; +static const DECLARE_TLV_DB_SCALE(micdecrease_tlv, 0, -300, 0); -static SOC_ENUM_SINGLE_DECL(mux_out_l_enum, RK730_MUXER_0, 2, mux_out_l_text); -static SOC_ENUM_SINGLE_DECL(mux_out_r_enum, RK730_MUXER_0, 6, mux_out_r_text); +static const char * const mux_input_l_text[] = { "DIFF", "VINR2", "VINL2" }; +static const char * const mux_input_r_text[] = { "DIFF", "VINR1", "VINL1" }; static SOC_ENUM_SINGLE_DECL(mux_input_l_enum, RK730_ADC_PGA_BLOCK_0, 4, mux_input_l_text); static SOC_ENUM_SINGLE_DECL(mux_input_r_enum, RK730_ADC_PGA_BLOCK_1, 4, mux_input_r_text); - -static const struct snd_kcontrol_new mux_out_l = - SOC_DAPM_ENUM("Left Out Mux", mux_out_l_enum); -static const struct snd_kcontrol_new mux_out_r = - SOC_DAPM_ENUM("Right Out Mux", mux_out_r_enum); static const struct snd_kcontrol_new mux_input_l = SOC_DAPM_ENUM("Left Input Mux", mux_input_l_enum); static const struct snd_kcontrol_new mux_input_r = SOC_DAPM_ENUM("Right Input Mux", mux_input_r_enum); -static const struct snd_kcontrol_new mix_ctls[] = { - SOC_DAPM_SINGLE("Left Out Mux Switch", RK730_MUXER_0, 0, 1, 1), - SOC_DAPM_SINGLE("Right Out Mux Switch", RK730_MUXER_0, 4, 1, 1), -}; +static const char * const adc_data_sel_text[] = { "normal", "left", "right", "swap" }; -static const char * const adc_hpf_cutoff_text[] = { - "3.79Hz", "60Hz", "243Hz", "493Hz", -}; - -static const char * const dac_hpf_cutoff_text[] = { - "80Hz", "100Hz", "120Hz", "140Hz", -}; - -static SOC_ENUM_SINGLE_DECL(adc_hpf_cutoff_enum, RK730_DADC_HPF, - 4, adc_hpf_cutoff_text); -static SOC_ENUM_SINGLE_DECL(dac_hpf_cutoff_enum, RK730_DDAC_MUTE_MIXCTL, - 5, dac_hpf_cutoff_text); +static SOC_ENUM_SINGLE_DECL(adc_data_sel_enum, RK730_DADC_SEL, + 0, adc_data_sel_text); +static const struct snd_kcontrol_new adc_data_sel = + SOC_DAPM_ENUM("ADCSel Mux", adc_data_sel_enum); static const char * const chop_freq_text[] = { "Disabled", "200kHz", "400kHz", "800kHz", }; -static SOC_ENUM_SINGLE_DECL(dac_ref_buf_chop_freq_enum, RK730_HK_TOP_1, - 6, chop_freq_text); +static const char * const hfp_center_freq_text[] = { + "80HZ", "100HZ", "120HZ", "140HZ", +}; + +static const char * const dac_hfp_center_freq_text[] = { + "C*0.8", "C*0.9", "C*1.0(fs=6.144M)", "C*1.1(fs=5.6448M)", + "C*1.2", "C*1.3", "C*1.4", "C*1.5(fs=4.096M)", +}; + static SOC_ENUM_SINGLE_DECL(mic_chop_freq_enum, RK730_MIC_BOOST_3, 6, chop_freq_text); static SOC_ENUM_SINGLE_DECL(adc_pga_chop_freq_enum, RK730_ADC_PGA_BLOCK_1, 6, chop_freq_text); -static SOC_ENUM_SINGLE_DECL(mux_out_chop_freq_enum, RK730_MUXER_1, - 0, chop_freq_text); -static SOC_ENUM_SINGLE_DECL(mix_chop_freq_enum, RK730_MIXER_2, - 6, chop_freq_text); static SOC_ENUM_SINGLE_DECL(hp_lo_chop_freq_enum, RK730_HP_1, 5, chop_freq_text); +static SOC_ENUM_SINGLE_DECL(dac_hfp_center_freq_enum, RK730_DDAC_FILTER, + 2, hfp_center_freq_text); + +static SOC_ENUM_SINGLE_DECL(adc_capacity_trim_enum, RK730_ADC_2, + 0, dac_hfp_center_freq_text); static const char * const micbias_volt_text[] = { "2.0v", "2.2v", "2.5v", "2.8v", }; -static const char * const charge_pump_volt_text[] = { - "2.1v", "2.3v", "2.5v", "2.7v", -}; - static SOC_ENUM_SINGLE_DECL(micbias_volt_enum, RK730_MIC_BIAS, 2, micbias_volt_text); -static SOC_ENUM_SINGLE_DECL(charge_pump_volt_enum, RK730_CHARGE_PUMP, - 1, charge_pump_volt_text); -static int rk730_adc_vol_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); - struct soc_mixer_control *mc = - (struct soc_mixer_control *)kcontrol->private_value; - unsigned int val = snd_soc_component_read(component, mc->reg); - unsigned int sign = snd_soc_component_read(component, RK730_DADC_SR_ACL); - unsigned int mask = (1 << fls(mc->max)) - 1; - unsigned int shift = mc->shift; - int mid = mc->max / 2; - int uv; +static const char * const dig_ldo_volt_text[] = { + "1.4v", "1.5v", "1.6v", "1.7v", +}; - uv = (val >> shift) & mask; - sign &= RK730_DADC_SR_ACL_VOLL_POL_MASK; - if (sign) - uv = mid + uv; - else - uv = mid - uv; +static SOC_ENUM_SINGLE_DECL(dig_ldo_volt_enum, RK730_LDO, + 0, dig_ldo_volt_text); - ucontrol->value.integer.value[0] = uv; - ucontrol->value.integer.value[1] = uv; +static const char * const ana_ldo_volt_text[] = { + "1.4v", "1.5v", "1.6v", "1.7v", +}; - return 0; -} +static const struct snd_kcontrol_new rk730_out1_switch = + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0); -static int rk730_adc_vol_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); - struct soc_mixer_control *mc = - (struct soc_mixer_control *)kcontrol->private_value; - unsigned int reg = mc->reg; - unsigned int rreg = mc->rreg; - unsigned int shift = mc->shift; - unsigned int mask = (1 << fls(mc->max)) - 1; - unsigned int val, val_mask, sign, sign_mask; - int uv = ucontrol->value.integer.value[0]; - int min = mc->min; - int mid = mc->max / 2; +static const struct snd_kcontrol_new rk730_out2_switch = + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0); - sign_mask = RK730_DADC_SR_ACL_VOLL_POL_MASK | RK730_DADC_SR_ACL_VOLR_POL_MASK; - - if (uv > mid) { - sign = RK730_DADC_SR_ACL_VOLL_POS | RK730_DADC_SR_ACL_VOLR_POS; - uv = uv - mid; - } else { - sign = RK730_DADC_SR_ACL_VOLL_NEG | RK730_DADC_SR_ACL_VOLR_NEG; - uv = mid - uv; - } - - val = ((uv + min) & mask); - val_mask = mask << shift; - val = val << shift; - - snd_soc_component_update_bits(component, reg, val_mask, val); - snd_soc_component_update_bits(component, rreg, val_mask, val); - snd_soc_component_update_bits(component, RK730_DADC_SR_ACL, sign_mask, sign); - - return 1; -} - -static int rk730_dac_vol_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); - struct soc_mixer_control *mc = - (struct soc_mixer_control *)kcontrol->private_value; - unsigned int val = snd_soc_component_read(component, mc->reg); - unsigned int sign = snd_soc_component_read(component, RK730_DDAC_SR_LMT); - unsigned int mask = (1 << fls(mc->max)) - 1; - unsigned int shift = mc->shift; - int mid = mc->max / 2; - int uv; - - uv = (val >> shift) & mask; - sign &= RK730_DDAC_SR_LMT_VOLL_POL_MASK; - if (sign) - uv = mid + uv; - else - uv = mid - uv; - - ucontrol->value.integer.value[0] = uv; - ucontrol->value.integer.value[1] = uv; - - return 0; -} - -static int rk730_dac_vol_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); - struct soc_mixer_control *mc = - (struct soc_mixer_control *)kcontrol->private_value; - unsigned int reg = mc->reg; - unsigned int rreg = mc->rreg; - unsigned int shift = mc->shift; - unsigned int mask = (1 << fls(mc->max)) - 1; - unsigned int val, val_mask, sign, sign_mask; - int uv = ucontrol->value.integer.value[0]; - int min = mc->min; - int mid = mc->max / 2; - - sign_mask = RK730_DDAC_SR_LMT_VOLL_POL_MASK | RK730_DDAC_SR_LMT_VOLR_POL_MASK; - - if (uv > mid) { - sign = RK730_DDAC_SR_LMT_VOLL_POS | RK730_DDAC_SR_LMT_VOLR_POS; - uv = uv - mid; - } else { - sign = RK730_DDAC_SR_LMT_VOLL_NEG | RK730_DDAC_SR_LMT_VOLR_NEG; - uv = mid - uv; - } - - val = ((uv + min) & mask); - val_mask = mask << shift; - val = val << shift; - - snd_soc_component_update_bits(component, reg, val_mask, val); - snd_soc_component_update_bits(component, rreg, val_mask, val); - snd_soc_component_update_bits(component, RK730_DDAC_SR_LMT, sign_mask, sign); - - return 1; -} - -static int rk730_cp_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - if (SND_SOC_DAPM_EVENT_ON(event)) - usleep_range(5000, 5100); - - return 0; -} +static SOC_ENUM_SINGLE_DECL(ana_ldo_volt_enum, RK730_LDO, + 4, ana_ldo_volt_text); static int rk730_pll_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); - if (SND_SOC_DAPM_EVENT_ON(event)) + if (SND_SOC_DAPM_EVENT_ON(event)) { + dev_dbg(component->dev, "%s on\n", __func__); snd_soc_component_write(component, RK730_SYSPLL_0, 0x00); - else - snd_soc_component_write(component, RK730_SYSPLL_0, 0xff); - - return 0; -} - -static int rk730_adc_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); - - if (SND_SOC_DAPM_EVENT_ON(event)) { - snd_soc_component_update_bits(component, RK730_ADC_0, - RK730_ADC_0_DEM_EN_MASK, - RK730_ADC_0_DEM_EN); - snd_soc_component_update_bits(component, RK730_DTOP_DIGEN_CLKE, - RK730_DTOP_DIGEN_CLKE_ADC_CKE_MASK | - RK730_DTOP_DIGEN_CLKE_I2STX_CKE_MASK | - RK730_DTOP_DIGEN_CLKE_ADC_EN_MASK | - RK730_DTOP_DIGEN_CLKE_I2STX_EN_MASK, - RK730_DTOP_DIGEN_CLKE_ADC_CKE_EN | - RK730_DTOP_DIGEN_CLKE_I2STX_CKE_EN | - RK730_DTOP_DIGEN_CLKE_ADC_EN | - RK730_DTOP_DIGEN_CLKE_I2STX_EN); - usleep_range(20000, 21000); - snd_soc_component_update_bits(component, RK730_DI2S_TXCR_3_TXCMD, - RK730_DI2S_TXCR_3_TXCMD_TXS_MASK, - RK730_DI2S_TXCR_3_TXCMD_TXS_EN); } else { - snd_soc_component_update_bits(component, RK730_DI2S_TXCR_3_TXCMD, - RK730_DI2S_TXCR_3_TXCMD_TXS_MASK, - RK730_DI2S_TXCR_3_TXCMD_TXS_DIS); - snd_soc_component_update_bits(component, RK730_ADC_0, - RK730_ADC_0_DEM_EN_MASK, - RK730_ADC_0_DEM_DIS); - snd_soc_component_update_bits(component, RK730_DTOP_DIGEN_CLKE, - RK730_DTOP_DIGEN_CLKE_ADC_CKE_MASK | - RK730_DTOP_DIGEN_CLKE_I2STX_CKE_MASK | - RK730_DTOP_DIGEN_CLKE_ADC_EN_MASK | - RK730_DTOP_DIGEN_CLKE_I2STX_EN_MASK, - RK730_DTOP_DIGEN_CLKE_ADC_CKE_DIS | - RK730_DTOP_DIGEN_CLKE_I2STX_CKE_DIS | - RK730_DTOP_DIGEN_CLKE_ADC_DIS | - RK730_DTOP_DIGEN_CLKE_I2STX_DIS); + dev_dbg(component->dev, "%s off\n", __func__); + snd_soc_component_write(component, RK730_SYSPLL_0, 0xff); } - return 0; } -static int rk730_dac_event(struct snd_soc_dapm_widget *w, +static int rk730_dacl_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); - if (SND_SOC_DAPM_EVENT_ON(event)) { - snd_soc_component_update_bits(component, RK730_DTOP_DIGEN_CLKE, - RK730_DTOP_DIGEN_CLKE_DAC_CKE_MASK | - RK730_DTOP_DIGEN_CLKE_I2SRX_CKE_MASK | - RK730_DTOP_DIGEN_CLKE_DAC_EN_MASK | - RK730_DTOP_DIGEN_CLKE_I2SRX_EN_MASK, - RK730_DTOP_DIGEN_CLKE_DAC_CKE_EN | - RK730_DTOP_DIGEN_CLKE_I2SRX_CKE_EN | - RK730_DTOP_DIGEN_CLKE_DAC_EN | - RK730_DTOP_DIGEN_CLKE_I2SRX_EN); + if (SND_SOC_DAPM_EVENT_ON(event)) + dev_dbg(component->dev, "%s on\n", __func__); + else + dev_dbg(component->dev, "%s off\n", __func__); + return 0; +} + +static int rk730_out1_drv_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + + if (SND_SOC_DAPM_EVENT_ON(event)) + dev_dbg(component->dev, "%s on\n", __func__); + else + dev_dbg(component->dev, "%s off\n", __func__); + return 0; +} + +static int rk730_out2_drv_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + + if (SND_SOC_DAPM_EVENT_ON(event)) + dev_dbg(component->dev, "%s on\n", __func__); + else + dev_dbg(component->dev, "%s off\n", __func__); + return 0; +} + +static int rk730_dacr_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + + if (SND_SOC_DAPM_EVENT_ON(event)) + dev_dbg(component->dev, "%s on\n", __func__); + else + dev_dbg(component->dev, "%s off\n", __func__); + return 0; +} + +static int rk730_sdin_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + dev_dbg(component->dev, "%s on\n", __func__); snd_soc_component_update_bits(component, RK730_DI2S_RXCMD_TSD, RK730_DI2S_RXCMD_TSD_RXS_MASK, RK730_DI2S_RXCMD_TSD_RXS_EN); - } else { + snd_soc_component_update_bits(component, RK730_DTOP_DIGEN_CLKE, + RK730_DTOP_DIGEN_CLKE_I2SRX_CKE_MASK | + RK730_DTOP_DIGEN_CLKE_I2SRX_EN_MASK, + RK730_DTOP_DIGEN_CLKE_I2SRX_CKE_EN | + RK730_DTOP_DIGEN_CLKE_I2SRX_EN); + snd_soc_component_update_bits(component, RK730_DTOP_DIGEN_CLKE, + RK730_DTOP_DIGEN_CLKE_DAC_CKE_MASK | + RK730_DTOP_DIGEN_CLKE_DAC_EN_MASK, + RK730_DTOP_DIGEN_CLKE_DAC_CKE_EN | + RK730_DTOP_DIGEN_CLKE_DAC_EN); + break; + case SND_SOC_DAPM_POST_PMD: + dev_dbg(component->dev, "%s off\n", __func__); + snd_soc_component_update_bits(component, RK730_DTOP_DIGEN_CLKE, + RK730_DTOP_DIGEN_CLKE_DAC_CKE_MASK | + RK730_DTOP_DIGEN_CLKE_DAC_EN_MASK, + RK730_DTOP_DIGEN_CLKE_DAC_CKE_DIS | + RK730_DTOP_DIGEN_CLKE_DAC_DIS); + snd_soc_component_update_bits(component, RK730_DTOP_DIGEN_CLKE, + RK730_DTOP_DIGEN_CLKE_I2SRX_CKE_MASK | + RK730_DTOP_DIGEN_CLKE_I2SRX_EN_MASK, + RK730_DTOP_DIGEN_CLKE_I2SRX_CKE_DIS | + RK730_DTOP_DIGEN_CLKE_I2SRX_DIS); snd_soc_component_update_bits(component, RK730_DI2S_RXCMD_TSD, RK730_DI2S_RXCMD_TSD_RXS_MASK, RK730_DI2S_RXCMD_TSD_RXS_DIS); - snd_soc_component_update_bits(component, RK730_DTOP_DIGEN_CLKE, - RK730_DTOP_DIGEN_CLKE_DAC_CKE_MASK | - RK730_DTOP_DIGEN_CLKE_I2SRX_CKE_MASK | - RK730_DTOP_DIGEN_CLKE_DAC_EN_MASK | - RK730_DTOP_DIGEN_CLKE_I2SRX_EN_MASK, - RK730_DTOP_DIGEN_CLKE_DAC_CKE_DIS | - RK730_DTOP_DIGEN_CLKE_I2SRX_CKE_DIS | - RK730_DTOP_DIGEN_CLKE_DAC_DIS | - RK730_DTOP_DIGEN_CLKE_I2SRX_DIS); + break; + default: + dev_err(component->dev, "%s Invalid event = 0x%x\n", __func__, event); } - return 0; } -static int rk730_mux_out_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) +static int rk730_sdout_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + + if (SND_SOC_DAPM_EVENT_ON(event)) { + dev_dbg(component->dev, "%s on\n", __func__); + snd_soc_component_update_bits(component, RK730_DI2S_TXCR3_TXCMD, + RK730_DI2S_TXCR_3_TXCMD_TXS_MASK, + RK730_DI2S_TXCR_3_TXCMD_TXS_EN); + snd_soc_component_update_bits(component, RK730_DTOP_DIGEN_CLKE, + RK730_DTOP_DIGEN_CLKE_ADC_CKE_MASK | + RK730_DTOP_DIGEN_CLKE_I2STX_CKE_MASK, + RK730_DTOP_DIGEN_CLKE_ADC_CKE_EN | + RK730_DTOP_DIGEN_CLKE_I2STX_CKE_EN); + usleep_range(20000, 21000); + snd_soc_component_update_bits(component, RK730_DTOP_DIGEN_CLKE, + RK730_DTOP_DIGEN_CLKE_ADC_EN_MASK | + RK730_DTOP_DIGEN_CLKE_I2STX_EN_MASK, + RK730_DTOP_DIGEN_CLKE_ADC_EN | + RK730_DTOP_DIGEN_CLKE_I2STX_EN); + } else { + dev_dbg(component->dev, "%s off\n", __func__); + + snd_soc_component_update_bits(component, RK730_DTOP_DIGEN_CLKE, + RK730_DTOP_DIGEN_CLKE_ADC_EN_MASK | + RK730_DTOP_DIGEN_CLKE_I2STX_EN_MASK, + RK730_DTOP_DIGEN_CLKE_ADC_DIS | + RK730_DTOP_DIGEN_CLKE_I2STX_DIS); + usleep_range(50, 60); + snd_soc_component_update_bits(component, RK730_DTOP_DIGEN_CLKE, + RK730_DTOP_DIGEN_CLKE_ADC_CKE_MASK | + RK730_DTOP_DIGEN_CLKE_I2STX_CKE_MASK, + RK730_DTOP_DIGEN_CLKE_ADC_CKE_DIS | + RK730_DTOP_DIGEN_CLKE_I2STX_CKE_DIS); + snd_soc_component_update_bits(component, RK730_DI2S_TXCR3_TXCMD, + RK730_DI2S_TXCR_3_TXCMD_TXS_MASK, + RK730_DI2S_TXCR_3_TXCMD_TXS_DIS); + } + return 0; +} + +static int rk730_adcr_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + dev_dbg(component->dev, "%s on\n", __func__); + break; + case SND_SOC_DAPM_PRE_PMD: + dev_dbg(component->dev, "%s off\n", __func__); + break; + default: + dev_err(component->dev, "%s Invalid event = 0x%x\n", __func__, event); + } + return 0; +} + +static int rk730_adcl_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + dev_dbg(component->dev, "%s on\n", __func__); + break; + case SND_SOC_DAPM_PRE_PMD: + dev_dbg(component->dev, "%s off\n", __func__); + break; + default: + dev_err(component->dev, "%s Invalid event = 0x%x\n", __func__, event); + } + return 0; +} + +static int rk730_dac0_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + + if (SND_SOC_DAPM_EVENT_ON(event)) { + dev_dbg(component->dev, "%s on\n", __func__); + + /* analog config */ + snd_soc_component_update_bits(component, RK730_DAC_0, + RK730_DAC_0_DAC_R_HP_PWD_MASK | + RK730_DAC_0_DAC_L_HP_PWD_MASK | + RK730_DAC_0_DAC_HP_IBIAS_MASK, + RK730_DAC_0_DAC_L_HP_PWU | + RK730_DAC_0_DAC_R_HP_PWU | + RK730_DAC_0_DAC_HP_IBIAS_ON); + snd_soc_component_update_bits(component, RK730_HP_0, + RK730_HP_0_ANTIPOP_PWR_MASK | + RK730_HP_0_HP_IBIAS_MASK | + RK730_HP_0_HP_TWOTAGE_EN_MASK | + RK730_HP_0_HP_OSTG_PWR_MASK | + RK730_HP_0_HP_BLOCK_PWR_MASK, + RK730_HP_0_ANTIPOP_PWR_OFF | + RK730_HP_0_HP_IBIAS_ON | + RK730_HP_0_HP_TWOTAGE_EN | + RK730_HP_0_HP_OSTG_PWR_ON | + RK730_HP_0_HP_BLOCK_PWR_ON); + } else { + dev_dbg(component->dev, "%s off\n", __func__); + + /* analog config */ + snd_soc_component_update_bits(component, RK730_HP_0, + RK730_HP_0_ANTIPOP_PWR_MASK | + RK730_HP_0_HP_IBIAS_MASK | + RK730_HP_0_HP_TWOTAGE_EN_MASK | + RK730_HP_0_HP_OSTG_PWR_MASK | + RK730_HP_0_HP_BLOCK_PWR_MASK, + RK730_HP_0_ANTIPOP_PWR_ON | + RK730_HP_0_HP_IBIAS_OFF | + RK730_HP_0_HP_TWOTAGE_DIS | + RK730_HP_0_HP_OSTG_PWR_OFF | + RK730_HP_0_HP_BLOCK_PWR_OFF); + snd_soc_component_update_bits(component, RK730_DAC_0, + RK730_DAC_0_DAC_R_HP_PWD_MASK | + RK730_DAC_0_DAC_L_HP_PWD_MASK | + RK730_DAC_0_DAC_HP_IBIAS_MASK, + RK730_DAC_0_DAC_L_HP_PWD | + RK730_DAC_0_DAC_R_HP_PWD| + RK730_DAC_0_DAC_HP_IBIAS_OFF); + } + return 0; +} + +static int rk730_dac1_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + + if (SND_SOC_DAPM_EVENT_ON(event)) { + dev_dbg(component->dev, "%s on\n", __func__); + + /* analog config */ + snd_soc_component_update_bits(component, RK730_DAC_1, + RK730_DAC_1_DAC_SPK_IBIAS_MASK | + RK730_DAC_1_DAC_R_SPK_PWD_MASK | + RK730_DAC_1_DAC_L_SPK_PWD_MASK, + RK730_DAC_1_DAC_SPK_IBIAS_ON | + RK730_DAC_1_DAC_R_SPK_PWU | + RK730_DAC_1_DAC_L_SPK_PWU); + snd_soc_component_update_bits(component, RK730_SPK_0, + RK730_SPK_0_ANTIPOP_PWR_MASK | + RK730_SPK_0_SPK_IBIAS_MASK | + RK730_SPK_0_SPK_OSTAGE_PWR_MASK | + RK730_SPK_0_SPK_BLOCK_PWR_MASK, + RK730_SPK_0_ANTIPOP_PWR_OFF | + RK730_SPK_0_SPK_IBIAS_ON | + RK730_SPK_0_SPK_OSTAGE_PWR_ON | + RK730_SPK_0_SPK_BLOCK_PWR_ON); + } else { + dev_dbg(component->dev, "%s off\n", __func__); + + /* analog config */ + snd_soc_component_update_bits(component, RK730_SPK_0, + RK730_SPK_0_ANTIPOP_PWR_MASK | + RK730_SPK_0_SPK_IBIAS_MASK | + RK730_SPK_0_SPK_OSTAGE_PWR_MASK | + RK730_SPK_0_SPK_BLOCK_PWR_MASK, + RK730_SPK_0_ANTIPOP_PWR_ON | + RK730_SPK_0_SPK_IBIAS_OFF | + RK730_SPK_0_SPK_OSTAGE_PWR_OFF | + RK730_SPK_0_SPK_BLOCK_PWR_OFF); + snd_soc_component_update_bits(component, RK730_DAC_1, + RK730_DAC_1_DAC_SPK_IBIAS_MASK | + RK730_DAC_1_DAC_R_SPK_PWD_MASK | + RK730_DAC_1_DAC_L_SPK_PWD_MASK, + RK730_DAC_1_DAC_SPK_IBIAS_OFF | + RK730_DAC_1_DAC_R_SPK_PWD | + RK730_DAC_1_DAC_L_SPK_PWD); + } + return 0; +} + +static int rk730_out1_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) { struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); - struct rk730_priv *rk730 = snd_soc_component_get_drvdata(component); - unsigned int val; if (SND_SOC_DAPM_EVENT_ON(event)) - val = atomic_inc_return(&rk730->mix_mode); + dev_dbg(component->dev, "%s on\n", __func__); else - val = atomic_dec_return(&rk730->mix_mode); + dev_dbg(component->dev, "%s off\n", __func__); + return 0; +} - snd_soc_component_update_bits(component, RK730_MIXER_2, - RK730_MIXER_2_MIX_R_MODE_MASK | - RK730_MIXER_2_MIX_L_MODE_MASK, - RK730_MIXER_2_MIX_R_MODE(val) | - RK730_MIXER_2_MIX_L_MODE(val)); +static int rk730_out2_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + + if (SND_SOC_DAPM_EVENT_ON(event)) + dev_dbg(component->dev, "%s on\n", __func__); + else + dev_dbg(component->dev, "%s off\n", __func__); return 0; } static const struct snd_kcontrol_new rk730_snd_controls[] = { - SOC_DOUBLE_R_TLV("ADC Volume", RK730_ADC_PGA_BLOCK_0, RK730_ADC_PGA_BLOCK_1, + SOC_DOUBLE_R_TLV("ADC PGA Volume", RK730_ADC_PGA_BLOCK_0, RK730_ADC_PGA_BLOCK_1, 1, 0x7, 1, adc_tlv), - SOC_DOUBLE_R_TLV("D2S Volume", RK730_DAC_1, RK730_DAC_2, - 1, 0x6, 1, d2s_tlv), - - SOC_DOUBLE_R_TLV("MIC1 Boost Volume", RK730_MIC_BOOST_0, RK730_MIC_BOOST_1, - 1, 0x18, 0, micboost_tlv), - SOC_DOUBLE_R_TLV("MIC2 Boost Volume", RK730_MIC_BOOST_2, RK730_MIC_BOOST_3, - 1, 0x18, 0, micboost_tlv), - - SOC_DOUBLE_TLV("Out Mux Volume", RK730_MUXER_0, 1, 5, 0x1, 0, mux_tlv), - - SOC_SINGLE_TLV("Left Out Mux -> Left Out Mixer Volume", - RK730_MIXER_0, 1, 0x6, 1, mix_buf_tlv), - SOC_SINGLE_TLV("Left Out Mux -> Right Out Mixer Volume", - RK730_MIXER_0, 5, 0x6, 1, mix_buf_tlv), - SOC_SINGLE_TLV("Right Out Mux -> Left Out Mixer Volume", - RK730_MIXER_1, 1, 0x6, 1, mix_buf_tlv), - SOC_SINGLE_TLV("Right Out Mux -> Right Out Mixer Volume", - RK730_MIXER_1, 5, 0x6, 1, mix_buf_tlv), - - SOC_SINGLE_TLV("HP Volume", RK730_HP_0, 6, 0x3, 0, hp_tlv), - SOC_SINGLE_TLV("Line Out Volume", RK730_LINEOUT_1, 2, 0x3, 0, lineout_tlv), - - SOC_DOUBLE_R_EXT_TLV("ADC Digital Volume", - RK730_DADC_VOLL, RK730_DADC_VOLR, 0, 0x1fe, 0, - rk730_adc_vol_get, - rk730_adc_vol_put, - adc_dig_tlv), - SOC_DOUBLE_R_EXT_TLV("DAC Digital Volume", - RK730_DDAC_VOLL, RK730_DDAC_VOLR, 0, 0x1fe, 0, - rk730_dac_vol_get, - rk730_dac_vol_put, - dac_dig_tlv), - - SOC_ENUM("ADC HPF Cutoff", adc_hpf_cutoff_enum), - SOC_ENUM("DAC HPF Cutoff", dac_hpf_cutoff_enum), - SOC_ENUM("DAC Ref Buf Chop Freq", dac_ref_buf_chop_freq_enum), + SOC_DOUBLE_R_TLV("MIC2 Boost Volume", RK730_MIC_BOOST_0, RK730_MIC_BOOST_1, + 1, 0x7, 0, micboost_tlv), + SOC_DOUBLE_R_TLV("MIC1 Boost Volume", RK730_MIC_BOOST_2, RK730_MIC_BOOST_3, + 1, 0x7, 0, micboost_tlv), + SOC_DOUBLE_R_TLV("MIC2 decrease Volume", RK730_MIC_BOOST_0, RK730_MIC_BOOST_1, + 4, 0x3, 0, micdecrease_tlv), + SOC_DOUBLE_R_TLV("MIC1 decrease Volume", RK730_MIC_BOOST_2, RK730_MIC_BOOST_3, + 4, 0x3, 0, micdecrease_tlv), + SOC_DOUBLE_R_TLV("ADC Digital Volume", RK730_DADC_VOLL, RK730_DADC_VOLR, + 0, 0xff, 1, adc_dig_tlv), + SOC_DOUBLE_R_TLV("DAC Digital Volume", RK730_DDAC_VOLL, RK730_DDAC_VOLR, + 0, 0xff, 1, dac_dig_tlv), + SOC_ENUM("DIG DLO VOLTAGE", dig_ldo_volt_enum), + SOC_ENUM("ANA DLO VOLTAGE", ana_ldo_volt_enum), SOC_ENUM("MIC Chop Freq", mic_chop_freq_enum), SOC_ENUM("ADC PGA Chop Freq", adc_pga_chop_freq_enum), - SOC_ENUM("Out Mux Chop Freq", mux_out_chop_freq_enum), - SOC_ENUM("Mixer Chop Freq", mix_chop_freq_enum), SOC_ENUM("HP / Lineout Chop Freq", hp_lo_chop_freq_enum), SOC_ENUM("Mic Bias Volt", micbias_volt_enum), - SOC_ENUM("Charge Pump Volt", charge_pump_volt_enum), - - SOC_SINGLE("ADCL HPF Switch", RK730_DADC_HPF, 7, 1, 0), - SOC_SINGLE("ADCR HPF Switch", RK730_DADC_HPF, 6, 1, 0), - SOC_SINGLE("DAC HPF Switch", RK730_DDAC_MUTE_MIXCTL, 7, 1, 0), + SOC_ENUM("DAC HPF Center Freq", dac_hfp_center_freq_enum), + SOC_ENUM("ADC CAPACITY TRIM", adc_capacity_trim_enum), SOC_SINGLE("ADC Volume Bypass Switch", RK730_DTOP_VUCTL, 7, 1, 0), SOC_SINGLE("DAC Volume Bypass Switch", RK730_DTOP_VUCTL, 6, 1, 0), SOC_SINGLE("ADC Fade Switch", RK730_DTOP_VUCTL, 5, 1, 0), SOC_SINGLE("DAC Fade Switch", RK730_DTOP_VUCTL, 4, 1, 0), + SOC_SINGLE("DAC Left gain polarity", RK730_DTOP_VUCTL, 3, 1, 0), + SOC_SINGLE("DAC Right gain polarity", RK730_DTOP_VUCTL, 2, 1, 0), SOC_SINGLE("ADC Zero Crossing Switch", RK730_DTOP_VUCTL, 1, 1, 0), SOC_SINGLE("DAC Zero Crossing Switch", RK730_DTOP_VUCTL, 0, 1, 0), SOC_SINGLE("MIC1N / MIC2P Exchanged Switch", RK730_MIC_BOOST_2, 7, 1, 0), + SOC_SINGLE("ADC CHOP EN", RK730_ADC_2, 4, 1, 0), }; static const struct snd_soc_dapm_widget rk730_dapm_widgets[] = { - SND_SOC_DAPM_SUPPLY_S("ANA LDO", 0, RK730_LDO, 7, 0, NULL, 0), - SND_SOC_DAPM_SUPPLY_S("OSC CLK", 1, RK730_HK_TOP_2, 4, 0, NULL, 0), - SND_SOC_DAPM_SUPPLY_S("VAG BUF", 1, RK730_HK_TOP_2, 2, 1, NULL, 0), - SND_SOC_DAPM_SUPPLY_S("ADC BUF", 1, RK730_HK_TOP_2, 1, 1, NULL, 0), - SND_SOC_DAPM_SUPPLY_S("DAC BUF", 1, RK730_HK_TOP_2, 0, 1, NULL, 0), - SND_SOC_DAPM_SUPPLY_S("MICBIAS", 1, RK730_MIC_BIAS, 0, 1, NULL, 0), - SND_SOC_DAPM_SUPPLY_S("Charge Pump", 1, RK730_CHARGE_PUMP, 0, 0, - rk730_cp_event, SND_SOC_DAPM_POST_PMU), - SND_SOC_DAPM_SUPPLY_S("PLL", 2, SND_SOC_NOPM, 0, 0, rk730_pll_event, + SND_SOC_DAPM_SUPPLY_S("ANA LDO", 1, RK730_LDO, 7, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY_S("PLL", 1, SND_SOC_NOPM, 0, 0, + rk730_pll_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_SUPPLY_S("DAC Bias", 2, RK730_DAC_0, 2, 1, NULL, 0), - SND_SOC_DAPM_SUPPLY_S("HP Bias", 2, RK730_HP_0, 5, 1, NULL, 0), - SND_SOC_DAPM_SUPPLY_S("Line Out Bias", 2, RK730_LINEOUT_1, 7, 1, NULL, 0), - - SND_SOC_DAPM_ADC_E("ADCL", "HiFi Capture", RK730_ADC_0, 0, 1, - rk730_adc_event, - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_ADC_E("ADCR", "HiFi Capture", RK730_ADC_0, 1, 1, - rk730_adc_event, - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_DAC_E("DACL", "HiFi Playback", RK730_DAC_0, 0, 1, - rk730_dac_event, - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_DAC_E("DACR", "HiFi Playback", RK730_DAC_0, 1, 1, - rk730_dac_event, - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_PGA("ADCL PGA", RK730_ADC_PGA_BLOCK_0, 0, 1, NULL, 0), - SND_SOC_DAPM_PGA("ADCR PGA", RK730_ADC_PGA_BLOCK_1, 0, 1, NULL, 0), - - SND_SOC_DAPM_PGA("D2SL", RK730_DAC_1, 0, 1, NULL, 0), - SND_SOC_DAPM_PGA("D2SR", RK730_DAC_2, 0, 1, NULL, 0), - - SND_SOC_DAPM_PGA("MIC1P", RK730_MIC_BOOST_0, 0, 1, NULL, 0), - SND_SOC_DAPM_PGA("MIC1N", RK730_MIC_BOOST_1, 0, 1, NULL, 0), - SND_SOC_DAPM_PGA("MIC2P", RK730_MIC_BOOST_2, 0, 1, NULL, 0), - SND_SOC_DAPM_PGA("MIC2N", RK730_MIC_BOOST_3, 0, 1, NULL, 0), + SND_SOC_DAPM_SUPPLY_S("DAC BUF", 2, RK730_HK_TOP_2, 0, 1, NULL, 0), + SND_SOC_DAPM_SUPPLY_S("HK VAG BUF", 0, RK730_HK_TOP_1, 7, 1, NULL, 0), + SND_SOC_DAPM_SUPPLY_S("HK DAC BUF", 0, RK730_HK_TOP_1, 6, 1, NULL, 0), + SND_SOC_DAPM_SUPPLY_S("MICBIAS", 1, RK730_MIC_BIAS, 0, 1, NULL, 0), + SND_SOC_DAPM_DAC_E("DAC0", NULL, SND_SOC_NOPM, 0, 0, + rk730_dac0_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_DAC_E("DAC1", NULL, SND_SOC_NOPM, 0, 0, + rk730_dac1_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_DAC_E("DACL", "Left Playback", SND_SOC_NOPM, 0, 0, + rk730_dacl_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_DAC_E("DACR", "Right Playback", SND_SOC_NOPM, 0, 0, + rk730_dacr_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY("OUT1 Power", SND_SOC_NOPM, 0, 0, + rk730_out1_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY("OUT2 Power", SND_SOC_NOPM, 0, 0, + rk730_out2_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SWITCH("OUT1", SND_SOC_NOPM, 0, 0, &rk730_out1_switch), + SND_SOC_DAPM_SWITCH("OUT2", SND_SOC_NOPM, 0, 0, &rk730_out2_switch), + SND_SOC_DAPM_OUT_DRV_E("OUT1 DRV", SND_SOC_NOPM, 0, 0, NULL, 0, rk730_out1_drv_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_OUT_DRV_E("OUT2 DRV", SND_SOC_NOPM, 0, 0, NULL, 0, rk730_out2_drv_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_OUTPUT("LOUT1"), + SND_SOC_DAPM_OUTPUT("ROUT1"), + SND_SOC_DAPM_OUTPUT("LOUT2"), + SND_SOC_DAPM_OUTPUT("ROUT2"), + SND_SOC_DAPM_AIF_IN_E("I2S IN", "HiFi Playback", 0, SND_SOC_NOPM, 0, 0, + rk730_sdin_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_AIF_OUT_E("I2S OUT", "HiFi Capture", 0, SND_SOC_NOPM, 0, 0, + rk730_sdout_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_ADC_E("ADCL", "Left Capture", RK730_ADC_0, 0, 1, + rk730_adcl_event, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_ADC_E("ADCR", "Right Capture", RK730_ADC_0, 1, 1, + rk730_adcr_event, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_MUX("ADCSel Mux", SND_SOC_NOPM, 0, 1, &adc_data_sel), + SND_SOC_DAPM_MUX("Left PGA Mux", RK730_ADC_PGA_BLOCK_0, 0, 1, &mux_input_l), + SND_SOC_DAPM_MUX("Right PGA Mux", RK730_ADC_PGA_BLOCK_1, 0, 1, &mux_input_r), + /* 0:mic_r2_pwd 3:1 mic_r2_boost */ + SND_SOC_DAPM_PGA("MIC2R", RK730_MIC_BOOST_0, 0, 1, NULL, 0), + SND_SOC_DAPM_PGA("MIC2L", RK730_MIC_BOOST_1, 0, 1, NULL, 0), + SND_SOC_DAPM_PGA("MIC1R", RK730_MIC_BOOST_2, 0, 1, NULL, 0), + SND_SOC_DAPM_PGA("MIC1L", RK730_MIC_BOOST_3, 0, 1, NULL, 0), SND_SOC_DAPM_PGA("DIFFL", SND_SOC_NOPM, 0, 0, NULL, 0), SND_SOC_DAPM_PGA("DIFFR", SND_SOC_NOPM, 0, 0, NULL, 0), - - SND_SOC_DAPM_PGA("HP Out", RK730_HP_0, 2, 1, NULL, 0), - SND_SOC_DAPM_PGA("HP Out Stage", RK730_HP_0, 3, 1, NULL, 0), - SND_SOC_DAPM_PGA("Line Out", RK730_LINEOUT_0, 2, 1, NULL, 0), - SND_SOC_DAPM_PGA("Line Out Stage", RK730_LINEOUT_0, 3, 1, NULL, 0), - - SND_SOC_DAPM_MUX_E("Left Out Mux", SND_SOC_NOPM, 0, 0, &mux_out_l, - rk730_mux_out_event, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MUX_E("Right Out Mux", SND_SOC_NOPM, 0, 0, &mux_out_r, - rk730_mux_out_event, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_MUX("Left Input Mux", SND_SOC_NOPM, 0, 0, &mux_input_l), - SND_SOC_DAPM_MUX("Right Input Mux", SND_SOC_NOPM, 0, 0, &mux_input_r), - - SND_SOC_DAPM_MIXER("Left Out Mixer", RK730_MIXER_2, 0, 1, - mix_ctls, ARRAY_SIZE(mix_ctls)), - SND_SOC_DAPM_MIXER("Right Out Mixer", RK730_MIXER_2, 3, 1, - mix_ctls, ARRAY_SIZE(mix_ctls)), - - SND_SOC_DAPM_OUTPUT("HPL"), - SND_SOC_DAPM_OUTPUT("HPR"), - SND_SOC_DAPM_OUTPUT("LINEOUTL"), - SND_SOC_DAPM_OUTPUT("LINEOUTR"), - SND_SOC_DAPM_INPUT("MIC1"), SND_SOC_DAPM_INPUT("MIC2"), }; static const struct snd_soc_dapm_route rk730_dapm_routes[] = { - { "DACL", NULL, "ANA LDO" }, - { "DACR", NULL, "ANA LDO" }, - { "DACL", NULL, "OSC CLK" }, - { "DACR", NULL, "OSC CLK" }, - { "DACL", NULL, "VAG BUF" }, - { "DACR", NULL, "VAG BUF" }, - { "DACL", NULL, "DAC BUF" }, - { "DACR", NULL, "DAC BUF" }, - { "DACL", NULL, "PLL" }, - { "DACR", NULL, "PLL" }, - { "DACL", NULL, "DAC Bias" }, - { "DACR", NULL, "DAC Bias" }, + {"OUT1", NULL, "OUT1 Power"}, + {"OUT2", NULL, "OUT2 Power"}, - { "D2SL", NULL, "DACL" }, - { "D2SR", NULL, "DACR" }, + {"LOUT1", NULL, "OUT1 DRV"}, + {"ROUT1", NULL, "OUT1 DRV"}, + {"LOUT2", NULL, "OUT2 DRV"}, + {"ROUT2", NULL, "OUT2 DRV"}, - { "Left Out Mixer", NULL, "D2SL" }, - { "Left Out Mixer", "Left Out Mux Switch", "Left Out Mux" }, - { "Left Out Mixer", "Right Out Mux Switch", "Right Out Mux" }, - { "Right Out Mixer", NULL, "D2SR" }, - { "Right Out Mixer", "Left Out Mux Switch", "Left Out Mux" }, - { "Right Out Mixer", "Right Out Mux Switch", "Right Out Mux" }, + {"OUT1 DRV", NULL, "OUT1"}, + {"OUT2 DRV", NULL, "OUT2"}, - { "Left Out Mux", "DIFF", "DIFFL" }, - { "Left Out Mux", "MIC1N", "MIC1N" }, - { "Left Out Mux", "MIC2N", "MIC2N" }, + {"OUT1", "Switch", "DAC1"}, + {"OUT2", "Switch", "DAC0"}, - { "Right Out Mux", "DIFF", "DIFFR" }, - { "Right Out Mux", "MIC1P", "MIC1P" }, - { "Right Out Mux", "MIC2P", "MIC2P" }, + {"DAC1", NULL, "I2S IN"}, + {"DAC0", NULL, "I2S IN"}, - { "HP Out", NULL, "HP Bias" }, - { "HP Out", NULL, "HP Bias" }, - { "Line Out", NULL, "Line Out Bias" }, + {"HK DAC BUF", NULL, "HK VAG BUF"}, + {"I2S IN", NULL, "HK DAC BUF"}, + {"I2S OUT", NULL, "HK VAG BUF"}, + {"I2S IN", NULL, "PLL"}, + {"I2S OUT", NULL, "PLL"}, + {"I2S IN", NULL, "ANA LDO"}, + {"I2S OUT", NULL, "ANA LDO"}, - { "HP Out", NULL, "Left Out Mixer" }, - { "HP Out", NULL, "Right Out Mixer" }, - { "Line Out", NULL, "Left Out Mixer" }, - { "Line Out", NULL, "Right Out Mixer" }, + {"I2S OUT", NULL, "ADCR"}, + {"I2S OUT", NULL, "ADCL"}, + {"ADCR", NULL, "ADCSel Mux"}, + {"ADCL", NULL, "ADCSel Mux"}, - { "HP Out Stage", NULL, "HP Out" }, - { "Line Out Stage", NULL, "Line Out" }, + {"ADCSel Mux", "normal", "Left PGA Mux"}, + {"ADCSel Mux", "normal", "Right PGA Mux"}, + {"ADCSel Mux", "swap", "Left PGA Mux"}, + {"ADCSel Mux", "swap", "Right PGA Mux"}, + {"ADCSel Mux", "left", "Left PGA Mux"}, + {"ADCSel Mux", "right", "Right PGA Mux"}, - { "HPL", NULL, "HP Out Stage" }, - { "HPR", NULL, "HP Out Stage" }, - { "HPL", NULL, "Charge Pump" }, - { "HPR", NULL, "Charge Pump" }, + {"Left PGA Mux", "DIFF", "DIFFL"}, + {"Left PGA Mux", "VINR2", "MIC2R"}, + {"Left PGA Mux", "VINL2", "MIC2L"}, - { "LINEOUTL", NULL, "Line Out Stage" }, - { "LINEOUTR", NULL, "Line Out Stage" }, - { "LINEOUTL", NULL, "Charge Pump" }, - { "LINEOUTR", NULL, "Charge Pump" }, + {"Right PGA Mux", "DIFF", "DIFFR"}, + {"Right PGA Mux", "VINR1", "MIC1R"}, + {"Right PGA Mux", "VINL1", "MIC1L"}, - { "ADCL", NULL, "ANA LDO" }, - { "ADCR", NULL, "ANA LDO" }, - { "ADCL", NULL, "OSC CLK" }, - { "ADCR", NULL, "OSC CLK" }, - { "ADCL", NULL, "ADC BUF" }, - { "ADCR", NULL, "ADC BUF" }, - { "ADCL", NULL, "VAG BUF" }, - { "ADCR", NULL, "VAG BUF" }, - { "ADCL", NULL, "PLL" }, - { "ADCR", NULL, "PLL" }, + {"DIFFL", NULL, "MIC2R"}, + {"DIFFL", NULL, "MIC2L"}, + {"DIFFR", NULL, "MIC1R"}, + {"DIFFR", NULL, "MIC1L"}, - { "ADCL", NULL, "ADCL PGA" }, - { "ADCR", NULL, "ADCR PGA" }, - { "ADCL PGA", NULL, "Left Input Mux" }, - { "ADCR PGA", NULL, "Right Input Mux" }, - - { "Left Input Mux", "DIFF", "DIFFL" }, - { "Left Input Mux", "VINP1", "MIC1P" }, - { "Left Input Mux", "VINN1", "MIC1N" }, - { "Right Input Mux", "DIFF", "DIFFR" }, - { "Right Input Mux", "VINP2", "MIC2P" }, - { "Right Input Mux", "VINN2", "MIC2N" }, - - { "DIFFL", NULL, "MIC1P" }, - { "DIFFL", NULL, "MIC1N" }, - { "DIFFR", NULL, "MIC2P" }, - { "DIFFR", NULL, "MIC2N" }, - - { "MIC1P", NULL, "MIC1" }, - { "MIC1N", NULL, "MIC1" }, - { "MIC2P", NULL, "MIC2" }, - { "MIC2N", NULL, "MIC2" }, - - { "MIC1", NULL, "MICBIAS" }, - { "MIC2", NULL, "MICBIAS" }, + {"MIC1R", NULL, "MIC1"}, + {"MIC1L", NULL, "MIC1"}, + {"MIC2R", NULL, "MIC2"}, + {"MIC2L", NULL, "MIC2"}, + {"MIC1", NULL, "MICBIAS"}, + {"MIC2", NULL, "MICBIAS"}, }; static unsigned int samplerate_to_bit(unsigned int samplerate) @@ -636,64 +640,134 @@ static int rk730_dai_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct snd_soc_component *component = dai->component; - unsigned int width, rate; + unsigned int rate; - width = min(params_width(params), 24); - rate = samplerate_to_bit(params_rate(params)); - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - snd_soc_component_update_bits(component, RK730_DI2S_RXCR_2, - RK730_DI2S_XCR2_VDW_MASK, - RK730_DI2S_XCR2_VDW(width)); - snd_soc_component_update_bits(component, RK730_DDAC_SR_LMT, - RK730_DDAC_SR_LMT_SRT_MASK, - RK730_DDAC_SR_LMT_SRT(rate)); - } else { - snd_soc_component_update_bits(component, RK730_DI2S_TXCR_2, - RK730_DI2S_XCR2_VDW_MASK, - RK730_DI2S_XCR2_VDW(width)); - snd_soc_component_update_bits(component, RK730_DADC_SR_ACL, - RK730_DADC_SR_ACL_SRT_MASK, - RK730_DADC_SR_ACL_SRT(rate)); + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + snd_soc_component_update_bits(component, RK730_DI2S_RXCR2, + RK730_DI2S_RXCR2_VDW_MASK, + RK730_DI2S_RXCR2_VDW(16)); + snd_soc_component_update_bits(component, RK730_DI2S_TXCR2, + RK730_DI2S_TXCR2_VDW_MASK, + RK730_DI2S_TXCR2_VDW(16)); + break; + case SNDRV_PCM_FORMAT_S24_LE: + case SNDRV_PCM_FORMAT_S32_LE: + snd_soc_component_update_bits(component, RK730_DI2S_RXCR2, + RK730_DI2S_RXCR2_VDW_MASK, + RK730_DI2S_RXCR2_VDW(24)); + snd_soc_component_update_bits(component, RK730_DI2S_TXCR2, + RK730_DI2S_TXCR2_VDW_MASK, + RK730_DI2S_TXCR2_VDW(24)); + break; + default: + return -EINVAL; } + rate = samplerate_to_bit(params_rate(params)); + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + snd_soc_component_update_bits(component, RK730_DTOP_SRT, + RK730_DTOP_DACSRT_MASK, + RK730_DTOP_DACSRT(rate)); + } else { + snd_soc_component_update_bits(component, RK730_DTOP_SRT, + RK730_DTOP_ADCSRT_MASK, + RK730_DTOP_ADCSRT(rate)); + } return 0; } static int rk730_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) { struct snd_soc_component *component = codec_dai->component; + u8 val = 0, format = 0; + u8 mask = RK730_DI2S_TXCR1_TFS_TX_MASK; + int ret = 0; - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: - snd_soc_component_update_bits(component, RK730_DI2S_CKM, - RK730_DI2S_CKM_MST_MASK, - RK730_DI2S_CKM_MST_SLAVE); + /* interface format */ + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + mask |= RK730_DI2S_TXCR1_IBM_TX_MASK; + format = RK730_DI2S_TXCR1_TFS_TX_I2S | RK730_DI2S_TXCR1_IBM_TX_NORMAL; break; - case SND_SOC_DAIFMT_CBM_CFM: - snd_soc_component_update_bits(component, RK730_DI2S_CKM, - RK730_DI2S_CKM_MST_MASK, - RK730_DI2S_CKM_MST_MASTER); + case SND_SOC_DAIFMT_RIGHT_J: + mask |= RK730_DI2S_TXCR1_IBM_TX_MASK; + format = RK730_DI2S_TXCR1_TFS_TX_I2S | RK730_DI2S_TXCR1_IBM_TX_RIGHT; + break; + case SND_SOC_DAIFMT_LEFT_J: + mask |= RK730_DI2S_TXCR1_PBM_TX_MASK; + format = RK730_DI2S_TXCR1_TFS_TX_I2S | RK730_DI2S_TXCR1_IBM_TX_LEFT; + break; + case SND_SOC_DAIFMT_DSP_A: + mask |= RK730_DI2S_TXCR1_PBM_TX_MASK; + format = RK730_DI2S_TXCR1_TFS_TX_PCM | RK730_DI2S_TXCR1_PBM_TX_NODELAY; + break; + case SND_SOC_DAIFMT_DSP_B: + mask |= RK730_DI2S_TXCR1_PBM_TX_MASK; + format = RK730_DI2S_TXCR1_TFS_TX_PCM | RK730_DI2S_TXCR1_PBM_TX_DELAY1; break; default: return -EINVAL; } + snd_soc_component_update_bits(component, RK730_DI2S_RXCR1, mask, format); + snd_soc_component_update_bits(component, RK730_DI2S_TXCR1, mask, format); - return 0; + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_IB_NF: + val |= RK730_DI2S_CKM_SCLK_INVERTED; + break; + case SND_SOC_DAIFMT_NB_NF: + val |= RK730_DI2S_CKM_SCLK_NORMAL; + break; + default: + ret = -EINVAL; + } + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBS_CFS: + val |= RK730_DI2S_CKM_MST_SLAVE | RK730_DI2S_CKM_SCLK_DIS; + break; + case SND_SOC_DAIFMT_CBM_CFM: + val |= RK730_DI2S_CKM_MST_MASTER | RK730_DI2S_CKM_SCLK_EN; + break; + default: + return -EINVAL; + } + snd_soc_component_update_bits(component, RK730_DI2S_CKM, + RK730_DI2S_CKM_MST_MASK | + RK730_DI2S_CKM_SCLK_POL_MASK | + RK730_DI2S_CKM_SCLK_EN_MASK, + val); + return ret; } -static int rk730_dai_mute(struct snd_soc_dai *codec_dai, int mute, int direction) +static int rk730_dai_mute(struct snd_soc_dai *codec_dai, int mute, int stream) { struct snd_soc_component *component = codec_dai->component; - if (mute) - snd_soc_component_update_bits(component, RK730_DDAC_MUTE_MIXCTL, - RK730_DDAC_MUTE_MIXCTL_MUTE_MASK, - RK730_DDAC_MUTE_MIXCTL_MUTE); - else - snd_soc_component_update_bits(component, RK730_DDAC_MUTE_MIXCTL, - RK730_DDAC_MUTE_MIXCTL_MUTE_MASK, - RK730_DDAC_MUTE_MIXCTL_UNMUTE); + dev_dbg(component->dev, "%s %d stream %d\n", __func__, mute, stream); + if (stream == SNDRV_PCM_STREAM_PLAYBACK) { + if (mute) { + snd_soc_component_update_bits(component, RK730_DADC_SEL, + RK730_DADC_DAC_MUTE_MASK, + RK730_DADC_DAC_MUTE); + } else { + snd_soc_component_update_bits(component, RK730_DADC_SEL, + RK730_DADC_DAC_MUTE_MASK, + RK730_DADC_DAC_UNMUTE); + } + } else { + if (mute) { + snd_soc_component_update_bits(component, RK730_DADC_SEL, + RK730_DADC_ADC_MUTE_MASK, + RK730_DADC_ADC_L_MUTE | + RK730_DADC_ADC_R_MUTE); + } else { + snd_soc_component_update_bits(component, RK730_DADC_SEL, + RK730_DADC_ADC_MUTE_MASK, + RK730_DADC_ADC_L_UNMUTE | + RK730_DADC_ADC_R_UNMUTE); + } + } return 0; } @@ -744,7 +818,6 @@ static const struct snd_soc_dai_ops rk730_dai_ops = { .set_fmt = rk730_dai_set_fmt, .hw_params = rk730_dai_hw_params, .mute_stream = rk730_dai_mute, - .no_capture_mute = 1, }; static struct snd_soc_dai_driver rk730_dai = { @@ -771,26 +844,19 @@ static int rk730_reset(struct snd_soc_component *component) struct rk730_priv *rk730 = snd_soc_component_get_drvdata(component); clk_prepare_enable(rk730->mclk); - snd_soc_component_write(component, RK730_DTOP_LPT_SRST, 0x40); udelay(10); /* WA: Initial micbias default, ADC stopped with micbias(>2.5v) */ snd_soc_component_update_bits(component, RK730_MIC_BIAS, - RK730_MIC_BIAS_VOLT_MASK, - RK730_MIC_BIAS_VOLT_2_2V); - /* PF: Use the maximum bias current for better performance */ - snd_soc_component_update_bits(component, RK730_HK_TOP_1, - RK730_HK_TOP_1_IBIAS_STD_SEL_MASK | - RK730_HK_TOP_1_IBIAS_GAIN_SEL_MASK, - RK730_HK_TOP_1_IBIAS_STD_SEL_27_5UA | - RK730_HK_TOP_1_IBIAS_GAIN_SEL_200); + RK730_MIC_BIAS_VOLT_MASK, + RK730_MIC_BIAS_VOLT_2_2V); /* PF: Use the chop 400kHz for better ADC noise performance */ snd_soc_component_update_bits(component, RK730_MIC_BOOST_3, - RK730_MIC_BOOST_3_MIC_CHOP_MASK, - RK730_MIC_BOOST_3_MIC_CHOP(RK730_CHOP_FREQ_400KHZ)); + RK730_MIC_BOOST_3_MIC_CHOP_MASK, + RK730_MIC_BOOST_3_MIC_CHOP(RK730_CHOP_FREQ_400KHZ)); snd_soc_component_update_bits(component, RK730_ADC_PGA_BLOCK_1, - RK730_ADC_PGA_BLOCK_1_PGA_CHOP_MASK, - RK730_ADC_PGA_BLOCK_1_PGA_CHOP(RK730_CHOP_FREQ_400KHZ)); - + RK730_ADC_PGA_BLOCK_1_PGA_CHOP_MASK, + RK730_ADC_PGA_BLOCK_1_PGA_CHOP(RK730_CHOP_FREQ_400KHZ)); + snd_soc_component_write(component, RK730_SYSPLL_3, 0x64); clk_disable_unprepare(rk730->mclk); return 0; @@ -833,83 +899,104 @@ static const struct snd_soc_component_driver rk730_component_driver = { }; static const struct reg_default rk730_reg_defaults[] = { - { 0x00, 0x40 }, - { 0x02, 0x17 }, - { 0x05, 0x03 }, - { 0x06, 0x22 }, - { 0x07, 0x02 }, - { 0x08, 0x07 }, - { 0x09, 0x01 }, - { 0x0a, 0x01 }, - { 0x0b, 0x01 }, - { 0x0c, 0x01 }, - { 0x0d, 0x01 }, - { 0x0e, 0x01 }, - { 0x0f, 0x07 }, - { 0x10, 0x07 }, - { 0x11, 0xff }, - { 0x12, 0x07 }, - { 0x13, 0x54 }, - { 0x14, 0x04 }, - { 0x15, 0x23 }, - { 0x16, 0x35 }, - { 0x17, 0x67 }, - { 0x18, 0x1e }, - { 0x19, 0xc0 }, - { 0x1a, 0x13 }, - { 0x1b, 0x04 }, - { 0x1c, 0x20 }, - { 0x1f, 0x90 }, - { 0x20, 0x11 }, - { 0x21, 0x09 }, - { 0x22, 0x33 }, - { 0x24, 0x11 }, - { 0x25, 0x11 }, - { 0x26, 0x09 }, - { 0x27, 0x02 }, - { 0x28, 0x2c }, - { 0x2a, 0x0c }, - { 0x2b, 0x80 }, - { 0x40, 0x03 }, - { 0x42, 0x20 }, - { 0x47, 0xe6 }, - { 0x48, 0xd0 }, - { 0x49, 0x17 }, - { 0x4a, 0x26 }, - { 0x4b, 0x01 }, - { 0x4c, 0x05 }, - { 0x4d, 0x0e }, - { 0x4e, 0x09 }, - { 0x4f, 0x02 }, - { 0x5b, 0xe6 }, - { 0x5c, 0xd0 }, - { 0x5d, 0x17 }, - { 0x5e, 0x26 }, - { 0x5f, 0x01 }, - { 0x60, 0x05 }, - { 0x61, 0x0e }, - { 0x62, 0x09 }, - { 0x63, 0x20 }, - { 0x66, 0x01 }, - { 0x69, 0x17 }, - { 0x6c, 0x17 }, + {0x00, 0x08}, + {0x01, 0xc0}, + {0x02, 0x00}, + {0x03, 0x00}, + {0x04, 0x03}, + {0x05, 0x42}, + {0x06, 0x02}, + {0x07, 0x05}, + {0x08, 0x07}, + {0x09, 0x70}, + {0x0a, 0x01}, + {0x0b, 0x01}, + {0x0c, 0x01}, + {0x0d, 0x01}, + {0x0e, 0x01}, + {0x0f, 0x01}, + {0x10, 0xff}, + {0x11, 0x07}, + {0x12, 0x54}, + {0x13, 0x04}, + {0x14, 0x23}, + {0x15, 0x35}, + {0x16, 0x67}, + {0x17, 0x1e}, + {0x18, 0xc0}, + {0x19, 0x13}, + {0x1a, 0x04}, + {0x1b, 0x20}, + {0x1c, 0x00}, + {0x1d, 0x00}, + {0x1e, 0x90}, + {0x1f, 0x11}, + {0x20, 0x09}, + {0x21, 0xac}, + {0x22, 0x80}, + {0x23, 0x00}, + {0x24, 0xac}, + {0x25, 0x80}, + {0x26, 0x00}, + {0x27, 0x00}, + {0x28, 0x20}, + {0x29, 0x00}, + {0x40, 0x00}, + {0x41, 0x00}, + {0x42, 0x00}, + {0x43, 0x88}, + {0x44, 0x01}, + {0x45, 0xff}, + {0x46, 0x00}, + {0x47, 0x00}, + {0x48, 0x00}, + {0x49, 0x00}, + {0x4a, 0x00}, + {0x4b, 0x00}, + {0x4c, 0xff}, + {0x4d, 0xff}, + {0x4e, 0x1e}, + {0x4f, 0xf4}, + {0x50, 0x00}, + {0x51, 0x00}, + {0x52, 0x1f}, + {0x53, 0x1f}, + {0x54, 0x02}, + {0x55, 0x00}, + {0x56, 0xc0}, + {0x57, 0x06}, + {0x58, 0x60}, + {0x59, 0x07}, + {0x5a, 0x03}, + {0x5b, 0x00}, + {0x5c, 0x03}, + {0x5d, 0x66}, + {0x5e, 0x9a}, + {0x5f, 0xcc}, + {0x60, 0x1f}, + {0x61, 0xcc}, + {0x62, 0x0e}, + {0x63, 0x08}, + {0x64, 0x06}, + {0x65, 0x02}, + {0x66, 0x05}, + {0x67, 0x01}, + {0x68, 0x00}, + {0x69, 0x01}, + {0x6a, 0x00}, + {0x6b, 0x00}, + {0x6c, 0x00}, + {0x6d, 0x17}, + {0x6e, 0x00}, + {0x6f, 0x00}, + {0x70, 0x17}, + {0x71, 0x00}, }; -static bool rk730_volatile_register(struct device *dev, unsigned int reg) -{ - switch (reg) { - case RK730_DTOP_LPT_SRST: - return true; - default: - return false; - } -} - static const struct regmap_config rk730_regmap = { .reg_bits = 8, .val_bits = 8, - .volatile_reg = rk730_volatile_register, - .max_register = RK730_DAC_ATTN, + .max_register = RK730_DI2S_TXCR3_TXCMD, .reg_defaults = rk730_reg_defaults, .num_reg_defaults = ARRAY_SIZE(rk730_reg_defaults), .cache_type = REGCACHE_RBTREE, diff --git a/sound/soc/codecs/rk730.h b/sound/soc/codecs/rk730.h index b06f81828bb4..b9ad4857e20f 100644 --- a/sound/soc/codecs/rk730.h +++ b/sound/soc/codecs/rk730.h @@ -12,98 +12,101 @@ #define RK730_HK_TOP_0 0x00 #define RK730_HK_TOP_1 0x01 #define RK730_HK_TOP_2 0x02 -#define RK730_HK_TRIM_0 0x03 -#define RK730_HK_TRIM_1 0x04 -#define RK730_ADC_0 0x05 -#define RK730_ADC_1 0x06 -#define RK730_ADC_2 0x07 +#define RK730_HK_TRIM 0x03 +#define RK730_ADC_0 0x04 +#define RK730_ADC_1 0x05 +#define RK730_ADC_2 0x06 +#define RK730_ADC_3 0x07 #define RK730_DAC_0 0x08 #define RK730_DAC_1 0x09 -#define RK730_DAC_2 0x0a -#define RK730_MIC_BOOST_0 0x0b -#define RK730_MIC_BOOST_1 0x0c -#define RK730_MIC_BOOST_2 0x0d -#define RK730_MIC_BOOST_3 0x0e -#define RK730_ADC_PGA_BLOCK_0 0x0f -#define RK730_ADC_PGA_BLOCK_1 0x10 -#define RK730_SYSPLL_0 0x11 -#define RK730_SYSPLL_1 0x12 -#define RK730_SYSPLL_2 0x13 -#define RK730_SYSPLL_3 0x14 -#define RK730_SYSPLL_LOOP_0 0x15 -#define RK730_SYSPLL_LOOP_1 0x16 -#define RK730_SYSPLL_LOOP_2 0x17 -#define RK730_SYSPLL_LOOP_3 0x18 -#define RK730_SYSPLL_RVCO_0 0x19 -#define RK730_SYSPLL_RVCO_1 0x1a -#define RK730_SYSPLL_RVCO_2 0x1b -#define RK730_SYSPLL_RVCO_3 0x1c -#define RK730_SYSPLL_FRACT_0 0x1d -#define RK730_SYSPLL_FRACT_1 0x1e -#define RK730_SYSPLL_FRACT_2 0x1f -#define RK730_LDO 0x20 -#define RK730_MIC_BIAS 0x21 -#define RK730_MUXER_0 0x22 -#define RK730_MUXER_1 0x23 -#define RK730_MIXER_0 0x24 -#define RK730_MIXER_1 0x25 -#define RK730_MIXER_2 0x26 -#define RK730_CHARGE_PUMP 0x27 -#define RK730_HP_0 0x28 -#define RK730_HP_1 0x29 -#define RK730_LINEOUT_0 0x2a -#define RK730_LINEOUT_1 0x2b - +#define RK730_MIC_BOOST_0 0x0a +#define RK730_MIC_BOOST_1 0x0b +#define RK730_MIC_BOOST_2 0x0c +#define RK730_MIC_BOOST_3 0x0d +#define RK730_ADC_PGA_BLOCK_0 0x0e +#define RK730_ADC_PGA_BLOCK_1 0x0f +#define RK730_SYSPLL_0 0x10 +#define RK730_SYSPLL_1 0x11 +#define RK730_SYSPLL_2 0x12 +#define RK730_SYSPLL_3 0x13 +#define RK730_SYSPLL_LOOP_0 0x14 +#define RK730_SYSPLL_LOOP_1 0x15 +#define RK730_SYSPLL_LOOP_2 0x16 +#define RK730_SYSPLL_LOOP_3 0x17 +#define RK730_SYSPLL_RVCO_0 0x18 +#define RK730_SYSPLL_RVCO_1 0x19 +#define RK730_SYSPLL_RVCO_2 0x1a +#define RK730_SYSPLL_RVCO_3 0x1b +#define RK730_SYSPLL_FRACT_0 0x1c +#define RK730_SYSPLL_FRACT_1 0x1d +#define RK730_SYSPLL_FRACT_2 0x1e +#define RK730_LDO 0x1f +#define RK730_MIC_BIAS 0x20 +/* SPK->LOUT1 HP -> LOUT2*/ +#define RK730_HP_0 0x21 +#define RK730_HP_1 0x22 +#define RK730_HP_2 0x23 +#define RK730_SPK_0 0x24 +#define RK730_SPK_1 0x25 +#define RK730_REG_REDG_0 0x26 +#define RK730_REG_REDG_1 0x27 +#define RK730_REG_REDG_2 0x28 +#define RK730_TEST 0x29 /* RK730 Digital Registers Definition */ -#define RK730_DTOP_VUCTL 0x40 -#define RK730_DTOP_VUCTIME 0x41 -#define RK730_DTOP_LPT_SRST 0x42 -#define RK730_DTOP_DIGEN_CLKE 0x43 -#define RK730_DADC_VOLL 0x44 -#define RK730_DADC_VOLR 0x45 -#define RK730_DADC_SR_ACL 0x46 -#define RK730_DADC_PR_0 0x47 -#define RK730_DADC_PR_1 0x48 -#define RK730_DADC_PR_2 0x49 -#define RK730_DADC_PR_3 0x4a -#define RK730_DADC_NG_0 0x4b -#define RK730_DADC_NG_1 0x4c -#define RK730_DADC_NG_2 0x4d -#define RK730_DADC_NG_3 0x4e -#define RK730_DADC_CICCOMP 0x4f -#define RK730_DADC_HPF 0x50 -#define RK730_DADC_RVOLL 0x51 -#define RK730_DADC_RVOLR 0x52 -#define RK730_DMIC_LMT_1 0x53 -#define RK730_DMIC_LMT_2 0x54 -#define RK730_DMIC_NG_1 0x55 -#define RK730_DMIC_NG_2 0x56 -#define RK730_DDAC_POPD_DACST 0x57 -#define RK730_DDAC_VOLL 0x58 -#define RK730_DDAC_VOLR 0x59 -#define RK730_DDAC_SR_LMT 0x5a -#define RK730_DDAC_PR_0 0x5b -#define RK730_DDAC_PR_1 0x5c -#define RK730_DDAC_PR_2 0x5d -#define RK730_DDAC_PR_3 0x5e -#define RK730_DDAC_NG_0 0x5f -#define RK730_DDAC_NG_1 0x60 -#define RK730_DDAC_NG_2 0x61 -#define RK730_DDAC_NG_3 0x62 -#define RK730_DDAC_MUTE_MIXCTL 0x63 -#define RK730_DDAC_RVOLL 0x64 -#define RK730_DDAC_RVOLR 0x65 -#define RK730_DI2S_CKM 0x66 -#define RK730_DI2S_RSD 0x67 -#define RK730_DI2S_RXCR_1 0x68 -#define RK730_DI2S_RXCR_2 0x69 -#define RK730_DI2S_RXCMD_TSD 0x6a -#define RK730_DI2S_TXCR_1 0x6b -#define RK730_DI2S_TXCR_2 0x6c -#define RK730_DI2S_TXCR_3_TXCMD 0x6d -#define RK730_DAC_ATTN 0x6e +#define RK730_DTOP_DIGEN_CLKE 0x40 +#define RK730_DTOP_SRT 0x41 +#define RK730_DADC_SEL 0x42 +#define RK730_DDAC_SEL 0x43 +#define RK730_DTOP_VUCTL 0x44 +#define RK730_DTOP_VUCTIME 0x45 +#define RK730_DADC_VOLL 0x46 +#define RK730_DADC_VOLR 0x47 +#define RK730_DDAC_VOLL 0x48 +#define RK730_DDAC_VOLR 0x49 +#define RK730_DADC_RVOLL 0x4a +#define RK730_DADC_RVOLR 0x4b +#define RK730_DDAC_RVOLL 0x4c +#define RK730_DDAC_RVOLR 0x4d +#define RK730_DADC_FILTER 0x4e +#define RK730_DDAC_FILTER 0x4f +#define RK730_DDAC_PREL 0x50 +#define RK730_DDAC_PRER 0x51 +#define RK730_DDAC_POSTL 0x52 +#define RK730_DDAC_POSTR 0x53 +#define RK730_DADC_AGC0 0x54 +#define RK730_DADC_AGC1 0x55 +#define RK730_DADC_AGC2 0x56 +#define RK730_DADC_AGC3 0x57 +#define RK730_DADC_AGC4 0x58 +#define RK730_DADC_AGC5 0x59 +#define RK730_DADC_AGC6 0x5a +#define RK730_DADC_AGC7 0x5b +#define RK730_DADC_AGC8 0x5c +#define RK730_DADC_AGC9 0x5d +#define RK730_DDAC_DRC0 0x5e +#define RK730_DDAC_DRC1 0x5f +#define RK730_DDAC_DRC2 0x60 +#define RK730_DDAC_DRC3 0x61 +#define RK730_DDAC_DRC4 0x62 +#define RK730_DDAC_DRC5 0x63 +#define RK730_DDAC_DRC6 0x64 +#define RK730_DDAC_DRC7 0x65 +#define RK730_DDAC_DRC8 0x66 +#define RK730_DDAC_DRC9 0x67 +#define RK730_READ1 0x68 +#define RK730_DI2S_CKM 0x69 +#define RK730_DI2S_OFFSET 0x6a +#define RK730_DI2S_RSD 0x6b +#define RK730_DI2S_RXCR1 0x6c +#define RK730_DI2S_RXCR2 0x6d +#define RK730_DI2S_RXCMD_TSD 0x6e +#define RK730_DI2S_TXCR1 0x6f +#define RK730_DI2S_TXCR2 0x70 +#define RK730_DI2S_TXCR3_TXCMD 0x71 /* RK730_HK_TOP_1 */ +#define RK730_HK_TOP_1_HK_PWD_VAG_BUF BIT(7) +#define RK730_HK_TOP_1_HK_PWD_DAC_BUF BIT(6) #define RK730_HK_TOP_1_DAC_REF_BUF_CHOP_MASK GENMASK(7, 6) #define RK730_HK_TOP_1_DAC_REF_BUF_CHOP(x) ((x) << 6) #define RK730_HK_TOP_1_IBIAS_STD_SEL_MASK GENMASK(5, 4) @@ -123,9 +126,34 @@ #define RK730_HK_TOP_1_IBIAS_GAIN_SEL_32 7 /* RK730_ADC_0 */ -#define RK730_ADC_0_DEM_EN_MASK BIT(3) -#define RK730_ADC_0_DEM_EN BIT(3) -#define RK730_ADC_0_DEM_DIS 0 +#define RK730_ADC_INT_RESET_SIGNAL BIT(2) +#define RK730_ADCR_PWR_MASK BIT(1) +#define RK730_ADCR_PWR_UP BIT(0) +#define RK730_ADCR_PWR_DOWN BIT(1) +#define RK730_ADCL_PWR_MASK BIT(0) +#define RK730_ADCL_PWR_UP BIT(0) +#define RK730_ADCL_PWR_DOWN BIT(1) +/* RK730_DAC_0 */ +#define RK730_DAC_0_DAC_HP_IBIAS_MASK BIT(2) +#define RK730_DAC_0_DAC_HP_IBIAS_OFF BIT(2) +#define RK730_DAC_0_DAC_HP_IBIAS_ON 0 +#define RK730_DAC_0_DAC_R_HP_PWD_MASK BIT(1) +#define RK730_DAC_0_DAC_R_HP_PWD BIT(1) +#define RK730_DAC_0_DAC_R_HP_PWU 0 +#define RK730_DAC_0_DAC_L_HP_PWD_MASK BIT(0) +#define RK730_DAC_0_DAC_L_HP_PWD BIT(0) +#define RK730_DAC_0_DAC_L_HP_PWU 0 + +/* RK730_DAC_1 */ +#define RK730_DAC_1_DAC_SPK_IBIAS_MASK BIT(6) +#define RK730_DAC_1_DAC_SPK_IBIAS_OFF BIT(6) +#define RK730_DAC_1_DAC_SPK_IBIAS_ON 0 +#define RK730_DAC_1_DAC_R_SPK_PWD_MASK BIT(5) +#define RK730_DAC_1_DAC_R_SPK_PWD BIT(5) +#define RK730_DAC_1_DAC_R_SPK_PWU 0 +#define RK730_DAC_1_DAC_L_SPK_PWD_MASK BIT(4) +#define RK730_DAC_1_DAC_L_SPK_PWD BIT(4) +#define RK730_DAC_1_DAC_L_SPK_PWU 0 /* RK730_MIC_BOOST_3 */ #define RK730_MIC_BOOST_3_MIC_CHOP_MASK GENMASK(7, 6) @@ -142,6 +170,40 @@ #define RK730_MIC_BIAS_VOLT_2_2V (1 << 2) #define RK730_MIC_BIAS_VOLT_2_0V (0 << 2) +/* RK730_HP_0 */ +#define RK730_HP_0_ANTIPOP_PWR_MASK BIT(7) +#define RK730_HP_0_ANTIPOP_PWR_OFF BIT(7) +#define RK730_HP_0_ANTIPOP_PWR_ON 0 +#define RK730_HP_0_HP_IBIAS_MASK BIT(5) +#define RK730_HP_0_HP_IBIAS_OFF BIT(5) +#define RK730_HP_0_HP_IBIAS_ON 0 +#define RK730_HP_0_HP_TWOTAGE_EN_MASK BIT(4) +#define RK730_HP_0_HP_TWOTAGE_EN BIT(4) +#define RK730_HP_0_HP_TWOTAGE_DIS 0 +#define RK730_HP_0_HP_OSTG_PWR_MASK BIT(3) +#define RK730_HP_0_HP_OSTG_PWR_OFF BIT(3) +#define RK730_HP_0_HP_OSTG_PWR_ON 0 +#define RK730_HP_0_HP_BLOCK_PWR_MASK BIT(2) +#define RK730_HP_0_HP_BLOCK_PWR_OFF BIT(2) +#define RK730_HP_0_HP_BLOCK_PWR_ON 0 + +/* RK730_SPK_0 */ +#define RK730_SPK_0_ANTIPOP_PWR_MASK BIT(7) +#define RK730_SPK_0_ANTIPOP_PWR_OFF BIT(7) +#define RK730_SPK_0_ANTIPOP_PWR_ON 0 +#define RK730_SPK_0_SPK_IBIAS_MASK BIT(5) +#define RK730_SPK_0_SPK_IBIAS_OFF BIT(5) +#define RK730_SPK_0_SPK_IBIAS_ON 0 +#define RK730_SPK_0_SPK_TWOTAGE_EN_MASK BIT(4) +#define RK730_SPK_0_SPK_TWOTAGE_EN BIT(4) +#define RK730_SPK_0_SPK_TWOTAGE_DIS 0 +#define RK730_SPK_0_SPK_OSTAGE_PWR_MASK BIT(3) +#define RK730_SPK_0_SPK_OSTAGE_PWR_OFF BIT(3) +#define RK730_SPK_0_SPK_OSTAGE_PWR_ON 0 +#define RK730_SPK_0_SPK_BLOCK_PWR_MASK BIT(2) +#define RK730_SPK_0_SPK_BLOCK_PWR_OFF BIT(2) +#define RK730_SPK_0_SPK_BLOCK_PWR_ON 0 + /* RK730_MUXER_1 */ #define RK730_MUXER_1_MUX_OUT_CHOP_MASK GENMASK(1, 0) #define RK730_MUXER_1_MUX_OUT_CHOP(x) ((x) << 0) @@ -184,6 +246,19 @@ #define RK730_DTOP_DIGEN_CLKE_I2SRX_EN BIT(0) #define RK730_DTOP_DIGEN_CLKE_I2SRX_DIS 0 +/* RK730_DTOP_SRT */ +#define RK730_DTOP_DACSRT_MASK GENMASK(6, 4) +#define RK730_DTOP_DACSRT(x) ((x) << 4) +#define RK730_DTOP_ADCSRT_MASK GENMASK(2, 0) +#define RK730_DTOP_ADCSRT(x) (x) + +/* RK730_DTOP_VUCTL */ +#define RK730_DTOP_VUCTL_ADC_BYPS BIT(7) +#define RK730_DTOP_VUCTL_DAC_BYPS BIT(6) +#define RK730_DTOP_VUCTL_DAC_LV_POL BIT(3) +#define RK730_DTOP_VUCTL_DAC_RV_POL BIT(2) +#define RK730_DTOP_VUCTL_DACZDT BIT(0) + /* RK730_DADC_SR_ACL */ #define RK730_DADC_SR_ACL_VOLL_POL_MASK BIT(5) #define RK730_DADC_SR_ACL_VOLL_POS BIT(5) @@ -194,42 +269,79 @@ #define RK730_DADC_SR_ACL_SRT_MASK GENMASK(2, 0) #define RK730_DADC_SR_ACL_SRT(x) (x) -/* RK730_DDAC_SR_LMT */ -#define RK730_DDAC_SR_LMT_VOLL_POL_MASK BIT(5) -#define RK730_DDAC_SR_LMT_VOLL_POS BIT(5) -#define RK730_DDAC_SR_LMT_VOLL_NEG 0 -#define RK730_DDAC_SR_LMT_VOLR_POL_MASK BIT(4) -#define RK730_DDAC_SR_LMT_VOLR_POS BIT(4) -#define RK730_DDAC_SR_LMT_VOLR_NEG 0 -#define RK730_DDAC_SR_LMT_SRT_MASK GENMASK(2, 0) -#define RK730_DDAC_SR_LMT_SRT(x) (x) - /* RK730_DDAC_MUTE_MIXCTL */ -#define RK730_DDAC_MUTE_MIXCTL_MUTE_MASK BIT(0) -#define RK730_DDAC_MUTE_MIXCTL_MUTE BIT(0) -#define RK730_DDAC_MUTE_MIXCTL_UNMUTE 0 +#define RK730_DADC_DAC_MUTE_MASK BIT(4) +#define RK730_DADC_DAC_MUTE BIT(4) +#define RK730_DADC_DAC_UNMUTE 0 +#define RK730_DADC_ADC_MUTE_MASK GENMASK(3, 2) +#define RK730_DADC_ADC_R_MUTE_MASK BIT(3) +#define RK730_DADC_ADC_R_MUTE BIT(3) +#define RK730_DADC_ADC_R_UNMUTE 0 +#define RK730_DADC_ADC_L_MUTE_MASK BIT(2) +#define RK730_DADC_ADC_L_MUTE BIT(2) +#define RK730_DADC_ADC_L_UNMUTE 0 +#define RK730_DADC_ADC_DATESEL GENMASK(1, 0) +#define RK730_DADC_ADC_DATESEL_NORMAL ((0) << 0) +#define RK730_DADC_ADC_DATESEL_LEFT ((1) << 0) +#define RK730_DADC_ADC_DATESEL_RIGHT ((2) << 0) +#define RK730_DADC_ADC_DATESEL_SWAP ((3) << 0) /* RK730_DI2S_CKM */ #define RK730_DI2S_CKM_SCLK_DIV_MASK GENMASK(7, 4) #define RK730_DI2S_CKM_SCLK_DIV(x) ((x - 1) << 4) -#define RK730_DI2S_CKM_SCLK_EN_MASK BIT(2) -#define RK730_DI2S_CKM_SCLK_EN BIT(2) -#define RK730_DI2S_CKM_SCLK_DIS 0 -#define RK730_DI2S_CKM_SCLK_POL_MASK BIT(1) -#define RK730_DI2S_CKM_SCLK_INVERTED BIT(1) -#define RK730_DI2S_CKM_SCLK_NORMAL 0 -#define RK730_DI2S_CKM_MST_MASK BIT(0) -#define RK730_DI2S_CKM_MST_MASTER BIT(0) -#define RK730_DI2S_CKM_MST_SLAVE 0 -/* RK730_DI2S_XCR2 */ -#define RK730_DI2S_XCR2_VDW_MASK GENMASK(4, 0) -#define RK730_DI2S_XCR2_VDW(x) (x - 1) +#define RK730_DI2S_CKM_SCLK_EN_MASK BIT(3) +#define RK730_DI2S_CKM_SCLK_EN BIT(3) +#define RK730_DI2S_CKM_SCLK_DIS 0 +#define RK730_DI2S_CKM_SCLK_POL_MASK BIT(2) +#define RK730_DI2S_CKM_SCLK_INVERTED BIT(2) +#define RK730_DI2S_CKM_SCLK_NORMAL 0 +#define RK730_DI2S_CKM_MST_MASK GENMASK(1, 0) +#define RK730_DI2S_CKM_MST_MASTER ((0x03) << 0) +#define RK730_DI2S_CKM_MST_SLAVE 0 +#define RK730_DI2S_RX_CKM_MST_MASK BIT(1) +#define RK730_DI2S_RX_CKM_MST_MASTER BIT(1) +#define RK730_DI2S_RX_CKM_MST_SLAVE 0 +#define RK730_DI2S_TX_CKM_MST_MASK BIT(0) +#define RK730_DI2S_TX_CKM_MST_MASTER BIT(0) +#define RK730_DI2S_TX_CKM_MST_SLAVE 0 + + +/* RK730_DI2S_TXCR1 */ +#define RK730_DI2S_TXCR1_TFS_TX_MASK BIT(6) +#define RK730_DI2S_TXCR1_TFS_TX_I2S 0 +#define RK730_DI2S_TXCR1_TFS_TX_PCM BIT(6) +#define RK730_DI2S_TXCR1_PBM_TX_MASK GENMASK(5, 4) +#define RK730_DI2S_TXCR1_PBM_TX_NODELAY ((0x00) << 4) +#define RK730_DI2S_TXCR1_PBM_TX_DELAY1 ((0x01) << 4) +#define RK730_DI2S_TXCR1_PBM_TX_DELAY2 ((0x02) << 4) +#define RK730_DI2S_TXCR1_PBM_TX_DELAY3 ((0x03) << 4) +#define RK730_DI2S_TXCR1_IBM_TX_MASK GENMASK(3, 2) +#define RK730_DI2S_TXCR1_IBM_TX_NORMAL ((0x00) << 2) +#define RK730_DI2S_TXCR1_IBM_TX_LEFT ((0x01) << 2) +#define RK730_DI2S_TXCR1_IBM_TX_RIGHT ((0x02) << 2) +#define RK730_DI2S_TXCR1_EXRL_TX_MASK BIT(1) +#define RK730_DI2S_TXCR1_EXRL_TX_NORMAL 0 +#define RK730_DI2S_TXCR1_EXRL_SWAP BIT(1) +#define RK730_DI2S_TXCR1_ALN_MASK BIT(0) +#define RK730_DI2S_TXCR1_LSB 0 +#define RK730_DI2S_TXCR1_MSB BIT(0) + +/* RK730_DI2S_RXCR2 */ +#define RK730_DI2S_RXCR2_VDW_MASK GENMASK(4, 0) +#define RK730_DI2S_RXCR2_VDW(x) (x - 1) /* RK730_DI2S_RXCMD_TSD */ -#define RK730_DI2S_RXCMD_TSD_RXS_MASK BIT(5) -#define RK730_DI2S_RXCMD_TSD_RXS_EN BIT(5) +#define RK730_DI2S_RXCMD_TSD_RXS_MASK BIT(7) +#define RK730_DI2S_RXCMD_TSD_RXS_EN BIT(7) #define RK730_DI2S_RXCMD_TSD_RXS_DIS 0 +#define RK730_DI2S_RXCMD_TSD_RXC_MASK BIT(7) +#define RK730_DI2S_RXCMD_TSD_RXC_EN BIT(7) +#define RK730_DI2S_RXCMD_TSD_RXC_DIS 0 + +/* RK730_DI2S_TXCR2 */ +#define RK730_DI2S_TXCR2_VDW_MASK GENMASK(4, 0) +#define RK730_DI2S_TXCR2_VDW(x) (x - 1) /* RK730_DI2S_TXCR_3_TXCMD */ #define RK730_DI2S_TXCR_3_TXCMD_TXS_MASK BIT(7)