Merge commit '1a7cee75ba63d6cce68924591b125d604bef39f5' into audio-kernel-5-4.lnx.1.0

Change-Id: Ie4363b4d1be12c7fd85e261bf728462009d8a2cf
This commit is contained in:
Vidyakumar Athota 2020-09-30 09:57:29 -07:00
commit 88c1c0288c
38 changed files with 957 additions and 483 deletions

View File

@ -1,5 +1,9 @@
# auto-detect subdirs
ifneq ($(CONFIG_ARCH_QTI_VM), y)
ifeq ($(CONFIG_QTI_QUIN_GVM), y)
include $(srctree)/techpack/audio/config/gvmauto.conf
export
endif
ifeq ($(CONFIG_ARCH_SDXPOORWILLS), y)
include $(srctree)/techpack/audio/config/sdxpoorwillsauto.conf
export
@ -34,6 +38,10 @@ LINUXINCLUDE += \
-I$(srctree)/techpack/audio/include/uapi/audio \
-I$(srctree)/techpack/audio/include
ifeq ($(CONFIG_QTI_QUIN_GVM), y)
LINUXINCLUDE += \
-include $(srctree)/techpack/audio/config/gvmautoconf.h
endif
ifeq ($(CONFIG_ARCH_SDXPOORWILLS), y)
LINUXINCLUDE += \
-include $(srctree)/techpack/audio/config/sdxpoorwillsautoconf.h

View File

@ -39,6 +39,7 @@ obj-m += asoc/codecs/wcd937x/
endif
ifeq ($(TARGET_SUPPORT), $(filter $(TARGET_SUPPORT), sa8155 sa8155ivi sa6155 sa8195 qtiquingvm))
KBUILD_OPTIONS += CONFIG_SND_SOC_AUTO=y
obj-m := ipc/
obj-m += dsp/
obj-m += asoc/
@ -63,6 +64,8 @@ all:
$(shell ln -s $(KERNEL_SRC)/drivers/base/regmap/internal.h $(shell pwd)/include/soc/internal.h)
$(shell rm -fr $(shell pwd)/soc/pinctrl-utils.h)
$(shell ln -s $(KERNEL_SRC)/drivers/pinctrl/pinctrl-utils.h $(shell pwd)/soc/pinctrl-utils.h)
$(shell rm -fr $(shell pwd)/include/soc/qcom/secure_buffer.h)
$(shell ln -s $(KERNEL_SRC)/include/soc/qcom/secure_buffer.h $(shell pwd)/include/soc/qcom/secure_buffer.h)
$(shell mkdir $(shell pwd)/linux)
$(shell mkdir $(shell pwd)/sound)
$(shell mkdir $(shell pwd)/linux/mfd)

View File

@ -13,6 +13,18 @@ ifeq ($(KERNEL_BUILD), 1)
AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio
endif
ifeq ($(CONFIG_SND_SOC_AUTO), y)
ifdef CONFIG_SND_SOC_SA8155
include $(AUDIO_ROOT)/config/sa8155auto.conf
export
INCS += -include $(AUDIO_ROOT)/config/sa8155autoconf.h
endif
ifdef CONFIG_SND_SOC_SA6155
include $(AUDIO_ROOT)/config/sa6155auto.conf
export
INCS += -include $(AUDIO_ROOT)/config/sa6155autoconf.h
endif
else
ifeq ($(KERNEL_BUILD), 0)
ifeq ($(CONFIG_ARCH_SM8150), y)
ifdef CONFIG_SND_SOC_SA8155
@ -71,12 +83,13 @@ ifeq ($(KERNEL_BUILD), 0)
export
INCS += -include $(AUDIO_ROOT)/config/qcs405autoconf.h
endif
ifeq ($(CONFIG_QTI_GVM), y)
ifeq ($(CONFIG_QTI_QUIN_GVM), y)
include $(AUDIO_ROOT)/config/gvmauto.conf
export
INCS += -include $(AUDIO_ROOT)/config/gvmautoconf.h
endif
endif
endif
# As per target team, build is done as follows:
# Defconfig : build with default flags

View File

@ -13,6 +13,18 @@ ifeq ($(KERNEL_BUILD), 1)
AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio
endif
ifeq ($(CONFIG_SND_SOC_AUTO), y)
ifdef CONFIG_SND_SOC_SA8155
include $(AUDIO_ROOT)/config/sa8155auto.conf
export
INCS += -include $(AUDIO_ROOT)/config/sa8155autoconf.h
endif
ifdef CONFIG_SND_SOC_SA6155
include $(AUDIO_ROOT)/config/sa6155auto.conf
export
INCS += -include $(AUDIO_ROOT)/config/sa6155autoconf.h
endif
else
ifeq ($(KERNEL_BUILD), 0)
ifeq ($(CONFIG_ARCH_SM8150), y)
ifdef CONFIG_SND_SOC_SA8155
@ -65,12 +77,13 @@ ifeq ($(KERNEL_BUILD), 0)
export
INCS += -include $(AUDIO_ROOT)/config/qcs405autoconf.h
endif
ifeq ($(CONFIG_QTI_GVM), y)
ifeq ($(CONFIG_QTI_QUIN_GVM), y)
include $(AUDIO_ROOT)/config/gvmauto.conf
export
INCS += -include $(AUDIO_ROOT)/config/gvmautoconf.h
endif
endif
endif
# As per target team, build is done as follows:
# Defconfig : build with default flags

View File

@ -18,6 +18,7 @@
#include "bolero-cdc.h"
#include "internal.h"
#include "bolero-clk-rsc.h"
#include "asoc/bolero-slave-internal.h"
#define DRV_NAME "bolero_codec"
@ -202,37 +203,37 @@ static int bolero_cdc_update_wcd_event(void *handle, u16 event, u32 data)
}
switch (event) {
case WCD_BOLERO_EVT_RX_MUTE:
case SLV_BOLERO_EVT_RX_MUTE:
if (priv->macro_params[RX_MACRO].event_handler)
priv->macro_params[RX_MACRO].event_handler(
priv->component,
BOLERO_MACRO_EVT_RX_MUTE, data);
break;
case WCD_BOLERO_EVT_IMPED_TRUE:
case SLV_BOLERO_EVT_IMPED_TRUE:
if (priv->macro_params[RX_MACRO].event_handler)
priv->macro_params[RX_MACRO].event_handler(
priv->component,
BOLERO_MACRO_EVT_IMPED_TRUE, data);
break;
case WCD_BOLERO_EVT_IMPED_FALSE:
case SLV_BOLERO_EVT_IMPED_FALSE:
if (priv->macro_params[RX_MACRO].event_handler)
priv->macro_params[RX_MACRO].event_handler(
priv->component,
BOLERO_MACRO_EVT_IMPED_FALSE, data);
break;
case WCD_BOLERO_EVT_RX_COMPANDER_SOFT_RST:
case SLV_BOLERO_EVT_RX_COMPANDER_SOFT_RST:
if (priv->macro_params[RX_MACRO].event_handler)
priv->macro_params[RX_MACRO].event_handler(
priv->component,
BOLERO_MACRO_EVT_RX_COMPANDER_SOFT_RST, data);
break;
case WCD_BOLERO_EVT_BCS_CLK_OFF:
case SLV_BOLERO_EVT_BCS_CLK_OFF:
if (priv->macro_params[TX_MACRO].event_handler)
priv->macro_params[TX_MACRO].event_handler(
priv->component,
BOLERO_MACRO_EVT_BCS_CLK_OFF, data);
break;
case WCD_BOLERO_EVT_RX_PA_GAIN_UPDATE:
case SLV_BOLERO_EVT_RX_PA_GAIN_UPDATE:
/* Update PA Gain only for bolero version 2.1 */
if (priv->version == BOLERO_VERSION_2_1)
if (priv->macro_params[RX_MACRO].event_handler)
@ -241,13 +242,13 @@ static int bolero_cdc_update_wcd_event(void *handle, u16 event, u32 data)
BOLERO_MACRO_EVT_RX_PA_GAIN_UPDATE,
data);
break;
case WCD_BOLERO_EVT_HPHL_HD2_ENABLE:
case SLV_BOLERO_EVT_HPHL_HD2_ENABLE:
if (priv->macro_params[RX_MACRO].event_handler)
priv->macro_params[RX_MACRO].event_handler(
priv->component,
BOLERO_MACRO_EVT_HPHL_HD2_ENABLE, data);
break;
case WCD_BOLERO_EVT_HPHR_HD2_ENABLE:
case SLV_BOLERO_EVT_HPHR_HD2_ENABLE:
if (priv->macro_params[RX_MACRO].event_handler)
priv->macro_params[RX_MACRO].event_handler(
priv->component,
@ -329,7 +330,7 @@ void bolero_clear_amic_tx_hold(struct device *dev, u16 adc_n)
dev_err(dev, "%s: priv is null\n", __func__);
return;
}
event = BOLERO_WCD_EVT_TX_CH_HOLD_CLEAR;
event = BOLERO_SLV_EVT_TX_CH_HOLD_CLEAR;
if (adc_n == BOLERO_ADC0)
amic = 0x1;
else if (adc_n == BOLERO_ADC1)
@ -687,6 +688,7 @@ int bolero_register_macro(struct device *dev, u16 macro_id,
bolero_mclk_mux_tbl[macro_id][MCLK_MUX0];
if (macro_id == TX_MACRO) {
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 =
ops->reg_evt_listener;
priv->macro_params[macro_id].clk_enable = ops->clk_enable;
@ -761,6 +763,7 @@ void bolero_unregister_macro(struct device *dev, u16 macro_id)
priv->macro_params[macro_id].dev = NULL;
if (macro_id == TX_MACRO) {
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].clk_enable = NULL;
}
@ -796,10 +799,10 @@ void bolero_wsa_pa_on(struct device *dev, bool adie_lb)
}
if (adie_lb)
bolero_cdc_notifier_call(priv,
BOLERO_WCD_EVT_PA_ON_POST_FSCLK_ADIE_LB);
BOLERO_SLV_EVT_PA_ON_POST_FSCLK_ADIE_LB);
else
bolero_cdc_notifier_call(priv,
BOLERO_WCD_EVT_PA_ON_POST_FSCLK);
BOLERO_SLV_EVT_PA_ON_POST_FSCLK);
}
EXPORT_SYMBOL(bolero_wsa_pa_on);
@ -916,7 +919,7 @@ static int bolero_ssr_enable(struct device *dev, void *data)
BOLERO_MACRO_EVT_SSR_UP, 0x0);
}
trace_printk("%s: SSR up events processed by all macros\n", __func__);
bolero_cdc_notifier_call(priv, BOLERO_WCD_EVT_SSR_UP);
bolero_cdc_notifier_call(priv, BOLERO_SLV_EVT_SSR_UP);
return 0;
}
@ -931,7 +934,7 @@ static void bolero_ssr_disable(struct device *dev, void *data)
return;
}
bolero_cdc_notifier_call(priv, BOLERO_WCD_EVT_PA_OFF_PRE_SSR);
bolero_cdc_notifier_call(priv, BOLERO_SLV_EVT_PA_OFF_PRE_SSR);
regcache_cache_only(priv->regmap, true);
mutex_lock(&priv->clk_lock);
@ -947,7 +950,7 @@ static void bolero_ssr_disable(struct device *dev, void *data)
priv->component,
BOLERO_MACRO_EVT_SSR_DOWN, 0x0);
}
bolero_cdc_notifier_call(priv, BOLERO_WCD_EVT_SSR_DOWN);
bolero_cdc_notifier_call(priv, BOLERO_SLV_EVT_SSR_DOWN);
}
static struct snd_info_entry_ops bolero_info_ops = {
@ -1064,6 +1067,40 @@ int bolero_register_wake_irq(struct snd_soc_component *component,
}
EXPORT_SYMBOL(bolero_register_wake_irq);
/**
* bolero_tx_clk_switch - Switch tx macro clock
*
* @component: pointer to codec component instance.
*
* @clk_src: clk source
*
* 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
*

View File

@ -37,6 +37,11 @@ enum {
BOLERO_ADC_MAX
};
enum {
CLK_SRC_TX_RCG = 0,
CLK_SRC_VA_RCG,
};
enum {
BOLERO_MACRO_EVT_RX_MUTE = 1, /* for RX mute/unmute */
BOLERO_MACRO_EVT_IMPED_TRUE, /* for imped true */
@ -74,6 +79,7 @@ struct macro_ops {
int (*set_port_map)(struct snd_soc_component *component, u32 uc,
u32 size, void *data);
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 (*clk_enable)(struct snd_soc_component *c, bool en);
char __iomem *io_base;
@ -100,6 +106,7 @@ void bolero_clear_amic_tx_hold(struct device *dev, u16 adc_n);
int bolero_runtime_resume(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_tx_clk_switch(struct snd_soc_component *component, int clk_src);
int bolero_register_event_listener(struct snd_soc_component *component,
bool enable);
void bolero_wsa_pa_on(struct device *dev, bool adie_lb);
@ -172,6 +179,12 @@ static inline int bolero_set_port_map(struct snd_soc_component *component,
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(
struct snd_soc_component *component,
bool enable)

View File

@ -9,16 +9,6 @@
#define BOLERO_CDC_CHILD_DEVICES_MAX 6
/* from bolero to WCD events */
enum {
BOLERO_WCD_EVT_TX_CH_HOLD_CLEAR = 1,
BOLERO_WCD_EVT_PA_OFF_PRE_SSR,
BOLERO_WCD_EVT_SSR_DOWN,
BOLERO_WCD_EVT_SSR_UP,
BOLERO_WCD_EVT_PA_ON_POST_FSCLK,
BOLERO_WCD_EVT_PA_ON_POST_FSCLK_ADIE_LB,
};
enum {
REG_NO_ACCESS,
RD_REG,
@ -26,18 +16,6 @@ enum {
RD_WR_REG
};
/* from WCD to bolero events */
enum {
WCD_BOLERO_EVT_RX_MUTE = 1, /* for RX mute/unmute */
WCD_BOLERO_EVT_IMPED_TRUE, /* for imped true */
WCD_BOLERO_EVT_IMPED_FALSE, /* for imped false */
WCD_BOLERO_EVT_RX_COMPANDER_SOFT_RST,
WCD_BOLERO_EVT_BCS_CLK_OFF,
WCD_BOLERO_EVT_RX_PA_GAIN_UPDATE,
WCD_BOLERO_EVT_HPHL_HD2_ENABLE, /* to enable hd2 config for hphl */
WCD_BOLERO_EVT_HPHR_HD2_ENABLE, /* to enable hd2 config for hphr */
};
struct wcd_ctrl_platform_data {
void *handle;
int (*update_wcd_event)(void *handle, u16 event, u32 data);

View File

@ -179,6 +179,7 @@ struct tx_macro_priv {
int amic_sample_rate;
bool lpi_enable;
bool register_event_listener;
u16 current_clk_id;
};
static bool tx_macro_get_data(struct snd_soc_component *component,
@ -1815,11 +1816,11 @@ static const struct snd_soc_dapm_widget tx_macro_dapm_widgets_v3[] = {
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_SUPPLY_S("TX_SWR_CLK", 0, SND_SOC_NOPM, 0, 0,
SND_SOC_DAPM_SUPPLY_S("TX_SWR_CLK", -1, SND_SOC_NOPM, 0, 0,
tx_macro_tx_swr_clk_event,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_SUPPLY_S("VA_SWR_CLK", 0, SND_SOC_NOPM, 0, 0,
SND_SOC_DAPM_SUPPLY_S("VA_SWR_CLK", -1, SND_SOC_NOPM, 0, 0,
tx_macro_va_swr_clk_event,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
};
@ -2846,6 +2847,70 @@ static int tx_macro_clk_div_get(struct snd_soc_component *component)
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;
}
dev_dbg(component->dev,
"%s: va_swr_clk_cnt %d, tx_swr_clk_cnt %d, tx_clk_status %d\n",
__func__, tx_priv->va_swr_clk_cnt,
tx_priv->tx_swr_clk_cnt, tx_priv->tx_clk_status);
if (tx_priv->current_clk_id == clk_src) {
dev_dbg(component->dev,
"%s: requested clk %d is same as current\n",
__func__, clk_src);
return 0;
} else if (tx_priv->va_swr_clk_cnt != 0 && tx_priv->tx_clk_status) {
ret = bolero_clk_rsc_request_clock(tx_priv->dev,
TX_CORE_CLK,
clk_src,
true);
if (ret) {
dev_dbg(component->dev,
"%s: request clock %d enable failed\n",
__func__, clk_src);
goto ret;
}
ret = bolero_clk_rsc_request_clock(tx_priv->dev,
TX_CORE_CLK,
tx_priv->current_clk_id,
false);
if (ret) {
dev_dbg(component->dev,
"%s: request clock disable failed\n",
__func__);
bolero_clk_rsc_request_clock(tx_priv->dev,
TX_CORE_CLK,
clk_src,
false);
goto ret;
}
tx_priv->current_clk_id = clk_src;
} else {
ret = -EBUSY;
}
ret:
return ret;
}
static int tx_macro_core_vote(void *handle, bool enable)
{
struct tx_macro_priv *tx_priv = (struct tx_macro_priv *) handle;
@ -3329,6 +3394,7 @@ static void tx_macro_init_ops(struct macro_ops *ops,
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;
ops->clk_enable = __tx_macro_mclk_enable;
}
@ -3427,6 +3493,7 @@ static int tx_macro_probe(struct platform_device *pdev)
tx_macro_init_ops(&ops, tx_io_base);
ops.clk_id_req = TX_CORE_CLK;
ops.default_clk_id = TX_CORE_CLK;
tx_priv->current_clk_id = TX_CORE_CLK;
ret = bolero_register_macro(&pdev->dev, TX_MACRO, &ops);
if (ret) {
dev_err(&pdev->dev,

View File

@ -393,12 +393,64 @@ static int va_macro_swr_pwr_event_v2(struct snd_soc_dapm_widget *w,
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
if (va_priv->default_clk_id != VA_CORE_CLK) {
ret = bolero_clk_rsc_request_clock(va_priv->dev,
va_priv->default_clk_id,
VA_CORE_CLK,
true);
if (ret) {
dev_dbg(component->dev,
"%s: request clock VA_CLK enable failed\n",
__func__);
break;
}
ret = bolero_clk_rsc_request_clock(va_priv->dev,
va_priv->default_clk_id,
TX_CORE_CLK,
false);
if (ret) {
dev_dbg(component->dev,
"%s: request clock TX_CLK enable failed\n",
__func__);
bolero_clk_rsc_request_clock(va_priv->dev,
va_priv->default_clk_id,
VA_CORE_CLK,
false);
break;
}
}
msm_cdc_pinctrl_set_wakeup_capable(
va_priv->va_swr_gpio_p, false);
break;
case SND_SOC_DAPM_POST_PMD:
msm_cdc_pinctrl_set_wakeup_capable(
va_priv->va_swr_gpio_p, true);
if (va_priv->default_clk_id == TX_CORE_CLK) {
ret = bolero_clk_rsc_request_clock(va_priv->dev,
va_priv->default_clk_id,
TX_CORE_CLK,
true);
if (ret) {
dev_dbg(component->dev,
"%s: request clock TX_CLK disable failed\n",
__func__);
break;
}
ret = bolero_clk_rsc_request_clock(va_priv->dev,
va_priv->default_clk_id,
VA_CORE_CLK,
false);
if (ret) {
dev_dbg(component->dev,
"%s: request clock VA_CLK disable failed\n",
__func__);
bolero_clk_rsc_request_clock(va_priv->dev,
TX_CORE_CLK,
TX_CORE_CLK,
false);
break;
}
}
break;
default:
dev_err(va_priv->dev,
@ -436,8 +488,13 @@ static int va_macro_swr_pwr_event(struct snd_soc_dapm_widget *w,
"%s: lpass audio hw enable failed\n",
__func__);
}
if (!ret) {
if (bolero_tx_clk_switch(component, VA_CORE_CLK))
dev_dbg(va_dev, "%s: clock switch failed\n",
__func__);
}
if (va_priv->lpi_enable &&
!va_priv->disable_afe_wakeup_event_listener) {
!va_priv->disable_afe_wakeup_event_listener) {
bolero_register_event_listener(component, true);
va_priv->register_event_listener = true;
}
@ -447,6 +504,8 @@ static int va_macro_swr_pwr_event(struct snd_soc_dapm_widget *w,
va_priv->register_event_listener = false;
bolero_register_event_listener(component, false);
}
if (bolero_tx_clk_switch(component, TX_CORE_CLK))
dev_dbg(va_dev, "%s: clock switch failed\n",__func__);
if (va_priv->lpass_audio_hw_vote)
digital_cdc_rsc_mgr_hw_vote_disable(
va_priv->lpass_audio_hw_vote);
@ -506,10 +565,11 @@ static int va_macro_mclk_event(struct snd_soc_dapm_widget *w,
ret = bolero_tx_mclk_enable(component, 1);
break;
case SND_SOC_DAPM_POST_PMD:
if (va_priv->lpi_enable)
if (va_priv->lpi_enable) {
va_macro_mclk_enable(va_priv, 0, true);
else
} else {
bolero_tx_mclk_enable(component, 0);
}
if (va_priv->tx_clk_status > 0) {
bolero_clk_rsc_request_clock(va_priv->dev,
@ -1900,15 +1960,15 @@ static const struct snd_soc_dapm_widget va_macro_dapm_widgets_v2[] = {
VA_MACRO_AIF3_CAP, 0,
va_aif3_cap_mixer_v2, ARRAY_SIZE(va_aif3_cap_mixer_v2)),
SND_SOC_DAPM_SUPPLY_S("VA_SWR_PWR", -1, SND_SOC_NOPM, 0, 0,
SND_SOC_DAPM_SUPPLY_S("VA_SWR_PWR", 0, SND_SOC_NOPM, 0, 0,
va_macro_swr_pwr_event_v2,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_SUPPLY_S("VA_TX_SWR_CLK", 0, SND_SOC_NOPM, 0, 0,
SND_SOC_DAPM_SUPPLY_S("VA_TX_SWR_CLK", -1, SND_SOC_NOPM, 0, 0,
va_macro_tx_swr_clk_event_v2,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_SUPPLY_S("VA_SWR_CLK", 0, SND_SOC_NOPM, 0, 0,
SND_SOC_DAPM_SUPPLY_S("VA_SWR_CLK", -1, SND_SOC_NOPM, 0, 0,
va_macro_swr_clk_event_v2,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
};
@ -1942,7 +2002,7 @@ static const struct snd_soc_dapm_widget va_macro_dapm_widgets_v3[] = {
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_SUPPLY_S("VA_SWR_PWR", -1, SND_SOC_NOPM, 0, 0,
SND_SOC_DAPM_SUPPLY_S("VA_SWR_PWR", 0, SND_SOC_NOPM, 0, 0,
va_macro_swr_pwr_event,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
};

View File

@ -44,6 +44,61 @@ static const unsigned int ep92_dsd_freq_table[4] = {
64, 128, 256, 0
};
/* EP92 register default values */
static struct reg_default ep92_reg_defaults[] = {
{EP92_BI_VENDOR_ID_0, 0x17},
{EP92_BI_VENDOR_ID_1, 0x7A},
{EP92_BI_DEVICE_ID_0, 0x94},
{EP92_BI_DEVICE_ID_1, 0xA3},
{EP92_BI_VERSION_NUM, 0x10},
{EP92_BI_VERSION_YEAR, 0x09},
{EP92_BI_VERSION_MONTH, 0x07},
{EP92_BI_VERSION_DATE, 0x06},
{EP92_BI_GENERAL_INFO_0, 0x00},
{EP92_BI_GENERAL_INFO_1, 0x00},
{EP92_BI_GENERAL_INFO_2, 0x00},
{EP92_BI_GENERAL_INFO_3, 0x00},
{EP92_BI_GENERAL_INFO_4, 0x00},
{EP92_BI_GENERAL_INFO_5, 0x00},
{EP92_BI_GENERAL_INFO_6, 0x00},
{EP92_ISP_MODE_ENTER_ISP, 0x00},
{EP92_GENERAL_CONTROL_0, 0x20},
{EP92_GENERAL_CONTROL_1, 0x00},
{EP92_GENERAL_CONTROL_2, 0x00},
{EP92_GENERAL_CONTROL_3, 0x10},
{EP92_GENERAL_CONTROL_4, 0x00},
{EP92_CEC_EVENT_CODE, 0x00},
{EP92_CEC_EVENT_PARAM_1, 0x00},
{EP92_CEC_EVENT_PARAM_2, 0x00},
{EP92_CEC_EVENT_PARAM_3, 0x00},
{EP92_CEC_EVENT_PARAM_4, 0x00},
{EP92_AUDIO_INFO_SYSTEM_STATUS_0, 0x00},
{EP92_AUDIO_INFO_SYSTEM_STATUS_1, 0x00},
{EP92_AUDIO_INFO_AUDIO_STATUS, 0x00},
{EP92_AUDIO_INFO_CHANNEL_STATUS_0, 0x00},
{EP92_AUDIO_INFO_CHANNEL_STATUS_1, 0x00},
{EP92_AUDIO_INFO_CHANNEL_STATUS_2, 0x00},
{EP92_AUDIO_INFO_CHANNEL_STATUS_3, 0x00},
{EP92_AUDIO_INFO_CHANNEL_STATUS_4, 0x00},
{EP92_AUDIO_INFO_ADO_INFO_FRAME_0, 0x00},
{EP92_AUDIO_INFO_ADO_INFO_FRAME_1, 0x00},
{EP92_AUDIO_INFO_ADO_INFO_FRAME_2, 0x00},
{EP92_AUDIO_INFO_ADO_INFO_FRAME_3, 0x00},
{EP92_AUDIO_INFO_ADO_INFO_FRAME_4, 0x00},
{EP92_AUDIO_INFO_ADO_INFO_FRAME_5, 0x00},
{EP92_OTHER_PACKETS_HDMI_VS_0, 0x00},
{EP92_OTHER_PACKETS_HDMI_VS_1, 0x00},
{EP92_OTHER_PACKETS_ACP_PACKET, 0x00},
{EP92_OTHER_PACKETS_AVI_INFO_FRAME_0, 0x00},
{EP92_OTHER_PACKETS_AVI_INFO_FRAME_1, 0x00},
{EP92_OTHER_PACKETS_AVI_INFO_FRAME_2, 0x00},
{EP92_OTHER_PACKETS_AVI_INFO_FRAME_3, 0x00},
{EP92_OTHER_PACKETS_AVI_INFO_FRAME_4, 0x00},
{EP92_OTHER_PACKETS_GC_PACKET_0, 0x00},
{EP92_OTHER_PACKETS_GC_PACKET_1, 0x00},
{EP92_OTHER_PACKETS_GC_PACKET_2, 0x00},
};
static bool ep92_volatile_register(struct device *dev, unsigned int reg)
{
/* do not cache register state in regmap */
@ -115,6 +170,77 @@ struct ep92_pdata {
#endif /* CONFIG_DEBUG_FS */
};
struct ep92_mclk_cfg_info {
uint32_t in_sample_rate;
uint32_t out_mclk_freq;
uint8_t mul_val;
};
#define EP92_MCLK_MUL_512 0x3
#define EP92_MCLK_MUL_384 0x2
#define EP92_MCLK_MUL_256 0x1
#define EP92_MCLK_MUL_128 0x0
#define EP92_MCLK_MUL_MASK 0x3
/**
* ep92_set_ext_mclk - Configure the mclk based on sample freq
*
* @codec: handle pointer to ep92 codec
* @mclk_freq: mclk frequency to be set
*
* Returns 0 for sucess or appropriate negative error code
*/
int ep92_set_ext_mclk(struct snd_soc_codec *codec, uint32_t mclk_freq)
{
unsigned int samp_freq = 0;
struct ep92_pdata *ep92 = NULL;
uint8_t value = 0;
int ret = 0;
if (!codec)
return -EINVAL;
ep92 = snd_soc_codec_get_drvdata(codec);
samp_freq = ep92_samp_freq_table[(ep92->ai.audio_status) &
EP92_AI_RATE_MASK];
if (!mclk_freq || (mclk_freq % samp_freq)) {
pr_err("%s incompatbile mclk:%u and sample freq:%u\n",
__func__, mclk_freq, samp_freq);
return -EINVAL;
}
switch (mclk_freq / samp_freq) {
case 512:
value = EP92_MCLK_MUL_512;
break;
case 384:
value = EP92_MCLK_MUL_384;
break;
case 256:
value = EP92_MCLK_MUL_256;
break;
case 128:
value = EP92_MCLK_MUL_128;
break;
default:
dev_err(codec->dev, "unsupported mclk:%u for sample freq:%u\n",
mclk_freq, samp_freq);
return -EINVAL;
}
pr_debug("%s mclk:%u, in sample freq:%u, write reg:0x%02x val:0x%02x\n",
__func__, mclk_freq, samp_freq,
EP92_GENERAL_CONTROL_2, EP92_MCLK_MUL_MASK & value);
ret = snd_soc_update_bits(codec, EP92_GENERAL_CONTROL_2,
EP92_MCLK_MUL_MASK, value);
return (((ret == 0) || (ret == 1)) ? 0 : ret);
}
EXPORT_SYMBOL(ep92_set_ext_mclk);
#if IS_ENABLED(CONFIG_DEBUG_FS)
static int debugfs_codec_open_op(struct inode *inode, struct file *file)
{

View File

@ -69,63 +69,6 @@
#define EP92_MAX_REGISTER_ADDR EP92_OTHER_PACKETS_GC_PACKET_2
/* EP92 register default values */
static struct reg_default ep92_reg_defaults[] = {
{EP92_BI_VENDOR_ID_0, 0x17},
{EP92_BI_VENDOR_ID_1, 0x7A},
{EP92_BI_DEVICE_ID_0, 0x94},
{EP92_BI_DEVICE_ID_1, 0xA3},
{EP92_BI_VERSION_NUM, 0x10},
{EP92_BI_VERSION_YEAR, 0x09},
{EP92_BI_VERSION_MONTH, 0x07},
{EP92_BI_VERSION_DATE, 0x06},
{EP92_BI_GENERAL_INFO_0, 0x00},
{EP92_BI_GENERAL_INFO_1, 0x00},
{EP92_BI_GENERAL_INFO_2, 0x00},
{EP92_BI_GENERAL_INFO_3, 0x00},
{EP92_BI_GENERAL_INFO_4, 0x00},
{EP92_BI_GENERAL_INFO_5, 0x00},
{EP92_BI_GENERAL_INFO_6, 0x00},
{EP92_ISP_MODE_ENTER_ISP, 0x00},
{EP92_GENERAL_CONTROL_0, 0x20},
{EP92_GENERAL_CONTROL_1, 0x00},
{EP92_GENERAL_CONTROL_2, 0x00},
{EP92_GENERAL_CONTROL_3, 0x10},
{EP92_GENERAL_CONTROL_4, 0x00},
{EP92_CEC_EVENT_CODE, 0x00},
{EP92_CEC_EVENT_PARAM_1, 0x00},
{EP92_CEC_EVENT_PARAM_2, 0x00},
{EP92_CEC_EVENT_PARAM_3, 0x00},
{EP92_CEC_EVENT_PARAM_4, 0x00},
{EP92_AUDIO_INFO_SYSTEM_STATUS_0, 0x00},
{EP92_AUDIO_INFO_SYSTEM_STATUS_1, 0x00},
{EP92_AUDIO_INFO_AUDIO_STATUS, 0x00},
{EP92_AUDIO_INFO_CHANNEL_STATUS_0, 0x00},
{EP92_AUDIO_INFO_CHANNEL_STATUS_1, 0x00},
{EP92_AUDIO_INFO_CHANNEL_STATUS_2, 0x00},
{EP92_AUDIO_INFO_CHANNEL_STATUS_3, 0x00},
{EP92_AUDIO_INFO_CHANNEL_STATUS_4, 0x00},
{EP92_AUDIO_INFO_ADO_INFO_FRAME_0, 0x00},
{EP92_AUDIO_INFO_ADO_INFO_FRAME_1, 0x00},
{EP92_AUDIO_INFO_ADO_INFO_FRAME_2, 0x00},
{EP92_AUDIO_INFO_ADO_INFO_FRAME_3, 0x00},
{EP92_AUDIO_INFO_ADO_INFO_FRAME_4, 0x00},
{EP92_AUDIO_INFO_ADO_INFO_FRAME_5, 0x00},
{EP92_OTHER_PACKETS_HDMI_VS_0, 0x00},
{EP92_OTHER_PACKETS_HDMI_VS_1, 0x00},
{EP92_OTHER_PACKETS_ACP_PACKET, 0x00},
{EP92_OTHER_PACKETS_AVI_INFO_FRAME_0, 0x00},
{EP92_OTHER_PACKETS_AVI_INFO_FRAME_1, 0x00},
{EP92_OTHER_PACKETS_AVI_INFO_FRAME_2, 0x00},
{EP92_OTHER_PACKETS_AVI_INFO_FRAME_3, 0x00},
{EP92_OTHER_PACKETS_AVI_INFO_FRAME_4, 0x00},
{EP92_OTHER_PACKETS_GC_PACKET_0, 0x00},
{EP92_OTHER_PACKETS_GC_PACKET_1, 0x00},
{EP92_OTHER_PACKETS_GC_PACKET_2, 0x00},
};
/* shift/masks for register bits
* GI = General Info
* GC = General Control
@ -211,4 +154,6 @@ enum {
EP92_KCTL_MAX
};
int ep92_set_ext_mclk(struct snd_soc_codec *codec, uint32_t mclk_freq);
#endif /* __EP92_H__ */

View File

@ -124,24 +124,6 @@ enum {
WCD_RX3
};
enum {
BOLERO_WCD_EVT_TX_CH_HOLD_CLEAR = 1,
BOLERO_WCD_EVT_PA_OFF_PRE_SSR,
BOLERO_WCD_EVT_SSR_DOWN,
BOLERO_WCD_EVT_SSR_UP,
};
enum {
WCD_BOLERO_EVT_RX_MUTE = 1, /* for RX mute/unmute */
WCD_BOLERO_EVT_IMPED_TRUE, /* for imped true */
WCD_BOLERO_EVT_IMPED_FALSE, /* for imped false */
WCD_BOLERO_EVT_RX_COMPANDER_SOFT_RST,
WCD_BOLERO_EVT_BCS_CLK_OFF,
WCD_BOLERO_EVT_RX_PA_GAIN_UPDATE, /* To reduce PA gain for low SoC */
WCD_BOLERO_EVT_HPHL_HD2_ENABLE, /* to enable hd2 config for hphl */
WCD_BOLERO_EVT_HPHR_HD2_ENABLE, /* to enable hd2 config for hphr */
};
enum {
/* INTR_CTRL_INT_MASK_0 */
ROULEUR_IRQ_MBHC_BUTTON_PRESS_DET = 0,

View File

@ -27,6 +27,7 @@
#include <dt-bindings/sound/audio-codec-port-types.h>
#include <asoc/msm-cdc-supply.h>
#include <linux/power_supply.h>
#include "asoc/bolero-slave-internal.h"
#define DRV_NAME "rouleur_codec"
@ -646,7 +647,7 @@ static int rouleur_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
/* Enable HD2 Config for HPHR if foundry id is SEC */
if (rouleur->foundry_id == FOUNDRY_ID_SEC)
rouleur->update_wcd_event(rouleur->handle,
WCD_BOLERO_EVT_HPHR_HD2_ENABLE,
SLV_BOLERO_EVT_HPHR_HD2_ENABLE,
0x04);
snd_soc_component_update_bits(component,
ROULEUR_DIG_SWR_PDM_WD_CTL1,
@ -664,7 +665,7 @@ static int rouleur_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
if (rouleur->update_wcd_event)
rouleur->update_wcd_event(rouleur->handle,
WCD_BOLERO_EVT_RX_MUTE,
SLV_BOLERO_EVT_RX_MUTE,
(WCD_RX2 << 0x10));
wcd_enable_irq(&rouleur->irq_info,
ROULEUR_IRQ_HPHR_PDM_WD_INT);
@ -674,7 +675,7 @@ static int rouleur_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
ROULEUR_IRQ_HPHR_PDM_WD_INT);
if (rouleur->update_wcd_event)
rouleur->update_wcd_event(rouleur->handle,
WCD_BOLERO_EVT_RX_MUTE,
SLV_BOLERO_EVT_RX_MUTE,
(WCD_RX2 << 0x10 | 0x1));
blocking_notifier_call_chain(&rouleur->mbhc->notifier,
WCD_EVENT_PRE_HPHR_PA_OFF,
@ -694,7 +695,7 @@ static int rouleur_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
if (rouleur->foundry_id == FOUNDRY_ID_SEC)
rouleur->update_wcd_event(rouleur->handle,
WCD_BOLERO_EVT_HPHR_HD2_ENABLE,
SLV_BOLERO_EVT_HPHR_HD2_ENABLE,
0x00);
blocking_notifier_call_chain(&rouleur->mbhc->notifier,
WCD_EVENT_POST_HPHR_PA_OFF,
@ -728,7 +729,7 @@ static int rouleur_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
usleep_range(200, 210);
if (rouleur->foundry_id == FOUNDRY_ID_SEC)
rouleur->update_wcd_event(rouleur->handle,
WCD_BOLERO_EVT_HPHL_HD2_ENABLE,
SLV_BOLERO_EVT_HPHL_HD2_ENABLE,
0x04);
snd_soc_component_update_bits(component,
ROULEUR_DIG_SWR_PDM_WD_CTL0,
@ -746,7 +747,7 @@ static int rouleur_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
if (rouleur->update_wcd_event)
rouleur->update_wcd_event(rouleur->handle,
WCD_BOLERO_EVT_RX_MUTE,
SLV_BOLERO_EVT_RX_MUTE,
(WCD_RX1 << 0x10));
wcd_enable_irq(&rouleur->irq_info,
ROULEUR_IRQ_HPHL_PDM_WD_INT);
@ -756,7 +757,7 @@ static int rouleur_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
ROULEUR_IRQ_HPHL_PDM_WD_INT);
if (rouleur->update_wcd_event)
rouleur->update_wcd_event(rouleur->handle,
WCD_BOLERO_EVT_RX_MUTE,
SLV_BOLERO_EVT_RX_MUTE,
(WCD_RX1 << 0x10 | 0x1));
blocking_notifier_call_chain(&rouleur->mbhc->notifier,
WCD_EVENT_PRE_HPHL_PA_OFF,
@ -775,7 +776,7 @@ static int rouleur_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
if (rouleur->foundry_id == FOUNDRY_ID_SEC)
rouleur->update_wcd_event(rouleur->handle,
WCD_BOLERO_EVT_HPHL_HD2_ENABLE,
SLV_BOLERO_EVT_HPHL_HD2_ENABLE,
0x00);
blocking_notifier_call_chain(&rouleur->mbhc->notifier,
WCD_EVENT_POST_HPHL_PA_OFF,
@ -819,7 +820,7 @@ static int rouleur_codec_enable_ear_pa(struct snd_soc_dapm_widget *w,
0x40, 0x00);
if (rouleur->foundry_id == FOUNDRY_ID_SEC)
rouleur->update_wcd_event(rouleur->handle,
WCD_BOLERO_EVT_HPHL_HD2_ENABLE,
SLV_BOLERO_EVT_HPHL_HD2_ENABLE,
0x04);
snd_soc_component_update_bits(component,
ROULEUR_DIG_SWR_PDM_WD_CTL0,
@ -832,7 +833,7 @@ static int rouleur_codec_enable_ear_pa(struct snd_soc_dapm_widget *w,
0x0F, 0x04);
if (rouleur->update_wcd_event)
rouleur->update_wcd_event(rouleur->handle,
WCD_BOLERO_EVT_RX_MUTE,
SLV_BOLERO_EVT_RX_MUTE,
(WCD_RX1 << 0x10));
wcd_enable_irq(&rouleur->irq_info,
ROULEUR_IRQ_HPHL_PDM_WD_INT);
@ -842,14 +843,14 @@ static int rouleur_codec_enable_ear_pa(struct snd_soc_dapm_widget *w,
ROULEUR_IRQ_HPHL_PDM_WD_INT);
if (rouleur->update_wcd_event)
rouleur->update_wcd_event(rouleur->handle,
WCD_BOLERO_EVT_RX_MUTE,
SLV_BOLERO_EVT_RX_MUTE,
(WCD_RX1 << 0x10 | 0x1));
break;
case SND_SOC_DAPM_POST_PMD:
usleep_range(5000, 5100);
if (rouleur->foundry_id == FOUNDRY_ID_SEC)
rouleur->update_wcd_event(rouleur->handle,
WCD_BOLERO_EVT_HPHL_HD2_ENABLE,
SLV_BOLERO_EVT_HPHL_HD2_ENABLE,
0x00);
snd_soc_component_update_bits(component,
ROULEUR_DIG_SWR_PDM_WD_CTL0,
@ -897,7 +898,7 @@ static int rouleur_codec_enable_lo_pa(struct snd_soc_dapm_widget *w,
0x0F, 0x04);
if (rouleur->update_wcd_event)
rouleur->update_wcd_event(rouleur->handle,
WCD_BOLERO_EVT_RX_MUTE,
SLV_BOLERO_EVT_RX_MUTE,
(WCD_RX1 << 0x10));
wcd_enable_irq(&rouleur->irq_info,
ROULEUR_IRQ_HPHL_PDM_WD_INT);
@ -907,7 +908,7 @@ static int rouleur_codec_enable_lo_pa(struct snd_soc_dapm_widget *w,
ROULEUR_IRQ_HPHL_PDM_WD_INT);
if (rouleur->update_wcd_event)
rouleur->update_wcd_event(rouleur->handle,
WCD_BOLERO_EVT_RX_MUTE,
SLV_BOLERO_EVT_RX_MUTE,
(WCD_RX1 << 0x10 | 0x1));
break;
case SND_SOC_DAPM_POST_PMD:
@ -1371,10 +1372,10 @@ void rouleur_disable_bcs_before_slow_insert(struct snd_soc_component *component,
if (rouleur->update_wcd_event) {
if (bcs_disable)
rouleur->update_wcd_event(rouleur->handle,
WCD_BOLERO_EVT_BCS_CLK_OFF, 0);
SLV_BOLERO_EVT_BCS_CLK_OFF, 0);
else
rouleur->update_wcd_event(rouleur->handle,
WCD_BOLERO_EVT_BCS_CLK_OFF, 1);
SLV_BOLERO_EVT_BCS_CLK_OFF, 1);
}
}
@ -1420,7 +1421,7 @@ static int rouleur_event_notify(struct notifier_block *block,
struct wcd_mbhc *mbhc;
switch (event) {
case BOLERO_WCD_EVT_PA_OFF_PRE_SSR:
case BOLERO_SLV_EVT_PA_OFF_PRE_SSR:
snd_soc_component_update_bits(component,
ROULEUR_ANA_HPHPA_CNP_CTL_2,
0xC0, 0x00);
@ -1437,7 +1438,7 @@ static int rouleur_event_notify(struct notifier_block *block,
ROULEUR_ANA_COMBOPA_CTL,
0x80, 0x00);
break;
case BOLERO_WCD_EVT_SSR_DOWN:
case BOLERO_SLV_EVT_SSR_DOWN:
rouleur->dev_up = false;
rouleur->mbhc->wcd_mbhc.deinit_in_progress = true;
mbhc = &rouleur->mbhc->wcd_mbhc;
@ -1446,7 +1447,7 @@ static int rouleur_event_notify(struct notifier_block *block,
rouleur_mbhc_ssr_down(rouleur->mbhc, component);
rouleur_reset(rouleur->dev, 0x01);
break;
case BOLERO_WCD_EVT_SSR_UP:
case BOLERO_SLV_EVT_SSR_UP:
rouleur_reset(rouleur->dev, 0x00);
/* allow reset to take effect */
usleep_range(10000, 10010);
@ -2094,7 +2095,7 @@ static void rouleur_evaluate_soc(struct work_struct *work)
/* Reduce PA Gain by 6DB for low SoC */
if (rouleur->update_wcd_event)
rouleur->update_wcd_event(rouleur->handle,
WCD_BOLERO_EVT_RX_PA_GAIN_UPDATE,
SLV_BOLERO_EVT_RX_PA_GAIN_UPDATE,
true);
rouleur->low_soc = true;
ret = msm_cdc_set_supply_min_voltage(rouleur->dev,
@ -2113,7 +2114,7 @@ static void rouleur_evaluate_soc(struct work_struct *work)
/* Reset PA Gain to default for normal SoC */
if (rouleur->update_wcd_event)
rouleur->update_wcd_event(rouleur->handle,
WCD_BOLERO_EVT_RX_PA_GAIN_UPDATE,
SLV_BOLERO_EVT_RX_PA_GAIN_UPDATE,
false);
ret = msm_cdc_set_supply_min_voltage(rouleur->dev,
rouleur->supplies,

View File

@ -885,8 +885,10 @@ correct_plug_type:
*/
if ((plug_type == MBHC_PLUG_TYPE_HEADSET) ||
(plug_type == MBHC_PLUG_TYPE_ANC_HEADPHONE)) {
pr_debug("%s: plug_type:0x%x already reported\n",
__func__, mbhc->current_plug);
pr_debug("%s: plug_type:0x%x current_plug: 0x%x already reported\n",
__func__, plug_type, mbhc->current_plug);
if (mbhc->current_plug != plug_type)
goto report;
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ADC_MODE, 0);
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ADC_EN, 0);
goto enable_supply;

View File

@ -515,6 +515,15 @@ static void wcd_mbhc_set_and_turnoff_hph_padac(struct wcd_mbhc *mbhc)
int wcd_mbhc_get_impedance(struct wcd_mbhc *mbhc, uint32_t *zl,
uint32_t *zr)
{
int detection_type = -EINVAL;
WCD_MBHC_REG_READ(WCD_MBHC_MECH_DETECTION_TYPE, detection_type);
/* Call compute impedance only when accessory is inserted */
if (!detection_type) {
if (mbhc->mbhc_cb->compute_impedance)
mbhc->mbhc_cb->compute_impedance(mbhc,
&mbhc->zl, &mbhc->zr);
}
*zl = mbhc->zl;
*zr = mbhc->zr;

View File

@ -128,21 +128,6 @@ enum {
WCD_RX3
};
enum {
BOLERO_WCD_EVT_TX_CH_HOLD_CLEAR = 1,
BOLERO_WCD_EVT_PA_OFF_PRE_SSR,
BOLERO_WCD_EVT_SSR_DOWN,
BOLERO_WCD_EVT_SSR_UP,
};
enum {
WCD_BOLERO_EVT_RX_MUTE = 1, /* for RX mute/unmute */
WCD_BOLERO_EVT_IMPED_TRUE, /* for imped true */
WCD_BOLERO_EVT_IMPED_FALSE, /* for imped false */
WCD_BOLERO_EVT_RX_COMPANDER_SOFT_RST,
WCD_BOLERO_EVT_BCS_CLK_OFF,
};
enum {
/* INTR_CTRL_INT_MASK_0 */
WCD937X_IRQ_MBHC_BUTTON_PRESS_DET = 0,

View File

@ -25,6 +25,7 @@
#include "wcd937x-registers.h"
#include "wcd937x.h"
#include "internal.h"
#include "asoc/bolero-slave-internal.h"
#define WCD9370_VARIANT 0
#define WCD9375_VARIANT 5
@ -719,9 +720,6 @@ static int wcd937x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
0x10, 0x10);
usleep_range(100, 110);
set_bit(HPH_PA_DELAY, &wcd937x->status_mask);
ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev,
wcd937x->rx_swr_dev->dev_num,
true);
snd_soc_component_update_bits(component,
WCD937X_DIGITAL_PDM_WD_CTL1, 0x17, 0x13);
break;
@ -748,7 +746,7 @@ static int wcd937x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
0x02, 0x02);
if (wcd937x->update_wcd_event)
wcd937x->update_wcd_event(wcd937x->handle,
WCD_BOLERO_EVT_RX_MUTE,
SLV_BOLERO_EVT_RX_MUTE,
(WCD_RX2 << 0x10));
wcd_enable_irq(&wcd937x->irq_info,
WCD937X_IRQ_HPHR_PDM_WD_INT);
@ -758,7 +756,7 @@ static int wcd937x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
WCD937X_IRQ_HPHR_PDM_WD_INT);
if (wcd937x->update_wcd_event)
wcd937x->update_wcd_event(wcd937x->handle,
WCD_BOLERO_EVT_RX_MUTE,
SLV_BOLERO_EVT_RX_MUTE,
(WCD_RX2 << 0x10 | 0x1));
blocking_notifier_call_chain(&wcd937x->mbhc->notifier,
WCD_EVENT_PRE_HPHR_PA_OFF,
@ -847,7 +845,7 @@ static int wcd937x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
0x02, 0x02);
if (wcd937x->update_wcd_event)
wcd937x->update_wcd_event(wcd937x->handle,
WCD_BOLERO_EVT_RX_MUTE,
SLV_BOLERO_EVT_RX_MUTE,
(WCD_RX1 << 0x10));
wcd_enable_irq(&wcd937x->irq_info,
WCD937X_IRQ_HPHL_PDM_WD_INT);
@ -857,7 +855,7 @@ static int wcd937x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
WCD937X_IRQ_HPHL_PDM_WD_INT);
if (wcd937x->update_wcd_event)
wcd937x->update_wcd_event(wcd937x->handle,
WCD_BOLERO_EVT_RX_MUTE,
SLV_BOLERO_EVT_RX_MUTE,
(WCD_RX1 << 0x10 | 0x1));
blocking_notifier_call_chain(&wcd937x->mbhc->notifier,
WCD_EVENT_PRE_HPHL_PA_OFF,
@ -923,7 +921,7 @@ static int wcd937x_codec_enable_aux_pa(struct snd_soc_dapm_widget *w,
0x02, 0x02);
if (wcd937x->update_wcd_event)
wcd937x->update_wcd_event(wcd937x->handle,
WCD_BOLERO_EVT_RX_MUTE,
SLV_BOLERO_EVT_RX_MUTE,
(WCD_RX3 << 0x10));
wcd_enable_irq(&wcd937x->irq_info, WCD937X_IRQ_AUX_PDM_WD_INT);
break;
@ -931,7 +929,7 @@ static int wcd937x_codec_enable_aux_pa(struct snd_soc_dapm_widget *w,
wcd_disable_irq(&wcd937x->irq_info, WCD937X_IRQ_AUX_PDM_WD_INT);
if (wcd937x->update_wcd_event)
wcd937x->update_wcd_event(wcd937x->handle,
WCD_BOLERO_EVT_RX_MUTE,
SLV_BOLERO_EVT_RX_MUTE,
(WCD_RX3 << 0x10 | 0x1));
break;
case SND_SOC_DAPM_POST_PMD:
@ -993,7 +991,7 @@ static int wcd937x_codec_enable_ear_pa(struct snd_soc_dapm_widget *w,
0x02, 0x02);
if (wcd937x->update_wcd_event)
wcd937x->update_wcd_event(wcd937x->handle,
WCD_BOLERO_EVT_RX_MUTE,
SLV_BOLERO_EVT_RX_MUTE,
(WCD_RX1 << 0x10));
if (wcd937x->ear_rx_path & EAR_RX_PATH_AUX)
wcd_enable_irq(&wcd937x->irq_info,
@ -1011,7 +1009,7 @@ static int wcd937x_codec_enable_ear_pa(struct snd_soc_dapm_widget *w,
WCD937X_IRQ_HPHL_PDM_WD_INT);
if (wcd937x->update_wcd_event)
wcd937x->update_wcd_event(wcd937x->handle,
WCD_BOLERO_EVT_RX_MUTE,
SLV_BOLERO_EVT_RX_MUTE,
(WCD_RX1 << 0x10 | 0x1));
break;
case SND_SOC_DAPM_POST_PMD:
@ -1214,7 +1212,9 @@ static int wcd937x_codec_enable_dmic(struct snd_soc_dapm_widget *w,
dmic_clk_reg, 0x08, 0x08);
snd_soc_component_update_bits(component,
dmic_clk_reg, 0x70, 0x20);
wcd937x_tx_connect_port(component, DMIC0 + (w->shift), true);
ret = swr_slvdev_datapath_control(wcd937x->tx_swr_dev,
wcd937x->tx_swr_dev->dev_num,
true);
break;
case SND_SOC_DAPM_POST_PMD:
wcd937x_tx_connect_port(component, DMIC0 + (w->shift), false);
@ -1330,9 +1330,17 @@ static int wcd937x_tx_swr_ctrl(struct snd_soc_dapm_widget *w,
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
ret = swr_slvdev_datapath_control(wcd937x->tx_swr_dev,
wcd937x->tx_swr_dev->dev_num,
true);
if (strnstr(w->name, "ADC", sizeof("ADC"))) {
/* Enable BCS for Headset mic */
if (w->shift == 1 && !(snd_soc_component_read32(component,
WCD937X_TX_NEW_TX_CH2_SEL) & 0x80)) {
wcd937x_tx_connect_port(component, MBHC, true);
set_bit(AMIC2_BCS_ENABLE, &wcd937x->status_mask);
}
wcd937x_tx_connect_port(component, ADC1 + (w->shift), true);
} else {
wcd937x_tx_connect_port(component, DMIC0 + (w->shift), true);
}
break;
case SND_SOC_DAPM_POST_PMD:
ret = swr_slvdev_datapath_control(wcd937x->tx_swr_dev,
@ -1352,6 +1360,7 @@ static int wcd937x_codec_enable_adc(struct snd_soc_dapm_widget *w,
snd_soc_dapm_to_component(w->dapm);
struct wcd937x_priv *wcd937x =
snd_soc_component_get_drvdata(component);
int ret = 0;
dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__,
w->name, event);
@ -1367,13 +1376,9 @@ static int wcd937x_codec_enable_adc(struct snd_soc_dapm_widget *w,
WCD937X_DIGITAL_CDC_ANA_CLK_CTL, 0x08, 0x08);
snd_soc_component_update_bits(component,
WCD937X_DIGITAL_CDC_ANA_CLK_CTL, 0x10, 0x10);
/* Enable BCS for Headset mic */
if (w->shift == 1 && !(snd_soc_component_read32(component,
WCD937X_TX_NEW_TX_CH2_SEL) & 0x80)) {
wcd937x_tx_connect_port(component, MBHC, true);
set_bit(AMIC2_BCS_ENABLE, &wcd937x->status_mask);
}
wcd937x_tx_connect_port(component, ADC1 + (w->shift), true);
ret = swr_slvdev_datapath_control(wcd937x->tx_swr_dev,
wcd937x->tx_swr_dev->dev_num,
true);
break;
case SND_SOC_DAPM_POST_PMD:
wcd937x_tx_connect_port(component, ADC1 + (w->shift), false);
@ -1387,7 +1392,7 @@ static int wcd937x_codec_enable_adc(struct snd_soc_dapm_widget *w,
break;
};
return 0;
return ret;
}
static int wcd937x_enable_req(struct snd_soc_dapm_widget *w,
@ -1585,10 +1590,10 @@ void wcd937x_disable_bcs_before_slow_insert(struct snd_soc_component *component,
if (wcd937x->update_wcd_event) {
if (bcs_disable)
wcd937x->update_wcd_event(wcd937x->handle,
WCD_BOLERO_EVT_BCS_CLK_OFF, 0);
SLV_BOLERO_EVT_BCS_CLK_OFF, 0);
else
wcd937x->update_wcd_event(wcd937x->handle,
WCD_BOLERO_EVT_BCS_CLK_OFF, 1);
SLV_BOLERO_EVT_BCS_CLK_OFF, 1);
}
}
@ -1636,7 +1641,7 @@ static int wcd937x_event_notify(struct notifier_block *block,
struct wcd_mbhc *mbhc;
switch (event) {
case BOLERO_WCD_EVT_TX_CH_HOLD_CLEAR:
case BOLERO_SLV_EVT_TX_CH_HOLD_CLEAR:
if (amic == 0x1 || amic == 0x2)
reg = WCD937X_ANA_TX_CH2;
else if (amic == 0x3)
@ -1647,7 +1652,7 @@ static int wcd937x_event_notify(struct notifier_block *block,
mask = 0x20;
snd_soc_component_update_bits(component, reg, mask, 0x00);
break;
case BOLERO_WCD_EVT_PA_OFF_PRE_SSR:
case BOLERO_SLV_EVT_PA_OFF_PRE_SSR:
snd_soc_component_update_bits(component, WCD937X_ANA_HPH,
0xC0, 0x00);
snd_soc_component_update_bits(component, WCD937X_ANA_EAR,
@ -1655,7 +1660,7 @@ static int wcd937x_event_notify(struct notifier_block *block,
snd_soc_component_update_bits(component, WCD937X_AUX_AUXPA,
0x80, 0x00);
break;
case BOLERO_WCD_EVT_SSR_DOWN:
case BOLERO_SLV_EVT_SSR_DOWN:
wcd937x->mbhc->wcd_mbhc.deinit_in_progress = true;
mbhc = &wcd937x->mbhc->wcd_mbhc;
wcd937x->usbc_hs_status = get_usbc_hs_status(component,
@ -1663,7 +1668,7 @@ static int wcd937x_event_notify(struct notifier_block *block,
wcd937x_mbhc_ssr_down(wcd937x->mbhc, component);
wcd937x_reset_low(wcd937x->dev);
break;
case BOLERO_WCD_EVT_SSR_UP:
case BOLERO_SLV_EVT_SSR_UP:
wcd937x_reset(wcd937x->dev);
/* allow reset to take effect */
usleep_range(10000, 10010);
@ -2263,7 +2268,7 @@ static const struct snd_soc_dapm_widget wcd937x_dapm_widgets[] = {
adc1_switch, ARRAY_SIZE(adc1_switch),
wcd937x_tx_swr_ctrl, SND_SOC_DAPM_PRE_PMU |
SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_MIXER_E("ADC2_MIXER", SND_SOC_NOPM, 0, 0,
SND_SOC_DAPM_MIXER_E("ADC2_MIXER", SND_SOC_NOPM, 1, 0,
adc2_switch, ARRAY_SIZE(adc2_switch),
wcd937x_tx_swr_ctrl, SND_SOC_DAPM_PRE_PMU |
SND_SOC_DAPM_POST_PMD),
@ -2414,27 +2419,27 @@ static const struct snd_soc_dapm_widget wcd9375_dapm_widgets[] = {
0, dmic1_switch, ARRAY_SIZE(dmic1_switch),
wcd937x_tx_swr_ctrl, SND_SOC_DAPM_PRE_PMU |
SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_MIXER_E("DMIC2_MIXER", SND_SOC_NOPM, 0,
SND_SOC_DAPM_MIXER_E("DMIC2_MIXER", SND_SOC_NOPM, 1,
0, dmic2_switch, ARRAY_SIZE(dmic2_switch),
wcd937x_tx_swr_ctrl, SND_SOC_DAPM_PRE_PMU |
SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_MIXER_E("DMIC3_MIXER", SND_SOC_NOPM, 0,
SND_SOC_DAPM_MIXER_E("DMIC3_MIXER", SND_SOC_NOPM, 2,
0, dmic3_switch, ARRAY_SIZE(dmic3_switch),
wcd937x_tx_swr_ctrl, SND_SOC_DAPM_PRE_PMU |
SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_MIXER_E("DMIC4_MIXER", SND_SOC_NOPM, 0,
SND_SOC_DAPM_MIXER_E("DMIC4_MIXER", SND_SOC_NOPM, 3,
0, dmic4_switch, ARRAY_SIZE(dmic4_switch),
wcd937x_tx_swr_ctrl, SND_SOC_DAPM_PRE_PMU |
SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_MIXER_E("DMIC5_MIXER", SND_SOC_NOPM, 0,
SND_SOC_DAPM_MIXER_E("DMIC5_MIXER", SND_SOC_NOPM, 4,
0, dmic5_switch, ARRAY_SIZE(dmic5_switch),
wcd937x_tx_swr_ctrl, SND_SOC_DAPM_PRE_PMU |
SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_MIXER_E("DMIC6_MIXER", SND_SOC_NOPM, 0,
SND_SOC_DAPM_MIXER_E("DMIC6_MIXER", SND_SOC_NOPM, 5,
0, dmic6_switch, ARRAY_SIZE(dmic6_switch),
wcd937x_tx_swr_ctrl, SND_SOC_DAPM_PRE_PMU |
SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_MIXER_E("ADC3_MIXER", SND_SOC_NOPM, 0, 0, adc3_switch,
SND_SOC_DAPM_MIXER_E("ADC3_MIXER", SND_SOC_NOPM, 2, 0, adc3_switch,
ARRAY_SIZE(adc3_switch), wcd937x_tx_swr_ctrl,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),

View File

@ -146,22 +146,6 @@ enum {
WCD_RX3
};
enum {
BOLERO_WCD_EVT_TX_CH_HOLD_CLEAR = 1,
BOLERO_WCD_EVT_PA_OFF_PRE_SSR,
BOLERO_WCD_EVT_SSR_DOWN,
BOLERO_WCD_EVT_SSR_UP,
BOLERO_WCD_EVT_CLK_NOTIFY,
};
enum {
WCD_BOLERO_EVT_RX_MUTE = 1, /* for RX mute/unmute */
WCD_BOLERO_EVT_IMPED_TRUE, /* for imped true */
WCD_BOLERO_EVT_IMPED_FALSE, /* for imped false */
WCD_BOLERO_EVT_RX_COMPANDER_SOFT_RST,
WCD_BOLERO_EVT_BCS_CLK_OFF,
};
enum {
/* INTR_CTRL_INT_MASK_0 */
WCD938X_IRQ_MBHC_BUTTON_PRESS_DET = 0,

View File

@ -24,6 +24,7 @@
#include "wcd938x-registers.h"
#include "wcd938x.h"
#include "internal.h"
#include "asoc/bolero-slave-internal.h"
#define NUM_SWRS_DT_PARAMS 5
#define WCD938X_VARIANT_ENTRY_SIZE 32
@ -789,7 +790,7 @@ static int wcd938x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
0x80, 0x80);
if (wcd938x->update_wcd_event)
wcd938x->update_wcd_event(wcd938x->handle,
WCD_BOLERO_EVT_RX_MUTE,
SLV_BOLERO_EVT_RX_MUTE,
(WCD_RX2 << 0x10 | 0x1));
ret = swr_slvdev_datapath_control(wcd938x->rx_swr_dev,
wcd938x->rx_swr_dev->dev_num,
@ -840,7 +841,7 @@ static int wcd938x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
WCD938X_ANA_RX_SUPPLIES, 0x02, 0x02);
if (wcd938x->update_wcd_event)
wcd938x->update_wcd_event(wcd938x->handle,
WCD_BOLERO_EVT_RX_MUTE,
SLV_BOLERO_EVT_RX_MUTE,
(WCD_RX2 << 0x10));
wcd_enable_irq(&wcd938x->irq_info,
WCD938X_IRQ_HPHR_PDM_WD_INT);
@ -848,13 +849,13 @@ static int wcd938x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
case SND_SOC_DAPM_PRE_PMD:
if (wcd938x->update_wcd_event)
wcd938x->update_wcd_event(wcd938x->handle,
WCD_BOLERO_EVT_RX_MUTE,
SLV_BOLERO_EVT_RX_MUTE,
(WCD_RX2 << 0x10 | 0x1));
wcd_disable_irq(&wcd938x->irq_info,
WCD938X_IRQ_HPHR_PDM_WD_INT);
if (wcd938x->update_wcd_event && wcd938x->comp2_enable)
wcd938x->update_wcd_event(wcd938x->handle,
WCD_BOLERO_EVT_RX_COMPANDER_SOFT_RST,
SLV_BOLERO_EVT_RX_COMPANDER_SOFT_RST,
(WCD_RX2 << 0x10));
/*
* 7ms sleep is required if compander is enabled as per
@ -925,7 +926,7 @@ static int wcd938x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
0x80, 0x80);
if (wcd938x->update_wcd_event)
wcd938x->update_wcd_event(wcd938x->handle,
WCD_BOLERO_EVT_RX_MUTE,
SLV_BOLERO_EVT_RX_MUTE,
(WCD_RX1 << 0x10 | 0x01));
ret = swr_slvdev_datapath_control(wcd938x->rx_swr_dev,
wcd938x->rx_swr_dev->dev_num,
@ -976,7 +977,7 @@ static int wcd938x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
WCD938X_ANA_RX_SUPPLIES, 0x02, 0x02);
if (wcd938x->update_wcd_event)
wcd938x->update_wcd_event(wcd938x->handle,
WCD_BOLERO_EVT_RX_MUTE,
SLV_BOLERO_EVT_RX_MUTE,
(WCD_RX1 << 0x10));
wcd_enable_irq(&wcd938x->irq_info,
WCD938X_IRQ_HPHL_PDM_WD_INT);
@ -984,13 +985,13 @@ static int wcd938x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
case SND_SOC_DAPM_PRE_PMD:
if (wcd938x->update_wcd_event)
wcd938x->update_wcd_event(wcd938x->handle,
WCD_BOLERO_EVT_RX_MUTE,
SLV_BOLERO_EVT_RX_MUTE,
(WCD_RX1 << 0x10 | 0x1));
wcd_disable_irq(&wcd938x->irq_info,
WCD938X_IRQ_HPHL_PDM_WD_INT);
if (wcd938x->update_wcd_event && wcd938x->comp1_enable)
wcd938x->update_wcd_event(wcd938x->handle,
WCD_BOLERO_EVT_RX_COMPANDER_SOFT_RST,
SLV_BOLERO_EVT_RX_COMPANDER_SOFT_RST,
(WCD_RX1 << 0x10));
/*
* 7ms sleep is required if compander is enabled as per
@ -1072,7 +1073,7 @@ static int wcd938x_codec_enable_aux_pa(struct snd_soc_dapm_widget *w,
0x02, 0x02);
if (wcd938x->update_wcd_event)
wcd938x->update_wcd_event(wcd938x->handle,
WCD_BOLERO_EVT_RX_MUTE,
SLV_BOLERO_EVT_RX_MUTE,
(WCD_RX3 << 0x10));
wcd_enable_irq(&wcd938x->irq_info, WCD938X_IRQ_AUX_PDM_WD_INT);
break;
@ -1081,7 +1082,7 @@ static int wcd938x_codec_enable_aux_pa(struct snd_soc_dapm_widget *w,
WCD938X_IRQ_AUX_PDM_WD_INT);
if (wcd938x->update_wcd_event)
wcd938x->update_wcd_event(wcd938x->handle,
WCD_BOLERO_EVT_RX_MUTE,
SLV_BOLERO_EVT_RX_MUTE,
(WCD_RX3 << 0x10 | 0x1));
break;
case SND_SOC_DAPM_POST_PMD:
@ -1152,14 +1153,14 @@ static int wcd938x_codec_enable_ear_pa(struct snd_soc_dapm_widget *w,
if (wcd938x->ear_rx_path & EAR_RX_PATH_AUX) {
if (wcd938x->update_wcd_event)
wcd938x->update_wcd_event(wcd938x->handle,
WCD_BOLERO_EVT_RX_MUTE,
SLV_BOLERO_EVT_RX_MUTE,
(WCD_RX3 << 0x10));
wcd_enable_irq(&wcd938x->irq_info,
WCD938X_IRQ_AUX_PDM_WD_INT);
} else {
if (wcd938x->update_wcd_event)
wcd938x->update_wcd_event(wcd938x->handle,
WCD_BOLERO_EVT_RX_MUTE,
SLV_BOLERO_EVT_RX_MUTE,
(WCD_RX1 << 0x10));
wcd_enable_irq(&wcd938x->irq_info,
WCD938X_IRQ_HPHL_PDM_WD_INT);
@ -1171,14 +1172,14 @@ static int wcd938x_codec_enable_ear_pa(struct snd_soc_dapm_widget *w,
WCD938X_IRQ_AUX_PDM_WD_INT);
if (wcd938x->update_wcd_event)
wcd938x->update_wcd_event(wcd938x->handle,
WCD_BOLERO_EVT_RX_MUTE,
SLV_BOLERO_EVT_RX_MUTE,
(WCD_RX3 << 0x10 | 0x1));
} else {
wcd_disable_irq(&wcd938x->irq_info,
WCD938X_IRQ_HPHL_PDM_WD_INT);
if (wcd938x->update_wcd_event)
wcd938x->update_wcd_event(wcd938x->handle,
WCD_BOLERO_EVT_RX_MUTE,
SLV_BOLERO_EVT_RX_MUTE,
(WCD_RX1 << 0x10 | 0x1));
}
break;
@ -1775,10 +1776,10 @@ void wcd938x_disable_bcs_before_slow_insert(struct snd_soc_component *component,
if (wcd938x->update_wcd_event) {
if (bcs_disable)
wcd938x->update_wcd_event(wcd938x->handle,
WCD_BOLERO_EVT_BCS_CLK_OFF, 0);
SLV_BOLERO_EVT_BCS_CLK_OFF, 0);
else
wcd938x->update_wcd_event(wcd938x->handle,
WCD_BOLERO_EVT_BCS_CLK_OFF, 1);
SLV_BOLERO_EVT_BCS_CLK_OFF, 1);
}
}
@ -2114,7 +2115,7 @@ static int wcd938x_event_notify(struct notifier_block *block,
struct wcd_mbhc *mbhc;
switch (event) {
case BOLERO_WCD_EVT_TX_CH_HOLD_CLEAR:
case BOLERO_SLV_EVT_TX_CH_HOLD_CLEAR:
if (test_bit(WCD_ADC1, &wcd938x->status_mask)) {
snd_soc_component_update_bits(component,
WCD938X_ANA_TX_CH2, 0x40, 0x00);
@ -2140,7 +2141,7 @@ static int wcd938x_event_notify(struct notifier_block *block,
clear_bit(WCD_ADC4, &wcd938x->status_mask);
}
break;
case BOLERO_WCD_EVT_PA_OFF_PRE_SSR:
case BOLERO_SLV_EVT_PA_OFF_PRE_SSR:
snd_soc_component_update_bits(component, WCD938X_ANA_HPH,
0xC0, 0x00);
snd_soc_component_update_bits(component, WCD938X_ANA_EAR,
@ -2148,7 +2149,7 @@ static int wcd938x_event_notify(struct notifier_block *block,
snd_soc_component_update_bits(component, WCD938X_AUX_AUXPA,
0x80, 0x00);
break;
case BOLERO_WCD_EVT_SSR_DOWN:
case BOLERO_SLV_EVT_SSR_DOWN:
wcd938x->dev_up = false;
if(wcd938x->notify_swr_dmic)
blocking_notifier_call_chain(&wcd938x->notifier,
@ -2163,7 +2164,7 @@ static int wcd938x_event_notify(struct notifier_block *block,
wcd938x_mbhc_ssr_down(wcd938x->mbhc, component);
wcd938x_reset_low(wcd938x->dev);
break;
case BOLERO_WCD_EVT_SSR_UP:
case BOLERO_SLV_EVT_SSR_UP:
wcd938x_reset(wcd938x->dev);
/* allow reset to take effect */
usleep_range(10000, 10010);
@ -2192,7 +2193,7 @@ static int wcd938x_event_notify(struct notifier_block *block,
WCD938X_EVT_SSR_UP,
NULL);
break;
case BOLERO_WCD_EVT_CLK_NOTIFY:
case BOLERO_SLV_EVT_CLK_NOTIFY:
snd_soc_component_update_bits(component,
WCD938X_DIGITAL_TOP_CLK_CFG, 0x06,
((val >> 0x10) << 0x01));

View File

@ -28,6 +28,7 @@
#include <asoc/msm-cdc-pinctrl.h>
#include "wsa881x.h"
#include "wsa881x-temp-sensor.h"
#include "asoc/bolero-slave-internal.h"
#define DRV_NAME "wsa-codec"
#define WSA881X_NUM_RETRY 5
@ -111,16 +112,6 @@ struct wsa881x_priv {
bool enable);
};
/* from bolero to WSA events */
enum {
BOLERO_WSA_EVT_TX_CH_HOLD_CLEAR = 1,
BOLERO_WSA_EVT_PA_OFF_PRE_SSR,
BOLERO_WSA_EVT_SSR_DOWN,
BOLERO_WSA_EVT_SSR_UP,
BOLERO_WSA_EVT_PA_ON_POST_FSCLK,
BOLERO_WSA_EVT_PA_ON_POST_FSCLK_ADIE_LB,
};
struct wsa_ctrl_platform_data {
void *handle;
int (*update_wsa_event)(void *handle, u16 event, u32 data);
@ -1395,7 +1386,7 @@ static int wsa881x_event_notify(struct notifier_block *nb,
return -EINVAL;
switch (event) {
case BOLERO_WSA_EVT_PA_OFF_PRE_SSR:
case BOLERO_SLV_EVT_PA_OFF_PRE_SSR:
snd_soc_component_update_bits(wsa881x->component,
WSA881X_SPKR_DRV_GAIN,
0xF0, 0xC0);
@ -1403,8 +1394,8 @@ static int wsa881x_event_notify(struct notifier_block *nb,
WSA881X_SPKR_DRV_EN,
0x80, 0x00);
break;
case BOLERO_WSA_EVT_PA_ON_POST_FSCLK:
case BOLERO_WSA_EVT_PA_ON_POST_FSCLK_ADIE_LB:
case BOLERO_SLV_EVT_PA_ON_POST_FSCLK:
case BOLERO_SLV_EVT_PA_ON_POST_FSCLK_ADIE_LB:
if ((snd_soc_component_read32(wsa881x->component,
WSA881X_SPKR_DAC_CTL) & 0x80) == 0x80)
snd_soc_component_update_bits(wsa881x->component,

View File

@ -60,15 +60,6 @@ enum {
SWR_VISENSE_PORT,
};
enum {
BOLERO_WSA_EVT_TX_CH_HOLD_CLEAR = 1,
BOLERO_WSA_EVT_PA_OFF_PRE_SSR,
BOLERO_WSA_EVT_SSR_DOWN,
BOLERO_WSA_EVT_SSR_UP,
BOLERO_WSA_EVT_PA_ON_POST_FSCLK,
BOLERO_WSA_EVT_PA_ON_POST_FSCLK_ADIE_LB,
};
struct wsa_ctrl_platform_data {
void *handle;
int (*update_wsa_event)(void *handle, u16 event, u32 data);

View File

@ -29,6 +29,7 @@
#include <asoc/msm-cdc-supply.h>
#include "wsa883x.h"
#include "internal.h"
#include "asoc/bolero-slave-internal.h"
#define T1_TEMP -10
#define T2_TEMP 150
@ -97,11 +98,13 @@ static const struct wsa_reg_mask_val reg_init[] = {
{WSA883X_CDC_SPK_DSM_R5, 0xFF, 0x8B},
{WSA883X_CDC_SPK_DSM_R6, 0xFF, 0x9B},
{WSA883X_CDC_SPK_DSM_R7, 0xFF, 0x3F},
{WSA883X_VBAT_SNS, 0x60, 0x20},
{WSA883X_DRE_CTL_0, 0xF0, 0x90},
{WSA883X_DRE_IDLE_DET_CTL, 0x10, 0x00},
{WSA883X_CURRENT_LIMIT, 0x78, 0x20},
{WSA883X_CURRENT_LIMIT, 0x78, 0x40},
{WSA883X_DRE_CTL_0, 0x07, 0x02},
{WSA883X_VAGC_TIME, 0x0F, 0x0F},
{WSA883X_VAGC_ATTN_LVL_1_2, 0x70, 0x10},
{WSA883X_VAGC_ATTN_LVL_3, 0x07, 0x02},
{WSA883X_VAGC_CTL, 0x01, 0x01},
{WSA883X_TAGC_CTL, 0x0E, 0x0A},
@ -1051,6 +1054,12 @@ static int wsa883x_spkr_event(struct snd_soc_dapm_widget *w,
/* Force remove group */
swr_remove_from_group(wsa883x->swr_slave,
wsa883x->swr_slave->dev_num);
snd_soc_component_update_bits(component,
WSA883X_VBAT_ADC_FLT_CTL,
0x0E, 0x06);
snd_soc_component_update_bits(component,
WSA883X_VBAT_ADC_FLT_CTL,
0x01, 0x01);
if (test_bit(SPKR_ADIE_LB, &wsa883x->status_mask))
snd_soc_component_update_bits(component,
WSA883X_PA_FSM_CTL, 0x01, 0x01);
@ -1059,6 +1068,12 @@ static int wsa883x_spkr_event(struct snd_soc_dapm_widget *w,
if (!test_bit(SPKR_ADIE_LB, &wsa883x->status_mask))
wcd_disable_irq(&wsa883x->irq_info,
WSA883X_IRQ_INT_PDM_WD);
snd_soc_component_update_bits(component,
WSA883X_VBAT_ADC_FLT_CTL,
0x01, 0x00);
snd_soc_component_update_bits(component,
WSA883X_VBAT_ADC_FLT_CTL,
0x0E, 0x00);
snd_soc_component_update_bits(component, WSA883X_PA_FSM_CTL,
0x01, 0x00);
snd_soc_component_update_bits(component, WSA883X_PDM_WD_CTL,
@ -1422,7 +1437,7 @@ static int wsa883x_event_notify(struct notifier_block *nb,
return -EINVAL;
switch (event) {
case BOLERO_WSA_EVT_PA_OFF_PRE_SSR:
case BOLERO_SLV_EVT_PA_OFF_PRE_SSR:
if (test_bit(SPKR_STATUS, &wsa883x->status_mask))
snd_soc_component_update_bits(wsa883x->component,
WSA883X_PA_FSM_CTL,
@ -1430,14 +1445,14 @@ static int wsa883x_event_notify(struct notifier_block *nb,
wsa883x_swr_down(wsa883x);
break;
case BOLERO_WSA_EVT_SSR_UP:
case BOLERO_SLV_EVT_SSR_UP:
wsa883x_swr_up(wsa883x);
/* Add delay to allow enumerate */
usleep_range(20000, 20010);
wsa883x_swr_reset(wsa883x);
break;
case BOLERO_WSA_EVT_PA_ON_POST_FSCLK:
case BOLERO_SLV_EVT_PA_ON_POST_FSCLK:
if (test_bit(SPKR_STATUS, &wsa883x->status_mask)) {
snd_soc_component_update_bits(wsa883x->component,
WSA883X_PDM_WD_CTL,
@ -1456,7 +1471,7 @@ static int wsa883x_event_notify(struct notifier_block *nb,
usleep_range(5000, 5050);
}
break;
case BOLERO_WSA_EVT_PA_ON_POST_FSCLK_ADIE_LB:
case BOLERO_SLV_EVT_PA_ON_POST_FSCLK_ADIE_LB:
if (test_bit(SPKR_STATUS, &wsa883x->status_mask))
set_bit(SPKR_ADIE_LB, &wsa883x->status_mask);
break;

View File

@ -41,19 +41,19 @@ static struct port_params tx_frame_params_default[SWR_MSTR_PORT_LEN] = {
};
static struct port_params tx_frame_params_wcd937x[SWR_MSTR_PORT_LEN] = {
{3, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX1 */
{3, 2, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1, 0x00, 0x00}, /* TX2 */
{3, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1, 0x00, 0x00}, /* TX1 */
{3, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */
{3, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX3 */
};
static struct swr_mstr_port_map sm_port_map[] = {
{TX_MACRO, SWR_UC0, tx_frame_params_default},
{VA_MACRO, SWR_UC0, tx_frame_params_default},
{RX_MACRO, SWR_UC0, rx_frame_params_default},
{RX_MACRO, SWR_UC1, rx_frame_params_dsd},
};
static struct swr_mstr_port_map sm_port_map_wcd937x[] = {
{TX_MACRO, SWR_UC0, tx_frame_params_wcd937x},
{VA_MACRO, SWR_UC0, tx_frame_params_wcd937x},
{RX_MACRO, SWR_UC0, rx_frame_params_default},
{RX_MACRO, SWR_UC1, rx_frame_params_dsd},
};

View File

@ -14,6 +14,7 @@
#include <linux/input.h>
#include <linux/of_device.h>
#include <linux/soc/qcom/fsa4480-i2c.h>
#include <linux/nvmem-consumer.h>
#include <sound/core.h>
#include <sound/soc.h>
#include <sound/soc-dapm.h>
@ -6368,6 +6369,7 @@ static int msm_aux_codec_init(struct snd_soc_pcm_runtime *rtd)
struct snd_info_entry *entry;
struct snd_card *card = NULL;
struct msm_asoc_mach_data *pdata;
bool is_wcd938x = false;
pdata = snd_soc_card_get_drvdata(rtd->card);
if(!pdata)
@ -6387,9 +6389,11 @@ static int msm_aux_codec_init(struct snd_soc_pcm_runtime *rtd)
}
component = snd_soc_rtdcom_lookup(rtd, WCD938X_DRV_NAME);
if (!component) {
if (!component)
component = snd_soc_rtdcom_lookup(rtd, WCD937X_DRV_NAME);
}
else
is_wcd938x = true;
if (!component) {
pr_err("%s component is NULL\n", __func__);
return -EINVAL;
@ -6460,7 +6464,12 @@ mbhc_cfg_cal:
if (!mbhc_calibration)
return -ENOMEM;
wcd_mbhc_cfg.calibration = mbhc_calibration;
ret = wcd938x_mbhc_hs_detect(component, &wcd_mbhc_cfg);
if (is_wcd938x)
ret = wcd938x_mbhc_hs_detect(component, &wcd_mbhc_cfg);
else
ret = wcd937x_mbhc_hs_detect(component, &wcd_mbhc_cfg);
if (ret) {
dev_err(component->dev, "%s: mbhc hs detect failed, err:%d\n",
__func__, ret);
@ -6594,6 +6603,49 @@ static int msm_audio_ssr_register(struct device *dev)
return ret;
}
static int msm_asoc_parse_soundcard_name(struct platform_device *pdev,
struct snd_soc_card *card)
{
struct nvmem_cell *cell;
size_t len;
u32 *buf;
u32 adsp_var_idx = 0;
int ret = 0;
/* get adsp variant idx */
cell = nvmem_cell_get(&pdev->dev, "adsp_variant");
if (IS_ERR_OR_NULL(cell)) {
dev_dbg(&pdev->dev, "%s: FAILED to get nvmem cell \n", __func__);
goto parse;
}
buf = nvmem_cell_read(cell, &len);
nvmem_cell_put(cell);
if (IS_ERR_OR_NULL(buf)) {
dev_dbg(&pdev->dev, "%s: FAILED to read nvmem cell \n", __func__);
goto parse;
}
if (len <= 0 || len > sizeof(u32)) {
dev_dbg(&pdev->dev, "%s: nvmem cell length out of range: %d\n",
__func__, len);
kfree(buf);
goto parse;
}
memcpy(&adsp_var_idx, buf, len);
kfree(buf);
parse:
if(adsp_var_idx == 1)
ret = snd_soc_of_parse_card_name(card, "qcom,sku-model");
else
ret = snd_soc_of_parse_card_name(card, "qcom,model");
if (ret)
dev_err(&pdev->dev, "%s: parse card name failed, err:%d\n",
__func__, ret);
return ret;
}
static int msm_asoc_machine_probe(struct platform_device *pdev)
{
struct snd_soc_card *card = NULL;
@ -6629,9 +6681,9 @@ static int msm_asoc_machine_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, card);
snd_soc_card_set_drvdata(card, pdata);
ret = snd_soc_of_parse_card_name(card, "qcom,model");
ret = msm_asoc_parse_soundcard_name(pdev, card);
if (ret) {
dev_err(&pdev->dev, "%s: parse card name failed, err:%d\n",
dev_err(&pdev->dev, "%s: parse soundcard name failed, err:%d\n",
__func__, ret);
goto err;
}

View File

@ -53,8 +53,8 @@ static struct port_params tx_frame_params_default[SWR_MSTR_PORT_LEN] = {
/* TX UC1: TX1: 1ch, TX2: 2chs, TX3: 1ch(MBHC) */
static struct port_params tx_frame_params_shima[SWR_MSTR_PORT_LEN] = {
{3, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX1 */
{3, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1, 0x00, 0x00}, /* TX2 */
{3, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1, 0x00, 0x00}, /* TX1 */
{3, 2, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */
{7, 2, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX3 */
};
@ -72,6 +72,20 @@ static struct port_params tx_frame_params_0p6MHz[SWR_MSTR_PORT_LEN] = {
{1, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX3 */
};
/* 4.8 MHz clock */
static struct port_params tx_frame_params_shima_4p8MHz[SWR_MSTR_PORT_LEN] = {
{3, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1, 0x00, 0x00}, /* TX1 */
{3, 2, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */
{7, 2, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX3 */
};
/* 0.6 MHz clock */
static struct port_params tx_frame_params_shima_0p6MHz[SWR_MSTR_PORT_LEN] = {
{1, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX1 */
{1, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */
{1, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX3 */
};
static struct swr_mstr_port_map sm_port_map[] = {
{TX_MACRO, SWR_UC0, tx_frame_params_default},
{TX_MACRO, SWR_UC1, tx_frame_params_4p8MHz},
@ -83,6 +97,8 @@ static struct swr_mstr_port_map sm_port_map[] = {
static struct swr_mstr_port_map sm_port_map_shima[] = {
{TX_MACRO, SWR_UC0, tx_frame_params_shima},
{TX_MACRO, SWR_UC1, tx_frame_params_shima_4p8MHz},
{TX_MACRO, SWR_UC2, tx_frame_params_shima_0p6MHz},
{RX_MACRO, SWR_UC0, rx_frame_params_default},
{RX_MACRO, SWR_UC1, rx_frame_params_dsd},
{WSA_MACRO, SWR_UC0, wsa_frame_params_default},

View File

@ -13,3 +13,4 @@ CONFIG_SND_SOC_MSM_STUB=m
CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=m
CONFIG_MSM_QDSP6V2_CODECS=m
CONFIG_SND_EVENT=m
CONFIG_SND_SOC_SA8155=m

View File

@ -25,3 +25,4 @@
#define CONFIG_SND_SOC_MSM_HDMI_CODEC_RX 1
#define CONFIG_MSM_QDSP6V2_CODECS 1
#define CONFIG_SND_EVENT 1
#define CONFIG_SND_SOC_SA8155 1

View File

@ -31,4 +31,7 @@ export CONFIG_SND_SOC_WCD937X_SLAVE=m
export CONFIG_SND_SOC_WSA881X_ANALOG=m
export CONFIG_SND_SOC_HOLI=m
export CONFIG_SND_EVENT=m
export CONFIG_TDM_DISABLE=m
export CONFIG_MI2S_DISABLE=m
export CONFIG_AUXPCM_DISABLE=m
export CONFIG_DIGITAL_CDC_RSC_MGR=m

View File

@ -35,4 +35,7 @@
#define CONFIG_SND_SOC_WSA881X_ANALOG 1
#define CONFIG_SND_SOC_HOLI 1
#define CONFIG_SND_EVENT 1
#define CONFIG_TDM_DISABLE 1
#define CONFIG_MI2S_DISABLE 1
#define CONFIG_AUXPCM_DISABLE 1
#define CONFIG_DIGITAL_CDC_RSC_MGR 1

View File

@ -13,6 +13,18 @@ ifeq ($(KERNEL_BUILD), 1)
AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio
endif
ifeq ($(CONFIG_SND_SOC_AUTO), y)
ifdef CONFIG_SND_SOC_SA8155
include $(AUDIO_ROOT)/config/sa8155auto.conf
export
INCS += -include $(AUDIO_ROOT)/config/sa8155autoconf.h
endif
ifdef CONFIG_SND_SOC_SA6155
include $(AUDIO_ROOT)/config/sa6155auto.conf
export
INCS += -include $(AUDIO_ROOT)/config/sa6155autoconf.h
endif
else
ifeq ($(KERNEL_BUILD), 0)
ifeq ($(CONFIG_ARCH_SM6150), y)
ifdef CONFIG_SND_SOC_SA6155
@ -71,14 +83,13 @@ ifeq ($(KERNEL_BUILD), 0)
export
INCS += -include $(AUDIO_ROOT)/config/qcs405autoconf.h
endif
ifeq ($(CONFIG_QTI_GVM), y)
ifeq ($(CONFIG_QTI_QUIN_GVM), y)
include $(AUDIO_ROOT)/config/gvmauto.conf
export
INCS += -include $(AUDIO_ROOT)/config/gvmautoconf.h
endif
endif
endif
# As per target team, build is done as follows:
# Defconfig : build with default flags

View File

@ -12,17 +12,14 @@
#include <linux/mutex.h>
#include <linux/list.h>
#include <linux/dma-mapping.h>
#include <linux/dma-contiguous.h>
#include <linux/dma-buf.h>
#include <linux/iommu.h>
#include <linux/platform_device.h>
#include <linux/of_device.h>
#include <linux/export.h>
#include <linux/ion_kernel.h>
#include <linux/ion.h>
#include <ipc/apr.h>
#include <asm/dma-iommu.h>
#include <dsp/msm_audio_ion.h>
#include <soc/qcom/secure_buffer.h>
#include <linux/habmm.h>
#define MSM_AUDIO_ION_PROBED (1 << 0)
@ -34,14 +31,10 @@
#define MSM_AUDIO_SMMU_VM_CMD_UNMAP 0x00000002
#define MSM_AUDIO_SMMU_VM_HAB_MINOR_ID 1
enum msm_audio_mem_type{
MSM_AUDIO_MEM_TYPE_ION,
MSM_AUDIO_MEM_TYPE_DMA,
};
struct msm_audio_ion_private {
bool smmu_enabled;
struct device *cb_dev;
struct device *cb_cma_dev;
u8 device_status;
struct list_head alloc_list;
struct mutex list_mutex;
@ -50,12 +43,10 @@ struct msm_audio_ion_private {
struct msm_audio_alloc_data {
size_t len;
void *vaddr;
void *handle;
struct dma_buf *dma_buf;
struct dma_buf_attachment *attach;
struct sg_table *table;
struct list_head list;
dma_addr_t *paddr;
enum msm_audio_mem_type type;
u32 export_id;
};
@ -97,31 +88,9 @@ static void msm_audio_ion_add_allocation(
mutex_unlock(&(msm_audio_ion_data->list_mutex));
}
static int msm_audio_dma_buf_map(void *handle, void *vaddr,
dma_addr_t *paddr,
size_t *len)
{
struct msm_audio_alloc_data *alloc_data;
/* Data required per buffer mapping */
alloc_data = kzalloc(sizeof(*alloc_data), GFP_KERNEL);
if (!alloc_data)
return -ENOMEM;
alloc_data->handle = handle;
alloc_data->len = *len;
alloc_data->vaddr = vaddr;
alloc_data->paddr = paddr;
alloc_data->type = MSM_AUDIO_MEM_TYPE_DMA;
msm_audio_ion_add_allocation(&msm_audio_ion_data,
alloc_data);
return 0;
}
static int msm_audio_ion_dma_buf_map(struct dma_buf *dma_buf,
dma_addr_t *addr, size_t *len)
static int msm_audio_dma_buf_map(struct dma_buf *dma_buf,
dma_addr_t *addr, size_t *len,
bool cma_mem)
{
struct msm_audio_alloc_data *alloc_data;
@ -129,20 +98,23 @@ static int msm_audio_ion_dma_buf_map(struct dma_buf *dma_buf,
unsigned long ionflag = 0;
int rc = 0;
cb_dev = msm_audio_ion_data.cb_dev;
if (cma_mem)
cb_dev = msm_audio_ion_data.cb_cma_dev;
else
cb_dev = msm_audio_ion_data.cb_dev;
/* Data required per buffer mapping */
alloc_data = kzalloc(sizeof(*alloc_data), GFP_KERNEL);
if (!alloc_data)
return -ENOMEM;
alloc_data->handle = (void*)dma_buf;
alloc_data->dma_buf = dma_buf;
alloc_data->len = dma_buf->size;
alloc_data->type = MSM_AUDIO_MEM_TYPE_ION;
*len = dma_buf->size;
/* Attach the dma_buf to context bank device */
alloc_data->attach = dma_buf_attach(dma_buf, cb_dev);
alloc_data->attach = dma_buf_attach(alloc_data->dma_buf,
cb_dev);
if (IS_ERR(alloc_data->attach)) {
rc = PTR_ERR(alloc_data->attach);
dev_err(cb_dev,
@ -152,7 +124,7 @@ static int msm_audio_ion_dma_buf_map(struct dma_buf *dma_buf,
}
/* For uncached buffers, avoid cache maintanance */
rc = dma_buf_get_flags(dma_buf, &ionflag);
rc = dma_buf_get_flags(alloc_data->dma_buf, &ionflag);
if (rc) {
dev_err(cb_dev, "%s: dma_buf_get_flags failed: %d\n",
__func__, rc);
@ -180,121 +152,74 @@ static int msm_audio_ion_dma_buf_map(struct dma_buf *dma_buf,
/* physical address from mapping */
*addr = MSM_AUDIO_ION_PHYS_ADDR(alloc_data);
alloc_data->paddr = addr;
msm_audio_ion_add_allocation(&msm_audio_ion_data,
alloc_data);
return rc;
detach_dma_buf:
dma_buf_detach(dma_buf, alloc_data->attach);
dma_buf_detach(alloc_data->dma_buf,
alloc_data->attach);
free_alloc_data:
kfree(alloc_data);
return rc;
}
static int msm_audio_ion_unmap_kernel(void *vaddr, void *handle)
{
int rc = 0;
struct device *cb_dev = msm_audio_ion_data.cb_dev;
if (!vaddr) {
dev_err(cb_dev,
"%s: cannot find allocation for handle %pK\n",
__func__, handle);
rc = -EINVAL;
goto err;
}
dma_buf_vunmap((struct dma_buf*)handle, vaddr);
rc = dma_buf_end_cpu_access((struct dma_buf*)handle, DMA_BIDIRECTIONAL);
if (rc) {
dev_err(cb_dev, "%s: kmap dma_buf_end_cpu_access fail\n",
__func__);
goto err;
}
err:
return rc;
}
static int msm_audio_dma_buf_unmap(void *handle)
static int msm_audio_dma_buf_unmap(struct dma_buf *dma_buf, bool cma_mem)
{
int rc = 0;
struct msm_audio_alloc_data *alloc_data = NULL;
struct list_head *ptr, *next;
struct device *cb_dev = msm_audio_ion_data.cb_dev;
struct device *cb_dev;
bool found = false;
if (cma_mem)
cb_dev = msm_audio_ion_data.cb_cma_dev;
else
cb_dev = msm_audio_ion_data.cb_dev;
/*
* Though list_for_each_safe is delete safe, lock
* should be explicitly acquired to avoid race condition
* on adding elements to the list.
*/
mutex_lock(&(msm_audio_ion_data.list_mutex));
list_for_each_safe(ptr, next, &(msm_audio_ion_data.alloc_list)) {
list_for_each_safe(ptr, next,
&(msm_audio_ion_data.alloc_list)) {
alloc_data = list_entry(ptr, struct msm_audio_alloc_data, list);
if(alloc_data->type == MSM_AUDIO_MEM_TYPE_ION) {
if (alloc_data->handle == handle) {
rc = msm_audio_ion_unmap_kernel(
alloc_data->vaddr,
handle);
if(rc) {
pr_err("%s: Unable to unmap ion mem rc: %d\n",
__func__, rc);
mutex_unlock(&(msm_audio_ion_data.list_mutex));
return rc;
}
alloc_data = list_entry(ptr, struct msm_audio_alloc_data,
list);
found = true;
dma_buf_unmap_attachment(alloc_data->attach,
alloc_data->table,
DMA_BIDIRECTIONAL);
if (alloc_data->dma_buf == dma_buf) {
found = true;
dma_buf_unmap_attachment(alloc_data->attach,
alloc_data->table,
DMA_BIDIRECTIONAL);
dma_buf_detach((struct dma_buf*)
alloc_data->handle,
alloc_data->attach);
dma_buf_detach(alloc_data->dma_buf,
alloc_data->attach);
dma_buf_put((struct dma_buf*)
alloc_data->handle);
dma_buf_put(alloc_data->dma_buf);
list_del(&(alloc_data->list));
kfree(alloc_data);
break;
}
} else {
alloc_data = list_entry(ptr,
struct msm_audio_alloc_data,
list);
if (alloc_data->handle == handle) {
found = true;
dma_free_coherent(cb_dev, alloc_data->len,
alloc_data->vaddr,
*(alloc_data->paddr));
list_del(&(alloc_data->list));
kfree(alloc_data);
break;
}
list_del(&(alloc_data->list));
kfree(alloc_data);
break;
}
}
mutex_unlock(&(msm_audio_ion_data.list_mutex));
if (!found) {
dev_err(cb_dev,
"%s: cannot find allocation, handle %pK",
__func__, handle);
"%s: cannot find allocation, dma_buf %pK",
__func__, dma_buf);
rc = -EINVAL;
}
return rc;
}
static int msm_audio_ion_smmu_map(void *handle,
static int msm_audio_ion_smmu_map(struct dma_buf *dma_buf,
dma_addr_t *paddr, size_t *len)
{
int rc;
@ -307,20 +232,20 @@ static int msm_audio_ion_smmu_map(void *handle,
struct msm_audio_alloc_data *alloc_data = NULL;
unsigned long delay = jiffies + (HZ / 2);
*len = ((struct dma_buf*)handle)->size;
*len = dma_buf->size;
mutex_lock(&(msm_audio_ion_data.list_mutex));
list_for_each_entry(alloc_data, &(msm_audio_ion_data.alloc_list),
list) {
if (alloc_data->handle == handle) {
if (alloc_data->dma_buf == dma_buf) {
found = true;
/* Export the buffer to physical VM */
rc = habmm_export(msm_audio_ion_hab_handle, handle, *len,
rc = habmm_export(msm_audio_ion_hab_handle, dma_buf, *len,
&export_id, HABMM_EXPIMP_FLAGS_DMABUF);
if (rc) {
pr_err("%s: habmm_export failed handle = %pK, len = %zd, rc = %d\n",
__func__, handle, *len, rc);
pr_err("%s: habmm_export failed dma_buf = %pK, len = %zd, rc = %d\n",
__func__, dma_buf, *len, rc);
goto err;
}
@ -374,7 +299,7 @@ static int msm_audio_ion_smmu_map(void *handle,
mutex_unlock(&(msm_audio_ion_data.list_mutex));
if (!found) {
pr_err("%s: cannot find allocation, handle %pK\n", __func__, handle);
pr_err("%s: cannot find allocation, dma_buf %pK", __func__, dma_buf);
return -EINVAL;
}
@ -388,7 +313,7 @@ err:
return rc;
}
static int msm_audio_ion_smmu_unmap(void *handle)
static int msm_audio_ion_smmu_unmap(struct dma_buf *dma_buf)
{
int rc;
bool found = false;
@ -407,7 +332,7 @@ static int msm_audio_ion_smmu_unmap(void *handle)
list_for_each_entry_safe(alloc_data, next,
&(msm_audio_ion_data.alloc_list), list) {
if (alloc_data->handle == handle) {
if (alloc_data->dma_buf == dma_buf) {
found = true;
smmu_unmap_cmd.cmd_id = MSM_AUDIO_SMMU_VM_CMD_UNMAP;
smmu_unmap_cmd.export_id = alloc_data->export_id;
@ -463,7 +388,7 @@ static int msm_audio_ion_smmu_unmap(void *handle)
mutex_unlock(&(msm_audio_ion_data.list_mutex));
if (!found) {
pr_err("%s: cannot find allocation, handle %pK\n", __func__, handle);
pr_err("%s: cannot find allocation, dma_buf %pK\n", __func__, dma_buf);
rc = -EINVAL;
}
@ -486,32 +411,31 @@ static int msm_audio_ion_get_phys(struct dma_buf *dma_buf,
{
int rc = 0;
rc = msm_audio_ion_dma_buf_map(dma_buf, addr, len);
rc = msm_audio_dma_buf_map(dma_buf, addr, len, false);
if (rc) {
pr_err("%s: failed to map DMA buf, err = %d\n",
__func__, rc);
goto err;
}
pr_debug("phys=%pK, len=%zd, rc=%d\n", addr, *len, rc);
pr_debug("phys=%pK, len=%zd, rc=%d\n", &(*addr), *len, rc);
err:
return rc;
}
static void *msm_audio_ion_map_kernel(void *handle)
static void *msm_audio_ion_map_kernel(struct dma_buf *dma_buf)
{
int rc = 0;
void *addr = NULL;
struct msm_audio_alloc_data *alloc_data = NULL;
rc = dma_buf_begin_cpu_access((struct dma_buf*)handle,
DMA_BIDIRECTIONAL);
rc = dma_buf_begin_cpu_access(dma_buf, DMA_BIDIRECTIONAL);
if (rc) {
pr_err("%s: kmap dma_buf_begin_cpu_access fail\n", __func__);
goto exit;
}
addr = dma_buf_vmap((struct dma_buf*)handle);
addr = dma_buf_vmap(dma_buf);
if (!addr) {
pr_err("%s: kernel mapping of dma_buf failed\n",
__func__);
@ -525,7 +449,7 @@ static void *msm_audio_ion_map_kernel(void *handle)
mutex_lock(&(msm_audio_ion_data.list_mutex));
list_for_each_entry(alloc_data, &(msm_audio_ion_data.alloc_list),
list) {
if (alloc_data->handle == handle) {
if (alloc_data->dma_buf == dma_buf) {
alloc_data->vaddr = addr;
break;
}
@ -536,12 +460,54 @@ exit:
return addr;
}
static int msm_audio_ion_map_buf(void *handle, dma_addr_t *paddr,
static int msm_audio_ion_unmap_kernel(struct dma_buf *dma_buf)
{
int rc = 0;
void *vaddr = NULL;
struct msm_audio_alloc_data *alloc_data = NULL;
struct device *cb_dev = msm_audio_ion_data.cb_dev;
/*
* TBD: remove the below section once new API
* for unmapping kernel virtual address is available.
*/
mutex_lock(&(msm_audio_ion_data.list_mutex));
list_for_each_entry(alloc_data, &(msm_audio_ion_data.alloc_list),
list) {
if (alloc_data->dma_buf == dma_buf) {
vaddr = alloc_data->vaddr;
break;
}
}
mutex_unlock(&(msm_audio_ion_data.list_mutex));
if (!vaddr) {
dev_err(cb_dev,
"%s: cannot find allocation for dma_buf %pK",
__func__, dma_buf);
rc = -EINVAL;
goto err;
}
dma_buf_vunmap(dma_buf, vaddr);
rc = dma_buf_end_cpu_access(dma_buf, DMA_BIDIRECTIONAL);
if (rc) {
dev_err(cb_dev, "%s: kmap dma_buf_end_cpu_access fail\n",
__func__);
goto err;
}
err:
return rc;
}
static int msm_audio_ion_map_buf(struct dma_buf *dma_buf, dma_addr_t *paddr,
size_t *plen, void **vaddr)
{
int rc = 0;
rc = msm_audio_ion_get_phys((struct dma_buf*) handle, paddr, plen);
rc = msm_audio_ion_get_phys(dma_buf, paddr, plen);
if (rc) {
pr_err("%s: ION Get Physical for AUDIO failed, rc = %d\n",
__func__, rc);
@ -549,20 +515,20 @@ static int msm_audio_ion_map_buf(void *handle, dma_addr_t *paddr,
goto err;
}
*vaddr = msm_audio_ion_map_kernel(handle);
*vaddr = msm_audio_ion_map_kernel(dma_buf);
if (IS_ERR_OR_NULL(*vaddr)) {
pr_err("%s: ION memory mapping for AUDIO failed\n", __func__);
rc = -ENOMEM;
msm_audio_dma_buf_unmap(dma_buf);
msm_audio_dma_buf_unmap(dma_buf, false);
goto err;
}
if (msm_audio_ion_data.smmu_enabled) {
rc = msm_audio_ion_smmu_map(handle, paddr, plen);
rc = msm_audio_ion_smmu_map(dma_buf, paddr, plen);
if (rc) {
pr_err("%s: failed to do smmu map, err = %d\n",
__func__, rc);
msm_audio_dma_buf_unmap((struct dma_buf *) handle);
msm_audio_dma_buf_unmap(dma_buf, false);
goto err;
}
}
@ -574,8 +540,7 @@ err:
* msm_audio_ion_alloc -
* Allocs ION memory for given client name
*
* @handle: generic handle to the memory allocation
* dma_buf for the system heap memory. vaddr for audio heap memory.
* @dma_buf: dma_buf for the ION memory
* @bufsz: buffer size
* @paddr: Physical address to be assigned with allocated region
* @plen: length of allocated region to be assigned
@ -583,7 +548,7 @@ err:
*
* Returns 0 on success or error on failure
*/
int msm_audio_ion_alloc(void **handle, size_t bufsz,
int msm_audio_ion_alloc(struct dma_buf **dma_buf, size_t bufsz,
dma_addr_t *paddr, size_t *plen, void **vaddr)
{
int rc = -EINVAL;
@ -593,48 +558,31 @@ int msm_audio_ion_alloc(void **handle, size_t bufsz,
pr_debug("%s:probe is not done, deferred\n", __func__);
return -EPROBE_DEFER;
}
if (!handle || !paddr || !vaddr || !bufsz || !plen) {
if (!dma_buf || !paddr || !vaddr || !bufsz || !plen) {
pr_err("%s: Invalid params\n", __func__);
return -EINVAL;
}
if (msm_audio_ion_data.smmu_enabled == true) {
pr_debug("%s: system heap is used\n", __func__);
*handle = ion_alloc(bufsz, ION_HEAP(ION_SYSTEM_HEAP_ID), 0);
*dma_buf = ion_alloc(bufsz, ION_HEAP(ION_SYSTEM_HEAP_ID), 0);
} else {
pr_debug("%s: audio heap is used\n", __func__);
*vaddr = *handle = dma_alloc_coherent(
msm_audio_ion_data.cb_dev,
bufsz, paddr, GFP_KERNEL);
if(*vaddr != NULL) {
pr_err("%s: vaddr = %pK, size=%zd\n", __func__, *vaddr,
bufsz);
rc = 0;
}
*dma_buf = ion_alloc(bufsz, ION_HEAP(ION_AUDIO_HEAP_ID), 0);
}
if (IS_ERR_OR_NULL((void *)(*handle))) {
if (IS_ERR((void *)(*handle)))
err_ion_ptr = PTR_ERR((int *)(*handle));
if (IS_ERR_OR_NULL((void *)(*dma_buf))) {
if (IS_ERR((void *)(*dma_buf)))
err_ion_ptr = PTR_ERR((int *)(*dma_buf));
pr_err("%s: ION alloc fail err ptr=%ld, smmu_enabled=%d\n",
__func__, err_ion_ptr, msm_audio_ion_data.smmu_enabled);
rc = -ENOMEM;
goto err;
}
if (msm_audio_ion_data.smmu_enabled) {
rc = msm_audio_ion_map_buf(*handle, paddr, plen, vaddr);
if (rc) {
pr_err("%s: failed to map ION buf, rc = %d\n", __func__,
rc);
}
} else {
rc = msm_audio_dma_buf_map(*handle, *vaddr, paddr,
&bufsz);
if (rc) {
pr_err("%s: failed to map ION buf, rc = %d\n", __func__,
rc);
dma_free_coherent(msm_audio_ion_data.cb_dev,
bufsz, vaddr, *paddr);
}
rc = msm_audio_ion_map_buf(*dma_buf, paddr, plen, vaddr);
if (rc) {
pr_err("%s: failed to map ION buf, rc = %d\n", __func__, rc);
goto err;
}
pr_debug("%s: mapped address = %pK, size=%zd\n", __func__,
*vaddr, bufsz);
@ -675,18 +623,17 @@ EXPORT_SYMBOL(msm_audio_is_hypervisor_supported);
* msm_audio_ion_import-
* Import ION buffer with given file descriptor
*
* @handle: generic handle to the memory allocation
* dma_buf for the system heap memory. vaddr for audio heap memory.
* @dma_buf: dma_buf for the ION memory
* @fd: file descriptor for the ION memory
* @ionflag: flags associated with ION buffer
* @bufsz: buffer size
* @paddr: Physical address to be assigned with allocated region
* @plen: length of allocated region to be assigned
* vaddr: virtual address to be assigned
* @vaddr: virtual address to be assigned
*
* Returns 0 on success or error on failure
*/
int msm_audio_ion_import(void **handle, int fd,
int msm_audio_ion_import(struct dma_buf **dma_buf, int fd,
unsigned long *ionflag, size_t bufsz,
dma_addr_t *paddr, size_t *plen, void **vaddr)
{
@ -697,22 +644,22 @@ int msm_audio_ion_import(void **handle, int fd,
return -EPROBE_DEFER;
}
if (!handle || !paddr || !vaddr || !plen) {
if (!dma_buf || !paddr || !vaddr || !plen) {
pr_err("%s: Invalid params\n", __func__);
return -EINVAL;
}
/* bufsz should be 0 and fd shouldn't be 0 as of now */
*handle = dma_buf_get(fd);
pr_debug("%s: handle =%pK, fd=%d\n", __func__, *handle, fd);
if (IS_ERR_OR_NULL((void *)(*handle))) {
*dma_buf = dma_buf_get(fd);
pr_debug("%s: dma_buf =%pK, fd=%d\n", __func__, *dma_buf, fd);
if (IS_ERR_OR_NULL((void *)(*dma_buf))) {
pr_err("%s: dma_buf_get failed\n", __func__);
rc = -EINVAL;
goto err;
}
if (ionflag != NULL) {
rc = dma_buf_get_flags((struct dma_buf*)*handle, ionflag);
rc = dma_buf_get_flags(*dma_buf, ionflag);
if (rc) {
pr_err("%s: could not get flags for the dma_buf\n",
__func__);
@ -720,7 +667,7 @@ int msm_audio_ion_import(void **handle, int fd,
}
}
rc = msm_audio_ion_map_buf(*handle, paddr, plen, vaddr);
rc = msm_audio_ion_map_buf(*dma_buf, paddr, plen, vaddr);
if (rc) {
pr_err("%s: failed to map ION buf, rc = %d\n", __func__, rc);
goto err;
@ -731,44 +678,129 @@ int msm_audio_ion_import(void **handle, int fd,
return 0;
err_ion_flag:
dma_buf_put((struct dma_buf*) *handle);
dma_buf_put(*dma_buf);
err:
*handle = NULL;
*dma_buf = NULL;
return rc;
}
EXPORT_SYMBOL(msm_audio_ion_import);
/**
* msm_audio_ion_free -
* fress ION memory for given client and handle
* msm_audio_ion_import_cma-
* Import ION buffer with given file descriptor
*
* @handle: generic handle to the memory allocation
* dma_buf for the system heap memory. vaddr for audio heap memory.
* @dma_buf: dma_buf for the ION memory
* @fd: file descriptor for the ION memory
* @ionflag: flags associated with ION buffer
* @bufsz: buffer size
* @paddr: Physical address to be assigned with allocated region
* @plen: length of allocated region to be assigned
* @vaddr: virtual address to be assigned
*
* Returns 0 on success or error on failure
*/
int msm_audio_ion_free(void *handle)
int msm_audio_ion_import_cma(struct dma_buf **dma_buf, int fd,
unsigned long *ionflag, size_t bufsz,
dma_addr_t *paddr, size_t *plen, void **vaddr)
{
int ret = 0;
int rc = 0;
if (!handle) {
pr_err("%s: handle invalid\n", __func__);
if (!(msm_audio_ion_data.device_status & MSM_AUDIO_ION_PROBED)) {
pr_debug("%s: probe is not done, deferred\n", __func__);
return -EPROBE_DEFER;
}
if (!dma_buf || !paddr || !vaddr || !plen ||
!msm_audio_ion_data.cb_cma_dev) {
pr_err("%s: Invalid params\n", __func__);
return -EINVAL;
}
/* bufsz should be 0 and fd shouldn't be 0 as of now */
*dma_buf = dma_buf_get(fd);
pr_debug("%s: dma_buf =%pK, fd=%d\n", __func__, *dma_buf, fd);
if (IS_ERR_OR_NULL((void *)(*dma_buf))) {
pr_err("%s: dma_buf_get failed\n", __func__);
rc = -EINVAL;
goto err;
}
if (ionflag != NULL) {
rc = dma_buf_get_flags(*dma_buf, ionflag);
if (rc) {
pr_err("%s: could not get flags for the dma_buf\n",
__func__);
goto err_ion_flag;
}
}
msm_audio_dma_buf_map(*dma_buf, paddr, plen, true);
return 0;
err_ion_flag:
dma_buf_put(*dma_buf);
err:
*dma_buf = NULL;
return rc;
}
EXPORT_SYMBOL(msm_audio_ion_import_cma);
/**
* msm_audio_ion_free -
* fress ION memory for given client and handle
*
* @dma_buf: dma_buf for the ION memory
*
* Returns 0 on success or error on failure
*/
int msm_audio_ion_free(struct dma_buf *dma_buf)
{
int ret = 0;
if (!dma_buf) {
pr_err("%s: dma_buf invalid\n", __func__);
return -EINVAL;
}
ret = msm_audio_ion_unmap_kernel(dma_buf);
if (ret)
return ret;
if (msm_audio_ion_data.smmu_enabled) {
ret = msm_audio_ion_smmu_unmap(handle);
ret = msm_audio_ion_smmu_unmap(dma_buf);
if (ret)
pr_err("%s: smmu unmap failed with ret %d\n",
__func__, ret);
}
msm_audio_dma_buf_unmap(handle);
msm_audio_dma_buf_unmap(dma_buf, false);
return 0;
}
EXPORT_SYMBOL(msm_audio_ion_free);
/**
* msm_audio_ion_free_cma -
* fress ION memory for given client and handle
*
* @dma_buf: dma_buf for the ION memory
*
* Returns 0 on success or error on failure
*/
int msm_audio_ion_free_cma(struct dma_buf *dma_buf)
{
if (!dma_buf) {
pr_err("%s: dma_buf invalid\n", __func__);
return -EINVAL;
}
msm_audio_dma_buf_unmap(dma_buf, true);
return 0;
}
EXPORT_SYMBOL(msm_audio_ion_free_cma);
/**
* msm_audio_ion_mmap -
* Audio ION memory map
@ -795,7 +827,7 @@ int msm_audio_ion_mmap(struct audio_buffer *abuff,
mutex_lock(&(msm_audio_ion_data.list_mutex));
list_for_each_entry(alloc_data, &(msm_audio_ion_data.alloc_list),
list) {
if (alloc_data->handle == abuff->mem_handle) {
if (alloc_data->dma_buf == abuff->dma_buf) {
found = true;
table = alloc_data->table;
break;
@ -806,7 +838,7 @@ int msm_audio_ion_mmap(struct audio_buffer *abuff,
if (!found) {
dev_err(cb_dev,
"%s: cannot find allocation, dma_buf %pK",
__func__, abuff->mem_handle);
__func__, abuff->dma_buf);
return -EINVAL;
}
/* uncached */
@ -870,6 +902,7 @@ EXPORT_SYMBOL(msm_audio_populate_upper_32_bits);
static const struct of_device_id msm_audio_ion_dt_match[] = {
{ .compatible = "qcom,msm-audio-ion" },
{ .compatible = "qcom,msm-audio-ion-cma"},
{ }
};
MODULE_DEVICE_TABLE(of, msm_audio_ion_dt_match);
@ -889,6 +922,11 @@ static int msm_audio_ion_probe(struct platform_device *pdev)
return 0;
}
if (of_device_is_compatible(dev->of_node, "qcom,msm-audio-ion-cma")) {
msm_audio_ion_data.cb_cma_dev = dev;
return 0;
}
smmu_enabled = of_property_read_bool(dev->of_node,
msm_audio_ion_dt);
msm_audio_ion_data.smmu_enabled = smmu_enabled;
@ -912,13 +950,14 @@ static int msm_audio_ion_probe(struct platform_device *pdev)
dev_info(dev, "%s: msm_audio_ion_hab_handle %x\n",
__func__, msm_audio_ion_hab_handle);
INIT_LIST_HEAD(&msm_audio_ion_data.alloc_list);
mutex_init(&(msm_audio_ion_data.list_mutex));
exit:
if (!rc)
msm_audio_ion_data.device_status |= MSM_AUDIO_ION_PROBED;
msm_audio_ion_data.cb_dev = dev;
INIT_LIST_HEAD(&msm_audio_ion_data.alloc_list);
mutex_init(&(msm_audio_ion_data.list_mutex));
return rc;
}
@ -928,10 +967,11 @@ static int msm_audio_ion_remove(struct platform_device *pdev)
if (msm_audio_ion_data.smmu_enabled) {
if (msm_audio_ion_hab_handle)
habmm_socket_close(msm_audio_ion_hab_handle);
mutex_destroy(&(msm_audio_ion_data.list_mutex));
}
msm_audio_ion_data.smmu_enabled = 0;
msm_audio_ion_data.device_status = 0;
mutex_destroy(&(msm_audio_ion_data.list_mutex));
return 0;
}

View File

@ -0,0 +1,27 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
*/
/* from Slave to bolero events */
enum {
SLV_BOLERO_EVT_RX_MUTE = 1, /* for RX mute/unmute */
SLV_BOLERO_EVT_IMPED_TRUE, /* for imped true */
SLV_BOLERO_EVT_IMPED_FALSE, /* for imped false */
SLV_BOLERO_EVT_RX_COMPANDER_SOFT_RST,
SLV_BOLERO_EVT_BCS_CLK_OFF,
SLV_BOLERO_EVT_RX_PA_GAIN_UPDATE,
SLV_BOLERO_EVT_HPHL_HD2_ENABLE, /* to enable hd2 config for hphl */
SLV_BOLERO_EVT_HPHR_HD2_ENABLE, /* to enable hd2 config for hphr */
};
/* from bolero to SLV events */
enum {
BOLERO_SLV_EVT_TX_CH_HOLD_CLEAR = 1,
BOLERO_SLV_EVT_PA_OFF_PRE_SSR,
BOLERO_SLV_EVT_SSR_DOWN,
BOLERO_SLV_EVT_SSR_UP,
BOLERO_SLV_EVT_PA_ON_POST_FSCLK,
BOLERO_SLV_EVT_PA_ON_POST_FSCLK_ADIE_LB,
BOLERO_SLV_EVT_CLK_NOTIFY,
};

View File

@ -10,6 +10,9 @@
#include <ipc/apr.h>
#include <audio/linux/msm_audio.h>
/* number of threshold levels in speaker protection module */
#define MAX_CPS_LEVELS 3
/* size of header needed for passing data out of band */
#define APR_CMD_OB_HDR_SZ 12
@ -2364,6 +2367,28 @@ int16_t excursionf[AFE_SPKR_PROT_EXCURSIONF_LEN];
*/
} __packed;
struct lpass_swr_spkr_dep_cfg_t {
uint32_t vbatt_pkd_reg_addr;
uint32_t temp_pkd_reg_addr;
uint32_t value_normal_thrsd[MAX_CPS_LEVELS];
uint32_t value_low1_thrsd[MAX_CPS_LEVELS];
uint32_t value_low2_thrsd[MAX_CPS_LEVELS];
} __packed;
struct lpass_swr_hw_reg_cfg_t {
uint32_t lpass_wr_cmd_reg_phy_addr;
uint32_t lpass_rd_cmd_reg_phy_addr;
uint32_t lpass_rd_fifo_reg_phy_addr;
uint32_t vbatt_lower1_threshold;
uint32_t vbatt_lower2_threshold;
uint32_t num_spkr;
} __packed;
struct afe_cps_hw_intf_cfg {
uint32_t lpass_hw_intf_cfg_mode;
struct lpass_swr_hw_reg_cfg_t hw_reg_cfg;
struct lpass_swr_spkr_dep_cfg_t *spkr_dep_cfg;
} __packed;
#define AFE_SERVICE_CMD_REGISTER_RT_PORT_DRIVER 0x000100E0
@ -3940,6 +3965,7 @@ struct afe_param_id_device_hw_delay_cfg {
} __packed;
#define AFE_PARAM_ID_SET_TOPOLOGY 0x0001025A
#define AFE_PARAM_ID_DEREGISTER_TOPOLOGY 0x000102E8
#define AFE_API_VERSION_TOPOLOGY_V1 0x1
struct afe_param_id_set_topology_cfg {
@ -10808,6 +10834,7 @@ struct cmd_set_topologies {
#define AFE_PARAM_ID_FBSP_MODE_RX_CFG 0x0001021D
#define AFE_PARAM_ID_FBSP_PTONE_RAMP_CFG 0x00010260
#define AFE_PARAM_ID_SP_RX_TMAX_XMAX_LOGGING 0x000102BC
#define AFE_PARAM_ID_CPS_LPASS_HW_INTF_CFG 0x000102EF
struct asm_fbsp_mode_rx_cfg {
uint32_t minor_version;
@ -12164,6 +12191,28 @@ struct afe_clk_set {
uint32_t enable;
};
#define AVS_BUILD_MAJOR_VERSION_V2 2
#define AVS_BUILD_MINOR_VERSION_V9 9
#define AVS_BUILD_BRANCH_VERSION_V0 0
#define AVS_BUILD_BRANCH_VERSION_V3 3
#define AFE_PARAM_ID_CLOCK_SET_V2 0x000102E6
#define AFE_API_VERSION_CLOCK_SET_V2 0x1
struct afe_param_id_clock_set_v2_t {
uint32_t clk_set_minor_version;
uint32_t clk_id;
uint32_t clk_freq_in_hz;
uint16_t clk_attri;
uint16_t clk_root;
uint32_t enable;
uint32_t divider_2x;
uint32_t m;
uint32_t n;
uint32_t d;
};
struct afe_clk_cfg {
/* Minor version used for tracking the version of the I2S
* configuration interface.

View File

@ -14,6 +14,18 @@ ifeq ($(KERNEL_BUILD), 1)
AUDIO_ROOT := $(KDIR)/techpack/audio
endif
ifeq ($(CONFIG_SND_SOC_AUTO), y)
ifdef CONFIG_SND_SOC_SA8155
include $(AUDIO_ROOT)/config/sa8155auto.conf
export
INCS += -include $(AUDIO_ROOT)/config/sa8155autoconf.h
endif
ifdef CONFIG_SND_SOC_SA6155
include $(AUDIO_ROOT)/config/sa6155auto.conf
export
INCS += -include $(AUDIO_ROOT)/config/sa6155autoconf.h
endif
else
ifeq ($(KERNEL_BUILD), 0)
ifeq ($(CONFIG_ARCH_SM6150), y)
ifdef CONFIG_SND_SOC_SA6155
@ -72,12 +84,13 @@ ifeq ($(KERNEL_BUILD), 0)
INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h
endif
endif
ifeq ($(CONFIG_QTI_GVM), y)
ifeq ($(CONFIG_QTI_QUIN_GVM), y)
include $(AUDIO_ROOT)/config/gvmauto.conf
export
INCS += -include $(AUDIO_ROOT)/config/gvmautoconf.h
endif
endif
endif
# As per target team, build is done as follows:
# Defconfig : build with default flags

View File

@ -13,6 +13,18 @@ ifeq ($(KERNEL_BUILD), 1)
AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio
endif
ifeq ($(CONFIG_SND_SOC_AUTO), y)
ifdef CONFIG_SND_SOC_SA8155
include $(AUDIO_ROOT)/config/sa8155auto.conf
export
INCS += -include $(AUDIO_ROOT)/config/sa8155autoconf.h
endif
ifdef CONFIG_SND_SOC_SA6155
include $(AUDIO_ROOT)/config/sa6155auto.conf
export
INCS += -include $(AUDIO_ROOT)/config/sa6155autoconf.h
endif
else
ifeq ($(KERNEL_BUILD), 0)
ifeq ($(CONFIG_ARCH_SM8150), y)
ifdef CONFIG_SND_SOC_SA8155
@ -71,12 +83,13 @@ ifeq ($(KERNEL_BUILD), 0)
export
INCS += -include $(AUDIO_ROOT)/config/qcs405autoconf.h
endif
ifeq ($(CONFIG_QTI_GVM), y)
ifeq ($(CONFIG_QTI_QUIN_GVM), y)
include $(AUDIO_ROOT)/config/gvmauto.conf
export
INCS += -include $(AUDIO_ROOT)/config/gvmautoconf.h
endif
endif
endif
# As per target team, build is done as follows:
# Defconfig : build with default flags

View File

@ -181,8 +181,6 @@ static int lpi_gpio_write(struct lpi_gpio_pad *pad, unsigned int addr,
int ret = 0;
if (!lpi_dev_up) {
pr_err_ratelimited("%s: ADSP is down due to SSR, return\n",
__func__);
return 0;
}
pm_runtime_get_sync(lpi_dev);

View File

@ -2183,12 +2183,12 @@ handle_irq:
dev_err_ratelimited(swrm->dev,
"%s: SWR wokeup during clock stop\n",
__func__);
/* It might be possible the slave device gets reset
* and slave interrupt gets missed. So re-enable
* Host IRQ and process slave pending
* interrupts, if any.
*/
swrm_enable_slave_irq(swrm);
/* It might be possible the slave device gets
* reset and slave interrupt gets missed. So
* re-enable Host IRQ and process slave pending
* interrupts, if any.
*/
swrm_enable_slave_irq(swrm);
}
break;
default:
@ -2493,7 +2493,6 @@ static int swrm_master_init(struct swr_mstr_ctrl *swrm)
reg[len] = SWRM_COMP_CFG;
value[len++] = 0x02;
reg[len] = SWRM_INTERRUPT_CLEAR;
value[len++] = 0xFFFFFFFF;
@ -2504,6 +2503,7 @@ static int swrm_master_init(struct swr_mstr_ctrl *swrm)
reg[len] = SWRM_CPU1_INTERRUPT_EN;
value[len++] = swrm->intr_mask;
reg[len] = SWRM_COMP_CFG;
value[len++] = 0x03;
@ -2583,6 +2583,7 @@ static int swrm_probe(struct platform_device *pdev)
int ret = 0;
struct clk *lpass_core_hw_vote = NULL;
struct clk *lpass_core_audio = NULL;
u32 is_wcd937x = 0;
/* Allocate soundwire master driver structure */
swrm = devm_kzalloc(&pdev->dev, sizeof(struct swr_mstr_ctrl),
@ -2615,6 +2616,14 @@ static int swrm_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "%s: failed to get master id\n", __func__);
goto err_pdata_fail;
}
/* update the physical device address if wcd937x. */
ret = of_property_read_u32(pdev->dev.of_node, "qcom,is_wcd937x",
&is_wcd937x);
if (ret)
dev_dbg(&pdev->dev, "%s: failed to get wcd info\n", __func__);
else if (is_wcd937x)
swrm_phy_dev[1] = 0xa01170223;
ret = of_property_read_u32(pdev->dev.of_node, "qcom,dynamic-port-map-supported",
&swrm->dynamic_port_map_supported);
if (ret) {
@ -3236,12 +3245,12 @@ static int swrm_runtime_suspend(struct device *dev)
swrm->ipc_wakeup_triggered = false;
}
}
}
/* Retain SSR state until resume */
if (current_state != SWR_MSTR_SSR)
swrm->state = SWR_MSTR_DOWN;
exit:
if (swrm->state != SWR_MSTR_UP) {
if (swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, false))

View File

@ -23,12 +23,21 @@ static struct port_params tx_dummy[SWR_MSTR_PORT_LEN] = {
};
/* AMIC 9.6 MHz clock */
#ifdef CONFIG_SND_SOC_HOLI
static struct port_params tx_wcd_9p6MHz[SWR_MSTR_PORT_LEN] = {
{3, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1, 0x00, 0x00}, /* TX1 */
{3, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */
{7, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX3 */
{7, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX4 */
};
#else
static struct port_params tx_wcd_9p6MHz[SWR_MSTR_PORT_LEN] = {
{3, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1, 0x00, 0x00}, /* TX1 */
{7, 5, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */
{7, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX3 */
{7, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX4 */
};
#endif
/* AMIC 4.8 MHz clock */
static struct port_params tx_wcd_4p8MHz[SWR_MSTR_PORT_LEN] = {