xref: /haiku/src/add-ons/kernel/drivers/audio/ice1712/multi.cpp (revision 71452e98334eaac603bf542d159e24788a46bebb)
1 /*
2  * Copyright 2004-2015 Haiku, Inc. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Jérôme Duval, jerome.duval@free.fr
7  *		Marcus Overhagen, marcus@overhagen.de
8  *		Jérôme Lévêque, leveque.jerome@gmail.com
9  */
10 
11 
12 #include "ice1712_reg.h"
13 #include "io.h"
14 #include "multi.h"
15 #include "util.h"
16 
17 #include <string.h>
18 #include "debug.h"
19 
20 status_t ice1712Settings_apply(ice1712 *card);
21 
22 static void ice1712Buffer_Start(ice1712 *card);
23 static uint32 ice1712UI_GetCombo(ice1712 *card, uint32 index);
24 static void ice1712UI_SetCombo(ice1712 *card, uint32 index, uint32 value);
25 static uint32 ice1712UI_GetOutput(ice1712 *card, uint32 index);
26 static void ice1712UI_SetOutput(ice1712 *card, uint32 index, uint32 value);
27 static void ice1712UI_GetVolume(ice1712 *card, multi_mix_value *mmv);
28 static void ice1712UI_SetVolume(ice1712 *card, multi_mix_value *mmv);
29 static void ice1712UI_CreateOutput(ice1712 *card, multi_mix_control **p_mmc,
30 	int32 output, int32 parent);
31 static void ice1712UI_CreateCombo(multi_mix_control **p_mmc,
32 	const char *values[], int32 parent, int32 nb_combo, const char *name);
33 static void ice1712UI_CreateChannel(multi_mix_control **p_mmc,
34 	int32 channel, int32 parent, const char* name);
35 static int32 ice1712UI_CreateGroup(multi_mix_control **p_mmc,
36 	int32 index, int32 parent, enum strind_id string, const char* name);
37 static int32 nb_control_created;
38 
39 #define AUTHORIZED_RATE (B_SR_SAME_AS_INPUT | B_SR_96000 \
40 	| B_SR_88200 | B_SR_48000 | B_SR_44100)
41 #define AUTHORIZED_SAMPLE_SIZE (B_FMT_24BIT)
42 
43 #define MAX_CONTROL	32
44 
45 //ICE1712 Multi - Buffer
46 //----------------------
47 
48 void
49 ice1712Buffer_Start(ice1712 *card)
50 {
51 	uint16 size = card->buffer_size * MAX_DAC;
52 
53 	write_mt_uint8(card, MT_PROF_PB_CONTROL, 0);
54 
55 	write_mt_uint32(card, MT_PROF_PB_DMA_BASE_ADDRESS,
56 		(uint32)(card->phys_pb.address));
57 	write_mt_uint16(card, MT_PROF_PB_DMA_COUNT_ADDRESS,
58 		(size * SWAPPING_BUFFERS) - 1);
59 	//We want interrupt only from playback
60 	write_mt_uint16(card, MT_PROF_PB_DMA_TERM_COUNT, size - 1);
61 	ITRACE("SIZE DMA PLAYBACK %#x\n", size);
62 
63 	size = card->buffer_size * MAX_ADC;
64 
65 	write_mt_uint32(card, MT_PROF_REC_DMA_BASE_ADDRESS,
66 		(uint32)(card->phys_rec.address));
67 	write_mt_uint16(card, MT_PROF_REC_DMA_COUNT_ADDRESS,
68 		(size * SWAPPING_BUFFERS) - 1);
69 	//We do not want any interrupt from the record
70 	write_mt_uint16(card, MT_PROF_REC_DMA_TERM_COUNT, 0);
71 	ITRACE("SIZE DMA RECORD %#x\n", size);
72 
73 	//Enable output AND Input from Analog CODEC
74 	switch (card->config.product) {
75 	//TODO: find correct value for all card
76 		case ICE1712_SUBDEVICE_DELTA66:
77 		case ICE1712_SUBDEVICE_DELTA44:
78 		case ICE1712_SUBDEVICE_AUDIOPHILE_2496:
79 		case ICE1712_SUBDEVICE_DELTADIO2496:
80 		case ICE1712_SUBDEVICE_DELTA410:
81 		case ICE1712_SUBDEVICE_DELTA1010LT:
82 		case ICE1712_SUBDEVICE_DELTA1010:
83 			codec_write(card, AK45xx_CLOCK_FORMAT_REGISTER, 0x69);
84 			codec_write(card, AK45xx_RESET_REGISTER, 0x03);
85 			break;
86 		case ICE1712_SUBDEVICE_VX442:
87 //			ak45xx_write_gpio(ice, reg_addr, data, VX442_CODEC_CS_0);
88 //			ak45xx_write_gpio(ice, reg_addr, data, VX442_CODEC_CS_1);
89 			break;
90 	}
91 
92 	//Set Data Format for SPDif codec
93 	switch (card->config.product) {
94 	//TODO: find correct value for all card
95 		case ICE1712_SUBDEVICE_DELTA1010:
96 			break;
97 		case ICE1712_SUBDEVICE_DELTADIO2496:
98 			break;
99 		case ICE1712_SUBDEVICE_DELTA66:
100 		case ICE1712_SUBDEVICE_DELTA44:
101 //			ak45xx_write_gpio(ice, reg_addr, data, DELTA66_CODEC_CS_0);
102 //			ak45xx_write_gpio(ice, reg_addr, data, DELTA66_CODEC_CS_1);
103 			break;
104 		case ICE1712_SUBDEVICE_AUDIOPHILE_2496:
105 			spdif_write(card, CS84xx_SERIAL_INPUT_FORMAT_REG, 0x85);
106 			spdif_write(card, CS84xx_SERIAL_OUTPUT_FORMAT_REG, 0x85);
107 //			spdif_write(card, CS84xx_SERIAL_OUTPUT_FORMAT_REG, 0x41);
108 			break;
109 		case ICE1712_SUBDEVICE_DELTA410:
110 			break;
111 		case ICE1712_SUBDEVICE_DELTA1010LT:
112 //			ak45xx_write_gpio(ice, reg_addr, data,
113 //				DELTA1010LT_CODEC_CS_0);
114 //			ak45xx_write_gpio(ice, reg_addr, data,
115 //				DELTA1010LT_CODEC_CS_1);
116 //			ak45xx_write_gpio(ice, reg_addr, data,
117 //				DELTA1010LT_CODEC_CS_2);
118 //			ak45xx_write_gpio(ice, reg_addr, data,
119 //				DELTA1010LT_CODEC_CS_3);
120 			break;
121 		case ICE1712_SUBDEVICE_VX442:
122 //			ak45xx_write_gpio(ice, reg_addr, data, VX442_CODEC_CS_0);
123 //			ak45xx_write_gpio(ice, reg_addr, data, VX442_CODEC_CS_1);
124 			break;
125 	}
126 
127 	card->buffer = 1;
128 	write_mt_uint8(card, MT_PROF_PB_CONTROL, 5);
129 }
130 
131 
132 status_t
133 ice1712Buffer_Exchange(ice1712 *card, multi_buffer_info *data)
134 {
135 	multi_buffer_info buffer_info;
136 
137 #ifdef __HAIKU__
138 	if (user_memcpy(&buffer_info, data, sizeof(buffer_info)) < B_OK)
139 		return B_BAD_ADDRESS;
140 #else
141 	memcpy(&buffer_info, data, sizeof(buffer_info));
142 #endif
143 
144 	buffer_info.flags = B_MULTI_BUFFER_PLAYBACK | B_MULTI_BUFFER_RECORD;
145 
146 	if (acquire_sem_etc(card->buffer_ready_sem, 1, B_RELATIVE_TIMEOUT
147 		| B_CAN_INTERRUPT, 50000) == B_TIMED_OUT) {
148 		ITRACE("buffer_exchange timeout\n");
149 	};
150 
151 	// Playback buffers info
152 	buffer_info.played_real_time = card->played_time;
153 	buffer_info.played_frames_count = card->frames_count;
154 	buffer_info.playback_buffer_cycle = (card->buffer - 1)
155 		% SWAPPING_BUFFERS; //Buffer played
156 
157 	// Record buffers info
158 	buffer_info.recorded_real_time = card->played_time;
159 	buffer_info.recorded_frames_count = card->frames_count;
160 	buffer_info.record_buffer_cycle = (card->buffer - 1)
161 		% SWAPPING_BUFFERS; //Buffer filled
162 
163 #ifdef __HAIKU__
164 	if (user_memcpy(data, &buffer_info, sizeof(buffer_info)) < B_OK)
165 		return B_BAD_ADDRESS;
166 #else
167 	memcpy(data, &buffer_info, sizeof(buffer_info));
168 #endif
169 
170 	return B_OK;
171 }
172 
173 
174 status_t
175 ice1712Buffer_Stop(ice1712 *card)
176 {
177 	write_mt_uint8(card, MT_PROF_PB_CONTROL, 0);
178 
179 	card->played_time = 0;
180 	card->frames_count = 0;
181 	card->buffer = 0;
182 
183 	return B_OK;
184 }
185 
186 //ICE1712 Multi - Description
187 //---------------------------
188 
189 status_t
190 ice1712Get_Description(ice1712 *card, multi_description *data)
191 {
192 	int chan = 0, i, size;
193 
194 	data->interface_version = B_CURRENT_INTERFACE_VERSION;
195 	data->interface_minimum = B_CURRENT_INTERFACE_VERSION;
196 
197 	switch (card->config.product) {
198 		case ICE1712_SUBDEVICE_DELTA1010:
199 			strncpy(data->friendly_name, "Delta 1010", 32);
200 			break;
201 		case ICE1712_SUBDEVICE_DELTADIO2496:
202 			strncpy(data->friendly_name, "Delta DIO 2496", 32);
203 			break;
204 		case ICE1712_SUBDEVICE_DELTA66:
205 			strncpy(data->friendly_name, "Delta 66", 32);
206 			break;
207 		case ICE1712_SUBDEVICE_DELTA44:
208 			strncpy(data->friendly_name, "Delta 44", 32);
209 			break;
210 		case ICE1712_SUBDEVICE_AUDIOPHILE_2496:
211 			strncpy(data->friendly_name, "Audiophile 2496", 32);
212 			break;
213 		case ICE1712_SUBDEVICE_DELTA410:
214 			strncpy(data->friendly_name, "Delta 410", 32);
215 			break;
216 		case ICE1712_SUBDEVICE_DELTA1010LT:
217 			strncpy(data->friendly_name, "Delta 1010 LT", 32);
218 			break;
219 		case ICE1712_SUBDEVICE_VX442:
220 			strncpy(data->friendly_name, "VX 442", 32);
221 			break;
222 
223 		default:
224 			strncpy(data->friendly_name, "Unknow device", 32);
225 			break;
226 	}
227 
228 	strncpy(data->vendor_info, "Haiku", 32);
229 
230 	data->output_channel_count = card->total_output_channels;
231 	data->input_channel_count = card->total_input_channels;
232 	data->output_bus_channel_count = 0;
233 	data->input_bus_channel_count = 0;
234 	data->aux_bus_channel_count = 0;
235 
236 	size =	data->output_channel_count + data->input_channel_count
237 		+ data->output_bus_channel_count + data->input_bus_channel_count
238 		+ data->aux_bus_channel_count;
239 
240 	ITRACE_VV("request_channel_count = %" B_PRIi32 "\n",
241 		data->request_channel_count);
242 
243 	if (size <= data->request_channel_count) {
244 		for (i = 0; i < card->config.nb_DAC; i++) {
245 		//Analog STEREO output
246 			data->channels[chan].channel_id = chan;
247 			data->channels[chan].kind = B_MULTI_OUTPUT_CHANNEL;
248 			data->channels[chan].designations = B_CHANNEL_STEREO_BUS
249 				| (((i & 1) == 0) ? B_CHANNEL_LEFT : B_CHANNEL_RIGHT);
250 			data->channels[chan].connectors = 0;
251 			chan++;
252 		}
253 
254 		if (card->config.spdif & SPDIF_OUT_PRESENT) {
255 		//SPDIF STEREO output
256 			data->channels[chan].channel_id = chan;
257 			data->channels[chan].kind = B_MULTI_OUTPUT_CHANNEL;
258 			data->channels[chan].designations = B_CHANNEL_STEREO_BUS
259 				| B_CHANNEL_LEFT;
260 			data->channels[chan].connectors = 0;
261 			chan++;
262 			data->channels[chan].channel_id = chan;
263 			data->channels[chan].kind = B_MULTI_OUTPUT_CHANNEL;
264 			data->channels[chan].designations = B_CHANNEL_STEREO_BUS
265 				| B_CHANNEL_RIGHT;
266 			data->channels[chan].connectors = 0;
267 			chan++;
268 		}
269 
270 		for (i = 0; i < card->config.nb_ADC; i++) {
271 		//Analog STEREO input
272 			data->channels[chan].channel_id = chan;
273 			data->channels[chan].kind = B_MULTI_INPUT_CHANNEL;
274 			data->channels[chan].designations = B_CHANNEL_STEREO_BUS
275 				| (((i & 1) == 0) ? B_CHANNEL_LEFT : B_CHANNEL_RIGHT);
276 			data->channels[chan].connectors = 0;
277 			chan++;
278 		}
279 
280 		if (card->config.spdif & SPDIF_IN_PRESENT) {
281 		//SPDIF STEREO input
282 			data->channels[chan].channel_id = chan;
283 			data->channels[chan].kind = B_MULTI_INPUT_CHANNEL;
284 			data->channels[chan].designations = B_CHANNEL_STEREO_BUS
285 				| B_CHANNEL_LEFT;
286 			data->channels[chan].connectors = 0;
287 			chan++;
288 			data->channels[chan].channel_id = chan;
289 			data->channels[chan].kind = B_MULTI_INPUT_CHANNEL;
290 			data->channels[chan].designations = B_CHANNEL_STEREO_BUS
291 				| B_CHANNEL_RIGHT;
292 			data->channels[chan].connectors = 0;
293 			chan++;
294 		}
295 
296 		//The digital mixer output (it's an Input for Haiku)
297 		data->channels[chan].channel_id = chan;
298 		data->channels[chan].kind = B_MULTI_INPUT_CHANNEL;
299 		data->channels[chan].designations = B_CHANNEL_STEREO_BUS
300 			| B_CHANNEL_LEFT;
301 		data->channels[chan].connectors = 0;
302 		chan++;
303 		data->channels[chan].channel_id = chan;
304 		data->channels[chan].kind = B_MULTI_INPUT_CHANNEL;
305 		data->channels[chan].designations = B_CHANNEL_STEREO_BUS
306 			| B_CHANNEL_RIGHT;
307 		data->channels[chan].connectors = 0;
308 		chan++;
309 	}
310 
311 	ITRACE("output_channel_count = %" B_PRIi32 "\n",
312 		data->output_channel_count);
313 	ITRACE("input_channel_count = %" B_PRIi32 "\n",
314 		data->input_channel_count);
315 	ITRACE("output_bus_channel_count = %" B_PRIi32 "\n",
316 		data->output_bus_channel_count);
317 	ITRACE("input_bus_channel_count = %" B_PRIi32 "\n",
318 		data->input_bus_channel_count);
319 
320 	data->output_rates = data->input_rates = AUTHORIZED_RATE;
321 	data->min_cvsr_rate = 44100;
322 	data->max_cvsr_rate = 96000;
323 
324 	data->output_formats = data->input_formats = AUTHORIZED_SAMPLE_SIZE;
325 	data->lock_sources = B_MULTI_LOCK_INTERNAL | B_MULTI_LOCK_SPDIF;
326 	data->timecode_sources = 0;
327 	data->interface_flags = B_MULTI_INTERFACE_PLAYBACK
328 		| B_MULTI_INTERFACE_RECORD;
329 	data->start_latency = 0;
330 
331 	strcpy(data->control_panel,"");
332 
333 	return B_OK;
334 }
335 
336 
337 status_t
338 ice1712Get_Channel(ice1712 *card, multi_channel_enable *data)
339 {
340 	int i, total_channel;
341 	uint8 reg;
342 
343 	total_channel = card->total_output_channels + card->total_input_channels;
344 	for (i = 0; i < total_channel; i++)
345 		B_SET_CHANNEL(data->enable_bits, i, true);
346 
347 	reg = read_mt_uint8(card, MT_SAMPLING_RATE_SELECT);
348 
349 	if (reg == 0x10)
350 		data->lock_source = B_MULTI_LOCK_SPDIF;
351 	else
352 		data->lock_source = B_MULTI_LOCK_INTERNAL;
353 
354 	return B_OK;
355 }
356 
357 
358 status_t
359 ice1712Set_Channel(ice1712 *card, multi_channel_enable *data)
360 {
361 	int i;
362 	int total_channel;
363 
364 	total_channel = card->total_output_channels + card->total_input_channels;
365 	for (i = 0; i < total_channel; i++)
366 		ITRACE_VV("set_enabled_channels %d : %s\n", i,
367 			B_TEST_CHANNEL(data->enable_bits, i) ? "enabled": "disabled");
368 
369 	ITRACE_VV("lock_source %" B_PRIx32 "\n", data->lock_source);
370 	ITRACE_VV("lock_data %" B_PRIx32 "\n", data->lock_data);
371 
372 	if (data->lock_source == B_MULTI_LOCK_SPDIF)
373 		write_mt_uint8(card, MT_SAMPLING_RATE_SELECT, 0x10);
374 	else
375 		write_mt_uint8(card, MT_SAMPLING_RATE_SELECT,
376 			card->config.samplingRate);
377 
378 	card->config.lockSource = data->lock_source;
379 
380 	return B_OK;
381 }
382 
383 
384 status_t
385 ice1712Get_Format(ice1712 *card, multi_format_info *data)
386 {
387 	uint8 sr = read_mt_uint8(card, MT_SAMPLING_RATE_SELECT);
388 
389 	switch (sr) {
390 		case ICE1712_SAMPLERATE_48K:
391 			data->input.rate = data->output.rate = B_SR_48000;
392 			data->input.cvsr = data->output.cvsr = 48000.0f;
393 			break;
394 		case ICE1712_SAMPLERATE_96K:
395 			data->input.rate = data->output.rate = B_SR_96000;
396 			data->input.cvsr = data->output.cvsr = 96000.0f;
397 			break;
398 		case ICE1712_SAMPLERATE_44K1:
399 			data->input.rate = data->output.rate = B_SR_44100;
400 			data->input.cvsr = data->output.cvsr = 44100.0f;
401 			break;
402 		case ICE1712_SAMPLERATE_88K2:
403 			data->input.rate = data->output.rate = B_SR_88200;
404 			data->input.cvsr = data->output.cvsr = 88200.0f;
405 			break;
406 	}
407 
408 	data->timecode_kind = 0;
409 	data->output_latency = data->input_latency = 0;
410 	data->output.format = data->input.format = AUTHORIZED_SAMPLE_SIZE;
411 
412 	ITRACE("Sampling Rate = %f\n", data->input.cvsr);
413 
414 	return B_OK;
415 }
416 
417 
418 status_t
419 ice1712Set_Format(ice1712 *card, multi_format_info *data)
420 {
421 	ITRACE("Input Sampling Rate = %" B_PRIu32 "\n",
422 		data->input.rate);
423 	ITRACE("Output Sampling Rate = %" B_PRIu32 "\n",
424 		data->output.rate);
425 
426 	//We can't have a different rate for input and output
427 	//so just wait to change our sample rate when
428 	//media server will do what we need
429 	//Lie to it and say we are living in wonderland
430 	if (data->input.rate != data->output.rate)
431 		return B_OK;
432 
433 	if (card->config.lockSource == B_MULTI_LOCK_INTERNAL) {
434 		switch (data->output.rate) {
435 			case B_SR_96000:
436 				card->config.samplingRate = 0x07;
437 				break;
438 			case B_SR_88200:
439 				card->config.samplingRate = 0x0B;
440 				break;
441 			case B_SR_48000:
442 				card->config.samplingRate = 0x00;
443 				break;
444 			case B_SR_44100:
445 				card->config.samplingRate = 0x08;
446 				break;
447 		}
448 		write_mt_uint8(card, MT_SAMPLING_RATE_SELECT,
449 			card->config.samplingRate);
450 	}
451 	ITRACE("New rate = %#x\n", read_mt_uint8(card, MT_SAMPLING_RATE_SELECT));
452 
453 	return B_OK;
454 }
455 
456 //ICE1712 Multi - UI
457 //------------------
458 
459 static const char *Clock[] = {
460 	"Internal",
461 	"Digital",
462 	NULL,
463 };
464 
465 static const char *DigitalFormat[] = {
466 	"Consumer",
467 	"Professional",
468 	NULL,
469 };
470 
471 static const char *DigitalEmphasis[] = {
472 	"None",
473 	"CCITT",
474 	"15/50usec",
475 	NULL,
476 };
477 
478 static const char *DigitalCopyMode[] = {
479 	"Original",
480 	"1st Generation",
481 	"No SCMS",
482 	NULL,
483 };
484 
485 static const char **SettingsGeneral[] = {
486 	Clock,
487 	NULL,
488 };
489 
490 static const char **SettingsDigital[] = {
491 	DigitalFormat,
492 	DigitalEmphasis,
493 	DigitalCopyMode,
494 	NULL,
495 };
496 
497 static const char *string_list[] = {
498 	"Setup",
499 	"General",
500 	"Digital",
501 	"Output Selection",
502 
503 	"Internal Mixer",
504 
505 	//General settings
506 	"Master clock",
507 	"reserved_0",
508 	"reserved_1",
509 
510 	//Digital settings
511 	"Output format",
512 	"Emphasis",
513 	"Copy mode",
514 
515 	//Output Selection
516 	"Output 1", //11
517 	"Output 2",
518 	"Output 3",
519 	"Output 4",
520 	"Digital Output", //15
521 
522 	"Haiku output", //16
523 
524 	"Input 1", //17
525 	"Input 2",
526 	"Input 3",
527 	"Input 4",
528 	"Digital Input", //21
529 	"Internal mixer", //22
530 };
531 
532 
533 /*
534  * This will create a Tab
535  */
536 int32
537 ice1712UI_CreateGroup(multi_mix_control **p_mmc, int32 index,
538 	int32 parent, enum strind_id string, const char* name)
539 {
540 	multi_mix_control *mmc = *p_mmc;
541 	int32 group;
542 
543 	mmc->id = ICE1712_MULTI_CONTROL_FIRSTID + ICE1712_MULTI_SET_INDEX(index);
544 	mmc->parent = parent;
545 	mmc->flags = B_MULTI_MIX_GROUP;
546 	mmc->master = CONTROL_IS_MASTER;
547 	mmc->string = string;
548 
549 	group = mmc->id;
550 
551 	if (name != NULL)
552 		strcpy(mmc->name, name);
553 
554 	ITRACE_VV("Create Group: ID %#" B_PRIx32 "\n", mmc->id);
555 
556 	nb_control_created++; mmc++;
557 	(*p_mmc) = mmc;
558 
559 	return group;
560 }
561 
562 
563 /*
564  * This will create a Slider with a "Mute" CheckBox
565  */
566 void
567 ice1712UI_CreateChannel(multi_mix_control **p_mmc, int32 channel,
568 	int32 parent, const char* name)
569 {
570 	int32 id = ICE1712_MULTI_CONTROL_FIRSTID
571 		+ ICE1712_MULTI_CONTROL_TYPE_VOLUME
572 		+ ICE1712_MULTI_SET_CHANNEL(channel);
573 	multi_mix_control *mmc = *p_mmc;
574 	multi_mix_control control;
575 
576 	control.master = CONTROL_IS_MASTER;
577 	control.parent = parent;
578 	control.gain.max_gain = 0.0;
579 	control.gain.min_gain = -144.0;
580 	control.gain.granularity = 1.5;
581 
582 	//The Mute Checkbox
583 	control.id = id++;
584 	control.flags = B_MULTI_MIX_ENABLE;
585 	control.string = S_MUTE;
586 	*mmc = control;
587 	mmc++;
588 
589 	ITRACE_VV("Create Channel (Mute): ID %#" B_PRIx32 "\n", control.id);
590 
591 	//The Left Slider
592 	control.string = S_null;
593 	control.id = id++;
594 	control.flags = B_MULTI_MIX_GAIN;
595 	if (name != NULL)
596 		strcpy(control.name, name);
597 	*mmc = control;
598 	mmc++;
599 
600 	ITRACE_VV("Create Channel (Left): ID %#" B_PRIx32 "\n", control.id);
601 
602 	//The Right Slider
603 	control.master = control.id; //The Id of the Left Slider
604 	control.id = id++;
605 	*mmc = control;
606 	mmc++;
607 
608 	ITRACE_VV("Create Channel (Right): ID %#" B_PRIx32 "\n", control.id);
609 
610 	nb_control_created += 3;
611 	(*p_mmc) = mmc;
612 }
613 
614 
615 void
616 ice1712UI_CreateCombo(multi_mix_control **p_mmc, const char *values[],
617 	int32 parent, int32 nb_combo, const char *name)
618 {
619 	int32 id = ICE1712_MULTI_CONTROL_FIRSTID
620 		+ ICE1712_MULTI_CONTROL_TYPE_COMBO
621 		+ ICE1712_MULTI_SET_CHANNEL(nb_combo);
622 	multi_mix_control *mmc = *p_mmc;
623 	int32 parentControl, i;
624 
625 	//The label
626 	parentControl = mmc->id = id++;
627 	mmc->flags = B_MULTI_MIX_MUX;
628 	mmc->parent = parent;
629 	strcpy(mmc->name, name);
630 
631 	ITRACE_VV("Create Combo (label): ID %#" B_PRIx32 "\n", parentControl);
632 
633 	nb_control_created++; mmc++;
634 
635 	//The values
636 	for (i = 0; values[i] != NULL; i++) {
637 		mmc->id = id++;
638 		mmc->flags = B_MULTI_MIX_MUX_VALUE;
639 		mmc->parent = parentControl;
640 		strcpy(mmc->name, values[i]);
641 
642 		ITRACE_VV("Create Combo (value): ID %#" B_PRIx32 "\n", mmc->id);
643 
644 		nb_control_created++; mmc++;
645 	}
646 
647 	(*p_mmc) = mmc;
648 }
649 
650 
651 /*
652  * This will create all possible value for the output
653  * output 0 -> 3 (physical stereo output) 4 is the Digital
654  */
655 void
656 ice1712UI_CreateOutput(ice1712 *card, multi_mix_control **p_mmc,
657 	int32 output, int32 parent)
658 {
659 	int32 id = ICE1712_MULTI_CONTROL_FIRSTID
660 		+ ICE1712_MULTI_CONTROL_TYPE_OUTPUT
661 		+ ICE1712_MULTI_SET_CHANNEL(output);
662 	multi_mix_control *mmc = *p_mmc;
663 	int32 parentControl, i;
664 
665 	//The label
666 	parentControl = mmc->id = id++;
667 	mmc->flags = B_MULTI_MIX_MUX;
668 	mmc->parent = parent;
669 	strcpy(mmc->name, string_list[11 + output]);
670 	nb_control_created++; mmc++;
671 
672 	ITRACE_VV("Create Output (label): ID %#" B_PRIx32 "\n", parentControl);
673 
674 	//Haiku output
675 	mmc->id = id++;
676 	mmc->flags = B_MULTI_MIX_MUX_VALUE;
677 	mmc->parent = parentControl;
678 	strcpy(mmc->name, string_list[16]);
679 
680 	ITRACE_VV("Create Output (Haiku): ID %#" B_PRIx32 "\n", mmc->id);
681 
682 	nb_control_created++; mmc++;
683 
684 	//Physical Input
685 	for (i = 0; i < card->config.nb_DAC; i += 2) {
686 		mmc->id = id++;
687 		mmc->flags = B_MULTI_MIX_MUX_VALUE;
688 		mmc->parent = parentControl;
689 		strcpy(mmc->name, string_list[17 + (i / 2)]);
690 
691 		ITRACE_VV("Create Output (Physical In): ID %#" B_PRIx32 "\n", mmc->id);
692 
693 		nb_control_created++; mmc++;
694 	}
695 
696 	//Physical Digital Input
697 	if (card->config.spdif & SPDIF_IN_PRESENT) {
698 		mmc->id = id++;
699 		mmc->flags = B_MULTI_MIX_MUX_VALUE;
700 		mmc->parent = parentControl;
701 		strcpy(mmc->name, string_list[21]);
702 
703 		ITRACE_VV("Create Output (Digital In) ID %#" B_PRIx32 "\n", mmc->id);
704 
705 		nb_control_created++; mmc++;
706 	}
707 
708 	//Internal mixer only for Output 1 and Digital Output
709 	if ((output == 0) || (output == 4)) {
710 		mmc->id = id++;
711 		mmc->flags = B_MULTI_MIX_MUX_VALUE;
712 		mmc->parent = parentControl;
713 		strcpy(mmc->name, string_list[22]);
714 
715 		ITRACE_VV("Create Output (Mix); ID %#" B_PRIx32 "\n", mmc->id);
716 
717 		nb_control_created++; mmc++;
718 	}
719 
720 	(*p_mmc) = mmc;
721 }
722 
723 
724 uint32
725 ice1712UI_GetCombo(ice1712 *card, uint32 index)
726 {
727 	uint32 value = 0;
728 
729 	switch (index) {
730 		case 0:
731 			value = card->settings.clock;
732 			break;
733 
734 		case 1:
735 			value = card->settings.outFormat;
736 			break;
737 
738 		case 2:
739 			value = card->settings.emphasis;
740 			break;
741 
742 		case 3:
743 			value = card->settings.copyMode;
744 			break;
745 	}
746 
747 	ITRACE_VV("Get combo: %" B_PRIu32 ", %" B_PRIu32 "\n",
748 		index, value);
749 
750 	return value;
751 }
752 
753 
754 void
755 ice1712UI_SetCombo(ice1712 *card, uint32 index, uint32 value)
756 {
757 	ITRACE_VV("Set combo: %" B_PRIu32 ", %" B_PRIu32 "\n", index, value);
758 
759 	switch (index) {
760 		case 0:
761 			if (value < 2)
762 				card->settings.clock = value;
763 			break;
764 
765 		case 1:
766 			if (value < 2)
767 				card->settings.outFormat = value;
768 			break;
769 
770 		case 2:
771 			if (value < 3)
772 				card->settings.emphasis = value;
773 			break;
774 
775 		case 3:
776 			if (value < 3)
777 				card->settings.copyMode = value;
778 			break;
779 	}
780 }
781 
782 
783 uint32
784 ice1712UI_GetOutput(ice1712 *card, uint32 index)
785 {
786 	uint32 value = 0;
787 
788 	if (index < 5)
789 		value = card->settings.output[index];
790 
791 	ITRACE_VV("Get output: %" B_PRIu32 ", %" B_PRIu32 "\n", index, value);
792 
793 	return value;
794 }
795 
796 
797 void
798 ice1712UI_SetOutput(ice1712 *card, uint32 index, uint32 value)
799 {
800 	if (index < 5)
801 		card->settings.output[index] = value;
802 
803 	ITRACE_VV("Set output: %" B_PRIu32 ", %" B_PRIu32 "\n", index, value);
804 }
805 
806 
807 void
808 ice1712UI_GetVolume(ice1712 *card, multi_mix_value *mmv)
809 {
810 	ice1712Volume *vol;
811 	uint32 chan = ICE1712_MULTI_GET_CHANNEL(mmv->id);
812 
813 	ITRACE_VV("Get volume\n");
814 
815 	if (chan < ICE1712_HARDWARE_VOLUME) {
816 		vol = card->settings.playback;
817 	} else {
818 		vol = card->settings.record;
819 		chan -= ICE1712_HARDWARE_VOLUME;
820 	}
821 
822 	//chan is normaly <= ICE1712_HARDWARE_VOLUME
823 	switch (ICE1712_MULTI_GET_INDEX(mmv->id)) {
824 		case 0: //Mute
825 			mmv->enable = vol[chan].mute | vol[chan + 1].mute;
826 			ITRACE_VV("	Get mute %d for channel %d or %d\n",
827 				mmv->enable, (int)chan, (int)chan + 1);
828 			break;
829 
830 		case 2: //Right channel
831 			chan++;
832 			//No break
833 		case 1: //Left channel
834 			mmv->gain = vol[chan].volume;
835 			ITRACE_VV("	Get Volume %f for channel %d\n",
836 				mmv->gain, (int)chan);
837 			break;
838 	}
839 }
840 
841 
842 void
843 ice1712UI_SetVolume(ice1712 *card, multi_mix_value *mmv)
844 {
845 	ice1712Volume *vol;
846 	uint32 chan = ICE1712_MULTI_GET_CHANNEL(mmv->id);
847 
848 	ITRACE_VV("Set volume\n");
849 
850 	if (chan < ICE1712_HARDWARE_VOLUME) {
851 		vol = card->settings.playback;
852 	} else {
853 		vol = card->settings.record;
854 		chan -= ICE1712_HARDWARE_VOLUME;
855 	}
856 
857 	//chan is normaly <= ICE1712_HARDWARE_VOLUME
858 	switch (ICE1712_MULTI_GET_INDEX(mmv->id)) {
859 		case 0: //Mute
860 			vol[chan].mute = mmv->enable;
861 			vol[chan + 1].mute = mmv->enable;
862 			ITRACE_VV("	Change mute to %d for channel %d and %d\n",
863 				mmv->enable, (int)chan, (int)chan + 1);
864 			break;
865 
866 		case 2: //Right channel
867 			chan++;
868 			//No break
869 		case 1: //Left channel
870 			vol[chan].volume = mmv->gain;
871 			ITRACE_VV("	Change Volume to %f for channel %d\n",
872 				mmv->gain, (int)chan);
873 			break;
874 	}
875 }
876 
877 //ICE1712 Multi - MIX
878 //-------------------
879 
880 status_t
881 ice1712Get_MixValue(ice1712 *card, multi_mix_value_info *data)
882 {
883 	int i;
884 
885 	for (i = 0; i < data->item_count; i++) {
886 		multi_mix_value *mmv = &(data->values[i]);
887 		ITRACE_VV("Get Mix: Id %" B_PRIu32 "\n", mmv->id);
888 		switch (mmv->id & ICE1712_MULTI_CONTROL_TYPE_MASK) {
889 			case ICE1712_MULTI_CONTROL_TYPE_COMBO:
890 				mmv->mux = ice1712UI_GetCombo(card,
891 					ICE1712_MULTI_GET_CHANNEL(mmv->id));
892 				break;
893 
894 			case ICE1712_MULTI_CONTROL_TYPE_VOLUME:
895 				ice1712UI_GetVolume(card, mmv);
896 				break;
897 
898 			case ICE1712_MULTI_CONTROL_TYPE_OUTPUT:
899 				mmv->mux = ice1712UI_GetOutput(card,
900 					ICE1712_MULTI_GET_CHANNEL(mmv->id));
901 				break;
902 
903 			default:
904 				ITRACE_VV("Get Mix: unknow %" B_PRIu32 "\n", mmv->id);
905 				break;
906 		}
907 	}
908 
909 	return B_OK;
910 }
911 
912 
913 status_t
914 ice1712Set_MixValue(ice1712 *card, multi_mix_value_info *data)
915 {
916 	int i;
917 
918 	for (i = 0; i < data->item_count; i++) {
919 		multi_mix_value *mmv = &(data->values[i]);
920 		ITRACE_VV("Set Mix: Id %" B_PRIu32 "\n", mmv->id);
921 		switch (mmv->id & ICE1712_MULTI_CONTROL_TYPE_MASK) {
922 			case ICE1712_MULTI_CONTROL_TYPE_COMBO:
923 				ice1712UI_SetCombo(card,
924 					ICE1712_MULTI_GET_CHANNEL(mmv->id), mmv->mux);
925 				break;
926 
927 			case ICE1712_MULTI_CONTROL_TYPE_VOLUME:
928 				ice1712UI_SetVolume(card, mmv);
929 				break;
930 
931 			case ICE1712_MULTI_CONTROL_TYPE_OUTPUT:
932 				ice1712UI_SetOutput(card,
933 					ICE1712_MULTI_GET_CHANNEL(mmv->id), mmv->mux);
934 				break;
935 
936 			default:
937 				ITRACE_VV("Set Mix: unknow %" B_PRIu32 "\n", mmv->id);
938 				break;
939 		}
940 	}
941 
942 	return ice1712Settings_apply(card);
943 }
944 
945 
946 /*
947  * Not implemented
948  */
949 status_t
950 ice1712Get_MixValueChannel(ice1712 *card, multi_mix_channel_info *data)
951 {
952 	return B_OK;
953 }
954 
955 
956 status_t
957 ice1712Get_MixValueControls(ice1712 *card, multi_mix_control_info *mmci)
958 {
959 	int32 i;
960 	uint32 parentTab, parentTabColumn;
961 	multi_mix_control *mmc = mmci->controls;
962 	uint32 group = 0, combo = 0, channel = 0;
963 
964 	nb_control_created = 0;
965 
966 	ITRACE_VV("Get MixValue Channels: Max %" B_PRIi32 "\n", mmci->control_count);
967 
968 	//Cleaning
969 	memset(mmc, 0, mmci->control_count * sizeof(multi_mix_control));
970 
971 	//Setup tab
972 	parentTab = ice1712UI_CreateGroup(&mmc, group++,
973 		CONTROL_IS_MASTER, S_SETUP, NULL);
974 
975 	//General Settings
976 	parentTabColumn = ice1712UI_CreateGroup(&mmc, group++, parentTab,
977 		S_null, string_list[1]);
978 	for (i = 0; SettingsGeneral[i] != NULL; i++) {
979 		ice1712UI_CreateCombo(&mmc, SettingsGeneral[i], parentTabColumn,
980 			combo++, string_list[5 + i]);
981 	}
982 
983 	//Digital Settings
984 	parentTabColumn = ice1712UI_CreateGroup(&mmc, group++, parentTab,
985 		S_null, string_list[2]);
986 	for (i = 0; SettingsDigital[i] != NULL; i++) {
987 		ice1712UI_CreateCombo(&mmc, SettingsDigital[i], parentTabColumn,
988 			combo++, string_list[8 + i]);
989 	}
990 
991 	//Output Selection Settings
992 	parentTabColumn = ice1712UI_CreateGroup(&mmc, group++, parentTab,
993 		S_null, string_list[3]);
994 	for (i = 0; i < card->config.nb_DAC; i += 2) {
995 		ice1712UI_CreateOutput(card, &mmc, i / 2, parentTabColumn);
996 	}
997 
998 	if (card->config.spdif & SPDIF_OUT_PRESENT) {
999 		ice1712UI_CreateOutput(card, &mmc, 4, parentTabColumn);
1000 	}
1001 
1002 	//Internal Mixer Tab
1003 	//Output
1004 	parentTab = ice1712UI_CreateGroup(&mmc, group++, CONTROL_IS_MASTER,
1005 		S_null, string_list[4]);
1006 
1007 	for (i = 0; i < card->config.nb_DAC; i += 2) {
1008 		parentTabColumn = ice1712UI_CreateGroup(&mmc, group++,
1009 			parentTab, S_null, string_list[(i / 2) + 11]);
1010 		ice1712UI_CreateChannel(&mmc, channel++, parentTabColumn, NULL);
1011 	}
1012 
1013 	if (card->config.spdif & SPDIF_OUT_PRESENT) {
1014 		parentTabColumn = ice1712UI_CreateGroup(&mmc, group++,
1015 			parentTab, S_null, string_list[15]);
1016 		ice1712UI_CreateChannel(&mmc, ICE1712_HARDWARE_VOLUME - 2,
1017 			parentTabColumn, NULL);
1018 	}
1019 
1020 	//Input
1021 	channel = ICE1712_HARDWARE_VOLUME;
1022 	for (i = 0; i < card->config.nb_ADC; i += 2) {
1023 		parentTabColumn = ice1712UI_CreateGroup(&mmc, group++,
1024 			parentTab, S_null, string_list[(i / 2) + 17]);
1025 		ice1712UI_CreateChannel(&mmc, channel++, parentTabColumn, NULL);
1026 	}
1027 
1028 	if (card->config.spdif & SPDIF_IN_PRESENT) {
1029 		parentTabColumn = ice1712UI_CreateGroup(&mmc, group++,
1030 			parentTab, S_null, string_list[21]);
1031 		ice1712UI_CreateChannel(&mmc, 2 * ICE1712_HARDWARE_VOLUME - 2,
1032 			parentTabColumn, NULL);
1033 	}
1034 
1035 	mmci->control_count = nb_control_created;
1036 	ITRACE_VV("Get MixValue Channels: Returned %" B_PRIi32 "\n",
1037 		mmci->control_count);
1038 
1039 	return B_OK;
1040 }
1041 
1042 
1043 /*
1044  * Not implemented
1045  */
1046 status_t
1047 ice1712Get_MixValueConnections(ice1712 *card,
1048 	multi_mix_connection_info *data)
1049 {
1050 	data->actual_count = 0;
1051 	return B_OK;
1052 }
1053 
1054 
1055 status_t
1056 ice1712Buffer_Get(ice1712 *card, multi_buffer_list *data)
1057 {
1058 	const size_t stride_o = MAX_DAC * SAMPLE_SIZE;
1059 	const size_t stride_i = MAX_ADC * SAMPLE_SIZE;
1060 	const uint32 buf_o = stride_o * card->buffer_size;
1061 	const uint32 buf_i = stride_i * card->buffer_size;
1062 	int buff, chan_i = 0, chan_o = 0;
1063 
1064 	ITRACE_VV("flags = %#" B_PRIx32 "\n", data->flags);
1065 	ITRACE_VV("request_playback_buffers = %" B_PRIu32 "\n",
1066 			data->request_playback_buffers);
1067 	ITRACE_VV("request_playback_channels = %" B_PRIu32 "\n",
1068 			data->request_playback_channels);
1069 	ITRACE_VV("request_playback_buffer_size = %" B_PRIx32 "\n",
1070 			data->request_playback_buffer_size);
1071 	ITRACE_VV("request_record_buffers = %" B_PRIu32 "\n",
1072 			data->request_record_buffers);
1073 	ITRACE_VV("request_record_channels = %" B_PRIu32 "\n",
1074 			data->request_record_channels);
1075 	ITRACE_VV("request_record_buffer_size = %" B_PRIx32 "\n",
1076 			data->request_record_buffer_size);
1077 
1078 	for (buff = 0; buff < SWAPPING_BUFFERS; buff++) {
1079 		if (data->request_playback_channels == card->total_output_channels) {
1080 			for (chan_o = 0; chan_o < card->config.nb_DAC; chan_o++) {
1081 			//Analog STEREO output
1082 				data->playback_buffers[buff][chan_o].base =
1083 					(char*)(card->log_addr_pb + buf_o * buff
1084 						+ SAMPLE_SIZE * chan_o);
1085 				data->playback_buffers[buff][chan_o].stride = stride_o;
1086 				ITRACE_VV("pb_buffer[%d][%d] = %p\n", buff, chan_o,
1087 					data->playback_buffers[buff][chan_o].base);
1088 			}
1089 
1090 			if (card->config.spdif & SPDIF_OUT_PRESENT) {
1091 			//SPDIF STEREO output
1092 				data->playback_buffers[buff][chan_o].base =
1093 					(char*)(card->log_addr_pb + buf_o * buff
1094 						+ SAMPLE_SIZE * SPDIF_LEFT);
1095 				data->playback_buffers[buff][chan_o].stride = stride_o;
1096 				ITRACE_VV("pb_buffer[%d][%d] = %p\n", buff, chan_o,
1097 					data->playback_buffers[buff][chan_o].base);
1098 
1099 				chan_o++;
1100 				data->playback_buffers[buff][chan_o].base =
1101 					(char*)(card->log_addr_pb + buf_o * buff
1102 						+ SAMPLE_SIZE * SPDIF_RIGHT);
1103 				data->playback_buffers[buff][chan_o].stride = stride_o;
1104 				ITRACE_VV("pb_buffer[%d][%d] = %p\n", buff, chan_o,
1105 					data->playback_buffers[buff][chan_o].base);
1106 				chan_o++;
1107 			}
1108 		}
1109 
1110 		if (data->request_record_channels ==
1111 			card->total_input_channels) {
1112 			for (chan_i = 0; chan_i < card->config.nb_ADC; chan_i++) {
1113 			//Analog STEREO input
1114 				data->record_buffers[buff][chan_i].base =
1115 					(char*)(card->log_addr_rec + buf_i * buff
1116 						+ SAMPLE_SIZE * chan_i);
1117 				data->record_buffers[buff][chan_i].stride = stride_i;
1118 				ITRACE_VV("rec_buffer[%d][%d] = %p\n", buff, chan_i,
1119 					data->record_buffers[buff][chan_i].base);
1120 			}
1121 
1122 			if (card->config.spdif & SPDIF_IN_PRESENT) {
1123 			//SPDIF STEREO input
1124 				data->record_buffers[buff][chan_i].base =
1125 					(char*)(card->log_addr_rec + buf_i * buff
1126 						+ SAMPLE_SIZE * SPDIF_LEFT);
1127 				data->record_buffers[buff][chan_i].stride = stride_i;
1128 				ITRACE_VV("rec_buffer[%d][%d] = %p\n", buff, chan_i,
1129 					data->record_buffers[buff][chan_i].base);
1130 
1131 				chan_i++;
1132 				data->record_buffers[buff][chan_i].base =
1133 					(char*)(card->log_addr_rec + buf_i * buff
1134 						+ SAMPLE_SIZE * SPDIF_RIGHT);
1135 				data->record_buffers[buff][chan_i].stride = stride_i;
1136 				ITRACE_VV("rec_buffer[%d][%d] = %p\n", buff, chan_i,
1137 					data->record_buffers[buff][chan_i].base);
1138 				chan_i++;
1139 			}
1140 
1141 			//The digital mixer output
1142 			data->record_buffers[buff][chan_i].base =
1143 				(char*)(card->log_addr_rec + buf_i * buff
1144 					+ SAMPLE_SIZE * MIXER_OUT_LEFT);
1145 			data->record_buffers[buff][chan_i].stride = stride_i;
1146 			ITRACE_VV("rec_buffer[%d][%d] = %p\n", buff, chan_i,
1147 					data->record_buffers[buff][chan_i].base);
1148 
1149 			chan_i++;
1150 			data->record_buffers[buff][chan_i].base =
1151 				(char*)(card->log_addr_rec + buf_i * buff
1152 					+ SAMPLE_SIZE * MIXER_OUT_RIGHT);
1153 			data->record_buffers[buff][chan_i].stride = stride_i;
1154 			ITRACE_VV("rec_buffer[%d][%d] = %p\n", buff, chan_i,
1155 					data->record_buffers[buff][chan_i].base);
1156 			chan_i++;
1157 		}
1158 	}
1159 
1160 	data->return_playback_buffers = SWAPPING_BUFFERS;
1161 	data->return_playback_channels = card->total_output_channels;
1162 	data->return_playback_buffer_size = card->buffer_size;
1163 
1164 	ITRACE("return_playback_buffers = %" B_PRIi32 "\n",
1165 		data->return_playback_buffers);
1166 	ITRACE("return_playback_channels = %" B_PRIi32 "\n",
1167 		data->return_playback_channels);
1168 	ITRACE("return_playback_buffer_size = %" B_PRIu32 "\n",
1169 		data->return_playback_buffer_size);
1170 
1171 	data->return_record_buffers = SWAPPING_BUFFERS;
1172 	data->return_record_channels = card->total_input_channels;
1173 	data->return_record_channels = chan_i;
1174 	data->return_record_buffer_size = card->buffer_size;
1175 
1176 	ITRACE("return_record_buffers = %" B_PRIi32 "\n",
1177 		data->return_record_buffers);
1178 	ITRACE("return_record_channels = %" B_PRIi32 "\n",
1179 		data->return_record_channels);
1180 	ITRACE("return_record_buffer_size = %" B_PRIu32 "\n",
1181 		data->return_record_buffer_size);
1182 
1183 	ice1712Buffer_Start(card);
1184 
1185 	return B_OK;
1186 }
1187