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