1 // Copyright 2017 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #pragma once
6 
7 #include <zircon/assert.h>
8 #include <zircon/types.h>
9 #include <fbl/unique_ptr.h>
10 #include <stddef.h>
11 #include <stdint.h>
12 
13 #include <intel-hda/utils/codec-caps.h>
14 #include <intel-hda/utils/codec-commands.h>
15 #include <intel-hda/utils/codec-state.h>
16 
17 namespace audio {
18 namespace intel_hda {
19 
20 struct AudioWidgetState;
21 using  AudioWidgetStatePtr = fbl::unique_ptr<AudioWidgetState>;
22 
23 struct FunctionGroupState;
24 struct AudioFunctionGroupState;
25 using  FunctionGroupStatePtr = fbl::unique_ptr<FunctionGroupState>;
26 
27 struct PowerState {
28     // Section 7.3.4.12 : Supported Power States
29     uint32_t supported_states_;
30 
31     // Section 7.3.3.10 : Current power state
32     uint8_t set_;
33     uint8_t active_;
34     bool    error_;
35     bool    clock_stop_ok_;
36     bool    settings_reset_;
37 };
38 
39 // Section 7.3.3.14.  Present only in nodes (function groups and widgets) whose
40 // capabilities indicate the ability to send unsolicited responses.
41 struct UnsolicitedResponseState {
enabledUnsolicitedResponseState42     bool    enabled() const { return (raw_data_ & 0x80) != 0; }
tagUnsolicitedResponseState43     uint8_t tag()     const { return static_cast<uint8_t>(raw_data_ & 0x3f); }
44     uint8_t raw_data_;
45 };
46 
47 struct AudioWidgetState {
48     struct StreamFormat {
49         // Stream format bitfields documented in section 3.7.1
50         static constexpr uint16_t FLAG_NON_PCM = (1u << 15);
51 
BASEAudioWidgetState::StreamFormat52         uint32_t BASE() const { return (raw_data_ & (1u << 14)) ? 44100 : 48000; }
CHANAudioWidgetState::StreamFormat53         uint32_t CHAN() const { return (raw_data_ & 0xF) + 1; }
DIVAudioWidgetState::StreamFormat54         uint32_t DIV()  const { return ((raw_data_ >> 8) & 0x7) + 1; }
MULTAudioWidgetState::StreamFormat55         uint32_t MULT() const {
56             uint32_t bits = (raw_data_ >> 11) & 0x7;
57             if (bits >= 4)
58                 return 0;
59             return bits + 1;
60         }
BITSAudioWidgetState::StreamFormat61         uint32_t BITS() const {
62             switch ((raw_data_ >> 4) & 0x7) {
63             case 0: return 8u;
64             case 1: return 16u;
65             case 2: return 20u;
66             case 3: return 24u;
67             case 4: return 32u;
68             default: return 0u;
69             }
70         }
71 
is_pcmAudioWidgetState::StreamFormat72         bool     is_pcm()        const { return (raw_data_ & FLAG_NON_PCM) == 0; }
sample_rateAudioWidgetState::StreamFormat73         uint32_t sample_rate()   const { return (BASE() * MULT()) / DIV(); }
channelsAudioWidgetState::StreamFormat74         uint32_t channels()      const { return CHAN(); }
bits_per_chanAudioWidgetState::StreamFormat75         uint32_t bits_per_chan() const { return BITS(); }
76 
77         uint16_t raw_data_;
78     };
79 
80     struct AmpState {
81         uint8_t gain[2];
82         bool    mute[2];
83     };
84 
85     struct ConnListEntry {
86         bool range_;
87         uint16_t nid_;
88         AmpState amp_state_;
89     };
90 
AudioWidgetStateAudioWidgetState91     explicit AudioWidgetState(const AudioWidgetCaps& caps) : caps_(caps) { }
92 
93     const AudioWidgetCaps caps_;
94     const AudioFunctionGroupState* afg_ = nullptr;
95     uint16_t nid_;
96 
97     // Note: to simplify life, the widget struct contains the union of all of
98     // the different field which may be needed for any type of audio widget.
99     // Not all of the fields will be meaningful depending on the widget type.
100     uint32_t pcm_size_rate_; // Section 7.3.4.7 : Supported PCM sizes and rates
101     uint32_t pcm_formats_;   // Section 7.3.4.8 : Supported PCM formats
102     uint32_t pin_caps_ = 0;  // Section 7.3.4.9 : Pin Capabilities
103     StreamFormat cur_format_;
104 
105     // Section 7.3.3.11 : Stream tag and channel routing for converters.
106     uint8_t stream_tag_;
107     uint8_t stream_chan_;
108 
109     // Section 7.3.4.10 : Amplifier capabilities
110     AmpCaps input_amp_caps_;
111     AmpCaps output_amp_caps_;
112 
113     // Section 7.3.3.7 : Amplifier Gain/Mute state
114     AmpState input_amp_state_;
115     AmpState output_amp_state_;
116 
117     // Sections 7.3.3.2, 7.3.3.3 & 7.3.4.11 : Connection List
118     bool    long_form_conn_list_;
119     uint8_t conn_list_len_;
120     fbl::unique_ptr<ConnListEntry[]> conn_list_;
121     uint16_t connected_nid_;
122     uint8_t  connected_nid_ndx_;
123 
124     // Sections 7.3.4.12 & 7.3.3.10.
125     PowerState power_;
126 
127     // Section 7.3.4.13 : Processing Capabilities
128     bool    can_bypass_processing_;
129     uint8_t processing_coefficient_count_;
130 
131     // Section 7.3.4.15 : Volume Knob Capabilities
132     bool    vol_knob_is_delta_;
133     uint8_t vol_knob_steps_;
134 
135     // Section 7.3.3.31.  Present only in pin complexes
136     ConfigDefaults cfg_defaults_;
137 
138     // Section 7.3.3.12.  Present only in pin complexes
139     PinWidgetCtrlState pin_widget_ctrl_;
140 
141     // Section 7.3.3.14.
142     UnsolicitedResponseState unsol_resp_ctrl_;
143 
144     // Section 7.3.3.15
145     //
146     // Only valid for pin complexes, only run if the pin complex supports
147     // presence detect and the config defaults do not indicate a jack detect
148     // override.
149     PinSenseState pin_sense_;
150     bool          pin_sense_valid_ = false;
151 
152     // Section 7.3.3.16 : External amp power down state
153     EAPDState eapd_state_;
154 };
155 
156 struct FunctionGroupState {
~FunctionGroupStateFunctionGroupState157     virtual ~FunctionGroupState() { }
158 
159     enum class Type : uint8_t {
160         AUDIO        = 0x01,
161         MODEM        = 0x02,
162         VENDOR_START = 0x80,
163         VENDOR_END   = 0xFF,
164     };
165 
166     // Section 7.3.3.30
167     struct ImplementationID {
BoardImplIDFunctionGroupState::ImplementationID168         uint32_t BoardImplID() const { return (raw_data_ >> 8)  & 0xFFFFFF; }
BoardMfrIDFunctionGroupState::ImplementationID169         uint16_t BoardMfrID()  const { return static_cast<uint16_t>(raw_data_ >> 16); }
BoardSKUFunctionGroupState::ImplementationID170         uint8_t  BoardSKU()    const { return static_cast<uint8_t>((raw_data_ >> 8) & 0xFF); }
AssemblyIDFunctionGroupState::ImplementationID171         uint8_t  AssemblyID()  const { return static_cast<uint8_t>(raw_data_ & 0xFF); }
172         uint32_t raw_data_;
173     };
174 
175     const Type       type_;
176     bool             can_send_unsolicited_;
177     uint16_t         nid_;
178     ImplementationID impl_id_;
179     UnsolicitedResponseState unsol_resp_ctrl_;
180 
181 protected:
FunctionGroupStateFunctionGroupState182     explicit FunctionGroupState(Type type)
183         : type_(type) { }
184 };
185 
186 struct AudioFunctionGroupState : public FunctionGroupState {
AudioFunctionGroupStateAudioFunctionGroupState187     AudioFunctionGroupState() : FunctionGroupState(Type::AUDIO) { }
188 
189     AudioFunctionGroupCaps caps_;
190     uint32_t default_pcm_size_rate_; // Section 7.3.4.7 : Supported PCM sizes and rates
191     uint32_t default_pcm_formats_;   // Section 7.3.4.8 : Supported PCM formats
192 
193     // Section 7.3.4.10 : Amplifier capabilities
194     AmpCaps default_input_amp_caps_;
195     AmpCaps default_output_amp_caps_;
196 
197     // Sections 7.3.4.12 & 7.3.3.10.
198     PowerState power_;
199 
200     // Section 7.3.4.14 : GPIO Counts
201     bool    gpio_can_wake_;
202     bool    gpio_can_send_unsolicited_;
203     uint8_t gpio_count_;
204     uint8_t gpo_count_;
205     uint8_t gpi_count_;
206 
207     uint8_t widget_count_ = 0;
208     uint8_t widget_starting_id_ = 0;
209     fbl::unique_ptr<AudioWidgetStatePtr[]> widgets_;
210 };
211 
212 struct ModemFunctionGroupState : public FunctionGroupState {
ModemFunctionGroupStateModemFunctionGroupState213     ModemFunctionGroupState() : FunctionGroupState(Type::MODEM) { }
214 };
215 
216 struct VendorFunctionGroupState : public FunctionGroupState {
VendorFunctionGroupStateVendorFunctionGroupState217     explicit VendorFunctionGroupState(Type type)
218         : FunctionGroupState(type) {
219             ZX_DEBUG_ASSERT((type >= Type::VENDOR_START) &&
220                             (type <= Type::VENDOR_START));
221         }
222 };
223 
224 struct CodecState {
resetCodecState225     void reset() { fn_groups_.reset(); }
226 
227     uint16_t vendor_id_;
228     uint16_t device_id_;
229 
230     uint8_t  major_rev_;
231     uint8_t  minor_rev_;
232     uint8_t  vendor_rev_id_;
233     uint8_t  vendor_stepping_id_;
234 
235     uint8_t  fn_group_count_;
236     uint8_t  fn_group_starting_id_;
237     fbl::unique_ptr<FunctionGroupStatePtr[]> fn_groups_;
238 };
239 
240 }  // namespace audio
241 }  // namespace intel_hda
242