Merge "asoc: bolero: remove extra semi-colon to avoid compile error"
diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c
index cee08dc..dcd3b98 100644
--- a/asoc/codecs/bolero/bolero-cdc.c
+++ b/asoc/codecs/bolero/bolero-cdc.c
@@ -623,6 +623,8 @@
mutex_lock(&priv->clk_lock);
priv->dev_up = true;
mutex_unlock(&priv->clk_lock);
+ regcache_mark_dirty(priv->regmap);
+ regcache_sync(priv->regmap);
/* call ssr event for supported macros */
for (macro_idx = START_MACRO; macro_idx < MAX_MACRO; macro_idx++) {
if (!priv->macro_params[macro_idx].event_handler)
diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c
index 0be5c4e..8ed9f23 100644
--- a/asoc/codecs/bolero/rx-macro.c
+++ b/asoc/codecs/bolero/rx-macro.c
@@ -764,9 +764,10 @@
port_cfg.size = size;
port_cfg.params = data;
- ret = swrm_wcd_notify(
- rx_priv->swr_ctrl_data[0].rx_swr_pdev,
- SWR_SET_PORT_MAP, &port_cfg);
+ if (rx_priv->swr_ctrl_data)
+ ret = swrm_wcd_notify(
+ rx_priv->swr_ctrl_data[0].rx_swr_pdev,
+ SWR_SET_PORT_MAP, &port_cfg);
return ret;
}
@@ -1152,16 +1153,18 @@
rx_priv->is_native_on) ||
(rx_priv->clk_id == RX_CORE_CLK &&
!rx_priv->is_native_on)) {
- swrm_wcd_notify(
- rx_priv->swr_ctrl_data[0].rx_swr_pdev,
- SWR_DEVICE_DOWN, NULL);
+ if (rx_priv->swr_ctrl_data)
+ swrm_wcd_notify(
+ rx_priv->swr_ctrl_data[0].rx_swr_pdev,
+ SWR_DEVICE_DOWN, NULL);
}
}
if (rx_priv->is_native_on)
mclk_freq = MCLK_FREQ_NATIVE;
- swrm_wcd_notify(
- rx_priv->swr_ctrl_data[0].rx_swr_pdev,
- SWR_CLK_FREQ, &mclk_freq);
+ if (rx_priv->swr_ctrl_data)
+ swrm_wcd_notify(
+ rx_priv->swr_ctrl_data[0].rx_swr_pdev,
+ SWR_CLK_FREQ, &mclk_freq);
ret = rx_macro_mclk_enable(rx_priv, 1, true);
if (ret)
rx_priv->dapm_mclk_enable = false;
@@ -1213,12 +1216,14 @@
break;
case BOLERO_MACRO_EVT_SSR_DOWN:
rx_priv->dev_up = false;
- swrm_wcd_notify(
- rx_priv->swr_ctrl_data[0].rx_swr_pdev,
- SWR_DEVICE_DOWN, NULL);
- swrm_wcd_notify(
- rx_priv->swr_ctrl_data[0].rx_swr_pdev,
- SWR_DEVICE_SSR_DOWN, NULL);
+ if (rx_priv->swr_ctrl_data) {
+ swrm_wcd_notify(
+ rx_priv->swr_ctrl_data[0].rx_swr_pdev,
+ SWR_DEVICE_DOWN, NULL);
+ swrm_wcd_notify(
+ rx_priv->swr_ctrl_data[0].rx_swr_pdev,
+ SWR_DEVICE_SSR_DOWN, NULL);
+ }
break;
case BOLERO_MACRO_EVT_SSR_UP:
rx_priv->dev_up = true;
@@ -1237,9 +1242,10 @@
rx_priv->default_clk_id,
RX_CORE_CLK, false);
- swrm_wcd_notify(
- rx_priv->swr_ctrl_data[0].rx_swr_pdev,
- SWR_DEVICE_SSR_UP, NULL);
+ if (rx_priv->swr_ctrl_data)
+ swrm_wcd_notify(
+ rx_priv->swr_ctrl_data[0].rx_swr_pdev,
+ SWR_DEVICE_SSR_UP, NULL);
break;
}
return ret;
@@ -3570,6 +3576,8 @@
int ret = 0;
u8 bcl_pmic_params[3];
u32 default_clk_id = 0;
+ u32 is_used_rx_swr_gpio = 1;
+ const char *is_used_rx_swr_gpio_dt = "qcom,is-used-swr-gpio";
rx_priv = devm_kzalloc(&pdev->dev, sizeof(struct rx_macro_priv),
GFP_KERNEL);
@@ -3598,13 +3606,30 @@
__func__, "qcom,default-clk-id");
default_clk_id = RX_CORE_CLK;
}
+ if (of_find_property(pdev->dev.of_node, is_used_rx_swr_gpio_dt,
+ NULL)) {
+ ret = of_property_read_u32(pdev->dev.of_node,
+ is_used_rx_swr_gpio_dt,
+ &is_used_rx_swr_gpio);
+ if (ret) {
+ dev_err(&pdev->dev, "%s: error reading %s in dt\n",
+ __func__, is_used_rx_swr_gpio_dt);
+ is_used_rx_swr_gpio = 1;
+ }
+ }
rx_priv->rx_swr_gpio_p = of_parse_phandle(pdev->dev.of_node,
"qcom,rx-swr-gpios", 0);
- if (!rx_priv->rx_swr_gpio_p) {
+ if (!rx_priv->rx_swr_gpio_p && is_used_rx_swr_gpio) {
dev_err(&pdev->dev, "%s: swr_gpios handle not provided!\n",
__func__);
return -EINVAL;
}
+ if (msm_cdc_pinctrl_get_state(rx_priv->rx_swr_gpio_p) < 0) {
+ dev_err(&pdev->dev, "%s: failed to get swr pin state\n",
+ __func__);
+ return -EPROBE_DEFER;
+ }
+
rx_io_base = devm_ioremap(&pdev->dev, rx_base_addr,
RX_MACRO_MAX_OFFSET);
if (!rx_io_base) {
diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c
index cb3aa59..1c9ccd0 100644
--- a/asoc/codecs/bolero/tx-macro.c
+++ b/asoc/codecs/bolero/tx-macro.c
@@ -346,19 +346,22 @@
switch (event) {
case BOLERO_MACRO_EVT_SSR_DOWN:
- swrm_wcd_notify(
- tx_priv->swr_ctrl_data[0].tx_swr_pdev,
- SWR_DEVICE_DOWN, NULL);
- swrm_wcd_notify(
- tx_priv->swr_ctrl_data[0].tx_swr_pdev,
- SWR_DEVICE_SSR_DOWN, NULL);
+ if (tx_priv->swr_ctrl_data) {
+ swrm_wcd_notify(
+ tx_priv->swr_ctrl_data[0].tx_swr_pdev,
+ SWR_DEVICE_DOWN, NULL);
+ swrm_wcd_notify(
+ tx_priv->swr_ctrl_data[0].tx_swr_pdev,
+ SWR_DEVICE_SSR_DOWN, NULL);
+ }
break;
case BOLERO_MACRO_EVT_SSR_UP:
/* reset swr after ssr/pdr */
tx_priv->reset_swr = true;
- swrm_wcd_notify(
- tx_priv->swr_ctrl_data[0].tx_swr_pdev,
- SWR_DEVICE_SSR_UP, NULL);
+ if (tx_priv->swr_ctrl_data)
+ swrm_wcd_notify(
+ tx_priv->swr_ctrl_data[0].tx_swr_pdev,
+ SWR_DEVICE_SSR_UP, NULL);
break;
}
return 0;
@@ -375,9 +378,10 @@
if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
return -EINVAL;
- ret = swrm_wcd_notify(
- tx_priv->swr_ctrl_data[0].tx_swr_pdev,
- SWR_REGISTER_WAKE_IRQ, &ipc_wakeup);
+ if (tx_priv->swr_ctrl_data)
+ ret = swrm_wcd_notify(
+ tx_priv->swr_ctrl_data[0].tx_swr_pdev,
+ SWR_REGISTER_WAKE_IRQ, &ipc_wakeup);
return ret;
}
@@ -1948,9 +1952,10 @@
port_cfg.size = size;
port_cfg.params = data;
- ret = swrm_wcd_notify(
- tx_priv->swr_ctrl_data[0].tx_swr_pdev,
- SWR_SET_PORT_MAP, &port_cfg);
+ if (tx_priv->swr_ctrl_data)
+ ret = swrm_wcd_notify(
+ tx_priv->swr_ctrl_data[0].tx_swr_pdev,
+ SWR_SET_PORT_MAP, &port_cfg);
return ret;
}
@@ -1977,6 +1982,8 @@
char __iomem *tx_io_base = NULL;
int ret = 0;
const char *dmic_sample_rate = "qcom,tx-dmic-sample-rate";
+ u32 is_used_tx_swr_gpio = 1;
+ const char *is_used_tx_swr_gpio_dt = "qcom,is-used-swr-gpio";
tx_priv = devm_kzalloc(&pdev->dev, sizeof(struct tx_macro_priv),
GFP_KERNEL);
@@ -1993,13 +2000,30 @@
return ret;
}
dev_set_drvdata(&pdev->dev, tx_priv);
+ if (of_find_property(pdev->dev.of_node, is_used_tx_swr_gpio_dt,
+ NULL)) {
+ ret = of_property_read_u32(pdev->dev.of_node,
+ is_used_tx_swr_gpio_dt,
+ &is_used_tx_swr_gpio);
+ if (ret) {
+ dev_err(&pdev->dev, "%s: error reading %s in dt\n",
+ __func__, is_used_tx_swr_gpio_dt);
+ is_used_tx_swr_gpio = 1;
+ }
+ }
tx_priv->tx_swr_gpio_p = of_parse_phandle(pdev->dev.of_node,
"qcom,tx-swr-gpios", 0);
- if (!tx_priv->tx_swr_gpio_p) {
+ if (!tx_priv->tx_swr_gpio_p && is_used_tx_swr_gpio) {
dev_err(&pdev->dev, "%s: swr_gpios handle not provided!\n",
__func__);
return -EINVAL;
}
+ if (msm_cdc_pinctrl_get_state(tx_priv->tx_swr_gpio_p) < 0) {
+ dev_err(&pdev->dev, "%s: failed to get swr pin state\n",
+ __func__);
+ return -EPROBE_DEFER;
+ }
+
tx_io_base = devm_ioremap(&pdev->dev,
tx_base_addr, TX_MACRO_MAX_OFFSET);
if (!tx_io_base) {
@@ -2064,7 +2088,8 @@
if (!tx_priv)
return -EINVAL;
- kfree(tx_priv->swr_ctrl_data);
+ if (tx_priv->swr_ctrl_data)
+ kfree(tx_priv->swr_ctrl_data);
for (count = 0; count < tx_priv->child_count &&
count < TX_MACRO_CHILD_DEVICES_MAX; count++)
platform_device_unregister(tx_priv->pdev_child_devices[count]);
diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c
index f41392d..1b48157 100644
--- a/asoc/codecs/bolero/wsa-macro.c
+++ b/asoc/codecs/bolero/wsa-macro.c
@@ -473,9 +473,10 @@
port_cfg.size = size;
port_cfg.params = data;
- ret = swrm_wcd_notify(
- wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
- SWR_SET_PORT_MAP, &port_cfg);
+ if (wsa_priv->swr_ctrl_data)
+ ret = swrm_wcd_notify(
+ wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
+ SWR_SET_PORT_MAP, &port_cfg);
return ret;
}
@@ -910,19 +911,22 @@
switch (event) {
case BOLERO_MACRO_EVT_SSR_DOWN:
- swrm_wcd_notify(
- wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
- SWR_DEVICE_DOWN, NULL);
- swrm_wcd_notify(
- wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
- SWR_DEVICE_SSR_DOWN, NULL);
+ if (wsa_priv->swr_ctrl_data) {
+ swrm_wcd_notify(
+ wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
+ SWR_DEVICE_DOWN, NULL);
+ swrm_wcd_notify(
+ wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
+ SWR_DEVICE_SSR_DOWN, NULL);
+ }
break;
case BOLERO_MACRO_EVT_SSR_UP:
/* reset swr after ssr/pdr */
wsa_priv->reset_swr = true;
- swrm_wcd_notify(
- wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
- SWR_DEVICE_SSR_UP, NULL);
+ if (wsa_priv->swr_ctrl_data)
+ swrm_wcd_notify(
+ wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
+ SWR_DEVICE_SSR_UP, NULL);
break;
}
return 0;
@@ -1135,12 +1139,14 @@
wsa_priv->rx_1_count++;
ch_cnt = wsa_priv->rx_0_count + wsa_priv->rx_1_count;
- swrm_wcd_notify(
- wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
- SWR_DEVICE_UP, NULL);
- swrm_wcd_notify(
- wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
- SWR_SET_NUM_RX_CH, &ch_cnt);
+ if (wsa_priv->swr_ctrl_data) {
+ swrm_wcd_notify(
+ wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
+ SWR_DEVICE_UP, NULL);
+ swrm_wcd_notify(
+ wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
+ SWR_SET_NUM_RX_CH, &ch_cnt);
+ }
break;
case SND_SOC_DAPM_POST_PMD:
if (!(strnstr(w->name, "RX0", sizeof("WSA_RX0"))) &&
@@ -1151,9 +1157,10 @@
wsa_priv->rx_1_count--;
ch_cnt = wsa_priv->rx_0_count + wsa_priv->rx_1_count;
- swrm_wcd_notify(
- wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
- SWR_SET_NUM_RX_CH, &ch_cnt);
+ if (wsa_priv->swr_ctrl_data)
+ swrm_wcd_notify(
+ wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
+ SWR_SET_NUM_RX_CH, &ch_cnt);
break;
}
dev_dbg(wsa_priv->dev, "%s: current swr ch cnt: %d\n",
@@ -2880,6 +2887,8 @@
char __iomem *wsa_io_base;
int ret = 0;
u8 bcl_pmic_params[3];
+ u32 is_used_wsa_swr_gpio = 1;
+ const char *is_used_wsa_swr_gpio_dt = "qcom,is-used-swr-gpio";
wsa_priv = devm_kzalloc(&pdev->dev, sizeof(struct wsa_macro_priv),
GFP_KERNEL);
@@ -2894,13 +2903,30 @@
__func__, "reg");
return ret;
}
+ if (of_find_property(pdev->dev.of_node, is_used_wsa_swr_gpio_dt,
+ NULL)) {
+ ret = of_property_read_u32(pdev->dev.of_node,
+ is_used_wsa_swr_gpio_dt,
+ &is_used_wsa_swr_gpio);
+ if (ret) {
+ dev_err(&pdev->dev, "%s: error reading %s in dt\n",
+ __func__, is_used_wsa_swr_gpio_dt);
+ is_used_wsa_swr_gpio = 1;
+ }
+ }
wsa_priv->wsa_swr_gpio_p = of_parse_phandle(pdev->dev.of_node,
"qcom,wsa-swr-gpios", 0);
- if (!wsa_priv->wsa_swr_gpio_p) {
+ if (!wsa_priv->wsa_swr_gpio_p && is_used_wsa_swr_gpio) {
dev_err(&pdev->dev, "%s: swr_gpios handle not provided!\n",
__func__);
return -EINVAL;
}
+ if (msm_cdc_pinctrl_get_state(wsa_priv->wsa_swr_gpio_p) < 0) {
+ dev_err(&pdev->dev, "%s: failed to get swr pin state\n",
+ __func__);
+ return -EPROBE_DEFER;
+ }
+
wsa_io_base = devm_ioremap(&pdev->dev,
wsa_base_addr, WSA_MACRO_MAX_OFFSET);
if (!wsa_io_base) {
diff --git a/asoc/codecs/msm-cdc-pinctrl.c b/asoc/codecs/msm-cdc-pinctrl.c
index 8ed0c8e..0dadb74 100644
--- a/asoc/codecs/msm-cdc-pinctrl.c
+++ b/asoc/codecs/msm-cdc-pinctrl.c
@@ -122,9 +122,10 @@
* msm_cdc_pinctrl_get_state: get curren pinctrl state
* @np: pointer to struct device_node
*
- * Returns 0 for sleep state, 1 for active state
+ * Returns 0 for sleep state, 1 for active state,
+ * error code for failure
*/
-bool msm_cdc_pinctrl_get_state(struct device_node *np)
+int msm_cdc_pinctrl_get_state(struct device_node *np)
{
struct msm_cdc_pinctrl_info *gpio_data;
diff --git a/asoc/codecs/wcd-clsh.c b/asoc/codecs/wcd-clsh.c
index 0f403ac..bda3893 100644
--- a/asoc/codecs/wcd-clsh.c
+++ b/asoc/codecs/wcd-clsh.c
@@ -34,6 +34,10 @@
return WCD_CLSH_STRINGIFY(CLS_AB);
case CLS_AB_HIFI:
return WCD_CLSH_STRINGIFY(CLS_AB_HIFI);
+ case CLS_AB_LP:
+ return WCD_CLSH_STRINGIFY(CLS_AB_LP);
+ case CLS_AB_LOHIFI:
+ return WCD_CLSH_STRINGIFY(CLS_AB_LOHIFI);
default:
return WCD_CLSH_STRINGIFY(CLS_H_INVALID);
};
@@ -107,7 +111,7 @@
int mode)
{
if (mode == CLS_H_HIFI || mode == CLS_H_LOHIFI ||
- mode == CLS_AB_HIFI)
+ mode == CLS_AB_HIFI || mode == CLS_AB_LOHIFI)
snd_soc_component_update_bits(component,
WCD9XXX_ANA_RX_SUPPLIES,
0x08, 0x08); /* set to HIFI */
@@ -122,7 +126,7 @@
int mode)
{
if (mode == CLS_H_HIFI || mode == CLS_H_LOHIFI ||
- mode == CLS_AB_HIFI) {
+ mode == CLS_AB_HIFI || mode == CLS_AB_LOHIFI) {
snd_soc_component_update_bits(component,
WCD9XXX_ANA_RX_SUPPLIES,
0x04, 0x04);
@@ -154,7 +158,7 @@
snd_soc_component_update_bits(component,
WCD9XXX_CLASSH_MODE_2,
0xFF, 0x1C);
- if (mode == CLS_H_LOHIFI) {
+ if (mode == CLS_H_LOHIFI || mode == CLS_AB_LOHIFI) {
snd_soc_component_update_bits(component,
WCD9XXX_HPH_NEW_INT_PA_MISC2,
0x20, 0x20);
@@ -258,6 +262,8 @@
break;
case CLS_H_LP:
case CLS_H_LOHIFI:
+ case CLS_AB_LP:
+ case CLS_AB_LOHIFI:
val = 0x04;
break;
default:
diff --git a/asoc/codecs/wcd938x/internal.h b/asoc/codecs/wcd938x/internal.h
index e1fea5c..87bea04 100644
--- a/asoc/codecs/wcd938x/internal.h
+++ b/asoc/codecs/wcd938x/internal.h
@@ -94,6 +94,8 @@
/* Entry for version info */
struct snd_info_entry *entry;
struct snd_info_entry *version_entry;
+ int flyback_cur_det_disable;
+ int ear_rx_path;
};
struct wcd938x_micbias_setting {
diff --git a/asoc/codecs/wcd938x/wcd938x-regmap.c b/asoc/codecs/wcd938x/wcd938x-regmap.c
index a06f975..6f59258 100644
--- a/asoc/codecs/wcd938x/wcd938x-regmap.c
+++ b/asoc/codecs/wcd938x/wcd938x-regmap.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
*/
#include <linux/regmap.h>
@@ -494,8 +494,10 @@
{
if(reg <= WCD938X_BASE_ADDRESS)
return 0;
- return (wcd938x_reg_access[WCD938X_REG(reg)] & RD_REG)
- & ~(wcd938x_reg_access[WCD938X_REG(reg)] & WR_REG);
+ if ((wcd938x_reg_access[WCD938X_REG(reg)] & RD_REG)
+ && !(wcd938x_reg_access[WCD938X_REG(reg)] & WR_REG))
+ return true;
+ return false;
}
struct regmap_config wcd938x_regmap_config = {
diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c
index 4ded2d2..98ea22e 100644
--- a/asoc/codecs/wcd938x/wcd938x.c
+++ b/asoc/codecs/wcd938x/wcd938x.c
@@ -29,6 +29,7 @@
#define WCD938X_VERSION_1_0 1
#define WCD938X_VERSION_ENTRY_SIZE 32
+#define EAR_RX_PATH_AUX 1
#define ADC_MODE_VAL_HIFI 0x01
#define ADC_MODE_VAL_LO_HIF 0x02
@@ -166,6 +167,12 @@
0xC0, 0x80);
snd_soc_component_update_bits(component, WCD938X_DIGITAL_CDC_DMIC_CTL,
0x02, 0x02);
+ snd_soc_component_update_bits(component,
+ WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2CASC_ULP,
+ 0xFF, 0x14);
+ snd_soc_component_update_bits(component,
+ WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2MAIN_ULP,
+ 0x1F, 0x08);
return 0;
}
@@ -364,6 +371,8 @@
WCD938X_DIGITAL_CDC_RX2_CTL, 0x40, 0x00);
snd_soc_component_update_bits(component,
WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x02, 0x02);
+ snd_soc_component_update_bits(component,
+ WCD938X_AUX_AUXPA, 0x10, 0x10);
}
wcd938x->rx_clk_cnt++;
@@ -539,8 +548,11 @@
WCD938X_DIGITAL_CDC_COMP_CTL_0, 0x02, 0x02);
/* 5 msec delay as per HW requirement */
usleep_range(5000, 5010);
- snd_soc_component_update_bits(component, WCD938X_FLYBACK_EN,
- 0x04, 0x00);
+ if (wcd938x->flyback_cur_det_disable == 0)
+ snd_soc_component_update_bits(component,
+ WCD938X_FLYBACK_EN,
+ 0x04, 0x00);
+ wcd938x->flyback_cur_det_disable++;
wcd_cls_h_fsm(component, &wcd938x->clsh_info,
WCD_CLSH_EVENT_PRE_DAC,
WCD_CLSH_STATE_EAR,
@@ -573,13 +585,17 @@
WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0x04, 0x04);
snd_soc_component_update_bits(component,
WCD938X_DIGITAL_CDC_AUX_GAIN_CTL, 0x01, 0x01);
+ if (wcd938x->flyback_cur_det_disable == 0)
+ snd_soc_component_update_bits(component,
+ WCD938X_FLYBACK_EN,
+ 0x04, 0x00);
+ wcd938x->flyback_cur_det_disable++;
wcd_cls_h_fsm(component, &wcd938x->clsh_info,
WCD_CLSH_EVENT_PRE_DAC,
WCD_CLSH_STATE_AUX,
wcd938x->hph_mode);
break;
case SND_SOC_DAPM_POST_PMD:
- wcd938x_rx_clk_disable(component);
snd_soc_component_update_bits(component,
WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x04, 0x00);
break;
@@ -614,6 +630,8 @@
/* 100 usec delay as per HW requirement */
usleep_range(100, 110);
set_bit(HPH_PA_DELAY, &wcd938x->status_mask);
+ snd_soc_component_update_bits(component,
+ WCD938X_DIGITAL_PDM_WD_CTL1, 0x17, 0x13);
break;
case SND_SOC_DAPM_POST_PMU:
/*
@@ -630,7 +648,8 @@
}
snd_soc_component_update_bits(component,
WCD938X_HPH_NEW_INT_HPH_TIMER1, 0x02, 0x02);
- if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI)
+ if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI ||
+ hph_mode == CLS_AB_LP || hph_mode == CLS_AB_LOHIFI)
snd_soc_component_update_bits(component,
WCD938X_ANA_RX_SUPPLIES, 0x02, 0x02);
if (wcd938x->update_wcd_event)
@@ -650,6 +669,8 @@
case SND_SOC_DAPM_POST_PMD:
/* 7 msec delay as per HW requirement */
usleep_range(7000, 7010);
+ snd_soc_component_update_bits(component,
+ WCD938X_DIGITAL_PDM_WD_CTL1, 0x17, 0x00);
blocking_notifier_call_chain(&wcd938x->mbhc->notifier,
WCD_EVENT_POST_HPHR_PA_OFF,
&wcd938x->mbhc->wcd_mbhc);
@@ -690,6 +711,8 @@
/* 100 usec delay as per HW requirement */
usleep_range(100, 110);
set_bit(HPH_PA_DELAY, &wcd938x->status_mask);
+ snd_soc_component_update_bits(component,
+ WCD938X_DIGITAL_PDM_WD_CTL0, 0x17, 0x13);
break;
case SND_SOC_DAPM_POST_PMU:
/*
@@ -706,7 +729,8 @@
}
snd_soc_component_update_bits(component,
WCD938X_HPH_NEW_INT_HPH_TIMER1, 0x02, 0x02);
- if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI)
+ if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI ||
+ hph_mode == CLS_AB_LP || hph_mode == CLS_AB_LOHIFI)
snd_soc_component_update_bits(component,
WCD938X_ANA_RX_SUPPLIES, 0x02, 0x02);
if (wcd938x->update_wcd_event)
@@ -726,6 +750,8 @@
case SND_SOC_DAPM_POST_PMD:
/* 7 msec delay as per HW requirement */
usleep_range(7000, 7010);
+ snd_soc_component_update_bits(component,
+ WCD938X_DIGITAL_PDM_WD_CTL0, 0x17, 0x00);
blocking_notifier_call_chain(&wcd938x->mbhc->notifier,
WCD_EVENT_POST_HPHL_PA_OFF,
&wcd938x->mbhc->wcd_mbhc);
@@ -758,14 +784,17 @@
ret = swr_slvdev_datapath_control(wcd938x->rx_swr_dev,
wcd938x->rx_swr_dev->dev_num,
true);
+ snd_soc_component_update_bits(component,
+ WCD938X_DIGITAL_PDM_WD_CTL2, 0x05, 0x05);
break;
case SND_SOC_DAPM_POST_PMU:
/* 1 msec delay as per HW requirement */
usleep_range(1000, 1010);
- if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI)
+ if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI ||
+ hph_mode == CLS_AB_LP || hph_mode == CLS_AB_LOHIFI)
snd_soc_component_update_bits(component,
WCD938X_ANA_RX_SUPPLIES,
- 0x20, 0x20);
+ 0x02, 0x02);
if (wcd938x->update_wcd_event)
wcd938x->update_wcd_event(wcd938x->handle,
WCD_BOLERO_EVT_RX_MUTE,
@@ -780,10 +809,18 @@
case SND_SOC_DAPM_POST_PMD:
/* 1 msec delay as per HW requirement */
usleep_range(1000, 1010);
+ snd_soc_component_update_bits(component,
+ WCD938X_DIGITAL_PDM_WD_CTL2, 0x05, 0x00);
wcd_cls_h_fsm(component, &wcd938x->clsh_info,
WCD_CLSH_EVENT_POST_PA,
WCD_CLSH_STATE_AUX,
hph_mode);
+
+ wcd938x->flyback_cur_det_disable--;
+ if (wcd938x->flyback_cur_det_disable == 0)
+ snd_soc_component_update_bits(component,
+ WCD938X_FLYBACK_EN,
+ 0x04, 0x04);
break;
};
return ret;
@@ -807,11 +844,27 @@
ret = swr_slvdev_datapath_control(wcd938x->rx_swr_dev,
wcd938x->rx_swr_dev->dev_num,
true);
+ /*
+ * Enable watchdog interrupt for HPHL or AUX
+ * depending on mux value
+ */
+ wcd938x->ear_rx_path =
+ snd_soc_component_read32(
+ component, WCD938X_DIGITAL_CDC_EAR_PATH_CTL);
+ if (wcd938x->ear_rx_path & EAR_RX_PATH_AUX)
+ snd_soc_component_update_bits(component,
+ WCD938X_DIGITAL_PDM_WD_CTL2,
+ 0x05, 0x05);
+ else
+ snd_soc_component_update_bits(component,
+ WCD938X_DIGITAL_PDM_WD_CTL0,
+ 0x17, 0x13);
break;
case SND_SOC_DAPM_POST_PMU:
/* 6 msec delay as per HW requirement */
usleep_range(6000, 6010);
- if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI)
+ if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI ||
+ hph_mode == CLS_AB_LP || hph_mode == CLS_AB_LOHIFI)
snd_soc_component_update_bits(component,
WCD938X_ANA_RX_SUPPLIES,
0x02, 0x02);
@@ -829,12 +882,24 @@
case SND_SOC_DAPM_POST_PMD:
/* 7 msec delay as per HW requirement */
usleep_range(7000, 7010);
+ if (wcd938x->ear_rx_path & EAR_RX_PATH_AUX)
+ snd_soc_component_update_bits(component,
+ WCD938X_DIGITAL_PDM_WD_CTL2,
+ 0x05, 0x00);
+ else
+ snd_soc_component_update_bits(component,
+ WCD938X_DIGITAL_PDM_WD_CTL0,
+ 0x17, 0x00);
wcd_cls_h_fsm(component, &wcd938x->clsh_info,
WCD_CLSH_EVENT_POST_PA,
WCD_CLSH_STATE_EAR,
hph_mode);
- snd_soc_component_update_bits(component, WCD938X_FLYBACK_EN,
- 0x04, 0x04);
+
+ wcd938x->flyback_cur_det_disable--;
+ if (wcd938x->flyback_cur_det_disable == 0)
+ snd_soc_component_update_bits(component,
+ WCD938X_FLYBACK_EN,
+ 0x04, 0x04);
break;
};
return ret;
@@ -1538,6 +1603,7 @@
wcd938x_reset(wcd938x->dev);
wcd938x_get_logical_addr(wcd938x->tx_swr_dev);
wcd938x_get_logical_addr(wcd938x->rx_swr_dev);
+ wcd938x_init_reg(component);
regcache_mark_dirty(wcd938x->regmap);
regcache_sync(wcd938x->regmap);
/* Initialize MBHC module */
@@ -1795,7 +1861,7 @@
static const char * const rx_hph_mode_mux_text[] = {
"CLS_H_INVALID", "CLS_H_HIFI", "CLS_H_LP", "CLS_AB", "CLS_H_LOHIFI",
- "CLS_H_ULP", "CLS_AB_HIFI",
+ "CLS_H_ULP", "CLS_AB_HIFI", "CLS_AB_LP", "CLS_AB_LOHIFI",
};
static const struct soc_enum rx_hph_mode_mux_enum =
@@ -2687,6 +2753,13 @@
return pdata;
}
+static irqreturn_t wcd938x_wd_handle_irq(int irq, void *data)
+{
+ pr_err_ratelimited("%s: Watchdog interrupt for irq =%d triggered\n",
+ __func__, irq);
+ return IRQ_HANDLED;
+}
+
static int wcd938x_bind(struct device *dev)
{
int ret = 0, i = 0;
@@ -2750,6 +2823,18 @@
}
wcd938x->tx_swr_dev->slave_irq = wcd938x->virq;
+ /* Request for watchdog interrupt */
+ wcd_request_irq(&wcd938x->irq_info, WCD938X_IRQ_HPHR_PDM_WD_INT,
+ "HPHR PDM WD INT", wcd938x_wd_handle_irq, NULL);
+ wcd_request_irq(&wcd938x->irq_info, WCD938X_IRQ_HPHL_PDM_WD_INT,
+ "HPHL PDM WD INT", wcd938x_wd_handle_irq, NULL);
+ wcd_request_irq(&wcd938x->irq_info, WCD938X_IRQ_AUX_PDM_WD_INT,
+ "AUX PDM WD INT", wcd938x_wd_handle_irq, NULL);
+ /* Enable watchdog interrupt for HPH and AUX */
+ wcd_enable_irq(&wcd938x->irq_info, WCD938X_IRQ_HPHR_PDM_WD_INT);
+ wcd_enable_irq(&wcd938x->irq_info, WCD938X_IRQ_HPHL_PDM_WD_INT);
+ wcd_enable_irq(&wcd938x->irq_info, WCD938X_IRQ_AUX_PDM_WD_INT);
+
ret = snd_soc_register_component(dev, &soc_codec_dev_wcd938x,
NULL, 0);
if (ret) {
@@ -2860,6 +2945,7 @@
return -ENOMEM;
dev_set_drvdata(dev, wcd938x);
+ wcd938x->dev = dev;
pdata = wcd938x_populate_dt_data(dev);
if (!pdata) {
@@ -2921,9 +3007,10 @@
goto err;
}
+ mutex_init(&wcd938x->micb_lock);
ret = wcd938x_add_slave_components(dev, &match);
if (ret)
- goto err;
+ goto err_lock_init;
wcd938x_reset(dev);
@@ -2932,13 +3019,19 @@
return component_master_add_with_match(dev,
&wcd938x_comp_ops, match);
+err_lock_init:
+ mutex_destroy(&wcd938x->micb_lock);
err:
return ret;
}
static int wcd938x_remove(struct platform_device *pdev)
{
+ struct wcd938x_priv *wcd938x = NULL;
+
+ wcd938x = platform_get_drvdata(pdev);
component_master_del(&pdev->dev, &wcd938x_comp_ops);
+ mutex_destroy(&wcd938x->micb_lock);
dev_set_drvdata(&pdev->dev, NULL);
return 0;
diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c
index d9e0927..a3618ca 100644
--- a/asoc/msm-compress-q6-v2.c
+++ b/asoc/msm-compress-q6-v2.c
@@ -4738,9 +4738,9 @@
chmixer_pspd->output_channel = ucontrol->value.integer.value[3];
chmixer_pspd->port_idx = ucontrol->value.integer.value[4];
- if (chmixer_pspd->input_channel <= 0 ||
+ if (chmixer_pspd->input_channel < 0 ||
chmixer_pspd->input_channel > PCM_FORMAT_MAX_NUM_CHANNEL_V8 ||
- chmixer_pspd->output_channel <= 0 ||
+ chmixer_pspd->output_channel < 0 ||
chmixer_pspd->output_channel > PCM_FORMAT_MAX_NUM_CHANNEL_V8) {
pr_err("%s: Invalid channels, in %d, out %d\n",
__func__, chmixer_pspd->input_channel,
@@ -4795,7 +4795,7 @@
if (prtd && prtd->audio_client) {
stream_id = prtd->audio_client->session;
be_id = chmixer_pspd->port_idx;
- ret = msm_pcm_routing_set_channel_mixer_runtime(be_id,
+ msm_pcm_routing_set_channel_mixer_runtime(be_id,
stream_id, session_type, chmixer_pspd);
}
}
diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c
index ed6af11..35ebff4 100644
--- a/asoc/msm-dai-q6-v2.c
+++ b/asoc/msm-dai-q6-v2.c
@@ -3738,6 +3738,9 @@
snd_ctl_new1(&afe_enc_config_controls[4],
dai));
rc = snd_ctl_add(dai->component->card->snd_card,
+ snd_ctl_new1(&afe_enc_config_controls[5],
+ dai));
+ rc = snd_ctl_add(dai->component->card->snd_card,
snd_ctl_new1(&avd_drift_config_controls[2],
dai));
break;
diff --git a/asoc/msm-pcm-q6-v2.c b/asoc/msm-pcm-q6-v2.c
index 3b20ecc..af15843 100644
--- a/asoc/msm-pcm-q6-v2.c
+++ b/asoc/msm-pcm-q6-v2.c
@@ -1934,9 +1934,9 @@
chmixer_pspd->output_channel = ucontrol->value.integer.value[3];
chmixer_pspd->port_idx = ucontrol->value.integer.value[4];
- if (chmixer_pspd->input_channel <= 0 ||
+ if (chmixer_pspd->input_channel < 0 ||
chmixer_pspd->input_channel > PCM_FORMAT_MAX_NUM_CHANNEL_V8 ||
- chmixer_pspd->output_channel <= 0 ||
+ chmixer_pspd->output_channel < 0 ||
chmixer_pspd->output_channel > PCM_FORMAT_MAX_NUM_CHANNEL_V8) {
pr_err("%s: Invalid channels, in %d, out %d\n",
__func__, chmixer_pspd->input_channel,
diff --git a/dsp/q6asm.c b/dsp/q6asm.c
index 66eef64..f2c7cfc 100644
--- a/dsp/q6asm.c
+++ b/dsp/q6asm.c
@@ -10820,6 +10820,26 @@
return ((struct apr_svc *)(session[session_id].ac)->apr)->id;
}
+uint8_t q6asm_get_asm_stream_id(int session_id)
+{
+ uint8_t stream_id = 1;
+ pr_debug("%s:\n", __func__);
+
+ if (session_id <= 0 || session_id > ASM_ACTIVE_STREAMS_ALLOWED) {
+ pr_err("%s: invalid session_id = %d\n", __func__, session_id);
+ goto done;
+ }
+ if (session[session_id].ac == NULL) {
+ pr_err("%s: session not created for session id = %d\n",
+ __func__, session_id);
+ goto done;
+ }
+ stream_id = (session[session_id].ac)->stream_id;
+
+done:
+ return stream_id;
+}
+
int q6asm_get_asm_topology(int session_id)
{
int topology = -EINVAL;
diff --git a/dsp/rtac.c b/dsp/rtac.c
index 37b7e49..7c7137e 100644
--- a/dsp/rtac.c
+++ b/dsp/rtac.c
@@ -985,6 +985,7 @@
u32 user_buf_size = 0;
u32 bytes_returned = 0;
u32 session_id = 0;
+ u8 stream_id = 0;
u32 payload_size;
u32 data_size = 0;
struct apr_hdr asm_params;
@@ -1044,6 +1045,13 @@
goto err;
}
+ stream_id = q6asm_get_asm_stream_id(session_id);
+ if ((stream_id != 1) && (stream_id != 2)) {
+ pr_err("%s: Invalid stream id %u\n", __func__, stream_id);
+ result = -EINVAL;
+ goto err;
+ }
+
switch (opcode) {
case ASM_STREAM_CMD_SET_PP_PARAMS_V2:
case ASM_STREAM_CMD_SET_PP_PARAMS_V3:
@@ -1103,10 +1111,10 @@
payload_size);
asm_params.src_svc = q6asm_get_apr_service_id(session_id);
asm_params.src_domain = APR_DOMAIN_APPS;
- asm_params.src_port = (session_id << 8) | 0x0001;
+ asm_params.src_port = (session_id << 8) | stream_id;
asm_params.dest_svc = APR_SVC_ASM;
asm_params.dest_domain = APR_DOMAIN_ADSP;
- asm_params.dest_port = (session_id << 8) | 0x0001;
+ asm_params.dest_port = (session_id << 8) | stream_id;
asm_params.token = session_id;
asm_params.opcode = opcode;
diff --git a/include/asoc/msm-cdc-pinctrl.h b/include/asoc/msm-cdc-pinctrl.h
index 4024d90..73022ab 100644
--- a/include/asoc/msm-cdc-pinctrl.h
+++ b/include/asoc/msm-cdc-pinctrl.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0-only */
-/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
*/
#ifndef __MFD_CDC_PINCTRL_H_
@@ -11,7 +11,7 @@
#if IS_ENABLED(CONFIG_MSM_CDC_PINCTRL)
extern int msm_cdc_pinctrl_select_sleep_state(struct device_node *np);
extern int msm_cdc_pinctrl_select_active_state(struct device_node *np);
-extern bool msm_cdc_pinctrl_get_state(struct device_node *np);
+extern int msm_cdc_pinctrl_get_state(struct device_node *np);
extern int msm_cdc_get_gpio_state(struct device_node *np);
int msm_cdc_pinctrl_drv_init(void);
void msm_cdc_pinctrl_drv_exit(void);
@@ -36,7 +36,7 @@
void msm_cdc_pinctrl_drv_exit(void)
{
}
-bool msm_cdc_pinctrl_get_state(struct device_node *np)
+int msm_cdc_pinctrl_get_state(struct device_node *np)
{
return true;
}
diff --git a/include/asoc/wcd-clsh.h b/include/asoc/wcd-clsh.h
index 64250e1..c8e49fd 100644
--- a/include/asoc/wcd-clsh.h
+++ b/include/asoc/wcd-clsh.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
- * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
*/
#ifndef _WCD_CLSH
@@ -62,6 +62,8 @@
CLS_H_LOHIFI, /* LoHIFI */
CLS_H_ULP, /* Ultra Low power */
CLS_AB_HIFI, /* Class-AB */
+ CLS_AB_LP, /* Class-AB Low Power */
+ CLS_AB_LOHIFI, /* Class-AB Low HIFI */
CLS_NONE, /* None of the above modes */
};
diff --git a/include/dsp/q6asm-v2.h b/include/dsp/q6asm-v2.h
index 1bb44b4..de7e31b 100644
--- a/include/dsp/q6asm-v2.h
+++ b/include/dsp/q6asm-v2.h
@@ -711,6 +711,7 @@
int q6asm_stream_send_meta_data(struct audio_client *ac, uint32_t stream_id,
uint32_t initial_samples, uint32_t trailing_samples);
+uint8_t q6asm_get_asm_stream_id(int session_id);
int q6asm_get_asm_topology(int session_id);
int q6asm_get_asm_app_type(int session_id);
diff --git a/soc/soundwire.c b/soc/soundwire.c
index 23e373a..72a94ac 100644
--- a/soc/soundwire.c
+++ b/soc/soundwire.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
*/
#include <linux/kernel.h>
@@ -998,10 +998,14 @@
if (!drv)
return -EINVAL;
- if (dev->type == &swr_dev_type)
+ if (dev->type == &swr_dev_type) {
swr_dev = to_swr_device(dev);
- else
+ if (!swr_dev)
+ return -EINVAL;
+ } else {
return 0;
+ }
+
if (drv->id_table)
return swr_match(drv->id_table, swr_dev) != NULL;
diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c
index 45781c7..194e976 100644
--- a/soc/swr-mstr-ctrl.c
+++ b/soc/swr-mstr-ctrl.c
@@ -984,6 +984,26 @@
mutex_lock(&swrm->mlock);
+ /*
+ * During disable if master is already down, which implies an ssr/pdr
+ * scenario, just mark ports as disabled and exit
+ */
+ if (swrm->state == SWR_MSTR_SSR && !enable) {
+ if (!test_bit(DISABLE_PENDING, &swrm->port_req_pending)) {
+ dev_dbg(swrm->dev, "%s:No pending disconn port req\n",
+ __func__);
+ goto exit;
+ }
+ clear_bit(DISABLE_PENDING, &swrm->port_req_pending);
+ swrm_cleanup_disabled_port_reqs(master);
+ if (!swrm_is_port_en(master)) {
+ dev_dbg(&master->dev, "%s: pm_runtime auto suspend triggered\n",
+ __func__);
+ pm_runtime_mark_last_busy(swrm->dev);
+ pm_runtime_put_autosuspend(swrm->dev);
+ }
+ goto exit;
+ }
bank = get_inactive_bank_num(swrm);
if (enable) {
@@ -2282,6 +2302,7 @@
struct platform_device *pdev = to_platform_device(dev);
struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev);
int ret = 0;
+ bool clk_err = false;
struct swr_master *mstr = &swrm->master;
struct swr_device *swr_dev;
@@ -2295,6 +2316,7 @@
dev_err(dev, "%s:lpass core hw enable failed\n",
__func__);
ret = 0;
+ clk_err = true;
}
}
@@ -2342,7 +2364,7 @@
swrm->state = SWR_MSTR_UP;
}
exit:
- if (swrm->lpass_core_hw_vote)
+ if (swrm->lpass_core_hw_vote && !clk_err)
clk_disable_unprepare(swrm->lpass_core_hw_vote);
pm_runtime_set_autosuspend_delay(&pdev->dev, auto_suspend_timer);
mutex_unlock(&swrm->reslock);
@@ -2354,6 +2376,7 @@
struct platform_device *pdev = to_platform_device(dev);
struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev);
int ret = 0;
+ bool clk_err = false;
struct swr_master *mstr = &swrm->master;
struct swr_device *swr_dev;
int current_state = 0;
@@ -2370,6 +2393,7 @@
dev_err(dev, "%s:lpass core hw enable failed\n",
__func__);
ret = 0;
+ clk_err = true;
}
}
@@ -2423,7 +2447,7 @@
if (current_state != SWR_MSTR_SSR)
swrm->state = SWR_MSTR_DOWN;
exit:
- if (swrm->lpass_core_hw_vote)
+ if (swrm->lpass_core_hw_vote && !clk_err)
clk_disable_unprepare(swrm->lpass_core_hw_vote);
mutex_unlock(&swrm->reslock);
return ret;