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