blob: 10c7c6c64a21f255d071c84f2b64184a376ebc15 [file] [log] [blame]
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#pragma once
#include <ddk/driver.h>
#include <ddk/protocol/bt/hci.h>
#include <ddktl/device.h>
#include <ddktl/protocol/bt/hci.h>
#include <fuchsia/hardware/bluetooth/c/fidl.h>
#include "vendor_hci.h"
namespace btintel {
class Device;
using DeviceType = ddk::Device<Device, ddk::GetProtocolable, ddk::UnbindableNew,
ddk::Messageable>;
class Device : public DeviceType, public ddk::BtHciProtocol<Device, ddk::base_protocol> {
public:
Device(zx_device_t* device, bt_hci_protocol_t* hci);
~Device() = default;
// Bind the device, invisibly.
zx_status_t Bind();
// Load the firmware and complete device initialization.
// if firmware is loaded, the device will be made visible.
// otherwise the device will be removed and devhost will
// unbind.
// If |secure| is true, use the "secure" firmware method.
zx_status_t LoadFirmware(bool secure);
// ddk::Device methods
void DdkUnbindNew(ddk::UnbindTxn txn);
void DdkRelease();
zx_status_t DdkGetProtocol(uint32_t proto_id, void* out_proto);
zx_status_t DdkMessage(fidl_msg_t* msg, fidl_txn_t* txn);
zx_status_t BtHciOpenCommandChannel(zx::channel in);
zx_status_t BtHciOpenAclDataChannel(zx::channel in);
zx_status_t BtHciOpenSnoopChannel(zx::channel in);
private:
static zx_status_t OpenCommandChannel(void* ctx, zx_handle_t in);
static zx_status_t OpenAclDataChannel(void* ctx, zx_handle_t in);
static zx_status_t OpenSnoopChannel(void* ctx, zx_handle_t in);
static constexpr fuchsia_hardware_bluetooth_Hci_ops_t fidl_ops_ = {
.OpenCommandChannel = OpenCommandChannel,
.OpenAclDataChannel = OpenAclDataChannel,
.OpenSnoopChannel = OpenSnoopChannel,
};
zx_status_t LoadSecureFirmware(zx::channel* cmd, zx::channel* acl);
zx_status_t LoadLegacyFirmware(zx::channel* cmd, zx::channel* acl);
// Removes the device and leaves an error on the kernel log
// prepended with |note|.
// Returns |status|.
zx_status_t Remove(zx_status_t status, const char* note);
// Maps the firmware refrenced by |name| into memory.
// Returns the vmo that the firmware is loaded into or ZX_HANDLE_INVALID if it
// could not be loaded.
// Closing this handle will invalidate |fw_addr|, which
// receives a pointer to the memory.
// |fw_size| receives the size of the firmware if valid.
zx_handle_t MapFirmware(const char* name, uintptr_t* fw_addr, size_t* fw_size);
ddk::BtHciProtocolClient hci_;
bool firmware_loaded_;
};
} // namespace btintel