asoc: add sys_usage automatically update function for tambora

Add sys_usage automatically update function for tambora,
and remove sys_usage set kcontrol,
optimize ear/aux path check logic.

Change-Id: I06a4676e22f73156f7e2f394c98ab3879aa00cad
Signed-off-by: Yuhui Zhao <quic_yuhuzhao@quicinc.com>
このコミットが含まれているのは:
Yuhui Zhao
2024-03-17 13:39:07 +08:00
コミット 1624212a65
3個のファイルの変更302行の追加194行の削除

ファイルの表示

@@ -65,13 +65,14 @@ enum {
struct wcd9378_priv {
struct device *dev;
u32 sys_usage;
/* to track the sys_usage status */
unsigned long sys_usage_status;
u32 wcd_mode;
int variant;
struct snd_soc_component *component;
struct device_node *rst_np;
struct regmap *regmap;
bool sjmic_support;
struct swr_device *rx_swr_dev;
struct swr_device *tx_swr_dev;
@@ -86,6 +87,7 @@ struct wcd9378_priv {
struct mutex micb_lock;
struct mutex wakeup_lock;
struct mutex sys_usage_lock;
s32 dmic_0_1_clk_cnt;
s32 dmic_2_3_clk_cnt;
s32 dmic_4_5_clk_cnt;
@@ -103,8 +105,6 @@ struct wcd9378_priv {
s32 adc_count;
bool comp1_enable;
bool comp2_enable;
bool ear_enable;
bool aux_enable;
bool ldoh;
bool bcs_dis;
bool dapm_bias_off;
@@ -138,8 +138,6 @@ struct wcd9378_priv {
struct snd_info_entry *version_entry;
struct snd_info_entry *variant_entry;
int flyback_cur_det_disable;
int ear_rx_path;
int aux_rx_path;
bool dev_up;
u8 tx_master_ch_map[WCD9378_MAX_SLAVE_CH_TYPES];
bool usbc_hs_status;

ファイルの表示

@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef WCD9378_REGISTERS_H
@@ -873,6 +873,7 @@ enum {
#define WCD9378_TX_NEW_TX_CH34_MUX_CH3_SEL_SHIFT 0x00
#define WCD9378_CDC_HPH_GAIN_CTL_HPHR_RX_EN_SHIFT 0x03
#define WCD9378_CDC_HPH_GAIN_CTL_HPHL_RX_EN_SHIFT 0x02
#define WCD9378_CDC_AUX_GAIN_CTL_AUX_EN_SHIFT 0x00
#define SWRS_SCP_BASE_CLK_BASE (0x004d)
#define SWRS_SCP_BUSCLOCK_SCALE_BANK0 (0x0062)

ファイルの表示

@@ -32,8 +32,6 @@
#define WCD9378_VERSION_1_0 1
#define WCD9378_VERSION_ENTRY_SIZE 32
#define EAR_RX_PATH_RX0 1
#define AUX_RX_PATH_RX1 1
#define SWR_BASECLK_19P2MHZ (0x01)
#define SWR_BASECLK_24P576MHZ (0x03)
@@ -101,7 +99,6 @@
.put = wcd9378_aux_pa_put_gain, \
.private_value = SOC_SINGLE_VALUE(reg, shift, max, invert, 0) }
enum {
CODEC_TX = 0,
CODEC_RX,
@@ -112,6 +109,22 @@ enum {
RX2_NORMAL_MODE,
};
enum {
CLASS_AB_EN = 0,
TX1_FOR_JACK,
TX2_AMIC4_EN,
TX2_AMIC1_EN,
TX1_AMIC3_EN,
TX1_AMIC2_EN,
TX0_AMIC2_EN,
TX0_AMIC1_EN,
RX2_EAR_EN,
RX2_AUX_EN,
RX1_AUX_EN,
RX0_EAR_EN,
RX0_RX1_HPH_EN,
};
enum {
WCD_ADC1 = 0,
WCD_ADC2,
@@ -130,25 +143,23 @@ enum {
WCD_EAR_EN,
};
enum {
NOSJ_SA_STEREO_3SM = 0,
SJ_SA_AUX_2SM,
NOSJ_SA_STEREO_3SM_1HDR,
SJ_SA_AUX_2SM_1HDR,
NOSJ_SA_EAR_3SM,
SJ_SA_EAR_2SM,
NOSJ_SA_EAR_3SM_1HDR,
SJ_SA_EAR_2SM_1HDR,
SJ_1HDR_SA_AUX_1SM,
SJ_1HDR_SA_EAR_1SM,
SJ_SA_STEREO_2SM,
SJ_NOMIC_SA_EAR_3SM,
SJ_NOMIC_SA_AUX_3SM,
WCD_SYS_USAGE_MAX,
SYS_USAGE_0,
SYS_USAGE_1,
SYS_USAGE_2,
SYS_USAGE_3,
SYS_USAGE_4,
SYS_USAGE_5,
SYS_USAGE_6,
SYS_USAGE_7,
SYS_USAGE_8,
SYS_USAGE_9,
SYS_USAGE_10,
SYS_USAGE_11,
SYS_USAGE_12,
SYS_USAGE_NUM,
};
enum {
NO_MICB_USED,
MICB1,
@@ -173,6 +184,29 @@ static int wcd9378_reset_low(struct device *dev);
static int wcd9378_swr_slave_clk_set(struct device *dev, int bank, int path, bool enable);
static void wcd9378_class_load(struct snd_soc_component *component);
/* sys_usage:
* rx0_rx1_hph_en,
* rx0_ear_en, rx1_aux_en, rx2_aux_en, rx2_ear_en,
* tx0_amic1_en, tx0_amic2_en, tx1_amic2_en, tx1_amic3_en,
* tx2_amic1_en, tx2_amic4_en, tx1_for_jack, class_ab_en;
*/
static const int sys_usage[SYS_USAGE_NUM] = {
[SYS_USAGE_0] = 0x0c95, /*0b0 1100 1001 0101*/
[SYS_USAGE_1] = 0x12a7, /*0b1 0010 1010 0111*/
[SYS_USAGE_2] = 0x0c99, /*0b0 1100 1001 1001*/
[SYS_USAGE_3] = 0x1aab, /*0b1 1010 1010 1011*/
[SYS_USAGE_4] = 0x0894, /*0b0 1000 1001 0100*/
[SYS_USAGE_5] = 0x11a6, /*0b1 0001 1010 0110*/
[SYS_USAGE_6] = 0x0898, /*0b0 1000 1001 1000*/
[SYS_USAGE_7] = 0x11ab, /*0b1 0001 1010 1011*/
[SYS_USAGE_8] = 0x126a, /*0b1 0010 0110 1010*/
[SYS_USAGE_9] = 0x116b, /*0b1 0001 0110 1011*/
[SYS_USAGE_10] = 0x1ca7, /*0b1 1100 1010 0111*/
[SYS_USAGE_11] = 0x1195, /*0b1 0001 1001 0101*/
[SYS_USAGE_12] = 0x1296, /*0b1 0010 1001 0101*/
};
static const struct regmap_irq wcd9378_regmap_irqs[WCD9378_NUM_IRQS] = {
REGMAP_IRQ_REG(WCD9378_IRQ_MBHC_BUTTON_PRESS_DET, 0, 0x01),
REGMAP_IRQ_REG(WCD9378_IRQ_MBHC_BUTTON_RELEASE_DET, 0, 0x02),
@@ -240,6 +274,8 @@ static int wcd9378_swr_slv_get_current_bank(struct swr_device *dev, u8 devnum)
static int wcd9378_init_reg(struct snd_soc_component *component)
{
struct wcd9378_priv *wcd9378 =
snd_soc_component_get_drvdata(component);
u32 val = 0;
val = snd_soc_component_read(component, WCD9378_EFUSE_REG_16);
@@ -339,13 +375,20 @@ static int wcd9378_init_reg(struct snd_soc_component *component)
/*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*/
/*SM1 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*/
/*SM2 MB SEL:MB3*/
snd_soc_component_update_bits(component, WCD9378_SM2_MB_SEL,
WCD9378_SM2_MB_SEL_SM2_MB_SEL_MASK, 0x03);
/*INIT SYS_USAGE*/
snd_soc_component_update_bits(component,
WCD9378_SYS_USAGE_CTRL,
WCD9378_SYS_USAGE_CTRL_SYS_USAGE_CTRL_MASK,
0);
wcd9378->sys_usage = 0;
wcd9378_class_load(component);
return 0;
}
@@ -937,6 +980,150 @@ static int wcd9378_get_adc_mode_val(int mode)
return ret;
}
static int wcd9378_sys_usage_auto_udpate(struct snd_soc_component *component,
int sys_usage_bit, bool set_enable)
{
struct wcd9378_priv *wcd9378 =
snd_soc_component_get_drvdata(component);
int i = 0;
dev_dbg(component->dev,
"%s: enter, current sys_usage: %d, sys_usage_status: 0x%x, sys_usage_bit: %d, set_enable: %d\n",
__func__, wcd9378->sys_usage,
wcd9378->sys_usage_status,
sys_usage_bit, set_enable);
mutex_lock(&wcd9378->sys_usage_lock);
if (set_enable) {
set_bit(sys_usage_bit, &wcd9378->sys_usage_status);
if ((sys_usage[wcd9378->sys_usage] &
wcd9378->sys_usage_status) == wcd9378->sys_usage_status)
goto exit;
for (i = 0; i < SYS_USAGE_NUM; i++) {
if ((sys_usage[i] & wcd9378->sys_usage_status)
== wcd9378->sys_usage_status) {
snd_soc_component_update_bits(component,
WCD9378_SYS_USAGE_CTRL,
WCD9378_SYS_USAGE_CTRL_SYS_USAGE_CTRL_MASK,
i);
wcd9378->sys_usage = i;
dev_dbg(component->dev, "%s: update sys_usage: %d\n",
__func__, wcd9378->sys_usage);
goto exit;
}
}
dev_dbg(component->dev, "%s: cannot find sys_usage\n",
__func__);
} else {
clear_bit(sys_usage_bit, &wcd9378->sys_usage_status);
}
exit:
mutex_unlock(&wcd9378->sys_usage_lock);
return 0;
}
static int wcd9378_sys_usage_bit_get(
struct snd_soc_component *component, u32 w_shift,
int *sys_usage_bit, int event)
{
struct wcd9378_priv *wcd9378 =
snd_soc_component_get_drvdata(component);
dev_dbg(component->dev, "%s: wshift: %d event: %d\n", __func__,
w_shift, event);
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
switch (w_shift) {
case ADC1:
if ((snd_soc_component_read(component,
WCD9378_TX_NEW_TX_CH12_MUX) &
WCD9378_TX_NEW_TX_CH12_MUX_CH1_SEL_MASK) == 0x01) {
*sys_usage_bit = TX0_AMIC1_EN;
} else if ((snd_soc_component_read(component,
WCD9378_TX_NEW_TX_CH12_MUX) &
WCD9378_TX_NEW_TX_CH12_MUX_CH1_SEL_MASK) == 0x02) {
*sys_usage_bit = TX0_AMIC2_EN;
} else {
dev_err(component->dev, "%s: unsupport usecase, pls check\n",
__func__);
return -EINVAL;
}
break;
case ADC2:
if ((snd_soc_component_read(component,
WCD9378_TX_NEW_TX_CH12_MUX) &
WCD9378_TX_NEW_TX_CH12_MUX_CH2_SEL_MASK) == 0x10) {
*sys_usage_bit = TX1_AMIC2_EN;
} else if ((snd_soc_component_read(component,
WCD9378_TX_NEW_TX_CH12_MUX) &
WCD9378_TX_NEW_TX_CH12_MUX_CH2_SEL_MASK) == 0x18) {
*sys_usage_bit = TX1_AMIC3_EN;
} else {
dev_err(component->dev, "%s: unsupport usecase, pls check\n",
__func__);
return -EINVAL;
}
break;
case ADC3:
if ((snd_soc_component_read(component,
WCD9378_TX_NEW_TX_CH34_MUX) &
WCD9378_TX_NEW_TX_CH34_MUX_CH3_SEL_SHIFT) == 0x01) {
*sys_usage_bit = TX2_AMIC1_EN;
} else if ((snd_soc_component_read(component,
WCD9378_TX_NEW_TX_CH34_MUX) &
WCD9378_TX_NEW_TX_CH34_MUX_CH3_SEL_SHIFT) == 0x03) {
*sys_usage_bit = TX2_AMIC4_EN;
} else {
dev_err(component->dev, "%s: unsupport usecase, pls check\n",
__func__);
return -EINVAL;
}
break;
default:
break;
}
break;
case SND_SOC_DAPM_POST_PMD:
switch (w_shift) {
case ADC1:
if (test_bit(TX0_AMIC1_EN, &wcd9378->sys_usage_status))
*sys_usage_bit = TX0_AMIC1_EN;
if (test_bit(TX0_AMIC2_EN, &wcd9378->sys_usage_status))
*sys_usage_bit = TX0_AMIC2_EN;
break;
case ADC2:
if (test_bit(TX1_AMIC2_EN, &wcd9378->sys_usage_status))
*sys_usage_bit = TX1_AMIC2_EN;
if (test_bit(TX1_AMIC3_EN, &wcd9378->sys_usage_status))
*sys_usage_bit = TX1_AMIC3_EN;
break;
case ADC3:
if (test_bit(TX2_AMIC1_EN, &wcd9378->sys_usage_status))
*sys_usage_bit = TX2_AMIC1_EN;
if (test_bit(TX2_AMIC4_EN, &wcd9378->sys_usage_status))
*sys_usage_bit = TX2_AMIC4_EN;
break;
default:
break;
}
break;
default:
break;
}
dev_dbg(component->dev, "%s: done, event: %d, sys_usage_bit: %d\n",
__func__, event, *sys_usage_bit);
return 0;
}
static int wcd9378_tx_sequencer_enable(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
@@ -944,7 +1131,7 @@ static int wcd9378_tx_sequencer_enable(struct snd_soc_dapm_widget *w,
struct wcd9378_priv *wcd9378 =
snd_soc_component_get_drvdata(component);
int mode_val = 0, bank = 0, ret = 0, rate = 0;
int act_ps = 0;
int act_ps = 0, sys_usage_bit = 0;
bank = (wcd9378_swr_slv_get_current_bank(wcd9378->tx_swr_dev,
wcd9378->tx_swr_dev->dev_num) ? 0 : 1);
@@ -952,8 +1139,15 @@ static int wcd9378_tx_sequencer_enable(struct snd_soc_dapm_widget *w,
dev_dbg(component->dev, "%s wname: %s wshift: %d event: %d\n", __func__,
w->name, w->shift, event);
ret = wcd9378_sys_usage_bit_get(component, w->shift, &sys_usage_bit, event);
if (ret < 0)
return ret;
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
/*Update sys_usage*/
wcd9378_sys_usage_auto_udpate(component, sys_usage_bit, true);
mode_val = wcd9378_get_adc_mode_val(wcd9378->tx_mode[w->shift - ADC1]);
if (mode_val < 0) {
dev_dbg(component->dev,
@@ -990,10 +1184,12 @@ static int wcd9378_tx_sequencer_enable(struct snd_soc_dapm_widget *w,
/*Power up TX0 sequencer*/
snd_soc_component_update_bits(component, WCD9378_PDE11_REQ_PS,
WCD9378_PDE11_REQ_PS_PDE11_REQ_PS_MASK, 0x00);
break;
case ADC2:
if (wcd9378->sjmic_support) {
/*Check if amic2 is connected to ADC2 MUX*/
if ((snd_soc_component_read(component,
WCD9378_TX_NEW_TX_CH12_MUX) &
WCD9378_TX_NEW_TX_CH12_MUX_CH2_SEL_MASK) == 0x10) {
/*SMP JACK IT31 USAGE SET*/
snd_soc_component_update_bits(component,
WCD9378_IT31_USAGE,
@@ -1003,7 +1199,6 @@ static int wcd9378_tx_sequencer_enable(struct snd_soc_dapm_widget *w,
WCD9378_PDE34_REQ_PS,
WCD9378_PDE34_REQ_PS_PDE34_REQ_PS_MASK, 0x00);
} else {
/*SMP MIC1 IT11 USAGE SET*/
snd_soc_component_update_bits(component,
WCD9378_SMP_MIC_CTRL1_IT11_USAGE,
WCD9378_SMP_MIC_CTRL1_IT11_USAGE_IT11_USAGE_MASK,
@@ -1064,7 +1259,7 @@ static int wcd9378_tx_sequencer_enable(struct snd_soc_dapm_widget *w,
snd_soc_component_update_bits(component, WCD9378_ANA_TX_CH2,
WCD9378_ANA_TX_CH2_HPF2_INIT_MASK, 0x00);
if (wcd9378->sjmic_support)
if (test_bit(TX1_AMIC2_EN, &wcd9378->sys_usage_status))
act_ps = snd_soc_component_read(component,
WCD9378_PDE34_ACT_PS);
else
@@ -1114,17 +1309,20 @@ static int wcd9378_tx_sequencer_enable(struct snd_soc_dapm_widget *w,
break;
case ADC2:
/*tear down TX1 sequencer*/
snd_soc_component_update_bits(component, WCD9378_PDE34_REQ_PS,
WCD9378_PDE34_REQ_PS_PDE34_REQ_PS_MASK, 0x03);
if (test_bit(TX1_AMIC2_EN, &wcd9378->sys_usage_status))
/*tear down TX1 sequencer*/
snd_soc_component_update_bits(component, WCD9378_PDE34_REQ_PS,
WCD9378_PDE34_REQ_PS_PDE34_REQ_PS_MASK, 0x03);
/*Normal TXFE Startup*/
snd_soc_component_update_bits(component, WCD9378_ANA_TX_CH2,
WCD9378_ANA_TX_CH2_HPF1_INIT_MASK, 0x00);
if (test_bit(TX1_AMIC3_EN, &wcd9378->sys_usage_status)) {
/*Normal TXFE Startup*/
snd_soc_component_update_bits(component, WCD9378_ANA_TX_CH2,
WCD9378_ANA_TX_CH2_HPF1_INIT_MASK, 0x00);
/*tear down TX1 sequencer*/
snd_soc_component_update_bits(component, WCD9378_PDE11_REQ_PS,
WCD9378_PDE11_REQ_PS_PDE11_REQ_PS_MASK, 0x03);
/*tear down TX1 sequencer*/
snd_soc_component_update_bits(component, WCD9378_PDE11_REQ_PS,
WCD9378_PDE11_REQ_PS_PDE11_REQ_PS_MASK, 0x03);
}
break;
case ADC3:
/*Normal TXFE Startup*/
@@ -1147,6 +1345,8 @@ static int wcd9378_tx_sequencer_enable(struct snd_soc_dapm_widget *w,
false);
wcd9378_swr_slave_clk_set(wcd9378->dev, bank, TX_PATH, false);
/*Disable sys_usage_status*/
wcd9378_sys_usage_auto_udpate(component, sys_usage_bit, false);
break;
default:
break;
@@ -1512,12 +1712,7 @@ static int wcd9378_codec_enable_aux_pa(struct snd_soc_dapm_widget *w,
wcd9378_swr_slave_clk_set(wcd9378->dev, !bank, RX_PATH, true);
wcd9378->aux_rx_path =
(snd_soc_component_read(
component, WCD9378_CDC_HPH_GAIN_CTL) &
WCD9378_CDC_HPH_GAIN_CTL_HPHR_RX_EN_MASK) >> 0x03;
if (wcd9378->aux_rx_path & AUX_RX_PATH_RX1) {
if (test_bit(RX1_AUX_EN, &wcd9378->sys_usage_status)) {
if (wcd9378->update_wcd_event)
wcd9378->update_wcd_event(wcd9378->handle,
SLV_BOLERO_EVT_RX_MUTE,
@@ -1539,7 +1734,7 @@ static int wcd9378_codec_enable_aux_pa(struct snd_soc_dapm_widget *w,
__func__, act_ps);
break;
case SND_SOC_DAPM_POST_PMD:
if (wcd9378->aux_rx_path & AUX_RX_PATH_RX1) {
if (test_bit(RX1_AUX_EN, &wcd9378->sys_usage_status)) {
if (wcd9378->update_wcd_event)
wcd9378->update_wcd_event(wcd9378->handle,
SLV_BOLERO_EVT_RX_MUTE,
@@ -1581,12 +1776,7 @@ static int wcd9378_codec_enable_ear_pa(struct snd_soc_dapm_widget *w,
wcd9378_swr_slave_clk_set(wcd9378->dev, !bank, RX_PATH, true);
wcd9378->ear_rx_path =
(snd_soc_component_read(
component, WCD9378_CDC_HPH_GAIN_CTL) &
WCD9378_CDC_HPH_GAIN_CTL_HPHL_RX_EN_MASK) >> 0x02;
if (wcd9378->ear_rx_path & EAR_RX_PATH_RX0) {
if (test_bit(RX0_EAR_EN, &wcd9378->sys_usage_status)) {
if (wcd9378->update_wcd_event)
wcd9378->update_wcd_event(wcd9378->handle,
SLV_BOLERO_EVT_RX_MUTE,
@@ -1608,7 +1798,7 @@ static int wcd9378_codec_enable_ear_pa(struct snd_soc_dapm_widget *w,
break;
case SND_SOC_DAPM_POST_PMD:
if (wcd9378->ear_rx_path & EAR_RX_PATH_RX0) {
if (test_bit(RX0_EAR_EN, &wcd9378->sys_usage_status)) {
if (wcd9378->update_wcd_event)
wcd9378->update_wcd_event(wcd9378->handle,
SLV_BOLERO_EVT_RX_MUTE,
@@ -1731,6 +1921,8 @@ static int wcd9378_hph_sequencer_enable(struct snd_soc_dapm_widget *w,
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
wcd9378_sys_usage_auto_udpate(component, RX0_RX1_HPH_EN, true);
if ((!wcd9378->comp1_enable) || (!wcd9378->comp2_enable)) {
snd_soc_component_update_bits(component, WCD9378_HPH_UP_T7,
WCD9378_HPH_UP_T7_HPH_UP_T7_MASK, 0x07);
@@ -1775,6 +1967,11 @@ static int wcd9378_hph_sequencer_enable(struct snd_soc_dapm_widget *w,
snd_soc_component_update_bits(component, WCD9378_FU42_MUTE_CH2,
WCD9378_FU42_MUTE_CH2_FU42_MUTE_CH2_MASK, 0x00);
if (wcd9378->sys_usage == SYS_USAGE_10)
/*FU23 UNMUTE*/
snd_soc_component_update_bits(component, WCD9378_FU23_MUTE,
WCD9378_FU23_MUTE_FU23_MUTE_MASK, 0x00);
swr_write(swr_dev, swr_dev->dev_num, 0x004c, &scp_commit_val);
wcd9378_swr_slave_clk_set(wcd9378->dev, bank, RX_PATH, true);
@@ -1803,6 +2000,8 @@ static int wcd9378_hph_sequencer_enable(struct snd_soc_dapm_widget *w,
else
/*COMP delay is 11250us*/
usleep_range(11300, 11310);
wcd9378_sys_usage_auto_udpate(component, RX0_RX1_HPH_EN, false);
break;
default:
break;
@@ -1817,19 +2016,30 @@ static int wcd9378_codec_ear_dac_event(struct snd_soc_dapm_widget *w,
{
struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
struct wcd9378_priv *wcd9378 = snd_soc_component_get_drvdata(component);
int ear_rx0 = 0;
int ear_rx2 = 0;
dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__,
w->name, event);
ear_rx0 = snd_soc_component_read(component, WCD9378_CDC_HPH_GAIN_CTL) &
WCD9378_CDC_HPH_GAIN_CTL_HPHL_RX_EN_MASK;
ear_rx2 = snd_soc_component_read(component, WCD9378_CDC_AUX_GAIN_CTL) &
WCD9378_CDC_AUX_GAIN_CTL_AUX_EN_MASK;
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
/*CHECK IF EAR CONNET TO RX2*/
if (!ear_rx0) {
pr_debug("%s: ear rx2 enter\n", __func__);
if (!ear_rx2) {
/*RX0 ENABLE*/
snd_soc_component_update_bits(component, WCD9378_CDC_HPH_GAIN_CTL,
WCD9378_CDC_HPH_GAIN_CTL_HPHL_RX_EN_MASK, 0x04);
wcd9378_sys_usage_auto_udpate(component, RX0_EAR_EN, true);
if (wcd9378->comp1_enable) {
snd_soc_component_update_bits(component, WCD9378_CDC_COMP_CTL_0,
WCD9378_CDC_COMP_CTL_0_EAR_COMP_EN_MASK, 0x04);
wcd9378_rx_connect_port(component, COMP_L, true);
}
wcd9378_rx_connect_port(component, HPH_L, true);
} else {
wcd9378_sys_usage_auto_udpate(component, RX2_EAR_EN, true);
/*FORCE CLASS_AB EN*/
snd_soc_component_update_bits(component, WCD9378_SEQ_OVRRIDE_CTL0,
WCD9378_SEQ_OVRRIDE_CTL0_CLASSAB_EN_OVR_MASK, 0x20);
@@ -1837,29 +2047,15 @@ static int wcd9378_codec_ear_dac_event(struct snd_soc_dapm_widget *w,
snd_soc_component_update_bits(component, WCD9378_CP_CP_DTOP_CTRL_14,
WCD9378_CP_CP_DTOP_CTRL_14_OVERRIDE_VREF_MASK, 0x80);
/*RX2 ENABLE*/
snd_soc_component_update_bits(component, WCD9378_CDC_AUX_GAIN_CTL,
WCD9378_CDC_AUX_GAIN_CTL_AUX_EN_MASK, 0x01);
if (wcd9378->rx2_clk_mode)
snd_soc_component_update_bits(component, WCD9378_CDC_PATH_MODE,
WCD9378_CDC_PATH_MODE_RX2_CLK_RATE_MASK, 0x40);
wcd9378_rx_connect_port(component, LO, true);
} else {
pr_debug("%s: ear rx0 enter\n", __func__);
if (wcd9378->comp1_enable) {
snd_soc_component_update_bits(component, WCD9378_CDC_COMP_CTL_0,
WCD9378_CDC_COMP_CTL_0_EAR_COMP_EN_MASK, 0x04);
wcd9378_rx_connect_port(component, COMP_L, true);
}
wcd9378_rx_connect_port(component, HPH_L, true);
}
break;
case SND_SOC_DAPM_POST_PMD:
if (ear_rx0) {
if (test_bit(RX0_EAR_EN, &wcd9378->sys_usage_status)) {
/*RX0 DISABLE*/
snd_soc_component_update_bits(component, WCD9378_CDC_HPH_GAIN_CTL,
WCD9378_CDC_HPH_GAIN_CTL_HPHL_RX_EN_MASK, 0x00);
@@ -1870,18 +2066,16 @@ static int wcd9378_codec_ear_dac_event(struct snd_soc_dapm_widget *w,
WCD9378_CDC_COMP_CTL_0_EAR_COMP_EN_MASK, 0x00);
wcd9378_rx_connect_port(component, COMP_L, false);
}
wcd9378_sys_usage_auto_udpate(component, RX0_EAR_EN, false);
} else {
/*RX1 DISABLE*/
snd_soc_component_update_bits(component, WCD9378_CDC_AUX_GAIN_CTL,
WCD9378_CDC_AUX_GAIN_CTL_AUX_EN_MASK, 0x00);
wcd9378_rx_connect_port(component, LO, false);
wcd9378_sys_usage_auto_udpate(component, RX2_EAR_EN, false);
}
break;
};
return 0;
return 0;
}
static int wcd9378_codec_aux_dac_event(struct snd_soc_dapm_widget *w,
@@ -1890,22 +2084,25 @@ static int wcd9378_codec_aux_dac_event(struct snd_soc_dapm_widget *w,
{
struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
struct wcd9378_priv *wcd9378 = snd_soc_component_get_drvdata(component);
int aux_rx1 = 0;
int aux_rx2 = 0;
dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__,
w->name, event);
aux_rx1 = snd_soc_component_read(component, WCD9378_CDC_HPH_GAIN_CTL) &
WCD9378_CDC_HPH_GAIN_CTL_HPHR_RX_EN_MASK;
aux_rx2 = snd_soc_component_read(component, WCD9378_CDC_AUX_GAIN_CTL) &
WCD9378_CDC_AUX_GAIN_CTL_AUX_EN_MASK;
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
if (aux_rx1) {
if (!aux_rx2) {
/*RX1 ENABLE*/
snd_soc_component_update_bits(component, WCD9378_CDC_HPH_GAIN_CTL,
WCD9378_CDC_HPH_GAIN_CTL_HPHR_RX_EN_MASK, 0x08);
wcd9378_sys_usage_auto_udpate(component, RX1_AUX_EN, true);
wcd9378_rx_connect_port(component, HPH_R, true);
} else {
/*RX2 ENABLE*/
snd_soc_component_update_bits(component, WCD9378_CDC_AUX_GAIN_CTL,
WCD9378_CDC_AUX_GAIN_CTL_AUX_EN_MASK, 0x01);
wcd9378_sys_usage_auto_udpate(component, RX2_AUX_EN, true);
if (wcd9378->rx2_clk_mode)
snd_soc_component_update_bits(component, WCD9378_CDC_PATH_MODE,
@@ -1915,17 +2112,17 @@ static int wcd9378_codec_aux_dac_event(struct snd_soc_dapm_widget *w,
}
break;
case SND_SOC_DAPM_POST_PMD:
if (aux_rx1) {
if (test_bit(RX1_AUX_EN, &wcd9378->sys_usage_status)) {
wcd9378_rx_connect_port(component, HPH_R, false);
wcd9378_sys_usage_auto_udpate(component, RX1_AUX_EN, false);
} else {
snd_soc_component_update_bits(component, WCD9378_CDC_AUX_GAIN_CTL,
WCD9378_CDC_AUX_GAIN_CTL_AUX_EN_MASK, 0x00);
wcd9378_rx_connect_port(component, LO, false);
wcd9378_rx_connect_port(component, LO, true);
wcd9378_sys_usage_auto_udpate(component, RX2_AUX_EN, false);
}
break;
};
return 0;
return 0;
}
static int wcd9378_sa_sequencer_enable(struct snd_soc_dapm_widget *w,
@@ -1948,7 +2145,6 @@ static int wcd9378_sa_sequencer_enable(struct snd_soc_dapm_widget *w,
/*FU23 UNMUTE*/
snd_soc_component_update_bits(component, WCD9378_FU23_MUTE,
WCD9378_FU23_MUTE_FU23_MUTE_MASK, 0x00);
break;
case SND_SOC_DAPM_POST_PMD:
/*FU23 MUTE*/
@@ -2045,7 +2241,7 @@ int wcd9378_micbias_control(struct snd_soc_component *component,
wcd9378->pullup_ref[micb_index]--;
if ((wcd9378->pullup_ref[micb_index] == 0) &&
(wcd9378->micb_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) {
@@ -2445,82 +2641,6 @@ static int wcd9378_tx_mode_put(struct snd_kcontrol *kcontrol,
return 0;
}
static int wcd9378_sys_usage_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_component *component =
snd_soc_kcontrol_component(kcontrol);
u32 sys_usage_val = 0;
if (!component)
return -EINVAL;
sys_usage_val = (snd_soc_component_read(component, WCD9378_SYS_USAGE_CTRL) &
WCD9378_SYS_USAGE_CTRL_SYS_USAGE_CTRL_MASK);
ucontrol->value.integer.value[0] = sys_usage_val;
return 0;
}
static int wcd9378_sys_usage_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 sys_usage_val = 0;
if (!component)
return -EINVAL;
wcd9378 = snd_soc_component_get_drvdata(component);
if (!wcd9378)
return -EINVAL;
sys_usage_val = ucontrol->value.enumerated.item[0];
if (sys_usage_val >= WCD_SYS_USAGE_MAX) {
dev_err(component->dev, "%s: unsupport sys_usage_val: %d\n",
__func__, sys_usage_val);
return -EINVAL;
}
if (wcd9378->sys_usage != sys_usage_val)
snd_soc_component_update_bits(component,
WCD9378_SYS_USAGE_CTRL,
WCD9378_SYS_USAGE_CTRL_SYS_USAGE_CTRL_MASK,
sys_usage_val);
wcd9378->sys_usage = sys_usage_val;
switch (wcd9378->sys_usage) {
case SJ_SA_AUX_2SM:
case SJ_SA_AUX_2SM_1HDR:
case SJ_SA_EAR_2SM:
case SJ_SA_EAR_2SM_1HDR:
case SJ_1HDR_SA_AUX_1SM:
case SJ_1HDR_SA_EAR_1SM:
wcd9378->sjmic_support = true;
break;
case NOSJ_SA_STEREO_3SM:
case NOSJ_SA_STEREO_3SM_1HDR:
case NOSJ_SA_EAR_3SM:
case NOSJ_SA_EAR_3SM_1HDR:
case SJ_NOMIC_SA_EAR_3SM:
case SJ_NOMIC_SA_AUX_3SM:
wcd9378->sjmic_support = false;
break;
default:
dev_err(component->dev, "%s: unsupport sys_usage: %d\n",
__func__, wcd9378->sys_usage);
return -EINVAL;
}
dev_err(component->dev, "%s: sys_usage_val: %d, sjmic_support: %d\n",
__func__, wcd9378->sys_usage, wcd9378->sjmic_support);
return 0;
}
static int wcd9378_loopback_mode_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -3003,17 +3123,6 @@ static int wcd9378_bcs_put(struct snd_kcontrol *kcontrol,
return 0;
}
static const char * const sys_usage_text[] = {
"NOSJ_SA_STEREO_3SM", "SJ_SA_AUX_2SM", "NOSJ_SA_STEREO_3SM_1HDR",
"SJ_SA_AUX_2SM_1HDR", "NOSJ_SA_EAR_3SM", "SJ_SA_EAR_2SM", "NOSJ_SA_EAR_3SM_1HDR",
"SJ_SA_EAR_2SM_1HDR", "SJ_1HDR_SA_AUX_1SM", "SJ_1HDR_SA_EAR_1SM",
"SJ_SA_STEREO_2SM", "SJ_NOMIC_SA_EAR_3SM", "SJ_NOMIC_SA_AUX_3SM",
};
static const struct soc_enum sys_usage_enum =
SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(sys_usage_text),
sys_usage_text);
static const char * const loopback_mode_text[] = {
"NO_LP", "SWR_LP1", "SWR_LP2", "SWR_LP3",
};
@@ -3071,9 +3180,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_ENUM_EXT("SYS_USAGE Mode", sys_usage_enum,
wcd9378_sys_usage_get, wcd9378_sys_usage_put),
SOC_ENUM_EXT("LOOPBACK Mode", loopback_mode_enum,
wcd9378_loopback_mode_get, wcd9378_loopback_mode_put),
SOC_ENUM_EXT("AUX_LB_IN SEL", aux_dsm_enum,
@@ -3194,15 +3300,15 @@ static const char * const adc2_mux_text[] = {
};
static const char * const adc3_mux_text[] = {
"CH3_AMIC_DISABLE", "CH3_AMIC1", "CH3_AMIC2", "CH3_AMIC3", "CH3_AMIC4"
"CH3_AMIC_DISABLE", "CH3_AMIC1", "CH3_AMIC3", "CH3_AMIC4"
};
static const char * const ear_mux_text[] = {
"RX2", "RX0"
"RX0", "RX2"
};
static const char * const aux_mux_text[] = {
"RX2", "RX1"
"RX1", "RX2"
};
static const struct soc_enum adc1_enum =
@@ -3221,13 +3327,13 @@ static const struct soc_enum adc3_enum =
ARRAY_SIZE(adc3_mux_text), adc3_mux_text);
static const struct soc_enum ear_enum =
SOC_ENUM_SINGLE(WCD9378_CDC_HPH_GAIN_CTL,
WCD9378_CDC_HPH_GAIN_CTL_HPHL_RX_EN_SHIFT,
SOC_ENUM_SINGLE(WCD9378_CDC_AUX_GAIN_CTL,
WCD9378_CDC_AUX_GAIN_CTL_AUX_EN_SHIFT,
ARRAY_SIZE(ear_mux_text), ear_mux_text);
static const struct soc_enum aux_enum =
SOC_ENUM_SINGLE(WCD9378_CDC_HPH_GAIN_CTL,
WCD9378_CDC_HPH_GAIN_CTL_HPHR_RX_EN_SHIFT,
SOC_ENUM_SINGLE(WCD9378_CDC_AUX_GAIN_CTL,
WCD9378_CDC_AUX_GAIN_CTL_AUX_EN_SHIFT,
ARRAY_SIZE(aux_mux_text), aux_mux_text);
static const struct snd_kcontrol_new tx_adc1_mux =
@@ -3505,7 +3611,6 @@ static const struct snd_soc_dapm_route wcd9378_audio_map[] = {
{"ADC3_OUTPUT", NULL, "TX2 SEQUENCER"},
{"TX2 SEQUENCER", NULL, "ADC3 MUX"},
{"ADC3 MUX", "CH3_AMIC1", "AMIC1_MIXER"},
{"ADC3 MUX", "CH3_AMIC2", "AMIC2_MIXER"},
{"ADC3 MUX", "CH3_AMIC3", "AMIC3_MIXER"},
{"ADC3 MUX", "CH3_AMIC4", "AMIC4_MIXER"},
@@ -3842,6 +3947,7 @@ static int wcd9378_soc_codec_probe(struct snd_soc_component *component)
return ret;
}
}
exit:
return ret;
}
@@ -4327,6 +4433,7 @@ static int wcd9378_probe(struct platform_device *pdev)
mutex_init(&wcd9378->wakeup_lock);
mutex_init(&wcd9378->micb_lock);
mutex_init(&wcd9378->sys_usage_lock);
ret = wcd9378_add_slave_components(dev, &match);
if (ret)
goto err_lock_init;
@@ -4345,6 +4452,7 @@ static int wcd9378_probe(struct platform_device *pdev)
err_lock_init:
mutex_destroy(&wcd9378->micb_lock);
mutex_destroy(&wcd9378->wakeup_lock);
mutex_destroy(&wcd9378->sys_usage_lock);
err:
return ret;
}
@@ -4357,6 +4465,7 @@ static int wcd9378_remove(struct platform_device *pdev)
component_master_del(&pdev->dev, &wcd9378_comp_ops);
mutex_destroy(&wcd9378->micb_lock);
mutex_destroy(&wcd9378->wakeup_lock);
mutex_destroy(&wcd9378->sys_usage_lock);
dev_set_drvdata(&pdev->dev, NULL);
return 0;