diff options
Diffstat (limited to 'sound/soc/intel/atom/sst-atom-controls.h')
-rw-r--r-- | sound/soc/intel/atom/sst-atom-controls.h | 870 |
1 files changed, 870 insertions, 0 deletions
diff --git a/sound/soc/intel/atom/sst-atom-controls.h b/sound/soc/intel/atom/sst-atom-controls.h new file mode 100644 index 000000000000..daecc58f28af --- /dev/null +++ b/sound/soc/intel/atom/sst-atom-controls.h | |||
@@ -0,0 +1,870 @@ | |||
1 | /* | ||
2 | * sst-atom-controls.h - Intel MID Platform driver header file | ||
3 | * | ||
4 | * Copyright (C) 2013-14 Intel Corp | ||
5 | * Author: Ramesh Babu <ramesh.babu.koul@intel.com> | ||
6 | * Omair M Abdullah <omair.m.abdullah@intel.com> | ||
7 | * Samreen Nilofer <samreen.nilofer@intel.com> | ||
8 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; version 2 of the License. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, but | ||
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | * General Public License for more details. | ||
18 | * | ||
19 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #ifndef __SST_ATOM_CONTROLS_H__ | ||
24 | #define __SST_ATOM_CONTROLS_H__ | ||
25 | |||
26 | #include <sound/soc.h> | ||
27 | #include <sound/tlv.h> | ||
28 | |||
29 | enum { | ||
30 | MERR_DPCM_AUDIO = 0, | ||
31 | MERR_DPCM_COMPR, | ||
32 | }; | ||
33 | |||
34 | /* define a bit for each mixer input */ | ||
35 | #define SST_MIX_IP(x) (x) | ||
36 | |||
37 | #define SST_IP_CODEC0 SST_MIX_IP(2) | ||
38 | #define SST_IP_CODEC1 SST_MIX_IP(3) | ||
39 | #define SST_IP_LOOP0 SST_MIX_IP(4) | ||
40 | #define SST_IP_LOOP1 SST_MIX_IP(5) | ||
41 | #define SST_IP_LOOP2 SST_MIX_IP(6) | ||
42 | #define SST_IP_PROBE SST_MIX_IP(7) | ||
43 | #define SST_IP_VOIP SST_MIX_IP(12) | ||
44 | #define SST_IP_PCM0 SST_MIX_IP(13) | ||
45 | #define SST_IP_PCM1 SST_MIX_IP(14) | ||
46 | #define SST_IP_MEDIA0 SST_MIX_IP(17) | ||
47 | #define SST_IP_MEDIA1 SST_MIX_IP(18) | ||
48 | #define SST_IP_MEDIA2 SST_MIX_IP(19) | ||
49 | #define SST_IP_MEDIA3 SST_MIX_IP(20) | ||
50 | |||
51 | #define SST_IP_LAST SST_IP_MEDIA3 | ||
52 | |||
53 | #define SST_SWM_INPUT_COUNT (SST_IP_LAST + 1) | ||
54 | #define SST_CMD_SWM_MAX_INPUTS 6 | ||
55 | |||
56 | #define SST_PATH_ID_SHIFT 8 | ||
57 | #define SST_DEFAULT_LOCATION_ID 0xFFFF | ||
58 | #define SST_DEFAULT_CELL_NBR 0xFF | ||
59 | #define SST_DEFAULT_MODULE_ID 0xFFFF | ||
60 | |||
61 | /* | ||
62 | * Audio DSP Path Ids. Specified by the audio DSP FW | ||
63 | */ | ||
64 | enum sst_path_index { | ||
65 | SST_PATH_INDEX_CODEC_OUT0 = (0x02 << SST_PATH_ID_SHIFT), | ||
66 | SST_PATH_INDEX_CODEC_OUT1 = (0x03 << SST_PATH_ID_SHIFT), | ||
67 | |||
68 | SST_PATH_INDEX_SPROT_LOOP_OUT = (0x04 << SST_PATH_ID_SHIFT), | ||
69 | SST_PATH_INDEX_MEDIA_LOOP1_OUT = (0x05 << SST_PATH_ID_SHIFT), | ||
70 | SST_PATH_INDEX_MEDIA_LOOP2_OUT = (0x06 << SST_PATH_ID_SHIFT), | ||
71 | |||
72 | SST_PATH_INDEX_VOIP_OUT = (0x0C << SST_PATH_ID_SHIFT), | ||
73 | SST_PATH_INDEX_PCM0_OUT = (0x0D << SST_PATH_ID_SHIFT), | ||
74 | SST_PATH_INDEX_PCM1_OUT = (0x0E << SST_PATH_ID_SHIFT), | ||
75 | SST_PATH_INDEX_PCM2_OUT = (0x0F << SST_PATH_ID_SHIFT), | ||
76 | |||
77 | SST_PATH_INDEX_MEDIA0_OUT = (0x12 << SST_PATH_ID_SHIFT), | ||
78 | SST_PATH_INDEX_MEDIA1_OUT = (0x13 << SST_PATH_ID_SHIFT), | ||
79 | |||
80 | |||
81 | /* Start of input paths */ | ||
82 | SST_PATH_INDEX_CODEC_IN0 = (0x82 << SST_PATH_ID_SHIFT), | ||
83 | SST_PATH_INDEX_CODEC_IN1 = (0x83 << SST_PATH_ID_SHIFT), | ||
84 | |||
85 | SST_PATH_INDEX_SPROT_LOOP_IN = (0x84 << SST_PATH_ID_SHIFT), | ||
86 | SST_PATH_INDEX_MEDIA_LOOP1_IN = (0x85 << SST_PATH_ID_SHIFT), | ||
87 | SST_PATH_INDEX_MEDIA_LOOP2_IN = (0x86 << SST_PATH_ID_SHIFT), | ||
88 | |||
89 | SST_PATH_INDEX_VOIP_IN = (0x8C << SST_PATH_ID_SHIFT), | ||
90 | |||
91 | SST_PATH_INDEX_PCM0_IN = (0x8D << SST_PATH_ID_SHIFT), | ||
92 | SST_PATH_INDEX_PCM1_IN = (0x8E << SST_PATH_ID_SHIFT), | ||
93 | |||
94 | SST_PATH_INDEX_MEDIA0_IN = (0x8F << SST_PATH_ID_SHIFT), | ||
95 | SST_PATH_INDEX_MEDIA1_IN = (0x90 << SST_PATH_ID_SHIFT), | ||
96 | SST_PATH_INDEX_MEDIA2_IN = (0x91 << SST_PATH_ID_SHIFT), | ||
97 | |||
98 | SST_PATH_INDEX_MEDIA3_IN = (0x9C << SST_PATH_ID_SHIFT), | ||
99 | |||
100 | SST_PATH_INDEX_RESERVED = (0xFF << SST_PATH_ID_SHIFT), | ||
101 | }; | ||
102 | |||
103 | /* | ||
104 | * path IDs | ||
105 | */ | ||
106 | enum sst_swm_inputs { | ||
107 | SST_SWM_IN_CODEC0 = (SST_PATH_INDEX_CODEC_IN0 | SST_DEFAULT_CELL_NBR), | ||
108 | SST_SWM_IN_CODEC1 = (SST_PATH_INDEX_CODEC_IN1 | SST_DEFAULT_CELL_NBR), | ||
109 | SST_SWM_IN_SPROT_LOOP = (SST_PATH_INDEX_SPROT_LOOP_IN | SST_DEFAULT_CELL_NBR), | ||
110 | SST_SWM_IN_MEDIA_LOOP1 = (SST_PATH_INDEX_MEDIA_LOOP1_IN | SST_DEFAULT_CELL_NBR), | ||
111 | SST_SWM_IN_MEDIA_LOOP2 = (SST_PATH_INDEX_MEDIA_LOOP2_IN | SST_DEFAULT_CELL_NBR), | ||
112 | SST_SWM_IN_VOIP = (SST_PATH_INDEX_VOIP_IN | SST_DEFAULT_CELL_NBR), | ||
113 | SST_SWM_IN_PCM0 = (SST_PATH_INDEX_PCM0_IN | SST_DEFAULT_CELL_NBR), | ||
114 | SST_SWM_IN_PCM1 = (SST_PATH_INDEX_PCM1_IN | SST_DEFAULT_CELL_NBR), | ||
115 | SST_SWM_IN_MEDIA0 = (SST_PATH_INDEX_MEDIA0_IN | SST_DEFAULT_CELL_NBR), /* Part of Media Mixer */ | ||
116 | SST_SWM_IN_MEDIA1 = (SST_PATH_INDEX_MEDIA1_IN | SST_DEFAULT_CELL_NBR), /* Part of Media Mixer */ | ||
117 | SST_SWM_IN_MEDIA2 = (SST_PATH_INDEX_MEDIA2_IN | SST_DEFAULT_CELL_NBR), /* Part of Media Mixer */ | ||
118 | SST_SWM_IN_MEDIA3 = (SST_PATH_INDEX_MEDIA3_IN | SST_DEFAULT_CELL_NBR), /* Part of Media Mixer */ | ||
119 | SST_SWM_IN_END = (SST_PATH_INDEX_RESERVED | SST_DEFAULT_CELL_NBR) | ||
120 | }; | ||
121 | |||
122 | /* | ||
123 | * path IDs | ||
124 | */ | ||
125 | enum sst_swm_outputs { | ||
126 | SST_SWM_OUT_CODEC0 = (SST_PATH_INDEX_CODEC_OUT0 | SST_DEFAULT_CELL_NBR), | ||
127 | SST_SWM_OUT_CODEC1 = (SST_PATH_INDEX_CODEC_OUT1 | SST_DEFAULT_CELL_NBR), | ||
128 | SST_SWM_OUT_SPROT_LOOP = (SST_PATH_INDEX_SPROT_LOOP_OUT | SST_DEFAULT_CELL_NBR), | ||
129 | SST_SWM_OUT_MEDIA_LOOP1 = (SST_PATH_INDEX_MEDIA_LOOP1_OUT | SST_DEFAULT_CELL_NBR), | ||
130 | SST_SWM_OUT_MEDIA_LOOP2 = (SST_PATH_INDEX_MEDIA_LOOP2_OUT | SST_DEFAULT_CELL_NBR), | ||
131 | SST_SWM_OUT_VOIP = (SST_PATH_INDEX_VOIP_OUT | SST_DEFAULT_CELL_NBR), | ||
132 | SST_SWM_OUT_PCM0 = (SST_PATH_INDEX_PCM0_OUT | SST_DEFAULT_CELL_NBR), | ||
133 | SST_SWM_OUT_PCM1 = (SST_PATH_INDEX_PCM1_OUT | SST_DEFAULT_CELL_NBR), | ||
134 | SST_SWM_OUT_PCM2 = (SST_PATH_INDEX_PCM2_OUT | SST_DEFAULT_CELL_NBR), | ||
135 | SST_SWM_OUT_MEDIA0 = (SST_PATH_INDEX_MEDIA0_OUT | SST_DEFAULT_CELL_NBR), /* Part of Media Mixer */ | ||
136 | SST_SWM_OUT_MEDIA1 = (SST_PATH_INDEX_MEDIA1_OUT | SST_DEFAULT_CELL_NBR), /* Part of Media Mixer */ | ||
137 | SST_SWM_OUT_END = (SST_PATH_INDEX_RESERVED | SST_DEFAULT_CELL_NBR), | ||
138 | }; | ||
139 | |||
140 | enum sst_ipc_msg { | ||
141 | SST_IPC_IA_CMD = 1, | ||
142 | SST_IPC_IA_SET_PARAMS, | ||
143 | SST_IPC_IA_GET_PARAMS, | ||
144 | }; | ||
145 | |||
146 | enum sst_cmd_type { | ||
147 | SST_CMD_BYTES_SET = 1, | ||
148 | SST_CMD_BYTES_GET = 2, | ||
149 | }; | ||
150 | |||
151 | enum sst_task { | ||
152 | SST_TASK_SBA = 1, | ||
153 | SST_TASK_MMX = 3, | ||
154 | }; | ||
155 | |||
156 | enum sst_type { | ||
157 | SST_TYPE_CMD = 1, | ||
158 | SST_TYPE_PARAMS, | ||
159 | }; | ||
160 | |||
161 | enum sst_flag { | ||
162 | SST_FLAG_BLOCKED = 1, | ||
163 | SST_FLAG_NONBLOCK, | ||
164 | }; | ||
165 | |||
166 | /* | ||
167 | * Enumeration for indexing the gain cells in VB_SET_GAIN DSP command | ||
168 | */ | ||
169 | enum sst_gain_index { | ||
170 | /* GAIN IDs for SB task start here */ | ||
171 | SST_GAIN_INDEX_CODEC_OUT0, | ||
172 | SST_GAIN_INDEX_CODEC_OUT1, | ||
173 | SST_GAIN_INDEX_CODEC_IN0, | ||
174 | SST_GAIN_INDEX_CODEC_IN1, | ||
175 | |||
176 | SST_GAIN_INDEX_SPROT_LOOP_OUT, | ||
177 | SST_GAIN_INDEX_MEDIA_LOOP1_OUT, | ||
178 | SST_GAIN_INDEX_MEDIA_LOOP2_OUT, | ||
179 | |||
180 | SST_GAIN_INDEX_PCM0_IN_LEFT, | ||
181 | SST_GAIN_INDEX_PCM0_IN_RIGHT, | ||
182 | |||
183 | SST_GAIN_INDEX_PCM1_OUT_LEFT, | ||
184 | SST_GAIN_INDEX_PCM1_OUT_RIGHT, | ||
185 | SST_GAIN_INDEX_PCM1_IN_LEFT, | ||
186 | SST_GAIN_INDEX_PCM1_IN_RIGHT, | ||
187 | SST_GAIN_INDEX_PCM2_OUT_LEFT, | ||
188 | |||
189 | SST_GAIN_INDEX_PCM2_OUT_RIGHT, | ||
190 | SST_GAIN_INDEX_VOIP_OUT, | ||
191 | SST_GAIN_INDEX_VOIP_IN, | ||
192 | |||
193 | /* Gain IDs for MMX task start here */ | ||
194 | SST_GAIN_INDEX_MEDIA0_IN_LEFT, | ||
195 | SST_GAIN_INDEX_MEDIA0_IN_RIGHT, | ||
196 | SST_GAIN_INDEX_MEDIA1_IN_LEFT, | ||
197 | SST_GAIN_INDEX_MEDIA1_IN_RIGHT, | ||
198 | |||
199 | SST_GAIN_INDEX_MEDIA2_IN_LEFT, | ||
200 | SST_GAIN_INDEX_MEDIA2_IN_RIGHT, | ||
201 | |||
202 | SST_GAIN_INDEX_GAIN_END | ||
203 | }; | ||
204 | |||
205 | /* | ||
206 | * Audio DSP module IDs specified by FW spec | ||
207 | * TODO: Update with all modules | ||
208 | */ | ||
209 | enum sst_module_id { | ||
210 | SST_MODULE_ID_PCM = 0x0001, | ||
211 | SST_MODULE_ID_MP3 = 0x0002, | ||
212 | SST_MODULE_ID_MP24 = 0x0003, | ||
213 | SST_MODULE_ID_AAC = 0x0004, | ||
214 | SST_MODULE_ID_AACP = 0x0005, | ||
215 | SST_MODULE_ID_EAACP = 0x0006, | ||
216 | SST_MODULE_ID_WMA9 = 0x0007, | ||
217 | SST_MODULE_ID_WMA10 = 0x0008, | ||
218 | SST_MODULE_ID_WMA10P = 0x0009, | ||
219 | SST_MODULE_ID_RA = 0x000A, | ||
220 | SST_MODULE_ID_DDAC3 = 0x000B, | ||
221 | SST_MODULE_ID_TRUE_HD = 0x000C, | ||
222 | SST_MODULE_ID_HD_PLUS = 0x000D, | ||
223 | |||
224 | SST_MODULE_ID_SRC = 0x0064, | ||
225 | SST_MODULE_ID_DOWNMIX = 0x0066, | ||
226 | SST_MODULE_ID_GAIN_CELL = 0x0067, | ||
227 | SST_MODULE_ID_SPROT = 0x006D, | ||
228 | SST_MODULE_ID_BASS_BOOST = 0x006E, | ||
229 | SST_MODULE_ID_STEREO_WDNG = 0x006F, | ||
230 | SST_MODULE_ID_AV_REMOVAL = 0x0070, | ||
231 | SST_MODULE_ID_MIC_EQ = 0x0071, | ||
232 | SST_MODULE_ID_SPL = 0x0072, | ||
233 | SST_MODULE_ID_ALGO_VTSV = 0x0073, | ||
234 | SST_MODULE_ID_NR = 0x0076, | ||
235 | SST_MODULE_ID_BWX = 0x0077, | ||
236 | SST_MODULE_ID_DRP = 0x0078, | ||
237 | SST_MODULE_ID_MDRP = 0x0079, | ||
238 | |||
239 | SST_MODULE_ID_ANA = 0x007A, | ||
240 | SST_MODULE_ID_AEC = 0x007B, | ||
241 | SST_MODULE_ID_NR_SNS = 0x007C, | ||
242 | SST_MODULE_ID_SER = 0x007D, | ||
243 | SST_MODULE_ID_AGC = 0x007E, | ||
244 | |||
245 | SST_MODULE_ID_CNI = 0x007F, | ||
246 | SST_MODULE_ID_CONTEXT_ALGO_AWARE = 0x0080, | ||
247 | SST_MODULE_ID_FIR_24 = 0x0081, | ||
248 | SST_MODULE_ID_IIR_24 = 0x0082, | ||
249 | |||
250 | SST_MODULE_ID_ASRC = 0x0083, | ||
251 | SST_MODULE_ID_TONE_GEN = 0x0084, | ||
252 | SST_MODULE_ID_BMF = 0x0086, | ||
253 | SST_MODULE_ID_EDL = 0x0087, | ||
254 | SST_MODULE_ID_GLC = 0x0088, | ||
255 | |||
256 | SST_MODULE_ID_FIR_16 = 0x0089, | ||
257 | SST_MODULE_ID_IIR_16 = 0x008A, | ||
258 | SST_MODULE_ID_DNR = 0x008B, | ||
259 | |||
260 | SST_MODULE_ID_VIRTUALIZER = 0x008C, | ||
261 | SST_MODULE_ID_VISUALIZATION = 0x008D, | ||
262 | SST_MODULE_ID_LOUDNESS_OPTIMIZER = 0x008E, | ||
263 | SST_MODULE_ID_REVERBERATION = 0x008F, | ||
264 | |||
265 | SST_MODULE_ID_CNI_TX = 0x0090, | ||
266 | SST_MODULE_ID_REF_LINE = 0x0091, | ||
267 | SST_MODULE_ID_VOLUME = 0x0092, | ||
268 | SST_MODULE_ID_FILT_DCR = 0x0094, | ||
269 | SST_MODULE_ID_SLV = 0x009A, | ||
270 | SST_MODULE_ID_NLF = 0x009B, | ||
271 | SST_MODULE_ID_TNR = 0x009C, | ||
272 | SST_MODULE_ID_WNR = 0x009D, | ||
273 | |||
274 | SST_MODULE_ID_LOG = 0xFF00, | ||
275 | |||
276 | SST_MODULE_ID_TASK = 0xFFFF, | ||
277 | }; | ||
278 | |||
279 | enum sst_cmd { | ||
280 | SBA_IDLE = 14, | ||
281 | SBA_VB_SET_SPEECH_PATH = 26, | ||
282 | MMX_SET_GAIN = 33, | ||
283 | SBA_VB_SET_GAIN = 33, | ||
284 | FBA_VB_RX_CNI = 35, | ||
285 | MMX_SET_GAIN_TIMECONST = 36, | ||
286 | SBA_VB_SET_TIMECONST = 36, | ||
287 | SBA_VB_START = 85, | ||
288 | SBA_SET_SWM = 114, | ||
289 | SBA_SET_MDRP = 116, | ||
290 | SBA_HW_SET_SSP = 117, | ||
291 | SBA_SET_MEDIA_LOOP_MAP = 118, | ||
292 | SBA_SET_MEDIA_PATH = 119, | ||
293 | MMX_SET_MEDIA_PATH = 119, | ||
294 | SBA_VB_LPRO = 126, | ||
295 | SBA_VB_SET_FIR = 128, | ||
296 | SBA_VB_SET_IIR = 129, | ||
297 | SBA_SET_SSP_SLOT_MAP = 130, | ||
298 | }; | ||
299 | |||
300 | enum sst_dsp_switch { | ||
301 | SST_SWITCH_OFF = 0, | ||
302 | SST_SWITCH_ON = 3, | ||
303 | }; | ||
304 | |||
305 | enum sst_path_switch { | ||
306 | SST_PATH_OFF = 0, | ||
307 | SST_PATH_ON = 1, | ||
308 | }; | ||
309 | |||
310 | enum sst_swm_state { | ||
311 | SST_SWM_OFF = 0, | ||
312 | SST_SWM_ON = 3, | ||
313 | }; | ||
314 | |||
315 | #define SST_FILL_LOCATION_IDS(dst, cell_idx, pipe_id) do { \ | ||
316 | dst.location_id.p.cell_nbr_idx = (cell_idx); \ | ||
317 | dst.location_id.p.path_id = (pipe_id); \ | ||
318 | } while (0) | ||
319 | #define SST_FILL_LOCATION_ID(dst, loc_id) (\ | ||
320 | dst.location_id.f = (loc_id)) | ||
321 | #define SST_FILL_MODULE_ID(dst, mod_id) (\ | ||
322 | dst.module_id = (mod_id)) | ||
323 | |||
324 | #define SST_FILL_DESTINATION1(dst, id) do { \ | ||
325 | SST_FILL_LOCATION_ID(dst, (id) & 0xFFFF); \ | ||
326 | SST_FILL_MODULE_ID(dst, ((id) & 0xFFFF0000) >> 16); \ | ||
327 | } while (0) | ||
328 | #define SST_FILL_DESTINATION2(dst, loc_id, mod_id) do { \ | ||
329 | SST_FILL_LOCATION_ID(dst, loc_id); \ | ||
330 | SST_FILL_MODULE_ID(dst, mod_id); \ | ||
331 | } while (0) | ||
332 | #define SST_FILL_DESTINATION3(dst, cell_idx, path_id, mod_id) do { \ | ||
333 | SST_FILL_LOCATION_IDS(dst, cell_idx, path_id); \ | ||
334 | SST_FILL_MODULE_ID(dst, mod_id); \ | ||
335 | } while (0) | ||
336 | |||
337 | #define SST_FILL_DESTINATION(level, dst, ...) \ | ||
338 | SST_FILL_DESTINATION##level(dst, __VA_ARGS__) | ||
339 | #define SST_FILL_DEFAULT_DESTINATION(dst) \ | ||
340 | SST_FILL_DESTINATION(2, dst, SST_DEFAULT_LOCATION_ID, SST_DEFAULT_MODULE_ID) | ||
341 | |||
342 | struct sst_destination_id { | ||
343 | union sst_location_id { | ||
344 | struct { | ||
345 | u8 cell_nbr_idx; /* module index */ | ||
346 | u8 path_id; /* pipe_id */ | ||
347 | } __packed p; /* part */ | ||
348 | u16 f; /* full */ | ||
349 | } __packed location_id; | ||
350 | u16 module_id; | ||
351 | } __packed; | ||
352 | struct sst_dsp_header { | ||
353 | struct sst_destination_id dst; | ||
354 | u16 command_id; | ||
355 | u16 length; | ||
356 | } __packed; | ||
357 | |||
358 | /* | ||
359 | * | ||
360 | * Common Commands | ||
361 | * | ||
362 | */ | ||
363 | struct sst_cmd_generic { | ||
364 | struct sst_dsp_header header; | ||
365 | } __packed; | ||
366 | |||
367 | struct swm_input_ids { | ||
368 | struct sst_destination_id input_id; | ||
369 | } __packed; | ||
370 | |||
371 | struct sst_cmd_set_swm { | ||
372 | struct sst_dsp_header header; | ||
373 | struct sst_destination_id output_id; | ||
374 | u16 switch_state; | ||
375 | u16 nb_inputs; | ||
376 | struct swm_input_ids input[SST_CMD_SWM_MAX_INPUTS]; | ||
377 | } __packed; | ||
378 | |||
379 | struct sst_cmd_set_media_path { | ||
380 | struct sst_dsp_header header; | ||
381 | u16 switch_state; | ||
382 | } __packed; | ||
383 | |||
384 | struct pcm_cfg { | ||
385 | u8 s_length:2; | ||
386 | u8 rate:3; | ||
387 | u8 format:3; | ||
388 | } __packed; | ||
389 | |||
390 | struct sst_cmd_set_speech_path { | ||
391 | struct sst_dsp_header header; | ||
392 | u16 switch_state; | ||
393 | struct { | ||
394 | u16 rsvd:8; | ||
395 | struct pcm_cfg cfg; | ||
396 | } config; | ||
397 | } __packed; | ||
398 | |||
399 | struct gain_cell { | ||
400 | struct sst_destination_id dest; | ||
401 | s16 cell_gain_left; | ||
402 | s16 cell_gain_right; | ||
403 | u16 gain_time_constant; | ||
404 | } __packed; | ||
405 | |||
406 | #define NUM_GAIN_CELLS 1 | ||
407 | struct sst_cmd_set_gain_dual { | ||
408 | struct sst_dsp_header header; | ||
409 | u16 gain_cell_num; | ||
410 | struct gain_cell cell_gains[NUM_GAIN_CELLS]; | ||
411 | } __packed; | ||
412 | struct sst_cmd_set_params { | ||
413 | struct sst_destination_id dst; | ||
414 | u16 command_id; | ||
415 | char params[0]; | ||
416 | } __packed; | ||
417 | |||
418 | |||
419 | struct sst_cmd_sba_vb_start { | ||
420 | struct sst_dsp_header header; | ||
421 | } __packed; | ||
422 | |||
423 | union sba_media_loop_params { | ||
424 | struct { | ||
425 | u16 rsvd:8; | ||
426 | struct pcm_cfg cfg; | ||
427 | } part; | ||
428 | u16 full; | ||
429 | } __packed; | ||
430 | |||
431 | struct sst_cmd_sba_set_media_loop_map { | ||
432 | struct sst_dsp_header header; | ||
433 | u16 switch_state; | ||
434 | union sba_media_loop_params param; | ||
435 | u16 map; | ||
436 | } __packed; | ||
437 | |||
438 | struct sst_cmd_tone_stop { | ||
439 | struct sst_dsp_header header; | ||
440 | u16 switch_state; | ||
441 | } __packed; | ||
442 | |||
443 | enum sst_ssp_mode { | ||
444 | SSP_MODE_MASTER = 0, | ||
445 | SSP_MODE_SLAVE = 1, | ||
446 | }; | ||
447 | |||
448 | enum sst_ssp_pcm_mode { | ||
449 | SSP_PCM_MODE_NORMAL = 0, | ||
450 | SSP_PCM_MODE_NETWORK = 1, | ||
451 | }; | ||
452 | |||
453 | enum sst_ssp_duplex { | ||
454 | SSP_DUPLEX = 0, | ||
455 | SSP_RX = 1, | ||
456 | SSP_TX = 2, | ||
457 | }; | ||
458 | |||
459 | enum sst_ssp_fs_frequency { | ||
460 | SSP_FS_8_KHZ = 0, | ||
461 | SSP_FS_16_KHZ = 1, | ||
462 | SSP_FS_44_1_KHZ = 2, | ||
463 | SSP_FS_48_KHZ = 3, | ||
464 | }; | ||
465 | |||
466 | enum sst_ssp_fs_polarity { | ||
467 | SSP_FS_ACTIVE_LOW = 0, | ||
468 | SSP_FS_ACTIVE_HIGH = 1, | ||
469 | }; | ||
470 | |||
471 | enum sst_ssp_protocol { | ||
472 | SSP_MODE_PCM = 0, | ||
473 | SSP_MODE_I2S = 1, | ||
474 | }; | ||
475 | |||
476 | enum sst_ssp_port_id { | ||
477 | SSP_MODEM = 0, | ||
478 | SSP_BT = 1, | ||
479 | SSP_FM = 2, | ||
480 | SSP_CODEC = 3, | ||
481 | }; | ||
482 | |||
483 | struct sst_cmd_sba_hw_set_ssp { | ||
484 | struct sst_dsp_header header; | ||
485 | u16 selection; /* 0:SSP0(def), 1:SSP1, 2:SSP2 */ | ||
486 | |||
487 | u16 switch_state; | ||
488 | |||
489 | u16 nb_bits_per_slots:6; /* 0-32 bits, 24 (def) */ | ||
490 | u16 nb_slots:4; /* 0-8: slots per frame */ | ||
491 | u16 mode:3; /* 0:Master, 1: Slave */ | ||
492 | u16 duplex:3; | ||
493 | |||
494 | u16 active_tx_slot_map:8; /* Bit map, 0:off, 1:on */ | ||
495 | u16 reserved1:8; | ||
496 | |||
497 | u16 active_rx_slot_map:8; /* Bit map 0: Off, 1:On */ | ||
498 | u16 reserved2:8; | ||
499 | |||
500 | u16 frame_sync_frequency; | ||
501 | |||
502 | u16 frame_sync_polarity:8; | ||
503 | u16 data_polarity:8; | ||
504 | |||
505 | u16 frame_sync_width; /* 1 to N clocks */ | ||
506 | u16 ssp_protocol:8; | ||
507 | u16 start_delay:8; /* Start delay in terms of clock ticks */ | ||
508 | } __packed; | ||
509 | |||
510 | #define SST_MAX_TDM_SLOTS 8 | ||
511 | |||
512 | struct sst_param_sba_ssp_slot_map { | ||
513 | struct sst_dsp_header header; | ||
514 | |||
515 | u16 param_id; | ||
516 | u16 param_len; | ||
517 | u16 ssp_index; | ||
518 | |||
519 | u8 rx_slot_map[SST_MAX_TDM_SLOTS]; | ||
520 | u8 tx_slot_map[SST_MAX_TDM_SLOTS]; | ||
521 | } __packed; | ||
522 | |||
523 | enum { | ||
524 | SST_PROBE_EXTRACTOR = 0, | ||
525 | SST_PROBE_INJECTOR = 1, | ||
526 | }; | ||
527 | |||
528 | /**** widget defines *****/ | ||
529 | |||
530 | #define SST_MODULE_GAIN 1 | ||
531 | #define SST_MODULE_ALGO 2 | ||
532 | |||
533 | #define SST_FMT_MONO 0 | ||
534 | #define SST_FMT_STEREO 3 | ||
535 | |||
536 | /* physical SSP numbers */ | ||
537 | enum { | ||
538 | SST_SSP0 = 0, | ||
539 | SST_SSP1, | ||
540 | SST_SSP2, | ||
541 | SST_SSP_LAST = SST_SSP2, | ||
542 | }; | ||
543 | |||
544 | #define SST_NUM_SSPS (SST_SSP_LAST + 1) /* physical SSPs */ | ||
545 | #define SST_MAX_SSP_MUX 2 /* single SSP muxed between pipes */ | ||
546 | #define SST_MAX_SSP_DOMAINS 2 /* domains present in each pipe */ | ||
547 | |||
548 | struct sst_module { | ||
549 | struct snd_kcontrol *kctl; | ||
550 | struct list_head node; | ||
551 | }; | ||
552 | |||
553 | struct sst_ssp_config { | ||
554 | u8 ssp_id; | ||
555 | u8 bits_per_slot; | ||
556 | u8 slots; | ||
557 | u8 ssp_mode; | ||
558 | u8 pcm_mode; | ||
559 | u8 duplex; | ||
560 | u8 ssp_protocol; | ||
561 | u8 fs_frequency; | ||
562 | u8 active_slot_map; | ||
563 | u8 start_delay; | ||
564 | u16 fs_width; | ||
565 | }; | ||
566 | |||
567 | struct sst_ssp_cfg { | ||
568 | const u8 ssp_number; | ||
569 | const int *mux_shift; | ||
570 | const int (*domain_shift)[SST_MAX_SSP_MUX]; | ||
571 | const struct sst_ssp_config (*ssp_config)[SST_MAX_SSP_MUX][SST_MAX_SSP_DOMAINS]; | ||
572 | }; | ||
573 | |||
574 | struct sst_ids { | ||
575 | u16 location_id; | ||
576 | u16 module_id; | ||
577 | u8 task_id; | ||
578 | u8 format; | ||
579 | u8 reg; | ||
580 | const char *parent_wname; | ||
581 | struct snd_soc_dapm_widget *parent_w; | ||
582 | struct list_head algo_list; | ||
583 | struct list_head gain_list; | ||
584 | const struct sst_pcm_format *pcm_fmt; | ||
585 | }; | ||
586 | |||
587 | |||
588 | #define SST_AIF_IN(wname, wevent) \ | ||
589 | { .id = snd_soc_dapm_aif_in, .name = wname, .sname = NULL, \ | ||
590 | .reg = SND_SOC_NOPM, .shift = 0, \ | ||
591 | .on_val = 1, .off_val = 0, \ | ||
592 | .event = wevent, .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD, \ | ||
593 | .priv = (void *)&(struct sst_ids) { .task_id = 0, .location_id = 0 } \ | ||
594 | } | ||
595 | |||
596 | #define SST_AIF_OUT(wname, wevent) \ | ||
597 | { .id = snd_soc_dapm_aif_out, .name = wname, .sname = NULL, \ | ||
598 | .reg = SND_SOC_NOPM, .shift = 0, \ | ||
599 | .on_val = 1, .off_val = 0, \ | ||
600 | .event = wevent, .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD, \ | ||
601 | .priv = (void *)&(struct sst_ids) { .task_id = 0, .location_id = 0 } \ | ||
602 | } | ||
603 | |||
604 | #define SST_INPUT(wname, wevent) \ | ||
605 | { .id = snd_soc_dapm_input, .name = wname, .sname = NULL, \ | ||
606 | .reg = SND_SOC_NOPM, .shift = 0, \ | ||
607 | .on_val = 1, .off_val = 0, \ | ||
608 | .event = wevent, .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD, \ | ||
609 | .priv = (void *)&(struct sst_ids) { .task_id = 0, .location_id = 0 } \ | ||
610 | } | ||
611 | |||
612 | #define SST_OUTPUT(wname, wevent) \ | ||
613 | { .id = snd_soc_dapm_output, .name = wname, .sname = NULL, \ | ||
614 | .reg = SND_SOC_NOPM, .shift = 0, \ | ||
615 | .on_val = 1, .off_val = 0, \ | ||
616 | .event = wevent, .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD, \ | ||
617 | .priv = (void *)&(struct sst_ids) { .task_id = 0, .location_id = 0 } \ | ||
618 | } | ||
619 | |||
620 | #define SST_DAPM_OUTPUT(wname, wloc_id, wtask_id, wformat, wevent) \ | ||
621 | { .id = snd_soc_dapm_output, .name = wname, .sname = NULL, \ | ||
622 | .reg = SND_SOC_NOPM, .shift = 0, \ | ||
623 | .on_val = 1, .off_val = 0, \ | ||
624 | .event = wevent, .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD, \ | ||
625 | .priv = (void *)&(struct sst_ids) { .location_id = wloc_id, .task_id = wtask_id,\ | ||
626 | .pcm_fmt = wformat, } \ | ||
627 | } | ||
628 | |||
629 | #define SST_PATH(wname, wtask, wloc_id, wevent, wflags) \ | ||
630 | { .id = snd_soc_dapm_pga, .name = wname, .reg = SND_SOC_NOPM, .shift = 0, \ | ||
631 | .kcontrol_news = NULL, .num_kcontrols = 0, \ | ||
632 | .on_val = 1, .off_val = 0, \ | ||
633 | .event = wevent, .event_flags = wflags, \ | ||
634 | .priv = (void *)&(struct sst_ids) { .task_id = wtask, .location_id = wloc_id, } \ | ||
635 | } | ||
636 | |||
637 | #define SST_LINKED_PATH(wname, wtask, wloc_id, linked_wname, wevent, wflags) \ | ||
638 | { .id = snd_soc_dapm_pga, .name = wname, .reg = SND_SOC_NOPM, .shift = 0, \ | ||
639 | .kcontrol_news = NULL, .num_kcontrols = 0, \ | ||
640 | .on_val = 1, .off_val = 0, \ | ||
641 | .event = wevent, .event_flags = wflags, \ | ||
642 | .priv = (void *)&(struct sst_ids) { .task_id = wtask, .location_id = wloc_id, \ | ||
643 | .parent_wname = linked_wname} \ | ||
644 | } | ||
645 | |||
646 | #define SST_PATH_MEDIA_LOOP(wname, wtask, wloc_id, wformat, wevent, wflags) \ | ||
647 | { .id = snd_soc_dapm_pga, .name = wname, .reg = SND_SOC_NOPM, .shift = 0, \ | ||
648 | .kcontrol_news = NULL, .num_kcontrols = 0, \ | ||
649 | .event = wevent, .event_flags = wflags, \ | ||
650 | .priv = (void *)&(struct sst_ids) { .task_id = wtask, .location_id = wloc_id, \ | ||
651 | .format = wformat,} \ | ||
652 | } | ||
653 | |||
654 | /* output is triggered before input */ | ||
655 | #define SST_PATH_INPUT(name, task_id, loc_id, event) \ | ||
656 | SST_PATH(name, task_id, loc_id, event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD) | ||
657 | |||
658 | #define SST_PATH_LINKED_INPUT(name, task_id, loc_id, linked_wname, event) \ | ||
659 | SST_LINKED_PATH(name, task_id, loc_id, linked_wname, event, \ | ||
660 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD) | ||
661 | |||
662 | #define SST_PATH_OUTPUT(name, task_id, loc_id, event) \ | ||
663 | SST_PATH(name, task_id, loc_id, event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD) | ||
664 | |||
665 | #define SST_PATH_LINKED_OUTPUT(name, task_id, loc_id, linked_wname, event) \ | ||
666 | SST_LINKED_PATH(name, task_id, loc_id, linked_wname, event, \ | ||
667 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD) | ||
668 | |||
669 | #define SST_PATH_MEDIA_LOOP_OUTPUT(name, task_id, loc_id, format, event) \ | ||
670 | SST_PATH_MEDIA_LOOP(name, task_id, loc_id, format, event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD) | ||
671 | |||
672 | |||
673 | #define SST_SWM_MIXER(wname, wreg, wtask, wloc_id, wcontrols, wevent) \ | ||
674 | { .id = snd_soc_dapm_mixer, .name = wname, .reg = SND_SOC_NOPM, .shift = 0, \ | ||
675 | .kcontrol_news = wcontrols, .num_kcontrols = ARRAY_SIZE(wcontrols),\ | ||
676 | .event = wevent, .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD | \ | ||
677 | SND_SOC_DAPM_POST_REG, \ | ||
678 | .priv = (void *)&(struct sst_ids) { .task_id = wtask, .location_id = wloc_id, \ | ||
679 | .reg = wreg } \ | ||
680 | } | ||
681 | |||
682 | enum sst_gain_kcontrol_type { | ||
683 | SST_GAIN_TLV, | ||
684 | SST_GAIN_MUTE, | ||
685 | SST_GAIN_RAMP_DURATION, | ||
686 | }; | ||
687 | |||
688 | struct sst_gain_mixer_control { | ||
689 | bool stereo; | ||
690 | enum sst_gain_kcontrol_type type; | ||
691 | struct sst_gain_value *gain_val; | ||
692 | int max; | ||
693 | int min; | ||
694 | u16 instance_id; | ||
695 | u16 module_id; | ||
696 | u16 pipe_id; | ||
697 | u16 task_id; | ||
698 | char pname[44]; | ||
699 | struct snd_soc_dapm_widget *w; | ||
700 | }; | ||
701 | |||
702 | struct sst_gain_value { | ||
703 | u16 ramp_duration; | ||
704 | s16 l_gain; | ||
705 | s16 r_gain; | ||
706 | bool mute; | ||
707 | }; | ||
708 | #define SST_GAIN_VOLUME_DEFAULT (-1440) | ||
709 | #define SST_GAIN_RAMP_DURATION_DEFAULT 5 /* timeconstant */ | ||
710 | #define SST_GAIN_MUTE_DEFAULT true | ||
711 | |||
712 | #define SST_GAIN_KCONTROL_TLV(xname, xhandler_get, xhandler_put, \ | ||
713 | xmod, xpipe, xinstance, xtask, tlv_array, xgain_val, \ | ||
714 | xmin, xmax, xpname) \ | ||
715 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ | ||
716 | .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ | ||
717 | SNDRV_CTL_ELEM_ACCESS_READWRITE, \ | ||
718 | .tlv.p = (tlv_array), \ | ||
719 | .info = sst_gain_ctl_info,\ | ||
720 | .get = xhandler_get, .put = xhandler_put, \ | ||
721 | .private_value = (unsigned long)&(struct sst_gain_mixer_control) \ | ||
722 | { .stereo = true, .max = xmax, .min = xmin, .type = SST_GAIN_TLV, \ | ||
723 | .module_id = xmod, .pipe_id = xpipe, .task_id = xtask,\ | ||
724 | .instance_id = xinstance, .gain_val = xgain_val, .pname = xpname} | ||
725 | |||
726 | #define SST_GAIN_KCONTROL_INT(xname, xhandler_get, xhandler_put, \ | ||
727 | xmod, xpipe, xinstance, xtask, xtype, xgain_val, \ | ||
728 | xmin, xmax, xpname) \ | ||
729 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ | ||
730 | .info = sst_gain_ctl_info, \ | ||
731 | .get = xhandler_get, .put = xhandler_put, \ | ||
732 | .private_value = (unsigned long)&(struct sst_gain_mixer_control) \ | ||
733 | { .stereo = false, .max = xmax, .min = xmin, .type = xtype, \ | ||
734 | .module_id = xmod, .pipe_id = xpipe, .task_id = xtask,\ | ||
735 | .instance_id = xinstance, .gain_val = xgain_val, .pname = xpname} | ||
736 | |||
737 | #define SST_GAIN_KCONTROL_BOOL(xname, xhandler_get, xhandler_put,\ | ||
738 | xmod, xpipe, xinstance, xtask, xgain_val, xpname) \ | ||
739 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ | ||
740 | .info = snd_soc_info_bool_ext, \ | ||
741 | .get = xhandler_get, .put = xhandler_put, \ | ||
742 | .private_value = (unsigned long)&(struct sst_gain_mixer_control) \ | ||
743 | { .stereo = false, .type = SST_GAIN_MUTE, \ | ||
744 | .module_id = xmod, .pipe_id = xpipe, .task_id = xtask,\ | ||
745 | .instance_id = xinstance, .gain_val = xgain_val, .pname = xpname} | ||
746 | #define SST_CONTROL_NAME(xpname, xmname, xinstance, xtype) \ | ||
747 | xpname " " xmname " " #xinstance " " xtype | ||
748 | |||
749 | #define SST_COMBO_CONTROL_NAME(xpname, xmname, xinstance, xtype, xsubmodule) \ | ||
750 | xpname " " xmname " " #xinstance " " xtype " " xsubmodule | ||
751 | |||
752 | /* | ||
753 | * 3 Controls for each Gain module | ||
754 | * e.g. - pcm0_in Gain 0 Volume | ||
755 | * - pcm0_in Gain 0 Ramp Delay | ||
756 | * - pcm0_in Gain 0 Switch | ||
757 | */ | ||
758 | #define SST_GAIN_KCONTROLS(xpname, xmname, xmin_gain, xmax_gain, xmin_tc, xmax_tc, \ | ||
759 | xhandler_get, xhandler_put, \ | ||
760 | xmod, xpipe, xinstance, xtask, tlv_array, xgain_val) \ | ||
761 | { SST_GAIN_KCONTROL_INT(SST_CONTROL_NAME(xpname, xmname, xinstance, "Ramp Delay"), \ | ||
762 | xhandler_get, xhandler_put, xmod, xpipe, xinstance, xtask, SST_GAIN_RAMP_DURATION, \ | ||
763 | xgain_val, xmin_tc, xmax_tc, xpname) }, \ | ||
764 | { SST_GAIN_KCONTROL_BOOL(SST_CONTROL_NAME(xpname, xmname, xinstance, "Switch"), \ | ||
765 | xhandler_get, xhandler_put, xmod, xpipe, xinstance, xtask, \ | ||
766 | xgain_val, xpname) } ,\ | ||
767 | { SST_GAIN_KCONTROL_TLV(SST_CONTROL_NAME(xpname, xmname, xinstance, "Volume"), \ | ||
768 | xhandler_get, xhandler_put, xmod, xpipe, xinstance, xtask, tlv_array, \ | ||
769 | xgain_val, xmin_gain, xmax_gain, xpname) } | ||
770 | |||
771 | #define SST_GAIN_TC_MIN 5 | ||
772 | #define SST_GAIN_TC_MAX 5000 | ||
773 | #define SST_GAIN_MIN_VALUE -1440 /* in 0.1 DB units */ | ||
774 | #define SST_GAIN_MAX_VALUE 360 | ||
775 | |||
776 | enum sst_algo_kcontrol_type { | ||
777 | SST_ALGO_PARAMS, | ||
778 | SST_ALGO_BYPASS, | ||
779 | }; | ||
780 | |||
781 | struct sst_algo_control { | ||
782 | enum sst_algo_kcontrol_type type; | ||
783 | int max; | ||
784 | u16 module_id; | ||
785 | u16 pipe_id; | ||
786 | u16 task_id; | ||
787 | u16 cmd_id; | ||
788 | bool bypass; | ||
789 | unsigned char *params; | ||
790 | struct snd_soc_dapm_widget *w; | ||
791 | }; | ||
792 | |||
793 | /* size of the control = size of params + size of length field */ | ||
794 | #define SST_ALGO_CTL_VALUE(xcount, xtype, xpipe, xmod, xtask, xcmd) \ | ||
795 | (struct sst_algo_control){ \ | ||
796 | .max = xcount + sizeof(u16), .type = xtype, .module_id = xmod, \ | ||
797 | .pipe_id = xpipe, .task_id = xtask, .cmd_id = xcmd, \ | ||
798 | } | ||
799 | |||
800 | #define SST_ALGO_KCONTROL(xname, xcount, xmod, xpipe, \ | ||
801 | xtask, xcmd, xtype, xinfo, xget, xput) \ | ||
802 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
803 | .name = xname, \ | ||
804 | .info = xinfo, .get = xget, .put = xput, \ | ||
805 | .private_value = (unsigned long)& \ | ||
806 | SST_ALGO_CTL_VALUE(xcount, xtype, xpipe, \ | ||
807 | xmod, xtask, xcmd), \ | ||
808 | } | ||
809 | |||
810 | #define SST_ALGO_KCONTROL_BYTES(xpname, xmname, xcount, xmod, \ | ||
811 | xpipe, xinstance, xtask, xcmd) \ | ||
812 | SST_ALGO_KCONTROL(SST_CONTROL_NAME(xpname, xmname, xinstance, "params"), \ | ||
813 | xcount, xmod, xpipe, xtask, xcmd, SST_ALGO_PARAMS, \ | ||
814 | sst_algo_bytes_ctl_info, \ | ||
815 | sst_algo_control_get, sst_algo_control_set) | ||
816 | |||
817 | #define SST_ALGO_KCONTROL_BOOL(xpname, xmname, xmod, xpipe, xinstance, xtask) \ | ||
818 | SST_ALGO_KCONTROL(SST_CONTROL_NAME(xpname, xmname, xinstance, "bypass"), \ | ||
819 | 0, xmod, xpipe, xtask, 0, SST_ALGO_BYPASS, \ | ||
820 | snd_soc_info_bool_ext, \ | ||
821 | sst_algo_control_get, sst_algo_control_set) | ||
822 | |||
823 | #define SST_ALGO_BYPASS_PARAMS(xpname, xmname, xcount, xmod, xpipe, \ | ||
824 | xinstance, xtask, xcmd) \ | ||
825 | SST_ALGO_KCONTROL_BOOL(xpname, xmname, xmod, xpipe, xinstance, xtask), \ | ||
826 | SST_ALGO_KCONTROL_BYTES(xpname, xmname, xcount, xmod, xpipe, xinstance, xtask, xcmd) | ||
827 | |||
828 | #define SST_COMBO_ALGO_KCONTROL_BYTES(xpname, xmname, xsubmod, xcount, xmod, \ | ||
829 | xpipe, xinstance, xtask, xcmd) \ | ||
830 | SST_ALGO_KCONTROL(SST_COMBO_CONTROL_NAME(xpname, xmname, xinstance, "params", \ | ||
831 | xsubmod), \ | ||
832 | xcount, xmod, xpipe, xtask, xcmd, SST_ALGO_PARAMS, \ | ||
833 | sst_algo_bytes_ctl_info, \ | ||
834 | sst_algo_control_get, sst_algo_control_set) | ||
835 | |||
836 | |||
837 | struct sst_enum { | ||
838 | bool tx; | ||
839 | unsigned short reg; | ||
840 | unsigned int max; | ||
841 | const char * const *texts; | ||
842 | struct snd_soc_dapm_widget *w; | ||
843 | }; | ||
844 | |||
845 | /* only 4 slots/channels supported atm */ | ||
846 | #define SST_SSP_SLOT_ENUM(s_ch_no, is_tx, xtexts) \ | ||
847 | (struct sst_enum){ .reg = s_ch_no, .tx = is_tx, .max = 4+1, .texts = xtexts, } | ||
848 | |||
849 | #define SST_SLOT_CTL_NAME(xpname, xmname, s_ch_name) \ | ||
850 | xpname " " xmname " " s_ch_name | ||
851 | |||
852 | #define SST_SSP_SLOT_CTL(xpname, xmname, s_ch_name, s_ch_no, is_tx, xtexts, xget, xput) \ | ||
853 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
854 | .name = SST_SLOT_CTL_NAME(xpname, xmname, s_ch_name), \ | ||
855 | .info = sst_slot_enum_info, \ | ||
856 | .get = xget, .put = xput, \ | ||
857 | .private_value = (unsigned long)&SST_SSP_SLOT_ENUM(s_ch_no, is_tx, xtexts), \ | ||
858 | } | ||
859 | |||
860 | #define SST_MUX_CTL_NAME(xpname, xinstance) \ | ||
861 | xpname " " #xinstance | ||
862 | |||
863 | #define SST_SSP_MUX_ENUM(xreg, xshift, xtexts) \ | ||
864 | (struct soc_enum) SOC_ENUM_DOUBLE(xreg, xshift, xshift, ARRAY_SIZE(xtexts), xtexts) | ||
865 | |||
866 | #define SST_SSP_MUX_CTL(xpname, xinstance, xreg, xshift, xtexts) \ | ||
867 | SOC_DAPM_ENUM(SST_MUX_CTL_NAME(xpname, xinstance), \ | ||
868 | SST_SSP_MUX_ENUM(xreg, xshift, xtexts)) | ||
869 | |||
870 | #endif | ||