hda: detect some audio devices per device ID
as it's possible they use the audio class_sub instead of hd_audio. * also power up the audio function, this seems required on Jasper Lake. * tested on Acer Swift 1 SF114-34. Change-Id: I603018b1b973e7884aa99a58be1c24e568f2d5ae Reviewed-on: https://review.haiku-os.org/c/haiku/+/4928 Reviewed-by: waddlesplash <waddlesplash@gmail.com> Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org>
This commit is contained in:
parent
a8d965a0c4
commit
32f411b9ab
@ -18,6 +18,34 @@ pci_module_info* gPci;
|
||||
pci_x86_module_info* gPCIx86Module;
|
||||
|
||||
|
||||
static struct {
|
||||
uint16 vendor;
|
||||
uint16 device;
|
||||
} kSupportedDevices[] = {
|
||||
{ 0x8086, 0x9d71}, // 200 Series HD Audio
|
||||
{ 0x8086, 0x9dc8}, // 300 Series HD Audio
|
||||
{ 0x8086, 0x06c8}, // 400 Series cAVS
|
||||
{ 0x8086, 0xa0c8}, // 500 Series HD Audio
|
||||
{ 0x8086, 0x4dc8}, // JasperLake HD Audio
|
||||
{ 0x8086, 0x43c8}, // Tiger Lake-H HD Audio
|
||||
{ 0x8086, 0xa171}, // CM238 HD Audio
|
||||
{ 0x8086, 0x3198}, // GeminiLake HD Audio
|
||||
};
|
||||
|
||||
|
||||
static bool
|
||||
supports_device(pci_info &info)
|
||||
{
|
||||
for (size_t i = 0; i < B_COUNT_OF(kSupportedDevices); i++) {
|
||||
if (info.vendor_id == kSupportedDevices[i].vendor
|
||||
&& info.device_id == kSupportedDevices[i].device) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
extern "C" status_t
|
||||
init_hardware(void)
|
||||
{
|
||||
@ -28,8 +56,9 @@ init_hardware(void)
|
||||
return ENODEV;
|
||||
|
||||
for (i = 0; gPci->get_nth_pci_info(i, &info) == B_OK; i++) {
|
||||
if (info.class_base == PCI_multimedia
|
||||
&& info.class_sub == PCI_hd_audio) {
|
||||
if ((info.class_base == PCI_multimedia
|
||||
&& info.class_sub == PCI_hd_audio)
|
||||
|| supports_device(info)) {
|
||||
put_module(B_PCI_MODULE_NAME);
|
||||
return B_OK;
|
||||
}
|
||||
@ -54,8 +83,9 @@ init_driver(void)
|
||||
|
||||
for (i = 0; gPci->get_nth_pci_info(i, &info) == B_OK
|
||||
&& gNumCards < MAX_CARDS; i++) {
|
||||
if (info.class_base == PCI_multimedia
|
||||
&& info.class_sub == PCI_hd_audio) {
|
||||
if ((info.class_base == PCI_multimedia
|
||||
&& info.class_sub == PCI_hd_audio)
|
||||
|| supports_device(info)) {
|
||||
#ifdef __HAIKU__
|
||||
if ((*gPci->reserve_device)(info.bus, info.device, info.function,
|
||||
"hda", &gCards[gNumCards]) < B_OK) {
|
||||
|
@ -720,6 +720,12 @@ hda_codec_parse_audio_group(hda_audio_group* audioGroup)
|
||||
|
||||
hda_codec* codec = audioGroup->codec;
|
||||
uint32 codec_id = (codec->vendor_id << 16) | codec->product_id;
|
||||
|
||||
// Power up the audio function
|
||||
verbs[0] = MAKE_VERB(audioGroup->codec->addr, audioGroup->widget.node_id,
|
||||
VID_SET_POWER_STATE, 0);
|
||||
hda_send_verbs(audioGroup->codec, verbs, NULL, 1);
|
||||
|
||||
hda_widget_get_stream_support(audioGroup, &audioGroup->widget);
|
||||
hda_widget_get_pm_support(audioGroup, &audioGroup->widget);
|
||||
hda_widget_get_amplifier_capabilities(audioGroup, &audioGroup->widget);
|
||||
|
@ -18,6 +18,14 @@
|
||||
#include "hda_codec_defs.h"
|
||||
|
||||
|
||||
//#define TRACE_HDA_VERBS
|
||||
#ifdef TRACE_HDA_VERBS
|
||||
# define TRACE_VERBS(x...) dprintf("\33[33mhda:\33[0m " x)
|
||||
#else
|
||||
# define TRACE_VERBS(x...) ;
|
||||
#endif
|
||||
|
||||
|
||||
#define MAKE_RATE(base, multiply, divide) \
|
||||
((base == 44100 ? FORMAT_44_1_BASE_RATE : 0) \
|
||||
| ((multiply - 1) << FORMAT_MULTIPLY_RATE_SHIFT) \
|
||||
@ -1026,6 +1034,9 @@ hda_send_verbs(hda_codec* codec, corb_t* verbs, uint32* responses, uint32 count)
|
||||
}
|
||||
|
||||
controller->corb[writePos] = verbs[sent++];
|
||||
TRACE_VERBS("send_verb: (%02x:%02x.%x:%u) cmd 0x%08" B_PRIx32 "\n",
|
||||
controller->pci_info.bus, controller->pci_info.device,
|
||||
controller->pci_info.function, codec->addr, controller->corb[writePos]);
|
||||
controller->corb_write_pos = writePos;
|
||||
queued++;
|
||||
}
|
||||
@ -1037,8 +1048,13 @@ hda_send_verbs(hda_codec* codec, corb_t* verbs, uint32* responses, uint32 count)
|
||||
return status;
|
||||
}
|
||||
|
||||
if (responses != NULL)
|
||||
if (responses != NULL) {
|
||||
TRACE_VERBS("send_verb: (%02x:%02x.%x:%u) resp 0x%08" B_PRIx32 "\n",
|
||||
controller->pci_info.bus, controller->pci_info.device,
|
||||
controller->pci_info.function, codec->addr, codec->responses[0]);
|
||||
|
||||
memcpy(responses, codec->responses, count * sizeof(uint32));
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
@ -1321,6 +1337,14 @@ hda_hw_stop(hda_controller* controller)
|
||||
if (controller->streams[index] && controller->streams[index]->running)
|
||||
hda_stream_stop(controller, controller->streams[index]);
|
||||
}
|
||||
|
||||
// Power off the audio functions
|
||||
for (uint32 index = 0; index < controller->active_codec->num_audio_groups; index++) {
|
||||
hda_audio_group* audioGroup = controller->active_codec->audio_groups[index];
|
||||
corb_t verb = MAKE_VERB(audioGroup->codec->addr, audioGroup->widget.node_id,
|
||||
VID_SET_POWER_STATE, 3);
|
||||
hda_send_verbs(audioGroup->codec, &verb, NULL, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user