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 15namespace audio { 16namespace intel_hda { 17 18class ZirconDevice { 19public: 20 zx_status_t Connect(); 21 void Disconnect(); 22 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 30protected: 31 explicit ZirconDevice(const char* const dev_name) 32 : dev_name_(::strdup(dev_name)) { } 33 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> 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 73private: 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