mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-10 22:40:54 -04:00
Merge "ASoC: msm: update QUAT/QUIN TDM slot mappings for A2B"
This commit is contained in:
commit
b8e5bd2fc8
8 changed files with 432 additions and 195 deletions
|
|
@ -1,5 +1,5 @@
|
|||
// 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/of_platform.h>
|
||||
|
|
@ -476,6 +476,129 @@ void bolero_unregister_res_clk(struct device *dev)
|
|||
}
|
||||
EXPORT_SYMBOL(bolero_unregister_res_clk);
|
||||
|
||||
static u8 bolero_dmic_clk_div_get(struct snd_soc_component *component,
|
||||
int mode)
|
||||
{
|
||||
struct bolero_priv* priv = snd_soc_component_get_drvdata(component);
|
||||
int macro = (mode ? VA_MACRO : TX_MACRO);
|
||||
int ret = 0;
|
||||
|
||||
if (priv->macro_params[macro].clk_div_get) {
|
||||
ret = priv->macro_params[macro].clk_div_get(component);
|
||||
if (ret > 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int bolero_dmic_clk_enable(struct snd_soc_component *component,
|
||||
u32 dmic, u32 tx_mode, bool enable)
|
||||
{
|
||||
struct bolero_priv* priv = snd_soc_component_get_drvdata(component);
|
||||
u8 dmic_clk_en = 0x01;
|
||||
u16 dmic_clk_reg = 0;
|
||||
s32 *dmic_clk_cnt = NULL;
|
||||
u8 *dmic_clk_div = NULL;
|
||||
u8 freq_change_mask = 0;
|
||||
u8 clk_div = 0;
|
||||
|
||||
dev_dbg(component->dev, "%s: enable: %d, tx_mode:%d, dmic: %d\n",
|
||||
__func__, enable, tx_mode, dmic);
|
||||
|
||||
switch (dmic) {
|
||||
case 0:
|
||||
case 1:
|
||||
dmic_clk_cnt = &(priv->dmic_0_1_clk_cnt);
|
||||
dmic_clk_div = &(priv->dmic_0_1_clk_div);
|
||||
dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC0_CTL;
|
||||
freq_change_mask = 0x01;
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
dmic_clk_cnt = &(priv->dmic_2_3_clk_cnt);
|
||||
dmic_clk_div = &(priv->dmic_2_3_clk_div);
|
||||
dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC1_CTL;
|
||||
freq_change_mask = 0x02;
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
dmic_clk_cnt = &(priv->dmic_4_5_clk_cnt);
|
||||
dmic_clk_div = &(priv->dmic_4_5_clk_div);
|
||||
dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC2_CTL;
|
||||
freq_change_mask = 0x04;
|
||||
break;
|
||||
case 6:
|
||||
case 7:
|
||||
dmic_clk_cnt = &(priv->dmic_6_7_clk_cnt);
|
||||
dmic_clk_div = &(priv->dmic_6_7_clk_div);
|
||||
dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC3_CTL;
|
||||
freq_change_mask = 0x08;
|
||||
break;
|
||||
default:
|
||||
dev_err(component->dev, "%s: Invalid DMIC Selection\n",
|
||||
__func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
dev_dbg(component->dev, "%s: DMIC%d dmic_clk_cnt %d\n",
|
||||
__func__, dmic, *dmic_clk_cnt);
|
||||
if (enable) {
|
||||
clk_div = bolero_dmic_clk_div_get(component, tx_mode);
|
||||
(*dmic_clk_cnt)++;
|
||||
if (*dmic_clk_cnt == 1) {
|
||||
snd_soc_component_update_bits(component,
|
||||
BOLERO_CDC_VA_TOP_CSR_DMIC_CFG,
|
||||
0x80, 0x00);
|
||||
snd_soc_component_update_bits(component, dmic_clk_reg,
|
||||
0x0E, clk_div << 0x1);
|
||||
snd_soc_component_update_bits(component, dmic_clk_reg,
|
||||
dmic_clk_en, dmic_clk_en);
|
||||
} else {
|
||||
if (*dmic_clk_div > clk_div) {
|
||||
snd_soc_component_update_bits(component,
|
||||
BOLERO_CDC_VA_TOP_CSR_DMIC_CFG,
|
||||
freq_change_mask, freq_change_mask);
|
||||
snd_soc_component_update_bits(component, dmic_clk_reg,
|
||||
0x0E, clk_div << 0x1);
|
||||
snd_soc_component_update_bits(component,
|
||||
BOLERO_CDC_VA_TOP_CSR_DMIC_CFG,
|
||||
freq_change_mask, 0x00);
|
||||
} else {
|
||||
clk_div = *dmic_clk_div;
|
||||
}
|
||||
}
|
||||
*dmic_clk_div = clk_div;
|
||||
} else {
|
||||
(*dmic_clk_cnt)--;
|
||||
if (*dmic_clk_cnt == 0) {
|
||||
snd_soc_component_update_bits(component, dmic_clk_reg,
|
||||
dmic_clk_en, 0);
|
||||
clk_div = 0;
|
||||
snd_soc_component_update_bits(component, dmic_clk_reg,
|
||||
0x0E, clk_div << 0x1);
|
||||
} else {
|
||||
clk_div = bolero_dmic_clk_div_get(component, tx_mode);
|
||||
if (*dmic_clk_div > clk_div) {
|
||||
clk_div = bolero_dmic_clk_div_get(component, !tx_mode);
|
||||
snd_soc_component_update_bits(component,
|
||||
BOLERO_CDC_VA_TOP_CSR_DMIC_CFG,
|
||||
freq_change_mask, freq_change_mask);
|
||||
snd_soc_component_update_bits(component, dmic_clk_reg,
|
||||
0x0E, clk_div << 0x1);
|
||||
snd_soc_component_update_bits(component,
|
||||
BOLERO_CDC_VA_TOP_CSR_DMIC_CFG,
|
||||
freq_change_mask, 0x00);
|
||||
} else {
|
||||
clk_div = *dmic_clk_div;
|
||||
}
|
||||
}
|
||||
*dmic_clk_div = clk_div;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(bolero_dmic_clk_enable);
|
||||
|
||||
/**
|
||||
* bolero_register_macro - Registers macro to bolero
|
||||
*
|
||||
|
|
@ -524,6 +647,9 @@ int bolero_register_macro(struct device *dev, u16 macro_id,
|
|||
priv->macro_params[macro_id].reg_evt_listener =
|
||||
ops->reg_evt_listener;
|
||||
}
|
||||
if (macro_id == TX_MACRO || macro_id == VA_MACRO)
|
||||
priv->macro_params[macro_id].clk_div_get = ops->clk_div_get;
|
||||
|
||||
if (priv->version == BOLERO_VERSION_2_1) {
|
||||
if (macro_id == VA_MACRO)
|
||||
priv->macro_params[macro_id].reg_wake_irq =
|
||||
|
|
@ -594,6 +720,8 @@ void bolero_unregister_macro(struct device *dev, u16 macro_id)
|
|||
priv->macro_params[macro_id].clk_switch = NULL;
|
||||
priv->macro_params[macro_id].reg_evt_listener = NULL;
|
||||
}
|
||||
if (macro_id == TX_MACRO || macro_id == VA_MACRO)
|
||||
priv->macro_params[macro_id].clk_div_get = NULL;
|
||||
|
||||
priv->num_dais -= priv->macro_params[macro_id].num_dais;
|
||||
priv->num_macros_registered--;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/* 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 BOLERO_CDC_H
|
||||
|
|
@ -50,6 +50,12 @@ enum {
|
|||
BOLERO_MACRO_EVT_BCS_CLK_OFF
|
||||
};
|
||||
|
||||
enum {
|
||||
DMIC_TX = 0,
|
||||
DMIC_VA = 1,
|
||||
|
||||
};
|
||||
|
||||
struct macro_ops {
|
||||
int (*init)(struct snd_soc_component *component);
|
||||
int (*exit)(struct snd_soc_component *component);
|
||||
|
|
@ -63,6 +69,7 @@ struct macro_ops {
|
|||
int (*set_port_map)(struct snd_soc_component *component, u32 uc,
|
||||
u32 size, void *data);
|
||||
int (*clk_switch)(struct snd_soc_component *component);
|
||||
int (*clk_div_get)(struct snd_soc_component *component);
|
||||
int (*reg_evt_listener)(struct snd_soc_component *component, bool en);
|
||||
char __iomem *io_base;
|
||||
u16 clk_id_req;
|
||||
|
|
@ -93,6 +100,8 @@ int bolero_register_event_listener(struct snd_soc_component *component,
|
|||
void bolero_wsa_pa_on(struct device *dev);
|
||||
bool bolero_check_core_votes(struct device *dev);
|
||||
int bolero_get_version(struct device *dev);
|
||||
int bolero_dmic_clk_enable(struct snd_soc_component *component,
|
||||
u32 dmic, u32 tx_mode, bool enable);
|
||||
#else
|
||||
static inline int bolero_register_res_clk(struct device *dev, rsc_clk_cb_t cb)
|
||||
{
|
||||
|
|
@ -177,5 +186,11 @@ static int bolero_get_version(struct device *dev)
|
|||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bolero_dmic_clk_enable(struct snd_soc_component *component,
|
||||
u32 dmic, u32 tx_mode, bool enable)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_SND_SOC_BOLERO */
|
||||
#endif /* BOLERO_CDC_H */
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/* 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 _BOLERO_INTERNAL_H
|
||||
|
|
@ -82,6 +82,14 @@ struct bolero_priv {
|
|||
struct blocking_notifier_head notifier;
|
||||
struct device *clk_dev;
|
||||
rsc_clk_cb_t rsc_clk_cb;
|
||||
s32 dmic_0_1_clk_cnt;
|
||||
s32 dmic_2_3_clk_cnt;
|
||||
s32 dmic_4_5_clk_cnt;
|
||||
s32 dmic_6_7_clk_cnt;
|
||||
u8 dmic_0_1_clk_div;
|
||||
u8 dmic_2_3_clk_div;
|
||||
u8 dmic_4_5_clk_div;
|
||||
u8 dmic_6_7_clk_div;
|
||||
};
|
||||
|
||||
struct regmap *bolero_regmap_init(struct device *dev,
|
||||
|
|
|
|||
|
|
@ -158,10 +158,6 @@ struct tx_macro_priv {
|
|||
struct work_struct tx_macro_add_child_devices_work;
|
||||
struct hpf_work tx_hpf_work[NUM_DECIMATORS];
|
||||
struct tx_mute_work tx_mute_dwork[NUM_DECIMATORS];
|
||||
s32 dmic_0_1_clk_cnt;
|
||||
s32 dmic_2_3_clk_cnt;
|
||||
s32 dmic_4_5_clk_cnt;
|
||||
s32 dmic_6_7_clk_cnt;
|
||||
u16 dmic_clk_div;
|
||||
u32 version;
|
||||
u32 is_used_tx_swr_gpio;
|
||||
|
|
@ -814,17 +810,9 @@ static int tx_macro_enable_dmic(struct snd_soc_dapm_widget *w,
|
|||
{
|
||||
struct snd_soc_component *component =
|
||||
snd_soc_dapm_to_component(w->dapm);
|
||||
u8 dmic_clk_en = 0x01;
|
||||
u16 dmic_clk_reg = 0;
|
||||
s32 *dmic_clk_cnt = NULL;
|
||||
unsigned int dmic = 0;
|
||||
int ret = 0;
|
||||
char *wname = NULL;
|
||||
struct device *tx_dev = NULL;
|
||||
struct tx_macro_priv *tx_priv = NULL;
|
||||
|
||||
if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
|
||||
return -EINVAL;
|
||||
|
||||
wname = strpbrk(w->name, "01234567");
|
||||
if (!wname) {
|
||||
|
|
@ -839,54 +827,15 @@ static int tx_macro_enable_dmic(struct snd_soc_dapm_widget *w,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (dmic) {
|
||||
case 0:
|
||||
case 1:
|
||||
dmic_clk_cnt = &(tx_priv->dmic_0_1_clk_cnt);
|
||||
dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC0_CTL;
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
dmic_clk_cnt = &(tx_priv->dmic_2_3_clk_cnt);
|
||||
dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC1_CTL;
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
dmic_clk_cnt = &(tx_priv->dmic_4_5_clk_cnt);
|
||||
dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC2_CTL;
|
||||
break;
|
||||
case 6:
|
||||
case 7:
|
||||
dmic_clk_cnt = &(tx_priv->dmic_6_7_clk_cnt);
|
||||
dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC3_CTL;
|
||||
break;
|
||||
default:
|
||||
dev_err(component->dev, "%s: Invalid DMIC Selection\n",
|
||||
__func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
dev_dbg(component->dev, "%s: event %d DMIC%d dmic_clk_cnt %d\n",
|
||||
__func__, event, dmic, *dmic_clk_cnt);
|
||||
dev_dbg(component->dev, "%s: event %d DMIC%d\n",
|
||||
__func__, event, dmic);
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_PRE_PMU:
|
||||
(*dmic_clk_cnt)++;
|
||||
if (*dmic_clk_cnt == 1) {
|
||||
snd_soc_component_update_bits(component,
|
||||
BOLERO_CDC_VA_TOP_CSR_DMIC_CFG,
|
||||
0x80, 0x00);
|
||||
|
||||
snd_soc_component_update_bits(component, dmic_clk_reg,
|
||||
0x0E, tx_priv->dmic_clk_div << 0x1);
|
||||
snd_soc_component_update_bits(component, dmic_clk_reg,
|
||||
dmic_clk_en, dmic_clk_en);
|
||||
}
|
||||
bolero_dmic_clk_enable(component, dmic, DMIC_TX, true);
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMD:
|
||||
(*dmic_clk_cnt)--;
|
||||
if (*dmic_clk_cnt == 0)
|
||||
snd_soc_component_update_bits(component, dmic_clk_reg,
|
||||
dmic_clk_en, 0);
|
||||
bolero_dmic_clk_enable(component, dmic, DMIC_TX, false);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -2665,6 +2614,17 @@ exit:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int tx_macro_clk_div_get(struct snd_soc_component *component)
|
||||
{
|
||||
struct device *tx_dev = NULL;
|
||||
struct tx_macro_priv *tx_priv = NULL;
|
||||
|
||||
if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
|
||||
return -EINVAL;
|
||||
|
||||
return tx_priv->dmic_clk_div;
|
||||
}
|
||||
|
||||
static int tx_macro_clk_switch(struct snd_soc_component *component)
|
||||
{
|
||||
struct device *tx_dev = NULL;
|
||||
|
|
@ -3168,6 +3128,7 @@ static void tx_macro_init_ops(struct macro_ops *ops,
|
|||
ops->event_handler = tx_macro_event_handler;
|
||||
ops->reg_wake_irq = tx_macro_reg_wake_irq;
|
||||
ops->set_port_map = tx_macro_set_port_map;
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -142,10 +142,6 @@ struct va_macro_priv {
|
|||
struct va_mute_work va_mute_dwork[VA_MACRO_NUM_DECIMATORS];
|
||||
unsigned long active_ch_mask[VA_MACRO_MAX_DAIS];
|
||||
unsigned long active_ch_cnt[VA_MACRO_MAX_DAIS];
|
||||
s32 dmic_0_1_clk_cnt;
|
||||
s32 dmic_2_3_clk_cnt;
|
||||
s32 dmic_4_5_clk_cnt;
|
||||
s32 dmic_6_7_clk_cnt;
|
||||
u16 dmic_clk_div;
|
||||
u16 va_mclk_users;
|
||||
int swr_clk_users;
|
||||
|
|
@ -196,6 +192,17 @@ static bool va_macro_get_data(struct snd_soc_component *component,
|
|||
return true;
|
||||
}
|
||||
|
||||
static int va_macro_clk_div_get(struct snd_soc_component *component)
|
||||
{
|
||||
struct device *va_dev = NULL;
|
||||
struct va_macro_priv *va_priv = NULL;
|
||||
|
||||
if (!va_macro_get_data(component, &va_dev, &va_priv, __func__))
|
||||
return -EINVAL;
|
||||
|
||||
return va_priv->dmic_clk_div;
|
||||
}
|
||||
|
||||
static int va_macro_mclk_enable(struct va_macro_priv *va_priv,
|
||||
bool mclk_enable, bool dapm)
|
||||
{
|
||||
|
|
@ -978,81 +985,32 @@ static int va_macro_enable_dmic(struct snd_soc_dapm_widget *w,
|
|||
{
|
||||
struct snd_soc_component *component =
|
||||
snd_soc_dapm_to_component(w->dapm);
|
||||
u8 dmic_clk_en = 0x01;
|
||||
u16 dmic_clk_reg;
|
||||
s32 *dmic_clk_cnt;
|
||||
unsigned int dmic;
|
||||
int ret;
|
||||
unsigned int dmic = 0;
|
||||
int ret = 0;
|
||||
char *wname;
|
||||
struct device *va_dev = NULL;
|
||||
struct va_macro_priv *va_priv = NULL;
|
||||
|
||||
if (!va_macro_get_data(component, &va_dev, &va_priv, __func__))
|
||||
return -EINVAL;
|
||||
|
||||
wname = strpbrk(w->name, "01234567");
|
||||
if (!wname) {
|
||||
dev_err(va_dev, "%s: widget not found\n", __func__);
|
||||
dev_err(component->dev, "%s: widget not found\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = kstrtouint(wname, 10, &dmic);
|
||||
if (ret < 0) {
|
||||
dev_err(va_dev, "%s: Invalid DMIC line on the codec\n",
|
||||
dev_err(component->dev, "%s: Invalid DMIC line on the codec\n",
|
||||
__func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (dmic) {
|
||||
case 0:
|
||||
case 1:
|
||||
dmic_clk_cnt = &(va_priv->dmic_0_1_clk_cnt);
|
||||
dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC0_CTL;
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
dmic_clk_cnt = &(va_priv->dmic_2_3_clk_cnt);
|
||||
dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC1_CTL;
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
dmic_clk_cnt = &(va_priv->dmic_4_5_clk_cnt);
|
||||
dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC2_CTL;
|
||||
break;
|
||||
case 6:
|
||||
case 7:
|
||||
dmic_clk_cnt = &(va_priv->dmic_6_7_clk_cnt);
|
||||
dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC3_CTL;
|
||||
break;
|
||||
default:
|
||||
dev_err(va_dev, "%s: Invalid DMIC Selection\n",
|
||||
__func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
dev_dbg(va_dev, "%s: event %d DMIC%d dmic_clk_cnt %d\n",
|
||||
__func__, event, dmic, *dmic_clk_cnt);
|
||||
dev_dbg(component->dev, "%s: event %d DMIC%d\n",
|
||||
__func__, event, dmic);
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_PRE_PMU:
|
||||
(*dmic_clk_cnt)++;
|
||||
if (*dmic_clk_cnt == 1) {
|
||||
snd_soc_component_update_bits(component,
|
||||
BOLERO_CDC_VA_TOP_CSR_DMIC_CFG,
|
||||
0x80, 0x00);
|
||||
snd_soc_component_update_bits(component, dmic_clk_reg,
|
||||
VA_MACRO_TX_DMIC_CLK_DIV_MASK,
|
||||
va_priv->dmic_clk_div <<
|
||||
VA_MACRO_TX_DMIC_CLK_DIV_SHFT);
|
||||
snd_soc_component_update_bits(component, dmic_clk_reg,
|
||||
dmic_clk_en, dmic_clk_en);
|
||||
}
|
||||
bolero_dmic_clk_enable(component, dmic, DMIC_VA, true);
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMD:
|
||||
(*dmic_clk_cnt)--;
|
||||
if (*dmic_clk_cnt == 0) {
|
||||
snd_soc_component_update_bits(component, dmic_clk_reg,
|
||||
dmic_clk_en, 0);
|
||||
}
|
||||
bolero_dmic_clk_enable(component, dmic, DMIC_VA, false);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -2834,6 +2792,7 @@ static void va_macro_init_ops(struct macro_ops *ops,
|
|||
ops->event_handler = va_macro_event_handler;
|
||||
ops->set_port_map = va_macro_set_port_map;
|
||||
ops->reg_wake_irq = va_macro_reg_wake_irq;
|
||||
ops->clk_div_get = va_macro_clk_div_get;
|
||||
}
|
||||
|
||||
static int va_macro_probe(struct platform_device *pdev)
|
||||
|
|
|
|||
|
|
@ -1,13 +1,4 @@
|
|||
/* Copyright (c) 2014-2019, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
/* Copyright (c) 2014-2020, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
/*
|
||||
* Copyright 2011, The Android Open Source Project
|
||||
|
|
@ -213,7 +204,7 @@ static struct dev_config tdm_rx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = {
|
|||
},
|
||||
{ /* QUAT TDM */
|
||||
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 8}, /* RX_0 */
|
||||
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */
|
||||
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 8}, /* RX_1 */
|
||||
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */
|
||||
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */
|
||||
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */
|
||||
|
|
@ -222,10 +213,10 @@ static struct dev_config tdm_rx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = {
|
|||
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */
|
||||
},
|
||||
{ /* QUIN TDM */
|
||||
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_0 */
|
||||
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_1 */
|
||||
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_2 */
|
||||
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_3 */
|
||||
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 6}, /* RX_0 */
|
||||
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */
|
||||
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */
|
||||
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */
|
||||
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */
|
||||
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */
|
||||
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */
|
||||
|
|
@ -276,9 +267,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 */
|
||||
},
|
||||
{ /* QUIN TDM */
|
||||
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 6}, /* TX_0 */
|
||||
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */
|
||||
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */
|
||||
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 4}, /* TX_0 */
|
||||
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* TX_1 */
|
||||
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* TX_2 */
|
||||
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */
|
||||
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */
|
||||
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */
|
||||
|
|
@ -415,20 +406,20 @@ static unsigned int tdm_rx_slot_offset
|
|||
{0xFFFF}, /* not used */
|
||||
},
|
||||
{/* QUAT TDM */
|
||||
{0, 4, 8, 12, 16, 20, 24, 28, 0xFFFF},/*AMP OUT*/
|
||||
{0, 8, 16, 24, 32, 40, 48, 56, 0xFFFF}, /*8 CH SPKR*/
|
||||
{4, 12, 20, 28, 36, 44, 52, 60, 0xFFFF}, /*8 CH SPKR*/
|
||||
{0xFFFF}, /* not used */
|
||||
{0xFFFF}, /* not used */
|
||||
{0xFFFF}, /* not used */
|
||||
{0xFFFF}, /* not used */
|
||||
{0xFFFF}, /* not used */
|
||||
{0xFFFF}, /* not used */
|
||||
{28,0xFFFF},
|
||||
{60,0xFFFF},
|
||||
},
|
||||
{/* QUIN TDM */
|
||||
{0, 4, 0xFFFF},/*STEREO SPKR1*/
|
||||
{8, 12, 0xFFFF},/*STEREO SPKR2*/
|
||||
{16, 20, 0xFFFF},/*STEREO SPKR3*/
|
||||
{24, 28, 0xFFFF},/*STEREO SPKR4*/
|
||||
{0, 4, 8, 12, 16, 20, 0xFFFF},
|
||||
{24, 0xFFFF},
|
||||
{28, 0xFFFF},
|
||||
{0xFFFF}, /* not used */
|
||||
{0xFFFF}, /* not used */
|
||||
{0xFFFF}, /* not used */
|
||||
{0xFFFF}, /* not used */
|
||||
|
|
@ -480,14 +471,14 @@ static unsigned int tdm_tx_slot_offset
|
|||
{60,0xFFFF},
|
||||
},
|
||||
{/* QUIN TDM */
|
||||
{0, 4, 8, 12, 16, 20, 0xFFFF},/*EC/ANC REF*/
|
||||
{0, 4, 8, 12, 0xFFFF},
|
||||
{16, 20, 0xFFFF},
|
||||
{24, 28, 0xFFFF},
|
||||
{0xFFFF}, /* not used */
|
||||
{0xFFFF}, /* not used */
|
||||
{0xFFFF}, /* not used */
|
||||
{0xFFFF}, /* not used */
|
||||
{0xFFFF}, /* not used */
|
||||
{0xFFFF}, /* not used */
|
||||
{20, 0xFFFF},
|
||||
{28, 0xFFFF},
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/* Copyright (c) 2014-2019, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2014-2020, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
/*
|
||||
* Copyright 2011, The Android Open Source Project
|
||||
|
|
@ -205,7 +205,7 @@ static struct dev_config tdm_rx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = {
|
|||
},
|
||||
{ /* QUAT TDM */
|
||||
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 8}, /* RX_0 */
|
||||
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */
|
||||
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 8}, /* RX_1 */
|
||||
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */
|
||||
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */
|
||||
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */
|
||||
|
|
@ -214,10 +214,10 @@ static struct dev_config tdm_rx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = {
|
|||
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */
|
||||
},
|
||||
{ /* QUIN TDM */
|
||||
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_0 */
|
||||
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_1 */
|
||||
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_2 */
|
||||
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_3 */
|
||||
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 16}, /* RX_0 */
|
||||
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */
|
||||
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */
|
||||
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */
|
||||
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */
|
||||
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */
|
||||
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */
|
||||
|
|
@ -268,7 +268,7 @@ static struct dev_config tdm_tx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = {
|
|||
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */
|
||||
},
|
||||
{ /* QUIN TDM */
|
||||
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 6}, /* TX_0 */
|
||||
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 16}, /* TX_0 */
|
||||
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */
|
||||
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */
|
||||
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */
|
||||
|
|
@ -407,24 +407,25 @@ static unsigned int tdm_rx_slot_offset
|
|||
{0xFFFF}, /* not used */
|
||||
},
|
||||
{/* QUAT TDM */
|
||||
{0, 4, 8, 12, 16, 20, 24, 28, 0xFFFF},/*AMP OUT*/
|
||||
{0, 8, 16, 24, 32, 40, 48, 56, 0xFFFF}, /*8 CH SPKR*/
|
||||
{4, 12, 20, 28, 36, 44, 52, 60, 0xFFFF}, /*8 CH SPKR*/
|
||||
{0xFFFF}, /* not used */
|
||||
{0xFFFF}, /* not used */
|
||||
{0xFFFF}, /* not used */
|
||||
{0xFFFF}, /* not used */
|
||||
{0xFFFF}, /* not used */
|
||||
{0xFFFF}, /* not used */
|
||||
{28,0xFFFF},
|
||||
{60,0xFFFF},
|
||||
},
|
||||
{/* QUIN TDM */
|
||||
{0, 4, 0xFFFF},/*STEREO SPKR1*/
|
||||
{8, 12, 0xFFFF},/*STEREO SPKR2*/
|
||||
{16, 20, 0xFFFF},/*STEREO SPKR3*/
|
||||
{24, 28, 0xFFFF},/*STEREO SPKR4*/
|
||||
{0, 8, 16, 24, 32, 40, 48, 56,
|
||||
4, 12, 20, 28, 36, 44, 52, 60, 0xFFFF}, /*16 CH SPKR*/
|
||||
{0xFFFF}, /* not used */
|
||||
{0xFFFF}, /* not used */
|
||||
{0xFFFF}, /* not used */
|
||||
{28, 0xFFFF},
|
||||
{0xFFFF}, /* not used */
|
||||
{0xFFFF}, /* not used */
|
||||
{0xFFFF}, /* not used */
|
||||
{60, 0xFFFF},
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -462,7 +463,7 @@ static unsigned int tdm_tx_slot_offset
|
|||
},
|
||||
{/* QUAT TDM */
|
||||
{0, 4, 8, 12, 16, 20, 24, 28,
|
||||
32, 36, 40, 44, 48, 52, 56, 60, 0xFFFF},/*MIC ARR*/
|
||||
32, 36, 40, 44, 48, 52, 56, 60, 0xFFFF},/*16 CH MIC ARR1*/
|
||||
{0xFFFF}, /* not used */
|
||||
{0xFFFF}, /* not used */
|
||||
{0xFFFF}, /* not used */
|
||||
|
|
@ -472,14 +473,15 @@ static unsigned int tdm_tx_slot_offset
|
|||
{60,0xFFFF},
|
||||
},
|
||||
{/* QUIN TDM */
|
||||
{0, 4, 8, 12, 16, 20, 0xFFFF},/*EC/ANC REF*/
|
||||
{0, 4, 8, 12, 16, 20, 24, 28,
|
||||
32, 36, 40, 44, 48, 52, 56, 60, 0xFFFF},/*16 CH MIC ARR2*/
|
||||
{0xFFFF}, /* not used */
|
||||
{0xFFFF}, /* not used */
|
||||
{0xFFFF}, /* not used */
|
||||
{0xFFFF}, /* not used */
|
||||
{0xFFFF}, /* not used */
|
||||
{0xFFFF}, /* not used */
|
||||
{20, 0xFFFF},
|
||||
{60, 0xFFFF},
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
231
dsp/q6afe.c
231
dsp/q6afe.c
|
|
@ -23,6 +23,7 @@
|
|||
#include "q6afecal-hwdep.h"
|
||||
|
||||
#define WAKELOCK_TIMEOUT 5000
|
||||
#define AFE_CLK_TOKEN 1024
|
||||
enum {
|
||||
AFE_COMMON_RX_CAL = 0,
|
||||
AFE_COMMON_TX_CAL,
|
||||
|
|
@ -106,8 +107,11 @@ struct afe_ctl {
|
|||
void *apr;
|
||||
atomic_t state;
|
||||
atomic_t status;
|
||||
atomic_t clk_state;
|
||||
atomic_t clk_status;
|
||||
wait_queue_head_t wait[AFE_MAX_PORTS];
|
||||
wait_queue_head_t wait_wakeup;
|
||||
wait_queue_head_t clk_wait;
|
||||
struct task_struct *task;
|
||||
wait_queue_head_t lpass_core_hw_wait;
|
||||
uint32_t lpass_hw_core_client_hdl[AFE_LPASS_CORE_HW_VOTE_MAX];
|
||||
|
|
@ -154,6 +158,7 @@ struct afe_ctl {
|
|||
struct aanc_data aanc_info;
|
||||
struct mutex afe_cmd_lock;
|
||||
struct mutex afe_apr_lock;
|
||||
struct mutex afe_clk_lock;
|
||||
int set_custom_topology;
|
||||
int dev_acdb_id[AFE_MAX_PORTS];
|
||||
routing_cb rt_cb;
|
||||
|
|
@ -680,8 +685,8 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv)
|
|||
if (data->token < AFE_LPASS_CORE_HW_VOTE_MAX)
|
||||
this_afe.lpass_hw_core_client_hdl[data->token] =
|
||||
payload[0];
|
||||
atomic_set(&this_afe.state, 0);
|
||||
atomic_set(&this_afe.status, 0);
|
||||
atomic_set(&this_afe.clk_state, 0);
|
||||
atomic_set(&this_afe.clk_status, 0);
|
||||
wake_up(&this_afe.lpass_core_hw_wait);
|
||||
} else if (data->payload_size) {
|
||||
uint32_t *payload;
|
||||
|
|
@ -699,7 +704,10 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv)
|
|||
payload[0], payload[1], data->token);
|
||||
/* payload[1] contains the error status for response */
|
||||
if (payload[1] != 0) {
|
||||
atomic_set(&this_afe.status, payload[1]);
|
||||
if(data->token == AFE_CLK_TOKEN)
|
||||
atomic_set(&this_afe.clk_status, payload[1]);
|
||||
else
|
||||
atomic_set(&this_afe.status, payload[1]);
|
||||
pr_err("%s: cmd = 0x%x returned error = 0x%x\n",
|
||||
__func__, payload[0], payload[1]);
|
||||
}
|
||||
|
|
@ -720,11 +728,16 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv)
|
|||
case AFE_SVC_CMD_SET_PARAM:
|
||||
case AFE_SVC_CMD_SET_PARAM_V2:
|
||||
case AFE_PORT_CMD_MOD_EVENT_CFG:
|
||||
atomic_set(&this_afe.state, 0);
|
||||
if (afe_token_is_valid(data->token))
|
||||
wake_up(&this_afe.wait[data->token]);
|
||||
else
|
||||
return -EINVAL;
|
||||
if(data->token == AFE_CLK_TOKEN) {
|
||||
atomic_set(&this_afe.clk_state, 0);
|
||||
wake_up(&this_afe.clk_wait);
|
||||
} else {
|
||||
atomic_set(&this_afe.state, 0);
|
||||
if (afe_token_is_valid(data->token))
|
||||
wake_up(&this_afe.wait[data->token]);
|
||||
else
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
case AFE_SERVICE_CMD_REGISTER_RT_PORT_DRIVER:
|
||||
break;
|
||||
|
|
@ -770,7 +783,9 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv)
|
|||
break;
|
||||
case AFE_CMD_REMOTE_LPASS_CORE_HW_VOTE_REQUEST:
|
||||
case AFE_CMD_REMOTE_LPASS_CORE_HW_DEVOTE_REQUEST:
|
||||
atomic_set(&this_afe.state, 0);
|
||||
if (payload[1] != 0)
|
||||
atomic_set(&this_afe.clk_state,
|
||||
payload[1]);
|
||||
wake_up(&this_afe.lpass_core_hw_wait);
|
||||
break;
|
||||
case AFE_SVC_CMD_EVENT_CFG:
|
||||
|
|
@ -1090,6 +1105,46 @@ static int afe_apr_send_pkt(void *data, wait_queue_head_t *wait)
|
|||
mutex_unlock(&this_afe.afe_apr_lock);
|
||||
return ret;
|
||||
}
|
||||
/*
|
||||
* afe_apr_send_clk_pkt : returns 0 on success, negative otherwise.
|
||||
*/
|
||||
static int afe_apr_send_clk_pkt(void *data, wait_queue_head_t *wait)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (wait)
|
||||
atomic_set(&this_afe.clk_state, 1);
|
||||
atomic_set(&this_afe.clk_status, 0);
|
||||
ret = apr_send_pkt(this_afe.apr, data);
|
||||
if (ret > 0) {
|
||||
if (wait) {
|
||||
ret = wait_event_timeout(*wait,
|
||||
(atomic_read(&this_afe.clk_state) == 0),
|
||||
msecs_to_jiffies(2 * TIMEOUT_MS));
|
||||
if (!ret) {
|
||||
pr_err("%s: timeout\n", __func__);
|
||||
ret = -ETIMEDOUT;
|
||||
} else if (atomic_read(&this_afe.clk_status) > 0) {
|
||||
pr_err("%s: DSP returned error[%s]\n", __func__,
|
||||
adsp_err_get_err_str(atomic_read(
|
||||
&this_afe.clk_status)));
|
||||
ret = adsp_err_get_lnx_err_code(
|
||||
atomic_read(&this_afe.clk_status));
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
} else if (ret == 0) {
|
||||
pr_err("%s: packet not transmitted\n", __func__);
|
||||
/* apr_send_pkt can return 0 when nothing is transmitted */
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
pr_debug("%s: leave %d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* This function shouldn't be called directly. Instead call q6afe_set_params. */
|
||||
static int q6afe_set_params_v2(u16 port_id, int index,
|
||||
|
|
@ -1486,6 +1541,122 @@ done:
|
|||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function shouldn't be called directly. Instead call
|
||||
* q6afe_clk_set_params.
|
||||
*/
|
||||
static int q6afe_clk_set_params_v1(int index, struct mem_mapping_hdr *mem_hdr,
|
||||
u8 *packed_param_data, u32 packed_data_size)
|
||||
{
|
||||
struct afe_svc_cmd_set_param_v1 *svc_set_param = NULL;
|
||||
uint32_t size = sizeof(struct afe_svc_cmd_set_param_v1);
|
||||
int rc = 0;
|
||||
|
||||
if (packed_param_data != NULL)
|
||||
size += packed_data_size;
|
||||
svc_set_param = kzalloc(size, GFP_KERNEL);
|
||||
if (svc_set_param == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
svc_set_param->apr_hdr.hdr_field =
|
||||
APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE),
|
||||
APR_PKT_VER);
|
||||
svc_set_param->apr_hdr.pkt_size = size;
|
||||
svc_set_param->apr_hdr.src_port = 0;
|
||||
svc_set_param->apr_hdr.dest_port = 0;
|
||||
svc_set_param->apr_hdr.token = AFE_CLK_TOKEN;
|
||||
svc_set_param->apr_hdr.opcode = AFE_SVC_CMD_SET_PARAM;
|
||||
svc_set_param->payload_size = packed_data_size;
|
||||
|
||||
if (mem_hdr != NULL) {
|
||||
/* Out of band case. */
|
||||
svc_set_param->mem_hdr = *mem_hdr;
|
||||
} else if (packed_param_data != NULL) {
|
||||
/* In band case. */
|
||||
memcpy(&svc_set_param->param_data, packed_param_data,
|
||||
packed_data_size);
|
||||
} else {
|
||||
pr_err("%s: Both memory header and param data are NULL\n",
|
||||
__func__);
|
||||
rc = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
rc = afe_apr_send_clk_pkt(svc_set_param, &this_afe.clk_wait);
|
||||
done:
|
||||
kfree(svc_set_param);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function shouldn't be called directly. Instead call
|
||||
* q6afe_clk_set_params.
|
||||
*/
|
||||
static int q6afe_clk_set_params_v2(int index, struct mem_mapping_hdr *mem_hdr,
|
||||
u8 *packed_param_data, u32 packed_data_size)
|
||||
{
|
||||
struct afe_svc_cmd_set_param_v2 *svc_set_param = NULL;
|
||||
uint16_t size = sizeof(struct afe_svc_cmd_set_param_v2);
|
||||
int rc = 0;
|
||||
|
||||
if (packed_param_data != NULL)
|
||||
size += packed_data_size;
|
||||
svc_set_param = kzalloc(size, GFP_KERNEL);
|
||||
if (svc_set_param == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
svc_set_param->apr_hdr.hdr_field =
|
||||
APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE),
|
||||
APR_PKT_VER);
|
||||
svc_set_param->apr_hdr.pkt_size = size;
|
||||
svc_set_param->apr_hdr.src_port = 0;
|
||||
svc_set_param->apr_hdr.dest_port = 0;
|
||||
svc_set_param->apr_hdr.token = AFE_CLK_TOKEN;
|
||||
svc_set_param->apr_hdr.opcode = AFE_SVC_CMD_SET_PARAM_V2;
|
||||
svc_set_param->payload_size = packed_data_size;
|
||||
|
||||
if (mem_hdr != NULL) {
|
||||
/* Out of band case. */
|
||||
svc_set_param->mem_hdr = *mem_hdr;
|
||||
} else if (packed_param_data != NULL) {
|
||||
/* In band case. */
|
||||
memcpy(&svc_set_param->param_data, packed_param_data,
|
||||
packed_data_size);
|
||||
} else {
|
||||
pr_err("%s: Both memory header and param data are NULL\n",
|
||||
__func__);
|
||||
rc = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
rc = afe_apr_send_clk_pkt(svc_set_param, &this_afe.clk_wait);
|
||||
done:
|
||||
kfree(svc_set_param);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int q6afe_clk_set_params(int index, struct mem_mapping_hdr *mem_hdr,
|
||||
u8 *packed_param_data, u32 packed_data_size,
|
||||
bool is_iid_supported)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = afe_q6_interface_prepare();
|
||||
if (ret != 0) {
|
||||
pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (is_iid_supported)
|
||||
return q6afe_clk_set_params_v2(index, mem_hdr,
|
||||
packed_param_data,
|
||||
packed_data_size);
|
||||
else
|
||||
return q6afe_clk_set_params_v1(index, mem_hdr,
|
||||
packed_param_data,
|
||||
packed_data_size);
|
||||
}
|
||||
|
||||
static int q6afe_svc_set_params(int index, struct mem_mapping_hdr *mem_hdr,
|
||||
u8 *packed_param_data, u32 packed_data_size,
|
||||
bool is_iid_supported)
|
||||
|
|
@ -1530,9 +1701,12 @@ static int q6afe_svc_pack_and_set_param_in_band(int index,
|
|||
__func__, ret);
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = q6afe_svc_set_params(index, NULL, packed_param_data,
|
||||
packed_data_size, is_iid_supported);
|
||||
if (param_hdr.module_id == AFE_MODULE_CLOCK_SET)
|
||||
ret = q6afe_clk_set_params(index, NULL, packed_param_data,
|
||||
packed_data_size, is_iid_supported);
|
||||
else
|
||||
ret = q6afe_svc_set_params(index, NULL, packed_param_data,
|
||||
packed_data_size, is_iid_supported);
|
||||
|
||||
done:
|
||||
kfree(packed_param_data);
|
||||
|
|
@ -7655,13 +7829,7 @@ int afe_set_lpass_clk_cfg(int index, struct afe_clk_set *cfg)
|
|||
|
||||
memset(¶m_hdr, 0, sizeof(param_hdr));
|
||||
|
||||
ret = afe_q6_interface_prepare();
|
||||
if (ret != 0) {
|
||||
pr_err_ratelimited("%s: Q6 interface prepare failed %d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
mutex_lock(&this_afe.afe_cmd_lock);
|
||||
mutex_lock(&this_afe.afe_clk_lock);
|
||||
param_hdr.module_id = AFE_MODULE_CLOCK_SET;
|
||||
param_hdr.instance_id = INSTANCE_ID_0;
|
||||
param_hdr.param_id = AFE_PARAM_ID_CLOCK_SET;
|
||||
|
|
@ -7681,7 +7849,7 @@ int afe_set_lpass_clk_cfg(int index, struct afe_clk_set *cfg)
|
|||
pr_err_ratelimited("%s: AFE clk cfg failed with ret %d\n",
|
||||
__func__, ret);
|
||||
|
||||
mutex_unlock(&this_afe.afe_cmd_lock);
|
||||
mutex_unlock(&this_afe.afe_clk_lock);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(afe_set_lpass_clk_cfg);
|
||||
|
|
@ -9028,6 +9196,8 @@ int __init afe_init(void)
|
|||
|
||||
atomic_set(&this_afe.state, 0);
|
||||
atomic_set(&this_afe.status, 0);
|
||||
atomic_set(&this_afe.clk_state, 0);
|
||||
atomic_set(&this_afe.clk_status, 0);
|
||||
atomic_set(&this_afe.mem_map_cal_index, -1);
|
||||
this_afe.apr = NULL;
|
||||
this_afe.dtmf_gen_rx_portid = -1;
|
||||
|
|
@ -9041,6 +9211,7 @@ int __init afe_init(void)
|
|||
this_afe.ex_ftm_cfg.mode = MSM_SPKR_PROT_DISABLED;
|
||||
mutex_init(&this_afe.afe_cmd_lock);
|
||||
mutex_init(&this_afe.afe_apr_lock);
|
||||
mutex_init(&this_afe.afe_clk_lock);
|
||||
for (i = 0; i < AFE_MAX_PORTS; i++) {
|
||||
this_afe.afe_cal_mode[i] = AFE_CAL_MODE_DEFAULT;
|
||||
this_afe.afe_sample_rates[i] = 0;
|
||||
|
|
@ -9052,6 +9223,7 @@ int __init afe_init(void)
|
|||
}
|
||||
init_waitqueue_head(&this_afe.wait_wakeup);
|
||||
init_waitqueue_head(&this_afe.lpass_core_hw_wait);
|
||||
init_waitqueue_head(&this_afe.clk_wait);
|
||||
wl.ws = wakeup_source_register(NULL, "spkr-prot");
|
||||
if (!wl.ws)
|
||||
return -ENOMEM;
|
||||
|
|
@ -9101,6 +9273,7 @@ void afe_exit(void)
|
|||
config_debug_fs_exit();
|
||||
mutex_destroy(&this_afe.afe_cmd_lock);
|
||||
mutex_destroy(&this_afe.afe_apr_lock);
|
||||
mutex_destroy(&this_afe.afe_clk_lock);
|
||||
wakeup_source_unregister(wl.ws);
|
||||
}
|
||||
|
||||
|
|
@ -9164,7 +9337,7 @@ int afe_vote_lpass_core_hw(uint32_t hw_block_id, char *client_name,
|
|||
return ret;
|
||||
}
|
||||
|
||||
mutex_lock(&this_afe.afe_cmd_lock);
|
||||
mutex_lock(&this_afe.afe_clk_lock);
|
||||
|
||||
memset(cmd_ptr, 0, sizeof(hw_vote_cfg));
|
||||
|
||||
|
|
@ -9184,15 +9357,15 @@ int afe_vote_lpass_core_hw(uint32_t hw_block_id, char *client_name,
|
|||
__func__, cmd_ptr->hdr.opcode, cmd_ptr->hw_block_id);
|
||||
|
||||
*client_handle = 0;
|
||||
ret = afe_apr_send_pkt((uint32_t *) cmd_ptr,
|
||||
&this_afe.lpass_core_hw_wait);
|
||||
|
||||
ret = afe_apr_send_clk_pkt((uint32_t *)cmd_ptr,
|
||||
&this_afe.lpass_core_hw_wait);
|
||||
if (ret == 0) {
|
||||
*client_handle = this_afe.lpass_hw_core_client_hdl[hw_block_id];
|
||||
pr_debug("%s: lpass_hw_core_client_hdl %d\n", __func__,
|
||||
this_afe.lpass_hw_core_client_hdl[hw_block_id]);
|
||||
}
|
||||
|
||||
mutex_unlock(&this_afe.afe_cmd_lock);
|
||||
mutex_unlock(&this_afe.afe_clk_lock);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(afe_vote_lpass_core_hw);
|
||||
|
|
@ -9218,7 +9391,7 @@ int afe_unvote_lpass_core_hw(uint32_t hw_block_id, uint32_t client_handle)
|
|||
return ret;
|
||||
}
|
||||
|
||||
mutex_lock(&this_afe.afe_cmd_lock);
|
||||
mutex_lock(&this_afe.afe_clk_lock);
|
||||
|
||||
if (!this_afe.lpass_hw_core_client_hdl[hw_block_id]) {
|
||||
pr_debug("%s: SSR in progress, return\n", __func__);
|
||||
|
|
@ -9247,10 +9420,10 @@ int afe_unvote_lpass_core_hw(uint32_t hw_block_id, uint32_t client_handle)
|
|||
goto done;
|
||||
}
|
||||
|
||||
ret = afe_apr_send_pkt((uint32_t *) cmd_ptr,
|
||||
&this_afe.lpass_core_hw_wait);
|
||||
ret = afe_apr_send_clk_pkt((uint32_t *)cmd_ptr,
|
||||
&this_afe.lpass_core_hw_wait);
|
||||
done:
|
||||
mutex_unlock(&this_afe.afe_cmd_lock);
|
||||
mutex_unlock(&this_afe.afe_clk_lock);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(afe_unvote_lpass_core_hw);
|
||||
|
|
|
|||
Loading…
Reference in a new issue