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

This commit is contained in:
Linux Build Service Account 2013-11-21 01:42:36 -08:00 committed by Gerrit - the friendly Code Review server
commit c6d7992a11
1 changed files with 121 additions and 16 deletions

View File

@ -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;