1/* SPDX-License-Identifier: GPL-2.0-only */
2/*
3 * Copyright(c) 2020 Intel Corporation. All rights reserved.
4 *
5 * Author: Cezary Rojewski <cezary.rojewski@intel.com>
6 */
7
8#ifndef __SND_SOC_INTEL_CATPT_MSG_H
9#define __SND_SOC_INTEL_CATPT_MSG_H
10
11struct catpt_dev;
12
13/* IPC messages base types  */
14
15enum catpt_reply_status {
16	CATPT_REPLY_SUCCESS = 0,
17	CATPT_REPLY_ERROR_INVALID_PARAM = 1,
18	CATPT_REPLY_UNKNOWN_MESSAGE_TYPE = 2,
19	CATPT_REPLY_OUT_OF_RESOURCES = 3,
20	CATPT_REPLY_BUSY = 4,
21	CATPT_REPLY_PENDING = 5,
22	CATPT_REPLY_FAILURE = 6,
23	CATPT_REPLY_INVALID_REQUEST = 7,
24	CATPT_REPLY_UNINITIALIZED = 8,
25	CATPT_REPLY_NOT_FOUND = 9,
26	CATPT_REPLY_SOURCE_NOT_STARTED = 10,
27};
28
29/* GLOBAL messages */
30
31enum catpt_global_msg_type {
32	CATPT_GLB_GET_FW_VERSION = 0,
33	CATPT_GLB_ALLOCATE_STREAM = 3,
34	CATPT_GLB_FREE_STREAM = 4,
35	CATPT_GLB_STREAM_MESSAGE = 6,
36	CATPT_GLB_REQUEST_CORE_DUMP = 7,
37	CATPT_GLB_SET_DEVICE_FORMATS = 10,
38	CATPT_GLB_ENTER_DX_STATE = 12,
39	CATPT_GLB_GET_MIXER_STREAM_INFO = 13,
40};
41
42union catpt_global_msg {
43	u32 val;
44	struct {
45		u32 status:5;
46		u32 context:19; /* stream or module specific */
47		u32 global_msg_type:5;
48		u32 fw_ready:1;
49		u32 done:1;
50		u32 busy:1;
51	};
52} __packed;
53
54#define CATPT_MSG(hdr) { .val = hdr }
55#define CATPT_GLOBAL_MSG(msg_type) \
56	{ .global_msg_type = CATPT_GLB_##msg_type }
57
58#define BUILD_HASH_SIZE		40
59
60struct catpt_fw_version {
61	u8 build;
62	u8 minor;
63	u8 major;
64	u8 type;
65	u8 build_hash[BUILD_HASH_SIZE];
66	u32 log_providers_hash;
67} __packed;
68
69int catpt_ipc_get_fw_version(struct catpt_dev *cdev,
70			     struct catpt_fw_version *version);
71
72enum catpt_pin_id {
73	CATPT_PIN_ID_SYSTEM = 0,
74	CATPT_PIN_ID_REFERENCE = 1,
75	CATPT_PIN_ID_CAPTURE1 = 2,
76	CATPT_PIN_ID_CAPTURE2 = 3,
77	CATPT_PIN_ID_OFFLOAD1 = 4,
78	CATPT_PIN_ID_OFFLOAD2 = 5,
79	CATPT_PIN_ID_MIXER = 7,
80	CATPT_PIN_ID_BLUETOOTH_CAPTURE = 8,
81	CATPT_PIN_ID_BLUETOOTH_RENDER = 9,
82};
83
84enum catpt_path_id {
85	CATPT_PATH_SSP0_OUT = 0,
86	CATPT_PATH_SSP0_IN = 1,
87	CATPT_PATH_SSP1_OUT = 2,
88	CATPT_PATH_SSP1_IN = 3,
89	/* duplicated audio in capture path */
90	CATPT_PATH_SSP0_IN_DUP = 4,
91};
92
93enum catpt_stream_type {
94	CATPT_STRM_TYPE_RENDER = 0, /* offload */
95	CATPT_STRM_TYPE_SYSTEM = 1,
96	CATPT_STRM_TYPE_CAPTURE = 2,
97	CATPT_STRM_TYPE_LOOPBACK = 3,
98	CATPT_STRM_TYPE_BLUETOOTH_RENDER = 4,
99	CATPT_STRM_TYPE_BLUETOOTH_CAPTURE = 5,
100};
101
102enum catpt_format_id {
103	CATPT_FORMAT_PCM = 0,
104	CATPT_FORMAT_MP3 = 1,
105	CATPT_FORMAT_AAC = 2,
106	CATPT_FORMAT_WMA = 3,
107};
108
109enum catpt_channel_index {
110	CATPT_CHANNEL_LEFT = 0x0,
111	CATPT_CHANNEL_CENTER = 0x1,
112	CATPT_CHANNEL_RIGHT = 0x2,
113	CATPT_CHANNEL_LEFT_SURROUND = 0x3,
114	CATPT_CHANNEL_CENTER_SURROUND = 0x3,
115	CATPT_CHANNEL_RIGHT_SURROUND = 0x4,
116	CATPT_CHANNEL_LFE = 0x7,
117	CATPT_CHANNEL_INVALID = 0xF,
118};
119
120enum catpt_channel_config {
121	CATPT_CHANNEL_CONFIG_MONO	= 0, /* One channel only */
122	CATPT_CHANNEL_CONFIG_STEREO	= 1, /* L & R */
123	CATPT_CHANNEL_CONFIG_2_POINT_1	= 2, /* L, R & LFE; PCM only */
124	CATPT_CHANNEL_CONFIG_3_POINT_0	= 3, /* L, C & R; MP3 & AAC only */
125	CATPT_CHANNEL_CONFIG_3_POINT_1	= 4, /* L, C, R & LFE; PCM only */
126	CATPT_CHANNEL_CONFIG_QUATRO	= 5, /* L, R, Ls & Rs; PCM only */
127	CATPT_CHANNEL_CONFIG_4_POINT_0	= 6, /* L, C, R & Cs; MP3 & AAC only */
128	CATPT_CHANNEL_CONFIG_5_POINT_0	= 7, /* L, C, R, Ls & Rs */
129	CATPT_CHANNEL_CONFIG_5_POINT_1	= 8, /* L, C, R, Ls, Rs & LFE */
130	CATPT_CHANNEL_CONFIG_DUAL_MONO	= 9, /* One channel replicated in two */
131	CATPT_CHANNEL_CONFIG_INVALID	= 10,
132};
133
134enum catpt_interleaving_style {
135	CATPT_INTERLEAVING_PER_CHANNEL	= 0,
136	CATPT_INTERLEAVING_PER_SAMPLE	= 1,
137};
138
139struct catpt_audio_format {
140	u32 sample_rate;
141	u32 bit_depth;
142	u32 channel_map;
143	u32 channel_config;
144	u32 interleaving;
145	u8 num_channels;
146	u8 valid_bit_depth;
147	u8 reserved[2];
148} __packed;
149
150struct catpt_ring_info {
151	u32 page_table_addr;
152	u32 num_pages;
153	u32 size;
154	u32 offset;
155	u32 ring_first_page_pfn;
156} __packed;
157
158#define CATPT_MODULE_COUNT (CATPT_MODID_LAST + 1)
159
160enum catpt_module_id {
161	CATPT_MODID_BASE_FW		= 0x0,
162	CATPT_MODID_MP3			= 0x1,
163	CATPT_MODID_AAC_5_1		= 0x2,
164	CATPT_MODID_AAC_2_0		= 0x3,
165	CATPT_MODID_SRC			= 0x4,
166	CATPT_MODID_WAVES		= 0x5,
167	CATPT_MODID_DOLBY		= 0x6,
168	CATPT_MODID_BOOST		= 0x7,
169	CATPT_MODID_LPAL		= 0x8,
170	CATPT_MODID_DTS			= 0x9,
171	CATPT_MODID_PCM_CAPTURE		= 0xA,
172	CATPT_MODID_PCM_SYSTEM		= 0xB,
173	CATPT_MODID_PCM_REFERENCE	= 0xC,
174	CATPT_MODID_PCM			= 0xD, /* offload */
175	CATPT_MODID_BLUETOOTH_RENDER	= 0xE,
176	CATPT_MODID_BLUETOOTH_CAPTURE	= 0xF,
177	CATPT_MODID_LAST		= CATPT_MODID_BLUETOOTH_CAPTURE,
178};
179
180struct catpt_module_entry {
181	u32 module_id;
182	u32 entry_point;
183} __packed;
184
185struct catpt_module_map {
186	u8 num_entries;
187	struct catpt_module_entry entries[];
188} __packed;
189
190struct catpt_memory_info {
191	u32 offset;
192	u32 size;
193} __packed;
194
195#define CATPT_CHANNELS_MAX	4
196#define CATPT_ALL_CHANNELS_MASK	UINT_MAX
197
198struct catpt_stream_info {
199	u32 stream_hw_id;
200	u32 reserved;
201	u32 read_pos_regaddr;
202	u32 pres_pos_regaddr;
203	u32 peak_meter_regaddr[CATPT_CHANNELS_MAX];
204	u32 volume_regaddr[CATPT_CHANNELS_MAX];
205} __packed;
206
207int catpt_ipc_alloc_stream(struct catpt_dev *cdev,
208			   enum catpt_path_id path_id,
209			   enum catpt_stream_type type,
210			   struct catpt_audio_format *afmt,
211			   struct catpt_ring_info *rinfo,
212			   u8 num_modules,
213			   struct catpt_module_entry *modules,
214			   struct resource *persistent,
215			   struct resource *scratch,
216			   struct catpt_stream_info *sinfo);
217int catpt_ipc_free_stream(struct catpt_dev *cdev, u8 stream_hw_id);
218
219enum catpt_ssp_iface {
220	CATPT_SSP_IFACE_0 = 0,
221	CATPT_SSP_IFACE_1 = 1,
222	CATPT_SSP_IFACE_LAST = CATPT_SSP_IFACE_1,
223};
224
225#define CATPT_SSP_COUNT (CATPT_SSP_IFACE_LAST + 1)
226
227enum catpt_mclk_frequency {
228	CATPT_MCLK_OFF = 0,
229	CATPT_MCLK_FREQ_6_MHZ = 1,
230	CATPT_MCLK_FREQ_21_MHZ = 2,
231	CATPT_MCLK_FREQ_24_MHZ = 3,
232};
233
234enum catpt_ssp_mode {
235	CATPT_SSP_MODE_I2S_CONSUMER = 0,
236	CATPT_SSP_MODE_I2S_PROVIDER = 1,
237	CATPT_SSP_MODE_TDM_PROVIDER = 2,
238};
239
240struct catpt_ssp_device_format {
241	u32 iface;
242	u32 mclk;
243	u32 mode;
244	u16 clock_divider;
245	u8 channels;
246} __packed;
247
248int catpt_ipc_set_device_format(struct catpt_dev *cdev,
249				struct catpt_ssp_device_format *devfmt);
250
251enum catpt_dx_state {
252	CATPT_DX_STATE_D3 = 3,
253};
254
255enum catpt_dx_type {
256	CATPT_DX_TYPE_FW_IMAGE = 0,
257	CATPT_DX_TYPE_MEMORY_DUMP = 1,
258};
259
260struct catpt_save_meminfo {
261	u32 offset;
262	u32 size;
263	u32 source;
264} __packed;
265
266#define SAVE_MEMINFO_MAX	14
267
268struct catpt_dx_context {
269	u32 num_meminfo;
270	struct catpt_save_meminfo meminfo[SAVE_MEMINFO_MAX];
271} __packed;
272
273int catpt_ipc_enter_dxstate(struct catpt_dev *cdev, enum catpt_dx_state state,
274			    struct catpt_dx_context *context);
275
276struct catpt_mixer_stream_info {
277	u32 mixer_hw_id;
278	u32 peak_meter_regaddr[CATPT_CHANNELS_MAX];
279	u32 volume_regaddr[CATPT_CHANNELS_MAX];
280} __packed;
281
282int catpt_ipc_get_mixer_stream_info(struct catpt_dev *cdev,
283				    struct catpt_mixer_stream_info *info);
284
285/* STREAM messages */
286
287enum catpt_stream_msg_type {
288	CATPT_STRM_RESET_STREAM = 0,
289	CATPT_STRM_PAUSE_STREAM = 1,
290	CATPT_STRM_RESUME_STREAM = 2,
291	CATPT_STRM_STAGE_MESSAGE = 3,
292	CATPT_STRM_NOTIFICATION = 4,
293};
294
295enum catpt_stage_action {
296	CATPT_STG_SET_VOLUME = 1,
297	CATPT_STG_SET_WRITE_POSITION = 2,
298	CATPT_STG_MUTE_LOOPBACK = 3,
299};
300
301union catpt_stream_msg {
302	u32 val;
303	struct {
304		u32 status:5;
305		u32 reserved:7;
306		u32 stage_action:4;
307		u32 stream_hw_id:4;
308		u32 stream_msg_type:4;
309		u32 global_msg_type:5;
310		u32 fw_ready:1;
311		u32 done:1;
312		u32 busy:1;
313	};
314} __packed;
315
316#define CATPT_STREAM_MSG(msg_type) \
317{ \
318	.stream_msg_type = CATPT_STRM_##msg_type, \
319	.global_msg_type = CATPT_GLB_STREAM_MESSAGE }
320#define CATPT_STAGE_MSG(msg_type) \
321{ \
322	.stage_action = CATPT_STG_##msg_type, \
323	.stream_msg_type = CATPT_STRM_STAGE_MESSAGE, \
324	.global_msg_type = CATPT_GLB_STREAM_MESSAGE }
325
326int catpt_ipc_reset_stream(struct catpt_dev *cdev, u8 stream_hw_id);
327int catpt_ipc_pause_stream(struct catpt_dev *cdev, u8 stream_hw_id);
328int catpt_ipc_resume_stream(struct catpt_dev *cdev, u8 stream_hw_id);
329
330/* STREAM messages - STAGE subtype */
331
332enum catpt_audio_curve_type {
333	CATPT_AUDIO_CURVE_NONE = 0,
334	CATPT_AUDIO_CURVE_WINDOWS_FADE = 1,
335};
336
337int catpt_ipc_set_volume(struct catpt_dev *cdev, u8 stream_hw_id,
338			 u32 channel, u32 volume,
339			 u32 curve_duration,
340			 enum catpt_audio_curve_type curve_type);
341
342int catpt_ipc_set_write_pos(struct catpt_dev *cdev, u8 stream_hw_id,
343			    u32 pos, bool eob, bool ll);
344
345int catpt_ipc_mute_loopback(struct catpt_dev *cdev, u8 stream_hw_id, bool mute);
346
347/* NOTIFICATION messages */
348
349enum catpt_notify_reason {
350	CATPT_NOTIFY_POSITION_CHANGED = 0,
351	CATPT_NOTIFY_GLITCH_OCCURRED = 1,
352};
353
354union catpt_notify_msg {
355	u32 val;
356	struct {
357		u32 mailbox_address:29;
358		u32 fw_ready:1;
359		u32 done:1;
360		u32 busy:1;
361	};
362	struct {
363		u32 status:5;
364		u32 reserved:7;
365		u32 notify_reason:4;
366		u32 stream_hw_id:4;
367		u32 stream_msg_type:4;
368		u32 global_msg_type:5;
369		u32 hdr:3; /* fw_ready, done, busy */
370	};
371} __packed;
372
373#define FW_INFO_SIZE_MAX	100
374
375struct catpt_fw_ready {
376	u32 inbox_offset;
377	u32 outbox_offset;
378	u32 inbox_size;
379	u32 outbox_size;
380	u32 fw_info_size;
381	char fw_info[FW_INFO_SIZE_MAX];
382} __packed;
383
384struct catpt_notify_position {
385	u32 stream_position;
386	u32 fw_cycle_count;
387} __packed;
388
389enum catpt_glitch_type {
390	CATPT_GLITCH_UNDERRUN = 1,
391	CATPT_GLITCH_DECODER_ERROR = 2,
392	CATPT_GLITCH_DOUBLED_WRITE_POS = 3,
393};
394
395struct catpt_notify_glitch {
396	u32 type;
397	u64 presentation_pos;
398	u32 write_pos;
399} __packed;
400
401#endif
402