* try to enable EAPD on capable pin widgets

* added a pin capabilities attribute instead of input and output pin attributes
* added ATI and nVidia vendor ids definitions
* uses "mic in" and "line in" when pin colors are undefined


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@28839 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Jérôme Duval 2009-01-01 17:13:43 +00:00
parent 321e633fa4
commit c71a6614e2
6 changed files with 50 additions and 19 deletions

View File

@ -216,8 +216,7 @@ struct hda_widget {
struct {
} mixer;
struct {
uint32 output;
uint32 input;
uint32 capabilities;
uint32 config;
} pin;
} d;

View File

@ -168,8 +168,8 @@ dump_audiogroup_widgets(hda_audio_group* audioGroup)
break;
case WT_PIN_COMPLEX:
dprintf("\t%s%s\n", widget.d.pin.input ? "[Input] " : "",
widget.d.pin.output ? "[Output]" : "");
dprintf("\t%s%s\n", PIN_CAP_IS_INPUT(widget.d.pin.capabilities) ? "[Input] " : "",
PIN_CAP_IS_OUTPUT(widget.d.pin.capabilities) ? "[Output]" : "");
break;
@ -586,11 +586,10 @@ hda_codec_parse_audio_group(hda_audio_group* audioGroup)
verbs[0] = MAKE_VERB(audioGroup->codec->addr, nodeID,
VID_GET_PARAMETER, PID_PIN_CAP);
if (hda_send_verbs(audioGroup->codec, verbs, resp, 1) == B_OK) {
widget.d.pin.input = resp[0] & PIN_CAP_IN;
widget.d.pin.output = resp[0] & PIN_CAP_OUT;
dprintf("\t%s%s\n", widget.d.pin.input ? "[Input] " : "",
widget.d.pin.output ? "[Output]" : "");
widget.d.pin.capabilities = resp[0];
dprintf("\t%s%s\n", PIN_CAP_IS_INPUT(resp[0]) ? "[Input] " : "",
PIN_CAP_IS_OUTPUT(resp[0]) ? "[Output]" : "");
} else {
dprintf("%s: Error getting Pin Complex IO\n", __func__);
}
@ -689,7 +688,7 @@ hda_widget_find_input_path(hda_audio_group* audioGroup, hda_widget* widget,
if (widget->flags & WIDGET_FLAG_INPUT_PATH)
return false;
if (widget->d.pin.input) {
if (PIN_CAP_IS_INPUT(widget->d.pin.capabilities)) {
switch (CONF_DEFAULT_DEVICE(widget->d.pin.config)) {
case PIN_DEV_CD:
case PIN_DEV_LINE_IN:
@ -743,7 +742,7 @@ dprintf("build output tree: %suse mixer\n", useMixer ? "" : "don't ");
for (uint32 i = 0; i < audioGroup->widget_count; i++) {
hda_widget& widget = audioGroup->widgets[i];
if (widget.type != WT_PIN_COMPLEX || !widget.d.pin.output)
if (widget.type != WT_PIN_COMPLEX || !PIN_CAP_IS_OUTPUT(widget.d.pin.capabilities))
continue;
int device = CONF_DEFAULT_DEVICE(widget.d.pin.config);
@ -957,6 +956,22 @@ dprintf("ENABLE pin widget %ld\n", widget.node_id);
PIN_ENABLE_HEAD_PHONE | PIN_ENABLE_OUTPUT
: PIN_ENABLE_INPUT);
hda_send_verbs(audioGroup->codec, &verb, NULL, 1);
if (PIN_CAP_IS_EAPD_CAP(widget.d.pin.capabilities)) {
uint32 result;
verb = MAKE_VERB(audioGroup->codec->addr,
widget.node_id, VID_GET_EAPDBTL_EN, 0);
if (hda_send_verbs(audioGroup->codec, &verb,
&result, 1) == B_OK) {
result &= 0xff;
verb = MAKE_VERB(audioGroup->codec->addr,
widget.node_id, VID_SET_EAPDBTL_EN,
result | EAPDBTL_ENABLE_EAPD);
hda_send_verbs(audioGroup->codec,
&verb, NULL, 1);
dprintf("ENABLE EAPD pin widget %ld\n", widget.node_id);
}
}
}
if (widget.capabilities.output_amplifier != 0) {

View File

@ -214,8 +214,8 @@ enum pin_dev_type {
#define PIN_CAP_TRIGGER_REQ (1L << 1)
#define PIN_CAP_PRES_DETECT (1L << 2)
#define PIN_CAP_HP_DRIVE (1L << 3)
#define PIN_CAP_OUT (1L << 4)
#define PIN_CAP_IN (1L << 5)
#define PIN_CAP_OUTPUT (1L << 4)
#define PIN_CAP_INPUT (1L << 5)
#define PIN_CAP_BALANCE (1L << 6)
#define PIN_CAP_VREF_CTRL_HIZ (1L << 8)
#define PIN_CAP_VREF_CTRL_50 (1L << 9)
@ -224,6 +224,10 @@ enum pin_dev_type {
#define PIN_CAP_VREF_CTRL_100 (1L << 13)
#define PIN_CAP_EAPD_CAP (1L << 16)
#define PIN_CAP_IS_OUTPUT(c) ((c & PIN_CAP_OUTPUT) != 0)
#define PIN_CAP_IS_INPUT(c) ((c & PIN_CAP_INPUT) != 0)
#define PIN_CAP_IS_EAPD_CAP(c) ((c & PIN_CAP_EAPD_CAP) != 0)
/* PCM support */
#define PCM_8_BIT (1L << 16)
#define PCM_16_BIT (1L << 17)
@ -297,6 +301,11 @@ 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)
/* EAPD/BTL enable */
#define EAPDBTL_ENABLE_BTL 0x1
#define EAPDBTL_ENABLE_EAPD 0x2
#define EAPDBTL_ENABLE_LRSWAP 0x4
/* GP I/O count */
#define GPIO_COUNT_NUM_GPIO_MASK 0x000000ff
#define GPIO_COUNT_NUM_GPIO_SHIFT 0

View File

@ -744,13 +744,11 @@ hda_hw_init(hda_controller* controller)
/* Enable snooping for ATI and Nvidia, right now for all their hda-devices,
but only based on guessing. */
switch (controller->pci_info.vendor_id) {
/* NVIDIA */
case 0x10de:
case NVIDIA_VENDORID:
update_pci_register(controller, NVIDIA_HDA_TRANSREG,
NVIDIA_HDA_TRANSREG_MASK, NVIDIA_HDA_ENABLE_COHBITS);
break;
/* ATI */
case 0x1002:
case ATI_VENDORID:
update_pci_register(controller, ATI_HDA_MISC_CNTR2,
ATI_HDA_MISC_CNTR2_MASK, ATI_HDA_ENABLE_SNOOP);
break;

View File

@ -142,6 +142,11 @@
#define NVIDIA_HDA_TRANSREG_MASK 0xf0
#define NVIDIA_HDA_ENABLE_COHBITS 0x0f
#define ATI_VENDORID 0x1002
#define INTEL_VENDORID 0x8086
#define NVIDIA_VENDORID 0x10de
typedef uint32 corb_t;
typedef struct {

View File

@ -305,6 +305,11 @@ hda_find_multi_custom_string(hda_widget& widget)
case 9:
return "Mic in";
}
if (CONF_DEFAULT_DEVICE(widget.d.pin.config) == PIN_DEV_LINE_IN)
return "Line In";
if (CONF_DEFAULT_DEVICE(widget.d.pin.config) == PIN_DEV_MIC_IN)
return "Mic In";
return "Line Out";
break;
case PIN_DEV_SPDIF_IN:
return "SPDIF In";
@ -382,7 +387,7 @@ hda_create_controls_list(hda_multi *multi)
if (complex.type != WT_PIN_COMPLEX)
continue;
if (!complex.d.pin.output)
if (!PIN_CAP_IS_OUTPUT(complex.d.pin.capabilities))
continue;
if ((complex.flags & WIDGET_FLAG_OUTPUT_PATH) == 0)
continue;
@ -412,7 +417,7 @@ hda_create_controls_list(hda_multi *multi)
hda_widget *complex = hda_audio_group_get_widget(audioGroup, widget.inputs[j]);
if (complex->type != WT_PIN_COMPLEX)
continue;
if (!complex->d.pin.input)
if (!PIN_CAP_IS_INPUT(complex->d.pin.capabilities))
continue;
if (complex->flags & WIDGET_FLAG_OUTPUT_PATH)
continue;