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