1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3  * Driver for Digigram miXart soundcards
4  *
5  * low level interface with interrupt handling and mail box implementation
6  *
7  * Copyright (c) 2003 by Digigram <alsa@digigram.com>
8  */
9 
10 #ifndef __SOUND_MIXART_CORE_H
11 #define __SOUND_MIXART_CORE_H
12 
13 
14 enum mixart_message_id {
15 	MSG_CONNECTOR_GET_AUDIO_INFO         = 0x050008,
16 	MSG_CONNECTOR_GET_OUT_AUDIO_LEVEL    = 0x050009,
17 	MSG_CONNECTOR_SET_OUT_AUDIO_LEVEL    = 0x05000A,
18 
19 	MSG_CONSOLE_MANAGER                  = 0x070000,
20 	MSG_CONSOLE_GET_CLOCK_UID            = 0x070003,
21 
22 	MSG_PHYSICALIO_SET_LEVEL             = 0x0F0008,
23 
24 	MSG_STREAM_ADD_INPUT_GROUP           = 0x130000,
25 	MSG_STREAM_ADD_OUTPUT_GROUP          = 0x130001,
26 	MSG_STREAM_DELETE_GROUP              = 0x130004,
27 	MSG_STREAM_START_STREAM_GRP_PACKET   = 0x130006,
28 	MSG_STREAM_START_INPUT_STAGE_PACKET  = 0x130007,
29 	MSG_STREAM_START_OUTPUT_STAGE_PACKET = 0x130008,
30 	MSG_STREAM_STOP_STREAM_GRP_PACKET    = 0x130009,
31 	MSG_STREAM_STOP_INPUT_STAGE_PACKET   = 0x13000A,
32 	MSG_STREAM_STOP_OUTPUT_STAGE_PACKET  = 0x13000B,
33 	MSG_STREAM_SET_INPUT_STAGE_PARAM     = 0x13000F,
34 	MSG_STREAM_SET_OUTPUT_STAGE_PARAM    = 0x130010,
35 	MSG_STREAM_SET_IN_AUDIO_LEVEL        = 0x130015,
36 	MSG_STREAM_SET_OUT_STREAM_LEVEL      = 0x130017,
37 
38 	MSG_SYSTEM_FIRST_ID                  = 0x160000,
39 	MSG_SYSTEM_ENUM_PHYSICAL_IO          = 0x16000E,
40 	MSG_SYSTEM_ENUM_PLAY_CONNECTOR       = 0x160017,
41 	MSG_SYSTEM_ENUM_RECORD_CONNECTOR     = 0x160018,
42 	MSG_SYSTEM_WAIT_SYNCHRO_CMD          = 0x16002C,
43 	MSG_SYSTEM_SEND_SYNCHRO_CMD          = 0x16002D,
44 
45 	MSG_SERVICES_TIMER_NOTIFY            = 0x1D0404,
46 	MSG_SERVICES_REPORT_TRACES           = 0x1D0700,
47 
48 	MSG_CLOCK_CHECK_PROPERTIES           = 0x200001,
49 	MSG_CLOCK_SET_PROPERTIES             = 0x200002,
50 };
51 
52 #define MSG_DEFAULT_SIZE            512
53 
54 struct mixart_msg
55 {
56 	u32          message_id;
57 	struct mixart_uid uid;
58 	void*        data;
59 	size_t       size;
60 };
61 
62 /* structs used to communicate with miXart */
63 
64 struct mixart_enum_connector_resp
65 {
66 	u32  error_code;
67 	u32  first_uid_offset;
68 	u32  uid_count;
69 	u32  current_uid_index;
70 	struct mixart_uid uid[MIXART_MAX_PHYS_CONNECTORS];
71 } __attribute__((packed));
72 
73 
74 /* used for following struct */
75 #define MIXART_FLOAT_P_22_0_TO_HEX      0x41b00000  /* 22.0f */
76 #define MIXART_FLOAT_M_20_0_TO_HEX      0xc1a00000  /* -20.0f */
77 #define MIXART_FLOAT____0_0_TO_HEX      0x00000000  /* 0.0f */
78 
79 struct mixart_audio_info_req
80 {
81 	u32 line_max_level;    /* float */
82 	u32 micro_max_level;   /* float */
83 	u32 cd_max_level;      /* float */
84 } __attribute__((packed));
85 
86 struct mixart_analog_hw_info
87 {
88 	u32 is_present;
89 	u32 hw_connection_type;
90 	u32 max_level;         /* float */
91 	u32 min_var_level;     /* float */
92 	u32 max_var_level;     /* float */
93 	u32 step_var_level;    /* float */
94 	u32 fix_gain;          /* float */
95 	u32 zero_var;          /* float */
96 } __attribute__((packed));
97 
98 struct mixart_digital_hw_info
99 {
100 	u32   hw_connection_type;
101 	u32   presence;
102 	u32   clock;
103 	u32   reserved;
104 } __attribute__((packed));
105 
106 struct mixart_analog_info
107 {
108 	u32                     type_mask;
109 	struct mixart_analog_hw_info micro_info;
110 	struct mixart_analog_hw_info line_info;
111 	struct mixart_analog_hw_info cd_info;
112 	u32                     analog_level_present;
113 } __attribute__((packed));
114 
115 struct mixart_digital_info
116 {
117 	u32 type_mask;
118 	struct mixart_digital_hw_info aes_info;
119 	struct mixart_digital_hw_info adat_info;
120 } __attribute__((packed));
121 
122 struct mixart_audio_info
123 {
124 	u32                   clock_type_mask;
125 	struct mixart_analog_info  analog_info;
126 	struct mixart_digital_info digital_info;
127 } __attribute__((packed));
128 
129 struct mixart_audio_info_resp
130 {
131 	u32                 txx_status;
132 	struct mixart_audio_info info;
133 } __attribute__((packed));
134 
135 
136 /* used for nb_bytes_max_per_sample */
137 #define MIXART_FLOAT_P__4_0_TO_HEX      0x40800000  /* +4.0f */
138 #define MIXART_FLOAT_P__8_0_TO_HEX      0x41000000  /* +8.0f */
139 
140 struct mixart_stream_info
141 {
142 	u32 size_max_byte_frame;
143 	u32 size_max_sample_frame;
144 	u32 nb_bytes_max_per_sample;  /* float */
145 } __attribute__((packed));
146 
147 /*  MSG_STREAM_ADD_INPUT_GROUP */
148 /*  MSG_STREAM_ADD_OUTPUT_GROUP */
149 
150 struct mixart_streaming_group_req
151 {
152 	u32 stream_count;
153 	u32 channel_count;
154 	u32 user_grp_number;
155 	u32 first_phys_audio;
156 	u32 latency;
157 	struct mixart_stream_info stream_info[32];
158 	struct mixart_uid connector;
159 	u32 flow_entry[32];
160 } __attribute__((packed));
161 
162 struct mixart_stream_desc
163 {
164 	struct mixart_uid stream_uid;
165 	u32          stream_desc;
166 } __attribute__((packed));
167 
168 struct mixart_streaming_group
169 {
170 	u32                  status;
171 	struct mixart_uid    group;
172 	u32                  pipe_desc;
173 	u32                  stream_count;
174 	struct mixart_stream_desc stream[32];
175 } __attribute__((packed));
176 
177 /* MSG_STREAM_DELETE_GROUP */
178 
179 /* request : mixart_uid_t group */
180 
181 struct mixart_delete_group_resp
182 {
183 	u32  status;
184 	u32  unused[2];
185 } __attribute__((packed));
186 
187 
188 /* 	MSG_STREAM_START_INPUT_STAGE_PACKET  = 0x130000 + 7,
189 	MSG_STREAM_START_OUTPUT_STAGE_PACKET = 0x130000 + 8,
190 	MSG_STREAM_STOP_INPUT_STAGE_PACKET   = 0x130000 + 10,
191 	MSG_STREAM_STOP_OUTPUT_STAGE_PACKET  = 0x130000 + 11,
192  */
193 
194 struct mixart_fx_couple_uid
195 {
196 	struct mixart_uid uid_fx_code;
197 	struct mixart_uid uid_fx_data;
198 } __attribute__((packed));
199 
200 struct mixart_txx_stream_desc
201 {
202 	struct mixart_uid       uid_pipe;
203 	u32                     stream_idx;
204 	u32                     fx_number;
205 	struct mixart_fx_couple_uid  uid_fx[4];
206 } __attribute__((packed));
207 
208 struct mixart_flow_info
209 {
210 	struct mixart_txx_stream_desc  stream_desc;
211 	u32                       flow_entry;
212 	u32                       flow_phy_addr;
213 } __attribute__((packed));
214 
215 struct mixart_stream_state_req
216 {
217 	u32                 delayed;
218 	u64                 scheduler;
219 	u32                 reserved4np[3];
220 	u32                 stream_count;  /* set to 1 for instance */
221 	struct mixart_flow_info  stream_info;   /* could be an array[stream_count] */
222 } __attribute__((packed));
223 
224 /* 	MSG_STREAM_START_STREAM_GRP_PACKET   = 0x130000 + 6
225 	MSG_STREAM_STOP_STREAM_GRP_PACKET    = 0x130000 + 9
226  */
227 
228 struct mixart_group_state_req
229 {
230 	u32           delayed;
231 	u64           scheduler;
232 	u32           reserved4np[2];
233 	u32           pipe_count;    /* set to 1 for instance */
234 	struct mixart_uid  pipe_uid; /* could be an array[pipe_count], in theory */
235 } __attribute__((packed));
236 
237 struct mixart_group_state_resp
238 {
239 	u32           txx_status;
240 	u64           scheduler;
241 } __attribute__((packed));
242 
243 
244 
245 /* Structures used by the MSG_SERVICES_TIMER_NOTIFY command */
246 
247 struct mixart_sample_pos
248 {
249 	u32   buffer_id;
250 	u32   validity;
251 	u32   sample_pos_high_part;
252 	u32   sample_pos_low_part;
253 } __attribute__((packed));
254 
255 /*
256  * This structure is limited by the size of MSG_DEFAULT_SIZE. Instead of
257  * having MIXART_MAX_STREAM_PER_CARD * MIXART_MAX_CARDS many streams,
258  * this is capped to have a total size below MSG_DEFAULT_SIZE.
259  */
260 #define MIXART_MAX_TIMER_NOTIFY_STREAMS				\
261 	((MSG_DEFAULT_SIZE - sizeof(u32)) / sizeof(struct mixart_sample_pos))
262 struct mixart_timer_notify
263 {
264 	u32                  stream_count;
265 	struct mixart_sample_pos  streams[MIXART_MAX_TIMER_NOTIFY_STREAMS];
266 } __attribute__((packed));
267 
268 
269 /*	MSG_CONSOLE_GET_CLOCK_UID            = 0x070003,
270  */
271 
272 /* request is a uid with desc = MSG_CONSOLE_MANAGER | cardindex */
273 
274 struct mixart_return_uid
275 {
276 	u32 error_code;
277 	struct mixart_uid uid;
278 } __attribute__((packed));
279 
280 /*	MSG_CLOCK_CHECK_PROPERTIES           = 0x200001,
281 	MSG_CLOCK_SET_PROPERTIES             = 0x200002,
282 */
283 
284 enum mixart_clock_generic_type {
285 	CGT_NO_CLOCK,
286 	CGT_INTERNAL_CLOCK,
287 	CGT_PROGRAMMABLE_CLOCK,
288 	CGT_INTERNAL_ENSLAVED_CLOCK,
289 	CGT_EXTERNAL_CLOCK,
290 	CGT_CURRENT_CLOCK
291 };
292 
293 enum mixart_clock_mode {
294 	CM_UNDEFINED,
295 	CM_MASTER,
296 	CM_SLAVE,
297 	CM_STANDALONE,
298 	CM_NOT_CONCERNED
299 };
300 
301 
302 struct mixart_clock_properties
303 {
304 	u32 error_code;
305 	u32 validation_mask;
306 	u32 frequency;
307 	u32 reference_frequency;
308 	u32 clock_generic_type;
309 	u32 clock_mode;
310 	struct mixart_uid uid_clock_source;
311 	struct mixart_uid uid_event_source;
312 	u32 event_mode;
313 	u32 synchro_signal_presence;
314 	u32 format;
315 	u32 board_mask;
316 	u32 nb_callers; /* set to 1 (see below) */
317 	struct mixart_uid uid_caller;
318 } __attribute__((packed));
319 
320 struct mixart_clock_properties_resp
321 {
322 	u32 status;
323 	u32 clock_mode;
324 } __attribute__((packed));
325 
326 
327 /*	MSG_STREAM_SET_INPUT_STAGE_PARAM     = 0x13000F */
328 /*	MSG_STREAM_SET_OUTPUT_STAGE_PARAM    = 0x130010 */
329 
330 enum mixart_coding_type {
331 	CT_NOT_DEFINED,
332 	CT_LINEAR,
333 	CT_MPEG_L1,
334 	CT_MPEG_L2,
335 	CT_MPEG_L3,
336 	CT_MPEG_L3_LSF,
337 	CT_GSM
338 };
339 enum mixart_sample_type {
340 	ST_NOT_DEFINED,
341 	ST_FLOATING_POINT_32BE,
342 	ST_FLOATING_POINT_32LE,
343 	ST_FLOATING_POINT_64BE,
344 	ST_FLOATING_POINT_64LE,
345 	ST_FIXED_POINT_8,
346 	ST_FIXED_POINT_16BE,
347 	ST_FIXED_POINT_16LE,
348 	ST_FIXED_POINT_24BE,
349 	ST_FIXED_POINT_24LE,
350 	ST_FIXED_POINT_32BE,
351 	ST_FIXED_POINT_32LE,
352 	ST_INTEGER_8,
353 	ST_INTEGER_16BE,
354 	ST_INTEGER_16LE,
355 	ST_INTEGER_24BE,
356 	ST_INTEGER_24LE,
357 	ST_INTEGER_32BE,
358 	ST_INTEGER_32LE
359 };
360 
361 struct mixart_stream_param_desc
362 {
363 	u32 coding_type;  /* use enum mixart_coding_type */
364 	u32 sample_type;  /* use enum mixart_sample_type */
365 
366 	union {
367 		struct {
368 			u32 linear_endian_ness;
369 			u32 linear_bits;
370 			u32 is_signed;
371 			u32 is_float;
372 		} linear_format_info;
373 
374 		struct {
375 			u32 mpeg_layer;
376 			u32 mpeg_mode;
377 			u32 mpeg_mode_extension;
378 			u32 mpeg_pre_emphasis;
379 			u32 mpeg_has_padding_bit;
380 			u32 mpeg_has_crc;
381 			u32 mpeg_has_extension;
382 			u32 mpeg_is_original;
383 			u32 mpeg_has_copyright;
384 		} mpeg_format_info;
385 	} format_info;
386 
387 	u32 delayed;
388 	u64 scheduler;
389 	u32 sample_size;
390 	u32 has_header;
391 	u32 has_suffix;
392 	u32 has_bitrate;
393 	u32 samples_per_frame;
394 	u32 bytes_per_frame;
395 	u32 bytes_per_sample;
396 	u32 sampling_freq;
397 	u32 number_of_channel;
398 	u32 stream_number;
399 	u32 buffer_size;
400 	u32 differed_time;
401 	u32 reserved4np[3];
402 	u32 pipe_count;                           /* set to 1 (array size !) */
403 	u32 stream_count;                         /* set to 1 (array size !) */
404 	struct mixart_txx_stream_desc stream_desc; /* only one stream per command, but this could be an array, in theory */
405 } __attribute__((packed));
406 
407 
408 /*	MSG_CONNECTOR_GET_OUT_AUDIO_LEVEL    = 0x050009,
409  */
410 
411 
412 struct mixart_get_out_audio_level
413 {
414 	u32 txx_status;
415 	u32 digital_level;   /* float */
416 	u32 analog_level;    /* float */
417 	u32 monitor_level;   /* float */
418 	u32 mute;
419 	u32 monitor_mute1;
420 	u32 monitor_mute2;
421 } __attribute__((packed));
422 
423 
424 /*	MSG_CONNECTOR_SET_OUT_AUDIO_LEVEL    = 0x05000A,
425  */
426 
427 /* used for valid_mask below */
428 #define MIXART_AUDIO_LEVEL_ANALOG_MASK	0x01
429 #define MIXART_AUDIO_LEVEL_DIGITAL_MASK	0x02
430 #define MIXART_AUDIO_LEVEL_MONITOR_MASK	0x04
431 #define MIXART_AUDIO_LEVEL_MUTE_MASK	0x08
432 #define MIXART_AUDIO_LEVEL_MUTE_M1_MASK	0x10
433 #define MIXART_AUDIO_LEVEL_MUTE_M2_MASK	0x20
434 
435 struct mixart_set_out_audio_level
436 {
437 	u32 delayed;
438 	u64 scheduler;
439 	u32 valid_mask1;
440 	u32 valid_mask2;
441 	u32 digital_level;   /* float */
442 	u32 analog_level;    /* float */
443 	u32 monitor_level;   /* float */
444 	u32 mute;
445 	u32 monitor_mute1;
446 	u32 monitor_mute2;
447 	u32 reserved4np;
448 } __attribute__((packed));
449 
450 
451 /*	MSG_SYSTEM_ENUM_PHYSICAL_IO          = 0x16000E,
452  */
453 
454 #define MIXART_MAX_PHYS_IO  (MIXART_MAX_CARDS * 2 * 2) /* 4 * (analog+digital) * (playback+capture) */
455 
456 struct mixart_uid_enumeration
457 {
458 	u32 error_code;
459 	u32 first_uid_offset;
460 	u32 nb_uid;
461 	u32 current_uid_index;
462 	struct mixart_uid uid[MIXART_MAX_PHYS_IO];
463 } __attribute__((packed));
464 
465 
466 /*	MSG_PHYSICALIO_SET_LEVEL             = 0x0F0008,
467 	MSG_PHYSICALIO_GET_LEVEL             = 0x0F000C,
468 */
469 
470 struct mixart_io_channel_level
471 {
472 	u32 analog_level;   /* float */
473 	u32 unused[2];
474 } __attribute__((packed));
475 
476 struct mixart_io_level
477 {
478 	s32 channel; /* 0=left, 1=right, -1=both, -2=both same */
479 	struct mixart_io_channel_level level[2];
480 } __attribute__((packed));
481 
482 
483 /*	MSG_STREAM_SET_IN_AUDIO_LEVEL        = 0x130015,
484  */
485 
486 struct mixart_in_audio_level_info
487 {
488 	struct mixart_uid connector;
489 	u32 valid_mask1;
490 	u32 valid_mask2;
491 	u32 digital_level;
492 	u32 analog_level;
493 } __attribute__((packed));
494 
495 struct mixart_set_in_audio_level_req
496 {
497 	u32 delayed;
498 	u64 scheduler;
499 	u32 audio_count;  /* set to <= 2 */
500 	u32 reserved4np;
501 	struct mixart_in_audio_level_info level[2];
502 } __attribute__((packed));
503 
504 /* response is a 32 bit status */
505 
506 
507 /*	MSG_STREAM_SET_OUT_STREAM_LEVEL      = 0x130017,
508  */
509 
510 /* defines used for valid_mask1 */
511 #define MIXART_OUT_STREAM_SET_LEVEL_LEFT_AUDIO1		0x01
512 #define MIXART_OUT_STREAM_SET_LEVEL_LEFT_AUDIO2		0x02
513 #define MIXART_OUT_STREAM_SET_LEVEL_RIGHT_AUDIO1	0x04
514 #define MIXART_OUT_STREAM_SET_LEVEL_RIGHT_AUDIO2	0x08
515 #define MIXART_OUT_STREAM_SET_LEVEL_STREAM_1		0x10
516 #define MIXART_OUT_STREAM_SET_LEVEL_STREAM_2		0x20
517 #define MIXART_OUT_STREAM_SET_LEVEL_MUTE_1		0x40
518 #define MIXART_OUT_STREAM_SET_LEVEL_MUTE_2		0x80
519 
520 struct mixart_out_stream_level_info
521 {
522 	u32 valid_mask1;
523 	u32 valid_mask2;
524 	u32 left_to_out1_level;
525 	u32 left_to_out2_level;
526 	u32 right_to_out1_level;
527 	u32 right_to_out2_level;
528 	u32 digital_level1;
529 	u32 digital_level2;
530 	u32 mute1;
531 	u32 mute2;
532 } __attribute__((packed));
533 
534 struct mixart_set_out_stream_level
535 {
536 	struct mixart_txx_stream_desc desc;
537 	struct mixart_out_stream_level_info out_level;
538 } __attribute__((packed));
539 
540 struct mixart_set_out_stream_level_req
541 {
542 	u32 delayed;
543 	u64 scheduler;
544 	u32 reserved4np[2];
545 	u32 nb_of_stream;  /* set to 1 */
546 	struct mixart_set_out_stream_level stream_level; /* could be an array */
547 } __attribute__((packed));
548 
549 /* response to this request is a u32 status value */
550 
551 
552 /* exported */
553 void snd_mixart_init_mailbox(struct mixart_mgr *mgr);
554 void snd_mixart_exit_mailbox(struct mixart_mgr *mgr);
555 
556 int  snd_mixart_send_msg(struct mixart_mgr *mgr, struct mixart_msg *request, int max_resp_size, void *resp_data);
557 int  snd_mixart_send_msg_wait_notif(struct mixart_mgr *mgr, struct mixart_msg *request, u32 notif_event);
558 int  snd_mixart_send_msg_nonblock(struct mixart_mgr *mgr, struct mixart_msg *request);
559 
560 irqreturn_t snd_mixart_interrupt(int irq, void *dev_id);
561 irqreturn_t snd_mixart_threaded_irq(int irq, void *dev_id);
562 
563 void snd_mixart_reset_board(struct mixart_mgr *mgr);
564 
565 #endif /* __SOUND_MIXART_CORE_H */
566