1// Copyright 2018 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 <ddk/device.h> 8#include <ddk/protocol/intel-hda-codec.h> 9#include <ddk/protocol/intel-hda-dsp.h> 10#include <fbl/mutex.h> 11#include <fbl/ref_counted.h> 12#include <fbl/ref_ptr.h> 13#include <zircon/thread_annotations.h> 14#include <stdint.h> 15#include <string.h> 16 17#include <dispatcher-pool/dispatcher-channel.h> 18#include <dispatcher-pool/dispatcher-execution-domain.h> 19#include <intel-hda/utils/intel-hda-proto.h> 20#include <intel-hda/utils/intel-hda-registers.h> 21#include <intel-hda/utils/utils.h> 22 23#include "debug-logging.h" 24#include "intel-hda-stream.h" 25 26namespace audio { 27namespace intel_hda { 28 29class IntelHDAController; 30 31class IntelHDADSP : public fbl::RefCounted<IntelHDADSP> { 32public: 33 static fbl::RefPtr<IntelHDADSP> Create(IntelHDAController& controller, 34 hda_pp_registers_t* pp_regs, 35 const fbl::RefPtr<RefCountedBti>& pci_bti); 36 37 const char* log_prefix() const { return log_prefix_; } 38 39 void ProcessIRQ(); 40 41private: 42 friend class fbl::RefPtr<IntelHDADSP>; 43 44 static zx_protocol_device_t DSP_DEVICE_THUNKS; 45 static ihda_codec_protocol_ops_t CODEC_PROTO_THUNKS; 46 static ihda_dsp_protocol_ops_t DSP_PROTO_THUNKS; 47 48 IntelHDADSP(IntelHDAController& controller, 49 hda_pp_registers_t* pp_regs, 50 const fbl::RefPtr<RefCountedBti>& pci_bti); 51 ~IntelHDADSP() { }; 52 53 hda_pp_registers_t* pp_regs() const { 54 return pp_regs_; 55 } 56 57 zx_status_t PublishDevice(); 58 59 // Device interface 60 zx_status_t DeviceGetProtocol(uint32_t proto_id, void* protocol); 61 zx_status_t DeviceIoctl(uint32_t op, void* out_buf, size_t out_len, size_t* out_actual); 62 void DeviceUnbind(); 63 64 // ZX_PROTOCOL_IHDA_DSP interface 65 void GetDevInfo(zx_pcie_device_info_t* out_info); 66 zx_status_t GetMmio(zx_handle_t* out_vmo, size_t* out_size); 67 zx_status_t GetBti(zx_handle_t* out_handle); 68 void Enable(); 69 void Disable(); 70 zx_status_t IrqEnable(ihda_dsp_irq_callback_t* callback, void* cookie); 71 void IrqDisable(); 72 73 // ZX_PROTOCOL_IHDA_CODEC Interface 74 zx_status_t CodecGetDispatcherChannel(zx_handle_t* channel_out); 75 76 // Thunks for interacting with clients and codec drivers. 77 zx_status_t ProcessClientRequest(dispatcher::Channel* channel, bool is_driver_channel); 78 void ProcessClientDeactivate(const dispatcher::Channel* channel); 79 zx_status_t ProcessRequestStream(dispatcher::Channel* channel, 80 const ihda_proto::RequestStreamReq& req); 81 zx_status_t ProcessReleaseStream(dispatcher::Channel* channel, 82 const ihda_proto::ReleaseStreamReq& req); 83 zx_status_t ProcessSetStreamFmt(dispatcher::Channel* channel, 84 const ihda_proto::SetStreamFmtReq& req); 85 86 // Reference to our owner. 87 IntelHDAController& controller_; 88 89 fbl::Mutex dsp_lock_; 90 ihda_dsp_irq_callback_t* irq_callback_ TA_GUARDED(dsp_lock_) = nullptr; 91 void* irq_cookie_ TA_GUARDED(dsp_lock_) = nullptr; 92 93 // Driver connection state 94 fbl::Mutex codec_driver_channel_lock_; 95 fbl::RefPtr<dispatcher::Channel> codec_driver_channel_ TA_GUARDED(codec_driver_channel_lock_); 96 97 // Log prefix storage 98 char log_prefix_[LOG_PREFIX_STORAGE] = { 0 }; 99 100 // Published device node. 101 zx_device_t* dev_node_ = nullptr; 102 103 // Pipe processintg registers 104 hda_pp_registers_t* pp_regs_ = nullptr; 105 106 // A handle to the Bus Transaction Initiator for the controller. 107 fbl::RefPtr<RefCountedBti> pci_bti_; 108 109 // Dispatcher framework state. 110 fbl::RefPtr<dispatcher::ExecutionDomain> default_domain_; 111 112 // Active DMA streams 113 fbl::Mutex active_streams_lock_; 114 IntelHDAStream::Tree active_streams_ TA_GUARDED(active_streams_lock_); 115}; 116 117} // namespace intel_hda 118} // namespace audio 119