// 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.

#include <ddk/debug.h>
#include <ddk/device.h>
#include <ddk/metadata.h>
#include <ddk/mmio-buffer.h>
#include <ddk/platform-defs.h>
#include <ddk/protocol/gpio.h>
#include <ddk/protocol/platform/bus.h>
#include <ddk/protocol/serial.h>
#include <fuchsia/hardware/serial/c/fidl.h>
#include <hw/reg.h>
#include <soc/aml-s912/s912-gpio.h>
#include <soc/aml-s912/s912-hw.h>
#include <unistd.h>

#include "vim.h"

namespace vim {
// set this to enable UART test driver, which uses the second UART
// on the 40 pin header
#define UART_TEST 1

#define WIFI_32K S912_GPIOX(16)
#define BT_EN S912_GPIOX(17)

static const pbus_mmio_t bt_uart_mmios[] = {
    // UART_A, for BT HCI
    {
        .base = S912_UART_A_BASE,
        .length = S912_UART_A_LENGTH,
    },
};

static const pbus_irq_t bt_uart_irqs[] = {
    // UART_A, for BT HCI
    {
        .irq = S912_UART_A_IRQ,
        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
    },
};

static const serial_port_info_t bt_uart_serial_info = {
    .serial_class = fuchsia_hardware_serial_Class_BLUETOOTH_HCI,
    .serial_vid = PDEV_VID_BROADCOM,
    .serial_pid = PDEV_PID_BCM4356,
};

static const pbus_metadata_t bt_uart_metadata[] = {
    {
        .type = DEVICE_METADATA_SERIAL_PORT_INFO,
        .data_buffer = &bt_uart_serial_info,
        .data_size = sizeof(bt_uart_serial_info),
    },
};

static pbus_dev_t bt_uart_dev = [] {
    pbus_dev_t dev;
    dev.name = "bt-uart";
    dev.vid = PDEV_VID_AMLOGIC;
    dev.pid = PDEV_PID_GENERIC;
    dev.did = PDEV_DID_AMLOGIC_UART;
    dev.mmio_list = bt_uart_mmios;
    dev.mmio_count = countof(bt_uart_mmios);
    dev.irq_list = bt_uart_irqs;
    dev.irq_count = countof(bt_uart_irqs);
    dev.metadata_list = bt_uart_metadata;
    dev.metadata_count = countof(bt_uart_metadata);
    return dev;
}();

#if UART_TEST
static const pbus_mmio_t header_uart_mmios[] = {
    // UART_AO_B, on 40 pin header
    {
        .base = S912_UART_AO_B_BASE,
        .length = S912_UART_AO_B_LENGTH,
    },
};

static const pbus_irq_t header_uart_irqs[] = {
    // UART_AO_B, on 40 pin header
    {
        .irq = S912_UART_AO_B_IRQ,
        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
    },
};

static const serial_port_info_t header_serial_info = []() {
    serial_port_info_t serial_port_info;
    serial_port_info.serial_class = fuchsia_hardware_serial_Class_GENERIC;
    return serial_port_info;
}();

static const pbus_metadata_t header_metadata[] = {
    {
        .type = DEVICE_METADATA_SERIAL_PORT_INFO,
        .data_buffer = &header_serial_info,
        .data_size = sizeof(header_serial_info),
    },
};

static pbus_dev_t header_uart_dev = []() {
    pbus_dev_t dev;
    dev.name = "header-uart";
    dev.vid = PDEV_VID_AMLOGIC;
    dev.pid = PDEV_PID_GENERIC;
    dev.did = PDEV_DID_AMLOGIC_UART;
    dev.mmio_list = header_uart_mmios;
    dev.mmio_count = countof(header_uart_mmios);
    dev.irq_list = header_uart_irqs;
    dev.irq_count = countof(header_uart_irqs);
    dev.metadata_list = header_metadata;
    dev.metadata_count = countof(header_metadata);
    return dev;
}();
#endif

// Enables and configures PWM_E on the WIFI_32K line for the Wifi/Bluetooth module
zx_status_t Vim::EnableWifi32K() {
    // Configure WIFI_32K pin for PWM_E
    zx_status_t status = gpio_impl_.SetAltFunction(WIFI_32K, 1);
    if (status != ZX_OK)
        return status;

    mmio_buffer_t buffer;
    // Please do not use get_root_resource() in new code. See ZX-1467.
    status = mmio_buffer_init_physical(&buffer, S912_PWM_BASE, 0x10000, get_root_resource(),
                                       ZX_CACHE_POLICY_UNCACHED_DEVICE);
    if (status != ZX_OK) {
        zxlogf(ERROR, "vim_enable_wifi_32K: io_buffer_init_physical failed: %d\n", status);
        return status;
    }
    uint32_t* regs = (uint32_t*)buffer.vaddr;

    // these magic numbers were gleaned by instrumenting drivers/amlogic/pwm/pwm_meson.c
    // TODO(voydanoff) write a proper PWM driver
    writel(0x016d016e, regs + S912_PWM_PWM_E);
    writel(0x016d016d, regs + S912_PWM_E2);
    writel(0x0a0a0609, regs + S912_PWM_TIME_EF);
    writel(0x02808003, regs + S912_PWM_MISC_REG_EF);

    mmio_buffer_release(&buffer);

    return ZX_OK;
}

zx_status_t Vim::UartInit() {
    zx_status_t status;

    // set alternate functions to enable UART_A and UART_AO_B
    status = gpio_impl_.SetAltFunction(S912_UART_TX_A, S912_UART_TX_A_FN);
    if (status != ZX_OK)
        return status;
    status = gpio_impl_.SetAltFunction(S912_UART_RX_A, S912_UART_RX_A_FN);
    if (status != ZX_OK)
        return status;
    status = gpio_impl_.SetAltFunction(S912_UART_CTS_A, S912_UART_CTS_A_FN);
    if (status != ZX_OK)
        return status;
    status = gpio_impl_.SetAltFunction(S912_UART_RTS_A, S912_UART_RTS_A_FN);
    if (status != ZX_OK)
        return status;
    status = gpio_impl_.SetAltFunction(S912_UART_TX_AO_B, S912_UART_TX_AO_B_FN);
    if (status != ZX_OK)
        return status;
    status = gpio_impl_.SetAltFunction(S912_UART_RX_AO_B, S912_UART_RX_AO_B_FN);
    if (status != ZX_OK)
        return status;

    // Configure the WIFI_32K PWM, which is needed for the Bluetooth module to work properly
    status = EnableWifi32K();
    if (status != ZX_OK) {
        return status;
    }

    // set GPIO to reset Bluetooth module
    gpio_impl_.ConfigOut(BT_EN, 0);
    usleep(10 * 1000);
    gpio_impl_.Write(BT_EN, 1);

    // Bind UART for Bluetooth HCI
    status = pbus_.DeviceAdd(&bt_uart_dev);
    if (status != ZX_OK) {
        zxlogf(ERROR, "UartInit: pbus_device_add failed: %d\n", status);
        return status;
    }

#if UART_TEST
    // Bind UART for 40-pin header
    status = pbus_.DeviceAdd(&header_uart_dev);
    if (status != ZX_OK) {
        zxlogf(ERROR, "UartInit: pbus_device_add failed: %d\n", status);
        return status;
    }
#endif

    return ZX_OK;
}
} //namespace vim
