blob: 232eb465a3273a536f0b0524caaa4c8728271590 [file] [log] [blame]
// 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.
#ifndef SRC_MEDIA_AUDIO_BIN_IHDA_CODEC_STATE_H_
#define SRC_MEDIA_AUDIO_BIN_IHDA_CODEC_STATE_H_
#include <stddef.h>
#include <stdint.h>
#include <zircon/assert.h>
#include <zircon/types.h>
#include <memory>
#include <intel-hda/utils/codec-caps.h>
#include <intel-hda/utils/codec-commands.h>
#include <intel-hda/utils/codec-state.h>
namespace audio {
namespace intel_hda {
struct AudioWidgetState;
using AudioWidgetStatePtr = std::unique_ptr<AudioWidgetState>;
struct FunctionGroupState;
struct AudioFunctionGroupState;
using FunctionGroupStatePtr = std::unique_ptr<FunctionGroupState>;
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<uint8_t>(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_;
std::unique_ptr<ConnListEntry[]> 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<uint16_t>(raw_data_ >> 16); }
uint8_t BoardSKU() const { return static_cast<uint8_t>((raw_data_ >> 8) & 0xFF); }
uint8_t AssemblyID() const { return static_cast<uint8_t>(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;
std::unique_ptr<AudioWidgetStatePtr[]> 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_ = nullptr; }
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_;
std::unique_ptr<FunctionGroupStatePtr[]> fn_groups_;
};
} // namespace intel_hda
} // namespace audio
#endif // SRC_MEDIA_AUDIO_BIN_IHDA_CODEC_STATE_H_