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

Commit a5a7ba3b authored by Karthikeyan Mani's avatar Karthikeyan Mani Committed by Gerrit - the friendly Code Review server
Browse files

asoc: codecs: wcd938x: Add widget to enable micbias standalone



Add widgets to enable mic bias standlaone without
dependency on any use case.

Change-Id: I1f61cd9403d3f83baa199f9c669680d9c7b5c371
Signed-off-by: default avatarKarthikeyan Mani <kmani@codeaurora.org>
parent 669b885a
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
 * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
 */

#ifndef _WCD938X_INTERNAL_H
@@ -55,6 +55,7 @@ struct wcd938x_priv {
	struct device_node *wcd_rst_np;

	struct mutex micb_lock;
	struct mutex wakeup_lock;
	s32 dmic_0_1_clk_cnt;
	s32 dmic_2_3_clk_cnt;
	s32 dmic_4_5_clk_cnt;
+71 −20
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
 * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
 */

#include <linux/module.h>
@@ -43,6 +43,11 @@

#define NUM_ATTEMPTS 5

#define DAPM_MICBIAS1_STANDALONE "MIC BIAS1 Standalone"
#define DAPM_MICBIAS2_STANDALONE "MIC BIAS2 Standalone"
#define DAPM_MICBIAS3_STANDALONE "MIC BIAS3 Standalone"
#define DAPM_MICBIAS4_STANDALONE "MIC BIAS4 Standalone"

enum {
	CODEC_TX = 0,
	CODEC_RX,
@@ -2033,6 +2038,55 @@ static int wcd938x_codec_enable_micbias_pullup(struct snd_soc_dapm_widget *w,
	return __wcd938x_codec_enable_micbias_pullup(w, event);
}

static int wcd938x_wakeup(void *handle, bool enable)
{
	struct wcd938x_priv *priv;
	int ret = 0;

	if (!handle) {
		pr_err("%s: NULL handle\n", __func__);
		return -EINVAL;
	}
	priv = (struct wcd938x_priv *)handle;
	if (!priv->tx_swr_dev) {
		pr_err("%s: tx swr dev is NULL\n", __func__);
		return -EINVAL;
	}
	mutex_lock(&priv->wakeup_lock);
	if (enable)
		ret = swr_device_wakeup_vote(priv->tx_swr_dev);
	else
		ret = swr_device_wakeup_unvote(priv->tx_swr_dev);
	mutex_unlock(&priv->wakeup_lock);

	return ret;
}

static int wcd938x_codec_force_enable_micbias(struct snd_soc_dapm_widget *w,
					    struct snd_kcontrol *kcontrol,
					    int event)
{
	int ret = 0;
	struct snd_soc_component *component =
			snd_soc_dapm_to_component(w->dapm);
	struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);

	switch (event) {
	case SND_SOC_DAPM_PRE_PMU:
		wcd938x_wakeup(wcd938x, true);
		ret = __wcd938x_codec_enable_micbias(w, SND_SOC_DAPM_PRE_PMU);
		wcd938x_wakeup(wcd938x, false);
		break;
	case SND_SOC_DAPM_POST_PMD:
		wcd938x_wakeup(wcd938x, true);
		ret = __wcd938x_codec_enable_micbias(w, SND_SOC_DAPM_POST_PMD);
		wcd938x_wakeup(wcd938x, false);
		break;
	}

	return ret;
}

static inline int wcd938x_tx_path_get(const char *wname,
				      unsigned int *path_num)
{
@@ -2641,6 +2695,19 @@ static const struct snd_soc_dapm_widget wcd938x_dapm_widgets[] = {
				SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
				SND_SOC_DAPM_POST_PMD),

	SND_SOC_DAPM_SUPPLY(DAPM_MICBIAS1_STANDALONE, SND_SOC_NOPM, 0, 0,
		wcd938x_codec_force_enable_micbias,
		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
	SND_SOC_DAPM_SUPPLY(DAPM_MICBIAS2_STANDALONE, SND_SOC_NOPM, 0, 0,
		wcd938x_codec_force_enable_micbias,
		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
	SND_SOC_DAPM_SUPPLY(DAPM_MICBIAS3_STANDALONE, SND_SOC_NOPM, 0, 0,
		wcd938x_codec_force_enable_micbias,
		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
	SND_SOC_DAPM_SUPPLY(DAPM_MICBIAS4_STANDALONE, SND_SOC_NOPM, 0, 0,
		wcd938x_codec_force_enable_micbias,
		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),

	SND_SOC_DAPM_SUPPLY_S("CLS_H_PORT", 1, SND_SOC_NOPM, 0, 0,
			     wcd938x_enable_clsh,
			     SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
@@ -3537,25 +3604,6 @@ static int wcd938x_add_slave_components(struct device *dev,
	return 0;
}

static int wcd938x_wakeup(void *handle, bool enable)
{
	struct wcd938x_priv *priv;

	if (!handle) {
		pr_err("%s: NULL handle\n", __func__);
		return -EINVAL;
	}
	priv = (struct wcd938x_priv *)handle;
	if (!priv->tx_swr_dev) {
		pr_err("%s: tx swr dev is NULL\n", __func__);
		return -EINVAL;
	}
	if (enable)
		return swr_device_wakeup_vote(priv->tx_swr_dev);
	else
		return swr_device_wakeup_unvote(priv->tx_swr_dev);
}

static int wcd938x_probe(struct platform_device *pdev)
{
	struct component_match *match = NULL;
@@ -3633,6 +3681,7 @@ static int wcd938x_probe(struct platform_device *pdev)
		goto err;
	}

	mutex_init(&wcd938x->wakeup_lock);
	mutex_init(&wcd938x->micb_lock);
	ret = wcd938x_add_slave_components(dev, &match);
	if (ret)
@@ -3647,6 +3696,7 @@ static int wcd938x_probe(struct platform_device *pdev)

err_lock_init:
	mutex_destroy(&wcd938x->micb_lock);
	mutex_destroy(&wcd938x->wakeup_lock);
err:
	return ret;
}
@@ -3658,6 +3708,7 @@ static int wcd938x_remove(struct platform_device *pdev)
	wcd938x = platform_get_drvdata(pdev);
	component_master_del(&pdev->dev, &wcd938x_comp_ops);
	mutex_destroy(&wcd938x->micb_lock);
	mutex_destroy(&wcd938x->wakeup_lock);
	dev_set_drvdata(&pdev->dev, NULL);

	return 0;