Loading sound/soc/msm/apq8074.c +121 −16 Original line number Diff line number Diff line Loading @@ -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" Loading Loading @@ -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) && Loading Loading @@ -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; Loading Loading @@ -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; } Loading Loading @@ -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; Loading Loading
sound/soc/msm/apq8074.c +121 −16 Original line number Diff line number Diff line Loading @@ -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" Loading Loading @@ -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) && Loading Loading @@ -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; Loading Loading @@ -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; } Loading Loading @@ -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; Loading