diff options
author | Mark Brown <broonie@kernel.org> | 2015-06-05 18:54:46 +0100 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2015-06-05 18:54:46 +0100 |
commit | f3b368d3b9a22bb1ddc80808a64ecb7559791e87 (patch) | |
tree | ffe7f0c236b24d441fd779a839f7a1224e6be8e6 /sound | |
parent | 977732b06045a508edc7b105e9fef524163616df (diff) | |
parent | 345b0f50e74671fd8299e26c73ab50c5a0cf6ed9 (diff) |
Merge remote-tracking branch 'asoc/topic/rt5645' into asoc-next
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/codecs/rt5645.c | 1078 | ||||
-rw-r--r-- | sound/soc/codecs/rt5645.h | 30 | ||||
-rw-r--r-- | sound/soc/intel/boards/cht_bsw_rt5645.c | 2 |
3 files changed, 847 insertions, 263 deletions
diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index 5da29374cd1d..d5f0f5680d3b 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -18,7 +18,9 @@ #include <linux/platform_device.h> #include <linux/spi/spi.h> #include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/acpi.h> +#include <linux/dmi.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> @@ -415,9 +417,9 @@ static bool rt5645_readable_register(struct device *dev, unsigned int reg) } static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -4650, 150, 0); -static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -65625, 375, 0); +static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -6525, 75, 0); static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0); -static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -17625, 375, 0); +static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -1725, 75, 0); static const DECLARE_TLV_DB_SCALE(adc_bst_tlv, 0, 1200, 0); /* {0, +20, +24, +30, +35, +40, +44, +50, +52} dB */ @@ -432,30 +434,6 @@ static unsigned int bst_tlv[] = { 8, 8, TLV_DB_SCALE_ITEM(5200, 0, 0), }; -static const char * const rt5645_tdm_data_swap_select[] = { - "L/R", "R/L", "L/L", "R/R" -}; - -static SOC_ENUM_SINGLE_DECL(rt5645_tdm_adc_slot0_1_enum, - RT5645_TDM_CTRL_1, 6, rt5645_tdm_data_swap_select); - -static SOC_ENUM_SINGLE_DECL(rt5645_tdm_adc_slot2_3_enum, - RT5645_TDM_CTRL_1, 4, rt5645_tdm_data_swap_select); - -static SOC_ENUM_SINGLE_DECL(rt5645_tdm_adc_slot4_5_enum, - RT5645_TDM_CTRL_1, 2, rt5645_tdm_data_swap_select); - -static SOC_ENUM_SINGLE_DECL(rt5645_tdm_adc_slot6_7_enum, - RT5645_TDM_CTRL_1, 0, rt5645_tdm_data_swap_select); - -static const char * const rt5645_tdm_adc_data_select[] = { - "1/2/R", "2/1/R", "R/1/2", "R/2/1" -}; - -static SOC_ENUM_SINGLE_DECL(rt5645_tdm_adc_sel_enum, - RT5645_TDM_CTRL_1, 8, - rt5645_tdm_adc_data_select); - static const struct snd_kcontrol_new rt5645_snd_controls[] = { /* Speaker Output Volume */ SOC_DOUBLE("Speaker Channel Switch", RT5645_SPK_VOL, @@ -481,9 +459,9 @@ static const struct snd_kcontrol_new rt5645_snd_controls[] = { SOC_DOUBLE("DAC2 Playback Switch", RT5645_DAC_CTRL, RT5645_M_DAC_L2_VOL_SFT, RT5645_M_DAC_R2_VOL_SFT, 1, 1), SOC_DOUBLE_TLV("DAC1 Playback Volume", RT5645_DAC1_DIG_VOL, - RT5645_L_VOL_SFT, RT5645_R_VOL_SFT, 175, 0, dac_vol_tlv), + RT5645_L_VOL_SFT + 1, RT5645_R_VOL_SFT + 1, 87, 0, dac_vol_tlv), SOC_DOUBLE_TLV("Mono DAC Playback Volume", RT5645_DAC2_DIG_VOL, - RT5645_L_VOL_SFT, RT5645_R_VOL_SFT, 175, 0, dac_vol_tlv), + RT5645_L_VOL_SFT + 1, RT5645_R_VOL_SFT + 1, 87, 0, dac_vol_tlv), /* IN1/IN2 Control */ SOC_SINGLE_TLV("IN1 Boost", RT5645_IN1_CTRL1, @@ -499,11 +477,11 @@ static const struct snd_kcontrol_new rt5645_snd_controls[] = { SOC_DOUBLE("ADC Capture Switch", RT5645_STO1_ADC_DIG_VOL, RT5645_L_MUTE_SFT, RT5645_R_MUTE_SFT, 1, 1), SOC_DOUBLE_TLV("ADC Capture Volume", RT5645_STO1_ADC_DIG_VOL, - RT5645_L_VOL_SFT, RT5645_R_VOL_SFT, 127, 0, adc_vol_tlv), + RT5645_L_VOL_SFT + 1, RT5645_R_VOL_SFT + 1, 63, 0, adc_vol_tlv), SOC_DOUBLE("Mono ADC Capture Switch", RT5645_MONO_ADC_DIG_VOL, RT5645_L_MUTE_SFT, RT5645_R_MUTE_SFT, 1, 1), SOC_DOUBLE_TLV("Mono ADC Capture Volume", RT5645_MONO_ADC_DIG_VOL, - RT5645_L_VOL_SFT, RT5645_R_VOL_SFT, 127, 0, adc_vol_tlv), + RT5645_L_VOL_SFT + 1, RT5645_R_VOL_SFT + 1, 63, 0, adc_vol_tlv), /* ADC Boost Volume Control */ SOC_DOUBLE_TLV("STO1 ADC Boost Gain", RT5645_ADC_BST_VOL1, @@ -516,17 +494,6 @@ static const struct snd_kcontrol_new rt5645_snd_controls[] = { /* I2S2 function select */ SOC_SINGLE("I2S2 Func Switch", RT5645_GPIO_CTRL1, RT5645_I2S2_SEL_SFT, 1, 1), - - /* TDM */ - SOC_ENUM("TDM Adc Slot0 1 Data", rt5645_tdm_adc_slot0_1_enum), - SOC_ENUM("TDM Adc Slot2 3 Data", rt5645_tdm_adc_slot2_3_enum), - SOC_ENUM("TDM Adc Slot4 5 Data", rt5645_tdm_adc_slot4_5_enum), - SOC_ENUM("TDM Adc Slot6 7 Data", rt5645_tdm_adc_slot6_7_enum), - SOC_ENUM("TDM IF1 ADC DATA Sel", rt5645_tdm_adc_sel_enum), - SOC_SINGLE("TDM IF1_DAC1_L Sel", RT5645_TDM_CTRL_3, 12, 7, 0), - SOC_SINGLE("TDM IF1_DAC1_R Sel", RT5645_TDM_CTRL_3, 8, 7, 0), - SOC_SINGLE("TDM IF1_DAC2_L Sel", RT5645_TDM_CTRL_3, 4, 7, 0), - SOC_SINGLE("TDM IF1_DAC2_R Sel", RT5645_TDM_CTRL_3, 0, 7, 0), }; /** @@ -1093,7 +1060,8 @@ static const struct snd_kcontrol_new rt5645_mono_adc_r2_mux = /* MX-77 [9:8] */ static const char * const rt5645_if1_adc_in_src[] = { - "IF_ADC1", "IF_ADC2", "VAD_ADC" + "IF_ADC1/IF_ADC2/VAD_ADC", "IF_ADC2/IF_ADC1/VAD_ADC", + "VAD_ADC/IF_ADC1/IF_ADC2", "VAD_ADC/IF_ADC2/IF_ADC1" }; static SOC_ENUM_SINGLE_DECL( @@ -1103,6 +1071,140 @@ static SOC_ENUM_SINGLE_DECL( static const struct snd_kcontrol_new rt5645_if1_adc_in_mux = SOC_DAPM_ENUM("IF1 ADC IN source", rt5645_if1_adc_in_enum); +/* MX-78 [4:0] */ +static const char * const rt5650_if1_adc_in_src[] = { + "IF_ADC1/IF_ADC2/DAC_REF/Null", + "IF_ADC1/IF_ADC2/Null/DAC_REF", + "IF_ADC1/DAC_REF/IF_ADC2/Null", + "IF_ADC1/DAC_REF/Null/IF_ADC2", + "IF_ADC1/Null/DAC_REF/IF_ADC2", + "IF_ADC1/Null/IF_ADC2/DAC_REF", + + "IF_ADC2/IF_ADC1/DAC_REF/Null", + "IF_ADC2/IF_ADC1/Null/DAC_REF", + "IF_ADC2/DAC_REF/IF_ADC1/Null", + "IF_ADC2/DAC_REF/Null/IF_ADC1", + "IF_ADC2/Null/DAC_REF/IF_ADC1", + "IF_ADC2/Null/IF_ADC1/DAC_REF", + + "DAC_REF/IF_ADC1/IF_ADC2/Null", + "DAC_REF/IF_ADC1/Null/IF_ADC2", + "DAC_REF/IF_ADC2/IF_ADC1/Null", + "DAC_REF/IF_ADC2/Null/IF_ADC1", + "DAC_REF/Null/IF_ADC1/IF_ADC2", + "DAC_REF/Null/IF_ADC2/IF_ADC1", + + "Null/IF_ADC1/IF_ADC2/DAC_REF", + "Null/IF_ADC1/DAC_REF/IF_ADC2", + "Null/IF_ADC2/IF_ADC1/DAC_REF", + "Null/IF_ADC2/DAC_REF/IF_ADC1", + "Null/DAC_REF/IF_ADC1/IF_ADC2", + "Null/DAC_REF/IF_ADC2/IF_ADC1", +}; + +static SOC_ENUM_SINGLE_DECL( + rt5650_if1_adc_in_enum, RT5645_TDM_CTRL_2, + 0, rt5650_if1_adc_in_src); + +static const struct snd_kcontrol_new rt5650_if1_adc_in_mux = + SOC_DAPM_ENUM("IF1 ADC IN source", rt5650_if1_adc_in_enum); + +/* MX-78 [15:14][13:12][11:10] */ +static const char * const rt5645_tdm_adc_swap_select[] = { + "L/R", "R/L", "L/L", "R/R" +}; + +static SOC_ENUM_SINGLE_DECL(rt5650_tdm_adc_slot0_1_enum, + RT5645_TDM_CTRL_2, 14, rt5645_tdm_adc_swap_select); + +static const struct snd_kcontrol_new rt5650_if1_adc1_in_mux = + SOC_DAPM_ENUM("IF1 ADC1 IN source", rt5650_tdm_adc_slot0_1_enum); + +static SOC_ENUM_SINGLE_DECL(rt5650_tdm_adc_slot2_3_enum, + RT5645_TDM_CTRL_2, 12, rt5645_tdm_adc_swap_select); + +static const struct snd_kcontrol_new rt5650_if1_adc2_in_mux = + SOC_DAPM_ENUM("IF1 ADC2 IN source", rt5650_tdm_adc_slot2_3_enum); + +static SOC_ENUM_SINGLE_DECL(rt5650_tdm_adc_slot4_5_enum, + RT5645_TDM_CTRL_2, 10, rt5645_tdm_adc_swap_select); + +static const struct snd_kcontrol_new rt5650_if1_adc3_in_mux = + SOC_DAPM_ENUM("IF1 ADC3 IN source", rt5650_tdm_adc_slot4_5_enum); + +/* MX-77 [7:6][5:4][3:2] */ +static SOC_ENUM_SINGLE_DECL(rt5645_tdm_adc_slot0_1_enum, + RT5645_TDM_CTRL_1, 6, rt5645_tdm_adc_swap_select); + +static const struct snd_kcontrol_new rt5645_if1_adc1_in_mux = + SOC_DAPM_ENUM("IF1 ADC1 IN source", rt5645_tdm_adc_slot0_1_enum); + +static SOC_ENUM_SINGLE_DECL(rt5645_tdm_adc_slot2_3_enum, + RT5645_TDM_CTRL_1, 4, rt5645_tdm_adc_swap_select); + +static const struct snd_kcontrol_new rt5645_if1_adc2_in_mux = + SOC_DAPM_ENUM("IF1 ADC2 IN source", rt5645_tdm_adc_slot2_3_enum); + +static SOC_ENUM_SINGLE_DECL(rt5645_tdm_adc_slot4_5_enum, + RT5645_TDM_CTRL_1, 2, rt5645_tdm_adc_swap_select); + +static const struct snd_kcontrol_new rt5645_if1_adc3_in_mux = + SOC_DAPM_ENUM("IF1 ADC3 IN source", rt5645_tdm_adc_slot4_5_enum); + +/* MX-79 [14:12][10:8][6:4][2:0] */ +static const char * const rt5645_tdm_dac_swap_select[] = { + "Slot0", "Slot1", "Slot2", "Slot3" +}; + +static SOC_ENUM_SINGLE_DECL(rt5645_tdm_dac0_enum, + RT5645_TDM_CTRL_3, 12, rt5645_tdm_dac_swap_select); + +static const struct snd_kcontrol_new rt5645_if1_dac0_tdm_sel_mux = + SOC_DAPM_ENUM("IF1 DAC0 source", rt5645_tdm_dac0_enum); + +static SOC_ENUM_SINGLE_DECL(rt5645_tdm_dac1_enum, + RT5645_TDM_CTRL_3, 8, rt5645_tdm_dac_swap_select); + +static const struct snd_kcontrol_new rt5645_if1_dac1_tdm_sel_mux = + SOC_DAPM_ENUM("IF1 DAC1 source", rt5645_tdm_dac1_enum); + +static SOC_ENUM_SINGLE_DECL(rt5645_tdm_dac2_enum, + RT5645_TDM_CTRL_3, 4, rt5645_tdm_dac_swap_select); + +static const struct snd_kcontrol_new rt5645_if1_dac2_tdm_sel_mux = + SOC_DAPM_ENUM("IF1 DAC2 source", rt5645_tdm_dac2_enum); + +static SOC_ENUM_SINGLE_DECL(rt5645_tdm_dac3_enum, + RT5645_TDM_CTRL_3, 0, rt5645_tdm_dac_swap_select); + +static const struct snd_kcontrol_new rt5645_if1_dac3_tdm_sel_mux = + SOC_DAPM_ENUM("IF1 DAC3 source", rt5645_tdm_dac3_enum); + +/* MX-7a [14:12][10:8][6:4][2:0] */ +static SOC_ENUM_SINGLE_DECL(rt5650_tdm_dac0_enum, + RT5650_TDM_CTRL_4, 12, rt5645_tdm_dac_swap_select); + +static const struct snd_kcontrol_new rt5650_if1_dac0_tdm_sel_mux = + SOC_DAPM_ENUM("IF1 DAC0 source", rt5650_tdm_dac0_enum); + +static SOC_ENUM_SINGLE_DECL(rt5650_tdm_dac1_enum, + RT5650_TDM_CTRL_4, 8, rt5645_tdm_dac_swap_select); + +static const struct snd_kcontrol_new rt5650_if1_dac1_tdm_sel_mux = + SOC_DAPM_ENUM("IF1 DAC1 source", rt5650_tdm_dac1_enum); + +static SOC_ENUM_SINGLE_DECL(rt5650_tdm_dac2_enum, + RT5650_TDM_CTRL_4, 4, rt5645_tdm_dac_swap_select); + +static const struct snd_kcontrol_new rt5650_if1_dac2_tdm_sel_mux = + SOC_DAPM_ENUM("IF1 DAC2 source", rt5650_tdm_dac2_enum); + +static SOC_ENUM_SINGLE_DECL(rt5650_tdm_dac3_enum, + RT5650_TDM_CTRL_4, 0, rt5645_tdm_dac_swap_select); + +static const struct snd_kcontrol_new rt5650_if1_dac3_tdm_sel_mux = + SOC_DAPM_ENUM("IF1 DAC3 source", rt5650_tdm_dac3_enum); + /* MX-2d [3] [2] */ static const char * const rt5650_a_dac1_src[] = { "DAC1", "Stereo DAC Mixer" @@ -1227,52 +1329,79 @@ static void hp_amp_power(struct snd_soc_codec *codec, int on) if (on) { if (hp_amp_power_count <= 0) { - /* depop parameters */ - snd_soc_update_bits(codec, RT5645_DEPOP_M2, - RT5645_DEPOP_MASK, RT5645_DEPOP_MAN); - snd_soc_write(codec, RT5645_DEPOP_M1, 0x000d); - regmap_write(rt5645->regmap, RT5645_PR_BASE + - RT5645_HP_DCC_INT1, 0x9f01); - mdelay(150); - /* headphone amp power on */ - snd_soc_update_bits(codec, RT5645_PWR_ANLG1, - RT5645_PWR_FV1 | RT5645_PWR_FV2 , 0); - snd_soc_update_bits(codec, RT5645_PWR_VOL, - RT5645_PWR_HV_L | RT5645_PWR_HV_R, - RT5645_PWR_HV_L | RT5645_PWR_HV_R); - snd_soc_update_bits(codec, RT5645_PWR_ANLG1, - RT5645_PWR_HP_L | RT5645_PWR_HP_R | - RT5645_PWR_HA, - RT5645_PWR_HP_L | RT5645_PWR_HP_R | - RT5645_PWR_HA); - mdelay(5); - snd_soc_update_bits(codec, RT5645_PWR_ANLG1, - RT5645_PWR_FV1 | RT5645_PWR_FV2, - RT5645_PWR_FV1 | RT5645_PWR_FV2); - - snd_soc_update_bits(codec, RT5645_DEPOP_M1, - RT5645_HP_CO_MASK | RT5645_HP_SG_MASK, - RT5645_HP_CO_EN | RT5645_HP_SG_EN); - regmap_write(rt5645->regmap, RT5645_PR_BASE + - 0x14, 0x1aaa); - regmap_write(rt5645->regmap, RT5645_PR_BASE + - 0x24, 0x0430); + if (rt5645->codec_type == CODEC_TYPE_RT5650) { + snd_soc_write(codec, RT5645_CHARGE_PUMP, + 0x0e06); + snd_soc_write(codec, RT5645_DEPOP_M1, 0x001d); + regmap_write(rt5645->regmap, RT5645_PR_BASE + + 0x3e, 0x7400); + snd_soc_write(codec, RT5645_DEPOP_M3, 0x0737); + regmap_write(rt5645->regmap, RT5645_PR_BASE + + RT5645_MAMP_INT_REG2, 0xfc00); + snd_soc_write(codec, RT5645_DEPOP_M2, 0x1140); + } else { + /* depop parameters */ + snd_soc_update_bits(codec, RT5645_DEPOP_M2, + RT5645_DEPOP_MASK, RT5645_DEPOP_MAN); + snd_soc_write(codec, RT5645_DEPOP_M1, 0x000d); + regmap_write(rt5645->regmap, RT5645_PR_BASE + + RT5645_HP_DCC_INT1, 0x9f01); + mdelay(150); + /* headphone amp power on */ + snd_soc_update_bits(codec, RT5645_PWR_ANLG1, + RT5645_PWR_FV1 | RT5645_PWR_FV2, 0); + snd_soc_update_bits(codec, RT5645_PWR_VOL, + RT5645_PWR_HV_L | RT5645_PWR_HV_R, + RT5645_PWR_HV_L | RT5645_PWR_HV_R); + snd_soc_update_bits(codec, RT5645_PWR_ANLG1, + RT5645_PWR_HP_L | RT5645_PWR_HP_R | + RT5645_PWR_HA, + RT5645_PWR_HP_L | RT5645_PWR_HP_R | + RT5645_PWR_HA); + mdelay(5); + snd_soc_update_bits(codec, RT5645_PWR_ANLG1, + RT5645_PWR_FV1 | RT5645_PWR_FV2, + RT5645_PWR_FV1 | RT5645_PWR_FV2); + + snd_soc_update_bits(codec, RT5645_DEPOP_M1, + RT5645_HP_CO_MASK | RT5645_HP_SG_MASK, + RT5645_HP_CO_EN | RT5645_HP_SG_EN); + regmap_write(rt5645->regmap, RT5645_PR_BASE + + 0x14, 0x1aaa); + regmap_write(rt5645->regmap, RT5645_PR_BASE + + 0x24, 0x0430); + } } hp_amp_power_count++; } else { hp_amp_power_count--; if (hp_amp_power_count <= 0) { - snd_soc_update_bits(codec, RT5645_DEPOP_M1, - RT5645_HP_SG_MASK | RT5645_HP_L_SMT_MASK | - RT5645_HP_R_SMT_MASK, RT5645_HP_SG_DIS | - RT5645_HP_L_SMT_DIS | RT5645_HP_R_SMT_DIS); - /* headphone amp power down */ - snd_soc_write(codec, RT5645_DEPOP_M1, 0x0000); - snd_soc_update_bits(codec, RT5645_PWR_ANLG1, - RT5645_PWR_HP_L | RT5645_PWR_HP_R | - RT5645_PWR_HA, 0); - snd_soc_update_bits(codec, RT5645_DEPOP_M2, - RT5645_DEPOP_MASK, 0); + if (rt5645->codec_type == CODEC_TYPE_RT5650) { + regmap_write(rt5645->regmap, RT5645_PR_BASE + + 0x3e, 0x7400); + snd_soc_write(codec, RT5645_DEPOP_M3, 0x0737); + regmap_write(rt5645->regmap, RT5645_PR_BASE + + RT5645_MAMP_INT_REG2, 0xfc00); + snd_soc_write(codec, RT5645_DEPOP_M2, 0x1140); + msleep(100); + snd_soc_write(codec, RT5645_DEPOP_M1, 0x0001); + + } else { + snd_soc_update_bits(codec, RT5645_DEPOP_M1, + RT5645_HP_SG_MASK | + RT5645_HP_L_SMT_MASK | + RT5645_HP_R_SMT_MASK, + RT5645_HP_SG_DIS | + RT5645_HP_L_SMT_DIS | + RT5645_HP_R_SMT_DIS); + /* headphone amp power down */ + snd_soc_write(codec, RT5645_DEPOP_M1, 0x0000); + snd_soc_update_bits(codec, RT5645_PWR_ANLG1, + RT5645_PWR_HP_L | RT5645_PWR_HP_R | + RT5645_PWR_HA, 0); + snd_soc_update_bits(codec, RT5645_DEPOP_M2, + RT5645_DEPOP_MASK, 0); + } } } } @@ -1287,56 +1416,52 @@ static int rt5645_hp_event(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_POST_PMU: hp_amp_power(codec, 1); /* headphone unmute sequence */ - if (rt5645->codec_type == CODEC_TYPE_RT5650) { - snd_soc_write(codec, RT5645_DEPOP_M3, 0x0737); - } else { + if (rt5645->codec_type == CODEC_TYPE_RT5645) { snd_soc_update_bits(codec, RT5645_DEPOP_M3, RT5645_CP_FQ1_MASK | RT5645_CP_FQ2_MASK | RT5645_CP_FQ3_MASK, (RT5645_CP_FQ_192_KHZ << RT5645_CP_FQ1_SFT) | (RT5645_CP_FQ_12_KHZ << RT5645_CP_FQ2_SFT) | (RT5645_CP_FQ_192_KHZ << RT5645_CP_FQ3_SFT)); + regmap_write(rt5645->regmap, RT5645_PR_BASE + + RT5645_MAMP_INT_REG2, 0xfc00); + snd_soc_update_bits(codec, RT5645_DEPOP_M1, + RT5645_SMT_TRIG_MASK, RT5645_SMT_TRIG_EN); + snd_soc_update_bits(codec, RT5645_DEPOP_M1, + RT5645_RSTN_MASK, RT5645_RSTN_EN); + snd_soc_update_bits(codec, RT5645_DEPOP_M1, + RT5645_RSTN_MASK | RT5645_HP_L_SMT_MASK | + RT5645_HP_R_SMT_MASK, RT5645_RSTN_DIS | + RT5645_HP_L_SMT_EN | RT5645_HP_R_SMT_EN); + msleep(40); + snd_soc_update_bits(codec, RT5645_DEPOP_M1, + RT5645_HP_SG_MASK | RT5645_HP_L_SMT_MASK | + RT5645_HP_R_SMT_MASK, RT5645_HP_SG_DIS | + RT5645_HP_L_SMT_DIS | RT5645_HP_R_SMT_DIS); } - regmap_write(rt5645->regmap, - RT5645_PR_BASE + RT5645_MAMP_INT_REG2, 0xfc00); - snd_soc_update_bits(codec, RT5645_DEPOP_M1, - RT5645_SMT_TRIG_MASK, RT5645_SMT_TRIG_EN); - snd_soc_update_bits(codec, RT5645_DEPOP_M1, - RT5645_RSTN_MASK, RT5645_RSTN_EN); - snd_soc_update_bits(codec, RT5645_DEPOP_M1, - RT5645_RSTN_MASK | RT5645_HP_L_SMT_MASK | - RT5645_HP_R_SMT_MASK, RT5645_RSTN_DIS | - RT5645_HP_L_SMT_EN | RT5645_HP_R_SMT_EN); - msleep(40); - snd_soc_update_bits(codec, RT5645_DEPOP_M1, - RT5645_HP_SG_MASK | RT5645_HP_L_SMT_MASK | - RT5645_HP_R_SMT_MASK, RT5645_HP_SG_DIS | - RT5645_HP_L_SMT_DIS | RT5645_HP_R_SMT_DIS); break; case SND_SOC_DAPM_PRE_PMD: /* headphone mute sequence */ - if (rt5645->codec_type == CODEC_TYPE_RT5650) { - snd_soc_write(codec, RT5645_DEPOP_M3, 0x0737); - } else { + if (rt5645->codec_type == CODEC_TYPE_RT5645) { snd_soc_update_bits(codec, RT5645_DEPOP_M3, RT5645_CP_FQ1_MASK | RT5645_CP_FQ2_MASK | RT5645_CP_FQ3_MASK, (RT5645_CP_FQ_96_KHZ << RT5645_CP_FQ1_SFT) | (RT5645_CP_FQ_12_KHZ << RT5645_CP_FQ2_SFT) | (RT5645_CP_FQ_96_KHZ << RT5645_CP_FQ3_SFT)); + regmap_write(rt5645->regmap, RT5645_PR_BASE + + RT5645_MAMP_INT_REG2, 0xfc00); + snd_soc_update_bits(codec, RT5645_DEPOP_M1, + RT5645_HP_SG_MASK, RT5645_HP_SG_EN); + snd_soc_update_bits(codec, RT5645_DEPOP_M1, + RT5645_RSTP_MASK, RT5645_RSTP_EN); + snd_soc_update_bits(codec, RT5645_DEPOP_M1, + RT5645_RSTP_MASK | RT5645_HP_L_SMT_MASK | + RT5645_HP_R_SMT_MASK, RT5645_RSTP_DIS | + RT5645_HP_L_SMT_EN | RT5645_HP_R_SMT_EN); + msleep(30); } - regmap_write(rt5645->regmap, - RT5645_PR_BASE + RT5645_MAMP_INT_REG2, 0xfc00); - snd_soc_update_bits(codec, RT5645_DEPOP_M1, - RT5645_HP_SG_MASK, RT5645_HP_SG_EN); - snd_soc_update_bits(codec, RT5645_DEPOP_M1, - RT5645_RSTP_MASK, RT5645_RSTP_EN); - snd_soc_update_bits(codec, RT5645_DEPOP_M1, - RT5645_RSTP_MASK | RT5645_HP_L_SMT_MASK | - RT5645_HP_R_SMT_MASK, RT5645_RSTP_DIS | - RT5645_HP_L_SMT_EN | RT5645_HP_R_SMT_EN); - msleep(30); hp_amp_power(codec, 0); break; @@ -1571,20 +1696,50 @@ static const struct snd_soc_dapm_widget rt5645_dapm_widgets[] = { SND_SOC_DAPM_PGA("IF1_ADC4", SND_SOC_NOPM, 0, 0, NULL, 0), /* IF1 2 Mux */ - SND_SOC_DAPM_MUX("IF1 ADC Mux", SND_SOC_NOPM, + SND_SOC_DAPM_MUX("RT5645 IF1 ADC1 Swap Mux", SND_SOC_NOPM, + 0, 0, &rt5645_if1_adc1_in_mux), + SND_SOC_DAPM_MUX("RT5645 IF1 ADC2 Swap Mux", SND_SOC_NOPM, + 0, 0, &rt5645_if1_adc2_in_mux), + SND_SOC_DAPM_MUX("RT5645 IF1 ADC3 Swap Mux", SND_SOC_NOPM, + 0, 0, &rt5645_if1_adc3_in_mux), + SND_SOC_DAPM_MUX("RT5645 IF1 ADC Mux", SND_SOC_NOPM, 0, 0, &rt5645_if1_adc_in_mux), + + SND_SOC_DAPM_MUX("RT5650 IF1 ADC1 Swap Mux", SND_SOC_NOPM, + 0, 0, &rt5650_if1_adc1_in_mux), + SND_SOC_DAPM_MUX("RT5650 IF1 ADC2 Swap Mux", SND_SOC_NOPM, + 0, 0, &rt5650_if1_adc2_in_mux), + SND_SOC_DAPM_MUX("RT5650 IF1 ADC3 Swap Mux", SND_SOC_NOPM, + 0, 0, &rt5650_if1_adc3_in_mux), + SND_SOC_DAPM_MUX("RT5650 IF1 ADC Mux", SND_SOC_NOPM, + 0, 0, &rt5650_if1_adc_in_mux), + SND_SOC_DAPM_MUX("IF2 ADC Mux", SND_SOC_NOPM, 0, 0, &rt5645_if2_adc_in_mux), /* Digital Interface */ SND_SOC_DAPM_SUPPLY("I2S1", RT5645_PWR_DIG1, RT5645_PWR_I2S1_BIT, 0, NULL, 0), + SND_SOC_DAPM_PGA("IF1 DAC0", SND_SOC_NOPM, 0, 0, NULL, 0), SND_SOC_DAPM_PGA("IF1 DAC1", SND_SOC_NOPM, 0, 0, NULL, 0), SND_SOC_DAPM_PGA("IF1 DAC2", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_PGA("IF1 DAC1 L", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_PGA("IF1 DAC1 R", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_PGA("IF1 DAC2 L", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_PGA("IF1 DAC2 R", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_PGA("IF1 DAC3", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MUX("RT5645 IF1 DAC1 L Mux", SND_SOC_NOPM, 0, 0, + &rt5645_if1_dac0_tdm_sel_mux), + SND_SOC_DAPM_MUX("RT5645 IF1 DAC1 R Mux", SND_SOC_NOPM, 0, 0, + &rt5645_if1_dac1_tdm_sel_mux), + SND_SOC_DAPM_MUX("RT5645 IF1 DAC2 L Mux", SND_SOC_NOPM, 0, 0, + &rt5645_if1_dac2_tdm_sel_mux), + SND_SOC_DAPM_MUX("RT5645 IF1 DAC2 R Mux", SND_SOC_NOPM, 0, 0, + &rt5645_if1_dac3_tdm_sel_mux), + SND_SOC_DAPM_MUX("RT5650 IF1 DAC1 L Mux", SND_SOC_NOPM, 0, 0, + &rt5650_if1_dac0_tdm_sel_mux), + SND_SOC_DAPM_MUX("RT5650 IF1 DAC1 R Mux", SND_SOC_NOPM, 0, 0, + &rt5650_if1_dac1_tdm_sel_mux), + SND_SOC_DAPM_MUX("RT5650 IF1 DAC2 L Mux", SND_SOC_NOPM, 0, 0, + &rt5650_if1_dac2_tdm_sel_mux), + SND_SOC_DAPM_MUX("RT5650 IF1 DAC2 R Mux", SND_SOC_NOPM, 0, 0, + &rt5650_if1_dac3_tdm_sel_mux), SND_SOC_DAPM_PGA("IF1 ADC", SND_SOC_NOPM, 0, 0, NULL, 0), SND_SOC_DAPM_PGA("IF1 ADC L", SND_SOC_NOPM, 0, 0, NULL, 0), SND_SOC_DAPM_PGA("IF1 ADC R", SND_SOC_NOPM, 0, 0, NULL, 0), @@ -1848,42 +2003,32 @@ static const struct snd_soc_dapm_route rt5645_dapm_routes[] = { { "IF_ADC2", NULL, "Mono ADC MIXR" }, { "VAD_ADC", NULL, "VAD ADC Mux" }, - { "IF1 ADC Mux", "IF_ADC1", "IF_ADC1" }, - { "IF1 ADC Mux", "IF_ADC2", "IF_ADC2" }, - { "IF1 ADC Mux", "VAD_ADC", "VAD_ADC" }, - { "IF2 ADC Mux", "IF_ADC1", "IF_ADC1" }, { "IF2 ADC Mux", "IF_ADC2", "IF_ADC2" }, { "IF2 ADC Mux", "VAD_ADC", "VAD_ADC" }, { "IF1 ADC", NULL, "I2S1" }, - { "IF1 ADC", NULL, "IF1 ADC Mux" }, { "IF2 ADC", NULL, "I2S2" }, { "IF2 ADC", NULL, "IF2 ADC Mux" }, - { "AIF1TX", NULL, "IF1 ADC" }, - { "AIF1TX", NULL, "IF2 ADC" }, { "AIF2TX", NULL, "IF2 ADC" }, + { "IF1 DAC0", NULL, "AIF1RX" }, { "IF1 DAC1", NULL, "AIF1RX" }, { "IF1 DAC2", NULL, "AIF1RX" }, + { "IF1 DAC3", NULL, "AIF1RX" }, { "IF2 DAC", NULL, "AIF2RX" }, + { "IF1 DAC0", NULL, "I2S1" }, { "IF1 DAC1", NULL, "I2S1" }, { "IF1 DAC2", NULL, "I2S1" }, + { "IF1 DAC3", NULL, "I2S1" }, { "IF2 DAC", NULL, "I2S2" }, - { "IF1 DAC2 L", NULL, "IF1 DAC2" }, - { "IF1 DAC2 R", NULL, "IF1 DAC2" }, - { "IF1 DAC1 L", NULL, "IF1 DAC1" }, - { "IF1 DAC1 R", NULL, "IF1 DAC1" }, { "IF2 DAC L", NULL, "IF2 DAC" }, { "IF2 DAC R", NULL, "IF2 DAC" }, - { "DAC1 L Mux", "IF1 DAC", "IF1 DAC1 L" }, { "DAC1 L Mux", "IF2 DAC", "IF2 DAC L" }, - - { "DAC1 R Mux", "IF1 DAC", "IF1 DAC1 R" }, { "DAC1 R Mux", "IF2 DAC", "IF2 DAC R" }, { "DAC1 MIXL", "Stereo ADC Switch", "Stereo1 ADC MIXL" }, @@ -1893,14 +2038,12 @@ static const struct snd_soc_dapm_route rt5645_dapm_routes[] = { { "DAC1 MIXR", "DAC1 Switch", "DAC1 R Mux" }, { "DAC1 MIXR", NULL, "dac stereo1 filter" }, - { "DAC L2 Mux", "IF1 DAC", "IF1 DAC2 L" }, { "DAC L2 Mux", "IF2 DAC", "IF2 DAC L" }, { "DAC L2 Mux", "Mono ADC", "Mono ADC MIXL" }, { "DAC L2 Mux", "VAD_ADC", "VAD_ADC" }, { "DAC L2 Volume", NULL, "DAC L2 Mux" }, { "DAC L2 Volume", NULL, "dac mono left filter" }, - { "DAC R2 Mux", "IF1 DAC", "IF1 DAC2 R" }, { "DAC R2 Mux", "IF2 DAC", "IF2 DAC R" }, { "DAC R2 Mux", "Mono ADC", "Mono ADC MIXR" }, { "DAC R2 Mux", "Haptic", "Haptic Generator" }, @@ -2038,6 +2181,80 @@ static const struct snd_soc_dapm_route rt5650_specific_dapm_routes[] = { { "DAC R1", NULL, "A DAC1 R Mux" }, { "DAC L2", NULL, "A DAC2 L Mux" }, { "DAC R2", NULL, "A DAC2 R Mux" }, + + { "RT5650 IF1 ADC1 Swap Mux", "L/R", "IF_ADC1" }, + { "RT5650 IF1 ADC1 Swap Mux", "R/L", "IF_ADC1" }, + { "RT5650 IF1 ADC1 Swap Mux", "L/L", "IF_ADC1" }, + { "RT5650 IF1 ADC1 Swap Mux", "R/R", "IF_ADC1" }, + + { "RT5650 IF1 ADC2 Swap Mux", "L/R", "IF_ADC2" }, + { "RT5650 IF1 ADC2 Swap Mux", "R/L", "IF_ADC2" }, + { "RT5650 IF1 ADC2 Swap Mux", "L/L", "IF_ADC2" }, + { "RT5650 IF1 ADC2 Swap Mux", "R/R", "IF_ADC2" }, + + { "RT5650 IF1 ADC3 Swap Mux", "L/R", "VAD_ADC" }, + { "RT5650 IF1 ADC3 Swap Mux", "R/L", "VAD_ADC" }, + { "RT5650 IF1 ADC3 Swap Mux", "L/L", "VAD_ADC" }, + { "RT5650 IF1 ADC3 Swap Mux", "R/R", "VAD_ADC" }, + + { "IF1 ADC", NULL, "RT5650 IF1 ADC1 Swap Mux" }, + { "IF1 ADC", NULL, "RT5650 IF1 ADC2 Swap Mux" }, + { "IF1 ADC", NULL, "RT5650 IF1 ADC3 Swap Mux" }, + + { "RT5650 IF1 ADC Mux", "IF_ADC1/IF_ADC2/DAC_REF/Null", "IF1 ADC" }, + { "RT5650 IF1 ADC Mux", "IF_ADC1/IF_ADC2/Null/DAC_REF", "IF1 ADC" }, + { "RT5650 IF1 ADC Mux", "IF_ADC1/DAC_REF/IF_ADC2/Null", "IF1 ADC" }, + { "RT5650 IF1 ADC Mux", "IF_ADC1/DAC_REF/Null/IF_ADC2", "IF1 ADC" }, + { "RT5650 IF1 ADC Mux", "IF_ADC1/Null/DAC_REF/IF_ADC2", "IF1 ADC" }, + { "RT5650 IF1 ADC Mux", "IF_ADC1/Null/IF_ADC2/DAC_REF", "IF1 ADC" }, + + { "RT5650 IF1 ADC Mux", "IF_ADC2/IF_ADC1/DAC_REF/Null", "IF1 ADC" }, + { "RT5650 IF1 ADC Mux", "IF_ADC2/IF_ADC1/Null/DAC_REF", "IF1 ADC" }, + { "RT5650 IF1 ADC Mux", "IF_ADC2/DAC_REF/IF_ADC1/Null", "IF1 ADC" }, + { "RT5650 IF1 ADC Mux", "IF_ADC2/DAC_REF/Null/IF_ADC1", "IF1 ADC" }, + { "RT5650 IF1 ADC Mux", "IF_ADC2/Null/DAC_REF/IF_ADC1", "IF1 ADC" }, + { "RT5650 IF1 ADC Mux", "IF_ADC2/Null/IF_ADC1/DAC_REF", "IF1 ADC" }, + + { "RT5650 IF1 ADC Mux", "DAC_REF/IF_ADC1/IF_ADC2/Null", "IF1 ADC" }, + { "RT5650 IF1 ADC Mux", "DAC_REF/IF_ADC1/Null/IF_ADC2", "IF1 ADC" }, + { "RT5650 IF1 ADC Mux", "DAC_REF/IF_ADC2/IF_ADC1/Null", "IF1 ADC" }, + { "RT5650 IF1 ADC Mux", "DAC_REF/IF_ADC2/Null/IF_ADC1", "IF1 ADC" }, + { "RT5650 IF1 ADC Mux", "DAC_REF/Null/IF_ADC1/IF_ADC2", "IF1 ADC" }, + { "RT5650 IF1 ADC Mux", "DAC_REF/Null/IF_ADC2/IF_ADC1", "IF1 ADC" }, + + { "RT5650 IF1 ADC Mux", "Null/IF_ADC1/IF_ADC2/DAC_REF", "IF1 ADC" }, + { "RT5650 IF1 ADC Mux", "Null/IF_ADC1/DAC_REF/IF_ADC2", "IF1 ADC" }, + { "RT5650 IF1 ADC Mux", "Null/IF_ADC2/IF_ADC1/DAC_REF", "IF1 ADC" }, + { "RT5650 IF1 ADC Mux", "Null/IF_ADC2/DAC_REF/IF_ADC1", "IF1 ADC" }, + { "RT5650 IF1 ADC Mux", "Null/DAC_REF/IF_ADC1/IF_ADC2", "IF1 ADC" }, + { "RT5650 IF1 ADC Mux", "Null/DAC_REF/IF_ADC2/IF_ADC1", "IF1 ADC" }, + { "AIF1TX", NULL, "RT5650 IF1 ADC Mux" }, + + { "RT5650 IF1 DAC1 L Mux", "Slot0", "IF1 DAC0" }, + { "RT5650 IF1 DAC1 L Mux", "Slot1", "IF1 DAC1" }, + { "RT5650 IF1 DAC1 L Mux", "Slot2", "IF1 DAC2" }, + { "RT5650 IF1 DAC1 L Mux", "Slot3", "IF1 DAC3" }, + + { "RT5650 IF1 DAC1 R Mux", "Slot0", "IF1 DAC0" }, + { "RT5650 IF1 DAC1 R Mux", "Slot1", "IF1 DAC1" }, + { "RT5650 IF1 DAC1 R Mux", "Slot2", "IF1 DAC2" }, + { "RT5650 IF1 DAC1 R Mux", "Slot3", "IF1 DAC3" }, + + { "RT5650 IF1 DAC2 L Mux", "Slot0", "IF1 DAC0" }, + { "RT5650 IF1 DAC2 L Mux", "Slot1", "IF1 DAC1" }, + { "RT5650 IF1 DAC2 L Mux", "Slot2", "IF1 DAC2" }, + { "RT5650 IF1 DAC2 L Mux", "Slot3", "IF1 DAC3" }, + + { "RT5650 IF1 DAC2 R Mux", "Slot0", "IF1 DAC0" }, + { "RT5650 IF1 DAC2 R Mux", "Slot1", "IF1 DAC1" }, + { "RT5650 IF1 DAC2 R Mux", "Slot2", "IF1 DAC2" }, + { "RT5650 IF1 DAC2 R Mux", "Slot3", "IF1 DAC3" }, + + { "DAC1 L Mux", "IF1 DAC", "RT5650 IF1 DAC1 L Mux" }, + { "DAC1 R Mux", "IF1 DAC", "RT5650 IF1 DAC1 R Mux" }, + + { "DAC L2 Mux", "IF1 DAC", "RT5650 IF1 DAC2 L Mux" }, + { "DAC R2 Mux", "IF1 DAC", "RT5650 IF1 DAC2 R Mux" }, }; static const struct snd_soc_dapm_route rt5645_specific_dapm_routes[] = { @@ -2045,6 +2262,57 @@ static const struct snd_soc_dapm_route rt5645_specific_dapm_routes[] = { { "DAC R1", NULL, "Stereo DAC MIXR" }, { "DAC L2", NULL, "Mono DAC MIXL" }, { "DAC R2", NULL, "Mono DAC MIXR" }, + + { "RT5645 IF1 ADC1 Swap Mux", "L/R", "IF_ADC1" }, + { "RT5645 IF1 ADC1 Swap Mux", "R/L", "IF_ADC1" }, + { "RT5645 IF1 ADC1 Swap Mux", "L/L", "IF_ADC1" }, + { "RT5645 IF1 ADC1 Swap Mux", "R/R", "IF_ADC1" }, + + { "RT5645 IF1 ADC2 Swap Mux", "L/R", "IF_ADC2" }, + { "RT5645 IF1 ADC2 Swap Mux", "R/L", "IF_ADC2" }, + { "RT5645 IF1 ADC2 Swap Mux", "L/L", "IF_ADC2" }, + { "RT5645 IF1 ADC2 Swap Mux", "R/R", "IF_ADC2" }, + + { "RT5645 IF1 ADC3 Swap Mux", "L/R", "VAD_ADC" }, + { "RT5645 IF1 ADC3 Swap Mux", "R/L", "VAD_ADC" }, + { "RT5645 IF1 ADC3 Swap Mux", "L/L", "VAD_ADC" }, + { "RT5645 IF1 ADC3 Swap Mux", "R/R", "VAD_ADC" }, + + { "IF1 ADC", NULL, "RT5645 IF1 ADC1 Swap Mux" }, + { "IF1 ADC", NULL, "RT5645 IF1 ADC2 Swap Mux" }, + { "IF1 ADC", NULL, "RT5645 IF1 ADC3 Swap Mux" }, + + { "RT5645 IF1 ADC Mux", "IF_ADC1/IF_ADC2/VAD_ADC", "IF1 ADC" }, + { "RT5645 IF1 ADC Mux", "IF_ADC2/IF_ADC1/VAD_ADC", "IF1 ADC" }, + { "RT5645 IF1 ADC Mux", "VAD_ADC/IF_ADC1/IF_ADC2", "IF1 ADC" }, + { "RT5645 IF1 ADC Mux", "VAD_ADC/IF_ADC2/IF_ADC1", "IF1 ADC" }, + { "AIF1TX", NULL, "RT5645 IF1 ADC Mux" }, + + { "RT5645 IF1 DAC1 L Mux", "Slot0", "IF1 DAC0" }, + { "RT5645 IF1 DAC1 L Mux", "Slot1", "IF1 DAC1" }, + { "RT5645 IF1 DAC1 L Mux", "Slot2", "IF1 DAC2" }, + { "RT5645 IF1 DAC1 L Mux", "Slot3", "IF1 DAC3" }, + + { "RT5645 IF1 DAC1 R Mux", "Slot0", "IF1 DAC0" }, + { "RT5645 IF1 DAC1 R Mux", "Slot1", "IF1 DAC1" }, + { "RT5645 IF1 DAC1 R Mux", "Slot2", "IF1 DAC2" }, + { "RT5645 IF1 DAC1 R Mux", "Slot3", "IF1 DAC3" }, + + { "RT5645 IF1 DAC2 L Mux", "Slot0", "IF1 DAC0" }, + { "RT5645 IF1 DAC2 L Mux", "Slot1", "IF1 DAC1" }, + { "RT5645 IF1 DAC2 L Mux", "Slot2", "IF1 DAC2" }, + { "RT5645 IF1 DAC2 L Mux", "Slot3", "IF1 DAC3" }, + + { "RT5645 IF1 DAC2 R Mux", "Slot0", "IF1 DAC0" }, + { "RT5645 IF1 DAC2 R Mux", "Slot1", "IF1 DAC1" }, + { "RT5645 IF1 DAC2 R Mux", "Slot2", "IF1 DAC2" }, + { "RT5645 IF1 DAC2 R Mux", "Slot3", "IF1 DAC3" }, + + { "DAC1 L Mux", "IF1 DAC", "RT5645 IF1 DAC1 L Mux" }, + { "DAC1 R Mux", "IF1 DAC", "RT5645 IF1 DAC1 R Mux" }, + + { "DAC L2 Mux", "IF1 DAC", "RT5645 IF1 DAC2 L Mux" }, + { "DAC R2 Mux", "IF1 DAC", "RT5645 IF1 DAC2 R Mux" }, }; static int rt5645_hw_params(struct snd_pcm_substream *substream, @@ -2102,9 +2370,8 @@ static int rt5645_hw_params(struct snd_pcm_substream *substream, switch (dai->id) { case RT5645_AIF1: - mask_clk = RT5645_I2S_BCLK_MS1_MASK | RT5645_I2S_PD1_MASK; - val_clk = bclk_ms << RT5645_I2S_BCLK_MS1_SFT | - pre_div << RT5645_I2S_PD1_SFT; + mask_clk = RT5645_I2S_PD1_MASK; + val_clk = pre_div << RT5645_I2S_PD1_SFT; snd_soc_update_bits(codec, RT5645_I2S1_SDP, (0x3 << dl_sft), (val_len << dl_sft)); snd_soc_update_bits(codec, RT5645_ADDA_CLK1, mask_clk, val_clk); @@ -2369,6 +2636,8 @@ static int rt5645_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, static int rt5645_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { + struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec); + switch (level) { case SND_SOC_BIAS_PREPARE: if (SND_SOC_BIAS_STANDBY == codec->dapm.bias_level) { @@ -2399,8 +2668,9 @@ static int rt5645_set_bias_level(struct snd_soc_codec *codec, case SND_SOC_BIAS_OFF: snd_soc_write(codec, RT5645_DEPOP_M2, 0x1100); - snd_soc_update_bits(codec, RT5645_GEN_CTRL1, - RT5645_DIG_GATE_CTRL, 0); + if (!rt5645->en_button_func) + snd_soc_update_bits(codec, RT5645_GEN_CTRL1, + RT5645_DIG_GATE_CTRL, 0); snd_soc_update_bits(codec, RT5645_PWR_ANLG1, RT5645_PWR_VREF1 | RT5645_PWR_MB | RT5645_PWR_BG | RT5645_PWR_VREF2 | @@ -2414,67 +2684,218 @@ static int rt5645_set_bias_level(struct snd_soc_codec *codec, return 0; } -static int rt5645_jack_detect(struct snd_soc_codec *codec) +static int rt5650_calibration(struct rt5645_priv *rt5645) { - struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec); - int gpio_state, jack_type = 0; - unsigned int val; + int val, i; + int ret = -1; - if (!gpio_is_valid(rt5645->pdata.hp_det_gpio)) { - dev_err(codec->dev, "invalid gpio\n"); - return -EINVAL; + regcache_cache_bypass(rt5645->regmap, true); + regmap_write(rt5645->regmap, RT5645_RESET, 0); + regmap_write(rt5645->regmap, RT5645_GEN_CTRL3, 0x0800); + regmap_write(rt5645->regmap, RT5645_PR_BASE + RT5645_CHOP_DAC_ADC, + 0x3600); + regmap_write(rt5645->regmap, RT5645_PR_BASE + 0x25, 0x7000); + regmap_write(rt5645->regmap, RT5645_I2S1_SDP, 0x8008); + /* headset type */ + regmap_write(rt5645->regmap, RT5645_GEN_CTRL1, 0x2061); + regmap_write(rt5645->regmap, RT5645_CHARGE_PUMP, 0x0006); + regmap_write(rt5645->regmap, RT5645_PWR_ANLG1, 0x2012); + regmap_write(rt5645->regmap, RT5645_PWR_MIXER, 0x0002); + regmap_write(rt5645->regmap, RT5645_PWR_VOL, 0x0020); + regmap_write(rt5645->regmap, RT5645_JD_CTRL3, 0x00f0); + regmap_write(rt5645->regmap, RT5645_IN1_CTRL1, 0x0006); + regmap_write(rt5645->regmap, RT5645_IN1_CTRL2, 0x1827); + regmap_write(rt5645->regmap, RT5645_IN1_CTRL2, 0x0827); + msleep(400); + /* Inline command */ + regmap_write(rt5645->regmap, RT5645_DEPOP_M1, 0x0001); + regmap_write(rt5645->regmap, RT5650_4BTN_IL_CMD2, 0xc000); + regmap_write(rt5645->regmap, RT5650_4BTN_IL_CMD1, 0x0008); + /* Calbration */ + regmap_write(rt5645->regmap, RT5645_GLB_CLK, 0x8000); + regmap_write(rt5645->regmap, RT5645_DEPOP_M1, 0x0000); + regmap_write(rt5645->regmap, RT5650_4BTN_IL_CMD2, 0xc000); + regmap_write(rt5645->regmap, RT5650_4BTN_IL_CMD1, 0x0008); + regmap_write(rt5645->regmap, RT5645_PWR_DIG2, 0x8800); + regmap_write(rt5645->regmap, RT5645_PWR_ANLG1, 0xe8fa); + regmap_write(rt5645->regmap, RT5645_PWR_ANLG2, 0x8c04); + regmap_write(rt5645->regmap, RT5645_DEPOP_M2, 0x3100); + regmap_write(rt5645->regmap, RT5645_CHARGE_PUMP, 0x0e06); + regmap_write(rt5645->regmap, RT5645_BASS_BACK, 0x8a13); + regmap_write(rt5645->regmap, RT5645_GEN_CTRL3, 0x0820); + regmap_write(rt5645->regmap, RT5645_DEPOP_M1, 0x000d); + /* Power on and Calbration */ + regmap_write(rt5645->regmap, RT5645_PR_BASE + RT5645_HP_DCC_INT1, + 0x9f01); + msleep(200); + for (i = 0; i < 5; i++) { + regmap_read(rt5645->regmap, RT5645_PR_BASE + 0x7a, &val); + if (val != 0 && val != 0x3f3f) { + ret = 0; + break; + } + msleep(50); } - gpio_state = gpio_get_value(rt5645->pdata.hp_det_gpio); + pr_debug("%s: PR-7A = 0x%x\n", __func__, val); + + /* mute */ + regmap_write(rt5645->regmap, RT5645_PR_BASE + 0x3e, 0x7400); + regmap_write(rt5645->regmap, RT5645_DEPOP_M3, 0x0737); + regmap_write(rt5645->regmap, RT5645_PR_BASE + RT5645_MAMP_INT_REG2, + 0xfc00); + regmap_write(rt5645->regmap, RT5645_DEPOP_M2, 0x1140); + regmap_write(rt5645->regmap, RT5645_DEPOP_M1, 0x0000); + regmap_write(rt5645->regmap, RT5645_GEN_CTRL2, 0x4020); + regmap_write(rt5645->regmap, RT5645_PWR_ANLG2, 0x0006); + regmap_write(rt5645->regmap, RT5645_PWR_DIG2, 0x0000); + msleep(350); + + regcache_cache_bypass(rt5645->regmap, false); + + return ret; +} - dev_dbg(codec->dev, "gpio = %d(%d)\n", rt5645->pdata.hp_det_gpio, - gpio_state); +static void rt5645_enable_push_button_irq(struct snd_soc_codec *codec, + bool enable) +{ + struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec); - if ((rt5645->pdata.gpio_hp_det_active_high && gpio_state) || - (!rt5645->pdata.gpio_hp_det_active_high && !gpio_state)) { - snd_soc_dapm_force_enable_pin(&codec->dapm, "micbias1"); - snd_soc_dapm_force_enable_pin(&codec->dapm, "micbias2"); - snd_soc_dapm_force_enable_pin(&codec->dapm, "LDO2"); - snd_soc_dapm_force_enable_pin(&codec->dapm, "Mic Det Power"); - snd_soc_dapm_sync(&codec->dapm); + if (enable) { + snd_soc_dapm_force_enable_pin_unlocked(&codec->dapm, + "ADC L power"); + snd_soc_dapm_force_enable_pin_unlocked(&codec->dapm, + "ADC R power"); + snd_soc_dapm_force_enable_pin_unlocked(&codec->dapm, + "LDO2"); + snd_soc_dapm_force_enable_pin_unlocked(&codec->dapm, + "Mic Det Power"); + snd_soc_dapm_sync_unlocked(&codec->dapm); + snd_soc_update_bits(codec, + RT5645_INT_IRQ_ST, 0x8, 0x8); + snd_soc_update_bits(codec, + RT5650_4BTN_IL_CMD2, 0x8000, 0x8000); + snd_soc_read(codec, RT5650_4BTN_IL_CMD1); + pr_debug("%s read %x = %x\n", __func__, RT5650_4BTN_IL_CMD1, + snd_soc_read(codec, RT5650_4BTN_IL_CMD1)); + } else { + snd_soc_update_bits(codec, RT5650_4BTN_IL_CMD2, 0x8000, 0x0); + snd_soc_update_bits(codec, RT5645_INT_IRQ_ST, 0x8, 0x0); + snd_soc_dapm_disable_pin_unlocked(&codec->dapm, + "ADC L power"); + snd_soc_dapm_disable_pin_unlocked(&codec->dapm, + "ADC R power"); + if (rt5645->pdata.jd_mode == 0) + snd_soc_dapm_disable_pin_unlocked(&codec->dapm, + "LDO2"); + snd_soc_dapm_disable_pin_unlocked(&codec->dapm, + "Mic Det Power"); + snd_soc_dapm_sync_unlocked(&codec->dapm); + } +} - snd_soc_write(codec, RT5645_IN1_CTRL1, 0x0006); - snd_soc_write(codec, RT5645_JD_CTRL3, 0x00b0); +static int rt5645_jack_detect(struct snd_soc_codec *codec, int jack_insert) +{ + struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec); + unsigned int val; - snd_soc_update_bits(codec, RT5645_IN1_CTRL2, - RT5645_CBJ_MN_JD, 0); - snd_soc_update_bits(codec, RT5645_IN1_CTRL2, - RT5645_CBJ_MN_JD, RT5645_CBJ_MN_JD); + if (jack_insert) { + regmap_write(rt5645->regmap, RT5645_CHARGE_PUMP, 0x0006); + + if (codec->component.card->instantiated) { + /* for jack type detect */ + snd_soc_dapm_force_enable_pin(&codec->dapm, "LDO2"); + snd_soc_dapm_force_enable_pin(&codec->dapm, + "Mic Det Power"); + snd_soc_dapm_sync(&codec->dapm); + } else { + /* Power up necessary bits for JD if dapm is + not ready yet */ + regmap_update_bits(rt5645->regmap, RT5645_PWR_ANLG1, + RT5645_PWR_MB | RT5645_PWR_VREF2, + RT5645_PWR_MB | RT5645_PWR_VREF2); + regmap_update_bits(rt5645->regmap, RT5645_PWR_MIXER, + RT5645_PWR_LDO2, RT5645_PWR_LDO2); + regmap_update_bits(rt5645->regmap, RT5645_PWR_VOL, + RT5645_PWR_MIC_DET, RT5645_PWR_MIC_DET); + } - msleep(400); - val = snd_soc_read(codec, RT5645_IN1_CTRL3) & 0x7; + regmap_write(rt5645->regmap, RT5645_JD_CTRL3, 0x00f0); + regmap_write(rt5645->regmap, RT5645_IN1_CTRL1, 0x0006); + regmap_update_bits(rt5645->regmap, + RT5645_IN1_CTRL2, 0x1000, 0x1000); + msleep(100); + regmap_update_bits(rt5645->regmap, + RT5645_IN1_CTRL2, 0x1000, 0x0000); + + msleep(450); + regmap_read(rt5645->regmap, RT5645_IN1_CTRL3, &val); + val &= 0x7; dev_dbg(codec->dev, "val = %d\n", val); - if (val == 1 || val == 2) - jack_type = SND_JACK_HEADSET; - else - jack_type = SND_JACK_HEADPHONE; + if (val == 1 || val == 2) { + rt5645->jack_type = SND_JACK_HEADSET; + if (rt5645->en_button_func) { + rt5645_enable_push_button_irq(codec, true); + } + } else { + if (codec->component.card->instantiated) { + snd_soc_dapm_disable_pin(&codec->dapm, + "Mic Det Power"); + snd_soc_dapm_sync(&codec->dapm); + } else + regmap_update_bits(rt5645->regmap, + RT5645_PWR_VOL, RT5645_PWR_MIC_DET, 0); + rt5645->jack_type = SND_JACK_HEADPHONE; + } - snd_soc_dapm_disable_pin(&codec->dapm, "micbias1"); - snd_soc_dapm_disable_pin(&codec->dapm, "micbias2"); - if (rt5645->pdata.jd_mode == 0) - snd_soc_dapm_disable_pin(&codec->dapm, "LDO2"); - snd_soc_dapm_disable_pin(&codec->dapm, "Mic Det Power"); - snd_soc_dapm_sync(&codec->dapm); + } else { /* jack out */ + rt5645->jack_type = 0; + if (rt5645->en_button_func) + rt5645_enable_push_button_irq(codec, false); + else { + if (codec->component.card->instantiated) { + if (rt5645->pdata.jd_mode == 0) + snd_soc_dapm_disable_pin(&codec->dapm, + "LDO2"); + snd_soc_dapm_disable_pin(&codec->dapm, + "Mic Det Power"); + snd_soc_dapm_sync(&codec->dapm); + } else { + if (rt5645->pdata.jd_mode == 0) + regmap_update_bits(rt5645->regmap, + RT5645_PWR_MIXER, + RT5645_PWR_LDO2, 0); + regmap_update_bits(rt5645->regmap, + RT5645_PWR_VOL, RT5645_PWR_MIC_DET, 0); + } + } } - snd_soc_jack_report(rt5645->hp_jack, jack_type, SND_JACK_HEADPHONE); - snd_soc_jack_report(rt5645->mic_jack, jack_type, SND_JACK_MICROPHONE); - return 0; + return rt5645->jack_type; } +static int rt5645_irq_detection(struct rt5645_priv *rt5645); +static irqreturn_t rt5645_irq(int irq, void *data); + int rt5645_set_jack_detect(struct snd_soc_codec *codec, - struct snd_soc_jack *hp_jack, struct snd_soc_jack *mic_jack) + struct snd_soc_jack *hp_jack, struct snd_soc_jack *mic_jack, + struct snd_soc_jack *btn_jack) { struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec); rt5645->hp_jack = hp_jack; rt5645->mic_jack = mic_jack; - rt5645_jack_detect(codec); + rt5645->btn_jack = btn_jack; + if (rt5645->btn_jack && rt5645->codec_type == CODEC_TYPE_RT5650) { + rt5645->en_button_func = true; + regmap_update_bits(rt5645->regmap, RT5645_GPIO_CTRL1, + RT5645_GP1_PIN_IRQ, RT5645_GP1_PIN_IRQ); + regmap_update_bits(rt5645->regmap, RT5645_DEPOP_M1, + RT5645_HP_CB_MASK, RT5645_HP_CB_PU); + regmap_update_bits(rt5645->regmap, RT5645_GEN_CTRL1, + RT5645_DIG_GATE_CTRL, RT5645_DIG_GATE_CTRL); + } + rt5645_irq(0, rt5645); return 0; } @@ -2485,7 +2906,7 @@ static void rt5645_jack_detect_work(struct work_struct *work) struct rt5645_priv *rt5645 = container_of(work, struct rt5645_priv, jack_detect_work.work); - rt5645_jack_detect(rt5645->codec); + rt5645_irq_detection(rt5645); } static irqreturn_t rt5645_irq(int irq, void *data) @@ -2498,6 +2919,126 @@ static irqreturn_t rt5645_irq(int irq, void *data) return IRQ_HANDLED; } +static int rt5645_button_detect(struct snd_soc_codec *codec) +{ + int btn_type, val; + + val = snd_soc_read(codec, RT5650_4BTN_IL_CMD1); + pr_debug("val=0x%x\n", val); + btn_type = val & 0xfff0; + snd_soc_write(codec, RT5650_4BTN_IL_CMD1, val); + + return btn_type; +} + +static int rt5645_irq_detection(struct rt5645_priv *rt5645) +{ + int val, btn_type, gpio_state = 0, report = 0; + + switch (rt5645->pdata.jd_mode) { + case 0: /* Not using rt5645 JD */ + if (gpio_is_valid(rt5645->pdata.hp_det_gpio)) { + gpio_state = gpio_get_value(rt5645->pdata.hp_det_gpio); + dev_dbg(rt5645->codec->dev, "gpio = %d(%d)\n", + rt5645->pdata.hp_det_gpio, gpio_state); + } + if ((rt5645->pdata.gpio_hp_det_active_high && gpio_state) || + (!rt5645->pdata.gpio_hp_det_active_high && + !gpio_state)) { + report = rt5645_jack_detect(rt5645->codec, 1); + } else { + report = rt5645_jack_detect(rt5645->codec, 0); + } + snd_soc_jack_report(rt5645->hp_jack, + report, SND_JACK_HEADPHONE); + snd_soc_jack_report(rt5645->mic_jack, + report, SND_JACK_MICROPHONE); + return report; + case 1: /* 2 port */ + val = snd_soc_read(rt5645->codec, RT5645_A_JD_CTRL1) & 0x0070; + break; + default: /* 1 port */ + val = snd_soc_read(rt5645->codec, RT5645_A_JD_CTRL1) & 0x0020; + break; + + } + + switch (val) { + /* jack in */ + case 0x30: /* 2 port */ + case 0x0: /* 1 port or 2 port */ + if (rt5645->jack_type == 0) { + report = rt5645_jack_detect(rt5645->codec, 1); + /* for push button and jack out */ + break; + } + btn_type = 0; + if (snd_soc_read(rt5645->codec, RT5645_INT_IRQ_ST) & 0x4) { + /* button pressed */ + report = SND_JACK_HEADSET; + btn_type = rt5645_button_detect(rt5645->codec); + /* rt5650 can report three kinds of button behavior, + one click, double click and hold. However, + currently we will report button pressed/released + event. So all the three button behaviors are + treated as button pressed. */ + switch (btn_type) { + case 0x8000: + case 0x4000: + case 0x2000: + report |= SND_JACK_BTN_0; + break; + case 0x1000: + case 0x0800: + case 0x0400: + report |= SND_JACK_BTN_1; + break; + case 0x0200: + case 0x0100: + case 0x0080: + report |= SND_JACK_BTN_2; + break; + case 0x0040: + case 0x0020: + case 0x0010: + report |= SND_JACK_BTN_3; + break; + case 0x0000: /* unpressed */ + break; + default: + dev_err(rt5645->codec->dev, + "Unexpected button code 0x%04x\n", + btn_type); + break; + } + } + if (btn_type == 0)/* button release */ + report = rt5645->jack_type; + + break; + /* jack out */ + case 0x70: /* 2 port */ + case 0x10: /* 2 port */ + case 0x20: /* 1 port */ + report = 0; + snd_soc_update_bits(rt5645->codec, + RT5645_INT_IRQ_ST, 0x1, 0x0); + rt5645_jack_detect(rt5645->codec, 0); + break; + default: + break; + } + + snd_soc_jack_report(rt5645->hp_jack, report, SND_JACK_HEADPHONE); + snd_soc_jack_report(rt5645->mic_jack, report, SND_JACK_MICROPHONE); + if (rt5645->en_button_func) + snd_soc_jack_report(rt5645->btn_jack, + report, SND_JACK_BTN_0 | SND_JACK_BTN_1 | + SND_JACK_BTN_2 | SND_JACK_BTN_3); + + return report; +} + static int rt5645_probe(struct snd_soc_codec *codec) { struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec); @@ -2522,10 +3063,8 @@ static int rt5645_probe(struct snd_soc_codec *codec) snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF); - snd_soc_update_bits(codec, RT5645_CHARGE_PUMP, 0x0300, 0x0200); - /* for JD function */ - if (rt5645->pdata.en_jd_func) { + if (rt5645->pdata.jd_mode) { snd_soc_dapm_force_enable_pin(&codec->dapm, "JD Power"); snd_soc_dapm_force_enable_pin(&codec->dapm, "LDO2"); snd_soc_dapm_sync(&codec->dapm); @@ -2665,6 +3204,32 @@ static struct acpi_device_id rt5645_acpi_match[] = { MODULE_DEVICE_TABLE(acpi, rt5645_acpi_match); #endif +static struct rt5645_platform_data *rt5645_pdata; + +static struct rt5645_platform_data strago_platform_data = { + .dmic1_data_pin = RT5645_DMIC1_DISABLE, + .dmic2_data_pin = RT5645_DMIC_DATA_IN2P, + .jd_mode = 3, +}; + +static int strago_quirk_cb(const struct dmi_system_id *id) +{ + rt5645_pdata = &strago_platform_data; + + return 1; +} + +static struct dmi_system_id dmi_platform_intel_braswell[] = { + { + .ident = "Intel Strago", + .callback = strago_quirk_cb, + .matches = { + DMI_MATCH(DMI_PRODUCT_NAME, "Strago"), + }, + }, + { } +}; + static int rt5645_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { @@ -2672,6 +3237,7 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, struct rt5645_priv *rt5645; int ret; unsigned int val; + struct gpio_desc *gpiod; rt5645 = devm_kzalloc(&i2c->dev, sizeof(struct rt5645_priv), GFP_KERNEL); @@ -2681,8 +3247,23 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, rt5645->i2c = i2c; i2c_set_clientdata(i2c, rt5645); - if (pdata) + if (pdata) { rt5645->pdata = *pdata; + } else { + if (dmi_check_system(dmi_platform_intel_braswell)) { + rt5645->pdata = *rt5645_pdata; + gpiod = devm_gpiod_get_index(&i2c->dev, "rt5645", 0); + + if (IS_ERR(gpiod) || gpiod_direction_input(gpiod)) { + rt5645->pdata.hp_det_gpio = -1; + dev_err(&i2c->dev, "failed to initialize gpiod\n"); + } else { + rt5645->pdata.hp_det_gpio = desc_to_gpio(gpiod); + rt5645->pdata.gpio_hp_det_active_high + = !gpiod_is_active_low(gpiod); + } + } + } rt5645->regmap = devm_regmap_init_i2c(i2c, &rt5645_regmap); if (IS_ERR(rt5645->regmap)) { @@ -2708,6 +3289,13 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, return -ENODEV; } + if (rt5645->codec_type == CODEC_TYPE_RT5650) { + ret = rt5650_calibration(rt5645); + + if (ret < 0) + pr_err("calibration failed!\n"); + } + regmap_write(rt5645->regmap, RT5645_RESET, 0); ret = regmap_register_patch(rt5645->regmap, init_list, @@ -2727,84 +3315,76 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, regmap_update_bits(rt5645->regmap, RT5645_IN2_CTRL, RT5645_IN_DF2, RT5645_IN_DF2); - if (rt5645->pdata.dmic_en) { + if (rt5645->pdata.dmic1_data_pin || rt5645->pdata.dmic2_data_pin) { regmap_update_bits(rt5645->regmap, RT5645_GPIO_CTRL1, RT5645_GP2_PIN_MASK, RT5645_GP2_PIN_DMIC1_SCL); + } + switch (rt5645->pdata.dmic1_data_pin) { + case RT5645_DMIC_DATA_IN2N: + regmap_update_bits(rt5645->regmap, RT5645_DMIC_CTRL1, + RT5645_DMIC_1_DP_MASK, RT5645_DMIC_1_DP_IN2N); + break; - switch (rt5645->pdata.dmic1_data_pin) { - case RT5645_DMIC_DATA_IN2N: - regmap_update_bits(rt5645->regmap, RT5645_DMIC_CTRL1, - RT5645_DMIC_1_DP_MASK, RT5645_DMIC_1_DP_IN2N); - break; - - case RT5645_DMIC_DATA_GPIO5: - regmap_update_bits(rt5645->regmap, RT5645_DMIC_CTRL1, - RT5645_DMIC_1_DP_MASK, RT5645_DMIC_1_DP_GPIO5); - regmap_update_bits(rt5645->regmap, RT5645_GPIO_CTRL1, - RT5645_GP5_PIN_MASK, RT5645_GP5_PIN_DMIC1_SDA); - break; - - case RT5645_DMIC_DATA_GPIO11: - regmap_update_bits(rt5645->regmap, RT5645_DMIC_CTRL1, - RT5645_DMIC_1_DP_MASK, RT5645_DMIC_1_DP_GPIO11); - regmap_update_bits(rt5645->regmap, RT5645_GPIO_CTRL1, - RT5645_GP11_PIN_MASK, - RT5645_GP11_PIN_DMIC1_SDA); - break; + case RT5645_DMIC_DATA_GPIO5: + regmap_update_bits(rt5645->regmap, RT5645_DMIC_CTRL1, + RT5645_DMIC_1_DP_MASK, RT5645_DMIC_1_DP_GPIO5); + regmap_update_bits(rt5645->regmap, RT5645_GPIO_CTRL1, + RT5645_GP5_PIN_MASK, RT5645_GP5_PIN_DMIC1_SDA); + break; - default: - break; - } + case RT5645_DMIC_DATA_GPIO11: + regmap_update_bits(rt5645->regmap, RT5645_DMIC_CTRL1, + RT5645_DMIC_1_DP_MASK, RT5645_DMIC_1_DP_GPIO11); + regmap_update_bits(rt5645->regmap, RT5645_GPIO_CTRL1, + RT5645_GP11_PIN_MASK, + RT5645_GP11_PIN_DMIC1_SDA); + break; - switch (rt5645->pdata.dmic2_data_pin) { - case RT5645_DMIC_DATA_IN2P: - regmap_update_bits(rt5645->regmap, RT5645_DMIC_CTRL1, - RT5645_DMIC_2_DP_MASK, RT5645_DMIC_2_DP_IN2P); - break; + default: + break; + } - case RT5645_DMIC_DATA_GPIO6: - regmap_update_bits(rt5645->regmap, RT5645_DMIC_CTRL1, - RT5645_DMIC_2_DP_MASK, RT5645_DMIC_2_DP_GPIO6); - regmap_update_bits(rt5645->regmap, RT5645_GPIO_CTRL1, - RT5645_GP6_PIN_MASK, RT5645_GP6_PIN_DMIC2_SDA); - break; + switch (rt5645->pdata.dmic2_data_pin) { + case RT5645_DMIC_DATA_IN2P: + regmap_update_bits(rt5645->regmap, RT5645_DMIC_CTRL1, + RT5645_DMIC_2_DP_MASK, RT5645_DMIC_2_DP_IN2P); + break; - case RT5645_DMIC_DATA_GPIO10: - regmap_update_bits(rt5645->regmap, RT5645_DMIC_CTRL1, - RT5645_DMIC_2_DP_MASK, RT5645_DMIC_2_DP_GPIO10); - regmap_update_bits(rt5645->regmap, RT5645_GPIO_CTRL1, - RT5645_GP10_PIN_MASK, - RT5645_GP10_PIN_DMIC2_SDA); - break; + case RT5645_DMIC_DATA_GPIO6: + regmap_update_bits(rt5645->regmap, RT5645_DMIC_CTRL1, + RT5645_DMIC_2_DP_MASK, RT5645_DMIC_2_DP_GPIO6); + regmap_update_bits(rt5645->regmap, RT5645_GPIO_CTRL1, + RT5645_GP6_PIN_MASK, RT5645_GP6_PIN_DMIC2_SDA); + break; - case RT5645_DMIC_DATA_GPIO12: - regmap_update_bits(rt5645->regmap, RT5645_DMIC_CTRL1, - RT5645_DMIC_2_DP_MASK, RT5645_DMIC_2_DP_GPIO12); - regmap_update_bits(rt5645->regmap, RT5645_GPIO_CTRL1, - RT5645_GP12_PIN_MASK, - RT5645_GP12_PIN_DMIC2_SDA); - break; + case RT5645_DMIC_DATA_GPIO10: + regmap_update_bits(rt5645->regmap, RT5645_DMIC_CTRL1, + RT5645_DMIC_2_DP_MASK, RT5645_DMIC_2_DP_GPIO10); + regmap_update_bits(rt5645->regmap, RT5645_GPIO_CTRL1, + RT5645_GP10_PIN_MASK, + RT5645_GP10_PIN_DMIC2_SDA); + break; - default: - break; - } + case RT5645_DMIC_DATA_GPIO12: + regmap_update_bits(rt5645->regmap, RT5645_DMIC_CTRL1, + RT5645_DMIC_2_DP_MASK, RT5645_DMIC_2_DP_GPIO12); + regmap_update_bits(rt5645->regmap, RT5645_GPIO_CTRL1, + RT5645_GP12_PIN_MASK, + RT5645_GP12_PIN_DMIC2_SDA); + break; + default: + break; } - if (rt5645->pdata.en_jd_func) { + if (rt5645->pdata.jd_mode) { regmap_update_bits(rt5645->regmap, RT5645_GEN_CTRL3, - RT5645_IRQ_CLK_GATE_CTRL | RT5645_MICINDET_MANU, - RT5645_IRQ_CLK_GATE_CTRL | RT5645_MICINDET_MANU); + RT5645_IRQ_CLK_GATE_CTRL, + RT5645_IRQ_CLK_GATE_CTRL); regmap_update_bits(rt5645->regmap, RT5645_IN1_CTRL1, - RT5645_CBJ_BST1_EN, RT5645_CBJ_BST1_EN); - regmap_update_bits(rt5645->regmap, RT5645_JD_CTRL3, - RT5645_JD_CBJ_EN | RT5645_JD_CBJ_POL, - RT5645_JD_CBJ_EN | RT5645_JD_CBJ_POL); + RT5645_CBJ_BST1_EN, RT5645_CBJ_BST1_EN); regmap_update_bits(rt5645->regmap, RT5645_MICBIAS, - RT5645_IRQ_CLK_INT, RT5645_IRQ_CLK_INT); - } - - if (rt5645->pdata.jd_mode) { + RT5645_IRQ_CLK_INT, RT5645_IRQ_CLK_INT); regmap_update_bits(rt5645->regmap, RT5645_IRQ_CTRL2, RT5645_IRQ_JD_1_1_EN, RT5645_IRQ_JD_1_1_EN); regmap_update_bits(rt5645->regmap, RT5645_GEN_CTRL3, diff --git a/sound/soc/codecs/rt5645.h b/sound/soc/codecs/rt5645.h index db78e9462876..9ec4e899795d 100644 --- a/sound/soc/codecs/rt5645.h +++ b/sound/soc/codecs/rt5645.h @@ -105,6 +105,7 @@ #define RT5645_TDM_CTRL_1 0x77 #define RT5645_TDM_CTRL_2 0x78 #define RT5645_TDM_CTRL_3 0x79 +#define RT5650_TDM_CTRL_4 0x7a /* Function - Analog */ #define RT5645_GLB_CLK 0x80 @@ -942,10 +943,6 @@ #define RT5645_I2S2_SDI_I2S2 (0x1 << 6) /* ADC/DAC Clock Control 1 (0x73) */ -#define RT5645_I2S_BCLK_MS1_MASK (0x1 << 15) -#define RT5645_I2S_BCLK_MS1_SFT 15 -#define RT5645_I2S_BCLK_MS1_32 (0x0 << 15) -#define RT5645_I2S_BCLK_MS1_64 (0x1 << 15) #define RT5645_I2S_PD1_MASK (0x7 << 12) #define RT5645_I2S_PD1_SFT 12 #define RT5645_I2S_PD1_1 (0x0 << 12) @@ -1067,13 +1064,14 @@ #define RT5645_SCLK_SRC_SFT 14 #define RT5645_SCLK_SRC_MCLK (0x0 << 14) #define RT5645_SCLK_SRC_PLL1 (0x1 << 14) -#define RT5645_SCLK_SRC_RCCLK (0x2 << 14) /* 15MHz */ -#define RT5645_PLL1_SRC_MASK (0x3 << 12) -#define RT5645_PLL1_SRC_SFT 12 -#define RT5645_PLL1_SRC_MCLK (0x0 << 12) -#define RT5645_PLL1_SRC_BCLK1 (0x1 << 12) -#define RT5645_PLL1_SRC_BCLK2 (0x2 << 12) -#define RT5645_PLL1_SRC_BCLK3 (0x3 << 12) +#define RT5645_SCLK_SRC_RCCLK (0x2 << 14) +#define RT5645_PLL1_SRC_MASK (0x7 << 11) +#define RT5645_PLL1_SRC_SFT 11 +#define RT5645_PLL1_SRC_MCLK (0x0 << 11) +#define RT5645_PLL1_SRC_BCLK1 (0x1 << 11) +#define RT5645_PLL1_SRC_BCLK2 (0x2 << 11) +#define RT5645_PLL1_SRC_BCLK3 (0x3 << 11) +#define RT5645_PLL1_SRC_RCCLK (0x4 << 11) #define RT5645_PLL1_PD_MASK (0x1 << 3) #define RT5645_PLL1_PD_SFT 3 #define RT5645_PLL1_PD_1 (0x0 << 3) @@ -2147,6 +2145,7 @@ enum { }; enum { + RT5645_DMIC1_DISABLE, RT5645_DMIC_DATA_IN2P, RT5645_DMIC_DATA_GPIO6, RT5645_DMIC_DATA_GPIO10, @@ -2154,6 +2153,7 @@ enum { }; enum { + RT5645_DMIC2_DISABLE, RT5645_DMIC_DATA_IN2N, RT5645_DMIC_DATA_GPIO5, RT5645_DMIC_DATA_GPIO11, @@ -2184,6 +2184,7 @@ struct rt5645_priv { struct i2c_client *i2c; struct snd_soc_jack *hp_jack; struct snd_soc_jack *mic_jack; + struct snd_soc_jack *btn_jack; struct delayed_work jack_detect_work; int codec_type; @@ -2196,9 +2197,12 @@ struct rt5645_priv { int pll_src; int pll_in; int pll_out; + + int jack_type; + bool en_button_func; }; int rt5645_set_jack_detect(struct snd_soc_codec *codec, - struct snd_soc_jack *hp_jack, struct snd_soc_jack *mic_jack); - + struct snd_soc_jack *hp_jack, struct snd_soc_jack *mic_jack, + struct snd_soc_jack *btn_jack); #endif /* __RT5645_H__ */ diff --git a/sound/soc/intel/boards/cht_bsw_rt5645.c b/sound/soc/intel/boards/cht_bsw_rt5645.c index 20a28b22e30f..26e01f36b704 100644 --- a/sound/soc/intel/boards/cht_bsw_rt5645.c +++ b/sound/soc/intel/boards/cht_bsw_rt5645.c @@ -185,7 +185,7 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime) return ret; } - rt5645_set_jack_detect(codec, &ctx->hp_jack, &ctx->mic_jack); + rt5645_set_jack_detect(codec, &ctx->hp_jack, &ctx->mic_jack, NULL); return ret; } |