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 #include <ddk/debug.h>
6 #include <ddk/metadata.h>
7 #include <ddk/platform-defs.h>
8 #include <ddk/protocol/serial.h>
9 #include <ddktl/protocol/gpioimpl.h>
10 #include <soc/aml-t931/t931-gpio.h>
11 #include <soc/aml-t931/t931-hw.h>
12 #include <unistd.h>
13 #include <zircon/device/serial.h>
14
15 #include "sherlock.h"
16
17 #define BT_REG_ON T931_GPIOX(17)
18
19 namespace sherlock {
20
21 namespace {
22
23 constexpr pbus_mmio_t bt_uart_mmios[] = {
24 {
25 .base = T931_UART_A_BASE,
26 .length = T931_UART_LENGTH,
27 },
28 };
29
30 constexpr pbus_irq_t bt_uart_irqs[] = {
31 {
32 .irq = T931_UART_A_IRQ,
33 .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
34 },
35 };
36
37 constexpr serial_port_info_t bt_uart_port_info = {
38 .serial_class = SERIAL_CLASS_BLUETOOTH_HCI,
39 .serial_vid = PDEV_VID_BROADCOM,
40 .serial_pid = PDEV_PID_BCM43458,
41 };
42
43 constexpr pbus_metadata_t bt_uart_metadata[] = {
44 {
45 .type = DEVICE_METADATA_SERIAL_PORT_INFO,
46 .data_buffer = &bt_uart_port_info,
47 .data_size = sizeof(bt_uart_port_info),
48 },
49 };
50
51 constexpr pbus_boot_metadata_t bt_uart_boot_metadata[] = {
52 {
53 .zbi_type = DEVICE_METADATA_MAC_ADDRESS,
54 .zbi_extra = MACADDR_BLUETOOTH,
55 },
56 };
57
__anon357aea5d0202() 58 const pbus_dev_t bt_uart_dev = []() {
59 pbus_dev_t dev;
60 dev.name = "bt-uart";
61 dev.vid = PDEV_VID_AMLOGIC;
62 dev.pid = PDEV_PID_GENERIC;
63 dev.did = PDEV_DID_AMLOGIC_UART;
64 dev.mmio_list = bt_uart_mmios;
65 dev.mmio_count = countof(bt_uart_mmios);
66 dev.irq_list = bt_uart_irqs;
67 dev.irq_count = countof(bt_uart_irqs);
68 dev.metadata_list = bt_uart_metadata;
69 dev.metadata_count = countof(bt_uart_metadata);
70 dev.boot_metadata_list = bt_uart_boot_metadata;
71 dev.boot_metadata_count = countof(bt_uart_boot_metadata);
72 return dev;
73 }();
74
75 } // namespace
76
BluetoothInit()77 zx_status_t Sherlock::BluetoothInit() {
78 zx_status_t status;
79
80 if (((status = gpio_impl_.SetAltFunction(T931_UART_A_TX, T931_UART_A_TX_FN)) != ZX_OK) ||
81 ((status = gpio_impl_.SetAltFunction(T931_UART_A_RX, T931_UART_A_RX_FN)) != ZX_OK) ||
82 ((status = gpio_impl_.SetAltFunction(T931_UART_A_CTS, T931_UART_A_CTS_FN)) != ZX_OK) ||
83 ((status = gpio_impl_.SetAltFunction(T931_UART_A_RTS, T931_UART_A_RTS_FN)) != ZX_OK)) {
84 return status;
85 }
86
87 if ((status = gpio_impl_.ConfigOut(BT_REG_ON, 0) != ZX_OK)) return status;
88 usleep(10 * 1000);
89 if ((status = gpio_impl_.Write(BT_REG_ON, 1) != ZX_OK)) return status;
90 usleep(10 * 1000);
91
92 status = pbus_.DeviceAdd(&bt_uart_dev);
93 if (status != ZX_OK) {
94 zxlogf(ERROR, "%s: DeviceAdd() error: %d\n", __func__, status);
95 return status;
96 }
97
98 return ZX_OK;
99 }
100
101 } // namespace sherlock
102