xref: /haiku/src/add-ons/kernel/drivers/audio/hda/hda_controller.cpp (revision 746cac055adc6ac3308c7bc2d29040fb95689cc9)
1 /*
2  * Copyright 2007-2008, Haiku, Inc. All Rights Reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Ithamar Adema, ithamar AT unet DOT nl
7  *		Axel Dörfler, axeld@pinc-software.de
8  */
9 
10 
11 #include "driver.h"
12 #include "hda_controller_defs.h"
13 #include "hda_codec_defs.h"
14 
15 
16 #define MAKE_RATE(base, multiply, divide) \
17 	((base == 44100 ? FORMAT_44_1_BASE_RATE : 0) \
18 		| ((multiply - 1) << FORMAT_MULTIPLY_RATE_SHIFT) \
19 		| ((divide - 1) << FORMAT_DIVIDE_RATE_SHIFT))
20 
21 #define HDAC_INPUT_STREAM_OFFSET(controller, index) \
22 	((index) * HDAC_STREAM_SIZE)
23 #define HDAC_OUTPUT_STREAM_OFFSET(controller, index) \
24 	(((controller)->num_input_streams + (index)) * HDAC_STREAM_SIZE)
25 #define HDAC_BIDIR_STREAM_OFFSET(controller, index) \
26 	(((controller)->num_input_streams + (controller)->num_output_streams \
27 		+ (index)) * HDAC_STREAM_SIZE)
28 
29 #define ALIGN(size, align)		(((size) + align - 1) & ~(align - 1))
30 #define PAGE_ALIGN(size)	(((size) + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1))
31 
32 static const struct {
33 	uint32 multi_rate;
34 	uint32 hw_rate;
35 	uint32 rate;
36 } kRates[] = {
37 	{B_SR_8000, MAKE_RATE(48000, 1, 6), 8000},
38 	{B_SR_11025, MAKE_RATE(44100, 1, 4), 11025},
39 	{B_SR_16000, MAKE_RATE(48000, 1, 3), 16000},
40 	{B_SR_22050, MAKE_RATE(44100, 1, 2), 22050},
41 	{B_SR_32000, MAKE_RATE(48000, 2, 3), 32000},
42 	{B_SR_44100, MAKE_RATE(44100, 1, 1), 44100},
43 	{B_SR_48000, MAKE_RATE(48000, 1, 1), 48000},
44 	{B_SR_88200, MAKE_RATE(44100, 2, 1), 88200},
45 	{B_SR_96000, MAKE_RATE(48000, 2, 1), 96000},
46 	{B_SR_176400, MAKE_RATE(44100, 4, 1), 176400},
47 	{B_SR_192000, MAKE_RATE(48000, 4, 1), 192000},
48 };
49 
50 
51 static inline rirb_t&
52 current_rirb(hda_controller *controller)
53 {
54 	return controller->rirb[controller->rirb_read_pos];
55 }
56 
57 
58 static inline uint32
59 next_rirb(hda_controller *controller)
60 {
61 	return (controller->rirb_read_pos + 1) % controller->rirb_length;
62 }
63 
64 
65 static inline uint32
66 next_corb(hda_controller *controller)
67 {
68 	return (controller->corb_write_pos + 1) % controller->corb_length;
69 }
70 
71 
72 //! Called with interrupts off
73 static void
74 stream_handle_interrupt(hda_controller* controller, hda_stream* stream)
75 {
76 	uint8 status;
77 	uint32 position, bufferSize;
78 
79 	if (!stream->running)
80 		return;
81 
82 	status = stream->Read8(HDAC_STREAM_STATUS);
83 	if (status == 0)
84 		return;
85 
86 	stream->Write8(HDAC_STREAM_STATUS, status);
87 
88 	if ((status & STATUS_BUFFER_COMPLETED) == 0) {
89 		dprintf("hda: stream status %x\n", status);
90 		return;
91 	}
92 
93 	position = stream->Read32(HDAC_STREAM_POSITION);
94 	bufferSize = ALIGN(stream->sample_size * stream->num_channels * stream->buffer_length, 128);
95 
96 	// Buffer Completed Interrupt
97 	acquire_spinlock(&stream->lock);
98 
99 	stream->real_time = system_time();
100 	stream->frames_count += stream->buffer_length;
101 	stream->buffer_cycle = 1 - (position / (bufferSize + 1)); // added 1 to avoid having 2
102 
103 	release_spinlock(&stream->lock);
104 
105 	release_sem_etc(stream->buffer_ready_sem, 1, B_DO_NOT_RESCHEDULE);
106 }
107 
108 
109 static int32
110 hda_interrupt_handler(hda_controller* controller)
111 {
112 	int32 handled = B_HANDLED_INTERRUPT;
113 
114 	/* Check if this interrupt is ours */
115 	uint32 intrStatus = controller->Read32(HDAC_INTR_STATUS);
116 	if ((intrStatus & INTR_STATUS_GLOBAL) == 0)
117 		return B_UNHANDLED_INTERRUPT;
118 
119 	/* Controller or stream related? */
120 	if (intrStatus & INTR_STATUS_CONTROLLER) {
121 		uint8 rirbStatus = controller->Read8(HDAC_RIRB_STATUS);
122 		uint8 corbStatus = controller->Read8(HDAC_CORB_STATUS);
123 
124 		/* Check for incoming responses */
125 		if (rirbStatus) {
126 			controller->Write8(HDAC_RIRB_STATUS, rirbStatus);
127 
128 			if ((rirbStatus & RIRB_STATUS_RESPONSE) != 0) {
129 				uint16 writePos = (controller->Read16(HDAC_RIRB_WRITE_POS) + 1)
130 					% controller->rirb_length;
131 
132 				for (; controller->rirb_read_pos != writePos;
133 						controller->rirb_read_pos = next_rirb(controller)) {
134 					uint32 response = current_rirb(controller).response;
135 					uint32 responseFlags = current_rirb(controller).flags;
136 					uint32 cad = responseFlags & RESPONSE_FLAGS_CODEC_MASK;
137 					hda_codec* codec = controller->codecs[cad];
138 
139 					if ((responseFlags & RESPONSE_FLAGS_UNSOLICITED) != 0) {
140 						dprintf("hda: Unsolicited response: %08lx/%08lx\n",
141 							response, responseFlags);
142 						continue;
143 					}
144 					if (codec == NULL) {
145 						dprintf("hda: Response for unknown codec %ld: "
146 							"%08lx/%08lx\n", cad, response, responseFlags);
147 						continue;
148 					}
149 					if (codec->response_count >= MAX_CODEC_RESPONSES) {
150 						dprintf("hda: too many responses received for codec %ld"
151 							": %08lx/%08lx!\n", cad, response, responseFlags);
152 						continue;
153 					}
154 
155 					/* Store response in codec */
156 					codec->responses[codec->response_count++] = response;
157 					release_sem_etc(codec->response_sem, 1, B_DO_NOT_RESCHEDULE);
158 					handled = B_INVOKE_SCHEDULER;
159 				}
160 			}
161 
162 			if ((rirbStatus & RIRB_STATUS_OVERRUN) != 0)
163 				dprintf("hda: RIRB Overflow\n");
164 		}
165 
166 		/* Check for sending errors */
167 		if (corbStatus) {
168 			controller->Write8(HDAC_CORB_STATUS, corbStatus);
169 
170 			if ((corbStatus & CORB_STATUS_MEMORY_ERROR) != 0)
171 				dprintf("hda: CORB Memory Error!\n");
172 		}
173 	}
174 
175 	if ((intrStatus & INTR_STATUS_STREAM_MASK) != 0) {
176 		for (uint32 index = 0; index < HDA_MAX_STREAMS; index++) {
177 			if ((intrStatus & (1 << index)) != 0) {
178 				if (controller->streams[index]) {
179 					stream_handle_interrupt(controller,
180 						controller->streams[index]);
181 				} else {
182 					dprintf("hda: Stream interrupt for unconfigured stream "
183 						"%ld!\n", index);
184 				}
185 			}
186 		}
187 	}
188 
189 	/* NOTE: See HDA001 => CIS/GIS cannot be cleared! */
190 
191 	return handled;
192 }
193 
194 
195 static status_t
196 reset_controller(hda_controller* controller)
197 {
198 	// stop streams
199 
200 	for (uint32 i = 0; i < controller->num_input_streams; i++) {
201 		controller->Write8(HDAC_STREAM_CONTROL0 + HDAC_STREAM_BASE
202 			+ HDAC_INPUT_STREAM_OFFSET(controller, i), 0);
203 		controller->Write8(HDAC_STREAM_STATUS + HDAC_STREAM_BASE
204 			+ HDAC_INPUT_STREAM_OFFSET(controller, i), 0);
205 	}
206 	for (uint32 i = 0; i < controller->num_output_streams; i++) {
207 		controller->Write8(HDAC_STREAM_CONTROL0 + HDAC_STREAM_BASE
208 			+ HDAC_OUTPUT_STREAM_OFFSET(controller, i), 0);
209 		controller->Write8(HDAC_STREAM_STATUS + HDAC_STREAM_BASE
210 			+ HDAC_OUTPUT_STREAM_OFFSET(controller, i), 0);
211 	}
212 	for (uint32 i = 0; i < controller->num_bidir_streams; i++) {
213 		controller->Write8(HDAC_STREAM_CONTROL0 + HDAC_STREAM_BASE
214 			+ HDAC_BIDIR_STREAM_OFFSET(controller, i), 0);
215 		controller->Write8(HDAC_STREAM_STATUS + HDAC_STREAM_BASE
216 			+ HDAC_BIDIR_STREAM_OFFSET(controller, i), 0);
217 	}
218 
219 	// stop DMA
220 	controller->Write8(HDAC_CORB_CONTROL, 0);
221 	controller->Write8(HDAC_RIRB_CONTROL, 0);
222 
223 	// reset DMA position buffer
224 	controller->Write32(HDAC_DMA_POSITION_BASE_LOWER, 0);
225 	controller->Write32(HDAC_DMA_POSITION_BASE_UPPER, 0);
226 
227 	// Set reset bit - it must be asserted for at least 100us
228 
229 	uint32 control = controller->Read32(HDAC_GLOBAL_CONTROL);
230 	controller->Write32(HDAC_GLOBAL_CONTROL, control & ~GLOBAL_CONTROL_RESET);
231 
232 	for (int timeout = 0; timeout < 10; timeout++) {
233 		snooze(100);
234 
235 		control = controller->Read32(HDAC_GLOBAL_CONTROL);
236 		if ((control & GLOBAL_CONTROL_RESET) == 0)
237 			break;
238 	}
239 	if ((control & GLOBAL_CONTROL_RESET) != 0) {
240 		dprintf("hda: unable to reset controller\n");
241 		return B_BUSY;
242 	}
243 
244 	// Unset reset bit
245 
246 	control = controller->Read32(HDAC_GLOBAL_CONTROL);
247 	controller->Write32(HDAC_GLOBAL_CONTROL, control | GLOBAL_CONTROL_RESET);
248 
249 	for (int timeout = 0; timeout < 10; timeout++) {
250 		snooze(100);
251 
252 		control = controller->Read32(HDAC_GLOBAL_CONTROL);
253 		if ((control & GLOBAL_CONTROL_RESET) != 0)
254 			break;
255 	}
256 	if ((control & GLOBAL_CONTROL_RESET) == 0) {
257 		dprintf("hda: unable to exit reset\n");
258 		return B_BUSY;
259 	}
260 
261 	// Wait for codecs to finish their own reset (apparently needs more
262 	// time than documented in the specs)
263 	snooze(1000);
264 	return B_OK;
265 }
266 
267 
268 /*! Allocates and initializes the Command Output Ring Buffer (CORB), and
269 	Response Input Ring Buffer (RIRB) to the maximum supported size, and also
270 	the DMA position buffer.
271 
272 	Programs the controller hardware to make use of these buffers (the DMA
273 	positioning is actually enabled in hda_stream_setup_buffers()).
274 */
275 static status_t
276 init_corb_rirb_pos(hda_controller* controller)
277 {
278 	uint32 memSize, rirbOffset, posOffset;
279 	uint8 corbSize, rirbSize, posSize;
280 	status_t rc = B_OK;
281 	physical_entry pe;
282 
283 	/* Determine and set size of CORB */
284 	corbSize = controller->Read8(HDAC_CORB_SIZE);
285 	if ((corbSize & CORB_SIZE_CAP_256_ENTRIES) != 0) {
286 		controller->corb_length = 256;
287 		controller->Write8(HDAC_CORB_SIZE, CORB_SIZE_256_ENTRIES);
288 	} else if (corbSize & CORB_SIZE_CAP_16_ENTRIES) {
289 		controller->corb_length = 16;
290 		controller->Write8(HDAC_CORB_SIZE, CORB_SIZE_16_ENTRIES);
291 	} else if (corbSize & CORB_SIZE_CAP_2_ENTRIES) {
292 		controller->corb_length = 2;
293 		controller->Write8(HDAC_CORB_SIZE, CORB_SIZE_2_ENTRIES);
294 	}
295 
296 	/* Determine and set size of RIRB */
297 	rirbSize = controller->Read8(HDAC_RIRB_SIZE);
298 	if (rirbSize & RIRB_SIZE_CAP_256_ENTRIES) {
299 		controller->rirb_length = 256;
300 		controller->Write8(HDAC_RIRB_SIZE, RIRB_SIZE_256_ENTRIES);
301 	} else if (rirbSize & RIRB_SIZE_CAP_16_ENTRIES) {
302 		controller->rirb_length = 16;
303 		controller->Write8(HDAC_RIRB_SIZE, RIRB_SIZE_16_ENTRIES);
304 	} else if (rirbSize & RIRB_SIZE_CAP_2_ENTRIES) {
305 		controller->rirb_length = 2;
306 		controller->Write8(HDAC_RIRB_SIZE, RIRB_SIZE_2_ENTRIES);
307 	}
308 
309 	/* Determine rirb offset in memory and total size of corb+alignment+rirb */
310 	rirbOffset = ALIGN(controller->corb_length * sizeof(corb_t), 128);
311 	posOffset = ALIGN(rirbOffset + controller->rirb_length * sizeof(rirb_t), 128);
312 	posSize = 8 * (controller->num_input_streams
313 		+ controller->num_output_streams + controller->num_bidir_streams);
314 
315 	memSize = PAGE_ALIGN(posOffset + posSize);
316 
317 	/* Allocate memory area */
318 	controller->corb_rirb_pos_area = create_area("hda corb/rirb/pos",
319 		(void**)&controller->corb, B_ANY_KERNEL_ADDRESS, memSize,
320 		B_CONTIGUOUS, 0);
321 	if (controller->corb_rirb_pos_area < 0)
322 		return controller->corb_rirb_pos_area;
323 
324 	/* Rirb is after corb+aligment */
325 	controller->rirb = (rirb_t*)(((uint8*)controller->corb) + rirbOffset);
326 
327 	if ((rc = get_memory_map(controller->corb, memSize, &pe, 1)) != B_OK) {
328 		delete_area(controller->corb_rirb_pos_area);
329 		return rc;
330 	}
331 
332 	/* Program CORB/RIRB for these locations */
333 	controller->Write32(HDAC_CORB_BASE_LOWER, (uint32)pe.address);
334 	controller->Write32(HDAC_CORB_BASE_UPPER, 0);
335 	controller->Write32(HDAC_RIRB_BASE_LOWER, (uint32)pe.address + rirbOffset);
336 	controller->Write32(HDAC_RIRB_BASE_UPPER, 0);
337 
338 	/* Program DMA position update */
339 	controller->Write32(HDAC_DMA_POSITION_BASE_LOWER,
340 		(uint32)pe.address + posOffset);
341 	controller->Write32(HDAC_DMA_POSITION_BASE_UPPER, 0);
342 
343 	controller->stream_positions = (uint32*)
344 		((uint8*)controller->corb + posOffset);
345 
346 	/* Reset CORB read pointer */
347 	/* NOTE: See HDA011 for corrected procedure! */
348 	controller->Write16(HDAC_CORB_READ_POS, CORB_READ_POS_RESET);
349 	do {
350 		spin(10);
351 	} while ((controller->Read16(HDAC_CORB_READ_POS)
352 		& CORB_READ_POS_RESET) == 0);
353 	controller->Write16(HDAC_CORB_READ_POS, 0);
354 
355 	/* Reset RIRB write pointer */
356 	controller->Write16(HDAC_RIRB_WRITE_POS, RIRB_WRITE_POS_RESET);
357 
358 	/* Generate interrupt for every response */
359 	controller->Write16(HDAC_RESPONSE_INTR_COUNT, 1);
360 
361 	/* Setup cached read/write indices */
362 	controller->rirb_read_pos = 1;
363 	controller->corb_write_pos = 0;
364 
365 	/* Gentlemen, start your engines... */
366 	controller->Write8(HDAC_CORB_CONTROL,
367 		CORB_CONTROL_RUN | CORB_CONTROL_MEMORY_ERROR_INTR);
368 	controller->Write8(HDAC_RIRB_CONTROL, RIRB_CONTROL_DMA_ENABLE
369 		| RIRB_CONTROL_OVERRUN_INTR | RIRB_CONTROL_RESPONSE_INTR);
370 
371 	return B_OK;
372 }
373 
374 
375 //	#pragma mark - public stream functions
376 
377 
378 void
379 hda_stream_delete(hda_stream* stream)
380 {
381 	if (stream->buffer_ready_sem >= B_OK)
382 		delete_sem(stream->buffer_ready_sem);
383 
384 	if (stream->buffer_area >= B_OK)
385 		delete_area(stream->buffer_area);
386 
387 	if (stream->buffer_descriptors_area >= B_OK)
388 		delete_area(stream->buffer_descriptors_area);
389 
390 	free(stream);
391 }
392 
393 
394 hda_stream*
395 hda_stream_new(hda_audio_group* audioGroup, int type)
396 {
397 	hda_controller* controller = audioGroup->codec->controller;
398 
399 	hda_stream* stream = (hda_stream*)calloc(1, sizeof(hda_stream));
400 	if (stream == NULL)
401 		return NULL;
402 
403 	stream->buffer_ready_sem = B_ERROR;
404 	stream->buffer_area = B_ERROR;
405 	stream->buffer_descriptors_area = B_ERROR;
406 	stream->type = type;
407 	stream->controller = controller;
408 
409 	switch (type) {
410 		case STREAM_PLAYBACK:
411 			stream->id = 1;
412 			stream->offset = HDAC_OUTPUT_STREAM_OFFSET(controller, 0);
413 			break;
414 
415 		case STREAM_RECORD:
416 			stream->id = 2;
417 			stream->offset = HDAC_INPUT_STREAM_OFFSET(controller, 0);
418 			break;
419 
420 		default:
421 			dprintf("%s: Unknown stream type %d!\n", __func__, type);
422 			free(stream);
423 			stream = NULL;
424 	}
425 
426 	// find I/O and Pin widgets for this stream
427 
428 	if (hda_audio_group_get_widgets(audioGroup, stream) == B_OK) {
429 		switch (type) {
430 			case STREAM_PLAYBACK:
431 				controller->streams[controller->num_input_streams] = stream;
432 				break;
433 			case STREAM_RECORD:
434 				controller->streams[0] = stream;
435 				break;
436 		}
437 
438 		return stream;
439 	}
440 
441 	dprintf("hda: hda_audio_group_get_widgets failed\n");
442 
443 	free(stream);
444 	return NULL;
445 }
446 
447 
448 /*!	Starts a stream's DMA engine, and enables generating and receiving
449 	interrupts for this stream.
450 */
451 status_t
452 hda_stream_start(hda_controller* controller, hda_stream* stream)
453 {
454 	dprintf("hda_stream_start() offset %lx\n", stream->offset);
455 	stream->buffer_ready_sem = create_sem(0, stream->type == STREAM_PLAYBACK
456 		? "hda_playback_sem" : "hda_record_sem");
457 	if (stream->buffer_ready_sem < B_OK)
458 		return stream->buffer_ready_sem;
459 
460 	controller->Write32(HDAC_INTR_CONTROL, controller->Read32(HDAC_INTR_CONTROL)
461 		| (1 << (stream->offset / HDAC_STREAM_SIZE)));
462 	stream->Write8(HDAC_STREAM_CONTROL0, stream->Read8(HDAC_STREAM_CONTROL0)
463 		| CONTROL0_BUFFER_COMPLETED_INTR | CONTROL0_FIFO_ERROR_INTR
464 		| CONTROL0_DESCRIPTOR_ERROR_INTR | CONTROL0_RUN);
465 
466 	stream->running = true;
467 	return B_OK;
468 }
469 
470 
471 /*!	Stops the stream's DMA engine, and turns off interrupts for this
472 	stream.
473 */
474 status_t
475 hda_stream_stop(hda_controller* controller, hda_stream* stream)
476 {
477 	dprintf("hda_stream_stop()\n");
478 	stream->Write8(HDAC_STREAM_CONTROL0, stream->Read8(HDAC_STREAM_CONTROL0)
479 		& ~(CONTROL0_BUFFER_COMPLETED_INTR | CONTROL0_FIFO_ERROR_INTR
480 			| CONTROL0_DESCRIPTOR_ERROR_INTR | CONTROL0_RUN));
481 	controller->Write32(HDAC_INTR_CONTROL, controller->Read32(HDAC_INTR_CONTROL)
482 		& ~(1 << (stream->offset / HDAC_STREAM_SIZE)));
483 
484 	stream->running = false;
485 	delete_sem(stream->buffer_ready_sem);
486 	stream->buffer_ready_sem = -1;
487 
488 	return B_OK;
489 }
490 
491 
492 status_t
493 hda_stream_setup_buffers(hda_audio_group* audioGroup, hda_stream* stream,
494 	const char* desc)
495 {
496 	uint32 bufferSize, bufferPhysicalAddress, alloc;
497 	uint32 response[2], index;
498 	physical_entry pe;
499 	bdl_entry_t* bufferDescriptors;
500 	corb_t verb[2];
501 	uint8* buffer;
502 	status_t rc;
503 	uint16 format;
504 
505 	/* Clear previously allocated memory */
506 	if (stream->buffer_area >= B_OK) {
507 		delete_area(stream->buffer_area);
508 		stream->buffer_area = B_ERROR;
509 	}
510 
511 	if (stream->buffer_descriptors_area >= B_OK) {
512 		delete_area(stream->buffer_descriptors_area);
513 		stream->buffer_descriptors_area = B_ERROR;
514 	}
515 
516 	/* Calculate size of buffer (aligned to 128 bytes) */
517 	bufferSize = stream->sample_size * stream->num_channels
518 		* stream->buffer_length;
519 	bufferSize = ALIGN(bufferSize, 128);
520 
521 	dprintf("HDA: sample size %ld, num channels %ld, buffer length %ld ****************\n",
522 		stream->sample_size, stream->num_channels, stream->buffer_length);
523 
524 	/* Calculate total size of all buffers (aligned to size of B_PAGE_SIZE) */
525 	alloc = bufferSize * stream->num_buffers;
526 	alloc = PAGE_ALIGN(alloc);
527 
528 	/* Allocate memory for buffers */
529 	stream->buffer_area = create_area("hda buffers", (void**)&buffer,
530 		B_ANY_KERNEL_ADDRESS, alloc, B_CONTIGUOUS, B_READ_AREA | B_WRITE_AREA);
531 	if (stream->buffer_area < B_OK)
532 		return stream->buffer_area;
533 
534 	/* Get the physical address of memory */
535 	rc = get_memory_map(buffer, alloc, &pe, 1);
536 	if (rc != B_OK) {
537 		delete_area(stream->buffer_area);
538 		return rc;
539 	}
540 
541 	bufferPhysicalAddress = (uint32)pe.address;
542 
543 	dprintf("%s(%s): Allocated %lu bytes for %ld buffers\n", __func__, desc,
544 		alloc, stream->num_buffers);
545 
546 	/* Store pointers (both virtual/physical) */
547 	for (index = 0; index < stream->num_buffers; index++) {
548 		stream->buffers[index] = buffer + (index * bufferSize);
549 		stream->physical_buffers[index] = bufferPhysicalAddress
550 			+ (index * bufferSize);
551 	}
552 
553 	/* Now allocate BDL for buffer range */
554 	alloc = stream->num_buffers * sizeof(bdl_entry_t);
555 	alloc = PAGE_ALIGN(alloc);
556 
557 	stream->buffer_descriptors_area = create_area("hda buffer descriptors",
558 		(void**)&bufferDescriptors, B_ANY_KERNEL_ADDRESS, alloc,
559 		B_CONTIGUOUS, 0);
560 	if (stream->buffer_descriptors_area < B_OK) {
561 		delete_area(stream->buffer_area);
562 		return stream->buffer_descriptors_area;
563 	}
564 
565 	/* Get the physical address of memory */
566 	rc = get_memory_map(bufferDescriptors, alloc, &pe, 1);
567 	if (rc != B_OK) {
568 		delete_area(stream->buffer_area);
569 		delete_area(stream->buffer_descriptors_area);
570 		return rc;
571 	}
572 
573 	stream->physical_buffer_descriptors = (uint32)pe.address;
574 
575 	dprintf("%s(%s): Allocated %ld bytes for %ld BDLEs\n", __func__, desc,
576 		alloc, stream->num_buffers);
577 
578 	/* Setup buffer descriptor list (BDL) entries */
579 	for (index = 0; index < stream->num_buffers; index++, bufferDescriptors++) {
580 		bufferDescriptors->lower = stream->physical_buffers[index];
581 		bufferDescriptors->upper = 0;
582 		bufferDescriptors->length = bufferSize;
583 		bufferDescriptors->ioc = 1;
584 			// we want an interrupt after every buffer
585 	}
586 
587 	/* Configure stream registers */
588 	format = (stream->num_channels - 1) & 0xf;
589 	switch (stream->sample_format) {
590 		case B_FMT_8BIT_S:	format |= FORMAT_8BIT; stream->bps = 8; break;
591 		case B_FMT_16BIT:	format |= FORMAT_16BIT; stream->bps = 16; break;
592 		case B_FMT_20BIT:	format |= FORMAT_20BIT; stream->bps = 20; break;
593 		case B_FMT_24BIT:	format |= FORMAT_24BIT; stream->bps = 24; break;
594 		case B_FMT_32BIT:	format |= FORMAT_32BIT; stream->bps = 32; break;
595 
596 		default:
597 			dprintf("hda: Invalid sample format: 0x%lx\n",
598 				stream->sample_format);
599 			break;
600 	}
601 
602 	for (index = 0; index < sizeof(kRates) / sizeof(kRates[0]); index++) {
603 		if (kRates[index].multi_rate == stream->sample_rate) {
604 			format |= kRates[index].hw_rate;
605 			stream->rate = kRates[index].rate;
606 			break;
607 		}
608 	}
609 
610 	dprintf("IRA: %s: setup stream %ld: SR=%ld, SF=%ld\n", __func__, stream->id,
611 		stream->rate, stream->bps);
612 
613 	stream->Write16(HDAC_STREAM_FORMAT, format);
614 	stream->Write32(HDAC_STREAM_BUFFERS_BASE_LOWER,
615 		stream->physical_buffer_descriptors);
616 	stream->Write32(HDAC_STREAM_BUFFERS_BASE_UPPER, 0);
617 	stream->Write16(HDAC_STREAM_LAST_VALID, stream->num_buffers - 1);
618 	/* total cyclic buffer size in _bytes_ */
619 	stream->Write32(HDAC_STREAM_BUFFER_SIZE, bufferSize
620 		* stream->num_buffers);
621 	stream->Write8(HDAC_STREAM_CONTROL2, stream->id << CONTROL2_STREAM_SHIFT);
622 
623 	stream->controller->Write32(HDAC_DMA_POSITION_BASE_LOWER,
624 		stream->controller->Read32(HDAC_DMA_POSITION_BASE_LOWER)
625 		| DMA_POSITION_ENABLED);
626 
627 	dprintf("hda: stream: %ld num_io_widgets: %ld\n", stream->id, stream->num_io_widgets);
628 	dprintf("hda: widgets: ");
629 
630 	hda_codec* codec = audioGroup->codec;
631 	uint32 channelNum = 0;
632 	for (uint32 i = 0; i < stream->num_io_widgets; i++) {
633 		verb[0] = MAKE_VERB(codec->addr, stream->io_widgets[i],
634 			VID_SET_CONVERTER_FORMAT, format);
635 		uint32 val = stream->id << 4;
636 		if (stream->type == STREAM_RECORD) {
637 			if (channelNum < stream->num_channels)
638 				val |= channelNum;
639 			else
640 				val = 0;
641 		}
642 		verb[1] = MAKE_VERB(codec->addr, stream->io_widgets[i],
643 			VID_SET_CONVERTER_STREAM_CHANNEL, val);
644 		hda_send_verbs(codec, verb, response, 2);
645 		channelNum += 2; // TODO stereo widget ?
646 		dprintf("%ld ", stream->io_widgets[i]);
647 	}
648 	dprintf("\n");
649 
650 	snooze(1000);
651 	return B_OK;
652 }
653 
654 
655 //	#pragma mark - public controller functions
656 
657 
658 status_t
659 hda_send_verbs(hda_codec* codec, corb_t* verbs, uint32* responses, uint32 count)
660 {
661 	hda_controller *controller = codec->controller;
662 	uint32 sent = 0;
663 
664 	codec->response_count = 0;
665 
666 	while (sent < count) {
667 		uint32 readPos = controller->Read16(HDAC_CORB_READ_POS);
668 		uint32 queued = 0;
669 
670 		while (sent < count) {
671 			uint32 writePos = next_corb(controller);
672 
673 			if (writePos == readPos) {
674 				// There is no space left in the ring buffer; execute the
675 				// queued commands and wait until
676 				break;
677 			}
678 
679 			controller->corb[writePos] = verbs[sent++];
680 			controller->corb_write_pos = writePos;
681 			queued++;
682 		}
683 
684 		controller->Write16(HDAC_CORB_WRITE_POS, controller->corb_write_pos);
685 		status_t status = acquire_sem_etc(codec->response_sem, queued,
686 			B_RELATIVE_TIMEOUT, 50000ULL);
687 		if (status < B_OK)
688 			return status;
689 	}
690 
691 	if (responses != NULL)
692 		memcpy(responses, codec->responses, count * sizeof(uint32));
693 
694 	return B_OK;
695 }
696 
697 
698 /*! Setup hardware for use; detect codecs; etc */
699 status_t
700 hda_hw_init(hda_controller* controller)
701 {
702 	uint16 capabilities, stateStatus, cmd;
703 	status_t status;
704 	uint8 tcsel;
705 
706 	/* Map MMIO registers */
707 	controller->regs_area = map_physical_memory("hda_hw_regs",
708 		(void*)controller->pci_info.u.h0.base_registers[0],
709 		controller->pci_info.u.h0.base_register_sizes[0], B_ANY_KERNEL_ADDRESS,
710 		0, (void**)&controller->regs);
711 	if (controller->regs_area < B_OK) {
712 		status = controller->regs_area;
713 		goto error;
714 	}
715 
716 	cmd = (gPci->read_pci_config)(controller->pci_info.bus,
717 		controller->pci_info.device, controller->pci_info.function, PCI_command, 2);
718 	if (!(cmd & PCI_command_master)) {
719 		(gPci->write_pci_config)(controller->pci_info.bus,
720 			controller->pci_info.device, controller->pci_info.function,
721 				PCI_command, 2, cmd | PCI_command_master);
722 		dprintf("hda: enabling PCI bus mastering\n");
723 	}
724 
725 	/* Absolute minimum hw is online; we can now install interrupt handler */
726 	controller->irq = controller->pci_info.u.h0.interrupt_line;
727 	status = install_io_interrupt_handler(controller->irq,
728 		(interrupt_handler)hda_interrupt_handler, controller, 0);
729 	if (status != B_OK)
730 		goto no_irq;
731 
732 	/* TCSEL is reset to TC0 (clear 0-2 bits) */
733 	tcsel = (gPci->read_pci_config)(controller->pci_info.bus,
734 		controller->pci_info.device, controller->pci_info.function, PCI_HDA_TCSEL, 1);
735 	(gPci->write_pci_config)(controller->pci_info.bus,
736 		controller->pci_info.device, controller->pci_info.function,
737 		PCI_HDA_TCSEL, 1, tcsel & 0xf8);
738 
739 	capabilities = controller->Read16(HDAC_GLOBAL_CAP);
740 	controller->num_input_streams = GLOBAL_CAP_INPUT_STREAMS(capabilities);
741 	controller->num_output_streams = GLOBAL_CAP_OUTPUT_STREAMS(capabilities);
742 	controller->num_bidir_streams = GLOBAL_CAP_BIDIR_STREAMS(capabilities);
743 
744 	/* show some hw features */
745 	dprintf("hda: HDA v%d.%d, O:%ld/I:%ld/B:%ld, #SDO:%d, 64bit:%s\n",
746 		controller->Read8(HDAC_VERSION_MAJOR),
747 		controller->Read8(HDAC_VERSION_MINOR),
748 		controller->num_output_streams, controller->num_input_streams,
749 		controller->num_bidir_streams,
750 		GLOBAL_CAP_NUM_SDO(capabilities),
751 		GLOBAL_CAP_64BIT(capabilities) ? "yes" : "no");
752 
753 	/* Get controller into valid state */
754 	status = reset_controller(controller);
755 	if (status != B_OK) {
756 		dprintf("hda: reset_controller failed\n");
757 		goto reset_failed;
758 	}
759 
760 	/* Setup CORB/RIRB/DMA POS */
761 	status = init_corb_rirb_pos(controller);
762 	if (status != B_OK) {
763 		dprintf("hda: init_corb_rirb_pos failed\n");
764 		goto corb_rirb_failed;
765 	}
766 
767 	controller->Write16(HDAC_WAKE_ENABLE, 0x7fff);
768 
769 	/* Enable controller interrupts */
770 	controller->Write32(HDAC_INTR_CONTROL, INTR_CONTROL_GLOBAL_ENABLE
771 		| INTR_CONTROL_CONTROLLER_ENABLE);
772 
773 	snooze(1000);
774 
775 	stateStatus = controller->Read16(HDAC_STATE_STATUS);
776 	if (!stateStatus) {
777 		dprintf("hda: bad codec status\n");
778 		status = ENODEV;
779 		goto corb_rirb_failed;
780 	}
781 	controller->Write16(HDAC_STATE_STATUS, stateStatus);
782 
783 	// Create codecs
784 	for (uint32 index = 0; index < HDA_MAX_CODECS; index++) {
785 		if ((stateStatus & (1 << index)) != 0)
786 			hda_codec_new(controller, index);
787 	}
788 	for (uint32 index = 0; index < HDA_MAX_CODECS; index++) {
789 		if (controller->codecs[index]
790 			&& controller->codecs[index]->num_audio_groups > 0) {
791 			controller->active_codec = controller->codecs[index];
792 			break;
793 		}
794 	}
795 
796 	if (controller->active_codec != NULL)
797 		return B_OK;
798 
799 	dprintf("hda: no active codec\n");
800 	status = ENODEV;
801 
802 corb_rirb_failed:
803 	controller->Write32(HDAC_INTR_CONTROL, 0);
804 
805 reset_failed:
806 	remove_io_interrupt_handler(controller->irq,
807 		(interrupt_handler)hda_interrupt_handler, controller);
808 
809 no_irq:
810 	delete_area(controller->regs_area);
811 	controller->regs_area = B_ERROR;
812 	controller->regs = NULL;
813 
814 error:
815 	dprintf("hda: ERROR: %s(%ld)\n", strerror(status), status);
816 
817 	return status;
818 }
819 
820 
821 /*! Stop any activity */
822 void
823 hda_hw_stop(hda_controller* controller)
824 {
825 	int index;
826 
827 	/* Stop all audio streams */
828 	for (index = 0; index < HDA_MAX_STREAMS; index++) {
829 		if (controller->streams[index] && controller->streams[index]->running)
830 			hda_stream_stop(controller, controller->streams[index]);
831 	}
832 }
833 
834 
835 /*! Free resources */
836 void
837 hda_hw_uninit(hda_controller* controller)
838 {
839 	uint32 index;
840 
841 	if (controller == NULL)
842 		return;
843 
844 	/* Stop all audio streams */
845 	hda_hw_stop(controller);
846 
847 	reset_controller(controller);
848 
849 	/* Disable interrupts, and remove interrupt handler */
850 	controller->Write32(HDAC_INTR_CONTROL, 0);
851 
852 	remove_io_interrupt_handler(controller->irq,
853 		(interrupt_handler)hda_interrupt_handler, controller);
854 
855 	/* Delete corb/rirb area */
856 	if (controller->corb_rirb_pos_area >= 0) {
857 		delete_area(controller->corb_rirb_pos_area);
858 		controller->corb_rirb_pos_area = B_ERROR;
859 		controller->corb = NULL;
860 		controller->rirb = NULL;
861 		controller->stream_positions = NULL;
862 	}
863 
864 	/* Unmap registers */
865 	if (controller->regs_area >= 0) {
866 		delete_area(controller->regs_area);
867 		controller->regs_area = B_ERROR;
868 		controller->regs = NULL;
869 	}
870 
871 	/* Now delete all codecs */
872 	for (index = 0; index < HDA_MAX_CODECS; index++) {
873 		if (controller->codecs[index] != NULL)
874 			hda_codec_delete(controller->codecs[index]);
875 	}
876 }
877 
878