Merge 4e4aec5874
on remote branch
Change-Id: I11ecf1e1308715c9e7f8f3a7c52fd3cb38e7f78b
Dieser Commit ist enthalten in:
@@ -1,5 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _LPASS_CDC_INTERNAL_H
|
||||
@@ -17,6 +18,7 @@ enum {
|
||||
LPASS_CDC_WCD_EVT_SSR_UP,
|
||||
LPASS_CDC_WCD_EVT_PA_ON_POST_FSCLK,
|
||||
LPASS_CDC_WCD_EVT_PA_ON_POST_FSCLK_ADIE_LB,
|
||||
LPASS_CDC_WCD_EVT_CLK_NOTIFY,
|
||||
};
|
||||
|
||||
enum {
|
||||
@@ -50,6 +52,7 @@ struct lpass_cdc_priv {
|
||||
struct device *dev;
|
||||
struct snd_soc_component *component;
|
||||
struct regmap *regmap;
|
||||
struct mutex macro_lock;
|
||||
struct mutex io_lock;
|
||||
struct mutex clk_lock;
|
||||
struct mutex vote_lock;
|
||||
|
@@ -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,14 @@ 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 && !rx_priv->is_native_on) {
|
||||
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;
|
||||
}
|
||||
lpass_cdc_notify_wcd_rx_clk(rx_dev, rx_priv->is_native_on);
|
||||
}
|
||||
rx_priv->main_clk_users[interp_idx]++;
|
||||
}
|
||||
@@ -2758,6 +2812,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 && !rx_priv->is_native_on) {
|
||||
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 +2850,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 +3734,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),
|
||||
|
@@ -212,7 +212,7 @@ static int lpass_cdc_wsa_macro_enable_vi_decimator(struct snd_soc_component *com
|
||||
.put = lpass_cdc_wsa_macro_set_digital_volume, \
|
||||
.private_value = (unsigned long)&(struct soc_mixer_control) \
|
||||
{.reg = xreg, .rreg = xreg, \
|
||||
.min = xmin, .max = xmax, .platform_max = xmax, \
|
||||
.min = xmin, .max = xmax, \
|
||||
.sign_bit = 7,} }
|
||||
|
||||
struct lpass_cdc_wsa_macro_swr_ctrl_platform_data {
|
||||
|
@@ -212,7 +212,7 @@ static int lpass_cdc_wsa2_macro_enable_vi_decimator(struct snd_soc_component *co
|
||||
.put = lpass_cdc_wsa2_macro_set_digital_volume, \
|
||||
.private_value = (unsigned long)&(struct soc_mixer_control) \
|
||||
{.reg = xreg, .rreg = xreg, \
|
||||
.min = xmin, .max = xmax, .platform_max = xmax, \
|
||||
.min = xmin, .max = xmax, \
|
||||
.sign_bit = 7,} }
|
||||
|
||||
struct lpass_cdc_wsa2_macro_swr_ctrl_platform_data {
|
||||
|
@@ -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/of_platform.h>
|
||||
@@ -663,6 +663,7 @@ int lpass_cdc_register_macro(struct device *dev, u16 macro_id,
|
||||
if (macro_id == VA_MACRO)
|
||||
priv->macro_params[macro_id].reg_wake_irq =
|
||||
ops->reg_wake_irq;
|
||||
mutex_lock(&priv->macro_lock);
|
||||
priv->num_dais += ops->num_dais;
|
||||
priv->num_macros_registered++;
|
||||
priv->macros_supported[macro_id] = true;
|
||||
@@ -673,6 +674,7 @@ int lpass_cdc_register_macro(struct device *dev, u16 macro_id,
|
||||
ret = lpass_cdc_copy_dais_from_macro(priv);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "%s: copy_dais failed\n", __func__);
|
||||
mutex_unlock(&priv->macro_lock);
|
||||
return ret;
|
||||
}
|
||||
if (priv->macros_supported[TX_MACRO] == false) {
|
||||
@@ -685,9 +687,11 @@ int lpass_cdc_register_macro(struct device *dev, u16 macro_id,
|
||||
priv->lpass_cdc_dais, priv->num_dais);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "%s: register codec failed\n", __func__);
|
||||
mutex_unlock(&priv->macro_lock);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&priv->macro_lock);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(lpass_cdc_register_macro);
|
||||
@@ -740,6 +744,36 @@ void lpass_cdc_unregister_macro(struct device *dev, u16 macro_id)
|
||||
}
|
||||
EXPORT_SYMBOL(lpass_cdc_unregister_macro);
|
||||
|
||||
void lpass_cdc_notify_wcd_rx_clk(struct device *dev, bool is_native_on)
|
||||
{
|
||||
struct lpass_cdc_priv *priv;
|
||||
u32 val;
|
||||
|
||||
if (!dev) {
|
||||
pr_err_ratelimited("%s: dev is null\n", __func__);
|
||||
return;
|
||||
}
|
||||
if (!lpass_cdc_is_valid_child_dev(dev)) {
|
||||
dev_err_ratelimited(dev, "%s: not a valid child dev\n",
|
||||
__func__);
|
||||
return;
|
||||
}
|
||||
priv = dev_get_drvdata(dev->parent);
|
||||
if (!priv) {
|
||||
dev_err_ratelimited(dev, "%s: priv is null\n", __func__);
|
||||
return;
|
||||
}
|
||||
if (is_native_on)
|
||||
val = 0x2; /* 11.2896M */
|
||||
else
|
||||
val = 0x0; /* 9.6M */
|
||||
|
||||
lpass_cdc_notifier_call(priv,
|
||||
((val << 16) | LPASS_CDC_WCD_EVT_CLK_NOTIFY));
|
||||
|
||||
}
|
||||
EXPORT_SYMBOL(lpass_cdc_notify_wcd_rx_clk);
|
||||
|
||||
void lpass_cdc_wsa_pa_on(struct device *dev, bool adie_lb)
|
||||
{
|
||||
struct lpass_cdc_priv *priv;
|
||||
@@ -1323,6 +1357,7 @@ static int lpass_cdc_probe(struct platform_device *pdev)
|
||||
priv->core_audio_vote_count = 0;
|
||||
|
||||
dev_set_drvdata(&pdev->dev, priv);
|
||||
mutex_init(&priv->macro_lock);
|
||||
mutex_init(&priv->io_lock);
|
||||
mutex_init(&priv->clk_lock);
|
||||
mutex_init(&priv->vote_lock);
|
||||
@@ -1363,6 +1398,7 @@ static int lpass_cdc_remove(struct platform_device *pdev)
|
||||
return -EINVAL;
|
||||
|
||||
of_platform_depopulate(&pdev->dev);
|
||||
mutex_destroy(&priv->macro_lock);
|
||||
mutex_destroy(&priv->io_lock);
|
||||
mutex_destroy(&priv->clk_lock);
|
||||
mutex_destroy(&priv->vote_lock);
|
||||
|
@@ -1,5 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef LPASS_CDC_H
|
||||
@@ -273,6 +274,7 @@ int lpass_cdc_set_port_map(struct snd_soc_component *component, u32 size, void *
|
||||
int lpass_cdc_register_event_listener(struct snd_soc_component *component,
|
||||
bool enable);
|
||||
void lpass_cdc_wsa_pa_on(struct device *dev, bool adie_lb);
|
||||
void lpass_cdc_notify_wcd_rx_clk(struct device *dev, bool is_native_on);
|
||||
bool lpass_cdc_check_core_votes(struct device *dev);
|
||||
int lpass_cdc_tx_mclk_enable(struct snd_soc_component *c, bool enable);
|
||||
int lpass_cdc_get_version(struct device *dev);
|
||||
@@ -357,6 +359,10 @@ static void lpass_cdc_wsa_pa_on(struct device *dev, bool adie_lb)
|
||||
{
|
||||
}
|
||||
|
||||
static void lpass_cdc_notify_wcd_rx_clk(struct device *dev, bool is_native_on)
|
||||
{
|
||||
}
|
||||
|
||||
static inline bool lpass_cdc_check_core_votes(struct device *dev)
|
||||
{
|
||||
return false;
|
||||
|
@@ -1786,6 +1786,14 @@ int wcd_mbhc_start(struct wcd_mbhc *mbhc, struct wcd_mbhc_config *mbhc_cfg)
|
||||
}
|
||||
}
|
||||
|
||||
/* Disable moisture detect and duty cycle for WCD USB AATC HS*/
|
||||
if (mbhc_cfg->enable_usbc_analog) {
|
||||
mbhc_cfg->moisture_en = false;
|
||||
mbhc_cfg->moisture_duty_cycle_en = false;
|
||||
pr_debug("%s: Disable moisture detect and duty cycle of AATC",
|
||||
__func__);
|
||||
}
|
||||
|
||||
/* Set btn key code */
|
||||
if ((!mbhc->is_btn_already_regd) && wcd_mbhc_set_keycode(mbhc))
|
||||
pr_err("Set btn key code error!!!\n");
|
||||
|
@@ -1,7 +1,7 @@
|
||||
// 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>
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "wcd937x.h"
|
||||
#include "internal.h"
|
||||
#include "asoc/bolero-slave-internal.h"
|
||||
#include <linux/qti-regmap-debugfs.h>
|
||||
|
||||
#define WCD9370_VARIANT 0
|
||||
#define WCD9375_VARIANT 5
|
||||
@@ -2839,6 +2840,9 @@ static int wcd937x_soc_codec_probe(struct snd_soc_component *component)
|
||||
|
||||
wcd937x->component = component;
|
||||
snd_soc_component_init_regmap(component, wcd937x->regmap);
|
||||
|
||||
devm_regmap_qti_debugfs_register(&wcd937x->tx_swr_dev->dev, wcd937x->regmap);
|
||||
|
||||
variant = (snd_soc_component_read(
|
||||
component, WCD937X_DIGITAL_EFUSE_REG_0) & 0x1E) >> 1;
|
||||
wcd937x->variant = variant;
|
||||
|
@@ -1,6 +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.
|
||||
*/
|
||||
|
||||
#ifndef _WCD939X_INTERNAL_H
|
||||
@@ -24,6 +25,18 @@
|
||||
#define TX_ADC_MAX 4
|
||||
#define SWR_NUM_PORTS 4
|
||||
|
||||
enum {
|
||||
RX_CLK_9P6MHZ,
|
||||
RX_CLK_12P288MHZ,
|
||||
RX_CLK_11P2896MHZ,
|
||||
};
|
||||
|
||||
enum {
|
||||
WCD939X_HPHL,
|
||||
WCD939X_HPHR,
|
||||
WCD939X_HPH_MAX,
|
||||
};
|
||||
|
||||
enum {
|
||||
TX_HDR12 = 0,
|
||||
TX_HDR34,
|
||||
@@ -32,6 +45,11 @@ enum {
|
||||
|
||||
extern struct regmap_config wcd939x_regmap_config;
|
||||
|
||||
struct comp_coeff_val {
|
||||
u8 lsb;
|
||||
u8 msb;
|
||||
};
|
||||
|
||||
struct codec_port_info {
|
||||
u32 slave_port_type;
|
||||
u32 master_port_type;
|
||||
@@ -69,6 +87,11 @@ struct wcd939x_priv {
|
||||
/* mbhc module */
|
||||
struct wcd939x_mbhc *mbhc;
|
||||
|
||||
/*compander and xtalk*/
|
||||
int compander_enabled[WCD939X_HPH_MAX];
|
||||
int xtalk_enabled[WCD939X_HPH_MAX];
|
||||
u8 hph_pcm_enabled;
|
||||
|
||||
u32 hph_mode;
|
||||
u32 tx_mode[TX_ADC_MAX];
|
||||
s32 adc_count;
|
||||
@@ -111,6 +134,7 @@ struct wcd939x_priv {
|
||||
bool dev_up;
|
||||
u8 tx_master_ch_map[WCD939X_MAX_SLAVE_CH_TYPES];
|
||||
bool usbc_hs_status;
|
||||
u8 rx_clk_config;
|
||||
/* wcd to swr dmic notification */
|
||||
bool notify_swr_dmic;
|
||||
struct blocking_notifier_head notifier;
|
||||
|
@@ -1,7 +1,7 @@
|
||||
// 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>
|
||||
@@ -22,7 +22,6 @@
|
||||
#include <asoc/msm-cdc-supply.h>
|
||||
#include <bindings/audio-codec-port-types.h>
|
||||
#include <linux/qti-regmap-debugfs.h>
|
||||
|
||||
#include "wcd939x-registers.h"
|
||||
#include "wcd939x.h"
|
||||
#include "internal.h"
|
||||
@@ -45,6 +44,8 @@
|
||||
#define ADC_MODE_VAL_ULP2 0x0B
|
||||
|
||||
#define NUM_ATTEMPTS 5
|
||||
#define COMP_MAX_COEFF 25
|
||||
#define HPH_MODE_MAX 4
|
||||
|
||||
#define DAPM_MICBIAS1_STANDALONE "MIC BIAS1 Standalone"
|
||||
#define DAPM_MICBIAS2_STANDALONE "MIC BIAS2 Standalone"
|
||||
@@ -66,6 +67,72 @@
|
||||
#define REG_FIELD_VALUE(register_name, field_name, value) \
|
||||
WCD939X_##register_name, FIELD_MASK(register_name, field_name), \
|
||||
value << FIELD_SHIFT(register_name, field_name)
|
||||
|
||||
#define WCD939X_COMP_OFFSET \
|
||||
(WCD939X_R_BASE - WCD939X_COMPANDER_HPHL_BASE)
|
||||
|
||||
#define WCD939X_XTALK_OFFSET \
|
||||
(WCD939X_HPHR_RX_PATH_SEC0 - WCD939X_HPHL_RX_PATH_SEC0)
|
||||
|
||||
static struct comp_coeff_val
|
||||
comp_coeff_table [HPH_MODE_MAX][COMP_MAX_COEFF] = {
|
||||
{
|
||||
{0x40, 0x00},
|
||||
{0x4C, 0x00},
|
||||
{0x5A, 0x00},
|
||||
{0x6B, 0x00},
|
||||
{0x7F, 0x00},
|
||||
{0x97, 0x00},
|
||||
{0xB3, 0x00},
|
||||
{0xD5, 0x00},
|
||||
{0xFD, 0x00},
|
||||
{0x2D, 0x01},
|
||||
{0x66, 0x01},
|
||||
{0xA7, 0x01},
|
||||
{0xF8, 0x01},
|
||||
{0x57, 0x02},
|
||||
{0xC7, 0x02},
|
||||
{0x4B, 0x03},
|
||||
{0xE9, 0x03},
|
||||
{0xA3, 0x04},
|
||||
{0x7D, 0x05},
|
||||
{0x90, 0x06},
|
||||
{0xD1, 0x07},
|
||||
{0x49, 0x09},
|
||||
{0x00, 0x0B},
|
||||
{0x01, 0x0D},
|
||||
{0x59, 0x0F},
|
||||
},
|
||||
{
|
||||
/*HPH_HIFI, HPH_LOHIFI, HPH_LP*/
|
||||
{0x40, 0x00},
|
||||
{0x4C, 0x00},
|
||||
{0x5A, 0x00},
|
||||
{0x6B, 0x00},
|
||||
{0x80, 0x00},
|
||||
{0x98, 0x00},
|
||||
{0xB4, 0x00},
|
||||
{0xD5, 0x00},
|
||||
{0xFE, 0x00},
|
||||
{0x2E, 0x01},
|
||||
{0x66, 0x01},
|
||||
{0xA9, 0x01},
|
||||
{0xF8, 0x01},
|
||||
{0x56, 0x02},
|
||||
{0xC4, 0x02},
|
||||
{0x4F, 0x03},
|
||||
{0xF0, 0x03},
|
||||
{0xAE, 0x04},
|
||||
{0x8B, 0x05},
|
||||
{0x8E, 0x06},
|
||||
{0xBC, 0x07},
|
||||
{0x56, 0x09},
|
||||
{0x0F, 0x0B},
|
||||
{0x13, 0x0D},
|
||||
{0x6F, 0x0F},
|
||||
},
|
||||
};
|
||||
|
||||
enum {
|
||||
CODEC_TX = 0,
|
||||
CODEC_RX,
|
||||
@@ -165,6 +232,131 @@ static int wcd939x_handle_post_irq(void *data)
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
int wcd939x_load_compander_coeff(struct snd_soc_component *component,
|
||||
u16 lsb_reg, u16 msb_reg,
|
||||
struct comp_coeff_val *comp_coeff_table,
|
||||
u16 arr_size)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
/* Load Compander Coeff */
|
||||
for (i = 0; i < arr_size; i++) {
|
||||
snd_soc_component_write(component, lsb_reg,
|
||||
comp_coeff_table[i].lsb);
|
||||
snd_soc_component_write(component, msb_reg,
|
||||
comp_coeff_table[i].msb);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(wcd939x_load_compander_coeff);
|
||||
|
||||
|
||||
static int wcd939x_hph_compander_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *component =
|
||||
snd_soc_kcontrol_component(kcontrol);
|
||||
struct wcd939x_priv *wcd939x = snd_soc_component_get_drvdata(component);
|
||||
|
||||
int compander = ((struct soc_multi_mixer_control *)
|
||||
kcontrol->private_value)->shift;
|
||||
|
||||
ucontrol->value.integer.value[0] = wcd939x->compander_enabled[compander];
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int wcd939x_hph_compander_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *component =
|
||||
snd_soc_kcontrol_component(kcontrol);
|
||||
struct wcd939x_priv *wcd939x = snd_soc_component_get_drvdata(component);
|
||||
|
||||
int compander = ((struct soc_multi_mixer_control *)
|
||||
kcontrol->private_value)->shift;
|
||||
|
||||
int value = ucontrol->value.integer.value[0];
|
||||
|
||||
if (value < WCD939X_HPH_MAX && value >= 0)
|
||||
wcd939x->compander_enabled[compander] = value;
|
||||
else {
|
||||
dev_err(component->dev, "%s: Invalid comp value = %d\n", __func__, value);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dev_dbg(component->dev, "%s: Compander %d value %d\n",
|
||||
__func__, wcd939x->compander_enabled[compander], value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wcd939x_hph_xtalk_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *component =
|
||||
snd_soc_kcontrol_component(kcontrol);
|
||||
struct wcd939x_priv *wcd939x = snd_soc_component_get_drvdata(component);
|
||||
|
||||
int xtalk = ((struct soc_multi_mixer_control *)
|
||||
kcontrol->private_value)->shift;
|
||||
|
||||
int value = ucontrol->value.integer.value[0];
|
||||
|
||||
if (value < WCD939X_HPH_MAX && value >= 0)
|
||||
wcd939x->xtalk_enabled[xtalk] = value;
|
||||
else {
|
||||
dev_err(component->dev, "%s: Invalid xtalk value = %d\n", __func__, value);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dev_dbg(component->dev, "%s: xtalk %d value %d\n",
|
||||
__func__, wcd939x->xtalk_enabled[xtalk], value);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static int wcd939x_hph_xtalk_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *component =
|
||||
snd_soc_kcontrol_component(kcontrol);
|
||||
struct wcd939x_priv *wcd939x = snd_soc_component_get_drvdata(component);
|
||||
|
||||
int xtalk = ((struct soc_multi_mixer_control *)
|
||||
kcontrol->private_value)->shift;
|
||||
|
||||
ucontrol->value.integer.value[0] = wcd939x->xtalk_enabled[xtalk];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wcd939x_hph_pcm_enable_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *component =
|
||||
snd_soc_kcontrol_component(kcontrol);
|
||||
struct wcd939x_priv *wcd939x = snd_soc_component_get_drvdata(component);
|
||||
|
||||
wcd939x->hph_pcm_enabled = ucontrol->value.integer.value[0];
|
||||
dev_dbg(component->dev, "%s: pcm enabled %d \n",
|
||||
__func__, wcd939x->hph_pcm_enabled);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static int wcd939x_hph_pcm_enable_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *component =
|
||||
snd_soc_kcontrol_component(kcontrol);
|
||||
struct wcd939x_priv *wcd939x = snd_soc_component_get_drvdata(component);
|
||||
|
||||
ucontrol->value.integer.value[0] = wcd939x->hph_pcm_enabled;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wcd939x_swr_slv_get_current_bank(struct swr_device *dev, u8 devnum)
|
||||
{
|
||||
@@ -238,8 +430,11 @@ static int wcd939x_set_swr_clk_rate(struct snd_soc_component *component,
|
||||
static int wcd939x_init_reg(struct snd_soc_component *component)
|
||||
{
|
||||
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(VBG_FINE_ADJ, VBG_FINE_ADJ, 0x04));
|
||||
struct wcd939x_priv *wcd939x = snd_soc_component_get_drvdata(component);
|
||||
|
||||
if (!wcd939x->hph_pcm_enabled)
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(VBG_FINE_ADJ, VBG_FINE_ADJ, 0x04));
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(BIAS, ANALOG_BIAS_EN, 0x01));
|
||||
snd_soc_component_update_bits(component,
|
||||
@@ -284,6 +479,8 @@ static int wcd939x_init_reg(struct snd_soc_component *component)
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(HPHLR_SURGE_EN, EN_SURGE_PROTECTION_HPHR, 0x01));
|
||||
|
||||
snd_soc_component_write(component, WCD939X_CFG0, 0x05);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -573,6 +770,12 @@ static int wcd939x_rx_clk_enable(struct snd_soc_component *component)
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(CDC_DIG_CLK_CTL, RXD2_CLK_EN, 0x01));
|
||||
|
||||
if (wcd939x->hph_pcm_enabled) {
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(PA_GAIN_CTL_L, RX_SUPPLY_LEVEL, 0x01));
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(VNEG_CTRL_4, ILIM_SEL, 0x02));
|
||||
}
|
||||
}
|
||||
wcd939x->rx_clk_cnt++;
|
||||
|
||||
@@ -634,22 +837,288 @@ struct wcd939x_mbhc *wcd939x_soc_get_mbhc(struct snd_soc_component *component)
|
||||
}
|
||||
EXPORT_SYMBOL(wcd939x_soc_get_mbhc);
|
||||
|
||||
static int wcd939x_config_power_mode(struct snd_soc_component *component,
|
||||
int event, int index, int mode)
|
||||
{
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
if (mode == CLS_H_ULP) {
|
||||
if (index == WCD939X_HPHL) {
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(CTL12, ZONE3_RMS, 0x21));
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(CTL13, ZONE4_RMS, 0x30));
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(CTL14, ZONE5_RMS, 0x3F));
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(CTL15, ZONE6_RMS, 0x48));
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(CTL17, PATH_GAIN, 0x0C));
|
||||
} else if (index == WCD939X_HPHR) {
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(R_CTL12, ZONE3_RMS, 0x21));
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(R_CTL13, ZONE4_RMS, 0x30));
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(R_CTL14, ZONE5_RMS, 0x3F));
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(R_CTL15, ZONE6_RMS, 0x48));
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(R_CTL17, PATH_GAIN, 0x0C));
|
||||
}
|
||||
} else {
|
||||
if (index == WCD939X_HPHL) {
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(CTL12, ZONE3_RMS, 0x1E));
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(CTL13, ZONE4_RMS, 0x2A));
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(CTL14, ZONE5_RMS, 0x36));
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(CTL15, ZONE6_RMS, 0x3C));
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(CTL17, PATH_GAIN, 0x00));
|
||||
} else if (index == WCD939X_HPHR) {
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(R_CTL12, ZONE3_RMS, 0x1E));
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(R_CTL13, ZONE4_RMS, 0x2A));
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(R_CTL14, ZONE5_RMS, 0x36));
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(R_CTL15, ZONE6_RMS, 0x2C));
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(R_CTL17, PATH_GAIN, 0x00));
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wcd939x_enable_hph_pcm_index(struct snd_soc_component *component,
|
||||
int event, int hph)
|
||||
{
|
||||
struct wcd939x_priv *wcd939x = NULL;
|
||||
|
||||
if (!component) {
|
||||
pr_err_ratelimited("%s: Invalid params, NULL component\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
wcd939x = snd_soc_component_get_drvdata(component);
|
||||
|
||||
if (!wcd939x->hph_pcm_enabled)
|
||||
return 0;
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
if (hph == WCD939X_HPHL) {
|
||||
if (wcd939x->rx_clk_config == RX_CLK_11P2896MHZ)
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(HPHL_RX_PATH_CFG1,
|
||||
RX_DC_DROOP_COEFF_SEL, 0x2));
|
||||
else if (wcd939x->rx_clk_config == RX_CLK_9P6MHZ)
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(HPHL_RX_PATH_CFG1,
|
||||
RX_DC_DROOP_COEFF_SEL, 0x3));
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(HPHL_RX_PATH_CFG0,
|
||||
DLY_ZN_EN, 0x1));
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(HPHL_RX_PATH_CFG0,
|
||||
INT_EN, 0x3));
|
||||
} else if (hph == WCD939X_HPHR) {
|
||||
if (wcd939x->rx_clk_config == RX_CLK_11P2896MHZ)
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(HPHR_RX_PATH_CFG1,
|
||||
RX_DC_DROOP_COEFF_SEL, 0x2));
|
||||
else if (wcd939x->rx_clk_config == RX_CLK_9P6MHZ)
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(HPHR_RX_PATH_CFG1,
|
||||
RX_DC_DROOP_COEFF_SEL, 0x3));
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(HPHR_RX_PATH_CFG0,
|
||||
DLY_ZN_EN, 0x1));
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(HPHR_RX_PATH_CFG0,
|
||||
INT_EN, 0x3));
|
||||
}
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMD:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wcd939x_config_compander(struct snd_soc_component *component,
|
||||
int event, int compander_indx)
|
||||
{
|
||||
u16 comp_coeff_lsb_reg = 0, comp_coeff_msb_reg = 0;
|
||||
u16 comp_ctl7_reg = 0, comp_ctl0_reg = 0;
|
||||
u16 comp_en_mask_val = 0;
|
||||
struct wcd939x_priv *wcd939x;
|
||||
int hph_mode;
|
||||
|
||||
|
||||
if (compander_indx >= WCD939X_HPH_MAX || compander_indx < 0) {
|
||||
pr_err_ratelimited("%s: Invalid compander value: %d\n",
|
||||
__func__, compander_indx);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!component) {
|
||||
pr_err_ratelimited("%s: Invalid params, NULL component\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
wcd939x = snd_soc_component_get_drvdata(component);
|
||||
|
||||
if (!wcd939x->compander_enabled[compander_indx])
|
||||
return 0;
|
||||
|
||||
hph_mode = wcd939x->hph_mode;
|
||||
dev_dbg(component->dev, "%s compander_index = %d hph mode = %d\n",
|
||||
__func__, compander_indx, wcd939x->hph_mode);
|
||||
|
||||
if (compander_indx == WCD939X_HPHL) {
|
||||
comp_coeff_lsb_reg = WCD939X_HPHL_COMP_WR_LSB;
|
||||
comp_coeff_msb_reg = WCD939X_HPHL_COMP_WR_MSB;
|
||||
comp_en_mask_val = 1 << 1;
|
||||
} else if (compander_indx == WCD939X_HPHR) {
|
||||
comp_coeff_lsb_reg = WCD939X_HPHR_COMP_WR_LSB;
|
||||
comp_coeff_msb_reg = WCD939X_HPHR_COMP_WR_MSB;
|
||||
comp_en_mask_val = 1 << 0;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
comp_ctl0_reg = WCD939X_CTL0 + (compander_indx * WCD939X_COMP_OFFSET);
|
||||
comp_ctl7_reg = WCD939X_CTL7 + (compander_indx * WCD939X_COMP_OFFSET);
|
||||
|
||||
if (SND_SOC_DAPM_EVENT_ON(event)){
|
||||
|
||||
snd_soc_component_update_bits(component,
|
||||
comp_ctl7_reg, 0x1E, 0x00);
|
||||
/* Enable compander clock*/
|
||||
snd_soc_component_update_bits(component,
|
||||
comp_ctl0_reg , 0x01, 0x01);
|
||||
|
||||
/* 250us sleep required as per HW Sequence */
|
||||
usleep_range(250, 260);
|
||||
snd_soc_component_update_bits(component,
|
||||
comp_ctl0_reg , 0x02, 0x01);
|
||||
snd_soc_component_update_bits(component,
|
||||
comp_ctl0_reg , 0x02, 0x00);
|
||||
|
||||
/* Compander coeff values are same for below modes */
|
||||
if (wcd939x->hph_mode == CLS_H_HIFI || wcd939x->hph_mode == CLS_H_LOHIFI
|
||||
|| wcd939x->hph_mode == CLS_H_LP)
|
||||
hph_mode = 1;
|
||||
else if (wcd939x->hph_mode == CLS_H_ULP)
|
||||
hph_mode = 0;
|
||||
|
||||
wcd939x_load_compander_coeff(component, comp_coeff_lsb_reg,
|
||||
comp_coeff_msb_reg, comp_coeff_table[hph_mode],
|
||||
COMP_MAX_COEFF);
|
||||
|
||||
/* Enable compander*/
|
||||
snd_soc_component_update_bits(component,
|
||||
WCD939X_CDC_COMP_CTL_0, comp_en_mask_val, comp_en_mask_val);
|
||||
|
||||
} if (SND_SOC_DAPM_EVENT_OFF(event)) {
|
||||
snd_soc_component_update_bits(component,
|
||||
WCD939X_CDC_COMP_CTL_0, comp_en_mask_val, 0x00);
|
||||
snd_soc_component_update_bits(component,
|
||||
comp_ctl0_reg , 0x01, 0x00);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wcd939x_config_xtalk(struct snd_soc_component *component,
|
||||
int event, int xtalk_indx)
|
||||
{
|
||||
u16 xtalk_sec0 = 0, xtalk_sec1 = 0, xtalk_sec2 = 0, xtalk_sec3 = 0;
|
||||
struct wcd939x_priv *wcd939x = NULL;
|
||||
|
||||
if (!component) {
|
||||
pr_err_ratelimited("%s: Invalid params, NULL component\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
wcd939x = snd_soc_component_get_drvdata(component);
|
||||
|
||||
if (!wcd939x->xtalk_enabled[xtalk_indx])
|
||||
return 0;
|
||||
|
||||
dev_dbg(component->dev, "%s xtalk_indx = %d event = %d\n",
|
||||
__func__, xtalk_indx, event);
|
||||
|
||||
switch(event) {
|
||||
|
||||
case SND_SOC_DAPM_PRE_PMU:
|
||||
|
||||
xtalk_sec0 = WCD939X_HPHL_RX_PATH_SEC0 + (xtalk_indx * WCD939X_XTALK_OFFSET);
|
||||
xtalk_sec1 = WCD939X_HPHL_RX_PATH_SEC1 + (xtalk_indx * WCD939X_XTALK_OFFSET);
|
||||
xtalk_sec2 = WCD939X_HPHL_RX_PATH_SEC2 + (xtalk_indx * WCD939X_XTALK_OFFSET);
|
||||
xtalk_sec3 = WCD939X_HPHL_RX_PATH_SEC3 + (xtalk_indx * WCD939X_XTALK_OFFSET);
|
||||
|
||||
snd_soc_component_update_bits(component, xtalk_sec1, 0xFF, 0xFE);
|
||||
snd_soc_component_update_bits(component, xtalk_sec0, 0x1F, 0x06);
|
||||
snd_soc_component_update_bits(component, xtalk_sec3, 0xFF, 0x4F);
|
||||
snd_soc_component_update_bits(component, xtalk_sec2, 0x1F, 0x11);
|
||||
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
/* enable xtalk for L and R channels*/
|
||||
snd_soc_component_update_bits(component, WCD939X_RX_PATH_CFG2,
|
||||
0x0F, 0x0F);
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMD:
|
||||
/* Disable Xtalk for L and R channels*/
|
||||
snd_soc_component_update_bits(component, WCD939X_RX_PATH_CFG2,
|
||||
0x00, 0x00);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wcd939x_rx_mux(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol,
|
||||
int event)
|
||||
{
|
||||
|
||||
int hph_mode = 0;
|
||||
struct wcd939x_priv *wcd939x = NULL;
|
||||
struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
|
||||
|
||||
wcd939x = snd_soc_component_get_drvdata(component);
|
||||
hph_mode = wcd939x->hph_mode;
|
||||
|
||||
dev_dbg(component->dev, "%s event: %d wshift: %d wname: %s\n",
|
||||
__func__, event, w->shift, w->name);
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_PRE_PMU:
|
||||
dev_err(component->dev, "before rx clk enable %s wname: %s event: %d\n", __func__,
|
||||
w->name, event);
|
||||
wcd939x_rx_clk_enable(component);
|
||||
if (wcd939x->hph_pcm_enabled)
|
||||
wcd939x_config_power_mode(component, event, w->shift, hph_mode);
|
||||
wcd939x_config_compander(component, event, w->shift);
|
||||
wcd939x_config_xtalk(component, event, w->shift);
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
wcd939x_config_xtalk(component, event, w->shift);
|
||||
/*TBD: need to revisit , for both L & R we are updating, but in QCRG only once*/
|
||||
if (wcd939x->hph_pcm_enabled)
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(TOP_CFG0, HPH_DAC_RATE_SEL, 0x1));
|
||||
wcd939x_enable_hph_pcm_index(component, event, w->shift);
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMD:
|
||||
dev_err(component->dev, "%s wname: %s event: %d\n", __func__,
|
||||
w->name, event);
|
||||
wcd939x_config_xtalk(component, event, w->shift);
|
||||
wcd939x_config_compander(component, event, w->shift);
|
||||
wcd939x_rx_clk_disable(component);
|
||||
break;
|
||||
|
||||
@@ -670,37 +1139,42 @@ static int wcd939x_codec_hphl_dac_event(struct snd_soc_dapm_widget *w,
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_PRE_PMU:
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(CDC_DIG_CLK_CTL, RXD0_CLK_EN, 0x01));
|
||||
if (!wcd939x->hph_pcm_enabled)
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(RDAC_CLK_CTL1, OPAMP_CHOP_CLK_EN, 0x00));
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(CDC_HPH_GAIN_CTL, HPHL_RX_EN, 0x01));
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(RDAC_CLK_CTL1, OPAMP_CHOP_CLK_EN, 0x00));
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(RDAC_HD2_CTL_L, HD2_RES_DIV_CTL_L, 0x0f));
|
||||
if (wcd939x->comp1_enable) {
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(RDAC_HD2_CTL_L, HD2_RES_DIV_CTL_L, 0x1D));
|
||||
if (!wcd939x->hph_pcm_enabled) {
|
||||
if (wcd939x->comp1_enable) {
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(CDC_COMP_CTL_0, HPHL_COMP_EN, 0x01));
|
||||
|
||||
/* 5msec compander delay as per HW requirement */
|
||||
if (!wcd939x->comp2_enable ||
|
||||
(snd_soc_component_read(component,
|
||||
WCD939X_CDC_COMP_CTL_0) & 0x01))
|
||||
usleep_range(5000, 5010);
|
||||
snd_soc_component_update_bits(component,
|
||||
/* 5msec compander delay as per HW requirement */
|
||||
if (!wcd939x->comp2_enable ||
|
||||
(snd_soc_component_read(component,
|
||||
WCD939X_CDC_COMP_CTL_0) & 0x01))
|
||||
usleep_range(5000, 5010);
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(HPH_TIMER1, AUTOCHOP_TIMER_CTL_EN, 0x00));
|
||||
} else {
|
||||
snd_soc_component_update_bits(component,
|
||||
} else {
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(CDC_COMP_CTL_0, HPHL_COMP_EN, 0x00));
|
||||
snd_soc_component_update_bits(component,
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(L_EN, GAIN_SOURCE_SEL, 0x01));
|
||||
}
|
||||
}
|
||||
if (wcd939x->hph_pcm_enabled)
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(HPH_TIMER1, AUTOCHOP_TIMER_CTL_EN, 0x00));
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMD:
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(RDAC_HD2_CTL_L, HD2_RES_DIV_CTL_L, 0x01));
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(RDAC_HD2_CTL_R, HD2_RES_DIV_CTL_R, 0x01));
|
||||
REG_FIELD_VALUE(CDC_HPH_GAIN_CTL, HPHL_RX_EN, 0x00));
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -719,36 +1193,39 @@ static int wcd939x_codec_hphr_dac_event(struct snd_soc_dapm_widget *w,
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_PRE_PMU:
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(CDC_DIG_CLK_CTL, RXD1_CLK_EN, 0x01));
|
||||
if (!wcd939x->hph_pcm_enabled)
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(RDAC_CLK_CTL1, OPAMP_CHOP_CLK_EN, 0x00));
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(CDC_HPH_GAIN_CTL, HPHR_RX_EN, 0x01));
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(RDAC_CLK_CTL1, OPAMP_CHOP_CLK_EN, 0x00));
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(RDAC_HD2_CTL_R, HD2_RES_DIV_CTL_R, 0x02));
|
||||
if (wcd939x->comp2_enable) {
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(RDAC_HD2_CTL_R, HD2_RES_DIV_CTL_R, 0x1D));
|
||||
if (!wcd939x->hph_pcm_enabled) {
|
||||
if (wcd939x->comp1_enable) {
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(CDC_COMP_CTL_0, HPHR_COMP_EN, 0x01));
|
||||
/* 5msec compander delay as per HW requirement */
|
||||
if (!wcd939x->comp1_enable ||
|
||||
(snd_soc_component_read(component,
|
||||
WCD939X_CDC_COMP_CTL_0) & 0x02))
|
||||
/* 5msec compander delay as per HW requirement */
|
||||
if (!wcd939x->comp2_enable ||
|
||||
(snd_soc_component_read(component,
|
||||
WCD939X_CDC_COMP_CTL_0) & 0x02))
|
||||
usleep_range(5000, 5010);
|
||||
snd_soc_component_update_bits(component,
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(HPH_TIMER1, AUTOCHOP_TIMER_CTL_EN, 0x00));
|
||||
} else {
|
||||
snd_soc_component_update_bits(component,
|
||||
} else {
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(CDC_COMP_CTL_0, HPHR_COMP_EN, 0x00));
|
||||
snd_soc_component_update_bits(component,
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(R_EN, GAIN_SOURCE_SEL, 0x01));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMD:
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(RDAC_HD2_CTL_R, HD2_RES_DIV_CTL_R, 0x01));
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(RDAC_HD2_CTL_R, HD2_RES_DIV_CTL_R, 0x01));
|
||||
REG_FIELD_VALUE(CDC_HPH_GAIN_CTL, HPHR_RX_EN, 0x00));
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -836,12 +1313,17 @@ static int wcd939x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
|
||||
wcd_clsh_set_hph_mode(component, CLS_H_HIFI);
|
||||
if (hph_mode == CLS_H_LP || hph_mode == CLS_H_LOHIFI ||
|
||||
hph_mode == CLS_H_ULP) {
|
||||
snd_soc_component_update_bits(component,
|
||||
if (!wcd939x->hph_pcm_enabled)
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(REFBUFF_LP_CTL, PREREF_FILT_BYPASS, 0x01));
|
||||
}
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(HPH, HPHR_REF_ENABLE, 0x01));
|
||||
wcd_clsh_set_hph_mode(component, hph_mode);
|
||||
/* update Mode for LOHIFI */
|
||||
if (hph_mode == CLS_H_LOHIFI)
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(HPH, PWR_LEVEL, 0x00));
|
||||
/* 100 usec delay as per HW requirement */
|
||||
usleep_range(100, 110);
|
||||
set_bit(HPH_PA_DELAY, &wcd939x->status_mask);
|
||||
@@ -862,7 +1344,8 @@ static int wcd939x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
|
||||
if (hph_mode == CLS_H_LP ||
|
||||
hph_mode == CLS_H_LOHIFI ||
|
||||
hph_mode == CLS_H_ULP)
|
||||
snd_soc_component_update_bits(component,
|
||||
if (!wcd939x->hph_pcm_enabled)
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(REFBUFF_LP_CTL, PREREF_FILT_BYPASS, 0x00));
|
||||
clear_bit(HPH_PA_DELAY, &wcd939x->status_mask);
|
||||
}
|
||||
@@ -876,7 +1359,9 @@ static int wcd939x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
|
||||
wcd939x->update_wcd_event(wcd939x->handle,
|
||||
SLV_BOLERO_EVT_RX_MUTE,
|
||||
(WCD_RX2 << 0x10));
|
||||
wcd_enable_irq(&wcd939x->irq_info,
|
||||
/*Enable PDM INT for PDM data path only*/
|
||||
if (!wcd939x->hph_pcm_enabled)
|
||||
wcd_enable_irq(&wcd939x->irq_info,
|
||||
WCD939X_IRQ_HPHR_PDM_WD_INT);
|
||||
break;
|
||||
case SND_SOC_DAPM_PRE_PMD:
|
||||
@@ -971,12 +1456,17 @@ static int wcd939x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
|
||||
wcd_clsh_set_hph_mode(component, CLS_H_HIFI);
|
||||
if (hph_mode == CLS_H_LP || hph_mode == CLS_H_LOHIFI ||
|
||||
hph_mode == CLS_H_ULP) {
|
||||
snd_soc_component_update_bits(component,
|
||||
if (!wcd939x->hph_pcm_enabled)
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(REFBUFF_LP_CTL, PREREF_FILT_BYPASS, 0x01));
|
||||
}
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(HPH, HPHL_REF_ENABLE, 0x01));
|
||||
wcd_clsh_set_hph_mode(component, hph_mode);
|
||||
/* update Mode for LOHIFI */
|
||||
if (hph_mode == CLS_H_LOHIFI)
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(HPH, PWR_LEVEL, 0x00));
|
||||
/* 100 usec delay as per HW requirement */
|
||||
usleep_range(100, 110);
|
||||
set_bit(HPH_PA_DELAY, &wcd939x->status_mask);
|
||||
@@ -997,8 +1487,9 @@ static int wcd939x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
|
||||
if (hph_mode == CLS_H_LP ||
|
||||
hph_mode == CLS_H_LOHIFI ||
|
||||
hph_mode == CLS_H_ULP)
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(REFBUFF_LP_CTL, PREREF_FILT_BYPASS, 0x00));
|
||||
if (!wcd939x->hph_pcm_enabled)
|
||||
snd_soc_component_update_bits(component,
|
||||
REG_FIELD_VALUE(REFBUFF_LP_CTL, PREREF_FILT_BYPASS, 0x00));
|
||||
clear_bit(HPH_PA_DELAY, &wcd939x->status_mask);
|
||||
}
|
||||
snd_soc_component_update_bits(component,
|
||||
@@ -1011,7 +1502,9 @@ static int wcd939x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
|
||||
wcd939x->update_wcd_event(wcd939x->handle,
|
||||
SLV_BOLERO_EVT_RX_MUTE,
|
||||
(WCD_RX1 << 0x10));
|
||||
wcd_enable_irq(&wcd939x->irq_info,
|
||||
/*Enable PDM INT for PDM data path only*/
|
||||
if (!wcd939x->hph_pcm_enabled)
|
||||
wcd_enable_irq(&wcd939x->irq_info,
|
||||
WCD939X_IRQ_HPHL_PDM_WD_INT);
|
||||
break;
|
||||
case SND_SOC_DAPM_PRE_PMD:
|
||||
@@ -1185,14 +1678,22 @@ static int wcd939x_enable_rx1(struct snd_soc_dapm_widget *w,
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_PRE_PMU:
|
||||
wcd939x_rx_connect_port(component, HPH_L, true);
|
||||
if (wcd939x->comp1_enable)
|
||||
wcd939x_rx_connect_port(component, COMP_L, true);
|
||||
if (wcd939x->hph_pcm_enabled)
|
||||
wcd939x_rx_connect_port(component, HIFI_PCM_L, true);
|
||||
else {
|
||||
wcd939x_rx_connect_port(component, HPH_L, true);
|
||||
if (wcd939x->comp1_enable)
|
||||
wcd939x_rx_connect_port(component, COMP_L, true);
|
||||
}
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMD:
|
||||
wcd939x_rx_connect_port(component, HPH_L, false);
|
||||
if (wcd939x->comp1_enable)
|
||||
wcd939x_rx_connect_port(component, COMP_L, false);
|
||||
if (wcd939x->hph_pcm_enabled)
|
||||
wcd939x_rx_connect_port(component, HIFI_PCM_L, false);
|
||||
else {
|
||||
wcd939x_rx_connect_port(component, HPH_L, false);
|
||||
if (wcd939x->comp1_enable)
|
||||
wcd939x_rx_connect_port(component, COMP_L, false);
|
||||
}
|
||||
break;
|
||||
};
|
||||
|
||||
@@ -1211,14 +1712,22 @@ static int wcd939x_enable_rx2(struct snd_soc_dapm_widget *w,
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_PRE_PMU:
|
||||
wcd939x_rx_connect_port(component, HPH_R, true);
|
||||
if (wcd939x->comp2_enable)
|
||||
wcd939x_rx_connect_port(component, COMP_R, true);
|
||||
if (wcd939x->hph_pcm_enabled)
|
||||
wcd939x_rx_connect_port(component, HIFI_PCM_R, true);
|
||||
else {
|
||||
wcd939x_rx_connect_port(component, HPH_R, true);
|
||||
if (wcd939x->comp2_enable)
|
||||
wcd939x_rx_connect_port(component, COMP_R, true);
|
||||
}
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMD:
|
||||
wcd939x_rx_connect_port(component, HPH_R, false);
|
||||
if (wcd939x->comp2_enable)
|
||||
wcd939x_rx_connect_port(component, COMP_R, false);
|
||||
if (wcd939x->hph_pcm_enabled)
|
||||
wcd939x_rx_connect_port(component, HIFI_PCM_R, false);
|
||||
else {
|
||||
wcd939x_rx_connect_port(component, HPH_R, false);
|
||||
if (wcd939x->comp2_enable)
|
||||
wcd939x_rx_connect_port(component, COMP_R, false);
|
||||
}
|
||||
break;
|
||||
};
|
||||
|
||||
@@ -2041,6 +2550,7 @@ static int wcd939x_event_notify(struct notifier_block *block,
|
||||
{
|
||||
u16 event = (val & 0xffff);
|
||||
int ret = 0;
|
||||
int rx_clk_type;
|
||||
struct wcd939x_priv *wcd939x = dev_get_drvdata((struct device *)data);
|
||||
struct snd_soc_component *component = wcd939x->component;
|
||||
struct wcd_mbhc *mbhc;
|
||||
@@ -2126,6 +2636,21 @@ static int wcd939x_event_notify(struct notifier_block *block,
|
||||
snd_soc_component_update_bits(component,
|
||||
WCD939X_TOP_CLK_CFG, 0x06,
|
||||
((val >> 0x10) << 0x01));
|
||||
|
||||
rx_clk_type = (val >> 0x10);
|
||||
|
||||
switch(rx_clk_type) {
|
||||
case RX_CLK_12P288MHZ:
|
||||
wcd939x->rx_clk_config = RX_CLK_12P288MHZ;
|
||||
break;
|
||||
case RX_CLK_11P2896MHZ:
|
||||
wcd939x->rx_clk_config = RX_CLK_11P2896MHZ;
|
||||
break;
|
||||
default:
|
||||
wcd939x->rx_clk_config = RX_CLK_9P6MHZ;
|
||||
break;
|
||||
}
|
||||
dev_dbg(component->dev, "%s: rx clk config %d\n", __func__, wcd939x->rx_clk_config);
|
||||
break;
|
||||
default:
|
||||
dev_dbg(component->dev, "%s: invalid event %d\n", __func__, event);
|
||||
@@ -2970,6 +3495,19 @@ static const struct snd_kcontrol_new wcd939x_snd_controls[] = {
|
||||
SOC_SINGLE_TLV("ADC4 Volume", WCD939X_TX_CH4, 0, 20, 0,
|
||||
analog_gain),
|
||||
|
||||
SOC_SINGLE_EXT("HPHL Compander", SND_SOC_NOPM, WCD939X_HPHL, 1, 0,
|
||||
wcd939x_hph_compander_get, wcd939x_hph_compander_put),
|
||||
SOC_SINGLE_EXT("HPHR Compander", SND_SOC_NOPM, WCD939X_HPHR, 1, 0,
|
||||
wcd939x_hph_compander_get, wcd939x_hph_compander_put),
|
||||
|
||||
SOC_SINGLE_EXT("HPHL XTALK", SND_SOC_NOPM, WCD939X_HPHL, 1, 0,
|
||||
wcd939x_hph_xtalk_get, wcd939x_hph_xtalk_put),
|
||||
SOC_SINGLE_EXT("HPHR XTALK", SND_SOC_NOPM, WCD939X_HPHR, 1, 0,
|
||||
wcd939x_hph_xtalk_get, wcd939x_hph_xtalk_put),
|
||||
|
||||
SOC_SINGLE_EXT("HPH PCM Enable", SND_SOC_NOPM, 0, 1, 0,
|
||||
wcd939x_hph_pcm_enable_get, wcd939x_hph_pcm_enable_put),
|
||||
|
||||
SOC_ENUM_EXT("ADC1 ChMap", tx_master_ch_enum,
|
||||
wcd939x_tx_master_ch_get, wcd939x_tx_master_ch_put),
|
||||
SOC_ENUM_EXT("ADC2 ChMap", tx_master_ch_enum,
|
||||
@@ -3158,19 +3696,19 @@ static const struct snd_kcontrol_new rx_rdac3_mux =
|
||||
static const char * const rx1_mux_text[] = {
|
||||
"ZERO", "RX1 MUX"
|
||||
};
|
||||
static const struct soc_enum rx_rx1_enum =
|
||||
static const struct soc_enum rx1_enum =
|
||||
SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, 0, rx1_mux_text);
|
||||
static const struct snd_kcontrol_new rx_rx1_mux =
|
||||
SOC_DAPM_ENUM("RX1 MUX Mux", rx_rx1_enum);
|
||||
static const struct snd_kcontrol_new rx1_mux =
|
||||
SOC_DAPM_ENUM("RX1 MUX Mux", rx1_enum);
|
||||
|
||||
|
||||
static const char * const rx2_mux_text[] = {
|
||||
"ZERO", "RX2 MUX"
|
||||
};
|
||||
static const struct soc_enum rx_rx2_enum =
|
||||
static const struct soc_enum rx2_enum =
|
||||
SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, 0, rx2_mux_text);
|
||||
static const struct snd_kcontrol_new rx_rx2_mux =
|
||||
SOC_DAPM_ENUM("RX2 MUX Mux", rx_rx2_enum);
|
||||
static const struct snd_kcontrol_new rx2_mux =
|
||||
SOC_DAPM_ENUM("RX2 MUX Mux", rx2_enum);
|
||||
|
||||
static const struct snd_soc_dapm_widget wcd939x_dapm_widgets[] = {
|
||||
|
||||
@@ -3401,11 +3939,12 @@ static const struct snd_soc_dapm_widget wcd939x_dapm_widgets[] = {
|
||||
|
||||
SND_SOC_DAPM_MUX("RDAC3_MUX", SND_SOC_NOPM, 0, 0, &rx_rdac3_mux),
|
||||
|
||||
SND_SOC_DAPM_MUX_E("RX1 MUX", SND_SOC_NOPM, WCD_RX1, 0, &rx_rx1_mux,
|
||||
wcd939x_rx_mux, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
|
||||
|
||||
SND_SOC_DAPM_MUX_E("RX2 MUX", SND_SOC_NOPM, WCD_RX2, 0, &rx_rx2_mux,
|
||||
wcd939x_rx_mux, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
|
||||
SND_SOC_DAPM_MUX_E("RX1 MUX", SND_SOC_NOPM, WCD_RX1, 0, &rx1_mux,
|
||||
wcd939x_rx_mux, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU
|
||||
| SND_SOC_DAPM_POST_PMD),
|
||||
SND_SOC_DAPM_MUX_E("RX2 MUX", SND_SOC_NOPM, WCD_RX2, 0, &rx2_mux,
|
||||
wcd939x_rx_mux, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU
|
||||
| SND_SOC_DAPM_POST_PMD),
|
||||
|
||||
SND_SOC_DAPM_MIXER_E("RX1", SND_SOC_NOPM, 0, 0, NULL, 0,
|
||||
wcd939x_enable_rx1, SND_SOC_DAPM_PRE_PMU |
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
#ifndef _PINEAPPLE_PORT_CONFIG
|
||||
@@ -56,7 +56,7 @@ static struct port_params rx_frame_params_dsd[SWR_MSTR_PORT_LEN] = {
|
||||
{3, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 3, 0, 0x00, 0x00}, /* DSD */
|
||||
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, /* GPPO */
|
||||
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, /* HAPT */
|
||||
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, /* HIFI */
|
||||
{49, 0, 0, 0, 15, 24, 1, 0, 1, 0x00, 0x01}, /* HIFI */
|
||||
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, /* HPHT */
|
||||
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, /* CMPT */
|
||||
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, /* IPCM */
|
||||
@@ -65,14 +65,14 @@ static struct port_params rx_frame_params_dsd[SWR_MSTR_PORT_LEN] = {
|
||||
/* Headset + PCM Haptics */
|
||||
static struct port_params rx_frame_params_default[SWR_MSTR_PORT_LEN] = {
|
||||
{3, 0, 0, 0xFF, 0xFF, 1, 0xFF, 0xFF, 1, 0x00, 0x00}, /* HPH/EAR */
|
||||
{31, 0, 0, 3, 6, 7, 0, 0xFF, 0, 0x00, 0x02}, /* HPH_CLH */
|
||||
{63, 0, 0, 3, 6, 7, 0, 0xFF, 0, 0x00, 0x02}, /* HPH_CLH */
|
||||
{31, 11, 11, 0xFF, 0xFF, 4, 1, 0xFF, 0, 0x00, 0x02}, /* HPH_CMP */
|
||||
{7, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* LO/AUX */
|
||||
{0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0x00, 0x00}, /* DSD */
|
||||
{0x18F, 0, 0, 0x8, 0x8, 0x0F, 0x00, 0, 0, 0x00, 0x01}, /* PCM_OUT */
|
||||
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, /* GPPO */
|
||||
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, /* HAPT */
|
||||
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, /* HIFI */
|
||||
{49, 0, 0, 0, 15, 24, 1, 0, 1, 0x00, 0x01}, /* HIFI */
|
||||
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, /* HPHT */
|
||||
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, /* CMPT */
|
||||
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, /* IPCM */
|
||||
@@ -89,7 +89,7 @@ static struct port_params rx_frame_params_44p1KHz[SWR_MSTR_PORT_LEN] = {
|
||||
{0x1FF, 0, 0, 0x8, 0x8, 0x0F, 0, 0, 0, 0x00, 0x01}, /* PCM_OUT */
|
||||
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, /* GPPO */
|
||||
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, /* HAPT */
|
||||
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, /* HIFI */
|
||||
{63, 0, 0, 0, 15, 31, 1, 0, 1, 0x00, 0x01}, /* HIFI */
|
||||
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, /* HPHT */
|
||||
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, /* CMPT */
|
||||
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, /* IPCM */
|
||||
|
@@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2016-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/clk.h>
|
||||
@@ -213,6 +213,9 @@ static void msm_set_upd_config(struct snd_soc_pcm_runtime *rtd)
|
||||
"wsa-codec.1");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
pr_err("%s wsa_max_devs are NULL\n", __func__);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
component = snd_soc_rtdcom_lookup(rtd, WCD939X_DRV_NAME);
|
||||
|
@@ -1,6 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2012-2014, 2017-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
@@ -137,6 +138,20 @@ load_adsp:
|
||||
{
|
||||
adsp_state = spf_core_is_apm_ready();
|
||||
if (adsp_state == SPF_SUBSYS_DOWN) {
|
||||
if (!priv->adsp_fw_name) {
|
||||
dev_info(&pdev->dev, "%s: Load default ADSP\n",
|
||||
__func__);
|
||||
} else {
|
||||
dev_info(&pdev->dev, "%s: Load ADSP with fw name %s\n",
|
||||
__func__, priv->adsp_fw_name);
|
||||
rc = rproc_set_firmware(priv->pil_h,
|
||||
priv->adsp_fw_name);
|
||||
if (rc) {
|
||||
dev_err(&pdev->dev, "%s: rproc set firmware failed,\n",
|
||||
__func__);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
rc = rproc_boot(priv->pil_h);
|
||||
if (rc) {
|
||||
dev_err(&pdev->dev, "%s: pil get failed,\n",
|
||||
@@ -144,8 +159,8 @@ load_adsp:
|
||||
goto fail;
|
||||
}
|
||||
} else if (adsp_state == SPF_SUBSYS_LOADED) {
|
||||
dev_dbg(&pdev->dev,
|
||||
"%s: ADSP state = %x\n", __func__, adsp_state);
|
||||
dev_dbg(&pdev->dev,
|
||||
"%s: ADSP state = %x\n", __func__, adsp_state);
|
||||
}
|
||||
|
||||
dev_dbg(&pdev->dev, "%s: Q6/ADSP image is loaded\n", __func__);
|
||||
@@ -409,6 +424,8 @@ static int adsp_loader_probe(struct platform_device *pdev)
|
||||
goto wqueue;
|
||||
}
|
||||
memcpy(&adsp_var_idx, buf, len);
|
||||
dev_info(&pdev->dev, "%s: adsp variant fuse reg value: 0x%x\n",
|
||||
__func__, adsp_var_idx);
|
||||
kfree(buf);
|
||||
|
||||
/* Get count of fw images */
|
||||
|
@@ -444,11 +444,12 @@ int msm_audio_get_phy_addr(int fd, dma_addr_t *paddr, size_t *pa_len)
|
||||
}
|
||||
EXPORT_SYMBOL(msm_audio_get_phy_addr);
|
||||
|
||||
int msm_audio_set_hyp_assign(int fd, bool assign)
|
||||
static int msm_audio_set_hyp_assign(int fd, bool assign)
|
||||
{
|
||||
struct msm_audio_fd_data *msm_audio_fd_data = NULL;
|
||||
int status = -EINVAL;
|
||||
pr_debug("%s, fd %d\n", __func__, fd);
|
||||
|
||||
mutex_lock(&(msm_audio_ion_fd_list.list_mutex));
|
||||
list_for_each_entry(msm_audio_fd_data,
|
||||
&msm_audio_ion_fd_list.fd_list, list) {
|
||||
@@ -577,7 +578,8 @@ static int msm_audio_ion_free(struct dma_buf *dma_buf, struct msm_audio_ion_priv
|
||||
return 0;
|
||||
}
|
||||
|
||||
int msm_audio_hyp_unassign(struct msm_audio_fd_data *msm_audio_fd_data) {
|
||||
static int msm_audio_hyp_unassign(struct msm_audio_fd_data *msm_audio_fd_data)
|
||||
{
|
||||
int ret = 0;
|
||||
int dest_perms_unmap[1] = {PERM_READ | PERM_WRITE | PERM_EXEC};
|
||||
int source_vm_unmap[3] = {VMID_LPASS, VMID_ADSP_HEAP, VMID_HLOS};
|
||||
|
@@ -1,5 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. */
|
||||
/* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.*/
|
||||
|
||||
#ifndef __AUDIO_CODEC_PORT_TYPES_H
|
||||
#define __AUDIO_CODEC_PORT_TYPES_H
|
||||
@@ -93,5 +94,6 @@
|
||||
#define SWRM_TX3_CH3 56
|
||||
#define SWRM_TX3_CH4 57
|
||||
#define SWRM_TX_PCM_IN 58
|
||||
|
||||
#define HIFI_PCM_L 59
|
||||
#define HIFI_PCM_R 60
|
||||
#endif /* __AUDIO_CODEC_PORT_TYPES_H */
|
||||
|
@@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2015-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/irq.h>
|
||||
@@ -800,19 +800,9 @@ static int swrm_pcm_port_config(struct swr_mstr_ctrl *swrm, u8 port_num,
|
||||
reg_addr = ((dir) ? SWRM_DIN_DP_PCM_PORT_CTRL(port_num) : \
|
||||
SWRM_DOUT_DP_PCM_PORT_CTRL(port_num));
|
||||
reg_val = enable ? 0x3 : 0x0;
|
||||
if (enable) {
|
||||
if (swrm->pcm_enable_count == 0)
|
||||
swr_master_write(swrm, reg_addr, reg_val);
|
||||
swrm->pcm_enable_count++;
|
||||
} else {
|
||||
if (swrm->pcm_enable_count > 0)
|
||||
swrm->pcm_enable_count--;
|
||||
if (swrm->pcm_enable_count == 0)
|
||||
swr_master_write(swrm, reg_addr, reg_val);
|
||||
}
|
||||
dev_dbg(swrm->dev, "%s : pcm port %s, reg_val = %d, for addr %x, pcm_enable_cnt:%d\n",
|
||||
__func__, enable ? "Enabled" : "disabled", reg_val, reg_addr,
|
||||
swrm->pcm_enable_count);
|
||||
swr_master_write(swrm, reg_addr, reg_val);
|
||||
dev_dbg(swrm->dev, "%s : pcm port %s, reg_val = %d, for addr %x\n",
|
||||
__func__, enable ? "Enabled" : "disabled", reg_val, reg_addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1710,8 +1700,6 @@ static int swrm_slvdev_datapath_control(struct swr_master *master, bool enable)
|
||||
}
|
||||
clear_bit(DISABLE_PENDING, &swrm->port_req_pending);
|
||||
swrm_cleanup_disabled_port_reqs(master);
|
||||
/* reset enable_count to 0 in SSR if master is already down */
|
||||
swrm->pcm_enable_count = 0;
|
||||
if (!swrm_is_port_en(master)) {
|
||||
dev_dbg(&master->dev, "%s: pm_runtime auto suspend triggered\n",
|
||||
__func__);
|
||||
@@ -2846,7 +2834,7 @@ static int swrm_probe(struct platform_device *pdev)
|
||||
dev_err(swrm->dev, "missing port mapping\n");
|
||||
goto err_pdata_fail;
|
||||
}
|
||||
swrm->pcm_enable_count = 0;
|
||||
|
||||
map_length = map_size / (3 * sizeof(u32));
|
||||
if (num_ports > SWR_MSTR_PORT_LEN) {
|
||||
dev_err(&pdev->dev, "%s:invalid number of swr ports\n",
|
||||
|
@@ -1,6 +1,7 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _SWR_WCD_CTRL_H
|
||||
@@ -185,7 +186,6 @@ struct swr_mstr_ctrl {
|
||||
struct clk *lpass_core_hw_vote;
|
||||
struct clk *lpass_core_audio;
|
||||
u8 num_usecase;
|
||||
u32 pcm_enable_count;
|
||||
u32 swr_irq_wakeup_capable;
|
||||
int hw_core_clk_en;
|
||||
int aud_core_clk_en;
|
||||
|
In neuem Issue referenzieren
Einen Benutzer sperren