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