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