// 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 <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, 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 = 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 < 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;

  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
