// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "intel_hda_codec.h"

#include <fbl/algorithm.h>

#include <utility>

namespace audio {
namespace intel_hda {

IntelHDACodec::CodecTree IntelHDACodec::codecs_;

extern void print_codec_state(const CodecState& codec);

////////////////////////////////////////////////////////////////////////////////
//
// Parser and CommandList for fetching the currently configured unsolicited
// response state (present in both function groups and widgets)
//
////////////////////////////////////////////////////////////////////////////////
static zx_status_t ParseUnsolicitedResponseState(UnsolicitedResponseState& state,
                                                 const CodecResponse& resp) {
    // Section 7.3.3.14.
    state.raw_data_ = static_cast<uint8_t>(resp.data & 0xFF);
    return ZX_OK;
}

static const IntelHDACodec::CommandListEntry<UnsolicitedResponseState>
    FETCH_UNSOLICITED_RESPONSE_STATE[] = {
    { GET_UNSOLICITED_RESP_CTRL, ParseUnsolicitedResponseState },
};

////////////////////////////////////////////////////////////////////////////////
//
// Parsers and CommandLists for fetching info about supported and current power
// state.
//
////////////////////////////////////////////////////////////////////////////////
static zx_status_t ParseSupportedPowerStates(PowerState& ps, const CodecResponse& resp) {
    ps.supported_states_ = resp.data;
    return ZX_OK;
}

static zx_status_t ParseCurrentPowerState(PowerState& ps, const CodecResponse& resp) {
    // Section 7.3.3.10
    ps.set_            = static_cast<uint8_t>(resp.data & 0xF);
    ps.active_         = static_cast<uint8_t>((resp.data >> 4) & 0xF);
    ps.error_          = (resp.data & (1u <<  8)) != 0;
    ps.clock_stop_ok_  = (resp.data & (1u <<  9)) != 0;
    ps.settings_reset_ = (resp.data & (1u << 10)) != 0;

    return ZX_OK;
}

static const IntelHDACodec::CommandListEntry<PowerState> FETCH_POWER_STATE[] = {
    { GET_PARAM(CodecParam::SUPPORTED_PWR_STATES), ParseSupportedPowerStates },
    { GET_POWER_STATE,                             ParseCurrentPowerState },
};

////////////////////////////////////////////////////////////////////////////////
//
// Parsers and CommandLists for fetching info about audio widgets
//
////////////////////////////////////////////////////////////////////////////////
static zx_status_t ParseAWPcmSizeRate(AudioWidgetState& widget, const CodecResponse& resp) {
    auto& afg = *widget.afg_;
    const auto& caps = widget.caps_;

    widget.pcm_size_rate_ = caps.format_override()
                          ? resp.data
                          : afg.default_pcm_size_rate_;

    return ZX_OK;
}

static zx_status_t ParseAWPcmFormats(AudioWidgetState& widget, const CodecResponse& resp) {
    auto& afg = *widget.afg_;
    const auto& caps = widget.caps_;

    widget.pcm_formats_ = caps.format_override()
                        ? resp.data
                        : afg.default_pcm_formats_;

    return ZX_OK;
}

static zx_status_t ParseAWInputAmpCaps(AudioWidgetState& widget, const CodecResponse& resp) {
    auto& afg = *widget.afg_;
    const auto& caps = widget.caps_;

    if (caps.input_amp_present()) {
        widget.input_amp_caps_ = caps.amp_param_override()
                               ? AmpCaps(resp.data)
                               : afg.default_input_amp_caps_;
    }

    return ZX_OK;
}

static zx_status_t ParseAWOutputAmpCaps(AudioWidgetState& widget, const CodecResponse& resp) {
    auto& afg = *widget.afg_;
    const auto& caps = widget.caps_;

    if (caps.output_amp_present()) {
        widget.output_amp_caps_ = caps.amp_param_override()
                                ? AmpCaps(resp.data)
                                : afg.default_output_amp_caps_;
    }

    return ZX_OK;
}

static zx_status_t ParseAWConnectionListLen(AudioWidgetState& widget, const CodecResponse& resp) {
    const auto& caps = widget.caps_;

    if (caps.has_conn_list()) {
        widget.long_form_conn_list_ = ((resp.data & 0x80) != 0);
        widget.conn_list_len_ = resp.data & 0x7f;

        if (widget.conn_list_len_) {
            fbl::AllocChecker ac;
            widget.conn_list_.reset(
                    new (&ac) AudioWidgetState::ConnListEntry[widget.conn_list_len_]);
            if (!ac.check()) {
                return ZX_ERR_NO_MEMORY;
            }
        }
    } else {
        widget.long_form_conn_list_ = false;
        widget.conn_list_len_ = 0;
    }

    return ZX_OK;
}

static zx_status_t ParseAWProcessingCaps(AudioWidgetState& widget, const CodecResponse& resp) {
    const auto& caps = widget.caps_;

    if (caps.proc_widget()) {
        widget.can_bypass_processing_ = (resp.data & 0x1) != 0;
        widget.processing_coefficient_count_ = ((resp.data >> 8) & 0xFF);
    }

    return ZX_OK;
}

static zx_status_t ParseAWPinCaps(AudioWidgetState& widget, const CodecResponse& resp) {
    widget.pin_caps_ = resp.data;
    return ZX_OK;
}

static zx_status_t ParseAWVolumeKnobCaps(AudioWidgetState& widget, const CodecResponse& resp) {
    widget.vol_knob_is_delta_ = (resp.data & 0x80) != 0;
    widget.vol_knob_steps_    = (resp.data & 0x7f);
    return ZX_OK;
}

static zx_status_t ParseAWStreamChan(AudioWidgetState& widget, const CodecResponse& resp) {
    // Section 7.3.3.11 and Table 85
    widget.stream_tag_  = static_cast<uint8_t>((resp.data >> 4) & 0xF);
    widget.stream_chan_ = static_cast<uint8_t>(resp.data & 0xF);
    return ZX_OK;
}

static zx_status_t ParseAWConfigDefaults(AudioWidgetState& widget, const CodecResponse& resp) {
    widget.cfg_defaults_.raw_data_ = resp.data;
    return ZX_OK;
}

static zx_status_t ParseAWPinWidgetCtrl(AudioWidgetState& widget, const CodecResponse& resp) {
    widget.pin_widget_ctrl_.raw_data_ = static_cast<uint8_t>(resp.data & 0xFF);
    return ZX_OK;
}

static zx_status_t ParseAudioWidgetType(AudioWidgetStatePtr& ptr, const CodecResponse& resp) {
    AudioWidgetCaps caps(resp.data);

    switch (caps.type()) {
    case AudioWidgetCaps::Type::OUTPUT:
    case AudioWidgetCaps::Type::INPUT:
    case AudioWidgetCaps::Type::MIXER:
    case AudioWidgetCaps::Type::SELECTOR:
    case AudioWidgetCaps::Type::PIN_COMPLEX:
    case AudioWidgetCaps::Type::POWER:
    case AudioWidgetCaps::Type::VOLUME_KNOB:
    case AudioWidgetCaps::Type::BEEP_GEN:
    case AudioWidgetCaps::Type::VENDOR:
        break;
    default:
        return ZX_ERR_INVALID_ARGS;
    }

    fbl::AllocChecker ac;
    ptr.reset(new (&ac) AudioWidgetState(caps));
    if (!ac.check()) {
        return ZX_ERR_NO_MEMORY;
    }

    return ZX_OK;
}

static const IntelHDACodec::CommandListEntry<AudioWidgetState> FETCH_AUDIO_INPUT_CAPS[] = {
    { GET_PARAM(CodecParam::SUPPORTED_PCM_SIZE_RATE),  ParseAWPcmSizeRate },
    { GET_PARAM(CodecParam::SUPPORTED_STREAM_FORMATS), ParseAWPcmFormats },
    { GET_PARAM(CodecParam::INPUT_AMP_CAPS),           ParseAWInputAmpCaps },
    { GET_PARAM(CodecParam::CONNECTION_LIST_LEN),      ParseAWConnectionListLen },
    { GET_PARAM(CodecParam::PROCESSING_CAPS),          ParseAWProcessingCaps },
    { GET_CONVERTER_STREAM_CHAN,                       ParseAWStreamChan },
};

static const IntelHDACodec::CommandListEntry<AudioWidgetState> FETCH_AUDIO_OUTPUT_CAPS[] = {
    { GET_PARAM(CodecParam::SUPPORTED_PCM_SIZE_RATE),  ParseAWPcmSizeRate },
    { GET_PARAM(CodecParam::SUPPORTED_STREAM_FORMATS), ParseAWPcmFormats },
    { GET_PARAM(CodecParam::OUTPUT_AMP_CAPS),          ParseAWOutputAmpCaps },
    { GET_PARAM(CodecParam::PROCESSING_CAPS),          ParseAWProcessingCaps },
    { GET_CONVERTER_STREAM_CHAN,                       ParseAWStreamChan },
};

static const IntelHDACodec::CommandListEntry<AudioWidgetState> FETCH_DIGITAL_PIN_COMPLEX_CAPS[] = {
    { GET_PARAM(CodecParam::PIN_CAPS),             ParseAWPinCaps },
    { GET_PARAM(CodecParam::OUTPUT_AMP_CAPS),      ParseAWOutputAmpCaps },
    { GET_PARAM(CodecParam::CONNECTION_LIST_LEN),  ParseAWConnectionListLen },
    { GET_PARAM(CodecParam::PROCESSING_CAPS),      ParseAWProcessingCaps },
    { GET_CONFIG_DEFAULT,                          ParseAWConfigDefaults },
    { GET_PIN_WIDGET_CTRL,                         ParseAWPinWidgetCtrl },
};

static const IntelHDACodec::CommandListEntry<AudioWidgetState>
FETCH_NON_DIGITAL_PIN_COMPLEX_CAPS[] = {
    { GET_PARAM(CodecParam::PIN_CAPS),             ParseAWPinCaps },
    { GET_PARAM(CodecParam::INPUT_AMP_CAPS),       ParseAWInputAmpCaps },
    { GET_PARAM(CodecParam::OUTPUT_AMP_CAPS),      ParseAWOutputAmpCaps },
    { GET_PARAM(CodecParam::CONNECTION_LIST_LEN),  ParseAWConnectionListLen },
    { GET_PARAM(CodecParam::PROCESSING_CAPS),      ParseAWProcessingCaps },
    { GET_CONFIG_DEFAULT,                          ParseAWConfigDefaults },
    { GET_PIN_WIDGET_CTRL,                         ParseAWPinWidgetCtrl },
};

static const IntelHDACodec::CommandListEntry<AudioWidgetState> FETCH_MIXER_CAPS[] = {
    { GET_PARAM(CodecParam::INPUT_AMP_CAPS),       ParseAWInputAmpCaps },
    { GET_PARAM(CodecParam::OUTPUT_AMP_CAPS),      ParseAWOutputAmpCaps },
    { GET_PARAM(CodecParam::CONNECTION_LIST_LEN),  ParseAWConnectionListLen },
};

static const IntelHDACodec::CommandListEntry<AudioWidgetState> FETCH_SELECTOR_CAPS[] = {
    { GET_PARAM(CodecParam::INPUT_AMP_CAPS),       ParseAWInputAmpCaps },
    { GET_PARAM(CodecParam::OUTPUT_AMP_CAPS),      ParseAWOutputAmpCaps },
    { GET_PARAM(CodecParam::CONNECTION_LIST_LEN),  ParseAWConnectionListLen },
    { GET_PARAM(CodecParam::PROCESSING_CAPS),      ParseAWProcessingCaps },
};

static const IntelHDACodec::CommandListEntry<AudioWidgetState> FETCH_POWER_CAPS[] = {
    { GET_PARAM(CodecParam::CONNECTION_LIST_LEN),  ParseAWConnectionListLen },
};

static const IntelHDACodec::CommandListEntry<AudioWidgetState> FETCH_VOLUME_KNOB_CAPS[] = {
    { GET_PARAM(CodecParam::CONNECTION_LIST_LEN),  ParseAWConnectionListLen },
    { GET_PARAM(CodecParam::VOLUME_KNOB_CAPS),     ParseAWVolumeKnobCaps },
};

static const IntelHDACodec::CommandListEntry<AudioWidgetStatePtr> FETCH_WIDGET_TYPE[] = {
    { GET_PARAM(CodecParam::AW_CAPS), ParseAudioWidgetType },
};

////////////////////////////////////////////////////////////////////////////////
//
// Parsers and CommandLists for fetching info about function groups.
//
////////////////////////////////////////////////////////////////////////////////
static zx_status_t ParseAFGCaps(AudioFunctionGroupState& afg, const CodecResponse& resp) {
    afg.caps_.raw_data_ = resp.data;
    return ZX_OK;
}

static zx_status_t ParseAFGPcmSizeRate(AudioFunctionGroupState& afg, const CodecResponse& resp) {
    // Section 7.3.4.7 : Supported PCM sizes and rates
    afg.default_pcm_size_rate_ = resp.data;
    return ZX_OK;
}

static zx_status_t ParseAFGPcmFormats(AudioFunctionGroupState& afg, const CodecResponse& resp) {
    afg.default_pcm_formats_ = resp.data;
    return ZX_OK;
}

static zx_status_t ParseAFGInputAmpCaps(AudioFunctionGroupState& afg, const CodecResponse& resp) {
    afg.default_input_amp_caps_.raw_data_ = resp.data;
    return ZX_OK;
}

static zx_status_t ParseAFGOutputAmpCaps(AudioFunctionGroupState& afg, const CodecResponse& resp) {
    afg.default_output_amp_caps_.raw_data_ = resp.data;
    return ZX_OK;
}

static zx_status_t ParseAFGGPIOCount(AudioFunctionGroupState& afg, const CodecResponse& resp) {
    // Section 7.3.4.14 : GPIO Counts
    afg.gpio_can_wake_             = (resp.data & 0x80000000) != 0;
    afg.gpio_can_send_unsolicited_ = (resp.data & 0x40000000) != 0;
    afg.gpi_count_                 = (resp.data >> 16) & 0xFF;
    afg.gpo_count_                 = (resp.data >>  8) & 0xFF;
    afg.gpio_count_                = (resp.data >>  0) & 0xFF;

    return ZX_OK;
}

static zx_status_t ParseAFGImplId(AudioFunctionGroupState& afg, const CodecResponse& resp) {
    afg.impl_id_.raw_data_ = resp.data;
    return ZX_OK;
}

static zx_status_t ParseAFGWidgetCount(AudioFunctionGroupState& afg, const CodecResponse& resp) {
    /* Response format documented in section 7.3.4.1 */
    afg.widget_count_       =  resp.data & 0xFF;
    afg.widget_starting_id_ = (resp.data >> 16) & 0xFF;
    uint32_t last_widget_nid  = static_cast<uint32_t>(afg.widget_starting_id_)
                              + afg.widget_count_ - 1;

    if (last_widget_nid > HDA_MAX_NID)
        return ZX_ERR_INTERNAL;

    if (afg.widget_count_) {
        fbl::AllocChecker ac;
        afg.widgets_.reset(new (&ac) AudioWidgetStatePtr[afg.widget_count_]);
        if (!ac.check()) {
            return ZX_ERR_NO_MEMORY;
        }
    }

    return ZX_OK;
}

static const IntelHDACodec::CommandListEntry<AudioFunctionGroupState> FETCH_AFG_PROPERTIES[] {
    { GET_PARAM(CodecParam::AFG_CAPS),                 ParseAFGCaps },
    { GET_PARAM(CodecParam::SUPPORTED_PCM_SIZE_RATE),  ParseAFGPcmSizeRate },
    { GET_PARAM(CodecParam::SUPPORTED_STREAM_FORMATS), ParseAFGPcmFormats },
    { GET_PARAM(CodecParam::INPUT_AMP_CAPS),           ParseAFGInputAmpCaps },
    { GET_PARAM(CodecParam::OUTPUT_AMP_CAPS),          ParseAFGOutputAmpCaps },
    { GET_PARAM(CodecParam::GPIO_COUNT),               ParseAFGGPIOCount },
    { GET_IMPLEMENTATION_ID,                           ParseAFGImplId },
    { GET_PARAM(CodecParam::SUBORDINATE_NODE_COUNT),   ParseAFGWidgetCount },
};

static zx_status_t ParseFnGroupType(FunctionGroupStatePtr& ptr, const CodecResponse& resp) {
    /* Response format documented in section 7.3.4.1 */
    auto type = static_cast<FunctionGroupState::Type>(resp.data & 0xFF);
    fbl::AllocChecker ac;

    switch (type) {
    case FunctionGroupState::Type::AUDIO:
        ptr.reset(new (&ac) AudioFunctionGroupState());
        if (!ac.check()) {
            return ZX_ERR_NO_MEMORY;
        }
        break;

    case FunctionGroupState::Type::MODEM:
        ptr.reset(new (&ac) ModemFunctionGroupState());
        if (!ac.check()) {
            return ZX_ERR_NO_MEMORY;
        }
        break;
    default:
        if ((type >= FunctionGroupState::Type::VENDOR_START) &&
            (type <= FunctionGroupState::Type::VENDOR_END)) {
            ptr.reset(new (&ac) VendorFunctionGroupState(type));
            if (!ac.check()) {
                return ZX_ERR_NO_MEMORY;
            }
        } else {
            return ZX_ERR_INTERNAL;
        }
        break;
    }

    ptr->can_send_unsolicited_ = ((resp.data & 0x100) != 0);
    return ZX_OK;
}

static const IntelHDACodec::CommandListEntry<FunctionGroupStatePtr> FETCH_FUNCTION_GROUP_TYPE[] = {
    { GET_PARAM(CodecParam::FUNCTION_GROUP_TYPE), ParseFnGroupType },
};

////////////////////////////////////////////////////////////////////////////////
//
// Parsers and command list for fetching info about core codec capabilities.
//
////////////////////////////////////////////////////////////////////////////////
static zx_status_t ParseVendorID(CodecState& codec, const CodecResponse& resp) {
    /* Response format documented in section 7.3.4.1 */

    codec.vendor_id_ = static_cast<uint16_t>((resp.data >> 16) & 0xFFFF);
    codec.device_id_ = static_cast<uint16_t>(resp.data & 0xFFFF);;

    return (codec.vendor_id_ != 0) ? ZX_OK : ZX_ERR_INTERNAL;
}

static zx_status_t ParseRevisionID(CodecState& codec, const CodecResponse& resp) {
    /* Response format documented in section 7.3.4.2 */

    codec.major_rev_          = (resp.data >> 20) & 0xF;
    codec.minor_rev_          = (resp.data >> 16) & 0xF;
    codec.vendor_rev_id_      = (resp.data >>  8) & 0xFF;
    codec.vendor_stepping_id_ = resp.data & 0xFF;

    return ZX_OK;
}

static zx_status_t ParseFnGroupCount(CodecState& codec, const CodecResponse& resp) {
    /* Response format documented in section 7.3.4.3 */

    codec.fn_group_count_ = resp.data & 0xFF;
    codec.fn_group_starting_id_ = (resp.data >> 16) & 0xFF;

    uint32_t last_fn_group_nid = static_cast<uint32_t>(codec.fn_group_starting_id_)
                               + codec.fn_group_count_ - 1;
    if (last_fn_group_nid > HDA_MAX_NID)
        return ZX_ERR_INTERNAL;

    // Allocate the storage for the function group state pointers, then
    // start the process of enumerating their properties and widgets.
    fbl::AllocChecker ac;
    codec.fn_groups_.reset(new (&ac) FunctionGroupStatePtr[codec.fn_group_count_]);
    if (!ac.check()) {
        return ZX_ERR_NO_MEMORY;
    }

    return ZX_OK;
}

static const IntelHDACodec::CommandListEntry<CodecState> FETCH_CODEC_ROOT_COMMANDS[] = {
    { GET_PARAM(CodecParam::VENDOR_ID),              ParseVendorID },
    { GET_PARAM(CodecParam::REVISION_ID),            ParseRevisionID },
    { GET_PARAM(CodecParam::SUBORDINATE_NODE_COUNT), ParseFnGroupCount },
};

zx_status_t IntelHDACodec::Enumerate() {
    static const char* const DEV_PATH = "/dev/class/intel-hda-codec";

    zx_status_t res = ZirconDevice::Enumerate(nullptr, DEV_PATH,
    [](void*, uint32_t id, const char* const dev_name) -> zx_status_t {
        fbl::AllocChecker ac;
        auto codec = fbl::unique_ptr<IntelHDACodec>(new (&ac) IntelHDACodec(id, dev_name));
        if (!ac.check()) {
            return ZX_ERR_NO_MEMORY;
        }

        if (codec == nullptr)
            return ZX_ERR_NO_MEMORY;

        if (!codecs_.insert_or_find(std::move(codec)))
            return ZX_ERR_INTERNAL;

        return ZX_OK;
    });

    return res;
}

zx_status_t IntelHDACodec::DumpCodec(int argc, const char** argv) {
    zx_status_t res = ReadCodecState();
    if (res != ZX_OK)
        return res;

    printf("Codec ID %u :: %s\n", codec_id_, dev_name_);
    print_codec_state(codec_state_);

    return ZX_OK;
}

#define RUN_COMMAND_LIST(_tgt, _nid, _list, _fail_msg, ...) {        \
    res = RunCommandList(_tgt, _nid, _list, fbl::count_of(_list));   \
    if (res != ZX_OK) {                                              \
        printf(_fail_msg " (res %d)\n", ##__VA_ARGS__, res);         \
        return res;                                                  \
    }                                                                \
}

zx_status_t IntelHDACodec::ReadCodecState() {
    zx_status_t res = Connect();

    if (res != ZX_OK)
        return res;

    codec_state_.reset();

    RUN_COMMAND_LIST(codec_state_, 0u, FETCH_CODEC_ROOT_COMMANDS,
                    "Failed while fetching codec root info");

    for (uint16_t group_ndx = 0; group_ndx < codec_state_.fn_group_count_; ++group_ndx) {
        auto& fn_group_ptr = codec_state_.fn_groups_[group_ndx];
        auto  nid          = static_cast<uint16_t>(group_ndx + codec_state_.fn_group_starting_id_);

        res = ReadFunctionGroupState(fn_group_ptr, nid);
        if (res != ZX_OK)
            return res;
    }

    return ZX_OK;
}

zx_status_t IntelHDACodec::ReadFunctionGroupState(FunctionGroupStatePtr& ptr, uint16_t nid) {
    zx_status_t res;

    RUN_COMMAND_LIST(ptr, nid, FETCH_FUNCTION_GROUP_TYPE,
                    "Failed to fetch function group type (nid %hu)", nid);

    if (ptr->can_send_unsolicited_) {
        RUN_COMMAND_LIST(ptr->unsol_resp_ctrl_, nid, FETCH_UNSOLICITED_RESPONSE_STATE,
                        "Failed to fetch unsolicited response control state (nid %hu)", nid);
    }

    ptr->nid_ = nid;

    switch (ptr->type_) {
    case FunctionGroupState::Type::AUDIO: {
        auto& afg = *(static_cast<AudioFunctionGroupState*>(ptr.get()));
        return ReadAudioFunctionGroupState(afg);
    }

    case FunctionGroupState::Type::MODEM: {
        // We do not support probing the state of modem function groups right now.
        printf("Warning: MODEM function group (nid %hd) state details not fetched.\n", nid);
        break;
    }

    default:
        // ParseFnGroupType should have aborted at this point if the function
        // group type was not valid.
        ZX_DEBUG_ASSERT((ptr->type_ >= FunctionGroupState::Type::VENDOR_START) &&
                        (ptr->type_ <= FunctionGroupState::Type::VENDOR_END));
        break;
    }

    return ZX_OK;
}

zx_status_t IntelHDACodec::ReadAudioFunctionGroupState(AudioFunctionGroupState& afg) {
    zx_status_t res;

    RUN_COMMAND_LIST(afg, afg.nid_, FETCH_AFG_PROPERTIES,
                    "Failed to audio fn group properties (nid %hu)", afg.nid_);

    RUN_COMMAND_LIST(afg.power_, afg.nid_, FETCH_POWER_STATE,
                     "Failed to fetch Power caps/state for audio function group (nid %hu)",
                     afg.nid_);

    for (uint32_t i = 0; i < afg.widget_count_; ++i) {
        auto& widget_ptr = afg.widgets_[i];
        uint16_t nid = static_cast<uint16_t>(afg.widget_starting_id_ + i);

        RUN_COMMAND_LIST(widget_ptr, nid, FETCH_WIDGET_TYPE,
                        "Failed to audio widget type (nid %hu) for function "
                        "group located at nid %hu", nid, afg.nid_);

        widget_ptr->nid_ = nid;
        widget_ptr->afg_ = &afg;

        res = ReadAudioWidgetState(*widget_ptr);
        if (res != ZX_OK)
            return res;
    }

    return ZX_OK;
}

zx_status_t IntelHDACodec::ReadAudioWidgetState(AudioWidgetState& widget) {
    zx_status_t res;

    switch (widget.caps_.type()) {
    case AudioWidgetCaps::Type::INPUT:
        RUN_COMMAND_LIST(widget, widget.nid_, FETCH_AUDIO_INPUT_CAPS,
                         "Failed to fetch INPUT_CAPS for audio widget (nid %hu)",
                         widget.nid_);
        break;

    case AudioWidgetCaps::Type::OUTPUT:
        RUN_COMMAND_LIST(widget, widget.nid_, FETCH_AUDIO_OUTPUT_CAPS,
                         "Failed to fetch OUTPUT_CAPS for audio widget (nid %hu)",
                         widget.nid_);
        break;

    case AudioWidgetCaps::Type::PIN_COMPLEX:
        if (widget.caps_.digital()) {
            RUN_COMMAND_LIST(widget, widget.nid_, FETCH_DIGITAL_PIN_COMPLEX_CAPS,
                             "Failed to fetch DIGITAL_PIN_COMPLEX_CAPS for audio widget "
                             "(nid %hu)", widget.nid_);
        } else {
            RUN_COMMAND_LIST(widget, widget.nid_, FETCH_NON_DIGITAL_PIN_COMPLEX_CAPS,
                             "Failed to fetch NON_DIGITAL_PIN_COMPLEX_CAPS for audio widget "
                             "(nid %hu)", widget.nid_);
        }
        break;

    case AudioWidgetCaps::Type::MIXER:
        RUN_COMMAND_LIST(widget, widget.nid_, FETCH_MIXER_CAPS,
                         "Failed to fetch MIXER_CAPS for audio widget (nid %hu)",
                         widget.nid_);
        break;

    case AudioWidgetCaps::Type::SELECTOR:
        RUN_COMMAND_LIST(widget, widget.nid_, FETCH_SELECTOR_CAPS,
                         "Failed to fetch SELECTOR_CAPS for audio widget (nid %hu)",
                         widget.nid_);
        break;

    case AudioWidgetCaps::Type::POWER:
        RUN_COMMAND_LIST(widget, widget.nid_, FETCH_POWER_CAPS,
                         "Failed to fetch POWER_CAPS for audio widget (nid %hu)",
                         widget.nid_);
        break;

    case AudioWidgetCaps::Type::VOLUME_KNOB:
        RUN_COMMAND_LIST(widget, widget.nid_, FETCH_VOLUME_KNOB_CAPS,
                         "Failed to fetch VOLUME_KNOB_CAPS for audio widget (nid %hu)",
                         widget.nid_);
        break;

    // We don't currently fetch any state for beep generators or vendor widgets.
    case AudioWidgetCaps::Type::BEEP_GEN:
    case AudioWidgetCaps::Type::VENDOR:
        break;

    default:
        printf("Unrecognized audio widget type (%u) at nid %hu\n",
                static_cast<uint32_t>(widget.caps_.type()), widget.nid_);
        return ZX_ERR_BAD_STATE;
    }

    // If this widget has a connection list, read it now.
    if (widget.caps_.has_conn_list()) {
        res = ReadConnList(widget);
        if (res != ZX_OK)
            return res;
    }

    // If this widget has power management capabilities, read the caps and the
    // current state now.
    if (widget.caps_.has_power_ctl()) {
        RUN_COMMAND_LIST(widget.power_, widget.nid_, FETCH_POWER_STATE,
                         "Failed to fetch Power caps/state for audio widget (nid %hu)",
                         widget.nid_);

        // From section 7.3.4.12.
        //
        // "If this is not implemented (returns 0's) or just returns 0 as
        // response to reading this parameter for a node that supports a Power
        // State Control (see section 7.3.3.10) then the supported power states
        // for that node will be the same as reported for the Function Group."
        if (widget.power_.supported_states_ == 0) {
            ZX_DEBUG_ASSERT(widget.afg_ != nullptr);
            widget.power_.supported_states_ = widget.afg_->power_.supported_states_;
        }
    }

    // If this is an input or output converter widget, read the currently configured format.
    if ((widget.caps_.type() == AudioWidgetCaps::Type::INPUT) ||
        (widget.caps_.type() == AudioWidgetCaps::Type::OUTPUT)) {
        CodecResponse resp;

        res = DoCodecCmd(widget.nid_, GET_CONVERTER_FORMAT, &resp);
        if (res != ZX_OK) {
            printf("Failed to get stream converter format for for nid %hu (res %d)\n",
                    widget.nid_, res);
            return res;
        }

        widget.cur_format_.raw_data_ = static_cast<uint16_t>(resp.data & 0xFFFF);
    }

    // If this is a pin complex, and it supports presence detection, and the
    // JackOverride bit has not been set in the config defaults, query the pin
    // sense.
    if ((widget.caps_.type() == AudioWidgetCaps::Type::PIN_COMPLEX) &&
        (widget.pin_caps_ & AW_PIN_CAPS_FLAG_CAN_PRESENCE_DETECT) &&
        (!widget.cfg_defaults_.jack_detect_override())) {

        // TODO(johngro): Add support for SW triggering a pin detection.  Timing
        // requirements are unclear and may be codec specific.  Also, triggering
        // the presence detection is a "set" operation, which is not currently
        // permitted by the driver.
        if (widget.pin_caps_ & AW_PIN_CAPS_FLAG_TRIGGER_REQUIRED) {
            printf("WARNING: SW triggered presence sensing not supported (nid %hu)\n",
                    widget.nid_);
        } else {
            // TODO(johngro): do we need to bring the pin complex to a
            // particular power state in order for presence detect to work, or
            // should it run at all power states?
            CodecResponse resp;
            res = DoCodecCmd(widget.nid_, GET_PIN_SENSE, &resp);
            if (res != ZX_OK) {
                printf("Failed to get pin sense status for pin complex nid %hu (res %d)\n",
                        widget.nid_, res);
                return res;
            }

            widget.pin_sense_.raw_data_ = resp.data;
            widget.pin_sense_valid_ = true;
        }
    }

    // Read the current state of the EAPD/BTL register if this is...
    //
    // 1) A pin complex with external amplifier control.
    // 2) A pin complex capable of balanced output.
    // 3) Any widget capable of swapping L/R channels
    if (widget.caps_.can_lr_swap() ||
       (widget.pin_caps_ & AW_PIN_CAPS_FLAG_BALANCED_IO) ||
       (widget.pin_caps_ & AW_PIN_CAPS_FLAG_CAN_EAPD)) {
        CodecResponse resp;
        res = DoCodecCmd(widget.nid_, GET_EAPD_BTL_ENABLE, &resp);
        if (res != ZX_OK) {
            printf("Failed to get EAPD/BTL state for nid %hu (res %d)\n",
                    widget.nid_, res);
            return res;
        }

        widget.eapd_state_.raw_data_ = resp.data;
    }

    // If this widget has an input or output amplifier, read its current state.
    //
    // Todo(johngro) : add support for reading gain settings for mixers and
    // summing widgets which have more than just a single amplifier gain/mute
    // setting.
    if (widget.caps_.input_amp_present()) {
        // If this a mixer, read the individual input amp state for each of the mixer inputs.
        // Otherwise, just read the common input amp state.
        if (widget.caps_.type() == AudioWidgetCaps::Type::MIXER) {
            for (uint8_t i = 0; i < widget.conn_list_len_; ++i) {
                res = ReadAmpState(widget.nid_, true, i,
                                   widget.input_amp_caps_,
                                   &widget.conn_list_[i].amp_state_);
                if (res != ZX_OK)
                    return res;
            }
        } else {
            res = ReadAmpState(widget.nid_, true, 0,
                               widget.input_amp_caps_, &widget.input_amp_state_);
            if (res != ZX_OK)
                return res;
        }
    }

    if (widget.caps_.output_amp_present()) {
        res = ReadAmpState(widget.nid_, false, 0,
                           widget.output_amp_caps_, &widget.output_amp_state_);
        if (res != ZX_OK)
            return res;
    }

    // If this widget can send unsolicited responses, query the current state of
    // the unsolicted response controls.
    if (widget.caps_.can_send_unsol()) {
        RUN_COMMAND_LIST(widget.unsol_resp_ctrl_, widget.nid_,
                         FETCH_UNSOLICITED_RESPONSE_STATE,
                         "Failed to fetch unsolicited response control state (nid %hu)",
                         widget.nid_);
    }

    // Finished.
    return ZX_OK;
}

#undef RUN_COMMAND_LIST

zx_status_t IntelHDACodec::ReadConnList(AudioWidgetState& widget) {
    CodecResponse resp;
    zx_status_t   res;

    ZX_DEBUG_ASSERT(widget.conn_list_len_ > 0);
    ZX_DEBUG_ASSERT(widget.conn_list_ != nullptr);

    size_t i = 0;
    while (i < widget.conn_list_len_) {
        res = DoCodecCmd(widget.nid_, GET_CONNECTION_LIST_ENTRY(static_cast<uint8_t>(i)), &resp);
        if (res != ZX_OK) {
            printf("Failed to get connection list entry at ndx %zu for nid %hu (res %d)\n",
                    i, widget.nid_, res);
            return res;
        }

        // See section 7.1.2 and figure 51 for the format of long and short form
        // connection widget.conn_list_ entries.
        if (widget.long_form_conn_list_) {
            for (size_t j = 0; (j < 2) && (i < widget.conn_list_len_); j++, i++) {
                uint16_t raw = static_cast<uint16_t>(resp.data & 0xFFFF);
                widget.conn_list_[i].range_ = (raw & 0x8000u) != 0;
                widget.conn_list_[i].nid_   = (raw & 0x7FFFu);
                resp.data >>= 16;
            }
        } else {
            for (size_t j = 0; (j < 4) && (i < widget.conn_list_len_); j++, i++) {
                uint8_t raw = static_cast<uint8_t>(resp.data & 0xFF);
                widget.conn_list_[i].range_ = (raw & 0x80u) != 0;
                widget.conn_list_[i].nid_   = (raw & 0x7Fu);
                resp.data >>= 8;
            }
        }
    }

    // Sanity check the widget.conn_list_.
    for (i = 0; i < widget.conn_list_len_; ++i) {
        if (widget.conn_list_[i].range_ && (!i || widget.conn_list_[i-1].range_)) {
            printf("Invalid connection widget.conn_list_ entry [nid, ndx] = [%hu, %zu]. "
                   "Range end may not be the first entry in the connection widget.conn_list_, "
                   "or proceeded by a range end entry.\n",
                   widget.nid_, i);
            return ZX_ERR_BAD_STATE;
        }
    }

    // If the connection list length is greater than 1, and this is not a mixer
    // widger, then there exists a selection control.  Read it's current setting
    // so we can report it.  Otherwise, the currently connected NID must be the
    // same as the first entry in the list, or this is a mixer widget in which
    // case it is always connected to all of the entries in the connection list.
    if (widget.caps_.type() != AudioWidgetCaps::Type::MIXER) {
        if (widget.conn_list_len_ == 1) {
            widget.connected_nid_ = widget.conn_list_[0].nid_;
            widget.connected_nid_ndx_ = 0;
        } else {
            // Select control response format documented in section 7.3.3.2 Table 73
            res = DoCodecCmd(widget.nid_, GET_CONNECTION_SELECT_CONTROL, &resp);
            if (res != ZX_OK) {
                printf("Failed to get connection selection for nid %hu (res %d)\n",
                        widget.nid_, res);
                return res;
            }

            widget.connected_nid_ndx_ = static_cast<uint8_t>(resp.data & 0xFF);
            widget.connected_nid_ = (widget.connected_nid_ndx_ < widget.conn_list_len_)
                                  ?  widget.conn_list_[widget.connected_nid_ndx_].nid_
                                  : 0;
        }
    } else {
        widget.connected_nid_ = 0;
        widget.connected_nid_ndx_ = 0;
    }

    return ZX_OK;
}

zx_status_t IntelHDACodec::ReadAmpState(uint16_t nid, bool is_input, uint8_t ndx,
                                        const AmpCaps& caps,
                                        AudioWidgetState::AmpState* state_out) {
    ZX_DEBUG_ASSERT(state_out);

    CodecResponse resp;
    zx_status_t   res;

    for (size_t i = 0; i < fbl::count_of(state_out->gain); ++i) {
        res = DoCodecCmd(nid, GET_AMPLIFIER_GAIN_MUTE(is_input, (i > 0), ndx), &resp);
        if (res != ZX_OK) {
            printf("Failed to get amp settings for nid %hu's %s %s amplifier #%u (res %d)\n",
                    nid,
                    (i > 0)  ? "right" : "left",
                    is_input ? "input" : "output",
                    ndx, res);
            return res;
        }

        // Section 7.3.3.7 and Figure 62
        state_out->gain[i] = static_cast<uint8_t>(resp.data & 0x7f);
        state_out->mute[i] = (resp.data & 0x80) != 0;
    }

    return ZX_OK;
}

zx_status_t IntelHDACodec::DoCodecCmd(uint16_t nid,
                                      const CodecVerb& verb,
                                      CodecResponse* resp_out) {

    ZX_DEBUG_ASSERT(resp_out != nullptr);

    ihda_codec_send_corb_cmd_req_t  req;
    ihda_codec_send_corb_cmd_resp_t resp;

    InitRequest(&req, IHDA_CODEC_SEND_CORB_CMD);
    req.nid  = nid;
    req.verb = verb.val;

    zx_status_t res = CallDevice(req, &resp);
    if (res != ZX_OK) {
        printf("Codec command failed; [nid, verb] = [%2u, 0x%05x] (res %d)\n", nid, verb.val, res);
        return res;
    }

    resp_out->data    = resp.data;
    resp_out->data_ex = resp.data_ex;

    return ZX_OK;
}

template <typename T>
zx_status_t IntelHDACodec::RunCommandList(T& target,
                                          uint16_t nid,
                                          const CommandListEntry<T>* cmds,
                                          size_t cmd_count) {
    ZX_DEBUG_ASSERT(cmds);

    for (size_t i = 0; i < cmd_count; ++i) {
        const auto& cmd = cmds[i];
        zx_status_t res;
        CodecResponse resp;

        res = DoCodecCmd(nid, cmd.verb, &resp);
        if (res != ZX_OK)
            return res;

        res = cmd.parser(target, resp);
        if (res != ZX_OK) {
            printf("Cmd parse; [nid, verb] = [%2u, 0x%05x] --> resp [0x%08x, 0x%08x] (res %d)\n",
                    nid, cmd.verb.val, resp.data, resp.data_ex, res);
            return res;
        }
    }

    return ZX_OK;
}

}  // namespace audio
}  // namespace intel_hda
