[haiku-commits] haiku: hrev55585 - src/add-ons/kernel/drivers/audio/hda

  • From: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Sun, 24 Oct 2021 09:58:59 +0000 (UTC)

hrev55585 adds 1 changeset to branch 'master'
old head: b594d76c81522870f97c5bb7ec6f48e3d6374ab7
new head: 69958ca2efd69e0c2ed37c0a512dd2125594e655
overview: 
https://git.haiku-os.org/haiku/log/?qt=range&q=69958ca2efd6+%5Eb594d76c8152

----------------------------------------------------------------------------

69958ca2efd6: hda: subsystem is from the codec, not the PCI bus.
  
  * Refactors so that we look for a codec subsystem ID, then the
    Audio Function Group subsystem ID if not found.
  * Moves the order around a bit so that the quirks are set early
    enough.
  * Also adds a quirk for MacBookAir 6,2, allows speakers to work.
  
  Change-Id: I4c64f96936a82a5d7187d86d8558f28516fd4ecb
  Reviewed-on: https://review.haiku-os.org/c/haiku/+/4654
  Reviewed-by: Adrien Destugues <pulkomandy@xxxxxxxxx>
  Tested-by: Commit checker robot <no-reply+buildbot@xxxxxxxxxxxx>

                         [ Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> ]

----------------------------------------------------------------------------

Revision:    hrev55585
Commit:      69958ca2efd69e0c2ed37c0a512dd2125594e655
URL:         https://git.haiku-os.org/haiku/commit/?id=69958ca2efd6
Author:      Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx>
Date:        Sun Oct 24 08:47:24 2021 UTC

----------------------------------------------------------------------------

3 files changed, 38 insertions(+), 19 deletions(-)
src/add-ons/kernel/drivers/audio/hda/driver.h    |  1 +
.../kernel/drivers/audio/hda/hda_codec.cpp       | 55 +++++++++++++-------
.../kernel/drivers/audio/hda/hda_codec_defs.h    |  1 +

----------------------------------------------------------------------------

diff --git a/src/add-ons/kernel/drivers/audio/hda/driver.h 
b/src/add-ons/kernel/drivers/audio/hda/driver.h
index 89c7604f66..9045e51de0 100644
--- a/src/add-ons/kernel/drivers/audio/hda/driver.h
+++ b/src/add-ons/kernel/drivers/audio/hda/driver.h
@@ -292,6 +292,7 @@ struct hda_audio_group {
 struct hda_codec {
        uint16          vendor_id;
        uint16          product_id;
+       uint32          subsystem_id;
        uint8           major;
        uint8           minor;
        uint8           revision;
diff --git a/src/add-ons/kernel/drivers/audio/hda/hda_codec.cpp 
b/src/add-ons/kernel/drivers/audio/hda/hda_codec.cpp
index 8c377abd9a..b08f95e4e9 100644
--- a/src/add-ons/kernel/drivers/audio/hda/hda_codec.cpp
+++ b/src/add-ons/kernel/drivers/audio/hda/hda_codec.cpp
@@ -95,6 +95,8 @@ static const struct {
                HDA_QUIRK_GPIO0 | HDA_QUIRK_OVREF50, 0},        // MacBook
        { 0x106b, 0x00a3, REALTEK_VENDORID, 0x0885,
                HDA_QUIRK_GPIO0, 0},                                            
// MacBook
+       { 0x106b, 0x7200, CIRRUSLOGIC_VENDORID, 0x4208,
+               HDA_QUIRK_GPIO0, 0},                                            
// MacBookAir 6,2
        { HDA_ALL, HDA_ALL, IDT_VENDORID, 0x76b2, HDA_QUIRK_GPIO0, 0},
 };
 
@@ -363,9 +365,8 @@ hda_codec_get_quirks(hda_codec* codec)
 {
        codec->quirks = 0;
 
-       uint32 subSystemID = codec->controller->pci_info.u.h0.subsystem_id;
-       uint32 subSystemVendorID
-               = codec->controller->pci_info.u.h0.subsystem_vendor_id;
+       uint32 subSystemID = codec->subsystem_id & 0xffff;
+       uint32 subSystemVendorID = codec->subsystem_id >> 16;
 
        for (uint32 i = 0;
                        i < (sizeof(kCodecQuirks) / sizeof(kCodecQuirks[0])); 
i++) {
@@ -1496,6 +1497,7 @@ hda_codec_new(hda_controller* controller, uint32 
codecAddress)
        struct {
                uint32 device : 16;
                uint32 vendor : 16;
+               uint32 subsystem : 32;
                uint32 stepping : 8;
                uint32 revision : 8;
                uint32 minor : 4;
@@ -1507,13 +1509,14 @@ hda_codec_new(hda_controller* controller, uint32 
codecAddress)
                uint32 _reserved2 : 8;
        } response;
 
-       corb_t verbs[3];
+       corb_t verbs[4];
        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[1] = MAKE_VERB(codecAddress, 0, VID_GET_PARAMETER, 
PID_SUBSYSTEM_ID);
+       verbs[2] = MAKE_VERB(codecAddress, 0, VID_GET_PARAMETER, 
PID_REVISION_ID);
+       verbs[3] = MAKE_VERB(codecAddress, 0, VID_GET_PARAMETER,
                PID_SUB_NODE_COUNT);
 
-       status = hda_send_verbs(codec, verbs, (uint32*)&response, 3);
+       status = hda_send_verbs(codec, verbs, (uint32*)&response, 4);
        if (status != B_OK) {
                ERROR("Failed to get vendor and revision parameters: %s\n",
                        strerror(status));
@@ -1521,6 +1524,7 @@ hda_codec_new(hda_controller* controller, uint32 
codecAddress)
        }
 
        codec->vendor_id = response.vendor;
+       codec->subsystem_id = response.subsystem;
        codec->product_id = response.device;
        codec->stepping = response.stepping;
        codec->revision = response.revision;
@@ -1528,29 +1532,30 @@ hda_codec_new(hda_controller* controller, uint32 
codecAddress)
        codec->major = response.major;
        hda_codec_get_quirks(codec);
 
-       TRACE("Codec %" B_PRIu32 " Vendor: %04" B_PRIx32 " "
-               "Product: %04" B_PRIx32 ", "
-               "Revision: %" B_PRIu32 ".%" B_PRIu32 ".%" B_PRIu32 ".%" 
B_PRIu32 " "
-               "Quirks: %04" B_PRIx32 "\n",
-               codecAddress, response.vendor,
-               response.device,
-               response.major, response.minor, response.revision, 
response.stepping,
-               codec->quirks);
-
        for (uint32 nodeID = response.start;
                        nodeID < response.start + response.count; nodeID++) {
-               uint32 groupType;
+               struct {
+                       uint32 groupType;
+                       uint32 subsystem;
+               } functionResponse;
                verbs[0] = MAKE_VERB(codecAddress, nodeID, VID_GET_PARAMETER,
                        PID_FUNCTION_GROUP_TYPE);
+               verbs[1] = MAKE_VERB(codecAddress, nodeID, VID_GET_SUBSYSTEMID, 
0);
 
-               if (hda_send_verbs(codec, verbs, &groupType, 1) != B_OK) {
+               if (hda_send_verbs(codec, verbs, (uint32*)&functionResponse, 2) 
!= B_OK) {
                        ERROR("Failed to get function group type\n");
                        goto err;
                }
 
-               if ((groupType & FUNCTION_GROUP_NODETYPE_MASK)
+               if ((functionResponse.groupType & FUNCTION_GROUP_NODETYPE_MASK)
                                == FUNCTION_GROUP_NODETYPE_AUDIO) {
                        // Found an Audio Function Group!
+                       if (response.subsystem == 0 && 
functionResponse.subsystem != 0) {
+                               // Update our subsystem, and re-check quirks 
for this codec
+                               codec->subsystem_id = 
functionResponse.subsystem;
+                               hda_codec_get_quirks(codec);
+                       }
+
                        status_t status = hda_codec_new_audio_group(codec, 
nodeID);
                        if (status != B_OK) {
                                ERROR("Failed to setup new audio function group 
(%s)!\n",
@@ -1560,6 +1565,18 @@ hda_codec_new(hda_controller* controller, uint32 
codecAddress)
                }
        }
 
+       TRACE("Codec %" B_PRIu32 " Vendor: %04" B_PRIx32 " "
+               "Product: %04" B_PRIx32 " "
+               "Subsystem: %08" B_PRIx32 ", "
+               "Revision: %" B_PRIu32 ".%" B_PRIu32 ".%" B_PRIu32 ".%" 
B_PRIu32 " "
+               "Quirks: %04" B_PRIx32 "\n",
+               codecAddress,
+               response.vendor,
+               response.device,
+               codec->subsystem_id,
+               response.major, response.minor, response.revision, 
response.stepping,
+               codec->quirks);
+
        codec->unsol_response_thread = spawn_kernel_thread(
                (status_t(*)(void*))hda_codec_switch_handler,
                "hda_codec_unsol_thread", B_LOW_PRIORITY, codec);
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 94797c2f71..b3eb6c4c7c 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
@@ -143,6 +143,7 @@ enum pin_dev_type {
 
 /* Parameter IDs */
 #define PID_VENDOR_ID                                  0x00
+#define PID_SUBSYSTEM_ID                               0x01
 #define PID_REVISION_ID                                        0x02
 #define PID_SUB_NODE_COUNT                             0x04
 #define PID_FUNCTION_GROUP_TYPE                        0x05


Other related posts:

  • » [haiku-commits] haiku: hrev55585 - src/add-ons/kernel/drivers/audio/hda - Jessica Hamilton