asoc: codec: lpass: add support to select PDM vs PCM path

add support to select PDM or PCM path in rx macro with the help
of mixer ctls.

Change-Id: I803e0bf440c1b3546cbda23e49736addb9083d92
Signed-off-by: Prasad Kumpatla <quic_pkumpatl@quicinc.com>
This commit is contained in:
Prasad Kumpatla
2022-10-10 16:54:49 +05:30
parent f8f8f14c93
commit d6ccee90de

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/module.h>
@@ -485,6 +485,7 @@ enum {
struct lpass_cdc_rx_macro_priv {
struct device *dev;
int comp_enabled[LPASS_CDC_RX_MACRO_COMP_MAX];
u8 is_pcm_enabled;
/* Main path clock users count */
int main_clk_users[INTERP_MAX];
int rx_port_value[LPASS_CDC_RX_MACRO_PORTS_MAX];
@@ -535,6 +536,7 @@ struct lpass_cdc_rx_macro_priv {
struct clk *hifi_fir_clk;
int8_t rx0_gain_val;
int8_t rx1_gain_val;
int pcm_select_users;
};
static struct snd_soc_dai_driver lpass_cdc_rx_macro_dai[];
@@ -1827,11 +1829,15 @@ static int lpass_cdc_rx_macro_enable_main_path(struct snd_soc_dapm_widget *w,
}
static void lpass_cdc_rx_macro_droop_setting(struct snd_soc_component *component,
int interp_n, int event)
struct lpass_cdc_rx_macro_priv *rx_priv,
int interp_n, int event)
{
u8 pcm_rate = 0, val = 0;
u16 rx0_path_ctl_reg = 0, rx_path_cfg3_reg = 0;
if (rx_priv->is_pcm_enabled)
return;
rx_path_cfg3_reg = LPASS_CDC_RX_RX0_RX_PATH_CFG3 +
(interp_n * LPASS_CDC_RX_MACRO_RX_PATH_OFFSET);
rx0_path_ctl_reg = LPASS_CDC_RX_RX0_RX_PATH_CTL +
@@ -1869,7 +1875,7 @@ static int lpass_cdc_rx_macro_config_compander(struct snd_soc_component *compone
return 0;
comp = interp_n;
if (!rx_priv->comp_enabled[comp])
if (!rx_priv->comp_enabled[comp] && rx_priv->is_pcm_enabled)
return 0;
if (rx_priv->is_ear_mode_on && interp_n == INTERP_HPHL)
@@ -2083,11 +2089,15 @@ static int lpass_cdc_rx_macro_config_classh(struct snd_soc_component *component,
}
static void lpass_cdc_rx_macro_hd2_control(struct snd_soc_component *component,
u16 interp_idx, int event)
struct lpass_cdc_rx_macro_priv *rx_priv,
u16 interp_idx, int event)
{
u16 hd2_scale_reg = 0;
u16 hd2_enable_reg = 0;
if (rx_priv->is_pcm_enabled)
return;
switch (interp_idx) {
case INTERP_HPHL:
hd2_scale_reg = LPASS_CDC_RX_RX0_RX_PATH_SEC3;
@@ -2148,6 +2158,36 @@ static int lpass_cdc_rx_macro_hph_idle_detect_put(struct snd_kcontrol *kcontrol,
return 0;
}
static int lpass_cdc_rx_macro_get_pcm_path(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_component *component =
snd_soc_kcontrol_component(kcontrol);
struct device *rx_dev = NULL;
struct lpass_cdc_rx_macro_priv *rx_priv = NULL;
if (!lpass_cdc_rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
return -EINVAL;
ucontrol->value.integer.value[0] = rx_priv->is_pcm_enabled;
return 0;
}
static int lpass_cdc_rx_macro_put_pcm_path(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_component *component =
snd_soc_kcontrol_component(kcontrol);
struct device *rx_dev = NULL;
struct lpass_cdc_rx_macro_priv *rx_priv = NULL;
if (!lpass_cdc_rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
return -EINVAL;
rx_priv->is_pcm_enabled = ucontrol->value.integer.value[0];
return 0;
}
static int lpass_cdc_rx_macro_get_compander(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -2618,6 +2658,9 @@ static void lpass_cdc_rx_macro_idle_detect_control(struct snd_soc_component *com
if (!rx_priv->idle_det_cfg.hph_idle_detect_en)
return;
if (!rx_priv->is_pcm_enabled)
return;
if (interp == INTERP_HPHL) {
reg = LPASS_CDC_RX_IDLE_DETECT_PATH_CTL;
mask = 0x01;
@@ -2647,6 +2690,9 @@ static void lpass_cdc_rx_macro_hphdelay_lutbypass(struct snd_soc_component *comp
u16 hph_lut_bypass_reg = 0;
u16 hph_comp_ctrl7 = 0;
if (rx_priv->is_pcm_enabled)
return;
switch (interp_idx) {
case INTERP_HPHL:
hph_lut_bypass_reg = LPASS_CDC_RX_TOP_HPHL_COMP_LUT;
@@ -2732,11 +2778,11 @@ static int lpass_cdc_rx_macro_enable_interp_clk(struct snd_soc_component *compon
interp_idx, event);
if (rx_priv->hph_hd2_mode)
lpass_cdc_rx_macro_hd2_control(
component, interp_idx, event);
component, rx_priv, interp_idx, event);
lpass_cdc_rx_macro_hphdelay_lutbypass(component, rx_priv,
interp_idx, event);
lpass_cdc_rx_macro_droop_setting(component,
interp_idx, event);
rx_priv, interp_idx, event);
lpass_cdc_rx_macro_config_compander(component, rx_priv,
interp_idx, event);
if (interp_idx == INTERP_AUX) {
@@ -2747,6 +2793,13 @@ static int lpass_cdc_rx_macro_enable_interp_clk(struct snd_soc_component *compon
}
lpass_cdc_rx_macro_config_classh(component, rx_priv,
interp_idx, event);
/*select PCM path and swr clk is 9.6MHz*/
if (rx_priv->is_pcm_enabled) {
if (rx_priv->pcm_select_users == 0)
snd_soc_component_update_bits(component,
LPASS_CDC_RX_TOP_SWR_CTRL, 0x02, 0x02);
++rx_priv->pcm_select_users;
}
}
rx_priv->main_clk_users[interp_idx]++;
}
@@ -2758,6 +2811,16 @@ static int lpass_cdc_rx_macro_enable_interp_clk(struct snd_soc_component *compon
/* Main path PGA mute enable */
snd_soc_component_update_bits(component, main_reg,
0x10, 0x10);
/*Unselect PCM path*/
if (rx_priv->is_pcm_enabled) {
if (rx_priv->pcm_select_users == 1)
snd_soc_component_update_bits(component,
LPASS_CDC_RX_TOP_SWR_CTRL, 0x02, 0x00);
--rx_priv->pcm_select_users;
if (rx_priv->pcm_select_users < 0)
rx_priv->pcm_select_users = 0;
}
/* Clk Disable */
snd_soc_component_update_bits(component, dsm_reg,
0x01, 0x00);
@@ -2786,8 +2849,8 @@ static int lpass_cdc_rx_macro_enable_interp_clk(struct snd_soc_component *compon
lpass_cdc_rx_macro_hphdelay_lutbypass(component, rx_priv,
interp_idx, event);
if (rx_priv->hph_hd2_mode)
lpass_cdc_rx_macro_hd2_control(component, interp_idx,
event);
lpass_cdc_rx_macro_hd2_control(component,
rx_priv, interp_idx, event);
lpass_cdc_rx_macro_idle_detect_control(component, rx_priv,
interp_idx, event);
}
@@ -3670,6 +3733,9 @@ static const struct snd_kcontrol_new lpass_cdc_rx_macro_snd_controls[] = {
SOC_SINGLE_EXT("RX_COMP2 Switch", SND_SOC_NOPM, LPASS_CDC_RX_MACRO_COMP2, 1, 0,
lpass_cdc_rx_macro_get_compander, lpass_cdc_rx_macro_set_compander),
SOC_SINGLE_EXT("RX_HPH PCM", SND_SOC_NOPM, 0, 1, 0,
lpass_cdc_rx_macro_get_pcm_path, lpass_cdc_rx_macro_put_pcm_path),
SOC_SINGLE_EXT("RX0 FIR Coeff Num", SND_SOC_NOPM, RX0_PATH,
(LPASS_CDC_RX_MACRO_FIR_COEFF_MAX * GRP_MAX), 0,
lpass_cdc_rx_macro_fir_coeff_num_get, lpass_cdc_rx_macro_fir_coeff_num_put),