Cleanup, no functional change intended.

This commit is contained in:
Axel Dörfler 2012-09-23 20:39:21 +02:00 committed by Alexander von Gluck IV
parent 53f1232b85
commit 7999e1048f
3 changed files with 146 additions and 138 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2007-2008, Haiku, Inc. All Rights Reserved.
* Copyright 2007-2012, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
@ -11,7 +11,7 @@
static status_t
hda_open(const char *name, uint32 flags, void** cookie)
hda_open(const char* name, uint32 flags, void** cookie)
{
hda_controller* controller = NULL;
@ -25,7 +25,7 @@ hda_open(const char *name, uint32 flags, void** cookie)
if (controller == NULL)
return ENODEV;
if (controller->opened)
if (controller->opened != 0)
return B_BUSY;
status_t status = hda_hw_init(controller);
@ -40,10 +40,9 @@ hda_open(const char *name, uint32 flags, void** cookie)
static status_t
hda_read(void* cookie, off_t position, void *buf, size_t* numBytes)
hda_read(void* cookie, off_t position, void* buffer, size_t* numBytes)
{
*numBytes = 0;
/* tell caller nothing was read */
return B_IO_ERROR;
}
@ -52,7 +51,6 @@ static status_t
hda_write(void* cookie, off_t position, const void* buffer, size_t* numBytes)
{
*numBytes = 0;
/* tell caller nothing was written */
return B_IO_ERROR;
}
@ -61,7 +59,7 @@ static status_t
hda_control(void* cookie, uint32 op, void* arg, size_t length)
{
hda_controller* controller = (hda_controller*)cookie;
if (controller->active_codec)
if (controller->active_codec != NULL)
return multi_audio_control(controller->active_codec, op, arg, length);
return B_BAD_VALUE;
@ -90,10 +88,10 @@ hda_free(void* cookie)
device_hooks gDriverHooks = {
hda_open, /* -> open entry point */
hda_close, /* -> close entry point */
hda_free, /* -> free cookie */
hda_control, /* -> control entry point */
hda_read, /* -> read entry point */
hda_write /* -> write entry point */
hda_open,
hda_close,
hda_free,
hda_control,
hda_read,
hda_write
};

View File

@ -1,5 +1,5 @@
/*
* Copyright 2007-2009, Haiku, Inc. All Rights Reserved.
* Copyright 2007-2012, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
@ -12,15 +12,17 @@
#include "driver.h"
#include "hda_codec_defs.h"
#undef TRACE
#define TRACE_CODEC
#ifdef TRACE_CODEC
#define TRACE(a...) dprintf(a)
# define TRACE(a...) dprintf(a)
#else
#define TRACE(a...)
# define TRACE(a...)
#endif
#define ERROR(a...) dprintf(a)
#define HDA_ALL 0xffffffff
#define HDA_QUIRK_GPIO_COUNT 8
#define HDA_QUIRK_GPIO0 (1 << 0)
@ -72,6 +74,24 @@ static const char* kJackColor[] = {
"Purple", "Pink", "-", "-", "-", "-", "White", "Other"
};
static const struct {
uint32 subsystem_vendor_id, subsystem_id;
uint32 codec_vendor_id, codec_id;
uint32 quirks, nonquirks;
} kCodecQuirks[] = {
{ HDA_ALL, HDA_ALL, HDA_ALL, HDA_ALL, HDA_QUIRK_IVREF, 0 },
{ HDA_ALL, HDA_ALL, HDA_ALL, HDA_ALL, HDA_QUIRK_IVREF, 0 },
{ 0x10de, 0xcb79, CIRRUSLOGIC_VENDORID, 0x4206,
HDA_QUIRK_GPIO1 | HDA_QUIRK_GPIO3, 0 }, // MacBook Pro 5.5
{ 0x8384, 0x7680, SIGMATEL_VENDORID, 0x7680,
HDA_QUIRK_GPIO0 | HDA_QUIRK_GPIO1, 0}, // Apple Intel Mac
{ 0x106b, 0x00a1, REALTEK_VENDORID, 0x0885,
HDA_QUIRK_GPIO0 | HDA_QUIRK_OVREF50, 0}, // MacBook
{ 0x106b, 0x00a3, REALTEK_VENDORID, 0x0885,
HDA_QUIRK_GPIO0, 0}, // MacBook
{ HDA_ALL, HDA_ALL, IDT_VENDORID, 0x76b2, HDA_QUIRK_GPIO0, 0},
};
static const char*
get_widget_type_name(hda_widget_type type)
@ -178,7 +198,7 @@ dump_widget_audio_capabilities(uint32 capabilities)
int offset = 0;
for (uint32 j = 0; j < sizeof(kFlags) / sizeof(kFlags[0]); j++) {
if (capabilities & kFlags[j].flag)
if ((capabilities & kFlags[j].flag) != 0)
offset += sprintf(buffer + offset, "[%s] ", kFlags[j].name);
}
@ -299,7 +319,7 @@ static void
dump_audiogroup_widgets(hda_audio_group* audioGroup)
{
TRACE("\tAudiogroup:\n");
/* Iterate over all Widgets and collect info */
// Iterate over all widgets and collect info
for (uint32 i = 0; i < audioGroup->widget_count; i++) {
hda_widget& widget = audioGroup->widgets[i];
uint32 nodeID = audioGroup->widget_start + i;
@ -331,19 +351,48 @@ dump_audiogroup_widgets(hda_audio_group* audioGroup)
// #pragma mark -
static void
hda_codec_get_quirks(hda_codec* codec)
{
codec->quirks = 0;
uint32 subSystemID = codec->controller->pci_info.u.h0.subsystem_id;
uint32 subSystemVendorID
= codec->controller->pci_info.u.h0.subsystem_vendor_id;
for (uint32 i = 0;
i < (sizeof(kCodecQuirks) / sizeof(kCodecQuirks[0])); i++) {
if (kCodecQuirks[i].subsystem_id != HDA_ALL
&& kCodecQuirks[i].subsystem_id != subSystemID)
continue;
if (kCodecQuirks[i].subsystem_vendor_id != HDA_ALL
&& kCodecQuirks[i].subsystem_vendor_id != subSystemVendorID)
continue;
if (kCodecQuirks[i].codec_vendor_id != HDA_ALL
&& kCodecQuirks[i].codec_vendor_id != codec->vendor_id)
continue;
if (kCodecQuirks[i].codec_id != HDA_ALL
&& kCodecQuirks[i].codec_id != codec->product_id)
continue;
codec->quirks |= kCodecQuirks[i].quirks;
codec->quirks &= ~kCodecQuirks[i].nonquirks;
}
}
static status_t
hda_get_pm_support(hda_codec* codec, uint32 nodeID, uint32* pm)
{
corb_t verb = MAKE_VERB(codec->addr, nodeID, VID_GET_PARAMETER,
PID_POWERSTATE_SUPPORT);
status_t rc;
uint32 response;
if ((rc = hda_send_verbs(codec, &verb, &response, 1)) == B_OK) {
status_t status = hda_send_verbs(codec, &verb, &response, 1);
if (status == B_OK)
*pm = response & 0xf;
}
return rc;
return status;
}
@ -420,8 +469,7 @@ hda_get_stream_support(hda_codec* codec, uint32 nodeID, uint32* formats,
static status_t
hda_widget_get_pm_support(hda_audio_group* audioGroup, hda_widget* widget)
{
return hda_get_pm_support(audioGroup->codec, widget->node_id,
&widget->pm);
return hda_get_pm_support(audioGroup->codec, widget->node_id, &widget->pm);
}
@ -456,7 +504,7 @@ hda_widget_get_amplifier_capabilities(hda_audio_group* audioGroup,
VID_GET_PARAMETER, PID_OUTPUT_AMPLIFIER_CAP);
status_t status = hda_send_verbs(audioGroup->codec, &verb,
&response, 1);
if (status < B_OK)
if (status != B_OK)
return status;
widget->capabilities.output_amplifier = response;
@ -475,7 +523,7 @@ hda_widget_get_amplifier_capabilities(hda_audio_group* audioGroup,
VID_GET_PARAMETER, PID_INPUT_AMPLIFIER_CAP);
status_t status = hda_send_verbs(audioGroup->codec, &verb,
&response, 1);
if (status < B_OK)
if (status != B_OK)
return status;
widget->capabilities.input_amplifier = response;
@ -617,7 +665,7 @@ hda_widget_get_associations(hda_audio_group* audioGroup)
static uint32
hda_widget_prepare_pin_ctrl(hda_audio_group* audioGroup, hda_widget *widget,
hda_widget_prepare_pin_ctrl(hda_audio_group* audioGroup, hda_widget* widget,
bool isOutput)
{
uint32 ctrl = 0;
@ -699,7 +747,7 @@ hda_codec_parse_audio_group(hda_audio_group* audioGroup)
return B_NO_MEMORY;
}
/* Iterate over all Widgets and collect info */
// Iterate over all Widgets and collect info
for (uint32 i = 0; i < audioGroup->widget_count; i++) {
hda_widget& widget = audioGroup->widgets[i];
uint32 nodeID = audioGroup->widget_start + i;
@ -713,7 +761,7 @@ hda_codec_parse_audio_group(hda_audio_group* audioGroup)
widget.type = (hda_widget_type)((capabilities & AUDIO_CAP_TYPE_MASK)
>> AUDIO_CAP_TYPE_SHIFT);
/* Check specific node ids declared as inputs as beepers */
// Check specific node ids declared as inputs as beepers
switch (codec_id) {
case 0x11d41882:
case 0x11d41883:
@ -748,7 +796,7 @@ hda_codec_parse_audio_group(hda_audio_group* audioGroup)
widget.node_id = nodeID;
if ((capabilities & AUDIO_CAP_POWER_CONTROL) != 0) {
/* We support power; switch us on! */
// We support power; switch us on!
verbs[0] = MAKE_VERB(audioGroup->codec->addr, nodeID,
VID_SET_POWER_STATE, 0);
hda_send_verbs(audioGroup->codec, verbs, NULL, 1);
@ -826,7 +874,7 @@ hda_codec_parse_audio_group(hda_audio_group* audioGroup)
uint32 tmp;
hda_verb_read(codec, 0x20, VID_GET_PROCESSING_COEFFICIENT, &tmp);
hda_verb_write(codec, 0x20, VID_SET_COEFFICIENT_INDEX, 0x7);
hda_verb_write(codec, 0x20, VID_SET_PROCESSING_COEFFICIENT,
hda_verb_write(codec, 0x20, VID_SET_PROCESSING_COEFFICIENT,
(tmp & 0xf0) == 0x20 ? 0x830 : 0x3030);
break;
}
@ -856,7 +904,7 @@ TRACE(" %*soutput: added output widget %ld\n", (int)depth * 2, "", widget->
case WT_AUDIO_SELECTOR:
{
// already used
if (widget->flags & WIDGET_FLAG_OUTPUT_PATH) {
if ((widget->flags & WIDGET_FLAG_OUTPUT_PATH) != 0) {
alreadyUsed = true;
return false;
}
@ -898,8 +946,8 @@ hda_widget_find_input_path(hda_audio_group* audioGroup, hda_widget* widget,
switch (widget->type) {
case WT_PIN_COMPLEX:
// already used
if ((widget->flags & (WIDGET_FLAG_INPUT_PATH
| WIDGET_FLAG_OUTPUT_PATH)) != 0)
if ((widget->flags
& (WIDGET_FLAG_INPUT_PATH | WIDGET_FLAG_OUTPUT_PATH)) != 0)
return false;
if (PIN_CAP_IS_INPUT(widget->d.pin.capabilities)) {
@ -919,8 +967,8 @@ TRACE(" %*sinput: added input widget %ld\n", (int)depth * 2, "", widget->no
case WT_AUDIO_SELECTOR:
{
// already used
if ((widget->flags & (WIDGET_FLAG_INPUT_PATH
| WIDGET_FLAG_OUTPUT_PATH)) != 0)
if ((widget->flags
& (WIDGET_FLAG_INPUT_PATH | WIDGET_FLAG_OUTPUT_PATH)) != 0)
return false;
// search for pin complex in this path
@ -1209,7 +1257,7 @@ hda_codec_new_audio_group(hda_codec* codec, uint32 audioGroupNodeID)
if (audioGroup == NULL)
return B_NO_MEMORY;
/* Setup minimal info needed by hda_codec_parse_afg */
// Setup minimal info needed by hda_codec_parse_afg
audioGroup->widget.node_id = audioGroupNodeID;
audioGroup->codec = codec;
audioGroup->multi = (hda_multi*)calloc(1,
@ -1220,12 +1268,12 @@ hda_codec_new_audio_group(hda_codec* codec, uint32 audioGroupNodeID)
}
audioGroup->multi->group = audioGroup;
/* Parse all widgets in Audio Function Group */
// Parse all widgets in Audio Function Group
status_t status = hda_codec_parse_audio_group(audioGroup);
if (status != B_OK)
goto err;
/* Setup for worst-case scenario; we cannot find any output Pin Widgets */
// Setup for worst-case scenario; we cannot find any output Pin Widgets
status = ENODEV;
if (hda_audio_group_build_tree(audioGroup) != B_OK)
@ -1282,7 +1330,7 @@ hda_audio_group_get_widgets(hda_audio_group* audioGroup, hda_stream* stream)
flags == WIDGET_FLAG_OUTPUT_PATH);
TRACE("ENABLE pin widget %ld\n", widget.node_id);
/* FIXME: Force Pin Widget to unmute; enable hp/output */
// FIXME: Force Pin Widget to unmute; enable hp/output
corb_t verb = MAKE_VERB(audioGroup->codec->addr,
widget.node_id,
VID_SET_PIN_WIDGET_CONTROL, ctrl);
@ -1358,50 +1406,6 @@ TRACE("UNMUTE/SET INPUT GAIN widget %ld (offset %ld)\n", widget.node_id,
}
static const struct {
uint32 subsystem_vendor_id, subsystem_id;
uint32 codec_vendor_id, codec_id;
uint32 quirks, nonquirks;
} hda_codec_quirks[] = {
{ HDA_ALL, HDA_ALL, HDA_ALL, HDA_ALL, HDA_QUIRK_IVREF, 0 },
{ HDA_ALL, HDA_ALL, HDA_ALL, HDA_ALL, HDA_QUIRK_IVREF, 0 },
{ 0x10de, 0xcb79, CIRRUSLOGIC_VENDORID, 0x4206, HDA_QUIRK_GPIO1 | HDA_QUIRK_GPIO3, 0 }, // MacBook Pro 5.5
{ 0x8384, 0x7680, SIGMATEL_VENDORID, 0x7680, HDA_QUIRK_GPIO0 | HDA_QUIRK_GPIO1, 0}, // Apple Intel Mac
{ 0x106b, 0x00a1, REALTEK_VENDORID, 0x0885, HDA_QUIRK_GPIO0 | HDA_QUIRK_OVREF50, 0}, // MacBook
{ 0x106b, 0x00a3, REALTEK_VENDORID, 0x0885, HDA_QUIRK_GPIO0, 0}, // MacBook
{ HDA_ALL, HDA_ALL, IDT_VENDORID, 0x76b2, HDA_QUIRK_GPIO0, 0},
};
void
hda_codec_get_quirks(hda_codec* codec)
{
codec->quirks = 0;
uint32 subsystem_id = codec->controller->pci_info.u.h0.subsystem_id;
uint32 subsystem_vendor_id = codec->controller->pci_info.u.h0.subsystem_vendor_id;
uint32 codec_vendor_id = codec->vendor_id;
uint32 codec_id = codec->product_id;
for (uint32 i = 0; i < (sizeof(hda_codec_quirks)
/ sizeof(hda_codec_quirks[0])); i++) {
if (hda_codec_quirks[i].subsystem_id != 0xffffffff
&& hda_codec_quirks[i].subsystem_id != subsystem_id)
continue;
if (hda_codec_quirks[i].subsystem_vendor_id != 0xffffffff
&& hda_codec_quirks[i].subsystem_vendor_id != subsystem_vendor_id)
continue;
if (hda_codec_quirks[i].codec_vendor_id != 0xffffffff
&& hda_codec_quirks[i].codec_vendor_id != codec_vendor_id)
continue;
if (hda_codec_quirks[i].codec_id != 0xffffffff
&& hda_codec_quirks[i].codec_id != codec_id)
continue;
codec->quirks |= hda_codec_quirks[i].quirks;
codec->quirks &= ~(hda_codec_quirks[i].nonquirks);
}
}
void
hda_codec_delete(hda_codec* codec)
{
@ -1435,6 +1439,8 @@ hda_codec_new(hda_controller* controller, uint32 codecAddress)
return NULL;
}
status_t status;
codec->controller = controller;
codec->addr = codecAddress;
codec->response_sem = create_sem(0, "hda_codec_response_sem");
@ -1465,15 +1471,17 @@ hda_codec_new(hda_controller* controller, uint32 codecAddress)
uint32 start : 8;
uint32 _reserved2 : 8;
} response;
corb_t verbs[3];
corb_t verbs[3];
verbs[0] = MAKE_VERB(codecAddress, 0, VID_GET_PARAMETER, PID_VENDOR_ID);
verbs[1] = MAKE_VERB(codecAddress, 0, VID_GET_PARAMETER, PID_REVISION_ID);
verbs[2] = MAKE_VERB(codecAddress, 0, VID_GET_PARAMETER,
PID_SUB_NODE_COUNT);
if (hda_send_verbs(codec, verbs, (uint32*)&response, 3) != B_OK) {
ERROR("hda: Failed to get vendor and revision parameters\n");
status = hda_send_verbs(codec, verbs, (uint32*)&response, 3);
if (status != B_OK) {
ERROR("hda: Failed to get vendor and revision parameters: %s\n",
strerror(status));
goto err;
}
@ -1489,8 +1497,8 @@ hda_codec_new(hda_controller* controller, uint32 codecAddress)
"%lu.%lu.%lu.%lu\n", codecAddress, response.vendor, response.device,
response.major, response.minor, response.revision, response.stepping);
for (uint32 nodeID = response.start; nodeID < response.start
+ response.count; nodeID++) {
for (uint32 nodeID = response.start;
nodeID < response.start + response.count; nodeID++) {
uint32 groupType;
verbs[0] = MAKE_VERB(codecAddress, nodeID, VID_GET_PARAMETER,
PID_FUNCTION_GROUP_TYPE);
@ -1500,8 +1508,9 @@ hda_codec_new(hda_controller* controller, uint32 codecAddress)
goto err;
}
if ((groupType & FUNCTION_GROUP_NODETYPE_MASK) == FUNCTION_GROUP_NODETYPE_AUDIO) {
/* Found an Audio Function Group! */
if ((groupType & FUNCTION_GROUP_NODETYPE_MASK)
== FUNCTION_GROUP_NODETYPE_AUDIO) {
// Found an Audio Function Group!
status_t status = hda_codec_new_audio_group(codec, nodeID);
if (status != B_OK) {
ERROR("hda: Failed to setup new audio function group (%s)!\n",
@ -1521,6 +1530,7 @@ hda_codec_new(hda_controller* controller, uint32 codecAddress)
resume_thread(codec->unsol_response_thread);
return codec;
err:
controller->codecs[codecAddress] = NULL;
hda_codec_delete(codec);

View File

@ -181,17 +181,17 @@ hda_interrupt_handler(hda_controller* controller)
{
int32 handled = B_HANDLED_INTERRUPT;
/* Check if this interrupt is ours */
// Check if this interrupt is ours
uint32 intrStatus = controller->Read32(HDAC_INTR_STATUS);
if ((intrStatus & INTR_STATUS_GLOBAL) == 0)
return B_UNHANDLED_INTERRUPT;
/* Controller or stream related? */
// Controller or stream related?
if (intrStatus & INTR_STATUS_CONTROLLER) {
uint8 rirbStatus = controller->Read8(HDAC_RIRB_STATUS);
uint8 corbStatus = controller->Read8(HDAC_CORB_STATUS);
/* Check for incoming responses */
// Check for incoming responses
if (rirbStatus) {
controller->Write8(HDAC_RIRB_STATUS, rirbStatus);
@ -229,7 +229,7 @@ hda_interrupt_handler(hda_controller* controller)
continue;
}
/* Store response in codec */
// Store response in codec
codec->responses[codec->response_count++] = response;
release_sem_etc(codec->response_sem, 1, B_DO_NOT_RESCHEDULE);
handled = B_INVOKE_SCHEDULER;
@ -240,7 +240,7 @@ hda_interrupt_handler(hda_controller* controller)
dprintf("hda: RIRB Overflow\n");
}
/* Check for sending errors */
// Check for sending errors
if (corbStatus) {
controller->Write8(HDAC_CORB_STATUS, corbStatus);
@ -265,7 +265,7 @@ hda_interrupt_handler(hda_controller* controller)
}
}
/* NOTE: See HDA001 => CIS/GIS cannot be cleared! */
// NOTE: See HDA001 => CIS/GIS cannot be cleared!
return handled;
}
@ -364,7 +364,7 @@ init_corb_rirb_pos(hda_controller* controller)
status_t rc = B_OK;
physical_entry pe;
/* Determine and set size of CORB */
// Determine and set size of CORB
corbSize = controller->Read8(HDAC_CORB_SIZE);
if ((corbSize & CORB_SIZE_CAP_256_ENTRIES) != 0) {
controller->corb_length = 256;
@ -377,7 +377,7 @@ init_corb_rirb_pos(hda_controller* controller)
controller->Write8(HDAC_CORB_SIZE, CORB_SIZE_2_ENTRIES);
}
/* Determine and set size of RIRB */
// Determine and set size of RIRB
rirbSize = controller->Read8(HDAC_RIRB_SIZE);
if (rirbSize & RIRB_SIZE_CAP_256_ENTRIES) {
controller->rirb_length = 256;
@ -390,7 +390,7 @@ init_corb_rirb_pos(hda_controller* controller)
controller->Write8(HDAC_RIRB_SIZE, RIRB_SIZE_2_ENTRIES);
}
/* Determine rirb offset in memory and total size of corb+alignment+rirb */
// Determine rirb offset in memory and total size of corb+alignment+rirb
rirbOffset = ALIGN(controller->corb_length * sizeof(corb_t), 128);
posOffset = ALIGN(rirbOffset + controller->rirb_length * sizeof(rirb_t), 128);
posSize = 8 * (controller->num_input_streams
@ -398,14 +398,14 @@ init_corb_rirb_pos(hda_controller* controller)
memSize = PAGE_ALIGN(posOffset + posSize);
/* Allocate memory area */
// Allocate memory area
controller->corb_rirb_pos_area = create_area("hda corb/rirb/pos",
(void**)&controller->corb, B_ANY_KERNEL_ADDRESS, memSize,
B_CONTIGUOUS, 0);
if (controller->corb_rirb_pos_area < 0)
return controller->corb_rirb_pos_area;
/* Rirb is after corb+aligment */
// Rirb is after corb+aligment
controller->rirb = (rirb_t*)(((uint8*)controller->corb) + rirbOffset);
if ((rc = get_memory_map(controller->corb, memSize, &pe, 1)) != B_OK) {
@ -413,7 +413,7 @@ init_corb_rirb_pos(hda_controller* controller)
return rc;
}
/* Program CORB/RIRB for these locations */
// Program CORB/RIRB for these locations
controller->Write32(HDAC_CORB_BASE_LOWER, (uint32)pe.address);
controller->Write32(HDAC_CORB_BASE_UPPER,
(uint32)((uint64)pe.address >> 32));
@ -421,7 +421,7 @@ init_corb_rirb_pos(hda_controller* controller)
controller->Write32(HDAC_RIRB_BASE_UPPER,
(uint32)(((uint64)pe.address + rirbOffset) >> 32));
/* Program DMA position update */
// Program DMA position update
controller->Write32(HDAC_DMA_POSITION_BASE_LOWER,
(uint32)pe.address + posOffset);
controller->Write32(HDAC_DMA_POSITION_BASE_UPPER,
@ -431,23 +431,23 @@ init_corb_rirb_pos(hda_controller* controller)
((uint8*)controller->corb + posOffset);
controller->Write16(HDAC_CORB_WRITE_POS, 0);
/* Reset CORB read pointer */
// Reset CORB read pointer
controller->Write16(HDAC_CORB_READ_POS, CORB_READ_POS_RESET);
/* Reading CORB_READ_POS_RESET as zero fails on some chips.
We reset the bit here. */
// Reading CORB_READ_POS_RESET as zero fails on some chips.
// We reset the bit here.
controller->Write16(HDAC_CORB_READ_POS, 0);
/* Reset RIRB write pointer */
// Reset RIRB write pointer
controller->Write16(HDAC_RIRB_WRITE_POS, RIRB_WRITE_POS_RESET);
/* Generate interrupt for every response */
// Generate interrupt for every response
controller->Write16(HDAC_RESPONSE_INTR_COUNT, 1);
/* Setup cached read/write indices */
// Setup cached read/write indices
controller->rirb_read_pos = 1;
controller->corb_write_pos = 0;
/* Gentlemen, start your engines... */
// Gentlemen, start your engines...
controller->Write8(HDAC_CORB_CONTROL,
CORB_CONTROL_RUN | CORB_CONTROL_MEMORY_ERROR_INTR);
controller->Write8(HDAC_RIRB_CONTROL, RIRB_CONTROL_DMA_ENABLE
@ -574,14 +574,7 @@ status_t
hda_stream_setup_buffers(hda_audio_group* audioGroup, hda_stream* stream,
const char* desc)
{
uint32 response[2];
physical_entry pe;
bdl_entry_t* bufferDescriptors;
corb_t verb[2];
uint8* buffer;
status_t rc;
/* Clear previously allocated memory */
// Clear previously allocated memory
if (stream->buffer_area >= B_OK) {
delete_area(stream->buffer_area);
stream->buffer_area = B_ERROR;
@ -592,7 +585,7 @@ hda_stream_setup_buffers(hda_audio_group* audioGroup, hda_stream* stream,
stream->buffer_descriptors_area = B_ERROR;
}
/* Find out stream format and sample rate */
// Find out stream format and sample rate
uint16 format = (stream->num_channels - 1) & 0xf;
switch (stream->sample_format) {
case B_FMT_8BIT_S: format |= FORMAT_8BIT; stream->bps = 8; break;
@ -615,30 +608,33 @@ hda_stream_setup_buffers(hda_audio_group* audioGroup, hda_stream* stream,
}
}
/* Calculate size of buffer (aligned to 128 bytes) */
// Calculate size of buffer (aligned to 128 bytes)
stream->buffer_size = ALIGN(stream->buffer_length * stream->num_channels
* stream->sample_size, 128);
dprintf("HDA: sample size %ld, num channels %ld, buffer length %ld, **********\n",
dprintf("HDA: sample size %ld, num channels %ld, buffer length %ld\n",
stream->sample_size, stream->num_channels, stream->buffer_length);
dprintf("IRA: %s: setup stream %ld: SR=%ld, SF=%ld F=0x%x (0x%lx)\n", __func__, stream->id,
stream->rate, stream->bps, format, stream->sample_format);
dprintf("IRA: %s: setup stream %ld: SR=%ld, SF=%ld F=0x%x (0x%lx)\n",
__func__, stream->id, stream->rate, stream->bps, format,
stream->sample_format);
/* Calculate total size of all buffers (aligned to size of B_PAGE_SIZE) */
// Calculate total size of all buffers (aligned to size of B_PAGE_SIZE)
uint32 alloc = stream->buffer_size * stream->num_buffers;
alloc = PAGE_ALIGN(alloc);
/* Allocate memory for buffers */
// Allocate memory for buffers
uint8* buffer;
stream->buffer_area = create_area("hda buffers", (void**)&buffer,
B_ANY_KERNEL_ADDRESS, alloc, B_CONTIGUOUS, B_READ_AREA | B_WRITE_AREA);
if (stream->buffer_area < B_OK)
return stream->buffer_area;
/* Get the physical address of memory */
rc = get_memory_map(buffer, alloc, &pe, 1);
if (rc != B_OK) {
// Get the physical address of memory
physical_entry pe;
status_t status = get_memory_map(buffer, alloc, &pe, 1);
if (status != B_OK) {
delete_area(stream->buffer_area);
return rc;
return status;
}
phys_addr_t bufferPhysicalAddress = pe.address;
@ -646,18 +642,19 @@ hda_stream_setup_buffers(hda_audio_group* audioGroup, hda_stream* stream,
dprintf("%s(%s): Allocated %lu bytes for %ld buffers\n", __func__, desc,
alloc, stream->num_buffers);
/* Store pointers (both virtual/physical) */
// Store pointers (both virtual/physical)
for (uint32 index = 0; index < stream->num_buffers; index++) {
stream->buffers[index] = buffer + (index * stream->buffer_size);
stream->physical_buffers[index] = bufferPhysicalAddress
+ (index * stream->buffer_size);
}
/* Now allocate BDL for buffer range */
// Now allocate BDL for buffer range
uint32 bdlCount = stream->num_buffers;
alloc = bdlCount * sizeof(bdl_entry_t);
alloc = PAGE_ALIGN(alloc);
bdl_entry_t* bufferDescriptors;
stream->buffer_descriptors_area = create_area("hda buffer descriptors",
(void**)&bufferDescriptors, B_ANY_KERNEL_ADDRESS, alloc,
B_CONTIGUOUS, 0);
@ -666,12 +663,12 @@ hda_stream_setup_buffers(hda_audio_group* audioGroup, hda_stream* stream,
return stream->buffer_descriptors_area;
}
/* Get the physical address of memory */
rc = get_memory_map(bufferDescriptors, alloc, &pe, 1);
if (rc != B_OK) {
// Get the physical address of memory
status = get_memory_map(bufferDescriptors, alloc, &pe, 1);
if (status != B_OK) {
delete_area(stream->buffer_area);
delete_area(stream->buffer_descriptors_area);
return rc;
return status;
}
stream->physical_buffer_descriptors = pe.address;
@ -679,7 +676,7 @@ hda_stream_setup_buffers(hda_audio_group* audioGroup, hda_stream* stream,
dprintf("%s(%s): Allocated %ld bytes for %ld BDLEs\n", __func__, desc,
alloc, bdlCount);
/* Setup buffer descriptor list (BDL) entries */
// Setup buffer descriptor list (BDL) entries
uint32 fragments = 0;
for (uint32 index = 0; index < stream->num_buffers;
index++, bufferDescriptors++) {
@ -715,6 +712,7 @@ hda_stream_setup_buffers(hda_audio_group* audioGroup, hda_stream* stream,
hda_codec* codec = audioGroup->codec;
uint32 channelNum = 0;
for (uint32 i = 0; i < stream->num_io_widgets; i++) {
corb_t verb[2];
verb[0] = MAKE_VERB(codec->addr, stream->io_widgets[i],
VID_SET_CONVERTER_FORMAT, format);
uint32 val = stream->id << 4;
@ -724,6 +722,8 @@ hda_stream_setup_buffers(hda_audio_group* audioGroup, hda_stream* stream,
val = 0;
verb[1] = MAKE_VERB(codec->addr, stream->io_widgets[i],
VID_SET_CONVERTER_STREAM_CHANNEL, val);
uint32 response[2];
hda_send_verbs(codec, verb, response, 2);
//channelNum += 2; // TODO stereo widget ? Every output gets the same stream for now
dprintf("%ld ", stream->io_widgets[i]);