diff --git a/src/add-ons/kernel/drivers/audio/hda/Jamfile b/src/add-ons/kernel/drivers/audio/hda/Jamfile index e735689be8..32995239aa 100644 --- a/src/add-ons/kernel/drivers/audio/hda/Jamfile +++ b/src/add-ons/kernel/drivers/audio/hda/Jamfile @@ -5,11 +5,11 @@ SetSubDirSupportedPlatformsBeOSCompatible ; UsePrivateHeaders media ; KernelAddon hda : - driver.c - hooks.c - hda_multi_audio.c - hda_controller.c - hda_codec.c + driver.cpp + device.cpp + hda_multi_audio.cpp + hda_controller.cpp + hda_codec.cpp ; Package haiku-hda-cvs : diff --git a/src/add-ons/kernel/drivers/audio/hda/hooks.c b/src/add-ons/kernel/drivers/audio/hda/device.cpp similarity index 89% rename from src/add-ons/kernel/drivers/audio/hda/hooks.c rename to src/add-ons/kernel/drivers/audio/hda/device.cpp index c12f7bc5b2..51e3dcebe5 100644 --- a/src/add-ons/kernel/drivers/audio/hda/hooks.c +++ b/src/add-ons/kernel/drivers/audio/hda/device.cpp @@ -14,10 +14,8 @@ static status_t hda_open(const char *name, uint32 flags, void** cookie) { hda_controller* controller = NULL; - status_t rc = B_OK; - long i; - for (i = 0; i < gNumCards; i++) { + for (uint32 i = 0; i < gNumCards; i++) { if (strcmp(gCards[i].devfs_path, name) == 0) { controller = &gCards[i]; break; @@ -30,11 +28,11 @@ hda_open(const char *name, uint32 flags, void** cookie) if (controller->opened) return B_BUSY; - rc = hda_hw_init(controller); - if (rc != B_OK) - return rc; + status_t status = hda_hw_init(controller); + if (status != B_OK) + return status; - controller->opened++; + atomic_add(&controller->opened, 1); *cookie = controller; return B_OK; @@ -75,7 +73,7 @@ hda_close(void* cookie) { hda_controller* controller = (hda_controller*)cookie; hda_hw_stop(controller); - --controller->opened; + atomic_add(&controller->opened, -1); return B_OK; } diff --git a/src/add-ons/kernel/drivers/audio/hda/driver.c b/src/add-ons/kernel/drivers/audio/hda/driver.cpp similarity index 92% rename from src/add-ons/kernel/drivers/audio/hda/driver.c rename to src/add-ons/kernel/drivers/audio/hda/driver.cpp index c65ed8b0b6..a2af84ccee 100644 --- a/src/add-ons/kernel/drivers/audio/hda/driver.c +++ b/src/add-ons/kernel/drivers/audio/hda/driver.cpp @@ -17,7 +17,7 @@ uint32 gNumCards; pci_module_info* gPci; -status_t +extern "C" status_t init_hardware(void) { pci_info info; @@ -39,7 +39,7 @@ init_hardware(void) } -status_t +extern "C" status_t init_driver(void) { char path[B_PATH_NAME_LENGTH]; @@ -76,13 +76,12 @@ init_driver(void) } -void +extern "C" void uninit_driver(void) { - long i; dprintf("IRA: %s\n", __func__); - for (i = 0; i < gNumCards; i++) { + for (uint32 i = 0; i < gNumCards; i++) { free((void*)gCards[i].devfs_path); gCards[i].devfs_path = NULL; } @@ -91,15 +90,16 @@ uninit_driver(void) } -const char** +extern "C" const char** publish_devices(void) { static const char* devs[MAX_CARDS + 1]; - long i; + uint32 i; dprintf("IRA: %s\n", __func__); - for (i = 0; i < gNumCards; i++) + for (i = 0; i < gNumCards; i++) { devs[i] = gCards[i].devfs_path; + } devs[i] = NULL; @@ -107,7 +107,7 @@ publish_devices(void) } -device_hooks* +extern "C" device_hooks* find_device(const char* name) { dprintf("IRA: %s\n", __func__); diff --git a/src/add-ons/kernel/drivers/audio/hda/driver.h b/src/add-ons/kernel/drivers/audio/hda/driver.h index 62f64f4cdc..9768ac2eb8 100644 --- a/src/add-ons/kernel/drivers/audio/hda/driver.h +++ b/src/add-ons/kernel/drivers/audio/hda/driver.h @@ -40,10 +40,6 @@ /* FIXME: Find out why we need so much! */ #define DEFAULT_FRAMES_PER_BUFFER 4096 -typedef struct hda_controller hda_controller; -typedef struct hda_codec hda_codec; -typedef struct hda_audio_group hda_audio_group; - #define STREAM_MAX_BUFFERS 10 #define STREAM_MIN_BUFFERS 2 @@ -52,12 +48,12 @@ enum { STREAM_RECORD }; -/* hda_stream - * - * This structure describes a single stream of audio data, - * which is can have multiple channels (for stereo or better). - */ -typedef struct hda_stream { +struct hda_codec; + +/*! This structure describes a single stream of audio data, + which is can have multiple channels (for stereo or better). +*/ +struct hda_stream { uint32 id; /* HDA controller stream # */ uint32 off; /* HDA I/O/B descriptor offset */ bool running; /* Is this stream active? */ @@ -74,7 +70,7 @@ typedef struct hda_stream { uint32 num_channels; uint32 buffer_length; /* size of buffer in samples */ uint32 sample_size; - void* buffers[STREAM_MAX_BUFFERS]; + uint8* buffers[STREAM_MAX_BUFFERS]; /* Virtual addresses for buffer */ uint32 physical_buffers[STREAM_MAX_BUFFERS]; /* Physical addresses for buffer */ @@ -88,68 +84,66 @@ typedef struct hda_stream { area_id buffer_area; area_id buffer_descriptors_area; uint32 physical_buffer_descriptors; /* BDL physical address */ -} hda_stream; - -/* hda_audio_group - * - * This structure describes a single Audio Function Group. An afg - * is a group of audio widgets which can be used to configure multiple - * streams of audio either from the HDA Link to an output device (= playback) - * or from an input device to the HDA link (= recording). - */ -struct hda_audio_group { - hda_codec* codec; - - /* Multi Audio API data */ - hda_stream* playback_stream; - hda_stream* record_stream; - - uint32 root_node_id; - uint32 widget_start; - uint32 widget_count; - - uint32 supported_formats; - uint32 supported_rates; - uint32 supported_pm; - - struct { - uint32 num_inputs; - int32 active_input; - uint32 inputs[MAX_INPUTS]; - uint32 flags; - - hda_widget_type type; - uint32 pm; - - union { - struct { - uint32 formats; - uint32 rates; - } output; - struct { - uint32 formats; - uint32 rates; - } input; - struct { - } mixer; - struct { - uint32 output; - uint32 input; - pin_dev_type device; - } pin; - } d; - } *widgets; }; -/* hda_codec - * - * This structure describes a single codec module in the - * HDA compliant device. This is a discrete component, which - * can contain both Audio Function Groups, Modem Function Groups, - * and other customized (vendor specific) Function Groups. - * - * NOTE: Atm, only Audio Function Groups are supported. - */ +struct hda_widget { + uint32 num_inputs; + int32 active_input; + uint32 inputs[MAX_INPUTS]; + uint32 flags; + + hda_widget_type type; + uint32 pm; + + union { + struct { + uint32 formats; + uint32 rates; + } output; + struct { + uint32 formats; + uint32 rates; + } input; + struct { + } mixer; + struct { + uint32 output; + uint32 input; + pin_dev_type device; + } pin; + } d; +}; + +/*! This structure describes a single Audio Function Group. An afg + is a group of audio widgets which can be used to configure multiple + streams of audio either from the HDA Link to an output device (= playback) + or from an input device to the HDA link (= recording). +*/ +struct hda_audio_group { + hda_codec* codec; + + /* Multi Audio API data */ + hda_stream* playback_stream; + hda_stream* record_stream; + + uint32 root_node_id; + uint32 widget_start; + uint32 widget_count; + + uint32 supported_formats; + uint32 supported_rates; + uint32 supported_pm; + + hda_widget* widgets; +}; + +/*! This structure describes a single codec module in the + HDA compliant device. This is a discrete component, which + can contain both Audio Function Groups, Modem Function Groups, + and other customized (vendor specific) Function Groups. + + NOTE: ATM, only Audio Function Groups are supported. +*/ struct hda_codec { uint16 vendor_id; uint16 product_id; @@ -167,16 +161,14 @@ struct hda_codec { struct hda_controller* controller; }; -/* hda_controller - * - * This structure describes a single HDA compliant - * controller. It contains a list of available streams - * for use by the codecs contained, and the messaging queue - * (verb/response) buffers for communication. - */ +/*! This structure describes a single HDA compliant + controller. It contains a list of available streams + for use by the codecs contained, and the messaging queue + (verb/response) buffers for communication. +*/ struct hda_controller { struct pci_info pci_info; - vuint32 opened; + vint32 opened; const char* devfs_path; area_id regs_area; @@ -222,7 +214,7 @@ status_t hda_hw_init(hda_controller* controller); void hda_hw_stop(hda_controller* controller); void hda_hw_uninit(hda_controller* controller); status_t hda_send_verbs(hda_codec* codec, corb_t* verbs, uint32* responses, - int count); + uint32 count); /* hda_controller.c: Stream support */ hda_stream* hda_stream_new(hda_controller* controller, int type); diff --git a/src/add-ons/kernel/drivers/audio/hda/hda_codec.c b/src/add-ons/kernel/drivers/audio/hda/hda_codec.cpp similarity index 83% rename from src/add-ons/kernel/drivers/audio/hda/hda_codec.c rename to src/add-ons/kernel/drivers/audio/hda/hda_codec.cpp index f31ad97375..15b27c18b2 100644 --- a/src/add-ons/kernel/drivers/audio/hda/hda_codec.c +++ b/src/add-ons/kernel/drivers/audio/hda/hda_codec.cpp @@ -174,7 +174,7 @@ hda_codec_parse_audio_group(hda_audio_group* audioGroup) audioGroup->widget_start = resp[2] >> 16; audioGroup->widget_count = resp[2] & 0xFF; - audioGroup->widgets = calloc(audioGroup->widget_count, + audioGroup->widgets = (hda_widget*)calloc(audioGroup->widget_count, sizeof(*audioGroup->widgets)); if (audioGroup->widgets == NULL) { dprintf("ERROR: Not enough memory!\n"); @@ -193,7 +193,7 @@ hda_codec_parse_audio_group(hda_audio_group* audioGroup) PID_CONNLIST_LEN); hda_send_verbs(audioGroup->codec, verbs, resp, 2); - audioGroup->widgets[widx].type = resp[0] >> 20; + audioGroup->widgets[widx].type = (hda_widget_type)(resp[0] >> 20); audioGroup->widgets[widx].num_inputs = resp[1] & 0x7F; off = 0; @@ -272,7 +272,8 @@ hda_codec_parse_audio_group(hda_audio_group* audioGroup) verbs[0] = MAKE_VERB(audioGroup->codec->addr, wid, VID_GET_CFGDEFAULT, 0); if (hda_send_verbs(audioGroup->codec, verbs, resp, 1) == B_OK) { - audioGroup->widgets[widx].d.pin.device = (resp[0] >> 20) & 0xF; + audioGroup->widgets[widx].d.pin.device = (pin_dev_type) + ((resp[0] >> 20) & 0xf); dprintf("\t%s, %s, %s, %s\n", kPortConnector[resp[0] >> 30], kDefaultDevice[audioGroup->widgets[widx].d.pin.device], @@ -304,10 +305,6 @@ hda_codec_parse_audio_group(hda_audio_group* audioGroup) &audioGroup->widgets[widx].pm); if (audioGroup->widgets[widx].num_inputs) { - int idx; - - off = 0; - if (audioGroup->widgets[widx].num_inputs > 1) { verbs[0] = MAKE_VERB(audioGroup->codec->addr, wid, VID_GET_CONNSEL, 0); @@ -318,10 +315,12 @@ hda_codec_parse_audio_group(hda_audio_group* audioGroup) } else audioGroup->widgets[widx].active_input = -1; - for (idx = 0; idx < audioGroup->widgets[widx].num_inputs; idx ++) { - if (!(idx % 4)) { + off = 0; + + for (uint32 i = 0; i < audioGroup->widgets[widx].num_inputs; i++) { + if (!(i % 4)) { verbs[0] = MAKE_VERB(audioGroup->codec->addr, wid, - VID_GET_CONNLENTRY, idx); + VID_GET_CONNLENTRY, i); if (hda_send_verbs(audioGroup->codec, verbs, resp, 1) != B_OK) { dprintf("%s: Error parsing inputs for widget %ld!\n", __func__, wid); @@ -329,16 +328,16 @@ hda_codec_parse_audio_group(hda_audio_group* audioGroup) } } - if (idx != audioGroup->widgets[widx].active_input) { + if ((int32)i != audioGroup->widgets[widx].active_input) { off += sprintf(buf + off, "%ld ", - (resp[0] >> (8 * (idx % 4))) & 0xff); + (resp[0] >> (8 * (i % 4))) & 0xff); } else { off += sprintf(buf + off, "(%ld) ", - (resp[0] >> (8 * (idx % 4))) & 0xff); + (resp[0] >> (8 * (i % 4))) & 0xff); } - audioGroup->widgets[widx].inputs[idx] - = (resp[0] >> (8 * (idx % 4))) & 0xff; + audioGroup->widgets[widx].inputs[i] + = (resp[0] >> (8 * (i % 4))) & 0xff; } dprintf("\t[ %s]\n", buf); @@ -349,35 +348,35 @@ hda_codec_parse_audio_group(hda_audio_group* audioGroup) } -/*! Find path from 'wid' to a widget of type 'wtype', returning its widget id. - * Returns 0 if not found. - */ +/*! Find path from 'wid' to a widget of type \a widgetType, returning its + widget id. + Returns 0 if not found. +*/ static uint32 hda_codec_audio_group_find_path(hda_audio_group* audioGroup, uint32 widget, - uint32 widgetType, uint32 depth) + hda_widget_type widgetType, uint32 depth) { int widx = widget - audioGroup->widget_start; - int idx; switch (audioGroup->widgets[widx].type) { case WT_AUDIO_MIXER: - for (idx = 0; idx < audioGroup->widgets[widx].num_inputs; idx++) { + for (uint32 i = 0; i < audioGroup->widgets[widx].num_inputs; i++) { if (hda_codec_audio_group_find_path(audioGroup, - audioGroup->widgets[widx].inputs[idx], widgetType, + audioGroup->widgets[widx].inputs[i], widgetType, depth + 1)) { if (audioGroup->widgets[widx].active_input == -1) - audioGroup->widgets[widx].active_input = idx; + audioGroup->widgets[widx].active_input = i; - return audioGroup->widgets[widx].inputs[idx]; + return audioGroup->widgets[widx].inputs[i]; } } break; case WT_AUDIO_SELECTOR: { - int idx = audioGroup->widgets[widx].active_input; - if (idx != -1) { - widget = audioGroup->widgets[widx].inputs[idx]; + int32 i = audioGroup->widgets[widx].active_input; + if (i != -1) { + widget = audioGroup->widgets[widx].inputs[i]; if (hda_codec_audio_group_find_path(audioGroup, widget, widgetType, depth + 1)) { return widget; @@ -417,49 +416,48 @@ hda_codec_delete_audio_group(hda_audio_group* audioGroup) static status_t hda_codec_new_audio_group(hda_codec* codec, uint32 audioGroupNodeID) { - hda_audio_group* audioGroup; - status_t rc; - uint32 idx; - - if ((audioGroup = calloc(1, sizeof(hda_audio_group))) == NULL) { - rc = B_NO_MEMORY; - goto done; - } + hda_audio_group* audioGroup = (hda_audio_group*)calloc(1, + sizeof(hda_audio_group)); + if (audioGroup == NULL) + return B_NO_MEMORY; /* Setup minimal info needed by hda_codec_parse_afg */ audioGroup->root_node_id = audioGroupNodeID; audioGroup->codec = codec; /* Parse all widgets in Audio Function Group */ - rc = hda_codec_parse_audio_group(audioGroup); - if (rc != B_OK) - goto free_audio_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 */ - rc = ENODEV; + status = ENODEV; /* Try to locate all input/output channels */ - for (idx = 0; idx < audioGroup->widget_count; idx++) { + for (uint32 i = 0; i < audioGroup->widget_count; i++) { uint32 outputWidget = 0, inputWidget = 0; - int32 iidx; if (audioGroup->playback_stream == NULL - && audioGroup->widgets[idx].type == WT_PIN_COMPLEX - && audioGroup->widgets[idx].d.pin.output) { - if (audioGroup->widgets[idx].d.pin.device == PIN_DEV_HP_OUT - || audioGroup->widgets[idx].d.pin.device == PIN_DEV_SPEAKER - || audioGroup->widgets[idx].d.pin.device == PIN_DEV_LINE_OUT) { - iidx = audioGroup->widgets[idx].active_input; - if (iidx != -1) { + && audioGroup->widgets[i].type == WT_PIN_COMPLEX + && audioGroup->widgets[i].d.pin.output) { + if (audioGroup->widgets[i].d.pin.device == PIN_DEV_HP_OUT + || audioGroup->widgets[i].d.pin.device == PIN_DEV_SPEAKER + || audioGroup->widgets[i].d.pin.device == PIN_DEV_LINE_OUT) { + int32 inputIndex = audioGroup->widgets[i].active_input; + if (inputIndex != -1) { outputWidget = hda_codec_audio_group_find_path(audioGroup, - audioGroup->widgets[idx].inputs[iidx], WT_AUDIO_OUTPUT, 0); + audioGroup->widgets[i].inputs[inputIndex], + WT_AUDIO_OUTPUT, 0); } else { - for (iidx = 0; iidx < audioGroup->widgets[idx].num_inputs; iidx++) { + for (inputIndex = 0; (uint32)inputIndex + < audioGroup->widgets[i].num_inputs; inputIndex++) { outputWidget = hda_codec_audio_group_find_path(audioGroup, - audioGroup->widgets[idx].inputs[iidx], WT_AUDIO_OUTPUT, 0); + audioGroup->widgets[i].inputs[inputIndex], + WT_AUDIO_OUTPUT, 0); if (outputWidget) { corb_t verb = MAKE_VERB(codec->addr, - idx + audioGroup->widget_start, VID_SET_CONNSEL, iidx); + i + audioGroup->widget_start, VID_SET_CONNSEL, + inputIndex); if (hda_send_verbs(codec, &verb, NULL, 1) != B_OK) dprintf("%s: Setting output selector failed!\n", __func__); break; @@ -477,40 +475,45 @@ hda_codec_new_audio_group(hda_codec* codec, uint32 audioGroupNodeID) audioGroup->record_stream = hda_stream_new( audioGroup->codec->controller, STREAM_RECORD); - audioGroup->playback_stream->pin_widget = idx + audioGroup->playback_stream->pin_widget = i + audioGroup->widget_start; audioGroup->playback_stream->io_widget = outputWidget; /* FIXME: Force Pin Widget to unmute; enable hp/output */ verb[0] = MAKE_VERB(codec->addr, - audioGroup->playback_stream->pin_widget, VID_SET_AMPGAINMUTE, + audioGroup->playback_stream->pin_widget, + VID_SET_AMPGAINMUTE, (1 << 15) | (1 << 13) | (1 << 12)); verb[1] = MAKE_VERB(codec->addr, - audioGroup->playback_stream->pin_widget, VID_SET_PINWCTRL, + audioGroup->playback_stream->pin_widget, + VID_SET_PINWCTRL, (1 << 7) | (1 << 6)); hda_send_verbs(codec, verb, NULL, 2); dprintf("%s: Found output PIN (%s) connected to output " "CONV wid:%ld\n", __func__, - kDefaultDevice[audioGroup->widgets[idx].d.pin.device], outputWidget); + kDefaultDevice[audioGroup->widgets[i].d.pin.device], outputWidget); } } } } - if (audioGroup->widgets[idx].type == WT_AUDIO_INPUT) { - iidx = audioGroup->widgets[idx].active_input; - if (iidx != -1) { + if (audioGroup->widgets[i].type == WT_AUDIO_INPUT) { + int32 inputIndex = audioGroup->widgets[i].active_input; + if (inputIndex != -1) { inputWidget = hda_codec_audio_group_find_path(audioGroup, - audioGroup->widgets[idx].inputs[iidx], WT_PIN_COMPLEX, 0); + audioGroup->widgets[i].inputs[inputIndex], WT_PIN_COMPLEX, + 0); } else { - for (iidx = 0; iidx < audioGroup->widgets[idx].num_inputs; iidx++) { + for (inputIndex = 0; (uint32)inputIndex + < audioGroup->widgets[i].num_inputs; inputIndex++) { inputWidget = hda_codec_audio_group_find_path(audioGroup, - audioGroup->widgets[idx].inputs[iidx], WT_PIN_COMPLEX, 0); + audioGroup->widgets[i].inputs[inputIndex], + WT_PIN_COMPLEX, 0); if (inputWidget) { corb_t verb = MAKE_VERB(codec->addr, - idx + audioGroup->widget_start, VID_SET_CONNSEL, - iidx); + i + audioGroup->widget_start, VID_SET_CONNSEL, + inputIndex); if (hda_send_verbs(codec, &verb, NULL, 1) != B_OK) { dprintf("%s: Setting input selector failed!\n", __func__); @@ -529,7 +532,7 @@ hda_codec_new_audio_group(hda_codec* codec, uint32 audioGroupNodeID) audioGroup->codec->controller, STREAM_RECORD); audioGroup->record_stream->pin_widget = inputWidget; - audioGroup->record_stream->io_widget = idx + audioGroup->record_stream->io_widget = i + audioGroup->widget_start; /* FIXME: Force Pin Widget to unmute */ @@ -542,7 +545,7 @@ hda_codec_new_audio_group(hda_codec* codec, uint32 audioGroupNodeID) dprintf("%s: Found input PIN (%s) connected to input CONV " "wid:%ld\n", __func__, kDefaultDevice[audioGroup->widgets[ inputWidget - audioGroup->widget_start].d.pin.device], - idx + audioGroup->widget_start); + i + audioGroup->widget_start); } } } @@ -550,15 +553,12 @@ hda_codec_new_audio_group(hda_codec* codec, uint32 audioGroupNodeID) /* If we found any valid output channels, we're in the clear */ if (audioGroup && audioGroup->playback_stream) { codec->audio_groups[codec->num_audio_groups++] = audioGroup; - rc = B_OK; - goto done; + return B_OK; } -free_audio_group: +err: free(audioGroup); - -done: - return rc; + return status; } @@ -586,7 +586,7 @@ hda_codec_delete(hda_codec* codec) hda_codec* hda_codec_new(hda_controller* controller, uint32 cad) { - hda_codec* codec = calloc(1, sizeof(hda_codec)); + hda_codec* codec = (hda_codec*)calloc(1, sizeof(hda_codec)); uint32 responses[3]; corb_t verbs[3]; uint32 nodeID; diff --git a/src/add-ons/kernel/drivers/audio/hda/hda_codec_defs.h b/src/add-ons/kernel/drivers/audio/hda/hda_codec_defs.h index 2e4f229db7..ce269bd6e3 100644 --- a/src/add-ons/kernel/drivers/audio/hda/hda_codec_defs.h +++ b/src/add-ons/kernel/drivers/audio/hda/hda_codec_defs.h @@ -8,7 +8,7 @@ #ifndef HDA_CODEC_H #define HDA_CODEC_H -typedef enum { +enum hda_widget_type { WT_AUDIO_OUTPUT = 0, WT_AUDIO_INPUT = 1, WT_AUDIO_MIXER = 2, @@ -18,10 +18,10 @@ typedef enum { WT_VOLUME_KNOB = 6, WT_BEEP_GENERATOR = 7, WT_VENDOR_DEFINED = 15 -} hda_widget_type; +}; -typedef enum { +enum pin_dev_type { PIN_DEV_LINE_OUT = 0, PIN_DEV_SPEAKER, PIN_DEV_HP_OUT, @@ -38,7 +38,7 @@ typedef enum { PIN_DEV_DIGITAL_OTHER_IN, PIN_DEV_RESERVED, PIN_DEV_OTHER -} pin_dev_type; +}; /* Verb Helper Macro */ diff --git a/src/add-ons/kernel/drivers/audio/hda/hda_controller.c b/src/add-ons/kernel/drivers/audio/hda/hda_controller.cpp similarity index 99% rename from src/add-ons/kernel/drivers/audio/hda/hda_controller.c rename to src/add-ons/kernel/drivers/audio/hda/hda_controller.cpp index 76c9510290..07f3a16899 100644 --- a/src/add-ons/kernel/drivers/audio/hda/hda_controller.c +++ b/src/add-ons/kernel/drivers/audio/hda/hda_controller.cpp @@ -4,6 +4,7 @@ * * Authors: * Ithamar Adema, ithamar AT unet DOT nl + * Axel Dörfler, axeld@pinc-software.de */ @@ -79,7 +80,7 @@ hda_stream_delete(hda_stream* stream) hda_stream* hda_stream_new(hda_controller* controller, int type) { - hda_stream* stream = calloc(1, sizeof(hda_stream)); + hda_stream* stream = (hda_stream*)calloc(1, sizeof(hda_stream)); if (stream == NULL) return NULL; @@ -333,7 +334,7 @@ dprintf("HDA: sample size %ld, num channels %ld, buffer length %ld ************* status_t -hda_send_verbs(hda_codec* codec, corb_t* verbs, uint32* responses, int count) +hda_send_verbs(hda_codec* codec, corb_t* verbs, uint32* responses, uint32 count) { hda_controller *controller = codec->controller; uint32 sent = 0; @@ -410,7 +411,7 @@ hda_interrupt_handler(hda_controller* controller) if ((responseFlags & RESPONSE_FLAGS_UNSOLICITED) != 0) { dprintf("hda: Unsolicited response: %08lx/%08lx\n", - response, extendedResponse); + response, responseFlags); continue; } if (codec == NULL) { diff --git a/src/add-ons/kernel/drivers/audio/hda/hda_multi_audio.c b/src/add-ons/kernel/drivers/audio/hda/hda_multi_audio.cpp similarity index 87% rename from src/add-ons/kernel/drivers/audio/hda/hda_multi_audio.c rename to src/add-ons/kernel/drivers/audio/hda/hda_multi_audio.cpp index f40c82582a..942451030b 100644 --- a/src/add-ons/kernel/drivers/audio/hda/hda_multi_audio.c +++ b/src/add-ons/kernel/drivers/audio/hda/hda_multi_audio.cpp @@ -188,11 +188,6 @@ list_mix_channels(hda_audio_group* audioGroup, multi_mix_channel_info *data) static status_t get_buffers(hda_audio_group* audioGroup, multi_buffer_list* data) { - uint32 playbackSampleSize = audioGroup->playback_stream->sample_size; - uint32 recordSampleSize = audioGroup->record_stream->sample_size; - uint32 cidx, bidx; - status_t status; - TRACE("playback: %ld buffers, %ld channels, %ld samples\n", data->request_playback_buffers, data->request_playback_channels, data->request_playback_buffer_size); @@ -237,8 +232,8 @@ get_buffers(hda_audio_group* audioGroup, multi_buffer_list* data) audioGroup->playback_stream->buffer_length = data->return_playback_buffer_size; - status = hda_stream_setup_buffers(audioGroup, audioGroup->playback_stream, - "Playback"); + status_t status = hda_stream_setup_buffers(audioGroup, + audioGroup->playback_stream, "Playback"); if (status != B_OK) { dprintf("hda: Error setting up playback buffers: %s\n", strerror(status)); @@ -260,22 +255,27 @@ get_buffers(hda_audio_group* audioGroup, multi_buffer_list* data) /* Setup data structure for multi_audio API... */ - for (bidx = 0; bidx < data->return_playback_buffers; bidx++) { - for (cidx = 0; cidx < data->return_playback_channels; cidx++) { - data->playback_buffers[bidx][cidx].base - = audioGroup->playback_stream->buffers[bidx] - + playbackSampleSize * cidx; - data->playback_buffers[bidx][cidx].stride + uint32 playbackSampleSize = audioGroup->playback_stream->sample_size; + uint32 recordSampleSize = audioGroup->record_stream->sample_size; + + for (int32 i = 0; i < data->return_playback_buffers; i++) { + for (int32 channelIndex = 0; + channelIndex < data->return_playback_channels; channelIndex++) { + data->playback_buffers[i][channelIndex].base + = (char*)audioGroup->playback_stream->buffers[i] + + playbackSampleSize * channelIndex; + data->playback_buffers[i][channelIndex].stride = playbackSampleSize * data->return_playback_channels; } } - for (bidx = 0; bidx < data->return_record_buffers; bidx++) { - for (cidx = 0; cidx < data->return_record_channels; cidx++) { - data->record_buffers[bidx][cidx].base - = audioGroup->record_stream->buffers[bidx] - + recordSampleSize * cidx; - data->record_buffers[bidx][cidx].stride + for (int32 i = 0; i < data->return_record_buffers; i++) { + for (int32 channelIndex = 0; + channelIndex < data->return_record_channels; channelIndex++) { + data->record_buffers[i][channelIndex].base + = (char*)audioGroup->record_stream->buffers[i] + + recordSampleSize * channelIndex; + data->record_buffers[i][channelIndex].stride = recordSampleSize * data->return_record_channels; } } @@ -347,31 +347,34 @@ multi_audio_control(void* cookie, uint32 op, void* arg, size_t len) audioGroup = codec->audio_groups[0]; + // TODO: make userland-safe when built for Haiku! + switch (op) { case B_MULTI_GET_DESCRIPTION: - return get_description(audioGroup, arg); + return get_description(audioGroup, (multi_description*)arg); case B_MULTI_GET_ENABLED_CHANNELS: - return get_enabled_channels(audioGroup, arg); + return get_enabled_channels(audioGroup, (multi_channel_enable*)arg); case B_MULTI_SET_ENABLED_CHANNELS: return B_OK; case B_MULTI_GET_GLOBAL_FORMAT: - return get_global_format(audioGroup, arg); + return get_global_format(audioGroup, (multi_format_info*)arg); case B_MULTI_SET_GLOBAL_FORMAT: - return set_global_format(audioGroup, arg); + return set_global_format(audioGroup, (multi_format_info*)arg); case B_MULTI_LIST_MIX_CHANNELS: - return list_mix_channels(audioGroup, arg); + return list_mix_channels(audioGroup, (multi_mix_channel_info*)arg); case B_MULTI_LIST_MIX_CONTROLS: - return list_mix_controls(audioGroup, arg); + return list_mix_controls(audioGroup, (multi_mix_control_info*)arg); case B_MULTI_LIST_MIX_CONNECTIONS: - return list_mix_connections(audioGroup, arg); + return list_mix_connections(audioGroup, + (multi_mix_connection_info*)arg); case B_MULTI_GET_BUFFERS: - return get_buffers(audioGroup, arg); + return get_buffers(audioGroup, (multi_buffer_list*)arg); case B_MULTI_BUFFER_EXCHANGE: - return buffer_exchange(audioGroup, arg); + return buffer_exchange(audioGroup, (multi_buffer_info*)arg); case B_MULTI_BUFFER_FORCE_STOP: return buffer_force_stop(audioGroup);