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

Commit c6d7992a authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "ASoC: apq8074: register for codec up event"

parents 1d4d6da3 5cd1b231
Loading
Loading
Loading
Loading
+121 −16
Original line number Diff line number Diff line
@@ -19,17 +19,22 @@
#include <linux/mfd/pm8xxx/pm8921.h>
#include <linux/qpnp/clkdiv.h>
#include <linux/regulator/consumer.h>
#include <linux/io.h>
#include <sound/core.h>
#include <sound/soc.h>
#include <sound/soc-dapm.h>
#include <sound/pcm.h>
#include <sound/jack.h>
#include <sound/q6afe-v2.h>
#include <mach/socinfo.h>
#include <sound/pcm_params.h>
#include <asm/mach-types.h>
#include <mach/subsystem_notif.h>
#include <mach/socinfo.h>

#include "qdsp6v2/msm-pcm-routing-v2.h"
#include "qdsp6v2/q6core.h"
#include "../codecs/wcd9xxx-common.h"
#include "../codecs/wcd9320.h"
#include <linux/io.h>

#define DRV_NAME "apq8074-asoc-taiko"

@@ -81,6 +86,10 @@ static int apq8074_auxpcm_rate = 8000;

#define NUM_OF_AUXPCM_GPIOS 4

static void *adsp_state_notifier;

#define ADSP_STATE_READY_TIMEOUT_MS 3000

static inline int param_is_mask(int p)
{
	return ((p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) &&
@@ -1238,6 +1247,101 @@ static bool apq8074_swap_gnd_mic(struct snd_soc_codec *codec)
	return true;
}

static int msm_afe_set_config(struct snd_soc_codec *codec)
{
	int rc;
	void *config_data;

	pr_debug("%s: enter\n", __func__);
	config_data = taiko_get_afe_config(codec, AFE_CDC_REGISTERS_CONFIG);
	rc = afe_set_config(AFE_CDC_REGISTERS_CONFIG, config_data, 0);
	if (rc) {
		pr_err("%s: Failed to set codec registers config %d\n",
		       __func__, rc);
		return rc;
	}

	config_data = taiko_get_afe_config(codec, AFE_SLIMBUS_SLAVE_CONFIG);
	rc = afe_set_config(AFE_SLIMBUS_SLAVE_CONFIG, config_data, 0);
	if (rc) {
		pr_err("%s: Failed to set slimbus slave config %d\n", __func__,
		       rc);
		return rc;
	}

	return 0;
}

static void msm_afe_clear_config(void)
{
	afe_clear_config(AFE_CDC_REGISTERS_CONFIG);
	afe_clear_config(AFE_SLIMBUS_SLAVE_CONFIG);
}

static int  msm8974_adsp_state_callback(struct notifier_block *nb,
		unsigned long value, void *priv)
{
	if (value == SUBSYS_BEFORE_SHUTDOWN) {
		pr_debug("%s: ADSP is about to shutdown. Clearing AFE config\n",
			 __func__);
		msm_afe_clear_config();
	} else if (value == SUBSYS_AFTER_POWERUP) {
		pr_debug("%s: ADSP is up\n", __func__);
	}

	return NOTIFY_OK;
}

static struct notifier_block adsp_state_notifier_block = {
	.notifier_call = msm8974_adsp_state_callback,
	.priority = -INT_MAX,
};

static int msm8974_taiko_codec_up(struct snd_soc_codec *codec)
{
	int err;
	unsigned long timeout;
	int adsp_ready = 0;

	timeout = jiffies +
		msecs_to_jiffies(ADSP_STATE_READY_TIMEOUT_MS);

	do {
		if (!q6core_is_adsp_ready()) {
			pr_err("%s: ADSP Audio isn't ready\n", __func__);
		} else {
			pr_debug("%s: ADSP Audio is ready\n", __func__);
			adsp_ready = 1;
			break;
		}
	} while (time_after(timeout, jiffies));

	if (!adsp_ready) {
		pr_err("%s: timed out waiting for ADSP Audio\n", __func__);
		return -ETIMEDOUT;
	}

	err = msm_afe_set_config(codec);
	if (err)
		pr_err("%s: Failed to set AFE config. err %d\n",
				__func__, err);
	return err;
}

static int apq8074_taiko_event_cb(struct snd_soc_codec *codec,
		enum wcd9xxx_codec_event codec_event)
{
	switch (codec_event) {
	case WCD9XXX_CODEC_EVENT_CODEC_UP:
		return msm8974_taiko_codec_up(codec);
		break;
	default:
		pr_err("%s: UnSupported codec event %d\n",
				__func__, codec_event);
		return -EINVAL;
	}
}

static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd)
{
	int err;
@@ -1299,19 +1403,9 @@ static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd)
				    tx_ch, ARRAY_SIZE(rx_ch), rx_ch);


	config_data = taiko_get_afe_config(codec, AFE_CDC_REGISTERS_CONFIG);
	err = afe_set_config(AFE_CDC_REGISTERS_CONFIG, config_data, 0);
	err = msm_afe_set_config(codec);
	if (err) {
		pr_err("%s: Failed to set codec registers config %d\n",
		       __func__, err);
		goto out;
	}

	config_data = taiko_get_afe_config(codec, AFE_SLIMBUS_SLAVE_CONFIG);
	err = afe_set_config(AFE_SLIMBUS_SLAVE_CONFIG, config_data, 0);
	if (err) {
		pr_err("%s: Failed to set slimbus slave config %d\n", __func__,
		       err);
		pr_err("%s: Failed to set AFE config %d\n", __func__, err);
		goto out;
	}

@@ -1348,12 +1442,23 @@ static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd)
		err = taiko_hs_detect(codec, &mbhc_cfg);
		if (err)
			goto out;
		else
			return err;
	} else {
		err = -ENOMEM;
		goto out;
	}
	adsp_state_notifier =
	    subsys_notif_register_notifier("adsp",
					   &adsp_state_notifier_block);
	if (!adsp_state_notifier) {
		pr_err("%s: Failed to register adsp state notifier\n",
		       __func__);
		err = -EFAULT;
		taiko_hs_detect_exit(codec);
		goto out;
	}

	taiko_event_register(apq8074_taiko_event_cb, rtd->codec);
	return 0;
out:
	clk_put(codec_clk);
	return err;