diff options
author | Vinod Koul <vinod.koul@intel.com> | 2014-10-15 10:42:56 -0400 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2014-10-20 07:20:32 -0400 |
commit | 4fa805738e497c6f5bad53fcdc76b9759bc9dc80 (patch) | |
tree | 4176fa874eafaac9112c72c3bbf1d2361d106324 | |
parent | f114040e3ea6e07372334ade75d1ee0775c355e1 (diff) |
ASoC: Intel: mrfld: add the gain controls
The DSP has various gain modules in the path,
add these as ALSA gain controls
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Signed-off-by: Subhransu S. Prusty <subhransu.s.prusty@intel.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r-- | sound/soc/intel/Kconfig | 2 | ||||
-rw-r--r-- | sound/soc/intel/sst-atom-controls.c | 202 | ||||
-rw-r--r-- | sound/soc/intel/sst-atom-controls.h | 121 |
3 files changed, 322 insertions, 3 deletions
diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig index f5b4a9c79cdf..726f7d891a7a 100644 --- a/sound/soc/intel/Kconfig +++ b/sound/soc/intel/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config SND_MFLD_MACHINE | 1 | config SND_MFLD_MACHINE |
2 | tristate "SOC Machine Audio driver for Intel Medfield MID platform" | 2 | tristate "SOC Machine Audio driver for Intel Medfield MID platform" |
3 | depends on INTEL_SCU_IPC | 3 | depends on INTEL_SCU_IPC || COMPILE_TEST |
4 | select SND_SOC_SN95031 | 4 | select SND_SOC_SN95031 |
5 | select SND_SST_MFLD_PLATFORM | 5 | select SND_SST_MFLD_PLATFORM |
6 | help | 6 | help |
diff --git a/sound/soc/intel/sst-atom-controls.c b/sound/soc/intel/sst-atom-controls.c index 7104a34181a9..a00d506af179 100644 --- a/sound/soc/intel/sst-atom-controls.c +++ b/sound/soc/intel/sst-atom-controls.c | |||
@@ -162,6 +162,190 @@ static int sst_algo_control_set(struct snd_kcontrol *kcontrol, | |||
162 | return ret; | 162 | return ret; |
163 | } | 163 | } |
164 | 164 | ||
165 | static int sst_gain_ctl_info(struct snd_kcontrol *kcontrol, | ||
166 | struct snd_ctl_elem_info *uinfo) | ||
167 | { | ||
168 | struct sst_gain_mixer_control *mc = (void *)kcontrol->private_value; | ||
169 | |||
170 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
171 | uinfo->count = mc->stereo ? 2 : 1; | ||
172 | uinfo->value.integer.min = mc->min; | ||
173 | uinfo->value.integer.max = mc->max; | ||
174 | |||
175 | return 0; | ||
176 | } | ||
177 | |||
178 | /** | ||
179 | * sst_send_gain_cmd - send the gain algorithm IPC to the FW | ||
180 | * @gv: the stored value of gain (also contains rampduration) | ||
181 | * @mute: flag that indicates whether this was called from the | ||
182 | * digital_mute callback or directly. If called from the | ||
183 | * digital_mute callback, module will be muted/unmuted based on this | ||
184 | * flag. The flag is always 0 if called directly. | ||
185 | * | ||
186 | * Called with sst_data.lock held | ||
187 | * | ||
188 | * The user-set gain value is sent only if the user-controllable 'mute' control | ||
189 | * is OFF (indicated by gv->mute). Otherwise, the mute value (MIN value) is | ||
190 | * sent. | ||
191 | */ | ||
192 | static int sst_send_gain_cmd(struct sst_data *drv, struct sst_gain_value *gv, | ||
193 | u16 task_id, u16 loc_id, u16 module_id, int mute) | ||
194 | { | ||
195 | struct sst_cmd_set_gain_dual cmd; | ||
196 | |||
197 | dev_dbg(&drv->pdev->dev, "Enter\n"); | ||
198 | |||
199 | cmd.header.command_id = MMX_SET_GAIN; | ||
200 | SST_FILL_DEFAULT_DESTINATION(cmd.header.dst); | ||
201 | cmd.gain_cell_num = 1; | ||
202 | |||
203 | if (mute || gv->mute) { | ||
204 | cmd.cell_gains[0].cell_gain_left = SST_GAIN_MIN_VALUE; | ||
205 | cmd.cell_gains[0].cell_gain_right = SST_GAIN_MIN_VALUE; | ||
206 | } else { | ||
207 | cmd.cell_gains[0].cell_gain_left = gv->l_gain; | ||
208 | cmd.cell_gains[0].cell_gain_right = gv->r_gain; | ||
209 | } | ||
210 | |||
211 | SST_FILL_DESTINATION(2, cmd.cell_gains[0].dest, | ||
212 | loc_id, module_id); | ||
213 | cmd.cell_gains[0].gain_time_constant = gv->ramp_duration; | ||
214 | |||
215 | cmd.header.length = sizeof(struct sst_cmd_set_gain_dual) | ||
216 | - sizeof(struct sst_dsp_header); | ||
217 | |||
218 | /* we are with lock held, so call the unlocked api to send */ | ||
219 | return sst_fill_and_send_cmd_unlocked(drv, SST_IPC_IA_SET_PARAMS, | ||
220 | SST_FLAG_BLOCKED, task_id, 0, &cmd, | ||
221 | sizeof(cmd.header) + cmd.header.length); | ||
222 | } | ||
223 | |||
224 | static int sst_gain_get(struct snd_kcontrol *kcontrol, | ||
225 | struct snd_ctl_elem_value *ucontrol) | ||
226 | { | ||
227 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); | ||
228 | struct sst_gain_mixer_control *mc = (void *)kcontrol->private_value; | ||
229 | struct sst_gain_value *gv = mc->gain_val; | ||
230 | |||
231 | switch (mc->type) { | ||
232 | case SST_GAIN_TLV: | ||
233 | ucontrol->value.integer.value[0] = gv->l_gain; | ||
234 | ucontrol->value.integer.value[1] = gv->r_gain; | ||
235 | break; | ||
236 | |||
237 | case SST_GAIN_MUTE: | ||
238 | ucontrol->value.integer.value[0] = gv->mute ? 1 : 0; | ||
239 | break; | ||
240 | |||
241 | case SST_GAIN_RAMP_DURATION: | ||
242 | ucontrol->value.integer.value[0] = gv->ramp_duration; | ||
243 | break; | ||
244 | |||
245 | default: | ||
246 | dev_err(component->dev, "Invalid Input- gain type:%d\n", | ||
247 | mc->type); | ||
248 | return -EINVAL; | ||
249 | }; | ||
250 | |||
251 | return 0; | ||
252 | } | ||
253 | |||
254 | static int sst_gain_put(struct snd_kcontrol *kcontrol, | ||
255 | struct snd_ctl_elem_value *ucontrol) | ||
256 | { | ||
257 | int ret = 0; | ||
258 | struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); | ||
259 | struct sst_data *drv = snd_soc_component_get_drvdata(cmpnt); | ||
260 | struct sst_gain_mixer_control *mc = (void *)kcontrol->private_value; | ||
261 | struct sst_gain_value *gv = mc->gain_val; | ||
262 | |||
263 | mutex_lock(&drv->lock); | ||
264 | |||
265 | switch (mc->type) { | ||
266 | case SST_GAIN_TLV: | ||
267 | gv->l_gain = ucontrol->value.integer.value[0]; | ||
268 | gv->r_gain = ucontrol->value.integer.value[1]; | ||
269 | dev_dbg(cmpnt->dev, "%s: Volume %d, %d\n", | ||
270 | mc->pname, gv->l_gain, gv->r_gain); | ||
271 | break; | ||
272 | |||
273 | case SST_GAIN_MUTE: | ||
274 | gv->mute = !!ucontrol->value.integer.value[0]; | ||
275 | dev_dbg(cmpnt->dev, "%s: Mute %d\n", mc->pname, gv->mute); | ||
276 | break; | ||
277 | |||
278 | case SST_GAIN_RAMP_DURATION: | ||
279 | gv->ramp_duration = ucontrol->value.integer.value[0]; | ||
280 | dev_dbg(cmpnt->dev, "%s: Ramp Delay%d\n", | ||
281 | mc->pname, gv->ramp_duration); | ||
282 | break; | ||
283 | |||
284 | default: | ||
285 | mutex_unlock(&drv->lock); | ||
286 | dev_err(cmpnt->dev, "Invalid Input- gain type:%d\n", | ||
287 | mc->type); | ||
288 | return -EINVAL; | ||
289 | }; | ||
290 | |||
291 | if (mc->w && mc->w->power) | ||
292 | ret = sst_send_gain_cmd(drv, gv, mc->task_id, | ||
293 | mc->pipe_id | mc->instance_id, mc->module_id, 0); | ||
294 | mutex_unlock(&drv->lock); | ||
295 | |||
296 | return ret; | ||
297 | } | ||
298 | |||
299 | static const DECLARE_TLV_DB_SCALE(sst_gain_tlv_common, SST_GAIN_MIN_VALUE * 10, 10, 0); | ||
300 | |||
301 | /* Gain helper with min/max set */ | ||
302 | #define SST_GAIN(name, path_id, task_id, instance, gain_var) \ | ||
303 | SST_GAIN_KCONTROLS(name, "Gain", SST_GAIN_MIN_VALUE, SST_GAIN_MAX_VALUE, \ | ||
304 | SST_GAIN_TC_MIN, SST_GAIN_TC_MAX, \ | ||
305 | sst_gain_get, sst_gain_put, \ | ||
306 | SST_MODULE_ID_GAIN_CELL, path_id, instance, task_id, \ | ||
307 | sst_gain_tlv_common, gain_var) | ||
308 | |||
309 | #define SST_VOLUME(name, path_id, task_id, instance, gain_var) \ | ||
310 | SST_GAIN_KCONTROLS(name, "Volume", SST_GAIN_MIN_VALUE, SST_GAIN_MAX_VALUE, \ | ||
311 | SST_GAIN_TC_MIN, SST_GAIN_TC_MAX, \ | ||
312 | sst_gain_get, sst_gain_put, \ | ||
313 | SST_MODULE_ID_VOLUME, path_id, instance, task_id, \ | ||
314 | sst_gain_tlv_common, gain_var) | ||
315 | |||
316 | static struct sst_gain_value sst_gains[]; | ||
317 | |||
318 | static const struct snd_kcontrol_new sst_gain_controls[] = { | ||
319 | SST_GAIN("media0_in", SST_PATH_INDEX_MEDIA0_IN, SST_TASK_MMX, 0, &sst_gains[0]), | ||
320 | SST_GAIN("media1_in", SST_PATH_INDEX_MEDIA1_IN, SST_TASK_MMX, 0, &sst_gains[1]), | ||
321 | SST_GAIN("media2_in", SST_PATH_INDEX_MEDIA2_IN, SST_TASK_MMX, 0, &sst_gains[2]), | ||
322 | SST_GAIN("media3_in", SST_PATH_INDEX_MEDIA3_IN, SST_TASK_MMX, 0, &sst_gains[3]), | ||
323 | |||
324 | SST_GAIN("pcm0_in", SST_PATH_INDEX_PCM0_IN, SST_TASK_SBA, 0, &sst_gains[4]), | ||
325 | SST_GAIN("pcm1_in", SST_PATH_INDEX_PCM1_IN, SST_TASK_SBA, 0, &sst_gains[5]), | ||
326 | SST_GAIN("pcm1_out", SST_PATH_INDEX_PCM1_OUT, SST_TASK_SBA, 0, &sst_gains[6]), | ||
327 | SST_GAIN("pcm2_out", SST_PATH_INDEX_PCM2_OUT, SST_TASK_SBA, 0, &sst_gains[7]), | ||
328 | |||
329 | SST_GAIN("codec_in0", SST_PATH_INDEX_CODEC_IN0, SST_TASK_SBA, 0, &sst_gains[8]), | ||
330 | SST_GAIN("codec_in1", SST_PATH_INDEX_CODEC_IN1, SST_TASK_SBA, 0, &sst_gains[9]), | ||
331 | SST_GAIN("codec_out0", SST_PATH_INDEX_CODEC_OUT0, SST_TASK_SBA, 0, &sst_gains[10]), | ||
332 | SST_GAIN("codec_out1", SST_PATH_INDEX_CODEC_OUT1, SST_TASK_SBA, 0, &sst_gains[11]), | ||
333 | SST_GAIN("media_loop1_out", SST_PATH_INDEX_MEDIA_LOOP1_OUT, SST_TASK_SBA, 0, &sst_gains[12]), | ||
334 | SST_GAIN("media_loop2_out", SST_PATH_INDEX_MEDIA_LOOP2_OUT, SST_TASK_SBA, 0, &sst_gains[13]), | ||
335 | SST_GAIN("sprot_loop_out", SST_PATH_INDEX_SPROT_LOOP_OUT, SST_TASK_SBA, 0, &sst_gains[14]), | ||
336 | SST_VOLUME("media0_in", SST_PATH_INDEX_MEDIA0_IN, SST_TASK_MMX, 0, &sst_gains[15]), | ||
337 | }; | ||
338 | |||
339 | #define SST_GAIN_NUM_CONTROLS 3 | ||
340 | /* the SST_GAIN macro above will create three alsa controls for each | ||
341 | * instance invoked, gain, mute and ramp duration, which use the same gain | ||
342 | * cell sst_gain to keep track of data | ||
343 | * To calculate number of gain cell instances we need to device by 3 in | ||
344 | * below caulcation for gain cell memory. | ||
345 | * This gets rid of static number and issues while adding new controls | ||
346 | */ | ||
347 | static struct sst_gain_value sst_gains[ARRAY_SIZE(sst_gain_controls)/SST_GAIN_NUM_CONTROLS]; | ||
348 | |||
165 | static const struct snd_kcontrol_new sst_algo_controls[] = { | 349 | static const struct snd_kcontrol_new sst_algo_controls[] = { |
166 | SST_ALGO_KCONTROL_BYTES("media_loop1_out", "fir", 272, SST_MODULE_ID_FIR_24, | 350 | SST_ALGO_KCONTROL_BYTES("media_loop1_out", "fir", 272, SST_MODULE_ID_FIR_24, |
167 | SST_PATH_INDEX_MEDIA_LOOP1_OUT, 0, SST_TASK_SBA, SBA_VB_SET_FIR), | 351 | SST_PATH_INDEX_MEDIA_LOOP1_OUT, 0, SST_TASK_SBA, SBA_VB_SET_FIR), |
@@ -200,19 +384,33 @@ static int sst_algo_control_init(struct device *dev) | |||
200 | 384 | ||
201 | int sst_dsp_init_v2_dpcm(struct snd_soc_platform *platform) | 385 | int sst_dsp_init_v2_dpcm(struct snd_soc_platform *platform) |
202 | { | 386 | { |
203 | int ret = 0; | 387 | int i, ret = 0; |
204 | struct sst_data *drv = snd_soc_platform_get_drvdata(platform); | 388 | struct sst_data *drv = snd_soc_platform_get_drvdata(platform); |
389 | unsigned int gains = ARRAY_SIZE(sst_gain_controls)/3; | ||
205 | 390 | ||
206 | drv->byte_stream = devm_kzalloc(platform->dev, | 391 | drv->byte_stream = devm_kzalloc(platform->dev, |
207 | SST_MAX_BIN_BYTES, GFP_KERNEL); | 392 | SST_MAX_BIN_BYTES, GFP_KERNEL); |
208 | if (!drv->byte_stream) | 393 | if (!drv->byte_stream) |
209 | return -ENOMEM; | 394 | return -ENOMEM; |
210 | 395 | ||
211 | /*Initialize algo control params*/ | 396 | for (i = 0; i < gains; i++) { |
397 | sst_gains[i].mute = SST_GAIN_MUTE_DEFAULT; | ||
398 | sst_gains[i].l_gain = SST_GAIN_VOLUME_DEFAULT; | ||
399 | sst_gains[i].r_gain = SST_GAIN_VOLUME_DEFAULT; | ||
400 | sst_gains[i].ramp_duration = SST_GAIN_RAMP_DURATION_DEFAULT; | ||
401 | } | ||
402 | |||
403 | ret = snd_soc_add_platform_controls(platform, sst_gain_controls, | ||
404 | ARRAY_SIZE(sst_gain_controls)); | ||
405 | if (ret) | ||
406 | return ret; | ||
407 | |||
408 | /* Initialize algo control params */ | ||
212 | ret = sst_algo_control_init(platform->dev); | 409 | ret = sst_algo_control_init(platform->dev); |
213 | if (ret) | 410 | if (ret) |
214 | return ret; | 411 | return ret; |
215 | ret = snd_soc_add_platform_controls(platform, sst_algo_controls, | 412 | ret = snd_soc_add_platform_controls(platform, sst_algo_controls, |
216 | ARRAY_SIZE(sst_algo_controls)); | 413 | ARRAY_SIZE(sst_algo_controls)); |
414 | |||
217 | return ret; | 415 | return ret; |
218 | } | 416 | } |
diff --git a/sound/soc/intel/sst-atom-controls.h b/sound/soc/intel/sst-atom-controls.h index a73e894b175c..e530002cd763 100644 --- a/sound/soc/intel/sst-atom-controls.h +++ b/sound/soc/intel/sst-atom-controls.h | |||
@@ -23,6 +23,9 @@ | |||
23 | #ifndef __SST_ATOM_CONTROLS_H__ | 23 | #ifndef __SST_ATOM_CONTROLS_H__ |
24 | #define __SST_ATOM_CONTROLS_H__ | 24 | #define __SST_ATOM_CONTROLS_H__ |
25 | 25 | ||
26 | #include <sound/soc.h> | ||
27 | #include <sound/tlv.h> | ||
28 | |||
26 | enum { | 29 | enum { |
27 | MERR_DPCM_AUDIO = 0, | 30 | MERR_DPCM_AUDIO = 0, |
28 | MERR_DPCM_COMPR, | 31 | MERR_DPCM_COMPR, |
@@ -360,16 +363,134 @@ struct sst_dsp_header { | |||
360 | struct sst_cmd_generic { | 363 | struct sst_cmd_generic { |
361 | struct sst_dsp_header header; | 364 | struct sst_dsp_header header; |
362 | } __packed; | 365 | } __packed; |
366 | |||
367 | struct gain_cell { | ||
368 | struct sst_destination_id dest; | ||
369 | s16 cell_gain_left; | ||
370 | s16 cell_gain_right; | ||
371 | u16 gain_time_constant; | ||
372 | } __packed; | ||
373 | |||
374 | #define NUM_GAIN_CELLS 1 | ||
375 | struct sst_cmd_set_gain_dual { | ||
376 | struct sst_dsp_header header; | ||
377 | u16 gain_cell_num; | ||
378 | struct gain_cell cell_gains[NUM_GAIN_CELLS]; | ||
379 | } __packed; | ||
363 | struct sst_cmd_set_params { | 380 | struct sst_cmd_set_params { |
364 | struct sst_destination_id dst; | 381 | struct sst_destination_id dst; |
365 | u16 command_id; | 382 | u16 command_id; |
366 | char params[0]; | 383 | char params[0]; |
367 | } __packed; | 384 | } __packed; |
385 | |||
386 | /**** widget defines *****/ | ||
387 | |||
388 | struct sst_ids { | ||
389 | u16 location_id; | ||
390 | u16 module_id; | ||
391 | u8 task_id; | ||
392 | u8 format; | ||
393 | u8 reg; | ||
394 | const char *parent_wname; | ||
395 | struct snd_soc_dapm_widget *parent_w; | ||
396 | struct list_head algo_list; | ||
397 | struct list_head gain_list; | ||
398 | const struct sst_pcm_format *pcm_fmt; | ||
399 | }; | ||
400 | enum sst_gain_kcontrol_type { | ||
401 | SST_GAIN_TLV, | ||
402 | SST_GAIN_MUTE, | ||
403 | SST_GAIN_RAMP_DURATION, | ||
404 | }; | ||
405 | |||
406 | struct sst_gain_mixer_control { | ||
407 | bool stereo; | ||
408 | enum sst_gain_kcontrol_type type; | ||
409 | struct sst_gain_value *gain_val; | ||
410 | int max; | ||
411 | int min; | ||
412 | u16 instance_id; | ||
413 | u16 module_id; | ||
414 | u16 pipe_id; | ||
415 | u16 task_id; | ||
416 | char pname[44]; | ||
417 | struct snd_soc_dapm_widget *w; | ||
418 | }; | ||
419 | |||
420 | struct sst_gain_value { | ||
421 | u16 ramp_duration; | ||
422 | s16 l_gain; | ||
423 | s16 r_gain; | ||
424 | bool mute; | ||
425 | }; | ||
426 | #define SST_GAIN_VOLUME_DEFAULT (-1440) | ||
427 | #define SST_GAIN_RAMP_DURATION_DEFAULT 5 /* timeconstant */ | ||
428 | #define SST_GAIN_MUTE_DEFAULT true | ||
429 | |||
430 | #define SST_GAIN_KCONTROL_TLV(xname, xhandler_get, xhandler_put, \ | ||
431 | xmod, xpipe, xinstance, xtask, tlv_array, xgain_val, \ | ||
432 | xmin, xmax, xpname) \ | ||
433 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ | ||
434 | .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ | ||
435 | SNDRV_CTL_ELEM_ACCESS_READWRITE, \ | ||
436 | .tlv.p = (tlv_array), \ | ||
437 | .info = sst_gain_ctl_info,\ | ||
438 | .get = xhandler_get, .put = xhandler_put, \ | ||
439 | .private_value = (unsigned long)&(struct sst_gain_mixer_control) \ | ||
440 | { .stereo = true, .max = xmax, .min = xmin, .type = SST_GAIN_TLV, \ | ||
441 | .module_id = xmod, .pipe_id = xpipe, .task_id = xtask,\ | ||
442 | .instance_id = xinstance, .gain_val = xgain_val, .pname = xpname} | ||
443 | |||
444 | #define SST_GAIN_KCONTROL_INT(xname, xhandler_get, xhandler_put, \ | ||
445 | xmod, xpipe, xinstance, xtask, xtype, xgain_val, \ | ||
446 | xmin, xmax, xpname) \ | ||
447 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ | ||
448 | .info = sst_gain_ctl_info, \ | ||
449 | .get = xhandler_get, .put = xhandler_put, \ | ||
450 | .private_value = (unsigned long)&(struct sst_gain_mixer_control) \ | ||
451 | { .stereo = false, .max = xmax, .min = xmin, .type = xtype, \ | ||
452 | .module_id = xmod, .pipe_id = xpipe, .task_id = xtask,\ | ||
453 | .instance_id = xinstance, .gain_val = xgain_val, .pname = xpname} | ||
454 | |||
455 | #define SST_GAIN_KCONTROL_BOOL(xname, xhandler_get, xhandler_put,\ | ||
456 | xmod, xpipe, xinstance, xtask, xgain_val, xpname) \ | ||
457 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ | ||
458 | .info = snd_soc_info_bool_ext, \ | ||
459 | .get = xhandler_get, .put = xhandler_put, \ | ||
460 | .private_value = (unsigned long)&(struct sst_gain_mixer_control) \ | ||
461 | { .stereo = false, .type = SST_GAIN_MUTE, \ | ||
462 | .module_id = xmod, .pipe_id = xpipe, .task_id = xtask,\ | ||
463 | .instance_id = xinstance, .gain_val = xgain_val, .pname = xpname} | ||
368 | #define SST_CONTROL_NAME(xpname, xmname, xinstance, xtype) \ | 464 | #define SST_CONTROL_NAME(xpname, xmname, xinstance, xtype) \ |
369 | xpname " " xmname " " #xinstance " " xtype | 465 | xpname " " xmname " " #xinstance " " xtype |
370 | 466 | ||
371 | #define SST_COMBO_CONTROL_NAME(xpname, xmname, xinstance, xtype, xsubmodule) \ | 467 | #define SST_COMBO_CONTROL_NAME(xpname, xmname, xinstance, xtype, xsubmodule) \ |
372 | xpname " " xmname " " #xinstance " " xtype " " xsubmodule | 468 | xpname " " xmname " " #xinstance " " xtype " " xsubmodule |
469 | |||
470 | /* | ||
471 | * 3 Controls for each Gain module | ||
472 | * e.g. - pcm0_in Gain 0 Volume | ||
473 | * - pcm0_in Gain 0 Ramp Delay | ||
474 | * - pcm0_in Gain 0 Switch | ||
475 | */ | ||
476 | #define SST_GAIN_KCONTROLS(xpname, xmname, xmin_gain, xmax_gain, xmin_tc, xmax_tc, \ | ||
477 | xhandler_get, xhandler_put, \ | ||
478 | xmod, xpipe, xinstance, xtask, tlv_array, xgain_val) \ | ||
479 | { SST_GAIN_KCONTROL_INT(SST_CONTROL_NAME(xpname, xmname, xinstance, "Ramp Delay"), \ | ||
480 | xhandler_get, xhandler_put, xmod, xpipe, xinstance, xtask, SST_GAIN_RAMP_DURATION, \ | ||
481 | xgain_val, xmin_tc, xmax_tc, xpname) }, \ | ||
482 | { SST_GAIN_KCONTROL_BOOL(SST_CONTROL_NAME(xpname, xmname, xinstance, "Switch"), \ | ||
483 | xhandler_get, xhandler_put, xmod, xpipe, xinstance, xtask, \ | ||
484 | xgain_val, xpname) } ,\ | ||
485 | { SST_GAIN_KCONTROL_TLV(SST_CONTROL_NAME(xpname, xmname, xinstance, "Volume"), \ | ||
486 | xhandler_get, xhandler_put, xmod, xpipe, xinstance, xtask, tlv_array, \ | ||
487 | xgain_val, xmin_gain, xmax_gain, xpname) } | ||
488 | |||
489 | #define SST_GAIN_TC_MIN 5 | ||
490 | #define SST_GAIN_TC_MAX 5000 | ||
491 | #define SST_GAIN_MIN_VALUE -1440 /* in 0.1 DB units */ | ||
492 | #define SST_GAIN_MAX_VALUE 360 | ||
493 | |||
373 | enum sst_algo_kcontrol_type { | 494 | enum sst_algo_kcontrol_type { |
374 | SST_ALGO_PARAMS, | 495 | SST_ALGO_PARAMS, |
375 | SST_ALGO_BYPASS, | 496 | SST_ALGO_BYPASS, |