diff options
-rw-r--r-- | sound/soc/codecs/wcd934x/wcd934x-dsp-cntl.c | 99 | ||||
-rw-r--r-- | sound/soc/codecs/wcd934x/wcd934x-dsp-cntl.h | 7 |
2 files changed, 80 insertions, 26 deletions
diff --git a/sound/soc/codecs/wcd934x/wcd934x-dsp-cntl.c b/sound/soc/codecs/wcd934x/wcd934x-dsp-cntl.c index c3758620177d..66d85c879eff 100644 --- a/sound/soc/codecs/wcd934x/wcd934x-dsp-cntl.c +++ b/sound/soc/codecs/wcd934x/wcd934x-dsp-cntl.c @@ -833,8 +833,7 @@ static int wcd_control_init(struct device *dev, void *priv_data) struct snd_soc_codec *codec = cntl->codec; struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); struct wcd9xxx_core_resource *core_res = &wcd9xxx->core_res; - char wcd_cntl_dir_name[WCD_CNTL_DIR_NAME_LEN_MAX]; - int ret, ret1; + int ret; bool err_irq_requested = false; ret = wcd9xxx_request_irq(core_res, @@ -876,25 +875,8 @@ static int wcd_control_init(struct device *dev, void *priv_data) } wcd_cntl_cpar_ctrl(cntl, true); - snprintf(wcd_cntl_dir_name, WCD_CNTL_DIR_NAME_LEN_MAX, - "%s%d", "wdsp", cntl->dsp_instance); - wcd_cntl_debugfs_init(wcd_cntl_dir_name, cntl); - ret = wcd_cntl_sysfs_init(wcd_cntl_dir_name, cntl); - if (IS_ERR_VALUE(ret)) { - dev_err(codec->dev, - "%s: Failed to init sysfs %d\n", - __func__, ret); - goto err_sysfs_init; - } - return 0; -err_sysfs_init: - wcd_cntl_cpar_ctrl(cntl, false); - ret1 = wcd_cntl_clocks_disable(cntl); - if (IS_ERR_VALUE(ret1)) - dev_err(codec->dev, "%s: Failed to disable clocks, err = %d\n", - __func__, ret1); err_clk_enable: /* Mask all error interrupts */ snd_soc_write(codec, WCD934X_CPE_SS_SS_ERROR_INT_MASK_0A, 0xFF); @@ -916,12 +898,6 @@ static int wcd_control_deinit(struct device *dev, void *priv_data) struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); struct wcd9xxx_core_resource *core_res = &wcd9xxx->core_res; - /* Remove the sysfs entries */ - wcd_cntl_sysfs_remove(cntl); - - /* Remove the debugfs entries */ - wcd_cntl_debugfs_remove(cntl); - wcd_cntl_clocks_disable(cntl); wcd_cntl_cpar_ctrl(cntl, false); @@ -951,6 +927,7 @@ static int wcd_ctrl_component_bind(struct device *dev, struct snd_card *card; struct snd_info_entry *entry; char proc_name[WCD_PROCFS_ENTRY_MAX_LEN]; + char wcd_cntl_dir_name[WCD_CNTL_DIR_NAME_LEN_MAX]; int ret = 0; if (!dev || !master || !data) { @@ -982,6 +959,17 @@ static int wcd_ctrl_component_bind(struct device *dev, goto done; } + snprintf(wcd_cntl_dir_name, WCD_CNTL_DIR_NAME_LEN_MAX, + "%s%d", "wdsp", cntl->dsp_instance); + ret = wcd_cntl_sysfs_init(wcd_cntl_dir_name, cntl); + if (IS_ERR_VALUE(ret)) { + dev_err(dev, "%s: sysfs_init failed, err = %d\n", + __func__, ret); + goto done; + } + + wcd_cntl_debugfs_init(wcd_cntl_dir_name, cntl); + codec = cntl->codec; card = codec->component.card->snd_card; snprintf(proc_name, WCD_PROCFS_ENTRY_MAX_LEN, "%s%d%s", "cpe", @@ -1032,6 +1020,13 @@ static void wcd_ctrl_component_unbind(struct device *dev, cntl->m_dev = NULL; cntl->m_ops = NULL; + + /* Remove the sysfs entries */ + wcd_cntl_sysfs_remove(cntl); + + /* Remove the debugfs entries */ + wcd_cntl_debugfs_remove(cntl); + } static const struct component_ops wcd_ctrl_component_ops = { @@ -1040,6 +1035,60 @@ static const struct component_ops wcd_ctrl_component_ops = { }; /* + * wcd_dsp_ssr_event: handle the SSR event raised by caller. + * @cntl: Handle to the wcd_dsp_cntl structure + * @event: The SSR event to be handled + * + * Notifies the manager driver about the SSR event. + * Returns 0 on success and negative error code on error. + */ +int wcd_dsp_ssr_event(struct wcd_dsp_cntl *cntl, enum cdc_ssr_event event) +{ + int ret = 0; + + if (!cntl) { + pr_err("%s: Invalid handle to control\n", __func__); + return -EINVAL; + } + + if (!cntl->m_dev || !cntl->m_ops || !cntl->m_ops->signal_handler) { + dev_err(cntl->codec->dev, + "%s: Invalid signal_handler callback\n", __func__); + return -EINVAL; + } + + switch (event) { + case WCD_CDC_DOWN_EVENT: + ret = cntl->m_ops->signal_handler(cntl->m_dev, + WDSP_CDC_DOWN_SIGNAL, + NULL); + if (IS_ERR_VALUE(ret)) + dev_err(cntl->codec->dev, + "%s: WDSP_CDC_DOWN_SIGNAL failed, err = %d\n", + __func__, ret); + wcd_cntl_change_online_state(cntl, 0); + break; + case WCD_CDC_UP_EVENT: + ret = cntl->m_ops->signal_handler(cntl->m_dev, + WDSP_CDC_UP_SIGNAL, + NULL); + if (IS_ERR_VALUE(ret)) + dev_err(cntl->codec->dev, + "%s: WDSP_CDC_UP_SIGNAL failed, err = %d\n", + __func__, ret); + break; + default: + dev_err(cntl->codec->dev, "%s: Invalid event %d\n", + __func__, event); + ret = -EINVAL; + break; + } + + return ret; +} +EXPORT_SYMBOL(wcd_dsp_ssr_event); + +/* * wcd_dsp_cntl_init: Initialize the wcd-dsp control * @codec: pointer to the codec handle * @params: Parameters required to initialize wcd-dsp control diff --git a/sound/soc/codecs/wcd934x/wcd934x-dsp-cntl.h b/sound/soc/codecs/wcd934x/wcd934x-dsp-cntl.h index cd6697b3d641..83c59ed7b676 100644 --- a/sound/soc/codecs/wcd934x/wcd934x-dsp-cntl.h +++ b/sound/soc/codecs/wcd934x/wcd934x-dsp-cntl.h @@ -17,6 +17,11 @@ #include <sound/soc.h> #include <sound/wcd-dsp-mgr.h> +enum cdc_ssr_event { + WCD_CDC_DOWN_EVENT, + WCD_CDC_UP_EVENT, +}; + struct wcd_dsp_cdc_cb { /* Callback to enable codec clock */ int (*cdc_clk_en)(struct snd_soc_codec *, bool); @@ -106,5 +111,5 @@ void wcd_dsp_cntl_init(struct snd_soc_codec *codec, struct wcd_dsp_params *params, struct wcd_dsp_cntl **cntl); void wcd_dsp_cntl_deinit(struct wcd_dsp_cntl **cntl); - +int wcd_dsp_ssr_event(struct wcd_dsp_cntl *cntl, enum cdc_ssr_event event); #endif /* end __WCD_DSP_CONTROL_H__ */ |