@@ -341,6 +341,11 @@ struct sst_hsw {
/* flags bit field to track module state when resume from RTD3,
* each bit represent state (enabled/disabled) of single module */
u32 enabled_modules_rtd3;
+
+ /* buffer to store parameter lines */
+ u32 param_idx_w; /* write index */
+ u32 param_idx_r; /* read index */
+ u8 param_buf[WAVES_PARAM_LINES][WAVES_PARAM_COUNT];
};
#define CREATE_TRACE_POINTS
@@ -2005,6 +2010,64 @@ bool sst_hsw_is_module_enabled_rtd3(struct sst_hsw *hsw, u32 module_id)
return hsw->enabled_modules_rtd3 & (1 << module_id);
}
+void sst_hsw_reset_param_buf(struct sst_hsw *hsw)
+{
+ hsw->param_idx_w = 0;
+ hsw->param_idx_r = 0;
+ memset((void *)hsw->param_buf, 0, sizeof(hsw->param_buf));
+}
+
+int sst_hsw_store_param_line(struct sst_hsw *hsw, u8 *buf)
+{
+ if (hsw->param_idx_w > WAVES_PARAM_LINES - 1) {
+ dev_warn(hsw->dev, "warning: param buffer overflow!\n");
+ return -EPERM;
+ }
+ memcpy(hsw->param_buf[hsw->param_idx_w], buf, WAVES_PARAM_COUNT);
+ hsw->param_idx_w++;
+ return 0;
+}
+
+int sst_hsw_load_param_line(struct sst_hsw *hsw, u8 *buf)
+{
+ u8 id = 0;
+
+ /* iterate param buffer lines, return the first matching line */
+ while (hsw->param_idx_r < WAVES_PARAM_LINES) {
+ id = hsw->param_buf[hsw->param_idx_r][0];
+ hsw->param_idx_r++;
+ if (buf[0] == id) {
+ memcpy(buf, hsw->param_buf[hsw->param_idx_r],
+ WAVES_PARAM_COUNT);
+ break;
+ }
+ }
+ if (hsw->param_idx_r > WAVES_PARAM_LINES - 1) {
+ dev_dbg(hsw->dev, "end of buffer, roll to the beginning\n");
+ hsw->param_idx_r = 0;
+ return 0;
+ }
+ return 0;
+}
+
+int sst_hsw_launch_param_buf(struct sst_hsw *hsw)
+{
+ int ret, idx;
+
+ for (idx = 0; idx < hsw->param_idx_w; idx++) {
+ /* 0 is invalid parameter id */
+ if (0 == hsw->param_buf[idx][0])
+ continue;
+
+ ret = sst_hsw_module_set_param(hsw,
+ SST_HSW_MODULE_WAVES, 0, hsw->param_buf[idx][0],
+ WAVES_PARAM_COUNT, hsw->param_buf[idx]);
+ if (ret < 0)
+ return ret;
+ }
+ return 0;
+}
+
int sst_hsw_module_load(struct sst_hsw *hsw,
u32 module_id, u32 instance_id, char *name)
{
@@ -2299,6 +2362,9 @@ int sst_hsw_dsp_init(struct device *dev, struct sst_pdata *pdata)
if (ret < 0)
goto boot_err;
+ /* init param buffer */
+ sst_hsw_reset_param_buf(hsw);
+
/* wait for DSP boot completion */
sst_dsp_boot(hsw->dsp);
ret = wait_event_timeout(hsw->boot_wait, hsw->boot_complete,
@@ -39,6 +39,7 @@
#define SST_HSW_BUILD_HASH_LENGTH 40
#define SST_HSW_IPC_MAX_SHORT_PARAMETER_SIZE 500
#define WAVES_PARAM_COUNT 128
+#define WAVES_PARAM_LINES 160
struct sst_hsw;
struct sst_hsw_stream;
@@ -504,6 +505,10 @@ bool sst_hsw_is_module_active(struct sst_hsw *hsw, u32 module_id);
void sst_hsw_set_module_enabled_rtd3(struct sst_hsw *hsw, u32 module_id);
void sst_hsw_set_module_disabled_rtd3(struct sst_hsw *hsw, u32 module_id);
bool sst_hsw_is_module_enabled_rtd3(struct sst_hsw *hsw, u32 module_id);
+void sst_hsw_reset_param_buf(struct sst_hsw *hsw);
+int sst_hsw_store_param_line(struct sst_hsw *hsw, u8 *buf);
+int sst_hsw_load_param_line(struct sst_hsw *hsw, u8 *buf);
+int sst_hsw_launch_param_buf(struct sst_hsw *hsw);
int sst_hsw_module_load(struct sst_hsw *hsw,
u32 module_id, u32 instance_id, char *name);
@@ -369,8 +369,12 @@ static int hsw_waves_switch_put(struct snd_kcontrol *kcontrol,
static int hsw_waves_param_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
- /* keep an empty function here to match alsa-lib calling */
- return 0;
+ struct snd_soc_platform *platform = snd_soc_kcontrol_platform(kcontrol);
+ struct hsw_priv_data *pdata = snd_soc_platform_get_drvdata(platform);
+ struct sst_hsw *hsw = pdata->hsw;
+
+ /* return a matching line from param buffer */
+ return sst_hsw_load_param_line(hsw, ucontrol->value.bytes.data);
}
static int hsw_waves_param_put(struct snd_kcontrol *kcontrol,
@@ -384,9 +388,21 @@ static int hsw_waves_param_put(struct snd_kcontrol *kcontrol,
int param_id = ucontrol->value.bytes.data[0];
int param_size = WAVES_PARAM_COUNT;
+ /* clear param buffer and reset buffer index */
+ if (param_id == 0xFF) {
+ sst_hsw_reset_param_buf(hsw);
+ return 0;
+ }
+
+ /* store params into buffer */
+ ret = sst_hsw_store_param_line(hsw, ucontrol->value.bytes.data);
+ if (ret < 0)
+ return ret;
+
if (sst_hsw_is_module_loaded(hsw, id)) {
if (!sst_hsw_is_module_active(hsw, id))
return 0;
+
ret = sst_hsw_module_set_param(hsw, id, 0, param_id,
param_size, ucontrol->value.bytes.data);
}
@@ -1250,6 +1266,10 @@ static int hsw_pcm_runtime_resume(struct device *dev)
ret = sst_hsw_module_enable(hsw, SST_HSW_MODULE_WAVES, 0);
if (ret < 0)
return ret;
+ /* put parameters from buffer to dsp */
+ ret = sst_hsw_launch_param_buf(hsw);
+ if (ret < 0)
+ return ret;
/* unset flag */
sst_hsw_set_module_disabled_rtd3(hsw, SST_HSW_MODULE_WAVES);
}