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
20status_t ice1712Settings_apply(ice1712 *card);
21
22static void ice1712Buffer_Start(ice1712 *card);
23static uint32 ice1712UI_GetCombo(ice1712 *card, uint32 index);
24static void ice1712UI_SetCombo(ice1712 *card, uint32 index, uint32 value);
25static uint32 ice1712UI_GetOutput(ice1712 *card, uint32 index);
26static void ice1712UI_SetOutput(ice1712 *card, uint32 index, uint32 value);
27static void ice1712UI_GetVolume(ice1712 *card, multi_mix_value *mmv);
28static void ice1712UI_SetVolume(ice1712 *card, multi_mix_value *mmv);
29static void ice1712UI_CreateOutput(ice1712 *card, multi_mix_control **p_mmc,
30	int32 output, int32 parent);
31static void ice1712UI_CreateCombo(multi_mix_control **p_mmc,
32	const char *values[], int32 parent, int32 nb_combo, const char *name);
33static void ice1712UI_CreateChannel(multi_mix_control **p_mmc,
34	int32 channel, int32 parent, const char* name);
35static int32 ice1712UI_CreateGroup(multi_mix_control **p_mmc,
36	int32 index, int32 parent, enum strind_id string, const char* name);
37static 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
48void
49ice1712Buffer_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
132status_t
133ice1712Buffer_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
174status_t
175ice1712Buffer_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
189status_t
190ice1712Get_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
337status_t
338ice1712Get_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
358status_t
359ice1712Set_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
384status_t
385ice1712Get_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
418status_t
419ice1712Set_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
459static const char *Clock[] = {
460	"Internal",
461	"Digital",
462	NULL,
463};
464
465static const char *DigitalFormat[] = {
466	"Consumer",
467	"Professional",
468	NULL,
469};
470
471static const char *DigitalEmphasis[] = {
472	"None",
473	"CCITT",
474	"15/50usec",
475	NULL,
476};
477
478static const char *DigitalCopyMode[] = {
479	"Original",
480	"1st Generation",
481	"No SCMS",
482	NULL,
483};
484
485static const char **SettingsGeneral[] = {
486	Clock,
487	NULL,
488};
489
490static const char **SettingsDigital[] = {
491	DigitalFormat,
492	DigitalEmphasis,
493	DigitalCopyMode,
494	NULL,
495};
496
497static 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 */
536int32
537ice1712UI_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 */
566void
567ice1712UI_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
615void
616ice1712UI_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 */
655void
656ice1712UI_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
724uint32
725ice1712UI_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
754void
755ice1712UI_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
783uint32
784ice1712UI_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
797void
798ice1712UI_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
807void
808ice1712UI_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
842void
843ice1712UI_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
880status_t
881ice1712Get_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
913status_t
914ice1712Set_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 */
949status_t
950ice1712Get_MixValueChannel(ice1712 *card, multi_mix_channel_info *data)
951{
952	return B_OK;
953}
954
955
956status_t
957ice1712Get_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 */
1046status_t
1047ice1712Get_MixValueConnections(ice1712 *card,
1048	multi_mix_connection_info *data)
1049{
1050	data->actual_count = 0;
1051	return B_OK;
1052}
1053
1054
1055status_t
1056ice1712Buffer_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