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