// 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. #pragma once #include #include #include #include #include #include #include #include namespace audio { namespace intel_hda { struct AudioWidgetState; using AudioWidgetStatePtr = fbl::unique_ptr; struct FunctionGroupState; struct AudioFunctionGroupState; using FunctionGroupStatePtr = fbl::unique_ptr; struct PowerState { // Section 7.3.4.12 : Supported Power States uint32_t supported_states_; // Section 7.3.3.10 : Current power state uint8_t set_; uint8_t active_; bool error_; bool clock_stop_ok_; bool settings_reset_; }; // Section 7.3.3.14. Present only in nodes (function groups and widgets) whose // capabilities indicate the ability to send unsolicited responses. struct UnsolicitedResponseState { bool enabled() const { return (raw_data_ & 0x80) != 0; } uint8_t tag() const { return static_cast(raw_data_ & 0x3f); } uint8_t raw_data_; }; struct AudioWidgetState { struct StreamFormat { // Stream format bitfields documented in section 3.7.1 static constexpr uint16_t FLAG_NON_PCM = (1u << 15); uint32_t BASE() const { return (raw_data_ & (1u << 14)) ? 44100 : 48000; } uint32_t CHAN() const { return (raw_data_ & 0xF) + 1; } uint32_t DIV() const { return ((raw_data_ >> 8) & 0x7) + 1; } uint32_t MULT() const { uint32_t bits = (raw_data_ >> 11) & 0x7; if (bits >= 4) return 0; return bits + 1; } uint32_t BITS() const { switch ((raw_data_ >> 4) & 0x7) { case 0: return 8u; case 1: return 16u; case 2: return 20u; case 3: return 24u; case 4: return 32u; default: return 0u; } } bool is_pcm() const { return (raw_data_ & FLAG_NON_PCM) == 0; } uint32_t sample_rate() const { return (BASE() * MULT()) / DIV(); } uint32_t channels() const { return CHAN(); } uint32_t bits_per_chan() const { return BITS(); } uint16_t raw_data_; }; struct AmpState { uint8_t gain[2]; bool mute[2]; }; struct ConnListEntry { bool range_; uint16_t nid_; AmpState amp_state_; }; explicit AudioWidgetState(const AudioWidgetCaps& caps) : caps_(caps) { } const AudioWidgetCaps caps_; const AudioFunctionGroupState* afg_ = nullptr; uint16_t nid_; // Note: to simplify life, the widget struct contains the union of all of // the different field which may be needed for any type of audio widget. // Not all of the fields will be meaningful depending on the widget type. uint32_t pcm_size_rate_; // Section 7.3.4.7 : Supported PCM sizes and rates uint32_t pcm_formats_; // Section 7.3.4.8 : Supported PCM formats uint32_t pin_caps_ = 0; // Section 7.3.4.9 : Pin Capabilities StreamFormat cur_format_; // Section 7.3.3.11 : Stream tag and channel routing for converters. uint8_t stream_tag_; uint8_t stream_chan_; // Section 7.3.4.10 : Amplifier capabilities AmpCaps input_amp_caps_; AmpCaps output_amp_caps_; // Section 7.3.3.7 : Amplifier Gain/Mute state AmpState input_amp_state_; AmpState output_amp_state_; // Sections 7.3.3.2, 7.3.3.3 & 7.3.4.11 : Connection List bool long_form_conn_list_; uint8_t conn_list_len_; fbl::unique_ptr conn_list_; uint16_t connected_nid_; uint8_t connected_nid_ndx_; // Sections 7.3.4.12 & 7.3.3.10. PowerState power_; // Section 7.3.4.13 : Processing Capabilities bool can_bypass_processing_; uint8_t processing_coefficient_count_; // Section 7.3.4.15 : Volume Knob Capabilities bool vol_knob_is_delta_; uint8_t vol_knob_steps_; // Section 7.3.3.31. Present only in pin complexes ConfigDefaults cfg_defaults_; // Section 7.3.3.12. Present only in pin complexes PinWidgetCtrlState pin_widget_ctrl_; // Section 7.3.3.14. UnsolicitedResponseState unsol_resp_ctrl_; // Section 7.3.3.15 // // Only valid for pin complexes, only run if the pin complex supports // presence detect and the config defaults do not indicate a jack detect // override. PinSenseState pin_sense_; bool pin_sense_valid_ = false; // Section 7.3.3.16 : External amp power down state EAPDState eapd_state_; }; struct FunctionGroupState { virtual ~FunctionGroupState() { } enum class Type : uint8_t { AUDIO = 0x01, MODEM = 0x02, VENDOR_START = 0x80, VENDOR_END = 0xFF, }; // Section 7.3.3.30 struct ImplementationID { uint32_t BoardImplID() const { return (raw_data_ >> 8) & 0xFFFFFF; } uint16_t BoardMfrID() const { return static_cast(raw_data_ >> 16); } uint8_t BoardSKU() const { return static_cast((raw_data_ >> 8) & 0xFF); } uint8_t AssemblyID() const { return static_cast(raw_data_ & 0xFF); } uint32_t raw_data_; }; const Type type_; bool can_send_unsolicited_; uint16_t nid_; ImplementationID impl_id_; UnsolicitedResponseState unsol_resp_ctrl_; protected: explicit FunctionGroupState(Type type) : type_(type) { } }; struct AudioFunctionGroupState : public FunctionGroupState { AudioFunctionGroupState() : FunctionGroupState(Type::AUDIO) { } AudioFunctionGroupCaps caps_; uint32_t default_pcm_size_rate_; // Section 7.3.4.7 : Supported PCM sizes and rates uint32_t default_pcm_formats_; // Section 7.3.4.8 : Supported PCM formats // Section 7.3.4.10 : Amplifier capabilities AmpCaps default_input_amp_caps_; AmpCaps default_output_amp_caps_; // Sections 7.3.4.12 & 7.3.3.10. PowerState power_; // Section 7.3.4.14 : GPIO Counts bool gpio_can_wake_; bool gpio_can_send_unsolicited_; uint8_t gpio_count_; uint8_t gpo_count_; uint8_t gpi_count_; uint8_t widget_count_ = 0; uint8_t widget_starting_id_ = 0; fbl::unique_ptr widgets_; }; struct ModemFunctionGroupState : public FunctionGroupState { ModemFunctionGroupState() : FunctionGroupState(Type::MODEM) { } }; struct VendorFunctionGroupState : public FunctionGroupState { explicit VendorFunctionGroupState(Type type) : FunctionGroupState(type) { ZX_DEBUG_ASSERT((type >= Type::VENDOR_START) && (type <= Type::VENDOR_START)); } }; struct CodecState { void reset() { fn_groups_.reset(); } uint16_t vendor_id_; uint16_t device_id_; uint8_t major_rev_; uint8_t minor_rev_; uint8_t vendor_rev_id_; uint8_t vendor_stepping_id_; uint8_t fn_group_count_; uint8_t fn_group_starting_id_; fbl::unique_ptr fn_groups_; }; } // namespace audio } // namespace intel_hda