Loading sound/soc/codecs/wcd9330.c +47 −23 Original line number Diff line number Diff line Loading @@ -2678,6 +2678,21 @@ static int tomtom_codec_enable_adc(struct snd_soc_dapm_widget *w, return 0; } static int tomtom_codec_ext_clk_en(struct snd_soc_codec *codec, int enable, bool dapm) { struct tomtom_priv *tomtom = snd_soc_codec_get_drvdata(codec); if (!tomtom->codec_ext_clk_en_cb) { dev_err(codec->dev, "%s: Invalid ext_clk_callback\n", __func__); return -EINVAL; } return tomtom->codec_ext_clk_en_cb(codec, enable, dapm); } /* tomtom_codec_internal_rco_ctrl( ) * Make sure that BG_CLK_LOCK is not acquired. Exit if acquired to avoid * potential deadlock as ext_clk_en_cb() also tries to acquire the same Loading @@ -2687,11 +2702,21 @@ static int tomtom_codec_internal_rco_ctrl(struct snd_soc_codec *codec, bool enable) { struct tomtom_priv *tomtom = snd_soc_codec_get_drvdata(codec); int ret = 0; if (mutex_is_locked(&tomtom->resmgr.codec_bg_clk_lock)) { dev_err(codec->dev, "%s: BG_CLK already acquired\n", __func__); return -EINVAL; ret = -EINVAL; goto done; } if (!tomtom->codec_ext_clk_en_cb) { dev_err(codec->dev, "%s: Invalid ext_clk_callback\n", __func__); ret = -EINVAL; goto done; } if (enable) { Loading @@ -2702,14 +2727,14 @@ static int tomtom_codec_internal_rco_ctrl(struct snd_soc_codec *codec, WCD9XXX_CLK_RCO); WCD9XXX_BG_CLK_UNLOCK(&tomtom->resmgr); } else { tomtom->codec_ext_clk_en_cb(codec, true, false); tomtom_codec_ext_clk_en(codec, true, false); WCD9XXX_BG_CLK_LOCK(&tomtom->resmgr); tomtom->resmgr.ext_clk_users = tomtom->codec_get_ext_clk_cnt(); wcd9xxx_resmgr_get_clk_block(&tomtom->resmgr, WCD9XXX_CLK_RCO); WCD9XXX_BG_CLK_UNLOCK(&tomtom->resmgr); tomtom->codec_ext_clk_en_cb(codec, false, false); tomtom_codec_ext_clk_en(codec, false, false); } } else { Loading @@ -2719,7 +2744,8 @@ static int tomtom_codec_internal_rco_ctrl(struct snd_soc_codec *codec, WCD9XXX_BG_CLK_UNLOCK(&tomtom->resmgr); } return 0; done: return ret; } static int tomtom_codec_enable_aux_pga(struct snd_soc_dapm_widget *w, Loading Loading @@ -7832,38 +7858,29 @@ static int tomtom_codec_fll_enable(struct snd_soc_codec *codec, return 0; } static void tomtom_codec_cpe_setup_callbacks( struct wcd_cpe_cdc_cb *cpe_cb, int (*cdc_ext_clk)(struct snd_soc_codec *codec, int enable, bool dapm)) { cpe_cb->cdc_clk_en = tomtom_codec_internal_rco_ctrl; cpe_cb->cpe_clk_en = tomtom_codec_fll_enable; cpe_cb->slimtx_lab_en = tomtom_codec_enable_slimtx_mad; if (cdc_ext_clk == NULL) pr_err("%s: MCLK could not be set", __func__); cpe_cb->cdc_ext_clk = cdc_ext_clk; } static const struct wcd_cpe_cdc_cb cpe_cb = { .cdc_clk_en = tomtom_codec_internal_rco_ctrl, .cpe_clk_en = tomtom_codec_fll_enable, .slimtx_lab_en = tomtom_codec_enable_slimtx_mad, .cdc_ext_clk = tomtom_codec_ext_clk_en, }; int tomtom_enable_cpe(struct snd_soc_codec *codec) static int tomtom_cpe_initialize(struct snd_soc_codec *codec) { struct tomtom_priv *tomtom = snd_soc_codec_get_drvdata(codec); struct wcd_cpe_params cpe_params; struct wcd_cpe_cdc_cb cpe_cdc_cb; tomtom_codec_cpe_setup_callbacks(&cpe_cdc_cb, tomtom->codec_ext_clk_en_cb); memset(&cpe_params, 0, sizeof(struct wcd_cpe_params)); cpe_params.codec = codec; cpe_params.get_cpe_core = tomtom_codec_get_cpe_core; cpe_params.cdc_cb = &cpe_cdc_cb; cpe_params.cdc_cb = &cpe_cb; cpe_params.dbg_mode = cpe_debug_mode; cpe_params.cdc_major_ver = TOMTOM_CPE_MAJOR_VER; cpe_params.cdc_minor_ver = TOMTOM_CPE_MINOR_VER; cpe_params.cdc_id = TOMTOM_CPE_CDC_ID; tomtom->cpe_core = wcd_cpe_init_and_boot("cpe", codec, tomtom->cpe_core = wcd_cpe_init("cpe", codec, &cpe_params); if (IS_ERR_OR_NULL(tomtom->cpe_core)) { dev_err(codec->dev, Loading @@ -7874,7 +7891,6 @@ int tomtom_enable_cpe(struct snd_soc_codec *codec) return 0; } EXPORT_SYMBOL(tomtom_enable_cpe); int tomtom_enable_qfuse_sensing(struct snd_soc_codec *codec) { Loading Loading @@ -8052,6 +8068,14 @@ static int tomtom_codec_probe(struct snd_soc_codec *codec) snd_soc_dapm_sync(dapm); codec->ignore_pmdown_time = 1; ret = tomtom_cpe_initialize(codec); if (ret) { dev_info(codec->dev, "%s: cpe initialization failed, ret = %d\n", __func__, ret); /* Do not fail probe if CPE failed */ ret = 0; } return ret; err_pdata: Loading sound/soc/codecs/wcd9330.h +0 −1 Original line number Diff line number Diff line Loading @@ -125,6 +125,5 @@ extern void tomtom_register_ext_clk_cb( int enable, bool dapm), int (*get_ext_clk_cnt) (void), struct snd_soc_codec *codec); extern int tomtom_enable_cpe(struct snd_soc_codec *codec); extern int tomtom_enable_qfuse_sensing(struct snd_soc_codec *codec); #endif sound/soc/codecs/wcd_cpe_core.c +164 −39 Original line number Diff line number Diff line Loading @@ -98,6 +98,32 @@ static void wcd_cpe_svc_event_cb(const struct cpe_svc_notification *param); static int wcd_cpe_setup_irqs(struct wcd_cpe_core *core); static void wcd_cpe_cleanup_irqs(struct wcd_cpe_core *core); struct cpe_load_priv { void *cdc_handle; int cpe_load; struct kobject *cpe_load_kobj; struct attribute_group *attr_group; }; static ssize_t wcd_cpe_load_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count); static struct kobj_attribute cpe_load_attr = __ATTR(load, 0600, NULL, wcd_cpe_load_store); static struct attribute *attrs[] = { &cpe_load_attr.attr, NULL, }; static struct attribute_group attr_grp = { .attrs = attrs, }; static struct cpe_load_priv cpe_priv; /* wcd_cpe_lsm_session_active: check if any session is active * return true if any session is active. */ Loading Loading @@ -245,21 +271,21 @@ static int wcd_cpe_enable_cpe_clks(struct wcd_cpe_core *core, bool enable) { int ret = 0; if (!core || !core->cpe_cdc_cb.cdc_clk_en || !core->cpe_cdc_cb.cpe_clk_en) { if (!core || !core->cpe_cdc_cb || !core->cpe_cdc_cb->cpe_clk_en) { pr_err("%s: invalid handle\n", __func__); return -EINVAL; } ret = core->cpe_cdc_cb.cdc_clk_en(core->codec, enable); ret = core->cpe_cdc_cb->cdc_clk_en(core->codec, enable); if (ret) { dev_err(core->dev, "%s: Failed to enable RCO\n", __func__); return ret; } ret = core->cpe_cdc_cb.cpe_clk_en(core->codec, enable); ret = core->cpe_cdc_cb->cpe_clk_en(core->codec, enable); if (ret) { dev_err(core->dev, "%s: cpe_clk_en() failed, err = %d\n", Loading Loading @@ -730,6 +756,17 @@ int wcd_cpe_ssr_event(void *core_handle, return -EINVAL; } /* * If CPE is not even enabled, the SSR event for * CPE needs to be ignored */ if (core->ssr_type == WCD_CPE_INITIALIZED) { dev_info(core->dev, "%s: CPE initialized but not enabled, skip CPE ssr\n", __func__); return 0; } dev_dbg(core->dev, "%s: Schedule ssr work, event = %d\n", __func__, core->ssr_type); Loading Loading @@ -1052,16 +1089,99 @@ fail_engine_irq: } /* * wcd_cpe_init_and_boot: Initialize and bootup CPE hardware block * wcd_cpe_enable: setup the cpe interrupts and schedule * the work to download image and bootup the CPE. * core: handle to cpe core structure */ static int wcd_cpe_enable(struct wcd_cpe_core *core) { int ret = 0; if (!core) { pr_err("%s: Invalid handle to core\n", __func__); ret = -EINVAL; goto done; } if (core->ssr_type != WCD_CPE_INITIALIZED) { dev_err(core->dev, "%s: CPE not initialized, state = 0x%x\n", __func__, core->ssr_type); ret = -EINVAL; goto done; } ret = wcd_cpe_setup_irqs(core); if (ret) { dev_err(core->dev, "%s: CPE IRQs setup failed, error = %d\n", __func__, ret); goto done; } core->ssr_type = WCD_CPE_ENABLED; schedule_work(&core->load_fw_work); done: return ret; } /* * wcd_cpe_load_store: Function invoked with sysfs property * is written to. Enable CPE if value of the cpe_load * property is non-zero. * kobj: Kobject associated with the sysfs property * attr: The attribute that is written to * buf: holds the data that is written * count: number of data bytes in the buffer */ static ssize_t wcd_cpe_load_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) { struct wcd_cpe_core *core; int ret = 0; if (cpe_priv.cpe_load) { pr_err("%s: CPE already loaded\n", __func__); goto done; } core = wcd_cpe_get_core_handle(cpe_priv.cdc_handle); if (!core) { pr_err("%s: Invalid core handle\n", __func__); goto done; } sscanf(buf, "%du", &cpe_priv.cpe_load); if (cpe_priv.cpe_load) { ret = wcd_cpe_enable(core); if (IS_ERR_VALUE(ret)) cpe_priv.cpe_load = 0; else pr_info("%s: CPE enabled for tomtom_codec\n", __func__); } done: return count; } /* * wcd_cpe_init: Initialize CPE related structures * @img_fname: filename for firmware image * @codec: handle to codec requesting for image download * @params: parameter structure passed from caller * * This API will initialize the cpe core and schedule work * to perform firmware image download to CPE and bootup * CPE. Will also request for CPE related interrupts. * This API will initialize the cpe core but will not * download the image or boot the cpe core. */ struct wcd_cpe_core *wcd_cpe_init_and_boot(const char *img_fname, struct wcd_cpe_core *wcd_cpe_init(const char *img_fname, struct snd_soc_codec *codec, struct wcd_cpe_params *params) { Loading Loading @@ -1114,10 +1234,7 @@ struct wcd_cpe_core *wcd_cpe_init_and_boot(const char *img_fname, core->cdc_info.minor_version = params->cdc_minor_ver; core->cdc_info.id = params->cdc_id; core->cpe_cdc_cb.cdc_clk_en = params->cdc_cb->cdc_clk_en; core->cpe_cdc_cb.cpe_clk_en = params->cdc_cb->cpe_clk_en; core->cpe_cdc_cb.cdc_ext_clk = params->cdc_cb->cdc_ext_clk; core->cpe_cdc_cb.slimtx_lab_en = params->cdc_cb->slimtx_lab_en; core->cpe_cdc_cb = params->cdc_cb; INIT_WORK(&core->load_fw_work, wcd_cpe_load_fw_image); INIT_WORK(&core->ssr_work, wcd_cpe_ssr_work); Loading Loading @@ -1154,13 +1271,6 @@ struct wcd_cpe_core *wcd_cpe_init_and_boot(const char *img_fname, goto fail_cpe_register; } ret = wcd_cpe_setup_irqs(core); if (ret) { dev_err(core->dev, "%s: CPE IRQs setup failed, error = %d\n", __func__, ret); goto fail_setup_irq; } card = codec->card->snd_card; snprintf(proc_name, (sizeof("cpe") + sizeof("_state") + Loading Loading @@ -1192,11 +1302,24 @@ struct wcd_cpe_core *wcd_cpe_init_and_boot(const char *img_fname, */ } schedule_work(&core->load_fw_work); return core; cpe_priv.cdc_handle = codec; cpe_priv.attr_group = &attr_grp; cpe_priv.cpe_load_kobj = kobject_create_and_add("wcd_cpe", kernel_kobj); if (!cpe_priv.cpe_load_kobj) { pr_err("%s: cpe_load: sysfs create_add failed\n", __func__); goto fail_cpe_register; } else if (sysfs_create_group(cpe_priv.cpe_load_kobj, cpe_priv.attr_group)) { pr_err("%s: sysfs_create_group failed\n", __func__); kobject_del(cpe_priv.cpe_load_kobj); goto fail_cpe_register; } core->ssr_type = WCD_CPE_INITIALIZED; fail_setup_irq: cpe_svc_deregister(core->cpe_handle, core->cpe_reg_handle); return core; fail_cpe_register: cpe_svc_deinitialize(core->cpe_handle); Loading @@ -1205,7 +1328,7 @@ fail_cpe_initialize: kfree(core); return NULL; } EXPORT_SYMBOL(wcd_cpe_init_and_boot); EXPORT_SYMBOL(wcd_cpe_init); /* * wcd_cpe_cmi_lsm_callback: callback called from cpe services Loading Loading @@ -2415,17 +2538,19 @@ static int slim_master_read_enable(void *core_handle, lsm_params = &lab_s->hw_params; /* The sequence should be maintained strictly */ WCD_CPE_GRAB_LOCK(&session->lsm_lock, "lsm"); if (core->cpe_cdc_cb.cdc_ext_clk) core->cpe_cdc_cb.cdc_ext_clk(codec, true, false); if (core->cpe_cdc_cb->cdc_ext_clk) core->cpe_cdc_cb->cdc_ext_clk(codec, true, false); else { pr_err("%s: MCLK cannot be enabled NULL\n", __func__); pr_err("%s: Invalid callback for codec ext clk\n", __func__); rc = -EINVAL; goto exit; } if (core->cpe_cdc_cb.slimtx_lab_en) core->cpe_cdc_cb.slimtx_lab_en(codec, 1); if (core->cpe_cdc_cb->slimtx_lab_en) core->cpe_cdc_cb->slimtx_lab_en(codec, 1); else { pr_err("%s: Err slim slave cannot be enabled\n", pr_err("%s: Failed to enable codec slave port\n", __func__); rc = -EINVAL; goto fail_mclk; Loading Loading @@ -2459,9 +2584,9 @@ static int slim_master_read_enable(void *core_handle, return 0; fail_slim_open: core->cpe_cdc_cb.slimtx_lab_en(codec, 0); core->cpe_cdc_cb->slimtx_lab_en(codec, 0); fail_mclk: core->cpe_cdc_cb.cdc_ext_clk(codec, false, false); core->cpe_cdc_cb->cdc_ext_clk(codec, false, false); exit: WCD_CPE_REL_LOCK(&session->lsm_lock, "lsm"); return rc; Loading Loading @@ -2514,10 +2639,10 @@ static int wcd_cpe_lsm_stop_lab(void *core_handle, lab_s = &session->lab; WCD_CPE_GRAB_LOCK(&session->lsm_lock, "lsm"); /* This seqeunce should be followed strictly for closing sequence */ if (core->cpe_cdc_cb.slimtx_lab_en) core->cpe_cdc_cb.slimtx_lab_en(codec, 0); if (core->cpe_cdc_cb->slimtx_lab_en) core->cpe_cdc_cb->slimtx_lab_en(codec, 0); else pr_err("%s: Err slim slave cannot be enabled\n", pr_err("%s: Failed to disable codec slave port\n", __func__); rc = wcd9xxx_slim_ch_master_close(wcd9xxx, &lab_s->slim_handle); Loading @@ -2541,10 +2666,10 @@ static int wcd_cpe_lsm_stop_lab(void *core_handle, lab_s->thread_status = MSM_LSM_LAB_THREAD_STOP; atomic_set(&lab_s->in_count, 0); lab_s->dma_write = 0; if (core->cpe_cdc_cb.cdc_ext_clk) core->cpe_cdc_cb.cdc_ext_clk(codec, false, false); if (core->cpe_cdc_cb->cdc_ext_clk) core->cpe_cdc_cb->cdc_ext_clk(codec, false, false); else pr_err("%s: MCLK cannot be disable NULL\n", pr_err("%s: Failed to disable cdc ext clk\n", __func__); WCD_CPE_REL_LOCK(&session->lsm_lock, "lsm"); return rc; Loading sound/soc/codecs/wcd_cpe_core.h +8 −4 Original line number Diff line number Diff line Loading @@ -38,8 +38,12 @@ struct wcd_cpe_cdc_cb { }; enum wcd_cpe_ssr_state_event { /* Indicates CPE is initialized */ WCD_CPE_INITIALIZED = 0, /* Indicates CPE is enabled */ WCD_CPE_ENABLED, /* Indicates that CPE is currently active */ WCD_CPE_ACTIVE = 0, WCD_CPE_ACTIVE, /* Event from underlying bus notifying bus is down */ WCD_CPE_BUS_DOWN_EVENT, /* Event from CPE block, notifying CPE is down */ Loading Loading @@ -84,7 +88,7 @@ struct wcd_cpe_core { int cpe_debug_mode; /* callbacks for codec specific implementation */ struct wcd_cpe_cdc_cb cpe_cdc_cb; const struct wcd_cpe_cdc_cb *cpe_cdc_cb; /* work to handle CPE SSR*/ struct work_struct ssr_work; Loading Loading @@ -118,7 +122,7 @@ struct wcd_cpe_params { struct snd_soc_codec *codec; struct wcd_cpe_core * (*get_cpe_core) ( struct snd_soc_codec *); struct wcd_cpe_cdc_cb *cdc_cb; const struct wcd_cpe_cdc_cb *cdc_cb; int dbg_mode; u16 cdc_major_ver; u16 cdc_minor_ver; Loading @@ -127,5 +131,5 @@ struct wcd_cpe_params { int wcd_cpe_ssr_event(void *core_handle, enum wcd_cpe_ssr_state_event event); struct wcd_cpe_core *wcd_cpe_init_and_boot(const char *, struct wcd_cpe_core *wcd_cpe_init(const char *, struct snd_soc_codec *, struct wcd_cpe_params *params); sound/soc/msm/apq8084.c +0 −77 Original line number Diff line number Diff line Loading @@ -88,33 +88,6 @@ static void *adsp_state_notifier; #define ADSP_STATE_READY_TIMEOUT_MS 3000 struct cpe_load_priv { void *cdc_handle; struct kobject *cpe_load_kobj; struct attribute_group *attr_group; }; static int cpe_load; static ssize_t cpe_load_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count); static struct kobj_attribute cpe_load_attr = __ATTR(cpe_load, 0600, NULL, cpe_load_store); static struct attribute *attrs[] = { &cpe_load_attr.attr, NULL, }; static struct attribute_group attr_grp = { .attrs = attrs, }; static struct cpe_load_priv cpe_priv; static inline int param_is_mask(int p) { return ((p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) && Loading Loading @@ -2111,44 +2084,6 @@ static int msm_snd_get_ext_clk_cnt(void) return clk_users; } static int apq8084_tomtom_cpe_enable(struct snd_soc_codec *codec) { int ret = 0; ret = tomtom_enable_cpe(codec); if (IS_ERR_VALUE(ret)) pr_err("%s: CPE enable failed, err (0x%x)\n", __func__, ret); return ret; } static ssize_t cpe_load_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) { int ret = 0; if (cpe_load) { pr_err("%s: CPE already loaded\n", __func__); return count; } sscanf(buf, "%du", &cpe_load); if (cpe_load) { ret = apq8084_tomtom_cpe_enable(cpe_priv.cdc_handle); if (IS_ERR_VALUE(ret)) cpe_load = 0; else pr_info("%s: CPE enabled for tomtom_codec\n", __func__); } return count; } static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) { int err; Loading Loading @@ -2326,18 +2261,6 @@ static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) tomtom_register_ext_clk_cb(msm_snd_enable_codec_ext_clk, msm_snd_get_ext_clk_cnt, rtd->codec); cpe_priv.cdc_handle = codec; cpe_priv.attr_group = &attr_grp; cpe_priv.cpe_load_kobj = kobject_create_and_add("snd_apq8084", kernel_kobj); if (!cpe_priv.cpe_load_kobj) { pr_err("%s: cpe_load: sysfs create_add failed\n", __func__); } else if (sysfs_create_group(cpe_priv.cpe_load_kobj, cpe_priv.attr_group)) { pr_err("%s: sysfs_create_group failed\n", __func__); kobject_del(cpe_priv.cpe_load_kobj); } err = msm_snd_enable_codec_ext_clk(rtd->codec, 1, false); if (IS_ERR_VALUE(err)) { Loading Loading
sound/soc/codecs/wcd9330.c +47 −23 Original line number Diff line number Diff line Loading @@ -2678,6 +2678,21 @@ static int tomtom_codec_enable_adc(struct snd_soc_dapm_widget *w, return 0; } static int tomtom_codec_ext_clk_en(struct snd_soc_codec *codec, int enable, bool dapm) { struct tomtom_priv *tomtom = snd_soc_codec_get_drvdata(codec); if (!tomtom->codec_ext_clk_en_cb) { dev_err(codec->dev, "%s: Invalid ext_clk_callback\n", __func__); return -EINVAL; } return tomtom->codec_ext_clk_en_cb(codec, enable, dapm); } /* tomtom_codec_internal_rco_ctrl( ) * Make sure that BG_CLK_LOCK is not acquired. Exit if acquired to avoid * potential deadlock as ext_clk_en_cb() also tries to acquire the same Loading @@ -2687,11 +2702,21 @@ static int tomtom_codec_internal_rco_ctrl(struct snd_soc_codec *codec, bool enable) { struct tomtom_priv *tomtom = snd_soc_codec_get_drvdata(codec); int ret = 0; if (mutex_is_locked(&tomtom->resmgr.codec_bg_clk_lock)) { dev_err(codec->dev, "%s: BG_CLK already acquired\n", __func__); return -EINVAL; ret = -EINVAL; goto done; } if (!tomtom->codec_ext_clk_en_cb) { dev_err(codec->dev, "%s: Invalid ext_clk_callback\n", __func__); ret = -EINVAL; goto done; } if (enable) { Loading @@ -2702,14 +2727,14 @@ static int tomtom_codec_internal_rco_ctrl(struct snd_soc_codec *codec, WCD9XXX_CLK_RCO); WCD9XXX_BG_CLK_UNLOCK(&tomtom->resmgr); } else { tomtom->codec_ext_clk_en_cb(codec, true, false); tomtom_codec_ext_clk_en(codec, true, false); WCD9XXX_BG_CLK_LOCK(&tomtom->resmgr); tomtom->resmgr.ext_clk_users = tomtom->codec_get_ext_clk_cnt(); wcd9xxx_resmgr_get_clk_block(&tomtom->resmgr, WCD9XXX_CLK_RCO); WCD9XXX_BG_CLK_UNLOCK(&tomtom->resmgr); tomtom->codec_ext_clk_en_cb(codec, false, false); tomtom_codec_ext_clk_en(codec, false, false); } } else { Loading @@ -2719,7 +2744,8 @@ static int tomtom_codec_internal_rco_ctrl(struct snd_soc_codec *codec, WCD9XXX_BG_CLK_UNLOCK(&tomtom->resmgr); } return 0; done: return ret; } static int tomtom_codec_enable_aux_pga(struct snd_soc_dapm_widget *w, Loading Loading @@ -7832,38 +7858,29 @@ static int tomtom_codec_fll_enable(struct snd_soc_codec *codec, return 0; } static void tomtom_codec_cpe_setup_callbacks( struct wcd_cpe_cdc_cb *cpe_cb, int (*cdc_ext_clk)(struct snd_soc_codec *codec, int enable, bool dapm)) { cpe_cb->cdc_clk_en = tomtom_codec_internal_rco_ctrl; cpe_cb->cpe_clk_en = tomtom_codec_fll_enable; cpe_cb->slimtx_lab_en = tomtom_codec_enable_slimtx_mad; if (cdc_ext_clk == NULL) pr_err("%s: MCLK could not be set", __func__); cpe_cb->cdc_ext_clk = cdc_ext_clk; } static const struct wcd_cpe_cdc_cb cpe_cb = { .cdc_clk_en = tomtom_codec_internal_rco_ctrl, .cpe_clk_en = tomtom_codec_fll_enable, .slimtx_lab_en = tomtom_codec_enable_slimtx_mad, .cdc_ext_clk = tomtom_codec_ext_clk_en, }; int tomtom_enable_cpe(struct snd_soc_codec *codec) static int tomtom_cpe_initialize(struct snd_soc_codec *codec) { struct tomtom_priv *tomtom = snd_soc_codec_get_drvdata(codec); struct wcd_cpe_params cpe_params; struct wcd_cpe_cdc_cb cpe_cdc_cb; tomtom_codec_cpe_setup_callbacks(&cpe_cdc_cb, tomtom->codec_ext_clk_en_cb); memset(&cpe_params, 0, sizeof(struct wcd_cpe_params)); cpe_params.codec = codec; cpe_params.get_cpe_core = tomtom_codec_get_cpe_core; cpe_params.cdc_cb = &cpe_cdc_cb; cpe_params.cdc_cb = &cpe_cb; cpe_params.dbg_mode = cpe_debug_mode; cpe_params.cdc_major_ver = TOMTOM_CPE_MAJOR_VER; cpe_params.cdc_minor_ver = TOMTOM_CPE_MINOR_VER; cpe_params.cdc_id = TOMTOM_CPE_CDC_ID; tomtom->cpe_core = wcd_cpe_init_and_boot("cpe", codec, tomtom->cpe_core = wcd_cpe_init("cpe", codec, &cpe_params); if (IS_ERR_OR_NULL(tomtom->cpe_core)) { dev_err(codec->dev, Loading @@ -7874,7 +7891,6 @@ int tomtom_enable_cpe(struct snd_soc_codec *codec) return 0; } EXPORT_SYMBOL(tomtom_enable_cpe); int tomtom_enable_qfuse_sensing(struct snd_soc_codec *codec) { Loading Loading @@ -8052,6 +8068,14 @@ static int tomtom_codec_probe(struct snd_soc_codec *codec) snd_soc_dapm_sync(dapm); codec->ignore_pmdown_time = 1; ret = tomtom_cpe_initialize(codec); if (ret) { dev_info(codec->dev, "%s: cpe initialization failed, ret = %d\n", __func__, ret); /* Do not fail probe if CPE failed */ ret = 0; } return ret; err_pdata: Loading
sound/soc/codecs/wcd9330.h +0 −1 Original line number Diff line number Diff line Loading @@ -125,6 +125,5 @@ extern void tomtom_register_ext_clk_cb( int enable, bool dapm), int (*get_ext_clk_cnt) (void), struct snd_soc_codec *codec); extern int tomtom_enable_cpe(struct snd_soc_codec *codec); extern int tomtom_enable_qfuse_sensing(struct snd_soc_codec *codec); #endif
sound/soc/codecs/wcd_cpe_core.c +164 −39 Original line number Diff line number Diff line Loading @@ -98,6 +98,32 @@ static void wcd_cpe_svc_event_cb(const struct cpe_svc_notification *param); static int wcd_cpe_setup_irqs(struct wcd_cpe_core *core); static void wcd_cpe_cleanup_irqs(struct wcd_cpe_core *core); struct cpe_load_priv { void *cdc_handle; int cpe_load; struct kobject *cpe_load_kobj; struct attribute_group *attr_group; }; static ssize_t wcd_cpe_load_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count); static struct kobj_attribute cpe_load_attr = __ATTR(load, 0600, NULL, wcd_cpe_load_store); static struct attribute *attrs[] = { &cpe_load_attr.attr, NULL, }; static struct attribute_group attr_grp = { .attrs = attrs, }; static struct cpe_load_priv cpe_priv; /* wcd_cpe_lsm_session_active: check if any session is active * return true if any session is active. */ Loading Loading @@ -245,21 +271,21 @@ static int wcd_cpe_enable_cpe_clks(struct wcd_cpe_core *core, bool enable) { int ret = 0; if (!core || !core->cpe_cdc_cb.cdc_clk_en || !core->cpe_cdc_cb.cpe_clk_en) { if (!core || !core->cpe_cdc_cb || !core->cpe_cdc_cb->cpe_clk_en) { pr_err("%s: invalid handle\n", __func__); return -EINVAL; } ret = core->cpe_cdc_cb.cdc_clk_en(core->codec, enable); ret = core->cpe_cdc_cb->cdc_clk_en(core->codec, enable); if (ret) { dev_err(core->dev, "%s: Failed to enable RCO\n", __func__); return ret; } ret = core->cpe_cdc_cb.cpe_clk_en(core->codec, enable); ret = core->cpe_cdc_cb->cpe_clk_en(core->codec, enable); if (ret) { dev_err(core->dev, "%s: cpe_clk_en() failed, err = %d\n", Loading Loading @@ -730,6 +756,17 @@ int wcd_cpe_ssr_event(void *core_handle, return -EINVAL; } /* * If CPE is not even enabled, the SSR event for * CPE needs to be ignored */ if (core->ssr_type == WCD_CPE_INITIALIZED) { dev_info(core->dev, "%s: CPE initialized but not enabled, skip CPE ssr\n", __func__); return 0; } dev_dbg(core->dev, "%s: Schedule ssr work, event = %d\n", __func__, core->ssr_type); Loading Loading @@ -1052,16 +1089,99 @@ fail_engine_irq: } /* * wcd_cpe_init_and_boot: Initialize and bootup CPE hardware block * wcd_cpe_enable: setup the cpe interrupts and schedule * the work to download image and bootup the CPE. * core: handle to cpe core structure */ static int wcd_cpe_enable(struct wcd_cpe_core *core) { int ret = 0; if (!core) { pr_err("%s: Invalid handle to core\n", __func__); ret = -EINVAL; goto done; } if (core->ssr_type != WCD_CPE_INITIALIZED) { dev_err(core->dev, "%s: CPE not initialized, state = 0x%x\n", __func__, core->ssr_type); ret = -EINVAL; goto done; } ret = wcd_cpe_setup_irqs(core); if (ret) { dev_err(core->dev, "%s: CPE IRQs setup failed, error = %d\n", __func__, ret); goto done; } core->ssr_type = WCD_CPE_ENABLED; schedule_work(&core->load_fw_work); done: return ret; } /* * wcd_cpe_load_store: Function invoked with sysfs property * is written to. Enable CPE if value of the cpe_load * property is non-zero. * kobj: Kobject associated with the sysfs property * attr: The attribute that is written to * buf: holds the data that is written * count: number of data bytes in the buffer */ static ssize_t wcd_cpe_load_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) { struct wcd_cpe_core *core; int ret = 0; if (cpe_priv.cpe_load) { pr_err("%s: CPE already loaded\n", __func__); goto done; } core = wcd_cpe_get_core_handle(cpe_priv.cdc_handle); if (!core) { pr_err("%s: Invalid core handle\n", __func__); goto done; } sscanf(buf, "%du", &cpe_priv.cpe_load); if (cpe_priv.cpe_load) { ret = wcd_cpe_enable(core); if (IS_ERR_VALUE(ret)) cpe_priv.cpe_load = 0; else pr_info("%s: CPE enabled for tomtom_codec\n", __func__); } done: return count; } /* * wcd_cpe_init: Initialize CPE related structures * @img_fname: filename for firmware image * @codec: handle to codec requesting for image download * @params: parameter structure passed from caller * * This API will initialize the cpe core and schedule work * to perform firmware image download to CPE and bootup * CPE. Will also request for CPE related interrupts. * This API will initialize the cpe core but will not * download the image or boot the cpe core. */ struct wcd_cpe_core *wcd_cpe_init_and_boot(const char *img_fname, struct wcd_cpe_core *wcd_cpe_init(const char *img_fname, struct snd_soc_codec *codec, struct wcd_cpe_params *params) { Loading Loading @@ -1114,10 +1234,7 @@ struct wcd_cpe_core *wcd_cpe_init_and_boot(const char *img_fname, core->cdc_info.minor_version = params->cdc_minor_ver; core->cdc_info.id = params->cdc_id; core->cpe_cdc_cb.cdc_clk_en = params->cdc_cb->cdc_clk_en; core->cpe_cdc_cb.cpe_clk_en = params->cdc_cb->cpe_clk_en; core->cpe_cdc_cb.cdc_ext_clk = params->cdc_cb->cdc_ext_clk; core->cpe_cdc_cb.slimtx_lab_en = params->cdc_cb->slimtx_lab_en; core->cpe_cdc_cb = params->cdc_cb; INIT_WORK(&core->load_fw_work, wcd_cpe_load_fw_image); INIT_WORK(&core->ssr_work, wcd_cpe_ssr_work); Loading Loading @@ -1154,13 +1271,6 @@ struct wcd_cpe_core *wcd_cpe_init_and_boot(const char *img_fname, goto fail_cpe_register; } ret = wcd_cpe_setup_irqs(core); if (ret) { dev_err(core->dev, "%s: CPE IRQs setup failed, error = %d\n", __func__, ret); goto fail_setup_irq; } card = codec->card->snd_card; snprintf(proc_name, (sizeof("cpe") + sizeof("_state") + Loading Loading @@ -1192,11 +1302,24 @@ struct wcd_cpe_core *wcd_cpe_init_and_boot(const char *img_fname, */ } schedule_work(&core->load_fw_work); return core; cpe_priv.cdc_handle = codec; cpe_priv.attr_group = &attr_grp; cpe_priv.cpe_load_kobj = kobject_create_and_add("wcd_cpe", kernel_kobj); if (!cpe_priv.cpe_load_kobj) { pr_err("%s: cpe_load: sysfs create_add failed\n", __func__); goto fail_cpe_register; } else if (sysfs_create_group(cpe_priv.cpe_load_kobj, cpe_priv.attr_group)) { pr_err("%s: sysfs_create_group failed\n", __func__); kobject_del(cpe_priv.cpe_load_kobj); goto fail_cpe_register; } core->ssr_type = WCD_CPE_INITIALIZED; fail_setup_irq: cpe_svc_deregister(core->cpe_handle, core->cpe_reg_handle); return core; fail_cpe_register: cpe_svc_deinitialize(core->cpe_handle); Loading @@ -1205,7 +1328,7 @@ fail_cpe_initialize: kfree(core); return NULL; } EXPORT_SYMBOL(wcd_cpe_init_and_boot); EXPORT_SYMBOL(wcd_cpe_init); /* * wcd_cpe_cmi_lsm_callback: callback called from cpe services Loading Loading @@ -2415,17 +2538,19 @@ static int slim_master_read_enable(void *core_handle, lsm_params = &lab_s->hw_params; /* The sequence should be maintained strictly */ WCD_CPE_GRAB_LOCK(&session->lsm_lock, "lsm"); if (core->cpe_cdc_cb.cdc_ext_clk) core->cpe_cdc_cb.cdc_ext_clk(codec, true, false); if (core->cpe_cdc_cb->cdc_ext_clk) core->cpe_cdc_cb->cdc_ext_clk(codec, true, false); else { pr_err("%s: MCLK cannot be enabled NULL\n", __func__); pr_err("%s: Invalid callback for codec ext clk\n", __func__); rc = -EINVAL; goto exit; } if (core->cpe_cdc_cb.slimtx_lab_en) core->cpe_cdc_cb.slimtx_lab_en(codec, 1); if (core->cpe_cdc_cb->slimtx_lab_en) core->cpe_cdc_cb->slimtx_lab_en(codec, 1); else { pr_err("%s: Err slim slave cannot be enabled\n", pr_err("%s: Failed to enable codec slave port\n", __func__); rc = -EINVAL; goto fail_mclk; Loading Loading @@ -2459,9 +2584,9 @@ static int slim_master_read_enable(void *core_handle, return 0; fail_slim_open: core->cpe_cdc_cb.slimtx_lab_en(codec, 0); core->cpe_cdc_cb->slimtx_lab_en(codec, 0); fail_mclk: core->cpe_cdc_cb.cdc_ext_clk(codec, false, false); core->cpe_cdc_cb->cdc_ext_clk(codec, false, false); exit: WCD_CPE_REL_LOCK(&session->lsm_lock, "lsm"); return rc; Loading Loading @@ -2514,10 +2639,10 @@ static int wcd_cpe_lsm_stop_lab(void *core_handle, lab_s = &session->lab; WCD_CPE_GRAB_LOCK(&session->lsm_lock, "lsm"); /* This seqeunce should be followed strictly for closing sequence */ if (core->cpe_cdc_cb.slimtx_lab_en) core->cpe_cdc_cb.slimtx_lab_en(codec, 0); if (core->cpe_cdc_cb->slimtx_lab_en) core->cpe_cdc_cb->slimtx_lab_en(codec, 0); else pr_err("%s: Err slim slave cannot be enabled\n", pr_err("%s: Failed to disable codec slave port\n", __func__); rc = wcd9xxx_slim_ch_master_close(wcd9xxx, &lab_s->slim_handle); Loading @@ -2541,10 +2666,10 @@ static int wcd_cpe_lsm_stop_lab(void *core_handle, lab_s->thread_status = MSM_LSM_LAB_THREAD_STOP; atomic_set(&lab_s->in_count, 0); lab_s->dma_write = 0; if (core->cpe_cdc_cb.cdc_ext_clk) core->cpe_cdc_cb.cdc_ext_clk(codec, false, false); if (core->cpe_cdc_cb->cdc_ext_clk) core->cpe_cdc_cb->cdc_ext_clk(codec, false, false); else pr_err("%s: MCLK cannot be disable NULL\n", pr_err("%s: Failed to disable cdc ext clk\n", __func__); WCD_CPE_REL_LOCK(&session->lsm_lock, "lsm"); return rc; Loading
sound/soc/codecs/wcd_cpe_core.h +8 −4 Original line number Diff line number Diff line Loading @@ -38,8 +38,12 @@ struct wcd_cpe_cdc_cb { }; enum wcd_cpe_ssr_state_event { /* Indicates CPE is initialized */ WCD_CPE_INITIALIZED = 0, /* Indicates CPE is enabled */ WCD_CPE_ENABLED, /* Indicates that CPE is currently active */ WCD_CPE_ACTIVE = 0, WCD_CPE_ACTIVE, /* Event from underlying bus notifying bus is down */ WCD_CPE_BUS_DOWN_EVENT, /* Event from CPE block, notifying CPE is down */ Loading Loading @@ -84,7 +88,7 @@ struct wcd_cpe_core { int cpe_debug_mode; /* callbacks for codec specific implementation */ struct wcd_cpe_cdc_cb cpe_cdc_cb; const struct wcd_cpe_cdc_cb *cpe_cdc_cb; /* work to handle CPE SSR*/ struct work_struct ssr_work; Loading Loading @@ -118,7 +122,7 @@ struct wcd_cpe_params { struct snd_soc_codec *codec; struct wcd_cpe_core * (*get_cpe_core) ( struct snd_soc_codec *); struct wcd_cpe_cdc_cb *cdc_cb; const struct wcd_cpe_cdc_cb *cdc_cb; int dbg_mode; u16 cdc_major_ver; u16 cdc_minor_ver; Loading @@ -127,5 +131,5 @@ struct wcd_cpe_params { int wcd_cpe_ssr_event(void *core_handle, enum wcd_cpe_ssr_state_event event); struct wcd_cpe_core *wcd_cpe_init_and_boot(const char *, struct wcd_cpe_core *wcd_cpe_init(const char *, struct snd_soc_codec *, struct wcd_cpe_params *params);
sound/soc/msm/apq8084.c +0 −77 Original line number Diff line number Diff line Loading @@ -88,33 +88,6 @@ static void *adsp_state_notifier; #define ADSP_STATE_READY_TIMEOUT_MS 3000 struct cpe_load_priv { void *cdc_handle; struct kobject *cpe_load_kobj; struct attribute_group *attr_group; }; static int cpe_load; static ssize_t cpe_load_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count); static struct kobj_attribute cpe_load_attr = __ATTR(cpe_load, 0600, NULL, cpe_load_store); static struct attribute *attrs[] = { &cpe_load_attr.attr, NULL, }; static struct attribute_group attr_grp = { .attrs = attrs, }; static struct cpe_load_priv cpe_priv; static inline int param_is_mask(int p) { return ((p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) && Loading Loading @@ -2111,44 +2084,6 @@ static int msm_snd_get_ext_clk_cnt(void) return clk_users; } static int apq8084_tomtom_cpe_enable(struct snd_soc_codec *codec) { int ret = 0; ret = tomtom_enable_cpe(codec); if (IS_ERR_VALUE(ret)) pr_err("%s: CPE enable failed, err (0x%x)\n", __func__, ret); return ret; } static ssize_t cpe_load_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) { int ret = 0; if (cpe_load) { pr_err("%s: CPE already loaded\n", __func__); return count; } sscanf(buf, "%du", &cpe_load); if (cpe_load) { ret = apq8084_tomtom_cpe_enable(cpe_priv.cdc_handle); if (IS_ERR_VALUE(ret)) cpe_load = 0; else pr_info("%s: CPE enabled for tomtom_codec\n", __func__); } return count; } static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) { int err; Loading Loading @@ -2326,18 +2261,6 @@ static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) tomtom_register_ext_clk_cb(msm_snd_enable_codec_ext_clk, msm_snd_get_ext_clk_cnt, rtd->codec); cpe_priv.cdc_handle = codec; cpe_priv.attr_group = &attr_grp; cpe_priv.cpe_load_kobj = kobject_create_and_add("snd_apq8084", kernel_kobj); if (!cpe_priv.cpe_load_kobj) { pr_err("%s: cpe_load: sysfs create_add failed\n", __func__); } else if (sysfs_create_group(cpe_priv.cpe_load_kobj, cpe_priv.attr_group)) { pr_err("%s: sysfs_create_group failed\n", __func__); kobject_del(cpe_priv.cpe_load_kobj); } err = msm_snd_enable_codec_ext_clk(rtd->codec, 1, false); if (IS_ERR_VALUE(err)) { Loading