diff options
author | Misael Lopez Cruz <misael.lopez@ti.com> | 2011-08-01 14:07:22 -0500 |
---|---|---|
committer | Simon Wilson <simonwilson@google.com> | 2011-08-03 17:42:36 -0700 |
commit | ecffea2308111ebd3e5cb85359385dd338261f69 (patch) | |
tree | 4471853761af749fb508bab579e532c7bc3cf167 | |
parent | 41ce48ea887fc79d5a7e437cf08e35b0f0e1da1d (diff) | |
download | kernel_samsung_tuna-ecffea2308111ebd3e5cb85359385dd338261f69.zip kernel_samsung_tuna-ecffea2308111ebd3e5cb85359385dd338261f69.tar.gz kernel_samsung_tuna-ecffea2308111ebd3e5cb85359385dd338261f69.tar.bz2 |
ASoC: ABE HAL: Allow flexible firmware loading
In preparation for ABE firmware loading from userspace,
allow ABE HAL API to receive the memory address storing
the firmware.
Change-Id: I1d0f9d7c81090eb4a67e04bf8f7f94c467fdbe71
Signed-off-by: Misael Lopez Cruz <misael.lopez@ti.com>
-rw-r--r-- | sound/soc/omap/abe/abe_api.h | 9 | ||||
-rw-r--r-- | sound/soc/omap/abe/abe_ini.c | 20 | ||||
-rw-r--r-- | sound/soc/omap/abe/abe_main.c | 25 | ||||
-rw-r--r-- | sound/soc/omap/abe/abe_main.h | 5 | ||||
-rw-r--r-- | sound/soc/omap/omap-abe-dsp.c | 40 |
5 files changed, 67 insertions, 32 deletions
diff --git a/sound/soc/omap/abe/abe_api.h b/sound/soc/omap/abe/abe_api.h index ba3f7be..a7ea963 100644 --- a/sound/soc/omap/abe/abe_api.h +++ b/sound/soc/omap/abe/abe_api.h @@ -132,15 +132,6 @@ abehal_status abe_reset_hal(void); */ abehal_status abe_load_fw_param(u32 *FW); /** - * abe_reload_fw - Reload ABE Firmware after OFF mode - */ -abehal_status abe_reload_fw(void); -/** - * abe_load_fw - Load ABE Firmware and initialize memories - * - */ -abehal_status abe_load_fw(void); -/** * abe_irq_processing - Process ABE interrupt * * This subroutine is call upon reception of "MA_IRQ_99 ABE_MPU_IRQ" Audio diff --git a/sound/soc/omap/abe/abe_ini.c b/sound/soc/omap/abe/abe_ini.c index 5a2bf08..f445da9 100644 --- a/sound/soc/omap/abe/abe_ini.c +++ b/sound/soc/omap/abe/abe_ini.c @@ -174,10 +174,10 @@ EXPORT_SYMBOL(abe_load_fw_param); * @abe: Pointer on abe handle * */ -int omap_abe_load_fw(struct omap_abe *abe) +int omap_abe_load_fw(struct omap_abe *abe, u32 *firmware) { _log(ABE_ID_LOAD_FW, 0, 0, 0); - abe_load_fw_param((u32 *) abe_firmware_array); + abe_load_fw_param(firmware); omap_abe_reset_all_ports(abe); omap_abe_build_scheduler_table(abe); omap_abe_reset_all_sequence(abe); @@ -189,10 +189,10 @@ EXPORT_SYMBOL(omap_abe_load_fw); /** * abe_reload_fw - Reload ABE Firmware after OFF mode */ -int abe_reload_fw(void) +int omap_abe_reload_fw(struct omap_abe *abe, u32 *firmware) { abe->warm_boot = 0; - abe_load_fw_param((u32 *) abe_firmware_array); + abe_load_fw_param(firmware); omap_abe_build_scheduler_table(abe); omap_abe_dbg_reset(&abe->dbg); /* IRQ circular read pointer in DMEM */ @@ -212,7 +212,17 @@ int abe_reload_fw(void) RAMP_100MS, GAIN_RIGHT_OFFSET); return 0; } -EXPORT_SYMBOL(abe_reload_fw); +EXPORT_SYMBOL(omap_abe_reload_fw); + +/** + * omap_abe_get_default_fw + * + * Get default ABE firmware + */ +u32 *omap_abe_get_default_fw(struct omap_abe *abe) +{ + return (u32 *)abe_firmware_array; +} /** * abe_build_scheduler_table diff --git a/sound/soc/omap/abe/abe_main.c b/sound/soc/omap/abe/abe_main.c index 1e874e6..86e969e 100644 --- a/sound/soc/omap/abe/abe_main.c +++ b/sound/soc/omap/abe/abe_main.c @@ -97,7 +97,9 @@ int omap_abe_connect_debug_trace(struct omap_abe *abe, struct omap_abe_dma *dma2); int omap_abe_reset_hal(struct omap_abe *abe); -int omap_abe_load_fw(struct omap_abe *abe); +int omap_abe_load_fw(struct omap_abe *abe, u32 *firmware); +int omap_abe_reload_fw(struct omap_abe *abe, u32 *firmware); +u32* omap_abe_get_default_fw(struct omap_abe *abe); int omap_abe_wakeup(struct omap_abe *abe); int omap_abe_irq_processing(struct omap_abe *abe); int omap_abe_clear_irq(struct omap_abe *abe); @@ -205,14 +207,31 @@ EXPORT_SYMBOL(abe_reset_hal); * abe_load_fw - Load ABE Firmware and initialize memories * */ -u32 abe_load_fw(void) +u32 abe_load_fw(u32 *firmware) { - omap_abe_load_fw(abe); + omap_abe_load_fw(abe, firmware); return 0; } EXPORT_SYMBOL(abe_load_fw); /** + * abe_reload_fw - Reload ABE Firmware and initialize memories + * + */ +u32 abe_reload_fw(u32 *firmware) +{ + omap_abe_reload_fw(abe, firmware); + return 0; +} +EXPORT_SYMBOL(abe_reload_fw); + +u32* abe_get_default_fw(void) +{ + return omap_abe_get_default_fw(abe); +} +EXPORT_SYMBOL(abe_get_default_fw); + +/** * abe_wakeup - Wakeup ABE * * Wakeup ABE in case of retention diff --git a/sound/soc/omap/abe/abe_main.h b/sound/soc/omap/abe/abe_main.h index 15f23cc..cf18376 100644 --- a/sound/soc/omap/abe/abe_main.h +++ b/sound/soc/omap/abe/abe_main.h @@ -615,8 +615,9 @@ extern u32 abe_irq_pingpong_player_id; void abe_init_mem(void __iomem **_io_base); u32 abe_reset_hal(void); -u32 abe_load_fw(void); -u32 abe_reload_fw(void); +int abe_load_fw(u32 *firmware); +int abe_reload_fw(u32 *firmware); +u32 *abe_get_default_fw(void); u32 abe_wakeup(void); u32 abe_irq_processing(void); u32 abe_clear_irq(void); diff --git a/sound/soc/omap/omap-abe-dsp.c b/sound/soc/omap/omap-abe-dsp.c index 6ad53c3..0dd63e2 100644 --- a/sound/soc/omap/omap-abe-dsp.c +++ b/sound/soc/omap/omap-abe-dsp.c @@ -117,6 +117,7 @@ struct abe_data { /* coefficients */ struct fw_header hdr; + u32 *firmware; s32 *equ[ABE_MAX_EQU]; int equ_profile[ABE_MAX_EQU]; struct soc_enum equalizer_enum[ABE_MAX_EQU]; @@ -1891,7 +1892,7 @@ static int aess_restore_context(struct abe_data *abe) loss_count = pdata->get_context_loss_count(abe->dev); if (loss_count != the_abe->loss_count) - abe_reload_fw(); + abe_reload_fw(abe->firmware); /* TODO: Find a better way to save/retore gains after dor OFF mode */ abe_unmute_gain(MIXSDT, MIX_SDT_INPUT_UP_MIXER); @@ -2248,7 +2249,7 @@ static int abe_resume(struct snd_soc_dai *dai) } if (loss_count != abe->loss_count) - abe_reload_fw(); + abe_reload_fw(abe->firmware); switch (dai->id) { case OMAP_ABE_DAI_PDM_UL: @@ -2316,10 +2317,10 @@ static int abe_probe(struct snd_soc_platform *platform) /* get firmware and coefficients header info */ memcpy(&abe->hdr, fw->data, sizeof(struct fw_header)); if (abe->hdr.firmware_size > ABE_MAX_FW_SIZE) { - dev_err(abe->dev, "Firmware too large at %d bytes: %d\n", + dev_err(abe->dev, "Firmware too large at %d bytes: %d\n", abe->hdr.firmware_size, ret); - ret = -EINVAL; - goto err_fw; + ret = -EINVAL; + goto err_fw; } dev_dbg(abe->dev, "ABE firmware size %d bytes\n", abe->hdr.firmware_size); @@ -2380,12 +2381,26 @@ static int abe_probe(struct snd_soc_platform *platform) abe->equ[i] = abe->equ[i - 1] + abe->equ_texts[i - 1].count * abe->equ_texts[i - 1].coeff * sizeof(s32); } + + /* store ABE firmware for later context restore */ + abe->firmware = kzalloc(abe->hdr.firmware_size, GFP_KERNEL); + if (abe->firmware == NULL) { + ret = -ENOMEM; + goto err_texts; + } + + memcpy(abe->firmware, + fw->data + sizeof(struct fw_header) + abe->hdr.coeff_size, + abe->hdr.firmware_size); +#else + abe->firmware = abe_get_default_fw(); #endif + ret = request_irq(abe->irq, abe_irq_handler, 0, "ABE", (void *)abe); if (ret) { dev_err(platform->dev, "request for ABE IRQ %d failed %d\n", abe->irq, ret); - goto err_texts; + goto err_irq; } /* query supported opps */ @@ -2425,12 +2440,7 @@ static int abe_probe(struct snd_soc_platform *platform) abe_reset_hal(); -#if 0 -#warning fixup load fw args - //abe_load_fw(fw->data + sizeof(struct fw_header) + abe->hdr.coeff_size); -#else - abe_load_fw(); -#endif + abe_load_fw(abe->firmware); /* "tick" of the audio engine */ abe_write_event_generator(EVENT_TIMER); @@ -2449,8 +2459,10 @@ static int abe_probe(struct snd_soc_platform *platform) err_opp: rcu_read_unlock(); free_irq(abe->irq, (void *)abe); -err_texts: +err_irq: #if defined(CONFIG_SND_OMAP_SOC_ABE_DSP_MODULE) + kfree(abe->firmware); +err_texts: for (i = 0; i < abe->hdr.num_equ; i++) kfree(abe->equalizer_enum[i].texts); kfree(abe->equ[0]); @@ -2476,6 +2488,8 @@ static int abe_remove(struct snd_soc_platform *platform) kfree(abe->equ[0]); kfree(abe->equ_texts); #endif + kfree(abe->firmware); + pm_runtime_disable(abe->dev); return 0; |