Renamed .c to .cpp, and fixed all warnings.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24178 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
105152d1f5
commit
340dd4fe3d
@ -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 :
|
||||
|
@ -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;
|
||||
}
|
@ -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__);
|
@ -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);
|
||||
|
@ -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;
|
@ -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 */
|
||||
|
@ -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) {
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user