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 <fbl/intrusive_wavl_tree.h>
8#include <fbl/unique_ptr.h>
9
10#include <intel-hda/utils/codec-commands.h>
11
12#include "codec_state.h"
13#include "intel_hda_device.h"
14
15namespace audio {
16namespace intel_hda {
17
18struct CodecVerb;
19struct CodecResponse;
20
21class IntelHDACodec : public IntelHDADevice,
22                      public fbl::WAVLTreeContainable<fbl::unique_ptr<IntelHDACodec>> {
23public:
24    using CodecTree = fbl::WAVLTree<uint32_t, fbl::unique_ptr<IntelHDACodec>>;
25
26    template <typename TARGET_TYPE>
27    struct CommandListEntry {
28        CodecVerb verb;
29        zx_status_t (*parser)(TARGET_TYPE& target, const CodecResponse& resp);
30    };
31
32    zx_status_t DumpCodec(int argc, const char** argv);
33
34    uint32_t id()     const { return codec_id_; }
35    uint32_t GetKey() const { return id(); }
36
37    static zx_status_t Enumerate();
38    static CodecTree& codecs() { return codecs_; }
39
40private:
41    friend class fbl::unique_ptr<IntelHDACodec>;
42
43    zx_status_t DoCodecCmd(uint16_t nid, const CodecVerb& verb, CodecResponse* resp_out);
44    zx_status_t ReadCodecState();
45    zx_status_t ReadFunctionGroupState(FunctionGroupStatePtr& ptr, uint16_t nid);
46    zx_status_t ReadAudioFunctionGroupState(AudioFunctionGroupState& afg);
47    zx_status_t ReadAudioWidgetState(AudioWidgetState& widget);
48    zx_status_t ReadConnList(AudioWidgetState& widget);
49    zx_status_t ReadAmpState(uint16_t nid, bool is_input, uint8_t ndx,
50                             const AmpCaps& caps,
51                             AudioWidgetState::AmpState* state_out);
52
53    template <typename T>
54    zx_status_t RunCommandList(T& target,
55                               uint16_t nid,
56                               const CommandListEntry<T>* cmds,
57                               size_t cmd_count);
58
59    IntelHDACodec(uint32_t codec_id, const char* const dev_name)
60        : IntelHDADevice(dev_name),
61          codec_id_(codec_id) { }
62
63    ~IntelHDACodec() { }
64
65    const uint32_t codec_id_;
66    CodecState codec_state_;
67
68    static CodecTree codecs_;
69};
70
71}  // namespace audio
72}  // namespace intel_hda
73