diff options
Diffstat (limited to 'sound/soc/codecs/rt5670.c')
| -rw-r--r-- | sound/soc/codecs/rt5670.c | 400 |
1 files changed, 284 insertions, 116 deletions
diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c index 70fee6849ab0..cb5d03bf4c7f 100644 --- a/sound/soc/codecs/rt5670.c +++ b/sound/soc/codecs/rt5670.c @@ -25,24 +25,24 @@ #include <sound/soc-dapm.h> #include <sound/initval.h> #include <sound/tlv.h> -#include <sound/rt5670.h> #include "rl6231.h" #include "rt5670.h" #include "rt5670-dsp.h" -#define RT5670_DEV_GPIO BIT(0) -#define RT5670_IN2_DIFF BIT(1) -#define RT5670_DMIC_EN BIT(2) -#define RT5670_DMIC1_IN2P BIT(3) -#define RT5670_DMIC1_GPIO6 BIT(4) -#define RT5670_DMIC1_GPIO7 BIT(5) -#define RT5670_DMIC2_INR BIT(6) -#define RT5670_DMIC2_GPIO8 BIT(7) -#define RT5670_DMIC3_GPIO5 BIT(8) -#define RT5670_JD_MODE1 BIT(9) -#define RT5670_JD_MODE2 BIT(10) -#define RT5670_JD_MODE3 BIT(11) +#define RT5670_GPIO1_IS_IRQ BIT(0) +#define RT5670_IN2_DIFF BIT(1) +#define RT5670_DMIC_EN BIT(2) +#define RT5670_DMIC1_IN2P BIT(3) +#define RT5670_DMIC1_GPIO6 BIT(4) +#define RT5670_DMIC1_GPIO7 BIT(5) +#define RT5670_DMIC2_INR BIT(6) +#define RT5670_DMIC2_GPIO8 BIT(7) +#define RT5670_DMIC3_GPIO5 BIT(8) +#define RT5670_JD_MODE1 BIT(9) +#define RT5670_JD_MODE2 BIT(10) +#define RT5670_JD_MODE3 BIT(11) +#define RT5670_GPIO1_IS_EXT_SPK_EN BIT(12) static unsigned long rt5670_quirk; static unsigned int quirk_override; @@ -431,7 +431,7 @@ static bool rt5670_readable_register(struct device *dev, unsigned int reg) static int rt5670_headset_detect(struct snd_soc_component *component, int jack_insert) { int val; - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component); if (jack_insert) { @@ -452,13 +452,13 @@ static int rt5670_headset_detect(struct snd_soc_component *component, int jack_i snd_soc_component_update_bits(component, RT5670_CJ_CTRL2, RT5670_CBJ_MN_JD, 0); msleep(300); - val = snd_soc_component_read32(component, RT5670_CJ_CTRL3) & 0x7; + val = snd_soc_component_read(component, RT5670_CJ_CTRL3) & 0x7; if (val == 0x1 || val == 0x2) { rt5670->jack_type = SND_JACK_HEADSET; /* for push button */ snd_soc_component_update_bits(component, RT5670_INT_IRQ_ST, 0x8, 0x8); snd_soc_component_update_bits(component, RT5670_IL_CMD, 0x40, 0x40); - snd_soc_component_read32(component, RT5670_IL_CMD); + snd_soc_component_read(component, RT5670_IL_CMD); } else { snd_soc_component_update_bits(component, RT5670_GEN_CTRL3, 0x4, 0x4); rt5670->jack_type = SND_JACK_HEADPHONE; @@ -498,12 +498,12 @@ static int rt5670_button_detect(struct snd_soc_component *component) { int btn_type, val; - val = snd_soc_component_read32(component, RT5670_IL_CMD); + val = snd_soc_component_read(component, RT5670_IL_CMD); btn_type = val & 0xff80; snd_soc_component_write(component, RT5670_IL_CMD, val); if (btn_type != 0) { msleep(20); - val = snd_soc_component_read32(component, RT5670_IL_CMD); + val = snd_soc_component_read(component, RT5670_IL_CMD); snd_soc_component_write(component, RT5670_IL_CMD, val); } @@ -517,10 +517,10 @@ static int rt5670_irq_detection(void *data) struct snd_soc_jack *jack = rt5670->jack; int val, btn_type, report = jack->status; - if (rt5670->pdata.jd_mode == 1) /* 2 port */ - val = snd_soc_component_read32(rt5670->component, RT5670_A_JD_CTRL1) & 0x0070; + if (rt5670->jd_mode == 1) /* 2 port */ + val = snd_soc_component_read(rt5670->component, RT5670_A_JD_CTRL1) & 0x0070; else - val = snd_soc_component_read32(rt5670->component, RT5670_A_JD_CTRL1) & 0x0020; + val = snd_soc_component_read(rt5670->component, RT5670_A_JD_CTRL1) & 0x0020; switch (val) { /* jack in */ @@ -533,7 +533,7 @@ static int rt5670_irq_detection(void *data) break; } btn_type = 0; - if (snd_soc_component_read32(rt5670->component, RT5670_INT_IRQ_ST) & 0x4) { + if (snd_soc_component_read(rt5670->component, RT5670_INT_IRQ_ST) & 0x4) { /* button pressed */ report = SND_JACK_HEADSET; btn_type = rt5670_button_detect(rt5670->component); @@ -602,9 +602,9 @@ int rt5670_set_jack_detect(struct snd_soc_component *component, EXPORT_SYMBOL_GPL(rt5670_set_jack_detect); 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_MINMAX(dac_vol_tlv, -6562, 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_MINMAX(adc_vol_tlv, -1762, 3000); static const DECLARE_TLV_DB_SCALE(adc_bst_tlv, 0, 1200, 0); /* {0, +20, +24, +30, +35, +40, +44, +50, +52} dB */ @@ -629,21 +629,69 @@ static SOC_ENUM_SINGLE_DECL(rt5670_if2_dac_enum, RT5670_DIG_INF1_DATA, static SOC_ENUM_SINGLE_DECL(rt5670_if2_adc_enum, RT5670_DIG_INF1_DATA, RT5670_IF2_ADC_SEL_SFT, rt5670_data_select); +/* + * For reliable output-mute LED control we need a "DAC1 Playback Switch" control. + * We emulate this by only clearing the RT5670_M_DAC1_L/_R AD_DA_MIXER register + * bits when both our emulated DAC1 Playback Switch control and the DAC1 MIXL/R + * DAPM-mixer DAC1 input are enabled. + */ +static void rt5670_update_ad_da_mixer_dac1_m_bits(struct rt5670_priv *rt5670) +{ + int val = RT5670_M_DAC1_L | RT5670_M_DAC1_R; + + if (rt5670->dac1_mixl_dac1_switch && rt5670->dac1_playback_switch_l) + val &= ~RT5670_M_DAC1_L; + + if (rt5670->dac1_mixr_dac1_switch && rt5670->dac1_playback_switch_r) + val &= ~RT5670_M_DAC1_R; + + regmap_update_bits(rt5670->regmap, RT5670_AD_DA_MIXER, + RT5670_M_DAC1_L | RT5670_M_DAC1_R, val); +} + +static int rt5670_dac1_playback_switch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = rt5670->dac1_playback_switch_l; + ucontrol->value.integer.value[1] = rt5670->dac1_playback_switch_r; + + return 0; +} + +static int rt5670_dac1_playback_switch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component); + + if (rt5670->dac1_playback_switch_l == ucontrol->value.integer.value[0] && + rt5670->dac1_playback_switch_r == ucontrol->value.integer.value[1]) + return 0; + + rt5670->dac1_playback_switch_l = ucontrol->value.integer.value[0]; + rt5670->dac1_playback_switch_r = ucontrol->value.integer.value[1]; + + rt5670_update_ad_da_mixer_dac1_m_bits(rt5670); + + return 1; +} + static const struct snd_kcontrol_new rt5670_snd_controls[] = { /* Headphone Output Volume */ - SOC_DOUBLE("HP Playback Switch", RT5670_HP_VOL, - RT5670_L_MUTE_SFT, RT5670_R_MUTE_SFT, 1, 1), SOC_DOUBLE_TLV("HP Playback Volume", RT5670_HP_VOL, RT5670_L_VOL_SFT, RT5670_R_VOL_SFT, 39, 1, out_vol_tlv), /* OUTPUT Control */ - SOC_DOUBLE("OUT Channel Switch", RT5670_LOUT1, - RT5670_VOL_L_SFT, RT5670_VOL_R_SFT, 1, 1), SOC_DOUBLE_TLV("OUT Playback Volume", RT5670_LOUT1, RT5670_L_VOL_SFT, RT5670_R_VOL_SFT, 39, 1, out_vol_tlv), /* DAC Digital Volume */ SOC_DOUBLE("DAC2 Playback Switch", RT5670_DAC_CTRL, RT5670_M_DAC_L2_VOL_SFT, RT5670_M_DAC_R2_VOL_SFT, 1, 1), + SOC_DOUBLE_EXT("DAC1 Playback Switch", SND_SOC_NOPM, 0, 1, 1, 0, + rt5670_dac1_playback_switch_get, rt5670_dac1_playback_switch_put), SOC_DOUBLE_TLV("DAC1 Playback Volume", RT5670_DAC1_DIG_VOL, RT5670_L_VOL_SFT, RT5670_R_VOL_SFT, 175, 0, dac_vol_tlv), @@ -762,7 +810,7 @@ static int is_using_asrc(struct snd_soc_dapm_widget *source, return 0; } - val = (snd_soc_component_read32(component, reg) >> shift) & 0xf; + val = (snd_soc_component_read(component, reg) >> shift) & 0xf; switch (val) { case 1: case 2: @@ -913,18 +961,44 @@ static const struct snd_kcontrol_new rt5670_mono_adc_r_mix[] = { RT5670_M_MONO_ADC_R2_SFT, 1, 1), }; +/* See comment above rt5670_update_ad_da_mixer_dac1_m_bits() */ +static int rt5670_put_dac1_mix_dac1_switch(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; + struct snd_soc_component *component = snd_soc_dapm_kcontrol_to_component(kcontrol); + struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component); + int ret; + + if (mc->shift == 0) + rt5670->dac1_mixl_dac1_switch = ucontrol->value.integer.value[0]; + else + rt5670->dac1_mixr_dac1_switch = ucontrol->value.integer.value[0]; + + /* Apply the update (if any) */ + ret = snd_soc_dapm_put_volsw(kcontrol, ucontrol); + if (ret == 0) + return 0; + + rt5670_update_ad_da_mixer_dac1_m_bits(rt5670); + + return 1; +} + +#define SOC_DAPM_SINGLE_RT5670_DAC1_SW(name, shift) \ + SOC_SINGLE_EXT(name, SND_SOC_NOPM, shift, 1, 0, \ + snd_soc_dapm_get_volsw, rt5670_put_dac1_mix_dac1_switch) + static const struct snd_kcontrol_new rt5670_dac_l_mix[] = { SOC_DAPM_SINGLE("Stereo ADC Switch", RT5670_AD_DA_MIXER, RT5670_M_ADCMIX_L_SFT, 1, 1), - SOC_DAPM_SINGLE("DAC1 Switch", RT5670_AD_DA_MIXER, - RT5670_M_DAC1_L_SFT, 1, 1), + SOC_DAPM_SINGLE_RT5670_DAC1_SW("DAC1 Switch", 0), }; static const struct snd_kcontrol_new rt5670_dac_r_mix[] = { SOC_DAPM_SINGLE("Stereo ADC Switch", RT5670_AD_DA_MIXER, RT5670_M_ADCMIX_R_SFT, 1, 1), - SOC_DAPM_SINGLE("DAC1 Switch", RT5670_AD_DA_MIXER, - RT5670_M_DAC1_R_SFT, 1, 1), + SOC_DAPM_SINGLE_RT5670_DAC1_SW("DAC1 Switch", 1), }; static const struct snd_kcontrol_new rt5670_sto_dac_l_mix[] = { @@ -1079,25 +1153,29 @@ static SOC_ENUM_SINGLE_DECL(rt5670_dac1r_enum, RT5670_AD_DA_MIXER, static const struct snd_kcontrol_new rt5670_dac1r_mux = SOC_DAPM_ENUM("DAC1 R source", rt5670_dac1r_enum); -/*DAC2 L/R source*/ /* MX-1B [6:4] [2:0] */ -/* TODO Use SOC_VALUE_ENUM_SINGLE_DECL */ -static const char * const rt5670_dac12_src[] = { - "IF1 DAC", "IF2 DAC", "IF3 DAC", "TxDC DAC", - "Bass", "VAD_ADC", "IF4 DAC" -}; +/* DAC2 L source*/ /* MX-1B [6:4] */ +static const char *const rt5670_dac12_src[] = { + "IF1 DAC", "IF2 DAC", "TxDC DAC", "VAD_ADC" +}; /* VAD_ADC or TxDP_ADC_R */ + +static const unsigned int rt5670_dac12_values[] = { 0, 1, 3, 5 }; -static SOC_ENUM_SINGLE_DECL(rt5670_dac2l_enum, RT5670_DAC_CTRL, - RT5670_DAC2_L_SEL_SFT, rt5670_dac12_src); +static SOC_VALUE_ENUM_SINGLE_DECL(rt5670_dac2l_enum, RT5670_DAC_CTRL, + RT5670_DAC2_L_SEL_SFT, RT5670_DAC2_L_SEL_MASK, + rt5670_dac12_src, rt5670_dac12_values); static const struct snd_kcontrol_new rt5670_dac_l2_mux = SOC_DAPM_ENUM("DAC2 L source", rt5670_dac2l_enum); -static const char * const rt5670_dacr2_src[] = { - "IF1 DAC", "IF2 DAC", "IF3 DAC", "TxDC DAC", "TxDP ADC", "IF4 DAC" -}; +/*DAC2 R source*/ /* MX-1B [2:0] */ +static const char *const rt5670_dacr2_src[] = { "IF1 DAC", "IF2 DAC", + "TxDC DAC", "TxDP ADC" }; -static SOC_ENUM_SINGLE_DECL(rt5670_dac2r_enum, RT5670_DAC_CTRL, - RT5670_DAC2_R_SEL_SFT, rt5670_dacr2_src); +static const unsigned int rt5670_dacr2_values[] = { 0, 1, 3, 4 }; + +static SOC_VALUE_ENUM_SINGLE_DECL(rt5670_dac2r_enum, RT5670_DAC_CTRL, + RT5670_DAC2_R_SEL_SFT, RT5670_DAC2_R_SEL_MASK, + rt5670_dacr2_src, rt5670_dacr2_values); static const struct snd_kcontrol_new rt5670_dac_r2_mux = SOC_DAPM_ENUM("DAC2 R source", rt5670_dac2r_enum); @@ -1447,6 +1525,33 @@ static int rt5670_hp_event(struct snd_soc_dapm_widget *w, return 0; } +static int rt5670_spk_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 rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component); + + if (!rt5670->gpio1_is_ext_spk_en) + return 0; + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + regmap_update_bits(rt5670->regmap, RT5670_GPIO_CTRL2, + RT5670_GP1_OUT_MASK, RT5670_GP1_OUT_HI); + break; + + case SND_SOC_DAPM_PRE_PMD: + regmap_update_bits(rt5670->regmap, RT5670_GPIO_CTRL2, + RT5670_GP1_OUT_MASK, RT5670_GP1_OUT_LO); + break; + + default: + return 0; + } + + return 0; +} + static int rt5670_bst1_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { @@ -1629,12 +1734,10 @@ static const struct snd_soc_dapm_widget rt5670_dapm_widgets[] = { RT5670_PWR_ADC_S1F_BIT, 0, NULL, 0), SND_SOC_DAPM_SUPPLY("ADC Stereo2 Filter", RT5670_PWR_DIG2, RT5670_PWR_ADC_S2F_BIT, 0, NULL, 0), - SND_SOC_DAPM_MIXER("Sto1 ADC MIXL", RT5670_STO1_ADC_DIG_VOL, - RT5670_L_MUTE_SFT, 1, rt5670_sto1_adc_l_mix, - ARRAY_SIZE(rt5670_sto1_adc_l_mix)), - SND_SOC_DAPM_MIXER("Sto1 ADC MIXR", RT5670_STO1_ADC_DIG_VOL, - RT5670_R_MUTE_SFT, 1, rt5670_sto1_adc_r_mix, - ARRAY_SIZE(rt5670_sto1_adc_r_mix)), + SND_SOC_DAPM_MIXER("Sto1 ADC MIXL", SND_SOC_NOPM, 0, 0, + rt5670_sto1_adc_l_mix, ARRAY_SIZE(rt5670_sto1_adc_l_mix)), + SND_SOC_DAPM_MIXER("Sto1 ADC MIXR", SND_SOC_NOPM, 0, 0, + rt5670_sto1_adc_r_mix, ARRAY_SIZE(rt5670_sto1_adc_r_mix)), SND_SOC_DAPM_MIXER("Sto2 ADC MIXL", SND_SOC_NOPM, 0, 0, rt5670_sto2_adc_l_mix, ARRAY_SIZE(rt5670_sto2_adc_l_mix)), @@ -1860,7 +1963,9 @@ static const struct snd_soc_dapm_widget rt5670_specific_dapm_widgets[] = { }; static const struct snd_soc_dapm_widget rt5672_specific_dapm_widgets[] = { - SND_SOC_DAPM_PGA("SPO Amp", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_PGA_E("SPO Amp", SND_SOC_NOPM, 0, 0, NULL, 0, + rt5670_spk_event, SND_SOC_DAPM_PRE_PMD | + SND_SOC_DAPM_POST_PMU), SND_SOC_DAPM_OUTPUT("SPOLP"), SND_SOC_DAPM_OUTPUT("SPOLN"), SND_SOC_DAPM_OUTPUT("SPORP"), @@ -2338,10 +2443,10 @@ static int rt5670_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) unsigned int reg_val = 0; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: rt5670->master[dai->id] = 1; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: reg_val |= RT5670_I2S_MS_S; rt5670->master[dai->id] = 0; break; @@ -2476,7 +2581,7 @@ static int rt5670_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source, ret = rl6231_pll_calc(freq_in, freq_out, &pll_code); if (ret < 0) { - dev_err(component->dev, "Unsupport input clock %d\n", freq_in); + dev_err(component->dev, "Unsupported input clock %d\n", freq_in); return ret; } @@ -2487,8 +2592,8 @@ static int rt5670_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source, snd_soc_component_write(component, RT5670_PLL_CTRL1, pll_code.n_code << RT5670_PLL_N_SFT | pll_code.k_code); snd_soc_component_write(component, RT5670_PLL_CTRL2, - (pll_code.m_bp ? 0 : pll_code.m_code) << RT5670_PLL_M_SFT | - pll_code.m_bp << RT5670_PLL_M_BP_SFT); + ((pll_code.m_bp ? 0 : pll_code.m_code) << RT5670_PLL_M_SFT) | + (pll_code.m_bp << RT5670_PLL_M_BP_SFT)); rt5670->pll_in = freq_in; rt5670->pll_out = freq_out; @@ -2565,10 +2670,11 @@ static int rt5670_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); switch (level) { case SND_SOC_BIAS_PREPARE: - if (SND_SOC_BIAS_STANDBY == snd_soc_component_get_bias_level(component)) { + if (SND_SOC_BIAS_STANDBY == snd_soc_dapm_get_bias_level(dapm)) { snd_soc_component_update_bits(component, RT5670_PWR_ANLG1, RT5670_PWR_VREF1 | RT5670_PWR_MB | RT5670_PWR_BG | RT5670_PWR_VREF2, @@ -2594,7 +2700,7 @@ static int rt5670_set_bias_level(struct snd_soc_component *component, RT5670_LDO_SEL_MASK, 0x3); break; case SND_SOC_BIAS_OFF: - if (rt5670->pdata.jd_mode) + if (rt5670->jd_mode) snd_soc_component_update_bits(component, RT5670_PWR_ANLG1, RT5670_PWR_VREF1 | RT5670_PWR_MB | RT5670_PWR_BG | RT5670_PWR_VREF2 | @@ -2618,10 +2724,10 @@ static int rt5670_set_bias_level(struct snd_soc_component *component, static int rt5670_probe(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component); - switch (snd_soc_component_read32(component, RT5670_RESET) & RT5670_ID_MASK) { + switch (snd_soc_component_read(component, RT5670_RESET) & RT5670_ID_MASK) { case RT5670_ID_5670: case RT5670_ID_5671: snd_soc_dapm_new_controls(dapm, @@ -2712,7 +2818,7 @@ static struct snd_soc_dai_driver rt5670_dai[] = { .formats = RT5670_FORMATS, }, .ops = &rt5670_aif_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }, { .name = "rt5670-aif2", @@ -2732,7 +2838,7 @@ static struct snd_soc_dai_driver rt5670_dai[] = { .formats = RT5670_FORMATS, }, .ops = &rt5670_aif_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }, }; @@ -2751,7 +2857,6 @@ static const struct snd_soc_component_driver soc_component_dev_rt5670 = { .num_dapm_routes = ARRAY_SIZE(rt5670_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config rt5670_regmap = { @@ -2763,7 +2868,7 @@ static const struct regmap_config rt5670_regmap = { RT5670_PR_SPACING), .volatile_reg = rt5670_volatile_register, .readable_reg = rt5670_readable_register, - .cache_type = REGCACHE_RBTREE, + .cache_type = REGCACHE_MAPLE, .reg_defaults = rt5670_reg, .num_reg_defaults = ARRAY_SIZE(rt5670_reg), .ranges = rt5670_ranges, @@ -2771,19 +2876,19 @@ static const struct regmap_config rt5670_regmap = { }; static const struct i2c_device_id rt5670_i2c_id[] = { - { "rt5670", 0 }, - { "rt5671", 0 }, - { "rt5672", 0 }, + { "rt5670" }, + { "rt5671" }, + { "rt5672" }, { } }; MODULE_DEVICE_TABLE(i2c, rt5670_i2c_id); #ifdef CONFIG_ACPI static const struct acpi_device_id rt5670_acpi_match[] = { - { "10EC5670", 0}, - { "10EC5672", 0}, - { "10EC5640", 0}, /* quirk */ - { }, + { "10EC5640" }, /* quirk */ + { "10EC5670" }, + { "10EC5672" }, + { } }; MODULE_DEVICE_TABLE(acpi, rt5670_acpi_match); #endif @@ -2804,7 +2909,7 @@ static const struct dmi_system_id dmi_platform_intel_quirks[] = { }, .driver_data = (unsigned long *)(RT5670_DMIC_EN | RT5670_DMIC1_IN2P | - RT5670_DEV_GPIO | + RT5670_GPIO1_IS_IRQ | RT5670_JD_MODE1), }, { @@ -2816,7 +2921,7 @@ static const struct dmi_system_id dmi_platform_intel_quirks[] = { }, .driver_data = (unsigned long *)(RT5670_DMIC_EN | RT5670_DMIC1_IN2P | - RT5670_DEV_GPIO | + RT5670_GPIO1_IS_IRQ | RT5670_JD_MODE1), }, { @@ -2828,7 +2933,7 @@ static const struct dmi_system_id dmi_platform_intel_quirks[] = { }, .driver_data = (unsigned long *)(RT5670_DMIC_EN | RT5670_DMIC2_INR | - RT5670_DEV_GPIO | + RT5670_GPIO1_IS_IRQ | RT5670_JD_MODE1), }, { @@ -2840,7 +2945,7 @@ static const struct dmi_system_id dmi_platform_intel_quirks[] = { }, .driver_data = (unsigned long *)(RT5670_DMIC_EN | RT5670_DMIC1_IN2P | - RT5670_DEV_GPIO | + RT5670_GPIO1_IS_IRQ | RT5670_JD_MODE1), }, { @@ -2852,19 +2957,19 @@ static const struct dmi_system_id dmi_platform_intel_quirks[] = { }, .driver_data = (unsigned long *)(RT5670_DMIC_EN | RT5670_DMIC1_IN2P | - RT5670_DEV_GPIO | + RT5670_GPIO1_IS_IRQ | RT5670_JD_MODE1), }, { .callback = rt5670_quirk_cb, - .ident = "Lenovo Thinkpad Tablet 10", + .ident = "Lenovo Miix 2 10", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Miix 2 10"), }, .driver_data = (unsigned long *)(RT5670_DMIC_EN | RT5670_DMIC1_IN2P | - RT5670_DEV_GPIO | + RT5670_GPIO1_IS_EXT_SPK_EN | RT5670_JD_MODE2), }, { @@ -2876,11 +2981,23 @@ static const struct dmi_system_id dmi_platform_intel_quirks[] = { }, .driver_data = (unsigned long *)(RT5670_DMIC_EN | RT5670_DMIC2_INR | - RT5670_DEV_GPIO | + RT5670_GPIO1_IS_IRQ | RT5670_JD_MODE3), }, { .callback = rt5670_quirk_cb, + .ident = "Dell Venue 10 Pro 5055", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Venue 10 Pro 5055"), + }, + .driver_data = (unsigned long *)(RT5670_DMIC_EN | + RT5670_DMIC2_INR | + RT5670_GPIO1_IS_IRQ | + RT5670_JD_MODE1), + }, + { + .callback = rt5670_quirk_cb, .ident = "Aegex 10 tablet (RU2)", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "AEGEX"), @@ -2888,16 +3005,53 @@ static const struct dmi_system_id dmi_platform_intel_quirks[] = { }, .driver_data = (unsigned long *)(RT5670_DMIC_EN | RT5670_DMIC2_INR | - RT5670_DEV_GPIO | + RT5670_GPIO1_IS_IRQ | RT5670_JD_MODE3), }, {} }; -static int rt5670_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +const char *rt5670_components(void) +{ + unsigned long quirk; + bool dmic1 = false; + bool dmic2 = false; + bool dmic3 = false; + + if (quirk_override) { + quirk = quirk_override; + } else { + dmi_check_system(dmi_platform_intel_quirks); + quirk = rt5670_quirk; + } + + if ((quirk & RT5670_DMIC1_IN2P) || + (quirk & RT5670_DMIC1_GPIO6) || + (quirk & RT5670_DMIC1_GPIO7)) + dmic1 = true; + + if ((quirk & RT5670_DMIC2_INR) || + (quirk & RT5670_DMIC2_GPIO8)) + dmic2 = true; + + if (quirk & RT5670_DMIC3_GPIO5) + dmic3 = true; + + if (dmic1 && dmic2) + return "cfg-spk:2 cfg-mic:dmics12"; + else if (dmic1) + return "cfg-spk:2 cfg-mic:dmic1"; + else if (dmic2) + return "cfg-spk:2 cfg-mic:dmic2"; + else if (dmic3) + return "cfg-spk:2 cfg-mic:dmic3"; + + return NULL; +} +EXPORT_SYMBOL_GPL(rt5670_components); + +static int rt5670_i2c_probe(struct i2c_client *i2c) { - struct rt5670_platform_data *pdata = dev_get_platdata(&i2c->dev); struct rt5670_priv *rt5670; int ret; unsigned int val; @@ -2910,9 +3064,6 @@ static int rt5670_i2c_probe(struct i2c_client *i2c, i2c_set_clientdata(i2c, rt5670); - if (pdata) - rt5670->pdata = *pdata; - dmi_check_system(dmi_platform_intel_quirks); if (quirk_override) { dev_info(&i2c->dev, "Overriding quirk 0x%x => 0x%x\n", @@ -2920,56 +3071,70 @@ static int rt5670_i2c_probe(struct i2c_client *i2c, rt5670_quirk = quirk_override; } - if (rt5670_quirk & RT5670_DEV_GPIO) { - rt5670->pdata.dev_gpio = true; - dev_info(&i2c->dev, "quirk dev_gpio\n"); + if (rt5670_quirk & RT5670_GPIO1_IS_IRQ) { + rt5670->gpio1_is_irq = true; + dev_info(&i2c->dev, "quirk GPIO1 is IRQ\n"); + } + if (rt5670_quirk & RT5670_GPIO1_IS_EXT_SPK_EN) { + rt5670->gpio1_is_ext_spk_en = true; + dev_info(&i2c->dev, "quirk GPIO1 is external speaker enable\n"); } if (rt5670_quirk & RT5670_IN2_DIFF) { - rt5670->pdata.in2_diff = true; + rt5670->in2_diff = true; dev_info(&i2c->dev, "quirk IN2_DIFF\n"); } if (rt5670_quirk & RT5670_DMIC_EN) { - rt5670->pdata.dmic_en = true; + rt5670->dmic_en = true; dev_info(&i2c->dev, "quirk DMIC enabled\n"); } if (rt5670_quirk & RT5670_DMIC1_IN2P) { - rt5670->pdata.dmic1_data_pin = RT5670_DMIC_DATA_IN2P; + rt5670->dmic1_data_pin = RT5670_DMIC_DATA_IN2P; dev_info(&i2c->dev, "quirk DMIC1 on IN2P pin\n"); } if (rt5670_quirk & RT5670_DMIC1_GPIO6) { - rt5670->pdata.dmic1_data_pin = RT5670_DMIC_DATA_GPIO6; + rt5670->dmic1_data_pin = RT5670_DMIC_DATA_GPIO6; dev_info(&i2c->dev, "quirk DMIC1 on GPIO6 pin\n"); } if (rt5670_quirk & RT5670_DMIC1_GPIO7) { - rt5670->pdata.dmic1_data_pin = RT5670_DMIC_DATA_GPIO7; + rt5670->dmic1_data_pin = RT5670_DMIC_DATA_GPIO7; dev_info(&i2c->dev, "quirk DMIC1 on GPIO7 pin\n"); } if (rt5670_quirk & RT5670_DMIC2_INR) { - rt5670->pdata.dmic2_data_pin = RT5670_DMIC_DATA_IN3N; + rt5670->dmic2_data_pin = RT5670_DMIC_DATA_IN3N; dev_info(&i2c->dev, "quirk DMIC2 on INR pin\n"); } if (rt5670_quirk & RT5670_DMIC2_GPIO8) { - rt5670->pdata.dmic2_data_pin = RT5670_DMIC_DATA_GPIO8; + rt5670->dmic2_data_pin = RT5670_DMIC_DATA_GPIO8; dev_info(&i2c->dev, "quirk DMIC2 on GPIO8 pin\n"); } if (rt5670_quirk & RT5670_DMIC3_GPIO5) { - rt5670->pdata.dmic3_data_pin = RT5670_DMIC_DATA_GPIO5; + rt5670->dmic3_data_pin = RT5670_DMIC_DATA_GPIO5; dev_info(&i2c->dev, "quirk DMIC3 on GPIO5 pin\n"); } if (rt5670_quirk & RT5670_JD_MODE1) { - rt5670->pdata.jd_mode = 1; + rt5670->jd_mode = 1; dev_info(&i2c->dev, "quirk JD mode 1\n"); } if (rt5670_quirk & RT5670_JD_MODE2) { - rt5670->pdata.jd_mode = 2; + rt5670->jd_mode = 2; dev_info(&i2c->dev, "quirk JD mode 2\n"); } if (rt5670_quirk & RT5670_JD_MODE3) { - rt5670->pdata.jd_mode = 3; + rt5670->jd_mode = 3; dev_info(&i2c->dev, "quirk JD mode 3\n"); } + /* + * Enable the emulated "DAC1 Playback Switch" by default to avoid + * muting the output with older UCM profiles. + */ + rt5670->dac1_playback_switch_l = true; + rt5670->dac1_playback_switch_r = true; + /* The Power-On-Reset values for the DAC1 mixer have the DAC1 input enabled. */ + rt5670->dac1_mixl_dac1_switch = true; + rt5670->dac1_mixr_dac1_switch = true; + rt5670->regmap = devm_regmap_init_i2c(i2c, &rt5670_regmap); if (IS_ERR(rt5670->regmap)) { ret = PTR_ERR(rt5670->regmap); @@ -3007,11 +3172,11 @@ static int rt5670_i2c_probe(struct i2c_client *i2c, regmap_update_bits(rt5670->regmap, RT5670_DIG_MISC, RT5670_MCLK_DET, RT5670_MCLK_DET); - if (rt5670->pdata.in2_diff) + if (rt5670->in2_diff) regmap_update_bits(rt5670->regmap, RT5670_IN2, RT5670_IN_DF2, RT5670_IN_DF2); - if (rt5670->pdata.dev_gpio) { + if (rt5670->gpio1_is_irq) { /* for push button */ regmap_write(rt5670->regmap, RT5670_IL_CMD, 0x0000); regmap_write(rt5670->regmap, RT5670_IL_CMD2, 0x0010); @@ -3023,7 +3188,14 @@ static int rt5670_i2c_probe(struct i2c_client *i2c, RT5670_GP1_PF_MASK, RT5670_GP1_PF_OUT); } - if (rt5670->pdata.jd_mode) { + if (rt5670->gpio1_is_ext_spk_en) { + regmap_update_bits(rt5670->regmap, RT5670_GPIO_CTRL1, + RT5670_GP1_PIN_MASK, RT5670_GP1_PIN_GPIO1); + regmap_update_bits(rt5670->regmap, RT5670_GPIO_CTRL2, + RT5670_GP1_PF_MASK, RT5670_GP1_PF_OUT); + } + + if (rt5670->jd_mode) { regmap_update_bits(rt5670->regmap, RT5670_GLB_CLK, RT5670_SCLK_SRC_MASK, RT5670_SCLK_SRC_RCCLK); rt5670->sysclk = 0; @@ -3038,7 +3210,7 @@ static int rt5670_i2c_probe(struct i2c_client *i2c, RT5670_JD_TRI_CBJ_SEL_MASK | RT5670_JD_TRI_HPO_SEL_MASK, RT5670_JD_CBJ_JD1_1 | RT5670_JD_HPO_JD1_1); - switch (rt5670->pdata.jd_mode) { + switch (rt5670->jd_mode) { case 1: regmap_update_bits(rt5670->regmap, RT5670_A_JD_CTRL1, RT5670_JD1_MODE_MASK, @@ -3059,12 +3231,12 @@ static int rt5670_i2c_probe(struct i2c_client *i2c, } } - if (rt5670->pdata.dmic_en) { + if (rt5670->dmic_en) { regmap_update_bits(rt5670->regmap, RT5670_GPIO_CTRL1, RT5670_GP2_PIN_MASK, RT5670_GP2_PIN_DMIC1_SCL); - switch (rt5670->pdata.dmic1_data_pin) { + switch (rt5670->dmic1_data_pin) { case RT5670_DMIC_DATA_IN2P: regmap_update_bits(rt5670->regmap, RT5670_DMIC_CTRL1, RT5670_DMIC_1_DP_MASK, @@ -3093,7 +3265,7 @@ static int rt5670_i2c_probe(struct i2c_client *i2c, break; } - switch (rt5670->pdata.dmic2_data_pin) { + switch (rt5670->dmic2_data_pin) { case RT5670_DMIC_DATA_IN3N: regmap_update_bits(rt5670->regmap, RT5670_DMIC_CTRL1, RT5670_DMIC_2_DP_MASK, @@ -3113,7 +3285,7 @@ static int rt5670_i2c_probe(struct i2c_client *i2c, break; } - switch (rt5670->pdata.dmic3_data_pin) { + switch (rt5670->dmic3_data_pin) { case RT5670_DMIC_DATA_GPIO5: regmap_update_bits(rt5670->regmap, RT5670_DMIC_CTRL2, RT5670_DMIC_3_DP_MASK, @@ -3144,8 +3316,6 @@ static int rt5670_i2c_probe(struct i2c_client *i2c, if (ret < 0) goto err; - pm_runtime_put(&i2c->dev); - return 0; err: pm_runtime_disable(&i2c->dev); @@ -3153,11 +3323,9 @@ err: return ret; } -static int rt5670_i2c_remove(struct i2c_client *i2c) +static void rt5670_i2c_remove(struct i2c_client *i2c) { pm_runtime_disable(&i2c->dev); - - return 0; } static struct i2c_driver rt5670_i2c_driver = { @@ -3165,7 +3333,7 @@ static struct i2c_driver rt5670_i2c_driver = { .name = "rt5670", .acpi_match_table = ACPI_PTR(rt5670_acpi_match), }, - .probe = rt5670_i2c_probe, + .probe = rt5670_i2c_probe, .remove = rt5670_i2c_remove, .id_table = rt5670_i2c_id, }; |
