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 "codec_state.h"
8
9namespace audio {
10namespace intel_hda {
11
12class IntelHDACodec;
13
14class CodecStateFetcher {
15public:
16    using FinishedFn = zx_status_t (InitialCodecStateFetcher::*)();
17
18    InitialCodecStateFetcher(IntelHDACodec& codec);
19
20    bool IsFinished() final {
21        // We are finished when we have received all responses to our last command
22        // list and have no function groups left to process.
23        return (rx_ndx_ >= cmd_count_) && (fn_group_iter_ >= codec_.fn_group_count_);
24    }
25
26    // Accessors used by non-member result parser functions
27    CodecState& get_codec() const { return codec_; }
28
29    FunctionGroupStatePtr& get_fn_group_ptr() const {
30        ZX_DEBUG_ASSERT(codec_.fn_groups_ != nullptr);
31        ZX_DEBUG_ASSERT(fn_group_iter_ < codec_.fn_group_count_);
32        return codec_.fn_groups_[fn_group_iter_];
33    }
34
35    AudioFunctionGroupState& get_afg() const {
36        auto& ptr = get_fn_group_ptr();
37        ZX_DEBUG_ASSERT(ptr != nullptr);
38        ZX_DEBUG_ASSERT(ptr->type_ == FunctionGroupState::Type::AUDIO);
39        return *(static_cast<AudioFunctionGroupState*>(ptr.get()));
40    }
41
42    AudioWidgetStatePtr& get_widget_ptr() const {
43        auto& afg = get_afg();
44        ZX_DEBUG_ASSERT(afg.widgets_ != nullptr);
45        ZX_DEBUG_ASSERT(widget_iter_ < afg.widget_count_);
46        return afg.widgets_[widget_iter_];
47    }
48
49    AudioWidgetState& get_widget() const {
50        auto& ptr = get_widget_ptr();
51        ZX_DEBUG_ASSERT(ptr != nullptr);
52        return *ptr;
53    }
54
55    uint16_t get_nid() const { return nid_; }
56
57private:
58    zx_status_t FinishedCodecRoot();
59    zx_status_t FinishedFunctionGroup();
60    zx_status_t FinishedFunctionGroupType();
61    zx_status_t FinishedAFGProperties();
62    zx_status_t FinishedAudioWidget();
63    zx_status_t FinishedAudioWidgetType();
64    zx_status_t FinishedAudioWidgetCaps();
65    zx_status_t FinishedConnList();
66
67    void SetupCmdList(const CommandListEntry* cmds,
68                      size_t                  cmd_count,
69                      FinishedFn              finished,
70                      uint16_t                nid) {
71        cmds_      = cmds;
72        cmd_count_ = cmd_count;
73        tx_ndx_    = 0;
74        rx_ndx_    = 0;
75        nid_       = nid;
76        send_cmd_  = cmd_count ? &InitialCodecStateFetcher::CommandListTX : nullptr;
77        proc_resp_ = &InitialCodecStateFetcher::CommandListRX;
78        finished_  = finished;
79    }
80
81    void SetupConnListFetch() {
82        cmd_count_ = 0;
83        tx_ndx_    = 0;
84        rx_ndx_    = 0;
85        send_cmd_  = &InitialCodecStateFetcher::ConnListTX;
86        proc_resp_ = &InitialCodecStateFetcher::ConnListRX;
87        finished_  = &InitialCodecStateFetcher::FinishedAudioWidget;
88    }
89
90    IntelHDACodec&          codec_;
91    const CommandListEntry* cmds_      = nullptr;
92    size_t                  cmd_count_ = 0;
93    size_t                  tx_ndx_    = 0;
94    size_t                  rx_ndx_    = 0;
95    uint16_t                nid_       = 0;
96    SendCommandsFn          send_cmd_  = nullptr;
97    ProcResponseFn          proc_resp_ = nullptr;
98    FinishedFn              finished_  = nullptr;
99
100    uint32_t                fn_group_iter_  = -1;
101    uint32_t                widget_iter_    = -1;
102};
103
104}  // namespace audio
105}  // namespace intel_hda
106