aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMisael Lopez Cruz <misael.lopez@ti.com>2011-08-01 14:07:22 -0500
committerSimon Wilson <simonwilson@google.com>2011-08-03 17:42:36 -0700
commitecffea2308111ebd3e5cb85359385dd338261f69 (patch)
tree4471853761af749fb508bab579e532c7bc3cf167
parent41ce48ea887fc79d5a7e437cf08e35b0f0e1da1d (diff)
downloadkernel_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.h9
-rw-r--r--sound/soc/omap/abe/abe_ini.c20
-rw-r--r--sound/soc/omap/abe/abe_main.c25
-rw-r--r--sound/soc/omap/abe/abe_main.h5
-rw-r--r--sound/soc/omap/omap-abe-dsp.c40
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;