asoc: update the micbias enable logic
Update the micbias enable logic for tambora, and add some widgets to switch between amic and va amic. Change-Id: I2c9a7658d79a7c9d255884df7b81aa8062185d72 Signed-off-by: Yuhui Zhao <quic_yuhuzhao@quicinc.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _WCD9378_INTERNAL_H
|
||||
@@ -97,12 +97,12 @@ struct wcd9378_priv {
|
||||
|
||||
u32 hph_mode;
|
||||
u16 hph_gain;
|
||||
u32 curr_micbias2;
|
||||
u32 rx2_clk_mode;
|
||||
u32 tx_mode[TX_ADC_MAX];
|
||||
s32 adc_count;
|
||||
bool comp1_enable;
|
||||
bool comp2_enable;
|
||||
bool va_amic_en;
|
||||
bool ear_enable;
|
||||
bool aux_enable;
|
||||
bool ldoh;
|
||||
@@ -226,5 +226,5 @@ extern int wcd9378_mbhc_micb_adjust_voltage(struct snd_soc_component *component,
|
||||
int volt, int micb_num);
|
||||
extern int wcd9378_get_micb_vout_ctl_val(u32 micb_mv);
|
||||
extern int wcd9378_micbias_control(struct snd_soc_component *component,
|
||||
unsigned char tx_path, int req, bool is_dapm);
|
||||
int micb_num, int req, bool is_dapm);
|
||||
#endif /* _WCD9378_INTERNAL_H */
|
||||
|
@@ -223,6 +223,15 @@ static void wcd9378_mbhc_mbhc_bias_control(struct snd_soc_component *component,
|
||||
0x01, 0x00);
|
||||
}
|
||||
|
||||
static void wcd9378_mbhc_get_micbias_val(struct wcd_mbhc *mbhc,
|
||||
int *mb)
|
||||
{
|
||||
struct snd_soc_component *component = mbhc->component;
|
||||
struct wcd9378_priv *wcd9378 = dev_get_drvdata(component->dev);
|
||||
|
||||
*mb = wcd9378->curr_micbias2;
|
||||
}
|
||||
|
||||
static void wcd9378_mbhc_program_btn_thr(struct snd_soc_component *component,
|
||||
s16 *btn_low, s16 *btn_high,
|
||||
int num_btn, bool is_micbias)
|
||||
@@ -273,13 +282,12 @@ static int wcd9378_mbhc_register_notifier(struct wcd_mbhc *mbhc,
|
||||
|
||||
static bool wcd9378_mbhc_micb_en_status(struct wcd_mbhc *mbhc, int micb_num)
|
||||
{
|
||||
u8 val = 0;
|
||||
struct snd_soc_component *component = mbhc->component;
|
||||
struct wcd9378_priv *wcd9378 =
|
||||
dev_get_drvdata(component->dev);
|
||||
|
||||
if (micb_num == MIC_BIAS_2) {
|
||||
val = ((snd_soc_component_read(mbhc->component,
|
||||
WCD9378_ANA_MICB2) & 0xC0)
|
||||
>> 6);
|
||||
if (val == 0x01)
|
||||
if (wcd9378->curr_micbias2)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -287,8 +295,10 @@ static bool wcd9378_mbhc_micb_en_status(struct wcd_mbhc *mbhc, int micb_num)
|
||||
|
||||
static bool wcd9378_mbhc_hph_pa_on_status(struct snd_soc_component *component)
|
||||
{
|
||||
return (snd_soc_component_read(component, WCD9378_ANA_HPH) & 0xC0) ?
|
||||
true : false;
|
||||
if (snd_soc_component_read(component, WCD9378_PDE47_ACT_PS))
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
static void wcd9378_mbhc_hph_l_pull_up_control(
|
||||
@@ -311,18 +321,7 @@ static void wcd9378_mbhc_hph_l_pull_up_control(
|
||||
static int wcd9378_mbhc_request_micbias(struct snd_soc_component *component,
|
||||
int micb_num, int req)
|
||||
{
|
||||
int ret = 0, tx_path = 0;
|
||||
|
||||
if (micb_num == MIC_BIAS_2) {
|
||||
tx_path = ADC2;
|
||||
} else {
|
||||
pr_err("%s: cannot support other micbias\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = wcd9378_micbias_control(component, tx_path, req, false);
|
||||
|
||||
return ret;
|
||||
return wcd9378_micbias_control(component, micb_num, req, false);
|
||||
}
|
||||
|
||||
static void wcd9378_mbhc_micb_ramp_control(struct snd_soc_component *component,
|
||||
@@ -841,6 +840,7 @@ static const struct wcd_mbhc_cb mbhc_cb = {
|
||||
.clk_setup = wcd9378_mbhc_clk_setup,
|
||||
.map_btn_code_to_num = wcd9378_mbhc_btn_to_num,
|
||||
.mbhc_bias = wcd9378_mbhc_mbhc_bias_control,
|
||||
.get_micbias_val = wcd9378_mbhc_get_micbias_val,
|
||||
.set_btn_thr = wcd9378_mbhc_program_btn_thr,
|
||||
.lock_sleep = wcd9378_mbhc_lock_sleep,
|
||||
.register_notifier = wcd9378_mbhc_register_notifier,
|
||||
|
@@ -336,6 +336,16 @@ static int wcd9378_init_reg(struct snd_soc_component *component)
|
||||
snd_soc_component_update_bits(component, WCD9378_HPH_DN_T0,
|
||||
WCD9378_HPH_DN_T0_HPH_DN_T0_MASK, 0x06);
|
||||
|
||||
/*SM0 MB SEL:MB1*/
|
||||
snd_soc_component_update_bits(component, WCD9378_SM0_MB_SEL,
|
||||
WCD9378_SM0_MB_SEL_SM0_MB_SEL_MASK, 0x01);
|
||||
/*SM0 MB SEL:MB2*/
|
||||
snd_soc_component_update_bits(component, WCD9378_SM1_MB_SEL,
|
||||
WCD9378_SM1_MB_SEL_SM1_MB_SEL_MASK, 0x02);
|
||||
/*SM0 MB SEL:MB3*/
|
||||
snd_soc_component_update_bits(component, WCD9378_SM2_MB_SEL,
|
||||
WCD9378_SM2_MB_SEL_SM2_MB_SEL_MASK, 0x03);
|
||||
|
||||
wcd9378_class_load(component);
|
||||
return 0;
|
||||
}
|
||||
@@ -818,11 +828,7 @@ int wcd9378_mbhc_micb_adjust_voltage(struct snd_soc_component *component,
|
||||
{
|
||||
struct wcd9378_priv *wcd9378 =
|
||||
snd_soc_component_get_drvdata(component);
|
||||
int micb_usage = 0, micb_mask = 0, req_vout_ctl;
|
||||
int sm_num = 0;
|
||||
struct wcd9378_pdata *pdata = NULL;
|
||||
|
||||
pdata = dev_get_platdata(wcd9378->dev);
|
||||
int micb_usage = 0, micb_mask = 0, req_vout_ctl = 0;
|
||||
|
||||
if (wcd9378 == NULL) {
|
||||
dev_err(component->dev,
|
||||
@@ -830,35 +836,22 @@ int wcd9378_mbhc_micb_adjust_voltage(struct snd_soc_component *component,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (sm_num = 0; sm_num < SIM_MIC_NUM; sm_num++)
|
||||
if (wcd9378->micb_sel[sm_num] == micb_num)
|
||||
break;
|
||||
|
||||
if ((sm_num == SIM_MIC_NUM) && (micb_num != MIC_BIAS_2)) {
|
||||
pr_err("%s: cannot find the simple mic function which connect to micbias_%d\n",
|
||||
__func__, micb_num);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
||||
switch (sm_num) {
|
||||
case SIM_MIC0:
|
||||
switch (micb_num) {
|
||||
case MIC_BIAS_1:
|
||||
micb_usage = WCD9378_IT11_USAGE;
|
||||
micb_mask = WCD9378_IT11_MICB_IT11_MICB_MASK;
|
||||
break;
|
||||
case SIM_MIC1:
|
||||
case MIC_BIAS_2:
|
||||
micb_usage = WCD9378_SMP_MIC_CTRL1_IT11_MICB;
|
||||
micb_mask = WCD9378_SMP_MIC_CTRL1_IT11_MICB_IT11_MICB_MASK;
|
||||
break;
|
||||
case SIM_MIC2:
|
||||
case MIC_BIAS_3:
|
||||
micb_usage = WCD9378_SMP_MIC_CTRL2_IT11_MICB;
|
||||
micb_mask = WCD9378_SMP_MIC_CTRL2_IT11_MICB_IT11_MICB_MASK;
|
||||
break;
|
||||
default:
|
||||
if (micb_num == MIC_BIAS_2) {
|
||||
micb_usage = WCD9378_IT31_MICB;
|
||||
micb_mask = WCD9378_IT31_MICB_IT31_MICB_MASK;
|
||||
}
|
||||
dev_err(component->dev,
|
||||
"%s: wcd9378 private data is NULL\n", __func__);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -870,6 +863,15 @@ int wcd9378_mbhc_micb_adjust_voltage(struct snd_soc_component *component,
|
||||
snd_soc_component_update_bits(component,
|
||||
micb_usage, micb_mask, req_vout_ctl);
|
||||
|
||||
if (micb_num == MIC_BIAS_2) {
|
||||
dev_err(component->dev,
|
||||
"%s: sj micbias set\n", __func__);
|
||||
snd_soc_component_update_bits(component,
|
||||
WCD9378_IT31_MICB,
|
||||
WCD9378_IT31_MICB_IT31_MICB_MASK,
|
||||
req_vout_ctl);
|
||||
wcd9378->curr_micbias2 = req_volt;
|
||||
}
|
||||
mutex_unlock(&wcd9378->micb_lock);
|
||||
return 0;
|
||||
|
||||
@@ -975,12 +977,6 @@ static int wcd9378_tx_sequencer_enable(struct snd_soc_dapm_widget *w,
|
||||
wcd9378_tx_connect_port(component, w->shift, rate,
|
||||
true);
|
||||
|
||||
if (wcd9378->va_amic_en)
|
||||
wcd9378_micbias_control(component, w->shift,
|
||||
MICB_PULLUP_ENABLE, true);
|
||||
else
|
||||
wcd9378_micbias_control(component, w->shift,
|
||||
MICB_ENABLE, true);
|
||||
switch (w->shift) {
|
||||
case ADC1:
|
||||
/*SMP MIC0 IT11 USAGE SET*/
|
||||
@@ -1151,12 +1147,6 @@ static int wcd9378_tx_sequencer_enable(struct snd_soc_dapm_widget *w,
|
||||
false);
|
||||
wcd9378_swr_slave_clk_set(wcd9378->dev, bank, TX_PATH, false);
|
||||
|
||||
if (wcd9378->va_amic_en)
|
||||
wcd9378_micbias_control(component, w->shift,
|
||||
MICB_PULLUP_DISABLE, true);
|
||||
else
|
||||
wcd9378_micbias_control(component, w->shift,
|
||||
MICB_DISABLE, true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -1189,36 +1179,13 @@ static int wcd9378_tx_swr_ctrl(struct snd_soc_dapm_widget *w,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int wcd9378_tx_num_get(struct snd_soc_component *component,
|
||||
int micb_num)
|
||||
{
|
||||
int sm_num = 0;
|
||||
struct wcd9378_priv *wcd9378 =
|
||||
snd_soc_component_get_drvdata(component);
|
||||
|
||||
for (sm_num = SIM_MIC0; sm_num <= SIM_MIC2; sm_num++) {
|
||||
if (wcd9378->micb_sel[sm_num] == micb_num) {
|
||||
if (sm_num == SIM_MIC0)
|
||||
return ADC1;
|
||||
else if (sm_num == SIM_MIC1)
|
||||
return ADC2;
|
||||
else if (sm_num == SIM_MIC2)
|
||||
return ADC3;
|
||||
else
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int wcd9378_codec_enable_micbias(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol,
|
||||
int event)
|
||||
{
|
||||
struct snd_soc_component *component =
|
||||
snd_soc_dapm_to_component(w->dapm);
|
||||
int micb_num = 0, tx_num = 0;
|
||||
int micb_num = 0;
|
||||
|
||||
dev_dbg(component->dev, "%s: wname: %s, event: %d\n",
|
||||
__func__, w->name, event);
|
||||
@@ -1232,20 +1199,16 @@ static int wcd9378_codec_enable_micbias(struct snd_soc_dapm_widget *w,
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
tx_num = wcd9378_tx_num_get(component, micb_num);
|
||||
if (tx_num < 0)
|
||||
pr_err("%s: SM MB SEL should be set properly\n", __func__);
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_PRE_PMU:
|
||||
wcd9378_micbias_control(component, tx_num,
|
||||
wcd9378_micbias_control(component, micb_num,
|
||||
MICB_ENABLE, true);
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
usleep_range(1000, 1100);
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMD:
|
||||
wcd9378_micbias_control(component, tx_num,
|
||||
wcd9378_micbias_control(component, micb_num,
|
||||
MICB_DISABLE, true);
|
||||
break;
|
||||
};
|
||||
@@ -1259,7 +1222,7 @@ static int wcd9378_codec_enable_micbias_pullup(struct snd_soc_dapm_widget *w,
|
||||
{
|
||||
struct snd_soc_component *component =
|
||||
snd_soc_dapm_to_component(w->dapm);
|
||||
int micb_num = 0, tx_num = 0;
|
||||
int micb_num = 0;
|
||||
|
||||
dev_dbg(component->dev, "%s: wname: %s, event: %d\n",
|
||||
__func__, w->name, event);
|
||||
@@ -1273,20 +1236,16 @@ static int wcd9378_codec_enable_micbias_pullup(struct snd_soc_dapm_widget *w,
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
tx_num = wcd9378_tx_num_get(component, micb_num);
|
||||
if (tx_num < 0)
|
||||
pr_err("%s: SM MB SEL should be set properly\n", __func__);
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_PRE_PMU:
|
||||
wcd9378_micbias_control(component, tx_num,
|
||||
wcd9378_micbias_control(component, micb_num,
|
||||
MICB_PULLUP_ENABLE, true);
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
usleep_range(1000, 1100);
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMD:
|
||||
wcd9378_micbias_control(component, tx_num,
|
||||
wcd9378_micbias_control(component, micb_num,
|
||||
MICB_PULLUP_DISABLE, true);
|
||||
break;
|
||||
};
|
||||
@@ -2010,56 +1969,33 @@ static int wcd9378_sa_sequencer_enable(struct snd_soc_dapm_widget *w,
|
||||
}
|
||||
|
||||
int wcd9378_micbias_control(struct snd_soc_component *component,
|
||||
unsigned char tx_path, int req, bool is_dapm)
|
||||
int micb_num, int req, bool is_dapm)
|
||||
{
|
||||
struct wcd9378_priv *wcd9378 =
|
||||
snd_soc_component_get_drvdata(component);
|
||||
struct wcd9378_pdata *pdata =
|
||||
dev_get_platdata(wcd9378->dev);
|
||||
struct wcd9378_micbias_setting *mb = &pdata->micbias;
|
||||
int micb_num = 0, micb_usage = 0, micb_mask = 0, micb_usage_val = 0;
|
||||
int micb_usage = 0, micb_mask = 0, micb_usage_val = 0;
|
||||
int pre_off_event = 0, post_off_event = 0;
|
||||
int post_on_event = 0, post_dapm_off = 0;
|
||||
int post_dapm_on = 0;
|
||||
int pull_up_mask = 0, pull_up_en = 0;
|
||||
int micb_index = 0, ret = 0;
|
||||
|
||||
switch (tx_path) {
|
||||
case ADC1:
|
||||
micb_num = wcd9378->micb_sel[0];
|
||||
micb_usage = WCD9378_IT11_MICB;
|
||||
micb_mask = WCD9378_IT11_MICB_IT11_MICB_MASK;
|
||||
break;
|
||||
case ADC2:
|
||||
if (wcd9378->sjmic_support) {
|
||||
micb_num = MIC_BIAS_2;
|
||||
micb_usage = WCD9378_IT31_MICB;
|
||||
micb_mask = WCD9378_IT31_MICB_IT31_MICB_MASK;
|
||||
} else {
|
||||
micb_num = wcd9378->micb_sel[1];
|
||||
micb_usage = WCD9378_SMP_MIC_CTRL1_IT11_MICB;
|
||||
micb_mask = WCD9378_SMP_MIC_CTRL1_IT11_MICB_IT11_MICB_MASK;
|
||||
}
|
||||
break;
|
||||
case ADC3:
|
||||
micb_num = wcd9378->micb_sel[2];
|
||||
micb_usage = WCD9378_SMP_MIC_CTRL2_IT11_MICB;
|
||||
micb_mask = WCD9378_SMP_MIC_CTRL2_IT11_MICB_IT11_MICB_MASK;
|
||||
break;
|
||||
default:
|
||||
pr_err("%s: unsupport tx path\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (micb_num) {
|
||||
case MIC_BIAS_1:
|
||||
pull_up_mask = WCD9378_MB_PULLUP_EN_MB1_1P8V_OR_PULLUP_SEL_MASK;
|
||||
pull_up_en = 0x01;
|
||||
micb_usage = WCD9378_IT11_MICB;
|
||||
micb_mask = WCD9378_IT11_MICB_IT11_MICB_MASK;
|
||||
micb_usage_val = mb->micb1_usage_val;
|
||||
break;
|
||||
case MIC_BIAS_2:
|
||||
pull_up_mask = WCD9378_MB_PULLUP_EN_MB2_1P8V_OR_PULLUP_SEL_MASK;
|
||||
pull_up_en = 0x02;
|
||||
micb_usage = WCD9378_SMP_MIC_CTRL1_IT11_MICB;
|
||||
micb_mask = WCD9378_SMP_MIC_CTRL1_IT11_MICB_IT11_MICB_MASK;
|
||||
micb_usage_val = mb->micb2_usage_val;
|
||||
pre_off_event = WCD_EVENT_PRE_MICBIAS_2_OFF;
|
||||
post_off_event = WCD_EVENT_POST_MICBIAS_2_OFF;
|
||||
@@ -2068,6 +2004,8 @@ int wcd9378_micbias_control(struct snd_soc_component *component,
|
||||
post_dapm_off = WCD_EVENT_POST_DAPM_MICBIAS_2_OFF;
|
||||
break;
|
||||
case MIC_BIAS_3:
|
||||
micb_usage = WCD9378_SMP_MIC_CTRL2_IT11_MICB;
|
||||
micb_mask = WCD9378_SMP_MIC_CTRL2_IT11_MICB_IT11_MICB_MASK;
|
||||
pull_up_mask = WCD9378_MB_PULLUP_EN_MB3_1P8V_OR_PULLUP_SEL_MASK;
|
||||
pull_up_en = 0x04;
|
||||
micb_usage_val = mb->micb3_usage_val;
|
||||
@@ -2090,6 +2028,16 @@ int wcd9378_micbias_control(struct snd_soc_component *component,
|
||||
pull_up_mask, pull_up_en);
|
||||
snd_soc_component_update_bits(component,
|
||||
micb_usage, micb_mask, 0x03);
|
||||
|
||||
if (micb_num == MIC_BIAS_2) {
|
||||
dev_dbg(component->dev, "%s: pull up sj micbias\n",
|
||||
__func__);
|
||||
snd_soc_component_update_bits(component,
|
||||
WCD9378_IT31_MICB,
|
||||
WCD9378_IT31_MICB_IT31_MICB_MASK,
|
||||
0x03);
|
||||
wcd9378->curr_micbias2 = 1800;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MICB_PULLUP_DISABLE:
|
||||
@@ -2099,6 +2047,17 @@ int wcd9378_micbias_control(struct snd_soc_component *component,
|
||||
if ((wcd9378->pullup_ref[micb_index] == 0) &&
|
||||
(wcd9378->micb_ref[micb_index] == 0))
|
||||
snd_soc_component_update_bits(component, micb_usage, micb_mask, 0x01);
|
||||
|
||||
if (micb_num == MIC_BIAS_2) {
|
||||
dev_dbg(component->dev, "%s: pull down sj micbias\n",
|
||||
__func__);
|
||||
snd_soc_component_update_bits(component,
|
||||
WCD9378_IT31_MICB,
|
||||
WCD9378_IT31_MICB_IT31_MICB_MASK,
|
||||
0x01);
|
||||
wcd9378->curr_micbias2 = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MICB_ENABLE:
|
||||
dev_dbg(component->dev, "%s: micbias enable enter\n",
|
||||
@@ -2116,6 +2075,15 @@ int wcd9378_micbias_control(struct snd_soc_component *component,
|
||||
snd_soc_component_update_bits(component,
|
||||
micb_usage, micb_mask, micb_usage_val);
|
||||
|
||||
if (micb_num == MIC_BIAS_2) {
|
||||
dev_dbg(component->dev, "%s: enable sj micbias\n",
|
||||
__func__);
|
||||
snd_soc_component_update_bits(component,
|
||||
WCD9378_IT31_MICB,
|
||||
WCD9378_IT31_MICB_IT31_MICB_MASK,
|
||||
micb_usage_val);
|
||||
wcd9378->curr_micbias2 = 1800;
|
||||
}
|
||||
if (post_on_event)
|
||||
blocking_notifier_call_chain(
|
||||
&wcd9378->mbhc->notifier,
|
||||
@@ -2128,15 +2096,17 @@ int wcd9378_micbias_control(struct snd_soc_component *component,
|
||||
&wcd9378->mbhc->wcd_mbhc);
|
||||
break;
|
||||
case MICB_DISABLE:
|
||||
dev_dbg(component->dev, "%s: micbias disable enter\n",
|
||||
__func__);
|
||||
if (wcd9378->micb_ref[micb_index] > 0)
|
||||
wcd9378->micb_ref[micb_index]--;
|
||||
if ((wcd9378->micb_ref[micb_index] == 0) &&
|
||||
(wcd9378->pullup_ref[micb_index] > 0)) {
|
||||
/*PULL UP?*/
|
||||
snd_soc_component_update_bits(component, WCD9378_MB_PULLUP_EN,
|
||||
pull_up_mask, pull_up_en);
|
||||
snd_soc_component_update_bits(component, micb_usage,
|
||||
micb_mask, 0x03);
|
||||
|
||||
if (micb_num == MIC_BIAS_2)
|
||||
wcd9378->curr_micbias2 = 1800;
|
||||
} else if ((wcd9378->micb_ref[micb_index] == 0) &&
|
||||
(wcd9378->pullup_ref[micb_index] == 0)) {
|
||||
if (pre_off_event && wcd9378->mbhc)
|
||||
@@ -2146,7 +2116,13 @@ int wcd9378_micbias_control(struct snd_soc_component *component,
|
||||
&wcd9378->mbhc->wcd_mbhc);
|
||||
snd_soc_component_update_bits(component, micb_usage,
|
||||
micb_mask, 0x00);
|
||||
|
||||
if (micb_num == MIC_BIAS_2) {
|
||||
snd_soc_component_update_bits(component,
|
||||
WCD9378_IT31_MICB,
|
||||
WCD9378_IT31_MICB_IT31_MICB_MASK,
|
||||
0x00);
|
||||
wcd9378->curr_micbias2 = 0;
|
||||
}
|
||||
if (post_off_event && wcd9378->mbhc)
|
||||
blocking_notifier_call_chain(
|
||||
&wcd9378->mbhc->notifier,
|
||||
@@ -2157,7 +2133,6 @@ int wcd9378_micbias_control(struct snd_soc_component *component,
|
||||
blocking_notifier_call_chain(&wcd9378->mbhc->notifier,
|
||||
post_dapm_off,
|
||||
&wcd9378->mbhc->wcd_mbhc);
|
||||
|
||||
break;
|
||||
default:
|
||||
dev_err(component->dev, "%s: Invalid req event: %d\n",
|
||||
@@ -2176,6 +2151,7 @@ done:
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(wcd9378_micbias_control);
|
||||
|
||||
|
||||
static int wcd9378_get_logical_addr(struct swr_device *swr_dev)
|
||||
{
|
||||
int ret = 0;
|
||||
@@ -2662,129 +2638,6 @@ static int wcd9378_hph_dsm_put(struct snd_kcontrol *kcontrol,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int wcd9378_simple_mic_num_get(const char *wname,
|
||||
unsigned int *sm_num)
|
||||
{
|
||||
int ret = 0;
|
||||
char *widget_name = NULL;
|
||||
char *w_name = NULL;
|
||||
char *sm_num_char = NULL;
|
||||
char *sm_name = NULL;
|
||||
|
||||
widget_name = kstrndup(wname, 9, GFP_KERNEL);
|
||||
if (!widget_name)
|
||||
return -EINVAL;
|
||||
|
||||
w_name = widget_name;
|
||||
|
||||
sm_name = strsep(&widget_name, " ");
|
||||
if (!sm_name) {
|
||||
pr_err("%s: Invalid widget name = %s\n",
|
||||
__func__, widget_name);
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
sm_num_char = strpbrk(sm_name, "0123");
|
||||
if (!sm_num_char) {
|
||||
pr_err("%s: simple mic index not found\n",
|
||||
__func__);
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
ret = kstrtouint(sm_num_char, 10, sm_num);
|
||||
if (ret < 0)
|
||||
pr_err("%s: Invalid micb num = %s\n",
|
||||
__func__, w_name);
|
||||
|
||||
err:
|
||||
kfree(w_name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int wcd9378_mb_sel_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *component =
|
||||
snd_soc_kcontrol_component(kcontrol);
|
||||
struct wcd9378_priv *wcd9378 = NULL;
|
||||
int ret = 0;
|
||||
unsigned int sm_num = 0;
|
||||
|
||||
if (!component)
|
||||
return -EINVAL;
|
||||
|
||||
wcd9378 = snd_soc_component_get_drvdata(component);
|
||||
|
||||
if (!wcd9378)
|
||||
return -EINVAL;
|
||||
|
||||
ret = wcd9378_simple_mic_num_get(kcontrol->id.name, &sm_num);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ucontrol->value.integer.value[0] = wcd9378->micb_sel[sm_num];
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static int wcd9378_mb_sel_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *component =
|
||||
snd_soc_kcontrol_component(kcontrol);
|
||||
struct wcd9378_priv *wcd9378 = NULL;
|
||||
u32 micb_num = 0, sm_sel = 0, sm_sel_mask = 0;
|
||||
unsigned int sm_num = 0;
|
||||
int ret = 0;
|
||||
|
||||
if (!component)
|
||||
return -EINVAL;
|
||||
|
||||
wcd9378 = snd_soc_component_get_drvdata(component);
|
||||
|
||||
if (!wcd9378)
|
||||
return -EINVAL;
|
||||
|
||||
ret = wcd9378_simple_mic_num_get(kcontrol->id.name, &sm_num);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
switch (sm_num) {
|
||||
case SIM_MIC0:
|
||||
sm_sel = WCD9378_SM0_MB_SEL;
|
||||
sm_sel_mask = WCD9378_SM0_MB_SEL_SM0_MB_SEL_MASK;
|
||||
break;
|
||||
case SIM_MIC1:
|
||||
sm_sel = WCD9378_SM1_MB_SEL;
|
||||
sm_sel_mask = WCD9378_SM1_MB_SEL_SM1_MB_SEL_MASK;
|
||||
break;
|
||||
case SIM_MIC2:
|
||||
sm_sel = WCD9378_SM2_MB_SEL;
|
||||
sm_sel_mask = WCD9378_SM2_MB_SEL_SM2_MB_SEL_MASK;
|
||||
break;
|
||||
default:
|
||||
pr_err("%s: unsupport sm_num: %d\n", __func__, sm_num);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
micb_num = ucontrol->value.enumerated.item[0];
|
||||
if (micb_num >= MICB_NUM) {
|
||||
pr_err("%s: unsupport micb num\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
snd_soc_component_update_bits(component, sm_sel,
|
||||
sm_sel_mask, micb_num);
|
||||
|
||||
wcd9378->micb_sel[sm_num] = micb_num;
|
||||
|
||||
dev_err(component->dev, "%s: sm%d_mb_sel :%d\n",
|
||||
__func__, sm_num, micb_num);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*TBD: NEED CHECK THE LOGIC*/
|
||||
static int wcd9378_hph_put_gain(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
@@ -2963,32 +2816,6 @@ static int wcd9378_set_compander(struct snd_kcontrol *kcontrol,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wcd9378_get_va_amic_switch(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *component =
|
||||
snd_soc_kcontrol_component(kcontrol);
|
||||
struct wcd9378_priv *wcd9378 = snd_soc_component_get_drvdata(component);
|
||||
|
||||
ucontrol->value.integer.value[0] = wcd9378->va_amic_en;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wcd9378_set_va_amic_switch(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *component =
|
||||
snd_soc_kcontrol_component(kcontrol);
|
||||
struct wcd9378_priv *wcd9378 =
|
||||
snd_soc_component_get_drvdata(component);
|
||||
int value = ucontrol->value.integer.value[0];
|
||||
|
||||
wcd9378->va_amic_en = value;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wcd9378_codec_enable_vdd_buck(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol,
|
||||
int event)
|
||||
@@ -3219,14 +3046,6 @@ static const struct soc_enum tx_mode_mux_enum =
|
||||
SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tx_mode_mux_text),
|
||||
tx_mode_mux_text);
|
||||
|
||||
static const char * const micb_sel_text[] = {
|
||||
"NO_MICB", "MICB1", "MICB2", "MICB3",
|
||||
};
|
||||
|
||||
static const struct soc_enum sm_micb_enum =
|
||||
SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(micb_sel_text),
|
||||
micb_sel_text);
|
||||
|
||||
static const char * const rx2_mode_text[] = {
|
||||
"HP", "NORMAL",
|
||||
};
|
||||
@@ -3252,9 +3071,6 @@ static const struct snd_kcontrol_new wcd9378_snd_controls[] = {
|
||||
SOC_SINGLE_EXT("ADC2_BCS Disable", SND_SOC_NOPM, 0, 1, 0,
|
||||
wcd9378_bcs_get, wcd9378_bcs_put),
|
||||
|
||||
SOC_SINGLE_EXT("VA_AMIC_MIXER Switch", SND_SOC_NOPM, 0, 1, 0,
|
||||
wcd9378_get_va_amic_switch, wcd9378_set_va_amic_switch),
|
||||
|
||||
SOC_ENUM_EXT("SYS_USAGE Mode", sys_usage_enum,
|
||||
wcd9378_sys_usage_get, wcd9378_sys_usage_put),
|
||||
|
||||
@@ -3272,13 +3088,6 @@ static const struct snd_kcontrol_new wcd9378_snd_controls[] = {
|
||||
SOC_ENUM_EXT("TX2 MODE", tx_mode_mux_enum,
|
||||
wcd9378_tx_mode_get, wcd9378_tx_mode_put),
|
||||
|
||||
SOC_ENUM_EXT("SM0 MICB SEL", sm_micb_enum,
|
||||
wcd9378_mb_sel_get, wcd9378_mb_sel_put),
|
||||
SOC_ENUM_EXT("SM1 MICB SEL", sm_micb_enum,
|
||||
wcd9378_mb_sel_get, wcd9378_mb_sel_put),
|
||||
SOC_ENUM_EXT("SM2 MICB SEL", sm_micb_enum,
|
||||
wcd9378_mb_sel_get, wcd9378_mb_sel_put),
|
||||
|
||||
SOC_ENUM_EXT("RX2 Mode", rx2_mode_enum,
|
||||
NULL, wcd9378_rx2_mode_put),
|
||||
SOC_ENUM_EXT("RX HPH Mode", rx_hph_mode_mux_enum,
|
||||
@@ -3319,6 +3128,39 @@ static const struct snd_kcontrol_new wcd9378_snd_controls[] = {
|
||||
wcd9378_tx_master_ch_get, wcd9378_tx_master_ch_put),
|
||||
};
|
||||
|
||||
|
||||
static const struct snd_kcontrol_new amic1_switch[] = {
|
||||
SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
|
||||
};
|
||||
|
||||
static const struct snd_kcontrol_new amic2_switch[] = {
|
||||
SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
|
||||
};
|
||||
|
||||
static const struct snd_kcontrol_new amic3_switch[] = {
|
||||
SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
|
||||
};
|
||||
|
||||
static const struct snd_kcontrol_new amic4_switch[] = {
|
||||
SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
|
||||
};
|
||||
|
||||
static const struct snd_kcontrol_new va_amic1_switch[] = {
|
||||
SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
|
||||
};
|
||||
|
||||
static const struct snd_kcontrol_new va_amic2_switch[] = {
|
||||
SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
|
||||
};
|
||||
|
||||
static const struct snd_kcontrol_new va_amic3_switch[] = {
|
||||
SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
|
||||
};
|
||||
|
||||
static const struct snd_kcontrol_new va_amic4_switch[] = {
|
||||
SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
|
||||
};
|
||||
|
||||
static const struct snd_kcontrol_new dmic1_switch[] = {
|
||||
SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
|
||||
};
|
||||
@@ -3443,6 +3285,11 @@ static const struct snd_soc_dapm_widget wcd9378_dapm_widgets[] = {
|
||||
SND_SOC_DAPM_INPUT("AMIC3"),
|
||||
SND_SOC_DAPM_INPUT("AMIC4"),
|
||||
|
||||
SND_SOC_DAPM_INPUT("VA AMIC1"),
|
||||
SND_SOC_DAPM_INPUT("VA AMIC2"),
|
||||
SND_SOC_DAPM_INPUT("VA AMIC3"),
|
||||
SND_SOC_DAPM_INPUT("VA AMIC4"),
|
||||
|
||||
SND_SOC_DAPM_INPUT("IN1_HPHL"),
|
||||
SND_SOC_DAPM_INPUT("IN2_HPHR"),
|
||||
SND_SOC_DAPM_INPUT("IN3_AUX"),
|
||||
@@ -3525,6 +3372,31 @@ static const struct snd_soc_dapm_widget wcd9378_dapm_widgets[] = {
|
||||
wcd9378_enable_clsh,
|
||||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
|
||||
|
||||
SND_SOC_DAPM_MIXER_E("AMIC1_MIXER", SND_SOC_NOPM, 0, 0,
|
||||
amic1_switch, ARRAY_SIZE(amic1_switch), NULL,
|
||||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
|
||||
SND_SOC_DAPM_MIXER_E("AMIC2_MIXER", SND_SOC_NOPM, 0, 0,
|
||||
amic2_switch, ARRAY_SIZE(amic2_switch), NULL,
|
||||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
|
||||
SND_SOC_DAPM_MIXER_E("AMIC3_MIXER", SND_SOC_NOPM, 0, 0,
|
||||
amic3_switch, ARRAY_SIZE(amic3_switch), NULL,
|
||||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
|
||||
SND_SOC_DAPM_MIXER_E("AMIC4_MIXER", SND_SOC_NOPM, 0, 0,
|
||||
amic4_switch, ARRAY_SIZE(amic4_switch), NULL,
|
||||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
|
||||
SND_SOC_DAPM_MIXER_E("VA_AMIC1_MIXER", SND_SOC_NOPM, 0, 0,
|
||||
va_amic1_switch, ARRAY_SIZE(va_amic1_switch), NULL,
|
||||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
|
||||
SND_SOC_DAPM_MIXER_E("VA_AMIC2_MIXER", SND_SOC_NOPM, 0, 0,
|
||||
va_amic2_switch, ARRAY_SIZE(va_amic2_switch), NULL,
|
||||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
|
||||
SND_SOC_DAPM_MIXER_E("VA_AMIC3_MIXER", SND_SOC_NOPM, 0, 0,
|
||||
va_amic3_switch, ARRAY_SIZE(va_amic3_switch), NULL,
|
||||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
|
||||
SND_SOC_DAPM_MIXER_E("VA_AMIC4_MIXER", SND_SOC_NOPM, 0, 0,
|
||||
va_amic4_switch, ARRAY_SIZE(va_amic4_switch), NULL,
|
||||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
|
||||
|
||||
SND_SOC_DAPM_MIXER_E("DMIC1_MIXER", SND_SOC_NOPM, DMIC1,
|
||||
0, dmic1_switch, ARRAY_SIZE(dmic1_switch),
|
||||
wcd9378_tx_swr_ctrl, SND_SOC_DAPM_PRE_PMU |
|
||||
@@ -3616,26 +3488,42 @@ static const struct snd_soc_dapm_route wcd9378_audio_map[] = {
|
||||
/*ADC-1 (channel-1)*/
|
||||
{"ADC1_OUTPUT", NULL, "TX0 SEQUENCER"},
|
||||
{"TX0 SEQUENCER", NULL, "ADC1 MUX"},
|
||||
{"ADC1 MUX", "CH1_AMIC1", "AMIC1"},
|
||||
{"ADC1 MUX", "CH1_AMIC2", "AMIC2"},
|
||||
{"ADC1 MUX", "CH1_AMIC3", "AMIC3"},
|
||||
{"ADC1 MUX", "CH1_AMIC4", "AMIC4"},
|
||||
{"ADC1 MUX", "CH1_AMIC1", "AMIC1_MIXER"},
|
||||
{"ADC1 MUX", "CH1_AMIC2", "AMIC2_MIXER"},
|
||||
{"ADC1 MUX", "CH1_AMIC3", "AMIC3_MIXER"},
|
||||
{"ADC1 MUX", "CH1_AMIC4", "AMIC4_MIXER"},
|
||||
|
||||
/*ADC-2 (channel-2)*/
|
||||
{"ADC2_OUTPUT", NULL, "TX1 SEQUENCER"},
|
||||
{"TX1 SEQUENCER", NULL, "ADC2 MUX"},
|
||||
{"ADC2 MUX", "CH2_AMIC1", "AMIC1"},
|
||||
{"ADC2 MUX", "CH2_AMIC2", "AMIC2"},
|
||||
{"ADC2 MUX", "CH2_AMIC3", "AMIC3"},
|
||||
{"ADC2 MUX", "CH2_AMIC4", "AMIC4"},
|
||||
{"ADC2 MUX", "CH2_AMIC1", "AMIC1_MIXER"},
|
||||
{"ADC2 MUX", "CH2_AMIC2", "AMIC2_MIXER"},
|
||||
{"ADC2 MUX", "CH2_AMIC3", "AMIC3_MIXER"},
|
||||
{"ADC2 MUX", "CH2_AMIC4", "AMIC4_MIXER"},
|
||||
|
||||
/*ADC-3 (channel-3)*/
|
||||
{"ADC3_OUTPUT", NULL, "TX2 SEQUENCER"},
|
||||
{"TX2 SEQUENCER", NULL, "ADC3 MUX"},
|
||||
{"ADC3 MUX", "CH3_AMIC1", "AMIC1"},
|
||||
{"ADC3 MUX", "CH3_AMIC2", "AMIC2"},
|
||||
{"ADC3 MUX", "CH3_AMIC3", "AMIC3"},
|
||||
{"ADC3 MUX", "CH3_AMIC4", "AMIC4"},
|
||||
{"ADC3 MUX", "CH3_AMIC1", "AMIC1_MIXER"},
|
||||
{"ADC3 MUX", "CH3_AMIC2", "AMIC2_MIXER"},
|
||||
{"ADC3 MUX", "CH3_AMIC3", "AMIC3_MIXER"},
|
||||
{"ADC3 MUX", "CH3_AMIC4", "AMIC4_MIXER"},
|
||||
|
||||
{"AMIC1_MIXER", "Switch", "AMIC1"},
|
||||
{"AMIC1_MIXER", NULL, "VA_AMIC1_MIXER"},
|
||||
{"VA_AMIC1_MIXER", "Switch", "VA AMIC1"},
|
||||
|
||||
{"AMIC2_MIXER", "Switch", "AMIC2"},
|
||||
{"AMIC2_MIXER", NULL, "VA_AMIC2_MIXER"},
|
||||
{"VA_AMIC2_MIXER", "Switch", "VA AMIC2"},
|
||||
|
||||
{"AMIC3_MIXER", "Switch", "AMIC3"},
|
||||
{"AMIC3_MIXER", NULL, "VA_AMIC3_MIXER"},
|
||||
{"VA_AMIC3_MIXER", "Switch", "VA AMIC3"},
|
||||
|
||||
{"AMIC4_MIXER", "Switch", "AMIC4"},
|
||||
{"AMIC4_MIXER", NULL, "VA_AMIC4_MIXER"},
|
||||
{"VA_AMIC4_MIXER", "Switch", "VA AMIC4"},
|
||||
|
||||
{"DMIC1_OUTPUT", NULL, "DMIC1_MIXER"},
|
||||
{"DMIC1_MIXER", "Switch", "DMIC1"},
|
||||
@@ -3914,12 +3802,14 @@ static int wcd9378_soc_codec_probe(struct snd_soc_component *component)
|
||||
goto exit;
|
||||
}
|
||||
|
||||
dev_dbg(component->dev, "%s: mbhc init done\n", __func__);
|
||||
|
||||
snd_soc_dapm_ignore_suspend(dapm, "AMIC1");
|
||||
snd_soc_dapm_ignore_suspend(dapm, "AMIC2");
|
||||
snd_soc_dapm_ignore_suspend(dapm, "AMIC3");
|
||||
snd_soc_dapm_ignore_suspend(dapm, "AMIC4");
|
||||
snd_soc_dapm_ignore_suspend(dapm, "VA AMIC1");
|
||||
snd_soc_dapm_ignore_suspend(dapm, "VA AMIC2");
|
||||
snd_soc_dapm_ignore_suspend(dapm, "VA AMIC3");
|
||||
snd_soc_dapm_ignore_suspend(dapm, "VA AMIC4");
|
||||
snd_soc_dapm_ignore_suspend(dapm, "IN1_HPHL");
|
||||
snd_soc_dapm_ignore_suspend(dapm, "IN2_HPHR");
|
||||
snd_soc_dapm_ignore_suspend(dapm, "IN3_AUX");
|
||||
|
Reference in New Issue
Block a user