// 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 <iterator>
#include <memory>
#include <utility>

#include <fbl/algorithm.h>

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;
}

// clang-format off
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 },
};
// clang-format on

////////////////////////////////////////////////////////////////////////////////
//
// 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[]{
    // clang-format off
  { 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 },
    // clang-format on
};

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[] = {
    // clang-format off
  { GET_PARAM(CodecParam::VENDOR_ID),              ParseVendorID },
  { GET_PARAM(CodecParam::REVISION_ID),            ParseRevisionID },
  { GET_PARAM(CodecParam::SUBORDINATE_NODE_COUNT), ParseFnGroupCount },
    // clang-format on
};

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 = std::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_.c_str());
  print_codec_state(codec_state_);

  return ZX_OK;
}

zx_status_t IntelHDACodec::Probe(IntelHDADevice* result) {
  return ProbeIntelHdaDevice(&device_, result);
}

#define RUN_COMMAND_LIST(_tgt, _nid, _list, _fail_msg, ...)    \
  {                                                            \
    res = RunCommandList(_tgt, _nid, _list, std::size(_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 = device_.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 < std::size(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;

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

  zx_status_t res = device_.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 intel_hda
}  // namespace audio
