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:
@@ -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),
|
||||
|
Reference in New Issue
Block a user