blob: a004998f9c6b65dd50007fc1f1912b84f8dc3760 [file] [log] [blame]
// Copyright 2018 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.
#ifndef GARNET_DRIVERS_BLUETOOTH_HCI_ATHEROS_DEVICE_H_
#define GARNET_DRIVERS_BLUETOOTH_HCI_ATHEROS_DEVICE_H_
#include <ddk/device.h>
#include <ddk/driver.h>
#include <ddk/protocol/bt/hci.h>
#include <ddk/protocol/usb.h>
#include <fbl/mutex.h>
#include <lib/sync/completion.h>
#include "garnet/drivers/bluetooth/lib/common/byte_buffer.h"
#include "garnet/drivers/bluetooth/lib/hci/control_packets.h"
#include "garnet/drivers/bluetooth/lib/hci/hci.h"
struct qca_version {
uint32_t rom_version;
uint32_t patch_version;
uint32_t ram_version;
uint32_t ref_clock;
uint8_t reserved[4];
} __PACKED;
namespace btatheros {
class Device {
public:
Device(zx_device_t* device, bt_hci_protocol_t* hci, usb_protocol_t* usb);
~Device() = default;
// Bind the device, invisibly.
zx_status_t Bind();
// Load the firmware over usb and complete device initialization.
// if firmware is loaded, the device will be made visible.
// otherwise the device will be removed and devhost will
// unbind.
zx_status_t LoadFirmware();
// ddk::Device methods
void DdkUnbind();
void DdkRelease();
zx_status_t DdkGetProtocol(uint32_t proto_id, void* out_proto);
zx_status_t DdkIoctl(uint32_t op, const void* in_buf, size_t in_len,
void* out_buf, size_t out_len, size_t* actual);
private:
// 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);
// Load the Qualcomm firmware in RAM
zx_status_t LoadRAM(const qca_version& ver);
// Load the Qualcomm firmware in NVM
zx_status_t LoadNVM(const qca_version& ver);
// Makes the device visible and leaves |note| on the kernel log.
// Returns ZX_OK.
zx_status_t Appear(const char* note);
// Maps the firmware referenced 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);
zx_device_t* parent_;
zx_device_t* zxdev_;
fbl::Mutex mutex_;
// Synchronization for the USB endpoint
sync_completion_t completion_ __TA_GUARDED(mutex_);
bt_hci_protocol_t hci_;
usb_protocol_t usb_;
size_t parent_req_size_ = 0;
uint8_t bulk_out_addr_ = 0;
bool firmware_loaded_ __TA_GUARDED(mutex_);
};
} // namespace btatheros
#endif // GARNET_DRIVERS_BLUETOOTH_HCI_ATHEROS_DEVICE_H_