From 9a3d5ebc7ca7350b60947e649d98fe870005dab9 Mon Sep 17 00:00:00 2001 From: Vaishnavi Kommaraju Date: Wed, 19 Sep 2018 18:16:39 +0530 Subject: [PATCH] asoc: sm6150: Add SND event FWK support for talos Add snd_event support for talos required for SSR. Change-Id: If689d9cda131324b99e0dda0b91f237b495eeadc Signed-off-by: Vaishnavi Kommaraju --- asoc/sm6150.c | 245 +++++++++++++++++++++++--------------------------- 1 file changed, 114 insertions(+), 131 deletions(-) diff --git a/asoc/sm6150.c b/asoc/sm6150.c index 72181221ea1f..467fba7d17ee 100644 --- a/asoc/sm6150.c +++ b/asoc/sm6150.c @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include #include "device_event.h" @@ -201,6 +201,7 @@ struct msm_asoc_mach_data { struct pinctrl *usbc_en2_gpio_p; /* used by pinctrl API */ struct device_node *hph_en1_gpio_p; /* used by pinctrl API */ struct device_node *hph_en0_gpio_p; /* used by pinctrl API */ + bool is_afe_config_done; }; struct msm_asoc_wcd93xx_codec { @@ -628,10 +629,7 @@ static SOC_ENUM_SINGLE_EXT_DECL(tx_cdc_dma_tx_3_sample_rate, static SOC_ENUM_SINGLE_EXT_DECL(tx_cdc_dma_tx_4_sample_rate, cdc_dma_sample_rate_text); -static struct platform_device *spdev; - static int msm_hifi_control; -static bool is_initial_boot; static bool codec_reg_done; static struct snd_soc_aux_dev *msm_aux_dev; static struct snd_soc_codec_conf *msm_codec_conf; @@ -4595,121 +4593,6 @@ static void msm_afe_clear_config(void) afe_clear_config(AFE_SLIMBUS_SLAVE_CONFIG); } -static int msm_adsp_power_up_config(struct snd_soc_codec *codec, - struct snd_card *card) -{ - int ret = 0; - unsigned long timeout; - int adsp_ready = 0; - bool snd_card_online = 0; - - timeout = jiffies + - msecs_to_jiffies(ADSP_STATE_READY_TIMEOUT_MS); - - do { - if (!snd_card_online) { - snd_card_online = snd_card_is_online_state(card); - pr_debug("%s: Sound card is %s\n", __func__, - snd_card_online ? "Online" : "Offline"); - } - if (!adsp_ready) { - adsp_ready = q6core_is_adsp_ready(); - pr_debug("%s: ADSP Audio is %s\n", __func__, - adsp_ready ? "ready" : "not ready"); - } - if (snd_card_online && adsp_ready) - break; - - /* - * Sound card/ADSP will be coming up after subsystem restart and - * it might not be fully up when the control reaches - * here. So, wait for 50msec before checking ADSP state - */ - msleep(50); - } while (time_after(timeout, jiffies)); - - if (!snd_card_online || !adsp_ready) { - pr_err("%s: Timeout. Sound card is %s, ADSP Audio is %s\n", - __func__, - snd_card_online ? "Online" : "Offline", - adsp_ready ? "ready" : "not ready"); - ret = -ETIMEDOUT; - goto err; - } - - ret = msm_afe_set_config(codec); - if (ret) - pr_err("%s: Failed to set AFE config. err %d\n", - __func__, ret); - - return 0; - -err: - return ret; -} - -static int sm6150_notifier_service_cb(struct notifier_block *this, - unsigned long opcode, void *ptr) -{ - int ret; - struct snd_soc_card *card = NULL; - const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX; - struct snd_soc_pcm_runtime *rtd; - struct snd_soc_codec *codec; - - pr_debug("%s: Service opcode 0x%lx\n", __func__, opcode); - - switch (opcode) { - case AUDIO_NOTIFIER_SERVICE_DOWN: - /* - * Use flag to ignore initial boot notifications - * On initial boot msm_adsp_power_up_config is - * called on init. There is no need to clear - * and set the config again on initial boot. - */ - if (is_initial_boot) - break; - msm_afe_clear_config(); - break; - case AUDIO_NOTIFIER_SERVICE_UP: - if (is_initial_boot) { - is_initial_boot = false; - break; - } - if (!spdev) - return -EINVAL; - - card = platform_get_drvdata(spdev); - rtd = snd_soc_get_pcm_runtime(card, be_dl_name); - if (!rtd) { - dev_err(card->dev, - "%s: snd_soc_get_pcm_runtime for %s failed!\n", - __func__, be_dl_name); - ret = -EINVAL; - goto err; - } - codec = rtd->codec; - - ret = msm_adsp_power_up_config(codec, card->snd_card); - if (ret < 0) { - dev_err(card->dev, - "%s: msm_adsp_power_up_config failed ret = %d!\n", - __func__, ret); - goto err; - } - break; - default: - break; - } -err: - return NOTIFY_OK; -} - -static struct notifier_block service_nb = { - .notifier_call = sm6150_notifier_service_cb, - .priority = -INT_MAX, -}; - static int msm_audrx_tavil_init(struct snd_soc_pcm_runtime *rtd) { int ret = 0; @@ -4797,11 +4680,12 @@ static int msm_audrx_tavil_init(struct snd_soc_pcm_runtime *rtd) msm_codec_fn.get_afe_config_fn = tavil_get_afe_config; - ret = msm_adsp_power_up_config(codec, rtd->card->snd_card); + ret = msm_afe_set_config(codec); if (ret) { pr_err("%s: Failed to set AFE config %d\n", __func__, ret); goto err; } + pdata->is_afe_config_done = true; config_data = msm_codec_fn.get_afe_config_fn(codec, AFE_AANC_VERSION); @@ -8309,6 +8193,108 @@ static void msm_i2s_auxpcm_deinit(void) mi2s_intf_conf[count].msm_is_mi2s_master = 0; } } + +static int sm6150_ssr_enable(struct device *dev, void *data) +{ + struct platform_device *pdev = to_platform_device(dev); + struct snd_soc_card *card = platform_get_drvdata(pdev); + struct msm_asoc_mach_data *pdata; + int ret = 0; + + if (!card) { + dev_err(dev, "%s: card is NULL\n", __func__); + ret = -EINVAL; + goto err; + } + + if (!strcmp(card->name, "sm6150-tavil-snd-card")) { + pdata = snd_soc_card_get_drvdata(card); + if (!pdata->is_afe_config_done) { + const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX; + struct snd_soc_pcm_runtime *rtd; + + rtd = snd_soc_get_pcm_runtime(card, be_dl_name); + if (!rtd) { + dev_err(dev, + "%s: snd_soc_get_pcm_runtime for %s failed!\n", + __func__, be_dl_name); + ret = -EINVAL; + goto err; + } + ret = msm_afe_set_config(rtd->codec); + if (ret) + dev_err(dev, "%s: Failed to set AFE config. err %d\n", + __func__, ret); + else + pdata->is_afe_config_done = true; + } + } + snd_soc_card_change_online_state(card, 1); + dev_dbg(dev, "%s: setting snd_card to ONLINE\n", __func__); + +err: + return ret; +} + +static void sm6150_ssr_disable(struct device *dev, void *data) +{ + struct platform_device *pdev = to_platform_device(dev); + struct snd_soc_card *card = platform_get_drvdata(pdev); + struct msm_asoc_mach_data *pdata; + + if (!card) { + dev_err(dev, "%s: card is NULL\n", __func__); + return; + } + + dev_dbg(dev, "%s: setting snd_card to OFFLINE\n", __func__); + snd_soc_card_change_online_state(card, 0); + + if (!strcmp(card->name, "sm6150-tavil-snd-card")) { + pdata = snd_soc_card_get_drvdata(card); + msm_afe_clear_config(); + pdata->is_afe_config_done = false; + } +} + +static const struct snd_event_ops sm6150_ssr_ops = { + .enable = sm6150_ssr_enable, + .disable = sm6150_ssr_disable, +}; + +static int msm_audio_ssr_compare(struct device *dev, void *data) +{ + struct device_node *node = data; + + dev_dbg(dev, "%s: dev->of_node = 0x%p, node = 0x%p\n", + __func__, dev->of_node, node); + return (dev->of_node && dev->of_node == node); +} + +static int msm_audio_ssr_register(struct device *dev) +{ + struct device_node *np = dev->of_node; + struct snd_event_clients *ssr_clients = NULL; + struct device_node *node; + int ret; + int i; + + for (i = 0; ; i++) { + node = of_parse_phandle(np, "qcom,msm_audio_ssr_devs", i); + if (!node) + break; + snd_event_mstr_add_client(&ssr_clients, + msm_audio_ssr_compare, node); + } + + ret = snd_event_master_register(dev, &sm6150_ssr_ops, + ssr_clients, NULL); + if (!ret) + snd_event_notify(dev, SND_EVENT_UP); + + return ret; +} + static int msm_asoc_machine_probe(struct platform_device *pdev) { struct snd_soc_card *card; @@ -8371,7 +8357,6 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) goto err; } dev_info(&pdev->dev, "Sound card %s registered\n", card->name); - spdev = pdev; pdata->hph_en1_gpio_p = of_parse_phandle(pdev->dev.of_node, "qcom,hph-en1-gpio", 0); @@ -8438,15 +8423,7 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) } msm_i2s_auxpcm_init(pdev); - if (!strcmp(card->name, "sm6150-tavil-snd-card")) { - is_initial_boot = true; - ret = audio_notifier_register("sm6150", - AUDIO_NOTIFIER_ADSP_DOMAIN, - &service_nb); - if (ret < 0) - pr_err("%s: Audio notifier register failed ret = %d\n", - __func__, ret); - } else { + if (strcmp(card->name, "sm6150-tavil-snd-card")) { pdata->dmic01_gpio_p = of_parse_phandle(pdev->dev.of_node, "qcom,cdc-dmic01-gpios", 0); @@ -8454,13 +8431,19 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) "qcom,cdc-dmic23-gpios", 0); } + + ret = msm_audio_ssr_register(&pdev->dev); + if (ret) + pr_err("%s: Registration with SND event FWK failed ret = %d\n", + __func__, ret); + err: return ret; } static int msm_asoc_machine_remove(struct platform_device *pdev) { - audio_notifier_deregister("sm6150"); + snd_event_master_deregister(&pdev->dev); msm_i2s_auxpcm_deinit(); return 0;