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
17namespace audio {
18namespace intel_hda {
19
20struct AudioWidgetState;
21using  AudioWidgetStatePtr = fbl::unique_ptr<AudioWidgetState>;
22
23struct FunctionGroupState;
24struct AudioFunctionGroupState;
25using  FunctionGroupStatePtr = fbl::unique_ptr<FunctionGroupState>;
26
27struct 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.
41struct UnsolicitedResponseState {
42    bool    enabled() const { return (raw_data_ & 0x80) != 0; }
43    uint8_t tag()     const { return static_cast<uint8_t>(raw_data_ & 0x3f); }
44    uint8_t raw_data_;
45};
46
47struct 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
52        uint32_t BASE() const { return (raw_data_ & (1u << 14)) ? 44100 : 48000; }
53        uint32_t CHAN() const { return (raw_data_ & 0xF) + 1; }
54        uint32_t DIV()  const { return ((raw_data_ >> 8) & 0x7) + 1; }
55        uint32_t MULT() const {
56            uint32_t bits = (raw_data_ >> 11) & 0x7;
57            if (bits >= 4)
58                return 0;
59            return bits + 1;
60        }
61        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
72        bool     is_pcm()        const { return (raw_data_ & FLAG_NON_PCM) == 0; }
73        uint32_t sample_rate()   const { return (BASE() * MULT()) / DIV(); }
74        uint32_t channels()      const { return CHAN(); }
75        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
91    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
156struct FunctionGroupState {
157    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 {
168        uint32_t BoardImplID() const { return (raw_data_ >> 8)  & 0xFFFFFF; }
169        uint16_t BoardMfrID()  const { return static_cast<uint16_t>(raw_data_ >> 16); }
170        uint8_t  BoardSKU()    const { return static_cast<uint8_t>((raw_data_ >> 8) & 0xFF); }
171        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
181protected:
182    explicit FunctionGroupState(Type type)
183        : type_(type) { }
184};
185
186struct AudioFunctionGroupState : public FunctionGroupState {
187    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
212struct ModemFunctionGroupState : public FunctionGroupState {
213    ModemFunctionGroupState() : FunctionGroupState(Type::MODEM) { }
214};
215
216struct VendorFunctionGroupState : public FunctionGroupState {
217    explicit VendorFunctionGroupState(Type type)
218        : FunctionGroupState(type) {
219            ZX_DEBUG_ASSERT((type >= Type::VENDOR_START) &&
220                            (type <= Type::VENDOR_START));
221        }
222};
223
224struct CodecState {
225    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