introduced a widget inside the audio function group to extract widget node attributes and reuse functions.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@28697 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
52a7c90673
commit
34bda3ae2d
@ -241,22 +241,15 @@ struct hda_association {
|
||||
*/
|
||||
struct hda_audio_group {
|
||||
hda_codec* codec;
|
||||
hda_widget widget;
|
||||
|
||||
/* 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;
|
||||
|
||||
uint32 input_amplifier_capabilities;
|
||||
uint32 output_amplifier_capabilities;
|
||||
|
||||
uint32 association_count;
|
||||
|
||||
hda_widget* widgets;
|
||||
|
@ -286,10 +286,11 @@ hda_widget_get_pm_support(hda_audio_group* audioGroup, hda_widget* widget)
|
||||
static status_t
|
||||
hda_widget_get_stream_support(hda_audio_group* audioGroup, hda_widget* widget)
|
||||
{
|
||||
if ((widget->capabilities.audio & AUDIO_CAP_FORMAT_OVERRIDE) == 0) {
|
||||
if (audioGroup->widget.node_id != widget->node_id
|
||||
&& (widget->capabilities.audio & AUDIO_CAP_FORMAT_OVERRIDE) == 0) {
|
||||
// adopt capabilities of the audio group
|
||||
widget->d.io.formats = audioGroup->supported_formats;
|
||||
widget->d.io.rates = audioGroup->supported_rates;
|
||||
widget->d.io.formats = audioGroup->widget.d.io.formats;
|
||||
widget->d.io.rates = audioGroup->widget.d.io.rates;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@ -305,8 +306,10 @@ hda_widget_get_amplifier_capabilities(hda_audio_group* audioGroup,
|
||||
uint32 response;
|
||||
corb_t verb;
|
||||
|
||||
if ((widget->capabilities.audio & AUDIO_CAP_OUTPUT_AMPLIFIER) != 0) {
|
||||
if ((widget->capabilities.audio & AUDIO_CAP_AMPLIFIER_OVERRIDE) != 0) {
|
||||
if ((widget->capabilities.audio & AUDIO_CAP_OUTPUT_AMPLIFIER) != 0
|
||||
|| audioGroup->widget.node_id == widget->node_id) {
|
||||
if ((widget->capabilities.audio & AUDIO_CAP_AMPLIFIER_OVERRIDE) != 0
|
||||
|| audioGroup->widget.node_id == widget->node_id) {
|
||||
verb = MAKE_VERB(audioGroup->codec->addr, widget->node_id,
|
||||
VID_GET_PARAMETER, PID_OUTPUT_AMPLIFIER_CAP);
|
||||
status_t status = hda_send_verbs(audioGroup->codec, &verb,
|
||||
@ -318,12 +321,14 @@ hda_widget_get_amplifier_capabilities(hda_audio_group* audioGroup,
|
||||
} else {
|
||||
// adopt capabilities from the audio function group
|
||||
widget->capabilities.output_amplifier
|
||||
= audioGroup->output_amplifier_capabilities;
|
||||
= audioGroup->widget.capabilities.output_amplifier;
|
||||
}
|
||||
}
|
||||
|
||||
if ((widget->capabilities.audio & AUDIO_CAP_INPUT_AMPLIFIER) != 0) {
|
||||
if ((widget->capabilities.audio & AUDIO_CAP_AMPLIFIER_OVERRIDE) != 0) {
|
||||
if ((widget->capabilities.audio & AUDIO_CAP_INPUT_AMPLIFIER) != 0
|
||||
|| audioGroup->widget.node_id == widget->node_id) {
|
||||
if ((widget->capabilities.audio & AUDIO_CAP_AMPLIFIER_OVERRIDE
|
||||
|| audioGroup->widget.node_id == widget->node_id) != 0) {
|
||||
verb = MAKE_VERB(audioGroup->codec->addr, widget->node_id,
|
||||
VID_GET_PARAMETER, PID_INPUT_AMPLIFIER_CAP);
|
||||
status_t status = hda_send_verbs(audioGroup->codec, &verb,
|
||||
@ -335,7 +340,7 @@ hda_widget_get_amplifier_capabilities(hda_audio_group* audioGroup,
|
||||
} else {
|
||||
// adopt capabilities from the audio function group
|
||||
widget->capabilities.input_amplifier
|
||||
= audioGroup->input_amplifier_capabilities;
|
||||
= audioGroup->widget.capabilities.input_amplifier;
|
||||
}
|
||||
}
|
||||
|
||||
@ -478,32 +483,32 @@ hda_codec_parse_audio_group(hda_audio_group* audioGroup)
|
||||
corb_t verbs[3];
|
||||
uint32 resp[3];
|
||||
|
||||
hda_get_stream_support(audioGroup->codec, audioGroup->root_node_id,
|
||||
&audioGroup->supported_formats, &audioGroup->supported_rates);
|
||||
hda_get_pm_support(audioGroup->codec, audioGroup->root_node_id,
|
||||
&audioGroup->supported_pm);
|
||||
|
||||
verbs[0] = MAKE_VERB(audioGroup->codec->addr, audioGroup->root_node_id,
|
||||
hda_widget_get_stream_support(audioGroup, &audioGroup->widget);
|
||||
hda_widget_get_pm_support(audioGroup, &audioGroup->widget);
|
||||
hda_widget_get_amplifier_capabilities(audioGroup, &audioGroup->widget);
|
||||
|
||||
verbs[0] = MAKE_VERB(audioGroup->codec->addr, audioGroup->widget.node_id,
|
||||
VID_GET_PARAMETER, PID_AUDIO_GROUP_CAP);
|
||||
verbs[1] = MAKE_VERB(audioGroup->codec->addr, audioGroup->root_node_id,
|
||||
verbs[1] = MAKE_VERB(audioGroup->codec->addr, audioGroup->widget.node_id,
|
||||
VID_GET_PARAMETER, PID_GPIO_COUNT);
|
||||
verbs[2] = MAKE_VERB(audioGroup->codec->addr, audioGroup->root_node_id,
|
||||
verbs[2] = MAKE_VERB(audioGroup->codec->addr, audioGroup->widget.node_id,
|
||||
VID_GET_PARAMETER, PID_SUB_NODE_COUNT);
|
||||
|
||||
if (hda_send_verbs(audioGroup->codec, verbs, resp, 3) != B_OK)
|
||||
return B_ERROR;
|
||||
|
||||
dprintf("hda: Audio Group: Output delay: %ld samples, Input delay: %ld "
|
||||
"samples, Beep Generator: %s\n", resp[0] & 0xf,
|
||||
(resp[0] >> 8) & 0xf, (resp[0] & (1 << 16)) ? "yes" : "no");
|
||||
"samples, Beep Generator: %s\n", AUDIO_GROUP_CAP_OUTPUT_DELAY(resp[0]),
|
||||
AUDIO_GROUP_CAP_INPUT_DELAY(resp[0]),
|
||||
AUDIO_GROUP_CAP_BEEPGEN(resp[0]) ? "yes" : "no");
|
||||
|
||||
dprintf("hda: #GPIO: %ld, #GPO: %ld, #GPI: %ld, unsol: %s, wake: %s\n",
|
||||
resp[4] & 0xff, (resp[1] >> 8) & 0xff,
|
||||
(resp[1] >> 16) & 0xff, (resp[1] & (1 << 30)) ? "yes" : "no",
|
||||
(resp[1] & (1 << 31)) ? "yes" : "no");
|
||||
GPIO_COUNT_NUM_GPIO(resp[1]), GPIO_COUNT_NUM_GPO(resp[1]),
|
||||
GPIO_COUNT_NUM_GPI(resp[1]), GPIO_COUNT_GPIUNSOL(resp[1]) ? "yes" : "no",
|
||||
GPIO_COUNT_GPIWAKE(resp[1]) ? "yes" : "no");
|
||||
|
||||
audioGroup->widget_start = resp[2] >> 16;
|
||||
audioGroup->widget_count = resp[2] & 0xff;
|
||||
audioGroup->widget_start = SUB_NODE_COUNT_START(resp[2]);
|
||||
audioGroup->widget_count = SUB_NODE_COUNT_TOTAL(resp[2]);
|
||||
|
||||
dprintf("hda: widget start %lu, count %lu\n", audioGroup->widget_start,
|
||||
audioGroup->widget_count);
|
||||
@ -873,7 +878,7 @@ hda_codec_new_audio_group(hda_codec* codec, uint32 audioGroupNodeID)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
/* Setup minimal info needed by hda_codec_parse_afg */
|
||||
audioGroup->root_node_id = audioGroupNodeID;
|
||||
audioGroup->widget.node_id = audioGroupNodeID;
|
||||
audioGroup->codec = codec;
|
||||
audioGroup->multi = (hda_multi*)calloc(1,
|
||||
sizeof(hda_multi));
|
||||
@ -1052,7 +1057,7 @@ hda_codec_new(hda_controller* controller, uint32 codecAddress)
|
||||
|
||||
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,
|
||||
verbs[2] = MAKE_VERB(codecAddress, 0, VID_GET_PARAMETER,
|
||||
PID_SUB_NODE_COUNT);
|
||||
|
||||
if (hda_send_verbs(codec, verbs, (uint32*)&response, 3) != B_OK)
|
||||
@ -1078,7 +1083,7 @@ hda_codec_new(hda_controller* controller, uint32 codecAddress)
|
||||
if (hda_send_verbs(codec, verbs, &groupType, 1) != B_OK)
|
||||
goto err;
|
||||
|
||||
if ((groupType & 0xff) == 1) {
|
||||
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) {
|
||||
|
@ -142,6 +142,40 @@ enum pin_dev_type {
|
||||
#define PID_OUTPUT_AMPLIFIER_CAP 0x12
|
||||
#define PID_VOLUME_KNOB_CAP 0x13
|
||||
|
||||
/* Subordinate node count */
|
||||
#define SUB_NODE_COUNT_TOTAL_MASK 0x000000ff
|
||||
#define SUB_NODE_COUNT_TOTAL_SHIFT 0
|
||||
#define SUB_NODE_COUNT_START_MASK 0x00ff0000
|
||||
#define SUB_NODE_COUNT_START_SHIFT 16
|
||||
|
||||
#define SUB_NODE_COUNT_TOTAL(c) ((c & SUB_NODE_COUNT_TOTAL_MASK) \
|
||||
>> SUB_NODE_COUNT_TOTAL_SHIFT)
|
||||
#define SUB_NODE_COUNT_START(c) ((c & SUB_NODE_COUNT_START_MASK) \
|
||||
>> SUB_NODE_COUNT_START_SHIFT)
|
||||
|
||||
/* Function group type */
|
||||
#define FUNCTION_GROUP_NODETYPE_MASK 0x000000ff
|
||||
#define FUNCTION_GROUP_UNSOLCAPABLE_MASK 0x00000100
|
||||
|
||||
#define FUNCTION_GROUP_NODETYPE_AUDIO 0x00000001
|
||||
#define FUNCTION_GROUP_NODETYPE_MODEM 0x00000002
|
||||
|
||||
/* Audio Function group capabilities */
|
||||
#define AUDIO_GROUP_CAP_OUTPUT_DELAY_MASK 0x0000000f
|
||||
#define AUDIO_GROUP_CAP_OUTPUT_DELAY_SHIFT 0
|
||||
#define AUDIO_GROUP_CAP_INPUT_DELAY_MASK 0x00000f00
|
||||
#define AUDIO_GROUP_CAP_INPUT_DELAY_SHIFT 8
|
||||
#define AUDIO_GROUP_CAP_BEEPGEN_MASK 0x00010000
|
||||
#define AUDIO_GROUP_CAP_BEEPGEN_SHIFT 16
|
||||
|
||||
#define AUDIO_GROUP_CAP_OUTPUT_DELAY(c) ((c & AUDIO_GROUP_CAP_OUTPUT_DELAY_MASK) \
|
||||
>> AUDIO_GROUP_CAP_OUTPUT_DELAY_SHIFT)
|
||||
#define AUDIO_GROUP_CAP_INPUT_DELAY(c) ((c & AUDIO_GROUP_CAP_INPUT_DELAY_MASK) \
|
||||
>> AUDIO_GROUP_CAP_INPUT_DELAY_SHIFT)
|
||||
#define AUDIO_GROUP_CAP_BEEPGEN(c) ((c & AUDIO_GROUP_CAP_BEEPGEN_MASK) \
|
||||
>> AUDIO_GROUP_CAP_BEEPGEN_SHIFT)
|
||||
|
||||
|
||||
/* Audio widget capabilities */
|
||||
#define AUDIO_CAP_DELAY_MASK 0x000f0000
|
||||
#define AUDIO_CAP_DELAY_SHIFT 16
|
||||
@ -263,4 +297,23 @@ enum pin_dev_type {
|
||||
#define CONF_DEFAULT_LOCATION(c) ((c & CONF_DEFAULT_LOCATION_MASK) >> CONF_DEFAULT_LOCATION_SHIFT)
|
||||
#define CONF_DEFAULT_CONNECTIVITY(c) ((c & CONF_DEFAULT_CONNECTIVITY_MASK) >> CONF_DEFAULT_CONNECTIVITY_SHIFT)
|
||||
|
||||
/* GP I/O count */
|
||||
#define GPIO_COUNT_NUM_GPIO_MASK 0x000000ff
|
||||
#define GPIO_COUNT_NUM_GPIO_SHIFT 0
|
||||
#define GPIO_COUNT_NUM_GPO_MASK 0x0000ff00
|
||||
#define GPIO_COUNT_NUM_GPO_SHIFT 8
|
||||
#define GPIO_COUNT_NUM_GPI_MASK 0x00ff0000
|
||||
#define GPIO_COUNT_NUM_GPI_SHIFT 16
|
||||
#define GPIO_COUNT_GPIUNSOL_MASK 0x40000000
|
||||
#define GPIO_COUNT_GPIUNSOL_SHIFT 30
|
||||
#define GPIO_COUNT_GPIWAKE_MASK 0x80000000
|
||||
#define GPIO_COUNT_GPIWAKE_SHIFT 31
|
||||
|
||||
#define GPIO_COUNT_NUM_GPIO(c) ((c & GPIO_COUNT_NUM_GPIO_MASK) >> GPIO_COUNT_NUM_GPIO_SHIFT)
|
||||
#define GPIO_COUNT_NUM_GPO(c) ((c & GPIO_COUNT_NUM_GPO_MASK) >> GPIO_COUNT_NUM_GPO_SHIFT)
|
||||
#define GPIO_COUNT_NUM_GPI(c) ((c & GPIO_COUNT_NUM_GPI_MASK) >> GPIO_COUNT_NUM_GPI_SHIFT)
|
||||
#define GPIO_COUNT_GPIUNSOL(c) ((c & GPIO_COUNT_GPIUNSOL_MASK) >> GPIO_COUNT_GPIUNSOL_SHIFT)
|
||||
#define GPIO_COUNT_GPIWAKE(c) ((c & GPIO_COUNT_GPIWAKE_MASK) >> GPIO_COUNT_GPIWAKE_SHIFT)
|
||||
|
||||
|
||||
#endif /* HDA_CODEC_H */
|
||||
|
@ -98,8 +98,8 @@ get_description(hda_audio_group* audioGroup, multi_description* data)
|
||||
}
|
||||
|
||||
/* determine output/input rates */
|
||||
data->output_rates = audioGroup->supported_rates;
|
||||
data->input_rates = audioGroup->supported_rates;
|
||||
data->output_rates = audioGroup->widget.d.io.rates;
|
||||
data->input_rates = audioGroup->widget.d.io.rates;
|
||||
|
||||
/* force existance of 48kHz if variable rates are not supported */
|
||||
if (data->output_rates == 0)
|
||||
@ -110,8 +110,8 @@ get_description(hda_audio_group* audioGroup, multi_description* data)
|
||||
data->max_cvsr_rate = 0;
|
||||
data->min_cvsr_rate = 0;
|
||||
|
||||
data->output_formats = audioGroup->supported_formats;
|
||||
data->input_formats = audioGroup->supported_formats;
|
||||
data->output_formats = audioGroup->widget.d.io.formats;
|
||||
data->input_formats = audioGroup->widget.d.io.formats;
|
||||
data->lock_sources = B_MULTI_LOCK_INTERNAL;
|
||||
data->timecode_sources = 0;
|
||||
data->interface_flags = B_MULTI_INTERFACE_PLAYBACK | B_MULTI_INTERFACE_RECORD;
|
||||
|
Loading…
Reference in New Issue
Block a user