Merge "asoc: sm6150: Add support for audio over display port"
diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c
index 749f87b..5001b7f 100644
--- a/asoc/codecs/bolero/bolero-cdc.c
+++ b/asoc/codecs/bolero/bolero-cdc.c
@@ -18,7 +18,7 @@
#include <linux/printk.h>
#include <linux/delay.h>
#include <linux/kernel.h>
-
+#include <soc/snd_event.h>
#include "bolero-cdc.h"
#include "internal.h"
@@ -26,6 +26,7 @@
#define BOLERO_VERSION_1_1 0x0002
#define BOLERO_VERSION_1_2 0x0003
#define BOLERO_VERSION_ENTRY_SIZE 32
+#define BOLERO_CDC_STRING_LEN 80
static struct snd_soc_codec_driver bolero;
@@ -61,6 +62,11 @@
u16 current_mclk_mux_macro;
mutex_lock(&priv->clk_lock);
+ if (!priv->dev_up) {
+ dev_dbg_ratelimited(priv->dev,
+ "%s: SSR in progress, exit\n", __func__);
+ goto err;
+ }
current_mclk_mux_macro =
priv->current_mclk_mux_macro[macro_id];
if (!priv->macro_params[current_mclk_mux_macro].mclk_fn) {
@@ -93,6 +99,11 @@
u16 current_mclk_mux_macro;
mutex_lock(&priv->clk_lock);
+ if (!priv->dev_up) {
+ dev_dbg_ratelimited(priv->dev,
+ "%s: SSR in progress, exit\n", __func__);
+ goto err;
+ }
current_mclk_mux_macro =
priv->current_mclk_mux_macro[macro_id];
if (!priv->macro_params[current_mclk_mux_macro].mclk_fn) {
@@ -118,6 +129,65 @@
return ret;
}
+static int bolero_cdc_update_wcd_event(void *handle, u16 event, u32 data)
+{
+ struct bolero_priv *priv = (struct bolero_priv *)handle;
+
+ if (!priv) {
+ pr_err("%s:Invalid bolero priv handle\n", __func__);
+ return -EINVAL;
+ }
+
+ switch (event) {
+ case WCD_BOLERO_EVT_RX_MUTE:
+ if (priv->macro_params[RX_MACRO].event_handler)
+ priv->macro_params[RX_MACRO].event_handler(priv->codec,
+ BOLERO_MACRO_EVT_RX_MUTE, data);
+ break;
+ case WCD_BOLERO_EVT_IMPED_TRUE:
+ if (priv->macro_params[RX_MACRO].event_handler)
+ priv->macro_params[RX_MACRO].event_handler(priv->codec,
+ BOLERO_MACRO_EVT_IMPED_TRUE, data);
+ break;
+ case WCD_BOLERO_EVT_IMPED_FALSE:
+ if (priv->macro_params[RX_MACRO].event_handler)
+ priv->macro_params[RX_MACRO].event_handler(priv->codec,
+ BOLERO_MACRO_EVT_IMPED_FALSE, data);
+ break;
+ default:
+ dev_err(priv->dev, "%s: Invalid event %d trigger from wcd\n",
+ __func__, event);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int bolero_cdc_register_notifier(void *handle,
+ struct notifier_block *nblock,
+ bool enable)
+{
+ struct bolero_priv *priv = (struct bolero_priv *)handle;
+
+ if (!priv) {
+ pr_err("%s: bolero priv is null\n", __func__);
+ return -EINVAL;
+ }
+ if (enable)
+ return blocking_notifier_chain_register(&priv->notifier,
+ nblock);
+
+ return blocking_notifier_chain_unregister(&priv->notifier,
+ nblock);
+}
+
+static void bolero_cdc_notifier_call(struct bolero_priv *priv,
+ u32 data)
+{
+ dev_dbg(priv->dev, "%s: notifier call, data:%d\n", __func__, data);
+ blocking_notifier_call_chain(&priv->notifier,
+ data, (void *)priv->wcd_dev);
+}
+
static bool bolero_is_valid_macro_dev(struct device *dev)
{
if (of_device_is_compatible(dev->parent->of_node, "qcom,bolero-codec"))
@@ -135,6 +205,46 @@
}
/**
+ * bolero_clear_amic_tx_hold - clears AMIC register on analog codec
+ *
+ * @dev: bolero device ptr.
+ *
+ */
+void bolero_clear_amic_tx_hold(struct device *dev, u16 adc_n)
+{
+ struct bolero_priv *priv;
+ u16 event;
+ u16 amic = 0;
+
+ if (!dev) {
+ pr_err("%s: dev is null\n", __func__);
+ return;
+ }
+
+ if (!bolero_is_valid_codec_dev(dev)) {
+ pr_err("%s: invalid codec\n", __func__);
+ return;
+ }
+ priv = dev_get_drvdata(dev);
+ if (!priv) {
+ dev_err(dev, "%s: priv is null\n", __func__);
+ return;
+ }
+ event = BOLERO_WCD_EVT_TX_CH_HOLD_CLEAR;
+ if (adc_n == BOLERO_ADC0)
+ amic = 0x1;
+ else if (adc_n == BOLERO_ADC2)
+ amic = 0x2;
+ else if (adc_n == BOLERO_ADC3)
+ amic = 0x3;
+ else
+ return;
+
+ bolero_cdc_notifier_call(priv, (amic << 0x10 | event));
+}
+EXPORT_SYMBOL(bolero_clear_amic_tx_hold);
+
+/**
* bolero_get_device_ptr - Get child or macro device ptr
*
* @dev: bolero device ptr.
@@ -230,6 +340,7 @@
priv->macro_params[macro_id].num_dais = ops->num_dais;
priv->macro_params[macro_id].dai_ptr = ops->dai_ptr;
priv->macro_params[macro_id].mclk_fn = ops->mclk_fn;
+ priv->macro_params[macro_id].event_handler = ops->event_handler;
priv->macro_params[macro_id].dev = dev;
priv->current_mclk_mux_macro[macro_id] =
bolero_mclk_mux_tbl[macro_id][MCLK_MUX0];
@@ -237,7 +348,7 @@
priv->num_macros_registered++;
priv->macros_supported[macro_id] = true;
- if (priv->num_macros_registered == priv->child_num) {
+ if (priv->num_macros_registered == priv->num_macros) {
ret = bolero_copy_dais_from_macro(priv);
if (ret < 0) {
dev_err(dev, "%s: copy_dais failed\n", __func__);
@@ -290,12 +401,13 @@
priv->macro_params[macro_id].num_dais = 0;
priv->macro_params[macro_id].dai_ptr = NULL;
priv->macro_params[macro_id].mclk_fn = NULL;
+ priv->macro_params[macro_id].event_handler = NULL;
priv->macro_params[macro_id].dev = NULL;
priv->num_dais -= priv->macro_params[macro_id].num_dais;
priv->num_macros_registered--;
/* UNREGISTER CODEC HERE */
- if (priv->child_num - 1 == priv->num_macros_registered)
+ if (priv->num_macros - 1 == priv->num_macros_registered)
snd_soc_unregister_codec(dev->parent);
}
EXPORT_SYMBOL(bolero_unregister_macro);
@@ -427,10 +539,64 @@
return simple_read_from_buffer(buf, count, &pos, buffer, len);
}
+static int bolero_ssr_enable(struct device *dev, void *data)
+{
+ struct bolero_priv *priv = data;
+ int macro_idx;
+
+ if (priv->initial_boot) {
+ priv->initial_boot = false;
+ return 0;
+ }
+
+ if (priv->macro_params[VA_MACRO].event_handler)
+ priv->macro_params[VA_MACRO].event_handler(priv->codec,
+ BOLERO_MACRO_EVT_WAIT_VA_CLK_RESET, 0x0);
+
+ regcache_cache_only(priv->regmap, false);
+ /* 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)
+ continue;
+ priv->macro_params[macro_idx].event_handler(priv->codec,
+ BOLERO_MACRO_EVT_SSR_UP, 0x0);
+ }
+ mutex_lock(&priv->clk_lock);
+ priv->dev_up = true;
+ mutex_unlock(&priv->clk_lock);
+ bolero_cdc_notifier_call(priv, BOLERO_WCD_EVT_SSR_UP);
+ return 0;
+}
+
+static void bolero_ssr_disable(struct device *dev, void *data)
+{
+ struct bolero_priv *priv = data;
+ int macro_idx;
+
+ regcache_cache_only(priv->regmap, true);
+
+ mutex_lock(&priv->clk_lock);
+ priv->dev_up = false;
+ mutex_unlock(&priv->clk_lock);
+ /* 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)
+ continue;
+ priv->macro_params[macro_idx].event_handler(priv->codec,
+ BOLERO_MACRO_EVT_SSR_DOWN, 0x0);
+ }
+ bolero_cdc_notifier_call(priv, BOLERO_WCD_EVT_SSR_DOWN);
+}
+
static struct snd_info_entry_ops bolero_info_ops = {
.read = bolero_version_read,
};
+static const struct snd_event_ops bolero_ssr_ops = {
+ .enable = bolero_ssr_enable,
+ .disable = bolero_ssr_disable,
+};
+
/*
* bolero_info_create_codec_entry - creates bolero module
* @codec_root: The parent directory
@@ -521,6 +687,16 @@
else if (priv->num_macros_registered > 2)
priv->version = BOLERO_VERSION_1_2;
+ ret = snd_event_client_register(priv->dev, &bolero_ssr_ops, priv);
+ if (!ret) {
+ snd_event_notify(priv->dev, SND_EVENT_UP);
+ } else {
+ dev_err(codec->dev,
+ "%s: Registration with SND event FWK failed ret = %d\n",
+ __func__, ret);
+ goto err;
+ }
+
dev_dbg(codec->dev, "%s: bolero soc codec probe success\n", __func__);
err:
return ret;
@@ -531,6 +707,7 @@
struct bolero_priv *priv = dev_get_drvdata(codec->dev);
int macro_idx;
+ snd_event_client_deregister(priv->dev);
/* call exit for supported macros */
for (macro_idx = START_MACRO; macro_idx < MAX_MACRO; macro_idx++)
if (priv->macro_params[macro_idx].exit)
@@ -555,7 +732,12 @@
static void bolero_add_child_devices(struct work_struct *work)
{
struct bolero_priv *priv;
- int rc;
+ bool wcd937x_node = false;
+ struct platform_device *pdev;
+ struct device_node *node;
+ int ret = 0, count = 0;
+ struct wcd_ctrl_platform_data *platdata = NULL;
+ char plat_dev_name[BOLERO_CDC_STRING_LEN] = "";
priv = container_of(work, struct bolero_priv,
bolero_add_child_devices_work);
@@ -569,12 +751,53 @@
__func__);
return;
}
- rc = of_platform_populate(priv->dev->of_node, NULL, NULL, priv->dev);
- if (rc)
- dev_err(priv->dev, "%s: failed to add child nodes, rc=%d\n",
- __func__, rc);
- else
- dev_dbg(priv->dev, "%s: added child node\n", __func__);
+
+ platdata = &priv->plat_data;
+ priv->child_count = 0;
+
+ for_each_available_child_of_node(priv->dev->of_node, node) {
+ wcd937x_node = false;
+ if (strnstr(node->name, "wcd937x", strlen("wcd937x")) != NULL)
+ wcd937x_node = true;
+
+ strlcpy(plat_dev_name, node->name,
+ (BOLERO_CDC_STRING_LEN - 1));
+
+ pdev = platform_device_alloc(plat_dev_name, -1);
+ if (!pdev) {
+ dev_err(priv->dev, "%s: pdev memory alloc failed\n",
+ __func__);
+ ret = -ENOMEM;
+ goto err;
+ }
+ pdev->dev.parent = priv->dev;
+ pdev->dev.of_node = node;
+
+ if (wcd937x_node) {
+ priv->dev->platform_data = platdata;
+ priv->wcd_dev = &pdev->dev;
+ }
+
+ ret = platform_device_add(pdev);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "%s: Cannot add platform device\n",
+ __func__);
+ platform_device_put(pdev);
+ goto fail_pdev_add;
+ }
+
+ if (priv->child_count < BOLERO_CDC_CHILD_DEVICES_MAX)
+ priv->pdev_child_devices[priv->child_count++] = pdev;
+ else
+ goto err;
+ }
+ return;
+fail_pdev_add:
+ for (count = 0; count < priv->child_count; count++)
+ platform_device_put(priv->pdev_child_devices[count]);
+err:
+ return;
}
static int bolero_probe(struct platform_device *pdev)
@@ -595,11 +818,11 @@
__func__);
return ret;
}
- priv->child_num = num_macros;
- if (priv->child_num > MAX_MACRO) {
+ priv->num_macros = num_macros;
+ if (priv->num_macros > MAX_MACRO) {
dev_err(&pdev->dev,
- "%s:child_num(%d) > MAX_MACRO(%d) than supported\n",
- __func__, priv->child_num, MAX_MACRO);
+ "%s:num_macros(%d) > MAX_MACRO(%d) than supported\n",
+ __func__, priv->num_macros, MAX_MACRO);
return -EINVAL;
}
priv->va_without_decimation = of_property_read_bool(pdev->dev.of_node,
@@ -608,6 +831,8 @@
bolero_reg_access[VA_MACRO] = bolero_va_top_reg_access;
priv->dev = &pdev->dev;
+ priv->dev_up = true;
+ priv->initial_boot = true;
priv->regmap = bolero_regmap_init(priv->dev,
&bolero_regmap_config);
if (IS_ERR_OR_NULL((void *)(priv->regmap))) {
@@ -617,6 +842,10 @@
priv->read_dev = __bolero_reg_read;
priv->write_dev = __bolero_reg_write;
+ priv->plat_data.handle = (void *) priv;
+ priv->plat_data.update_wcd_event = bolero_cdc_update_wcd_event;
+ priv->plat_data.register_notifier = bolero_cdc_register_notifier;
+
dev_set_drvdata(&pdev->dev, priv);
mutex_init(&priv->io_lock);
mutex_init(&priv->clk_lock);
diff --git a/asoc/codecs/bolero/bolero-cdc.h b/asoc/codecs/bolero/bolero-cdc.h
index f7e95ee..aa52491 100644
--- a/asoc/codecs/bolero/bolero-cdc.h
+++ b/asoc/codecs/bolero/bolero-cdc.h
@@ -31,6 +31,23 @@
MCLK_MUX_MAX
};
+enum {
+ BOLERO_ADC0 = 1,
+ BOLERO_ADC1,
+ BOLERO_ADC2,
+ BOLERO_ADC3,
+ BOLERO_ADC_MAX
+};
+
+enum {
+ BOLERO_MACRO_EVT_RX_MUTE = 1, /* for RX mute/unmute */
+ BOLERO_MACRO_EVT_IMPED_TRUE, /* for imped true */
+ BOLERO_MACRO_EVT_IMPED_FALSE, /* for imped false */
+ BOLERO_MACRO_EVT_SSR_DOWN,
+ BOLERO_MACRO_EVT_SSR_UP,
+ BOLERO_MACRO_EVT_WAIT_VA_CLK_RESET
+};
+
struct macro_ops {
int (*init)(struct snd_soc_codec *codec);
int (*exit)(struct snd_soc_codec *codec);
@@ -38,6 +55,8 @@
struct device *dev;
struct snd_soc_dai_driver *dai_ptr;
int (*mclk_fn)(struct device *dev, bool enable);
+ int (*event_handler)(struct snd_soc_codec *codec, u16 event,
+ u32 data);
char __iomem *io_base;
};
@@ -52,6 +71,7 @@
int bolero_info_create_codec_entry(
struct snd_info_entry *codec_root,
struct snd_soc_codec *codec);
+void bolero_clear_amic_tx_hold(struct device *dev, u16 adc_n);
#else
static inline int bolero_register_macro(struct device *dev,
u16 macro_id,
@@ -83,5 +103,9 @@
{
return 0;
}
+
+static inline void bolero_clear_amic_tx_hold(struct device *dev, u16 adc_n)
+{
+}
#endif /* CONFIG_SND_SOC_BOLERO */
#endif /* BOLERO_CDC_H */
diff --git a/asoc/codecs/bolero/internal.h b/asoc/codecs/bolero/internal.h
index 2979ee0..0129c39 100644
--- a/asoc/codecs/bolero/internal.h
+++ b/asoc/codecs/bolero/internal.h
@@ -15,6 +15,15 @@
#include "bolero-cdc-registers.h"
+#define BOLERO_CDC_CHILD_DEVICES_MAX 5
+
+/* from bolero to WCD events */
+enum {
+ BOLERO_WCD_EVT_TX_CH_HOLD_CLEAR = 1,
+ BOLERO_WCD_EVT_SSR_DOWN,
+ BOLERO_WCD_EVT_SSR_UP,
+};
+
enum {
REG_NO_ACCESS,
RD_REG,
@@ -22,6 +31,21 @@
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 */
+};
+
+struct wcd_ctrl_platform_data {
+ void *handle;
+ int (*update_wcd_event)(void *handle, u16 event, u32 data);
+ int (*register_notifier)(void *handle,
+ struct notifier_block *nblock,
+ bool enable);
+};
+
struct bolero_priv {
struct device *dev;
struct snd_soc_codec *codec;
@@ -30,11 +54,13 @@
struct mutex clk_lock;
bool va_without_decimation;
bool macros_supported[MAX_MACRO];
+ bool dev_up;
+ bool initial_boot;
struct macro_ops macro_params[MAX_MACRO];
struct snd_soc_dai_driver *bolero_dais;
u16 num_dais;
u16 num_macros_registered;
- u16 child_num;
+ u16 num_macros;
u16 current_mclk_mux_macro[MAX_MACRO];
struct work_struct bolero_add_child_devices_work;
u32 version;
@@ -47,6 +73,12 @@
u16 macro_id, u16 reg, u8 *val);
int (*write_dev)(struct bolero_priv *priv,
u16 macro_id, u16 reg, u8 val);
+ struct platform_device *pdev_child_devices
+ [BOLERO_CDC_CHILD_DEVICES_MAX];
+ u16 child_count;
+ struct wcd_ctrl_platform_data plat_data;
+ struct device *wcd_dev;
+ struct blocking_notifier_head notifier;
};
struct regmap *bolero_regmap_init(struct device *dev,
diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c
index 006f863..6c936cb 100644
--- a/asoc/codecs/bolero/rx-macro.c
+++ b/asoc/codecs/bolero/rx-macro.c
@@ -75,6 +75,107 @@
#define RX_MACRO_RX_PATH_OFFSET 0x80
#define RX_MACRO_COMP_OFFSET 0x40
+#define MAX_IMPED_PARAMS 6
+
+struct wcd_imped_val {
+ u32 imped_val;
+ u8 index;
+};
+
+static const struct wcd_imped_val imped_index[] = {
+ {4, 0},
+ {5, 1},
+ {6, 2},
+ {7, 3},
+ {8, 4},
+ {9, 5},
+ {10, 6},
+ {11, 7},
+ {12, 8},
+ {13, 9},
+};
+
+struct rx_macro_reg_mask_val {
+ u16 reg;
+ u8 mask;
+ u8 val;
+};
+
+static const struct rx_macro_reg_mask_val imped_table[][MAX_IMPED_PARAMS] = {
+ {
+ {BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xf2},
+ {BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xf2},
+ {BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x00},
+ {BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xf2},
+ {BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xf2},
+ {BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x00},
+ },
+ {
+ {BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xf4},
+ {BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xf4},
+ {BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x00},
+ {BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xf4},
+ {BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xf4},
+ {BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x00},
+ },
+ {
+ {BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xf7},
+ {BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xf7},
+ {BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x01},
+ {BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xf7},
+ {BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xf7},
+ {BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x01},
+ },
+ {
+ {BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xf9},
+ {BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xf9},
+ {BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x00},
+ {BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xf9},
+ {BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xf9},
+ {BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x00},
+ },
+ {
+ {BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xfa},
+ {BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xfa},
+ {BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x00},
+ {BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xfa},
+ {BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xfa},
+ {BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x00},
+ },
+ {
+ {BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xfb},
+ {BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xfb},
+ {BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x00},
+ {BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xfb},
+ {BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xfb},
+ {BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x00},
+ },
+ {
+ {BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xfc},
+ {BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xfc},
+ {BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x00},
+ {BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xfc},
+ {BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xfc},
+ {BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x00},
+ },
+ {
+ {BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xfd},
+ {BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xfd},
+ {BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x00},
+ {BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xfd},
+ {BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xfd},
+ {BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x00},
+ },
+ {
+ {BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xfd},
+ {BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xfd},
+ {BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x01},
+ {BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xfd},
+ {BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xfd},
+ {BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x01},
+ },
+};
+
enum {
INTERP_HPHL,
INTERP_HPHR,
@@ -160,6 +261,12 @@
{176400, 0xB}, {352800, 0xC},
};
+struct rx_macro_bcl_pmic_params {
+ u8 id;
+ u8 sid;
+ u8 ppid;
+};
+
static int rx_macro_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai);
@@ -258,6 +365,9 @@
struct platform_device *pdev_child_devices
[RX_MACRO_CHILD_DEVICES_MAX];
int child_count;
+ int is_softclip_on;
+ int softclip_clk_users;
+ struct rx_macro_bcl_pmic_params bcl_pmic_params;
};
static struct snd_soc_dai_driver rx_macro_dai[];
@@ -321,6 +431,14 @@
static const struct soc_enum rx_macro_ear_mode_enum =
SOC_ENUM_SINGLE_EXT(2, rx_macro_ear_mode_text);
+static const char * const rx_macro_vbat_bcl_gsm_mode_text[] = {"OFF", "ON"};
+static const struct soc_enum rx_macro_vbat_bcl_gsm_mode_enum =
+ SOC_ENUM_SINGLE_EXT(2, rx_macro_vbat_bcl_gsm_mode_text);
+
+static const struct snd_kcontrol_new rx_int2_1_vbat_mix_switch[] = {
+ SOC_DAPM_SINGLE("RX AUX VBAT Enable", SND_SOC_NOPM, 0, 1, 0)
+};
+
RX_MACRO_DAPM_ENUM(rx_int0_2, BOLERO_CDC_RX_INP_MUX_RX_INT0_CFG1, 0,
rx_int_mix_mux_text);
RX_MACRO_DAPM_ENUM(rx_int1_2, BOLERO_CDC_RX_INP_MUX_RX_INT1_CFG1, 0,
@@ -477,6 +595,80 @@
},
};
+static int get_impedance_index(int imped)
+{
+ int i = 0;
+
+ if (imped < imped_index[i].imped_val) {
+ pr_debug("%s, detected impedance is less than %d Ohm\n",
+ __func__, imped_index[i].imped_val);
+ i = 0;
+ goto ret;
+ }
+ if (imped >= imped_index[ARRAY_SIZE(imped_index) - 1].imped_val) {
+ pr_debug("%s, detected impedance is greater than %d Ohm\n",
+ __func__,
+ imped_index[ARRAY_SIZE(imped_index) - 1].imped_val);
+ i = ARRAY_SIZE(imped_index) - 1;
+ goto ret;
+ }
+ for (i = 0; i < ARRAY_SIZE(imped_index) - 1; i++) {
+ if (imped >= imped_index[i].imped_val &&
+ imped < imped_index[i + 1].imped_val)
+ break;
+ }
+ret:
+ pr_debug("%s: selected impedance index = %d\n",
+ __func__, imped_index[i].index);
+ return imped_index[i].index;
+}
+
+/*
+ * rx_macro_wcd_clsh_imped_config -
+ * This function updates HPHL and HPHR gain settings
+ * according to the impedance value.
+ *
+ * @codec: codec pointer handle
+ * @imped: impedance value of HPHL/R
+ * @reset: bool variable to reset registers when teardown
+ */
+static void rx_macro_wcd_clsh_imped_config(struct snd_soc_codec *codec,
+ int imped, bool reset)
+{
+ int i;
+ int index = 0;
+ int table_size;
+
+ static const struct rx_macro_reg_mask_val
+ (*imped_table_ptr)[MAX_IMPED_PARAMS];
+
+ table_size = ARRAY_SIZE(imped_table);
+ imped_table_ptr = imped_table;
+ /* reset = 1, which means request is to reset the register values */
+ if (reset) {
+ for (i = 0; i < MAX_IMPED_PARAMS; i++)
+ snd_soc_update_bits(codec,
+ imped_table_ptr[index][i].reg,
+ imped_table_ptr[index][i].mask, 0);
+ return;
+ }
+ index = get_impedance_index(imped);
+ if (index >= (ARRAY_SIZE(imped_index) - 1)) {
+ pr_debug("%s, impedance not in range = %d\n", __func__, imped);
+ return;
+ }
+ if (index >= table_size) {
+ pr_debug("%s, impedance index not in range = %d\n", __func__,
+ index);
+ return;
+ }
+ for (i = 0; i < MAX_IMPED_PARAMS; i++)
+ snd_soc_update_bits(codec,
+ imped_table_ptr[index][i].reg,
+ imped_table_ptr[index][i].mask,
+ imped_table_ptr[index][i].val);
+}
+
static bool rx_macro_get_data(struct snd_soc_codec *codec,
struct device **rx_dev,
struct rx_macro_priv **rx_priv,
@@ -770,6 +962,11 @@
struct regmap *regmap = dev_get_regmap(rx_priv->dev->parent, NULL);
int ret = 0, mclk_mux = MCLK_MUX0;
+ if (regmap == NULL) {
+ dev_err(rx_priv->dev, "%s: regmap is NULL\n", __func__);
+ return -EINVAL;
+ }
+
dev_dbg(rx_priv->dev, "%s: mclk_enable = %u, dapm = %d clk_users= %d\n",
__func__, mclk_enable, dapm, rx_priv->rx_mclk_users);
@@ -906,6 +1103,50 @@
return 0;
}
+static int rx_macro_event_handler(struct snd_soc_codec *codec, u16 event,
+ u32 data)
+{
+ u16 reg = 0, reg_mix = 0, rx_idx = 0, mute = 0x0;
+ struct device *rx_dev = NULL;
+ struct rx_macro_priv *rx_priv = NULL;
+
+ if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__))
+ return -EINVAL;
+
+ switch (event) {
+ case BOLERO_MACRO_EVT_RX_MUTE:
+ rx_idx = data >> 0x10;
+ mute = data & 0xffff;
+ reg = BOLERO_CDC_RX_RX0_RX_PATH_CTL + (rx_idx *
+ RX_MACRO_RX_PATH_OFFSET);
+ reg_mix = BOLERO_CDC_RX_RX0_RX_PATH_MIX_CTL + (rx_idx *
+ RX_MACRO_RX_PATH_OFFSET);
+ snd_soc_update_bits(codec, reg, 0x10, mute << 0x10);
+ snd_soc_update_bits(codec, reg_mix, 0x10, mute << 0x10);
+ break;
+ case BOLERO_MACRO_EVT_IMPED_TRUE:
+ rx_macro_wcd_clsh_imped_config(codec, data, true);
+ break;
+ case BOLERO_MACRO_EVT_IMPED_FALSE:
+ rx_macro_wcd_clsh_imped_config(codec, data, false);
+ break;
+ case BOLERO_MACRO_EVT_SSR_DOWN:
+ swrm_wcd_notify(
+ rx_priv->swr_ctrl_data[0].rx_swr_pdev,
+ SWR_DEVICE_SSR_DOWN, NULL);
+ swrm_wcd_notify(
+ rx_priv->swr_ctrl_data[0].rx_swr_pdev,
+ SWR_DEVICE_DOWN, NULL);
+ break;
+ case BOLERO_MACRO_EVT_SSR_UP:
+ swrm_wcd_notify(
+ rx_priv->swr_ctrl_data[0].rx_swr_pdev,
+ SWR_DEVICE_SSR_UP, NULL);
+ break;
+ }
+ return 0;
+}
+
static int rx_macro_find_playback_dai_id_for_port(int port_id,
struct rx_macro_priv *rx_priv)
{
@@ -1056,7 +1297,6 @@
case SND_SOC_DAPM_POST_PMU:
snd_soc_write(codec, gain_reg,
snd_soc_read(codec, gain_reg));
- snd_soc_update_bits(codec, mix_reg, 0x10, 0x00);
break;
case SND_SOC_DAPM_POST_PMD:
/* Clk Disable */
@@ -1106,7 +1346,6 @@
case SND_SOC_DAPM_POST_PMU:
snd_soc_write(codec, gain_reg,
snd_soc_read(codec, gain_reg));
- snd_soc_update_bits(codec, reg, 0x10, 0x00);
break;
case SND_SOC_DAPM_POST_PMD:
rx_macro_enable_interp_clk(codec, event, w->shift);
@@ -1159,6 +1398,52 @@
return 0;
}
+static void rx_macro_enable_softclip_clk(struct snd_soc_codec *codec,
+ struct rx_macro_priv *rx_priv,
+ bool enable)
+{
+ if (enable) {
+ if (rx_priv->softclip_clk_users == 0)
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_RX_SOFTCLIP_CRC,
+ 0x01, 0x01);
+ rx_priv->softclip_clk_users++;
+ } else {
+ rx_priv->softclip_clk_users--;
+ if (rx_priv->softclip_clk_users == 0)
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_RX_SOFTCLIP_CRC,
+ 0x01, 0x00);
+ }
+}
+
+static int rx_macro_config_softclip(struct snd_soc_codec *codec,
+ struct rx_macro_priv *rx_priv,
+ int event)
+{
+ dev_dbg(codec->dev, "%s: event %d, enabled %d\n",
+ __func__, event, rx_priv->is_softclip_on);
+
+ if (!rx_priv->is_softclip_on)
+ return 0;
+
+ if (SND_SOC_DAPM_EVENT_ON(event)) {
+ /* Enable Softclip clock */
+ rx_macro_enable_softclip_clk(codec, rx_priv, true);
+ /* Enable Softclip control */
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_RX_SOFTCLIP_SOFTCLIP_CTRL, 0x01, 0x01);
+ }
+
+ if (SND_SOC_DAPM_EVENT_OFF(event)) {
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_RX_SOFTCLIP_SOFTCLIP_CTRL, 0x01, 0x00);
+ rx_macro_enable_softclip_clk(codec, rx_priv, false);
+ }
+
+ return 0;
+}
+
static inline void
rx_macro_enable_clsh_block(struct rx_macro_priv *rx_priv, bool enable)
{
@@ -1391,6 +1676,191 @@
return 0;
}
+static int rx_macro_vbat_bcl_gsm_mode_func_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+
+ ucontrol->value.integer.value[0] =
+ ((snd_soc_read(codec, BOLERO_CDC_RX_BCL_VBAT_CFG) & 0x04) ?
+ 1 : 0);
+
+ dev_dbg(codec->dev, "%s: value: %lu\n", __func__,
+ ucontrol->value.integer.value[0]);
+
+ return 0;
+}
+
+static int rx_macro_vbat_bcl_gsm_mode_func_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+
+ dev_dbg(codec->dev, "%s: value: %lu\n", __func__,
+ ucontrol->value.integer.value[0]);
+
+ /* Set Vbat register configuration for GSM mode bit based on value */
+ if (ucontrol->value.integer.value[0])
+ snd_soc_update_bits(codec, BOLERO_CDC_RX_BCL_VBAT_CFG,
+ 0x04, 0x04);
+ else
+ snd_soc_update_bits(codec, BOLERO_CDC_RX_BCL_VBAT_CFG,
+ 0x04, 0x00);
+
+ return 0;
+}
+
+static int rx_macro_soft_clip_enable_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct device *rx_dev = NULL;
+ struct rx_macro_priv *rx_priv = NULL;
+
+ if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__))
+ return -EINVAL;
+
+ ucontrol->value.integer.value[0] = rx_priv->is_softclip_on;
+
+ dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
+ __func__, ucontrol->value.integer.value[0]);
+
+ return 0;
+}
+
+static int rx_macro_soft_clip_enable_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct device *rx_dev = NULL;
+ struct rx_macro_priv *rx_priv = NULL;
+
+ if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__))
+ return -EINVAL;
+
+ rx_priv->is_softclip_on = ucontrol->value.integer.value[0];
+
+ dev_dbg(codec->dev, "%s: soft clip enable = %d\n", __func__,
+ rx_priv->is_softclip_on);
+
+ return 0;
+}
+
+static int rx_macro_enable_vbat(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol,
+ int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ struct device *rx_dev = NULL;
+ struct rx_macro_priv *rx_priv = NULL;
+
+ dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
+ if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__))
+ return -EINVAL;
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ /* Enable clock for VBAT block */
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_RX_BCL_VBAT_PATH_CTL, 0x10, 0x10);
+ /* Enable VBAT block */
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_RX_BCL_VBAT_CFG, 0x01, 0x01);
+ /* Update interpolator with 384K path */
+ snd_soc_update_bits(codec, BOLERO_CDC_RX_RX2_RX_PATH_CFG1,
+ 0x80, 0x80);
+ /* Update DSM FS rate */
+ snd_soc_update_bits(codec, BOLERO_CDC_RX_RX2_RX_PATH_SEC7,
+ 0x02, 0x02);
+ /* Use attenuation mode */
+ snd_soc_update_bits(codec, BOLERO_CDC_RX_BCL_VBAT_CFG,
+ 0x02, 0x00);
+ /* BCL block needs softclip clock to be enabled */
+ rx_macro_enable_softclip_clk(codec, rx_priv, true);
+ /* Enable VBAT at channel level */
+ snd_soc_update_bits(codec, BOLERO_CDC_RX_RX2_RX_PATH_CFG1,
+ 0x02, 0x02);
+ /* Set the ATTK1 gain */
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD1,
+ 0xFF, 0xFF);
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD2,
+ 0xFF, 0x03);
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD3,
+ 0xFF, 0x00);
+ /* Set the ATTK2 gain */
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD4,
+ 0xFF, 0xFF);
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD5,
+ 0xFF, 0x03);
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD6,
+ 0xFF, 0x00);
+ /* Set the ATTK3 gain */
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD7,
+ 0xFF, 0xFF);
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD8,
+ 0xFF, 0x03);
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD9,
+ 0xFF, 0x00);
+ break;
+
+ case SND_SOC_DAPM_POST_PMD:
+ snd_soc_update_bits(codec, BOLERO_CDC_RX_RX2_RX_PATH_CFG1,
+ 0x80, 0x00);
+ snd_soc_update_bits(codec, BOLERO_CDC_RX_RX2_RX_PATH_SEC7,
+ 0x02, 0x00);
+ snd_soc_update_bits(codec, BOLERO_CDC_RX_BCL_VBAT_CFG,
+ 0x02, 0x02);
+ snd_soc_update_bits(codec, BOLERO_CDC_RX_RX2_RX_PATH_CFG1,
+ 0x02, 0x00);
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD1,
+ 0xFF, 0x00);
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD2,
+ 0xFF, 0x00);
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD3,
+ 0xFF, 0x00);
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD4,
+ 0xFF, 0x00);
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD5,
+ 0xFF, 0x00);
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD6,
+ 0xFF, 0x00);
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD7,
+ 0xFF, 0x00);
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD8,
+ 0xFF, 0x00);
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD9,
+ 0xFF, 0x00);
+ rx_macro_enable_softclip_clk(codec, rx_priv, false);
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_RX_BCL_VBAT_CFG, 0x01, 0x00);
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_RX_BCL_VBAT_PATH_CTL, 0x10, 0x00);
+ break;
+ default:
+ dev_err(rx_dev, "%s: Invalid event %d\n", __func__, event);
+ break;
+ }
+ return 0;
+}
+
static void rx_macro_idle_detect_control(struct snd_soc_codec *codec,
struct rx_macro_priv *rx_priv,
int interp, int event)
@@ -1504,6 +1974,9 @@
event);
rx_macro_config_compander(codec, rx_priv,
interp_idx, event);
+ if (interp_idx == INTERP_AUX)
+ rx_macro_config_softclip(codec, rx_priv,
+ event);
rx_macro_config_classh(codec, rx_priv,
interp_idx, event);
}
@@ -1518,6 +1991,9 @@
interp_idx, event);
rx_macro_config_compander(codec, rx_priv,
interp_idx, event);
+ if (interp_idx == INTERP_AUX)
+ rx_macro_config_softclip(codec, rx_priv,
+ event);
rx_macro_hphdelay_lutbypass(codec, rx_priv, interp_idx,
event);
rx_macro_hd2_control(codec, interp_idx, event);
@@ -1570,6 +2046,11 @@
u16 reg_add = 0, coeff_idx = 0, idx = 0;
struct regmap *regmap = dev_get_regmap(rx_priv->dev->parent, NULL);
+ if (regmap == NULL) {
+ dev_err(rx_priv->dev, "%s: regmap is NULL\n", __func__);
+ return;
+ }
+
regmap_write(regmap,
(BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL + 0x80 * iir_idx),
(band_idx * BAND_MAX * sizeof(uint32_t)) & 0x7F);
@@ -1881,6 +2362,13 @@
SOC_ENUM_EXT("RX_EAR Mode", rx_macro_ear_mode_enum,
rx_macro_get_ear_mode, rx_macro_put_ear_mode),
+ SOC_ENUM_EXT("RX_GSM mode Enable", rx_macro_vbat_bcl_gsm_mode_enum,
+ rx_macro_vbat_bcl_gsm_mode_func_get,
+ rx_macro_vbat_bcl_gsm_mode_func_put),
+ SOC_SINGLE_EXT("RX_Softclip Enable", SND_SOC_NOPM, 0, 1, 0,
+ rx_macro_soft_clip_enable_get,
+ rx_macro_soft_clip_enable_put),
+
SOC_SINGLE_SX_TLV("IIR0 INP0 Volume",
BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B1_CTL, 0, -84, 40,
digital_gain),
@@ -2079,6 +2567,12 @@
0, &rx_int2_mix2_inp_mux, rx_macro_enable_rx_path_clk,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MIXER_E("RX INT2_1 VBAT", SND_SOC_NOPM,
+ 0, 0, rx_int2_1_vbat_mix_switch,
+ ARRAY_SIZE(rx_int2_1_vbat_mix_switch),
+ rx_macro_enable_vbat,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
SND_SOC_DAPM_MIXER("RX INT0 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
SND_SOC_DAPM_MIXER("RX INT1 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
SND_SOC_DAPM_MIXER("RX INT2 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
@@ -2269,6 +2763,10 @@
{"HPHR_OUT", NULL, "RX_MCLK"},
{"RX INT2_1 INTERP", NULL, "RX INT2_1 MIX1"},
+
+ {"RX INT2_1 VBAT", "RX AUX VBAT Enable", "RX INT2_1 INTERP"},
+ {"RX INT2 SEC MIX", NULL, "RX INT2_1 VBAT"},
+
{"RX INT2 SEC MIX", NULL, "RX INT2_1 INTERP"},
{"RX INT2 MIX2", NULL, "RX INT2 SEC MIX"},
{"RX INT2 MIX2", NULL, "RX INT2 MIX2 INP"},
@@ -2383,6 +2881,11 @@
struct regmap *regmap = dev_get_regmap(rx_priv->dev->parent, NULL);
int ret = 0;
+ if (regmap == NULL) {
+ dev_err(rx_priv->dev, "%s: regmap is NULL\n", __func__);
+ return -EINVAL;
+ }
+
mutex_lock(&rx_priv->swr_clk_lock);
dev_dbg(rx_priv->dev, "%s: swrm clock %s\n",
@@ -2434,6 +2937,53 @@
return ret;
}
+static void rx_macro_init_bcl_pmic_reg(struct snd_soc_codec *codec)
+{
+ struct device *rx_dev = NULL;
+ struct rx_macro_priv *rx_priv = NULL;
+
+ if (!codec) {
+ pr_err("%s: NULL codec pointer!\n", __func__);
+ return;
+ }
+
+ if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__))
+ return;
+
+ switch (rx_priv->bcl_pmic_params.id) {
+ case 0:
+ /* Enable ID0 to listen to respective PMIC group interrupts */
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_RX_BCL_VBAT_DECODE_CTL1, 0x02, 0x02);
+ /* Update MC_SID0 */
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_RX_BCL_VBAT_DECODE_CFG1, 0x0F,
+ rx_priv->bcl_pmic_params.sid);
+ /* Update MC_PPID0 */
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_RX_BCL_VBAT_DECODE_CFG2, 0xFF,
+ rx_priv->bcl_pmic_params.ppid);
+ break;
+ case 1:
+ /* Enable ID1 to listen to respective PMIC group interrupts */
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_RX_BCL_VBAT_DECODE_CTL1, 0x01, 0x01);
+ /* Update MC_SID1 */
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_RX_BCL_VBAT_DECODE_CFG3, 0x0F,
+ rx_priv->bcl_pmic_params.sid);
+ /* Update MC_PPID1 */
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_RX_BCL_VBAT_DECODE_CFG1, 0xFF,
+ rx_priv->bcl_pmic_params.ppid);
+ break;
+ default:
+ dev_err(rx_dev, "%s: PMIC ID is invalid\n",
+ __func__, rx_priv->bcl_pmic_params.id);
+ break;
+ }
+}
+
static int rx_macro_init(struct snd_soc_codec *codec)
{
struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
@@ -2486,6 +3036,7 @@
snd_soc_update_bits(codec, BOLERO_CDC_RX_RX0_RX_PATH_CFG3, 0x03, 0x02);
snd_soc_update_bits(codec, BOLERO_CDC_RX_RX1_RX_PATH_CFG3, 0x03, 0x02);
snd_soc_update_bits(codec, BOLERO_CDC_RX_RX2_RX_PATH_CFG3, 0x03, 0x02);
+ rx_macro_init_bcl_pmic_reg(codec);
rx_priv->codec = codec;
@@ -2621,6 +3172,7 @@
ops->dai_ptr = rx_macro_dai;
ops->num_dais = ARRAY_SIZE(rx_macro_dai);
ops->mclk_fn = rx_macro_mclk_ctrl;
+ ops->event_handler = rx_macro_event_handler;
}
static int rx_macro_probe(struct platform_device *pdev)
@@ -2631,6 +3183,7 @@
char __iomem *rx_io_base = NULL, *muxsel_io = NULL;
int ret = 0;
struct clk *rx_core_clk = NULL, *rx_npl_clk = NULL;
+ u8 bcl_pmic_params[3];
rx_priv = devm_kzalloc(&pdev->dev, sizeof(struct rx_macro_priv),
GFP_KERNEL);
@@ -2700,6 +3253,19 @@
return ret;
}
rx_priv->rx_npl_clk = rx_npl_clk;
+
+ ret = of_property_read_u8_array(pdev->dev.of_node,
+ "qcom,rx-bcl-pmic-params", bcl_pmic_params,
+ sizeof(bcl_pmic_params));
+ if (ret) {
+ dev_dbg(&pdev->dev, "%s: could not find %s entry in dt\n",
+ __func__, "qcom,rx-bcl-pmic-params");
+ } else {
+ rx_priv->bcl_pmic_params.id = bcl_pmic_params[0];
+ rx_priv->bcl_pmic_params.sid = bcl_pmic_params[1];
+ rx_priv->bcl_pmic_params.ppid = bcl_pmic_params[2];
+ }
+
dev_set_drvdata(&pdev->dev, rx_priv);
mutex_init(&rx_priv->mclk_lock);
mutex_init(&rx_priv->swr_clk_lock);
diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c
index 4f9736e..44826de 100644
--- a/asoc/codecs/bolero/tx-macro.c
+++ b/asoc/codecs/bolero/tx-macro.c
@@ -19,6 +19,7 @@
#include <sound/soc.h>
#include <sound/soc-dapm.h>
#include <sound/tlv.h>
+#include <soc/swr-wcd.h>
#include "bolero-cdc.h"
#include "bolero-cdc-registers.h"
#include "../msm-cdc-pinctrl.h"
@@ -42,6 +43,8 @@
#define TX_MACRO_DMIC_SAMPLE_RATE_UNDEFINED 0
#define TX_MACRO_MCLK_FREQ 9600000
#define TX_MACRO_TX_PATH_OFFSET 0x80
+#define TX_MACRO_SWR_MIC_MUX_SEL_MASK 0xF
+#define TX_MACRO_ADC_MUX_CFG_OFFSET 0x2
#define TX_MACRO_TX_UNMUTE_DELAY_MS 40
@@ -107,6 +110,12 @@
TX_MACRO_CLK_DIV_16,
};
+enum {
+ MSM_DMIC,
+ SWR_MIC,
+ ANC_FB_TUNE1
+};
+
struct tx_mute_work {
struct tx_macro_priv *tx_priv;
u32 decimator;
@@ -183,6 +192,11 @@
struct regmap *regmap = dev_get_regmap(tx_priv->dev->parent, NULL);
int ret = 0;
+ if (regmap == NULL) {
+ dev_err(tx_priv->dev, "%s: regmap is NULL\n", __func__);
+ return -EINVAL;
+ }
+
dev_dbg(tx_priv->dev, "%s: mclk_enable = %u,clk_users= %d\n",
__func__, mclk_enable, tx_priv->tx_mclk_users);
@@ -290,6 +304,33 @@
return ret;
}
+static int tx_macro_event_handler(struct snd_soc_codec *codec, u16 event,
+ u32 data)
+{
+ struct device *tx_dev = NULL;
+ struct tx_macro_priv *tx_priv = NULL;
+
+ if (!tx_macro_get_data(codec, &tx_dev, &tx_priv, __func__))
+ return -EINVAL;
+
+ switch (event) {
+ case BOLERO_MACRO_EVT_SSR_DOWN:
+ swrm_wcd_notify(
+ tx_priv->swr_ctrl_data[0].tx_swr_pdev,
+ SWR_DEVICE_SSR_DOWN, NULL);
+ swrm_wcd_notify(
+ tx_priv->swr_ctrl_data[0].tx_swr_pdev,
+ SWR_DEVICE_DOWN, NULL);
+ break;
+ case BOLERO_MACRO_EVT_SSR_UP:
+ swrm_wcd_notify(
+ tx_priv->swr_ctrl_data[0].tx_swr_pdev,
+ SWR_DEVICE_SSR_UP, NULL);
+ break;
+ }
+ return 0;
+}
+
static void tx_macro_tx_hpf_corner_freq_callback(struct work_struct *work)
{
struct delayed_work *hpf_delayed_work = NULL;
@@ -298,6 +339,7 @@
struct snd_soc_codec *codec = NULL;
u16 dec_cfg_reg = 0, hpf_gate_reg = 0;
u8 hpf_cut_off_freq = 0;
+ u16 adc_mux_reg = 0, adc_n = 0, adc_reg = 0;
hpf_delayed_work = to_delayed_work(work);
hpf_work = container_of(hpf_delayed_work, struct hpf_work, dwork);
@@ -313,6 +355,19 @@
dev_dbg(codec->dev, "%s: decimator %u hpf_cut_of_freq 0x%x\n",
__func__, hpf_work->decimator, hpf_cut_off_freq);
+ adc_mux_reg = BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG1 +
+ TX_MACRO_ADC_MUX_CFG_OFFSET * hpf_work->decimator;
+ if (snd_soc_read(codec, adc_mux_reg) & SWR_MIC) {
+ adc_reg = BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG0 +
+ TX_MACRO_ADC_MUX_CFG_OFFSET * hpf_work->decimator;
+ adc_n = snd_soc_read(codec, adc_reg) &
+ TX_MACRO_SWR_MIC_MUX_SEL_MASK;
+ if (adc_n >= BOLERO_ADC_MAX)
+ goto tx_hpf_set;
+ /* analog mic clear TX hold */
+ bolero_clear_amic_tx_hold(codec->dev, adc_n);
+ }
+tx_hpf_set:
snd_soc_update_bits(codec, dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK,
hpf_cut_off_freq << 5);
snd_soc_update_bits(codec, hpf_gate_reg, 0x02, 0x02);
@@ -394,7 +449,7 @@
__func__, e->reg);
return -EINVAL;
}
- if (strnstr(widget->name, "smic", strlen(widget->name))) {
+ if (strnstr(widget->name, "SMIC", strlen(widget->name))) {
if (val != 0) {
if (val < 5)
snd_soc_update_bits(codec, mic_sel_reg,
@@ -1319,6 +1374,11 @@
struct regmap *regmap = dev_get_regmap(tx_priv->dev->parent, NULL);
int ret = 0;
+ if (regmap == NULL) {
+ dev_err(tx_priv->dev, "%s: regmap is NULL\n", __func__);
+ return -EINVAL;
+ }
+
mutex_lock(&tx_priv->swr_clk_lock);
dev_dbg(tx_priv->dev, "%s: swrm clock %s\n",
@@ -1608,6 +1668,7 @@
ops->dai_ptr = tx_macro_dai;
ops->num_dais = ARRAY_SIZE(tx_macro_dai);
ops->mclk_fn = tx_macro_mclk_ctrl;
+ ops->event_handler = tx_macro_event_handler;
}
static int tx_macro_probe(struct platform_device *pdev)
diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c
index 03bdfa1..1d28e41 100644
--- a/asoc/codecs/bolero/va-macro.c
+++ b/asoc/codecs/bolero/va-macro.c
@@ -46,6 +46,7 @@
#define VA_MACRO_TX_DMIC_CLK_DIV_SHFT 0x01
#define BOLERO_CDC_VA_TX_UNMUTE_DELAY_MS 40
+#define MAX_RETRY_ATTEMPTS 50
static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0);
static int va_tx_unmute_delay = BOLERO_CDC_VA_TX_UNMUTE_DELAY_MS;
@@ -143,6 +144,11 @@
struct regmap *regmap = dev_get_regmap(va_priv->dev->parent, NULL);
int ret = 0;
+ if (regmap == NULL) {
+ dev_err(va_priv->dev, "%s: regmap is NULL\n", __func__);
+ return -EINVAL;
+ }
+
dev_dbg(va_priv->dev, "%s: mclk_enable = %u, dapm = %d clk_users= %d\n",
__func__, mclk_enable, dapm, va_priv->va_mclk_users);
@@ -173,8 +179,7 @@
0x02, 0x02);
}
} else {
- va_priv->va_mclk_users--;
- if (va_priv->va_mclk_users == 0) {
+ if (va_priv->va_mclk_users == 1) {
regmap_update_bits(regmap,
BOLERO_CDC_VA_TOP_CSR_TOP_CFG0,
0x02, 0x00);
@@ -187,12 +192,47 @@
bolero_request_clock(va_priv->dev,
VA_MACRO, MCLK_MUX0, false);
}
+ va_priv->va_mclk_users--;
}
exit:
mutex_unlock(&va_priv->mclk_lock);
return ret;
}
+static int va_macro_event_handler(struct snd_soc_codec *codec, u16 event,
+ u32 data)
+{
+ struct device *va_dev = NULL;
+ struct va_macro_priv *va_priv = NULL;
+ int retry_cnt = MAX_RETRY_ATTEMPTS;
+
+ if (!va_macro_get_data(codec, &va_dev, &va_priv, __func__))
+ return -EINVAL;
+
+ switch (event) {
+ case BOLERO_MACRO_EVT_WAIT_VA_CLK_RESET:
+ while ((va_priv->va_mclk_users != 0) && (retry_cnt != 0)) {
+ dev_dbg(va_dev, "%s:retry_cnt: %d\n",
+ __func__, retry_cnt);
+ /*
+ * loop and check every 20ms for va_mclk user count
+ * to get reset to 0 which ensures userspace teardown
+ * is done and SSR powerup seq can proceed.
+ */
+ msleep(20);
+ retry_cnt--;
+ }
+ if (retry_cnt == 0)
+ dev_err(va_dev,
+ "%s: va_mclk_users is non-zero still, audio SSR fail!!\n",
+ __func__);
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
static int va_macro_mclk_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
@@ -1049,13 +1089,13 @@
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_MCLK", 0, SND_SOC_NOPM, 0, 0,
+ SND_SOC_DAPM_SUPPLY_S("VA_MCLK", -1, SND_SOC_NOPM, 0, 0,
va_macro_mclk_event,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
};
static const struct snd_soc_dapm_widget va_macro_wod_dapm_widgets[] = {
- SND_SOC_DAPM_SUPPLY_S("VA_MCLK", 0, SND_SOC_NOPM, 0, 0,
+ SND_SOC_DAPM_SUPPLY_S("VA_MCLK", -1, SND_SOC_NOPM, 0, 0,
va_macro_mclk_event,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
};
@@ -1460,6 +1500,7 @@
ops->exit = va_macro_deinit;
ops->io_base = va_io_base;
ops->mclk_fn = va_macro_mclk_ctrl;
+ ops->event_handler = va_macro_event_handler;
}
static int va_macro_probe(struct platform_device *pdev)
diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c
index 47c5cd4..d527186 100644
--- a/asoc/codecs/bolero/wsa-macro.c
+++ b/asoc/codecs/bolero/wsa-macro.c
@@ -50,6 +50,7 @@
#define WSA_MACRO_MUX_CFG_OFFSET 0x8
#define WSA_MACRO_MUX_CFG1_OFFSET 0x4
#define WSA_MACRO_RX_COMP_OFFSET 0x40
+#define WSA_MACRO_RX_SOFTCLIP_OFFSET 0x40
#define WSA_MACRO_RX_PATH_OFFSET 0x80
#define WSA_MACRO_RX_PATH_CFG3_OFFSET 0x10
#define WSA_MACRO_RX_PATH_DSMDEM_OFFSET 0x4C
@@ -82,6 +83,12 @@
WSA_MACRO_COMP_MAX
};
+enum {
+ WSA_MACRO_SOFTCLIP0, /* RX0 */
+ WSA_MACRO_SOFTCLIP1, /* RX1 */
+ WSA_MACRO_SOFTCLIP_MAX
+};
+
struct interp_sample_rate {
int sample_rate;
int rate_val;
@@ -141,6 +148,12 @@
int action);
};
+struct wsa_macro_bcl_pmic_params {
+ u8 id;
+ u8 sid;
+ u8 ppid;
+};
+
enum {
WSA_MACRO_AIF_INVALID = 0,
WSA_MACRO_AIF1_PB,
@@ -205,6 +218,9 @@
int ear_spkr_gain;
int spkr_gain_offset;
int spkr_mode;
+ int is_softclip_on[WSA_MACRO_SOFTCLIP_MAX];
+ int softclip_clk_users[WSA_MACRO_SOFTCLIP_MAX];
+ struct wsa_macro_bcl_pmic_params bcl_pmic_params;
};
static int wsa_macro_config_ear_spkr_gain(struct snd_soc_codec *codec,
@@ -242,10 +258,24 @@
"NO_MAX_STATE", "MAX_STATE_1", "MAX_STATE_2"
};
+static const char * const wsa_macro_vbat_bcl_gsm_mode_text[] = {
+ "OFF", "ON"
+};
+
+static const struct snd_kcontrol_new wsa_int0_vbat_mix_switch[] = {
+ SOC_DAPM_SINGLE("WSA RX0 VBAT Enable", SND_SOC_NOPM, 0, 1, 0)
+};
+
+static const struct snd_kcontrol_new wsa_int1_vbat_mix_switch[] = {
+ SOC_DAPM_SINGLE("WSA RX1 VBAT Enable", SND_SOC_NOPM, 0, 1, 0)
+};
+
static SOC_ENUM_SINGLE_EXT_DECL(wsa_macro_ear_spkr_pa_gain_enum,
wsa_macro_ear_spkr_pa_gain_text);
static SOC_ENUM_SINGLE_EXT_DECL(wsa_macro_spkr_boost_stage_enum,
wsa_macro_speaker_boost_stage_text);
+static SOC_ENUM_SINGLE_EXT_DECL(wsa_macro_vbat_bcl_gsm_mode_enum,
+ wsa_macro_vbat_bcl_gsm_mode_text);
/* RX INT0 */
static const struct soc_enum rx0_prim_inp0_chain_enum =
@@ -829,6 +859,33 @@
return ret;
}
+static int wsa_macro_event_handler(struct snd_soc_codec *codec, u16 event,
+ u32 data)
+{
+ struct device *wsa_dev = NULL;
+ struct wsa_macro_priv *wsa_priv = NULL;
+
+ if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__))
+ return -EINVAL;
+
+ switch (event) {
+ case BOLERO_MACRO_EVT_SSR_DOWN:
+ swrm_wcd_notify(
+ wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
+ SWR_DEVICE_SSR_DOWN, NULL);
+ swrm_wcd_notify(
+ wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
+ SWR_DEVICE_DOWN, NULL);
+ break;
+ case BOLERO_MACRO_EVT_SSR_UP:
+ swrm_wcd_notify(
+ wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
+ SWR_DEVICE_SSR_UP, NULL);
+ break;
+ }
+ return 0;
+}
+
static int wsa_macro_enable_vi_feedback(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol,
int event)
@@ -1095,6 +1152,82 @@
return 0;
}
+static void wsa_macro_enable_softclip_clk(struct snd_soc_codec *codec,
+ struct wsa_macro_priv *wsa_priv,
+ int path,
+ bool enable)
+{
+ u16 softclip_clk_reg = BOLERO_CDC_WSA_SOFTCLIP0_CRC +
+ (path * WSA_MACRO_RX_SOFTCLIP_OFFSET);
+ u8 softclip_mux_mask = (1 << path);
+ u8 softclip_mux_value = (1 << path);
+
+ dev_dbg(codec->dev, "%s: path %d, enable %d\n",
+ __func__, path, enable);
+ if (enable) {
+ if (wsa_priv->softclip_clk_users[path] == 0) {
+ snd_soc_update_bits(codec,
+ softclip_clk_reg, 0x01, 0x01);
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_WSA_RX_INP_MUX_SOFTCLIP_CFG0,
+ softclip_mux_mask, softclip_mux_value);
+ }
+ wsa_priv->softclip_clk_users[path]++;
+ } else {
+ wsa_priv->softclip_clk_users[path]--;
+ if (wsa_priv->softclip_clk_users[path] == 0) {
+ snd_soc_update_bits(codec,
+ softclip_clk_reg, 0x01, 0x00);
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_WSA_RX_INP_MUX_SOFTCLIP_CFG0,
+ softclip_mux_mask, 0x00);
+ }
+ }
+}
+
+static int wsa_macro_config_softclip(struct snd_soc_codec *codec,
+ int path, int event)
+{
+ u16 softclip_ctrl_reg = 0;
+ struct device *wsa_dev = NULL;
+ struct wsa_macro_priv *wsa_priv = NULL;
+ int softclip_path = 0;
+
+ if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__))
+ return -EINVAL;
+
+ if (path == WSA_MACRO_COMP1)
+ softclip_path = WSA_MACRO_SOFTCLIP0;
+ else if (path == WSA_MACRO_COMP2)
+ softclip_path = WSA_MACRO_SOFTCLIP1;
+
+ dev_dbg(codec->dev, "%s: event %d path %d, enabled %d\n",
+ __func__, event, softclip_path,
+ wsa_priv->is_softclip_on[softclip_path]);
+
+ if (!wsa_priv->is_softclip_on[softclip_path])
+ return 0;
+
+ softclip_ctrl_reg = BOLERO_CDC_WSA_SOFTCLIP0_SOFTCLIP_CTRL +
+ (softclip_path * WSA_MACRO_RX_SOFTCLIP_OFFSET);
+
+ if (SND_SOC_DAPM_EVENT_ON(event)) {
+ /* Enable Softclip clock and mux */
+ wsa_macro_enable_softclip_clk(codec, wsa_priv, softclip_path,
+ true);
+ /* Enable Softclip control */
+ snd_soc_update_bits(codec, softclip_ctrl_reg, 0x01, 0x01);
+ }
+
+ if (SND_SOC_DAPM_EVENT_OFF(event)) {
+ snd_soc_update_bits(codec, softclip_ctrl_reg, 0x01, 0x00);
+ wsa_macro_enable_softclip_clk(codec, wsa_priv, softclip_path,
+ false);
+ }
+
+ return 0;
+}
+
static int wsa_macro_interp_get_primary_reg(u16 reg, u16 *ind)
{
u16 prim_int_reg = 0;
@@ -1204,6 +1337,7 @@
break;
case SND_SOC_DAPM_POST_PMU:
wsa_macro_config_compander(codec, w->shift, event);
+ wsa_macro_config_softclip(codec, w->shift, event);
/* apply gain after int clk is enabled */
if ((wsa_priv->spkr_gain_offset ==
WSA_MACRO_GAIN_OFFSET_M1P5_DB) &&
@@ -1231,6 +1365,7 @@
break;
case SND_SOC_DAPM_POST_PMD:
wsa_macro_config_compander(codec, w->shift, event);
+ wsa_macro_config_softclip(codec, w->shift, event);
wsa_macro_enable_prim_interpolator(codec, reg, event);
if ((wsa_priv->spkr_gain_offset ==
WSA_MACRO_GAIN_OFFSET_M1P5_DB) &&
@@ -1356,6 +1491,127 @@
return 0;
}
+
+static int wsa_macro_enable_vbat(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol,
+ int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ struct device *wsa_dev = NULL;
+ struct wsa_macro_priv *wsa_priv = NULL;
+ u16 vbat_path_cfg = 0;
+ int softclip_path = 0;
+
+ if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__))
+ return -EINVAL;
+
+ dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
+ if (!strcmp(w->name, "WSA_RX INT0 VBAT")) {
+ vbat_path_cfg = BOLERO_CDC_WSA_RX0_RX_PATH_CFG1;
+ softclip_path = WSA_MACRO_SOFTCLIP0;
+ } else if (!strcmp(w->name, "WSA_RX INT1 VBAT")) {
+ vbat_path_cfg = BOLERO_CDC_WSA_RX1_RX_PATH_CFG1;
+ softclip_path = WSA_MACRO_SOFTCLIP1;
+ }
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ /* Enable clock for VBAT block */
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_WSA_VBAT_BCL_VBAT_PATH_CTL, 0x10, 0x10);
+ /* Enable VBAT block */
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG, 0x01, 0x01);
+ /* Update interpolator with 384K path */
+ snd_soc_update_bits(codec, vbat_path_cfg, 0x80, 0x80);
+ /* Use attenuation mode */
+ snd_soc_update_bits(codec, BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG,
+ 0x02, 0x00);
+ /*
+ * BCL block needs softclip clock and mux config to be enabled
+ */
+ wsa_macro_enable_softclip_clk(codec, wsa_priv, softclip_path,
+ true);
+ /* Enable VBAT at channel level */
+ snd_soc_update_bits(codec, vbat_path_cfg, 0x02, 0x02);
+ /* Set the ATTK1 gain */
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD1,
+ 0xFF, 0xFF);
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD2,
+ 0xFF, 0x03);
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD3,
+ 0xFF, 0x00);
+ /* Set the ATTK2 gain */
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD4,
+ 0xFF, 0xFF);
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD5,
+ 0xFF, 0x03);
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD6,
+ 0xFF, 0x00);
+ /* Set the ATTK3 gain */
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD7,
+ 0xFF, 0xFF);
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD8,
+ 0xFF, 0x03);
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD9,
+ 0xFF, 0x00);
+ break;
+
+ case SND_SOC_DAPM_POST_PMD:
+ snd_soc_update_bits(codec, vbat_path_cfg, 0x80, 0x00);
+ snd_soc_update_bits(codec, BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG,
+ 0x02, 0x02);
+ snd_soc_update_bits(codec, vbat_path_cfg, 0x02, 0x00);
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD1,
+ 0xFF, 0x00);
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD2,
+ 0xFF, 0x00);
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD3,
+ 0xFF, 0x00);
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD4,
+ 0xFF, 0x00);
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD5,
+ 0xFF, 0x00);
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD6,
+ 0xFF, 0x00);
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD7,
+ 0xFF, 0x00);
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD8,
+ 0xFF, 0x00);
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD9,
+ 0xFF, 0x00);
+ wsa_macro_enable_softclip_clk(codec, wsa_priv, softclip_path,
+ false);
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG, 0x01, 0x00);
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_WSA_VBAT_BCL_VBAT_PATH_CTL, 0x10, 0x00);
+ break;
+ default:
+ dev_err(wsa_dev, "%s: Invalid event %d\n", __func__, event);
+ break;
+ }
+ return 0;
+}
+
static int wsa_macro_enable_echo(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol,
int event)
@@ -1637,6 +1893,80 @@
return 0;
}
+static int wsa_macro_vbat_bcl_gsm_mode_func_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+
+ ucontrol->value.integer.value[0] =
+ ((snd_soc_read(codec, BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG) & 0x04) ?
+ 1 : 0);
+
+ dev_dbg(codec->dev, "%s: value: %lu\n", __func__,
+ ucontrol->value.integer.value[0]);
+
+ return 0;
+}
+
+static int wsa_macro_vbat_bcl_gsm_mode_func_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+
+ dev_dbg(codec->dev, "%s: value: %lu\n", __func__,
+ ucontrol->value.integer.value[0]);
+
+ /* Set Vbat register configuration for GSM mode bit based on value */
+ if (ucontrol->value.integer.value[0])
+ snd_soc_update_bits(codec, BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG,
+ 0x04, 0x04);
+ else
+ snd_soc_update_bits(codec, BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG,
+ 0x04, 0x00);
+
+ return 0;
+}
+
+static int wsa_macro_soft_clip_enable_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct device *wsa_dev = NULL;
+ struct wsa_macro_priv *wsa_priv = NULL;
+ int path = ((struct soc_multi_mixer_control *)
+ kcontrol->private_value)->shift;
+
+ if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__))
+ return -EINVAL;
+
+ ucontrol->value.integer.value[0] = wsa_priv->is_softclip_on[path];
+
+ dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
+ __func__, ucontrol->value.integer.value[0]);
+
+ return 0;
+}
+
+static int wsa_macro_soft_clip_enable_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct device *wsa_dev = NULL;
+ struct wsa_macro_priv *wsa_priv = NULL;
+ int path = ((struct soc_multi_mixer_control *)
+ kcontrol->private_value)->shift;
+
+ if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__))
+ return -EINVAL;
+
+ wsa_priv->is_softclip_on[path] = ucontrol->value.integer.value[0];
+
+ dev_dbg(codec->dev, "%s: soft clip enable for %d: %d\n", __func__,
+ path, wsa_priv->is_softclip_on[path]);
+
+ return 0;
+}
+
static const struct snd_kcontrol_new wsa_macro_snd_controls[] = {
SOC_ENUM_EXT("EAR SPKR PA Gain", wsa_macro_ear_spkr_pa_gain_enum,
wsa_macro_ear_spkr_pa_gain_get,
@@ -1649,6 +1979,17 @@
wsa_macro_spkr_boost_stage_enum,
wsa_macro_spkr_right_boost_stage_get,
wsa_macro_spkr_right_boost_stage_put),
+ SOC_ENUM_EXT("GSM mode Enable", wsa_macro_vbat_bcl_gsm_mode_enum,
+ wsa_macro_vbat_bcl_gsm_mode_func_get,
+ wsa_macro_vbat_bcl_gsm_mode_func_put),
+ SOC_SINGLE_EXT("WSA_Softclip0 Enable", SND_SOC_NOPM,
+ WSA_MACRO_SOFTCLIP0, 1, 0,
+ wsa_macro_soft_clip_enable_get,
+ wsa_macro_soft_clip_enable_put),
+ SOC_SINGLE_EXT("WSA_Softclip1 Enable", SND_SOC_NOPM,
+ WSA_MACRO_SOFTCLIP1, 1, 0,
+ wsa_macro_soft_clip_enable_get,
+ wsa_macro_soft_clip_enable_put),
SOC_SINGLE_SX_TLV("WSA_RX0 Digital Volume",
BOLERO_CDC_WSA_RX0_RX_VOL_CTL,
0, -84, 40, digital_gain),
@@ -1862,6 +2203,17 @@
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MIXER_E("WSA_RX INT0 VBAT", SND_SOC_NOPM,
+ 0, 0, wsa_int0_vbat_mix_switch,
+ ARRAY_SIZE(wsa_int0_vbat_mix_switch),
+ wsa_macro_enable_vbat,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MIXER_E("WSA_RX INT1 VBAT", SND_SOC_NOPM,
+ 0, 0, wsa_int1_vbat_mix_switch,
+ ARRAY_SIZE(wsa_int1_vbat_mix_switch),
+ wsa_macro_enable_vbat,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
SND_SOC_DAPM_INPUT("VIINPUT_WSA"),
SND_SOC_DAPM_OUTPUT("WSA_SPK1 OUT"),
@@ -1939,6 +2291,10 @@
{"WSA_RX0 INT0 SIDETONE MIX", "SRC0", "WSA SRC0_INP"},
{"WSA_RX INT0 INTERP", NULL, "WSA_RX0 INT0 SIDETONE MIX"},
{"WSA_RX INT0 CHAIN", NULL, "WSA_RX INT0 INTERP"},
+
+ {"WSA_RX INT0 VBAT", "WSA RX0 VBAT Enable", "WSA_RX INT0 INTERP"},
+ {"WSA_RX INT0 CHAIN", NULL, "WSA_RX INT0 VBAT"},
+
{"WSA_SPK1 OUT", NULL, "WSA_RX INT0 CHAIN"},
{"WSA_SPK1 OUT", NULL, "WSA_MCLK"},
@@ -1974,6 +2330,10 @@
{"WSA_RX INT1 SEC MIX", NULL, "WSA_RX INT1 MIX"},
{"WSA_RX INT1 INTERP", NULL, "WSA_RX INT1 SEC MIX"},
+
+ {"WSA_RX INT1 VBAT", "WSA RX1 VBAT Enable", "WSA_RX INT1 INTERP"},
+ {"WSA_RX INT1 CHAIN", NULL, "WSA_RX INT1 VBAT"},
+
{"WSA_RX INT1 CHAIN", NULL, "WSA_RX INT1 INTERP"},
{"WSA_SPK2 OUT", NULL, "WSA_RX INT1 CHAIN"},
{"WSA_SPK2 OUT", NULL, "WSA_MCLK"},
@@ -2006,6 +2366,53 @@
{BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CFG, 0x01, 0x01},
};
+static void wsa_macro_init_bcl_pmic_reg(struct snd_soc_codec *codec)
+{
+ struct device *wsa_dev = NULL;
+ struct wsa_macro_priv *wsa_priv = NULL;
+
+ if (!codec) {
+ pr_err("%s: NULL codec pointer!\n", __func__);
+ return;
+ }
+
+ if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__))
+ return;
+
+ switch (wsa_priv->bcl_pmic_params.id) {
+ case 0:
+ /* Enable ID0 to listen to respective PMIC group interrupts */
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CTL1, 0x02, 0x02);
+ /* Update MC_SID0 */
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG1, 0x0F,
+ wsa_priv->bcl_pmic_params.sid);
+ /* Update MC_PPID0 */
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG2, 0xFF,
+ wsa_priv->bcl_pmic_params.ppid);
+ break;
+ case 1:
+ /* Enable ID1 to listen to respective PMIC group interrupts */
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CTL1, 0x01, 0x01);
+ /* Update MC_SID1 */
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG3, 0x0F,
+ wsa_priv->bcl_pmic_params.sid);
+ /* Update MC_PPID1 */
+ snd_soc_update_bits(codec,
+ BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG4, 0xFF,
+ wsa_priv->bcl_pmic_params.ppid);
+ break;
+ default:
+ dev_err(wsa_dev, "%s: PMIC ID is invalid %d\n",
+ __func__, wsa_priv->bcl_pmic_params.id);
+ break;
+ }
+}
+
static void wsa_macro_init_reg(struct snd_soc_codec *codec)
{
int i;
@@ -2015,6 +2422,8 @@
wsa_macro_reg_init[i].reg,
wsa_macro_reg_init[i].mask,
wsa_macro_reg_init[i].val);
+
+ wsa_macro_init_bcl_pmic_reg(codec);
}
static int wsa_swrm_clock(void *handle, bool enable)
@@ -2235,6 +2644,7 @@
ops->dai_ptr = wsa_macro_dai;
ops->num_dais = ARRAY_SIZE(wsa_macro_dai);
ops->mclk_fn = wsa_macro_mclk_ctrl;
+ ops->event_handler = wsa_macro_event_handler;
}
static int wsa_macro_probe(struct platform_device *pdev)
@@ -2245,6 +2655,7 @@
char __iomem *wsa_io_base;
int ret = 0;
struct clk *wsa_core_clk, *wsa_npl_clk;
+ u8 bcl_pmic_params[3];
wsa_priv = devm_kzalloc(&pdev->dev, sizeof(struct wsa_macro_priv),
GFP_KERNEL);
@@ -2300,6 +2711,19 @@
return ret;
}
wsa_priv->wsa_npl_clk = wsa_npl_clk;
+
+ ret = of_property_read_u8_array(pdev->dev.of_node,
+ "qcom,wsa-bcl-pmic-params", bcl_pmic_params,
+ sizeof(bcl_pmic_params));
+ if (ret) {
+ dev_dbg(&pdev->dev, "%s: could not find %s entry in dt\n",
+ __func__, "qcom,wsa-bcl-pmic-params");
+ } else {
+ wsa_priv->bcl_pmic_params.id = bcl_pmic_params[0];
+ wsa_priv->bcl_pmic_params.sid = bcl_pmic_params[1];
+ wsa_priv->bcl_pmic_params.ppid = bcl_pmic_params[2];
+ }
+
dev_set_drvdata(&pdev->dev, wsa_priv);
mutex_init(&wsa_priv->mclk_lock);
mutex_init(&wsa_priv->swr_clk_lock);
diff --git a/asoc/codecs/wcd934x/wcd934x.c b/asoc/codecs/wcd934x/wcd934x.c
index 3667676..2a6d829 100644
--- a/asoc/codecs/wcd934x/wcd934x.c
+++ b/asoc/codecs/wcd934x/wcd934x.c
@@ -10010,9 +10010,13 @@
(&priv->mbhc->wcd_mbhc, false);
}
- if (priv->swr.ctrl_data)
+ if (priv->swr.ctrl_data) {
+ if (is_snd_event_fwk_enabled())
+ swrm_wcd_notify(priv->swr.ctrl_data[0].swr_pdev,
+ SWR_DEVICE_SSR_DOWN, NULL);
swrm_wcd_notify(priv->swr.ctrl_data[0].swr_pdev,
SWR_DEVICE_DOWN, NULL);
+ }
tavil_dsd_reset(priv->dsd_config);
if (!is_snd_event_fwk_enabled())
snd_soc_card_change_online_state(codec->component.card, 0);
@@ -10110,6 +10114,9 @@
goto done;
}
+ if (tavil->swr.ctrl_data && is_snd_event_fwk_enabled())
+ swrm_wcd_notify(tavil->swr.ctrl_data[0].swr_pdev,
+ SWR_DEVICE_SSR_UP, NULL);
tavil_set_spkr_mode(codec, tavil->swr.spkr_mode);
/*
* Once the codec initialization is completed, the svs vote
diff --git a/asoc/codecs/wcd937x/internal.h b/asoc/codecs/wcd937x/internal.h
index e2f1e03..4ca8272 100644
--- a/asoc/codecs/wcd937x/internal.h
+++ b/asoc/codecs/wcd937x/internal.h
@@ -74,6 +74,14 @@
rx_port_mapping[MAX_PORT][MAX_CH_PER_PORT];
struct regulator_bulk_data *supplies;
+ struct notifier_block nblock;
+ /* wcd callback to bolero */
+ void *handle;
+ int (*update_wcd_event)(void *handle, u16 event, u32 data);
+ int (*register_notifier)(void *handle,
+ struct notifier_block *nblock,
+ bool enable);
+
u32 version;
/* Entry for version info */
struct snd_info_entry *entry;
@@ -99,6 +107,32 @@
int num_supplies;
};
+struct wcd_ctrl_platform_data {
+ void *handle;
+ int (*update_wcd_event)(void *handle, u16 event, u32 data);
+ int (*register_notifier)(void *handle,
+ struct notifier_block *nblock,
+ bool enable);
+};
+
+enum {
+ WCD_RX1,
+ WCD_RX2,
+ WCD_RX3
+};
+
+enum {
+ BOLERO_WCD_EVT_TX_CH_HOLD_CLEAR = 1,
+ 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 */
+};
+
enum {
/* INTR_CTRL_INT_MASK_0 */
WCD937X_IRQ_MBHC_BUTTON_RELEASE_DET = 0,
diff --git a/asoc/codecs/wcd937x/wcd937x-mbhc.c b/asoc/codecs/wcd937x/wcd937x-mbhc.c
index 52bc009..c95de4b 100644
--- a/asoc/codecs/wcd937x/wcd937x-mbhc.c
+++ b/asoc/codecs/wcd937x/wcd937x-mbhc.c
@@ -974,6 +974,7 @@
return -EINVAL;
}
+ wcd937x_mbhc_hs_detect_exit(codec);
wcd_mbhc_deinit(wcd_mbhc);
ret = wcd_mbhc_init(wcd_mbhc, codec, &mbhc_cb, &intr_ids,
wcd_mbhc_registers, WCD937X_ZDET_SUPPORTED);
diff --git a/asoc/codecs/wcd937x/wcd937x-regmap.c b/asoc/codecs/wcd937x/wcd937x-regmap.c
index f445abc..0d15c10 100644
--- a/asoc/codecs/wcd937x/wcd937x-regmap.c
+++ b/asoc/codecs/wcd937x/wcd937x-regmap.c
@@ -450,8 +450,10 @@
{
if(reg <= WCD937X_BASE_ADDRESS)
return 0;
- return (wcd937x_reg_access[WCD937X_REG(reg)] & RD_REG)
- & ~(wcd937x_reg_access[WCD937X_REG(reg)] & WR_REG);
+ if ((wcd937x_reg_access[WCD937X_REG(reg)] & RD_REG)
+ && !(wcd937x_reg_access[WCD937X_REG(reg)] & WR_REG))
+ return true;
+ return false;
}
struct regmap_config wcd937x_regmap_config = {
diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c
index 75ff26b..0bdfda1 100644
--- a/asoc/codecs/wcd937x/wcd937x.c
+++ b/asoc/codecs/wcd937x/wcd937x.c
@@ -48,6 +48,8 @@
static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1);
static int wcd937x_handle_post_irq(void *data);
+static int wcd937x_reset(struct device *dev);
+static int wcd937x_reset_low(struct device *dev);
static const struct regmap_irq wcd937x_irqs[WCD937X_NUM_IRQS] = {
REGMAP_IRQ_REG(WCD937X_IRQ_MBHC_BUTTON_PRESS_DET, 0, 0x01),
@@ -142,8 +144,8 @@
u8 *port_type, u8 path)
{
int i, j;
- u8 num_ports;
- struct codec_port_info (*map)[MAX_PORT][MAX_CH_PER_PORT];
+ u8 num_ports = 0;
+ struct codec_port_info (*map)[MAX_PORT][MAX_CH_PER_PORT] = NULL;
struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec);
switch (path) {
@@ -186,8 +188,8 @@
u32 slave_port_type, master_port_type;
u32 i, ch_iter = 0;
int ret = 0;
- u8 *num_ports;
- struct codec_port_info (*map)[MAX_PORT][MAX_CH_PER_PORT];
+ u8 *num_ports = NULL;
+ struct codec_port_info (*map)[MAX_PORT][MAX_CH_PER_PORT] = NULL;
struct wcd937x_priv *wcd937x = dev_get_drvdata(dev);
switch (path) {
@@ -568,8 +570,16 @@
ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev,
wcd937x->rx_swr_dev->dev_num,
true);
+ if (wcd937x->update_wcd_event)
+ wcd937x->update_wcd_event(wcd937x->handle,
+ WCD_BOLERO_EVT_RX_MUTE,
+ (WCD_RX2 << 0x10));
break;
case SND_SOC_DAPM_PRE_PMD:
+ if (wcd937x->update_wcd_event)
+ wcd937x->update_wcd_event(wcd937x->handle,
+ WCD_BOLERO_EVT_RX_MUTE,
+ (WCD_RX2 << 0x10 | 0x1));
blocking_notifier_call_chain(&wcd937x->mbhc->notifier,
WCD_EVENT_PRE_HPHR_PA_OFF,
&wcd937x->mbhc->wcd_mbhc);
@@ -607,8 +617,16 @@
ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev,
wcd937x->rx_swr_dev->dev_num,
true);
+ if (wcd937x->update_wcd_event)
+ wcd937x->update_wcd_event(wcd937x->handle,
+ WCD_BOLERO_EVT_RX_MUTE,
+ (WCD_RX1 << 0x10));
break;
case SND_SOC_DAPM_PRE_PMD:
+ if (wcd937x->update_wcd_event)
+ wcd937x->update_wcd_event(wcd937x->handle,
+ WCD_BOLERO_EVT_RX_MUTE,
+ (WCD_RX1 << 0x10 | 0x1));
blocking_notifier_call_chain(&wcd937x->mbhc->notifier,
WCD_EVENT_PRE_HPHL_PA_OFF,
&wcd937x->mbhc->wcd_mbhc);
@@ -650,6 +668,16 @@
ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev,
wcd937x->rx_swr_dev->dev_num,
true);
+ if (wcd937x->update_wcd_event)
+ wcd937x->update_wcd_event(wcd937x->handle,
+ WCD_BOLERO_EVT_RX_MUTE,
+ (WCD_RX3 << 0x10));
+ break;
+ case SND_SOC_DAPM_PRE_PMD:
+ if (wcd937x->update_wcd_event)
+ wcd937x->update_wcd_event(wcd937x->handle,
+ WCD_BOLERO_EVT_RX_MUTE,
+ (WCD_RX3 << 0x10 | 0x1));
break;
case SND_SOC_DAPM_POST_PMD:
usleep_range(1000, 1010);
@@ -685,6 +713,16 @@
ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev,
wcd937x->rx_swr_dev->dev_num,
true);
+ if (wcd937x->update_wcd_event)
+ wcd937x->update_wcd_event(wcd937x->handle,
+ WCD_BOLERO_EVT_RX_MUTE,
+ (WCD_RX1 << 0x10));
+ break;
+ case SND_SOC_DAPM_PRE_PMD:
+ if (wcd937x->update_wcd_event)
+ wcd937x->update_wcd_event(wcd937x->handle,
+ WCD_BOLERO_EVT_RX_MUTE,
+ (WCD_RX1 << 0x10 | 0x1));
break;
case SND_SOC_DAPM_POST_PMD:
usleep_range(7000, 7010);
@@ -1180,6 +1218,73 @@
}
EXPORT_SYMBOL(wcd937x_micbias_control);
+static int wcd937x_get_logical_addr(struct swr_device *swr_dev)
+{
+ int ret = 0;
+ uint8_t devnum = 0;
+
+ ret = swr_get_logical_dev_num(swr_dev, swr_dev->addr, &devnum);
+ if (ret) {
+ dev_err(&swr_dev->dev,
+ "%s get devnum %d for dev addr %lx failed\n",
+ __func__, devnum, swr_dev->addr);
+ swr_remove_device(swr_dev);
+ return ret;
+ }
+ swr_dev->dev_num = devnum;
+ return 0;
+}
+
+static int wcd937x_event_notify(struct notifier_block *block,
+ unsigned long val,
+ void *data)
+{
+ u16 event = (val & 0xffff);
+ u16 amic = (val >> 0x10);
+ u16 mask = 0x40, reg = 0x0;
+ int ret = 0;
+ struct wcd937x_priv *wcd937x = dev_get_drvdata((struct device *)data);
+ struct snd_soc_codec *codec = wcd937x->codec;
+ struct wcd_mbhc *mbhc;
+
+ switch (event) {
+ case BOLERO_WCD_EVT_TX_CH_HOLD_CLEAR:
+ if (amic == 0x1 || amic == 0x2)
+ reg = WCD937X_ANA_TX_CH2;
+ else if (amic == 0x3)
+ reg = WCD937X_ANA_TX_CH3_HPF;
+ else
+ return 0;
+ if (amic == 0x2)
+ mask = 0x20;
+ snd_soc_update_bits(codec, reg, mask, 0x00);
+ break;
+ case BOLERO_WCD_EVT_SSR_DOWN:
+ wcd937x_reset_low(wcd937x->dev);
+ break;
+ case BOLERO_WCD_EVT_SSR_UP:
+ wcd937x_reset(wcd937x->dev);
+ wcd937x_get_logical_addr(wcd937x->tx_swr_dev);
+ wcd937x_get_logical_addr(wcd937x->rx_swr_dev);
+ regcache_mark_dirty(wcd937x->regmap);
+ regcache_sync(wcd937x->regmap);
+ /* Initialize MBHC module */
+ mbhc = &wcd937x->mbhc->wcd_mbhc;
+ ret = wcd937x_mbhc_post_ssr_init(wcd937x->mbhc, codec);
+ if (ret) {
+ dev_err(codec->dev, "%s: mbhc initialization failed\n",
+ __func__);
+ } else {
+ wcd937x_mbhc_hs_detect(codec, mbhc->mbhc_cfg);
+ }
+ break;
+ default:
+ dev_err(codec->dev, "%s: invalid event %d\n", __func__, event);
+ break;
+ }
+ return 0;
+}
+
static int __wcd937x_codec_enable_micbias(struct snd_soc_dapm_widget *w,
int event)
{
@@ -1443,11 +1548,11 @@
SND_SOC_DAPM_PGA_E("EAR PGA", WCD937X_ANA_EAR, 7, 0, NULL, 0,
wcd937x_codec_enable_ear_pa,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
- SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_PGA_E("AUX PGA", WCD937X_AUX_AUXPA, 7, 0, NULL, 0,
wcd937x_codec_enable_aux_pa,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
- SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_PGA_E("HPHL PGA", WCD937X_ANA_HPH, 7, 0, NULL, 0,
wcd937x_codec_enable_hphl_pa,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
@@ -1754,7 +1859,6 @@
return -EINVAL;
wcd937x->codec = codec;
-
variant = (snd_soc_read(codec, WCD937X_DIGITAL_EFUSE_REG_0) & 0x0E) >> 1;
wcd937x->variant = variant;
@@ -1802,6 +1906,19 @@
snd_soc_dapm_sync(dapm);
}
wcd937x->version = WCD937X_VERSION_1_0;
+ /* Register event notifier */
+ wcd937x->nblock.notifier_call = wcd937x_event_notify;
+ if (wcd937x->register_notifier) {
+ ret = wcd937x->register_notifier(wcd937x->handle,
+ &wcd937x->nblock,
+ true);
+ if (ret) {
+ dev_err(codec->dev,
+ "%s: Failed to register notifier %d\n",
+ __func__, ret);
+ return ret;
+ }
+ }
return ret;
err_hwdep:
@@ -1818,6 +1935,10 @@
if (!wcd937x)
return -EINVAL;
+ if (wcd937x->register_notifier)
+ return wcd937x->register_notifier(wcd937x->handle,
+ &wcd937x->nblock,
+ false);
return 0;
}
@@ -1842,7 +1963,7 @@
},
};
-int wcd937x_reset(struct device *dev)
+static int wcd937x_reset(struct device *dev)
{
struct wcd937x_priv *wcd937x = NULL;
int rc = 0;
@@ -1945,6 +2066,36 @@
}
}
+static int wcd937x_reset_low(struct device *dev)
+{
+ struct wcd937x_priv *wcd937x = NULL;
+ int rc = 0;
+
+ if (!dev)
+ return -ENODEV;
+
+ wcd937x = dev_get_drvdata(dev);
+ if (!wcd937x)
+ return -EINVAL;
+
+ if (!wcd937x->rst_np) {
+ dev_err(dev, "%s: reset gpio device node not specified\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ rc = msm_cdc_pinctrl_select_sleep_state(wcd937x->rst_np);
+ if (rc) {
+ dev_err(dev, "%s: wcd sleep state request fail!\n",
+ __func__);
+ return rc;
+ }
+ /* 20ms sleep required after pulling the reset gpio to LOW */
+ usleep_range(20, 30);
+
+ return rc;
+}
+
struct wcd937x_pdata *wcd937x_populate_dt_data(struct device *dev)
{
struct wcd937x_pdata *pdata = NULL;
@@ -1985,6 +2136,7 @@
int ret = 0, i = 0;
struct wcd937x_priv *wcd937x = NULL;
struct wcd937x_pdata *pdata = NULL;
+ struct wcd_ctrl_platform_data *plat_data = NULL;
wcd937x = devm_kzalloc(dev, sizeof(struct wcd937x_priv), GFP_KERNEL);
if (!wcd937x)
@@ -2008,6 +2160,30 @@
return ret;
}
+ plat_data = dev_get_platdata(dev->parent);
+ if (!plat_data) {
+ dev_err(dev, "%s: platform data from parent is NULL\n",
+ __func__);
+ return -EINVAL;
+ }
+ wcd937x->handle = (void *)plat_data->handle;
+ if (!wcd937x->handle) {
+ dev_err(dev, "%s: handle is NULL\n", __func__);
+ return -EINVAL;
+ }
+ wcd937x->update_wcd_event = plat_data->update_wcd_event;
+ if (!wcd937x->update_wcd_event) {
+ dev_err(dev, "%s: update_wcd_event api is null!\n",
+ __func__);
+ return -EINVAL;
+ }
+ wcd937x->register_notifier = plat_data->register_notifier;
+ if (!wcd937x->register_notifier) {
+ dev_err(dev, "%s: register_notifier api is null!\n",
+ __func__);
+ return -EINVAL;
+ }
+
ret = msm_cdc_enable_static_supplies(dev, wcd937x->supplies,
pdata->regulator,
pdata->num_supplies);
diff --git a/asoc/codecs/wcd937x/wcd937x_slave.c b/asoc/codecs/wcd937x/wcd937x_slave.c
index 36c2af1..252504f 100644
--- a/asoc/codecs/wcd937x/wcd937x_slave.c
+++ b/asoc/codecs/wcd937x/wcd937x_slave.c
@@ -85,6 +85,21 @@
.unbind = wcd937x_slave_unbind,
};
+static int wcd937x_swr_up(struct swr_device *pdev)
+{
+ return 0;
+}
+
+static int wcd937x_swr_down(struct swr_device *pdev)
+{
+ return 0;
+}
+
+static int wcd937x_swr_reset(struct swr_device *pdev)
+{
+ return 0;
+}
+
static int wcd937x_swr_probe(struct swr_device *pdev)
{
return component_add(&pdev->dev, &wcd937x_slave_comp_ops);
@@ -105,6 +120,9 @@
.probe = wcd937x_swr_probe,
.remove = wcd937x_swr_remove,
.id_table = wcd937x_swr_id,
+ .device_up = wcd937x_swr_up,
+ .device_down = wcd937x_swr_down,
+ .reset_device = wcd937x_swr_reset,
};
static int __init wcd937x_slave_init(void)
diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c
index 9e44594..1c9ad1a 100644
--- a/asoc/msm-pcm-routing-v2.c
+++ b/asoc/msm-pcm-routing-v2.c
@@ -301,342 +301,342 @@
#define SLIMBUS_EXTPROC_RX AFE_PORT_INVALID
struct msm_pcm_routing_bdai_data msm_bedais[MSM_BACKEND_DAI_MAX] = {
- { PRIMARY_I2S_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_PRI_I2S_RX},
- { PRIMARY_I2S_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_PRI_I2S_TX},
- { SLIMBUS_0_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SLIMBUS_0_RX},
- { SLIMBUS_0_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SLIMBUS_0_TX},
- { HDMI_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_HDMI},
- { INT_BT_SCO_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_INT_BT_SCO_RX},
- { INT_BT_SCO_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_INT_BT_SCO_TX},
- { INT_FM_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_INT_FM_RX},
- { INT_FM_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_INT_FM_TX},
- { RT_PROXY_PORT_001_RX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { PRIMARY_I2S_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_PRI_I2S_RX},
+ { PRIMARY_I2S_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_PRI_I2S_TX},
+ { SLIMBUS_0_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SLIMBUS_0_RX},
+ { SLIMBUS_0_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SLIMBUS_0_TX},
+ { HDMI_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_HDMI},
+ { INT_BT_SCO_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_INT_BT_SCO_RX},
+ { INT_BT_SCO_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_INT_BT_SCO_TX},
+ { INT_FM_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_INT_FM_RX},
+ { INT_FM_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_INT_FM_TX},
+ { RT_PROXY_PORT_001_RX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_AFE_PCM_RX},
- { RT_PROXY_PORT_001_TX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { RT_PROXY_PORT_001_TX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_AFE_PCM_TX},
- { AFE_PORT_ID_PRIMARY_PCM_RX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_PRIMARY_PCM_RX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_AUXPCM_RX},
- { AFE_PORT_ID_PRIMARY_PCM_TX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_PRIMARY_PCM_TX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_AUXPCM_TX},
- { VOICE_PLAYBACK_TX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { VOICE_PLAYBACK_TX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_VOICE_PLAYBACK_TX},
- { VOICE2_PLAYBACK_TX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { VOICE2_PLAYBACK_TX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_VOICE2_PLAYBACK_TX},
- { VOICE_RECORD_RX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { VOICE_RECORD_RX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_INCALL_RECORD_RX},
- { VOICE_RECORD_TX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { VOICE_RECORD_TX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_INCALL_RECORD_TX},
- { MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_MI2S_RX},
- { MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_MI2S_TX},
- { SECONDARY_I2S_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SEC_I2S_RX},
- { SLIMBUS_1_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SLIMBUS_1_RX},
- { SLIMBUS_1_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SLIMBUS_1_TX},
- { SLIMBUS_2_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SLIMBUS_2_RX},
- { SLIMBUS_2_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SLIMBUS_2_TX},
- { SLIMBUS_3_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SLIMBUS_3_RX},
- { SLIMBUS_3_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SLIMBUS_3_TX},
- { SLIMBUS_4_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SLIMBUS_4_RX},
- { SLIMBUS_4_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SLIMBUS_4_TX},
- { SLIMBUS_5_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SLIMBUS_5_RX},
- { SLIMBUS_5_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SLIMBUS_5_TX},
- { SLIMBUS_6_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SLIMBUS_6_RX},
- { SLIMBUS_6_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SLIMBUS_6_TX},
- { SLIMBUS_7_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SLIMBUS_7_RX},
- { SLIMBUS_7_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SLIMBUS_7_TX},
- { SLIMBUS_8_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SLIMBUS_8_RX},
- { SLIMBUS_8_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SLIMBUS_8_TX},
- { SLIMBUS_EXTPROC_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_STUB_RX},
- { SLIMBUS_EXTPROC_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_STUB_TX},
- { SLIMBUS_EXTPROC_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_STUB_1_TX},
- { AFE_PORT_ID_QUATERNARY_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_MI2S_RX},
+ { MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_MI2S_TX},
+ { SECONDARY_I2S_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SEC_I2S_RX},
+ { SLIMBUS_1_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SLIMBUS_1_RX},
+ { SLIMBUS_1_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SLIMBUS_1_TX},
+ { SLIMBUS_2_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SLIMBUS_2_RX},
+ { SLIMBUS_2_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SLIMBUS_2_TX},
+ { SLIMBUS_3_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SLIMBUS_3_RX},
+ { SLIMBUS_3_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SLIMBUS_3_TX},
+ { SLIMBUS_4_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SLIMBUS_4_RX},
+ { SLIMBUS_4_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SLIMBUS_4_TX},
+ { SLIMBUS_5_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SLIMBUS_5_RX},
+ { SLIMBUS_5_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SLIMBUS_5_TX},
+ { SLIMBUS_6_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SLIMBUS_6_RX},
+ { SLIMBUS_6_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SLIMBUS_6_TX},
+ { SLIMBUS_7_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SLIMBUS_7_RX},
+ { SLIMBUS_7_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SLIMBUS_7_TX},
+ { SLIMBUS_8_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SLIMBUS_8_RX},
+ { SLIMBUS_8_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SLIMBUS_8_TX},
+ { SLIMBUS_EXTPROC_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_STUB_RX},
+ { SLIMBUS_EXTPROC_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_STUB_TX},
+ { SLIMBUS_EXTPROC_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_STUB_1_TX},
+ { AFE_PORT_ID_QUATERNARY_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_QUAT_MI2S_RX},
- { AFE_PORT_ID_QUATERNARY_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_QUATERNARY_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_QUAT_MI2S_TX},
- { AFE_PORT_ID_SECONDARY_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_SECONDARY_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_SEC_MI2S_RX},
- { AFE_PORT_ID_SECONDARY_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_SECONDARY_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_SEC_MI2S_TX},
- { AFE_PORT_ID_PRIMARY_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_PRIMARY_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_PRI_MI2S_RX},
- { AFE_PORT_ID_PRIMARY_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_PRIMARY_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_PRI_MI2S_TX},
- { AFE_PORT_ID_TERTIARY_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_TERTIARY_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_TERT_MI2S_RX},
- { AFE_PORT_ID_TERTIARY_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_TERTIARY_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_TERT_MI2S_TX},
- { AUDIO_PORT_ID_I2S_RX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AUDIO_PORT_ID_I2S_RX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_AUDIO_I2S_RX},
- { AFE_PORT_ID_SECONDARY_PCM_RX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_SECONDARY_PCM_RX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_SEC_AUXPCM_RX},
- { AFE_PORT_ID_SECONDARY_PCM_TX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_SECONDARY_PCM_TX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_SEC_AUXPCM_TX},
- { AFE_PORT_ID_PRIMARY_SPDIF_RX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_PRIMARY_SPDIF_RX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_PRI_SPDIF_RX},
- { AFE_PORT_ID_SECONDARY_MI2S_RX_SD1, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_SECONDARY_MI2S_RX_SD1, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_SEC_MI2S_RX_SD1},
- { AFE_PORT_ID_QUINARY_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_QUINARY_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_QUIN_MI2S_RX},
- { AFE_PORT_ID_QUINARY_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_QUINARY_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_QUIN_MI2S_TX},
- { AFE_PORT_ID_SENARY_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_SENARY_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_SENARY_MI2S_TX},
- { AFE_PORT_ID_PRIMARY_TDM_RX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_PRIMARY_TDM_RX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_PRI_TDM_RX_0},
- { AFE_PORT_ID_PRIMARY_TDM_TX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_PRIMARY_TDM_TX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_PRI_TDM_TX_0},
- { AFE_PORT_ID_PRIMARY_TDM_RX_1, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_PRIMARY_TDM_RX_1, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_PRI_TDM_RX_1},
- { AFE_PORT_ID_PRIMARY_TDM_TX_1, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_PRIMARY_TDM_TX_1, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_PRI_TDM_TX_1},
- { AFE_PORT_ID_PRIMARY_TDM_RX_2, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_PRIMARY_TDM_RX_2, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_PRI_TDM_RX_2},
- { AFE_PORT_ID_PRIMARY_TDM_TX_2, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_PRIMARY_TDM_TX_2, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_PRI_TDM_TX_2},
- { AFE_PORT_ID_PRIMARY_TDM_RX_3, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_PRIMARY_TDM_RX_3, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_PRI_TDM_RX_3},
- { AFE_PORT_ID_PRIMARY_TDM_TX_3, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_PRIMARY_TDM_TX_3, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_PRI_TDM_TX_3},
- { AFE_PORT_ID_PRIMARY_TDM_RX_4, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_PRIMARY_TDM_RX_4, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_PRI_TDM_RX_4},
- { AFE_PORT_ID_PRIMARY_TDM_TX_4, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_PRIMARY_TDM_TX_4, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_PRI_TDM_TX_4},
- { AFE_PORT_ID_PRIMARY_TDM_RX_5, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_PRIMARY_TDM_RX_5, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_PRI_TDM_RX_5},
- { AFE_PORT_ID_PRIMARY_TDM_TX_5, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_PRIMARY_TDM_TX_5, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_PRI_TDM_TX_5},
- { AFE_PORT_ID_PRIMARY_TDM_RX_6, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_PRIMARY_TDM_RX_6, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_PRI_TDM_RX_6},
- { AFE_PORT_ID_PRIMARY_TDM_TX_6, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_PRIMARY_TDM_TX_6, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_PRI_TDM_TX_6},
- { AFE_PORT_ID_PRIMARY_TDM_RX_7, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_PRIMARY_TDM_RX_7, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_PRI_TDM_RX_7},
- { AFE_PORT_ID_PRIMARY_TDM_TX_7, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_PRIMARY_TDM_TX_7, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_PRI_TDM_TX_7},
- { AFE_PORT_ID_SECONDARY_TDM_RX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_SECONDARY_TDM_RX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_SEC_TDM_RX_0},
- { AFE_PORT_ID_SECONDARY_TDM_TX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_SECONDARY_TDM_TX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_SEC_TDM_TX_0},
- { AFE_PORT_ID_SECONDARY_TDM_RX_1, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_SECONDARY_TDM_RX_1, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_SEC_TDM_RX_1},
- { AFE_PORT_ID_SECONDARY_TDM_TX_1, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_SECONDARY_TDM_TX_1, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_SEC_TDM_TX_1},
- { AFE_PORT_ID_SECONDARY_TDM_RX_2, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_SECONDARY_TDM_RX_2, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_SEC_TDM_RX_2},
- { AFE_PORT_ID_SECONDARY_TDM_TX_2, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_SECONDARY_TDM_TX_2, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_SEC_TDM_TX_2},
- { AFE_PORT_ID_SECONDARY_TDM_RX_3, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_SECONDARY_TDM_RX_3, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_SEC_TDM_RX_3},
- { AFE_PORT_ID_SECONDARY_TDM_TX_3, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_SECONDARY_TDM_TX_3, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_SEC_TDM_TX_3},
- { AFE_PORT_ID_SECONDARY_TDM_RX_4, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_SECONDARY_TDM_RX_4, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_SEC_TDM_RX_4},
- { AFE_PORT_ID_SECONDARY_TDM_TX_4, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_SECONDARY_TDM_TX_4, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_SEC_TDM_TX_4},
- { AFE_PORT_ID_SECONDARY_TDM_RX_5, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_SECONDARY_TDM_RX_5, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_SEC_TDM_RX_5},
- { AFE_PORT_ID_SECONDARY_TDM_TX_5, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_SECONDARY_TDM_TX_5, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_SEC_TDM_TX_5},
- { AFE_PORT_ID_SECONDARY_TDM_RX_6, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_SECONDARY_TDM_RX_6, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_SEC_TDM_RX_6},
- { AFE_PORT_ID_SECONDARY_TDM_TX_6, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_SECONDARY_TDM_TX_6, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_SEC_TDM_TX_6},
- { AFE_PORT_ID_SECONDARY_TDM_RX_7, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_SECONDARY_TDM_RX_7, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_SEC_TDM_RX_7},
- { AFE_PORT_ID_SECONDARY_TDM_TX_7, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_SECONDARY_TDM_TX_7, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_SEC_TDM_TX_7},
- { AFE_PORT_ID_TERTIARY_TDM_RX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_TERTIARY_TDM_RX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_TERT_TDM_RX_0},
- { AFE_PORT_ID_TERTIARY_TDM_TX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_TERTIARY_TDM_TX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_TERT_TDM_TX_0},
- { AFE_PORT_ID_TERTIARY_TDM_RX_1, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_TERTIARY_TDM_RX_1, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_TERT_TDM_RX_1},
- { AFE_PORT_ID_TERTIARY_TDM_TX_1, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_TERTIARY_TDM_TX_1, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_TERT_TDM_TX_1},
- { AFE_PORT_ID_TERTIARY_TDM_RX_2, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_TERTIARY_TDM_RX_2, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_TERT_TDM_RX_2},
- { AFE_PORT_ID_TERTIARY_TDM_TX_2, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_TERTIARY_TDM_TX_2, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_TERT_TDM_TX_2},
- { AFE_PORT_ID_TERTIARY_TDM_RX_3, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_TERTIARY_TDM_RX_3, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_TERT_TDM_RX_3},
- { AFE_PORT_ID_TERTIARY_TDM_TX_3, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_TERTIARY_TDM_TX_3, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_TERT_TDM_TX_3},
- { AFE_PORT_ID_TERTIARY_TDM_RX_4, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_TERTIARY_TDM_RX_4, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_TERT_TDM_RX_4},
- { AFE_PORT_ID_TERTIARY_TDM_TX_4, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_TERTIARY_TDM_TX_4, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_TERT_TDM_TX_4},
- { AFE_PORT_ID_TERTIARY_TDM_RX_5, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_TERTIARY_TDM_RX_5, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_TERT_TDM_RX_5},
- { AFE_PORT_ID_TERTIARY_TDM_TX_5, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_TERTIARY_TDM_TX_5, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_TERT_TDM_TX_5},
- { AFE_PORT_ID_TERTIARY_TDM_RX_6, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_TERTIARY_TDM_RX_6, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_TERT_TDM_RX_6},
- { AFE_PORT_ID_TERTIARY_TDM_TX_6, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_TERTIARY_TDM_TX_6, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_TERT_TDM_TX_6},
- { AFE_PORT_ID_TERTIARY_TDM_RX_7, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_TERTIARY_TDM_RX_7, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_TERT_TDM_RX_7},
- { AFE_PORT_ID_TERTIARY_TDM_TX_7, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_TERTIARY_TDM_TX_7, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_TERT_TDM_TX_7},
- { AFE_PORT_ID_QUATERNARY_TDM_RX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_QUATERNARY_TDM_RX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_QUAT_TDM_RX_0},
- { AFE_PORT_ID_QUATERNARY_TDM_TX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_QUATERNARY_TDM_TX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_QUAT_TDM_TX_0},
- { AFE_PORT_ID_QUATERNARY_TDM_RX_1, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_QUATERNARY_TDM_RX_1, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_QUAT_TDM_RX_1},
- { AFE_PORT_ID_QUATERNARY_TDM_TX_1, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_QUATERNARY_TDM_TX_1, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_QUAT_TDM_TX_1},
- { AFE_PORT_ID_QUATERNARY_TDM_RX_2, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_QUATERNARY_TDM_RX_2, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_QUAT_TDM_RX_2},
- { AFE_PORT_ID_QUATERNARY_TDM_TX_2, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_QUATERNARY_TDM_TX_2, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_QUAT_TDM_TX_2},
- { AFE_PORT_ID_QUATERNARY_TDM_RX_3, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_QUATERNARY_TDM_RX_3, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_QUAT_TDM_RX_3},
- { AFE_PORT_ID_QUATERNARY_TDM_TX_3, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_QUATERNARY_TDM_TX_3, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_QUAT_TDM_TX_3},
- { AFE_PORT_ID_QUATERNARY_TDM_RX_4, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_QUATERNARY_TDM_RX_4, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_QUAT_TDM_RX_4},
- { AFE_PORT_ID_QUATERNARY_TDM_TX_4, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_QUATERNARY_TDM_TX_4, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_QUAT_TDM_TX_4},
- { AFE_PORT_ID_QUATERNARY_TDM_RX_5, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_QUATERNARY_TDM_RX_5, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_QUAT_TDM_RX_5},
- { AFE_PORT_ID_QUATERNARY_TDM_TX_5, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_QUATERNARY_TDM_TX_5, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_QUAT_TDM_TX_5},
- { AFE_PORT_ID_QUATERNARY_TDM_RX_6, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_QUATERNARY_TDM_RX_6, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_QUAT_TDM_RX_6},
- { AFE_PORT_ID_QUATERNARY_TDM_TX_6, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_QUATERNARY_TDM_TX_6, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_QUAT_TDM_TX_6},
- { AFE_PORT_ID_QUATERNARY_TDM_RX_7, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_QUATERNARY_TDM_RX_7, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_QUAT_TDM_RX_7},
- { AFE_PORT_ID_QUATERNARY_TDM_TX_7, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_QUATERNARY_TDM_TX_7, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_QUAT_TDM_TX_7},
- { AFE_PORT_ID_QUINARY_TDM_RX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_QUINARY_TDM_RX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_QUIN_TDM_RX_0},
- { AFE_PORT_ID_QUINARY_TDM_TX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_QUINARY_TDM_TX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_QUIN_TDM_TX_0},
- { AFE_PORT_ID_QUINARY_TDM_RX_1, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_QUINARY_TDM_RX_1, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_QUIN_TDM_RX_1},
- { AFE_PORT_ID_QUINARY_TDM_TX_1, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_QUINARY_TDM_TX_1, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_QUIN_TDM_TX_1},
- { AFE_PORT_ID_QUINARY_TDM_RX_2, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_QUINARY_TDM_RX_2, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_QUIN_TDM_RX_2},
- { AFE_PORT_ID_QUINARY_TDM_TX_2, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_QUINARY_TDM_TX_2, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_QUIN_TDM_TX_2},
- { AFE_PORT_ID_QUINARY_TDM_RX_3, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_QUINARY_TDM_RX_3, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_QUIN_TDM_RX_3},
- { AFE_PORT_ID_QUINARY_TDM_TX_3, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_QUINARY_TDM_TX_3, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_QUIN_TDM_TX_3},
- { AFE_PORT_ID_QUINARY_TDM_RX_4, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_QUINARY_TDM_RX_4, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_QUIN_TDM_RX_4},
- { AFE_PORT_ID_QUINARY_TDM_TX_4, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_QUINARY_TDM_TX_4, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_QUIN_TDM_TX_4},
- { AFE_PORT_ID_QUINARY_TDM_RX_5, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_QUINARY_TDM_RX_5, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_QUIN_TDM_RX_5},
- { AFE_PORT_ID_QUINARY_TDM_TX_5, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_QUINARY_TDM_TX_5, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_QUIN_TDM_TX_5},
- { AFE_PORT_ID_QUINARY_TDM_RX_6, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_QUINARY_TDM_RX_6, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_QUIN_TDM_RX_6},
- { AFE_PORT_ID_QUINARY_TDM_TX_6, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_QUINARY_TDM_TX_6, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_QUIN_TDM_TX_6},
- { AFE_PORT_ID_QUINARY_TDM_RX_7, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_QUINARY_TDM_RX_7, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_QUIN_TDM_RX_7},
- { AFE_PORT_ID_QUINARY_TDM_TX_7, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_QUINARY_TDM_TX_7, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_QUIN_TDM_TX_7},
- { INT_BT_A2DP_RX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { INT_BT_A2DP_RX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_INT_BT_A2DP_RX},
- { AFE_PORT_ID_USB_RX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_USB_RX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_USB_AUDIO_RX},
- { AFE_PORT_ID_USB_TX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_USB_TX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_USB_AUDIO_TX},
- { DISPLAY_PORT_RX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { DISPLAY_PORT_RX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_DISPLAY_PORT},
- { DISPLAY_PORT_RX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { DISPLAY_PORT_RX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_DISPLAY_PORT1},
- { AFE_PORT_ID_TERTIARY_PCM_RX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_TERTIARY_PCM_RX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_TERT_AUXPCM_RX},
- { AFE_PORT_ID_TERTIARY_PCM_TX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_TERTIARY_PCM_TX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_TERT_AUXPCM_TX},
- { AFE_PORT_ID_QUATERNARY_PCM_RX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_QUATERNARY_PCM_RX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_QUAT_AUXPCM_RX},
- { AFE_PORT_ID_QUATERNARY_PCM_TX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_QUATERNARY_PCM_TX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_QUAT_AUXPCM_TX},
- { AFE_PORT_ID_QUINARY_PCM_RX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_QUINARY_PCM_RX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_QUIN_AUXPCM_RX},
- { AFE_PORT_ID_QUINARY_PCM_TX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_QUINARY_PCM_TX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_QUIN_AUXPCM_TX},
- { AFE_PORT_ID_INT0_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_INT0_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_INT0_MI2S_RX},
- { AFE_PORT_ID_INT0_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_INT0_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_INT0_MI2S_TX},
- { AFE_PORT_ID_INT1_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_INT1_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_INT1_MI2S_RX},
- { AFE_PORT_ID_INT1_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_INT1_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_INT1_MI2S_TX},
- { AFE_PORT_ID_INT2_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_INT2_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_INT2_MI2S_RX},
- { AFE_PORT_ID_INT2_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_INT2_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_INT2_MI2S_TX},
- { AFE_PORT_ID_INT3_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_INT3_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_INT3_MI2S_RX},
- { AFE_PORT_ID_INT3_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_INT3_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_INT3_MI2S_TX},
- { AFE_PORT_ID_INT4_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_INT4_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_INT4_MI2S_RX},
- { AFE_PORT_ID_INT4_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_INT4_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_INT4_MI2S_TX},
- { AFE_PORT_ID_INT5_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_INT5_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_INT5_MI2S_RX},
- { AFE_PORT_ID_INT5_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_INT5_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_INT5_MI2S_TX},
- { AFE_PORT_ID_INT6_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_INT6_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_INT6_MI2S_RX},
- { AFE_PORT_ID_INT6_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_INT6_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_INT6_MI2S_TX},
- { AFE_PORT_ID_WSA_CODEC_DMA_RX_0, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_WSA_CODEC_DMA_RX_0, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_WSA_CDC_DMA_RX_0},
- { AFE_PORT_ID_WSA_CODEC_DMA_TX_0, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_WSA_CODEC_DMA_TX_0, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_WSA_CDC_DMA_TX_0},
- { AFE_PORT_ID_WSA_CODEC_DMA_RX_1, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_WSA_CODEC_DMA_RX_1, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_WSA_CDC_DMA_RX_1},
- { AFE_PORT_ID_WSA_CODEC_DMA_TX_1, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_WSA_CODEC_DMA_TX_1, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_WSA_CDC_DMA_TX_1},
- { AFE_PORT_ID_WSA_CODEC_DMA_TX_2, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_WSA_CODEC_DMA_TX_2, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_WSA_CDC_DMA_TX_2},
- { AFE_PORT_ID_VA_CODEC_DMA_TX_0, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_VA_CODEC_DMA_TX_0, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_VA_CDC_DMA_TX_0},
- { AFE_PORT_ID_VA_CODEC_DMA_TX_1, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_VA_CODEC_DMA_TX_1, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_VA_CDC_DMA_TX_1},
- { AFE_PORT_ID_RX_CODEC_DMA_RX_0, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_RX_CODEC_DMA_RX_0, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_RX_CDC_DMA_RX_0},
- { AFE_PORT_ID_TX_CODEC_DMA_TX_0, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_TX_CODEC_DMA_TX_0, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_TX_CDC_DMA_TX_0},
- { AFE_PORT_ID_RX_CODEC_DMA_RX_1, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_RX_CODEC_DMA_RX_1, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_RX_CDC_DMA_RX_1},
- { AFE_PORT_ID_TX_CODEC_DMA_TX_1, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_TX_CODEC_DMA_TX_1, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_TX_CDC_DMA_TX_1},
- { AFE_PORT_ID_RX_CODEC_DMA_RX_2, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_RX_CODEC_DMA_RX_2, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_RX_CDC_DMA_RX_2},
- { AFE_PORT_ID_TX_CODEC_DMA_TX_2, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_TX_CODEC_DMA_TX_2, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_TX_CDC_DMA_TX_2},
- { AFE_PORT_ID_RX_CODEC_DMA_RX_3, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_RX_CODEC_DMA_RX_3, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_RX_CDC_DMA_RX_3},
- { AFE_PORT_ID_TX_CODEC_DMA_TX_3, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_TX_CODEC_DMA_TX_3, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_TX_CDC_DMA_TX_3},
- { AFE_PORT_ID_RX_CODEC_DMA_RX_4, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_RX_CODEC_DMA_RX_4, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_RX_CDC_DMA_RX_4},
- { AFE_PORT_ID_TX_CODEC_DMA_TX_4, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_TX_CODEC_DMA_TX_4, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_TX_CDC_DMA_TX_4},
- { AFE_PORT_ID_RX_CODEC_DMA_RX_5, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_RX_CODEC_DMA_RX_5, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_RX_CDC_DMA_RX_5},
- { AFE_PORT_ID_TX_CODEC_DMA_TX_5, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_TX_CODEC_DMA_TX_5, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_TX_CDC_DMA_TX_5},
- { AFE_PORT_ID_RX_CODEC_DMA_RX_6, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_RX_CODEC_DMA_RX_6, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_RX_CDC_DMA_RX_6},
- { AFE_PORT_ID_RX_CODEC_DMA_RX_7, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_RX_CODEC_DMA_RX_7, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_RX_CDC_DMA_RX_7},
- { AFE_PORT_ID_PRIMARY_SPDIF_TX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_PRIMARY_SPDIF_TX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_PRI_SPDIF_TX},
- { AFE_PORT_ID_SECONDARY_SPDIF_RX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_SECONDARY_SPDIF_RX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_SEC_SPDIF_RX},
- { AFE_PORT_ID_SECONDARY_SPDIF_TX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ { AFE_PORT_ID_SECONDARY_SPDIF_TX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_SEC_SPDIF_TX},
};
@@ -646,128 +646,128 @@
static struct msm_pcm_routing_fdai_data
fe_dai_map[MSM_FRONTEND_DAI_MAX][2] = {
/* MULTIMEDIA1 */
- {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
- {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM},
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} },
/* MULTIMEDIA2 */
- {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
- {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM},
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} },
/* MULTIMEDIA3 */
- {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
- {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM},
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} },
/* MULTIMEDIA4 */
- {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
- {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM},
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} },
/* MULTIMEDIA5 */
- {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
- {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM},
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} },
/* MULTIMEDIA6 */
- {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
- {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM},
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} },
/* MULTIMEDIA7*/
- {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
- {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM},
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} },
/* MULTIMEDIA8 */
- {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
- {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM},
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} },
/* MULTIMEDIA9 */
- {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
- {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM},
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} },
/* MULTIMEDIA10 */
- {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
- {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM},
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} },
/* MULTIMEDIA11 */
- {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
- {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM},
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} },
/* MULTIMEDIA12 */
- {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
- {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM},
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} },
/* MULTIMEDIA13 */
- {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
- {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM},
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} },
/* MULTIMEDIA14 */
- {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
- {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM},
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} },
/* MULTIMEDIA15 */
- {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
- {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM},
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} },
/* MULTIMEDIA16 */
- {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
- {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM},
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} },
/* MULTIMEDIA17 */
- {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
- {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM},
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} },
/* MULTIMEDIA18 */
- {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
- {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM},
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} },
/* MULTIMEDIA19 */
- {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
- {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM},
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} },
/* MULTIMEDIA20 */
- {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
- {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM},
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} },
/* MULTIMEDIA21 */
- {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
- {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM},
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} },
/* MULTIMEDIA28 */
- {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
- {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM},
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} },
/* MULTIMEDIA29 */
- {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
- {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM},
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} },
/* VOIP */
- {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
- {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM},
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} },
/* AFE_RX */
- {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
- {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM},
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} },
/* AFE_TX */
- {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
- {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM},
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} },
/* VOICE_STUB */
- {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
- {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM},
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} },
/* DTMF_RX */
- {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
- {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM},
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} },
/* QCHAT */
- {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
- {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM},
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} },
/* VOLTE_STUB */
- {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
- {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM},
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} },
/* LSM1 */
- {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
- {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM},
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} },
/* LSM2 */
- {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
- {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM},
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} },
/* LSM3 */
- {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
- {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM},
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} },
/* LSM4 */
- {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
- {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM},
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} },
/* LSM5 */
- {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
- {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM},
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} },
/* LSM6 */
- {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
- {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM},
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} },
/* LSM7 */
- {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
- {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM},
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} },
/* LSM8 */
- {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
- {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM},
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} },
/* VOICE2_STUB */
- {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
- {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM},
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} },
/* VOICEMMODE1 */
- {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
- {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM},
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} },
/* VOICEMMODE2 */
- {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
- {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM},
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} },
};
static unsigned long session_copp_map[MSM_FRONTEND_DAI_MAX][2]
@@ -1293,12 +1293,6 @@
return -EINVAL;
}
- if (!route_check_fe_id_adm_support(fe_id)) {
- /* ignore adm open if not supported for fe_id */
- pr_debug("%s: No ADM support for fe id %d\n", __func__, fe_id);
- return 0;
- }
-
if (stream_type == SNDRV_PCM_STREAM_PLAYBACK) {
session_type = SESSION_TYPE_RX;
if (passthr_mode != LEGACY_PCM)
@@ -1322,14 +1316,20 @@
(fe_id <= MSM_FRONTEND_DAI_LSM8);
mutex_lock(&routing_lock);
- payload.num_copps = 0; /* only RX needs to use payload */
fe_dai_map[fe_id][session_type].strm_id = dspst_id;
+ fe_dai_map[fe_id][session_type].perf_mode = perf_mode;
+ fe_dai_map[fe_id][session_type].passthr_mode = passthr_mode;
+ if (!route_check_fe_id_adm_support(fe_id)) {
+ /* ignore adm open if not supported for fe_id */
+ pr_debug("%s: No ADM support for fe id %d\n", __func__, fe_id);
+ mutex_unlock(&routing_lock);
+ return 0;
+ }
+
+ payload.num_copps = 0; /* only RX needs to use payload */
/* re-enable EQ if active */
msm_qti_pp_send_eq_values(fe_id);
for (i = 0; i < MSM_BACKEND_DAI_MAX; i++) {
- if (test_bit(fe_id, &msm_bedais[i].fe_sessions[0]))
- msm_bedais[i].passthr_mode[fe_id] = passthr_mode;
-
if (!is_be_dai_extproc(i) &&
(afe_get_port_type(msm_bedais[i].port_id) ==
port_type) &&
@@ -1431,8 +1431,7 @@
}
if (passthr_mode != COMPRESSED_PASSTHROUGH_DSD
&& passthr_mode != COMPRESSED_PASSTHROUGH_GEN
- && passthr_mode !=
- COMPRESSED_PASSTHROUGH_IEC61937)
+ && passthr_mode != COMPRESSED_PASSTHROUGH_IEC61937)
msm_routing_send_device_pp_params(
msm_bedais[i].port_id,
copp_idx, fe_id);
@@ -1560,6 +1559,7 @@
payload.num_copps = 0; /* only RX needs to use payload */
fe_dai_map[fedai_id][session_type].strm_id = dspst_id;
fe_dai_map[fedai_id][session_type].perf_mode = perf_mode;
+ fe_dai_map[fedai_id][session_type].passthr_mode = LEGACY_PCM;
/* re-enable EQ if active */
msm_qti_pp_send_eq_values(fedai_id);
@@ -1577,8 +1577,6 @@
channels = msm_bedais[i].channel;
else
channels = msm_bedais[i].adm_override_ch;
- msm_bedais[i].passthr_mode[fedai_id] =
- LEGACY_PCM;
bits_per_sample = msm_routing_get_bit_width(
msm_bedais[i].format);
@@ -1647,12 +1645,9 @@
num_copps++;
}
}
- if ((perf_mode == LEGACY_PCM_MODE) &&
- (msm_bedais[i].passthr_mode[fedai_id] ==
- LEGACY_PCM))
+ if (perf_mode == LEGACY_PCM_MODE)
msm_pcm_routing_cfg_pp(msm_bedais[i].port_id,
- copp_idx, topology,
- channels);
+ copp_idx, topology, channels);
}
}
if (num_copps) {
@@ -1737,8 +1732,7 @@
if ((topology == DOLBY_ADM_COPP_TOPOLOGY_ID ||
topology == DS2_ADM_COPP_TOPOLOGY_ID) &&
(fdai->perf_mode == LEGACY_PCM_MODE) &&
- (msm_bedais[i].passthr_mode[fedai_id] ==
- LEGACY_PCM))
+ (fdai->passthr_mode == LEGACY_PCM))
msm_pcm_routing_deinit_pp(msm_bedais[i].port_id,
topology);
}
@@ -1789,16 +1783,17 @@
return;
}
- passthr_mode = msm_bedais[reg].passthr_mode[val];
- if (afe_get_port_type(msm_bedais[reg].port_id) ==
- MSM_AFE_PORT_TYPE_RX) {
- session_type = SESSION_TYPE_RX;
+ session_type =
+ (afe_get_port_type(msm_bedais[reg].port_id) == MSM_AFE_PORT_TYPE_RX) ?
+ SESSION_TYPE_RX : SESSION_TYPE_TX;
+ fdai = &fe_dai_map[val][session_type];
+ passthr_mode = fdai->passthr_mode;
+ if (session_type == SESSION_TYPE_RX) {
if (passthr_mode != LEGACY_PCM)
path_type = ADM_PATH_COMPRESSED_RX;
else
path_type = ADM_PATH_PLAYBACK;
} else {
- session_type = SESSION_TYPE_TX;
if ((passthr_mode != LEGACY_PCM) && (passthr_mode != LISTEN))
path_type = ADM_PATH_COMPRESSED_TX;
else
@@ -1815,7 +1810,6 @@
voc_start_playback(set, msm_bedais[reg].port_id);
set_bit(val, &msm_bedais[reg].fe_sessions[0]);
- fdai = &fe_dai_map[val][session_type];
if (msm_bedais[reg].active && fdai->strm_id !=
INVALID_SESSION) {
int app_type, app_type_idx, copp_idx, acdb_dev_id;
@@ -1913,7 +1907,6 @@
(msm_bedais[reg].port_id == VOICE2_PLAYBACK_TX)))
voc_start_playback(set, msm_bedais[reg].port_id);
clear_bit(val, &msm_bedais[reg].fe_sessions[0]);
- fdai = &fe_dai_map[val][session_type];
if (msm_bedais[reg].active && fdai->strm_id !=
INVALID_SESSION) {
int idx;
@@ -22405,7 +22398,7 @@
clear_bit(idx,
&session_copp_map[i][session_type][be_id]);
if ((fdai->perf_mode == LEGACY_PCM_MODE) &&
- (bedai->passthr_mode[i] == LEGACY_PCM))
+ (fdai->passthr_mode == LEGACY_PCM))
msm_pcm_routing_deinit_pp(bedai->port_id,
topology);
}
@@ -22414,10 +22407,6 @@
bedai->active = 0;
bedai->sample_rate = 0;
bedai->channel = 0;
- for (i = 0; i < MSM_FRONTEND_DAI_MAX; i++) {
- if (bedai->passthr_mode[i] != LISTEN)
- bedai->passthr_mode[i] = LEGACY_PCM;
- }
mutex_unlock(&routing_lock);
return 0;
@@ -22463,24 +22452,24 @@
route_check_fe_id_adm_support(i)))
continue;
+ session_type = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
+ SESSION_TYPE_RX : SESSION_TYPE_TX;
+ fdai = &fe_dai_map[i][session_type];
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- if (bedai->passthr_mode[i] != LEGACY_PCM)
+ if (fdai->passthr_mode != LEGACY_PCM)
path_type = ADM_PATH_COMPRESSED_RX;
else
path_type = ADM_PATH_PLAYBACK;
- session_type = SESSION_TYPE_RX;
} else {
- if ((bedai->passthr_mode[i] != LEGACY_PCM) &&
- (bedai->passthr_mode[i] != LISTEN))
+ if ((fdai->passthr_mode != LEGACY_PCM) &&
+ (fdai->passthr_mode != LISTEN))
path_type = ADM_PATH_COMPRESSED_TX;
else
path_type = ADM_PATH_LIVE_REC;
- session_type = SESSION_TYPE_TX;
}
is_lsm = (i >= MSM_FRONTEND_DAI_LSM1) &&
(i <= MSM_FRONTEND_DAI_LSM8);
- fdai = &fe_dai_map[i][session_type];
if (fdai->strm_id != INVALID_SESSION) {
int app_type, app_type_idx, copp_idx, acdb_dev_id;
@@ -22533,12 +22522,9 @@
topology = msm_routing_get_adm_topology(i, session_type,
be_id);
- if ((bedai->passthr_mode[i] ==
- COMPRESSED_PASSTHROUGH_DSD)
- || (bedai->passthr_mode[i] ==
- COMPRESSED_PASSTHROUGH_GEN)
- || (bedai->passthr_mode[i] ==
- COMPRESSED_PASSTHROUGH_IEC61937))
+ if ((fdai->passthr_mode == COMPRESSED_PASSTHROUGH_DSD)
+ || (fdai->passthr_mode == COMPRESSED_PASSTHROUGH_GEN)
+ || (fdai->passthr_mode == COMPRESSED_PASSTHROUGH_IEC61937))
topology = COMPRESSED_PASSTHROUGH_NONE_TOPOLOGY;
copp_idx = adm_open(bedai->port_id, path_type,
@@ -22564,10 +22550,9 @@
bedai->sample_rate);
msm_pcm_routing_build_matrix(i, session_type, path_type,
- fdai->perf_mode,
- bedai->passthr_mode[i]);
+ fdai->perf_mode, fdai->passthr_mode);
if ((fdai->perf_mode == LEGACY_PCM_MODE) &&
- (bedai->passthr_mode[i] == LEGACY_PCM))
+ (fdai->passthr_mode == LEGACY_PCM))
msm_pcm_routing_cfg_pp(bedai->port_id, copp_idx,
topology, channels);
}
@@ -22638,7 +22623,7 @@
int index, topo_id, be_idx;
unsigned long pp_config = 0;
bool mute_on;
- int latency;
+ int latency, session_type;
bool compr_passthr_mode = true;
pr_debug("%s: port_id %d, copp_idx %d\n", __func__, port_id, copp_idx);
@@ -22676,8 +22661,12 @@
return -EINVAL;
}
- if ((msm_bedais[be_idx].passthr_mode[fe_id] == LEGACY_PCM) ||
- (msm_bedais[be_idx].passthr_mode[fe_id] == LISTEN))
+ session_type =
+ (afe_get_port_type(port_id) == MSM_AFE_PORT_TYPE_RX) ?
+ SESSION_TYPE_RX : SESSION_TYPE_TX;
+
+ if ((fe_dai_map[fe_id][session_type].passthr_mode == LEGACY_PCM) ||
+ (fe_dai_map[fe_id][session_type].passthr_mode == LISTEN))
compr_passthr_mode = false;
pp_config = msm_bedais_pp_params[index].pp_params_config;
@@ -22764,7 +22753,7 @@
int port_id = 0;
int index, be_idx, i, topo_id, idx;
bool mute;
- int latency;
+ int latency, session_type;
bool compr_passthr_mode = true;
pr_debug("%s: pp_id: 0x%x\n", __func__, pp_id);
@@ -22790,10 +22779,14 @@
return -EINVAL;
}
+ session_type =
+ (afe_get_port_type(port_id) == MSM_AFE_PORT_TYPE_RX) ?
+ SESSION_TYPE_RX : SESSION_TYPE_TX;
+
for_each_set_bit(i, &msm_bedais[be_idx].fe_sessions[0],
MSM_FRONTEND_DAI_MM_SIZE) {
- if ((msm_bedais[be_idx].passthr_mode[i] == LEGACY_PCM) ||
- (msm_bedais[be_idx].passthr_mode[i] == LISTEN))
+ if ((fe_dai_map[i][session_type].passthr_mode == LEGACY_PCM) ||
+ (fe_dai_map[i][session_type].passthr_mode == LISTEN))
compr_passthr_mode = false;
for (idx = 0; idx < MAX_COPPS_PER_PORT; idx++) {
@@ -22808,7 +22801,7 @@
continue;
pr_debug("%s: port: 0x%x, copp %ld, be active: %d, passt: %d\n",
__func__, port_id, copp, msm_bedais[be_idx].active,
- msm_bedais[be_idx].passthr_mode[i]);
+ fe_dai_map[i][session_type].passthr_mode);
switch (pp_id) {
case ADM_PP_PARAM_MUTE_ID:
pr_debug("%s: ADM_PP_PARAM_MUTE\n", __func__);
diff --git a/asoc/msm-pcm-routing-v2.h b/asoc/msm-pcm-routing-v2.h
index b4ff50f..26a5428 100644
--- a/asoc/msm-pcm-routing-v2.h
+++ b/asoc/msm-pcm-routing-v2.h
@@ -523,7 +523,6 @@
unsigned int channel;
unsigned int format;
unsigned int adm_override_ch;
- u32 passthr_mode[MSM_FRONTEND_DAI_MAX];
char *name;
};
@@ -532,6 +531,7 @@
int strm_id; /* ASM stream ID */
int perf_mode;
struct msm_pcm_routing_evt event_info;
+ u32 passthr_mode;
};
#define MAX_APP_TYPES 16
diff --git a/asoc/sm6150.c b/asoc/sm6150.c
index 0128d52..1849605 100644
--- a/asoc/sm6150.c
+++ b/asoc/sm6150.c
@@ -28,7 +28,7 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/info.h>
-#include <dsp/audio_notifier.h>
+#include <soc/snd_event.h>
#include <dsp/q6afe-v2.h>
#include <dsp/q6core.h>
#include "device_event.h"
@@ -201,6 +201,7 @@
struct pinctrl *usbc_en2_gpio_p; /* used by pinctrl API */
struct device_node *hph_en1_gpio_p; /* used by pinctrl API */
struct device_node *hph_en0_gpio_p; /* used by pinctrl API */
+ bool is_afe_config_done;
};
struct msm_asoc_wcd93xx_codec {
@@ -628,10 +629,7 @@
static SOC_ENUM_SINGLE_EXT_DECL(tx_cdc_dma_tx_4_sample_rate,
cdc_dma_sample_rate_text);
-static struct platform_device *spdev;
-
static int msm_hifi_control;
-static bool is_initial_boot;
static bool codec_reg_done;
static struct snd_soc_aux_dev *msm_aux_dev;
static struct snd_soc_codec_conf *msm_codec_conf;
@@ -1250,8 +1248,10 @@
{
int ch_num = cdc_dma_get_port_idx(kcontrol);
- if (ch_num < 0)
+ if (ch_num < 0) {
+ pr_err("%s: ch_num: %d is invalid\n", __func__, ch_num);
return ch_num;
+ }
pr_debug("%s: cdc_dma_rx_ch = %d\n", __func__,
cdc_dma_rx_cfg[ch_num].channels - 1);
@@ -1264,8 +1264,10 @@
{
int ch_num = cdc_dma_get_port_idx(kcontrol);
- if (ch_num < 0)
+ if (ch_num < 0) {
+ pr_err("%s: ch_num: %d is invalid\n", __func__, ch_num);
return ch_num;
+ }
cdc_dma_rx_cfg[ch_num].channels = ucontrol->value.integer.value[0] + 1;
@@ -1279,6 +1281,11 @@
{
int ch_num = cdc_dma_get_port_idx(kcontrol);
+ if (ch_num < 0) {
+ pr_err("%s: ch_num: %d is invalid\n", __func__, ch_num);
+ return ch_num;
+ }
+
switch (cdc_dma_rx_cfg[ch_num].bit_format) {
case SNDRV_PCM_FORMAT_S32_LE:
ucontrol->value.integer.value[0] = 3;
@@ -1307,6 +1314,11 @@
int rc = 0;
int ch_num = cdc_dma_get_port_idx(kcontrol);
+ if (ch_num < 0) {
+ pr_err("%s: ch_num: %d is invalid\n", __func__, ch_num);
+ return ch_num;
+ }
+
switch (ucontrol->value.integer.value[0]) {
case 3:
cdc_dma_rx_cfg[ch_num].bit_format = SNDRV_PCM_FORMAT_S32_LE;
@@ -1437,8 +1449,10 @@
{
int ch_num = cdc_dma_get_port_idx(kcontrol);
- if (ch_num < 0)
+ if (ch_num < 0) {
+ pr_err("%s: ch_num: %d is invalid\n", __func__, ch_num);
return ch_num;
+ }
ucontrol->value.enumerated.item[0] =
cdc_dma_get_sample_rate_val(cdc_dma_rx_cfg[ch_num].sample_rate);
@@ -1453,8 +1467,10 @@
{
int ch_num = cdc_dma_get_port_idx(kcontrol);
- if (ch_num < 0)
+ if (ch_num < 0) {
+ pr_err("%s: ch_num: %d is invalid\n", __func__, ch_num);
return ch_num;
+ }
cdc_dma_rx_cfg[ch_num].sample_rate =
cdc_dma_get_sample_rate(ucontrol->value.enumerated.item[0]);
@@ -1471,6 +1487,11 @@
{
int ch_num = cdc_dma_get_port_idx(kcontrol);
+ if (ch_num < 0) {
+ pr_err("%s: ch_num: %d is invalid\n", __func__, ch_num);
+ return ch_num;
+ }
+
pr_debug("%s: cdc_dma_tx_ch = %d\n", __func__,
cdc_dma_tx_cfg[ch_num].channels);
ucontrol->value.integer.value[0] = cdc_dma_tx_cfg[ch_num].channels - 1;
@@ -1482,6 +1503,11 @@
{
int ch_num = cdc_dma_get_port_idx(kcontrol);
+ if (ch_num < 0) {
+ pr_err("%s: ch_num: %d is invalid\n", __func__, ch_num);
+ return ch_num;
+ }
+
cdc_dma_tx_cfg[ch_num].channels = ucontrol->value.integer.value[0] + 1;
pr_debug("%s: cdc_dma_tx_ch = %d\n", __func__,
@@ -1495,6 +1521,11 @@
int sample_rate_val;
int ch_num = cdc_dma_get_port_idx(kcontrol);
+ if (ch_num < 0) {
+ pr_err("%s: ch_num: %d is invalid\n", __func__, ch_num);
+ return ch_num;
+ }
+
switch (cdc_dma_tx_cfg[ch_num].sample_rate) {
case SAMPLING_RATE_384KHZ:
sample_rate_val = 12;
@@ -1551,6 +1582,11 @@
{
int ch_num = cdc_dma_get_port_idx(kcontrol);
+ if (ch_num < 0) {
+ pr_err("%s: ch_num: %d is invalid\n", __func__, ch_num);
+ return ch_num;
+ }
+
switch (ucontrol->value.integer.value[0]) {
case 12:
cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_384KHZ;
@@ -1607,6 +1643,11 @@
{
int ch_num = cdc_dma_get_port_idx(kcontrol);
+ if (ch_num < 0) {
+ pr_err("%s: ch_num: %d is invalid\n", __func__, ch_num);
+ return ch_num;
+ }
+
switch (cdc_dma_tx_cfg[ch_num].bit_format) {
case SNDRV_PCM_FORMAT_S32_LE:
ucontrol->value.integer.value[0] = 3;
@@ -1635,6 +1676,11 @@
int rc = 0;
int ch_num = cdc_dma_get_port_idx(kcontrol);
+ if (ch_num < 0) {
+ pr_err("%s: ch_num: %d is invalid\n", __func__, ch_num);
+ return ch_num;
+ }
+
switch (ucontrol->value.integer.value[0]) {
case 3:
cdc_dma_tx_cfg[ch_num].bit_format = SNDRV_PCM_FORMAT_S32_LE;
@@ -4595,121 +4641,6 @@
afe_clear_config(AFE_SLIMBUS_SLAVE_CONFIG);
}
-static int msm_adsp_power_up_config(struct snd_soc_codec *codec,
- struct snd_card *card)
-{
- int ret = 0;
- unsigned long timeout;
- int adsp_ready = 0;
- bool snd_card_online = 0;
-
- timeout = jiffies +
- msecs_to_jiffies(ADSP_STATE_READY_TIMEOUT_MS);
-
- do {
- if (!snd_card_online) {
- snd_card_online = snd_card_is_online_state(card);
- pr_debug("%s: Sound card is %s\n", __func__,
- snd_card_online ? "Online" : "Offline");
- }
- if (!adsp_ready) {
- adsp_ready = q6core_is_adsp_ready();
- pr_debug("%s: ADSP Audio is %s\n", __func__,
- adsp_ready ? "ready" : "not ready");
- }
- if (snd_card_online && adsp_ready)
- break;
-
- /*
- * Sound card/ADSP will be coming up after subsystem restart and
- * it might not be fully up when the control reaches
- * here. So, wait for 50msec before checking ADSP state
- */
- msleep(50);
- } while (time_after(timeout, jiffies));
-
- if (!snd_card_online || !adsp_ready) {
- pr_err("%s: Timeout. Sound card is %s, ADSP Audio is %s\n",
- __func__,
- snd_card_online ? "Online" : "Offline",
- adsp_ready ? "ready" : "not ready");
- ret = -ETIMEDOUT;
- goto err;
- }
-
- ret = msm_afe_set_config(codec);
- if (ret)
- pr_err("%s: Failed to set AFE config. err %d\n",
- __func__, ret);
-
- return 0;
-
-err:
- return ret;
-}
-
-static int sm6150_notifier_service_cb(struct notifier_block *this,
- unsigned long opcode, void *ptr)
-{
- int ret;
- struct snd_soc_card *card = NULL;
- const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX;
- struct snd_soc_pcm_runtime *rtd;
- struct snd_soc_codec *codec;
-
- pr_debug("%s: Service opcode 0x%lx\n", __func__, opcode);
-
- switch (opcode) {
- case AUDIO_NOTIFIER_SERVICE_DOWN:
- /*
- * Use flag to ignore initial boot notifications
- * On initial boot msm_adsp_power_up_config is
- * called on init. There is no need to clear
- * and set the config again on initial boot.
- */
- if (is_initial_boot)
- break;
- msm_afe_clear_config();
- break;
- case AUDIO_NOTIFIER_SERVICE_UP:
- if (is_initial_boot) {
- is_initial_boot = false;
- break;
- }
- if (!spdev)
- return -EINVAL;
-
- card = platform_get_drvdata(spdev);
- rtd = snd_soc_get_pcm_runtime(card, be_dl_name);
- if (!rtd) {
- dev_err(card->dev,
- "%s: snd_soc_get_pcm_runtime for %s failed!\n",
- __func__, be_dl_name);
- ret = -EINVAL;
- goto err;
- }
- codec = rtd->codec;
-
- ret = msm_adsp_power_up_config(codec, card->snd_card);
- if (ret < 0) {
- dev_err(card->dev,
- "%s: msm_adsp_power_up_config failed ret = %d!\n",
- __func__, ret);
- goto err;
- }
- break;
- default:
- break;
- }
-err:
- return NOTIFY_OK;
-}
-
-static struct notifier_block service_nb = {
- .notifier_call = sm6150_notifier_service_cb,
- .priority = -INT_MAX,
-};
-
static int msm_audrx_tavil_init(struct snd_soc_pcm_runtime *rtd)
{
int ret = 0;
@@ -4797,11 +4728,12 @@
msm_codec_fn.get_afe_config_fn = tavil_get_afe_config;
- ret = msm_adsp_power_up_config(codec, rtd->card->snd_card);
+ ret = msm_afe_set_config(codec);
if (ret) {
pr_err("%s: Failed to set AFE config %d\n", __func__, ret);
goto err;
}
+ pdata->is_afe_config_done = true;
config_data = msm_codec_fn.get_afe_config_fn(codec,
AFE_AANC_VERSION);
@@ -8309,6 +8241,108 @@
mi2s_intf_conf[count].msm_is_mi2s_master = 0;
}
}
+
+static int sm6150_ssr_enable(struct device *dev, void *data)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct snd_soc_card *card = platform_get_drvdata(pdev);
+ struct msm_asoc_mach_data *pdata;
+ int ret = 0;
+
+ if (!card) {
+ dev_err(dev, "%s: card is NULL\n", __func__);
+ ret = -EINVAL;
+ goto err;
+ }
+
+ if (!strcmp(card->name, "sm6150-tavil-snd-card")) {
+ pdata = snd_soc_card_get_drvdata(card);
+ if (!pdata->is_afe_config_done) {
+ const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX;
+ struct snd_soc_pcm_runtime *rtd;
+
+ rtd = snd_soc_get_pcm_runtime(card, be_dl_name);
+ if (!rtd) {
+ dev_err(dev,
+ "%s: snd_soc_get_pcm_runtime for %s failed!\n",
+ __func__, be_dl_name);
+ ret = -EINVAL;
+ goto err;
+ }
+ ret = msm_afe_set_config(rtd->codec);
+ if (ret)
+ dev_err(dev, "%s: Failed to set AFE config. err %d\n",
+ __func__, ret);
+ else
+ pdata->is_afe_config_done = true;
+ }
+ }
+ snd_soc_card_change_online_state(card, 1);
+ dev_dbg(dev, "%s: setting snd_card to ONLINE\n", __func__);
+
+err:
+ return ret;
+}
+
+static void sm6150_ssr_disable(struct device *dev, void *data)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct snd_soc_card *card = platform_get_drvdata(pdev);
+ struct msm_asoc_mach_data *pdata;
+
+ if (!card) {
+ dev_err(dev, "%s: card is NULL\n", __func__);
+ return;
+ }
+
+ dev_dbg(dev, "%s: setting snd_card to OFFLINE\n", __func__);
+ snd_soc_card_change_online_state(card, 0);
+
+ if (!strcmp(card->name, "sm6150-tavil-snd-card")) {
+ pdata = snd_soc_card_get_drvdata(card);
+ msm_afe_clear_config();
+ pdata->is_afe_config_done = false;
+ }
+}
+
+static const struct snd_event_ops sm6150_ssr_ops = {
+ .enable = sm6150_ssr_enable,
+ .disable = sm6150_ssr_disable,
+};
+
+static int msm_audio_ssr_compare(struct device *dev, void *data)
+{
+ struct device_node *node = data;
+
+ dev_dbg(dev, "%s: dev->of_node = 0x%p, node = 0x%p\n",
+ __func__, dev->of_node, node);
+ return (dev->of_node && dev->of_node == node);
+}
+
+static int msm_audio_ssr_register(struct device *dev)
+{
+ struct device_node *np = dev->of_node;
+ struct snd_event_clients *ssr_clients = NULL;
+ struct device_node *node;
+ int ret;
+ int i;
+
+ for (i = 0; ; i++) {
+ node = of_parse_phandle(np, "qcom,msm_audio_ssr_devs", i);
+ if (!node)
+ break;
+ snd_event_mstr_add_client(&ssr_clients,
+ msm_audio_ssr_compare, node);
+ }
+
+ ret = snd_event_master_register(dev, &sm6150_ssr_ops,
+ ssr_clients, NULL);
+ if (!ret)
+ snd_event_notify(dev, SND_EVENT_UP);
+
+ return ret;
+}
+
static int msm_asoc_machine_probe(struct platform_device *pdev)
{
struct snd_soc_card *card;
@@ -8371,7 +8405,6 @@
goto err;
}
dev_info(&pdev->dev, "Sound card %s registered\n", card->name);
- spdev = pdev;
pdata->hph_en1_gpio_p = of_parse_phandle(pdev->dev.of_node,
"qcom,hph-en1-gpio", 0);
@@ -8438,15 +8471,7 @@
}
msm_i2s_auxpcm_init(pdev);
- if (!strcmp(card->name, "sm6150-tavil-snd-card")) {
- is_initial_boot = true;
- ret = audio_notifier_register("sm6150",
- AUDIO_NOTIFIER_ADSP_DOMAIN,
- &service_nb);
- if (ret < 0)
- pr_err("%s: Audio notifier register failed ret = %d\n",
- __func__, ret);
- } else {
+ if (strcmp(card->name, "sm6150-tavil-snd-card")) {
pdata->dmic01_gpio_p = of_parse_phandle(pdev->dev.of_node,
"qcom,cdc-dmic01-gpios",
0);
@@ -8454,13 +8479,19 @@
"qcom,cdc-dmic23-gpios",
0);
}
+
+ ret = msm_audio_ssr_register(&pdev->dev);
+ if (ret)
+ pr_err("%s: Registration with SND event FWK failed ret = %d\n",
+ __func__, ret);
+
err:
return ret;
}
static int msm_asoc_machine_remove(struct platform_device *pdev)
{
- audio_notifier_deregister("sm6150");
+ snd_event_master_deregister(&pdev->dev);
msm_i2s_auxpcm_deinit();
return 0;
diff --git a/include/soc/swr-wcd.h b/include/soc/swr-wcd.h
index 75d0e65..8ea8616 100644
--- a/include/soc/swr-wcd.h
+++ b/include/soc/swr-wcd.h
@@ -24,6 +24,8 @@
SWR_SUBSYS_RESTART,
SWR_SET_NUM_RX_CH,
SWR_CLK_FREQ,
+ SWR_DEVICE_SSR_DOWN,
+ SWR_DEVICE_SSR_UP,
};
struct swr_mstr_port {
diff --git a/soc/pinctrl-lpi.c b/soc/pinctrl-lpi.c
index f5ba3d6..21d51fb 100644
--- a/soc/pinctrl-lpi.c
+++ b/soc/pinctrl-lpi.c
@@ -21,6 +21,7 @@
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/types.h>
+#include <soc/snd_event.h>
#include <dsp/audio_notifier.h>
#include "core.h"
@@ -59,6 +60,7 @@
#define LPI_GPIO_FUNC_FUNC5 "func5"
static bool lpi_dev_up;
+static struct device *lpi_dev;
/* The index of each function in lpi_gpio_functions[] array */
enum lpi_gpio_func_index {
@@ -384,12 +386,14 @@
initial_boot = false;
break;
}
+ snd_event_notify(lpi_dev, SND_EVENT_DOWN);
lpi_dev_up = false;
break;
case AUDIO_NOTIFIER_SERVICE_UP:
if (initial_boot)
initial_boot = false;
lpi_dev_up = true;
+ snd_event_notify(lpi_dev, SND_EVENT_UP);
break;
default:
break;
@@ -402,6 +406,15 @@
.priority = -INT_MAX,
};
+static void lpi_pinctrl_ssr_disable(struct device *dev, void *data)
+{
+ lpi_dev_up = false;
+}
+
+static const struct snd_event_ops lpi_pinctrl_ssr_ops = {
+ .disable = lpi_pinctrl_ssr_disable,
+};
+
#ifdef CONFIG_DEBUG_FS
#include <linux/seq_file.h>
@@ -576,6 +589,7 @@
goto err_range;
}
+ lpi_dev = &pdev->dev;
lpi_dev_up = true;
ret = audio_notifier_register("lpi_tlmm", AUDIO_NOTIFIER_ADSP_DOMAIN,
&service_nb);
@@ -585,8 +599,19 @@
goto err_range;
}
+ ret = snd_event_client_register(dev, &lpi_pinctrl_ssr_ops, NULL);
+ if (!ret) {
+ snd_event_notify(dev, SND_EVENT_UP);
+ } else {
+ dev_err(dev, "%s: snd_event registration failed, ret [%d]\n",
+ __func__, ret);
+ goto err_snd_evt;
+ }
+
return 0;
+err_snd_evt:
+ audio_notifier_deregister("lpi_tlmm");
err_range:
gpiochip_remove(&state->chip);
err_chip:
@@ -597,6 +622,7 @@
{
struct lpi_gpio_state *state = platform_get_drvdata(pdev);
+ snd_event_client_deregister(&pdev->dev);
audio_notifier_deregister("lpi_tlmm");
gpiochip_remove(&state->chip);
return 0;
diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c
index d3fb087..7232fe8 100644
--- a/soc/swr-mstr-ctrl.c
+++ b/soc/swr-mstr-ctrl.c
@@ -248,35 +248,47 @@
u16 reg, u32 *value)
{
u32 temp = (u32)(*value);
- int ret;
+ int ret = 0;
+
+ mutex_lock(&swrm->devlock);
+ if (!swrm->dev_up)
+ goto err;
ret = swrm_clk_request(swrm, TRUE);
-
- if (ret)
- return -EINVAL;
-
+ if (ret) {
+ dev_err_ratelimited(swrm->dev, "%s: clock request failed\n",
+ __func__);
+ goto err;
+ }
iowrite32(temp, swrm->swrm_dig_base + reg);
-
swrm_clk_request(swrm, FALSE);
-
- return 0;
+err:
+ mutex_unlock(&swrm->devlock);
+ return ret;
}
static int swrm_ahb_read(struct swr_mstr_ctrl *swrm,
u16 reg, u32 *value)
{
u32 temp = 0;
- int ret;
+ int ret = 0;
+
+ mutex_lock(&swrm->devlock);
+ if (!swrm->dev_up)
+ goto err;
ret = swrm_clk_request(swrm, TRUE);
-
- if (ret)
- return -EINVAL;
-
+ if (ret) {
+ dev_err_ratelimited(swrm->dev, "%s: clock request failed\n",
+ __func__);
+ goto err;
+ }
temp = ioread32(swrm->swrm_dig_base + reg);
*value = temp;
swrm_clk_request(swrm, FALSE);
- return 0;
+err:
+ mutex_unlock(&swrm->devlock);
+ return ret;
}
static u32 swr_master_read(struct swr_mstr_ctrl *swrm, unsigned int reg_addr)
@@ -501,6 +513,13 @@
dev_err(&master->dev, "%s: swrm is NULL\n", __func__);
return -EINVAL;
}
+ mutex_lock(&swrm->devlock);
+ if (!swrm->dev_up) {
+ mutex_unlock(&swrm->devlock);
+ return 0;
+ }
+ mutex_unlock(&swrm->devlock);
+
pm_runtime_get_sync(swrm->dev);
if (dev_num)
ret = swrm_cmd_fifo_rd_cmd(swrm, &val, dev_num, 0, reg_addr,
@@ -527,6 +546,12 @@
dev_err(&master->dev, "%s: swrm is NULL\n", __func__);
return -EINVAL;
}
+ mutex_lock(&swrm->devlock);
+ if (!swrm->dev_up) {
+ mutex_unlock(&swrm->devlock);
+ return 0;
+ }
+ mutex_unlock(&swrm->devlock);
pm_runtime_get_sync(swrm->dev);
if (dev_num)
@@ -554,6 +579,12 @@
}
if (len <= 0)
return -EINVAL;
+ mutex_lock(&swrm->devlock);
+ if (!swrm->dev_up) {
+ mutex_unlock(&swrm->devlock);
+ return 0;
+ }
+ mutex_unlock(&swrm->devlock);
pm_runtime_get_sync(swrm->dev);
if (dev_num) {
@@ -921,8 +952,6 @@
}
mutex_lock(&swrm->mlock);
- if (enable)
- pm_runtime_get_sync(swrm->dev);
bank = get_inactive_bank_num(swrm);
if (enable) {
@@ -983,6 +1012,8 @@
else {
swrm_disable_ports(master, inactive_bank);
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);
@@ -1014,6 +1045,8 @@
}
mutex_lock(&swrm->mlock);
+ if (!swrm_is_port_en(master))
+ pm_runtime_get_sync(swrm->dev);
for (i = 0; i < portinfo->num_port; i++) {
ret = swrm_get_master_port(swrm, &mstr_port_id, &mstr_ch_msk,
@@ -1639,6 +1672,7 @@
swrm->num_rx_chs = 0;
swrm->clk_ref_count = 0;
swrm->mclk_freq = MCLK_FREQ;
+ swrm->dev_up = true;
swrm->state = SWR_MSTR_RESUME;
init_completion(&swrm->reset);
init_completion(&swrm->broadcast);
@@ -1646,6 +1680,7 @@
mutex_init(&swrm->reslock);
mutex_init(&swrm->force_down_lock);
mutex_init(&swrm->iolock);
+ mutex_init(&swrm->devlock);
for (i = 0 ; i < SWR_MSTR_PORT_LEN; i++)
INIT_LIST_HEAD(&swrm->mport_cfg[i].port_req_list);
@@ -1916,11 +1951,16 @@
mutex_lock(&swrm->force_down_lock);
swrm->state = SWR_MSTR_SSR;
mutex_unlock(&swrm->force_down_lock);
- /* Use pm runtime function to tear down */
- ret = pm_runtime_put_sync_suspend(dev);
- pm_runtime_get_noresume(dev);
+ if (!pm_runtime_enabled(dev) || !pm_runtime_suspended(dev)) {
+ ret = swrm_runtime_suspend(dev);
+ if (!ret) {
+ pm_runtime_disable(dev);
+ pm_runtime_set_suspended(dev);
+ pm_runtime_enable(dev);
+ }
+ }
- return ret;
+ return 0;
}
/**
@@ -1959,6 +1999,16 @@
mutex_unlock(&swrm->mlock);
}
break;
+ case SWR_DEVICE_SSR_DOWN:
+ mutex_lock(&swrm->devlock);
+ swrm->dev_up = false;
+ mutex_unlock(&swrm->devlock);
+ break;
+ case SWR_DEVICE_SSR_UP:
+ mutex_lock(&swrm->devlock);
+ swrm->dev_up = true;
+ mutex_unlock(&swrm->devlock);
+ break;
case SWR_DEVICE_DOWN:
dev_dbg(swrm->dev, "%s: swr master down called\n", __func__);
mutex_lock(&swrm->mlock);
diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h
index b3dfd7d..8625966 100644
--- a/soc/swr-mstr-ctrl.h
+++ b/soc/swr-mstr-ctrl.h
@@ -113,6 +113,7 @@
struct completion reset;
struct completion broadcast;
struct mutex iolock;
+ struct mutex devlock;
struct mutex mlock;
struct mutex reslock;
u32 swrm_base_reg;
@@ -149,6 +150,8 @@
u32 clk_stop_mode0_supp;
struct work_struct wakeup_work;
u32 wakeup_req;
+
+ bool dev_up;
};
#endif /* _SWR_WCD_CTRL_H */