Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 497a651e authored by Laxminath Kasam's avatar Laxminath Kasam
Browse files

asoc: codecs: Add parent child relation for bolero and tanggu



In bolero and tanggu combination, make bolero parent of tanggu.
Bolero and tanggu can communicate mutually using notifier and
plat_data callback APIs.

Change-Id: Iecd119df7f0ad1ba225c0427f3f42f217146b092
Signed-off-by: default avatarLaxminath Kasam <lkasam@codeaurora.org>
parent 53f339b5
Loading
Loading
Loading
Loading
+165 −13
Original line number Diff line number Diff line
@@ -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;

@@ -118,6 +119,65 @@ static int __bolero_reg_write(struct bolero_priv *priv,
	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"))
@@ -134,6 +194,46 @@ static bool bolero_is_valid_codec_dev(struct device *dev)
	return false;
}

/**
 * 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
 *
@@ -230,6 +330,7 @@ int bolero_register_macro(struct device *dev, u16 macro_id,
	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 +338,7 @@ int bolero_register_macro(struct device *dev, u16 macro_id,
	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 +391,13 @@ void bolero_unregister_macro(struct device *dev, u16 macro_id)
	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);
@@ -555,7 +657,12 @@ static struct snd_soc_codec_driver bolero = {
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 +676,53 @@ static void bolero_add_child_devices(struct work_struct *work)
			__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);

	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
		dev_dbg(priv->dev, "%s: added child node\n", __func__);
			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 +743,11 @@ static int bolero_probe(struct platform_device *pdev)
			__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,
@@ -617,6 +765,10 @@ static int bolero_probe(struct platform_device *pdev)
	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);
+21 −0
Original line number Diff line number Diff line
@@ -31,6 +31,20 @@ enum mclk_mux {
	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 */
};

struct macro_ops {
	int (*init)(struct snd_soc_codec *codec);
	int (*exit)(struct snd_soc_codec *codec);
@@ -38,6 +52,8 @@ struct macro_ops {
	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 +68,7 @@ int bolero_request_clock(struct device *dev, u16 macro_id,
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 +100,9 @@ static int bolero_info_create_codec_entry(
{
	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 */
+29 −1
Original line number Diff line number Diff line
@@ -15,6 +15,13 @@

#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,
};

enum {
	REG_NO_ACCESS,
	RD_REG,
@@ -22,6 +29,21 @@ enum {
	RD_WR_REG
};

/* from WCD to bolero events */
enum {
	WCD_BOLERO_EVT_RX_MUTE = 1, /* for RX mute/unmute */
	WCD_BOLERO_EVT_IMPED_TRUE,   /* for imped true */
	WCD_BOLERO_EVT_IMPED_FALSE,  /* for imped false */
};

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;
@@ -34,7 +56,7 @@ struct bolero_priv {
	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 +69,12 @@ struct bolero_priv {
			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,
+207 −2
Original line number Diff line number Diff line
@@ -75,6 +75,107 @@ static const struct snd_kcontrol_new name##_mux = \
#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,
@@ -494,6 +595,80 @@ static struct snd_soc_dai_driver rx_macro_dai[] = {
	},
};

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,
@@ -928,6 +1103,37 @@ static int rx_macro_mclk_ctrl(struct device *dev, bool enable)
	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;
	}
	return 0;
}

static int rx_macro_find_playback_dai_id_for_port(int port_id,
						  struct rx_macro_priv *rx_priv)
{
@@ -1078,7 +1284,6 @@ static int rx_macro_enable_mix_path(struct snd_soc_dapm_widget *w,
	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 */
@@ -1128,7 +1333,6 @@ static int rx_macro_enable_main_path(struct snd_soc_dapm_widget *w,
	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);
@@ -2955,6 +3159,7 @@ static void rx_macro_init_ops(struct macro_ops *ops, char __iomem *rx_io_base)
	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)
+23 −1
Original line number Diff line number Diff line
@@ -42,6 +42,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 +109,12 @@ enum {
	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;
@@ -303,6 +311,7 @@ static void tx_macro_tx_hpf_corner_freq_callback(struct work_struct *work)
	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);
@@ -318,6 +327,19 @@ static void tx_macro_tx_hpf_corner_freq_callback(struct work_struct *work)
	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);
@@ -399,7 +421,7 @@ static int tx_macro_put_dec_enum(struct snd_kcontrol *kcontrol,
			__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,
Loading