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