Merge commit '33ea77356f47c6c596c8505ca90307fc1245ef3f' into audio-kernel-5-4.lnx.1.0
Change-Id: Iacb389506a643a1ac70a3d51c2dfc1eeb47f690c
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _BENGAL_PORT_CONFIG
|
#ifndef _BENGAL_PORT_CONFIG
|
||||||
@@ -21,6 +21,15 @@ static struct port_params rx_frame_params_default[SWR_MSTR_PORT_LEN] = {
|
|||||||
{0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0},
|
{0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct port_params rx_frame_params_rouleur[SWR_MSTR_PORT_LEN] = {
|
||||||
|
{3, 0, 0, 0xFF, 0xFF, 1, 0xFF, 0xFF, 1},
|
||||||
|
{31, 0, 0, 3, 6, 7, 0, 0xFF, 0},
|
||||||
|
{31, 1, 0, 0xFF, 0xFF, 4, 1, 0xFF, 0},
|
||||||
|
{7, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0},
|
||||||
|
{0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0},
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
static struct port_params rx_frame_params_dsd[SWR_MSTR_PORT_LEN] = {
|
static struct port_params rx_frame_params_dsd[SWR_MSTR_PORT_LEN] = {
|
||||||
{3, 0, 0, 0xFF, 0xFF, 1, 0xFF, 0xFF, 1},
|
{3, 0, 0, 0xFF, 0xFF, 1, 0xFF, 0xFF, 1},
|
||||||
{31, 0, 0, 3, 6, 7, 0, 0xFF, 0},
|
{31, 0, 0, 3, 6, 7, 0, 0xFF, 0},
|
||||||
@@ -42,4 +51,9 @@ static struct swr_mstr_port_map sm_port_map[] = {
|
|||||||
{RX_MACRO, SWR_UC1, rx_frame_params_dsd},
|
{RX_MACRO, SWR_UC1, rx_frame_params_dsd},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct swr_mstr_port_map sm_port_map_rouleur[] = {
|
||||||
|
{VA_MACRO, SWR_UC0, tx_frame_params_default},
|
||||||
|
{RX_MACRO, SWR_UC0, rx_frame_params_rouleur},
|
||||||
|
{RX_MACRO, SWR_UC1, rx_frame_params_dsd},
|
||||||
|
};
|
||||||
#endif /* _BENGAL_PORT_CONFIG */
|
#endif /* _BENGAL_PORT_CONFIG */
|
||||||
|
128
asoc/bengal.c
128
asoc/bengal.c
@@ -59,10 +59,12 @@
|
|||||||
|
|
||||||
#define WCD9XXX_MBHC_DEF_RLOADS 5
|
#define WCD9XXX_MBHC_DEF_RLOADS 5
|
||||||
#define WCD9XXX_MBHC_DEF_BUTTONS 8
|
#define WCD9XXX_MBHC_DEF_BUTTONS 8
|
||||||
|
#define ROULEUR_MBHC_DEF_BUTTONS 5
|
||||||
#define CODEC_EXT_CLK_RATE 9600000
|
#define CODEC_EXT_CLK_RATE 9600000
|
||||||
#define ADSP_STATE_READY_TIMEOUT_MS 3000
|
#define ADSP_STATE_READY_TIMEOUT_MS 3000
|
||||||
#define DEV_NAME_STR_LEN 32
|
#define DEV_NAME_STR_LEN 32
|
||||||
#define WCD_MBHC_HS_V_MAX 1600
|
#define WCD_MBHC_HS_V_MAX 1600
|
||||||
|
#define ROULEUR_MBHC_HS_V_MAX 1700
|
||||||
|
|
||||||
#define TDM_CHANNEL_MAX 8
|
#define TDM_CHANNEL_MAX 8
|
||||||
#define DEV_NAME_STR_LEN 32
|
#define DEV_NAME_STR_LEN 32
|
||||||
@@ -555,6 +557,7 @@ static int dmic_0_1_gpio_cnt;
|
|||||||
static int dmic_2_3_gpio_cnt;
|
static int dmic_2_3_gpio_cnt;
|
||||||
|
|
||||||
static void *def_wcd_mbhc_cal(void);
|
static void *def_wcd_mbhc_cal(void);
|
||||||
|
static void *def_rouleur_mbhc_cal(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Need to report LINEIN
|
* Need to report LINEIN
|
||||||
@@ -4259,6 +4262,9 @@ static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd)
|
|||||||
struct snd_soc_dapm_context *dapm;
|
struct snd_soc_dapm_context *dapm;
|
||||||
struct snd_card *card;
|
struct snd_card *card;
|
||||||
struct snd_info_entry *entry;
|
struct snd_info_entry *entry;
|
||||||
|
struct platform_device *pdev = NULL;
|
||||||
|
int i = 0;
|
||||||
|
char *data = NULL;
|
||||||
struct msm_asoc_mach_data *pdata =
|
struct msm_asoc_mach_data *pdata =
|
||||||
snd_soc_card_get_drvdata(rtd->card);
|
snd_soc_card_get_drvdata(rtd->card);
|
||||||
|
|
||||||
@@ -4305,8 +4311,38 @@ static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd)
|
|||||||
|
|
||||||
snd_soc_dapm_sync(dapm);
|
snd_soc_dapm_sync(dapm);
|
||||||
|
|
||||||
bolero_set_port_map(component, ARRAY_SIZE(sm_port_map),
|
for (i = 0; i < rtd->card->num_aux_devs; i++)
|
||||||
|
{
|
||||||
|
if (msm_aux_dev[i].name != NULL ) {
|
||||||
|
if (strstr(msm_aux_dev[i].name, "wsa"))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msm_aux_dev[i].codec_of_node) {
|
||||||
|
pdev = of_find_device_by_node(
|
||||||
|
msm_aux_dev[i].codec_of_node);
|
||||||
|
|
||||||
|
if (pdev)
|
||||||
|
data = (char*) of_device_get_match_data(
|
||||||
|
&pdev->dev);
|
||||||
|
if (data != NULL) {
|
||||||
|
if (!strncmp(data, "wcd937x",
|
||||||
|
sizeof("wcd937x"))) {
|
||||||
|
bolero_set_port_map(component,
|
||||||
|
ARRAY_SIZE(sm_port_map),
|
||||||
sm_port_map);
|
sm_port_map);
|
||||||
|
break;
|
||||||
|
} else if (!strncmp( data, "rouleur",
|
||||||
|
sizeof("rouleur"))) {
|
||||||
|
bolero_set_port_map(component,
|
||||||
|
ARRAY_SIZE(sm_port_map_rouleur),
|
||||||
|
sm_port_map_rouleur);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
card = rtd->card->snd_card;
|
card = rtd->card->snd_card;
|
||||||
if (!pdata->codec_root) {
|
if (!pdata->codec_root) {
|
||||||
entry = snd_info_create_subdir(card->module, "codecs",
|
entry = snd_info_create_subdir(card->module, "codecs",
|
||||||
@@ -4356,6 +4392,34 @@ static void *def_wcd_mbhc_cal(void)
|
|||||||
return wcd_mbhc_cal;
|
return wcd_mbhc_cal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void *def_rouleur_mbhc_cal(void)
|
||||||
|
{
|
||||||
|
void *wcd_mbhc_cal;
|
||||||
|
struct wcd_mbhc_btn_detect_cfg *btn_cfg;
|
||||||
|
u16 *btn_high;
|
||||||
|
|
||||||
|
wcd_mbhc_cal = kzalloc(WCD_MBHC_CAL_SIZE(ROULEUR_MBHC_DEF_BUTTONS,
|
||||||
|
WCD9XXX_MBHC_DEF_RLOADS), GFP_KERNEL);
|
||||||
|
if (!wcd_mbhc_cal)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
WCD_MBHC_CAL_PLUG_TYPE_PTR(wcd_mbhc_cal)->v_hs_max =
|
||||||
|
ROULEUR_MBHC_HS_V_MAX;
|
||||||
|
WCD_MBHC_CAL_BTN_DET_PTR(wcd_mbhc_cal)->num_btn =
|
||||||
|
ROULEUR_MBHC_DEF_BUTTONS;
|
||||||
|
btn_cfg = WCD_MBHC_CAL_BTN_DET_PTR(wcd_mbhc_cal);
|
||||||
|
btn_high = ((void *)&btn_cfg->_v_btn_low) +
|
||||||
|
(sizeof(btn_cfg->_v_btn_low[0]) * btn_cfg->num_btn);
|
||||||
|
|
||||||
|
btn_high[0] = 75;
|
||||||
|
btn_high[1] = 150;
|
||||||
|
btn_high[2] = 237;
|
||||||
|
btn_high[3] = 500;
|
||||||
|
btn_high[4] = 500;
|
||||||
|
|
||||||
|
return wcd_mbhc_cal;
|
||||||
|
}
|
||||||
|
|
||||||
/* Digital audio interface glue - connects codec <---> CPU */
|
/* Digital audio interface glue - connects codec <---> CPU */
|
||||||
static struct snd_soc_dai_link msm_common_dai_links[] = {
|
static struct snd_soc_dai_link msm_common_dai_links[] = {
|
||||||
/* FrontEnd DAI Links */
|
/* FrontEnd DAI Links */
|
||||||
@@ -4985,6 +5049,22 @@ static struct snd_soc_dai_link msm_common_misc_fe_dai_links[] = {
|
|||||||
.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
|
.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
|
||||||
.ops = &msm_cdc_dma_be_ops,
|
.ops = &msm_cdc_dma_be_ops,
|
||||||
},
|
},
|
||||||
|
{/* hw:x,39 */
|
||||||
|
.name = MSM_DAILINK_NAME(Compress3),
|
||||||
|
.stream_name = "Compress3",
|
||||||
|
.cpu_dai_name = "MultiMedia10",
|
||||||
|
.platform_name = "msm-compress-dsp",
|
||||||
|
.dynamic = 1,
|
||||||
|
.dpcm_playback = 1,
|
||||||
|
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
|
||||||
|
SND_SOC_DPCM_TRIGGER_POST},
|
||||||
|
.codec_dai_name = "snd-soc-dummy-dai",
|
||||||
|
.codec_name = "snd-soc-dummy",
|
||||||
|
.ignore_suspend = 1,
|
||||||
|
.ignore_pmdown_time = 1,
|
||||||
|
/* this dainlink has playback support */
|
||||||
|
.id = MSM_FRONTEND_DAI_MULTIMEDIA10,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct snd_soc_dai_link msm_common_be_dai_links[] = {
|
static struct snd_soc_dai_link msm_common_be_dai_links[] = {
|
||||||
@@ -5075,6 +5155,33 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = {
|
|||||||
.ignore_suspend = 1,
|
.ignore_suspend = 1,
|
||||||
.ignore_pmdown_time = 1,
|
.ignore_pmdown_time = 1,
|
||||||
},
|
},
|
||||||
|
/* Proxy Tx BACK END DAI Link */
|
||||||
|
{
|
||||||
|
.name = LPASS_BE_PROXY_TX,
|
||||||
|
.stream_name = "Proxy Capture",
|
||||||
|
.cpu_dai_name = "msm-dai-q6-dev.8195",
|
||||||
|
.platform_name = "msm-pcm-routing",
|
||||||
|
.codec_name = "msm-stub-codec.1",
|
||||||
|
.codec_dai_name = "msm-stub-tx",
|
||||||
|
.no_pcm = 1,
|
||||||
|
.dpcm_capture = 1,
|
||||||
|
.id = MSM_BACKEND_DAI_PROXY_TX,
|
||||||
|
.ignore_suspend = 1,
|
||||||
|
},
|
||||||
|
/* Proxy Rx BACK END DAI Link */
|
||||||
|
{
|
||||||
|
.name = LPASS_BE_PROXY_RX,
|
||||||
|
.stream_name = "Proxy Playback",
|
||||||
|
.cpu_dai_name = "msm-dai-q6-dev.8194",
|
||||||
|
.platform_name = "msm-pcm-routing",
|
||||||
|
.codec_name = "msm-stub-codec.1",
|
||||||
|
.codec_dai_name = "msm-stub-rx",
|
||||||
|
.no_pcm = 1,
|
||||||
|
.dpcm_playback = 1,
|
||||||
|
.id = MSM_BACKEND_DAI_PROXY_RX,
|
||||||
|
.ignore_pmdown_time = 1,
|
||||||
|
.ignore_suspend = 1,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
.name = LPASS_BE_USB_AUDIO_RX,
|
.name = LPASS_BE_USB_AUDIO_RX,
|
||||||
.stream_name = "USB Audio Playback",
|
.stream_name = "USB Audio Playback",
|
||||||
@@ -6115,16 +6222,21 @@ static int msm_aux_codec_init(struct snd_soc_component *component)
|
|||||||
}
|
}
|
||||||
|
|
||||||
mbhc_cfg_cal:
|
mbhc_cfg_cal:
|
||||||
|
if (data != NULL) {
|
||||||
|
if (!strncmp(data, "wcd937x", sizeof("wcd937x"))) {
|
||||||
mbhc_calibration = def_wcd_mbhc_cal();
|
mbhc_calibration = def_wcd_mbhc_cal();
|
||||||
if (!mbhc_calibration)
|
if (!mbhc_calibration)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
wcd_mbhc_cfg.calibration = mbhc_calibration;
|
wcd_mbhc_cfg.calibration = mbhc_calibration;
|
||||||
if (data != NULL) {
|
|
||||||
if (!strncmp(data, "wcd937x", sizeof("wcd937x")))
|
|
||||||
ret = wcd937x_mbhc_hs_detect(component, &wcd_mbhc_cfg);
|
ret = wcd937x_mbhc_hs_detect(component, &wcd_mbhc_cfg);
|
||||||
else if (!strncmp( data, "rouleur", sizeof("rouleur")))
|
} else if (!strncmp( data, "rouleur", sizeof("rouleur"))) {
|
||||||
|
mbhc_calibration = def_rouleur_mbhc_cal();
|
||||||
|
if (!mbhc_calibration)
|
||||||
|
return -ENOMEM;
|
||||||
|
wcd_mbhc_cfg.calibration = mbhc_calibration;
|
||||||
ret = rouleur_mbhc_hs_detect(component, &wcd_mbhc_cfg);
|
ret = rouleur_mbhc_hs_detect(component, &wcd_mbhc_cfg);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(component->dev, "%s: mbhc hs detect failed, err:%d\n",
|
dev_err(component->dev, "%s: mbhc hs detect failed, err:%d\n",
|
||||||
@@ -6714,10 +6826,16 @@ static int msm_asoc_machine_probe(struct platform_device *pdev)
|
|||||||
}
|
}
|
||||||
buf = nvmem_cell_read(cell, &len);
|
buf = nvmem_cell_read(cell, &len);
|
||||||
nvmem_cell_put(cell);
|
nvmem_cell_put(cell);
|
||||||
if (IS_ERR_OR_NULL(buf) || len <= 0 || len > sizeof(32)) {
|
if (IS_ERR_OR_NULL(buf)) {
|
||||||
dev_dbg(&pdev->dev, "%s: FAILED to read nvmem cell \n", __func__);
|
dev_dbg(&pdev->dev, "%s: FAILED to read nvmem cell \n", __func__);
|
||||||
goto ret;
|
goto ret;
|
||||||
}
|
}
|
||||||
|
if (len <= 0 || len > sizeof(u32)) {
|
||||||
|
dev_dbg(&pdev->dev, "%s: nvmem cell length out of range: %d\n",
|
||||||
|
__func__, len);
|
||||||
|
kfree(buf);
|
||||||
|
goto ret;
|
||||||
|
}
|
||||||
memcpy(&adsp_var_idx, buf, len);
|
memcpy(&adsp_var_idx, buf, len);
|
||||||
kfree(buf);
|
kfree(buf);
|
||||||
va_disable = adsp_var_idx;
|
va_disable = adsp_var_idx;
|
||||||
|
@@ -600,6 +600,28 @@ int bolero_dmic_clk_enable(struct snd_soc_component *component,
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(bolero_dmic_clk_enable);
|
EXPORT_SYMBOL(bolero_dmic_clk_enable);
|
||||||
|
|
||||||
|
bool bolero_is_va_macro_registered(struct device *dev)
|
||||||
|
{
|
||||||
|
struct bolero_priv *priv;
|
||||||
|
|
||||||
|
if (!dev) {
|
||||||
|
pr_err("%s: dev is null\n", __func__);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!bolero_is_valid_child_dev(dev)) {
|
||||||
|
dev_err(dev, "%s: child device calling is not added yet\n",
|
||||||
|
__func__);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
priv = dev_get_drvdata(dev->parent);
|
||||||
|
if (!priv) {
|
||||||
|
dev_err(dev, "%s: priv is null\n", __func__);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return priv->macros_supported[VA_MACRO];
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(bolero_is_va_macro_registered);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* bolero_register_macro - Registers macro to bolero
|
* bolero_register_macro - Registers macro to bolero
|
||||||
*
|
*
|
||||||
@@ -644,7 +666,6 @@ int bolero_register_macro(struct device *dev, u16 macro_id,
|
|||||||
bolero_mclk_mux_tbl[macro_id][MCLK_MUX0];
|
bolero_mclk_mux_tbl[macro_id][MCLK_MUX0];
|
||||||
if (macro_id == TX_MACRO) {
|
if (macro_id == TX_MACRO) {
|
||||||
priv->macro_params[macro_id].reg_wake_irq = ops->reg_wake_irq;
|
priv->macro_params[macro_id].reg_wake_irq = ops->reg_wake_irq;
|
||||||
priv->macro_params[macro_id].clk_switch = ops->clk_switch;
|
|
||||||
priv->macro_params[macro_id].reg_evt_listener =
|
priv->macro_params[macro_id].reg_evt_listener =
|
||||||
ops->reg_evt_listener;
|
ops->reg_evt_listener;
|
||||||
priv->macro_params[macro_id].clk_enable = ops->clk_enable;
|
priv->macro_params[macro_id].clk_enable = ops->clk_enable;
|
||||||
@@ -661,7 +682,7 @@ int bolero_register_macro(struct device *dev, u16 macro_id,
|
|||||||
priv->num_macros_registered++;
|
priv->num_macros_registered++;
|
||||||
priv->macros_supported[macro_id] = true;
|
priv->macros_supported[macro_id] = true;
|
||||||
|
|
||||||
dev_dbg(dev, "%s: register macro successful:%d\n", macro_id);
|
dev_info(dev, "%s: register macro successful:%d\n", __func__, macro_id);
|
||||||
|
|
||||||
if (priv->num_macros_registered == priv->num_macros) {
|
if (priv->num_macros_registered == priv->num_macros) {
|
||||||
ret = bolero_copy_dais_from_macro(priv);
|
ret = bolero_copy_dais_from_macro(priv);
|
||||||
@@ -719,7 +740,6 @@ void bolero_unregister_macro(struct device *dev, u16 macro_id)
|
|||||||
priv->macro_params[macro_id].dev = NULL;
|
priv->macro_params[macro_id].dev = NULL;
|
||||||
if (macro_id == TX_MACRO) {
|
if (macro_id == TX_MACRO) {
|
||||||
priv->macro_params[macro_id].reg_wake_irq = NULL;
|
priv->macro_params[macro_id].reg_wake_irq = NULL;
|
||||||
priv->macro_params[macro_id].clk_switch = NULL;
|
|
||||||
priv->macro_params[macro_id].reg_evt_listener = NULL;
|
priv->macro_params[macro_id].reg_evt_listener = NULL;
|
||||||
priv->macro_params[macro_id].clk_enable = NULL;
|
priv->macro_params[macro_id].clk_enable = NULL;
|
||||||
}
|
}
|
||||||
@@ -836,6 +856,18 @@ static int bolero_ssr_enable(struct device *dev, void *data)
|
|||||||
BOLERO_MACRO_EVT_CLK_RESET, 0x0);
|
BOLERO_MACRO_EVT_CLK_RESET, 0x0);
|
||||||
}
|
}
|
||||||
trace_printk("%s: clk count reset\n", __func__);
|
trace_printk("%s: clk count reset\n", __func__);
|
||||||
|
|
||||||
|
if (priv->rsc_clk_cb)
|
||||||
|
priv->rsc_clk_cb(priv->clk_dev, BOLERO_MACRO_EVT_SSR_GFMUX_UP);
|
||||||
|
|
||||||
|
for (macro_idx = START_MACRO; macro_idx < MAX_MACRO; macro_idx++) {
|
||||||
|
if (!priv->macro_params[macro_idx].event_handler)
|
||||||
|
continue;
|
||||||
|
priv->macro_params[macro_idx].event_handler(
|
||||||
|
priv->component,
|
||||||
|
BOLERO_MACRO_EVT_PRE_SSR_UP, 0x0);
|
||||||
|
}
|
||||||
|
|
||||||
regcache_cache_only(priv->regmap, false);
|
regcache_cache_only(priv->regmap, false);
|
||||||
mutex_lock(&priv->clk_lock);
|
mutex_lock(&priv->clk_lock);
|
||||||
priv->dev_up = true;
|
priv->dev_up = true;
|
||||||
@@ -1004,40 +1036,6 @@ int bolero_register_wake_irq(struct snd_soc_component *component,
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(bolero_register_wake_irq);
|
EXPORT_SYMBOL(bolero_register_wake_irq);
|
||||||
|
|
||||||
/**
|
|
||||||
* bolero_tx_clk_switch - Switch tx macro clock
|
|
||||||
*
|
|
||||||
* @component: pointer to codec component instance.
|
|
||||||
*
|
|
||||||
* @clk_src: 0 for TX_RCG and 1 for VA_RCG
|
|
||||||
*
|
|
||||||
* Returns 0 on success or -EINVAL on error.
|
|
||||||
*/
|
|
||||||
int bolero_tx_clk_switch(struct snd_soc_component *component, int clk_src)
|
|
||||||
{
|
|
||||||
struct bolero_priv *priv = NULL;
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
if (!component)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
priv = snd_soc_component_get_drvdata(component);
|
|
||||||
if (!priv)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
if (!bolero_is_valid_codec_dev(priv->dev)) {
|
|
||||||
dev_err(component->dev, "%s: invalid codec\n", __func__);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (priv->macro_params[TX_MACRO].clk_switch)
|
|
||||||
ret = priv->macro_params[TX_MACRO].clk_switch(component,
|
|
||||||
clk_src);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(bolero_tx_clk_switch);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* bolero_tx_mclk_enable - Enable/Disable TX Macro mclk
|
* bolero_tx_mclk_enable - Enable/Disable TX Macro mclk
|
||||||
*
|
*
|
||||||
|
@@ -37,11 +37,6 @@ enum {
|
|||||||
BOLERO_ADC_MAX
|
BOLERO_ADC_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
|
||||||
CLK_SRC_TX_RCG = 0,
|
|
||||||
CLK_SRC_VA_RCG,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
BOLERO_MACRO_EVT_RX_MUTE = 1, /* for RX mute/unmute */
|
BOLERO_MACRO_EVT_RX_MUTE = 1, /* for RX mute/unmute */
|
||||||
BOLERO_MACRO_EVT_IMPED_TRUE, /* for imped true */
|
BOLERO_MACRO_EVT_IMPED_TRUE, /* for imped true */
|
||||||
@@ -52,7 +47,9 @@ enum {
|
|||||||
BOLERO_MACRO_EVT_CLK_RESET,
|
BOLERO_MACRO_EVT_CLK_RESET,
|
||||||
BOLERO_MACRO_EVT_REG_WAKE_IRQ,
|
BOLERO_MACRO_EVT_REG_WAKE_IRQ,
|
||||||
BOLERO_MACRO_EVT_RX_COMPANDER_SOFT_RST,
|
BOLERO_MACRO_EVT_RX_COMPANDER_SOFT_RST,
|
||||||
BOLERO_MACRO_EVT_BCS_CLK_OFF
|
BOLERO_MACRO_EVT_BCS_CLK_OFF,
|
||||||
|
BOLERO_MACRO_EVT_SSR_GFMUX_UP,
|
||||||
|
BOLERO_MACRO_EVT_PRE_SSR_UP,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@@ -74,7 +71,6 @@ struct macro_ops {
|
|||||||
int (*set_port_map)(struct snd_soc_component *component, u32 uc,
|
int (*set_port_map)(struct snd_soc_component *component, u32 uc,
|
||||||
u32 size, void *data);
|
u32 size, void *data);
|
||||||
int (*clk_div_get)(struct snd_soc_component *component);
|
int (*clk_div_get)(struct snd_soc_component *component);
|
||||||
int (*clk_switch)(struct snd_soc_component *component, int clk_src);
|
|
||||||
int (*reg_evt_listener)(struct snd_soc_component *component, bool en);
|
int (*reg_evt_listener)(struct snd_soc_component *component, bool en);
|
||||||
int (*clk_enable)(struct snd_soc_component *c, bool en);
|
int (*clk_enable)(struct snd_soc_component *c, bool en);
|
||||||
char __iomem *io_base;
|
char __iomem *io_base;
|
||||||
@@ -87,6 +83,7 @@ typedef int (*rsc_clk_cb_t)(struct device *dev, u16 event);
|
|||||||
#if IS_ENABLED(CONFIG_SND_SOC_BOLERO)
|
#if IS_ENABLED(CONFIG_SND_SOC_BOLERO)
|
||||||
int bolero_register_res_clk(struct device *dev, rsc_clk_cb_t cb);
|
int bolero_register_res_clk(struct device *dev, rsc_clk_cb_t cb);
|
||||||
void bolero_unregister_res_clk(struct device *dev);
|
void bolero_unregister_res_clk(struct device *dev);
|
||||||
|
bool bolero_is_va_macro_registered(struct device *dev);
|
||||||
int bolero_register_macro(struct device *dev, u16 macro_id,
|
int bolero_register_macro(struct device *dev, u16 macro_id,
|
||||||
struct macro_ops *ops);
|
struct macro_ops *ops);
|
||||||
void bolero_unregister_macro(struct device *dev, u16 macro_id);
|
void bolero_unregister_macro(struct device *dev, u16 macro_id);
|
||||||
@@ -100,7 +97,6 @@ void bolero_clear_amic_tx_hold(struct device *dev, u16 adc_n);
|
|||||||
int bolero_runtime_resume(struct device *dev);
|
int bolero_runtime_resume(struct device *dev);
|
||||||
int bolero_runtime_suspend(struct device *dev);
|
int bolero_runtime_suspend(struct device *dev);
|
||||||
int bolero_set_port_map(struct snd_soc_component *component, u32 size, void *data);
|
int bolero_set_port_map(struct snd_soc_component *component, u32 size, void *data);
|
||||||
int bolero_tx_clk_switch(struct snd_soc_component *component, int clk_src);
|
|
||||||
int bolero_register_event_listener(struct snd_soc_component *component,
|
int bolero_register_event_listener(struct snd_soc_component *component,
|
||||||
bool enable);
|
bool enable);
|
||||||
void bolero_wsa_pa_on(struct device *dev);
|
void bolero_wsa_pa_on(struct device *dev);
|
||||||
@@ -118,6 +114,11 @@ static inline void bolero_unregister_res_clk(struct device *dev)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool bolero_is_va_macro_registered(struct device *dev)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static inline int bolero_register_macro(struct device *dev,
|
static inline int bolero_register_macro(struct device *dev,
|
||||||
u16 macro_id,
|
u16 macro_id,
|
||||||
struct macro_ops *ops)
|
struct macro_ops *ops)
|
||||||
@@ -168,12 +169,6 @@ static inline int bolero_set_port_map(struct snd_soc_component *component,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int bolero_tx_clk_switch(struct snd_soc_component *component,
|
|
||||||
int clk_src)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int bolero_register_event_listener(
|
static inline int bolero_register_event_listener(
|
||||||
struct snd_soc_component *component,
|
struct snd_soc_component *component,
|
||||||
bool enable)
|
bool enable)
|
||||||
|
@@ -38,6 +38,7 @@ struct bolero_clk_rsc {
|
|||||||
int reg_seq_en_cnt;
|
int reg_seq_en_cnt;
|
||||||
int va_tx_clk_cnt;
|
int va_tx_clk_cnt;
|
||||||
bool dev_up;
|
bool dev_up;
|
||||||
|
bool dev_up_gfmux;
|
||||||
u32 num_fs_reg;
|
u32 num_fs_reg;
|
||||||
u32 *fs_gen_seq;
|
u32 *fs_gen_seq;
|
||||||
int default_clk_id[MAX_CLK];
|
int default_clk_id[MAX_CLK];
|
||||||
@@ -65,10 +66,14 @@ static int bolero_clk_rsc_cb(struct device *dev, u16 event)
|
|||||||
}
|
}
|
||||||
|
|
||||||
mutex_lock(&priv->rsc_clk_lock);
|
mutex_lock(&priv->rsc_clk_lock);
|
||||||
if (event == BOLERO_MACRO_EVT_SSR_UP)
|
if (event == BOLERO_MACRO_EVT_SSR_UP) {
|
||||||
priv->dev_up = true;
|
priv->dev_up = true;
|
||||||
else if (event == BOLERO_MACRO_EVT_SSR_DOWN)
|
} else if (event == BOLERO_MACRO_EVT_SSR_DOWN) {
|
||||||
priv->dev_up = false;
|
priv->dev_up = false;
|
||||||
|
priv->dev_up_gfmux = false;
|
||||||
|
} else if (event == BOLERO_MACRO_EVT_SSR_GFMUX_UP) {
|
||||||
|
priv->dev_up_gfmux = true;
|
||||||
|
}
|
||||||
mutex_unlock(&priv->rsc_clk_lock);
|
mutex_unlock(&priv->rsc_clk_lock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -282,10 +287,12 @@ static int bolero_clk_rsc_mux1_clk_request(struct bolero_clk_rsc *priv,
|
|||||||
* care in DSP itself
|
* care in DSP itself
|
||||||
*/
|
*/
|
||||||
if (clk_id != VA_CORE_CLK) {
|
if (clk_id != VA_CORE_CLK) {
|
||||||
|
if (priv->dev_up_gfmux) {
|
||||||
iowrite32(0x1, clk_muxsel);
|
iowrite32(0x1, clk_muxsel);
|
||||||
muxsel = ioread32(clk_muxsel);
|
muxsel = ioread32(clk_muxsel);
|
||||||
trace_printk("%s: muxsel value after enable: %d\n",
|
trace_printk("%s: muxsel value after enable: %d\n",
|
||||||
__func__, muxsel);
|
__func__, muxsel);
|
||||||
|
}
|
||||||
bolero_clk_rsc_mux0_clk_request(priv,
|
bolero_clk_rsc_mux0_clk_request(priv,
|
||||||
default_clk_id,
|
default_clk_id,
|
||||||
false);
|
false);
|
||||||
@@ -313,12 +320,14 @@ static int bolero_clk_rsc_mux1_clk_request(struct bolero_clk_rsc *priv,
|
|||||||
* This configuration would be taken
|
* This configuration would be taken
|
||||||
* care in DSP itself.
|
* care in DSP itself.
|
||||||
*/
|
*/
|
||||||
|
if (priv->dev_up_gfmux) {
|
||||||
iowrite32(0x0, clk_muxsel);
|
iowrite32(0x0, clk_muxsel);
|
||||||
muxsel = ioread32(clk_muxsel);
|
muxsel = ioread32(clk_muxsel);
|
||||||
trace_printk("%s: muxsel value after disable: %d\n",
|
trace_printk("%s: muxsel value after disable: %d\n",
|
||||||
__func__, muxsel);
|
__func__, muxsel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (priv->clk[clk_id + NPL_CLK_OFFSET])
|
if (priv->clk[clk_id + NPL_CLK_OFFSET])
|
||||||
clk_disable_unprepare(
|
clk_disable_unprepare(
|
||||||
priv->clk[clk_id + NPL_CLK_OFFSET]);
|
priv->clk[clk_id + NPL_CLK_OFFSET]);
|
||||||
@@ -706,6 +715,7 @@ static int bolero_clk_rsc_probe(struct platform_device *pdev)
|
|||||||
}
|
}
|
||||||
priv->dev = &pdev->dev;
|
priv->dev = &pdev->dev;
|
||||||
priv->dev_up = true;
|
priv->dev_up = true;
|
||||||
|
priv->dev_up_gfmux = true;
|
||||||
mutex_init(&priv->rsc_clk_lock);
|
mutex_init(&priv->rsc_clk_lock);
|
||||||
mutex_init(&priv->fs_gen_lock);
|
mutex_init(&priv->fs_gen_lock);
|
||||||
dev_set_drvdata(&pdev->dev, priv);
|
dev_set_drvdata(&pdev->dev, priv);
|
||||||
|
@@ -387,6 +387,7 @@ enum {
|
|||||||
RX_MACRO_AIF3_PB,
|
RX_MACRO_AIF3_PB,
|
||||||
RX_MACRO_AIF4_PB,
|
RX_MACRO_AIF4_PB,
|
||||||
RX_MACRO_AIF_ECHO,
|
RX_MACRO_AIF_ECHO,
|
||||||
|
RX_MACRO_AIF5_PB,
|
||||||
RX_MACRO_AIF6_PB,
|
RX_MACRO_AIF6_PB,
|
||||||
RX_MACRO_MAX_DAIS,
|
RX_MACRO_MAX_DAIS,
|
||||||
};
|
};
|
||||||
@@ -719,6 +720,20 @@ static struct snd_soc_dai_driver rx_macro_dai[] = {
|
|||||||
},
|
},
|
||||||
.ops = &rx_macro_dai_ops,
|
.ops = &rx_macro_dai_ops,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.name = "rx_macro_rx5",
|
||||||
|
.id = RX_MACRO_AIF5_PB,
|
||||||
|
.playback = {
|
||||||
|
.stream_name = "RX_MACRO_AIF5 Playback",
|
||||||
|
.rates = RX_MACRO_RATES | RX_MACRO_FRAC_RATES,
|
||||||
|
.formats = RX_MACRO_FORMATS,
|
||||||
|
.rate_max = 384000,
|
||||||
|
.rate_min = 8000,
|
||||||
|
.channels_min = 1,
|
||||||
|
.channels_max = 4,
|
||||||
|
},
|
||||||
|
.ops = &rx_macro_dai_ops,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
.name = "rx_macro_rx6",
|
.name = "rx_macro_rx6",
|
||||||
.id = RX_MACRO_AIF6_PB,
|
.id = RX_MACRO_AIF6_PB,
|
||||||
@@ -1138,6 +1153,13 @@ static int rx_macro_get_channel_map(struct snd_soc_dai *dai,
|
|||||||
"%s: dai->id:%d, ch_mask:0x%x, active_ch_cnt:%d active_mask: 0x%x\n",
|
"%s: dai->id:%d, ch_mask:0x%x, active_ch_cnt:%d active_mask: 0x%x\n",
|
||||||
__func__, dai->id, *rx_slot, *rx_num, rx_priv->active_ch_mask[dai->id]);
|
__func__, dai->id, *rx_slot, *rx_num, rx_priv->active_ch_mask[dai->id]);
|
||||||
break;
|
break;
|
||||||
|
case RX_MACRO_AIF5_PB:
|
||||||
|
*rx_slot = 0x1;
|
||||||
|
*rx_num = 0x01;
|
||||||
|
dev_dbg(rx_priv->dev,
|
||||||
|
"%s: dai->id:%d, ch_mask:0x%x, active_ch_cnt:%d\n",
|
||||||
|
__func__, dai->id, *rx_slot, *rx_num);
|
||||||
|
break;
|
||||||
case RX_MACRO_AIF6_PB:
|
case RX_MACRO_AIF6_PB:
|
||||||
*rx_slot = 0x1;
|
*rx_slot = 0x1;
|
||||||
*rx_num = 0x01;
|
*rx_num = 0x01;
|
||||||
@@ -1410,11 +1432,7 @@ static int rx_macro_event_handler(struct snd_soc_component *component,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case BOLERO_MACRO_EVT_SSR_UP:
|
case BOLERO_MACRO_EVT_PRE_SSR_UP:
|
||||||
trace_printk("%s, enter SSR up\n", __func__);
|
|
||||||
rx_priv->dev_up = true;
|
|
||||||
/* reset swr after ssr/pdr */
|
|
||||||
rx_priv->reset_swr = true;
|
|
||||||
/* enable&disable RX_CORE_CLK to reset GFMUX reg */
|
/* enable&disable RX_CORE_CLK to reset GFMUX reg */
|
||||||
ret = bolero_clk_rsc_request_clock(rx_priv->dev,
|
ret = bolero_clk_rsc_request_clock(rx_priv->dev,
|
||||||
rx_priv->default_clk_id,
|
rx_priv->default_clk_id,
|
||||||
@@ -1427,6 +1445,12 @@ static int rx_macro_event_handler(struct snd_soc_component *component,
|
|||||||
bolero_clk_rsc_request_clock(rx_priv->dev,
|
bolero_clk_rsc_request_clock(rx_priv->dev,
|
||||||
rx_priv->default_clk_id,
|
rx_priv->default_clk_id,
|
||||||
RX_CORE_CLK, false);
|
RX_CORE_CLK, false);
|
||||||
|
break;
|
||||||
|
case BOLERO_MACRO_EVT_SSR_UP:
|
||||||
|
trace_printk("%s, enter SSR up\n", __func__);
|
||||||
|
rx_priv->dev_up = true;
|
||||||
|
/* reset swr after ssr/pdr */
|
||||||
|
rx_priv->reset_swr = true;
|
||||||
|
|
||||||
if (rx_priv->swr_ctrl_data)
|
if (rx_priv->swr_ctrl_data)
|
||||||
swrm_wcd_notify(
|
swrm_wcd_notify(
|
||||||
@@ -1709,13 +1733,6 @@ static int rx_macro_config_compander(struct snd_soc_component *component,
|
|||||||
dev_dbg(component->dev, "%s: event %d compander %d, enabled %d\n",
|
dev_dbg(component->dev, "%s: event %d compander %d, enabled %d\n",
|
||||||
__func__, event, comp + 1, rx_priv->comp_enabled[comp]);
|
__func__, event, comp + 1, rx_priv->comp_enabled[comp]);
|
||||||
|
|
||||||
if (!rx_priv->comp_enabled[comp])
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
comp_ctl0_reg = BOLERO_CDC_RX_COMPANDER0_CTL0 +
|
|
||||||
(comp * RX_MACRO_COMP_OFFSET);
|
|
||||||
rx_path_cfg0_reg = BOLERO_CDC_RX_RX0_RX_PATH_CFG0 +
|
|
||||||
(comp * RX_MACRO_RX_PATH_OFFSET);
|
|
||||||
rx_path_cfg3_reg = BOLERO_CDC_RX_RX0_RX_PATH_CFG3 +
|
rx_path_cfg3_reg = BOLERO_CDC_RX_RX0_RX_PATH_CFG3 +
|
||||||
(comp * RX_MACRO_RX_PATH_OFFSET);
|
(comp * RX_MACRO_RX_PATH_OFFSET);
|
||||||
rx0_path_ctl_reg = BOLERO_CDC_RX_RX0_RX_PATH_CTL +
|
rx0_path_ctl_reg = BOLERO_CDC_RX_RX0_RX_PATH_CTL +
|
||||||
@@ -1731,6 +1748,19 @@ static int rx_macro_config_compander(struct snd_soc_component *component,
|
|||||||
else
|
else
|
||||||
val = 0x00;
|
val = 0x00;
|
||||||
|
|
||||||
|
if (SND_SOC_DAPM_EVENT_ON(event))
|
||||||
|
snd_soc_component_update_bits(component, rx_path_cfg3_reg,
|
||||||
|
0x03, val);
|
||||||
|
if (SND_SOC_DAPM_EVENT_OFF(event))
|
||||||
|
snd_soc_component_update_bits(component, rx_path_cfg3_reg,
|
||||||
|
0x03, 0x03);
|
||||||
|
if (!rx_priv->comp_enabled[comp])
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
comp_ctl0_reg = BOLERO_CDC_RX_COMPANDER0_CTL0 +
|
||||||
|
(comp * RX_MACRO_COMP_OFFSET);
|
||||||
|
rx_path_cfg0_reg = BOLERO_CDC_RX_RX0_RX_PATH_CFG0 +
|
||||||
|
(comp * RX_MACRO_RX_PATH_OFFSET);
|
||||||
if (SND_SOC_DAPM_EVENT_ON(event)) {
|
if (SND_SOC_DAPM_EVENT_ON(event)) {
|
||||||
/* Enable Compander Clock */
|
/* Enable Compander Clock */
|
||||||
snd_soc_component_update_bits(component, comp_ctl0_reg,
|
snd_soc_component_update_bits(component, comp_ctl0_reg,
|
||||||
@@ -1741,8 +1771,6 @@ static int rx_macro_config_compander(struct snd_soc_component *component,
|
|||||||
0x02, 0x00);
|
0x02, 0x00);
|
||||||
snd_soc_component_update_bits(component, rx_path_cfg0_reg,
|
snd_soc_component_update_bits(component, rx_path_cfg0_reg,
|
||||||
0x02, 0x02);
|
0x02, 0x02);
|
||||||
snd_soc_component_update_bits(component, rx_path_cfg3_reg,
|
|
||||||
0x03, val);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SND_SOC_DAPM_EVENT_OFF(event)) {
|
if (SND_SOC_DAPM_EVENT_OFF(event)) {
|
||||||
@@ -1754,8 +1782,6 @@ static int rx_macro_config_compander(struct snd_soc_component *component,
|
|||||||
0x01, 0x00);
|
0x01, 0x00);
|
||||||
snd_soc_component_update_bits(component, comp_ctl0_reg,
|
snd_soc_component_update_bits(component, comp_ctl0_reg,
|
||||||
0x04, 0x00);
|
0x04, 0x00);
|
||||||
snd_soc_component_update_bits(component, rx_path_cfg3_reg,
|
|
||||||
0x03, 0x03);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1930,6 +1956,11 @@ static int rx_macro_config_classh(struct snd_soc_component *component,
|
|||||||
0x40, 0x40);
|
0x40, 0x40);
|
||||||
break;
|
break;
|
||||||
case INTERP_HPHR:
|
case INTERP_HPHR:
|
||||||
|
if (rx_priv->is_ear_mode_on)
|
||||||
|
snd_soc_component_update_bits(component,
|
||||||
|
BOLERO_CDC_RX_CLSH_HPH_V_PA,
|
||||||
|
0x3F, 0x39);
|
||||||
|
else
|
||||||
snd_soc_component_update_bits(component,
|
snd_soc_component_update_bits(component,
|
||||||
BOLERO_CDC_RX_CLSH_HPH_V_PA,
|
BOLERO_CDC_RX_CLSH_HPH_V_PA,
|
||||||
0x3F, 0x1C);
|
0x3F, 0x1C);
|
||||||
@@ -2988,21 +3019,24 @@ static int rx_macro_set_iir_gain(struct snd_soc_dapm_widget *w,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const struct snd_kcontrol_new rx_macro_snd_controls[] = {
|
static const struct snd_kcontrol_new rx_macro_snd_controls[] = {
|
||||||
SOC_SINGLE_SX_TLV("RX_RX0 Digital Volume",
|
SOC_SINGLE_S8_TLV("RX_RX0 Digital Volume",
|
||||||
BOLERO_CDC_RX_RX0_RX_VOL_CTL,
|
BOLERO_CDC_RX_RX0_RX_VOL_CTL,
|
||||||
0, -84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("RX_RX1 Digital Volume",
|
SOC_SINGLE_S8_TLV("RX_RX1 Digital Volume",
|
||||||
BOLERO_CDC_RX_RX1_RX_VOL_CTL,
|
BOLERO_CDC_RX_RX1_RX_VOL_CTL,
|
||||||
0, -84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("RX_RX2 Digital Volume",
|
SOC_SINGLE_S8_TLV("RX_RX2 Digital Volume",
|
||||||
BOLERO_CDC_RX_RX2_RX_VOL_CTL,
|
BOLERO_CDC_RX_RX2_RX_VOL_CTL,
|
||||||
0, -84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("RX_RX0 Mix Digital Volume",
|
SOC_SINGLE_S8_TLV("RX_RX0 Mix Digital Volume",
|
||||||
BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0, -84, 40, digital_gain),
|
BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL,
|
||||||
SOC_SINGLE_SX_TLV("RX_RX1 Mix Digital Volume",
|
-84, 40, digital_gain),
|
||||||
BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0, -84, 40, digital_gain),
|
SOC_SINGLE_S8_TLV("RX_RX1 Mix Digital Volume",
|
||||||
SOC_SINGLE_SX_TLV("RX_RX2 Mix Digital Volume",
|
BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL,
|
||||||
BOLERO_CDC_RX_RX2_RX_VOL_MIX_CTL, 0, -84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
|
SOC_SINGLE_S8_TLV("RX_RX2 Mix Digital Volume",
|
||||||
|
BOLERO_CDC_RX_RX2_RX_VOL_MIX_CTL,
|
||||||
|
-84, 40, digital_gain),
|
||||||
|
|
||||||
SOC_SINGLE_EXT("RX_COMP1 Switch", SND_SOC_NOPM, RX_MACRO_COMP1, 1, 0,
|
SOC_SINGLE_EXT("RX_COMP1 Switch", SND_SOC_NOPM, RX_MACRO_COMP1, 1, 0,
|
||||||
rx_macro_get_compander, rx_macro_set_compander),
|
rx_macro_get_compander, rx_macro_set_compander),
|
||||||
@@ -3031,29 +3065,29 @@ static const struct snd_kcontrol_new rx_macro_snd_controls[] = {
|
|||||||
rx_macro_aux_hpf_mode_get,
|
rx_macro_aux_hpf_mode_get,
|
||||||
rx_macro_aux_hpf_mode_put),
|
rx_macro_aux_hpf_mode_put),
|
||||||
|
|
||||||
SOC_SINGLE_SX_TLV("IIR0 INP0 Volume",
|
SOC_SINGLE_S8_TLV("IIR0 INP0 Volume",
|
||||||
BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B1_CTL, 0, -84, 40,
|
BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B1_CTL, -84, 40,
|
||||||
digital_gain),
|
digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("IIR0 INP1 Volume",
|
SOC_SINGLE_S8_TLV("IIR0 INP1 Volume",
|
||||||
BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B2_CTL, 0, -84, 40,
|
BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B2_CTL, -84, 40,
|
||||||
digital_gain),
|
digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("IIR0 INP2 Volume",
|
SOC_SINGLE_S8_TLV("IIR0 INP2 Volume",
|
||||||
BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B3_CTL, 0, -84, 40,
|
BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B3_CTL, -84, 40,
|
||||||
digital_gain),
|
digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("IIR0 INP3 Volume",
|
SOC_SINGLE_S8_TLV("IIR0 INP3 Volume",
|
||||||
BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B4_CTL, 0, -84, 40,
|
BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B4_CTL, -84, 40,
|
||||||
digital_gain),
|
digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("IIR1 INP0 Volume",
|
SOC_SINGLE_S8_TLV("IIR1 INP0 Volume",
|
||||||
BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B1_CTL, 0, -84, 40,
|
BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B1_CTL, -84, 40,
|
||||||
digital_gain),
|
digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("IIR1 INP1 Volume",
|
SOC_SINGLE_S8_TLV("IIR1 INP1 Volume",
|
||||||
BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B2_CTL, 0, -84, 40,
|
BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B2_CTL, -84, 40,
|
||||||
digital_gain),
|
digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("IIR1 INP2 Volume",
|
SOC_SINGLE_S8_TLV("IIR1 INP2 Volume",
|
||||||
BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B3_CTL, 0, -84, 40,
|
BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B3_CTL, -84, 40,
|
||||||
digital_gain),
|
digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("IIR1 INP3 Volume",
|
SOC_SINGLE_S8_TLV("IIR1 INP3 Volume",
|
||||||
BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B4_CTL, 0, -84, 40,
|
BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B4_CTL, -84, 40,
|
||||||
digital_gain),
|
digital_gain),
|
||||||
|
|
||||||
SOC_SINGLE_EXT("IIR0 Enable Band1", IIR0, BAND1, 1, 0,
|
SOC_SINGLE_EXT("IIR0 Enable Band1", IIR0, BAND1, 1, 0,
|
||||||
@@ -3179,6 +3213,9 @@ static const struct snd_soc_dapm_widget rx_macro_dapm_widgets[] = {
|
|||||||
SND_SOC_DAPM_AIF_OUT("RX AIF_ECHO", "RX_AIF_ECHO Capture", 0,
|
SND_SOC_DAPM_AIF_OUT("RX AIF_ECHO", "RX_AIF_ECHO Capture", 0,
|
||||||
SND_SOC_NOPM, 0, 0),
|
SND_SOC_NOPM, 0, 0),
|
||||||
|
|
||||||
|
SND_SOC_DAPM_AIF_IN("RX AIF5 PB", "RX_MACRO_AIF5 Playback", 0,
|
||||||
|
SND_SOC_NOPM, 0, 0),
|
||||||
|
|
||||||
SND_SOC_DAPM_AIF_IN("RX AIF6 PB", "RX_MACRO_AIF6 Playback", 0,
|
SND_SOC_DAPM_AIF_IN("RX AIF6 PB", "RX_MACRO_AIF6 Playback", 0,
|
||||||
SND_SOC_NOPM, 0, 0),
|
SND_SOC_NOPM, 0, 0),
|
||||||
|
|
||||||
@@ -3849,6 +3886,7 @@ static int rx_macro_init(struct snd_soc_component *component)
|
|||||||
snd_soc_dapm_ignore_suspend(dapm, "RX_MACRO_AIF2 Playback");
|
snd_soc_dapm_ignore_suspend(dapm, "RX_MACRO_AIF2 Playback");
|
||||||
snd_soc_dapm_ignore_suspend(dapm, "RX_MACRO_AIF3 Playback");
|
snd_soc_dapm_ignore_suspend(dapm, "RX_MACRO_AIF3 Playback");
|
||||||
snd_soc_dapm_ignore_suspend(dapm, "RX_MACRO_AIF4 Playback");
|
snd_soc_dapm_ignore_suspend(dapm, "RX_MACRO_AIF4 Playback");
|
||||||
|
snd_soc_dapm_ignore_suspend(dapm, "RX_MACRO_AIF5 Playback");
|
||||||
snd_soc_dapm_ignore_suspend(dapm, "RX_MACRO_AIF6 Playback");
|
snd_soc_dapm_ignore_suspend(dapm, "RX_MACRO_AIF6 Playback");
|
||||||
snd_soc_dapm_ignore_suspend(dapm, "HPHL_OUT");
|
snd_soc_dapm_ignore_suspend(dapm, "HPHL_OUT");
|
||||||
snd_soc_dapm_ignore_suspend(dapm, "HPHR_OUT");
|
snd_soc_dapm_ignore_suspend(dapm, "HPHR_OUT");
|
||||||
@@ -4016,6 +4054,12 @@ static int rx_macro_probe(struct platform_device *pdev)
|
|||||||
u32 is_used_rx_swr_gpio = 1;
|
u32 is_used_rx_swr_gpio = 1;
|
||||||
const char *is_used_rx_swr_gpio_dt = "qcom,is-used-swr-gpio";
|
const char *is_used_rx_swr_gpio_dt = "qcom,is-used-swr-gpio";
|
||||||
|
|
||||||
|
if (!bolero_is_va_macro_registered(&pdev->dev)) {
|
||||||
|
dev_err(&pdev->dev,
|
||||||
|
"%s: va-macro not registered yet, defer\n", __func__);
|
||||||
|
return -EPROBE_DEFER;
|
||||||
|
}
|
||||||
|
|
||||||
rx_priv = devm_kzalloc(&pdev->dev, sizeof(struct rx_macro_priv),
|
rx_priv = devm_kzalloc(&pdev->dev, sizeof(struct rx_macro_priv),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (!rx_priv)
|
if (!rx_priv)
|
||||||
|
@@ -176,6 +176,7 @@ struct tx_macro_priv {
|
|||||||
int bcs_ch;
|
int bcs_ch;
|
||||||
bool bcs_clk_en;
|
bool bcs_clk_en;
|
||||||
bool hs_slow_insert_complete;
|
bool hs_slow_insert_complete;
|
||||||
|
int amic_sample_rate;
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool tx_macro_get_data(struct snd_soc_component *component,
|
static bool tx_macro_get_data(struct snd_soc_component *component,
|
||||||
@@ -411,6 +412,9 @@ static int tx_macro_event_handler(struct snd_soc_component *component,
|
|||||||
else
|
else
|
||||||
tx_priv->hs_slow_insert_complete = false;
|
tx_priv->hs_slow_insert_complete = false;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
pr_debug("%s Invalid Event\n", __func__);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -497,6 +501,29 @@ static void tx_macro_tx_hpf_corner_freq_callback(struct work_struct *work)
|
|||||||
hpf_cut_off_freq << 5);
|
hpf_cut_off_freq << 5);
|
||||||
snd_soc_component_update_bits(component, hpf_gate_reg,
|
snd_soc_component_update_bits(component, hpf_gate_reg,
|
||||||
0x03, 0x02);
|
0x03, 0x02);
|
||||||
|
/* Add delay between toggle hpf gate based on sample rate */
|
||||||
|
switch(tx_priv->amic_sample_rate) {
|
||||||
|
case 8000:
|
||||||
|
usleep_range(125, 130);
|
||||||
|
break;
|
||||||
|
case 16000:
|
||||||
|
usleep_range(62, 65);
|
||||||
|
break;
|
||||||
|
case 32000:
|
||||||
|
usleep_range(31, 32);
|
||||||
|
break;
|
||||||
|
case 48000:
|
||||||
|
usleep_range(20, 21);
|
||||||
|
break;
|
||||||
|
case 96000:
|
||||||
|
usleep_range(10, 11);
|
||||||
|
break;
|
||||||
|
case 192000:
|
||||||
|
usleep_range(5, 6);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
usleep_range(125, 130);
|
||||||
|
}
|
||||||
snd_soc_component_update_bits(component, hpf_gate_reg,
|
snd_soc_component_update_bits(component, hpf_gate_reg,
|
||||||
0x03, 0x01);
|
0x03, 0x01);
|
||||||
} else {
|
} else {
|
||||||
@@ -932,6 +959,7 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w,
|
|||||||
u16 dec_cfg_reg = 0;
|
u16 dec_cfg_reg = 0;
|
||||||
u16 hpf_gate_reg = 0;
|
u16 hpf_gate_reg = 0;
|
||||||
u16 tx_gain_ctl_reg = 0;
|
u16 tx_gain_ctl_reg = 0;
|
||||||
|
u16 tx_fs_reg = 0;
|
||||||
u8 hpf_cut_off_freq = 0;
|
u8 hpf_cut_off_freq = 0;
|
||||||
u16 adc_mux_reg = 0;
|
u16 adc_mux_reg = 0;
|
||||||
int hpf_delay = TX_MACRO_DMIC_HPF_DELAY_MS;
|
int hpf_delay = TX_MACRO_DMIC_HPF_DELAY_MS;
|
||||||
@@ -957,6 +985,11 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w,
|
|||||||
TX_MACRO_TX_PATH_OFFSET * decimator;
|
TX_MACRO_TX_PATH_OFFSET * decimator;
|
||||||
adc_mux_reg = BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG1 +
|
adc_mux_reg = BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG1 +
|
||||||
TX_MACRO_ADC_MUX_CFG_OFFSET * decimator;
|
TX_MACRO_ADC_MUX_CFG_OFFSET * decimator;
|
||||||
|
tx_fs_reg = BOLERO_CDC_TX0_TX_PATH_CTL +
|
||||||
|
TX_MACRO_TX_PATH_OFFSET * decimator;
|
||||||
|
|
||||||
|
tx_priv->amic_sample_rate = (snd_soc_component_read32(component,
|
||||||
|
tx_fs_reg) & 0x0F);
|
||||||
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case SND_SOC_DAPM_PRE_PMU:
|
case SND_SOC_DAPM_PRE_PMU:
|
||||||
@@ -2362,18 +2395,18 @@ static const struct snd_soc_dapm_route tx_audio_map[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const struct snd_kcontrol_new tx_macro_snd_controls_common[] = {
|
static const struct snd_kcontrol_new tx_macro_snd_controls_common[] = {
|
||||||
SOC_SINGLE_SX_TLV("TX_DEC0 Volume",
|
SOC_SINGLE_S8_TLV("TX_DEC0 Volume",
|
||||||
BOLERO_CDC_TX0_TX_VOL_CTL,
|
BOLERO_CDC_TX0_TX_VOL_CTL,
|
||||||
0, -84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("TX_DEC1 Volume",
|
SOC_SINGLE_S8_TLV("TX_DEC1 Volume",
|
||||||
BOLERO_CDC_TX1_TX_VOL_CTL,
|
BOLERO_CDC_TX1_TX_VOL_CTL,
|
||||||
0, -84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("TX_DEC2 Volume",
|
SOC_SINGLE_S8_TLV("TX_DEC2 Volume",
|
||||||
BOLERO_CDC_TX2_TX_VOL_CTL,
|
BOLERO_CDC_TX2_TX_VOL_CTL,
|
||||||
0, -84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("TX_DEC3 Volume",
|
SOC_SINGLE_S8_TLV("TX_DEC3 Volume",
|
||||||
BOLERO_CDC_TX3_TX_VOL_CTL,
|
BOLERO_CDC_TX3_TX_VOL_CTL,
|
||||||
0, -84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
|
|
||||||
SOC_ENUM_EXT("DEC0 MODE", dec_mode_mux_enum,
|
SOC_ENUM_EXT("DEC0 MODE", dec_mode_mux_enum,
|
||||||
tx_macro_dec_mode_get, tx_macro_dec_mode_put),
|
tx_macro_dec_mode_get, tx_macro_dec_mode_put),
|
||||||
@@ -2398,18 +2431,18 @@ static const struct snd_kcontrol_new tx_macro_snd_controls_common[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const struct snd_kcontrol_new tx_macro_snd_controls_v3[] = {
|
static const struct snd_kcontrol_new tx_macro_snd_controls_v3[] = {
|
||||||
SOC_SINGLE_SX_TLV("TX_DEC4 Volume",
|
SOC_SINGLE_S8_TLV("TX_DEC4 Volume",
|
||||||
BOLERO_CDC_TX4_TX_VOL_CTL,
|
BOLERO_CDC_TX4_TX_VOL_CTL,
|
||||||
0, -84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("TX_DEC5 Volume",
|
SOC_SINGLE_S8_TLV("TX_DEC5 Volume",
|
||||||
BOLERO_CDC_TX5_TX_VOL_CTL,
|
BOLERO_CDC_TX5_TX_VOL_CTL,
|
||||||
0, -84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("TX_DEC6 Volume",
|
SOC_SINGLE_S8_TLV("TX_DEC6 Volume",
|
||||||
BOLERO_CDC_TX6_TX_VOL_CTL,
|
BOLERO_CDC_TX6_TX_VOL_CTL,
|
||||||
0, -84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("TX_DEC7 Volume",
|
SOC_SINGLE_S8_TLV("TX_DEC7 Volume",
|
||||||
BOLERO_CDC_TX7_TX_VOL_CTL,
|
BOLERO_CDC_TX7_TX_VOL_CTL,
|
||||||
0, -84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
|
|
||||||
SOC_ENUM_EXT("DEC4 MODE", dec_mode_mux_enum,
|
SOC_ENUM_EXT("DEC4 MODE", dec_mode_mux_enum,
|
||||||
tx_macro_dec_mode_get, tx_macro_dec_mode_put),
|
tx_macro_dec_mode_get, tx_macro_dec_mode_put),
|
||||||
@@ -2425,30 +2458,30 @@ static const struct snd_kcontrol_new tx_macro_snd_controls_v3[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const struct snd_kcontrol_new tx_macro_snd_controls[] = {
|
static const struct snd_kcontrol_new tx_macro_snd_controls[] = {
|
||||||
SOC_SINGLE_SX_TLV("TX_DEC0 Volume",
|
SOC_SINGLE_S8_TLV("TX_DEC0 Volume",
|
||||||
BOLERO_CDC_TX0_TX_VOL_CTL,
|
BOLERO_CDC_TX0_TX_VOL_CTL,
|
||||||
0, -84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("TX_DEC1 Volume",
|
SOC_SINGLE_S8_TLV("TX_DEC1 Volume",
|
||||||
BOLERO_CDC_TX1_TX_VOL_CTL,
|
BOLERO_CDC_TX1_TX_VOL_CTL,
|
||||||
0, -84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("TX_DEC2 Volume",
|
SOC_SINGLE_S8_TLV("TX_DEC2 Volume",
|
||||||
BOLERO_CDC_TX2_TX_VOL_CTL,
|
BOLERO_CDC_TX2_TX_VOL_CTL,
|
||||||
0, -84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("TX_DEC3 Volume",
|
SOC_SINGLE_S8_TLV("TX_DEC3 Volume",
|
||||||
BOLERO_CDC_TX3_TX_VOL_CTL,
|
BOLERO_CDC_TX3_TX_VOL_CTL,
|
||||||
0, -84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("TX_DEC4 Volume",
|
SOC_SINGLE_S8_TLV("TX_DEC4 Volume",
|
||||||
BOLERO_CDC_TX4_TX_VOL_CTL,
|
BOLERO_CDC_TX4_TX_VOL_CTL,
|
||||||
0, -84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("TX_DEC5 Volume",
|
SOC_SINGLE_S8_TLV("TX_DEC5 Volume",
|
||||||
BOLERO_CDC_TX5_TX_VOL_CTL,
|
BOLERO_CDC_TX5_TX_VOL_CTL,
|
||||||
0, -84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("TX_DEC6 Volume",
|
SOC_SINGLE_S8_TLV("TX_DEC6 Volume",
|
||||||
BOLERO_CDC_TX6_TX_VOL_CTL,
|
BOLERO_CDC_TX6_TX_VOL_CTL,
|
||||||
0, -84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("TX_DEC7 Volume",
|
SOC_SINGLE_S8_TLV("TX_DEC7 Volume",
|
||||||
BOLERO_CDC_TX7_TX_VOL_CTL,
|
BOLERO_CDC_TX7_TX_VOL_CTL,
|
||||||
0, -84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
|
|
||||||
SOC_ENUM_EXT("DEC0 MODE", dec_mode_mux_enum,
|
SOC_ENUM_EXT("DEC0 MODE", dec_mode_mux_enum,
|
||||||
tx_macro_dec_mode_get, tx_macro_dec_mode_put),
|
tx_macro_dec_mode_get, tx_macro_dec_mode_put),
|
||||||
@@ -2722,36 +2755,6 @@ static int tx_macro_clk_div_get(struct snd_soc_component *component)
|
|||||||
return tx_priv->dmic_clk_div;
|
return tx_priv->dmic_clk_div;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tx_macro_clk_switch(struct snd_soc_component *component, int clk_src)
|
|
||||||
{
|
|
||||||
struct device *tx_dev = NULL;
|
|
||||||
struct tx_macro_priv *tx_priv = NULL;
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
if (!component)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
tx_dev = bolero_get_device_ptr(component->dev, TX_MACRO);
|
|
||||||
if (!tx_dev) {
|
|
||||||
dev_err(component->dev,
|
|
||||||
"%s: null device for macro!\n", __func__);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
tx_priv = dev_get_drvdata(tx_dev);
|
|
||||||
if (!tx_priv) {
|
|
||||||
dev_err(component->dev,
|
|
||||||
"%s: priv is null for macro!\n", __func__);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
if (tx_priv->swr_ctrl_data) {
|
|
||||||
ret = swrm_wcd_notify(
|
|
||||||
tx_priv->swr_ctrl_data[0].tx_swr_pdev,
|
|
||||||
SWR_REQ_CLK_SWITCH, &clk_src);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int tx_macro_core_vote(void *handle, bool enable)
|
static int tx_macro_core_vote(void *handle, bool enable)
|
||||||
{
|
{
|
||||||
struct tx_macro_priv *tx_priv = (struct tx_macro_priv *) handle;
|
struct tx_macro_priv *tx_priv = (struct tx_macro_priv *) handle;
|
||||||
@@ -3233,7 +3236,6 @@ static void tx_macro_init_ops(struct macro_ops *ops,
|
|||||||
ops->reg_wake_irq = tx_macro_reg_wake_irq;
|
ops->reg_wake_irq = tx_macro_reg_wake_irq;
|
||||||
ops->set_port_map = tx_macro_set_port_map;
|
ops->set_port_map = tx_macro_set_port_map;
|
||||||
ops->clk_div_get = tx_macro_clk_div_get;
|
ops->clk_div_get = tx_macro_clk_div_get;
|
||||||
ops->clk_switch = tx_macro_clk_switch;
|
|
||||||
ops->reg_evt_listener = tx_macro_register_event_listener;
|
ops->reg_evt_listener = tx_macro_register_event_listener;
|
||||||
ops->clk_enable = __tx_macro_mclk_enable;
|
ops->clk_enable = __tx_macro_mclk_enable;
|
||||||
}
|
}
|
||||||
@@ -3249,6 +3251,12 @@ static int tx_macro_probe(struct platform_device *pdev)
|
|||||||
u32 is_used_tx_swr_gpio = 1;
|
u32 is_used_tx_swr_gpio = 1;
|
||||||
const char *is_used_tx_swr_gpio_dt = "qcom,is-used-swr-gpio";
|
const char *is_used_tx_swr_gpio_dt = "qcom,is-used-swr-gpio";
|
||||||
|
|
||||||
|
if (!bolero_is_va_macro_registered(&pdev->dev)) {
|
||||||
|
dev_err(&pdev->dev,
|
||||||
|
"%s: va-macro not registered yet, defer\n", __func__);
|
||||||
|
return -EPROBE_DEFER;
|
||||||
|
}
|
||||||
|
|
||||||
tx_priv = devm_kzalloc(&pdev->dev, sizeof(struct tx_macro_priv),
|
tx_priv = devm_kzalloc(&pdev->dev, sizeof(struct tx_macro_priv),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (!tx_priv)
|
if (!tx_priv)
|
||||||
|
@@ -298,8 +298,7 @@ static int va_macro_event_handler(struct snd_soc_component *component,
|
|||||||
"%s: va_mclk_users is non-zero still, audio SSR fail!!\n",
|
"%s: va_mclk_users is non-zero still, audio SSR fail!!\n",
|
||||||
__func__);
|
__func__);
|
||||||
break;
|
break;
|
||||||
case BOLERO_MACRO_EVT_SSR_UP:
|
case BOLERO_MACRO_EVT_PRE_SSR_UP:
|
||||||
trace_printk("%s, enter SSR up\n", __func__);
|
|
||||||
/* enable&disable VA_CORE_CLK to reset GFMUX reg */
|
/* enable&disable VA_CORE_CLK to reset GFMUX reg */
|
||||||
ret = bolero_clk_rsc_request_clock(va_priv->dev,
|
ret = bolero_clk_rsc_request_clock(va_priv->dev,
|
||||||
va_priv->default_clk_id,
|
va_priv->default_clk_id,
|
||||||
@@ -312,6 +311,9 @@ static int va_macro_event_handler(struct snd_soc_component *component,
|
|||||||
bolero_clk_rsc_request_clock(va_priv->dev,
|
bolero_clk_rsc_request_clock(va_priv->dev,
|
||||||
va_priv->default_clk_id,
|
va_priv->default_clk_id,
|
||||||
VA_CORE_CLK, false);
|
VA_CORE_CLK, false);
|
||||||
|
break;
|
||||||
|
case BOLERO_MACRO_EVT_SSR_UP:
|
||||||
|
trace_printk("%s, enter SSR up\n", __func__);
|
||||||
/* reset swr after ssr/pdr */
|
/* reset swr after ssr/pdr */
|
||||||
va_priv->reset_swr = true;
|
va_priv->reset_swr = true;
|
||||||
if (va_priv->swr_ctrl_data)
|
if (va_priv->swr_ctrl_data)
|
||||||
@@ -378,7 +380,6 @@ static int va_macro_swr_pwr_event_v2(struct snd_soc_dapm_widget *w,
|
|||||||
int ret = 0;
|
int ret = 0;
|
||||||
struct device *va_dev = NULL;
|
struct device *va_dev = NULL;
|
||||||
struct va_macro_priv *va_priv = NULL;
|
struct va_macro_priv *va_priv = NULL;
|
||||||
int clk_src = 0;
|
|
||||||
|
|
||||||
if (!va_macro_get_data(component, &va_dev, &va_priv, __func__))
|
if (!va_macro_get_data(component, &va_dev, &va_priv, __func__))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@@ -391,30 +392,12 @@ static int va_macro_swr_pwr_event_v2(struct snd_soc_dapm_widget *w,
|
|||||||
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case SND_SOC_DAPM_PRE_PMU:
|
case SND_SOC_DAPM_PRE_PMU:
|
||||||
if (va_priv->swr_ctrl_data) {
|
|
||||||
clk_src = CLK_SRC_VA_RCG;
|
|
||||||
ret = swrm_wcd_notify(
|
|
||||||
va_priv->swr_ctrl_data[0].va_swr_pdev,
|
|
||||||
SWR_REQ_CLK_SWITCH, &clk_src);
|
|
||||||
if (ret)
|
|
||||||
dev_dbg(va_dev, "%s: clock switch failed\n",
|
|
||||||
__func__);
|
|
||||||
}
|
|
||||||
msm_cdc_pinctrl_set_wakeup_capable(
|
msm_cdc_pinctrl_set_wakeup_capable(
|
||||||
va_priv->va_swr_gpio_p, false);
|
va_priv->va_swr_gpio_p, false);
|
||||||
break;
|
break;
|
||||||
case SND_SOC_DAPM_POST_PMD:
|
case SND_SOC_DAPM_POST_PMD:
|
||||||
msm_cdc_pinctrl_set_wakeup_capable(
|
msm_cdc_pinctrl_set_wakeup_capable(
|
||||||
va_priv->va_swr_gpio_p, true);
|
va_priv->va_swr_gpio_p, true);
|
||||||
if (va_priv->swr_ctrl_data) {
|
|
||||||
clk_src = CLK_SRC_TX_RCG;
|
|
||||||
ret = swrm_wcd_notify(
|
|
||||||
va_priv->swr_ctrl_data[0].va_swr_pdev,
|
|
||||||
SWR_REQ_CLK_SWITCH, &clk_src);
|
|
||||||
if (ret)
|
|
||||||
dev_dbg(va_dev, "%s: clock switch failed\n",
|
|
||||||
__func__);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
dev_err(va_priv->dev,
|
dev_err(va_priv->dev,
|
||||||
@@ -452,10 +435,6 @@ static int va_macro_swr_pwr_event(struct snd_soc_dapm_widget *w,
|
|||||||
"%s: lpass audio hw enable failed\n",
|
"%s: lpass audio hw enable failed\n",
|
||||||
__func__);
|
__func__);
|
||||||
}
|
}
|
||||||
if (!ret)
|
|
||||||
if (bolero_tx_clk_switch(component, CLK_SRC_VA_RCG))
|
|
||||||
dev_dbg(va_dev, "%s: clock switch failed\n",
|
|
||||||
__func__);
|
|
||||||
if (va_priv->lpi_enable) {
|
if (va_priv->lpi_enable) {
|
||||||
bolero_register_event_listener(component, true);
|
bolero_register_event_listener(component, true);
|
||||||
va_priv->register_event_listener = true;
|
va_priv->register_event_listener = true;
|
||||||
@@ -466,8 +445,6 @@ static int va_macro_swr_pwr_event(struct snd_soc_dapm_widget *w,
|
|||||||
va_priv->register_event_listener = false;
|
va_priv->register_event_listener = false;
|
||||||
bolero_register_event_listener(component, false);
|
bolero_register_event_listener(component, false);
|
||||||
}
|
}
|
||||||
if (bolero_tx_clk_switch(component, CLK_SRC_TX_RCG))
|
|
||||||
dev_dbg(va_dev, "%s: clock switch failed\n",__func__);
|
|
||||||
if (va_priv->lpass_audio_hw_vote)
|
if (va_priv->lpass_audio_hw_vote)
|
||||||
digital_cdc_rsc_mgr_hw_vote_disable(
|
digital_cdc_rsc_mgr_hw_vote_disable(
|
||||||
va_priv->lpass_audio_hw_vote);
|
va_priv->lpass_audio_hw_vote);
|
||||||
@@ -507,7 +484,6 @@ static int va_macro_mclk_event(struct snd_soc_dapm_widget *w,
|
|||||||
int ret = 0;
|
int ret = 0;
|
||||||
struct device *va_dev = NULL;
|
struct device *va_dev = NULL;
|
||||||
struct va_macro_priv *va_priv = NULL;
|
struct va_macro_priv *va_priv = NULL;
|
||||||
int clk_src = 0;
|
|
||||||
|
|
||||||
if (!va_macro_get_data(component, &va_dev, &va_priv, __func__))
|
if (!va_macro_get_data(component, &va_dev, &va_priv, __func__))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@@ -528,27 +504,10 @@ static int va_macro_mclk_event(struct snd_soc_dapm_widget *w,
|
|||||||
ret = bolero_tx_mclk_enable(component, 1);
|
ret = bolero_tx_mclk_enable(component, 1);
|
||||||
break;
|
break;
|
||||||
case SND_SOC_DAPM_POST_PMD:
|
case SND_SOC_DAPM_POST_PMD:
|
||||||
if (va_priv->lpi_enable) {
|
if (va_priv->lpi_enable)
|
||||||
if (va_priv->version == BOLERO_VERSION_2_1) {
|
|
||||||
if (va_priv->swr_ctrl_data) {
|
|
||||||
clk_src = CLK_SRC_TX_RCG;
|
|
||||||
ret = swrm_wcd_notify(
|
|
||||||
va_priv->swr_ctrl_data[0].va_swr_pdev,
|
|
||||||
SWR_REQ_CLK_SWITCH, &clk_src);
|
|
||||||
if (ret)
|
|
||||||
dev_dbg(va_dev,
|
|
||||||
"%s: clock switch failed\n",
|
|
||||||
__func__);
|
|
||||||
}
|
|
||||||
} else if (bolero_tx_clk_switch(component,
|
|
||||||
CLK_SRC_TX_RCG)) {
|
|
||||||
dev_dbg(va_dev, "%s: clock switch failed\n",
|
|
||||||
__func__);
|
|
||||||
}
|
|
||||||
va_macro_mclk_enable(va_priv, 0, true);
|
va_macro_mclk_enable(va_priv, 0, true);
|
||||||
} else {
|
else
|
||||||
bolero_tx_mclk_enable(component, 0);
|
bolero_tx_mclk_enable(component, 0);
|
||||||
}
|
|
||||||
|
|
||||||
if (va_priv->tx_clk_status > 0) {
|
if (va_priv->tx_clk_status > 0) {
|
||||||
bolero_clk_rsc_request_clock(va_priv->dev,
|
bolero_clk_rsc_request_clock(va_priv->dev,
|
||||||
@@ -2536,30 +2495,30 @@ static const struct soc_enum dec_mode_mux_enum =
|
|||||||
dec_mode_mux_text);
|
dec_mode_mux_text);
|
||||||
|
|
||||||
static const struct snd_kcontrol_new va_macro_snd_controls[] = {
|
static const struct snd_kcontrol_new va_macro_snd_controls[] = {
|
||||||
SOC_SINGLE_SX_TLV("VA_DEC0 Volume",
|
SOC_SINGLE_S8_TLV("VA_DEC0 Volume",
|
||||||
BOLERO_CDC_VA_TX0_TX_VOL_CTL,
|
BOLERO_CDC_VA_TX0_TX_VOL_CTL,
|
||||||
0, -84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("VA_DEC1 Volume",
|
SOC_SINGLE_S8_TLV("VA_DEC1 Volume",
|
||||||
BOLERO_CDC_VA_TX1_TX_VOL_CTL,
|
BOLERO_CDC_VA_TX1_TX_VOL_CTL,
|
||||||
0, -84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("VA_DEC2 Volume",
|
SOC_SINGLE_S8_TLV("VA_DEC2 Volume",
|
||||||
BOLERO_CDC_VA_TX2_TX_VOL_CTL,
|
BOLERO_CDC_VA_TX2_TX_VOL_CTL,
|
||||||
0, -84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("VA_DEC3 Volume",
|
SOC_SINGLE_S8_TLV("VA_DEC3 Volume",
|
||||||
BOLERO_CDC_VA_TX3_TX_VOL_CTL,
|
BOLERO_CDC_VA_TX3_TX_VOL_CTL,
|
||||||
0, -84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("VA_DEC4 Volume",
|
SOC_SINGLE_S8_TLV("VA_DEC4 Volume",
|
||||||
BOLERO_CDC_VA_TX4_TX_VOL_CTL,
|
BOLERO_CDC_VA_TX4_TX_VOL_CTL,
|
||||||
0, -84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("VA_DEC5 Volume",
|
SOC_SINGLE_S8_TLV("VA_DEC5 Volume",
|
||||||
BOLERO_CDC_VA_TX5_TX_VOL_CTL,
|
BOLERO_CDC_VA_TX5_TX_VOL_CTL,
|
||||||
0, -84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("VA_DEC6 Volume",
|
SOC_SINGLE_S8_TLV("VA_DEC6 Volume",
|
||||||
BOLERO_CDC_VA_TX6_TX_VOL_CTL,
|
BOLERO_CDC_VA_TX6_TX_VOL_CTL,
|
||||||
0, -84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("VA_DEC7 Volume",
|
SOC_SINGLE_S8_TLV("VA_DEC7 Volume",
|
||||||
BOLERO_CDC_VA_TX7_TX_VOL_CTL,
|
BOLERO_CDC_VA_TX7_TX_VOL_CTL,
|
||||||
0, -84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_EXT("LPI Enable", 0, 0, 1, 0,
|
SOC_SINGLE_EXT("LPI Enable", 0, 0, 1, 0,
|
||||||
va_macro_lpi_get, va_macro_lpi_put),
|
va_macro_lpi_get, va_macro_lpi_put),
|
||||||
|
|
||||||
@@ -2577,23 +2536,23 @@ static const struct snd_kcontrol_new va_macro_snd_controls[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const struct snd_kcontrol_new va_macro_snd_controls_common[] = {
|
static const struct snd_kcontrol_new va_macro_snd_controls_common[] = {
|
||||||
SOC_SINGLE_SX_TLV("VA_DEC0 Volume",
|
SOC_SINGLE_S8_TLV("VA_DEC0 Volume",
|
||||||
BOLERO_CDC_VA_TX0_TX_VOL_CTL,
|
BOLERO_CDC_VA_TX0_TX_VOL_CTL,
|
||||||
0, -84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("VA_DEC1 Volume",
|
SOC_SINGLE_S8_TLV("VA_DEC1 Volume",
|
||||||
BOLERO_CDC_VA_TX1_TX_VOL_CTL,
|
BOLERO_CDC_VA_TX1_TX_VOL_CTL,
|
||||||
0, -84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_EXT("LPI Enable", 0, 0, 1, 0,
|
SOC_SINGLE_EXT("LPI Enable", 0, 0, 1, 0,
|
||||||
va_macro_lpi_get, va_macro_lpi_put),
|
va_macro_lpi_get, va_macro_lpi_put),
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct snd_kcontrol_new va_macro_snd_controls_v3[] = {
|
static const struct snd_kcontrol_new va_macro_snd_controls_v3[] = {
|
||||||
SOC_SINGLE_SX_TLV("VA_DEC2 Volume",
|
SOC_SINGLE_S8_TLV("VA_DEC2 Volume",
|
||||||
BOLERO_CDC_VA_TX2_TX_VOL_CTL,
|
BOLERO_CDC_VA_TX2_TX_VOL_CTL,
|
||||||
0, -84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("VA_DEC3 Volume",
|
SOC_SINGLE_S8_TLV("VA_DEC3 Volume",
|
||||||
BOLERO_CDC_VA_TX3_TX_VOL_CTL,
|
BOLERO_CDC_VA_TX3_TX_VOL_CTL,
|
||||||
0, -84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
};
|
};
|
||||||
|
|
||||||
static int va_macro_validate_dmic_sample_rate(u32 dmic_sample_rate,
|
static int va_macro_validate_dmic_sample_rate(u32 dmic_sample_rate,
|
||||||
|
@@ -1022,10 +1022,7 @@ static int wsa_macro_event_handler(struct snd_soc_component *component,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case BOLERO_MACRO_EVT_SSR_UP:
|
case BOLERO_MACRO_EVT_PRE_SSR_UP:
|
||||||
trace_printk("%s, enter SSR up\n", __func__);
|
|
||||||
/* reset swr after ssr/pdr */
|
|
||||||
wsa_priv->reset_swr = true;
|
|
||||||
/* enable&disable WSA_CORE_CLK to reset GFMUX reg */
|
/* enable&disable WSA_CORE_CLK to reset GFMUX reg */
|
||||||
ret = bolero_clk_rsc_request_clock(wsa_priv->dev,
|
ret = bolero_clk_rsc_request_clock(wsa_priv->dev,
|
||||||
wsa_priv->default_clk_id,
|
wsa_priv->default_clk_id,
|
||||||
@@ -1038,6 +1035,11 @@ static int wsa_macro_event_handler(struct snd_soc_component *component,
|
|||||||
bolero_clk_rsc_request_clock(wsa_priv->dev,
|
bolero_clk_rsc_request_clock(wsa_priv->dev,
|
||||||
wsa_priv->default_clk_id,
|
wsa_priv->default_clk_id,
|
||||||
WSA_CORE_CLK, false);
|
WSA_CORE_CLK, false);
|
||||||
|
break;
|
||||||
|
case BOLERO_MACRO_EVT_SSR_UP:
|
||||||
|
trace_printk("%s, enter SSR up\n", __func__);
|
||||||
|
/* reset swr after ssr/pdr */
|
||||||
|
wsa_priv->reset_swr = true;
|
||||||
if (wsa_priv->swr_ctrl_data)
|
if (wsa_priv->swr_ctrl_data)
|
||||||
swrm_wcd_notify(
|
swrm_wcd_notify(
|
||||||
wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
|
wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
|
||||||
@@ -1178,45 +1180,6 @@ static int wsa_macro_enable_vi_feedback(struct snd_soc_dapm_widget *w,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int wsa_macro_enable_mix_path(struct snd_soc_dapm_widget *w,
|
|
||||||
struct snd_kcontrol *kcontrol, int event)
|
|
||||||
{
|
|
||||||
struct snd_soc_component *component =
|
|
||||||
snd_soc_dapm_to_component(w->dapm);
|
|
||||||
u16 gain_reg;
|
|
||||||
int offset_val = 0;
|
|
||||||
int val = 0;
|
|
||||||
|
|
||||||
dev_dbg(component->dev, "%s %d %s\n", __func__, event, w->name);
|
|
||||||
|
|
||||||
switch (w->reg) {
|
|
||||||
case BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL:
|
|
||||||
gain_reg = BOLERO_CDC_WSA_RX0_RX_VOL_MIX_CTL;
|
|
||||||
break;
|
|
||||||
case BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CTL:
|
|
||||||
gain_reg = BOLERO_CDC_WSA_RX1_RX_VOL_MIX_CTL;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
dev_err(component->dev, "%s: No gain register avail for %s\n",
|
|
||||||
__func__, w->name);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (event) {
|
|
||||||
case SND_SOC_DAPM_POST_PMU:
|
|
||||||
val = snd_soc_component_read32(component, gain_reg);
|
|
||||||
val += offset_val;
|
|
||||||
snd_soc_component_write(component, gain_reg, val);
|
|
||||||
break;
|
|
||||||
case SND_SOC_DAPM_POST_PMD:
|
|
||||||
snd_soc_component_update_bits(component,
|
|
||||||
w->reg, 0x20, 0x00);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void wsa_macro_hd2_control(struct snd_soc_component *component,
|
static void wsa_macro_hd2_control(struct snd_soc_component *component,
|
||||||
u16 reg, int event)
|
u16 reg, int event)
|
||||||
{
|
{
|
||||||
@@ -1303,6 +1266,44 @@ static int wsa_macro_enable_swr(struct snd_soc_dapm_widget *w,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int wsa_macro_enable_mix_path(struct snd_soc_dapm_widget *w,
|
||||||
|
struct snd_kcontrol *kcontrol, int event)
|
||||||
|
{
|
||||||
|
struct snd_soc_component *component =
|
||||||
|
snd_soc_dapm_to_component(w->dapm);
|
||||||
|
u16 gain_reg;
|
||||||
|
int offset_val = 0;
|
||||||
|
int val = 0;
|
||||||
|
|
||||||
|
dev_dbg(component->dev, "%s %d %s\n", __func__, event, w->name);
|
||||||
|
|
||||||
|
if (!(strcmp(w->name, "WSA_RX0 MIX INP"))) {
|
||||||
|
gain_reg = BOLERO_CDC_WSA_RX0_RX_VOL_MIX_CTL;
|
||||||
|
} else if (!(strcmp(w->name, "WSA_RX1 MIX INP"))) {
|
||||||
|
gain_reg = BOLERO_CDC_WSA_RX1_RX_VOL_MIX_CTL;
|
||||||
|
} else {
|
||||||
|
dev_err(component->dev, "%s: No gain register avail for %s\n",
|
||||||
|
__func__, w->name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (event) {
|
||||||
|
case SND_SOC_DAPM_PRE_PMU:
|
||||||
|
wsa_macro_enable_swr(w, kcontrol, event);
|
||||||
|
val = snd_soc_component_read32(component, gain_reg);
|
||||||
|
val += offset_val;
|
||||||
|
snd_soc_component_write(component, gain_reg, val);
|
||||||
|
break;
|
||||||
|
case SND_SOC_DAPM_POST_PMD:
|
||||||
|
snd_soc_component_update_bits(component,
|
||||||
|
w->reg, 0x20, 0x00);
|
||||||
|
wsa_macro_enable_swr(w, kcontrol, event);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int wsa_macro_config_compander(struct snd_soc_component *component,
|
static int wsa_macro_config_compander(struct snd_soc_component *component,
|
||||||
int comp, int event)
|
int comp, int event)
|
||||||
{
|
{
|
||||||
@@ -2007,10 +2008,12 @@ static int wsa_macro_set_rx_mute_status(struct snd_kcontrol *kcontrol,
|
|||||||
int value = ucontrol->value.integer.value[0];
|
int value = ucontrol->value.integer.value[0];
|
||||||
int wsa_rx_shift = ((struct soc_multi_mixer_control *)
|
int wsa_rx_shift = ((struct soc_multi_mixer_control *)
|
||||||
kcontrol->private_value)->shift;
|
kcontrol->private_value)->shift;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
|
if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
pm_runtime_get_sync(wsa_priv->dev);
|
||||||
switch (wsa_rx_shift) {
|
switch (wsa_rx_shift) {
|
||||||
case 0:
|
case 0:
|
||||||
snd_soc_component_update_bits(component,
|
snd_soc_component_update_bits(component,
|
||||||
@@ -2035,13 +2038,16 @@ static int wsa_macro_set_rx_mute_status(struct snd_kcontrol *kcontrol,
|
|||||||
default:
|
default:
|
||||||
pr_err("%s: invalid argument rx_shift = %d\n", __func__,
|
pr_err("%s: invalid argument rx_shift = %d\n", __func__,
|
||||||
wsa_rx_shift);
|
wsa_rx_shift);
|
||||||
return -EINVAL;
|
ret = -EINVAL;
|
||||||
}
|
}
|
||||||
|
pm_runtime_mark_last_busy(wsa_priv->dev);
|
||||||
|
pm_runtime_put_autosuspend(wsa_priv->dev);
|
||||||
|
|
||||||
dev_dbg(component->dev, "%s: WSA Digital Mute RX %d Enable %d\n",
|
dev_dbg(component->dev, "%s: WSA Digital Mute RX %d Enable %d\n",
|
||||||
__func__, wsa_rx_shift, value);
|
__func__, wsa_rx_shift, value);
|
||||||
wsa_priv->wsa_digital_mute_status[wsa_rx_shift] = value;
|
wsa_priv->wsa_digital_mute_status[wsa_rx_shift] = value;
|
||||||
return 0;
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int wsa_macro_get_compander(struct snd_kcontrol *kcontrol,
|
static int wsa_macro_get_compander(struct snd_kcontrol *kcontrol,
|
||||||
@@ -2370,12 +2376,12 @@ static const struct snd_kcontrol_new wsa_macro_snd_controls[] = {
|
|||||||
WSA_MACRO_SOFTCLIP1, 1, 0,
|
WSA_MACRO_SOFTCLIP1, 1, 0,
|
||||||
wsa_macro_soft_clip_enable_get,
|
wsa_macro_soft_clip_enable_get,
|
||||||
wsa_macro_soft_clip_enable_put),
|
wsa_macro_soft_clip_enable_put),
|
||||||
SOC_SINGLE_SX_TLV("WSA_RX0 Digital Volume",
|
SOC_SINGLE_S8_TLV("WSA_RX0 Digital Volume",
|
||||||
BOLERO_CDC_WSA_RX0_RX_VOL_CTL,
|
BOLERO_CDC_WSA_RX0_RX_VOL_CTL,
|
||||||
0, -84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("WSA_RX1 Digital Volume",
|
SOC_SINGLE_S8_TLV("WSA_RX1 Digital Volume",
|
||||||
BOLERO_CDC_WSA_RX1_RX_VOL_CTL,
|
BOLERO_CDC_WSA_RX1_RX_VOL_CTL,
|
||||||
0, -84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_EXT("WSA_RX0 Digital Mute", SND_SOC_NOPM, WSA_MACRO_RX0, 1,
|
SOC_SINGLE_EXT("WSA_RX0 Digital Mute", SND_SOC_NOPM, WSA_MACRO_RX0, 1,
|
||||||
0, wsa_macro_get_rx_mute_status,
|
0, wsa_macro_get_rx_mute_status,
|
||||||
wsa_macro_set_rx_mute_status),
|
wsa_macro_set_rx_mute_status),
|
||||||
@@ -2550,7 +2556,7 @@ static const struct snd_soc_dapm_widget wsa_macro_dapm_widgets[] = {
|
|||||||
SND_SOC_DAPM_MUX_E("WSA_RX0 INP2", SND_SOC_NOPM, 0, 0,
|
SND_SOC_DAPM_MUX_E("WSA_RX0 INP2", SND_SOC_NOPM, 0, 0,
|
||||||
&rx0_prim_inp2_mux, wsa_macro_enable_swr,
|
&rx0_prim_inp2_mux, wsa_macro_enable_swr,
|
||||||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
|
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
|
||||||
SND_SOC_DAPM_MUX_E("WSA_RX0 MIX INP", BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL,
|
SND_SOC_DAPM_MUX_E("WSA_RX0 MIX INP", SND_SOC_NOPM,
|
||||||
0, 0, &rx0_mix_mux, wsa_macro_enable_mix_path,
|
0, 0, &rx0_mix_mux, wsa_macro_enable_mix_path,
|
||||||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
|
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
|
||||||
SND_SOC_DAPM_MUX_E("WSA_RX1 INP0", SND_SOC_NOPM, 0, 0,
|
SND_SOC_DAPM_MUX_E("WSA_RX1 INP0", SND_SOC_NOPM, 0, 0,
|
||||||
@@ -2562,7 +2568,7 @@ static const struct snd_soc_dapm_widget wsa_macro_dapm_widgets[] = {
|
|||||||
SND_SOC_DAPM_MUX_E("WSA_RX1 INP2", SND_SOC_NOPM, 0, 0,
|
SND_SOC_DAPM_MUX_E("WSA_RX1 INP2", SND_SOC_NOPM, 0, 0,
|
||||||
&rx1_prim_inp2_mux, wsa_macro_enable_swr,
|
&rx1_prim_inp2_mux, wsa_macro_enable_swr,
|
||||||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
|
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
|
||||||
SND_SOC_DAPM_MUX_E("WSA_RX1 MIX INP", BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CTL,
|
SND_SOC_DAPM_MUX_E("WSA_RX1 MIX INP", SND_SOC_NOPM,
|
||||||
0, 0, &rx1_mix_mux, wsa_macro_enable_mix_path,
|
0, 0, &rx1_mix_mux, wsa_macro_enable_mix_path,
|
||||||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
|
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
|
||||||
SND_SOC_DAPM_MIXER_E("WSA_RX INT0 MIX", SND_SOC_NOPM,
|
SND_SOC_DAPM_MIXER_E("WSA_RX INT0 MIX", SND_SOC_NOPM,
|
||||||
@@ -3138,6 +3144,12 @@ static int wsa_macro_probe(struct platform_device *pdev)
|
|||||||
u32 is_used_wsa_swr_gpio = 1;
|
u32 is_used_wsa_swr_gpio = 1;
|
||||||
const char *is_used_wsa_swr_gpio_dt = "qcom,is-used-swr-gpio";
|
const char *is_used_wsa_swr_gpio_dt = "qcom,is-used-swr-gpio";
|
||||||
|
|
||||||
|
if (!bolero_is_va_macro_registered(&pdev->dev)) {
|
||||||
|
dev_err(&pdev->dev,
|
||||||
|
"%s: va-macro not registered yet, defer\n", __func__);
|
||||||
|
return -EPROBE_DEFER;
|
||||||
|
}
|
||||||
|
|
||||||
wsa_priv = devm_kzalloc(&pdev->dev, sizeof(struct wsa_macro_priv),
|
wsa_priv = devm_kzalloc(&pdev->dev, sizeof(struct wsa_macro_priv),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (!wsa_priv)
|
if (!wsa_priv)
|
||||||
@@ -3175,6 +3187,8 @@ static int wsa_macro_probe(struct platform_device *pdev)
|
|||||||
__func__);
|
__func__);
|
||||||
return -EPROBE_DEFER;
|
return -EPROBE_DEFER;
|
||||||
}
|
}
|
||||||
|
msm_cdc_pinctrl_set_wakeup_capable(
|
||||||
|
wsa_priv->wsa_swr_gpio_p, false);
|
||||||
|
|
||||||
wsa_io_base = devm_ioremap(&pdev->dev,
|
wsa_io_base = devm_ioremap(&pdev->dev,
|
||||||
wsa_base_addr, WSA_MACRO_MAX_OFFSET);
|
wsa_base_addr, WSA_MACRO_MAX_OFFSET);
|
||||||
@@ -3221,6 +3235,7 @@ static int wsa_macro_probe(struct platform_device *pdev)
|
|||||||
wsa_macro_init_ops(&ops, wsa_io_base);
|
wsa_macro_init_ops(&ops, wsa_io_base);
|
||||||
ops.clk_id_req = wsa_priv->default_clk_id;
|
ops.clk_id_req = wsa_priv->default_clk_id;
|
||||||
ops.default_clk_id = wsa_priv->default_clk_id;
|
ops.default_clk_id = wsa_priv->default_clk_id;
|
||||||
|
|
||||||
ret = bolero_register_macro(&pdev->dev, WSA_MACRO, &ops);
|
ret = bolero_register_macro(&pdev->dev, WSA_MACRO, &ops);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dev_err(&pdev->dev, "%s: register macro failed\n", __func__);
|
dev_err(&pdev->dev, "%s: register macro failed\n", __func__);
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
@@ -602,6 +602,25 @@ static const struct snd_soc_dapm_route csra66x0_dapm_routes[] = {
|
|||||||
{"PGA", NULL, "DAC"},
|
{"PGA", NULL, "DAC"},
|
||||||
{"SPKR", NULL, "PGA"},
|
{"SPKR", NULL, "PGA"},
|
||||||
};
|
};
|
||||||
|
/*
|
||||||
|
* csra66x0_hw_free_mute - Update csra66x0 mute register
|
||||||
|
*
|
||||||
|
* @component - csra66x0 component
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void csra66x0_hw_free_mute(struct snd_soc_component *component)
|
||||||
|
{
|
||||||
|
int val = 0;
|
||||||
|
|
||||||
|
if (component == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
val = snd_soc_component_read32(component,
|
||||||
|
CSRA66X0_MISC_CONTROL_STATUS_1_FA);
|
||||||
|
snd_soc_component_write(component, CSRA66X0_MISC_CONTROL_STATUS_1_FA,
|
||||||
|
val | 0x04);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(csra66x0_hw_free_mute);
|
||||||
|
|
||||||
static int csra66x0_wait_for_config_state(struct snd_soc_component *component)
|
static int csra66x0_wait_for_config_state(struct snd_soc_component *component)
|
||||||
{
|
{
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _CSRA66X0_H
|
#ifndef _CSRA66X0_H
|
||||||
@@ -226,4 +226,6 @@
|
|||||||
#define FAULT_STATUS_TEMP 0x10
|
#define FAULT_STATUS_TEMP 0x10
|
||||||
#define FAULT_STATUS_PROTECT 0x20
|
#define FAULT_STATUS_PROTECT 0x20
|
||||||
|
|
||||||
|
|
||||||
|
void csra66x0_hw_free_mute(struct snd_soc_component *component);
|
||||||
#endif /* _CSRA66X0_H */
|
#endif /* _CSRA66X0_H */
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
@@ -40,6 +40,10 @@ static const unsigned int ep92_samp_freq_table[8] = {
|
|||||||
32000, 44100, 48000, 88200, 96000, 176400, 192000, 768000
|
32000, 44100, 48000, 88200, 96000, 176400, 192000, 768000
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const unsigned int ep92_dsd_freq_table[4] = {
|
||||||
|
64, 128, 256, 0
|
||||||
|
};
|
||||||
|
|
||||||
static bool ep92_volatile_register(struct device *dev, unsigned int reg)
|
static bool ep92_volatile_register(struct device *dev, unsigned int reg)
|
||||||
{
|
{
|
||||||
/* do not cache register state in regmap */
|
/* do not cache register state in regmap */
|
||||||
@@ -549,6 +553,23 @@ static void ep92_read_audio_info(struct snd_soc_component *component,
|
|||||||
send_uevent = true;
|
send_uevent = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
old = ep92->ai.system_status_1;
|
||||||
|
ep92->ai.system_status_1 = snd_soc_read(codec,
|
||||||
|
EP92_AUDIO_INFO_SYSTEM_STATUS_1);
|
||||||
|
if (ep92->ai.system_status_1 == 0xff) {
|
||||||
|
dev_dbg(codec->dev,
|
||||||
|
"ep92 EP92_AUDIO_INFO_SYSTEM_STATUS_1 read 0xff\n");
|
||||||
|
ep92->ai.system_status_1 = old;
|
||||||
|
}
|
||||||
|
change = ep92->ai.system_status_1 ^ old;
|
||||||
|
if (change & EP92_AI_DSD_RATE_MASK) {
|
||||||
|
dev_dbg(codec->dev, "ep92 dsd rate changed to %d\n",
|
||||||
|
ep92_dsd_freq_table[(ep92->ai.system_status_1 &
|
||||||
|
EP92_AI_DSD_RATE_MASK)
|
||||||
|
>> EP92_AI_DSD_RATE_SHIFT]);
|
||||||
|
send_uevent = true;
|
||||||
|
}
|
||||||
|
|
||||||
old = ep92->ai.audio_status;
|
old = ep92->ai.audio_status;
|
||||||
ep92->ai.audio_status = snd_soc_component_read32(component,
|
ep92->ai.audio_status = snd_soc_component_read32(component,
|
||||||
EP92_AUDIO_INFO_AUDIO_STATUS);
|
EP92_AUDIO_INFO_AUDIO_STATUS);
|
||||||
@@ -580,7 +601,9 @@ static void ep92_read_audio_info(struct snd_soc_component *component,
|
|||||||
}
|
}
|
||||||
|
|
||||||
new_mode = ep92->old_mode;
|
new_mode = ep92->old_mode;
|
||||||
if (ep92->ai.audio_status & EP92_AI_STD_ADO_MASK) {
|
if (ep92->ai.audio_status & EP92_AI_DSD_ADO_MASK)
|
||||||
|
new_mode = 2; /* One bit audio */
|
||||||
|
else if (ep92->ai.audio_status & EP92_AI_STD_ADO_MASK) {
|
||||||
if (ep92->ai.cs[0] & EP92_AI_NPCM_MASK)
|
if (ep92->ai.cs[0] & EP92_AI_NPCM_MASK)
|
||||||
new_mode = 1; /* Compr */
|
new_mode = 1; /* Compr */
|
||||||
else
|
else
|
||||||
@@ -897,6 +920,27 @@ static ssize_t ep92_sysfs_rda_audio_format(struct device *dev,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ssize_t ep92_sysfs_rda_dsd_rate(struct device *dev,
|
||||||
|
struct device_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
ssize_t ret = 0;
|
||||||
|
int val;
|
||||||
|
struct ep92_pdata *ep92 = dev_get_drvdata(dev);
|
||||||
|
|
||||||
|
if (!ep92 || !ep92->codec) {
|
||||||
|
dev_err(dev, "%s: device error\n", __func__);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
val = ep92_dsd_freq_table[(ep92->ai.system_status_1 &
|
||||||
|
EP92_AI_DSD_RATE_MASK) >> EP92_AI_DSD_RATE_SHIFT];
|
||||||
|
|
||||||
|
ret = snprintf(buf, EP92_SYSFS_ENTRY_MAX_LEN, "%d\n", val);
|
||||||
|
dev_dbg(dev, "%s: '%d'\n", __func__, val);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static ssize_t ep92_sysfs_rda_audio_rate(struct device *dev,
|
static ssize_t ep92_sysfs_rda_audio_rate(struct device *dev,
|
||||||
struct device_attribute *attr, char *buf)
|
struct device_attribute *attr, char *buf)
|
||||||
{
|
{
|
||||||
@@ -1621,6 +1665,7 @@ static DEVICE_ATTR(cec_volume, 0644, ep92_sysfs_rda_cec_volume,
|
|||||||
static DEVICE_ATTR(runout, 0444, ep92_sysfs_rda_runout, NULL);
|
static DEVICE_ATTR(runout, 0444, ep92_sysfs_rda_runout, NULL);
|
||||||
static DEVICE_ATTR(force_inactive, 0644, ep92_sysfs_rda_force_inactive,
|
static DEVICE_ATTR(force_inactive, 0644, ep92_sysfs_rda_force_inactive,
|
||||||
ep92_sysfs_wta_force_inactive);
|
ep92_sysfs_wta_force_inactive);
|
||||||
|
static DEVICE_ATTR(dsd_rate, 0444, ep92_sysfs_rda_dsd_rate, NULL);
|
||||||
|
|
||||||
static struct attribute *ep92_fs_attrs[] = {
|
static struct attribute *ep92_fs_attrs[] = {
|
||||||
&dev_attr_chipid.attr,
|
&dev_attr_chipid.attr,
|
||||||
@@ -1647,6 +1692,7 @@ static struct attribute *ep92_fs_attrs[] = {
|
|||||||
&dev_attr_cec_volume.attr,
|
&dev_attr_cec_volume.attr,
|
||||||
&dev_attr_runout.attr,
|
&dev_attr_runout.attr,
|
||||||
&dev_attr_force_inactive.attr,
|
&dev_attr_force_inactive.attr,
|
||||||
|
&dev_attr_dsd_rate.attr,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __EP92_H__
|
#ifndef __EP92_H__
|
||||||
@@ -175,6 +175,10 @@ static struct reg_default ep92_reg_defaults[] = {
|
|||||||
#define EP92_AI_PREEMPH_MASK 0x38
|
#define EP92_AI_PREEMPH_MASK 0x38
|
||||||
#define EP92_AI_CH_COUNT_MASK 0x07
|
#define EP92_AI_CH_COUNT_MASK 0x07
|
||||||
#define EP92_AI_CH_ALLOC_MASK 0xff
|
#define EP92_AI_CH_ALLOC_MASK 0xff
|
||||||
|
#define EP92_AI_DSD_ADO_SHIFT 4
|
||||||
|
#define EP92_AI_DSD_ADO_MASK 0x10
|
||||||
|
#define EP92_AI_DSD_RATE_SHIFT 4
|
||||||
|
#define EP92_AI_DSD_RATE_MASK 0x30
|
||||||
|
|
||||||
#define EP92_2CHOICE_MASK 1
|
#define EP92_2CHOICE_MASK 1
|
||||||
#define EP92_GC_CEC_VOLUME_MIN 0
|
#define EP92_GC_CEC_VOLUME_MIN 0
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
|
/* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
@@ -21,6 +21,7 @@ struct msm_cdc_pinctrl_info {
|
|||||||
struct pinctrl *pinctrl;
|
struct pinctrl *pinctrl;
|
||||||
struct pinctrl_state *pinctrl_active;
|
struct pinctrl_state *pinctrl_active;
|
||||||
struct pinctrl_state *pinctrl_sleep;
|
struct pinctrl_state *pinctrl_sleep;
|
||||||
|
struct pinctrl_state *pinctrl_alt_active;
|
||||||
int gpio;
|
int gpio;
|
||||||
bool state;
|
bool state;
|
||||||
u32 tlmm_gpio[MAX_GPIOS];
|
u32 tlmm_gpio[MAX_GPIOS];
|
||||||
@@ -104,6 +105,31 @@ int msm_cdc_pinctrl_select_sleep_state(struct device_node *np)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(msm_cdc_pinctrl_select_sleep_state);
|
EXPORT_SYMBOL(msm_cdc_pinctrl_select_sleep_state);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* msm_cdc_pinctrl_select_alt_active_state: select pinctrl alt_active state
|
||||||
|
* @np: pointer to struct device_node
|
||||||
|
*
|
||||||
|
* Returns error code for failure
|
||||||
|
*/
|
||||||
|
int msm_cdc_pinctrl_select_alt_active_state(struct device_node *np)
|
||||||
|
{
|
||||||
|
struct msm_cdc_pinctrl_info *gpio_data;
|
||||||
|
|
||||||
|
gpio_data = msm_cdc_pinctrl_get_gpiodata(np);
|
||||||
|
if (!gpio_data)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (!gpio_data->pinctrl_alt_active) {
|
||||||
|
pr_err("%s: pinctrl alt_active state is null\n", __func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
gpio_data->state = true;
|
||||||
|
|
||||||
|
return pinctrl_select_state(gpio_data->pinctrl,
|
||||||
|
gpio_data->pinctrl_alt_active);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(msm_cdc_pinctrl_select_alt_active_state);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* msm_cdc_pinctrl_select_active_state: select pinctrl active state
|
* msm_cdc_pinctrl_select_active_state: select pinctrl active state
|
||||||
* @np: pointer to struct device_node
|
* @np: pointer to struct device_node
|
||||||
@@ -231,6 +257,14 @@ static int msm_cdc_pinctrl_probe(struct platform_device *pdev)
|
|||||||
ret = PTR_ERR(gpio_data->pinctrl_sleep);
|
ret = PTR_ERR(gpio_data->pinctrl_sleep);
|
||||||
goto err_lookup_state;
|
goto err_lookup_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gpio_data->pinctrl_alt_active = pinctrl_lookup_state(
|
||||||
|
gpio_data->pinctrl, "aud_alt_active");
|
||||||
|
if (IS_ERR_OR_NULL(gpio_data->pinctrl_alt_active)) {
|
||||||
|
dev_dbg(&pdev->dev, "%s: Cannot get aud_alt_active pinctrl state:%ld\n",
|
||||||
|
__func__, PTR_ERR(gpio_data->pinctrl_alt_active));
|
||||||
|
}
|
||||||
|
|
||||||
/* skip setting to sleep state for LPI_TLMM GPIOs */
|
/* skip setting to sleep state for LPI_TLMM GPIOs */
|
||||||
if (!of_property_read_bool(pdev->dev.of_node, "qcom,lpi-gpios")) {
|
if (!of_property_read_bool(pdev->dev.of_node, "qcom,lpi-gpios")) {
|
||||||
/* Set pinctrl state to aud_sleep by default */
|
/* Set pinctrl state to aud_sleep by default */
|
||||||
|
@@ -60,9 +60,22 @@ static int msm_cdc_dt_parse_vreg_info(struct device *dev,
|
|||||||
}
|
}
|
||||||
cdc_vreg->optimum_uA = prop_val;
|
cdc_vreg->optimum_uA = prop_val;
|
||||||
|
|
||||||
dev_info(dev, "%s: %s: vol=[%d %d]uV, curr=[%d]uA, ond %d\n",
|
/* Parse supply - LPM or NOM mode(default NOM) */
|
||||||
|
snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE, "qcom,%s-lpm-supported", name);
|
||||||
|
rc = of_property_read_u32(dev->of_node, prop_name, &prop_val);
|
||||||
|
if (rc) {
|
||||||
|
dev_dbg(dev, "%s: Looking up %s property in node %s failed",
|
||||||
|
__func__, prop_name, dev->of_node->full_name);
|
||||||
|
cdc_vreg->lpm_supported = 0;
|
||||||
|
rc = 0;
|
||||||
|
} else {
|
||||||
|
cdc_vreg->lpm_supported = prop_val;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev_info(dev, "%s: %s: vol=[%d %d]uV, curr=[%d]uA, ond %d lpm %d\n",
|
||||||
__func__, cdc_vreg->name, cdc_vreg->min_uV, cdc_vreg->max_uV,
|
__func__, cdc_vreg->name, cdc_vreg->min_uV, cdc_vreg->max_uV,
|
||||||
cdc_vreg->optimum_uA, cdc_vreg->ondemand);
|
cdc_vreg->optimum_uA, cdc_vreg->ondemand,
|
||||||
|
cdc_vreg->lpm_supported);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
return rc;
|
return rc;
|
||||||
@@ -260,6 +273,59 @@ int msm_cdc_enable_ondemand_supply(struct device *dev,
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(msm_cdc_enable_ondemand_supply);
|
EXPORT_SYMBOL(msm_cdc_enable_ondemand_supply);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* msm_cdc_set_supplies_lpm_mode:
|
||||||
|
* Update load for given supply string
|
||||||
|
*
|
||||||
|
* @dev: pointer to codec device
|
||||||
|
* @supplies: pointer to regulator bulk data
|
||||||
|
* @cdc_vreg: pointer to platform regulator data
|
||||||
|
* @num_supplies: number of supplies
|
||||||
|
* @supply_name: supply name to be checked
|
||||||
|
* @min_max: Apply optimum or 0 current
|
||||||
|
*
|
||||||
|
* Return error code if set current fail
|
||||||
|
*/
|
||||||
|
int msm_cdc_set_supplies_lpm_mode(struct device *dev,
|
||||||
|
struct regulator_bulk_data *supplies,
|
||||||
|
struct cdc_regulator *cdc_vreg,
|
||||||
|
int num_supplies,
|
||||||
|
bool flag)
|
||||||
|
{
|
||||||
|
int rc = 0, i;
|
||||||
|
|
||||||
|
if (!supplies) {
|
||||||
|
pr_err("%s: supplies is NULL\n",
|
||||||
|
__func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
/* input parameter validation */
|
||||||
|
rc = msm_cdc_check_supply_param(dev, cdc_vreg, num_supplies);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
for (i = 0; i < num_supplies; i++) {
|
||||||
|
if (cdc_vreg[i].lpm_supported) {
|
||||||
|
rc = regulator_set_load(
|
||||||
|
supplies[i].consumer,
|
||||||
|
flag ? 0 : cdc_vreg[i].optimum_uA);
|
||||||
|
if (rc)
|
||||||
|
dev_err(dev,
|
||||||
|
"%s: failed to set supply %s to %s, err:%d\n",
|
||||||
|
__func__, supplies[i].supply,
|
||||||
|
flag ? "LPM" : "NOM",
|
||||||
|
rc);
|
||||||
|
else
|
||||||
|
dev_dbg(dev, "%s: regulator %s load set to %s\n",
|
||||||
|
__func__, supplies[i].supply,
|
||||||
|
flag ? "LPM" : "NOM");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(msm_cdc_set_supplies_lpm_mode);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* msm_cdc_disable_static_supplies:
|
* msm_cdc_disable_static_supplies:
|
||||||
* Disable codec static supplies
|
* Disable codec static supplies
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
|
/* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
@@ -25,8 +25,8 @@
|
|||||||
static SOC_ENUM_SINGLE_DECL(ext_disp_audio_ack_state##index, \
|
static SOC_ENUM_SINGLE_DECL(ext_disp_audio_ack_state##index, \
|
||||||
SND_SOC_NOPM, index, ext_disp_audio_ack_text)
|
SND_SOC_NOPM, index, ext_disp_audio_ack_text)
|
||||||
|
|
||||||
#define SWITCH_DP_CODEC(codec_info, codec_data, dai_id) \
|
#define SWITCH_DP_CODEC(codec_info, codec_data, dai_id, type) \
|
||||||
codec_info.type = EXT_DISPLAY_TYPE_DP; \
|
codec_info.type = type; \
|
||||||
codec_info.ctrl_id = codec_data->ctl[dai_id]; \
|
codec_info.ctrl_id = codec_data->ctl[dai_id]; \
|
||||||
codec_info.stream_id = codec_data->stream[dai_id]; \
|
codec_info.stream_id = codec_data->stream[dai_id]; \
|
||||||
|
|
||||||
@@ -38,6 +38,7 @@ enum {
|
|||||||
enum {
|
enum {
|
||||||
DP_STREAM0 = 0,
|
DP_STREAM0 = 0,
|
||||||
DP_STREAM1,
|
DP_STREAM1,
|
||||||
|
HDMI,
|
||||||
DP_STREAM_MAX,
|
DP_STREAM_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -49,6 +50,7 @@ enum {
|
|||||||
DP_DAI1 = 1,
|
DP_DAI1 = 1,
|
||||||
DP_DAI2,
|
DP_DAI2,
|
||||||
HDMI_DAI,
|
HDMI_DAI,
|
||||||
|
HDMI_MS_DAI,
|
||||||
DP_DAI_MAX,
|
DP_DAI_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -60,6 +62,8 @@ SOC_EXT_DISP_AUDIO_TYPE(1);
|
|||||||
SOC_EXT_DISP_AUDIO_ACK_STATE(1);
|
SOC_EXT_DISP_AUDIO_ACK_STATE(1);
|
||||||
SOC_EXT_DISP_AUDIO_TYPE(2);
|
SOC_EXT_DISP_AUDIO_TYPE(2);
|
||||||
SOC_EXT_DISP_AUDIO_ACK_STATE(2);
|
SOC_EXT_DISP_AUDIO_ACK_STATE(2);
|
||||||
|
SOC_EXT_DISP_AUDIO_TYPE(3);
|
||||||
|
SOC_EXT_DISP_AUDIO_ACK_STATE(3);
|
||||||
|
|
||||||
struct msm_ext_disp_audio_codec_rx_data {
|
struct msm_ext_disp_audio_codec_rx_data {
|
||||||
struct platform_device *ext_disp_core_pdev;
|
struct platform_device *ext_disp_core_pdev;
|
||||||
@@ -80,6 +84,7 @@ static int msm_ext_disp_edid_ctl_info(struct snd_kcontrol *kcontrol,
|
|||||||
int rc = 0;
|
int rc = 0;
|
||||||
struct msm_ext_disp_codec_id codec_info;
|
struct msm_ext_disp_codec_id codec_info;
|
||||||
int dai_id = kcontrol->private_value;
|
int dai_id = kcontrol->private_value;
|
||||||
|
int type;
|
||||||
|
|
||||||
codec_data = snd_soc_component_get_drvdata(component);
|
codec_data = snd_soc_component_get_drvdata(component);
|
||||||
if (!codec_data) {
|
if (!codec_data) {
|
||||||
@@ -91,7 +96,11 @@ static int msm_ext_disp_edid_ctl_info(struct snd_kcontrol *kcontrol,
|
|||||||
codec_data->ctl[dai_id], codec_data->stream[dai_id]);
|
codec_data->ctl[dai_id], codec_data->stream[dai_id]);
|
||||||
|
|
||||||
mutex_lock(&codec_data->dp_ops_lock);
|
mutex_lock(&codec_data->dp_ops_lock);
|
||||||
SWITCH_DP_CODEC(codec_info, codec_data, dai_id);
|
if (dai_id == HDMI_MS_DAI)
|
||||||
|
type = EXT_DISPLAY_TYPE_HDMI;
|
||||||
|
else
|
||||||
|
type = EXT_DISPLAY_TYPE_DP;
|
||||||
|
SWITCH_DP_CODEC(codec_info, codec_data, dai_id, type);
|
||||||
rc = msm_ext_disp_select_audio_codec(codec_data->ext_disp_core_pdev,
|
rc = msm_ext_disp_select_audio_codec(codec_data->ext_disp_core_pdev,
|
||||||
&codec_info);
|
&codec_info);
|
||||||
if (!codec_data->ext_disp_ops.get_audio_edid_blk || rc) {
|
if (!codec_data->ext_disp_ops.get_audio_edid_blk || rc) {
|
||||||
@@ -126,6 +135,7 @@ static int msm_ext_disp_edid_get(struct snd_kcontrol *kcontrol,
|
|||||||
struct msm_ext_disp_codec_id codec_info;
|
struct msm_ext_disp_codec_id codec_info;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
int dai_id = kcontrol->private_value;
|
int dai_id = kcontrol->private_value;
|
||||||
|
int type;
|
||||||
|
|
||||||
codec_data = snd_soc_component_get_drvdata(component);
|
codec_data = snd_soc_component_get_drvdata(component);
|
||||||
if (!codec_data) {
|
if (!codec_data) {
|
||||||
@@ -138,7 +148,11 @@ static int msm_ext_disp_edid_get(struct snd_kcontrol *kcontrol,
|
|||||||
codec_data->ctl[dai_id], codec_data->stream[dai_id]);
|
codec_data->ctl[dai_id], codec_data->stream[dai_id]);
|
||||||
|
|
||||||
mutex_lock(&codec_data->dp_ops_lock);
|
mutex_lock(&codec_data->dp_ops_lock);
|
||||||
SWITCH_DP_CODEC(codec_info, codec_data, dai_id);
|
if (dai_id == HDMI_MS_DAI)
|
||||||
|
type = EXT_DISPLAY_TYPE_HDMI;
|
||||||
|
else
|
||||||
|
type = EXT_DISPLAY_TYPE_DP;
|
||||||
|
SWITCH_DP_CODEC(codec_info, codec_data, dai_id, type);
|
||||||
rc = msm_ext_disp_select_audio_codec(codec_data->ext_disp_core_pdev,
|
rc = msm_ext_disp_select_audio_codec(codec_data->ext_disp_core_pdev,
|
||||||
&codec_info);
|
&codec_info);
|
||||||
if (!codec_data->ext_disp_ops.get_audio_edid_blk || rc) {
|
if (!codec_data->ext_disp_ops.get_audio_edid_blk || rc) {
|
||||||
@@ -147,7 +161,6 @@ static int msm_ext_disp_edid_get(struct snd_kcontrol *kcontrol,
|
|||||||
mutex_unlock(&codec_data->dp_ops_lock);
|
mutex_unlock(&codec_data->dp_ops_lock);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = codec_data->ext_disp_ops.get_audio_edid_blk(
|
rc = codec_data->ext_disp_ops.get_audio_edid_blk(
|
||||||
codec_data->ext_disp_core_pdev, &edid_blk);
|
codec_data->ext_disp_core_pdev, &edid_blk);
|
||||||
mutex_unlock(&codec_data->dp_ops_lock);
|
mutex_unlock(&codec_data->dp_ops_lock);
|
||||||
@@ -188,6 +201,7 @@ static int msm_ext_disp_audio_type_get(struct snd_kcontrol *kcontrol,
|
|||||||
struct msm_ext_disp_codec_id codec_info;
|
struct msm_ext_disp_codec_id codec_info;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
int dai_id = ((struct soc_enum *) kcontrol->private_value)->shift_l;
|
int dai_id = ((struct soc_enum *) kcontrol->private_value)->shift_l;
|
||||||
|
int type;
|
||||||
|
|
||||||
codec_data = snd_soc_component_get_drvdata(component);
|
codec_data = snd_soc_component_get_drvdata(component);
|
||||||
if (!codec_data) {
|
if (!codec_data) {
|
||||||
@@ -200,7 +214,11 @@ static int msm_ext_disp_audio_type_get(struct snd_kcontrol *kcontrol,
|
|||||||
codec_data->ctl[dai_id], codec_data->stream[dai_id]);
|
codec_data->ctl[dai_id], codec_data->stream[dai_id]);
|
||||||
|
|
||||||
mutex_lock(&codec_data->dp_ops_lock);
|
mutex_lock(&codec_data->dp_ops_lock);
|
||||||
SWITCH_DP_CODEC(codec_info, codec_data, dai_id);
|
if (dai_id == HDMI_MS_DAI)
|
||||||
|
type = EXT_DISPLAY_TYPE_HDMI;
|
||||||
|
else
|
||||||
|
type = EXT_DISPLAY_TYPE_DP;
|
||||||
|
SWITCH_DP_CODEC(codec_info, codec_data, dai_id, type);
|
||||||
rc = msm_ext_disp_select_audio_codec(codec_data->ext_disp_core_pdev,
|
rc = msm_ext_disp_select_audio_codec(codec_data->ext_disp_core_pdev,
|
||||||
&codec_info);
|
&codec_info);
|
||||||
|
|
||||||
@@ -274,6 +292,7 @@ static int msm_ext_disp_audio_ack_set(struct snd_kcontrol *kcontrol,
|
|||||||
struct msm_ext_disp_codec_id codec_info;
|
struct msm_ext_disp_codec_id codec_info;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
int dai_id = ((struct soc_enum *) kcontrol->private_value)->shift_l;
|
int dai_id = ((struct soc_enum *) kcontrol->private_value)->shift_l;
|
||||||
|
int type;
|
||||||
|
|
||||||
codec_data = snd_soc_component_get_drvdata(component);
|
codec_data = snd_soc_component_get_drvdata(component);
|
||||||
if (!codec_data) {
|
if (!codec_data) {
|
||||||
@@ -287,7 +306,11 @@ static int msm_ext_disp_audio_ack_set(struct snd_kcontrol *kcontrol,
|
|||||||
codec_data->ctl[dai_id], codec_data->stream[dai_id]);
|
codec_data->ctl[dai_id], codec_data->stream[dai_id]);
|
||||||
|
|
||||||
mutex_lock(&codec_data->dp_ops_lock);
|
mutex_lock(&codec_data->dp_ops_lock);
|
||||||
SWITCH_DP_CODEC(codec_info, codec_data, dai_id);
|
if (dai_id == HDMI_MS_DAI)
|
||||||
|
type = EXT_DISPLAY_TYPE_HDMI;
|
||||||
|
else
|
||||||
|
type = EXT_DISPLAY_TYPE_DP;
|
||||||
|
SWITCH_DP_CODEC(codec_info, codec_data, dai_id, type);
|
||||||
rc = msm_ext_disp_select_audio_codec(codec_data->ext_disp_core_pdev,
|
rc = msm_ext_disp_select_audio_codec(codec_data->ext_disp_core_pdev,
|
||||||
&codec_info);
|
&codec_info);
|
||||||
|
|
||||||
@@ -421,6 +444,15 @@ static const struct snd_kcontrol_new msm_ext_disp_codec_rx_controls[] = {
|
|||||||
.get = msm_ext_disp_edid_get,
|
.get = msm_ext_disp_edid_get,
|
||||||
.private_value = HDMI_DAI,
|
.private_value = HDMI_DAI,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.access = SNDRV_CTL_ELEM_ACCESS_READ |
|
||||||
|
SNDRV_CTL_ELEM_ACCESS_VOLATILE,
|
||||||
|
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
|
||||||
|
.name = "HDMI MS EDID",
|
||||||
|
.info = msm_ext_disp_edid_ctl_info,
|
||||||
|
.get = msm_ext_disp_edid_get,
|
||||||
|
.private_value = HDMI_MS_DAI,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
.access = SNDRV_CTL_ELEM_ACCESS_READ |
|
.access = SNDRV_CTL_ELEM_ACCESS_READ |
|
||||||
SNDRV_CTL_ELEM_ACCESS_VOLATILE,
|
SNDRV_CTL_ELEM_ACCESS_VOLATILE,
|
||||||
@@ -445,12 +477,18 @@ static const struct snd_kcontrol_new msm_ext_disp_codec_rx_controls[] = {
|
|||||||
SOC_ENUM_EXT("External Display1 Type",
|
SOC_ENUM_EXT("External Display1 Type",
|
||||||
ext_disp_audio_type2,
|
ext_disp_audio_type2,
|
||||||
msm_ext_disp_audio_type_get, NULL),
|
msm_ext_disp_audio_type_get, NULL),
|
||||||
|
SOC_ENUM_EXT("External HDMI Type",
|
||||||
|
ext_disp_audio_type3,
|
||||||
|
msm_ext_disp_audio_type_get, NULL),
|
||||||
SOC_ENUM_EXT("External Display Audio Ack",
|
SOC_ENUM_EXT("External Display Audio Ack",
|
||||||
ext_disp_audio_ack_state1,
|
ext_disp_audio_ack_state1,
|
||||||
NULL, msm_ext_disp_audio_ack_set),
|
NULL, msm_ext_disp_audio_ack_set),
|
||||||
SOC_ENUM_EXT("External Display1 Audio Ack",
|
SOC_ENUM_EXT("External Display1 Audio Ack",
|
||||||
ext_disp_audio_ack_state2,
|
ext_disp_audio_ack_state2,
|
||||||
NULL, msm_ext_disp_audio_ack_set),
|
NULL, msm_ext_disp_audio_ack_set),
|
||||||
|
SOC_ENUM_EXT("External HDMI Audio Ack",
|
||||||
|
ext_disp_audio_ack_state3,
|
||||||
|
NULL, msm_ext_disp_audio_ack_set),
|
||||||
|
|
||||||
SOC_SINGLE_MULTI_EXT("External Display Audio Device",
|
SOC_SINGLE_MULTI_EXT("External Display Audio Device",
|
||||||
SND_SOC_NOPM, DP_DAI1, DP_STREAM_MAX - 1, 0, 2,
|
SND_SOC_NOPM, DP_DAI1, DP_STREAM_MAX - 1, 0, 2,
|
||||||
@@ -460,6 +498,11 @@ static const struct snd_kcontrol_new msm_ext_disp_codec_rx_controls[] = {
|
|||||||
SND_SOC_NOPM, DP_DAI2, DP_STREAM_MAX - 1, 0, 2,
|
SND_SOC_NOPM, DP_DAI2, DP_STREAM_MAX - 1, 0, 2,
|
||||||
msm_ext_disp_audio_device_get,
|
msm_ext_disp_audio_device_get,
|
||||||
msm_ext_disp_audio_device_set),
|
msm_ext_disp_audio_device_set),
|
||||||
|
SOC_SINGLE_MULTI_EXT("External HDMI Device",
|
||||||
|
SND_SOC_NOPM, HDMI_MS_DAI, DP_STREAM_MAX - 1, 0, 2,
|
||||||
|
msm_ext_disp_audio_device_get,
|
||||||
|
msm_ext_disp_audio_device_set),
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int msm_ext_disp_audio_codec_rx_dai_startup(
|
static int msm_ext_disp_audio_codec_rx_dai_startup(
|
||||||
@@ -470,6 +513,7 @@ static int msm_ext_disp_audio_codec_rx_dai_startup(
|
|||||||
struct msm_ext_disp_codec_id codec_info;
|
struct msm_ext_disp_codec_id codec_info;
|
||||||
struct msm_ext_disp_audio_codec_rx_data *codec_data =
|
struct msm_ext_disp_audio_codec_rx_data *codec_data =
|
||||||
dev_get_drvdata(dai->component->dev);
|
dev_get_drvdata(dai->component->dev);
|
||||||
|
int type;
|
||||||
|
|
||||||
if (!codec_data) {
|
if (!codec_data) {
|
||||||
dev_err(dai->dev, "%s() codec_data is null\n",
|
dev_err(dai->dev, "%s() codec_data is null\n",
|
||||||
@@ -482,7 +526,11 @@ static int msm_ext_disp_audio_codec_rx_dai_startup(
|
|||||||
codec_data->ctl[dai->id], codec_data->stream[dai->id]);
|
codec_data->ctl[dai->id], codec_data->stream[dai->id]);
|
||||||
|
|
||||||
mutex_lock(&codec_data->dp_ops_lock);
|
mutex_lock(&codec_data->dp_ops_lock);
|
||||||
SWITCH_DP_CODEC(codec_info, codec_data, dai->id);
|
if (dai->id == HDMI_MS_DAI)
|
||||||
|
type = EXT_DISPLAY_TYPE_HDMI;
|
||||||
|
else
|
||||||
|
type = EXT_DISPLAY_TYPE_DP;
|
||||||
|
SWITCH_DP_CODEC(codec_info, codec_data, dai->id, type);
|
||||||
rc = msm_ext_disp_select_audio_codec(codec_data->ext_disp_core_pdev,
|
rc = msm_ext_disp_select_audio_codec(codec_data->ext_disp_core_pdev,
|
||||||
&codec_info);
|
&codec_info);
|
||||||
|
|
||||||
@@ -524,7 +572,7 @@ static int msm_ext_disp_audio_codec_rx_dai_hw_params(
|
|||||||
struct msm_ext_disp_codec_id codec_info;
|
struct msm_ext_disp_codec_id codec_info;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
struct msm_ext_disp_audio_setup_params audio_setup_params = {0};
|
struct msm_ext_disp_audio_setup_params audio_setup_params = {0};
|
||||||
|
int type;
|
||||||
struct msm_ext_disp_audio_codec_rx_data *codec_data =
|
struct msm_ext_disp_audio_codec_rx_data *codec_data =
|
||||||
dev_get_drvdata(dai->component->dev);
|
dev_get_drvdata(dai->component->dev);
|
||||||
|
|
||||||
@@ -539,7 +587,11 @@ static int msm_ext_disp_audio_codec_rx_dai_hw_params(
|
|||||||
codec_data->ctl[dai->id], codec_data->stream[dai->id]);
|
codec_data->ctl[dai->id], codec_data->stream[dai->id]);
|
||||||
|
|
||||||
mutex_lock(&codec_data->dp_ops_lock);
|
mutex_lock(&codec_data->dp_ops_lock);
|
||||||
SWITCH_DP_CODEC(codec_info, codec_data, dai->id);
|
if (dai->id == HDMI_MS_DAI)
|
||||||
|
type = EXT_DISPLAY_TYPE_HDMI;
|
||||||
|
else
|
||||||
|
type = EXT_DISPLAY_TYPE_DP;
|
||||||
|
SWITCH_DP_CODEC(codec_info, codec_data, dai->id, type);
|
||||||
rc = msm_ext_disp_select_audio_codec(codec_data->ext_disp_core_pdev,
|
rc = msm_ext_disp_select_audio_codec(codec_data->ext_disp_core_pdev,
|
||||||
&codec_info);
|
&codec_info);
|
||||||
|
|
||||||
@@ -609,7 +661,7 @@ static int msm_ext_disp_audio_codec_rx_dai_hw_params(
|
|||||||
audio_setup_params.down_mix = down_mix;
|
audio_setup_params.down_mix = down_mix;
|
||||||
|
|
||||||
mutex_lock(&codec_data->dp_ops_lock);
|
mutex_lock(&codec_data->dp_ops_lock);
|
||||||
SWITCH_DP_CODEC(codec_info, codec_data, dai->id);
|
SWITCH_DP_CODEC(codec_info, codec_data, dai->id, type);
|
||||||
rc = msm_ext_disp_select_audio_codec(codec_data->ext_disp_core_pdev,
|
rc = msm_ext_disp_select_audio_codec(codec_data->ext_disp_core_pdev,
|
||||||
&codec_info);
|
&codec_info);
|
||||||
if (rc)
|
if (rc)
|
||||||
@@ -636,6 +688,7 @@ static void msm_ext_disp_audio_codec_rx_dai_shutdown(
|
|||||||
|
|
||||||
struct msm_ext_disp_audio_codec_rx_data *codec_data =
|
struct msm_ext_disp_audio_codec_rx_data *codec_data =
|
||||||
dev_get_drvdata(dai->component->dev);
|
dev_get_drvdata(dai->component->dev);
|
||||||
|
int type;
|
||||||
|
|
||||||
if (!codec_data) {
|
if (!codec_data) {
|
||||||
dev_err(dai->dev, "%s() codec_data is null\n",
|
dev_err(dai->dev, "%s() codec_data is null\n",
|
||||||
@@ -648,7 +701,11 @@ static void msm_ext_disp_audio_codec_rx_dai_shutdown(
|
|||||||
codec_data->ctl[dai->id], codec_data->stream[dai->id]);
|
codec_data->ctl[dai->id], codec_data->stream[dai->id]);
|
||||||
|
|
||||||
mutex_lock(&codec_data->dp_ops_lock);
|
mutex_lock(&codec_data->dp_ops_lock);
|
||||||
SWITCH_DP_CODEC(codec_info, codec_data, dai->id);
|
if (dai->id == HDMI_MS_DAI)
|
||||||
|
type = EXT_DISPLAY_TYPE_HDMI;
|
||||||
|
else
|
||||||
|
type = EXT_DISPLAY_TYPE_DP;
|
||||||
|
SWITCH_DP_CODEC(codec_info, codec_data, dai->id, type);
|
||||||
rc = msm_ext_disp_select_audio_codec(codec_data->ext_disp_core_pdev,
|
rc = msm_ext_disp_select_audio_codec(codec_data->ext_disp_core_pdev,
|
||||||
&codec_info);
|
&codec_info);
|
||||||
|
|
||||||
@@ -754,6 +811,20 @@ static struct snd_soc_dai_driver msm_ext_disp_audio_codec_rx_dais[] = {
|
|||||||
},
|
},
|
||||||
.ops = &msm_ext_disp_audio_codec_rx_dai_ops,
|
.ops = &msm_ext_disp_audio_codec_rx_dai_ops,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.name = "msm_hdmi_ms_audio_codec_rx_dai",
|
||||||
|
.id = HDMI_MS_DAI,
|
||||||
|
.playback = {
|
||||||
|
.stream_name = "HDMI MS Playback",
|
||||||
|
.channels_min = 1,
|
||||||
|
.channels_max = 8,
|
||||||
|
.rate_min = 48000,
|
||||||
|
.rate_max = 48000,
|
||||||
|
.rates = MSM_EXT_DISP_PCM_RATES,
|
||||||
|
.formats = SNDRV_PCM_FMTBIT_S16_LE,
|
||||||
|
},
|
||||||
|
.ops = &msm_ext_disp_audio_codec_rx_dai_ops,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
.name = "msm_dp_audio_codec_rx_dai",
|
.name = "msm_dp_audio_codec_rx_dai",
|
||||||
.id = DP_DAI1,
|
.id = DP_DAI1,
|
||||||
|
@@ -50,6 +50,7 @@ struct rouleur_priv {
|
|||||||
|
|
||||||
bool comp1_enable;
|
bool comp1_enable;
|
||||||
bool comp2_enable;
|
bool comp2_enable;
|
||||||
|
bool dapm_bias_off;
|
||||||
|
|
||||||
struct irq_domain *virq;
|
struct irq_domain *virq;
|
||||||
struct wcd_irq_info irq_info;
|
struct wcd_irq_info irq_info;
|
||||||
@@ -82,6 +83,8 @@ struct rouleur_priv {
|
|||||||
int mbias_cnt;
|
int mbias_cnt;
|
||||||
struct mutex rx_clk_lock;
|
struct mutex rx_clk_lock;
|
||||||
struct mutex main_bias_lock;
|
struct mutex main_bias_lock;
|
||||||
|
bool dev_up;
|
||||||
|
bool usbc_hs_status;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rouleur_micbias_setting {
|
struct rouleur_micbias_setting {
|
||||||
@@ -169,4 +172,6 @@ extern int rouleur_mbhc_micb_adjust_voltage(struct snd_soc_component *component,
|
|||||||
extern int rouleur_get_micb_vout_ctl_val(u32 micb_mv);
|
extern int rouleur_get_micb_vout_ctl_val(u32 micb_mv);
|
||||||
extern int rouleur_micbias_control(struct snd_soc_component *component,
|
extern int rouleur_micbias_control(struct snd_soc_component *component,
|
||||||
int micb_num, int req, bool is_dapm);
|
int micb_num, int req, bool is_dapm);
|
||||||
|
extern int rouleur_global_mbias_enable(struct snd_soc_component *component);
|
||||||
|
extern int rouleur_global_mbias_disable(struct snd_soc_component *component);
|
||||||
#endif
|
#endif
|
||||||
|
@@ -22,20 +22,19 @@
|
|||||||
|
|
||||||
#define ROULEUR_ZDET_SUPPORTED true
|
#define ROULEUR_ZDET_SUPPORTED true
|
||||||
/* Z value defined in milliohm */
|
/* Z value defined in milliohm */
|
||||||
#define ROULEUR_ZDET_VAL_32 32000
|
|
||||||
#define ROULEUR_ZDET_VAL_400 400000
|
|
||||||
#define ROULEUR_ZDET_VAL_1200 1200000
|
|
||||||
#define ROULEUR_ZDET_VAL_100K 100000000
|
#define ROULEUR_ZDET_VAL_100K 100000000
|
||||||
/* Z floating defined in ohms */
|
/* Z floating defined in ohms */
|
||||||
#define ROULEUR_ZDET_FLOATING_IMPEDANCE 0x0FFFFFFE
|
#define ROULEUR_ZDET_FLOATING_IMPEDANCE 0x0FFFFFFE
|
||||||
|
|
||||||
#define ROULEUR_ZDET_NUM_MEASUREMENTS 900
|
#define ROULEUR_ZDET_NUM_MEASUREMENTS 100
|
||||||
#define ROULEUR_MBHC_GET_C1(c) ((c & 0xC000) >> 14)
|
#define ROULEUR_ZDET_RMAX 1280000
|
||||||
#define ROULEUR_MBHC_GET_X1(x) (x & 0x3FFF)
|
#define ROULEUR_ZDET_C1 7500000
|
||||||
/* Z value compared in milliOhm */
|
#define ROULEUR_ZDET_C2 187
|
||||||
#define ROULEUR_MBHC_IS_SECOND_RAMP_REQUIRED(z) ((z > 400000) || (z < 32000))
|
#define ROULEUR_ZDET_C3 4500
|
||||||
#define ROULEUR_MBHC_ZDET_CONST (86 * 16384)
|
|
||||||
#define ROULEUR_MBHC_MOISTURE_RREF R_24_KOHM
|
/* Cross connection thresholds in mV */
|
||||||
|
#define ROULEUR_HPHL_CROSS_CONN_THRESHOLD 350
|
||||||
|
#define ROULEUR_HPHR_CROSS_CONN_THRESHOLD 350
|
||||||
|
|
||||||
static struct wcd_mbhc_register
|
static struct wcd_mbhc_register
|
||||||
wcd_mbhc_registers[WCD_MBHC_REG_FUNC_MAX] = {
|
wcd_mbhc_registers[WCD_MBHC_REG_FUNC_MAX] = {
|
||||||
@@ -88,7 +87,7 @@ static struct wcd_mbhc_register
|
|||||||
WCD_MBHC_REGISTER("WCD_MBHC_ELECT_RESULT",
|
WCD_MBHC_REGISTER("WCD_MBHC_ELECT_RESULT",
|
||||||
ROULEUR_ANA_MBHC_RESULT_3, 0xFF, 0, 0),
|
ROULEUR_ANA_MBHC_RESULT_3, 0xFF, 0, 0),
|
||||||
WCD_MBHC_REGISTER("WCD_MBHC_MICB_CTRL",
|
WCD_MBHC_REGISTER("WCD_MBHC_MICB_CTRL",
|
||||||
ROULEUR_ANA_MICBIAS_MICB_1_2_EN, 0x04, 2, 0),
|
ROULEUR_ANA_MICBIAS_MICB_1_2_EN, 0x06, 1, 0),
|
||||||
WCD_MBHC_REGISTER("WCD_MBHC_HPH_CNP_WG_TIME",
|
WCD_MBHC_REGISTER("WCD_MBHC_HPH_CNP_WG_TIME",
|
||||||
SND_SOC_NOPM, 0x00, 0, 0),
|
SND_SOC_NOPM, 0x00, 0, 0),
|
||||||
WCD_MBHC_REGISTER("WCD_MBHC_HPHR_PA_EN",
|
WCD_MBHC_REGISTER("WCD_MBHC_HPHR_PA_EN",
|
||||||
@@ -153,9 +152,6 @@ struct rouleur_mbhc_zdet_param {
|
|||||||
u16 ldo_ctl;
|
u16 ldo_ctl;
|
||||||
u16 noff;
|
u16 noff;
|
||||||
u16 nshift;
|
u16 nshift;
|
||||||
u16 btn5;
|
|
||||||
u16 btn6;
|
|
||||||
u16 btn7;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int rouleur_mbhc_request_irq(struct snd_soc_component *component,
|
static int rouleur_mbhc_request_irq(struct snd_soc_component *component,
|
||||||
@@ -320,11 +316,11 @@ static void rouleur_mbhc_micb_ramp_control(struct snd_soc_component *component,
|
|||||||
0x1C, 0x0C);
|
0x1C, 0x0C);
|
||||||
snd_soc_component_update_bits(component,
|
snd_soc_component_update_bits(component,
|
||||||
ROULEUR_ANA_MBHC_MICB2_RAMP,
|
ROULEUR_ANA_MBHC_MICB2_RAMP,
|
||||||
0xA0, 0x80);
|
0x80, 0x80);
|
||||||
} else {
|
} else {
|
||||||
snd_soc_component_update_bits(component,
|
snd_soc_component_update_bits(component,
|
||||||
ROULEUR_ANA_MBHC_MICB2_RAMP,
|
ROULEUR_ANA_MBHC_MICB2_RAMP,
|
||||||
0xA0, 0x00);
|
0x80, 0x00);
|
||||||
snd_soc_component_update_bits(component,
|
snd_soc_component_update_bits(component,
|
||||||
ROULEUR_ANA_MBHC_MICB2_RAMP,
|
ROULEUR_ANA_MBHC_MICB2_RAMP,
|
||||||
0x1C, 0x00);
|
0x1C, 0x00);
|
||||||
@@ -376,174 +372,180 @@ static int rouleur_mbhc_micb_ctrl_threshold_mic(
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void rouleur_mbhc_get_result_params(struct rouleur_priv *rouleur,
|
static void rouleur_mbhc_get_result_params(struct rouleur_priv *rouleur,
|
||||||
s16 *d1_a, u16 noff,
|
struct snd_soc_component *component,
|
||||||
int32_t *zdet)
|
int32_t *zdet)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int val = 0, val1 = 0;
|
int zcode = 0, zcode1 = 0, zdet_cal_result = 0, zdet_est_range = 0;
|
||||||
s16 c1 = 0;
|
int noff = 0, ndac = 14;
|
||||||
s32 x1 = 0, d1 = 0;
|
int zdet_cal_coeff = 0, div_ratio = 0;
|
||||||
int32_t denom;
|
int num = 0, denom = 0;
|
||||||
int minCode_param[] = {
|
|
||||||
3277, 1639, 820, 410, 205, 103, 52, 26
|
|
||||||
};
|
|
||||||
|
|
||||||
|
/* Charge enable and wait for zcode to be updated */
|
||||||
regmap_update_bits(rouleur->regmap, ROULEUR_ANA_MBHC_ZDET, 0x20, 0x20);
|
regmap_update_bits(rouleur->regmap, ROULEUR_ANA_MBHC_ZDET, 0x20, 0x20);
|
||||||
for (i = 0; i < ROULEUR_ZDET_NUM_MEASUREMENTS; i++) {
|
for (i = 0; i < ROULEUR_ZDET_NUM_MEASUREMENTS; i++) {
|
||||||
regmap_read(rouleur->regmap, ROULEUR_ANA_MBHC_RESULT_2, &val);
|
regmap_read(rouleur->regmap, ROULEUR_ANA_MBHC_RESULT_2, &zcode);
|
||||||
if (val & 0x80)
|
if (zcode & 0x80)
|
||||||
|
break;
|
||||||
|
usleep_range(200, 210);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If zcode updation is not complete, give additional 10ms */
|
||||||
|
if (!(zcode & 0x80))
|
||||||
|
usleep_range(10000, 10100);
|
||||||
|
|
||||||
|
regmap_read(rouleur->regmap, ROULEUR_ANA_MBHC_RESULT_2, &zcode);
|
||||||
|
if (!(zcode & 0x80)) {
|
||||||
|
dev_dbg(rouleur->dev,
|
||||||
|
"%s: Impedance detect calculation error, zcode=0x%x\n",
|
||||||
|
__func__, zcode);
|
||||||
|
regmap_update_bits(rouleur->regmap, ROULEUR_ANA_MBHC_ZDET,
|
||||||
|
0x20, 0x00);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
zcode = zcode << 0x8;
|
||||||
|
zcode = zcode & 0x3FFF;
|
||||||
|
regmap_read(rouleur->regmap, ROULEUR_ANA_MBHC_RESULT_1, &zcode1);
|
||||||
|
zcode |= zcode1;
|
||||||
|
|
||||||
|
dev_dbg(rouleur->dev,
|
||||||
|
"%s: zcode: %d, zcode1: %d\n", __func__, zcode, zcode1);
|
||||||
|
|
||||||
|
/* Calculate calibration coefficient */
|
||||||
|
zdet_cal_result = (snd_soc_component_read32(component,
|
||||||
|
ROULEUR_ANA_MBHC_ZDET_CALIB_RESULT)) & 0x1F;
|
||||||
|
zdet_cal_coeff = ROULEUR_ZDET_C1 /
|
||||||
|
((ROULEUR_ZDET_C2 * zdet_cal_result) + ROULEUR_ZDET_C3);
|
||||||
|
/* Rload calculation */
|
||||||
|
zdet_est_range = (snd_soc_component_read32(component,
|
||||||
|
ROULEUR_ANA_MBHC_ZDET_CALIB_RESULT) & 0x60) >> 5;
|
||||||
|
|
||||||
|
dev_dbg(rouleur->dev,
|
||||||
|
"%s: zdet_cal_result: %d, zdet_cal_coeff: %d, zdet_est_range: %d\n",
|
||||||
|
__func__, zdet_cal_result, zdet_cal_coeff, zdet_est_range);
|
||||||
|
switch (zdet_est_range) {
|
||||||
|
case 0:
|
||||||
|
default:
|
||||||
|
noff = 0;
|
||||||
|
div_ratio = 320;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
noff = 0;
|
||||||
|
div_ratio = 64;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
noff = 4;
|
||||||
|
div_ratio = 64;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
noff = 5;
|
||||||
|
div_ratio = 40;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
val = val << 0x8;
|
|
||||||
regmap_read(rouleur->regmap, ROULEUR_ANA_MBHC_RESULT_1, &val1);
|
|
||||||
val |= val1;
|
|
||||||
regmap_update_bits(rouleur->regmap, ROULEUR_ANA_MBHC_ZDET, 0x20, 0x00);
|
|
||||||
x1 = ROULEUR_MBHC_GET_X1(val);
|
|
||||||
c1 = ROULEUR_MBHC_GET_C1(val);
|
|
||||||
/* If ramp is not complete, give additional 5ms */
|
|
||||||
if ((c1 < 2) && x1)
|
|
||||||
usleep_range(5000, 5050);
|
|
||||||
|
|
||||||
if (!c1 || !x1) {
|
num = zdet_cal_coeff * ROULEUR_ZDET_RMAX;
|
||||||
|
denom = ((zcode * div_ratio * 100) - (1 << (ndac - noff)) * 1000);
|
||||||
dev_dbg(rouleur->dev,
|
dev_dbg(rouleur->dev,
|
||||||
"%s: Impedance detect ramp error, c1=%d, x1=0x%x\n",
|
"%s: num: %d, denom: %d\n", __func__, num, denom);
|
||||||
__func__, c1, x1);
|
|
||||||
goto ramp_down;
|
|
||||||
}
|
|
||||||
d1 = d1_a[c1];
|
|
||||||
denom = (x1 * d1) - (1 << (14 - noff));
|
|
||||||
if (denom > 0)
|
if (denom > 0)
|
||||||
*zdet = (ROULEUR_MBHC_ZDET_CONST * 1000) / denom;
|
*zdet = (int32_t) ((num / denom) * 1000);
|
||||||
else if (x1 < minCode_param[noff])
|
else
|
||||||
*zdet = ROULEUR_ZDET_FLOATING_IMPEDANCE;
|
*zdet = ROULEUR_ZDET_FLOATING_IMPEDANCE;
|
||||||
|
|
||||||
dev_dbg(rouleur->dev, "%s: d1=%d, c1=%d, x1=0x%x, z_val=%d(milliOhm)\n",
|
dev_dbg(rouleur->dev, "%s: z_val=%d(milliOhm)\n",
|
||||||
__func__, d1, c1, x1, *zdet);
|
__func__, *zdet);
|
||||||
ramp_down:
|
/* Start discharge */
|
||||||
i = 0;
|
regmap_update_bits(rouleur->regmap, ROULEUR_ANA_MBHC_ZDET, 0x20, 0x00);
|
||||||
while (x1) {
|
|
||||||
regmap_read(rouleur->regmap, ROULEUR_ANA_MBHC_RESULT_1, &val);
|
|
||||||
regmap_read(rouleur->regmap, ROULEUR_ANA_MBHC_RESULT_2, &val1);
|
|
||||||
val = val << 0x8;
|
|
||||||
val |= val1;
|
|
||||||
x1 = ROULEUR_MBHC_GET_X1(val);
|
|
||||||
i++;
|
|
||||||
if (i == ROULEUR_ZDET_NUM_MEASUREMENTS)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
static void rouleur_mbhc_zdet_start(struct snd_soc_component *component,
|
||||||
static void rouleur_mbhc_zdet_ramp(struct snd_soc_component *component,
|
int32_t *zl, int32_t *zr)
|
||||||
struct rouleur_mbhc_zdet_param *zdet_param,
|
|
||||||
int32_t *zl, int32_t *zr, s16 *d1_a)
|
|
||||||
{
|
{
|
||||||
struct rouleur_priv *rouleur = dev_get_drvdata(component->dev);
|
struct rouleur_priv *rouleur = dev_get_drvdata(component->dev);
|
||||||
int32_t zdet = 0;
|
int32_t zdet = 0;
|
||||||
|
|
||||||
snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_ZDET_ANA_CTL,
|
|
||||||
0x70, zdet_param->ldo_ctl << 4);
|
|
||||||
snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_BTN5, 0xFC,
|
|
||||||
zdet_param->btn5);
|
|
||||||
snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_BTN6, 0xFC,
|
|
||||||
zdet_param->btn6);
|
|
||||||
snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_BTN7, 0xFC,
|
|
||||||
zdet_param->btn7);
|
|
||||||
snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_ZDET_ANA_CTL,
|
|
||||||
0x0F, zdet_param->noff);
|
|
||||||
snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_ZDET_RAMP_CTL,
|
|
||||||
0x0F, zdet_param->nshift);
|
|
||||||
|
|
||||||
if (!zl)
|
if (!zl)
|
||||||
goto z_right;
|
goto z_right;
|
||||||
/* Start impedance measurement for HPH_L */
|
|
||||||
|
/* HPHL pull down switch to force OFF */
|
||||||
|
regmap_update_bits(rouleur->regmap,
|
||||||
|
ROULEUR_ANA_HPHPA_CNP_CTL_2, 0x30, 0x00);
|
||||||
|
/* Averaging enable for reliable results */
|
||||||
|
regmap_update_bits(rouleur->regmap,
|
||||||
|
ROULEUR_ANA_MBHC_ZDET_ANA_CTL, 0x80, 0x80);
|
||||||
|
/* ZDET left measurement enable */
|
||||||
regmap_update_bits(rouleur->regmap,
|
regmap_update_bits(rouleur->regmap,
|
||||||
ROULEUR_ANA_MBHC_ZDET, 0x80, 0x80);
|
ROULEUR_ANA_MBHC_ZDET, 0x80, 0x80);
|
||||||
dev_dbg(rouleur->dev, "%s: ramp for HPH_L, noff = %d\n",
|
/* Calculate the left Rload result */
|
||||||
__func__, zdet_param->noff);
|
rouleur_mbhc_get_result_params(rouleur, component, &zdet);
|
||||||
rouleur_mbhc_get_result_params(rouleur, d1_a, zdet_param->noff, &zdet);
|
|
||||||
regmap_update_bits(rouleur->regmap,
|
regmap_update_bits(rouleur->regmap,
|
||||||
ROULEUR_ANA_MBHC_ZDET, 0x80, 0x00);
|
ROULEUR_ANA_MBHC_ZDET, 0x80, 0x00);
|
||||||
|
regmap_update_bits(rouleur->regmap,
|
||||||
|
ROULEUR_ANA_MBHC_ZDET_ANA_CTL, 0x80, 0x00);
|
||||||
|
regmap_update_bits(rouleur->regmap,
|
||||||
|
ROULEUR_ANA_HPHPA_CNP_CTL_2, 0x30, 0x20);
|
||||||
|
|
||||||
*zl = zdet;
|
*zl = zdet;
|
||||||
|
|
||||||
z_right:
|
z_right:
|
||||||
if (!zr)
|
if (!zr)
|
||||||
return;
|
return;
|
||||||
/* Start impedance measurement for HPH_R */
|
/* HPHR pull down switch to force OFF */
|
||||||
|
regmap_update_bits(rouleur->regmap,
|
||||||
|
ROULEUR_ANA_HPHPA_CNP_CTL_2, 0x0C, 0x00);
|
||||||
|
/* Averaging enable for reliable results */
|
||||||
|
regmap_update_bits(rouleur->regmap,
|
||||||
|
ROULEUR_ANA_MBHC_ZDET_ANA_CTL, 0x80, 0x80);
|
||||||
|
/* ZDET right measurement enable */
|
||||||
regmap_update_bits(rouleur->regmap,
|
regmap_update_bits(rouleur->regmap,
|
||||||
ROULEUR_ANA_MBHC_ZDET, 0x40, 0x40);
|
ROULEUR_ANA_MBHC_ZDET, 0x40, 0x40);
|
||||||
dev_dbg(rouleur->dev, "%s: ramp for HPH_R, noff = %d\n",
|
|
||||||
__func__, zdet_param->noff);
|
/* Calculate the right Rload result */
|
||||||
rouleur_mbhc_get_result_params(rouleur, d1_a, zdet_param->noff, &zdet);
|
rouleur_mbhc_get_result_params(rouleur, component, &zdet);
|
||||||
|
|
||||||
regmap_update_bits(rouleur->regmap,
|
regmap_update_bits(rouleur->regmap,
|
||||||
ROULEUR_ANA_MBHC_ZDET, 0x40, 0x00);
|
ROULEUR_ANA_MBHC_ZDET, 0x40, 0x00);
|
||||||
|
regmap_update_bits(rouleur->regmap,
|
||||||
|
ROULEUR_ANA_MBHC_ZDET_ANA_CTL, 0x80, 0x00);
|
||||||
|
regmap_update_bits(rouleur->regmap,
|
||||||
|
ROULEUR_ANA_HPHPA_CNP_CTL_2, 0x0C, 0x08);
|
||||||
|
|
||||||
*zr = zdet;
|
*zr = zdet;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void rouleur_wcd_mbhc_qfuse_cal(
|
|
||||||
struct snd_soc_component *component,
|
|
||||||
int32_t *z_val, int flag_l_r)
|
|
||||||
{
|
|
||||||
s16 q1;
|
|
||||||
int q1_cal;
|
|
||||||
|
|
||||||
if (*z_val < (ROULEUR_ZDET_VAL_400/1000))
|
|
||||||
q1 = snd_soc_component_read32(component,
|
|
||||||
ROULEUR_DIGITAL_EFUSE_REG_23 + (2 * flag_l_r));
|
|
||||||
else
|
|
||||||
q1 = snd_soc_component_read32(component,
|
|
||||||
ROULEUR_DIGITAL_EFUSE_REG_24 + (2 * flag_l_r));
|
|
||||||
if (q1 & 0x80)
|
|
||||||
q1_cal = (10000 - ((q1 & 0x7F) * 25));
|
|
||||||
else
|
|
||||||
q1_cal = (10000 + (q1 * 25));
|
|
||||||
if (q1_cal > 0)
|
|
||||||
*z_val = ((*z_val) * 10000) / q1_cal;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void rouleur_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl,
|
static void rouleur_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl,
|
||||||
uint32_t *zr)
|
uint32_t *zr)
|
||||||
{
|
{
|
||||||
struct snd_soc_component *component = mbhc->component;
|
struct snd_soc_component *component = mbhc->component;
|
||||||
struct rouleur_priv *rouleur = dev_get_drvdata(component->dev);
|
struct rouleur_priv *rouleur = dev_get_drvdata(component->dev);
|
||||||
s16 reg0, reg1, reg2, reg3, reg4;
|
s16 reg0;
|
||||||
int32_t z1L, z1R, z1Ls;
|
int32_t z1L, z1R, z1Ls;
|
||||||
int zMono, z_diff1, z_diff2;
|
int zMono, z_diff1, z_diff2;
|
||||||
bool is_fsm_disable = false;
|
bool is_fsm_disable = false;
|
||||||
struct rouleur_mbhc_zdet_param zdet_param[] = {
|
|
||||||
{4, 0, 4, 0x08, 0x14, 0x18}, /* < 32ohm */
|
|
||||||
{2, 0, 3, 0x18, 0x7C, 0x90}, /* 32ohm < Z < 400ohm */
|
|
||||||
{1, 4, 5, 0x18, 0x7C, 0x90}, /* 400ohm < Z < 1200ohm */
|
|
||||||
{1, 6, 7, 0x18, 0x7C, 0x90}, /* >1200ohm */
|
|
||||||
};
|
|
||||||
struct rouleur_mbhc_zdet_param *zdet_param_ptr = NULL;
|
|
||||||
s16 d1_a[][4] = {
|
|
||||||
{0, 30, 90, 30},
|
|
||||||
{0, 30, 30, 5},
|
|
||||||
{0, 30, 30, 5},
|
|
||||||
{0, 30, 30, 5},
|
|
||||||
};
|
|
||||||
s16 *d1 = NULL;
|
|
||||||
|
|
||||||
WCD_MBHC_RSC_ASSERT_LOCKED(mbhc);
|
WCD_MBHC_RSC_ASSERT_LOCKED(mbhc);
|
||||||
|
|
||||||
reg0 = snd_soc_component_read32(component, ROULEUR_ANA_MBHC_BTN5);
|
reg0 = snd_soc_component_read32(component, ROULEUR_ANA_MBHC_ELECT);
|
||||||
reg1 = snd_soc_component_read32(component, ROULEUR_ANA_MBHC_BTN6);
|
|
||||||
reg2 = snd_soc_component_read32(component, ROULEUR_ANA_MBHC_BTN7);
|
|
||||||
reg3 = snd_soc_component_read32(component, ROULEUR_MBHC_CTL_CLK);
|
|
||||||
reg4 = snd_soc_component_read32(component,
|
|
||||||
ROULEUR_ANA_MBHC_ZDET_ANA_CTL);
|
|
||||||
|
|
||||||
if (snd_soc_component_read32(component, ROULEUR_ANA_MBHC_ELECT) &
|
if (reg0 & 0x80) {
|
||||||
0x80) {
|
|
||||||
is_fsm_disable = true;
|
is_fsm_disable = true;
|
||||||
regmap_update_bits(rouleur->regmap,
|
regmap_update_bits(rouleur->regmap,
|
||||||
ROULEUR_ANA_MBHC_ELECT, 0x80, 0x00);
|
ROULEUR_ANA_MBHC_ELECT, 0x80, 0x00);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Enable electrical bias */
|
||||||
|
snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_ELECT,
|
||||||
|
0x01, 0x01);
|
||||||
|
|
||||||
|
/* Enable codec main bias */
|
||||||
|
rouleur_global_mbias_enable(component);
|
||||||
|
|
||||||
|
/* Enable RCO clock */
|
||||||
|
snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_CTL_1,
|
||||||
|
0x80, 0x80);
|
||||||
|
|
||||||
/* For NO-jack, disable L_DET_EN before Z-det measurements */
|
/* For NO-jack, disable L_DET_EN before Z-det measurements */
|
||||||
if (mbhc->hphl_swh)
|
if (mbhc->hphl_swh)
|
||||||
regmap_update_bits(rouleur->regmap,
|
regmap_update_bits(rouleur->regmap,
|
||||||
@@ -553,79 +555,34 @@ static void rouleur_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl,
|
|||||||
regmap_update_bits(rouleur->regmap,
|
regmap_update_bits(rouleur->regmap,
|
||||||
ROULEUR_ANA_MBHC_MECH, 0x01, 0x00);
|
ROULEUR_ANA_MBHC_MECH, 0x01, 0x00);
|
||||||
|
|
||||||
/* Disable surge protection before impedance detection.
|
/*
|
||||||
|
* Disable surge protection before impedance detection.
|
||||||
* This is done to give correct value for high impedance.
|
* This is done to give correct value for high impedance.
|
||||||
*/
|
*/
|
||||||
regmap_update_bits(rouleur->regmap,
|
snd_soc_component_update_bits(component, ROULEUR_ANA_SURGE_EN,
|
||||||
ROULEUR_HPH_SURGE_HPHLR_SURGE_EN, 0xC0, 0x00);
|
0xC0, 0x00);
|
||||||
/* 1ms delay needed after disable surge protection */
|
/* 1ms delay needed after disable surge protection */
|
||||||
usleep_range(1000, 1010);
|
usleep_range(1000, 1010);
|
||||||
|
|
||||||
/* First get impedance on Left */
|
/* Start of left ch impedance calculation */
|
||||||
d1 = d1_a[1];
|
rouleur_mbhc_zdet_start(component, &z1L, NULL);
|
||||||
zdet_param_ptr = &zdet_param[1];
|
|
||||||
rouleur_mbhc_zdet_ramp(component, zdet_param_ptr, &z1L, NULL, d1);
|
|
||||||
|
|
||||||
if (!ROULEUR_MBHC_IS_SECOND_RAMP_REQUIRED(z1L))
|
|
||||||
goto left_ch_impedance;
|
|
||||||
|
|
||||||
/* Second ramp for left ch */
|
|
||||||
if (z1L < ROULEUR_ZDET_VAL_32) {
|
|
||||||
zdet_param_ptr = &zdet_param[0];
|
|
||||||
d1 = d1_a[0];
|
|
||||||
} else if ((z1L > ROULEUR_ZDET_VAL_400) &&
|
|
||||||
(z1L <= ROULEUR_ZDET_VAL_1200)) {
|
|
||||||
zdet_param_ptr = &zdet_param[2];
|
|
||||||
d1 = d1_a[2];
|
|
||||||
} else if (z1L > ROULEUR_ZDET_VAL_1200) {
|
|
||||||
zdet_param_ptr = &zdet_param[3];
|
|
||||||
d1 = d1_a[3];
|
|
||||||
}
|
|
||||||
rouleur_mbhc_zdet_ramp(component, zdet_param_ptr, &z1L, NULL, d1);
|
|
||||||
|
|
||||||
left_ch_impedance:
|
|
||||||
if ((z1L == ROULEUR_ZDET_FLOATING_IMPEDANCE) ||
|
if ((z1L == ROULEUR_ZDET_FLOATING_IMPEDANCE) ||
|
||||||
(z1L > ROULEUR_ZDET_VAL_100K)) {
|
(z1L > ROULEUR_ZDET_VAL_100K))
|
||||||
*zl = ROULEUR_ZDET_FLOATING_IMPEDANCE;
|
*zl = ROULEUR_ZDET_FLOATING_IMPEDANCE;
|
||||||
zdet_param_ptr = &zdet_param[1];
|
else
|
||||||
d1 = d1_a[1];
|
|
||||||
} else {
|
|
||||||
*zl = z1L/1000;
|
*zl = z1L/1000;
|
||||||
rouleur_wcd_mbhc_qfuse_cal(component, zl, 0);
|
|
||||||
}
|
|
||||||
dev_dbg(component->dev, "%s: impedance on HPH_L = %d(ohms)\n",
|
dev_dbg(component->dev, "%s: impedance on HPH_L = %d(ohms)\n",
|
||||||
__func__, *zl);
|
__func__, *zl);
|
||||||
|
|
||||||
/* Start of right impedance ramp and calculation */
|
/* Start of right ch impedance calculation */
|
||||||
rouleur_mbhc_zdet_ramp(component, zdet_param_ptr, NULL, &z1R, d1);
|
rouleur_mbhc_zdet_start(component, NULL, &z1R);
|
||||||
if (ROULEUR_MBHC_IS_SECOND_RAMP_REQUIRED(z1R)) {
|
|
||||||
if (((z1R > ROULEUR_ZDET_VAL_1200) &&
|
|
||||||
(zdet_param_ptr->noff == 0x6)) ||
|
|
||||||
((*zl) != ROULEUR_ZDET_FLOATING_IMPEDANCE))
|
|
||||||
goto right_ch_impedance;
|
|
||||||
/* Second ramp for right ch */
|
|
||||||
if (z1R < ROULEUR_ZDET_VAL_32) {
|
|
||||||
zdet_param_ptr = &zdet_param[0];
|
|
||||||
d1 = d1_a[0];
|
|
||||||
} else if ((z1R > ROULEUR_ZDET_VAL_400) &&
|
|
||||||
(z1R <= ROULEUR_ZDET_VAL_1200)) {
|
|
||||||
zdet_param_ptr = &zdet_param[2];
|
|
||||||
d1 = d1_a[2];
|
|
||||||
} else if (z1R > ROULEUR_ZDET_VAL_1200) {
|
|
||||||
zdet_param_ptr = &zdet_param[3];
|
|
||||||
d1 = d1_a[3];
|
|
||||||
}
|
|
||||||
rouleur_mbhc_zdet_ramp(component, zdet_param_ptr, NULL,
|
|
||||||
&z1R, d1);
|
|
||||||
}
|
|
||||||
right_ch_impedance:
|
|
||||||
if ((z1R == ROULEUR_ZDET_FLOATING_IMPEDANCE) ||
|
if ((z1R == ROULEUR_ZDET_FLOATING_IMPEDANCE) ||
|
||||||
(z1R > ROULEUR_ZDET_VAL_100K)) {
|
(z1R > ROULEUR_ZDET_VAL_100K))
|
||||||
*zr = ROULEUR_ZDET_FLOATING_IMPEDANCE;
|
*zr = ROULEUR_ZDET_FLOATING_IMPEDANCE;
|
||||||
} else {
|
else
|
||||||
*zr = z1R/1000;
|
*zr = z1R/1000;
|
||||||
rouleur_wcd_mbhc_qfuse_cal(component, zr, 1);
|
|
||||||
}
|
|
||||||
dev_dbg(component->dev, "%s: impedance on HPH_R = %d(ohms)\n",
|
dev_dbg(component->dev, "%s: impedance on HPH_R = %d(ohms)\n",
|
||||||
__func__, *zr);
|
__func__, *zr);
|
||||||
|
|
||||||
@@ -647,24 +604,10 @@ right_ch_impedance:
|
|||||||
mbhc->hph_type = WCD_MBHC_HPH_MONO;
|
mbhc->hph_type = WCD_MBHC_HPH_MONO;
|
||||||
goto zdet_complete;
|
goto zdet_complete;
|
||||||
}
|
}
|
||||||
snd_soc_component_update_bits(component, ROULEUR_HPH_R_ATEST,
|
|
||||||
0x02, 0x02);
|
z1Ls = z1L/1000;
|
||||||
snd_soc_component_update_bits(component, ROULEUR_HPH_PA_CTL2,
|
/* Parallel of left Z and 20 ohm pull down resistor */
|
||||||
0x40, 0x01);
|
zMono = ((*zl) * 20) / ((*zl) + 20);
|
||||||
if (*zl < (ROULEUR_ZDET_VAL_32/1000))
|
|
||||||
rouleur_mbhc_zdet_ramp(component, &zdet_param[0], &z1Ls,
|
|
||||||
NULL, d1);
|
|
||||||
else
|
|
||||||
rouleur_mbhc_zdet_ramp(component, &zdet_param[1], &z1Ls,
|
|
||||||
NULL, d1);
|
|
||||||
snd_soc_component_update_bits(component, ROULEUR_HPH_PA_CTL2,
|
|
||||||
0x40, 0x00);
|
|
||||||
snd_soc_component_update_bits(component, ROULEUR_HPH_R_ATEST,
|
|
||||||
0x02, 0x00);
|
|
||||||
z1Ls /= 1000;
|
|
||||||
rouleur_wcd_mbhc_qfuse_cal(component, &z1Ls, 0);
|
|
||||||
/* Parallel of left Z and 9 ohm pull down resistor */
|
|
||||||
zMono = ((*zl) * 9) / ((*zl) + 9);
|
|
||||||
z_diff1 = (z1Ls > zMono) ? (z1Ls - zMono) : (zMono - z1Ls);
|
z_diff1 = (z1Ls > zMono) ? (z1Ls - zMono) : (zMono - z1Ls);
|
||||||
z_diff2 = ((*zl) > z1Ls) ? ((*zl) - z1Ls) : (z1Ls - (*zl));
|
z_diff2 = ((*zl) > z1Ls) ? ((*zl) - z1Ls) : (z1Ls - (*zl));
|
||||||
if ((z_diff1 * (*zl + z1Ls)) > (z_diff2 * (z1Ls + zMono))) {
|
if ((z_diff1 * (*zl + z1Ls)) > (z_diff2 * (z1Ls + zMono))) {
|
||||||
@@ -677,13 +620,10 @@ right_ch_impedance:
|
|||||||
mbhc->hph_type = WCD_MBHC_HPH_MONO;
|
mbhc->hph_type = WCD_MBHC_HPH_MONO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
zdet_complete:
|
||||||
/* Enable surge protection again after impedance detection */
|
/* Enable surge protection again after impedance detection */
|
||||||
regmap_update_bits(rouleur->regmap,
|
regmap_update_bits(rouleur->regmap,
|
||||||
ROULEUR_HPH_SURGE_HPHLR_SURGE_EN, 0xC0, 0xC0);
|
ROULEUR_ANA_SURGE_EN, 0xC0, 0xC0);
|
||||||
zdet_complete:
|
|
||||||
snd_soc_component_write(component, ROULEUR_ANA_MBHC_BTN5, reg0);
|
|
||||||
snd_soc_component_write(component, ROULEUR_ANA_MBHC_BTN6, reg1);
|
|
||||||
snd_soc_component_write(component, ROULEUR_ANA_MBHC_BTN7, reg2);
|
|
||||||
/* Turn on 100k pull down on HPHL */
|
/* Turn on 100k pull down on HPHL */
|
||||||
regmap_update_bits(rouleur->regmap,
|
regmap_update_bits(rouleur->regmap,
|
||||||
ROULEUR_ANA_MBHC_MECH, 0x01, 0x01);
|
ROULEUR_ANA_MBHC_MECH, 0x01, 0x01);
|
||||||
@@ -693,13 +633,14 @@ zdet_complete:
|
|||||||
regmap_update_bits(rouleur->regmap,
|
regmap_update_bits(rouleur->regmap,
|
||||||
ROULEUR_ANA_MBHC_MECH, 0x80, 0x80);
|
ROULEUR_ANA_MBHC_MECH, 0x80, 0x80);
|
||||||
|
|
||||||
snd_soc_component_write(component, ROULEUR_ANA_MBHC_ZDET_ANA_CTL, reg4);
|
/* Restore electrical bias state */
|
||||||
snd_soc_component_write(component, ROULEUR_MBHC_CTL_CLK, reg3);
|
snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_ELECT, 0x01,
|
||||||
|
reg0 >> 7);
|
||||||
if (is_fsm_disable)
|
if (is_fsm_disable)
|
||||||
regmap_update_bits(rouleur->regmap,
|
regmap_update_bits(rouleur->regmap,
|
||||||
ROULEUR_ANA_MBHC_ELECT, 0x80, 0x80);
|
ROULEUR_ANA_MBHC_ELECT, 0x80, 0x80);
|
||||||
|
rouleur_global_mbias_disable(component);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
static void rouleur_mbhc_gnd_det_ctrl(struct snd_soc_component *component,
|
static void rouleur_mbhc_gnd_det_ctrl(struct snd_soc_component *component,
|
||||||
bool enable)
|
bool enable)
|
||||||
@@ -723,10 +664,10 @@ static void rouleur_mbhc_hph_pull_down_ctrl(struct snd_soc_component *component,
|
|||||||
if (enable) {
|
if (enable) {
|
||||||
snd_soc_component_update_bits(component,
|
snd_soc_component_update_bits(component,
|
||||||
ROULEUR_ANA_HPHPA_CNP_CTL_2,
|
ROULEUR_ANA_HPHPA_CNP_CTL_2,
|
||||||
0x30, 0x10);
|
0x30, 0x20);
|
||||||
snd_soc_component_update_bits(component,
|
snd_soc_component_update_bits(component,
|
||||||
ROULEUR_ANA_HPHPA_CNP_CTL_2,
|
ROULEUR_ANA_HPHPA_CNP_CTL_2,
|
||||||
0x0C, 0x04);
|
0x0C, 0x08);
|
||||||
} else {
|
} else {
|
||||||
snd_soc_component_update_bits(component,
|
snd_soc_component_update_bits(component,
|
||||||
ROULEUR_ANA_HPHPA_CNP_CTL_2,
|
ROULEUR_ANA_HPHPA_CNP_CTL_2,
|
||||||
@@ -820,6 +761,54 @@ static void rouleur_mbhc_bcs_enable(struct wcd_mbhc *mbhc,
|
|||||||
rouleur_disable_bcs_before_slow_insert(mbhc->component, true);
|
rouleur_disable_bcs_before_slow_insert(mbhc->component, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void rouleur_mbhc_get_micbias_val(struct wcd_mbhc *mbhc, int *mb)
|
||||||
|
{
|
||||||
|
u8 vout_ctl = 0;
|
||||||
|
|
||||||
|
/* Read MBHC Micbias (Mic Bias2) voltage */
|
||||||
|
WCD_MBHC_REG_READ(WCD_MBHC_MICB2_VOUT, vout_ctl);
|
||||||
|
|
||||||
|
/* Formula for getting micbias from vout
|
||||||
|
* micbias = 1.6V + VOUT_CTL * 50mV
|
||||||
|
*/
|
||||||
|
*mb = 1600 + (vout_ctl * 50);
|
||||||
|
pr_debug("%s: vout_ctl: %d, micbias: %d\n", __func__, vout_ctl, *mb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rouleur_mbhc_comp_autozero_control(struct wcd_mbhc *mbhc,
|
||||||
|
bool az_enable)
|
||||||
|
{
|
||||||
|
if (az_enable)
|
||||||
|
snd_soc_component_update_bits(mbhc->component,
|
||||||
|
ROULEUR_ANA_MBHC_CTL_CLK, 0x08, 0x08);
|
||||||
|
else
|
||||||
|
snd_soc_component_update_bits(mbhc->component,
|
||||||
|
ROULEUR_ANA_MBHC_CTL_CLK, 0x08, 0x00);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rouleur_mbhc_surge_control(struct wcd_mbhc *mbhc,
|
||||||
|
bool surge_enable)
|
||||||
|
{
|
||||||
|
if (surge_enable)
|
||||||
|
snd_soc_component_update_bits(mbhc->component,
|
||||||
|
ROULEUR_ANA_SURGE_EN, 0xC0, 0xC0);
|
||||||
|
else
|
||||||
|
snd_soc_component_update_bits(mbhc->component,
|
||||||
|
ROULEUR_ANA_SURGE_EN, 0xC0, 0x00);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rouleur_mbhc_update_cross_conn_thr(struct wcd_mbhc *mbhc)
|
||||||
|
{
|
||||||
|
mbhc->hphl_cross_conn_thr = ROULEUR_HPHL_CROSS_CONN_THRESHOLD;
|
||||||
|
mbhc->hphr_cross_conn_thr = ROULEUR_HPHR_CROSS_CONN_THRESHOLD;
|
||||||
|
|
||||||
|
pr_debug("%s: Cross connection threshold for hphl: %d, hphr: %d\n",
|
||||||
|
__func__, mbhc->hphl_cross_conn_thr,
|
||||||
|
mbhc->hphr_cross_conn_thr);
|
||||||
|
}
|
||||||
|
|
||||||
static const struct wcd_mbhc_cb mbhc_cb = {
|
static const struct wcd_mbhc_cb mbhc_cb = {
|
||||||
.request_irq = rouleur_mbhc_request_irq,
|
.request_irq = rouleur_mbhc_request_irq,
|
||||||
.irq_control = rouleur_mbhc_irq_control,
|
.irq_control = rouleur_mbhc_irq_control,
|
||||||
@@ -837,13 +826,17 @@ static const struct wcd_mbhc_cb mbhc_cb = {
|
|||||||
.mbhc_micb_ramp_control = rouleur_mbhc_micb_ramp_control,
|
.mbhc_micb_ramp_control = rouleur_mbhc_micb_ramp_control,
|
||||||
.get_hwdep_fw_cal = rouleur_get_hwdep_fw_cal,
|
.get_hwdep_fw_cal = rouleur_get_hwdep_fw_cal,
|
||||||
.mbhc_micb_ctrl_thr_mic = rouleur_mbhc_micb_ctrl_threshold_mic,
|
.mbhc_micb_ctrl_thr_mic = rouleur_mbhc_micb_ctrl_threshold_mic,
|
||||||
//.compute_impedance = rouleur_wcd_mbhc_calc_impedance,
|
.compute_impedance = rouleur_wcd_mbhc_calc_impedance,
|
||||||
.mbhc_gnd_det_ctrl = rouleur_mbhc_gnd_det_ctrl,
|
.mbhc_gnd_det_ctrl = rouleur_mbhc_gnd_det_ctrl,
|
||||||
.hph_pull_down_ctrl = rouleur_mbhc_hph_pull_down_ctrl,
|
.hph_pull_down_ctrl = rouleur_mbhc_hph_pull_down_ctrl,
|
||||||
.mbhc_moisture_config = rouleur_mbhc_moisture_config,
|
.mbhc_moisture_config = rouleur_mbhc_moisture_config,
|
||||||
.mbhc_get_moisture_status = rouleur_mbhc_get_moisture_status,
|
.mbhc_get_moisture_status = rouleur_mbhc_get_moisture_status,
|
||||||
.mbhc_moisture_detect_en = rouleur_mbhc_moisture_detect_en,
|
.mbhc_moisture_detect_en = rouleur_mbhc_moisture_detect_en,
|
||||||
.bcs_enable = rouleur_mbhc_bcs_enable,
|
.bcs_enable = rouleur_mbhc_bcs_enable,
|
||||||
|
.get_micbias_val = rouleur_mbhc_get_micbias_val,
|
||||||
|
.mbhc_comp_autozero_control = rouleur_mbhc_comp_autozero_control,
|
||||||
|
.mbhc_surge_ctl = rouleur_mbhc_surge_control,
|
||||||
|
.update_cross_conn_thr = rouleur_mbhc_update_cross_conn_thr,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int rouleur_get_hph_type(struct snd_kcontrol *kcontrol,
|
static int rouleur_get_hph_type(struct snd_kcontrol *kcontrol,
|
||||||
|
@@ -45,7 +45,7 @@ enum {
|
|||||||
#define ROULEUR_ANA_MBHC_ZDET_RAMP_CTL (ROULEUR_ANA_BASE_ADDR+0x06A)
|
#define ROULEUR_ANA_MBHC_ZDET_RAMP_CTL (ROULEUR_ANA_BASE_ADDR+0x06A)
|
||||||
#define ROULEUR_ANA_MBHC_FSM_STATUS (ROULEUR_ANA_BASE_ADDR+0x06B)
|
#define ROULEUR_ANA_MBHC_FSM_STATUS (ROULEUR_ANA_BASE_ADDR+0x06B)
|
||||||
#define ROULEUR_ANA_MBHC_ADC_RESULT (ROULEUR_ANA_BASE_ADDR+0x06C)
|
#define ROULEUR_ANA_MBHC_ADC_RESULT (ROULEUR_ANA_BASE_ADDR+0x06C)
|
||||||
#define ROULEUR_ANA_MBHC_MCLK (ROULEUR_ANA_BASE_ADDR+0x06D)
|
#define ROULEUR_ANA_MBHC_CTL_CLK (ROULEUR_ANA_BASE_ADDR+0x06D)
|
||||||
#define ROULEUR_ANA_MBHC_ZDET_CALIB_RESULT (ROULEUR_ANA_BASE_ADDR+0x072)
|
#define ROULEUR_ANA_MBHC_ZDET_CALIB_RESULT (ROULEUR_ANA_BASE_ADDR+0x072)
|
||||||
#define ROULEUR_ANA_NCP_EN (ROULEUR_ANA_BASE_ADDR+0x077)
|
#define ROULEUR_ANA_NCP_EN (ROULEUR_ANA_BASE_ADDR+0x077)
|
||||||
#define ROULEUR_ANA_HPHPA_CNP_CTL_1 (ROULEUR_ANA_BASE_ADDR+0x083)
|
#define ROULEUR_ANA_HPHPA_CNP_CTL_1 (ROULEUR_ANA_BASE_ADDR+0x083)
|
||||||
|
@@ -38,13 +38,15 @@ static const struct reg_default rouleur_defaults[] = {
|
|||||||
{ ROULEUR_ANA_MBHC_ZDET_RAMP_CTL, 0x00 },
|
{ ROULEUR_ANA_MBHC_ZDET_RAMP_CTL, 0x00 },
|
||||||
{ ROULEUR_ANA_MBHC_FSM_STATUS, 0x00 },
|
{ ROULEUR_ANA_MBHC_FSM_STATUS, 0x00 },
|
||||||
{ ROULEUR_ANA_MBHC_ADC_RESULT, 0x00 },
|
{ ROULEUR_ANA_MBHC_ADC_RESULT, 0x00 },
|
||||||
{ ROULEUR_ANA_MBHC_MCLK, 0x30 },
|
{ ROULEUR_ANA_MBHC_CTL_CLK, 0x30 },
|
||||||
{ ROULEUR_ANA_MBHC_ZDET_CALIB_RESULT, 0x00 },
|
{ ROULEUR_ANA_MBHC_ZDET_CALIB_RESULT, 0x00 },
|
||||||
{ ROULEUR_ANA_NCP_EN, 0x00 },
|
{ ROULEUR_ANA_NCP_EN, 0x00 },
|
||||||
{ ROULEUR_ANA_HPHPA_CNP_CTL_1, 0x54 },
|
{ ROULEUR_ANA_HPHPA_CNP_CTL_1, 0x54 },
|
||||||
{ ROULEUR_ANA_HPHPA_CNP_CTL_2, 0x2B },
|
{ ROULEUR_ANA_HPHPA_CNP_CTL_2, 0x2B },
|
||||||
{ ROULEUR_ANA_HPHPA_PA_STATUS, 0x00 },
|
{ ROULEUR_ANA_HPHPA_PA_STATUS, 0x00 },
|
||||||
{ ROULEUR_ANA_HPHPA_FSM_CLK, 0x12 },
|
{ ROULEUR_ANA_HPHPA_FSM_CLK, 0x12 },
|
||||||
|
{ ROULEUR_ANA_HPHPA_L_GAIN, 0x00 },
|
||||||
|
{ ROULEUR_ANA_HPHPA_R_GAIN, 0x00 },
|
||||||
{ ROULEUR_SWR_HPHPA_HD2, 0x1B },
|
{ ROULEUR_SWR_HPHPA_HD2, 0x1B },
|
||||||
{ ROULEUR_ANA_HPHPA_SPARE_CTL, 0x02 },
|
{ ROULEUR_ANA_HPHPA_SPARE_CTL, 0x02 },
|
||||||
{ ROULEUR_ANA_SURGE_EN, 0x38 },
|
{ ROULEUR_ANA_SURGE_EN, 0x38 },
|
||||||
|
@@ -33,13 +33,15 @@ const u8 rouleur_reg_access_analog[ROULEUR_REG(
|
|||||||
[ROULEUR_REG(ROULEUR_ANA_MBHC_ZDET_RAMP_CTL)] = RD_WR_REG,
|
[ROULEUR_REG(ROULEUR_ANA_MBHC_ZDET_RAMP_CTL)] = RD_WR_REG,
|
||||||
[ROULEUR_REG(ROULEUR_ANA_MBHC_FSM_STATUS)] = RD_REG,
|
[ROULEUR_REG(ROULEUR_ANA_MBHC_FSM_STATUS)] = RD_REG,
|
||||||
[ROULEUR_REG(ROULEUR_ANA_MBHC_ADC_RESULT)] = RD_REG,
|
[ROULEUR_REG(ROULEUR_ANA_MBHC_ADC_RESULT)] = RD_REG,
|
||||||
[ROULEUR_REG(ROULEUR_ANA_MBHC_MCLK)] = RD_WR_REG,
|
[ROULEUR_REG(ROULEUR_ANA_MBHC_CTL_CLK)] = RD_WR_REG,
|
||||||
[ROULEUR_REG(ROULEUR_ANA_MBHC_ZDET_CALIB_RESULT)] = RD_REG,
|
[ROULEUR_REG(ROULEUR_ANA_MBHC_ZDET_CALIB_RESULT)] = RD_REG,
|
||||||
[ROULEUR_REG(ROULEUR_ANA_NCP_EN)] = RD_WR_REG,
|
[ROULEUR_REG(ROULEUR_ANA_NCP_EN)] = RD_WR_REG,
|
||||||
[ROULEUR_REG(ROULEUR_ANA_HPHPA_CNP_CTL_1)] = RD_WR_REG,
|
[ROULEUR_REG(ROULEUR_ANA_HPHPA_CNP_CTL_1)] = RD_WR_REG,
|
||||||
[ROULEUR_REG(ROULEUR_ANA_HPHPA_CNP_CTL_2)] = RD_WR_REG,
|
[ROULEUR_REG(ROULEUR_ANA_HPHPA_CNP_CTL_2)] = RD_WR_REG,
|
||||||
[ROULEUR_REG(ROULEUR_ANA_HPHPA_PA_STATUS)] = RD_REG,
|
[ROULEUR_REG(ROULEUR_ANA_HPHPA_PA_STATUS)] = RD_REG,
|
||||||
[ROULEUR_REG(ROULEUR_ANA_HPHPA_FSM_CLK)] = RD_WR_REG,
|
[ROULEUR_REG(ROULEUR_ANA_HPHPA_FSM_CLK)] = RD_WR_REG,
|
||||||
|
[ROULEUR_REG(ROULEUR_ANA_HPHPA_L_GAIN)] = RD_WR_REG,
|
||||||
|
[ROULEUR_REG(ROULEUR_ANA_HPHPA_R_GAIN)] = RD_WR_REG,
|
||||||
[ROULEUR_REG(ROULEUR_ANA_HPHPA_SPARE_CTL)] = RD_WR_REG,
|
[ROULEUR_REG(ROULEUR_ANA_HPHPA_SPARE_CTL)] = RD_WR_REG,
|
||||||
[ROULEUR_REG(ROULEUR_SWR_HPHPA_HD2)] = RD_WR_REG,
|
[ROULEUR_REG(ROULEUR_SWR_HPHPA_HD2)] = RD_WR_REG,
|
||||||
[ROULEUR_REG(ROULEUR_ANA_SURGE_EN)] = RD_WR_REG,
|
[ROULEUR_REG(ROULEUR_ANA_SURGE_EN)] = RD_WR_REG,
|
||||||
|
@@ -46,6 +46,7 @@ enum {
|
|||||||
HPH_COMP_DELAY,
|
HPH_COMP_DELAY,
|
||||||
HPH_PA_DELAY,
|
HPH_PA_DELAY,
|
||||||
AMIC2_BCS_ENABLE,
|
AMIC2_BCS_ENABLE,
|
||||||
|
WCD_SUPPLIES_LPM_MODE,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* TODO: Check on the step values */
|
/* TODO: Check on the step values */
|
||||||
@@ -107,6 +108,9 @@ static int rouleur_handle_post_irq(void *data)
|
|||||||
|
|
||||||
static int rouleur_init_reg(struct snd_soc_component *component)
|
static int rouleur_init_reg(struct snd_soc_component *component)
|
||||||
{
|
{
|
||||||
|
/* Disable HPH OCP */
|
||||||
|
snd_soc_component_update_bits(component, ROULEUR_ANA_HPHPA_CNP_CTL_2,
|
||||||
|
0x03, 0x00);
|
||||||
/* Enable surge protection */
|
/* Enable surge protection */
|
||||||
snd_soc_component_update_bits(component, ROULEUR_ANA_SURGE_EN,
|
snd_soc_component_update_bits(component, ROULEUR_ANA_SURGE_EN,
|
||||||
0xC0, 0xC0);
|
0xC0, 0xC0);
|
||||||
@@ -301,7 +305,7 @@ static int rouleur_rx_connect_port(struct snd_soc_component *component,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rouleur_global_mbias_enable(struct snd_soc_component *component)
|
int rouleur_global_mbias_enable(struct snd_soc_component *component)
|
||||||
{
|
{
|
||||||
struct rouleur_priv *rouleur = snd_soc_component_get_drvdata(component);
|
struct rouleur_priv *rouleur = snd_soc_component_get_drvdata(component);
|
||||||
|
|
||||||
@@ -319,7 +323,7 @@ static int rouleur_global_mbias_enable(struct snd_soc_component *component)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rouleur_global_mbias_disable(struct snd_soc_component *component)
|
int rouleur_global_mbias_disable(struct snd_soc_component *component)
|
||||||
{
|
{
|
||||||
struct rouleur_priv *rouleur = snd_soc_component_get_drvdata(component);
|
struct rouleur_priv *rouleur = snd_soc_component_get_drvdata(component);
|
||||||
|
|
||||||
@@ -354,7 +358,7 @@ static int rouleur_rx_clk_enable(struct snd_soc_component *component)
|
|||||||
usleep_range(5000, 5100);
|
usleep_range(5000, 5100);
|
||||||
rouleur_global_mbias_enable(component);
|
rouleur_global_mbias_enable(component);
|
||||||
snd_soc_component_update_bits(component,
|
snd_soc_component_update_bits(component,
|
||||||
ROULEUR_ANA_HPHPA_FSM_CLK, 0x11, 0x11);
|
ROULEUR_ANA_HPHPA_FSM_CLK, 0x7F, 0x11);
|
||||||
snd_soc_component_update_bits(component,
|
snd_soc_component_update_bits(component,
|
||||||
ROULEUR_ANA_HPHPA_FSM_CLK, 0x80, 0x80);
|
ROULEUR_ANA_HPHPA_FSM_CLK, 0x80, 0x80);
|
||||||
snd_soc_component_update_bits(component,
|
snd_soc_component_update_bits(component,
|
||||||
@@ -382,14 +386,14 @@ static int rouleur_rx_clk_disable(struct snd_soc_component *component)
|
|||||||
snd_soc_component_update_bits(component,
|
snd_soc_component_update_bits(component,
|
||||||
ROULEUR_ANA_HPHPA_FSM_CLK, 0x80, 0x00);
|
ROULEUR_ANA_HPHPA_FSM_CLK, 0x80, 0x00);
|
||||||
snd_soc_component_update_bits(component,
|
snd_soc_component_update_bits(component,
|
||||||
ROULEUR_ANA_HPHPA_FSM_CLK, 0x11, 0x00);
|
ROULEUR_ANA_HPHPA_FSM_CLK, 0x7F, 0x00);
|
||||||
snd_soc_component_update_bits(component,
|
snd_soc_component_update_bits(component,
|
||||||
ROULEUR_ANA_NCP_EN, 0x01, 0x00);
|
ROULEUR_ANA_NCP_EN, 0x01, 0x00);
|
||||||
rouleur_global_mbias_disable(component);
|
|
||||||
snd_soc_component_update_bits(component,
|
snd_soc_component_update_bits(component,
|
||||||
ROULEUR_DIG_SWR_CDC_RX_CLK_CTL, 0x20, 0x00);
|
ROULEUR_DIG_SWR_CDC_RX_CLK_CTL, 0x20, 0x00);
|
||||||
snd_soc_component_update_bits(component,
|
snd_soc_component_update_bits(component,
|
||||||
ROULEUR_DIG_SWR_CDC_RX_CLK_CTL, 0x10, 0x00);
|
ROULEUR_DIG_SWR_CDC_RX_CLK_CTL, 0x10, 0x00);
|
||||||
|
rouleur_global_mbias_disable(component);
|
||||||
|
|
||||||
}
|
}
|
||||||
mutex_unlock(&rouleur->rx_clk_lock);
|
mutex_unlock(&rouleur->rx_clk_lock);
|
||||||
@@ -469,23 +473,27 @@ static int rouleur_codec_hphl_dac_event(struct snd_soc_dapm_widget *w,
|
|||||||
}
|
}
|
||||||
snd_soc_component_update_bits(component,
|
snd_soc_component_update_bits(component,
|
||||||
ROULEUR_DIG_SWR_CDC_RX0_CTL,
|
ROULEUR_DIG_SWR_CDC_RX0_CTL,
|
||||||
0x7C, 0x7C);
|
0x80, 0x00);
|
||||||
snd_soc_component_update_bits(component,
|
snd_soc_component_update_bits(component,
|
||||||
ROULEUR_DIG_SWR_CDC_RX_GAIN_CTL,
|
ROULEUR_DIG_SWR_CDC_RX_GAIN_CTL,
|
||||||
0x04, 0x04);
|
0x04, 0x04);
|
||||||
snd_soc_component_update_bits(component,
|
snd_soc_component_update_bits(component,
|
||||||
ROULEUR_DIG_SWR_CDC_RX_CLK_CTL, 0x01, 0x01);
|
ROULEUR_DIG_SWR_CDC_RX_CLK_CTL, 0x01, 0x01);
|
||||||
snd_soc_component_update_bits(component,
|
|
||||||
ROULEUR_DIG_SWR_PDM_WD_CTL0,
|
|
||||||
0x03, 0x03);
|
|
||||||
break;
|
break;
|
||||||
case SND_SOC_DAPM_POST_PMD:
|
case SND_SOC_DAPM_POST_PMD:
|
||||||
snd_soc_component_update_bits(component,
|
|
||||||
ROULEUR_DIG_SWR_PDM_WD_CTL0,
|
|
||||||
0x03, 0x00);
|
|
||||||
snd_soc_component_update_bits(component,
|
snd_soc_component_update_bits(component,
|
||||||
ROULEUR_DIG_SWR_CDC_RX_CLK_CTL,
|
ROULEUR_DIG_SWR_CDC_RX_CLK_CTL,
|
||||||
0x01, 0x00);
|
0x01, 0x00);
|
||||||
|
snd_soc_component_update_bits(component,
|
||||||
|
ROULEUR_DIG_SWR_CDC_RX_GAIN_CTL,
|
||||||
|
0x04, 0x00);
|
||||||
|
snd_soc_component_update_bits(component,
|
||||||
|
ROULEUR_DIG_SWR_CDC_RX0_CTL,
|
||||||
|
0x80, 0x80);
|
||||||
|
if (rouleur->comp1_enable)
|
||||||
|
snd_soc_component_update_bits(component,
|
||||||
|
ROULEUR_DIG_SWR_CDC_COMP_CTL_0,
|
||||||
|
0x02, 0x00);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -540,22 +548,26 @@ static int rouleur_codec_hphr_dac_event(struct snd_soc_dapm_widget *w,
|
|||||||
}
|
}
|
||||||
snd_soc_component_update_bits(component,
|
snd_soc_component_update_bits(component,
|
||||||
ROULEUR_DIG_SWR_CDC_RX1_CTL,
|
ROULEUR_DIG_SWR_CDC_RX1_CTL,
|
||||||
0x7C, 0x7C);
|
0x80, 0x00);
|
||||||
snd_soc_component_update_bits(component,
|
snd_soc_component_update_bits(component,
|
||||||
ROULEUR_DIG_SWR_CDC_RX_GAIN_CTL,
|
ROULEUR_DIG_SWR_CDC_RX_GAIN_CTL,
|
||||||
0x08, 0x08);
|
0x08, 0x08);
|
||||||
snd_soc_component_update_bits(component,
|
snd_soc_component_update_bits(component,
|
||||||
ROULEUR_DIG_SWR_CDC_RX_CLK_CTL, 0x02, 0x02);
|
ROULEUR_DIG_SWR_CDC_RX_CLK_CTL, 0x02, 0x02);
|
||||||
snd_soc_component_update_bits(component,
|
|
||||||
ROULEUR_DIG_SWR_PDM_WD_CTL1,
|
|
||||||
0x03, 0x03);
|
|
||||||
break;
|
break;
|
||||||
case SND_SOC_DAPM_POST_PMD:
|
case SND_SOC_DAPM_POST_PMD:
|
||||||
snd_soc_component_update_bits(component,
|
|
||||||
ROULEUR_DIG_SWR_PDM_WD_CTL1,
|
|
||||||
0x03, 0x00);
|
|
||||||
snd_soc_component_update_bits(component,
|
snd_soc_component_update_bits(component,
|
||||||
ROULEUR_DIG_SWR_CDC_RX_CLK_CTL, 0x02, 0x00);
|
ROULEUR_DIG_SWR_CDC_RX_CLK_CTL, 0x02, 0x00);
|
||||||
|
snd_soc_component_update_bits(component,
|
||||||
|
ROULEUR_DIG_SWR_CDC_RX_GAIN_CTL,
|
||||||
|
0x08, 0x00);
|
||||||
|
snd_soc_component_update_bits(component,
|
||||||
|
ROULEUR_DIG_SWR_CDC_RX1_CTL,
|
||||||
|
0x80, 0x80);
|
||||||
|
if (rouleur->comp2_enable)
|
||||||
|
snd_soc_component_update_bits(component,
|
||||||
|
ROULEUR_DIG_SWR_CDC_COMP_CTL_0,
|
||||||
|
0x01, 0x00);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -578,25 +590,25 @@ static int rouleur_codec_ear_lo_dac_event(struct snd_soc_dapm_widget *w,
|
|||||||
rouleur_rx_clk_enable(component);
|
rouleur_rx_clk_enable(component);
|
||||||
snd_soc_component_update_bits(component,
|
snd_soc_component_update_bits(component,
|
||||||
ROULEUR_DIG_SWR_CDC_RX0_CTL,
|
ROULEUR_DIG_SWR_CDC_RX0_CTL,
|
||||||
0x7C, 0x7C);
|
0x80, 0x00);
|
||||||
snd_soc_component_update_bits(component,
|
|
||||||
ROULEUR_DIG_SWR_CDC_RX_CLK_CTL,
|
|
||||||
0x01, 0x01);
|
|
||||||
snd_soc_component_update_bits(component,
|
|
||||||
ROULEUR_DIG_SWR_PDM_WD_CTL0,
|
|
||||||
0x03, 0x03);
|
|
||||||
snd_soc_component_update_bits(component,
|
snd_soc_component_update_bits(component,
|
||||||
ROULEUR_DIG_SWR_CDC_RX_GAIN_CTL,
|
ROULEUR_DIG_SWR_CDC_RX_GAIN_CTL,
|
||||||
0x04, 0x04);
|
0x04, 0x04);
|
||||||
|
snd_soc_component_update_bits(component,
|
||||||
|
ROULEUR_DIG_SWR_CDC_RX_CLK_CTL,
|
||||||
|
0x01, 0x01);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case SND_SOC_DAPM_POST_PMD:
|
case SND_SOC_DAPM_POST_PMD:
|
||||||
snd_soc_component_update_bits(component,
|
|
||||||
ROULEUR_DIG_SWR_PDM_WD_CTL0,
|
|
||||||
0x03, 0x00);
|
|
||||||
snd_soc_component_update_bits(component,
|
snd_soc_component_update_bits(component,
|
||||||
ROULEUR_DIG_SWR_CDC_RX_CLK_CTL,
|
ROULEUR_DIG_SWR_CDC_RX_CLK_CTL,
|
||||||
0x01, 0x00);
|
0x01, 0x00);
|
||||||
|
snd_soc_component_update_bits(component,
|
||||||
|
ROULEUR_DIG_SWR_CDC_RX_GAIN_CTL,
|
||||||
|
0x04, 0x00);
|
||||||
|
snd_soc_component_update_bits(component,
|
||||||
|
ROULEUR_DIG_SWR_CDC_RX0_CTL,
|
||||||
|
0x80, 0x80);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
@@ -622,14 +634,11 @@ static int rouleur_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
|
|||||||
rouleur->rx_swr_dev->dev_num,
|
rouleur->rx_swr_dev->dev_num,
|
||||||
true);
|
true);
|
||||||
|
|
||||||
snd_soc_component_update_bits(component,
|
|
||||||
ROULEUR_ANA_HPHPA_CNP_CTL_2,
|
|
||||||
0x40, 0x40);
|
|
||||||
set_bit(HPH_PA_DELAY, &rouleur->status_mask);
|
set_bit(HPH_PA_DELAY, &rouleur->status_mask);
|
||||||
/* TODO: WHY SECOND TIME */
|
usleep_range(5000, 5100);
|
||||||
ret = swr_slvdev_datapath_control(rouleur->rx_swr_dev,
|
snd_soc_component_update_bits(component,
|
||||||
rouleur->rx_swr_dev->dev_num,
|
ROULEUR_DIG_SWR_PDM_WD_CTL1,
|
||||||
true);
|
0x03, 0x03);
|
||||||
break;
|
break;
|
||||||
case SND_SOC_DAPM_POST_PMU:
|
case SND_SOC_DAPM_POST_PMU:
|
||||||
/*
|
/*
|
||||||
@@ -676,8 +685,8 @@ static int rouleur_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
|
|||||||
WCD_EVENT_POST_HPHR_PA_OFF,
|
WCD_EVENT_POST_HPHR_PA_OFF,
|
||||||
&rouleur->mbhc->wcd_mbhc);
|
&rouleur->mbhc->wcd_mbhc);
|
||||||
snd_soc_component_update_bits(component,
|
snd_soc_component_update_bits(component,
|
||||||
ROULEUR_ANA_HPHPA_CNP_CTL_2,
|
ROULEUR_DIG_SWR_PDM_WD_CTL1,
|
||||||
0x40, 0x00);
|
0x03, 0x00);
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
return ret;
|
return ret;
|
||||||
@@ -700,10 +709,11 @@ static int rouleur_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
|
|||||||
ret = swr_slvdev_datapath_control(rouleur->rx_swr_dev,
|
ret = swr_slvdev_datapath_control(rouleur->rx_swr_dev,
|
||||||
rouleur->rx_swr_dev->dev_num,
|
rouleur->rx_swr_dev->dev_num,
|
||||||
true);
|
true);
|
||||||
snd_soc_component_update_bits(component,
|
|
||||||
ROULEUR_ANA_HPHPA_CNP_CTL_2,
|
|
||||||
0x80, 0x80);
|
|
||||||
set_bit(HPH_PA_DELAY, &rouleur->status_mask);
|
set_bit(HPH_PA_DELAY, &rouleur->status_mask);
|
||||||
|
usleep_range(5000, 5100);
|
||||||
|
snd_soc_component_update_bits(component,
|
||||||
|
ROULEUR_DIG_SWR_PDM_WD_CTL0,
|
||||||
|
0x03, 0x03);
|
||||||
break;
|
break;
|
||||||
case SND_SOC_DAPM_POST_PMU:
|
case SND_SOC_DAPM_POST_PMU:
|
||||||
/*
|
/*
|
||||||
@@ -748,8 +758,8 @@ static int rouleur_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
|
|||||||
WCD_EVENT_POST_HPHL_PA_OFF,
|
WCD_EVENT_POST_HPHL_PA_OFF,
|
||||||
&rouleur->mbhc->wcd_mbhc);
|
&rouleur->mbhc->wcd_mbhc);
|
||||||
snd_soc_component_update_bits(component,
|
snd_soc_component_update_bits(component,
|
||||||
ROULEUR_ANA_HPHPA_CNP_CTL_2,
|
ROULEUR_DIG_SWR_PDM_WD_CTL0,
|
||||||
0x80, 0x00);
|
0x03, 0x00);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
@@ -773,10 +783,10 @@ static int rouleur_codec_enable_ear_pa(struct snd_soc_dapm_widget *w,
|
|||||||
ret = swr_slvdev_datapath_control(rouleur->rx_swr_dev,
|
ret = swr_slvdev_datapath_control(rouleur->rx_swr_dev,
|
||||||
rouleur->rx_swr_dev->dev_num,
|
rouleur->rx_swr_dev->dev_num,
|
||||||
true);
|
true);
|
||||||
snd_soc_component_update_bits(component,
|
|
||||||
ROULEUR_ANA_COMBOPA_CTL,
|
|
||||||
0x80, 0x80);
|
|
||||||
usleep_range(5000, 5100);
|
usleep_range(5000, 5100);
|
||||||
|
snd_soc_component_update_bits(component,
|
||||||
|
ROULEUR_DIG_SWR_PDM_WD_CTL0,
|
||||||
|
0x03, 0x03);
|
||||||
break;
|
break;
|
||||||
case SND_SOC_DAPM_POST_PMU:
|
case SND_SOC_DAPM_POST_PMU:
|
||||||
if (rouleur->update_wcd_event)
|
if (rouleur->update_wcd_event)
|
||||||
@@ -795,10 +805,10 @@ static int rouleur_codec_enable_ear_pa(struct snd_soc_dapm_widget *w,
|
|||||||
(WCD_RX1 << 0x10 | 0x1));
|
(WCD_RX1 << 0x10 | 0x1));
|
||||||
break;
|
break;
|
||||||
case SND_SOC_DAPM_POST_PMD:
|
case SND_SOC_DAPM_POST_PMD:
|
||||||
snd_soc_component_update_bits(component,
|
|
||||||
ROULEUR_ANA_COMBOPA_CTL,
|
|
||||||
0x80, 0x00);
|
|
||||||
usleep_range(5000, 5100);
|
usleep_range(5000, 5100);
|
||||||
|
snd_soc_component_update_bits(component,
|
||||||
|
ROULEUR_DIG_SWR_PDM_WD_CTL0,
|
||||||
|
0x03, 0x00);
|
||||||
};
|
};
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -823,10 +833,10 @@ static int rouleur_codec_enable_lo_pa(struct snd_soc_dapm_widget *w,
|
|||||||
snd_soc_component_update_bits(component,
|
snd_soc_component_update_bits(component,
|
||||||
ROULEUR_ANA_COMBOPA_CTL,
|
ROULEUR_ANA_COMBOPA_CTL,
|
||||||
0x40, 0x40);
|
0x40, 0x40);
|
||||||
snd_soc_component_update_bits(component,
|
|
||||||
ROULEUR_ANA_COMBOPA_CTL,
|
|
||||||
0x80, 0x80);
|
|
||||||
usleep_range(5000, 5100);
|
usleep_range(5000, 5100);
|
||||||
|
snd_soc_component_update_bits(component,
|
||||||
|
ROULEUR_DIG_SWR_PDM_WD_CTL0,
|
||||||
|
0x03, 0x03);
|
||||||
break;
|
break;
|
||||||
case SND_SOC_DAPM_POST_PMU:
|
case SND_SOC_DAPM_POST_PMU:
|
||||||
if (rouleur->update_wcd_event)
|
if (rouleur->update_wcd_event)
|
||||||
@@ -845,13 +855,13 @@ static int rouleur_codec_enable_lo_pa(struct snd_soc_dapm_widget *w,
|
|||||||
(WCD_RX1 << 0x10 | 0x1));
|
(WCD_RX1 << 0x10 | 0x1));
|
||||||
break;
|
break;
|
||||||
case SND_SOC_DAPM_POST_PMD:
|
case SND_SOC_DAPM_POST_PMD:
|
||||||
snd_soc_component_update_bits(component,
|
|
||||||
ROULEUR_ANA_COMBOPA_CTL,
|
|
||||||
0x80, 0x00);
|
|
||||||
snd_soc_component_update_bits(component,
|
snd_soc_component_update_bits(component,
|
||||||
ROULEUR_ANA_COMBOPA_CTL,
|
ROULEUR_ANA_COMBOPA_CTL,
|
||||||
0x40, 0x00);
|
0x40, 0x00);
|
||||||
usleep_range(5000, 5100);
|
usleep_range(5000, 5100);
|
||||||
|
snd_soc_component_update_bits(component,
|
||||||
|
ROULEUR_DIG_SWR_PDM_WD_CTL0,
|
||||||
|
0x03, 0x00);
|
||||||
};
|
};
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -1166,6 +1176,7 @@ int rouleur_micbias_control(struct snd_soc_component *component,
|
|||||||
int post_on_event = 0, post_dapm_off = 0;
|
int post_on_event = 0, post_dapm_off = 0;
|
||||||
int post_dapm_on = 0;
|
int post_dapm_on = 0;
|
||||||
u8 pullup_mask = 0, enable_mask = 0;
|
u8 pullup_mask = 0, enable_mask = 0;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
if ((micb_index < 0) || (micb_index > ROULEUR_MAX_MICBIAS - 1)) {
|
if ((micb_index < 0) || (micb_index > ROULEUR_MAX_MICBIAS - 1)) {
|
||||||
dev_err(component->dev, "%s: Invalid micbias index, micb_ind:%d\n",
|
dev_err(component->dev, "%s: Invalid micbias index, micb_ind:%d\n",
|
||||||
@@ -1201,6 +1212,12 @@ int rouleur_micbias_control(struct snd_soc_component *component,
|
|||||||
|
|
||||||
switch (req) {
|
switch (req) {
|
||||||
case MICB_PULLUP_ENABLE:
|
case MICB_PULLUP_ENABLE:
|
||||||
|
if (!rouleur->dev_up) {
|
||||||
|
dev_dbg(component->dev, "%s: enable req %d wcd device down\n",
|
||||||
|
__func__, req);
|
||||||
|
ret = -ENODEV;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
rouleur->pullup_ref[micb_index]++;
|
rouleur->pullup_ref[micb_index]++;
|
||||||
if ((rouleur->pullup_ref[micb_index] == 1) &&
|
if ((rouleur->pullup_ref[micb_index] == 1) &&
|
||||||
(rouleur->micb_ref[micb_index] == 0))
|
(rouleur->micb_ref[micb_index] == 0))
|
||||||
@@ -1208,6 +1225,12 @@ int rouleur_micbias_control(struct snd_soc_component *component,
|
|||||||
pullup_mask, pullup_mask);
|
pullup_mask, pullup_mask);
|
||||||
break;
|
break;
|
||||||
case MICB_PULLUP_DISABLE:
|
case MICB_PULLUP_DISABLE:
|
||||||
|
if (!rouleur->dev_up) {
|
||||||
|
dev_dbg(component->dev, "%s: enable req %d wcd device down\n",
|
||||||
|
__func__, req);
|
||||||
|
ret = -ENODEV;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
if (rouleur->pullup_ref[micb_index] > 0)
|
if (rouleur->pullup_ref[micb_index] > 0)
|
||||||
rouleur->pullup_ref[micb_index]--;
|
rouleur->pullup_ref[micb_index]--;
|
||||||
if ((rouleur->pullup_ref[micb_index] == 0) &&
|
if ((rouleur->pullup_ref[micb_index] == 0) &&
|
||||||
@@ -1216,11 +1239,15 @@ int rouleur_micbias_control(struct snd_soc_component *component,
|
|||||||
pullup_mask, 0x00);
|
pullup_mask, 0x00);
|
||||||
break;
|
break;
|
||||||
case MICB_ENABLE:
|
case MICB_ENABLE:
|
||||||
|
if (!rouleur->dev_up) {
|
||||||
|
dev_dbg(component->dev, "%s: enable req %d wcd device down\n",
|
||||||
|
__func__, req);
|
||||||
|
ret = -ENODEV;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
rouleur->micb_ref[micb_index]++;
|
rouleur->micb_ref[micb_index]++;
|
||||||
if (rouleur->micb_ref[micb_index] == 1) {
|
if (rouleur->micb_ref[micb_index] == 1) {
|
||||||
rouleur_global_mbias_enable(component);
|
rouleur_global_mbias_enable(component);
|
||||||
snd_soc_component_update_bits(component, micb_reg,
|
|
||||||
0x80, 0x80);
|
|
||||||
snd_soc_component_update_bits(component,
|
snd_soc_component_update_bits(component,
|
||||||
micb_reg, enable_mask, enable_mask);
|
micb_reg, enable_mask, enable_mask);
|
||||||
if (post_on_event)
|
if (post_on_event)
|
||||||
@@ -1236,7 +1263,20 @@ int rouleur_micbias_control(struct snd_soc_component *component,
|
|||||||
case MICB_DISABLE:
|
case MICB_DISABLE:
|
||||||
if (rouleur->micb_ref[micb_index] > 0)
|
if (rouleur->micb_ref[micb_index] > 0)
|
||||||
rouleur->micb_ref[micb_index]--;
|
rouleur->micb_ref[micb_index]--;
|
||||||
|
if (!rouleur->dev_up) {
|
||||||
|
dev_dbg(component->dev, "%s: enable req %d wcd device down\n",
|
||||||
|
__func__, req);
|
||||||
|
ret = -ENODEV;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
if ((rouleur->micb_ref[micb_index] == 0) &&
|
if ((rouleur->micb_ref[micb_index] == 0) &&
|
||||||
|
(rouleur->pullup_ref[micb_index] > 0)) {
|
||||||
|
snd_soc_component_update_bits(component, micb_reg,
|
||||||
|
pullup_mask, pullup_mask);
|
||||||
|
snd_soc_component_update_bits(component, micb_reg,
|
||||||
|
enable_mask, 0x00);
|
||||||
|
rouleur_global_mbias_disable(component);
|
||||||
|
} else if ((rouleur->micb_ref[micb_index] == 0) &&
|
||||||
(rouleur->pullup_ref[micb_index] == 0)) {
|
(rouleur->pullup_ref[micb_index] == 0)) {
|
||||||
if (pre_off_event && rouleur->mbhc)
|
if (pre_off_event && rouleur->mbhc)
|
||||||
blocking_notifier_call_chain(
|
blocking_notifier_call_chain(
|
||||||
@@ -1244,8 +1284,6 @@ int rouleur_micbias_control(struct snd_soc_component *component,
|
|||||||
&rouleur->mbhc->wcd_mbhc);
|
&rouleur->mbhc->wcd_mbhc);
|
||||||
snd_soc_component_update_bits(component, micb_reg,
|
snd_soc_component_update_bits(component, micb_reg,
|
||||||
enable_mask, 0x00);
|
enable_mask, 0x00);
|
||||||
snd_soc_component_update_bits(component, micb_reg,
|
|
||||||
0x80, 0x00);
|
|
||||||
rouleur_global_mbias_disable(component);
|
rouleur_global_mbias_disable(component);
|
||||||
if (post_off_event && rouleur->mbhc)
|
if (post_off_event && rouleur->mbhc)
|
||||||
blocking_notifier_call_chain(
|
blocking_notifier_call_chain(
|
||||||
@@ -1263,8 +1301,8 @@ int rouleur_micbias_control(struct snd_soc_component *component,
|
|||||||
dev_dbg(component->dev, "%s: micb_num:%d, micb_ref: %d, pullup_ref: %d\n",
|
dev_dbg(component->dev, "%s: micb_num:%d, micb_ref: %d, pullup_ref: %d\n",
|
||||||
__func__, micb_num, rouleur->micb_ref[micb_index],
|
__func__, micb_num, rouleur->micb_ref[micb_index],
|
||||||
rouleur->pullup_ref[micb_index]);
|
rouleur->pullup_ref[micb_index]);
|
||||||
|
done:
|
||||||
mutex_unlock(&rouleur->micb_lock);
|
mutex_unlock(&rouleur->micb_lock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(rouleur_micbias_control);
|
EXPORT_SYMBOL(rouleur_micbias_control);
|
||||||
@@ -1304,6 +1342,17 @@ static int rouleur_get_logical_addr(struct swr_device *swr_dev)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool get_usbc_hs_status(struct snd_soc_component *component,
|
||||||
|
struct wcd_mbhc_config *mbhc_cfg)
|
||||||
|
{
|
||||||
|
if (mbhc_cfg->enable_usbc_analog) {
|
||||||
|
if (!(snd_soc_component_read32(component, ROULEUR_ANA_MBHC_MECH)
|
||||||
|
& 0x20))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static int rouleur_event_notify(struct notifier_block *block,
|
static int rouleur_event_notify(struct notifier_block *block,
|
||||||
unsigned long val,
|
unsigned long val,
|
||||||
void *data)
|
void *data)
|
||||||
@@ -1333,8 +1382,11 @@ static int rouleur_event_notify(struct notifier_block *block,
|
|||||||
0x80, 0x00);
|
0x80, 0x00);
|
||||||
break;
|
break;
|
||||||
case BOLERO_WCD_EVT_SSR_DOWN:
|
case BOLERO_WCD_EVT_SSR_DOWN:
|
||||||
|
rouleur->dev_up = false;
|
||||||
rouleur->mbhc->wcd_mbhc.deinit_in_progress = true;
|
rouleur->mbhc->wcd_mbhc.deinit_in_progress = true;
|
||||||
mbhc = &rouleur->mbhc->wcd_mbhc;
|
mbhc = &rouleur->mbhc->wcd_mbhc;
|
||||||
|
rouleur->usbc_hs_status = get_usbc_hs_status(component,
|
||||||
|
mbhc->mbhc_cfg);
|
||||||
rouleur_mbhc_ssr_down(rouleur->mbhc, component);
|
rouleur_mbhc_ssr_down(rouleur->mbhc, component);
|
||||||
rouleur_reset(rouleur->dev, 0x01);
|
rouleur_reset(rouleur->dev, 0x01);
|
||||||
break;
|
break;
|
||||||
@@ -1356,8 +1408,11 @@ static int rouleur_event_notify(struct notifier_block *block,
|
|||||||
__func__);
|
__func__);
|
||||||
} else {
|
} else {
|
||||||
rouleur_mbhc_hs_detect(component, mbhc->mbhc_cfg);
|
rouleur_mbhc_hs_detect(component, mbhc->mbhc_cfg);
|
||||||
|
if (rouleur->usbc_hs_status)
|
||||||
|
mdelay(500);
|
||||||
}
|
}
|
||||||
rouleur->mbhc->wcd_mbhc.deinit_in_progress = false;
|
rouleur->mbhc->wcd_mbhc.deinit_in_progress = false;
|
||||||
|
rouleur->dev_up = true;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
dev_err(component->dev, "%s: invalid event %d\n", __func__,
|
dev_err(component->dev, "%s: invalid event %d\n", __func__,
|
||||||
@@ -1552,6 +1607,9 @@ static int rouleur_codec_enable_pa_vpos(struct snd_soc_dapm_widget *w,
|
|||||||
break;
|
break;
|
||||||
case SND_SOC_DAPM_POST_PMD:
|
case SND_SOC_DAPM_POST_PMD:
|
||||||
set_bit(ALLOW_VPOS_DISABLE, &rouleur->status_mask);
|
set_bit(ALLOW_VPOS_DISABLE, &rouleur->status_mask);
|
||||||
|
ret = swr_slvdev_datapath_control(rouleur->rx_swr_dev,
|
||||||
|
rouleur->rx_swr_dev->dev_num,
|
||||||
|
false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1822,7 +1880,7 @@ static ssize_t rouleur_version_read(struct snd_info_entry *entry,
|
|||||||
|
|
||||||
switch (priv->version) {
|
switch (priv->version) {
|
||||||
case ROULEUR_VERSION_1_0:
|
case ROULEUR_VERSION_1_0:
|
||||||
len = snprintf(buffer, sizeof(buffer), "rouleur_1_0\n");
|
len = snprintf(buffer, sizeof(buffer), "ROULEUR_1_0\n");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
len = snprintf(buffer, sizeof(buffer), "VER_UNDEFINED\n");
|
len = snprintf(buffer, sizeof(buffer), "VER_UNDEFINED\n");
|
||||||
@@ -1986,6 +2044,7 @@ static int rouleur_soc_codec_probe(struct snd_soc_component *component)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
rouleur->dev_up = true;
|
||||||
done:
|
done:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -2003,6 +2062,26 @@ static void rouleur_soc_codec_remove(struct snd_soc_component *component)
|
|||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int rouleur_soc_codec_suspend(struct snd_soc_component *component)
|
||||||
|
{
|
||||||
|
struct rouleur_priv *rouleur = snd_soc_component_get_drvdata(component);
|
||||||
|
|
||||||
|
if (!rouleur)
|
||||||
|
return 0;
|
||||||
|
rouleur->dapm_bias_off = true;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rouleur_soc_codec_resume(struct snd_soc_component *component)
|
||||||
|
{
|
||||||
|
struct rouleur_priv *rouleur = snd_soc_component_get_drvdata(component);
|
||||||
|
|
||||||
|
if (!rouleur)
|
||||||
|
return 0;
|
||||||
|
rouleur->dapm_bias_off = false;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static const struct snd_soc_component_driver soc_codec_dev_rouleur = {
|
static const struct snd_soc_component_driver soc_codec_dev_rouleur = {
|
||||||
.name = DRV_NAME,
|
.name = DRV_NAME,
|
||||||
.probe = rouleur_soc_codec_probe,
|
.probe = rouleur_soc_codec_probe,
|
||||||
@@ -2013,6 +2092,8 @@ static const struct snd_soc_component_driver soc_codec_dev_rouleur = {
|
|||||||
.num_dapm_widgets = ARRAY_SIZE(rouleur_dapm_widgets),
|
.num_dapm_widgets = ARRAY_SIZE(rouleur_dapm_widgets),
|
||||||
.dapm_routes = rouleur_audio_map,
|
.dapm_routes = rouleur_audio_map,
|
||||||
.num_dapm_routes = ARRAY_SIZE(rouleur_audio_map),
|
.num_dapm_routes = ARRAY_SIZE(rouleur_audio_map),
|
||||||
|
.suspend = rouleur_soc_codec_suspend,
|
||||||
|
.resume = rouleur_soc_codec_resume,
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_PM_SLEEP
|
#ifdef CONFIG_PM_SLEEP
|
||||||
@@ -2049,11 +2130,45 @@ static int rouleur_suspend(struct device *dev)
|
|||||||
}
|
}
|
||||||
clear_bit(ALLOW_VPOS_DISABLE, &rouleur->status_mask);
|
clear_bit(ALLOW_VPOS_DISABLE, &rouleur->status_mask);
|
||||||
}
|
}
|
||||||
|
if (rouleur->dapm_bias_off) {
|
||||||
|
msm_cdc_set_supplies_lpm_mode(rouleur->dev,
|
||||||
|
rouleur->supplies,
|
||||||
|
pdata->regulator,
|
||||||
|
pdata->num_supplies,
|
||||||
|
true);
|
||||||
|
set_bit(WCD_SUPPLIES_LPM_MODE, &rouleur->status_mask);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rouleur_resume(struct device *dev)
|
static int rouleur_resume(struct device *dev)
|
||||||
{
|
{
|
||||||
|
struct rouleur_priv *rouleur = NULL;
|
||||||
|
struct rouleur_pdata *pdata = NULL;
|
||||||
|
|
||||||
|
if (!dev)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
rouleur = dev_get_drvdata(dev);
|
||||||
|
if (!rouleur)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
pdata = dev_get_platdata(rouleur->dev);
|
||||||
|
|
||||||
|
if (!pdata) {
|
||||||
|
dev_err(dev, "%s: pdata is NULL\n", __func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (test_bit(WCD_SUPPLIES_LPM_MODE, &rouleur->status_mask)) {
|
||||||
|
msm_cdc_set_supplies_lpm_mode(rouleur->dev,
|
||||||
|
rouleur->supplies,
|
||||||
|
pdata->regulator,
|
||||||
|
pdata->num_supplies,
|
||||||
|
false);
|
||||||
|
clear_bit(WCD_SUPPLIES_LPM_MODE, &rouleur->status_mask);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -2484,10 +2599,8 @@ static int rouleur_remove(struct platform_device *pdev)
|
|||||||
|
|
||||||
#ifdef CONFIG_PM_SLEEP
|
#ifdef CONFIG_PM_SLEEP
|
||||||
static const struct dev_pm_ops rouleur_dev_pm_ops = {
|
static const struct dev_pm_ops rouleur_dev_pm_ops = {
|
||||||
SET_SYSTEM_SLEEP_PM_OPS(
|
.suspend_late = rouleur_suspend,
|
||||||
rouleur_suspend,
|
.resume_early = rouleur_resume
|
||||||
rouleur_resume
|
|
||||||
)
|
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -11,15 +11,276 @@
|
|||||||
#include <linux/component.h>
|
#include <linux/component.h>
|
||||||
#include <soc/soundwire.h>
|
#include <soc/soundwire.h>
|
||||||
|
|
||||||
|
#ifdef CONFIG_DEBUG_FS
|
||||||
|
#include <linux/debugfs.h>
|
||||||
|
#include <linux/uaccess.h>
|
||||||
|
|
||||||
|
#define SWR_SLV_MAX_REG_ADDR 0x2009
|
||||||
|
#define SWR_SLV_START_REG_ADDR 0x40
|
||||||
|
#define SWR_SLV_MAX_BUF_LEN 20
|
||||||
|
#define BYTES_PER_LINE 12
|
||||||
|
#define SWR_SLV_RD_BUF_LEN 8
|
||||||
|
#define SWR_SLV_WR_BUF_LEN 32
|
||||||
|
#define SWR_SLV_MAX_DEVICES 2
|
||||||
|
#endif /* CONFIG_DEBUG_FS */
|
||||||
|
|
||||||
struct rouleur_slave_priv {
|
struct rouleur_slave_priv {
|
||||||
struct swr_device *swr_slave;
|
struct swr_device *swr_slave;
|
||||||
|
#ifdef CONFIG_DEBUG_FS
|
||||||
|
struct dentry *debugfs_rouleur_dent;
|
||||||
|
struct dentry *debugfs_peek;
|
||||||
|
struct dentry *debugfs_poke;
|
||||||
|
struct dentry *debugfs_reg_dump;
|
||||||
|
unsigned int read_data;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef CONFIG_DEBUG_FS
|
||||||
|
static int codec_debug_open(struct inode *inode, struct file *file)
|
||||||
|
{
|
||||||
|
file->private_data = inode->i_private;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_parameters(char *buf, u32 *param1, int num_of_par)
|
||||||
|
{
|
||||||
|
char *token = NULL;
|
||||||
|
int base = 0, cnt = 0;
|
||||||
|
|
||||||
|
token = strsep(&buf, " ");
|
||||||
|
for (cnt = 0; cnt < num_of_par; cnt++) {
|
||||||
|
if (token) {
|
||||||
|
if ((token[1] == 'x') || (token[1] == 'X'))
|
||||||
|
base = 16;
|
||||||
|
else
|
||||||
|
base = 10;
|
||||||
|
|
||||||
|
if (kstrtou32(token, base, ¶m1[cnt]) != 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
token = strsep(&buf, " ");
|
||||||
|
} else {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool is_swr_slv_reg_readable(int reg)
|
||||||
|
{
|
||||||
|
int ret = true;
|
||||||
|
|
||||||
|
if (((reg > 0x46) && (reg < 0x4A)) ||
|
||||||
|
((reg > 0x4A) && (reg < 0x50)) ||
|
||||||
|
((reg > 0x55) && (reg < 0xD0)) ||
|
||||||
|
((reg > 0xD0) && (reg < 0xE0)) ||
|
||||||
|
((reg > 0xE0) && (reg < 0xF0)) ||
|
||||||
|
((reg > 0xF0) && (reg < 0x100)) ||
|
||||||
|
((reg > 0x105) && (reg < 0x120)) ||
|
||||||
|
((reg > 0x205) && (reg < 0x220)) ||
|
||||||
|
((reg > 0x305) && (reg < 0x320)) ||
|
||||||
|
((reg > 0x405) && (reg < 0x420)) ||
|
||||||
|
((reg > 0x128) && (reg < 0x130)) ||
|
||||||
|
((reg > 0x228) && (reg < 0x230)) ||
|
||||||
|
((reg > 0x328) && (reg < 0x330)) ||
|
||||||
|
((reg > 0x428) && (reg < 0x430)) ||
|
||||||
|
((reg > 0x138) && (reg < 0x205)) ||
|
||||||
|
((reg > 0x238) && (reg < 0x305)) ||
|
||||||
|
((reg > 0x338) && (reg < 0x405)) ||
|
||||||
|
((reg > 0x405) && (reg < 0xF00)) ||
|
||||||
|
((reg > 0xF05) && (reg < 0xF20)) ||
|
||||||
|
((reg > 0xF25) && (reg < 0xF30)) ||
|
||||||
|
((reg > 0xF35) && (reg < 0x2000)))
|
||||||
|
ret = false;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t rouleur_swrslave_reg_show(struct swr_device *pdev,
|
||||||
|
char __user *ubuf,
|
||||||
|
size_t count, loff_t *ppos)
|
||||||
|
{
|
||||||
|
int i, reg_val, len;
|
||||||
|
ssize_t total = 0;
|
||||||
|
char tmp_buf[SWR_SLV_MAX_BUF_LEN];
|
||||||
|
|
||||||
|
if (!ubuf || !ppos)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (i = (((int) *ppos/BYTES_PER_LINE) + SWR_SLV_START_REG_ADDR);
|
||||||
|
i <= SWR_SLV_MAX_REG_ADDR; i++) {
|
||||||
|
if (!is_swr_slv_reg_readable(i))
|
||||||
|
continue;
|
||||||
|
swr_read(pdev, pdev->dev_num, i, ®_val, 1);
|
||||||
|
len = snprintf(tmp_buf, sizeof(tmp_buf), "0x%.3x: 0x%.2x\n", i,
|
||||||
|
(reg_val & 0xFF));
|
||||||
|
if (len < 0) {
|
||||||
|
pr_err("%s: fail to fill the buffer\n", __func__);
|
||||||
|
total = -EFAULT;
|
||||||
|
goto copy_err;
|
||||||
|
}
|
||||||
|
if (((total + len) >= count - 1) || (len < 0))
|
||||||
|
break;
|
||||||
|
if (copy_to_user((ubuf + total), tmp_buf, len)) {
|
||||||
|
pr_err("%s: fail to copy reg dump\n", __func__);
|
||||||
|
total = -EFAULT;
|
||||||
|
goto copy_err;
|
||||||
|
}
|
||||||
|
total += len;
|
||||||
|
*ppos += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
copy_err:
|
||||||
|
*ppos = SWR_SLV_MAX_REG_ADDR * BYTES_PER_LINE;
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t codec_debug_dump(struct file *file, char __user *ubuf,
|
||||||
|
size_t count, loff_t *ppos)
|
||||||
|
{
|
||||||
|
struct swr_device *pdev;
|
||||||
|
|
||||||
|
if (!count || !file || !ppos || !ubuf)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
pdev = file->private_data;
|
||||||
|
if (!pdev)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (*ppos < 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
return rouleur_swrslave_reg_show(pdev, ubuf, count, ppos);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t codec_debug_read(struct file *file, char __user *ubuf,
|
||||||
|
size_t count, loff_t *ppos)
|
||||||
|
{
|
||||||
|
char lbuf[SWR_SLV_RD_BUF_LEN];
|
||||||
|
struct swr_device *pdev = NULL;
|
||||||
|
struct rouleur_slave_priv *rouleur_slave = NULL;
|
||||||
|
|
||||||
|
if (!count || !file || !ppos || !ubuf)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
pdev = file->private_data;
|
||||||
|
if (!pdev)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
rouleur_slave = swr_get_dev_data(pdev);
|
||||||
|
if (!rouleur_slave)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (*ppos < 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
snprintf(lbuf, sizeof(lbuf), "0x%x\n",
|
||||||
|
(rouleur_slave->read_data & 0xFF));
|
||||||
|
|
||||||
|
return simple_read_from_buffer(ubuf, count, ppos, lbuf,
|
||||||
|
strnlen(lbuf, 7));
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t codec_debug_peek_write(struct file *file,
|
||||||
|
const char __user *ubuf, size_t cnt, loff_t *ppos)
|
||||||
|
{
|
||||||
|
char lbuf[SWR_SLV_WR_BUF_LEN];
|
||||||
|
int rc = 0;
|
||||||
|
u32 param[5];
|
||||||
|
struct swr_device *pdev = NULL;
|
||||||
|
struct rouleur_slave_priv *rouleur_slave = NULL;
|
||||||
|
|
||||||
|
if (!cnt || !file || !ppos || !ubuf)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
pdev = file->private_data;
|
||||||
|
if (!pdev)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
rouleur_slave = swr_get_dev_data(pdev);
|
||||||
|
if (!rouleur_slave)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (*ppos < 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (cnt > sizeof(lbuf) - 1)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
rc = copy_from_user(lbuf, ubuf, cnt);
|
||||||
|
if (rc)
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
|
lbuf[cnt] = '\0';
|
||||||
|
rc = get_parameters(lbuf, param, 1);
|
||||||
|
if (!((param[0] <= SWR_SLV_MAX_REG_ADDR) && (rc == 0)))
|
||||||
|
return -EINVAL;
|
||||||
|
swr_read(pdev, pdev->dev_num, param[0], &rouleur_slave->read_data, 1);
|
||||||
|
if (rc == 0)
|
||||||
|
rc = cnt;
|
||||||
|
else
|
||||||
|
pr_err("%s: rc = %d\n", __func__, rc);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t codec_debug_write(struct file *file,
|
||||||
|
const char __user *ubuf, size_t cnt, loff_t *ppos)
|
||||||
|
{
|
||||||
|
char lbuf[SWR_SLV_WR_BUF_LEN];
|
||||||
|
int rc = 0;
|
||||||
|
u32 param[5];
|
||||||
|
struct swr_device *pdev;
|
||||||
|
|
||||||
|
if (!file || !ppos || !ubuf)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
pdev = file->private_data;
|
||||||
|
if (!pdev)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (cnt > sizeof(lbuf) - 1)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
rc = copy_from_user(lbuf, ubuf, cnt);
|
||||||
|
if (rc)
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
|
lbuf[cnt] = '\0';
|
||||||
|
rc = get_parameters(lbuf, param, 2);
|
||||||
|
if (!((param[0] <= SWR_SLV_MAX_REG_ADDR) &&
|
||||||
|
(param[1] <= 0xFF) && (rc == 0)))
|
||||||
|
return -EINVAL;
|
||||||
|
swr_write(pdev, pdev->dev_num, param[0], ¶m[1]);
|
||||||
|
if (rc == 0)
|
||||||
|
rc = cnt;
|
||||||
|
else
|
||||||
|
pr_err("%s: rc = %d\n", __func__, rc);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct file_operations codec_debug_write_ops = {
|
||||||
|
.open = codec_debug_open,
|
||||||
|
.write = codec_debug_write,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct file_operations codec_debug_read_ops = {
|
||||||
|
.open = codec_debug_open,
|
||||||
|
.read = codec_debug_read,
|
||||||
|
.write = codec_debug_peek_write,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct file_operations codec_debug_dump_ops = {
|
||||||
|
.open = codec_debug_open,
|
||||||
|
.read = codec_debug_dump,
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
static int rouleur_slave_bind(struct device *dev,
|
static int rouleur_slave_bind(struct device *dev,
|
||||||
struct device *master, void *data)
|
struct device *master, void *data)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
struct rouleur_slave_priv *rouleur_slave = NULL;
|
|
||||||
uint8_t devnum = 0;
|
uint8_t devnum = 0;
|
||||||
struct swr_device *pdev = to_swr_device(dev);
|
struct swr_device *pdev = to_swr_device(dev);
|
||||||
|
|
||||||
@@ -28,15 +289,6 @@ static int rouleur_slave_bind(struct device *dev,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
rouleur_slave = devm_kzalloc(&pdev->dev,
|
|
||||||
sizeof(struct rouleur_slave_priv), GFP_KERNEL);
|
|
||||||
if (!rouleur_slave)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
swr_set_dev_data(pdev, rouleur_slave);
|
|
||||||
|
|
||||||
rouleur_slave->swr_slave = pdev;
|
|
||||||
|
|
||||||
ret = swr_get_logical_dev_num(pdev, pdev->addr, &devnum);
|
ret = swr_get_logical_dev_num(pdev, pdev->addr, &devnum);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_dbg(&pdev->dev,
|
dev_dbg(&pdev->dev,
|
||||||
@@ -67,7 +319,6 @@ static void rouleur_slave_unbind(struct device *dev,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
swr_set_dev_data(pdev, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct swr_device_id rouleur_swr_id[] = {
|
static const struct swr_device_id rouleur_swr_id[] = {
|
||||||
@@ -104,12 +355,61 @@ static int rouleur_swr_reset(struct swr_device *pdev)
|
|||||||
|
|
||||||
static int rouleur_swr_probe(struct swr_device *pdev)
|
static int rouleur_swr_probe(struct swr_device *pdev)
|
||||||
{
|
{
|
||||||
|
struct rouleur_slave_priv *rouleur_slave = NULL;
|
||||||
|
|
||||||
|
rouleur_slave = devm_kzalloc(&pdev->dev,
|
||||||
|
sizeof(struct rouleur_slave_priv), GFP_KERNEL);
|
||||||
|
if (!rouleur_slave)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
swr_set_dev_data(pdev, rouleur_slave);
|
||||||
|
|
||||||
|
rouleur_slave->swr_slave = pdev;
|
||||||
|
#ifdef CONFIG_DEBUG_FS
|
||||||
|
if (!rouleur_slave->debugfs_rouleur_dent) {
|
||||||
|
rouleur_slave->debugfs_rouleur_dent = debugfs_create_dir(
|
||||||
|
dev_name(&pdev->dev), 0);
|
||||||
|
if (!IS_ERR(rouleur_slave->debugfs_rouleur_dent)) {
|
||||||
|
rouleur_slave->debugfs_peek =
|
||||||
|
debugfs_create_file("swrslave_peek",
|
||||||
|
S_IFREG | 0444,
|
||||||
|
rouleur_slave->debugfs_rouleur_dent,
|
||||||
|
(void *) pdev,
|
||||||
|
&codec_debug_read_ops);
|
||||||
|
|
||||||
|
rouleur_slave->debugfs_poke =
|
||||||
|
debugfs_create_file("swrslave_poke",
|
||||||
|
S_IFREG | 0444,
|
||||||
|
rouleur_slave->debugfs_rouleur_dent,
|
||||||
|
(void *) pdev,
|
||||||
|
&codec_debug_write_ops);
|
||||||
|
|
||||||
|
rouleur_slave->debugfs_reg_dump =
|
||||||
|
debugfs_create_file(
|
||||||
|
"swrslave_reg_dump",
|
||||||
|
S_IFREG | 0444,
|
||||||
|
rouleur_slave->debugfs_rouleur_dent,
|
||||||
|
(void *) pdev,
|
||||||
|
&codec_debug_dump_ops);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
return component_add(&pdev->dev, &rouleur_slave_comp_ops);
|
return component_add(&pdev->dev, &rouleur_slave_comp_ops);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rouleur_swr_remove(struct swr_device *pdev)
|
static int rouleur_swr_remove(struct swr_device *pdev)
|
||||||
{
|
{
|
||||||
|
#ifdef CONFIG_DEBUG_FS
|
||||||
|
struct rouleur_slave_priv *rouleur_slave = swr_get_dev_data(pdev);
|
||||||
|
|
||||||
|
if (rouleur_slave) {
|
||||||
|
debugfs_remove_recursive(rouleur_slave->debugfs_rouleur_dent);
|
||||||
|
rouleur_slave->debugfs_rouleur_dent = NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
component_del(&pdev->dev, &rouleur_slave_comp_ops);
|
component_del(&pdev->dev, &rouleur_slave_comp_ops);
|
||||||
|
swr_set_dev_data(pdev, NULL);
|
||||||
|
swr_remove_device(pdev);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,5 +440,5 @@ static void __exit rouleur_slave_exit(void)
|
|||||||
module_init(rouleur_slave_init);
|
module_init(rouleur_slave_init);
|
||||||
module_exit(rouleur_slave_exit);
|
module_exit(rouleur_slave_exit);
|
||||||
|
|
||||||
MODULE_DESCRIPTION("WCD937X Swr Slave driver");
|
MODULE_DESCRIPTION("Rouleur Swr Slave driver");
|
||||||
MODULE_LICENSE("GPL v2");
|
MODULE_LICENSE("GPL v2");
|
||||||
|
@@ -30,6 +30,9 @@
|
|||||||
#include "wcd938x/wcd938x.h"
|
#include "wcd938x/wcd938x.h"
|
||||||
#include "swr-dmic.h"
|
#include "swr-dmic.h"
|
||||||
|
|
||||||
|
#define NUM_ATTEMPTS 5
|
||||||
|
#define SWRS_SCP_CONTROL 0x44
|
||||||
|
|
||||||
static int swr_master_channel_map[] = {
|
static int swr_master_channel_map[] = {
|
||||||
ZERO,
|
ZERO,
|
||||||
SWRM_TX1_CH1,
|
SWRM_TX1_CH1,
|
||||||
@@ -64,6 +67,7 @@ struct swr_dmic_priv {
|
|||||||
int is_en_supply;
|
int is_en_supply;
|
||||||
int port_type;
|
int port_type;
|
||||||
u8 tx_master_port_map[SWR_DMIC_MAX_PORTS];
|
u8 tx_master_port_map[SWR_DMIC_MAX_PORTS];
|
||||||
|
struct notifier_block nblock;
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *codec_name_list[] = {
|
const char *codec_name_list[] = {
|
||||||
@@ -243,38 +247,6 @@ static int dmic_swr_ctrl(struct snd_soc_dapm_widget *w,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int swr_dmic_enable_supply(struct snd_soc_dapm_widget *w,
|
|
||||||
struct snd_kcontrol *kcontrol,
|
|
||||||
int event)
|
|
||||||
{
|
|
||||||
struct snd_soc_component *component =
|
|
||||||
snd_soc_dapm_to_component(w->dapm);
|
|
||||||
struct swr_dmic_priv *swr_dmic =
|
|
||||||
snd_soc_component_get_drvdata(component);
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__,
|
|
||||||
w->name, event);
|
|
||||||
|
|
||||||
switch (event) {
|
|
||||||
case SND_SOC_DAPM_PRE_PMU:
|
|
||||||
ret = swr_dmic_up(swr_dmic->swr_slave);
|
|
||||||
break;
|
|
||||||
case SND_SOC_DAPM_POST_PMU:
|
|
||||||
ret = swr_dmic_reset(swr_dmic->swr_slave);
|
|
||||||
break;
|
|
||||||
case SND_SOC_DAPM_POST_PMD:
|
|
||||||
ret = swr_dmic_down(swr_dmic->swr_slave);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret)
|
|
||||||
dev_dbg(component->dev, "%s wname: %s event: %d ret : %d\n",
|
|
||||||
__func__, w->name, event, ret);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char * const tx_master_port_text[] = {
|
static const char * const tx_master_port_text[] = {
|
||||||
"ZERO", "SWRM_TX1_CH1", "SWRM_TX1_CH2", "SWRM_TX1_CH3", "SWRM_TX1_CH4",
|
"ZERO", "SWRM_TX1_CH1", "SWRM_TX1_CH2", "SWRM_TX1_CH3", "SWRM_TX1_CH4",
|
||||||
"SWRM_TX2_CH1", "SWRM_TX2_CH2", "SWRM_TX2_CH3", "SWRM_TX2_CH4",
|
"SWRM_TX2_CH1", "SWRM_TX2_CH2", "SWRM_TX2_CH3", "SWRM_TX2_CH4",
|
||||||
@@ -304,10 +276,6 @@ static const struct snd_soc_dapm_widget swr_dmic_dapm_widgets[] = {
|
|||||||
|
|
||||||
SND_SOC_DAPM_INPUT("SWR_DMIC"),
|
SND_SOC_DAPM_INPUT("SWR_DMIC"),
|
||||||
|
|
||||||
SND_SOC_DAPM_SUPPLY_S("SMIC_SUPPLY", 1, SND_SOC_NOPM, 0, 0,
|
|
||||||
swr_dmic_enable_supply,
|
|
||||||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
|
|
||||||
SND_SOC_DAPM_POST_PMD),
|
|
||||||
SND_SOC_DAPM_OUT_DRV_E("SMIC_PORT_EN", SND_SOC_NOPM, 0, 0, NULL, 0,
|
SND_SOC_DAPM_OUT_DRV_E("SMIC_PORT_EN", SND_SOC_NOPM, 0, 0, NULL, 0,
|
||||||
swr_dmic_port_enable,
|
swr_dmic_port_enable,
|
||||||
SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
|
SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
|
||||||
@@ -315,7 +283,6 @@ static const struct snd_soc_dapm_widget swr_dmic_dapm_widgets[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const struct snd_soc_dapm_route swr_dmic_audio_map[] = {
|
static const struct snd_soc_dapm_route swr_dmic_audio_map[] = {
|
||||||
{"SWR_DMIC", NULL, "SMIC_SUPPLY"},
|
|
||||||
{"SWR_DMIC_MIXER", "Switch", "SWR_DMIC"},
|
{"SWR_DMIC_MIXER", "Switch", "SWR_DMIC"},
|
||||||
{"SMIC_PORT_EN", NULL, "SWR_DMIC_MIXER"},
|
{"SMIC_PORT_EN", NULL, "SWR_DMIC_MIXER"},
|
||||||
{"SWR_DMIC_OUTPUT", NULL, "SMIC_PORT_EN"},
|
{"SWR_DMIC_OUTPUT", NULL, "SMIC_PORT_EN"},
|
||||||
@@ -325,11 +292,38 @@ static int swr_dmic_codec_probe(struct snd_soc_component *component)
|
|||||||
{
|
{
|
||||||
struct swr_dmic_priv *swr_dmic =
|
struct swr_dmic_priv *swr_dmic =
|
||||||
snd_soc_component_get_drvdata(component);
|
snd_soc_component_get_drvdata(component);
|
||||||
|
struct snd_soc_dapm_context *dapm =
|
||||||
|
snd_soc_component_get_dapm(component);
|
||||||
|
char w_name[100];
|
||||||
|
|
||||||
if (!swr_dmic)
|
if (!swr_dmic)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
swr_dmic->component = component;
|
swr_dmic->component = component;
|
||||||
|
snd_soc_dapm_ignore_suspend(dapm,
|
||||||
|
swr_dmic->dai_driver->capture.stream_name);
|
||||||
|
memset(w_name, 0, 100);
|
||||||
|
strlcpy(w_name, component->name_prefix, 100);
|
||||||
|
strlcat(w_name, " SWR_DMIC", 100);
|
||||||
|
snd_soc_dapm_ignore_suspend(dapm, w_name);
|
||||||
|
|
||||||
|
memset(w_name, 0, 100);
|
||||||
|
strlcpy(w_name, component->name_prefix, 100);
|
||||||
|
strlcat(w_name, " SMIC_SUPPLY", 100);
|
||||||
|
snd_soc_dapm_ignore_suspend(dapm, w_name);
|
||||||
|
|
||||||
|
memset(w_name, 0, 100);
|
||||||
|
strlcpy(w_name, component->name_prefix, 100);
|
||||||
|
strlcat(w_name, " SMIC_PORT_EN", 100);
|
||||||
|
snd_soc_dapm_ignore_suspend(dapm, w_name);
|
||||||
|
|
||||||
|
memset(w_name, 0, 100);
|
||||||
|
strlcpy(w_name, component->name_prefix, 100);
|
||||||
|
strlcat(w_name, " SWR_DMIC_OUTPUT", 100);
|
||||||
|
snd_soc_dapm_ignore_suspend(dapm, w_name);
|
||||||
|
|
||||||
|
snd_soc_dapm_sync(dapm);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -364,6 +358,8 @@ static int enable_wcd_codec_supply(struct swr_dmic_priv *swr_dmic, bool enable)
|
|||||||
pr_err("%s: component is NULL\n", __func__);
|
pr_err("%s: component is NULL\n", __func__);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
dev_dbg(component->dev, "%s: supply %d micbias: %d enable: %d\n",
|
||||||
|
__func__, swr_dmic->is_en_supply, micb_num, enable);
|
||||||
|
|
||||||
if (enable)
|
if (enable)
|
||||||
rc = wcd938x_codec_force_enable_micbias_v2(component,
|
rc = wcd938x_codec_force_enable_micbias_v2(component,
|
||||||
@@ -412,6 +408,29 @@ static struct snd_soc_dai_driver swr_dmic_dai[] = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int swr_dmic_event_notify(struct notifier_block *block,
|
||||||
|
unsigned long val,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
u16 event = (val & 0xffff);
|
||||||
|
int ret = 0;
|
||||||
|
struct swr_dmic_priv *swr_dmic = container_of(block,
|
||||||
|
struct swr_dmic_priv,
|
||||||
|
nblock);
|
||||||
|
switch (event) {
|
||||||
|
case WCD938X_EVT_SSR_DOWN:
|
||||||
|
ret = swr_dmic_down(swr_dmic->swr_slave);
|
||||||
|
break;
|
||||||
|
case WCD938X_EVT_SSR_UP:
|
||||||
|
ret = swr_dmic_up(swr_dmic->swr_slave);
|
||||||
|
if (!ret)
|
||||||
|
ret = swr_dmic_reset(swr_dmic->swr_slave);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int swr_dmic_probe(struct swr_device *pdev)
|
static int swr_dmic_probe(struct swr_device *pdev)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@@ -423,6 +442,7 @@ static int swr_dmic_probe(struct swr_device *pdev)
|
|||||||
const char *swr_dmic_name_prefix_of = NULL;
|
const char *swr_dmic_name_prefix_of = NULL;
|
||||||
const char *swr_dmic_codec_name_of = NULL;
|
const char *swr_dmic_codec_name_of = NULL;
|
||||||
struct snd_soc_component *component = NULL;
|
struct snd_soc_component *component = NULL;
|
||||||
|
int num_retry = NUM_ATTEMPTS;
|
||||||
|
|
||||||
swr_dmic = devm_kzalloc(&pdev->dev, sizeof(struct swr_dmic_priv),
|
swr_dmic = devm_kzalloc(&pdev->dev, sizeof(struct swr_dmic_priv),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
@@ -485,13 +505,18 @@ static int swr_dmic_probe(struct swr_device *pdev)
|
|||||||
* as per HW requirement.
|
* as per HW requirement.
|
||||||
*/
|
*/
|
||||||
usleep_range(5000, 5010);
|
usleep_range(5000, 5010);
|
||||||
|
do {
|
||||||
|
/* Add delay for soundwire enumeration */
|
||||||
|
usleep_range(100, 110);
|
||||||
ret = swr_get_logical_dev_num(pdev, pdev->addr, &swr_devnum);
|
ret = swr_get_logical_dev_num(pdev, pdev->addr, &swr_devnum);
|
||||||
|
} while (ret && --num_retry);
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_dbg(&pdev->dev,
|
dev_info(&pdev->dev,
|
||||||
"%s get devnum %d for dev addr %lx failed\n",
|
"%s get devnum %d for dev addr %llx failed\n",
|
||||||
__func__, swr_devnum, pdev->addr);
|
__func__, swr_devnum, pdev->addr);
|
||||||
ret = -EPROBE_DEFER;
|
ret = -EPROBE_DEFER;
|
||||||
goto err;
|
goto dev_err;
|
||||||
}
|
}
|
||||||
pdev->dev_num = swr_devnum;
|
pdev->dev_num = swr_devnum;
|
||||||
|
|
||||||
@@ -561,10 +586,9 @@ static int swr_dmic_probe(struct swr_device *pdev)
|
|||||||
strlen(swr_dmic_name_prefix_of) + 1);
|
strlen(swr_dmic_name_prefix_of) + 1);
|
||||||
component->name_prefix = prefix_name;
|
component->name_prefix = prefix_name;
|
||||||
|
|
||||||
if (swr_dmic->is_en_supply == 1) {
|
swr_dmic->nblock.notifier_call = swr_dmic_event_notify;
|
||||||
enable_wcd_codec_supply(swr_dmic, false);
|
wcd938x_swr_dmic_register_notifier(swr_dmic->supply_component,
|
||||||
--swr_dmic->is_en_supply;
|
&swr_dmic->nblock, true);
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@@ -589,7 +613,10 @@ static int swr_dmic_remove(struct swr_device *pdev)
|
|||||||
dev_err(&pdev->dev, "%s: swr_dmic is NULL\n", __func__);
|
dev_err(&pdev->dev, "%s: swr_dmic is NULL\n", __func__);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
if (swr_dmic->is_en_supply == 1) {
|
||||||
|
enable_wcd_codec_supply(swr_dmic, false);
|
||||||
|
--swr_dmic->is_en_supply;
|
||||||
|
}
|
||||||
snd_soc_unregister_component(&pdev->dev);
|
snd_soc_unregister_component(&pdev->dev);
|
||||||
swr_set_dev_data(pdev, NULL);
|
swr_set_dev_data(pdev, NULL);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -624,6 +651,8 @@ static int swr_dmic_down(struct swr_device *pdev)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dev_dbg(&pdev->dev, "%s: is_en_supply: %d\n",
|
||||||
|
__func__, swr_dmic->is_en_supply);
|
||||||
--swr_dmic->is_en_supply;
|
--swr_dmic->is_en_supply;
|
||||||
if (swr_dmic->is_en_supply < 0) {
|
if (swr_dmic->is_en_supply < 0) {
|
||||||
dev_warn(&pdev->dev, "%s: mismatch in supply count %d\n",
|
dev_warn(&pdev->dev, "%s: mismatch in supply count %d\n",
|
||||||
@@ -641,7 +670,7 @@ done:
|
|||||||
static int swr_dmic_reset(struct swr_device *pdev)
|
static int swr_dmic_reset(struct swr_device *pdev)
|
||||||
{
|
{
|
||||||
struct swr_dmic_priv *swr_dmic;
|
struct swr_dmic_priv *swr_dmic;
|
||||||
u8 retry = 5;
|
u8 retry = NUM_ATTEMPTS;
|
||||||
u8 devnum = 0;
|
u8 devnum = 0;
|
||||||
|
|
||||||
swr_dmic = swr_get_dev_data(pdev);
|
swr_dmic = swr_get_dev_data(pdev);
|
||||||
@@ -706,7 +735,6 @@ static struct swr_driver swr_dmic_driver = {
|
|||||||
.probe = swr_dmic_probe,
|
.probe = swr_dmic_probe,
|
||||||
.remove = swr_dmic_remove,
|
.remove = swr_dmic_remove,
|
||||||
.id_table = swr_dmic_id,
|
.id_table = swr_dmic_id,
|
||||||
.device_down = swr_dmic_down,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init swr_dmic_init(void)
|
static int __init swr_dmic_init(void)
|
||||||
|
@@ -186,12 +186,6 @@ static int hap_enable_swr_dac_port(struct snd_soc_dapm_widget *w,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SND_SOC_DAPM_PRE_PMD:
|
case SND_SOC_DAPM_PRE_PMD:
|
||||||
swr_disconnect_port(swr_hap->swr_slave, &port_id, num_port,
|
|
||||||
&ch_mask, &port_type);
|
|
||||||
break;
|
|
||||||
case SND_SOC_DAPM_POST_PMD:
|
|
||||||
swr_slvdev_datapath_control(swr_hap->swr_slave,
|
|
||||||
swr_hap->swr_slave->dev_num, false);
|
|
||||||
/* stop SWR play */
|
/* stop SWR play */
|
||||||
val = 0;
|
val = 0;
|
||||||
rc = regmap_write(swr_hap->regmap, SWR_PLAY_REG, val);
|
rc = regmap_write(swr_hap->regmap, SWR_PLAY_REG, val);
|
||||||
@@ -200,6 +194,12 @@ static int hap_enable_swr_dac_port(struct snd_soc_dapm_widget *w,
|
|||||||
__func__, rc);
|
__func__, rc);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case SND_SOC_DAPM_POST_PMD:
|
||||||
|
swr_disconnect_port(swr_hap->swr_slave, &port_id, num_port,
|
||||||
|
&ch_mask, &port_type);
|
||||||
|
swr_slvdev_datapath_control(swr_hap->swr_slave,
|
||||||
|
swr_hap->swr_slave->dev_num, false);
|
||||||
swr_device_wakeup_unvote(swr_hap->swr_slave);
|
swr_device_wakeup_unvote(swr_hap->swr_slave);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -314,6 +314,7 @@ static int swr_haptics_probe(struct swr_device *sdev)
|
|||||||
struct swr_haptics_dev *swr_hap;
|
struct swr_haptics_dev *swr_hap;
|
||||||
int rc;
|
int rc;
|
||||||
u8 devnum;
|
u8 devnum;
|
||||||
|
int retry = 5;
|
||||||
|
|
||||||
swr_hap = devm_kzalloc(&sdev->dev,
|
swr_hap = devm_kzalloc(&sdev->dev,
|
||||||
sizeof(struct swr_haptics_dev), GFP_KERNEL);
|
sizeof(struct swr_haptics_dev), GFP_KERNEL);
|
||||||
@@ -346,8 +347,12 @@ static int swr_haptics_probe(struct swr_device *sdev)
|
|||||||
__func__, rc);
|
__func__, rc);
|
||||||
goto clean;
|
goto clean;
|
||||||
}
|
}
|
||||||
|
do {
|
||||||
|
/* Add delay for soundwire enumeration */
|
||||||
|
usleep_range(500, 510);
|
||||||
rc = swr_get_logical_dev_num(sdev, sdev->addr, &devnum);
|
rc = swr_get_logical_dev_num(sdev, sdev->addr, &devnum);
|
||||||
|
} while (rc && --retry);
|
||||||
|
|
||||||
if (rc) {
|
if (rc) {
|
||||||
dev_err(swr_hap->dev, "%s: failed to get devnum for swr-haptics, rc=%d\n",
|
dev_err(swr_hap->dev, "%s: failed to get devnum for swr-haptics, rc=%d\n",
|
||||||
__func__, rc);
|
__func__, rc);
|
||||||
|
@@ -33,6 +33,10 @@ static int wcd_mbhc_get_micbias(struct wcd_mbhc *mbhc)
|
|||||||
int micbias = 0;
|
int micbias = 0;
|
||||||
u8 vout_ctl = 0;
|
u8 vout_ctl = 0;
|
||||||
|
|
||||||
|
if (mbhc->mbhc_cb->get_micbias_val) {
|
||||||
|
mbhc->mbhc_cb->get_micbias_val(mbhc, &micbias);
|
||||||
|
pr_debug("%s: micbias: %d\n", __func__, micbias);
|
||||||
|
} else {
|
||||||
/* Read MBHC Micbias (Mic Bias2) voltage */
|
/* Read MBHC Micbias (Mic Bias2) voltage */
|
||||||
WCD_MBHC_REG_READ(WCD_MBHC_MICB2_VOUT, vout_ctl);
|
WCD_MBHC_REG_READ(WCD_MBHC_MICB2_VOUT, vout_ctl);
|
||||||
|
|
||||||
@@ -42,7 +46,7 @@ static int wcd_mbhc_get_micbias(struct wcd_mbhc *mbhc)
|
|||||||
micbias = 1000 + (vout_ctl * 50);
|
micbias = 1000 + (vout_ctl * 50);
|
||||||
pr_debug("%s: vout_ctl: %d, micbias: %d\n",
|
pr_debug("%s: vout_ctl: %d, micbias: %d\n",
|
||||||
__func__, vout_ctl, micbias);
|
__func__, vout_ctl, micbias);
|
||||||
|
}
|
||||||
return micbias;
|
return micbias;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,8 +80,22 @@ static int wcd_measure_adc_continuous(struct wcd_mbhc *mbhc)
|
|||||||
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, 0);
|
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, 0);
|
||||||
/* Set the MUX selection to IN2P */
|
/* Set the MUX selection to IN2P */
|
||||||
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_MUX_CTL, MUX_CTL_IN2P);
|
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_MUX_CTL, MUX_CTL_IN2P);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Current source mode requires Auto zeroing to be enabled
|
||||||
|
* automatically. If HW doesn't do it, SW has to take care of this
|
||||||
|
* for button interrupts to work fine and to avoid
|
||||||
|
* fake electrical removal interrupts by enabling autozero before FSM
|
||||||
|
* enable and disable it after FSM enable
|
||||||
|
*/
|
||||||
|
if (mbhc->mbhc_cb->mbhc_comp_autozero_control)
|
||||||
|
mbhc->mbhc_cb->mbhc_comp_autozero_control(mbhc,
|
||||||
|
true);
|
||||||
/* Enable MBHC FSM */
|
/* Enable MBHC FSM */
|
||||||
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, 1);
|
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, 1);
|
||||||
|
if (mbhc->mbhc_cb->mbhc_comp_autozero_control)
|
||||||
|
mbhc->mbhc_cb->mbhc_comp_autozero_control(mbhc,
|
||||||
|
false);
|
||||||
/* Enable ADC_ENABLE bit */
|
/* Enable ADC_ENABLE bit */
|
||||||
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ADC_EN, 1);
|
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ADC_EN, 1);
|
||||||
|
|
||||||
@@ -290,6 +308,10 @@ static int wcd_check_cross_conn(struct wcd_mbhc *mbhc)
|
|||||||
WCD_MBHC_REG_READ(WCD_MBHC_ELECT_SCHMT_ISRC, elect_ctl);
|
WCD_MBHC_REG_READ(WCD_MBHC_ELECT_SCHMT_ISRC, elect_ctl);
|
||||||
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ELECT_SCHMT_ISRC, 0x00);
|
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ELECT_SCHMT_ISRC, 0x00);
|
||||||
|
|
||||||
|
/* Disable surge detection before ADC measurement */
|
||||||
|
if (mbhc->mbhc_cb->mbhc_surge_ctl)
|
||||||
|
mbhc->mbhc_cb->mbhc_surge_ctl(mbhc, false);
|
||||||
|
|
||||||
/* Read and set ADC to single measurement */
|
/* Read and set ADC to single measurement */
|
||||||
WCD_MBHC_REG_READ(WCD_MBHC_ADC_MODE, adc_mode);
|
WCD_MBHC_REG_READ(WCD_MBHC_ADC_MODE, adc_mode);
|
||||||
/* Read ADC Enable bit to restore after adc measurement */
|
/* Read ADC Enable bit to restore after adc measurement */
|
||||||
@@ -313,7 +335,12 @@ static int wcd_check_cross_conn(struct wcd_mbhc *mbhc)
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hphl_adc_res > 100 || hphr_adc_res > 100) {
|
/* Update cross connection threshold voltages if needed */
|
||||||
|
if (mbhc->mbhc_cb->update_cross_conn_thr)
|
||||||
|
mbhc->mbhc_cb->update_cross_conn_thr(mbhc);
|
||||||
|
|
||||||
|
if (hphl_adc_res > mbhc->hphl_cross_conn_thr ||
|
||||||
|
hphr_adc_res > mbhc->hphr_cross_conn_thr) {
|
||||||
plug_type = MBHC_PLUG_TYPE_GND_MIC_SWAP;
|
plug_type = MBHC_PLUG_TYPE_GND_MIC_SWAP;
|
||||||
pr_debug("%s: Cross connection identified\n", __func__);
|
pr_debug("%s: Cross connection identified\n", __func__);
|
||||||
} else {
|
} else {
|
||||||
@@ -335,6 +362,10 @@ done:
|
|||||||
/* Restore FSM state */
|
/* Restore FSM state */
|
||||||
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, fsm_en);
|
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, fsm_en);
|
||||||
|
|
||||||
|
/* Restore surge detection */
|
||||||
|
if (mbhc->mbhc_cb->mbhc_surge_ctl)
|
||||||
|
mbhc->mbhc_cb->mbhc_surge_ctl(mbhc, true);
|
||||||
|
|
||||||
/* Restore electrical detection */
|
/* Restore electrical detection */
|
||||||
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ELECT_SCHMT_ISRC, elect_ctl);
|
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ELECT_SCHMT_ISRC, elect_ctl);
|
||||||
|
|
||||||
|
@@ -80,10 +80,12 @@ static void wcd_program_hs_vref(struct wcd_mbhc *mbhc)
|
|||||||
struct snd_soc_component *component = mbhc->component;
|
struct snd_soc_component *component = mbhc->component;
|
||||||
u32 reg_val;
|
u32 reg_val;
|
||||||
|
|
||||||
plug_type_cfg = WCD_MBHC_CAL_PLUG_TYPE_PTR(mbhc->mbhc_cfg->calibration);
|
plug_type_cfg = WCD_MBHC_CAL_PLUG_TYPE_PTR(
|
||||||
|
mbhc->mbhc_cfg->calibration);
|
||||||
reg_val = ((plug_type_cfg->v_hs_max - HS_VREF_MIN_VAL) / 100);
|
reg_val = ((plug_type_cfg->v_hs_max - HS_VREF_MIN_VAL) / 100);
|
||||||
|
|
||||||
dev_dbg(component->dev, "%s: reg_val = %x\n", __func__, reg_val);
|
dev_dbg(component->dev, "%s: reg_val = %x\n",
|
||||||
|
__func__, reg_val);
|
||||||
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HS_VREF, reg_val);
|
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HS_VREF, reg_val);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1619,6 +1621,8 @@ static int wcd_mbhc_set_keycode(struct wcd_mbhc *mbhc)
|
|||||||
static int wcd_mbhc_usbc_ana_event_handler(struct notifier_block *nb,
|
static int wcd_mbhc_usbc_ana_event_handler(struct notifier_block *nb,
|
||||||
unsigned long mode, void *ptr)
|
unsigned long mode, void *ptr)
|
||||||
{
|
{
|
||||||
|
unsigned int l_det_en = 0;
|
||||||
|
unsigned int detection_type = 0;
|
||||||
struct wcd_mbhc *mbhc = container_of(nb, struct wcd_mbhc, fsa_nb);
|
struct wcd_mbhc *mbhc = container_of(nb, struct wcd_mbhc, fsa_nb);
|
||||||
|
|
||||||
if (!mbhc)
|
if (!mbhc)
|
||||||
@@ -1631,6 +1635,23 @@ static int wcd_mbhc_usbc_ana_event_handler(struct notifier_block *nb,
|
|||||||
mbhc->mbhc_cb->clk_setup(mbhc->component, true);
|
mbhc->mbhc_cb->clk_setup(mbhc->component, true);
|
||||||
/* insertion detected, enable L_DET_EN */
|
/* insertion detected, enable L_DET_EN */
|
||||||
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_L_DET_EN, 1);
|
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_L_DET_EN, 1);
|
||||||
|
} else {
|
||||||
|
WCD_MBHC_REG_READ(WCD_MBHC_MECH_DETECTION_TYPE, detection_type);
|
||||||
|
WCD_MBHC_REG_READ(WCD_MBHC_L_DET_EN, l_det_en);
|
||||||
|
/* If both l_det_en and detection type are set, it means device was
|
||||||
|
* unplugged during SSR and detection interrupt was not handled.
|
||||||
|
* So trigger device disconnect */
|
||||||
|
if (detection_type && l_det_en) {
|
||||||
|
/* Set the detection type appropriately */
|
||||||
|
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_MECH_DETECTION_TYPE,
|
||||||
|
!detection_type);
|
||||||
|
/* Set current plug type to the state before SSR */
|
||||||
|
mbhc->current_plug = mbhc->plug_before_ssr;
|
||||||
|
|
||||||
|
wcd_mbhc_swch_irq_handler(mbhc);
|
||||||
|
mbhc->mbhc_cb->lock_sleep(mbhc, false);
|
||||||
|
mbhc->plug_before_ssr = MBHC_PLUG_TYPE_NONE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1838,6 +1859,8 @@ int wcd_mbhc_init(struct wcd_mbhc *mbhc, struct snd_soc_component *component,
|
|||||||
mbhc->hph_type = WCD_MBHC_HPH_NONE;
|
mbhc->hph_type = WCD_MBHC_HPH_NONE;
|
||||||
mbhc->wcd_mbhc_regs = wcd_mbhc_regs;
|
mbhc->wcd_mbhc_regs = wcd_mbhc_regs;
|
||||||
mbhc->swap_thr = GND_MIC_SWAP_THRESHOLD;
|
mbhc->swap_thr = GND_MIC_SWAP_THRESHOLD;
|
||||||
|
mbhc->hphl_cross_conn_thr = HPHL_CROSS_CONN_THRESHOLD;
|
||||||
|
mbhc->hphr_cross_conn_thr = HPHR_CROSS_CONN_THRESHOLD;
|
||||||
|
|
||||||
if (mbhc->intr_ids == NULL) {
|
if (mbhc->intr_ids == NULL) {
|
||||||
pr_err("%s: Interrupt mapping not provided\n", __func__);
|
pr_err("%s: Interrupt mapping not provided\n", __func__);
|
||||||
|
@@ -8608,95 +8608,95 @@ static const struct soc_enum amic_pwr_lvl_enum =
|
|||||||
amic_pwr_lvl_text);
|
amic_pwr_lvl_text);
|
||||||
|
|
||||||
static const struct snd_kcontrol_new tasha_snd_controls[] = {
|
static const struct snd_kcontrol_new tasha_snd_controls[] = {
|
||||||
SOC_SINGLE_SX_TLV("RX0 Digital Volume", WCD9335_CDC_RX0_RX_VOL_CTL,
|
SOC_SINGLE_S8_TLV("RX0 Digital Volume", WCD9335_CDC_RX0_RX_VOL_CTL,
|
||||||
0, -84, 40, digital_gain), /* -84dB min - 40dB max */
|
-84, 40, digital_gain), /* -84dB min - 40dB max */
|
||||||
SOC_SINGLE_SX_TLV("RX1 Digital Volume", WCD9335_CDC_RX1_RX_VOL_CTL,
|
SOC_SINGLE_S8_TLV("RX1 Digital Volume", WCD9335_CDC_RX1_RX_VOL_CTL,
|
||||||
0, -84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("RX2 Digital Volume", WCD9335_CDC_RX2_RX_VOL_CTL,
|
SOC_SINGLE_S8_TLV("RX2 Digital Volume", WCD9335_CDC_RX2_RX_VOL_CTL,
|
||||||
0, -84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("RX3 Digital Volume", WCD9335_CDC_RX3_RX_VOL_CTL,
|
SOC_SINGLE_S8_TLV("RX3 Digital Volume", WCD9335_CDC_RX3_RX_VOL_CTL,
|
||||||
0, -84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("RX4 Digital Volume", WCD9335_CDC_RX4_RX_VOL_CTL,
|
SOC_SINGLE_S8_TLV("RX4 Digital Volume", WCD9335_CDC_RX4_RX_VOL_CTL,
|
||||||
0, -84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("RX5 Digital Volume", WCD9335_CDC_RX5_RX_VOL_CTL,
|
SOC_SINGLE_S8_TLV("RX5 Digital Volume", WCD9335_CDC_RX5_RX_VOL_CTL,
|
||||||
0, -84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("RX6 Digital Volume", WCD9335_CDC_RX6_RX_VOL_CTL,
|
SOC_SINGLE_S8_TLV("RX6 Digital Volume", WCD9335_CDC_RX6_RX_VOL_CTL,
|
||||||
0, -84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("RX7 Digital Volume", WCD9335_CDC_RX7_RX_VOL_CTL,
|
SOC_SINGLE_S8_TLV("RX7 Digital Volume", WCD9335_CDC_RX7_RX_VOL_CTL,
|
||||||
0, -84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("RX8 Digital Volume", WCD9335_CDC_RX8_RX_VOL_CTL,
|
SOC_SINGLE_S8_TLV("RX8 Digital Volume", WCD9335_CDC_RX8_RX_VOL_CTL,
|
||||||
0, -84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
|
|
||||||
SOC_SINGLE_SX_TLV("RX0 Mix Digital Volume",
|
SOC_SINGLE_S8_TLV("RX0 Mix Digital Volume",
|
||||||
WCD9335_CDC_RX0_RX_VOL_MIX_CTL,
|
WCD9335_CDC_RX0_RX_VOL_MIX_CTL,
|
||||||
0, -84, 40, digital_gain), /* -84dB min - 40dB max */
|
-84, 40, digital_gain), /* -84dB min - 40dB max */
|
||||||
SOC_SINGLE_SX_TLV("RX1 Mix Digital Volume",
|
SOC_SINGLE_S8_TLV("RX1 Mix Digital Volume",
|
||||||
WCD9335_CDC_RX1_RX_VOL_MIX_CTL,
|
WCD9335_CDC_RX1_RX_VOL_MIX_CTL,
|
||||||
0, -84, 40, digital_gain), /* -84dB min - 40dB max */
|
-84, 40, digital_gain), /* -84dB min - 40dB max */
|
||||||
SOC_SINGLE_SX_TLV("RX2 Mix Digital Volume",
|
SOC_SINGLE_S8_TLV("RX2 Mix Digital Volume",
|
||||||
WCD9335_CDC_RX2_RX_VOL_MIX_CTL,
|
WCD9335_CDC_RX2_RX_VOL_MIX_CTL,
|
||||||
0, -84, 40, digital_gain), /* -84dB min - 40dB max */
|
-84, 40, digital_gain), /* -84dB min - 40dB max */
|
||||||
SOC_SINGLE_SX_TLV("RX3 Mix Digital Volume",
|
SOC_SINGLE_S8_TLV("RX3 Mix Digital Volume",
|
||||||
WCD9335_CDC_RX3_RX_VOL_MIX_CTL,
|
WCD9335_CDC_RX3_RX_VOL_MIX_CTL,
|
||||||
0, -84, 40, digital_gain), /* -84dB min - 40dB max */
|
-84, 40, digital_gain), /* -84dB min - 40dB max */
|
||||||
SOC_SINGLE_SX_TLV("RX4 Mix Digital Volume",
|
SOC_SINGLE_S8_TLV("RX4 Mix Digital Volume",
|
||||||
WCD9335_CDC_RX4_RX_VOL_MIX_CTL,
|
WCD9335_CDC_RX4_RX_VOL_MIX_CTL,
|
||||||
0, -84, 40, digital_gain), /* -84dB min - 40dB max */
|
-84, 40, digital_gain), /* -84dB min - 40dB max */
|
||||||
SOC_SINGLE_SX_TLV("RX5 Mix Digital Volume",
|
SOC_SINGLE_S8_TLV("RX5 Mix Digital Volume",
|
||||||
WCD9335_CDC_RX5_RX_VOL_MIX_CTL,
|
WCD9335_CDC_RX5_RX_VOL_MIX_CTL,
|
||||||
0, -84, 40, digital_gain), /* -84dB min - 40dB max */
|
-84, 40, digital_gain), /* -84dB min - 40dB max */
|
||||||
SOC_SINGLE_SX_TLV("RX6 Mix Digital Volume",
|
SOC_SINGLE_S8_TLV("RX6 Mix Digital Volume",
|
||||||
WCD9335_CDC_RX6_RX_VOL_MIX_CTL,
|
WCD9335_CDC_RX6_RX_VOL_MIX_CTL,
|
||||||
0, -84, 40, digital_gain), /* -84dB min - 40dB max */
|
-84, 40, digital_gain), /* -84dB min - 40dB max */
|
||||||
SOC_SINGLE_SX_TLV("RX7 Mix Digital Volume",
|
SOC_SINGLE_S8_TLV("RX7 Mix Digital Volume",
|
||||||
WCD9335_CDC_RX7_RX_VOL_MIX_CTL,
|
WCD9335_CDC_RX7_RX_VOL_MIX_CTL,
|
||||||
0, -84, 40, digital_gain), /* -84dB min - 40dB max */
|
-84, 40, digital_gain), /* -84dB min - 40dB max */
|
||||||
SOC_SINGLE_SX_TLV("RX8 Mix Digital Volume",
|
SOC_SINGLE_S8_TLV("RX8 Mix Digital Volume",
|
||||||
WCD9335_CDC_RX8_RX_VOL_MIX_CTL,
|
WCD9335_CDC_RX8_RX_VOL_MIX_CTL,
|
||||||
0, -84, 40, digital_gain), /* -84dB min - 40dB max */
|
-84, 40, digital_gain), /* -84dB min - 40dB max */
|
||||||
|
|
||||||
SOC_SINGLE_SX_TLV("DEC0 Volume", WCD9335_CDC_TX0_TX_VOL_CTL, 0,
|
SOC_SINGLE_S8_TLV("DEC0 Volume", WCD9335_CDC_TX0_TX_VOL_CTL,
|
||||||
-84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("DEC1 Volume", WCD9335_CDC_TX1_TX_VOL_CTL, 0,
|
SOC_SINGLE_S8_TLV("DEC1 Volume", WCD9335_CDC_TX1_TX_VOL_CTL,
|
||||||
-84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("DEC2 Volume", WCD9335_CDC_TX2_TX_VOL_CTL, 0,
|
SOC_SINGLE_S8_TLV("DEC2 Volume", WCD9335_CDC_TX2_TX_VOL_CTL,
|
||||||
-84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("DEC3 Volume", WCD9335_CDC_TX3_TX_VOL_CTL, 0,
|
SOC_SINGLE_S8_TLV("DEC3 Volume", WCD9335_CDC_TX3_TX_VOL_CTL,
|
||||||
-84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("DEC4 Volume", WCD9335_CDC_TX4_TX_VOL_CTL, 0,
|
SOC_SINGLE_S8_TLV("DEC4 Volume", WCD9335_CDC_TX4_TX_VOL_CTL,
|
||||||
-84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("DEC5 Volume", WCD9335_CDC_TX5_TX_VOL_CTL, 0,
|
SOC_SINGLE_S8_TLV("DEC5 Volume", WCD9335_CDC_TX5_TX_VOL_CTL,
|
||||||
-84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("DEC6 Volume", WCD9335_CDC_TX6_TX_VOL_CTL, 0,
|
SOC_SINGLE_S8_TLV("DEC6 Volume", WCD9335_CDC_TX6_TX_VOL_CTL,
|
||||||
-84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("DEC7 Volume", WCD9335_CDC_TX7_TX_VOL_CTL, 0,
|
SOC_SINGLE_S8_TLV("DEC7 Volume", WCD9335_CDC_TX7_TX_VOL_CTL,
|
||||||
-84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("DEC8 Volume", WCD9335_CDC_TX8_TX_VOL_CTL, 0,
|
SOC_SINGLE_S8_TLV("DEC8 Volume", WCD9335_CDC_TX8_TX_VOL_CTL,
|
||||||
-84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
|
|
||||||
SOC_SINGLE_SX_TLV("IIR0 INP0 Volume",
|
SOC_SINGLE_S8_TLV("IIR0 INP0 Volume",
|
||||||
WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL, 0, -84,
|
WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL, -84,
|
||||||
40, digital_gain),
|
40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("IIR0 INP1 Volume",
|
SOC_SINGLE_S8_TLV("IIR0 INP1 Volume",
|
||||||
WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL, 0, -84,
|
WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL, -84,
|
||||||
40, digital_gain),
|
40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("IIR0 INP2 Volume",
|
SOC_SINGLE_S8_TLV("IIR0 INP2 Volume",
|
||||||
WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL, 0, -84,
|
WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL, -84,
|
||||||
40, digital_gain),
|
40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("IIR0 INP3 Volume",
|
SOC_SINGLE_S8_TLV("IIR0 INP3 Volume",
|
||||||
WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL, 0, -84,
|
WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL, -84,
|
||||||
40, digital_gain),
|
40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("IIR1 INP0 Volume",
|
SOC_SINGLE_S8_TLV("IIR1 INP0 Volume",
|
||||||
WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B1_CTL, 0, -84,
|
WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B1_CTL, -84,
|
||||||
40, digital_gain),
|
40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("IIR1 INP1 Volume",
|
SOC_SINGLE_S8_TLV("IIR1 INP1 Volume",
|
||||||
WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B2_CTL, 0, -84,
|
WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B2_CTL, -84,
|
||||||
40, digital_gain),
|
40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("IIR1 INP2 Volume",
|
SOC_SINGLE_S8_TLV("IIR1 INP2 Volume",
|
||||||
WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B3_CTL, 0, -84,
|
WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B3_CTL, -84,
|
||||||
40, digital_gain),
|
40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("IIR1 INP3 Volume",
|
SOC_SINGLE_S8_TLV("IIR1 INP3 Volume",
|
||||||
WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B4_CTL, 0, -84,
|
WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B4_CTL, -84,
|
||||||
40, digital_gain),
|
40, digital_gain),
|
||||||
|
|
||||||
SOC_SINGLE_EXT("ANC Slot", SND_SOC_NOPM, 0, 100, 0, tasha_get_anc_slot,
|
SOC_SINGLE_EXT("ANC Slot", SND_SOC_NOPM, 0, 100, 0, tasha_get_anc_slot,
|
||||||
|
@@ -6548,77 +6548,77 @@ static const struct snd_kcontrol_new tavil_snd_controls[] = {
|
|||||||
SOC_SINGLE_TLV("ADC3 Volume", WCD934X_ANA_AMIC3, 0, 20, 0, analog_gain),
|
SOC_SINGLE_TLV("ADC3 Volume", WCD934X_ANA_AMIC3, 0, 20, 0, analog_gain),
|
||||||
SOC_SINGLE_TLV("ADC4 Volume", WCD934X_ANA_AMIC4, 0, 20, 0, analog_gain),
|
SOC_SINGLE_TLV("ADC4 Volume", WCD934X_ANA_AMIC4, 0, 20, 0, analog_gain),
|
||||||
|
|
||||||
SOC_SINGLE_SX_TLV("RX0 Digital Volume", WCD934X_CDC_RX0_RX_VOL_CTL,
|
SOC_SINGLE_S8_TLV("RX0 Digital Volume", WCD934X_CDC_RX0_RX_VOL_CTL,
|
||||||
0, -84, 40, digital_gain), /* -84dB min - 40dB max */
|
-84, 40, digital_gain), /* -84dB min - 40dB max */
|
||||||
SOC_SINGLE_SX_TLV("RX1 Digital Volume", WCD934X_CDC_RX1_RX_VOL_CTL,
|
SOC_SINGLE_S8_TLV("RX1 Digital Volume", WCD934X_CDC_RX1_RX_VOL_CTL,
|
||||||
0, -84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("RX2 Digital Volume", WCD934X_CDC_RX2_RX_VOL_CTL,
|
SOC_SINGLE_S8_TLV("RX2 Digital Volume", WCD934X_CDC_RX2_RX_VOL_CTL,
|
||||||
0, -84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("RX3 Digital Volume", WCD934X_CDC_RX3_RX_VOL_CTL,
|
SOC_SINGLE_S8_TLV("RX3 Digital Volume", WCD934X_CDC_RX3_RX_VOL_CTL,
|
||||||
0, -84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("RX4 Digital Volume", WCD934X_CDC_RX4_RX_VOL_CTL,
|
SOC_SINGLE_S8_TLV("RX4 Digital Volume", WCD934X_CDC_RX4_RX_VOL_CTL,
|
||||||
0, -84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("RX7 Digital Volume", WCD934X_CDC_RX7_RX_VOL_CTL,
|
SOC_SINGLE_S8_TLV("RX7 Digital Volume", WCD934X_CDC_RX7_RX_VOL_CTL,
|
||||||
0, -84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("RX8 Digital Volume", WCD934X_CDC_RX8_RX_VOL_CTL,
|
SOC_SINGLE_S8_TLV("RX8 Digital Volume", WCD934X_CDC_RX8_RX_VOL_CTL,
|
||||||
0, -84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("RX0 Mix Digital Volume",
|
SOC_SINGLE_S8_TLV("RX0 Mix Digital Volume",
|
||||||
WCD934X_CDC_RX0_RX_VOL_MIX_CTL, 0, -84, 40, digital_gain),
|
WCD934X_CDC_RX0_RX_VOL_MIX_CTL, -84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("RX1 Mix Digital Volume",
|
SOC_SINGLE_S8_TLV("RX1 Mix Digital Volume",
|
||||||
WCD934X_CDC_RX1_RX_VOL_MIX_CTL, 0, -84, 40, digital_gain),
|
WCD934X_CDC_RX1_RX_VOL_MIX_CTL, -84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("RX2 Mix Digital Volume",
|
SOC_SINGLE_S8_TLV("RX2 Mix Digital Volume",
|
||||||
WCD934X_CDC_RX2_RX_VOL_MIX_CTL, 0, -84, 40, digital_gain),
|
WCD934X_CDC_RX2_RX_VOL_MIX_CTL, -84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("RX3 Mix Digital Volume",
|
SOC_SINGLE_S8_TLV("RX3 Mix Digital Volume",
|
||||||
WCD934X_CDC_RX3_RX_VOL_MIX_CTL, 0, -84, 40, digital_gain),
|
WCD934X_CDC_RX3_RX_VOL_MIX_CTL, -84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("RX4 Mix Digital Volume",
|
SOC_SINGLE_S8_TLV("RX4 Mix Digital Volume",
|
||||||
WCD934X_CDC_RX4_RX_VOL_MIX_CTL, 0, -84, 40, digital_gain),
|
WCD934X_CDC_RX4_RX_VOL_MIX_CTL, -84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("RX7 Mix Digital Volume",
|
SOC_SINGLE_S8_TLV("RX7 Mix Digital Volume",
|
||||||
WCD934X_CDC_RX7_RX_VOL_MIX_CTL, 0, -84, 40, digital_gain),
|
WCD934X_CDC_RX7_RX_VOL_MIX_CTL, -84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("RX8 Mix Digital Volume",
|
SOC_SINGLE_S8_TLV("RX8 Mix Digital Volume",
|
||||||
WCD934X_CDC_RX8_RX_VOL_MIX_CTL, 0, -84, 40, digital_gain),
|
WCD934X_CDC_RX8_RX_VOL_MIX_CTL, -84, 40, digital_gain),
|
||||||
|
|
||||||
SOC_SINGLE_SX_TLV("DEC0 Volume", WCD934X_CDC_TX0_TX_VOL_CTL, 0,
|
SOC_SINGLE_S8_TLV("DEC0 Volume", WCD934X_CDC_TX0_TX_VOL_CTL,
|
||||||
-84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("DEC1 Volume", WCD934X_CDC_TX1_TX_VOL_CTL, 0,
|
SOC_SINGLE_S8_TLV("DEC1 Volume", WCD934X_CDC_TX1_TX_VOL_CTL,
|
||||||
-84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("DEC2 Volume", WCD934X_CDC_TX2_TX_VOL_CTL, 0,
|
SOC_SINGLE_S8_TLV("DEC2 Volume", WCD934X_CDC_TX2_TX_VOL_CTL,
|
||||||
-84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("DEC3 Volume", WCD934X_CDC_TX3_TX_VOL_CTL, 0,
|
SOC_SINGLE_S8_TLV("DEC3 Volume", WCD934X_CDC_TX3_TX_VOL_CTL,
|
||||||
-84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("DEC4 Volume", WCD934X_CDC_TX4_TX_VOL_CTL, 0,
|
SOC_SINGLE_S8_TLV("DEC4 Volume", WCD934X_CDC_TX4_TX_VOL_CTL,
|
||||||
-84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("DEC5 Volume", WCD934X_CDC_TX5_TX_VOL_CTL, 0,
|
SOC_SINGLE_S8_TLV("DEC5 Volume", WCD934X_CDC_TX5_TX_VOL_CTL,
|
||||||
-84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("DEC6 Volume", WCD934X_CDC_TX6_TX_VOL_CTL, 0,
|
SOC_SINGLE_S8_TLV("DEC6 Volume", WCD934X_CDC_TX6_TX_VOL_CTL,
|
||||||
-84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("DEC7 Volume", WCD934X_CDC_TX7_TX_VOL_CTL, 0,
|
SOC_SINGLE_S8_TLV("DEC7 Volume", WCD934X_CDC_TX7_TX_VOL_CTL,
|
||||||
-84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("DEC8 Volume", WCD934X_CDC_TX8_TX_VOL_CTL, 0,
|
SOC_SINGLE_S8_TLV("DEC8 Volume", WCD934X_CDC_TX8_TX_VOL_CTL,
|
||||||
-84, 40, digital_gain),
|
-84, 40, digital_gain),
|
||||||
|
|
||||||
SOC_SINGLE_SX_TLV("IIR0 INP0 Volume",
|
SOC_SINGLE_S8_TLV("IIR0 INP0 Volume",
|
||||||
WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL, 0, -84, 40,
|
WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL, -84, 40,
|
||||||
digital_gain),
|
digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("IIR0 INP1 Volume",
|
SOC_SINGLE_S8_TLV("IIR0 INP1 Volume",
|
||||||
WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL, 0, -84, 40,
|
WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL, -84, 40,
|
||||||
digital_gain),
|
digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("IIR0 INP2 Volume",
|
SOC_SINGLE_S8_TLV("IIR0 INP2 Volume",
|
||||||
WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL, 0, -84, 40,
|
WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL, -84, 40,
|
||||||
digital_gain),
|
digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("IIR0 INP3 Volume",
|
SOC_SINGLE_S8_TLV("IIR0 INP3 Volume",
|
||||||
WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL, 0, -84, 40,
|
WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL, -84, 40,
|
||||||
digital_gain),
|
digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("IIR1 INP0 Volume",
|
SOC_SINGLE_S8_TLV("IIR1 INP0 Volume",
|
||||||
WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B1_CTL, 0, -84, 40,
|
WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B1_CTL, -84, 40,
|
||||||
digital_gain),
|
digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("IIR1 INP1 Volume",
|
SOC_SINGLE_S8_TLV("IIR1 INP1 Volume",
|
||||||
WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B2_CTL, 0, -84, 40,
|
WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B2_CTL, -84, 40,
|
||||||
digital_gain),
|
digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("IIR1 INP2 Volume",
|
SOC_SINGLE_S8_TLV("IIR1 INP2 Volume",
|
||||||
WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B3_CTL, 0, -84, 40,
|
WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B3_CTL, -84, 40,
|
||||||
digital_gain),
|
digital_gain),
|
||||||
SOC_SINGLE_SX_TLV("IIR1 INP3 Volume",
|
SOC_SINGLE_S8_TLV("IIR1 INP3 Volume",
|
||||||
WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B4_CTL, 0, -84, 40,
|
WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B4_CTL, -84, 40,
|
||||||
digital_gain),
|
digital_gain),
|
||||||
|
|
||||||
SOC_SINGLE_EXT("ANC Slot", SND_SOC_NOPM, 0, 100, 0, tavil_get_anc_slot,
|
SOC_SINGLE_EXT("ANC Slot", SND_SOC_NOPM, 0, 100, 0, tavil_get_anc_slot,
|
||||||
|
@@ -17,6 +17,7 @@
|
|||||||
#define WCD_VOUT_CTL_TO_MICB(v) (1000 + v * 50)
|
#define WCD_VOUT_CTL_TO_MICB(v) (1000 + v * 50)
|
||||||
#define MAX_PORT 8
|
#define MAX_PORT 8
|
||||||
#define MAX_CH_PER_PORT 8
|
#define MAX_CH_PER_PORT 8
|
||||||
|
#define MAX_TX_PWR_CH 2
|
||||||
|
|
||||||
#define WCD937X_MAX_SLAVE_PORT_TYPES 10
|
#define WCD937X_MAX_SLAVE_PORT_TYPES 10
|
||||||
extern struct regmap_config wcd937x_regmap_config;
|
extern struct regmap_config wcd937x_regmap_config;
|
||||||
@@ -91,6 +92,7 @@ struct wcd937x_priv {
|
|||||||
struct mutex ana_tx_clk_lock;
|
struct mutex ana_tx_clk_lock;
|
||||||
u8 tx_master_ch_map[WCD937X_MAX_SLAVE_CH_TYPES];
|
u8 tx_master_ch_map[WCD937X_MAX_SLAVE_CH_TYPES];
|
||||||
bool usbc_hs_status;
|
bool usbc_hs_status;
|
||||||
|
u32 tx_ch_pwr[MAX_TX_PWR_CH];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wcd937x_micbias_setting {
|
struct wcd937x_micbias_setting {
|
||||||
|
@@ -1777,6 +1777,48 @@ static int wcd937x_rx_hph_mode_put(struct snd_kcontrol *kcontrol,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int wcd937x_tx_ch_pwr_level_get(struct snd_kcontrol *kcontrol,
|
||||||
|
struct snd_ctl_elem_value *ucontrol)
|
||||||
|
{
|
||||||
|
struct snd_soc_component *component =
|
||||||
|
snd_soc_kcontrol_component(kcontrol);
|
||||||
|
struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component);
|
||||||
|
|
||||||
|
if (strnstr(kcontrol->id.name, "CH1", sizeof(kcontrol->id.name)))
|
||||||
|
ucontrol->value.integer.value[0] = wcd937x->tx_ch_pwr[0];
|
||||||
|
else if (strnstr(kcontrol->id.name, "CH3", sizeof(kcontrol->id.name)))
|
||||||
|
ucontrol->value.integer.value[0] = wcd937x->tx_ch_pwr[1];
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int wcd937x_tx_ch_pwr_level_put(struct snd_kcontrol *kcontrol,
|
||||||
|
struct snd_ctl_elem_value *ucontrol)
|
||||||
|
{
|
||||||
|
struct snd_soc_component *component =
|
||||||
|
snd_soc_kcontrol_component(kcontrol);
|
||||||
|
struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component);
|
||||||
|
u32 pwr_level = ucontrol->value.enumerated.item[0];
|
||||||
|
|
||||||
|
dev_dbg(component->dev, "%s: tx ch pwr_level: %d\n",
|
||||||
|
__func__, pwr_level);
|
||||||
|
|
||||||
|
if (strnstr(kcontrol->id.name, "CH1",
|
||||||
|
sizeof(kcontrol->id.name))) {
|
||||||
|
snd_soc_component_update_bits(component,
|
||||||
|
WCD937X_ANA_TX_CH1, 0x60,
|
||||||
|
pwr_level << 0x5);
|
||||||
|
wcd937x->tx_ch_pwr[0] = pwr_level;
|
||||||
|
} else if (strnstr(kcontrol->id.name, "CH3",
|
||||||
|
sizeof(kcontrol->id.name))) {
|
||||||
|
snd_soc_component_update_bits(component,
|
||||||
|
WCD937X_ANA_TX_CH3, 0x60,
|
||||||
|
pwr_level << 0x5);
|
||||||
|
wcd937x->tx_ch_pwr[1] = pwr_level;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int wcd937x_ear_pa_gain_get(struct snd_kcontrol *kcontrol,
|
static int wcd937x_ear_pa_gain_get(struct snd_kcontrol *kcontrol,
|
||||||
struct snd_ctl_elem_value *ucontrol)
|
struct snd_ctl_elem_value *ucontrol)
|
||||||
{
|
{
|
||||||
@@ -2001,6 +2043,10 @@ static int wcd937x_tx_master_ch_put(struct snd_kcontrol *kcontrol,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char * const wcd937x_tx_ch_pwr_level_text[] = {
|
||||||
|
"L0", "L1", "L2", "L3",
|
||||||
|
};
|
||||||
|
|
||||||
static const char * const wcd937x_ear_pa_gain_text[] = {
|
static const char * const wcd937x_ear_pa_gain_text[] = {
|
||||||
"G_6_DB", "G_4P5_DB", "G_3_DB", "G_1P5_DB", "G_0_DB",
|
"G_6_DB", "G_4P5_DB", "G_3_DB", "G_1P5_DB", "G_0_DB",
|
||||||
"G_M1P5_DB", "G_M3_DB", "G_M4P5_DB",
|
"G_M1P5_DB", "G_M3_DB", "G_M4P5_DB",
|
||||||
@@ -2016,6 +2062,9 @@ static const struct soc_enum rx_hph_mode_mux_enum =
|
|||||||
static SOC_ENUM_SINGLE_EXT_DECL(wcd937x_ear_pa_gain_enum,
|
static SOC_ENUM_SINGLE_EXT_DECL(wcd937x_ear_pa_gain_enum,
|
||||||
wcd937x_ear_pa_gain_text);
|
wcd937x_ear_pa_gain_text);
|
||||||
|
|
||||||
|
static SOC_ENUM_SINGLE_EXT_DECL(wcd937x_tx_ch_pwr_level_enum,
|
||||||
|
wcd937x_tx_ch_pwr_level_text);
|
||||||
|
|
||||||
static const struct snd_kcontrol_new wcd937x_snd_controls[] = {
|
static const struct snd_kcontrol_new wcd937x_snd_controls[] = {
|
||||||
SOC_ENUM_EXT("EAR PA GAIN", wcd937x_ear_pa_gain_enum,
|
SOC_ENUM_EXT("EAR PA GAIN", wcd937x_ear_pa_gain_enum,
|
||||||
wcd937x_ear_pa_gain_get, wcd937x_ear_pa_gain_put),
|
wcd937x_ear_pa_gain_get, wcd937x_ear_pa_gain_put),
|
||||||
@@ -2054,6 +2103,10 @@ static const struct snd_kcontrol_new wcd937x_snd_controls[] = {
|
|||||||
wcd937x_tx_master_ch_get, wcd937x_tx_master_ch_put),
|
wcd937x_tx_master_ch_get, wcd937x_tx_master_ch_put),
|
||||||
SOC_ENUM_EXT("DMIC5 ChMap", tx_master_ch_enum,
|
SOC_ENUM_EXT("DMIC5 ChMap", tx_master_ch_enum,
|
||||||
wcd937x_tx_master_ch_get, wcd937x_tx_master_ch_put),
|
wcd937x_tx_master_ch_get, wcd937x_tx_master_ch_put),
|
||||||
|
SOC_ENUM_EXT("TX CH1 PWR", wcd937x_tx_ch_pwr_level_enum,
|
||||||
|
wcd937x_tx_ch_pwr_level_get, wcd937x_tx_ch_pwr_level_put),
|
||||||
|
SOC_ENUM_EXT("TX CH3 PWR", wcd937x_tx_ch_pwr_level_enum,
|
||||||
|
wcd937x_tx_ch_pwr_level_get, wcd937x_tx_ch_pwr_level_put),
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct snd_kcontrol_new adc1_switch[] = {
|
static const struct snd_kcontrol_new adc1_switch[] = {
|
||||||
@@ -3114,7 +3167,9 @@ static int wcd937x_bind(struct device *dev)
|
|||||||
dev_err(dev, "%s: bad micbias pdata\n", __func__);
|
dev_err(dev, "%s: bad micbias pdata\n", __func__);
|
||||||
goto err_irq;
|
goto err_irq;
|
||||||
}
|
}
|
||||||
|
/* default L1 power setting */
|
||||||
|
wcd937x->tx_ch_pwr[0] = 1;
|
||||||
|
wcd937x->tx_ch_pwr[1] = 1;
|
||||||
mutex_init(&wcd937x->micb_lock);
|
mutex_init(&wcd937x->micb_lock);
|
||||||
mutex_init(&wcd937x->ana_tx_clk_lock);
|
mutex_init(&wcd937x->ana_tx_clk_lock);
|
||||||
/* Request for watchdog interrupt */
|
/* Request for watchdog interrupt */
|
||||||
|
@@ -73,6 +73,7 @@ struct wcd938x_priv {
|
|||||||
bool comp2_enable;
|
bool comp2_enable;
|
||||||
bool ldoh;
|
bool ldoh;
|
||||||
bool bcs_dis;
|
bool bcs_dis;
|
||||||
|
bool dapm_bias_off;
|
||||||
struct irq_domain *virq;
|
struct irq_domain *virq;
|
||||||
struct wcd_irq_info irq_info;
|
struct wcd_irq_info irq_info;
|
||||||
u32 rx_clk_cnt;
|
u32 rx_clk_cnt;
|
||||||
@@ -105,6 +106,9 @@ struct wcd938x_priv {
|
|||||||
bool dev_up;
|
bool dev_up;
|
||||||
u8 tx_master_ch_map[WCD938X_MAX_SLAVE_CH_TYPES];
|
u8 tx_master_ch_map[WCD938X_MAX_SLAVE_CH_TYPES];
|
||||||
bool usbc_hs_status;
|
bool usbc_hs_status;
|
||||||
|
/* wcd to swr dmic notification */
|
||||||
|
bool notify_swr_dmic;
|
||||||
|
struct blocking_notifier_head notifier;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wcd938x_micbias_setting {
|
struct wcd938x_micbias_setting {
|
||||||
|
@@ -24,6 +24,8 @@
|
|||||||
#define SWR_SLV_MAX_DEVICES 2
|
#define SWR_SLV_MAX_DEVICES 2
|
||||||
#endif /* CONFIG_DEBUG_FS */
|
#endif /* CONFIG_DEBUG_FS */
|
||||||
|
|
||||||
|
#define SWR_MAX_RETRY 5
|
||||||
|
|
||||||
struct wcd938x_slave_priv {
|
struct wcd938x_slave_priv {
|
||||||
struct swr_device *swr_slave;
|
struct swr_device *swr_slave;
|
||||||
#ifdef CONFIG_DEBUG_FS
|
#ifdef CONFIG_DEBUG_FS
|
||||||
@@ -278,17 +280,24 @@ static int wcd938x_slave_bind(struct device *dev,
|
|||||||
int ret = 0;
|
int ret = 0;
|
||||||
uint8_t devnum = 0;
|
uint8_t devnum = 0;
|
||||||
struct swr_device *pdev = to_swr_device(dev);
|
struct swr_device *pdev = to_swr_device(dev);
|
||||||
|
int retry = SWR_MAX_RETRY;
|
||||||
|
|
||||||
if (!pdev) {
|
if (!pdev) {
|
||||||
pr_err("%s: invalid swr device handle\n", __func__);
|
pr_err("%s: invalid swr device handle\n", __func__);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
/* Add delay for soundwire enumeration */
|
||||||
|
usleep_range(100, 110);
|
||||||
ret = swr_get_logical_dev_num(pdev, pdev->addr, &devnum);
|
ret = swr_get_logical_dev_num(pdev, pdev->addr, &devnum);
|
||||||
|
} while (ret && --retry);
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_dbg(&pdev->dev,
|
dev_dbg(&pdev->dev,
|
||||||
"%s get devnum %d for dev addr %lx failed\n",
|
"%s get devnum %d for dev addr %llx failed\n",
|
||||||
__func__, devnum, pdev->addr);
|
__func__, devnum, pdev->addr);
|
||||||
|
ret = -EPROBE_DEFER;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
pdev->dev_num = devnum;
|
pdev->dev_num = devnum;
|
||||||
|
@@ -72,6 +72,11 @@ enum {
|
|||||||
HPH_COMP_DELAY,
|
HPH_COMP_DELAY,
|
||||||
HPH_PA_DELAY,
|
HPH_PA_DELAY,
|
||||||
AMIC2_BCS_ENABLE,
|
AMIC2_BCS_ENABLE,
|
||||||
|
WCD_SUPPLIES_LPM_MODE,
|
||||||
|
WCD_ADC1_MODE,
|
||||||
|
WCD_ADC2_MODE,
|
||||||
|
WCD_ADC3_MODE,
|
||||||
|
WCD_ADC4_MODE,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@@ -1540,13 +1545,17 @@ static int wcd938x_tx_swr_ctrl(struct snd_soc_dapm_widget *w,
|
|||||||
switch (event) {
|
switch (event) {
|
||||||
case SND_SOC_DAPM_PRE_PMU:
|
case SND_SOC_DAPM_PRE_PMU:
|
||||||
if (strnstr(w->name, "ADC", sizeof("ADC"))) {
|
if (strnstr(w->name, "ADC", sizeof("ADC"))) {
|
||||||
if (test_bit(WCD_ADC1, &wcd938x->status_mask))
|
if (test_bit(WCD_ADC1, &wcd938x->status_mask) ||
|
||||||
|
test_bit(WCD_ADC1_MODE, &wcd938x->status_mask))
|
||||||
mode |= tx_mode_bit[wcd938x->tx_mode[WCD_ADC1]];
|
mode |= tx_mode_bit[wcd938x->tx_mode[WCD_ADC1]];
|
||||||
if (test_bit(WCD_ADC2, &wcd938x->status_mask))
|
if (test_bit(WCD_ADC2, &wcd938x->status_mask) ||
|
||||||
|
test_bit(WCD_ADC2_MODE, &wcd938x->status_mask))
|
||||||
mode |= tx_mode_bit[wcd938x->tx_mode[WCD_ADC2]];
|
mode |= tx_mode_bit[wcd938x->tx_mode[WCD_ADC2]];
|
||||||
if (test_bit(WCD_ADC3, &wcd938x->status_mask))
|
if (test_bit(WCD_ADC3, &wcd938x->status_mask) ||
|
||||||
|
test_bit(WCD_ADC3_MODE, &wcd938x->status_mask))
|
||||||
mode |= tx_mode_bit[wcd938x->tx_mode[WCD_ADC3]];
|
mode |= tx_mode_bit[wcd938x->tx_mode[WCD_ADC3]];
|
||||||
if (test_bit(WCD_ADC4, &wcd938x->status_mask))
|
if (test_bit(WCD_ADC4, &wcd938x->status_mask) ||
|
||||||
|
test_bit(WCD_ADC4_MODE, &wcd938x->status_mask))
|
||||||
mode |= tx_mode_bit[wcd938x->tx_mode[WCD_ADC4]];
|
mode |= tx_mode_bit[wcd938x->tx_mode[WCD_ADC4]];
|
||||||
|
|
||||||
if (mode != 0) {
|
if (mode != 0) {
|
||||||
@@ -1593,6 +1602,14 @@ static int wcd938x_tx_swr_ctrl(struct snd_soc_dapm_widget *w,
|
|||||||
|
|
||||||
if (strnstr(w->name, "ADC", sizeof("ADC")))
|
if (strnstr(w->name, "ADC", sizeof("ADC")))
|
||||||
wcd938x_set_swr_clk_rate(component, rate, bank);
|
wcd938x_set_swr_clk_rate(component, rate, bank);
|
||||||
|
if (strnstr(w->name, "ADC1", sizeof("ADC1")))
|
||||||
|
clear_bit(WCD_ADC1_MODE, &wcd938x->status_mask);
|
||||||
|
else if (strnstr(w->name, "ADC2", sizeof("ADC2")))
|
||||||
|
clear_bit(WCD_ADC2_MODE, &wcd938x->status_mask);
|
||||||
|
else if (strnstr(w->name, "ADC3", sizeof("ADC3")))
|
||||||
|
clear_bit(WCD_ADC3_MODE, &wcd938x->status_mask);
|
||||||
|
else if (strnstr(w->name, "ADC4", sizeof("ADC4")))
|
||||||
|
clear_bit(WCD_ADC4_MODE, &wcd938x->status_mask);
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1633,57 +1650,6 @@ static int wcd938x_get_adc_mode(int val)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int wcd938x_codec_enable_adc(struct snd_soc_dapm_widget *w,
|
|
||||||
struct snd_kcontrol *kcontrol,
|
|
||||||
int event){
|
|
||||||
struct snd_soc_component *component =
|
|
||||||
snd_soc_dapm_to_component(w->dapm);
|
|
||||||
struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
|
|
||||||
int clk_rate = 0, ret = 0;
|
|
||||||
|
|
||||||
dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__,
|
|
||||||
w->name, event);
|
|
||||||
|
|
||||||
switch (event) {
|
|
||||||
case SND_SOC_DAPM_PRE_PMU:
|
|
||||||
snd_soc_component_update_bits(component,
|
|
||||||
WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x08, 0x08);
|
|
||||||
snd_soc_component_update_bits(component,
|
|
||||||
WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x10, 0x10);
|
|
||||||
set_bit(w->shift, &wcd938x->status_mask);
|
|
||||||
clk_rate = wcd938x_get_clk_rate(wcd938x->tx_mode[w->shift]);
|
|
||||||
ret = swr_slvdev_datapath_control(wcd938x->tx_swr_dev,
|
|
||||||
wcd938x->tx_swr_dev->dev_num,
|
|
||||||
true);
|
|
||||||
break;
|
|
||||||
case SND_SOC_DAPM_POST_PMD:
|
|
||||||
ret = swr_slvdev_datapath_control(wcd938x->tx_swr_dev,
|
|
||||||
wcd938x->tx_swr_dev->dev_num,
|
|
||||||
false);
|
|
||||||
snd_soc_component_update_bits(component,
|
|
||||||
WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x08, 0x00);
|
|
||||||
clear_bit(w->shift, &wcd938x->status_mask);
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void wcd938x_disable_bcs_before_slow_insert(struct snd_soc_component *component,
|
|
||||||
bool bcs_disable)
|
|
||||||
{
|
|
||||||
struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
|
|
||||||
|
|
||||||
if (wcd938x->update_wcd_event) {
|
|
||||||
if (bcs_disable)
|
|
||||||
wcd938x->update_wcd_event(wcd938x->handle,
|
|
||||||
WCD_BOLERO_EVT_BCS_CLK_OFF, 0);
|
|
||||||
else
|
|
||||||
wcd938x->update_wcd_event(wcd938x->handle,
|
|
||||||
WCD_BOLERO_EVT_BCS_CLK_OFF, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int wcd938x_tx_channel_config(struct snd_soc_component *component,
|
int wcd938x_tx_channel_config(struct snd_soc_component *component,
|
||||||
int channel, int mode)
|
int channel, int mode)
|
||||||
{
|
{
|
||||||
@@ -1724,14 +1690,14 @@ int wcd938x_tx_channel_config(struct snd_soc_component *component,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int wcd938x_enable_req(struct snd_soc_dapm_widget *w,
|
static int wcd938x_codec_enable_adc(struct snd_soc_dapm_widget *w,
|
||||||
struct snd_kcontrol *kcontrol, int event)
|
struct snd_kcontrol *kcontrol,
|
||||||
{
|
int event){
|
||||||
struct snd_soc_component *component =
|
struct snd_soc_component *component =
|
||||||
snd_soc_dapm_to_component(w->dapm);
|
snd_soc_dapm_to_component(w->dapm);
|
||||||
int mode;
|
|
||||||
int ret = 0;
|
|
||||||
struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
|
struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
|
||||||
|
int clk_rate = 0, ret = 0;
|
||||||
|
int mode;
|
||||||
|
|
||||||
dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__,
|
dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__,
|
||||||
w->name, event);
|
w->name, event);
|
||||||
@@ -1739,9 +1705,14 @@ static int wcd938x_enable_req(struct snd_soc_dapm_widget *w,
|
|||||||
switch (event) {
|
switch (event) {
|
||||||
case SND_SOC_DAPM_PRE_PMU:
|
case SND_SOC_DAPM_PRE_PMU:
|
||||||
snd_soc_component_update_bits(component,
|
snd_soc_component_update_bits(component,
|
||||||
WCD938X_DIGITAL_CDC_REQ_CTL, 0x02, 0x02);
|
WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x08, 0x08);
|
||||||
snd_soc_component_update_bits(component,
|
snd_soc_component_update_bits(component,
|
||||||
WCD938X_DIGITAL_CDC_REQ_CTL, 0x01, 0x00);
|
WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x10, 0x10);
|
||||||
|
set_bit(w->shift, &wcd938x->status_mask);
|
||||||
|
clk_rate = wcd938x_get_clk_rate(wcd938x->tx_mode[w->shift]);
|
||||||
|
ret = swr_slvdev_datapath_control(wcd938x->tx_swr_dev,
|
||||||
|
wcd938x->tx_swr_dev->dev_num,
|
||||||
|
true);
|
||||||
ret = wcd938x_tx_channel_config(component, w->shift, 1);
|
ret = wcd938x_tx_channel_config(component, w->shift, 1);
|
||||||
mode = wcd938x_get_adc_mode(wcd938x->tx_mode[w->shift]);
|
mode = wcd938x_get_adc_mode(wcd938x->tx_mode[w->shift]);
|
||||||
if (mode < 0) {
|
if (mode < 0) {
|
||||||
@@ -1817,6 +1788,51 @@ static int wcd938x_enable_req(struct snd_soc_dapm_widget *w,
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
ret = swr_slvdev_datapath_control(wcd938x->tx_swr_dev,
|
||||||
|
wcd938x->tx_swr_dev->dev_num,
|
||||||
|
false);
|
||||||
|
snd_soc_component_update_bits(component,
|
||||||
|
WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x08, 0x00);
|
||||||
|
clear_bit(w->shift, &wcd938x->status_mask);
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wcd938x_disable_bcs_before_slow_insert(struct snd_soc_component *component,
|
||||||
|
bool bcs_disable)
|
||||||
|
{
|
||||||
|
struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
|
||||||
|
|
||||||
|
if (wcd938x->update_wcd_event) {
|
||||||
|
if (bcs_disable)
|
||||||
|
wcd938x->update_wcd_event(wcd938x->handle,
|
||||||
|
WCD_BOLERO_EVT_BCS_CLK_OFF, 0);
|
||||||
|
else
|
||||||
|
wcd938x->update_wcd_event(wcd938x->handle,
|
||||||
|
WCD_BOLERO_EVT_BCS_CLK_OFF, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int wcd938x_enable_req(struct snd_soc_dapm_widget *w,
|
||||||
|
struct snd_kcontrol *kcontrol, int event)
|
||||||
|
{
|
||||||
|
struct snd_soc_component *component =
|
||||||
|
snd_soc_dapm_to_component(w->dapm);
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__,
|
||||||
|
w->name, event);
|
||||||
|
|
||||||
|
switch (event) {
|
||||||
|
case SND_SOC_DAPM_PRE_PMU:
|
||||||
|
snd_soc_component_update_bits(component,
|
||||||
|
WCD938X_DIGITAL_CDC_REQ_CTL, 0x02, 0x02);
|
||||||
|
snd_soc_component_update_bits(component,
|
||||||
|
WCD938X_DIGITAL_CDC_REQ_CTL, 0x01, 0x00);
|
||||||
|
break;
|
||||||
|
case SND_SOC_DAPM_POST_PMD:
|
||||||
snd_soc_component_update_bits(component,
|
snd_soc_component_update_bits(component,
|
||||||
WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x10, 0x00);
|
WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x10, 0x00);
|
||||||
break;
|
break;
|
||||||
@@ -1991,15 +2007,16 @@ static int wcd938x_get_logical_addr(struct swr_device *swr_dev)
|
|||||||
int num_retry = NUM_ATTEMPTS;
|
int num_retry = NUM_ATTEMPTS;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
ret = swr_get_logical_dev_num(swr_dev, swr_dev->addr, &devnum);
|
|
||||||
if (ret) {
|
|
||||||
dev_err(&swr_dev->dev,
|
|
||||||
"%s get devnum %d for dev addr %lx failed\n",
|
|
||||||
__func__, devnum, swr_dev->addr);
|
|
||||||
/* retry after 1ms */
|
/* retry after 1ms */
|
||||||
usleep_range(1000, 1010);
|
usleep_range(1000, 1010);
|
||||||
}
|
ret = swr_get_logical_dev_num(swr_dev, swr_dev->addr, &devnum);
|
||||||
} while (ret && --num_retry);
|
} while (ret && --num_retry);
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
dev_err(&swr_dev->dev,
|
||||||
|
"%s get devnum %d for dev addr %llx failed\n",
|
||||||
|
__func__, devnum, swr_dev->addr);
|
||||||
|
|
||||||
swr_dev->dev_num = devnum;
|
swr_dev->dev_num = devnum;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -2015,6 +2032,27 @@ static bool get_usbc_hs_status(struct snd_soc_component *component,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int wcd938x_swr_dmic_register_notifier(struct snd_soc_component *component,
|
||||||
|
struct notifier_block *nblock,
|
||||||
|
bool enable)
|
||||||
|
{
|
||||||
|
struct wcd938x_priv *wcd938x_priv;
|
||||||
|
if(NULL == component) {
|
||||||
|
pr_err("%s: wcd938x component is NULL\n", __func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
wcd938x_priv = snd_soc_component_get_drvdata(component);
|
||||||
|
wcd938x_priv->notify_swr_dmic = enable;
|
||||||
|
if (enable)
|
||||||
|
return blocking_notifier_chain_register(&wcd938x_priv->notifier,
|
||||||
|
nblock);
|
||||||
|
else
|
||||||
|
return blocking_notifier_chain_unregister(
|
||||||
|
&wcd938x_priv->notifier, nblock);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(wcd938x_swr_dmic_register_notifier);
|
||||||
|
|
||||||
static int wcd938x_event_notify(struct notifier_block *block,
|
static int wcd938x_event_notify(struct notifier_block *block,
|
||||||
unsigned long val,
|
unsigned long val,
|
||||||
void *data)
|
void *data)
|
||||||
@@ -2030,21 +2068,25 @@ static int wcd938x_event_notify(struct notifier_block *block,
|
|||||||
if (test_bit(WCD_ADC1, &wcd938x->status_mask)) {
|
if (test_bit(WCD_ADC1, &wcd938x->status_mask)) {
|
||||||
snd_soc_component_update_bits(component,
|
snd_soc_component_update_bits(component,
|
||||||
WCD938X_ANA_TX_CH2, 0x40, 0x00);
|
WCD938X_ANA_TX_CH2, 0x40, 0x00);
|
||||||
|
set_bit(WCD_ADC1_MODE, &wcd938x->status_mask);
|
||||||
clear_bit(WCD_ADC1, &wcd938x->status_mask);
|
clear_bit(WCD_ADC1, &wcd938x->status_mask);
|
||||||
}
|
}
|
||||||
if (test_bit(WCD_ADC2, &wcd938x->status_mask)) {
|
if (test_bit(WCD_ADC2, &wcd938x->status_mask)) {
|
||||||
snd_soc_component_update_bits(component,
|
snd_soc_component_update_bits(component,
|
||||||
WCD938X_ANA_TX_CH2, 0x20, 0x00);
|
WCD938X_ANA_TX_CH2, 0x20, 0x00);
|
||||||
|
set_bit(WCD_ADC2_MODE, &wcd938x->status_mask);
|
||||||
clear_bit(WCD_ADC2, &wcd938x->status_mask);
|
clear_bit(WCD_ADC2, &wcd938x->status_mask);
|
||||||
}
|
}
|
||||||
if (test_bit(WCD_ADC3, &wcd938x->status_mask)) {
|
if (test_bit(WCD_ADC3, &wcd938x->status_mask)) {
|
||||||
snd_soc_component_update_bits(component,
|
snd_soc_component_update_bits(component,
|
||||||
WCD938X_ANA_TX_CH4, 0x40, 0x00);
|
WCD938X_ANA_TX_CH4, 0x40, 0x00);
|
||||||
|
set_bit(WCD_ADC3_MODE, &wcd938x->status_mask);
|
||||||
clear_bit(WCD_ADC3, &wcd938x->status_mask);
|
clear_bit(WCD_ADC3, &wcd938x->status_mask);
|
||||||
}
|
}
|
||||||
if (test_bit(WCD_ADC4, &wcd938x->status_mask)) {
|
if (test_bit(WCD_ADC4, &wcd938x->status_mask)) {
|
||||||
snd_soc_component_update_bits(component,
|
snd_soc_component_update_bits(component,
|
||||||
WCD938X_ANA_TX_CH4, 0x20, 0x00);
|
WCD938X_ANA_TX_CH4, 0x20, 0x00);
|
||||||
|
set_bit(WCD_ADC4_MODE, &wcd938x->status_mask);
|
||||||
clear_bit(WCD_ADC4, &wcd938x->status_mask);
|
clear_bit(WCD_ADC4, &wcd938x->status_mask);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -2058,7 +2100,13 @@ static int wcd938x_event_notify(struct notifier_block *block,
|
|||||||
break;
|
break;
|
||||||
case BOLERO_WCD_EVT_SSR_DOWN:
|
case BOLERO_WCD_EVT_SSR_DOWN:
|
||||||
wcd938x->dev_up = false;
|
wcd938x->dev_up = false;
|
||||||
|
if(wcd938x->notify_swr_dmic)
|
||||||
|
blocking_notifier_call_chain(&wcd938x->notifier,
|
||||||
|
WCD938X_EVT_SSR_DOWN,
|
||||||
|
NULL);
|
||||||
wcd938x->mbhc->wcd_mbhc.deinit_in_progress = true;
|
wcd938x->mbhc->wcd_mbhc.deinit_in_progress = true;
|
||||||
|
wcd938x->mbhc->wcd_mbhc.plug_before_ssr =
|
||||||
|
wcd938x->mbhc->wcd_mbhc.current_plug;
|
||||||
mbhc = &wcd938x->mbhc->wcd_mbhc;
|
mbhc = &wcd938x->mbhc->wcd_mbhc;
|
||||||
wcd938x->usbc_hs_status = get_usbc_hs_status(component,
|
wcd938x->usbc_hs_status = get_usbc_hs_status(component,
|
||||||
mbhc->mbhc_cfg);
|
mbhc->mbhc_cfg);
|
||||||
@@ -2089,6 +2137,10 @@ static int wcd938x_event_notify(struct notifier_block *block,
|
|||||||
}
|
}
|
||||||
wcd938x->mbhc->wcd_mbhc.deinit_in_progress = false;
|
wcd938x->mbhc->wcd_mbhc.deinit_in_progress = false;
|
||||||
wcd938x->dev_up = true;
|
wcd938x->dev_up = true;
|
||||||
|
if(wcd938x->notify_swr_dmic)
|
||||||
|
blocking_notifier_call_chain(&wcd938x->notifier,
|
||||||
|
WCD938X_EVT_SSR_UP,
|
||||||
|
NULL);
|
||||||
break;
|
break;
|
||||||
case BOLERO_WCD_EVT_CLK_NOTIFY:
|
case BOLERO_WCD_EVT_CLK_NOTIFY:
|
||||||
snd_soc_component_update_bits(component,
|
snd_soc_component_update_bits(component,
|
||||||
@@ -2272,6 +2324,9 @@ static int wcd938x_enable_micbias(struct wcd938x_priv *wcd938x,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pr_debug("%s: req: %d micb_num: %d micb_ref: %d pullup_ref: %d\n",
|
||||||
|
__func__, req, micb_num, wcd938x->micb_ref[micb_index],
|
||||||
|
wcd938x->pullup_ref[micb_index]);
|
||||||
mutex_lock(&wcd938x->micb_lock);
|
mutex_lock(&wcd938x->micb_lock);
|
||||||
|
|
||||||
switch (req) {
|
switch (req) {
|
||||||
@@ -2336,6 +2391,8 @@ int wcd938x_codec_force_enable_micbias_v2(struct snd_soc_component *component,
|
|||||||
int event, int micb_num)
|
int event, int micb_num)
|
||||||
{
|
{
|
||||||
struct wcd938x_priv *wcd938x_priv = NULL;
|
struct wcd938x_priv *wcd938x_priv = NULL;
|
||||||
|
int ret = 0;
|
||||||
|
int micb_index = micb_num - 1;
|
||||||
|
|
||||||
if(NULL == component) {
|
if(NULL == component) {
|
||||||
pr_err("%s: wcd938x component is NULL\n", __func__);
|
pr_err("%s: wcd938x component is NULL\n", __func__);
|
||||||
@@ -2352,6 +2409,15 @@ int wcd938x_codec_force_enable_micbias_v2(struct snd_soc_component *component,
|
|||||||
|
|
||||||
wcd938x_priv = snd_soc_component_get_drvdata(component);
|
wcd938x_priv = snd_soc_component_get_drvdata(component);
|
||||||
|
|
||||||
|
if (!wcd938x_priv->dev_up) {
|
||||||
|
if ((wcd938x_priv->pullup_ref[micb_index] > 0) &&
|
||||||
|
(event == SND_SOC_DAPM_POST_PMD)) {
|
||||||
|
wcd938x_priv->pullup_ref[micb_index]--;
|
||||||
|
ret = -ENODEV;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case SND_SOC_DAPM_PRE_PMU:
|
case SND_SOC_DAPM_PRE_PMU:
|
||||||
wcd938x_wakeup(wcd938x_priv, true);
|
wcd938x_wakeup(wcd938x_priv, true);
|
||||||
@@ -2365,7 +2431,8 @@ int wcd938x_codec_force_enable_micbias_v2(struct snd_soc_component *component,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
done:
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(wcd938x_codec_force_enable_micbias_v2);
|
EXPORT_SYMBOL(wcd938x_codec_force_enable_micbias_v2);
|
||||||
|
|
||||||
@@ -3050,9 +3117,17 @@ static const struct snd_soc_dapm_widget wcd938x_dapm_widgets[] = {
|
|||||||
SND_SOC_DAPM_INPUT("AMIC5"),
|
SND_SOC_DAPM_INPUT("AMIC5"),
|
||||||
SND_SOC_DAPM_INPUT("AMIC6"),
|
SND_SOC_DAPM_INPUT("AMIC6"),
|
||||||
SND_SOC_DAPM_INPUT("AMIC7"),
|
SND_SOC_DAPM_INPUT("AMIC7"),
|
||||||
|
|
||||||
SND_SOC_DAPM_INPUT("IN1_HPHL"),
|
SND_SOC_DAPM_INPUT("IN1_HPHL"),
|
||||||
SND_SOC_DAPM_INPUT("IN2_HPHR"),
|
SND_SOC_DAPM_INPUT("IN2_HPHR"),
|
||||||
SND_SOC_DAPM_INPUT("IN3_AUX"),
|
SND_SOC_DAPM_INPUT("IN3_AUX"),
|
||||||
|
/*
|
||||||
|
* These dummy widgets are null connected to WCD938x dapm input and
|
||||||
|
* output widgets which are not actual path endpoints. This ensures
|
||||||
|
* dapm doesnt set these dapm input and output widgets as endpoints.
|
||||||
|
*/
|
||||||
|
SND_SOC_DAPM_INPUT("WCD_TX_DUMMY"),
|
||||||
|
SND_SOC_DAPM_OUTPUT("WCD_RX_DUMMY"),
|
||||||
|
|
||||||
/*tx widgets*/
|
/*tx widgets*/
|
||||||
SND_SOC_DAPM_ADC_E("ADC1", NULL, SND_SOC_NOPM, 0, 0,
|
SND_SOC_DAPM_ADC_E("ADC1", NULL, SND_SOC_NOPM, 0, 0,
|
||||||
@@ -3289,6 +3364,7 @@ static const struct snd_soc_dapm_widget wcd938x_dapm_widgets[] = {
|
|||||||
|
|
||||||
static const struct snd_soc_dapm_route wcd938x_audio_map[] = {
|
static const struct snd_soc_dapm_route wcd938x_audio_map[] = {
|
||||||
|
|
||||||
|
{"WCD_TX_DUMMY", NULL, "WCD_TX_OUTPUT"},
|
||||||
{"WCD_TX_OUTPUT", NULL, "ADC1_MIXER"},
|
{"WCD_TX_OUTPUT", NULL, "ADC1_MIXER"},
|
||||||
{"ADC1_MIXER", "Switch", "ADC1 REQ"},
|
{"ADC1_MIXER", "Switch", "ADC1 REQ"},
|
||||||
{"ADC1 REQ", NULL, "ADC1"},
|
{"ADC1 REQ", NULL, "ADC1"},
|
||||||
@@ -3343,6 +3419,7 @@ static const struct snd_soc_dapm_route wcd938x_audio_map[] = {
|
|||||||
{"WCD_TX_OUTPUT", NULL, "DMIC8_MIXER"},
|
{"WCD_TX_OUTPUT", NULL, "DMIC8_MIXER"},
|
||||||
{"DMIC8_MIXER", "Switch", "DMIC8"},
|
{"DMIC8_MIXER", "Switch", "DMIC8"},
|
||||||
|
|
||||||
|
{"IN1_HPHL", NULL, "WCD_RX_DUMMY"},
|
||||||
{"IN1_HPHL", NULL, "VDD_BUCK"},
|
{"IN1_HPHL", NULL, "VDD_BUCK"},
|
||||||
{"IN1_HPHL", NULL, "CLS_H_PORT"},
|
{"IN1_HPHL", NULL, "CLS_H_PORT"},
|
||||||
{"RX1", NULL, "IN1_HPHL"},
|
{"RX1", NULL, "IN1_HPHL"},
|
||||||
@@ -3351,6 +3428,7 @@ static const struct snd_soc_dapm_route wcd938x_audio_map[] = {
|
|||||||
{"HPHL PGA", NULL, "HPHL_RDAC"},
|
{"HPHL PGA", NULL, "HPHL_RDAC"},
|
||||||
{"HPHL", NULL, "HPHL PGA"},
|
{"HPHL", NULL, "HPHL PGA"},
|
||||||
|
|
||||||
|
{"IN2_HPHR", NULL, "WCD_RX_DUMMY"},
|
||||||
{"IN2_HPHR", NULL, "VDD_BUCK"},
|
{"IN2_HPHR", NULL, "VDD_BUCK"},
|
||||||
{"IN2_HPHR", NULL, "CLS_H_PORT"},
|
{"IN2_HPHR", NULL, "CLS_H_PORT"},
|
||||||
{"RX2", NULL, "IN2_HPHR"},
|
{"RX2", NULL, "IN2_HPHR"},
|
||||||
@@ -3359,6 +3437,7 @@ static const struct snd_soc_dapm_route wcd938x_audio_map[] = {
|
|||||||
{"HPHR PGA", NULL, "HPHR_RDAC"},
|
{"HPHR PGA", NULL, "HPHR_RDAC"},
|
||||||
{"HPHR", NULL, "HPHR PGA"},
|
{"HPHR", NULL, "HPHR PGA"},
|
||||||
|
|
||||||
|
{"IN3_AUX", NULL, "WCD_RX_DUMMY"},
|
||||||
{"IN3_AUX", NULL, "VDD_BUCK"},
|
{"IN3_AUX", NULL, "VDD_BUCK"},
|
||||||
{"IN3_AUX", NULL, "CLS_H_PORT"},
|
{"IN3_AUX", NULL, "CLS_H_PORT"},
|
||||||
{"RX3", NULL, "IN3_AUX"},
|
{"RX3", NULL, "IN3_AUX"},
|
||||||
@@ -3634,6 +3713,8 @@ static int wcd938x_soc_codec_probe(struct snd_soc_component *component)
|
|||||||
goto err_hwdep;
|
goto err_hwdep;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
snd_soc_dapm_ignore_suspend(dapm, "WCD938X_AIF Playback");
|
||||||
|
snd_soc_dapm_ignore_suspend(dapm, "WCD938X_AIF Capture");
|
||||||
snd_soc_dapm_ignore_suspend(dapm, "AMIC1");
|
snd_soc_dapm_ignore_suspend(dapm, "AMIC1");
|
||||||
snd_soc_dapm_ignore_suspend(dapm, "AMIC2");
|
snd_soc_dapm_ignore_suspend(dapm, "AMIC2");
|
||||||
snd_soc_dapm_ignore_suspend(dapm, "AMIC3");
|
snd_soc_dapm_ignore_suspend(dapm, "AMIC3");
|
||||||
@@ -3649,6 +3730,8 @@ static int wcd938x_soc_codec_probe(struct snd_soc_component *component)
|
|||||||
snd_soc_dapm_ignore_suspend(dapm, "AUX");
|
snd_soc_dapm_ignore_suspend(dapm, "AUX");
|
||||||
snd_soc_dapm_ignore_suspend(dapm, "HPHL");
|
snd_soc_dapm_ignore_suspend(dapm, "HPHL");
|
||||||
snd_soc_dapm_ignore_suspend(dapm, "HPHR");
|
snd_soc_dapm_ignore_suspend(dapm, "HPHR");
|
||||||
|
snd_soc_dapm_ignore_suspend(dapm, "WCD_TX_DUMMY");
|
||||||
|
snd_soc_dapm_ignore_suspend(dapm, "WCD_RX_DUMMY");
|
||||||
snd_soc_dapm_sync(dapm);
|
snd_soc_dapm_sync(dapm);
|
||||||
|
|
||||||
wcd_cls_h_init(&wcd938x->clsh_info);
|
wcd_cls_h_init(&wcd938x->clsh_info);
|
||||||
@@ -3688,7 +3771,6 @@ static int wcd938x_soc_codec_probe(struct snd_soc_component *component)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
wcd938x->dev_up = true;
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
err_hwdep:
|
err_hwdep:
|
||||||
@@ -3713,6 +3795,26 @@ static void wcd938x_soc_codec_remove(struct snd_soc_component *component)
|
|||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int wcd938x_soc_codec_suspend(struct snd_soc_component *component)
|
||||||
|
{
|
||||||
|
struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
|
||||||
|
|
||||||
|
if (!wcd938x)
|
||||||
|
return 0;
|
||||||
|
wcd938x->dapm_bias_off = true;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int wcd938x_soc_codec_resume(struct snd_soc_component *component)
|
||||||
|
{
|
||||||
|
struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
|
||||||
|
|
||||||
|
if (!wcd938x)
|
||||||
|
return 0;
|
||||||
|
wcd938x->dapm_bias_off = false;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static struct snd_soc_component_driver soc_codec_dev_wcd938x = {
|
static struct snd_soc_component_driver soc_codec_dev_wcd938x = {
|
||||||
.name = WCD938X_DRV_NAME,
|
.name = WCD938X_DRV_NAME,
|
||||||
.probe = wcd938x_soc_codec_probe,
|
.probe = wcd938x_soc_codec_probe,
|
||||||
@@ -3723,6 +3825,8 @@ static struct snd_soc_component_driver soc_codec_dev_wcd938x = {
|
|||||||
.num_dapm_widgets = ARRAY_SIZE(wcd938x_dapm_widgets),
|
.num_dapm_widgets = ARRAY_SIZE(wcd938x_dapm_widgets),
|
||||||
.dapm_routes = wcd938x_audio_map,
|
.dapm_routes = wcd938x_audio_map,
|
||||||
.num_dapm_routes = ARRAY_SIZE(wcd938x_audio_map),
|
.num_dapm_routes = ARRAY_SIZE(wcd938x_audio_map),
|
||||||
|
.suspend = wcd938x_soc_codec_suspend,
|
||||||
|
.resume = wcd938x_soc_codec_resume,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int wcd938x_reset(struct device *dev)
|
static int wcd938x_reset(struct device *dev)
|
||||||
@@ -4026,6 +4130,7 @@ static int wcd938x_bind(struct device *dev)
|
|||||||
__func__);
|
__func__);
|
||||||
goto err_irq;
|
goto err_irq;
|
||||||
}
|
}
|
||||||
|
wcd938x->dev_up = true;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
err_irq:
|
err_irq:
|
||||||
@@ -4242,19 +4347,51 @@ static int wcd938x_suspend(struct device *dev)
|
|||||||
}
|
}
|
||||||
clear_bit(ALLOW_BUCK_DISABLE, &wcd938x->status_mask);
|
clear_bit(ALLOW_BUCK_DISABLE, &wcd938x->status_mask);
|
||||||
}
|
}
|
||||||
|
if (wcd938x->dapm_bias_off) {
|
||||||
|
msm_cdc_set_supplies_lpm_mode(wcd938x->dev,
|
||||||
|
wcd938x->supplies,
|
||||||
|
pdata->regulator,
|
||||||
|
pdata->num_supplies,
|
||||||
|
true);
|
||||||
|
set_bit(WCD_SUPPLIES_LPM_MODE, &wcd938x->status_mask);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int wcd938x_resume(struct device *dev)
|
static int wcd938x_resume(struct device *dev)
|
||||||
{
|
{
|
||||||
|
struct wcd938x_priv *wcd938x = NULL;
|
||||||
|
struct wcd938x_pdata *pdata = NULL;
|
||||||
|
|
||||||
|
if (!dev)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
wcd938x = dev_get_drvdata(dev);
|
||||||
|
if (!wcd938x)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
pdata = dev_get_platdata(wcd938x->dev);
|
||||||
|
|
||||||
|
if (!pdata) {
|
||||||
|
dev_err(dev, "%s: pdata is NULL\n", __func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (test_bit(WCD_SUPPLIES_LPM_MODE, &wcd938x->status_mask)) {
|
||||||
|
msm_cdc_set_supplies_lpm_mode(wcd938x->dev,
|
||||||
|
wcd938x->supplies,
|
||||||
|
pdata->regulator,
|
||||||
|
pdata->num_supplies,
|
||||||
|
false);
|
||||||
|
clear_bit(WCD_SUPPLIES_LPM_MODE, &wcd938x->status_mask);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct dev_pm_ops wcd938x_dev_pm_ops = {
|
static const struct dev_pm_ops wcd938x_dev_pm_ops = {
|
||||||
SET_SYSTEM_SLEEP_PM_OPS(
|
.suspend_late = wcd938x_suspend,
|
||||||
wcd938x_suspend,
|
.resume_early = wcd938x_resume,
|
||||||
wcd938x_resume
|
|
||||||
)
|
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -17,6 +17,12 @@ enum {
|
|||||||
WCD9385 = 5,
|
WCD9385 = 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* from WCD to SWR DMIC events */
|
||||||
|
enum {
|
||||||
|
WCD938X_EVT_SSR_DOWN,
|
||||||
|
WCD938X_EVT_SSR_UP,
|
||||||
|
};
|
||||||
|
|
||||||
struct swr_slave_ch_map {
|
struct swr_slave_ch_map {
|
||||||
u8 ch_type;
|
u8 ch_type;
|
||||||
u8 index;
|
u8 index;
|
||||||
@@ -62,6 +68,9 @@ int wcd938x_info_create_codec_entry(struct snd_info_entry *codec_root,
|
|||||||
int wcd938x_get_codec_variant(struct snd_soc_component *component);
|
int wcd938x_get_codec_variant(struct snd_soc_component *component);
|
||||||
int wcd938x_codec_force_enable_micbias_v2(struct snd_soc_component *wcd938x,
|
int wcd938x_codec_force_enable_micbias_v2(struct snd_soc_component *wcd938x,
|
||||||
int event, int micb_num);
|
int event, int micb_num);
|
||||||
|
int wcd938x_swr_dmic_register_notifier(struct snd_soc_component *wcd938x,
|
||||||
|
struct notifier_block *nblock,
|
||||||
|
bool enable);
|
||||||
|
|
||||||
static inline int wcd938x_slave_get_master_ch_val(int ch)
|
static inline int wcd938x_slave_get_master_ch_val(int ch)
|
||||||
{
|
{
|
||||||
|
@@ -1083,6 +1083,9 @@ static int wsa881x_spkr_pa_event(struct snd_soc_dapm_widget *w,
|
|||||||
0x80, 0x00);
|
0x80, 0x00);
|
||||||
if (wsa881x->visense_enable) {
|
if (wsa881x->visense_enable) {
|
||||||
wsa881x_visense_adc_ctrl(component, DISABLE);
|
wsa881x_visense_adc_ctrl(component, DISABLE);
|
||||||
|
snd_soc_component_update_bits(component,
|
||||||
|
WSA881X_ADC_EN_SEL_IBAIS,
|
||||||
|
0x07, 0x00);
|
||||||
wsa881x_visense_txfe_ctrl(component, DISABLE,
|
wsa881x_visense_txfe_ctrl(component, DISABLE,
|
||||||
0x00, 0x01, 0x01);
|
0x00, 0x01, 0x01);
|
||||||
}
|
}
|
||||||
@@ -1614,8 +1617,6 @@ static int wsa881x_swr_down(struct swr_device *pdev)
|
|||||||
else
|
else
|
||||||
wsa881x->state = WSA881X_DEV_DOWN;
|
wsa881x->state = WSA881X_DEV_DOWN;
|
||||||
|
|
||||||
if (delayed_work_pending(&wsa881x->ocp_ctl_work))
|
|
||||||
cancel_delayed_work_sync(&wsa881x->ocp_ctl_work);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -97,6 +97,7 @@ struct wsa883x_priv {
|
|||||||
bool comp_enable;
|
bool comp_enable;
|
||||||
bool visense_enable;
|
bool visense_enable;
|
||||||
bool ext_vdd_spk;
|
bool ext_vdd_spk;
|
||||||
|
bool dapm_bias_off;
|
||||||
struct swr_port port[WSA883X_MAX_SWR_PORTS];
|
struct swr_port port[WSA883X_MAX_SWR_PORTS];
|
||||||
int global_pa_cnt;
|
int global_pa_cnt;
|
||||||
int dev_mode;
|
int dev_mode;
|
||||||
|
@@ -123,6 +123,7 @@ static const struct wsa_reg_mask_val reg_init[] = {
|
|||||||
{WSA883X_GMAMP_SUP1, 0x60, 0x60},
|
{WSA883X_GMAMP_SUP1, 0x60, 0x60},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int wsa883x_handle_post_irq(void *data);
|
||||||
static int wsa883x_get_temperature(struct snd_soc_component *component,
|
static int wsa883x_get_temperature(struct snd_soc_component *component,
|
||||||
int *temp);
|
int *temp);
|
||||||
enum {
|
enum {
|
||||||
@@ -132,6 +133,7 @@ enum {
|
|||||||
|
|
||||||
enum {
|
enum {
|
||||||
SPKR_STATUS = 0,
|
SPKR_STATUS = 0,
|
||||||
|
WSA_SUPPLIES_LPM_MODE,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@@ -172,9 +174,24 @@ static struct regmap_irq_chip wsa883x_regmap_irq_chip = {
|
|||||||
.ack_base = WSA883X_INTR_CLEAR0,
|
.ack_base = WSA883X_INTR_CLEAR0,
|
||||||
.use_ack = 1,
|
.use_ack = 1,
|
||||||
.runtime_pm = false,
|
.runtime_pm = false,
|
||||||
|
.handle_post_irq = wsa883x_handle_post_irq,
|
||||||
.irq_drv_data = NULL,
|
.irq_drv_data = NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int wsa883x_handle_post_irq(void *data)
|
||||||
|
{
|
||||||
|
struct wsa883x_priv *wsa883x = data;
|
||||||
|
u32 sts1 = 0, sts2 = 0;
|
||||||
|
|
||||||
|
regmap_read(wsa883x->regmap, WSA883X_INTR_STATUS0, &sts1);
|
||||||
|
regmap_read(wsa883x->regmap, WSA883X_INTR_STATUS1, &sts2);
|
||||||
|
|
||||||
|
wsa883x->swr_slave->slave_irq_pending =
|
||||||
|
((sts1 || sts2) ? true : false);
|
||||||
|
|
||||||
|
return IRQ_HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_FS
|
#ifdef CONFIG_DEBUG_FS
|
||||||
static int codec_debug_open(struct inode *inode, struct file *file)
|
static int codec_debug_open(struct inode *inode, struct file *file)
|
||||||
{
|
{
|
||||||
@@ -253,7 +270,12 @@ static ssize_t swr_slave_reg_show(struct swr_device *pdev, char __user *ubuf,
|
|||||||
swr_read(pdev, pdev->dev_num, i, ®_val, 1);
|
swr_read(pdev, pdev->dev_num, i, ®_val, 1);
|
||||||
len = snprintf(tmp_buf, sizeof(tmp_buf), "0x%.3x: 0x%.2x\n", i,
|
len = snprintf(tmp_buf, sizeof(tmp_buf), "0x%.3x: 0x%.2x\n", i,
|
||||||
(reg_val & 0xFF));
|
(reg_val & 0xFF));
|
||||||
if (((total + len) >= count - 1) || (len < 0))
|
if (len < 0) {
|
||||||
|
pr_err("%s: fail to fill the buffer\n", __func__);
|
||||||
|
total = -EFAULT;
|
||||||
|
goto copy_err;
|
||||||
|
}
|
||||||
|
if ((total + len) >= count - 1)
|
||||||
break;
|
break;
|
||||||
if (copy_to_user((ubuf + total), tmp_buf, len)) {
|
if (copy_to_user((ubuf + total), tmp_buf, len)) {
|
||||||
pr_err("%s: fail to copy reg dump\n", __func__);
|
pr_err("%s: fail to copy reg dump\n", __func__);
|
||||||
@@ -598,9 +620,14 @@ static int wsa_get_temp(struct snd_kcontrol *kcontrol,
|
|||||||
{
|
{
|
||||||
struct snd_soc_component *component =
|
struct snd_soc_component *component =
|
||||||
snd_soc_kcontrol_component(kcontrol);
|
snd_soc_kcontrol_component(kcontrol);
|
||||||
|
struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component);
|
||||||
int temp = 0;
|
int temp = 0;
|
||||||
|
|
||||||
|
if (test_bit(SPKR_STATUS, &wsa883x->status_mask))
|
||||||
|
temp = wsa883x->curr_temp;
|
||||||
|
else
|
||||||
wsa883x_get_temperature(component, &temp);
|
wsa883x_get_temperature(component, &temp);
|
||||||
|
|
||||||
ucontrol->value.integer.value[0] = temp;
|
ucontrol->value.integer.value[0] = temp;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -989,6 +1016,7 @@ static int wsa883x_spkr_event(struct snd_soc_dapm_widget *w,
|
|||||||
wsa883x->swr_slave->dev_num,
|
wsa883x->swr_slave->dev_num,
|
||||||
true);
|
true);
|
||||||
wcd_enable_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_PDM_WD);
|
wcd_enable_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_PDM_WD);
|
||||||
|
wcd_enable_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_UVLO);
|
||||||
/* Force remove group */
|
/* Force remove group */
|
||||||
swr_remove_from_group(wsa883x->swr_slave,
|
swr_remove_from_group(wsa883x->swr_slave,
|
||||||
wsa883x->swr_slave->dev_num);
|
wsa883x->swr_slave->dev_num);
|
||||||
@@ -998,6 +1026,7 @@ static int wsa883x_spkr_event(struct snd_soc_dapm_widget *w,
|
|||||||
snd_soc_component_update_bits(component, WSA883X_PA_FSM_CTL,
|
snd_soc_component_update_bits(component, WSA883X_PA_FSM_CTL,
|
||||||
0x01, 0x00);
|
0x01, 0x00);
|
||||||
wcd_disable_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_PDM_WD);
|
wcd_disable_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_PDM_WD);
|
||||||
|
wcd_disable_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_UVLO);
|
||||||
clear_bit(SPKR_STATUS, &wsa883x->status_mask);
|
clear_bit(SPKR_STATUS, &wsa883x->status_mask);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1186,6 +1215,8 @@ static int wsa883x_codec_probe(struct snd_soc_component *component)
|
|||||||
struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component);
|
struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component);
|
||||||
struct swr_device *dev;
|
struct swr_device *dev;
|
||||||
int variant = 0, version = 0;
|
int variant = 0, version = 0;
|
||||||
|
struct snd_soc_dapm_context *dapm =
|
||||||
|
snd_soc_component_get_dapm(component);
|
||||||
|
|
||||||
if (!wsa883x)
|
if (!wsa883x)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@@ -1205,6 +1236,10 @@ static int wsa883x_codec_probe(struct snd_soc_component *component)
|
|||||||
wsa883x_codec_init(component);
|
wsa883x_codec_init(component);
|
||||||
wsa883x->global_pa_cnt = 0;
|
wsa883x->global_pa_cnt = 0;
|
||||||
|
|
||||||
|
snd_soc_dapm_ignore_suspend(dapm,
|
||||||
|
wsa883x->dai_driver->playback.stream_name);
|
||||||
|
snd_soc_dapm_sync(dapm);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1220,6 +1255,28 @@ static void wsa883x_codec_remove(struct snd_soc_component *component)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int wsa883x_soc_codec_suspend(struct snd_soc_component *component)
|
||||||
|
{
|
||||||
|
struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component);
|
||||||
|
|
||||||
|
if (!wsa883x)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
wsa883x->dapm_bias_off = true;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int wsa883x_soc_codec_resume(struct snd_soc_component *component)
|
||||||
|
{
|
||||||
|
struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component);
|
||||||
|
|
||||||
|
if (!wsa883x)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
wsa883x->dapm_bias_off = false;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static const struct snd_soc_component_driver soc_codec_dev_wsa883x_wsa = {
|
static const struct snd_soc_component_driver soc_codec_dev_wsa883x_wsa = {
|
||||||
.name = "",
|
.name = "",
|
||||||
.probe = wsa883x_codec_probe,
|
.probe = wsa883x_codec_probe,
|
||||||
@@ -1230,6 +1287,8 @@ static const struct snd_soc_component_driver soc_codec_dev_wsa883x_wsa = {
|
|||||||
.num_dapm_widgets = ARRAY_SIZE(wsa883x_dapm_widgets),
|
.num_dapm_widgets = ARRAY_SIZE(wsa883x_dapm_widgets),
|
||||||
.dapm_routes = wsa883x_audio_map,
|
.dapm_routes = wsa883x_audio_map,
|
||||||
.num_dapm_routes = ARRAY_SIZE(wsa883x_audio_map),
|
.num_dapm_routes = ARRAY_SIZE(wsa883x_audio_map),
|
||||||
|
.suspend = wsa883x_soc_codec_suspend,
|
||||||
|
.resume = wsa883x_soc_codec_resume,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int wsa883x_gpio_ctrl(struct wsa883x_priv *wsa883x, bool enable)
|
static int wsa883x_gpio_ctrl(struct wsa883x_priv *wsa883x, bool enable)
|
||||||
@@ -1454,12 +1513,18 @@ static int wsa883x_swr_probe(struct swr_device *pdev)
|
|||||||
wcd_request_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_SAF2WAR,
|
wcd_request_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_SAF2WAR,
|
||||||
"WSA SAF2WAR", wsa883x_saf2war_handle_irq, NULL);
|
"WSA SAF2WAR", wsa883x_saf2war_handle_irq, NULL);
|
||||||
|
|
||||||
|
wcd_disable_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_SAF2WAR);
|
||||||
|
|
||||||
wcd_request_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_WAR2SAF,
|
wcd_request_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_WAR2SAF,
|
||||||
"WSA WAR2SAF", wsa883x_war2saf_handle_irq, NULL);
|
"WSA WAR2SAF", wsa883x_war2saf_handle_irq, NULL);
|
||||||
|
|
||||||
|
wcd_disable_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_WAR2SAF);
|
||||||
|
|
||||||
wcd_request_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_DISABLE,
|
wcd_request_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_DISABLE,
|
||||||
"WSA OTP", wsa883x_otp_handle_irq, NULL);
|
"WSA OTP", wsa883x_otp_handle_irq, NULL);
|
||||||
|
|
||||||
|
wcd_disable_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_DISABLE);
|
||||||
|
|
||||||
wcd_request_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_OCP,
|
wcd_request_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_OCP,
|
||||||
"WSA OCP", wsa883x_ocp_handle_irq, NULL);
|
"WSA OCP", wsa883x_ocp_handle_irq, NULL);
|
||||||
|
|
||||||
@@ -1483,10 +1548,14 @@ static int wsa883x_swr_probe(struct swr_device *pdev)
|
|||||||
wcd_request_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_INTR_PIN,
|
wcd_request_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_INTR_PIN,
|
||||||
"WSA EXT INT", wsa883x_ext_int_handle_irq, NULL);
|
"WSA EXT INT", wsa883x_ext_int_handle_irq, NULL);
|
||||||
|
|
||||||
|
wcd_disable_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_INTR_PIN);
|
||||||
|
|
||||||
/* Under Voltage Lock out (UVLO) interrupt handle */
|
/* Under Voltage Lock out (UVLO) interrupt handle */
|
||||||
wcd_request_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_UVLO,
|
wcd_request_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_UVLO,
|
||||||
"WSA UVLO", wsa883x_uvlo_handle_irq, NULL);
|
"WSA UVLO", wsa883x_uvlo_handle_irq, NULL);
|
||||||
|
|
||||||
|
wcd_disable_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_UVLO);
|
||||||
|
|
||||||
wcd_request_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_PA_ON_ERR,
|
wcd_request_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_PA_ON_ERR,
|
||||||
"WSA PA ERR", wsa883x_pa_on_err_handle_irq, NULL);
|
"WSA PA ERR", wsa883x_pa_on_err_handle_irq, NULL);
|
||||||
|
|
||||||
@@ -1692,7 +1761,20 @@ static int wsa883x_swr_remove(struct swr_device *pdev)
|
|||||||
#ifdef CONFIG_PM_SLEEP
|
#ifdef CONFIG_PM_SLEEP
|
||||||
static int wsa883x_swr_suspend(struct device *dev)
|
static int wsa883x_swr_suspend(struct device *dev)
|
||||||
{
|
{
|
||||||
|
struct wsa883x_priv *wsa883x = swr_get_dev_data(to_swr_device(dev));
|
||||||
|
|
||||||
|
if (!wsa883x) {
|
||||||
|
dev_err(dev, "%s: wsa883x private data is NULL\n", __func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
dev_dbg(dev, "%s: system suspend\n", __func__);
|
dev_dbg(dev, "%s: system suspend\n", __func__);
|
||||||
|
if (wsa883x->dapm_bias_off) {
|
||||||
|
msm_cdc_set_supplies_lpm_mode(dev, wsa883x->supplies,
|
||||||
|
wsa883x->regulator,
|
||||||
|
wsa883x->num_supplies,
|
||||||
|
true);
|
||||||
|
set_bit(WSA_SUPPLIES_LPM_MODE, &wsa883x->status_mask);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1704,13 +1786,21 @@ static int wsa883x_swr_resume(struct device *dev)
|
|||||||
dev_err(dev, "%s: wsa883x private data is NULL\n", __func__);
|
dev_err(dev, "%s: wsa883x private data is NULL\n", __func__);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
if (test_bit(WSA_SUPPLIES_LPM_MODE, &wsa883x->status_mask)) {
|
||||||
|
msm_cdc_set_supplies_lpm_mode(dev, wsa883x->supplies,
|
||||||
|
wsa883x->regulator,
|
||||||
|
wsa883x->num_supplies,
|
||||||
|
false);
|
||||||
|
clear_bit(WSA_SUPPLIES_LPM_MODE, &wsa883x->status_mask);
|
||||||
|
}
|
||||||
dev_dbg(dev, "%s: system resume\n", __func__);
|
dev_dbg(dev, "%s: system resume\n", __func__);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_PM_SLEEP */
|
#endif /* CONFIG_PM_SLEEP */
|
||||||
|
|
||||||
static const struct dev_pm_ops wsa883x_swr_pm_ops = {
|
static const struct dev_pm_ops wsa883x_swr_pm_ops = {
|
||||||
SET_SYSTEM_SLEEP_PM_OPS(wsa883x_swr_suspend, wsa883x_swr_resume)
|
.suspend_late = wsa883x_swr_suspend,
|
||||||
|
.resume_early = wsa883x_swr_resume,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct swr_device_id wsa883x_swr_id[] = {
|
static const struct swr_device_id wsa883x_swr_id[] = {
|
||||||
|
@@ -47,9 +47,11 @@
|
|||||||
#define DEV_NAME_STR_LEN 32
|
#define DEV_NAME_STR_LEN 32
|
||||||
#define WCD_MBHC_HS_V_MAX 1600
|
#define WCD_MBHC_HS_V_MAX 1600
|
||||||
|
|
||||||
#define WSA8810_NAME_1 "wsa881x.20170211"
|
#define WSA8810_NAME_1 "wsa881x.1020170211"
|
||||||
#define WSA8810_NAME_2 "wsa881x.20170212"
|
#define WSA8810_NAME_2 "wsa881x.1020170212"
|
||||||
|
|
||||||
|
#define WSA8815_NAME_1 "wsa881x.1021170213"
|
||||||
|
#define WSA8815_NAME_2 "wsa881x.1021170214"
|
||||||
#define WCN_CDC_SLIM_RX_CH_MAX 2
|
#define WCN_CDC_SLIM_RX_CH_MAX 2
|
||||||
#define WCN_CDC_SLIM_TX_CH_MAX 2
|
#define WCN_CDC_SLIM_TX_CH_MAX 2
|
||||||
|
|
||||||
|
152
asoc/lahaina.c
152
asoc/lahaina.c
@@ -384,9 +384,6 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = {
|
|||||||
{
|
{
|
||||||
.name = LPASS_BE_RT_PROXY_PCM_TX,
|
.name = LPASS_BE_RT_PROXY_PCM_TX,
|
||||||
.stream_name = LPASS_BE_RT_PROXY_PCM_TX,
|
.stream_name = LPASS_BE_RT_PROXY_PCM_TX,
|
||||||
#if IS_ENABLED(CONFIG_AUDIO_QGKI)
|
|
||||||
.async_ops = ASYNC_DPCM_SND_SOC_PREPARE,
|
|
||||||
#endif /* CONFIG_AUDIO_QGKI */
|
|
||||||
.capture_only = 1,
|
.capture_only = 1,
|
||||||
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
|
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
|
||||||
SND_SOC_DPCM_TRIGGER_POST},
|
SND_SOC_DPCM_TRIGGER_POST},
|
||||||
@@ -398,9 +395,6 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = {
|
|||||||
{
|
{
|
||||||
.name = LPASS_BE_RT_PROXY_PCM_RX,
|
.name = LPASS_BE_RT_PROXY_PCM_RX,
|
||||||
.stream_name = LPASS_BE_RT_PROXY_PCM_RX,
|
.stream_name = LPASS_BE_RT_PROXY_PCM_RX,
|
||||||
#if IS_ENABLED(CONFIG_AUDIO_QGKI)
|
|
||||||
.async_ops = ASYNC_DPCM_SND_SOC_PREPARE,
|
|
||||||
#endif /* CONFIG_AUDIO_QGKI */
|
|
||||||
.playback_only = 1,
|
.playback_only = 1,
|
||||||
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
|
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
|
||||||
SND_SOC_DPCM_TRIGGER_POST},
|
SND_SOC_DPCM_TRIGGER_POST},
|
||||||
@@ -412,9 +406,6 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = {
|
|||||||
{
|
{
|
||||||
.name = LPASS_BE_USB_AUDIO_RX,
|
.name = LPASS_BE_USB_AUDIO_RX,
|
||||||
.stream_name = LPASS_BE_USB_AUDIO_RX,
|
.stream_name = LPASS_BE_USB_AUDIO_RX,
|
||||||
#if IS_ENABLED(CONFIG_AUDIO_QGKI)
|
|
||||||
.async_ops = ASYNC_DPCM_SND_SOC_PREPARE,
|
|
||||||
#endif /* CONFIG_AUDIO_QGKI */
|
|
||||||
.playback_only = 1,
|
.playback_only = 1,
|
||||||
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
|
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
|
||||||
SND_SOC_DPCM_TRIGGER_POST},
|
SND_SOC_DPCM_TRIGGER_POST},
|
||||||
@@ -426,9 +417,6 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = {
|
|||||||
{
|
{
|
||||||
.name = LPASS_BE_USB_AUDIO_TX,
|
.name = LPASS_BE_USB_AUDIO_TX,
|
||||||
.stream_name = LPASS_BE_USB_AUDIO_TX,
|
.stream_name = LPASS_BE_USB_AUDIO_TX,
|
||||||
#if IS_ENABLED(CONFIG_AUDIO_QGKI)
|
|
||||||
.async_ops = ASYNC_DPCM_SND_SOC_PREPARE,
|
|
||||||
#endif /* CONFIG_AUDIO_QGKI */
|
|
||||||
.capture_only = 1,
|
.capture_only = 1,
|
||||||
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
|
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
|
||||||
SND_SOC_DPCM_TRIGGER_POST},
|
SND_SOC_DPCM_TRIGGER_POST},
|
||||||
@@ -442,9 +430,6 @@ static struct snd_soc_dai_link msm_wcn_be_dai_links[] = {
|
|||||||
{
|
{
|
||||||
.name = LPASS_BE_SLIMBUS_7_RX,
|
.name = LPASS_BE_SLIMBUS_7_RX,
|
||||||
.stream_name = LPASS_BE_SLIMBUS_7_RX,
|
.stream_name = LPASS_BE_SLIMBUS_7_RX,
|
||||||
#if IS_ENABLED(CONFIG_AUDIO_QGKI)
|
|
||||||
.async_ops = ASYNC_DPCM_SND_SOC_PREPARE,
|
|
||||||
#endif /* CONFIG_AUDIO_QGKI */
|
|
||||||
.playback_only = 1,
|
.playback_only = 1,
|
||||||
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
|
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
|
||||||
SND_SOC_DPCM_TRIGGER_POST},
|
SND_SOC_DPCM_TRIGGER_POST},
|
||||||
@@ -458,9 +443,6 @@ static struct snd_soc_dai_link msm_wcn_be_dai_links[] = {
|
|||||||
{
|
{
|
||||||
.name = LPASS_BE_SLIMBUS_7_TX,
|
.name = LPASS_BE_SLIMBUS_7_TX,
|
||||||
.stream_name = LPASS_BE_SLIMBUS_7_TX,
|
.stream_name = LPASS_BE_SLIMBUS_7_TX,
|
||||||
#if IS_ENABLED(CONFIG_AUDIO_QGKI)
|
|
||||||
.async_ops = ASYNC_DPCM_SND_SOC_PREPARE,
|
|
||||||
#endif /* CONFIG_AUDIO_QGKI */
|
|
||||||
.capture_only = 1,
|
.capture_only = 1,
|
||||||
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
|
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
|
||||||
SND_SOC_DPCM_TRIGGER_POST},
|
SND_SOC_DPCM_TRIGGER_POST},
|
||||||
@@ -476,9 +458,6 @@ static struct snd_soc_dai_link ext_disp_be_dai_link[] = {
|
|||||||
{
|
{
|
||||||
.name = LPASS_BE_DISPLAY_PORT_RX,
|
.name = LPASS_BE_DISPLAY_PORT_RX,
|
||||||
.stream_name = LPASS_BE_DISPLAY_PORT_RX,
|
.stream_name = LPASS_BE_DISPLAY_PORT_RX,
|
||||||
#if IS_ENABLED(CONFIG_AUDIO_QGKI)
|
|
||||||
.async_ops = ASYNC_DPCM_SND_SOC_PREPARE,
|
|
||||||
#endif /* CONFIG_AUDIO_QGKI */
|
|
||||||
.playback_only = 1,
|
.playback_only = 1,
|
||||||
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
|
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
|
||||||
SND_SOC_DPCM_TRIGGER_POST},
|
SND_SOC_DPCM_TRIGGER_POST},
|
||||||
@@ -486,22 +465,6 @@ static struct snd_soc_dai_link ext_disp_be_dai_link[] = {
|
|||||||
.ignore_suspend = 1,
|
.ignore_suspend = 1,
|
||||||
SND_SOC_DAILINK_REG(display_port),
|
SND_SOC_DAILINK_REG(display_port),
|
||||||
},
|
},
|
||||||
#if 0
|
|
||||||
/* DISP PORT 1 BACK END DAI Link */
|
|
||||||
{
|
|
||||||
.name = LPASS_BE_DISPLAY_PORT1,
|
|
||||||
.stream_name = LPASS_BE_DISPLAY_PORT1,
|
|
||||||
#if IS_ENABLED(CONFIG_AUDIO_QGKI)
|
|
||||||
.async_ops = ASYNC_DPCM_SND_SOC_PREPARE,
|
|
||||||
#endif /* CONFIG_AUDIO_QGKI */
|
|
||||||
.playback_only = 1,
|
|
||||||
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
|
|
||||||
SND_SOC_DPCM_TRIGGER_POST},
|
|
||||||
.ignore_pmdown_time = 1,
|
|
||||||
.ignore_suspend = 1,
|
|
||||||
SND_SOC_DAILINK_REG(display_port1),
|
|
||||||
},
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -510,9 +473,6 @@ static struct snd_soc_dai_link msm_wsa_cdc_dma_be_dai_links[] = {
|
|||||||
{
|
{
|
||||||
.name = LPASS_BE_WSA_CDC_DMA_RX_0,
|
.name = LPASS_BE_WSA_CDC_DMA_RX_0,
|
||||||
.stream_name = LPASS_BE_WSA_CDC_DMA_RX_0,
|
.stream_name = LPASS_BE_WSA_CDC_DMA_RX_0,
|
||||||
#if IS_ENABLED(CONFIG_AUDIO_QGKI)
|
|
||||||
.async_ops = ASYNC_DPCM_SND_SOC_PREPARE,
|
|
||||||
#endif /* CONFIG_AUDIO_QGKI */
|
|
||||||
.playback_only = 1,
|
.playback_only = 1,
|
||||||
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
|
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
|
||||||
SND_SOC_DPCM_TRIGGER_POST},
|
SND_SOC_DPCM_TRIGGER_POST},
|
||||||
@@ -525,9 +485,6 @@ static struct snd_soc_dai_link msm_wsa_cdc_dma_be_dai_links[] = {
|
|||||||
{
|
{
|
||||||
.name = LPASS_BE_WSA_CDC_DMA_RX_1,
|
.name = LPASS_BE_WSA_CDC_DMA_RX_1,
|
||||||
.stream_name = LPASS_BE_WSA_CDC_DMA_RX_1,
|
.stream_name = LPASS_BE_WSA_CDC_DMA_RX_1,
|
||||||
#if IS_ENABLED(CONFIG_AUDIO_QGKI)
|
|
||||||
.async_ops = ASYNC_DPCM_SND_SOC_PREPARE,
|
|
||||||
#endif /* CONFIG_AUDIO_QGKI */
|
|
||||||
.playback_only = 1,
|
.playback_only = 1,
|
||||||
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
|
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
|
||||||
SND_SOC_DPCM_TRIGGER_POST},
|
SND_SOC_DPCM_TRIGGER_POST},
|
||||||
@@ -539,9 +496,6 @@ static struct snd_soc_dai_link msm_wsa_cdc_dma_be_dai_links[] = {
|
|||||||
{
|
{
|
||||||
.name = LPASS_BE_WSA_CDC_DMA_TX_1,
|
.name = LPASS_BE_WSA_CDC_DMA_TX_1,
|
||||||
.stream_name = LPASS_BE_WSA_CDC_DMA_TX_1,
|
.stream_name = LPASS_BE_WSA_CDC_DMA_TX_1,
|
||||||
#if IS_ENABLED(CONFIG_AUDIO_QGKI)
|
|
||||||
.async_ops = ASYNC_DPCM_SND_SOC_PREPARE,
|
|
||||||
#endif /* CONFIG_AUDIO_QGKI */
|
|
||||||
.capture_only = 1,
|
.capture_only = 1,
|
||||||
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
|
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
|
||||||
SND_SOC_DPCM_TRIGGER_POST},
|
SND_SOC_DPCM_TRIGGER_POST},
|
||||||
@@ -556,9 +510,6 @@ static struct snd_soc_dai_link msm_rx_tx_cdc_dma_be_dai_links[] = {
|
|||||||
{
|
{
|
||||||
.name = LPASS_BE_RX_CDC_DMA_RX_0,
|
.name = LPASS_BE_RX_CDC_DMA_RX_0,
|
||||||
.stream_name = LPASS_BE_RX_CDC_DMA_RX_0,
|
.stream_name = LPASS_BE_RX_CDC_DMA_RX_0,
|
||||||
#if IS_ENABLED(CONFIG_AUDIO_QGKI)
|
|
||||||
.async_ops = ASYNC_DPCM_SND_SOC_PREPARE,
|
|
||||||
#endif /* CONFIG_AUDIO_QGKI */
|
|
||||||
.playback_only = 1,
|
.playback_only = 1,
|
||||||
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
|
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
|
||||||
SND_SOC_DPCM_TRIGGER_POST},
|
SND_SOC_DPCM_TRIGGER_POST},
|
||||||
@@ -571,9 +522,6 @@ static struct snd_soc_dai_link msm_rx_tx_cdc_dma_be_dai_links[] = {
|
|||||||
{
|
{
|
||||||
.name = LPASS_BE_RX_CDC_DMA_RX_1,
|
.name = LPASS_BE_RX_CDC_DMA_RX_1,
|
||||||
.stream_name = LPASS_BE_RX_CDC_DMA_RX_1,
|
.stream_name = LPASS_BE_RX_CDC_DMA_RX_1,
|
||||||
#if IS_ENABLED(CONFIG_AUDIO_QGKI)
|
|
||||||
.async_ops = ASYNC_DPCM_SND_SOC_PREPARE,
|
|
||||||
#endif /* CONFIG_AUDIO_QGKI */
|
|
||||||
.playback_only = 1,
|
.playback_only = 1,
|
||||||
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
|
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
|
||||||
SND_SOC_DPCM_TRIGGER_POST},
|
SND_SOC_DPCM_TRIGGER_POST},
|
||||||
@@ -581,13 +529,11 @@ static struct snd_soc_dai_link msm_rx_tx_cdc_dma_be_dai_links[] = {
|
|||||||
.ignore_suspend = 1,
|
.ignore_suspend = 1,
|
||||||
.ops = &msm_common_be_ops,
|
.ops = &msm_common_be_ops,
|
||||||
SND_SOC_DAILINK_REG(rx_dma_rx1),
|
SND_SOC_DAILINK_REG(rx_dma_rx1),
|
||||||
|
.init = &msm_int_audrx_init,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = LPASS_BE_RX_CDC_DMA_RX_2,
|
.name = LPASS_BE_RX_CDC_DMA_RX_2,
|
||||||
.stream_name = LPASS_BE_RX_CDC_DMA_RX_2,
|
.stream_name = LPASS_BE_RX_CDC_DMA_RX_2,
|
||||||
#if IS_ENABLED(CONFIG_AUDIO_QGKI)
|
|
||||||
.async_ops = ASYNC_DPCM_SND_SOC_PREPARE,
|
|
||||||
#endif /* CONFIG_AUDIO_QGKI */
|
|
||||||
.playback_only = 1,
|
.playback_only = 1,
|
||||||
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
|
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
|
||||||
SND_SOC_DPCM_TRIGGER_POST},
|
SND_SOC_DPCM_TRIGGER_POST},
|
||||||
@@ -599,9 +545,6 @@ static struct snd_soc_dai_link msm_rx_tx_cdc_dma_be_dai_links[] = {
|
|||||||
{
|
{
|
||||||
.name = LPASS_BE_RX_CDC_DMA_RX_3,
|
.name = LPASS_BE_RX_CDC_DMA_RX_3,
|
||||||
.stream_name = LPASS_BE_RX_CDC_DMA_RX_3,
|
.stream_name = LPASS_BE_RX_CDC_DMA_RX_3,
|
||||||
#if IS_ENABLED(CONFIG_AUDIO_QGKI)
|
|
||||||
.async_ops = ASYNC_DPCM_SND_SOC_PREPARE,
|
|
||||||
#endif /* CONFIG_AUDIO_QGKI */
|
|
||||||
.playback_only = 1,
|
.playback_only = 1,
|
||||||
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
|
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
|
||||||
SND_SOC_DPCM_TRIGGER_POST},
|
SND_SOC_DPCM_TRIGGER_POST},
|
||||||
@@ -610,12 +553,20 @@ static struct snd_soc_dai_link msm_rx_tx_cdc_dma_be_dai_links[] = {
|
|||||||
.ops = &msm_common_be_ops,
|
.ops = &msm_common_be_ops,
|
||||||
SND_SOC_DAILINK_REG(rx_dma_rx3),
|
SND_SOC_DAILINK_REG(rx_dma_rx3),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.name = LPASS_BE_RX_CDC_DMA_RX_5,
|
||||||
|
.stream_name = LPASS_BE_RX_CDC_DMA_RX_5,
|
||||||
|
.playback_only = 1,
|
||||||
|
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
|
||||||
|
SND_SOC_DPCM_TRIGGER_POST},
|
||||||
|
.ignore_pmdown_time = 1,
|
||||||
|
.ignore_suspend = 1,
|
||||||
|
.ops = &msm_common_be_ops,
|
||||||
|
SND_SOC_DAILINK_REG(rx_dma_rx5),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
.name = LPASS_BE_RX_CDC_DMA_RX_6,
|
.name = LPASS_BE_RX_CDC_DMA_RX_6,
|
||||||
.stream_name = LPASS_BE_RX_CDC_DMA_RX_6,
|
.stream_name = LPASS_BE_RX_CDC_DMA_RX_6,
|
||||||
#if IS_ENABLED(CONFIG_AUDIO_QGKI)
|
|
||||||
.async_ops = ASYNC_DPCM_SND_SOC_PREPARE,
|
|
||||||
#endif /* CONFIG_AUDIO_QGKI */
|
|
||||||
.playback_only = 1,
|
.playback_only = 1,
|
||||||
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
|
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
|
||||||
SND_SOC_DPCM_TRIGGER_POST},
|
SND_SOC_DPCM_TRIGGER_POST},
|
||||||
@@ -628,9 +579,6 @@ static struct snd_soc_dai_link msm_rx_tx_cdc_dma_be_dai_links[] = {
|
|||||||
{
|
{
|
||||||
.name = LPASS_BE_TX_CDC_DMA_TX_3,
|
.name = LPASS_BE_TX_CDC_DMA_TX_3,
|
||||||
.stream_name = LPASS_BE_TX_CDC_DMA_TX_3,
|
.stream_name = LPASS_BE_TX_CDC_DMA_TX_3,
|
||||||
#if IS_ENABLED(CONFIG_AUDIO_QGKI)
|
|
||||||
.async_ops = ASYNC_DPCM_SND_SOC_PREPARE,
|
|
||||||
#endif /* CONFIG_AUDIO_QGKI */
|
|
||||||
.capture_only = 1,
|
.capture_only = 1,
|
||||||
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
|
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
|
||||||
SND_SOC_DPCM_TRIGGER_POST},
|
SND_SOC_DPCM_TRIGGER_POST},
|
||||||
@@ -641,9 +589,6 @@ static struct snd_soc_dai_link msm_rx_tx_cdc_dma_be_dai_links[] = {
|
|||||||
{
|
{
|
||||||
.name = LPASS_BE_TX_CDC_DMA_TX_4,
|
.name = LPASS_BE_TX_CDC_DMA_TX_4,
|
||||||
.stream_name = LPASS_BE_TX_CDC_DMA_TX_4,
|
.stream_name = LPASS_BE_TX_CDC_DMA_TX_4,
|
||||||
#if IS_ENABLED(CONFIG_AUDIO_QGKI)
|
|
||||||
.async_ops = ASYNC_DPCM_SND_SOC_PREPARE,
|
|
||||||
#endif /* CONFIG_AUDIO_QGKI */
|
|
||||||
.capture_only = 1,
|
.capture_only = 1,
|
||||||
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
|
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
|
||||||
SND_SOC_DPCM_TRIGGER_POST},
|
SND_SOC_DPCM_TRIGGER_POST},
|
||||||
@@ -657,9 +602,6 @@ static struct snd_soc_dai_link msm_va_cdc_dma_be_dai_links[] = {
|
|||||||
{
|
{
|
||||||
.name = LPASS_BE_VA_CDC_DMA_TX_0,
|
.name = LPASS_BE_VA_CDC_DMA_TX_0,
|
||||||
.stream_name = LPASS_BE_VA_CDC_DMA_TX_0,
|
.stream_name = LPASS_BE_VA_CDC_DMA_TX_0,
|
||||||
#if IS_ENABLED(CONFIG_AUDIO_QGKI)
|
|
||||||
.async_ops = ASYNC_DPCM_SND_SOC_PREPARE,
|
|
||||||
#endif /* CONFIG_AUDIO_QGKI */
|
|
||||||
.capture_only = 1,
|
.capture_only = 1,
|
||||||
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
|
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
|
||||||
SND_SOC_DPCM_TRIGGER_POST},
|
SND_SOC_DPCM_TRIGGER_POST},
|
||||||
@@ -670,9 +612,6 @@ static struct snd_soc_dai_link msm_va_cdc_dma_be_dai_links[] = {
|
|||||||
{
|
{
|
||||||
.name = LPASS_BE_VA_CDC_DMA_TX_1,
|
.name = LPASS_BE_VA_CDC_DMA_TX_1,
|
||||||
.stream_name = LPASS_BE_VA_CDC_DMA_TX_1,
|
.stream_name = LPASS_BE_VA_CDC_DMA_TX_1,
|
||||||
#if IS_ENABLED(CONFIG_AUDIO_QGKI)
|
|
||||||
.async_ops = ASYNC_DPCM_SND_SOC_PREPARE,
|
|
||||||
#endif /* CONFIG_AUDIO_QGKI */
|
|
||||||
.capture_only = 1,
|
.capture_only = 1,
|
||||||
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
|
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
|
||||||
SND_SOC_DPCM_TRIGGER_POST},
|
SND_SOC_DPCM_TRIGGER_POST},
|
||||||
@@ -683,9 +622,6 @@ static struct snd_soc_dai_link msm_va_cdc_dma_be_dai_links[] = {
|
|||||||
{
|
{
|
||||||
.name = LPASS_BE_VA_CDC_DMA_TX_2,
|
.name = LPASS_BE_VA_CDC_DMA_TX_2,
|
||||||
.stream_name = LPASS_BE_VA_CDC_DMA_TX_2,
|
.stream_name = LPASS_BE_VA_CDC_DMA_TX_2,
|
||||||
#if IS_ENABLED(CONFIG_AUDIO_QGKI)
|
|
||||||
.async_ops = ASYNC_DPCM_SND_SOC_PREPARE,
|
|
||||||
#endif /* CONFIG_AUDIO_QGKI */
|
|
||||||
.capture_only = 1,
|
.capture_only = 1,
|
||||||
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
|
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
|
||||||
SND_SOC_DPCM_TRIGGER_POST},
|
SND_SOC_DPCM_TRIGGER_POST},
|
||||||
@@ -855,6 +791,45 @@ static const struct of_device_id lahaina_asoc_machine_of_match[] = {
|
|||||||
{},
|
{},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int msm_snd_card_late_probe(struct snd_soc_card *card)
|
||||||
|
{
|
||||||
|
struct snd_soc_component *component = NULL;
|
||||||
|
const char *be_dl_name = LPASS_BE_RX_CDC_DMA_RX_0;
|
||||||
|
struct snd_soc_pcm_runtime *rtd;
|
||||||
|
int ret = 0;
|
||||||
|
void *mbhc_calibration;
|
||||||
|
|
||||||
|
rtd = snd_soc_get_pcm_runtime(card, be_dl_name);
|
||||||
|
if (!rtd) {
|
||||||
|
dev_err(card->dev,
|
||||||
|
"%s: snd_soc_get_pcm_runtime for %s failed!\n",
|
||||||
|
__func__, be_dl_name);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
component = snd_soc_rtdcom_lookup(rtd, WCD938X_DRV_NAME);
|
||||||
|
if (!component) {
|
||||||
|
pr_err("%s component is NULL\n", __func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
mbhc_calibration = def_wcd_mbhc_cal();
|
||||||
|
if (!mbhc_calibration)
|
||||||
|
return -ENOMEM;
|
||||||
|
wcd_mbhc_cfg.calibration = mbhc_calibration;
|
||||||
|
ret = wcd938x_mbhc_hs_detect(component, &wcd_mbhc_cfg);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(component->dev, "%s: mbhc hs detect failed, err:%d\n",
|
||||||
|
__func__, ret);
|
||||||
|
goto err_hs_detect;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err_hs_detect:
|
||||||
|
kfree(mbhc_calibration);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev)
|
static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev)
|
||||||
{
|
{
|
||||||
struct snd_soc_card *card = NULL;
|
struct snd_soc_card *card = NULL;
|
||||||
@@ -934,6 +909,7 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev)
|
|||||||
if (card) {
|
if (card) {
|
||||||
card->dai_link = dailink;
|
card->dai_link = dailink;
|
||||||
card->num_links = total_links;
|
card->num_links = total_links;
|
||||||
|
card->late_probe = msm_snd_card_late_probe;
|
||||||
}
|
}
|
||||||
|
|
||||||
return card;
|
return card;
|
||||||
@@ -958,6 +934,10 @@ static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd)
|
|||||||
snd_soc_card_get_drvdata(rtd->card);
|
snd_soc_card_get_drvdata(rtd->card);
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
if (codec_reg_done) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (pdata->wsa_max_devs > 0) {
|
if (pdata->wsa_max_devs > 0) {
|
||||||
component = snd_soc_rtdcom_lookup(rtd, "wsa-codec.1");
|
component = snd_soc_rtdcom_lookup(rtd, "wsa-codec.1");
|
||||||
if (!component) {
|
if (!component) {
|
||||||
@@ -1064,8 +1044,6 @@ static int msm_aux_codec_init(struct snd_soc_pcm_runtime *rtd)
|
|||||||
{
|
{
|
||||||
struct snd_soc_component *component = NULL;
|
struct snd_soc_component *component = NULL;
|
||||||
struct snd_soc_dapm_context *dapm = NULL;
|
struct snd_soc_dapm_context *dapm = NULL;
|
||||||
int ret = 0;
|
|
||||||
void *mbhc_calibration;
|
|
||||||
struct snd_info_entry *entry;
|
struct snd_info_entry *entry;
|
||||||
struct snd_card *card = NULL;
|
struct snd_card *card = NULL;
|
||||||
struct msm_asoc_mach_data *pdata;
|
struct msm_asoc_mach_data *pdata;
|
||||||
@@ -1095,8 +1073,7 @@ static int msm_aux_codec_init(struct snd_soc_pcm_runtime *rtd)
|
|||||||
if (!entry) {
|
if (!entry) {
|
||||||
dev_dbg(component->dev, "%s: Cannot create codecs module entry\n",
|
dev_dbg(component->dev, "%s: Cannot create codecs module entry\n",
|
||||||
__func__);
|
__func__);
|
||||||
ret = 0;
|
return 0;
|
||||||
goto mbhc_cfg_cal;
|
|
||||||
}
|
}
|
||||||
pdata->codec_root = entry;
|
pdata->codec_root = entry;
|
||||||
}
|
}
|
||||||
@@ -1121,23 +1098,8 @@ static int msm_aux_codec_init(struct snd_soc_pcm_runtime *rtd)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mbhc_cfg_cal:
|
|
||||||
mbhc_calibration = def_wcd_mbhc_cal();
|
|
||||||
if (!mbhc_calibration)
|
|
||||||
return -ENOMEM;
|
|
||||||
wcd_mbhc_cfg.calibration = mbhc_calibration;
|
|
||||||
ret = wcd938x_mbhc_hs_detect(component, &wcd_mbhc_cfg);
|
|
||||||
if (ret) {
|
|
||||||
dev_err(component->dev, "%s: mbhc hs detect failed, err:%d\n",
|
|
||||||
__func__, ret);
|
|
||||||
goto err_hs_detect;
|
|
||||||
}
|
|
||||||
msm_common_dai_link_init(rtd);
|
msm_common_dai_link_init(rtd);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_hs_detect:
|
|
||||||
kfree(mbhc_calibration);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int lahaina_ssr_enable(struct device *dev, void *data)
|
static int lahaina_ssr_enable(struct device *dev, void *data)
|
||||||
|
4
asoc/msm-compress-q6-v2.h
Normal file
4
asoc/msm-compress-q6-v2.h
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
/* Copyright (c) 2020 The Linux Foundation. All rights reserved.
|
||||||
|
*/
|
||||||
|
int msm_compr_new(struct snd_soc_pcm_runtime *rtd, int num);
|
@@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
#include <sound/soc.h>
|
#include <sound/soc.h>
|
||||||
|
|
||||||
|
|
||||||
SND_SOC_DAILINK_DEFS(usb_audio_rx,
|
SND_SOC_DAILINK_DEFS(usb_audio_rx,
|
||||||
DAILINK_COMP_ARRAY(COMP_CPU("snd-soc-dummy-dai")),
|
DAILINK_COMP_ARRAY(COMP_CPU("snd-soc-dummy-dai")),
|
||||||
DAILINK_COMP_ARRAY(COMP_DUMMY()),
|
DAILINK_COMP_ARRAY(COMP_DUMMY()),
|
||||||
@@ -16,7 +15,6 @@ SND_SOC_DAILINK_DEFS(usb_audio_tx,
|
|||||||
DAILINK_COMP_ARRAY(COMP_DUMMY()),
|
DAILINK_COMP_ARRAY(COMP_DUMMY()),
|
||||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("snd-soc-dummy")));
|
DAILINK_COMP_ARRAY(COMP_PLATFORM("snd-soc-dummy")));
|
||||||
|
|
||||||
|
|
||||||
SND_SOC_DAILINK_DEFS(slimbus_7_rx,
|
SND_SOC_DAILINK_DEFS(slimbus_7_rx,
|
||||||
DAILINK_COMP_ARRAY(COMP_CPU("snd-soc-dummy-dai")),
|
DAILINK_COMP_ARRAY(COMP_CPU("snd-soc-dummy-dai")),
|
||||||
DAILINK_COMP_ARRAY(COMP_CODEC("btfmslim_slave",
|
DAILINK_COMP_ARRAY(COMP_CODEC("btfmslim_slave",
|
||||||
@@ -96,6 +94,12 @@ SND_SOC_DAILINK_DEFS(rx_dma_rx3,
|
|||||||
COMP_CODEC("wcd938x_codec", "wcd938x_cdc")),
|
COMP_CODEC("wcd938x_codec", "wcd938x_cdc")),
|
||||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("snd-soc-dummy")));
|
DAILINK_COMP_ARRAY(COMP_PLATFORM("snd-soc-dummy")));
|
||||||
|
|
||||||
|
SND_SOC_DAILINK_DEFS(rx_dma_rx5,
|
||||||
|
DAILINK_COMP_ARRAY(COMP_CPU("snd-soc-dummy-dai")),
|
||||||
|
DAILINK_COMP_ARRAY(COMP_CODEC("bolero_codec", "rx_macro_rx5"),
|
||||||
|
COMP_CODEC("wcd938x_codec", "wcd938x_cdc")),
|
||||||
|
DAILINK_COMP_ARRAY(COMP_PLATFORM("snd-soc-dummy")));
|
||||||
|
|
||||||
SND_SOC_DAILINK_DEFS(rx_dma_rx6,
|
SND_SOC_DAILINK_DEFS(rx_dma_rx6,
|
||||||
DAILINK_COMP_ARRAY(COMP_CPU("snd-soc-dummy-dai")),
|
DAILINK_COMP_ARRAY(COMP_CPU("snd-soc-dummy-dai")),
|
||||||
DAILINK_COMP_ARRAY(COMP_CODEC("bolero_codec", "rx_macro_rx6"),
|
DAILINK_COMP_ARRAY(COMP_CODEC("bolero_codec", "rx_macro_rx6"),
|
||||||
|
326
asoc/qcs405.c
326
asoc/qcs405.c
@@ -1,5 +1,5 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
|
/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
#include <linux/clk.h>
|
#include <linux/clk.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
@@ -148,6 +148,11 @@ enum {
|
|||||||
SPDIF_TX_MAX,
|
SPDIF_TX_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
HDMI_RX_IDX = 0,
|
||||||
|
EXT_HDMI_RX_IDX_MAX,
|
||||||
|
};
|
||||||
|
|
||||||
struct mi2s_conf {
|
struct mi2s_conf {
|
||||||
struct mutex lock;
|
struct mutex lock;
|
||||||
u32 ref_cnt;
|
u32 ref_cnt;
|
||||||
@@ -344,7 +349,9 @@ static struct dev_config tdm_tx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = {
|
|||||||
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */
|
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
static struct dev_config ext_hdmi_rx_cfg[] = {
|
||||||
|
[HDMI_RX_IDX] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
|
||||||
|
};
|
||||||
|
|
||||||
/* Default configuration of slimbus channels */
|
/* Default configuration of slimbus channels */
|
||||||
static struct dev_config slim_rx_cfg[] = {
|
static struct dev_config slim_rx_cfg[] = {
|
||||||
@@ -488,6 +495,12 @@ static char const *usb_sample_rate_text[] = {"KHZ_8", "KHZ_11P025",
|
|||||||
"KHZ_32", "KHZ_44P1", "KHZ_48",
|
"KHZ_32", "KHZ_44P1", "KHZ_48",
|
||||||
"KHZ_88P2", "KHZ_96", "KHZ_176P4",
|
"KHZ_88P2", "KHZ_96", "KHZ_176P4",
|
||||||
"KHZ_192", "KHZ_352P8", "KHZ_384"};
|
"KHZ_192", "KHZ_352P8", "KHZ_384"};
|
||||||
|
static char const *ext_hdmi_sample_rate_text[] = {"KHZ_48", "KHZ_96",
|
||||||
|
"KHZ_192", "KHZ_32", "KHZ_44P1",
|
||||||
|
"KHZ_88P2", "KHZ_176P4"};
|
||||||
|
static char const *ext_hdmi_bit_format_text[] = {"S16_LE", "S24_LE",
|
||||||
|
"S24_3LE"};
|
||||||
|
|
||||||
static char const *tdm_ch_text[] = {"One", "Two", "Three", "Four",
|
static char const *tdm_ch_text[] = {"One", "Two", "Three", "Four",
|
||||||
"Five", "Six", "Seven", "Eight"};
|
"Five", "Six", "Seven", "Eight"};
|
||||||
static char const *tdm_bit_format_text[] = {"S16_LE", "S24_LE", "S32_LE"};
|
static char const *tdm_bit_format_text[] = {"S16_LE", "S24_LE", "S32_LE"};
|
||||||
@@ -539,6 +552,7 @@ static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_chs, slim_rx_ch_text);
|
|||||||
static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_chs, usb_ch_text);
|
static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_chs, usb_ch_text);
|
||||||
static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_chs, usb_ch_text);
|
static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_chs, usb_ch_text);
|
||||||
static SOC_ENUM_SINGLE_EXT_DECL(vi_feed_tx_chs, vi_feed_ch_text);
|
static SOC_ENUM_SINGLE_EXT_DECL(vi_feed_tx_chs, vi_feed_ch_text);
|
||||||
|
static SOC_ENUM_SINGLE_EXT_DECL(ext_hdmi_rx_chs, ch_text);
|
||||||
static SOC_ENUM_SINGLE_EXT_DECL(proxy_rx_chs, ch_text);
|
static SOC_ENUM_SINGLE_EXT_DECL(proxy_rx_chs, ch_text);
|
||||||
static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_format, bit_format_text);
|
static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_format, bit_format_text);
|
||||||
static SOC_ENUM_SINGLE_EXT_DECL(slim_5_rx_format, bit_format_text);
|
static SOC_ENUM_SINGLE_EXT_DECL(slim_5_rx_format, bit_format_text);
|
||||||
@@ -546,6 +560,7 @@ static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_format, bit_format_text);
|
|||||||
static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_format, bit_format_text);
|
static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_format, bit_format_text);
|
||||||
static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_format, bit_format_text);
|
static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_format, bit_format_text);
|
||||||
static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_format, bit_format_text);
|
static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_format, bit_format_text);
|
||||||
|
static SOC_ENUM_SINGLE_EXT_DECL(ext_hdmi_rx_format, ext_hdmi_bit_format_text);
|
||||||
static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_sample_rate, slim_sample_rate_text);
|
static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_sample_rate, slim_sample_rate_text);
|
||||||
static SOC_ENUM_SINGLE_EXT_DECL(slim_2_rx_sample_rate, slim_sample_rate_text);
|
static SOC_ENUM_SINGLE_EXT_DECL(slim_2_rx_sample_rate, slim_sample_rate_text);
|
||||||
static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_sample_rate, slim_sample_rate_text);
|
static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_sample_rate, slim_sample_rate_text);
|
||||||
@@ -553,6 +568,8 @@ static SOC_ENUM_SINGLE_EXT_DECL(slim_5_rx_sample_rate, slim_sample_rate_text);
|
|||||||
static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_sample_rate, slim_sample_rate_text);
|
static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_sample_rate, slim_sample_rate_text);
|
||||||
static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate, bt_sample_rate_text);
|
static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate, bt_sample_rate_text);
|
||||||
static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate_sink, bt_sample_rate_text);
|
static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate_sink, bt_sample_rate_text);
|
||||||
|
static SOC_ENUM_SINGLE_EXT_DECL(ext_hdmi_rx_sample_rate,
|
||||||
|
ext_hdmi_sample_rate_text);
|
||||||
static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_sample_rate, usb_sample_rate_text);
|
static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_sample_rate, usb_sample_rate_text);
|
||||||
static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_sample_rate, usb_sample_rate_text);
|
static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_sample_rate, usb_sample_rate_text);
|
||||||
static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_chs, tdm_ch_text);
|
static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_chs, tdm_ch_text);
|
||||||
@@ -2110,6 +2127,191 @@ static int usb_audio_tx_format_put(struct snd_kcontrol *kcontrol,
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ext_hdmi_get_port_idx(struct snd_kcontrol *kcontrol)
|
||||||
|
{
|
||||||
|
int idx;
|
||||||
|
|
||||||
|
if (strnstr(kcontrol->id.name, "HDMI_RX",
|
||||||
|
sizeof("HDMI_RX"))) {
|
||||||
|
idx = HDMI_RX_IDX;
|
||||||
|
} else {
|
||||||
|
pr_err("%s: unsupported BE: %s",
|
||||||
|
__func__, kcontrol->id.name);
|
||||||
|
idx = -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ext_hdmi_rx_format_get(struct snd_kcontrol *kcontrol,
|
||||||
|
struct snd_ctl_elem_value *ucontrol)
|
||||||
|
{
|
||||||
|
int idx = ext_hdmi_get_port_idx(kcontrol);
|
||||||
|
|
||||||
|
if (idx < 0)
|
||||||
|
return idx;
|
||||||
|
|
||||||
|
switch (ext_hdmi_rx_cfg[idx].bit_format) {
|
||||||
|
case SNDRV_PCM_FORMAT_S24_LE:
|
||||||
|
ucontrol->value.integer.value[0] = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SNDRV_PCM_FORMAT_S16_LE:
|
||||||
|
default:
|
||||||
|
ucontrol->value.integer.value[0] = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
pr_debug("%s: ext_hdmi_rx[%d].format = %d, ucontrol value = %ld\n",
|
||||||
|
__func__, idx, ext_hdmi_rx_cfg[idx].bit_format,
|
||||||
|
ucontrol->value.integer.value[0]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ext_hdmi_rx_format_put(struct snd_kcontrol *kcontrol,
|
||||||
|
struct snd_ctl_elem_value *ucontrol)
|
||||||
|
{
|
||||||
|
int idx = ext_hdmi_get_port_idx(kcontrol);
|
||||||
|
|
||||||
|
if (idx < 0)
|
||||||
|
return idx;
|
||||||
|
|
||||||
|
switch (ucontrol->value.integer.value[0]) {
|
||||||
|
case 1:
|
||||||
|
ext_hdmi_rx_cfg[idx].bit_format = SNDRV_PCM_FORMAT_S24_LE;
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
default:
|
||||||
|
ext_hdmi_rx_cfg[idx].bit_format = SNDRV_PCM_FORMAT_S16_LE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pr_debug("%s: ext_hdmi_rx[%d].format = %d, ucontrol value = %ld\n",
|
||||||
|
__func__, idx, ext_hdmi_rx_cfg[idx].bit_format,
|
||||||
|
ucontrol->value.integer.value[0]);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ext_hdmi_rx_ch_get(struct snd_kcontrol *kcontrol,
|
||||||
|
struct snd_ctl_elem_value *ucontrol)
|
||||||
|
{
|
||||||
|
int idx = ext_hdmi_get_port_idx(kcontrol);
|
||||||
|
|
||||||
|
if (idx < 0)
|
||||||
|
return idx;
|
||||||
|
|
||||||
|
ucontrol->value.integer.value[0] =
|
||||||
|
ext_hdmi_rx_cfg[idx].channels - 2;
|
||||||
|
|
||||||
|
pr_debug("%s: ext_hdmi_rx[%d].ch = %d\n", __func__,
|
||||||
|
idx, ext_hdmi_rx_cfg[idx].channels);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ext_hdmi_rx_ch_put(struct snd_kcontrol *kcontrol,
|
||||||
|
struct snd_ctl_elem_value *ucontrol)
|
||||||
|
{
|
||||||
|
int idx = ext_hdmi_get_port_idx(kcontrol);
|
||||||
|
|
||||||
|
if (idx < 0)
|
||||||
|
return idx;
|
||||||
|
|
||||||
|
ext_hdmi_rx_cfg[idx].channels =
|
||||||
|
ucontrol->value.integer.value[0] + 2;
|
||||||
|
|
||||||
|
pr_debug("%s: ext_hdmi_rx[%d].ch = %d\n", __func__,
|
||||||
|
idx, ext_hdmi_rx_cfg[idx].channels);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ext_hdmi_rx_sample_rate_get(struct snd_kcontrol *kcontrol,
|
||||||
|
struct snd_ctl_elem_value *ucontrol)
|
||||||
|
{
|
||||||
|
int sample_rate_val;
|
||||||
|
int idx = ext_hdmi_get_port_idx(kcontrol);
|
||||||
|
|
||||||
|
if (idx < 0)
|
||||||
|
return idx;
|
||||||
|
|
||||||
|
switch (ext_hdmi_rx_cfg[idx].sample_rate) {
|
||||||
|
case SAMPLING_RATE_176P4KHZ:
|
||||||
|
sample_rate_val = 6;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SAMPLING_RATE_88P2KHZ:
|
||||||
|
sample_rate_val = 5;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SAMPLING_RATE_44P1KHZ:
|
||||||
|
sample_rate_val = 4;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SAMPLING_RATE_32KHZ:
|
||||||
|
sample_rate_val = 3;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SAMPLING_RATE_192KHZ:
|
||||||
|
sample_rate_val = 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SAMPLING_RATE_96KHZ:
|
||||||
|
sample_rate_val = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SAMPLING_RATE_48KHZ:
|
||||||
|
default:
|
||||||
|
sample_rate_val = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ucontrol->value.integer.value[0] = sample_rate_val;
|
||||||
|
pr_debug("%s: ext_hdmi_rx[%d].sample_rate = %d\n", __func__,
|
||||||
|
idx, ext_hdmi_rx_cfg[idx].sample_rate);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int ext_hdmi_rx_sample_rate_put(struct snd_kcontrol *kcontrol,
|
||||||
|
struct snd_ctl_elem_value *ucontrol)
|
||||||
|
{
|
||||||
|
int idx = ext_hdmi_get_port_idx(kcontrol);
|
||||||
|
|
||||||
|
if (idx < 0)
|
||||||
|
return idx;
|
||||||
|
|
||||||
|
switch (ucontrol->value.integer.value[0]) {
|
||||||
|
case 6:
|
||||||
|
ext_hdmi_rx_cfg[idx].sample_rate = SAMPLING_RATE_176P4KHZ;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
ext_hdmi_rx_cfg[idx].sample_rate = SAMPLING_RATE_88P2KHZ;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
ext_hdmi_rx_cfg[idx].sample_rate = SAMPLING_RATE_44P1KHZ;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
ext_hdmi_rx_cfg[idx].sample_rate = SAMPLING_RATE_32KHZ;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
ext_hdmi_rx_cfg[idx].sample_rate = SAMPLING_RATE_192KHZ;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
ext_hdmi_rx_cfg[idx].sample_rate = SAMPLING_RATE_96KHZ;
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
default:
|
||||||
|
ext_hdmi_rx_cfg[idx].sample_rate = SAMPLING_RATE_48KHZ;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
pr_debug("%s: control value = %ld, ext_hdmi_rx[%d].sample_rate = %d\n",
|
||||||
|
__func__, ucontrol->value.integer.value[0], idx,
|
||||||
|
ext_hdmi_rx_cfg[idx].sample_rate);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int proxy_rx_ch_get(struct snd_kcontrol *kcontrol,
|
static int proxy_rx_ch_get(struct snd_kcontrol *kcontrol,
|
||||||
struct snd_ctl_elem_value *ucontrol)
|
struct snd_ctl_elem_value *ucontrol)
|
||||||
{
|
{
|
||||||
@@ -3842,6 +4044,14 @@ static const struct snd_kcontrol_new msm_snd_sb_controls[] = {
|
|||||||
slim_rx_bit_format_get, slim_rx_bit_format_put),
|
slim_rx_bit_format_get, slim_rx_bit_format_put),
|
||||||
SOC_ENUM_EXT("SLIM_0_TX Format", slim_0_tx_format,
|
SOC_ENUM_EXT("SLIM_0_TX Format", slim_0_tx_format,
|
||||||
slim_tx_bit_format_get, slim_tx_bit_format_put),
|
slim_tx_bit_format_get, slim_tx_bit_format_put),
|
||||||
|
SOC_ENUM_EXT("HDMI_RX Bit Format", ext_hdmi_rx_format,
|
||||||
|
ext_hdmi_rx_format_get, ext_hdmi_rx_format_put),
|
||||||
|
SOC_ENUM_EXT("HDMI_RX SampleRate", ext_hdmi_rx_sample_rate,
|
||||||
|
ext_hdmi_rx_sample_rate_get,
|
||||||
|
ext_hdmi_rx_sample_rate_put),
|
||||||
|
SOC_ENUM_EXT("HDMI_RX Channels", ext_hdmi_rx_chs,
|
||||||
|
ext_hdmi_rx_ch_get,
|
||||||
|
ext_hdmi_rx_ch_put),
|
||||||
SOC_ENUM_EXT("SLIM_0_RX SampleRate", slim_0_rx_sample_rate,
|
SOC_ENUM_EXT("SLIM_0_RX SampleRate", slim_0_rx_sample_rate,
|
||||||
slim_rx_sample_rate_get, slim_rx_sample_rate_put),
|
slim_rx_sample_rate_get, slim_rx_sample_rate_put),
|
||||||
SOC_ENUM_EXT("SLIM_2_RX SampleRate", slim_2_rx_sample_rate,
|
SOC_ENUM_EXT("SLIM_2_RX SampleRate", slim_2_rx_sample_rate,
|
||||||
@@ -4506,6 +4716,23 @@ static int msm_slim_get_ch_from_beid(int32_t be_id)
|
|||||||
return ch_id;
|
return ch_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int msm_ext_hdmi_get_idx_from_beid(int32_t be_id)
|
||||||
|
{
|
||||||
|
int idx;
|
||||||
|
|
||||||
|
switch (be_id) {
|
||||||
|
case MSM_BACKEND_DAI_HDMI_RX_MS:
|
||||||
|
idx = HDMI_RX_IDX;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
pr_err("%s: Incorrect ext_hdmi BE id %d\n", __func__, be_id);
|
||||||
|
idx = -EINVAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
|
||||||
static int msm_cdc_dma_get_idx_from_beid(int32_t be_id)
|
static int msm_cdc_dma_get_idx_from_beid(int32_t be_id)
|
||||||
{
|
{
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
@@ -5040,11 +5267,27 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
|
|||||||
channels->min = channels->max = afe_lb_tx_cfg.channels;
|
channels->min = channels->max = afe_lb_tx_cfg.channels;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MSM_BACKEND_DAI_HDMI_RX_MS:
|
||||||
|
idx = msm_ext_hdmi_get_idx_from_beid(dai_link->id);
|
||||||
|
|
||||||
|
if (idx < 0) {
|
||||||
|
pr_err("%s: Incorrect ext hdmi idx %d\n",
|
||||||
|
__func__, idx);
|
||||||
|
rc = idx;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
|
||||||
|
ext_hdmi_rx_cfg[idx].bit_format);
|
||||||
|
rate->min = rate->max = ext_hdmi_rx_cfg[idx].sample_rate;
|
||||||
|
channels->min = channels->max = ext_hdmi_rx_cfg[idx].channels;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
rate->min = rate->max = SAMPLING_RATE_48KHZ;
|
rate->min = rate->max = SAMPLING_RATE_48KHZ;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
done:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6104,7 +6347,6 @@ static struct snd_soc_ops msm_fe_qos_ops = {
|
|||||||
.prepare = msm_fe_qos_prepare,
|
.prepare = msm_fe_qos_prepare,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream)
|
static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@@ -6177,6 +6419,36 @@ err:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int msm_mi2s_snd_hw_free(struct snd_pcm_substream *substream)
|
||||||
|
{
|
||||||
|
int i, data_format = 0;
|
||||||
|
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||||
|
int index = rtd->cpu_dai->id;
|
||||||
|
struct snd_soc_card *card = rtd->card;
|
||||||
|
struct snd_soc_component *component;
|
||||||
|
|
||||||
|
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||||
|
data_format = mi2s_rx_cfg[index].data_format;
|
||||||
|
else
|
||||||
|
data_format = mi2s_tx_cfg[index].data_format;
|
||||||
|
|
||||||
|
pr_debug("%s(): substream = %s stream = %d\n", __func__,
|
||||||
|
substream->name, substream->stream);
|
||||||
|
|
||||||
|
/* Call csra mute function if data format is DSD, else return */
|
||||||
|
if (data_format != AFE_DSD_DATA)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (i = 0; i < card->num_aux_devs; i++) {
|
||||||
|
component =
|
||||||
|
soc_find_component(card->aux_dev[i].codec_of_node,
|
||||||
|
NULL);
|
||||||
|
csra66x0_hw_free_mute(component);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream)
|
static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
@@ -6279,6 +6551,7 @@ static int msm_meta_mi2s_snd_startup(struct snd_pcm_substream *substream)
|
|||||||
unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS;
|
unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS;
|
||||||
struct snd_soc_card *card = rtd->card;
|
struct snd_soc_card *card = rtd->card;
|
||||||
struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
|
struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
|
||||||
|
u16 port_id = 0;
|
||||||
|
|
||||||
dev_dbg(rtd->card->dev,
|
dev_dbg(rtd->card->dev,
|
||||||
"%s: substream = %s stream = %d, dai name %s, dai ID %d\n",
|
"%s: substream = %s stream = %d, dai name %s, dai ID %d\n",
|
||||||
@@ -6312,6 +6585,13 @@ static int msm_meta_mi2s_snd_startup(struct snd_pcm_substream *substream)
|
|||||||
meta_mi2s_intf_conf[index].clk_enable[i] = true;
|
meta_mi2s_intf_conf[index].clk_enable[i] = true;
|
||||||
|
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
|
port_id = msm_get_port_id(rtd->dai_link->id);
|
||||||
|
ret = afe_set_clk_id(port_id,
|
||||||
|
mi2s_clk[member_port].clk_id);
|
||||||
|
if (ret < 0)
|
||||||
|
pr_err("%s: afe_set_clk_id fail %d\n",
|
||||||
|
__func__, ret);
|
||||||
|
|
||||||
ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
|
ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
pr_err("%s: set fmt cpu dai failed for META_MI2S (%d), err:%d\n",
|
pr_err("%s: set fmt cpu dai failed for META_MI2S (%d), err:%d\n",
|
||||||
@@ -6504,6 +6784,7 @@ static void msm_spdif_snd_shutdown(struct snd_pcm_substream *substream)
|
|||||||
|
|
||||||
static struct snd_soc_ops msm_mi2s_be_ops = {
|
static struct snd_soc_ops msm_mi2s_be_ops = {
|
||||||
.startup = msm_mi2s_snd_startup,
|
.startup = msm_mi2s_snd_startup,
|
||||||
|
.hw_free = msm_mi2s_snd_hw_free,
|
||||||
.shutdown = msm_mi2s_snd_shutdown,
|
.shutdown = msm_mi2s_snd_shutdown,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -7298,6 +7579,24 @@ static struct snd_soc_dai_link msm_common_misc_fe_dai_links[] = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct snd_soc_dai_link ext_hdmi_be_dai_link[] = {
|
||||||
|
/* HDMI RX BACK END DAI Link */
|
||||||
|
{
|
||||||
|
.name = LPASS_BE_HDMI_MS,
|
||||||
|
.stream_name = "HDMI MS Playback",
|
||||||
|
.cpu_dai_name = "msm-dai-q6-hdmi.24578",
|
||||||
|
.platform_name = "msm-pcm-routing",
|
||||||
|
.codec_name = "msm-ext-disp-audio-codec-rx",
|
||||||
|
.codec_dai_name = "msm_hdmi_ms_audio_codec_rx_dai",
|
||||||
|
.no_pcm = 1,
|
||||||
|
.dpcm_playback = 1,
|
||||||
|
.id = MSM_BACKEND_DAI_HDMI_RX_MS,
|
||||||
|
.be_hw_params_fixup = msm_be_hw_params_fixup,
|
||||||
|
.ignore_pmdown_time = 1,
|
||||||
|
.ignore_suspend = 1,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
static struct snd_soc_dai_link msm_common_be_dai_links[] = {
|
static struct snd_soc_dai_link msm_common_be_dai_links[] = {
|
||||||
/* Backend AFE DAI Links */
|
/* Backend AFE DAI Links */
|
||||||
{
|
{
|
||||||
@@ -8305,7 +8604,8 @@ static struct snd_soc_dai_link msm_qcs405_dai_links[
|
|||||||
ARRAY_SIZE(msm_wsa_cdc_dma_be_dai_links) +
|
ARRAY_SIZE(msm_wsa_cdc_dma_be_dai_links) +
|
||||||
ARRAY_SIZE(msm_bolero_fe_dai_links) +
|
ARRAY_SIZE(msm_bolero_fe_dai_links) +
|
||||||
ARRAY_SIZE(msm_spdif_be_dai_links) +
|
ARRAY_SIZE(msm_spdif_be_dai_links) +
|
||||||
ARRAY_SIZE(msm_afe_rxtx_lb_be_dai_link)];
|
ARRAY_SIZE(msm_afe_rxtx_lb_be_dai_link) +
|
||||||
|
ARRAY_SIZE(ext_hdmi_be_dai_link)];
|
||||||
|
|
||||||
static int msm_snd_card_tasha_late_probe(struct snd_soc_card *card)
|
static int msm_snd_card_tasha_late_probe(struct snd_soc_card *card)
|
||||||
{
|
{
|
||||||
@@ -8556,6 +8856,7 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev)
|
|||||||
uint32_t va_bolero_codec = 0, wsa_bolero_codec = 0, mi2s_audio_intf = 0;
|
uint32_t va_bolero_codec = 0, wsa_bolero_codec = 0, mi2s_audio_intf = 0;
|
||||||
uint32_t spdif_audio_intf = 0, wcn_audio_intf = 0;
|
uint32_t spdif_audio_intf = 0, wcn_audio_intf = 0;
|
||||||
uint32_t afe_loopback_intf = 0, meta_mi2s_intf = 0;
|
uint32_t afe_loopback_intf = 0, meta_mi2s_intf = 0;
|
||||||
|
uint32_t ext_disp_hdmi_rx = 0;
|
||||||
const struct of_device_id *match;
|
const struct of_device_id *match;
|
||||||
char __iomem *spdif_cfg, *spdif_pin_ctl;
|
char __iomem *spdif_cfg, *spdif_pin_ctl;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
@@ -8743,6 +9044,20 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev)
|
|||||||
ARRAY_SIZE(msm_afe_rxtx_lb_be_dai_link);
|
ARRAY_SIZE(msm_afe_rxtx_lb_be_dai_link);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
rc = of_property_read_u32(dev->of_node,
|
||||||
|
"qcom,ext-disp-audio-rx", &ext_disp_hdmi_rx);
|
||||||
|
if (rc) {
|
||||||
|
dev_dbg(dev, "%s: No DT match ext disp hdmi rx\n",
|
||||||
|
__func__);
|
||||||
|
} else {
|
||||||
|
if (ext_disp_hdmi_rx) {
|
||||||
|
memcpy(msm_qcs405_dai_links + total_links,
|
||||||
|
ext_hdmi_be_dai_link,
|
||||||
|
sizeof(ext_hdmi_be_dai_link));
|
||||||
|
total_links += ARRAY_SIZE(ext_hdmi_be_dai_link);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
dailink = msm_qcs405_dai_links;
|
dailink = msm_qcs405_dai_links;
|
||||||
} else if (!strcmp(match->data, "stub_codec")) {
|
} else if (!strcmp(match->data, "stub_codec")) {
|
||||||
card = &snd_soc_card_stub_msm;
|
card = &snd_soc_card_stub_msm;
|
||||||
@@ -8756,7 +9071,6 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev)
|
|||||||
msm_stub_be_dai_links,
|
msm_stub_be_dai_links,
|
||||||
sizeof(msm_stub_be_dai_links));
|
sizeof(msm_stub_be_dai_links));
|
||||||
total_links += ARRAY_SIZE(msm_stub_be_dai_links);
|
total_links += ARRAY_SIZE(msm_stub_be_dai_links);
|
||||||
|
|
||||||
dailink = msm_stub_dai_links;
|
dailink = msm_stub_dai_links;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -157,6 +157,10 @@ ifdef CONFIG_DIGITAL_CDC_RSC_MGR
|
|||||||
SPF_CORE_OBJS += digital-cdc-rsc-mgr.o
|
SPF_CORE_OBJS += digital-cdc-rsc-mgr.o
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifdef CONFIG_DIGITAL_CDC_RSC_MGR
|
||||||
|
Q6_OBJS += digital-cdc-rsc-mgr.o
|
||||||
|
endif
|
||||||
|
|
||||||
LINUX_INC += -Iinclude/linux
|
LINUX_INC += -Iinclude/linux
|
||||||
|
|
||||||
INCS += $(COMMON_INC) \
|
INCS += $(COMMON_INC) \
|
||||||
|
@@ -28,6 +28,7 @@ enum apr_subsys_state {
|
|||||||
APR_SUBSYS_DOWN,
|
APR_SUBSYS_DOWN,
|
||||||
APR_SUBSYS_UP,
|
APR_SUBSYS_UP,
|
||||||
APR_SUBSYS_LOADED,
|
APR_SUBSYS_LOADED,
|
||||||
|
APR_SUBSYS_UNKNOWN,
|
||||||
};
|
};
|
||||||
|
|
||||||
static ssize_t adsp_boot_store(struct kobject *kobj,
|
static ssize_t adsp_boot_store(struct kobject *kobj,
|
||||||
@@ -61,6 +62,53 @@ static struct work_struct adsp_ldr_work;
|
|||||||
static struct platform_device *adsp_private;
|
static struct platform_device *adsp_private;
|
||||||
static void adsp_loader_unload(struct platform_device *pdev);
|
static void adsp_loader_unload(struct platform_device *pdev);
|
||||||
|
|
||||||
|
static int adsp_restart_subsys(void)
|
||||||
|
{
|
||||||
|
struct subsys_device *adsp_dev = NULL;
|
||||||
|
struct platform_device *pdev = adsp_private;
|
||||||
|
struct adsp_loader_private *priv = NULL;
|
||||||
|
int rc = -EINVAL;
|
||||||
|
|
||||||
|
priv = platform_get_drvdata(pdev);
|
||||||
|
if (!priv)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
adsp_dev = (struct subsys_device *)priv->pil_h;
|
||||||
|
if (!adsp_dev)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
/* subsystem_restart_dev has worker queue to handle */
|
||||||
|
rc = subsystem_restart_dev(adsp_dev);
|
||||||
|
if (rc) {
|
||||||
|
dev_err(&pdev->dev, "subsystem_restart_dev failed\n");
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
pr_debug("%s :: Restart Success %d\n", __func__, rc);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
static void adsp_load_state_notify_cb(enum apr_subsys_state state,
|
||||||
|
void *phandle)
|
||||||
|
{
|
||||||
|
struct platform_device *pdev = adsp_private;
|
||||||
|
struct adsp_loader_private *priv = NULL;
|
||||||
|
|
||||||
|
priv = platform_get_drvdata(pdev);
|
||||||
|
if (!priv)
|
||||||
|
return;
|
||||||
|
if (phandle != adsp_private) {
|
||||||
|
pr_err("%s:callback is not for adsp-loader client\n", __func__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pr_debug("%s:: Received cb for ADSP restart\n", __func__);
|
||||||
|
if (state == APR_SUBSYS_UNKNOWN)
|
||||||
|
adsp_restart_subsys();
|
||||||
|
else
|
||||||
|
pr_debug("%s:Ignore restart request for ADSP", __func__);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void adsp_load_fw(struct work_struct *adsp_ldr_work)
|
static void adsp_load_fw(struct work_struct *adsp_ldr_work)
|
||||||
{
|
{
|
||||||
struct platform_device *pdev = adsp_private;
|
struct platform_device *pdev = adsp_private;
|
||||||
@@ -69,6 +117,7 @@ static void adsp_load_fw(struct work_struct *adsp_ldr_work)
|
|||||||
int rc = 0;
|
int rc = 0;
|
||||||
u32 adsp_state;
|
u32 adsp_state;
|
||||||
const char *img_name;
|
const char *img_name;
|
||||||
|
// void *padsp_restart_cb = &adsp_load_state_notify_cb;
|
||||||
|
|
||||||
if (!pdev) {
|
if (!pdev) {
|
||||||
dev_err(&pdev->dev, "%s: Platform device null\n", __func__);
|
dev_err(&pdev->dev, "%s: Platform device null\n", __func__);
|
||||||
@@ -125,7 +174,7 @@ static void adsp_load_fw(struct work_struct *adsp_ldr_work)
|
|||||||
}
|
}
|
||||||
|
|
||||||
dev_dbg(&pdev->dev, "%s: Q6/MDSP image is loaded\n", __func__);
|
dev_dbg(&pdev->dev, "%s: Q6/MDSP image is loaded\n", __func__);
|
||||||
return;
|
goto success;
|
||||||
}
|
}
|
||||||
|
|
||||||
load_adsp:
|
load_adsp:
|
||||||
@@ -159,10 +208,13 @@ load_adsp:
|
|||||||
}
|
}
|
||||||
|
|
||||||
dev_dbg(&pdev->dev, "%s: Q6/ADSP image is loaded\n", __func__);
|
dev_dbg(&pdev->dev, "%s: Q6/ADSP image is loaded\n", __func__);
|
||||||
return;
|
// apr_register_adsp_state_cb(padsp_restart_cb, adsp_private);
|
||||||
|
goto success;
|
||||||
}
|
}
|
||||||
fail:
|
fail:
|
||||||
dev_err(&pdev->dev, "%s: Q6 image loading failed\n", __func__);
|
dev_err(&pdev->dev, "%s: Q6 image loading failed\n", __func__);
|
||||||
|
success:
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void adsp_loader_do(struct platform_device *pdev)
|
static void adsp_loader_do(struct platform_device *pdev)
|
||||||
@@ -176,37 +228,24 @@ static ssize_t adsp_ssr_store(struct kobject *kobj,
|
|||||||
size_t count)
|
size_t count)
|
||||||
{
|
{
|
||||||
int ssr_command = 0;
|
int ssr_command = 0;
|
||||||
struct subsys_device *adsp_dev = NULL;
|
|
||||||
struct platform_device *pdev = adsp_private;
|
struct platform_device *pdev = adsp_private;
|
||||||
struct adsp_loader_private *priv = NULL;
|
struct adsp_loader_private *priv = NULL;
|
||||||
int rc;
|
int rc = -EINVAL;
|
||||||
|
|
||||||
dev_dbg(&pdev->dev, "%s: going to call adsp ssr\n ", __func__);
|
dev_dbg(&pdev->dev, "%s: going to call adsp ssr\n ", __func__);
|
||||||
|
|
||||||
|
priv = platform_get_drvdata(pdev);
|
||||||
|
if (!priv)
|
||||||
|
return rc;
|
||||||
|
|
||||||
if (kstrtoint(buf, 10, &ssr_command) < 0)
|
if (kstrtoint(buf, 10, &ssr_command) < 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (ssr_command != SSR_RESET_CMD)
|
if (ssr_command != SSR_RESET_CMD)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
priv = platform_get_drvdata(pdev);
|
adsp_restart_subsys();
|
||||||
if (!priv)
|
dev_dbg(&pdev->dev, "%s :: ADSP restarted\n", __func__);
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
adsp_dev = (struct subsys_device *)priv->pil_h;
|
|
||||||
if (!adsp_dev)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
dev_err(&pdev->dev, "requesting for ADSP restart\n");
|
|
||||||
|
|
||||||
/* subsystem_restart_dev has worker queue to handle */
|
|
||||||
rc = subsystem_restart_dev(adsp_dev);
|
|
||||||
if (rc) {
|
|
||||||
dev_err(&pdev->dev, "subsystem_restart_dev failed\n");
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
dev_dbg(&pdev->dev, "ADSP restarted\n");
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -339,6 +378,8 @@ static int adsp_loader_probe(struct platform_device *pdev)
|
|||||||
int fw_name_size;
|
int fw_name_size;
|
||||||
u32 adsp_var_idx = 0;
|
u32 adsp_var_idx = 0;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
u32 adsp_fuse_not_supported = 0;
|
||||||
|
const char *adsp_fw_name;
|
||||||
|
|
||||||
ret = adsp_loader_init_sysfs(pdev);
|
ret = adsp_loader_init_sysfs(pdev);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
@@ -350,15 +391,58 @@ static int adsp_loader_probe(struct platform_device *pdev)
|
|||||||
/* get adsp variant idx */
|
/* get adsp variant idx */
|
||||||
cell = nvmem_cell_get(&pdev->dev, "adsp_variant");
|
cell = nvmem_cell_get(&pdev->dev, "adsp_variant");
|
||||||
if (IS_ERR_OR_NULL(cell)) {
|
if (IS_ERR_OR_NULL(cell)) {
|
||||||
dev_dbg(&pdev->dev, "%s: FAILED to get nvmem cell \n", __func__);
|
dev_dbg(&pdev->dev, "%s: FAILED to get nvmem cell \n",
|
||||||
|
__func__);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When ADSP variant read from fuse register is not
|
||||||
|
* supported, check if image with different fw image
|
||||||
|
* name needs to be loaded
|
||||||
|
*/
|
||||||
|
ret = of_property_read_u32(pdev->dev.of_node,
|
||||||
|
"adsp-fuse-not-supported",
|
||||||
|
&adsp_fuse_not_supported);
|
||||||
|
if (ret) {
|
||||||
|
dev_dbg(&pdev->dev,
|
||||||
|
"%s: adsp_fuse_not_supported prop not found",
|
||||||
|
__func__, ret);
|
||||||
|
goto wqueue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (adsp_fuse_not_supported) {
|
||||||
|
/* Read ADSP firmware image name */
|
||||||
|
ret = of_property_read_string(pdev->dev.of_node,
|
||||||
|
"adsp-fw-name",
|
||||||
|
&adsp_fw_name);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_dbg(&pdev->dev, "%s: unable to read fw-name\n",
|
||||||
|
__func__);
|
||||||
|
goto wqueue;
|
||||||
|
}
|
||||||
|
|
||||||
|
fw_name_size = strlen(adsp_fw_name) + 1;
|
||||||
|
priv->adsp_fw_name = devm_kzalloc(&pdev->dev,
|
||||||
|
fw_name_size,
|
||||||
|
GFP_KERNEL);
|
||||||
|
if (!priv->adsp_fw_name)
|
||||||
|
goto wqueue;
|
||||||
|
strlcpy(priv->adsp_fw_name, adsp_fw_name,
|
||||||
|
fw_name_size);
|
||||||
|
}
|
||||||
goto wqueue;
|
goto wqueue;
|
||||||
}
|
}
|
||||||
buf = nvmem_cell_read(cell, &len);
|
buf = nvmem_cell_read(cell, &len);
|
||||||
nvmem_cell_put(cell);
|
nvmem_cell_put(cell);
|
||||||
if (IS_ERR_OR_NULL(buf) || len <= 0 || len > sizeof(u32)) {
|
if (IS_ERR_OR_NULL(buf)) {
|
||||||
dev_dbg(&pdev->dev, "%s: FAILED to read nvmem cell \n", __func__);
|
dev_dbg(&pdev->dev, "%s: FAILED to read nvmem cell \n", __func__);
|
||||||
goto wqueue;
|
goto wqueue;
|
||||||
}
|
}
|
||||||
|
if (len <= 0 || len > sizeof(u32)) {
|
||||||
|
dev_dbg(&pdev->dev, "%s: nvmem cell length out of range: %d\n",
|
||||||
|
__func__, len);
|
||||||
|
kfree(buf);
|
||||||
|
goto wqueue;
|
||||||
|
}
|
||||||
memcpy(&adsp_var_idx, buf, len);
|
memcpy(&adsp_var_idx, buf, len);
|
||||||
kfree(buf);
|
kfree(buf);
|
||||||
|
|
||||||
|
@@ -606,6 +606,7 @@ static int __init audio_notifier_late_init(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_MSM_QDSP6_PDR
|
||||||
static int __init audio_notifier_init(void)
|
static int __init audio_notifier_init(void)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
@@ -624,6 +625,17 @@ static int __init audio_notifier_init(void)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
static int __init audio_notifier_init(void)
|
||||||
|
{
|
||||||
|
audio_notifier_subsys_init();
|
||||||
|
audio_notifier_disable_service(AUDIO_NOTIFIER_PDR_SERVICE);
|
||||||
|
|
||||||
|
audio_notifier_late_init();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
module_init(audio_notifier_init);
|
module_init(audio_notifier_init);
|
||||||
|
|
||||||
static void __exit audio_notifier_exit(void)
|
static void __exit audio_notifier_exit(void)
|
||||||
|
@@ -87,13 +87,13 @@ void digital_cdc_rsc_mgr_hw_vote_reset(struct clk* vote_handle)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(digital_cdc_rsc_mgr_hw_vote_reset);
|
EXPORT_SYMBOL(digital_cdc_rsc_mgr_hw_vote_reset);
|
||||||
|
|
||||||
void digital_cdc_rsc_mgr_init()
|
void digital_cdc_rsc_mgr_init(void)
|
||||||
{
|
{
|
||||||
mutex_init(&hw_vote_lock);
|
mutex_init(&hw_vote_lock);
|
||||||
is_init_done = true;
|
is_init_done = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void digital_cdc_rsc_mgr_exit()
|
void digital_cdc_rsc_mgr_exit(void)
|
||||||
{
|
{
|
||||||
mutex_destroy(&hw_vote_lock);
|
mutex_destroy(&hw_vote_lock);
|
||||||
is_init_done = false;
|
is_init_done = false;
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
|
/* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __MFD_CDC_PINCTRL_H_
|
#ifndef __MFD_CDC_PINCTRL_H_
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
#if IS_ENABLED(CONFIG_MSM_CDC_PINCTRL)
|
#if IS_ENABLED(CONFIG_MSM_CDC_PINCTRL)
|
||||||
extern int msm_cdc_pinctrl_select_sleep_state(struct device_node *np);
|
extern int msm_cdc_pinctrl_select_sleep_state(struct device_node *np);
|
||||||
extern int msm_cdc_pinctrl_select_active_state(struct device_node *np);
|
extern int msm_cdc_pinctrl_select_active_state(struct device_node *np);
|
||||||
|
extern int msm_cdc_pinctrl_select_alt_active_state(struct device_node *np);
|
||||||
extern int msm_cdc_pinctrl_get_state(struct device_node *np);
|
extern int msm_cdc_pinctrl_get_state(struct device_node *np);
|
||||||
extern int msm_cdc_get_gpio_state(struct device_node *np);
|
extern int msm_cdc_get_gpio_state(struct device_node *np);
|
||||||
extern int msm_cdc_pinctrl_set_wakeup_capable(struct device_node *np,
|
extern int msm_cdc_pinctrl_set_wakeup_capable(struct device_node *np,
|
||||||
@@ -27,6 +28,10 @@ int msm_cdc_pinctrl_select_active_state(struct device_node *np)
|
|||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
int msm_cdc_pinctrl_select_alt_active_state(struct device_node *np)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
int msm_cdc_get_gpio_state(struct device_node *np)
|
int msm_cdc_get_gpio_state(struct device_node *np)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
@@ -15,6 +15,7 @@ struct cdc_regulator {
|
|||||||
int max_uV;
|
int max_uV;
|
||||||
int optimum_uA;
|
int optimum_uA;
|
||||||
bool ondemand;
|
bool ondemand;
|
||||||
|
bool lpm_supported;
|
||||||
struct regulator *regulator;
|
struct regulator *regulator;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -51,6 +52,11 @@ extern int msm_cdc_enable_static_supplies(struct device *dev,
|
|||||||
struct regulator_bulk_data *supplies,
|
struct regulator_bulk_data *supplies,
|
||||||
struct cdc_regulator *cdc_vreg,
|
struct cdc_regulator *cdc_vreg,
|
||||||
int num_supplies);
|
int num_supplies);
|
||||||
|
extern int msm_cdc_set_supplies_lpm_mode(struct device *dev,
|
||||||
|
struct regulator_bulk_data *supplies,
|
||||||
|
struct cdc_regulator *cdc_vreg,
|
||||||
|
int num_supplies,
|
||||||
|
bool flag);
|
||||||
extern int msm_cdc_init_supplies(struct device *dev,
|
extern int msm_cdc_init_supplies(struct device *dev,
|
||||||
struct regulator_bulk_data **supplies,
|
struct regulator_bulk_data **supplies,
|
||||||
struct cdc_regulator *cdc_vreg,
|
struct cdc_regulator *cdc_vreg,
|
||||||
|
@@ -145,6 +145,8 @@ do { \
|
|||||||
#define FW_READ_ATTEMPTS 15
|
#define FW_READ_ATTEMPTS 15
|
||||||
#define FW_READ_TIMEOUT 4000000
|
#define FW_READ_TIMEOUT 4000000
|
||||||
#define FAKE_REM_RETRY_ATTEMPTS 3
|
#define FAKE_REM_RETRY_ATTEMPTS 3
|
||||||
|
#define HPHL_CROSS_CONN_THRESHOLD 100
|
||||||
|
#define HPHR_CROSS_CONN_THRESHOLD 100
|
||||||
|
|
||||||
#define WCD_MBHC_BTN_PRESS_COMPL_TIMEOUT_MS 50
|
#define WCD_MBHC_BTN_PRESS_COMPL_TIMEOUT_MS 50
|
||||||
#define ANC_DETECT_RETRY_CNT 7
|
#define ANC_DETECT_RETRY_CNT 7
|
||||||
@@ -456,6 +458,14 @@ struct wcd_mbhc_register {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct wcd_mbhc_cb {
|
struct wcd_mbhc_cb {
|
||||||
|
void (*update_cross_conn_thr)
|
||||||
|
(struct wcd_mbhc *mbhc);
|
||||||
|
void (*mbhc_surge_ctl)
|
||||||
|
(struct wcd_mbhc *mbhc, bool surge_en);
|
||||||
|
void (*mbhc_comp_autozero_control)
|
||||||
|
(struct wcd_mbhc *mbhc, bool az_enable);
|
||||||
|
void (*get_micbias_val)
|
||||||
|
(struct wcd_mbhc *mbhc, int *mb);
|
||||||
void (*bcs_enable)
|
void (*bcs_enable)
|
||||||
(struct wcd_mbhc *mbhc, bool bcs_enable);
|
(struct wcd_mbhc *mbhc, bool bcs_enable);
|
||||||
int (*enable_mb_source)(struct wcd_mbhc *mbhc, bool turn_on);
|
int (*enable_mb_source)(struct wcd_mbhc *mbhc, bool turn_on);
|
||||||
@@ -541,6 +551,7 @@ struct wcd_mbhc {
|
|||||||
wait_queue_head_t wait_btn_press;
|
wait_queue_head_t wait_btn_press;
|
||||||
bool is_btn_press;
|
bool is_btn_press;
|
||||||
u8 current_plug;
|
u8 current_plug;
|
||||||
|
u8 plug_before_ssr;
|
||||||
bool in_swch_irq_handler;
|
bool in_swch_irq_handler;
|
||||||
bool hphl_swh; /*track HPHL switch NC / NO */
|
bool hphl_swh; /*track HPHL switch NC / NO */
|
||||||
bool gnd_swh; /*track GND switch NC / NO */
|
bool gnd_swh; /*track GND switch NC / NO */
|
||||||
@@ -551,6 +562,8 @@ struct wcd_mbhc {
|
|||||||
u32 moist_vref;
|
u32 moist_vref;
|
||||||
u32 moist_iref;
|
u32 moist_iref;
|
||||||
u32 moist_rref;
|
u32 moist_rref;
|
||||||
|
u32 hphl_cross_conn_thr;
|
||||||
|
u32 hphr_cross_conn_thr;
|
||||||
u8 micbias1_cap_mode; /* track ext cap setting */
|
u8 micbias1_cap_mode; /* track ext cap setting */
|
||||||
u8 micbias2_cap_mode; /* track ext cap setting */
|
u8 micbias2_cap_mode; /* track ext cap setting */
|
||||||
bool hs_detect_work_stop;
|
bool hs_detect_work_stop;
|
||||||
|
@@ -598,7 +598,7 @@ struct adm_cmd_device_open_v8 {
|
|||||||
* In all other use cases this should be set to 0xffff
|
* In all other use cases this should be set to 0xffff
|
||||||
*/
|
*/
|
||||||
|
|
||||||
u16 reserved;
|
u16 compressed_data_type;
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1356,6 +1356,7 @@ struct adm_cmd_connect_afe_port_v5 {
|
|||||||
#define RT_PROXY_PORT_001_RX 0x2000
|
#define RT_PROXY_PORT_001_RX 0x2000
|
||||||
#define RT_PROXY_PORT_001_TX 0x2001
|
#define RT_PROXY_PORT_001_TX 0x2001
|
||||||
#define AFE_LOOPBACK_TX 0x6001
|
#define AFE_LOOPBACK_TX 0x6001
|
||||||
|
#define HDMI_RX_MS 0x6002
|
||||||
#define DISPLAY_PORT_RX 0x6020
|
#define DISPLAY_PORT_RX 0x6020
|
||||||
|
|
||||||
#define AFE_LANE_MASK_INVALID 0
|
#define AFE_LANE_MASK_INVALID 0
|
||||||
@@ -1562,6 +1563,8 @@ struct adm_cmd_connect_afe_port_v5 {
|
|||||||
#define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_9_RX 0x4012
|
#define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_9_RX 0x4012
|
||||||
/* SLIMbus Tx port on channel 9. */
|
/* SLIMbus Tx port on channel 9. */
|
||||||
#define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_9_TX 0x4013
|
#define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_9_TX 0x4013
|
||||||
|
/*AFE Rx port for audio over hdmi*/
|
||||||
|
#define AFE_PORT_ID_HDMI_MS 0x6002
|
||||||
/* AFE Rx port for audio over Display port */
|
/* AFE Rx port for audio over Display port */
|
||||||
#define AFE_PORT_ID_HDMI_OVER_DP_RX 0x6020
|
#define AFE_PORT_ID_HDMI_OVER_DP_RX 0x6020
|
||||||
/*USB AFE port */
|
/*USB AFE port */
|
||||||
@@ -2554,6 +2557,7 @@ struct afe_port_data_cmd_rt_proxy_port_read_v2 {
|
|||||||
#define AFE_GENERIC_COMPRESSED 0x8
|
#define AFE_GENERIC_COMPRESSED 0x8
|
||||||
#define AFE_LINEAR_PCM_DATA_PACKED_16BIT 0X6
|
#define AFE_LINEAR_PCM_DATA_PACKED_16BIT 0X6
|
||||||
#define AFE_DSD_DOP_W_MARKER_DATA 0x9
|
#define AFE_DSD_DOP_W_MARKER_DATA 0x9
|
||||||
|
#define AFE_DSD_DATA 0xA
|
||||||
|
|
||||||
/* This param id is used to configure I2S interface */
|
/* This param id is used to configure I2S interface */
|
||||||
#define AFE_PARAM_ID_I2S_CONFIG 0x0001020D
|
#define AFE_PARAM_ID_I2S_CONFIG 0x0001020D
|
||||||
@@ -4139,6 +4143,16 @@ struct afe_id_aptx_adaptive_enc_init
|
|||||||
#define AFE_MODULE_ID_DEPACKETIZER_COP 0x00013233
|
#define AFE_MODULE_ID_DEPACKETIZER_COP 0x00013233
|
||||||
#define AFE_MODULE_ID_DEPACKETIZER_COP_V1 0x000132E9
|
#define AFE_MODULE_ID_DEPACKETIZER_COP_V1 0x000132E9
|
||||||
|
|
||||||
|
/* Macros for dynamic loading of modules by AVCS */
|
||||||
|
|
||||||
|
#define AVS_MODULE_ID_PACKETIZER_COP 0x0001322A
|
||||||
|
|
||||||
|
#define AVS_MODULE_ID_PACKETIZER_COP_V1 0x000132E8
|
||||||
|
|
||||||
|
#define AVS_MODULE_ID_DEPACKETIZER_COP 0x00013233
|
||||||
|
|
||||||
|
#define AVS_MODULE_ID_DEPACKETIZER_COP_V1 0x000132E9
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Depacketizer type parameter for the #AVS_MODULE_ID_DECODER module.
|
* Depacketizer type parameter for the #AVS_MODULE_ID_DECODER module.
|
||||||
* This parameter cannot be set runtime.
|
* This parameter cannot be set runtime.
|
||||||
@@ -4734,6 +4748,56 @@ struct afe_enc_config {
|
|||||||
union afe_enc_config_data data;
|
union afe_enc_config_data data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Enable TTP generator in AFE.
|
||||||
|
*/
|
||||||
|
#define AVS_DEPACKETIZER_PARAM_ID_TTP_GEN_STATE 0x000132EF
|
||||||
|
/*
|
||||||
|
* Configure TTP generator params in AFE.
|
||||||
|
*/
|
||||||
|
#define AVS_DEPACKETIZER_PARAM_ID_TTP_GEN_CFG 0x000132F0
|
||||||
|
#define MAX_TTP_OFFSET_PAIRS 4
|
||||||
|
struct afe_ttp_gen_enable_t {
|
||||||
|
uint16_t enable;
|
||||||
|
uint16_t reserved;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
struct afe_ttp_ssrc_offset_pair_t {
|
||||||
|
uint32_t ssrc;
|
||||||
|
uint32_t offset;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
struct afe_ttp_gen_cfg_t {
|
||||||
|
uint32_t ttp_offset_default;
|
||||||
|
/*
|
||||||
|
* TTP offset uses for all other cases
|
||||||
|
* where no valid SSRC is received.
|
||||||
|
*/
|
||||||
|
uint32_t settling_time;
|
||||||
|
/*
|
||||||
|
* If settling_mode==0x00: time in [us]
|
||||||
|
* after first received packet until
|
||||||
|
* packets are no longer dropped.
|
||||||
|
*/
|
||||||
|
uint16_t settling_mode;
|
||||||
|
/*
|
||||||
|
* 0x00(Drop), 0x01(Settle)
|
||||||
|
*/
|
||||||
|
uint16_t num_ssrc_offsets;
|
||||||
|
/*
|
||||||
|
* Number of SSRC/TTPOFFSET pairs to follow
|
||||||
|
*/
|
||||||
|
struct afe_ttp_ssrc_offset_pair_t ssrc_ttp_offset[MAX_TTP_OFFSET_PAIRS];
|
||||||
|
/*
|
||||||
|
* Array of ssrc/offset pairs
|
||||||
|
*/
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
struct afe_ttp_config {
|
||||||
|
struct afe_ttp_gen_enable_t ttp_gen_enable;
|
||||||
|
struct afe_ttp_gen_cfg_t ttp_gen_cfg;
|
||||||
|
};
|
||||||
|
|
||||||
union afe_dec_config_data {
|
union afe_dec_config_data {
|
||||||
struct asm_sbc_dec_cfg_t sbc_config;
|
struct asm_sbc_dec_cfg_t sbc_config;
|
||||||
struct asm_aac_dec_cfg_v2_t aac_config;
|
struct asm_aac_dec_cfg_v2_t aac_config;
|
||||||
@@ -4876,6 +4940,9 @@ struct avs_dec_congestion_buffer_param_t {
|
|||||||
/* Payload of the AFE_PARAM_ID_ISLAND_CONFIG parameter used by
|
/* Payload of the AFE_PARAM_ID_ISLAND_CONFIG parameter used by
|
||||||
* AFE_MODULE_AUDIO_DEV_INTERFACE.
|
* AFE_MODULE_AUDIO_DEV_INTERFACE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define AFE_PARAM_ID_POWER_MODE_CONFIG 0x0002002c
|
||||||
|
#define AFE_API_VERSION_POWER_MODE_CONFIG 0x1
|
||||||
struct afe_param_id_island_cfg_t {
|
struct afe_param_id_island_cfg_t {
|
||||||
uint32_t island_cfg_minor_version;
|
uint32_t island_cfg_minor_version;
|
||||||
/* Tracks the configuration of this parameter.
|
/* Tracks the configuration of this parameter.
|
||||||
@@ -4889,6 +4956,19 @@ struct afe_param_id_island_cfg_t {
|
|||||||
*/
|
*/
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
|
struct afe_param_id_power_mode_cfg_t {
|
||||||
|
uint32_t power_mode_cfg_minor_version;
|
||||||
|
/* Tracks the configuration of this parameter
|
||||||
|
* Supported values: #AFE_API_VERSION_POWER_MODE_CONFIG
|
||||||
|
*/
|
||||||
|
|
||||||
|
uint32_t power_mode_enable;
|
||||||
|
/* Specifies whether island mode should be enabled or disabled for the
|
||||||
|
* use-case being setup.
|
||||||
|
* Supported values: 0 - Disable, 1 - Enable
|
||||||
|
*/
|
||||||
|
} __packed;
|
||||||
|
|
||||||
/* ID of the parameter used by #AFE_MODULE_AUDIO_DEV_INTERFACE to configure
|
/* ID of the parameter used by #AFE_MODULE_AUDIO_DEV_INTERFACE to configure
|
||||||
* the Codec DMA interface.
|
* the Codec DMA interface.
|
||||||
*/
|
*/
|
||||||
@@ -5380,6 +5460,7 @@ struct afe_param_id_lpass_core_shared_clk_cfg {
|
|||||||
#define COMPRESSED_PASSTHROUGH_NONE_TOPOLOGY 0x00010774
|
#define COMPRESSED_PASSTHROUGH_NONE_TOPOLOGY 0x00010774
|
||||||
#define VPM_TX_SM_ECNS_V2_COPP_TOPOLOGY 0x00010F89
|
#define VPM_TX_SM_ECNS_V2_COPP_TOPOLOGY 0x00010F89
|
||||||
#define VPM_TX_VOICE_SMECNS_V2_COPP_TOPOLOGY 0x10000003
|
#define VPM_TX_VOICE_SMECNS_V2_COPP_TOPOLOGY 0x10000003
|
||||||
|
#define VPM_TX_VOICE_FLUENCE_SM_COPP_TOPOLOGY 0x10000004
|
||||||
#define VPM_TX_DM_FLUENCE_COPP_TOPOLOGY 0x00010F72
|
#define VPM_TX_DM_FLUENCE_COPP_TOPOLOGY 0x00010F72
|
||||||
#define VPM_TX_QMIC_FLUENCE_COPP_TOPOLOGY 0x00010F75
|
#define VPM_TX_QMIC_FLUENCE_COPP_TOPOLOGY 0x00010F75
|
||||||
#define VPM_TX_DM_RFECNS_COPP_TOPOLOGY 0x00010F86
|
#define VPM_TX_DM_RFECNS_COPP_TOPOLOGY 0x00010F86
|
||||||
@@ -8887,6 +8968,13 @@ struct asm_data_cmd_remove_silence {
|
|||||||
/* Shift value for the IEC 61937 to 61937 pass-through capture. */
|
/* Shift value for the IEC 61937 to 61937 pass-through capture. */
|
||||||
#define ASM_SHIFT_IEC_61937_PASS_THROUGH_FLAG 0
|
#define ASM_SHIFT_IEC_61937_PASS_THROUGH_FLAG 0
|
||||||
|
|
||||||
|
/* Bitmask for the DSD pass-through capture. */
|
||||||
|
#define ASM_BIT_MASK_COMPRESSED_FORMAT_FLAG (0x00000003UL)
|
||||||
|
|
||||||
|
/* Shift value for the DSD pass-through capture. */
|
||||||
|
#define ASM_SHIFT_DSD_COMPRESSED_FORMAT_FLAG 0
|
||||||
|
|
||||||
|
#define ASM_DSD_FORMAT_FLAG 2
|
||||||
struct asm_stream_cmd_open_read_compressed {
|
struct asm_stream_cmd_open_read_compressed {
|
||||||
struct apr_hdr hdr;
|
struct apr_hdr hdr;
|
||||||
u32 mode_flags;
|
u32 mode_flags;
|
||||||
@@ -8898,6 +8986,12 @@ struct asm_stream_cmd_open_read_compressed {
|
|||||||
* - Use #ASM_BIT_MASK_IEC_61937_PASS_THROUGH_FLAG to set the bitmask
|
* - Use #ASM_BIT_MASK_IEC_61937_PASS_THROUGH_FLAG to set the bitmask
|
||||||
* and #ASM_SHIFT_IEC_61937_PASS_THROUGH_FLAG to set the shift value
|
* and #ASM_SHIFT_IEC_61937_PASS_THROUGH_FLAG to set the shift value
|
||||||
* for this bit.
|
* for this bit.
|
||||||
|
* Supported values for bit 1: (DSD native pass-through mode)
|
||||||
|
* 0 -- non DSD operation
|
||||||
|
* 1 -- Pass-through transfer of the DSD format stream
|
||||||
|
* To set this bit, use #ASM_BIT_MASK_DSD_PASS_THROUGH_FLAG and
|
||||||
|
* use #ASM_SHIFT_DSD_PASS_THROUGH_FLAG to set the shift value for
|
||||||
|
* this bit
|
||||||
* Supported values for bit 4:
|
* Supported values for bit 4:
|
||||||
* - 0 -- Return data buffer contains all encoded frames only; it does
|
* - 0 -- Return data buffer contains all encoded frames only; it does
|
||||||
* not contain frame metadata.
|
* not contain frame metadata.
|
||||||
@@ -8914,6 +9008,9 @@ struct asm_stream_cmd_open_read_compressed {
|
|||||||
* Supported values: should be greater than 0 for IEC to RAW compressed
|
* Supported values: should be greater than 0 for IEC to RAW compressed
|
||||||
* unpack mode.
|
* unpack mode.
|
||||||
* Value is don't care for IEC 61937 pass-through mode.
|
* Value is don't care for IEC 61937 pass-through mode.
|
||||||
|
* @values
|
||||||
|
* - >0 -- For IEC 61937-to-RAW Compressed Unpack mode
|
||||||
|
* - 1 -- For IEC 61937 or DSD Pass-through mode
|
||||||
*/
|
*/
|
||||||
|
|
||||||
} __packed;
|
} __packed;
|
||||||
@@ -12102,6 +12199,35 @@ struct afe_clk_cfg {
|
|||||||
#define AFE_MODULE_CLOCK_SET 0x0001028F
|
#define AFE_MODULE_CLOCK_SET 0x0001028F
|
||||||
#define AFE_PARAM_ID_CLOCK_SET 0x00010290
|
#define AFE_PARAM_ID_CLOCK_SET 0x00010290
|
||||||
|
|
||||||
|
struct afe_set_clk_drift {
|
||||||
|
/*
|
||||||
|
* Clock ID
|
||||||
|
* @values
|
||||||
|
* - 0x100 to 0x10E
|
||||||
|
* - 0x200 to 0x20C
|
||||||
|
* - 0x500 to 0x505
|
||||||
|
*/
|
||||||
|
uint32_t clk_id;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Clock drift (in PPB) to be set.
|
||||||
|
* @values
|
||||||
|
* - need to get values from DSP team
|
||||||
|
*/
|
||||||
|
int32_t clk_drift;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Clock rest.
|
||||||
|
* @values
|
||||||
|
* - 1 -- Reset PLL with the original frequency
|
||||||
|
* - 0 -- Adjust the clock with the clk drift value
|
||||||
|
*/
|
||||||
|
uint32_t clk_reset;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
/* This param id is used to adjust audio interface PLL*/
|
||||||
|
#define AFE_PARAM_ID_CLOCK_ADJUST 0x000102C6
|
||||||
|
|
||||||
enum afe_lpass_digital_clk_src {
|
enum afe_lpass_digital_clk_src {
|
||||||
Q6AFE_LPASS_DIGITAL_ROOT_INVALID,
|
Q6AFE_LPASS_DIGITAL_ROOT_INVALID,
|
||||||
Q6AFE_LPASS_DIGITAL_ROOT_PRI_MI2S_OSR,
|
Q6AFE_LPASS_DIGITAL_ROOT_PRI_MI2S_OSR,
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2010-2017, 2019, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2010-2017, 2019, 2020, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
#ifndef __APR_H_
|
#ifndef __APR_H_
|
||||||
#define __APR_H_
|
#define __APR_H_
|
||||||
@@ -12,6 +12,7 @@ enum apr_subsys_state {
|
|||||||
APR_SUBSYS_DOWN,
|
APR_SUBSYS_DOWN,
|
||||||
APR_SUBSYS_UP,
|
APR_SUBSYS_UP,
|
||||||
APR_SUBSYS_LOADED,
|
APR_SUBSYS_LOADED,
|
||||||
|
APR_SUBSYS_UNKNOWN,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct apr_q6 {
|
struct apr_q6 {
|
||||||
@@ -19,6 +20,13 @@ struct apr_q6 {
|
|||||||
atomic_t q6_state;
|
atomic_t q6_state;
|
||||||
atomic_t modem_state;
|
atomic_t modem_state;
|
||||||
struct mutex lock;
|
struct mutex lock;
|
||||||
|
/*
|
||||||
|
* ToDo - Multiple client support to be added.
|
||||||
|
* And checking for state UNKNOWN currently.
|
||||||
|
*/
|
||||||
|
void (*state_notify_cb)(enum apr_subsys_state state,
|
||||||
|
void *client_handle);
|
||||||
|
void *client_handle;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct apr_hdr {
|
struct apr_hdr {
|
||||||
@@ -186,4 +194,5 @@ const char *apr_get_lpass_subsys_name(void);
|
|||||||
uint16_t apr_get_reset_domain(uint16_t proc);
|
uint16_t apr_get_reset_domain(uint16_t proc);
|
||||||
int apr_start_rx_rt(void *handle);
|
int apr_start_rx_rt(void *handle);
|
||||||
int apr_end_rx_rt(void *handle);
|
int apr_end_rx_rt(void *handle);
|
||||||
|
void apr_register_adsp_state_cb(void *adsp_cb, void *client_handle);
|
||||||
#endif
|
#endif
|
||||||
|
@@ -7,9 +7,9 @@
|
|||||||
|
|
||||||
|
|
||||||
/* CONFIG GET/SET */
|
/* CONFIG GET/SET */
|
||||||
#define CONFIG_CACHE 0
|
#define AUDIO_EFFECTS_CONFIG_CACHE 0
|
||||||
#define CONFIG_SET 1
|
#define AUDIO_EFFECTS_CONFIG_SET 1
|
||||||
#define CONFIG_GET 2
|
#define AUDIO_EFFECTS_CONFIG_GET 2
|
||||||
|
|
||||||
/* CONFIG HEADER */
|
/* CONFIG HEADER */
|
||||||
/*
|
/*
|
||||||
@@ -17,14 +17,14 @@
|
|||||||
* DEVICE,
|
* DEVICE,
|
||||||
* NUM_COMMANDS,
|
* NUM_COMMANDS,
|
||||||
* COMMAND_ID_1,
|
* COMMAND_ID_1,
|
||||||
* CONFIG_CACHE/SET/GET,
|
* AUDIO_EFFECTS_CONFIG_CACHE/SET/GET,
|
||||||
* OFFSET_1,
|
* OFFSET_1,
|
||||||
* LENGTH_1,
|
* LENGTH_1,
|
||||||
* VALUES_1,
|
* VALUES_1,
|
||||||
* ...,
|
* ...,
|
||||||
* ...,
|
* ...,
|
||||||
* COMMAND_ID_2,
|
* COMMAND_ID_2,
|
||||||
* CONFIG_CACHE/SET/GET,
|
* AUDIO_EFFECTS_CONFIG_CACHE/SET/GET,
|
||||||
* OFFSET_2,
|
* OFFSET_2,
|
||||||
* LENGTH_2,
|
* LENGTH_2,
|
||||||
* VALUES_2,
|
* VALUES_2,
|
||||||
|
@@ -5,9 +5,8 @@
|
|||||||
#define LSM_EVENT_TIMESTAMP_MODE_SUPPORT
|
#define LSM_EVENT_TIMESTAMP_MODE_SUPPORT
|
||||||
|
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <sound/asound.h>
|
|
||||||
|
|
||||||
#define SNDRV_LSM_VERSION SNDRV_PROTOCOL_VERSION(0, 3, 1)
|
#define SNDRV_LSM_VERSION SNDRV_PROTOCOL_VERSION(0, 3, 2)
|
||||||
|
|
||||||
#define LSM_MAX_STAGES_PER_SESSION 2
|
#define LSM_MAX_STAGES_PER_SESSION 2
|
||||||
#define LSM_STAGE_INDEX_FIRST 0
|
#define LSM_STAGE_INDEX_FIRST 0
|
||||||
@@ -34,7 +33,10 @@
|
|||||||
#define LSM_POLLING_ENABLE (7)
|
#define LSM_POLLING_ENABLE (7)
|
||||||
#define LSM_DET_EVENT_TYPE (8)
|
#define LSM_DET_EVENT_TYPE (8)
|
||||||
#define LSM_LAB_CONTROL (9)
|
#define LSM_LAB_CONTROL (9)
|
||||||
#define LSM_PARAMS_MAX (LSM_LAB_CONTROL + 1)
|
#define LSM_REG_MULTI_SND_MODEL (10)
|
||||||
|
#define LSM_DEREG_MULTI_SND_MODEL (11)
|
||||||
|
#define LSM_MULTI_SND_MODEL_CONFIDENCE_LEVELS (12)
|
||||||
|
#define LSM_PARAMS_MAX (LSM_MULTI_SND_MODEL_CONFIDENCE_LEVELS + 1)
|
||||||
|
|
||||||
#define LSM_EVENT_NON_TIME_STAMP_MODE (0)
|
#define LSM_EVENT_NON_TIME_STAMP_MODE (0)
|
||||||
#define LSM_EVENT_TIME_STAMP_MODE (1)
|
#define LSM_EVENT_TIME_STAMP_MODE (1)
|
||||||
@@ -227,6 +229,7 @@ struct lsm_params_info {
|
|||||||
* Member variables applicable only to V2:
|
* Member variables applicable only to V2:
|
||||||
* @instance_id: instance id of the param to which parameter is to be set
|
* @instance_id: instance id of the param to which parameter is to be set
|
||||||
* @stage_idx: detection stage for which the param is applicable
|
* @stage_idx: detection stage for which the param is applicable
|
||||||
|
* @model_id: an unique number to identify sound models in DSP
|
||||||
*/
|
*/
|
||||||
struct lsm_params_info_v2 {
|
struct lsm_params_info_v2 {
|
||||||
__u32 module_id;
|
__u32 module_id;
|
||||||
@@ -236,6 +239,7 @@ struct lsm_params_info_v2 {
|
|||||||
__u32 param_type;
|
__u32 param_type;
|
||||||
__u16 instance_id;
|
__u16 instance_id;
|
||||||
__u16 stage_idx;
|
__u16 stage_idx;
|
||||||
|
__u32 model_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -1,6 +1,8 @@
|
|||||||
#ifndef _CALIB_HWDEP_H
|
#ifndef _CALIB_HWDEP_H
|
||||||
#define _CALIB_HWDEP_H
|
#define _CALIB_HWDEP_H
|
||||||
|
|
||||||
|
#include <linux/types.h>
|
||||||
|
|
||||||
#define WCD9XXX_CODEC_HWDEP_NODE 1000
|
#define WCD9XXX_CODEC_HWDEP_NODE 1000
|
||||||
#define AQT1000_CODEC_HWDEP_NODE 1001
|
#define AQT1000_CODEC_HWDEP_NODE 1001
|
||||||
#define Q6AFE_HWDEP_NODE 1002
|
#define Q6AFE_HWDEP_NODE 1002
|
||||||
|
@@ -2,7 +2,6 @@
|
|||||||
#define __VOICE_PARAMS_H__
|
#define __VOICE_PARAMS_H__
|
||||||
|
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <sound/asound.h>
|
|
||||||
|
|
||||||
enum voice_lch_mode {
|
enum voice_lch_mode {
|
||||||
VOICE_LCH_START = 1,
|
VOICE_LCH_START = 1,
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016-2020 The Linux Foundation. All rights reserved.
|
* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/gpio.h>
|
#include <linux/gpio.h>
|
||||||
@@ -15,6 +15,7 @@
|
|||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/clk.h>
|
#include <linux/clk.h>
|
||||||
#include <linux/bitops.h>
|
#include <linux/bitops.h>
|
||||||
|
#include <linux/delay.h>
|
||||||
#include <soc/snd_event.h>
|
#include <soc/snd_event.h>
|
||||||
#include <dsp/digital-cdc-rsc-mgr.h>
|
#include <dsp/digital-cdc-rsc-mgr.h>
|
||||||
#include <linux/pm_runtime.h>
|
#include <linux/pm_runtime.h>
|
||||||
@@ -489,6 +490,8 @@ static int lpi_notifier_service_cb(struct notifier_block *this,
|
|||||||
|
|
||||||
/* Reset HW votes after SSR */
|
/* Reset HW votes after SSR */
|
||||||
if (!lpi_dev_up) {
|
if (!lpi_dev_up) {
|
||||||
|
/* Add 100ms sleep to ensure AVS is up after SSR */
|
||||||
|
msleep(100);
|
||||||
if (state->lpass_core_hw_vote)
|
if (state->lpass_core_hw_vote)
|
||||||
digital_cdc_rsc_mgr_hw_vote_reset(
|
digital_cdc_rsc_mgr_hw_vote_reset(
|
||||||
state->lpass_core_hw_vote);
|
state->lpass_core_hw_vote);
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
@@ -473,10 +473,6 @@ int swr_get_logical_dev_num(struct swr_device *dev, u64 dev_id,
|
|||||||
}
|
}
|
||||||
mutex_lock(&master->mlock);
|
mutex_lock(&master->mlock);
|
||||||
ret = master->get_logical_dev_num(master, dev_id, dev_num);
|
ret = master->get_logical_dev_num(master, dev_id, dev_num);
|
||||||
if (ret) {
|
|
||||||
pr_err("%s: Error %d to get logical addr for device %llx\n",
|
|
||||||
__func__, ret, dev_id);
|
|
||||||
}
|
|
||||||
mutex_unlock(&master->mlock);
|
mutex_unlock(&master->mlock);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@@ -41,7 +41,6 @@
|
|||||||
#define SWRM_DSD_PARAMS_PORT 4
|
#define SWRM_DSD_PARAMS_PORT 4
|
||||||
|
|
||||||
#define SWR_BROADCAST_CMD_ID 0x0F
|
#define SWR_BROADCAST_CMD_ID 0x0F
|
||||||
#define SWR_AUTO_SUSPEND_DELAY 1 /* delay in sec */
|
|
||||||
#define SWR_DEV_ID_MASK 0xFFFFFFFFFFFF
|
#define SWR_DEV_ID_MASK 0xFFFFFFFFFFFF
|
||||||
#define SWR_REG_VAL_PACK(data, dev, id, reg) \
|
#define SWR_REG_VAL_PACK(data, dev, id, reg) \
|
||||||
((reg) | ((id) << 16) | ((dev) << 20) | ((data) << 24))
|
((reg) | ((id) << 16) | ((dev) << 20) | ((data) << 24))
|
||||||
@@ -82,7 +81,7 @@
|
|||||||
#define SWRM_DP_PORT_CTRL_OFFSET1_SHFT 0x08
|
#define SWRM_DP_PORT_CTRL_OFFSET1_SHFT 0x08
|
||||||
|
|
||||||
/* pm runtime auto suspend timer in msecs */
|
/* pm runtime auto suspend timer in msecs */
|
||||||
static int auto_suspend_timer = SWR_AUTO_SUSPEND_DELAY * 1000;
|
static int auto_suspend_timer = 500;
|
||||||
module_param(auto_suspend_timer, int, 0664);
|
module_param(auto_suspend_timer, int, 0664);
|
||||||
MODULE_PARM_DESC(auto_suspend_timer, "timer for auto suspend");
|
MODULE_PARM_DESC(auto_suspend_timer, "timer for auto suspend");
|
||||||
|
|
||||||
@@ -121,7 +120,7 @@ static bool swrm_lock_sleep(struct swr_mstr_ctrl *swrm);
|
|||||||
static void swrm_unlock_sleep(struct swr_mstr_ctrl *swrm);
|
static void swrm_unlock_sleep(struct swr_mstr_ctrl *swrm);
|
||||||
static u32 swr_master_read(struct swr_mstr_ctrl *swrm, unsigned int reg_addr);
|
static u32 swr_master_read(struct swr_mstr_ctrl *swrm, unsigned int reg_addr);
|
||||||
static void swr_master_write(struct swr_mstr_ctrl *swrm, u16 reg_addr, u32 val);
|
static void swr_master_write(struct swr_mstr_ctrl *swrm, u16 reg_addr, u32 val);
|
||||||
|
static int swrm_runtime_resume(struct device *dev);
|
||||||
|
|
||||||
static u8 swrm_get_clk_div(int mclk_freq, int bus_clk_freq)
|
static u8 swrm_get_clk_div(int mclk_freq, int bus_clk_freq)
|
||||||
{
|
{
|
||||||
@@ -647,6 +646,7 @@ static int swr_master_bulk_write(struct swr_mstr_ctrl *swrm, u32 *reg_addr,
|
|||||||
usleep_range(50, 55);
|
usleep_range(50, 55);
|
||||||
swr_master_write(swrm, reg_addr[i], val[i]);
|
swr_master_write(swrm, reg_addr[i], val[i]);
|
||||||
}
|
}
|
||||||
|
usleep_range(100, 110);
|
||||||
mutex_unlock(&swrm->iolock);
|
mutex_unlock(&swrm->iolock);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@@ -901,6 +901,8 @@ static int swrm_read(struct swr_master *master, u8 dev_num, u16 reg_addr,
|
|||||||
mutex_unlock(&swrm->devlock);
|
mutex_unlock(&swrm->devlock);
|
||||||
|
|
||||||
pm_runtime_get_sync(swrm->dev);
|
pm_runtime_get_sync(swrm->dev);
|
||||||
|
if (swrm->req_clk_switch)
|
||||||
|
swrm_runtime_resume(swrm->dev);
|
||||||
ret = swrm_cmd_fifo_rd_cmd(swrm, &val, dev_num, 0, reg_addr, len);
|
ret = swrm_cmd_fifo_rd_cmd(swrm, &val, dev_num, 0, reg_addr, len);
|
||||||
|
|
||||||
if (!ret)
|
if (!ret)
|
||||||
@@ -934,6 +936,8 @@ static int swrm_write(struct swr_master *master, u8 dev_num, u16 reg_addr,
|
|||||||
mutex_unlock(&swrm->devlock);
|
mutex_unlock(&swrm->devlock);
|
||||||
|
|
||||||
pm_runtime_get_sync(swrm->dev);
|
pm_runtime_get_sync(swrm->dev);
|
||||||
|
if (swrm->req_clk_switch)
|
||||||
|
swrm_runtime_resume(swrm->dev);
|
||||||
ret = swrm_cmd_fifo_wr_cmd(swrm, reg_val, dev_num, 0, reg_addr);
|
ret = swrm_cmd_fifo_wr_cmd(swrm, reg_val, dev_num, 0, reg_addr);
|
||||||
|
|
||||||
pm_runtime_put_autosuspend(swrm->dev);
|
pm_runtime_put_autosuspend(swrm->dev);
|
||||||
@@ -1105,6 +1109,8 @@ int swrm_get_clk_div_rate(int mclk_freq, int bus_clk_freq)
|
|||||||
bus_clk_freq = SWR_CLK_RATE_4P8MHZ;
|
bus_clk_freq = SWR_CLK_RATE_4P8MHZ;
|
||||||
else if(bus_clk_freq <= SWR_CLK_RATE_9P6MHZ)
|
else if(bus_clk_freq <= SWR_CLK_RATE_9P6MHZ)
|
||||||
bus_clk_freq = SWR_CLK_RATE_9P6MHZ;
|
bus_clk_freq = SWR_CLK_RATE_9P6MHZ;
|
||||||
|
else
|
||||||
|
bus_clk_freq = SWR_CLK_RATE_9P6MHZ;
|
||||||
} else if (mclk_freq == SWR_CLK_RATE_11P2896MHZ)
|
} else if (mclk_freq == SWR_CLK_RATE_11P2896MHZ)
|
||||||
bus_clk_freq = SWR_CLK_RATE_11P2896MHZ;
|
bus_clk_freq = SWR_CLK_RATE_11P2896MHZ;
|
||||||
|
|
||||||
@@ -1871,7 +1877,7 @@ handle_irq:
|
|||||||
swrm_enable_slave_irq(swrm);
|
swrm_enable_slave_irq(swrm);
|
||||||
if (status == swrm->slave_status) {
|
if (status == swrm->slave_status) {
|
||||||
dev_dbg(swrm->dev,
|
dev_dbg(swrm->dev,
|
||||||
"%s: No change in slave status: %d\n",
|
"%s: No change in slave status: 0x%x\n",
|
||||||
__func__, status);
|
__func__, status);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1923,16 +1929,22 @@ handle_irq:
|
|||||||
swrm->intr_mask);
|
swrm->intr_mask);
|
||||||
break;
|
break;
|
||||||
case SWRM_INTERRUPT_STATUS_RD_FIFO_OVERFLOW:
|
case SWRM_INTERRUPT_STATUS_RD_FIFO_OVERFLOW:
|
||||||
dev_dbg(swrm->dev, "%s: SWR read FIFO overflow\n",
|
value = swr_master_read(swrm, SWRM_CMD_FIFO_STATUS);
|
||||||
__func__);
|
dev_err(swrm->dev,
|
||||||
|
"%s: SWR read FIFO overflow fifo status\n",
|
||||||
|
__func__, value);
|
||||||
break;
|
break;
|
||||||
case SWRM_INTERRUPT_STATUS_RD_FIFO_UNDERFLOW:
|
case SWRM_INTERRUPT_STATUS_RD_FIFO_UNDERFLOW:
|
||||||
dev_dbg(swrm->dev, "%s: SWR read FIFO underflow\n",
|
value = swr_master_read(swrm, SWRM_CMD_FIFO_STATUS);
|
||||||
__func__);
|
dev_err(swrm->dev,
|
||||||
|
"%s: SWR read FIFO underflow fifo status\n",
|
||||||
|
__func__, value);
|
||||||
break;
|
break;
|
||||||
case SWRM_INTERRUPT_STATUS_WR_CMD_FIFO_OVERFLOW:
|
case SWRM_INTERRUPT_STATUS_WR_CMD_FIFO_OVERFLOW:
|
||||||
dev_dbg(swrm->dev, "%s: SWR write FIFO overflow\n",
|
value = swr_master_read(swrm, SWRM_CMD_FIFO_STATUS);
|
||||||
__func__);
|
dev_err(swrm->dev,
|
||||||
|
"%s: SWR write FIFO overflow fifo status\n",
|
||||||
|
__func__, value);
|
||||||
swr_master_write(swrm, SWRM_CMD_FIFO_CMD, 0x1);
|
swr_master_write(swrm, SWRM_CMD_FIFO_CMD, 0x1);
|
||||||
break;
|
break;
|
||||||
case SWRM_INTERRUPT_STATUS_CMD_ERROR:
|
case SWRM_INTERRUPT_STATUS_CMD_ERROR:
|
||||||
@@ -2175,16 +2187,18 @@ static int swrm_get_logical_dev_num(struct swr_master *mstr, u64 dev_id,
|
|||||||
if ((id & SWR_DEV_ID_MASK) == dev_id) {
|
if ((id & SWR_DEV_ID_MASK) == dev_id) {
|
||||||
*dev_num = i;
|
*dev_num = i;
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
dev_info(swrm->dev,
|
||||||
|
"%s: devnum %d assigned for dev %llx\n",
|
||||||
|
__func__, i,
|
||||||
|
swr_dev->addr);
|
||||||
}
|
}
|
||||||
dev_dbg(swrm->dev,
|
|
||||||
"%s: devnum %d is assigned for dev addr %lx\n",
|
|
||||||
__func__, i, swr_dev->addr);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ret)
|
if (ret)
|
||||||
dev_err(swrm->dev, "%s: device 0x%llx is not ready\n",
|
dev_err_ratelimited(swrm->dev,
|
||||||
|
"%s: device 0x%llx is not ready\n",
|
||||||
__func__, dev_id);
|
__func__, dev_id);
|
||||||
|
|
||||||
pm_runtime_mark_last_busy(swrm->dev);
|
pm_runtime_mark_last_busy(swrm->dev);
|
||||||
@@ -2659,6 +2673,8 @@ static int swrm_probe(struct platform_device *pdev)
|
|||||||
* controller will be up now
|
* controller will be up now
|
||||||
*/
|
*/
|
||||||
swr_master_add_boarddevices(&swrm->master);
|
swr_master_add_boarddevices(&swrm->master);
|
||||||
|
if (swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, true))
|
||||||
|
dev_dbg(&pdev->dev, "%s: Audio HW Vote is failed\n", __func__);
|
||||||
mutex_lock(&swrm->mlock);
|
mutex_lock(&swrm->mlock);
|
||||||
swrm_clk_request(swrm, true);
|
swrm_clk_request(swrm, true);
|
||||||
swrm->version = swr_master_read(swrm, SWRM_COMP_HW_VERSION);
|
swrm->version = swr_master_read(swrm, SWRM_COMP_HW_VERSION);
|
||||||
@@ -2721,13 +2737,13 @@ err_mstr_fail:
|
|||||||
swrm->reg_irq(swrm->handle, swr_mstr_interrupt,
|
swrm->reg_irq(swrm->handle, swr_mstr_interrupt,
|
||||||
swrm, SWR_IRQ_FREE);
|
swrm, SWR_IRQ_FREE);
|
||||||
} else if (swrm->irq) {
|
} else if (swrm->irq) {
|
||||||
free_irq(swrm->irq, swrm);
|
|
||||||
irqd_set_trigger_type(
|
irqd_set_trigger_type(
|
||||||
irq_get_irq_data(swrm->irq),
|
irq_get_irq_data(swrm->irq),
|
||||||
IRQ_TYPE_NONE);
|
IRQ_TYPE_NONE);
|
||||||
}
|
|
||||||
if (swrm->swr_irq_wakeup_capable)
|
if (swrm->swr_irq_wakeup_capable)
|
||||||
irq_set_irq_wake(swrm->irq, 0);
|
irq_set_irq_wake(swrm->irq, 0);
|
||||||
|
free_irq(swrm->irq, swrm);
|
||||||
|
}
|
||||||
err_irq_fail:
|
err_irq_fail:
|
||||||
mutex_destroy(&swrm->irq_lock);
|
mutex_destroy(&swrm->irq_lock);
|
||||||
mutex_destroy(&swrm->mlock);
|
mutex_destroy(&swrm->mlock);
|
||||||
@@ -2751,15 +2767,15 @@ static int swrm_remove(struct platform_device *pdev)
|
|||||||
swrm->reg_irq(swrm->handle, swr_mstr_interrupt,
|
swrm->reg_irq(swrm->handle, swr_mstr_interrupt,
|
||||||
swrm, SWR_IRQ_FREE);
|
swrm, SWR_IRQ_FREE);
|
||||||
} else if (swrm->irq) {
|
} else if (swrm->irq) {
|
||||||
free_irq(swrm->irq, swrm);
|
|
||||||
irqd_set_trigger_type(
|
irqd_set_trigger_type(
|
||||||
irq_get_irq_data(swrm->irq),
|
irq_get_irq_data(swrm->irq),
|
||||||
IRQ_TYPE_NONE);
|
IRQ_TYPE_NONE);
|
||||||
|
if (swrm->swr_irq_wakeup_capable)
|
||||||
|
irq_set_irq_wake(swrm->irq, 0);
|
||||||
|
free_irq(swrm->irq, swrm);
|
||||||
} else if (swrm->wake_irq > 0) {
|
} else if (swrm->wake_irq > 0) {
|
||||||
free_irq(swrm->wake_irq, swrm);
|
free_irq(swrm->wake_irq, swrm);
|
||||||
}
|
}
|
||||||
if (swrm->swr_irq_wakeup_capable)
|
|
||||||
irq_set_irq_wake(swrm->irq, 0);
|
|
||||||
cancel_work_sync(&swrm->wakeup_work);
|
cancel_work_sync(&swrm->wakeup_work);
|
||||||
pm_runtime_disable(&pdev->dev);
|
pm_runtime_disable(&pdev->dev);
|
||||||
pm_runtime_set_suspended(&pdev->dev);
|
pm_runtime_set_suspended(&pdev->dev);
|
||||||
@@ -2799,7 +2815,6 @@ static int swrm_runtime_resume(struct device *dev)
|
|||||||
int ret = 0;
|
int ret = 0;
|
||||||
bool swrm_clk_req_err = false;
|
bool swrm_clk_req_err = false;
|
||||||
bool hw_core_err = false;
|
bool hw_core_err = false;
|
||||||
bool aud_core_err = false;
|
|
||||||
struct swr_master *mstr = &swrm->master;
|
struct swr_master *mstr = &swrm->master;
|
||||||
struct swr_device *swr_dev;
|
struct swr_device *swr_dev;
|
||||||
u32 temp = 0;
|
u32 temp = 0;
|
||||||
@@ -2815,11 +2830,9 @@ static int swrm_runtime_resume(struct device *dev)
|
|||||||
__func__);
|
__func__);
|
||||||
hw_core_err = true;
|
hw_core_err = true;
|
||||||
}
|
}
|
||||||
if (swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, true)) {
|
if (swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, true))
|
||||||
dev_err(dev, "%s:lpass audio hw enable failed\n",
|
dev_err(dev, "%s:lpass audio hw enable failed\n",
|
||||||
__func__);
|
__func__);
|
||||||
aud_core_err = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((swrm->state == SWR_MSTR_DOWN) ||
|
if ((swrm->state == SWR_MSTR_DOWN) ||
|
||||||
(swrm->state == SWR_MSTR_SSR && swrm->dev_up)) {
|
(swrm->state == SWR_MSTR_SSR && swrm->dev_up)) {
|
||||||
@@ -2911,8 +2924,6 @@ static int swrm_runtime_resume(struct device *dev)
|
|||||||
swrm->state = SWR_MSTR_UP;
|
swrm->state = SWR_MSTR_UP;
|
||||||
}
|
}
|
||||||
exit:
|
exit:
|
||||||
if (!aud_core_err)
|
|
||||||
swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, false);
|
|
||||||
if (!hw_core_err)
|
if (!hw_core_err)
|
||||||
swrm_request_hw_vote(swrm, LPASS_HW_CORE, false);
|
swrm_request_hw_vote(swrm, LPASS_HW_CORE, false);
|
||||||
if (swrm_clk_req_err)
|
if (swrm_clk_req_err)
|
||||||
@@ -2921,6 +2932,8 @@ exit:
|
|||||||
else
|
else
|
||||||
pm_runtime_set_autosuspend_delay(&pdev->dev,
|
pm_runtime_set_autosuspend_delay(&pdev->dev,
|
||||||
auto_suspend_timer);
|
auto_suspend_timer);
|
||||||
|
if (swrm->req_clk_switch)
|
||||||
|
swrm->req_clk_switch = false;
|
||||||
mutex_unlock(&swrm->reslock);
|
mutex_unlock(&swrm->reslock);
|
||||||
|
|
||||||
trace_printk("%s: pm_runtime: resume done, state:%d\n",
|
trace_printk("%s: pm_runtime: resume done, state:%d\n",
|
||||||
@@ -2934,7 +2947,6 @@ static int swrm_runtime_suspend(struct device *dev)
|
|||||||
struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev);
|
struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev);
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
bool hw_core_err = false;
|
bool hw_core_err = false;
|
||||||
bool aud_core_err = false;
|
|
||||||
struct swr_master *mstr = &swrm->master;
|
struct swr_master *mstr = &swrm->master;
|
||||||
struct swr_device *swr_dev;
|
struct swr_device *swr_dev;
|
||||||
int current_state = 0;
|
int current_state = 0;
|
||||||
@@ -2953,11 +2965,6 @@ static int swrm_runtime_suspend(struct device *dev)
|
|||||||
__func__);
|
__func__);
|
||||||
hw_core_err = true;
|
hw_core_err = true;
|
||||||
}
|
}
|
||||||
if (swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, true)) {
|
|
||||||
dev_err(dev, "%s:lpass audio hw enable failed\n",
|
|
||||||
__func__);
|
|
||||||
aud_core_err = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((current_state == SWR_MSTR_UP) ||
|
if ((current_state == SWR_MSTR_UP) ||
|
||||||
(current_state == SWR_MSTR_SSR)) {
|
(current_state == SWR_MSTR_SSR)) {
|
||||||
@@ -3036,12 +3043,14 @@ static int swrm_runtime_suspend(struct device *dev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
if (swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, false))
|
||||||
|
dev_dbg(dev, "%s:lpass audio hw enable failed\n",
|
||||||
|
__func__);
|
||||||
|
|
||||||
/* Retain SSR state until resume */
|
/* Retain SSR state until resume */
|
||||||
if (current_state != SWR_MSTR_SSR)
|
if (current_state != SWR_MSTR_SSR)
|
||||||
swrm->state = SWR_MSTR_DOWN;
|
swrm->state = SWR_MSTR_DOWN;
|
||||||
exit:
|
exit:
|
||||||
if (!aud_core_err)
|
|
||||||
swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, false);
|
|
||||||
if (!hw_core_err)
|
if (!hw_core_err)
|
||||||
swrm_request_hw_vote(swrm, LPASS_HW_CORE, false);
|
swrm_request_hw_vote(swrm, LPASS_HW_CORE, false);
|
||||||
mutex_unlock(&swrm->reslock);
|
mutex_unlock(&swrm->reslock);
|
||||||
@@ -3214,8 +3223,12 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data)
|
|||||||
}
|
}
|
||||||
mutex_lock(&swrm->mlock);
|
mutex_lock(&swrm->mlock);
|
||||||
if (swrm->clk_src != *(int *)data) {
|
if (swrm->clk_src != *(int *)data) {
|
||||||
if (swrm->state == SWR_MSTR_UP)
|
if (swrm->state == SWR_MSTR_UP) {
|
||||||
|
swrm->req_clk_switch = true;
|
||||||
swrm_device_suspend(&pdev->dev);
|
swrm_device_suspend(&pdev->dev);
|
||||||
|
if (swrm->state == SWR_MSTR_UP)
|
||||||
|
swrm->req_clk_switch = false;
|
||||||
|
}
|
||||||
swrm->clk_src = *(int *)data;
|
swrm->clk_src = *(int *)data;
|
||||||
}
|
}
|
||||||
mutex_unlock(&swrm->mlock);
|
mutex_unlock(&swrm->mlock);
|
||||||
|
@@ -175,6 +175,7 @@ struct swr_mstr_ctrl {
|
|||||||
u32 ipc_wakeup;
|
u32 ipc_wakeup;
|
||||||
bool dev_up;
|
bool dev_up;
|
||||||
bool ipc_wakeup_triggered;
|
bool ipc_wakeup_triggered;
|
||||||
|
bool req_clk_switch;
|
||||||
struct pm_qos_request pm_qos_req;
|
struct pm_qos_request pm_qos_req;
|
||||||
enum swrm_pm_state pm_state;
|
enum swrm_pm_state pm_state;
|
||||||
wait_queue_head_t pm_wq;
|
wait_queue_head_t pm_wq;
|
||||||
|
Reference in New Issue
Block a user