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