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/device/intel-hda.h> 9 #include <zircon/syscalls.h> 10 #include <zircon/types.h> 11 #include <stdlib.h> 12 #include <string.h> 13 #include <unistd.h> 14 15 namespace audio { 16 namespace intel_hda { 17 18 class ZirconDevice { 19 public: 20 zx_status_t Connect(); 21 void Disconnect(); 22 dev_name()23 const char* dev_name() const { return dev_name_ ? dev_name_ : "<unknown>"; } 24 25 using EnumerateCbk = zx_status_t (*)(void* ctx, uint32_t id, const char* const str); 26 static zx_status_t Enumerate(void* ctx, 27 const char* const dev_path, 28 EnumerateCbk cbk); 29 30 protected: ZirconDevice(const char * const dev_name)31 explicit ZirconDevice(const char* const dev_name) 32 : dev_name_(::strdup(dev_name)) { } 33 ~ZirconDevice()34 ~ZirconDevice() { 35 Disconnect(); 36 if (dev_name_) ::free(dev_name_); 37 } 38 39 template <typename ReqType, typename RespType> 40 zx_status_t CallDevice(const ReqType& req, RespType* resp, uint64_t timeout_msec = 100) { 41 if (!resp) 42 return ZX_ERR_INVALID_ARGS; 43 44 zx_status_t res = Connect(); 45 if (res != ZX_OK) 46 return res; 47 48 zx_channel_call_args_t args; 49 memset(&args, 0, sizeof(args)); 50 51 // TODO(johngro) : get rid of this const cast 52 args.wr_bytes = const_cast<ReqType*>(&req); 53 args.wr_num_bytes = sizeof(req); 54 args.rd_bytes = resp; 55 args.rd_num_bytes = sizeof(*resp); 56 57 return CallDevice(args, timeout_msec); 58 } 59 60 template <typename ReqType> InitRequest(ReqType * req,ihda_cmd_t cmd)61 static void InitRequest(ReqType* req, ihda_cmd_t cmd) { 62 ZX_DEBUG_ASSERT(req != nullptr); 63 memset(req, 0, sizeof(*req)); 64 do { 65 req->hdr.transaction_id = ++transaction_id_; 66 } while (req->hdr.transaction_id == IHDA_INVALID_TRANSACTION_ID); 67 req->hdr.cmd = cmd; 68 } 69 70 char* dev_name_; 71 zx_handle_t dev_channel_ = ZX_HANDLE_INVALID; 72 73 private: 74 zx_status_t CallDevice(const zx_channel_call_args_t& args, uint64_t timeout_msec); 75 static uint32_t transaction_id_; 76 }; 77 78 } // namespace audio 79 } // namespace intel_hda 80