aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/soc/intel/sst-haswell-ipc.c64
-rw-r--r--sound/soc/intel/sst-haswell-ipc.h6
-rw-r--r--sound/soc/intel/sst-haswell-pcm.c50
3 files changed, 120 insertions, 0 deletions
diff --git a/sound/soc/intel/sst-haswell-ipc.c b/sound/soc/intel/sst-haswell-ipc.c
index a97324dff8fa..43fb5f339168 100644
--- a/sound/soc/intel/sst-haswell-ipc.c
+++ b/sound/soc/intel/sst-haswell-ipc.c
@@ -341,6 +341,11 @@ struct sst_hsw {
341 /* flags bit field to track module state when resume from RTD3, 341 /* flags bit field to track module state when resume from RTD3,
342 * each bit represent state (enabled/disabled) of single module */ 342 * each bit represent state (enabled/disabled) of single module */
343 u32 enabled_modules_rtd3; 343 u32 enabled_modules_rtd3;
344
345 /* buffer to store parameter lines */
346 u32 param_idx_w; /* write index */
347 u32 param_idx_r; /* read index */
348 u8 param_buf[WAVES_PARAM_LINES][WAVES_PARAM_COUNT];
344}; 349};
345 350
346#define CREATE_TRACE_POINTS 351#define CREATE_TRACE_POINTS
@@ -2005,6 +2010,62 @@ bool sst_hsw_is_module_enabled_rtd3(struct sst_hsw *hsw, u32 module_id)
2005 return hsw->enabled_modules_rtd3 & (1 << module_id); 2010 return hsw->enabled_modules_rtd3 & (1 << module_id);
2006} 2011}
2007 2012
2013void sst_hsw_reset_param_buf(struct sst_hsw *hsw)
2014{
2015 hsw->param_idx_w = 0;
2016 hsw->param_idx_r = 0;
2017 memset((void *)hsw->param_buf, 0, sizeof(hsw->param_buf));
2018}
2019
2020int sst_hsw_store_param_line(struct sst_hsw *hsw, u8 *buf)
2021{
2022 /* save line to the first available position of param buffer */
2023 if (hsw->param_idx_w > WAVES_PARAM_LINES - 1) {
2024 dev_warn(hsw->dev, "warning: param buffer overflow!\n");
2025 return -EPERM;
2026 }
2027 memcpy(hsw->param_buf[hsw->param_idx_w], buf, WAVES_PARAM_COUNT);
2028 hsw->param_idx_w++;
2029 return 0;
2030}
2031
2032int sst_hsw_load_param_line(struct sst_hsw *hsw, u8 *buf)
2033{
2034 u8 id = 0;
2035
2036 /* read the first matching line from param buffer */
2037 while (hsw->param_idx_r < WAVES_PARAM_LINES) {
2038 id = hsw->param_buf[hsw->param_idx_r][0];
2039 hsw->param_idx_r++;
2040 if (buf[0] == id) {
2041 memcpy(buf, hsw->param_buf[hsw->param_idx_r],
2042 WAVES_PARAM_COUNT);
2043 break;
2044 }
2045 }
2046 if (hsw->param_idx_r > WAVES_PARAM_LINES - 1) {
2047 dev_dbg(hsw->dev, "end of buffer, roll to the beginning\n");
2048 hsw->param_idx_r = 0;
2049 return 0;
2050 }
2051 return 0;
2052}
2053
2054int sst_hsw_launch_param_buf(struct sst_hsw *hsw)
2055{
2056 int ret, idx;
2057
2058 /* put all param lines to DSP through ipc */
2059 for (idx = 0; idx < hsw->param_idx_w; idx++) {
2060 ret = sst_hsw_module_set_param(hsw,
2061 SST_HSW_MODULE_WAVES, 0, hsw->param_buf[idx][0],
2062 WAVES_PARAM_COUNT, hsw->param_buf[idx]);
2063 if (ret < 0)
2064 return ret;
2065 }
2066 return 0;
2067}
2068
2008int sst_hsw_module_load(struct sst_hsw *hsw, 2069int sst_hsw_module_load(struct sst_hsw *hsw,
2009 u32 module_id, u32 instance_id, char *name) 2070 u32 module_id, u32 instance_id, char *name)
2010{ 2071{
@@ -2299,6 +2360,9 @@ int sst_hsw_dsp_init(struct device *dev, struct sst_pdata *pdata)
2299 if (ret < 0) 2360 if (ret < 0)
2300 goto boot_err; 2361 goto boot_err;
2301 2362
2363 /* init param buffer */
2364 sst_hsw_reset_param_buf(hsw);
2365
2302 /* wait for DSP boot completion */ 2366 /* wait for DSP boot completion */
2303 sst_dsp_boot(hsw->dsp); 2367 sst_dsp_boot(hsw->dsp);
2304 ret = wait_event_timeout(hsw->boot_wait, hsw->boot_complete, 2368 ret = wait_event_timeout(hsw->boot_wait, hsw->boot_complete,
diff --git a/sound/soc/intel/sst-haswell-ipc.h b/sound/soc/intel/sst-haswell-ipc.h
index 16bec433265c..06d71aefa1fe 100644
--- a/sound/soc/intel/sst-haswell-ipc.h
+++ b/sound/soc/intel/sst-haswell-ipc.h
@@ -38,6 +38,8 @@
38#define SST_HSW_MAX_INFO_SIZE 64 38#define SST_HSW_MAX_INFO_SIZE 64
39#define SST_HSW_BUILD_HASH_LENGTH 40 39#define SST_HSW_BUILD_HASH_LENGTH 40
40#define SST_HSW_IPC_MAX_SHORT_PARAMETER_SIZE 500 40#define SST_HSW_IPC_MAX_SHORT_PARAMETER_SIZE 500
41#define WAVES_PARAM_COUNT 128
42#define WAVES_PARAM_LINES 160
41 43
42struct sst_hsw; 44struct sst_hsw;
43struct sst_hsw_stream; 45struct sst_hsw_stream;
@@ -503,6 +505,10 @@ bool sst_hsw_is_module_active(struct sst_hsw *hsw, u32 module_id);
503void sst_hsw_set_module_enabled_rtd3(struct sst_hsw *hsw, u32 module_id); 505void sst_hsw_set_module_enabled_rtd3(struct sst_hsw *hsw, u32 module_id);
504void sst_hsw_set_module_disabled_rtd3(struct sst_hsw *hsw, u32 module_id); 506void sst_hsw_set_module_disabled_rtd3(struct sst_hsw *hsw, u32 module_id);
505bool sst_hsw_is_module_enabled_rtd3(struct sst_hsw *hsw, u32 module_id); 507bool sst_hsw_is_module_enabled_rtd3(struct sst_hsw *hsw, u32 module_id);
508void sst_hsw_reset_param_buf(struct sst_hsw *hsw);
509int sst_hsw_store_param_line(struct sst_hsw *hsw, u8 *buf);
510int sst_hsw_load_param_line(struct sst_hsw *hsw, u8 *buf);
511int sst_hsw_launch_param_buf(struct sst_hsw *hsw);
506 512
507int sst_hsw_module_load(struct sst_hsw *hsw, 513int sst_hsw_module_load(struct sst_hsw *hsw,
508 u32 module_id, u32 instance_id, char *name); 514 u32 module_id, u32 instance_id, char *name);
diff --git a/sound/soc/intel/sst-haswell-pcm.c b/sound/soc/intel/sst-haswell-pcm.c
index b3de87aac373..b40ec746bc19 100644
--- a/sound/soc/intel/sst-haswell-pcm.c
+++ b/sound/soc/intel/sst-haswell-pcm.c
@@ -366,6 +366,49 @@ static int hsw_waves_switch_put(struct snd_kcontrol *kcontrol,
366 return ret; 366 return ret;
367} 367}
368 368
369static int hsw_waves_param_get(struct snd_kcontrol *kcontrol,
370 struct snd_ctl_elem_value *ucontrol)
371{
372 struct snd_soc_platform *platform = snd_soc_kcontrol_platform(kcontrol);
373 struct hsw_priv_data *pdata = snd_soc_platform_get_drvdata(platform);
374 struct sst_hsw *hsw = pdata->hsw;
375
376 /* return a matching line from param buffer */
377 return sst_hsw_load_param_line(hsw, ucontrol->value.bytes.data);
378}
379
380static int hsw_waves_param_put(struct snd_kcontrol *kcontrol,
381 struct snd_ctl_elem_value *ucontrol)
382{
383 struct snd_soc_platform *platform = snd_soc_kcontrol_platform(kcontrol);
384 struct hsw_priv_data *pdata = snd_soc_platform_get_drvdata(platform);
385 struct sst_hsw *hsw = pdata->hsw;
386 int ret;
387 enum sst_hsw_module_id id = SST_HSW_MODULE_WAVES;
388 int param_id = ucontrol->value.bytes.data[0];
389 int param_size = WAVES_PARAM_COUNT;
390
391 /* clear param buffer and reset buffer index */
392 if (param_id == 0xFF) {
393 sst_hsw_reset_param_buf(hsw);
394 return 0;
395 }
396
397 /* store params into buffer */
398 ret = sst_hsw_store_param_line(hsw, ucontrol->value.bytes.data);
399 if (ret < 0)
400 return ret;
401
402 if (sst_hsw_is_module_loaded(hsw, id)) {
403 if (!sst_hsw_is_module_active(hsw, id))
404 return 0;
405
406 ret = sst_hsw_module_set_param(hsw, id, 0, param_id,
407 param_size, ucontrol->value.bytes.data);
408 }
409 return ret;
410}
411
369/* TLV used by both global and stream volumes */ 412/* TLV used by both global and stream volumes */
370static const DECLARE_TLV_DB_SCALE(hsw_vol_tlv, -9000, 300, 1); 413static const DECLARE_TLV_DB_SCALE(hsw_vol_tlv, -9000, 300, 1);
371 414
@@ -390,6 +433,9 @@ static const struct snd_kcontrol_new hsw_volume_controls[] = {
390 /* enable/disable module waves */ 433 /* enable/disable module waves */
391 SOC_SINGLE_BOOL_EXT("Waves Switch", 0, 434 SOC_SINGLE_BOOL_EXT("Waves Switch", 0,
392 hsw_waves_switch_get, hsw_waves_switch_put), 435 hsw_waves_switch_get, hsw_waves_switch_put),
436 /* set parameters to module waves */
437 SND_SOC_BYTES_EXT("Waves Set Param", WAVES_PARAM_COUNT,
438 hsw_waves_param_get, hsw_waves_param_put),
393}; 439};
394 440
395/* Create DMA buffer page table for DSP */ 441/* Create DMA buffer page table for DSP */
@@ -1220,6 +1266,10 @@ static int hsw_pcm_runtime_resume(struct device *dev)
1220 ret = sst_hsw_module_enable(hsw, SST_HSW_MODULE_WAVES, 0); 1266 ret = sst_hsw_module_enable(hsw, SST_HSW_MODULE_WAVES, 0);
1221 if (ret < 0) 1267 if (ret < 0)
1222 return ret; 1268 return ret;
1269 /* put parameters from buffer to dsp */
1270 ret = sst_hsw_launch_param_buf(hsw);
1271 if (ret < 0)
1272 return ret;
1223 /* unset flag */ 1273 /* unset flag */
1224 sst_hsw_set_module_disabled_rtd3(hsw, SST_HSW_MODULE_WAVES); 1274 sst_hsw_set_module_disabled_rtd3(hsw, SST_HSW_MODULE_WAVES);
1225 } 1275 }