ASoC: Intel: add function to load sound effect module waves
authorLu, Han <han.lu@intel.com>
Tue, 10 Mar 2015 02:41:21 +0000 (10:41 +0800)
committerMark Brown <broonie@kernel.org>
Wed, 11 Mar 2015 12:53:45 +0000 (12:53 +0000)
Try to load module waves and allocate runtime blocks for it if the firmware
image of module waves exists.

Signed-off-by: Lu, Han <han.lu@intel.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/intel/sst-haswell-dsp.c
sound/soc/intel/sst-haswell-ipc.c
sound/soc/intel/sst-haswell-ipc.h
sound/soc/intel/sst-haswell-pcm.c

index 8ad733befbbd978699477eed446ddc321280169d..b3e957d469336599c01d573ff4341afa1e891c28 100644 (file)
@@ -100,6 +100,7 @@ static int hsw_parse_module(struct sst_dsp *dsp, struct sst_fw *fw,
                && module->type != SST_HSW_MODULE_PCM
                && module->type != SST_HSW_MODULE_PCM_REFERENCE
                && module->type != SST_HSW_MODULE_PCM_CAPTURE
+               && module->type != SST_HSW_MODULE_WAVES
                && module->type != SST_HSW_MODULE_LPAL)
                return 0;
 
@@ -139,6 +140,7 @@ static int hsw_parse_module(struct sst_dsp *dsp, struct sst_fw *fw,
                        mod->type = SST_MEM_IRAM;
                        break;
                case SST_HSW_DRAM:
+               case SST_HSW_REGS:
                        ram = dsp->addr.lpe;
                        mod->offset = block->ram_offset;
                        mod->type = SST_MEM_DRAM;
index ec688f598320bf635020a00314dff53a6c921a6a..63740e36dd2620d2b927ca7f069c84d4465428f4 100644 (file)
@@ -1896,11 +1896,27 @@ void sst_hsw_init_module_state(struct sst_hsw *hsw)
        /* the base fw contains several modules */
        for (id = SST_HSW_MODULE_BASE_FW; id < SST_HSW_MAX_MODULE_ID; id++) {
                module = sst_module_get_from_id(hsw->dsp, id);
-               if (module)
-                       module->state = SST_MODULE_STATE_ACTIVE;
+               if (module) {
+                       /* module waves is active only after being enabled */
+                       if (id == SST_HSW_MODULE_WAVES)
+                               module->state = SST_MODULE_STATE_INITIALIZED;
+                       else
+                               module->state = SST_MODULE_STATE_ACTIVE;
+               }
        }
 }
 
+bool sst_hsw_is_module_loaded(struct sst_hsw *hsw, u32 module_id)
+{
+       struct sst_module *module;
+
+       module = sst_module_get_from_id(hsw->dsp, module_id);
+       if (module == NULL || module->state == SST_MODULE_STATE_UNLOADED)
+               return false;
+       else
+               return true;
+}
+
 int sst_hsw_module_load(struct sst_hsw *hsw,
        u32 module_id, u32 instance_id, char *name)
 {
@@ -2022,6 +2038,9 @@ int sst_hsw_dsp_init(struct device *dev, struct sst_pdata *pdata)
        if (ret < 0)
                goto fw_err;
 
+       /* try to load module waves */
+       sst_hsw_module_load(hsw, SST_HSW_MODULE_WAVES, 0, "intel/IntcPP01.bin");
+
        /* allocate scratch mem regions */
        ret = sst_block_alloc_scratch(hsw->dsp);
        if (ret < 0)
index e071b3a54eaecbbfc96f85edf26eb7811e32c9bb..208724b74cf7b5246c1c004d8c4c1e7b5a8fbe10 100644 (file)
@@ -469,6 +469,7 @@ struct sst_dsp *sst_hsw_get_dsp(struct sst_hsw *hsw);
 
 /* fw module function */
 void sst_hsw_init_module_state(struct sst_hsw *hsw);
+bool sst_hsw_is_module_loaded(struct sst_hsw *hsw, u32 module_id);
 
 int sst_hsw_module_load(struct sst_hsw *hsw,
        u32 module_id, u32 instance_id, char *name);
index 7e21e8f85885e436cb896a806dde544d3cd8ec4d..a604cc4421110acb3deda7208d687a85cda217d5 100644 (file)
@@ -807,6 +807,17 @@ static int hsw_pcm_create_modules(struct hsw_priv_data *pdata)
                        pcm_data->runtime->persistent_offset;
        }
 
+       /* create runtime blocks for module waves */
+       if (sst_hsw_is_module_loaded(hsw, SST_HSW_MODULE_WAVES)) {
+               pcm_data = &pdata->pcm[HSW_PCM_COUNT-1][0];
+               pcm_data->runtime = sst_hsw_runtime_module_create(hsw,
+                       SST_HSW_MODULE_WAVES, pcm_data->persistent_offset);
+               if (pcm_data->runtime == NULL)
+                       goto err;
+               pcm_data->persistent_offset =
+                       pcm_data->runtime->persistent_offset;
+       }
+
        return 0;
 
 err:
@@ -820,12 +831,16 @@ err:
 
 static void hsw_pcm_free_modules(struct hsw_priv_data *pdata)
 {
+       struct sst_hsw *hsw = pdata->hsw;
        struct hsw_pcm_data *pcm_data;
        int i;
 
        for (i = 0; i < ARRAY_SIZE(mod_map); i++) {
                pcm_data = &pdata->pcm[mod_map[i].dai_id][mod_map[i].stream];
-
+               sst_hsw_runtime_module_free(pcm_data->runtime);
+       }
+       if (sst_hsw_is_module_loaded(hsw, SST_HSW_MODULE_WAVES)) {
+               pcm_data = &pdata->pcm[HSW_PCM_COUNT-1][0];
                sst_hsw_runtime_module_free(pcm_data->runtime);
        }
 }
@@ -984,7 +999,9 @@ static int hsw_pcm_probe(struct snd_soc_platform *platform)
        }
 
        /* allocate runtime modules */
-       hsw_pcm_create_modules(priv_data);
+       ret = hsw_pcm_create_modules(priv_data);
+       if (ret < 0)
+               goto err;
 
        /* enable runtime PM with auto suspend */
        pm_runtime_set_autosuspend_delay(platform->dev,