Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/sound/soc/intel/atom/sst-atom-controls.h
26493 views
1
/* SPDX-License-Identifier: GPL-2.0-only */
2
/*
3
* sst-atom-controls.h - Intel MID Platform driver header file
4
*
5
* Copyright (C) 2013-14 Intel Corp
6
* Author: Ramesh Babu <[email protected]>
7
* Omair M Abdullah <[email protected]>
8
* Samreen Nilofer <[email protected]>
9
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10
*
11
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
12
*/
13
14
#ifndef __SST_ATOM_CONTROLS_H__
15
#define __SST_ATOM_CONTROLS_H__
16
17
#include <sound/soc.h>
18
#include <sound/tlv.h>
19
20
enum {
21
MERR_DPCM_AUDIO = 0,
22
MERR_DPCM_DEEP_BUFFER,
23
MERR_DPCM_COMPR,
24
};
25
26
/* define a bit for each mixer input */
27
#define SST_MIX_IP(x) (x)
28
29
#define SST_IP_MODEM SST_MIX_IP(0)
30
#define SST_IP_BT SST_MIX_IP(1)
31
#define SST_IP_CODEC0 SST_MIX_IP(2)
32
#define SST_IP_CODEC1 SST_MIX_IP(3)
33
#define SST_IP_LOOP0 SST_MIX_IP(4)
34
#define SST_IP_LOOP1 SST_MIX_IP(5)
35
#define SST_IP_LOOP2 SST_MIX_IP(6)
36
#define SST_IP_PROBE SST_MIX_IP(7)
37
#define SST_IP_VOIP SST_MIX_IP(12)
38
#define SST_IP_PCM0 SST_MIX_IP(13)
39
#define SST_IP_PCM1 SST_MIX_IP(14)
40
#define SST_IP_MEDIA0 SST_MIX_IP(17)
41
#define SST_IP_MEDIA1 SST_MIX_IP(18)
42
#define SST_IP_MEDIA2 SST_MIX_IP(19)
43
#define SST_IP_MEDIA3 SST_MIX_IP(20)
44
45
#define SST_IP_LAST SST_IP_MEDIA3
46
47
#define SST_SWM_INPUT_COUNT (SST_IP_LAST + 1)
48
#define SST_CMD_SWM_MAX_INPUTS 6
49
50
#define SST_PATH_ID_SHIFT 8
51
#define SST_DEFAULT_LOCATION_ID 0xFFFF
52
#define SST_DEFAULT_CELL_NBR 0xFF
53
#define SST_DEFAULT_MODULE_ID 0xFFFF
54
55
/*
56
* Audio DSP Path Ids. Specified by the audio DSP FW
57
*/
58
enum sst_path_index {
59
SST_PATH_INDEX_MODEM_OUT = (0x00 << SST_PATH_ID_SHIFT),
60
SST_PATH_INDEX_CODEC_OUT0 = (0x02 << SST_PATH_ID_SHIFT),
61
SST_PATH_INDEX_CODEC_OUT1 = (0x03 << SST_PATH_ID_SHIFT),
62
63
SST_PATH_INDEX_SPROT_LOOP_OUT = (0x04 << SST_PATH_ID_SHIFT),
64
SST_PATH_INDEX_MEDIA_LOOP1_OUT = (0x05 << SST_PATH_ID_SHIFT),
65
SST_PATH_INDEX_MEDIA_LOOP2_OUT = (0x06 << SST_PATH_ID_SHIFT),
66
67
SST_PATH_INDEX_VOIP_OUT = (0x0C << SST_PATH_ID_SHIFT),
68
SST_PATH_INDEX_PCM0_OUT = (0x0D << SST_PATH_ID_SHIFT),
69
SST_PATH_INDEX_PCM1_OUT = (0x0E << SST_PATH_ID_SHIFT),
70
SST_PATH_INDEX_PCM2_OUT = (0x0F << SST_PATH_ID_SHIFT),
71
72
SST_PATH_INDEX_MEDIA0_OUT = (0x12 << SST_PATH_ID_SHIFT),
73
SST_PATH_INDEX_MEDIA1_OUT = (0x13 << SST_PATH_ID_SHIFT),
74
75
76
/* Start of input paths */
77
SST_PATH_INDEX_MODEM_IN = (0x80 << SST_PATH_ID_SHIFT),
78
SST_PATH_INDEX_CODEC_IN0 = (0x82 << SST_PATH_ID_SHIFT),
79
SST_PATH_INDEX_CODEC_IN1 = (0x83 << SST_PATH_ID_SHIFT),
80
81
SST_PATH_INDEX_SPROT_LOOP_IN = (0x84 << SST_PATH_ID_SHIFT),
82
SST_PATH_INDEX_MEDIA_LOOP1_IN = (0x85 << SST_PATH_ID_SHIFT),
83
SST_PATH_INDEX_MEDIA_LOOP2_IN = (0x86 << SST_PATH_ID_SHIFT),
84
85
SST_PATH_INDEX_VOIP_IN = (0x8C << SST_PATH_ID_SHIFT),
86
87
SST_PATH_INDEX_PCM0_IN = (0x8D << SST_PATH_ID_SHIFT),
88
SST_PATH_INDEX_PCM1_IN = (0x8E << SST_PATH_ID_SHIFT),
89
90
SST_PATH_INDEX_MEDIA0_IN = (0x8F << SST_PATH_ID_SHIFT),
91
SST_PATH_INDEX_MEDIA1_IN = (0x90 << SST_PATH_ID_SHIFT),
92
SST_PATH_INDEX_MEDIA2_IN = (0x91 << SST_PATH_ID_SHIFT),
93
94
SST_PATH_INDEX_MEDIA3_IN = (0x9C << SST_PATH_ID_SHIFT),
95
96
SST_PATH_INDEX_RESERVED = (0xFF << SST_PATH_ID_SHIFT),
97
};
98
99
/*
100
* path IDs
101
*/
102
enum sst_swm_inputs {
103
SST_SWM_IN_MODEM = (SST_PATH_INDEX_MODEM_IN | SST_DEFAULT_CELL_NBR),
104
SST_SWM_IN_CODEC0 = (SST_PATH_INDEX_CODEC_IN0 | SST_DEFAULT_CELL_NBR),
105
SST_SWM_IN_CODEC1 = (SST_PATH_INDEX_CODEC_IN1 | SST_DEFAULT_CELL_NBR),
106
SST_SWM_IN_SPROT_LOOP = (SST_PATH_INDEX_SPROT_LOOP_IN | SST_DEFAULT_CELL_NBR),
107
SST_SWM_IN_MEDIA_LOOP1 = (SST_PATH_INDEX_MEDIA_LOOP1_IN | SST_DEFAULT_CELL_NBR),
108
SST_SWM_IN_MEDIA_LOOP2 = (SST_PATH_INDEX_MEDIA_LOOP2_IN | SST_DEFAULT_CELL_NBR),
109
SST_SWM_IN_VOIP = (SST_PATH_INDEX_VOIP_IN | SST_DEFAULT_CELL_NBR),
110
SST_SWM_IN_PCM0 = (SST_PATH_INDEX_PCM0_IN | SST_DEFAULT_CELL_NBR),
111
SST_SWM_IN_PCM1 = (SST_PATH_INDEX_PCM1_IN | SST_DEFAULT_CELL_NBR),
112
SST_SWM_IN_MEDIA0 = (SST_PATH_INDEX_MEDIA0_IN | SST_DEFAULT_CELL_NBR), /* Part of Media Mixer */
113
SST_SWM_IN_MEDIA1 = (SST_PATH_INDEX_MEDIA1_IN | SST_DEFAULT_CELL_NBR), /* Part of Media Mixer */
114
SST_SWM_IN_MEDIA2 = (SST_PATH_INDEX_MEDIA2_IN | SST_DEFAULT_CELL_NBR), /* Part of Media Mixer */
115
SST_SWM_IN_MEDIA3 = (SST_PATH_INDEX_MEDIA3_IN | SST_DEFAULT_CELL_NBR), /* Part of Media Mixer */
116
SST_SWM_IN_END = (SST_PATH_INDEX_RESERVED | SST_DEFAULT_CELL_NBR)
117
};
118
119
/*
120
* path IDs
121
*/
122
enum sst_swm_outputs {
123
SST_SWM_OUT_MODEM = (SST_PATH_INDEX_MODEM_OUT | SST_DEFAULT_CELL_NBR),
124
SST_SWM_OUT_CODEC0 = (SST_PATH_INDEX_CODEC_OUT0 | SST_DEFAULT_CELL_NBR),
125
SST_SWM_OUT_CODEC1 = (SST_PATH_INDEX_CODEC_OUT1 | SST_DEFAULT_CELL_NBR),
126
SST_SWM_OUT_SPROT_LOOP = (SST_PATH_INDEX_SPROT_LOOP_OUT | SST_DEFAULT_CELL_NBR),
127
SST_SWM_OUT_MEDIA_LOOP1 = (SST_PATH_INDEX_MEDIA_LOOP1_OUT | SST_DEFAULT_CELL_NBR),
128
SST_SWM_OUT_MEDIA_LOOP2 = (SST_PATH_INDEX_MEDIA_LOOP2_OUT | SST_DEFAULT_CELL_NBR),
129
SST_SWM_OUT_VOIP = (SST_PATH_INDEX_VOIP_OUT | SST_DEFAULT_CELL_NBR),
130
SST_SWM_OUT_PCM0 = (SST_PATH_INDEX_PCM0_OUT | SST_DEFAULT_CELL_NBR),
131
SST_SWM_OUT_PCM1 = (SST_PATH_INDEX_PCM1_OUT | SST_DEFAULT_CELL_NBR),
132
SST_SWM_OUT_PCM2 = (SST_PATH_INDEX_PCM2_OUT | SST_DEFAULT_CELL_NBR),
133
SST_SWM_OUT_MEDIA0 = (SST_PATH_INDEX_MEDIA0_OUT | SST_DEFAULT_CELL_NBR), /* Part of Media Mixer */
134
SST_SWM_OUT_MEDIA1 = (SST_PATH_INDEX_MEDIA1_OUT | SST_DEFAULT_CELL_NBR), /* Part of Media Mixer */
135
SST_SWM_OUT_END = (SST_PATH_INDEX_RESERVED | SST_DEFAULT_CELL_NBR),
136
};
137
138
enum sst_ipc_msg {
139
SST_IPC_IA_CMD = 1,
140
SST_IPC_IA_SET_PARAMS,
141
SST_IPC_IA_GET_PARAMS,
142
};
143
144
enum sst_cmd_type {
145
SST_CMD_BYTES_SET = 1,
146
SST_CMD_BYTES_GET = 2,
147
};
148
149
enum sst_task {
150
SST_TASK_SBA = 1,
151
SST_TASK_MMX = 3,
152
};
153
154
enum sst_type {
155
SST_TYPE_CMD = 1,
156
SST_TYPE_PARAMS,
157
};
158
159
enum sst_flag {
160
SST_FLAG_BLOCKED = 1,
161
SST_FLAG_NONBLOCK,
162
};
163
164
/*
165
* Enumeration for indexing the gain cells in VB_SET_GAIN DSP command
166
*/
167
enum sst_gain_index {
168
/* GAIN IDs for SB task start here */
169
SST_GAIN_INDEX_CODEC_OUT0,
170
SST_GAIN_INDEX_CODEC_OUT1,
171
SST_GAIN_INDEX_CODEC_IN0,
172
SST_GAIN_INDEX_CODEC_IN1,
173
174
SST_GAIN_INDEX_SPROT_LOOP_OUT,
175
SST_GAIN_INDEX_MEDIA_LOOP1_OUT,
176
SST_GAIN_INDEX_MEDIA_LOOP2_OUT,
177
178
SST_GAIN_INDEX_PCM0_IN_LEFT,
179
SST_GAIN_INDEX_PCM0_IN_RIGHT,
180
181
SST_GAIN_INDEX_PCM1_OUT_LEFT,
182
SST_GAIN_INDEX_PCM1_OUT_RIGHT,
183
SST_GAIN_INDEX_PCM1_IN_LEFT,
184
SST_GAIN_INDEX_PCM1_IN_RIGHT,
185
SST_GAIN_INDEX_PCM2_OUT_LEFT,
186
187
SST_GAIN_INDEX_PCM2_OUT_RIGHT,
188
SST_GAIN_INDEX_VOIP_OUT,
189
SST_GAIN_INDEX_VOIP_IN,
190
191
/* Gain IDs for MMX task start here */
192
SST_GAIN_INDEX_MEDIA0_IN_LEFT,
193
SST_GAIN_INDEX_MEDIA0_IN_RIGHT,
194
SST_GAIN_INDEX_MEDIA1_IN_LEFT,
195
SST_GAIN_INDEX_MEDIA1_IN_RIGHT,
196
197
SST_GAIN_INDEX_MEDIA2_IN_LEFT,
198
SST_GAIN_INDEX_MEDIA2_IN_RIGHT,
199
200
SST_GAIN_INDEX_GAIN_END
201
};
202
203
/*
204
* Audio DSP module IDs specified by FW spec
205
* TODO: Update with all modules
206
*/
207
enum sst_module_id {
208
SST_MODULE_ID_PCM = 0x0001,
209
SST_MODULE_ID_MP3 = 0x0002,
210
SST_MODULE_ID_MP24 = 0x0003,
211
SST_MODULE_ID_AAC = 0x0004,
212
SST_MODULE_ID_AACP = 0x0005,
213
SST_MODULE_ID_EAACP = 0x0006,
214
SST_MODULE_ID_WMA9 = 0x0007,
215
SST_MODULE_ID_WMA10 = 0x0008,
216
SST_MODULE_ID_WMA10P = 0x0009,
217
SST_MODULE_ID_RA = 0x000A,
218
SST_MODULE_ID_DDAC3 = 0x000B,
219
SST_MODULE_ID_TRUE_HD = 0x000C,
220
SST_MODULE_ID_HD_PLUS = 0x000D,
221
222
SST_MODULE_ID_SRC = 0x0064,
223
SST_MODULE_ID_DOWNMIX = 0x0066,
224
SST_MODULE_ID_GAIN_CELL = 0x0067,
225
SST_MODULE_ID_SPROT = 0x006D,
226
SST_MODULE_ID_BASS_BOOST = 0x006E,
227
SST_MODULE_ID_STEREO_WDNG = 0x006F,
228
SST_MODULE_ID_AV_REMOVAL = 0x0070,
229
SST_MODULE_ID_MIC_EQ = 0x0071,
230
SST_MODULE_ID_SPL = 0x0072,
231
SST_MODULE_ID_ALGO_VTSV = 0x0073,
232
SST_MODULE_ID_NR = 0x0076,
233
SST_MODULE_ID_BWX = 0x0077,
234
SST_MODULE_ID_DRP = 0x0078,
235
SST_MODULE_ID_MDRP = 0x0079,
236
237
SST_MODULE_ID_ANA = 0x007A,
238
SST_MODULE_ID_AEC = 0x007B,
239
SST_MODULE_ID_NR_SNS = 0x007C,
240
SST_MODULE_ID_SER = 0x007D,
241
SST_MODULE_ID_AGC = 0x007E,
242
243
SST_MODULE_ID_CNI = 0x007F,
244
SST_MODULE_ID_CONTEXT_ALGO_AWARE = 0x0080,
245
SST_MODULE_ID_FIR_24 = 0x0081,
246
SST_MODULE_ID_IIR_24 = 0x0082,
247
248
SST_MODULE_ID_ASRC = 0x0083,
249
SST_MODULE_ID_TONE_GEN = 0x0084,
250
SST_MODULE_ID_BMF = 0x0086,
251
SST_MODULE_ID_EDL = 0x0087,
252
SST_MODULE_ID_GLC = 0x0088,
253
254
SST_MODULE_ID_FIR_16 = 0x0089,
255
SST_MODULE_ID_IIR_16 = 0x008A,
256
SST_MODULE_ID_DNR = 0x008B,
257
258
SST_MODULE_ID_VIRTUALIZER = 0x008C,
259
SST_MODULE_ID_VISUALIZATION = 0x008D,
260
SST_MODULE_ID_LOUDNESS_OPTIMIZER = 0x008E,
261
SST_MODULE_ID_REVERBERATION = 0x008F,
262
263
SST_MODULE_ID_CNI_TX = 0x0090,
264
SST_MODULE_ID_REF_LINE = 0x0091,
265
SST_MODULE_ID_VOLUME = 0x0092,
266
SST_MODULE_ID_FILT_DCR = 0x0094,
267
SST_MODULE_ID_SLV = 0x009A,
268
SST_MODULE_ID_NLF = 0x009B,
269
SST_MODULE_ID_TNR = 0x009C,
270
SST_MODULE_ID_WNR = 0x009D,
271
272
SST_MODULE_ID_LOG = 0xFF00,
273
274
SST_MODULE_ID_TASK = 0xFFFF,
275
};
276
277
enum sst_cmd {
278
SBA_IDLE = 14,
279
SBA_VB_SET_SPEECH_PATH = 26,
280
MMX_SET_GAIN = 33,
281
SBA_VB_SET_GAIN = 33,
282
FBA_VB_RX_CNI = 35,
283
MMX_SET_GAIN_TIMECONST = 36,
284
SBA_VB_SET_TIMECONST = 36,
285
SBA_VB_START = 85,
286
SBA_SET_SWM = 114,
287
SBA_SET_MDRP = 116,
288
SBA_HW_SET_SSP = 117,
289
SBA_SET_MEDIA_LOOP_MAP = 118,
290
SBA_SET_MEDIA_PATH = 119,
291
MMX_SET_MEDIA_PATH = 119,
292
SBA_VB_LPRO = 126,
293
SBA_VB_SET_FIR = 128,
294
SBA_VB_SET_IIR = 129,
295
SBA_SET_SSP_SLOT_MAP = 130,
296
};
297
298
enum sst_dsp_switch {
299
SST_SWITCH_OFF = 0,
300
SST_SWITCH_ON = 3,
301
};
302
303
enum sst_path_switch {
304
SST_PATH_OFF = 0,
305
SST_PATH_ON = 1,
306
};
307
308
enum sst_swm_state {
309
SST_SWM_OFF = 0,
310
SST_SWM_ON = 3,
311
};
312
313
#define SST_FILL_LOCATION_IDS(dst, cell_idx, pipe_id) do { \
314
dst.location_id.p.cell_nbr_idx = (cell_idx); \
315
dst.location_id.p.path_id = (pipe_id); \
316
} while (0)
317
#define SST_FILL_LOCATION_ID(dst, loc_id) (\
318
dst.location_id.f = (loc_id))
319
#define SST_FILL_MODULE_ID(dst, mod_id) (\
320
dst.module_id = (mod_id))
321
322
#define SST_FILL_DESTINATION1(dst, id) do { \
323
SST_FILL_LOCATION_ID(dst, (id) & 0xFFFF); \
324
SST_FILL_MODULE_ID(dst, ((id) & 0xFFFF0000) >> 16); \
325
} while (0)
326
#define SST_FILL_DESTINATION2(dst, loc_id, mod_id) do { \
327
SST_FILL_LOCATION_ID(dst, loc_id); \
328
SST_FILL_MODULE_ID(dst, mod_id); \
329
} while (0)
330
#define SST_FILL_DESTINATION3(dst, cell_idx, path_id, mod_id) do { \
331
SST_FILL_LOCATION_IDS(dst, cell_idx, path_id); \
332
SST_FILL_MODULE_ID(dst, mod_id); \
333
} while (0)
334
335
#define SST_FILL_DESTINATION(level, dst, ...) \
336
SST_FILL_DESTINATION##level(dst, __VA_ARGS__)
337
#define SST_FILL_DEFAULT_DESTINATION(dst) \
338
SST_FILL_DESTINATION(2, dst, SST_DEFAULT_LOCATION_ID, SST_DEFAULT_MODULE_ID)
339
340
struct sst_destination_id {
341
union sst_location_id {
342
struct {
343
u8 cell_nbr_idx; /* module index */
344
u8 path_id; /* pipe_id */
345
} __packed p; /* part */
346
u16 f; /* full */
347
} __packed location_id;
348
u16 module_id;
349
} __packed;
350
struct sst_dsp_header {
351
struct sst_destination_id dst;
352
u16 command_id;
353
u16 length;
354
} __packed;
355
356
/*
357
*
358
* Common Commands
359
*
360
*/
361
struct sst_cmd_generic {
362
struct sst_dsp_header header;
363
} __packed;
364
365
struct swm_input_ids {
366
struct sst_destination_id input_id;
367
} __packed;
368
369
struct sst_cmd_set_swm {
370
struct sst_dsp_header header;
371
struct sst_destination_id output_id;
372
u16 switch_state;
373
u16 nb_inputs;
374
struct swm_input_ids input[SST_CMD_SWM_MAX_INPUTS];
375
} __packed;
376
377
struct sst_cmd_set_media_path {
378
struct sst_dsp_header header;
379
u16 switch_state;
380
} __packed;
381
382
struct pcm_cfg {
383
u8 s_length:2;
384
u8 rate:3;
385
u8 format:3;
386
} __packed;
387
388
struct sst_cmd_set_speech_path {
389
struct sst_dsp_header header;
390
u16 switch_state;
391
struct {
392
u16 rsvd:8;
393
struct pcm_cfg cfg;
394
} config;
395
} __packed;
396
397
struct gain_cell {
398
struct sst_destination_id dest;
399
s16 cell_gain_left;
400
s16 cell_gain_right;
401
u16 gain_time_constant;
402
} __packed;
403
404
#define NUM_GAIN_CELLS 1
405
struct sst_cmd_set_gain_dual {
406
struct sst_dsp_header header;
407
u16 gain_cell_num;
408
struct gain_cell cell_gains[NUM_GAIN_CELLS];
409
} __packed;
410
struct sst_cmd_set_params {
411
struct sst_destination_id dst;
412
u16 command_id;
413
char params[];
414
} __packed;
415
416
417
struct sst_cmd_sba_vb_start {
418
struct sst_dsp_header header;
419
} __packed;
420
421
union sba_media_loop_params {
422
struct {
423
u16 rsvd:8;
424
struct pcm_cfg cfg;
425
} part;
426
u16 full;
427
} __packed;
428
429
struct sst_cmd_sba_set_media_loop_map {
430
struct sst_dsp_header header;
431
u16 switch_state;
432
union sba_media_loop_params param;
433
u16 map;
434
} __packed;
435
436
struct sst_cmd_tone_stop {
437
struct sst_dsp_header header;
438
u16 switch_state;
439
} __packed;
440
441
enum sst_ssp_mode {
442
SSP_MODE_PROVIDER = 0,
443
SSP_MODE_CONSUMER = 1,
444
};
445
446
enum sst_ssp_pcm_mode {
447
SSP_PCM_MODE_NORMAL = 0,
448
SSP_PCM_MODE_NETWORK = 1,
449
};
450
451
enum sst_ssp_duplex {
452
SSP_DUPLEX = 0,
453
SSP_RX = 1,
454
SSP_TX = 2,
455
};
456
457
enum sst_ssp_fs_frequency {
458
SSP_FS_8_KHZ = 0,
459
SSP_FS_16_KHZ = 1,
460
SSP_FS_44_1_KHZ = 2,
461
SSP_FS_48_KHZ = 3,
462
};
463
464
enum sst_ssp_fs_polarity {
465
SSP_FS_ACTIVE_LOW = 0,
466
SSP_FS_ACTIVE_HIGH = 1,
467
};
468
469
enum sst_ssp_protocol {
470
SSP_MODE_PCM = 0,
471
SSP_MODE_I2S = 1,
472
};
473
474
enum sst_ssp_port_id {
475
SSP_MODEM = 0,
476
SSP_BT = 1,
477
SSP_FM = 2,
478
SSP_CODEC = 3,
479
};
480
481
struct sst_cmd_sba_hw_set_ssp {
482
struct sst_dsp_header header;
483
u16 selection; /* 0:SSP0(def), 1:SSP1, 2:SSP2 */
484
485
u16 switch_state;
486
487
u16 nb_bits_per_slots:6; /* 0-32 bits, 24 (def) */
488
u16 nb_slots:4; /* 0-8: slots per frame */
489
u16 mode:3; /* 0:Master, 1: Slave */
490
u16 duplex:3;
491
492
u16 active_tx_slot_map:8; /* Bit map, 0:off, 1:on */
493
u16 reserved1:8;
494
495
u16 active_rx_slot_map:8; /* Bit map 0: Off, 1:On */
496
u16 reserved2:8;
497
498
u16 frame_sync_frequency;
499
500
u16 frame_sync_polarity:8;
501
u16 data_polarity:8;
502
503
u16 frame_sync_width; /* 1 to N clocks */
504
u16 ssp_protocol:8;
505
u16 start_delay:8; /* Start delay in terms of clock ticks */
506
} __packed;
507
508
#define SST_MAX_TDM_SLOTS 8
509
510
struct sst_param_sba_ssp_slot_map {
511
struct sst_dsp_header header;
512
513
u16 param_id;
514
u16 param_len;
515
u16 ssp_index;
516
517
u8 rx_slot_map[SST_MAX_TDM_SLOTS];
518
u8 tx_slot_map[SST_MAX_TDM_SLOTS];
519
} __packed;
520
521
enum {
522
SST_PROBE_EXTRACTOR = 0,
523
SST_PROBE_INJECTOR = 1,
524
};
525
526
/**** widget defines *****/
527
528
#define SST_MODULE_GAIN 1
529
#define SST_MODULE_ALGO 2
530
531
#define SST_FMT_MONO 0
532
#define SST_FMT_STEREO 3
533
534
/* physical SSP numbers */
535
enum {
536
SST_SSP0 = 0,
537
SST_SSP1,
538
SST_SSP2,
539
SST_SSP_LAST = SST_SSP2,
540
};
541
542
#define SST_NUM_SSPS (SST_SSP_LAST + 1) /* physical SSPs */
543
#define SST_MAX_SSP_MUX 2 /* single SSP muxed between pipes */
544
#define SST_MAX_SSP_DOMAINS 2 /* domains present in each pipe */
545
546
struct sst_module {
547
struct snd_kcontrol *kctl;
548
struct list_head node;
549
};
550
551
struct sst_ssp_config {
552
u8 ssp_id;
553
u8 bits_per_slot;
554
u8 slots;
555
u8 ssp_mode;
556
u8 pcm_mode;
557
u8 duplex;
558
u8 ssp_protocol;
559
u8 fs_frequency;
560
u8 active_slot_map;
561
u8 start_delay;
562
u16 fs_width;
563
u8 frame_sync_polarity;
564
u8 data_polarity;
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[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
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
int sst_fill_ssp_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
871
unsigned int rx_mask, int slots, int slot_width);
872
int sst_fill_ssp_config(struct snd_soc_dai *dai, unsigned int fmt);
873
void sst_fill_ssp_defaults(struct snd_soc_dai *dai);
874
875
#endif
876
877