xref: /haiku/src/add-ons/kernel/drivers/audio/ac97/es1370/multi.c (revision 0d452c8f34013b611a54c746a71c05e28796eae2)
1 /*
2  * ES1370 Haiku Driver for ES1370 audio
3  *
4  * Copyright 2002-2007, Haiku, Inc.
5  * Distributed under the terms of the MIT License.
6  *
7  * Authors:
8  *		Jerome Duval, jerome.duval@free.fr
9  */
10 
11 #include <driver_settings.h>
12 #include <OS.h>
13 #include <MediaDefs.h>
14 #include <strings.h>
15 #include "hmulti_audio.h"
16 #include "multi.h"
17 #include "ac97.h"
18 
19 //#define DEBUG 1
20 
21 #include "debug.h"
22 #include "es1370.h"
23 #include "util.h"
24 #include "io.h"
25 
26 static void
27 es1370_ac97_get_mix(void *card, const void *cookie, int32 type, float *values) {
28 	es1370_dev *dev = (es1370_dev*)card;
29 	ac97_source_info *info = (ac97_source_info *)cookie;
30 	uint16 value, mask;
31 	float gain;
32 
33 	switch(type) {
34 		case B_MIX_GAIN:
35 			value = es1370_codec_read(&dev->config, info->reg);
36 			//PRINT(("B_MIX_GAIN value : %u\n", value));
37 			if (info->type & B_MIX_STEREO) {
38 				mask = ((1 << (info->bits + 1)) - 1) << 8;
39 				gain = ((value & mask) >> 8) * info->granularity;
40 				if (info->polarity == 1)
41 					values[0] = info->max_gain - gain;
42 				else
43 					values[0] = gain - info->min_gain;
44 
45 				mask = ((1 << (info->bits + 1)) - 1);
46 				gain = (value & mask) * info->granularity;
47 				if (info->polarity == 1)
48 					values[1] = info->max_gain - gain;
49 				else
50 					values[1] = gain - info->min_gain;
51 			} else {
52 				mask = ((1 << (info->bits + 1)) - 1);
53 				gain = (value & mask) * info->granularity;
54 				if (info->polarity == 1)
55 					values[0] = info->max_gain - gain;
56 				else
57 					values[0] = gain - info->min_gain;
58 			}
59 			break;
60 		case B_MIX_MUTE:
61 			mask = ((1 << 1) - 1) << 15;
62 			value = es1370_codec_read(&dev->config, info->reg);
63 			//PRINT(("B_MIX_MUTE value : %u\n", value));
64 			value &= mask;
65 			values[0] = ((value >> 15) == 1) ? 1.0 : 0.0;
66 			break;
67 		case B_MIX_MICBOOST:
68 			mask = ((1 << 1) - 1) << 6;
69 			value = es1370_codec_read(&dev->config, info->reg);
70 			//PRINT(("B_MIX_MICBOOST value : %u\n", value));
71 			value &= mask;
72 			values[0] = ((value >> 6) == 1) ? 1.0 : 0.0;
73 			break;
74 		case B_MIX_MUX:
75 			mask = ((1 << 3) - 1);
76 			value = es1370_codec_read(&dev->config, AC97_RECORD_SELECT);
77 			value &= mask;
78 			//PRINT(("B_MIX_MUX value : %u\n", value));
79 			values[0] = (float)value;
80 			break;
81 	}
82 }
83 
84 static void
85 es1370_ac97_set_mix(void *card, const void *cookie, int32 type, float *values) {
86 	es1370_dev *dev = (es1370_dev*)card;
87 	ac97_source_info *info = (ac97_source_info *)cookie;
88 	uint16 value, mask;
89 	float gain;
90 
91 	switch(type) {
92 		case B_MIX_GAIN:
93 			value = es1370_codec_read(&dev->config, info->reg);
94 			if (info->type & B_MIX_STEREO) {
95 				mask = ((1 << (info->bits + 1)) - 1) << 8;
96 				value &= ~mask;
97 
98 				if (info->polarity == 1)
99 					gain = info->max_gain - values[0];
100 				else
101 					gain =  values[0] - info->min_gain;
102 				value |= ((uint16)(gain	/ info->granularity) << 8) & mask;
103 
104 				mask = ((1 << (info->bits + 1)) - 1);
105 				value &= ~mask;
106 				if (info->polarity == 1)
107 					gain = info->max_gain - values[1];
108 				else
109 					gain =  values[1] - info->min_gain;
110 				value |= ((uint16)(gain / info->granularity)) & mask;
111 			} else {
112 				mask = ((1 << (info->bits + 1)) - 1);
113 				value &= ~mask;
114 				if (info->polarity == 1)
115 					gain = info->max_gain - values[0];
116 				else
117 					gain =  values[0] - info->min_gain;
118 				value |= ((uint16)(gain / info->granularity)) & mask;
119 			}
120 			//PRINT(("B_MIX_GAIN value : %u\n", value));
121 			es1370_codec_write(&dev->config, info->reg, value);
122 			break;
123 		case B_MIX_MUTE:
124 			mask = ((1 << 1) - 1) << 15;
125 			value = es1370_codec_read(&dev->config, info->reg);
126 			value &= ~mask;
127 			value |= ((values[0] == 1.0 ? 1 : 0 ) << 15 & mask);
128 			if (info->reg == AC97_SURR_VOLUME) {
129 				// there is a independent mute for each channel
130 				mask = ((1 << 1) - 1) << 7;
131 				value &= ~mask;
132 				value |= ((values[0] == 1.0 ? 1 : 0 ) << 7 & mask);
133 			}
134 			//PRINT(("B_MIX_MUTE value : %u\n", value));
135 			es1370_codec_write(&dev->config, info->reg, value);
136 			break;
137 		case B_MIX_MICBOOST:
138 			mask = ((1 << 1) - 1) << 6;
139 			value = es1370_codec_read(&dev->config, info->reg);
140 			value &= ~mask;
141 			value |= ((values[0] == 1.0 ? 1 : 0 ) << 6 & mask);
142 			//PRINT(("B_MIX_MICBOOST value : %u\n", value));
143 			es1370_codec_write(&dev->config, info->reg, value);
144 			break;
145 		case B_MIX_MUX:
146 			mask = ((1 << 3) - 1);
147 			value = ((int32)values[0]) & mask;
148 			value = value | (value << 8);
149 			//PRINT(("B_MIX_MUX value : %u\n", value));
150 			es1370_codec_write(&dev->config, AC97_RECORD_SELECT, value);
151 			break;
152 	}
153 
154 }
155 
156 static int32
157 es1370_create_group_control(multi_dev *multi, int32 *index, int32 parent,
158 	int32 string, const char* name) {
159 	int32 i = *index;
160 	(*index)++;
161 	multi->controls[i].mix_control.id = EMU_MULTI_CONTROL_FIRSTID + i;
162 	multi->controls[i].mix_control.parent = parent;
163 	multi->controls[i].mix_control.flags = B_MULTI_MIX_GROUP;
164 	multi->controls[i].mix_control.master = EMU_MULTI_CONTROL_MASTERID;
165 	multi->controls[i].mix_control.string = string;
166 	if (name)
167 		strcpy(multi->controls[i].mix_control.name, name);
168 
169 	return multi->controls[i].mix_control.id;
170 }
171 
172 static status_t
173 es1370_create_controls_list(multi_dev *multi)
174 {
175 	multi->control_count = 0;
176 	PRINT(("multi->control_count %lu\n", multi->control_count));
177 	return B_OK;
178 }
179 
180 static status_t
181 es1370_get_mix(es1370_dev *card, multi_mix_value_info * mmvi)
182 {
183 	int32 i, id;
184 	multi_mixer_control *control = NULL;
185 	for (i = 0; i < mmvi->item_count; i++) {
186 		id = mmvi->values[i].id - EMU_MULTI_CONTROL_FIRSTID;
187 		if (id < 0 || id >= card->multi.control_count) {
188 			PRINT(("es1370_get_mix : invalid control id requested : %li\n", id));
189 			continue;
190 		}
191 		control = &card->multi.controls[id];
192 
193 		if (control->mix_control.flags & B_MULTI_MIX_GAIN) {
194 			if (control->get) {
195 				float values[2];
196 				control->get(card, control->cookie, control->type, values);
197 				if (control->mix_control.master == EMU_MULTI_CONTROL_MASTERID)
198 					mmvi->values[i].u.gain = values[0];
199 				else
200 					mmvi->values[i].u.gain = values[1];
201 			}
202 		}
203 
204 		if (control->mix_control.flags & B_MULTI_MIX_ENABLE && control->get) {
205 			float values[1];
206 			control->get(card, control->cookie, control->type, values);
207 			mmvi->values[i].u.enable = (values[0] == 1.0);
208 		}
209 
210 		if (control->mix_control.flags & B_MULTI_MIX_MUX && control->get) {
211 			float values[1];
212 			control->get(card, control->cookie, control->type, values);
213 			mmvi->values[i].u.mux = (int32)values[0];
214 		}
215 	}
216 	return B_OK;
217 }
218 
219 static status_t
220 es1370_set_mix(es1370_dev *card, multi_mix_value_info * mmvi)
221 {
222 	int32 i, id;
223 	multi_mixer_control *control = NULL;
224 	for (i = 0; i < mmvi->item_count; i++) {
225 		id = mmvi->values[i].id - EMU_MULTI_CONTROL_FIRSTID;
226 		if (id < 0 || id >= card->multi.control_count) {
227 			PRINT(("es1370_set_mix : invalid control id requested : %li\n", id));
228 			continue;
229 		}
230 		control = &card->multi.controls[id];
231 
232 		if (control->mix_control.flags & B_MULTI_MIX_GAIN) {
233 			multi_mixer_control *control2 = NULL;
234 			if (i+1<mmvi->item_count) {
235 				id = mmvi->values[i + 1].id - EMU_MULTI_CONTROL_FIRSTID;
236 				if (id < 0 || id >= card->multi.control_count) {
237 					PRINT(("es1370_set_mix : invalid control id requested : %li\n", id));
238 				} else {
239 					control2 = &card->multi.controls[id];
240 					if (control2->mix_control.master != control->mix_control.id)
241 						control2 = NULL;
242 				}
243 			}
244 
245 			if (control->set) {
246 				float values[2];
247 				values[0] = 0.0;
248 				values[1] = 0.0;
249 
250 				if (control->mix_control.master == EMU_MULTI_CONTROL_MASTERID)
251 					values[0] = mmvi->values[i].u.gain;
252 				else
253 					values[1] = mmvi->values[i].u.gain;
254 
255 				if (control2 && control2->mix_control.master != EMU_MULTI_CONTROL_MASTERID)
256 					values[1] = mmvi->values[i+1].u.gain;
257 
258 				control->set(card, control->cookie, control->type, values);
259 			}
260 
261 			if (control2)
262 				i++;
263 		}
264 
265 		if (control->mix_control.flags & B_MULTI_MIX_ENABLE && control->set) {
266 			float values[1];
267 
268 			values[0] = mmvi->values[i].u.enable ? 1.0 : 0.0;
269 			control->set(card, control->cookie, control->type, values);
270 		}
271 
272 		if (control->mix_control.flags & B_MULTI_MIX_MUX && control->set) {
273 			float values[1];
274 
275 			values[0] = (float)mmvi->values[i].u.mux;
276 			control->set(card, control->cookie, control->type, values);
277 		}
278 	}
279 	return B_OK;
280 }
281 
282 static status_t
283 es1370_list_mix_controls(es1370_dev *card, multi_mix_control_info * mmci)
284 {
285 	multi_mix_control	*mmc;
286 	int32 i;
287 
288 	mmc = mmci->controls;
289 	if (mmci->control_count < 24)
290 		return B_ERROR;
291 
292 	if (es1370_create_controls_list(&card->multi) < B_OK)
293 		return B_ERROR;
294 	for (i = 0; i < card->multi.control_count; i++) {
295 		mmc[i] = card->multi.controls[i].mix_control;
296 	}
297 
298 	mmci->control_count = card->multi.control_count;
299 	return B_OK;
300 }
301 
302 static status_t
303 es1370_list_mix_connections(es1370_dev *card, multi_mix_connection_info * data)
304 {
305 	return B_ERROR;
306 }
307 
308 static status_t
309 es1370_list_mix_channels(es1370_dev *card, multi_mix_channel_info *data)
310 {
311 	return B_ERROR;
312 }
313 
314 /*multi_channel_info chans[] = {
315 {  0, B_MULTI_OUTPUT_CHANNEL, 	B_CHANNEL_LEFT | B_CHANNEL_STEREO_BUS, 0 },
316 {  1, B_MULTI_OUTPUT_CHANNEL, 	B_CHANNEL_RIGHT | B_CHANNEL_STEREO_BUS, 0 },
317 {  2, B_MULTI_OUTPUT_CHANNEL, 	B_CHANNEL_LEFT | B_CHANNEL_STEREO_BUS, 0 },
318 {  3, B_MULTI_OUTPUT_CHANNEL, 	B_CHANNEL_RIGHT | B_CHANNEL_STEREO_BUS, 0 },
319 {  4, B_MULTI_INPUT_CHANNEL, 	B_CHANNEL_LEFT | B_CHANNEL_STEREO_BUS, 0 },
320 {  5, B_MULTI_INPUT_CHANNEL, 	B_CHANNEL_RIGHT | B_CHANNEL_STEREO_BUS, 0 },
321 {  6, B_MULTI_INPUT_CHANNEL, 	B_CHANNEL_LEFT | B_CHANNEL_STEREO_BUS, 0 },
322 {  7, B_MULTI_INPUT_CHANNEL, 	B_CHANNEL_RIGHT | B_CHANNEL_STEREO_BUS, 0 },
323 {  8, B_MULTI_OUTPUT_BUS, 		B_CHANNEL_LEFT | B_CHANNEL_STEREO_BUS, 	B_CHANNEL_MINI_JACK_STEREO },
324 {  9, B_MULTI_OUTPUT_BUS, 		B_CHANNEL_RIGHT | B_CHANNEL_STEREO_BUS, B_CHANNEL_MINI_JACK_STEREO },
325 {  10, B_MULTI_INPUT_BUS, 		B_CHANNEL_LEFT | B_CHANNEL_STEREO_BUS, 	B_CHANNEL_MINI_JACK_STEREO },
326 {  11, B_MULTI_INPUT_BUS, 		B_CHANNEL_RIGHT | B_CHANNEL_STEREO_BUS, B_CHANNEL_MINI_JACK_STEREO },
327 };*/
328 
329 /*multi_channel_info chans[] = {
330 {  0, B_MULTI_OUTPUT_CHANNEL, 	B_CHANNEL_LEFT | B_CHANNEL_STEREO_BUS, 0 },
331 {  1, B_MULTI_OUTPUT_CHANNEL, 	B_CHANNEL_RIGHT | B_CHANNEL_STEREO_BUS, 0 },
332 {  2, B_MULTI_OUTPUT_CHANNEL, 	B_CHANNEL_LEFT | B_CHANNEL_SURROUND_BUS, 0 },
333 {  3, B_MULTI_OUTPUT_CHANNEL, 	B_CHANNEL_RIGHT | B_CHANNEL_SURROUND_BUS, 0 },
334 {  4, B_MULTI_OUTPUT_CHANNEL, 	B_CHANNEL_REARLEFT | B_CHANNEL_SURROUND_BUS, 0 },
335 {  5, B_MULTI_OUTPUT_CHANNEL, 	B_CHANNEL_REARRIGHT | B_CHANNEL_SURROUND_BUS, 0 },
336 {  6, B_MULTI_INPUT_CHANNEL, 	B_CHANNEL_LEFT | B_CHANNEL_STEREO_BUS, 0 },
337 {  7, B_MULTI_INPUT_CHANNEL, 	B_CHANNEL_RIGHT | B_CHANNEL_STEREO_BUS, 0 },
338 {  8, B_MULTI_INPUT_CHANNEL, 	B_CHANNEL_LEFT | B_CHANNEL_STEREO_BUS, 0 },
339 {  9, B_MULTI_INPUT_CHANNEL, 	B_CHANNEL_RIGHT | B_CHANNEL_STEREO_BUS, 0 },
340 {  10, B_MULTI_OUTPUT_BUS, 		B_CHANNEL_LEFT | B_CHANNEL_STEREO_BUS, 	B_CHANNEL_MINI_JACK_STEREO },
341 {  11, B_MULTI_OUTPUT_BUS, 		B_CHANNEL_RIGHT | B_CHANNEL_STEREO_BUS, B_CHANNEL_MINI_JACK_STEREO },
342 {  12, B_MULTI_INPUT_BUS, 		B_CHANNEL_LEFT | B_CHANNEL_STEREO_BUS, 	B_CHANNEL_MINI_JACK_STEREO },
343 {  13, B_MULTI_INPUT_BUS, 		B_CHANNEL_RIGHT | B_CHANNEL_STEREO_BUS, B_CHANNEL_MINI_JACK_STEREO },
344 };*/
345 
346 
347 static void
348 es1370_create_channels_list(multi_dev *multi)
349 {
350 	es1370_stream *stream;
351 	uint32 index, i, mode, designations;
352 	multi_channel_info *chans;
353 	uint32 chan_designations[] = {
354 		B_CHANNEL_LEFT,
355 		B_CHANNEL_RIGHT,
356 		B_CHANNEL_REARLEFT,
357 		B_CHANNEL_REARRIGHT,
358 		B_CHANNEL_CENTER,
359 		B_CHANNEL_SUB
360 	};
361 
362 	chans = multi->chans;
363 	index = 0;
364 
365 	for (mode=ES1370_USE_PLAY; mode!=-1;
366 		mode = (mode == ES1370_USE_PLAY) ? ES1370_USE_RECORD : -1) {
367 		LIST_FOREACH(stream, &((es1370_dev*)multi->card)->streams, next) {
368 			if ((stream->use & mode) == 0)
369 				continue;
370 
371 			if (stream->channels == 2)
372 				designations = B_CHANNEL_STEREO_BUS;
373 			else
374 				designations = B_CHANNEL_SURROUND_BUS;
375 
376 			for (i = 0; i < stream->channels; i++) {
377 				chans[index].channel_id = index;
378 				chans[index].kind = (mode == ES1370_USE_PLAY) ? B_MULTI_OUTPUT_CHANNEL : B_MULTI_INPUT_CHANNEL;
379 				chans[index].designations = designations | chan_designations[i];
380 				chans[index].connectors = 0;
381 				index++;
382 			}
383 		}
384 
385 		if (mode==ES1370_USE_PLAY) {
386 			multi->output_channel_count = index;
387 		} else {
388 			multi->input_channel_count = index - multi->output_channel_count;
389 		}
390 	}
391 
392 	chans[index].channel_id = index;
393 	chans[index].kind = B_MULTI_OUTPUT_BUS;
394 	chans[index].designations = B_CHANNEL_LEFT | B_CHANNEL_STEREO_BUS;
395 	chans[index].connectors = B_CHANNEL_MINI_JACK_STEREO;
396 	index++;
397 
398 	chans[index].channel_id = index;
399 	chans[index].kind = B_MULTI_OUTPUT_BUS;
400 	chans[index].designations = B_CHANNEL_RIGHT | B_CHANNEL_STEREO_BUS;
401 	chans[index].connectors = B_CHANNEL_MINI_JACK_STEREO;
402 	index++;
403 
404 	multi->output_bus_channel_count = index - multi->output_channel_count
405 		- multi->input_channel_count;
406 
407 	chans[index].channel_id = index;
408 	chans[index].kind = B_MULTI_INPUT_BUS;
409 	chans[index].designations = B_CHANNEL_LEFT | B_CHANNEL_STEREO_BUS;
410 	chans[index].connectors = B_CHANNEL_MINI_JACK_STEREO;
411 	index++;
412 
413 	chans[index].channel_id = index;
414 	chans[index].kind = B_MULTI_INPUT_BUS;
415 	chans[index].designations = B_CHANNEL_RIGHT | B_CHANNEL_STEREO_BUS;
416 	chans[index].connectors = B_CHANNEL_MINI_JACK_STEREO;
417 	index++;
418 
419 	multi->input_bus_channel_count = index - multi->output_channel_count
420 		- multi->input_channel_count - multi->output_bus_channel_count;
421 
422 	multi->aux_bus_channel_count = 0;
423 }
424 
425 
426 static status_t
427 es1370_get_description(es1370_dev *card, multi_description *data)
428 {
429 	uint32 size;
430 
431 	data->interface_version = B_CURRENT_INTERFACE_VERSION;
432 	data->interface_minimum = B_CURRENT_INTERFACE_VERSION;
433 
434 	strncpy(data->friendly_name, FRIENDLY_NAME, 32);
435 	strcpy(data->vendor_info, AUTHOR);
436 
437 	data->output_channel_count = card->multi.output_channel_count;
438 	data->input_channel_count = card->multi.input_channel_count;
439 	data->output_bus_channel_count = card->multi.output_bus_channel_count;
440 	data->input_bus_channel_count = card->multi.input_bus_channel_count;
441 	data->aux_bus_channel_count = card->multi.aux_bus_channel_count;
442 
443 	size = card->multi.output_channel_count + card->multi.input_channel_count
444 			+ card->multi.output_bus_channel_count + card->multi.input_bus_channel_count
445 			+ card->multi.aux_bus_channel_count;
446 
447 	// for each channel, starting with the first output channel,
448 	// then the second, third..., followed by the first input
449 	// channel, second, third, ..., followed by output bus
450 	// channels and input bus channels and finally auxillary channels,
451 
452 	LOG(("request_channel_count = %d\n",data->request_channel_count));
453 	if (data->request_channel_count >= size) {
454 		LOG(("copying data\n"));
455 		memcpy(data->channels, card->multi.chans, size * sizeof(card->multi.chans[0]));
456 	}
457 
458 	data->output_rates = B_SR_44100;// | B_SR_48000 | B_SR_CVSR;
459 	data->input_rates = B_SR_44100;// | B_SR_48000 | B_SR_CVSR;
460 	data->output_rates = B_SR_44100;
461 	data->input_rates = B_SR_44100;
462 	data->min_cvsr_rate = 0;
463 	data->max_cvsr_rate = 44100;
464 
465 	data->output_formats = B_FMT_16BIT;
466 	data->input_formats = B_FMT_16BIT;
467 	data->lock_sources = B_MULTI_LOCK_INTERNAL;
468 	data->timecode_sources = 0;
469 	data->interface_flags = B_MULTI_INTERFACE_PLAYBACK | B_MULTI_INTERFACE_RECORD;
470 	data->start_latency = 3000;
471 
472 	strcpy(data->control_panel,"");
473 
474 	return B_OK;
475 }
476 
477 static status_t
478 es1370_get_enabled_channels(es1370_dev *card, multi_channel_enable *data)
479 {
480 	B_SET_CHANNEL(data->enable_bits, 0, true);
481 	B_SET_CHANNEL(data->enable_bits, 1, true);
482 	B_SET_CHANNEL(data->enable_bits, 2, true);
483 	B_SET_CHANNEL(data->enable_bits, 3, true);
484 	data->lock_source = B_MULTI_LOCK_INTERNAL;
485 /*
486 	uint32			lock_source;
487 	int32			lock_data;
488 	uint32			timecode_source;
489 	uint32 *		connectors;
490 */
491 	return B_OK;
492 }
493 
494 static status_t
495 es1370_set_enabled_channels(es1370_dev *card, multi_channel_enable *data)
496 {
497 	PRINT(("set_enabled_channels 0 : %s\n", B_TEST_CHANNEL(data->enable_bits, 0) ? "enabled": "disabled"));
498 	PRINT(("set_enabled_channels 1 : %s\n", B_TEST_CHANNEL(data->enable_bits, 1) ? "enabled": "disabled"));
499 	PRINT(("set_enabled_channels 2 : %s\n", B_TEST_CHANNEL(data->enable_bits, 2) ? "enabled": "disabled"));
500 	PRINT(("set_enabled_channels 3 : %s\n", B_TEST_CHANNEL(data->enable_bits, 3) ? "enabled": "disabled"));
501 	return B_OK;
502 }
503 
504 static status_t
505 es1370_get_global_format(es1370_dev *card, multi_format_info *data)
506 {
507 	data->output_latency = 0;
508 	data->input_latency = 0;
509 	data->timecode_kind = 0;
510 	data->input.rate = B_SR_44100;
511 	data->input.cvsr = 44100;
512 	data->input.format = B_FMT_16BIT;
513 	data->output.rate = B_SR_44100;
514 	data->output.cvsr = 44100;
515 	data->output.format = B_FMT_16BIT;
516 	return B_OK;
517 }
518 
519 static status_t
520 es1370_get_buffers(es1370_dev *card, multi_buffer_list *data)
521 {
522 	uint8 i, j, pchannels, rchannels, bufcount;
523 
524 	LOG(("flags = %#x\n",data->flags));
525 	LOG(("request_playback_buffers = %#x\n",data->request_playback_buffers));
526 	LOG(("request_playback_channels = %#x\n",data->request_playback_channels));
527 	LOG(("request_playback_buffer_size = %#x\n",data->request_playback_buffer_size));
528 	LOG(("request_record_buffers = %#x\n",data->request_record_buffers));
529 	LOG(("request_record_channels = %#x\n",data->request_record_channels));
530 	LOG(("request_record_buffer_size = %#x\n",data->request_record_buffer_size));
531 
532 	pchannels = card->pstream->channels;
533 	rchannels = card->rstream->channels;
534 
535 	if (data->request_playback_buffers < current_settings.buffer_count ||
536 		data->request_playback_channels < (pchannels) ||
537 		data->request_record_buffers < current_settings.buffer_count ||
538 		data->request_record_channels < (rchannels)) {
539 		LOG(("not enough channels/buffers\n"));
540 	}
541 
542 	data->flags = B_MULTI_BUFFER_PLAYBACK | B_MULTI_BUFFER_RECORD; // XXX ???
543 //	data->flags = 0;
544 
545 	data->return_playback_buffers = current_settings.buffer_count;	/* playback_buffers[b][] */
546 	data->return_playback_channels = pchannels;		/* playback_buffers[][c] */
547 	data->return_playback_buffer_size = current_settings.buffer_frames;		/* frames */
548 
549 	bufcount = current_settings.buffer_count;
550 	if (bufcount > data->request_playback_buffers)
551 		bufcount = data->request_playback_buffers;
552 
553 	for (i = 0; i < bufcount; i++)
554 		for (j=0; j<pchannels; j++)
555 			es1370_stream_get_nth_buffer(card->pstream, j, i,
556 				&data->playback_buffers[i][j].base,
557 				&data->playback_buffers[i][j].stride);
558 
559 	data->return_record_buffers = current_settings.buffer_count;
560 	data->return_record_channels = rchannels;
561 	data->return_record_buffer_size = current_settings.buffer_frames;	/* frames */
562 
563 	bufcount = current_settings.buffer_count;
564 	if (bufcount > data->request_record_buffers)
565 		bufcount = data->request_record_buffers;
566 
567 	for (i = 0; i < bufcount; i++)
568 		for (j=0; j<rchannels; j++)
569 			es1370_stream_get_nth_buffer(card->rstream, j, i,
570 				&data->record_buffers[i][j].base,
571 				&data->record_buffers[i][j].stride);
572 
573 	return B_OK;
574 }
575 
576 
577 static void
578 es1370_play_inth(void* inthparams)
579 {
580 	es1370_stream *stream = (es1370_stream *)inthparams;
581 	//int32 count;
582 
583 	acquire_spinlock(&slock);
584 	stream->real_time = system_time();
585 	stream->frames_count += current_settings.buffer_frames;
586 	stream->buffer_cycle = (stream->trigblk
587 		+ stream->blkmod - 1) % stream->blkmod;
588 	stream->update_needed = true;
589 	release_spinlock(&slock);
590 
591 	//TRACE(("es1370_play_inth : cycle : %d\n", stream->buffer_cycle));
592 
593 	release_sem_etc(stream->card->buffer_ready_sem, 1, B_DO_NOT_RESCHEDULE);
594 }
595 
596 static void
597 es1370_record_inth(void* inthparams)
598 {
599 	es1370_stream *stream = (es1370_stream *)inthparams;
600 	//int32 count;
601 
602 	acquire_spinlock(&slock);
603 	stream->real_time = system_time();
604 	stream->frames_count += current_settings.buffer_frames;
605 	stream->buffer_cycle = (stream->trigblk
606 		+ stream->blkmod - 1) % stream->blkmod;
607 	stream->update_needed = true;
608 	release_spinlock(&slock);
609 
610 	//TRACE(("es1370_record_inth : cycle : %d\n", stream->buffer_cycle));
611 
612 	release_sem_etc(stream->card->buffer_ready_sem, 1, B_DO_NOT_RESCHEDULE);
613 }
614 
615 static status_t
616 es1370_buffer_exchange(es1370_dev *card, multi_buffer_info *data)
617 {
618 	cpu_status status;
619 	es1370_stream *pstream, *rstream;
620 	multi_buffer_info buffer_info;
621 
622 #ifdef __HAIKU__
623 	if (user_memcpy(&buffer_info, data, sizeof(buffer_info)) < B_OK)
624 		return B_BAD_ADDRESS;
625 #else
626 	memcpy(&buffer_info, data, sizeof(buffer_info));
627 #endif
628 
629 	buffer_info.flags = B_MULTI_BUFFER_PLAYBACK | B_MULTI_BUFFER_RECORD;
630 
631 	if (!(card->pstream->state & ES1370_STATE_STARTED))
632 		es1370_stream_start(card->pstream, es1370_play_inth, card->pstream);
633 
634 	if (!(card->rstream->state & ES1370_STATE_STARTED))
635 		es1370_stream_start(card->rstream, es1370_record_inth, card->rstream);
636 
637 	if (acquire_sem_etc(card->buffer_ready_sem, 1, B_RELATIVE_TIMEOUT | B_CAN_INTERRUPT, 100000)
638 		== B_TIMED_OUT) {
639 		LOG(("buffer_exchange timeout ff\n"));
640 	}
641 
642 	status = lock();
643 
644 	LIST_FOREACH(pstream, &card->streams, next) {
645 		if ((pstream->use & ES1370_USE_PLAY) == 0 ||
646 			(pstream->state & ES1370_STATE_STARTED) == 0)
647 			continue;
648 		if (pstream->update_needed)
649 			break;
650 	}
651 
652 	LIST_FOREACH(rstream, &card->streams, next) {
653 		if ((rstream->use & ES1370_USE_RECORD) == 0 ||
654 			(rstream->state & ES1370_STATE_STARTED) == 0)
655 			continue;
656 		if (rstream->update_needed)
657 			break;
658 	}
659 
660 	if (!pstream)
661 		pstream = card->pstream;
662 	if (!rstream)
663 		rstream = card->rstream;
664 
665 	/* do playback */
666 	buffer_info.playback_buffer_cycle = pstream->buffer_cycle;
667 	buffer_info.played_real_time = pstream->real_time;
668 	buffer_info.played_frames_count = pstream->frames_count;
669 	buffer_info._reserved_0 = pstream->first_channel;
670 	pstream->update_needed = false;
671 
672 	/* do record */
673 	buffer_info.record_buffer_cycle = rstream->buffer_cycle;
674 	buffer_info.recorded_frames_count = rstream->frames_count;
675 	buffer_info.recorded_real_time = rstream->real_time;
676 	buffer_info._reserved_1 = rstream->first_channel;
677 	rstream->update_needed = false;
678 	unlock(status);
679 
680 #ifdef __HAIKU__
681 	if (user_memcpy(data, &buffer_info, sizeof(buffer_info)) < B_OK)
682 		return B_BAD_ADDRESS;
683 #else
684 	memcpy(data, &buffer_info, sizeof(buffer_info));
685 #endif
686 
687 	//TRACE(("buffer_exchange ended\n"));
688 	return B_OK;
689 }
690 
691 static status_t
692 es1370_buffer_force_stop(es1370_dev *card)
693 {
694 	//es1370_voice_halt(card->pvoice);
695 	return B_OK;
696 }
697 
698 static status_t
699 es1370_multi_control(void *cookie, uint32 op, void *data, size_t length)
700 {
701 	es1370_dev *card = (es1370_dev *)cookie;
702 
703     switch (op) {
704 		case B_MULTI_GET_DESCRIPTION:
705 			LOG(("B_MULTI_GET_DESCRIPTION\n"));
706 			return es1370_get_description(card, (multi_description *)data);
707 		case B_MULTI_GET_EVENT_INFO:
708 			LOG(("B_MULTI_GET_EVENT_INFO\n"));
709 			return B_ERROR;
710 		case B_MULTI_SET_EVENT_INFO:
711 			LOG(("B_MULTI_SET_EVENT_INFO\n"));
712 			return B_ERROR;
713 		case B_MULTI_GET_EVENT:
714 			LOG(("B_MULTI_GET_EVENT\n"));
715 			return B_ERROR;
716 		case B_MULTI_GET_ENABLED_CHANNELS:
717 			LOG(("B_MULTI_GET_ENABLED_CHANNELS\n"));
718 			return es1370_get_enabled_channels(card, (multi_channel_enable *)data);
719 		case B_MULTI_SET_ENABLED_CHANNELS:
720 			LOG(("B_MULTI_SET_ENABLED_CHANNELS\n"));
721 			return es1370_set_enabled_channels(card, (multi_channel_enable *)data);
722 		case B_MULTI_GET_GLOBAL_FORMAT:
723 			LOG(("B_MULTI_GET_GLOBAL_FORMAT\n"));
724 			return es1370_get_global_format(card, (multi_format_info *)data);
725 		case B_MULTI_SET_GLOBAL_FORMAT:
726 			LOG(("B_MULTI_SET_GLOBAL_FORMAT\n"));
727 			return B_OK; /* XXX BUG! we *MUST* return B_OK, returning B_ERROR will prevent
728 						  * BeOS to accept the format returned in B_MULTI_GET_GLOBAL_FORMAT
729 						  */
730 		case B_MULTI_GET_CHANNEL_FORMATS:
731 			LOG(("B_MULTI_GET_CHANNEL_FORMATS\n"));
732 			return B_ERROR;
733 		case B_MULTI_SET_CHANNEL_FORMATS:	/* only implemented if possible */
734 			LOG(("B_MULTI_SET_CHANNEL_FORMATS\n"));
735 			return B_ERROR;
736 		case B_MULTI_GET_MIX:
737 			LOG(("B_MULTI_GET_MIX\n"));
738 			return es1370_get_mix(card, (multi_mix_value_info *)data);
739 		case B_MULTI_SET_MIX:
740 			LOG(("B_MULTI_SET_MIX\n"));
741 			return es1370_set_mix(card, (multi_mix_value_info *)data);
742 		case B_MULTI_LIST_MIX_CHANNELS:
743 			LOG(("B_MULTI_LIST_MIX_CHANNELS\n"));
744 			return es1370_list_mix_channels(card, (multi_mix_channel_info *)data);
745 		case B_MULTI_LIST_MIX_CONTROLS:
746 			LOG(("B_MULTI_LIST_MIX_CONTROLS\n"));
747 			return es1370_list_mix_controls(card, (multi_mix_control_info *)data);
748 		case B_MULTI_LIST_MIX_CONNECTIONS:
749 			LOG(("B_MULTI_LIST_MIX_CONNECTIONS\n"));
750 			return es1370_list_mix_connections(card, (multi_mix_connection_info *)data);
751 		case B_MULTI_GET_BUFFERS:			/* Fill out the struct for the first time; doesn't start anything. */
752 			LOG(("B_MULTI_GET_BUFFERS\n"));
753 			return es1370_get_buffers(card, data);
754 		case B_MULTI_SET_BUFFERS:			/* Set what buffers to use, if the driver supports soft buffers. */
755 			LOG(("B_MULTI_SET_BUFFERS\n"));
756 			return B_ERROR; /* we do not support soft buffers */
757 		case B_MULTI_SET_START_TIME:			/* When to actually start */
758 			LOG(("B_MULTI_SET_START_TIME\n"));
759 			return B_ERROR;
760 		case B_MULTI_BUFFER_EXCHANGE:		/* stop and go are derived from this being called */
761 			//TRACE(("B_MULTI_BUFFER_EXCHANGE\n"));
762 			return es1370_buffer_exchange(card, (multi_buffer_info *)data);
763 		case B_MULTI_BUFFER_FORCE_STOP:		/* force stop of playback, nothing in data */
764 			LOG(("B_MULTI_BUFFER_FORCE_STOP\n"));
765 			return es1370_buffer_force_stop(card);
766 	}
767 	LOG(("ERROR: unknown multi_control %#x\n",op));
768 	return B_ERROR;
769 }
770 
771 static status_t es1370_open(const char *name, uint32 flags, void** cookie);
772 static status_t es1370_close(void* cookie);
773 static status_t es1370_free(void* cookie);
774 static status_t es1370_control(void* cookie, uint32 op, void* arg, size_t len);
775 static status_t es1370_read(void* cookie, off_t position, void *buf, size_t* num_bytes);
776 static status_t es1370_write(void* cookie, off_t position, const void* buffer, size_t* num_bytes);
777 
778 device_hooks multi_hooks = {
779 	es1370_open, 			/* -> open entry point */
780 	es1370_close, 			/* -> close entry point */
781 	es1370_free,			/* -> free cookie */
782 	es1370_control, 		/* -> control entry point */
783 	es1370_read,			/* -> read entry point */
784 	es1370_write,			/* -> write entry point */
785 	NULL,					/* start select */
786 	NULL,					/* stop select */
787 	NULL,					/* scatter-gather read from the device */
788 	NULL					/* scatter-gather write to the device */
789 };
790 
791 static status_t
792 es1370_open(const char *name, uint32 flags, void** cookie)
793 {
794 	es1370_dev *card = NULL;
795 	void *settings_handle;
796 	int ix;
797 
798 	LOG(("open()\n"));
799 
800 	for (ix=0; ix<num_cards; ix++) {
801 		if (!strcmp(cards[ix].name, name)) {
802 			card = &cards[ix];
803 		}
804 	}
805 
806 	if (card == NULL) {
807 		LOG(("open() card not found %s\n", name));
808 		for (ix=0; ix<num_cards; ix++) {
809 			LOG(("open() card available %s\n", cards[ix].name));
810 		}
811 		return B_ERROR;
812 	}
813 
814 	LOG(("open() got card\n"));
815 
816 	if (card->pstream !=NULL)
817 		return B_ERROR;
818 	if (card->rstream !=NULL)
819 		return B_ERROR;
820 
821 	*cookie = card;
822 	card->multi.card = card;
823 
824 	// get driver settings
825 	settings_handle = load_driver_settings(ES1370_SETTINGS);
826 	if (settings_handle != NULL) {
827 		const char *item;
828 		char       *end;
829 		uint32      value;
830 
831 		item = get_driver_parameter (settings_handle, "sample_rate", "44100", "44100");
832 		value = strtoul (item, &end, 0);
833 		if (*end == '\0')
834 			current_settings.sample_rate = value;
835 
836 		item = get_driver_parameter (settings_handle, "buffer_frames", "512", "512");
837 		value = strtoul (item, &end, 0);
838 		if (*end == '\0')
839 			current_settings.buffer_frames = value;
840 
841 		item = get_driver_parameter (settings_handle, "buffer_count", "2", "2");
842 		value = strtoul (item, &end, 0);
843 		if (*end == '\0')
844 			current_settings.buffer_count = value;
845 
846 		unload_driver_settings(settings_handle);
847 	}
848 
849 	LOG(("stream_new\n"));
850 
851 	card->rstream = es1370_stream_new(card, ES1370_USE_RECORD, current_settings.buffer_frames, current_settings.buffer_count);
852 	card->pstream = es1370_stream_new(card, ES1370_USE_PLAY, current_settings.buffer_frames, current_settings.buffer_count);
853 
854 	card->buffer_ready_sem = create_sem(0, "pbuffer ready");
855 
856 	LOG(("stream_setaudio\n"));
857 
858 	es1370_stream_set_audioparms(card->pstream, 2, true, current_settings.sample_rate);
859 	es1370_stream_set_audioparms(card->rstream, 2, true, current_settings.sample_rate);
860 
861 	card->pstream->first_channel = 0;
862 	card->rstream->first_channel = 2;
863 
864 	es1370_stream_commit_parms(card->pstream);
865 	es1370_stream_commit_parms(card->rstream);
866 
867 	es1370_create_channels_list(&card->multi);
868 
869 	return B_OK;
870 }
871 
872 static status_t
873 es1370_close(void* cookie)
874 {
875 	//es1370_dev *card = cookie;
876 	LOG(("close()\n"));
877 
878 	return B_OK;
879 }
880 
881 static status_t
882 es1370_free(void* cookie)
883 {
884 	es1370_dev *card = cookie;
885 	es1370_stream *stream;
886 	LOG(("free()\n"));
887 
888 	if (card->buffer_ready_sem > B_OK)
889 		delete_sem(card->buffer_ready_sem);
890 
891 	LIST_FOREACH(stream, &card->streams, next) {
892 		es1370_stream_halt(stream);
893 	}
894 
895 	while (!LIST_EMPTY(&card->streams)) {
896 		es1370_stream_delete(LIST_FIRST(&card->streams));
897 	}
898 
899 	card->pstream = NULL;
900 	card->rstream = NULL;
901 
902 	return B_OK;
903 }
904 
905 static status_t
906 es1370_control(void* cookie, uint32 op, void* arg, size_t len)
907 {
908 	return es1370_multi_control(cookie, op, arg, len);
909 }
910 
911 static status_t
912 es1370_read(void* cookie, off_t position, void *buf, size_t* num_bytes)
913 {
914 	*num_bytes = 0;				/* tell caller nothing was read */
915 	return B_IO_ERROR;
916 }
917 
918 static status_t
919 es1370_write(void* cookie, off_t position, const void* buffer, size_t* num_bytes)
920 {
921 	*num_bytes = 0;				/* tell caller nothing was written */
922 	return B_IO_ERROR;
923 }
924 
925