diff options
| -rw-r--r-- | sound/soc/intel/sst-haswell-ipc.c | 64 | ||||
| -rw-r--r-- | sound/soc/intel/sst-haswell-ipc.h | 6 | ||||
| -rw-r--r-- | sound/soc/intel/sst-haswell-pcm.c | 50 |
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 | ||
| 2013 | void 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 | |||
| 2020 | int 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 | |||
| 2032 | int 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 | |||
| 2054 | int 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 | |||
| 2008 | int sst_hsw_module_load(struct sst_hsw *hsw, | 2069 | int 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 | ||
| 42 | struct sst_hsw; | 44 | struct sst_hsw; |
| 43 | struct sst_hsw_stream; | 45 | struct sst_hsw_stream; |
| @@ -503,6 +505,10 @@ bool sst_hsw_is_module_active(struct sst_hsw *hsw, u32 module_id); | |||
| 503 | void sst_hsw_set_module_enabled_rtd3(struct sst_hsw *hsw, u32 module_id); | 505 | void sst_hsw_set_module_enabled_rtd3(struct sst_hsw *hsw, u32 module_id); |
| 504 | void sst_hsw_set_module_disabled_rtd3(struct sst_hsw *hsw, u32 module_id); | 506 | void sst_hsw_set_module_disabled_rtd3(struct sst_hsw *hsw, u32 module_id); |
| 505 | bool sst_hsw_is_module_enabled_rtd3(struct sst_hsw *hsw, u32 module_id); | 507 | bool sst_hsw_is_module_enabled_rtd3(struct sst_hsw *hsw, u32 module_id); |
| 508 | void sst_hsw_reset_param_buf(struct sst_hsw *hsw); | ||
| 509 | int sst_hsw_store_param_line(struct sst_hsw *hsw, u8 *buf); | ||
| 510 | int sst_hsw_load_param_line(struct sst_hsw *hsw, u8 *buf); | ||
| 511 | int sst_hsw_launch_param_buf(struct sst_hsw *hsw); | ||
| 506 | 512 | ||
| 507 | int sst_hsw_module_load(struct sst_hsw *hsw, | 513 | int 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 | ||
| 369 | static 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 | |||
| 380 | static 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 */ |
| 370 | static const DECLARE_TLV_DB_SCALE(hsw_vol_tlv, -9000, 300, 1); | 413 | static 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 | } |
