/*
 * Copyright (c) 2023 Ambiq Micro Inc.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @brief Ambiq Apollox Blue SoC extended driver for SPI based HCI.
 */

#define DT_DRV_COMPAT ambiq_bt_hci_spi

#include <zephyr/init.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/pinctrl.h>
#include <zephyr/drivers/bluetooth/hci_driver.h>
#include <zephyr/bluetooth/hci.h>
#include <zephyr/bluetooth/hci_raw.h>

#define LOG_LEVEL CONFIG_BT_HCI_DRIVER_LOG_LEVEL
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(bt_apollox_driver);

#include <zephyr/drivers/clock_control.h>
#include <zephyr/drivers/clock_control/clock_control_ambiq.h>

#include "apollox_blue.h"
#include "am_devices_cooper.h"

#define HCI_SPI_NODE DT_COMPAT_GET_ANY_STATUS_OKAY(ambiq_bt_hci_spi)
#define SPI_DEV_NODE DT_BUS(HCI_SPI_NODE)
#define CLK_32M_NODE DT_NODELABEL(xo32m)
#define CLK_32K_NODE DT_NODELABEL(xo32k)

/* Command/response for SPI operation */
#define SPI_WRITE   0x80
#define SPI_READ    0x04
#define READY_BYTE0 0x68
#define READY_BYTE1 0xA8

/* Maximum attempts of SPI write */
#define SPI_WRITE_TIMEOUT 200

#define SPI_MAX_RX_MSG_LEN 258

static const struct gpio_dt_spec irq_gpio = GPIO_DT_SPEC_GET(HCI_SPI_NODE, irq_gpios);
static const struct gpio_dt_spec rst_gpio = GPIO_DT_SPEC_GET(HCI_SPI_NODE, reset_gpios);
static const struct gpio_dt_spec cs_gpio = GPIO_DT_SPEC_GET(SPI_DEV_NODE, cs_gpios);
static const struct gpio_dt_spec clkreq_gpio = GPIO_DT_SPEC_GET(HCI_SPI_NODE, clkreq_gpios);

static struct gpio_callback irq_gpio_cb;
static struct gpio_callback clkreq_gpio_cb;

static const struct device *clk32m_dev = DEVICE_DT_GET(CLK_32M_NODE);
static const struct device *clk32k_dev = DEVICE_DT_GET(CLK_32K_NODE);

extern void bt_packet_irq_isr(const struct device *unused1, struct gpio_callback *unused2,
			      uint32_t unused3);

static bool irq_pin_state(void)
{
	int pin_state;

	pin_state = gpio_pin_get_dt(&irq_gpio);
	LOG_DBG("IRQ Pin: %d", pin_state);
	return pin_state > 0;
}

static bool clkreq_pin_state(void)
{
	int pin_state;

	pin_state = gpio_pin_get_dt(&clkreq_gpio);
	LOG_DBG("CLKREQ Pin: %d", pin_state);
	return pin_state > 0;
}

static void bt_clkreq_isr(const struct device *unused1, struct gpio_callback *unused2,
			  uint32_t unused3)
{
	if (clkreq_pin_state()) {
		/* Enable XO32MHz */
		clock_control_on(clk32m_dev,
				 (clock_control_subsys_t)CLOCK_CONTROL_AMBIQ_TYPE_HFXTAL_BLE);
		gpio_pin_interrupt_configure_dt(&clkreq_gpio, GPIO_INT_EDGE_FALLING);
	} else {
		/* Disable XO32MHz */
		clock_control_off(clk32m_dev,
				  (clock_control_subsys_t)CLOCK_CONTROL_AMBIQ_TYPE_HFXTAL_BLE);
		gpio_pin_interrupt_configure_dt(&clkreq_gpio, GPIO_INT_EDGE_RISING);
	}
}

static void bt_apollo_controller_ready_wait(void)
{
	/* The CS pin is used to wake up the controller as well. If the controller is not ready
	 * to receive the SPI packet, need to inactivate the CS at first and reconfigure the pin
	 * to CS function again before next sending attempt.
	 */
	gpio_pin_configure_dt(&cs_gpio, GPIO_OUTPUT_INACTIVE);
	k_busy_wait(200);
	PINCTRL_DT_DEFINE(SPI_DEV_NODE);
	pinctrl_apply_state(PINCTRL_DT_DEV_CONFIG_GET(SPI_DEV_NODE), PINCTRL_STATE_DEFAULT);
	k_busy_wait(2000);
}

static void bt_apollo_controller_reset(void)
{
	/* Reset the controller*/
	gpio_pin_set_dt(&rst_gpio, 1);

	/* Take controller out of reset */
	k_sleep(K_MSEC(10));
	gpio_pin_set_dt(&rst_gpio, 0);

	/* Give the controller some time to boot */
	k_sleep(K_MSEC(500));
}

int bt_apollo_spi_send(uint8_t *data, uint16_t len, bt_spi_transceive_fun transceive)
{
	int ret;
	uint8_t command[1] = {SPI_WRITE};
	uint8_t response[2] = {0, 0};
	uint16_t fail_count = 0;

	do {
		/* Check if the controller is ready to receive the HCI packets. */
		ret = transceive(command, 1, response, 2);
		if ((response[0] != READY_BYTE0) || (response[1] != READY_BYTE1) || ret) {
			bt_apollo_controller_ready_wait();
		} else {
			/* Transmit the message */
			ret = transceive(data, len, NULL, 0);
			if (ret) {
				LOG_ERR("SPI write error %d", ret);
			}
			break;
		}
	} while (fail_count++ < SPI_WRITE_TIMEOUT);

	return ret;
}

int bt_apollo_spi_rcv(uint8_t *data, uint16_t *len, bt_spi_transceive_fun transceive)
{
	int ret;
	uint8_t command[1] = {SPI_READ};
	uint8_t response[2] = {0, 0};
	uint16_t read_size = 0;

	do {
		/* Skip if the IRQ pin is not in high state */
		if (!irq_pin_state()) {
			ret = -1;
			break;
		}

		/* Check the available packet bytes */
		ret = transceive(command, 1, response, 2);
		if (ret) {
			break;
		}

		/* Check if the read size is acceptable */
		read_size = (uint16_t)(response[0] | response[1] << 8);
		if ((read_size == 0) || (read_size > SPI_MAX_RX_MSG_LEN)) {
			ret = -1;
			break;
		}

		*len = read_size;

		/* Read the HCI data from controller */
		ret = transceive(NULL, 0, data, read_size);

		if (ret) {
			LOG_ERR("SPI read error %d", ret);
			break;
		}
	} while (0);

	return ret;
}

bool bt_apollo_vnd_rcv_ongoing(uint8_t *data, uint16_t len)
{
	/* The vendor specific handshake command/response is incompatible with
	 * standard Bluetooth HCI format, need to handle the received packets
	 * specifically.
	 */
	if (am_devices_cooper_get_initialize_state() != AM_DEVICES_COOPER_STATE_INITIALIZED) {
		am_devices_cooper_handshake_recv(data, len);
		return true;
	} else {
		return false;
	}
}

int bt_hci_transport_setup(const struct device *dev)
{
	ARG_UNUSED(dev);

	int ret;

	/* Configure the XO32MHz and XO32kHz clocks.*/
	clock_control_configure(clk32k_dev, NULL, NULL);
	clock_control_configure(clk32m_dev, NULL, NULL);

	/* Enable XO32kHz for Controller */
	clock_control_on(clk32k_dev, (clock_control_subsys_t)CLOCK_CONTROL_AMBIQ_TYPE_LFXTAL);

	/* Enable XO32MHz for Controller */
	clock_control_on(clk32m_dev, (clock_control_subsys_t)CLOCK_CONTROL_AMBIQ_TYPE_HFXTAL_BLE);

	/* Configure RST pin and hold BLE in Reset */
	ret = gpio_pin_configure_dt(&rst_gpio, GPIO_OUTPUT_ACTIVE);
	if (ret) {
		return ret;
	}

	/* Configure IRQ pin and register the callback */
	ret = gpio_pin_configure_dt(&irq_gpio, GPIO_INPUT);
	if (ret) {
		return ret;
	}

	gpio_init_callback(&irq_gpio_cb, bt_packet_irq_isr, BIT(irq_gpio.pin));
	ret = gpio_add_callback(irq_gpio.port, &irq_gpio_cb);
	if (ret) {
		return ret;
	}

	/* Configure CLKREQ pin and register the callback */
	ret = gpio_pin_configure_dt(&clkreq_gpio, GPIO_INPUT);
	if (ret) {
		return ret;
	}

	gpio_init_callback(&clkreq_gpio_cb, bt_clkreq_isr, BIT(clkreq_gpio.pin));
	ret = gpio_add_callback(clkreq_gpio.port, &clkreq_gpio_cb);
	if (ret) {
		return ret;
	}

	/* Configure the interrupt edge for CLKREQ pin */
	gpio_pin_interrupt_configure_dt(&clkreq_gpio, GPIO_INT_EDGE_RISING);

	/* Take controller out of reset */
	k_sleep(K_MSEC(10));
	gpio_pin_set_dt(&rst_gpio, 0);

	/* Give the controller some time to boot */
	k_sleep(K_MSEC(500));

	/* Configure the interrupt edge for IRQ pin */
	gpio_pin_interrupt_configure_dt(&irq_gpio, GPIO_INT_EDGE_RISING);

	return 0;
}

int bt_apollo_controller_init(spi_transmit_fun transmit)
{
	int ret;
	am_devices_cooper_callback_t cb = {
		.write = transmit,
		.reset = bt_apollo_controller_reset,
	};

	/* Initialize the BLE controller */
	ret = am_devices_cooper_init(&cb);
	if (ret == AM_DEVICES_COOPER_STATUS_SUCCESS) {
		am_devices_cooper_set_initialize_state(AM_DEVICES_COOPER_STATE_INITIALIZED);
		LOG_INF("BT controller initialized");
	} else {
		am_devices_cooper_set_initialize_state(AM_DEVICES_COOPER_STATE_INITIALIZE_FAIL);
		LOG_ERR("BT controller initialization fail");
	}

	return ret;
}

static int bt_apollo_set_nvds(void)
{
	int ret;
	struct net_buf *buf;

#if defined(CONFIG_BT_HCI_RAW)
	struct bt_hci_cmd_hdr hdr;

	hdr.opcode = sys_cpu_to_le16(HCI_VSC_UPDATE_NVDS_CFG_CMD_OPCODE);
	hdr.param_len = HCI_VSC_UPDATE_NVDS_CFG_CMD_LENGTH;
	buf = bt_buf_get_tx(BT_BUF_CMD, K_NO_WAIT, &hdr, sizeof(hdr));
	if (!buf) {
		return -ENOBUFS;
	}

	net_buf_add_mem(buf, &am_devices_cooper_nvds[0], HCI_VSC_UPDATE_NVDS_CFG_CMD_LENGTH);
	ret = bt_send(buf);

	if (!ret) {
		/* Give some time to make NVDS take effect in BLE controller */
		k_sleep(K_MSEC(5));

		/* Need to send reset command to make the NVDS take effect */
		hdr.opcode = sys_cpu_to_le16(BT_HCI_OP_RESET);
		hdr.param_len = 0;
		buf = bt_buf_get_tx(BT_BUF_CMD, K_NO_WAIT, &hdr, sizeof(hdr));
		if (!buf) {
			return -ENOBUFS;
		}

		ret = bt_send(buf);
	}
#else
	uint8_t *p;

	buf = bt_hci_cmd_create(HCI_VSC_UPDATE_NVDS_CFG_CMD_OPCODE,
				HCI_VSC_UPDATE_NVDS_CFG_CMD_LENGTH);
	if (!buf) {
		return -ENOBUFS;
	}

	p = net_buf_add(buf, HCI_VSC_UPDATE_NVDS_CFG_CMD_LENGTH);
	memcpy(p, &am_devices_cooper_nvds[0], HCI_VSC_UPDATE_NVDS_CFG_CMD_LENGTH);
	ret = bt_hci_cmd_send_sync(HCI_VSC_UPDATE_NVDS_CFG_CMD_OPCODE, buf, NULL);

	if (!ret) {
		/* Give some time to make NVDS take effect in BLE controller */
		k_sleep(K_MSEC(5));
	}
#endif /* defined(CONFIG_BT_HCI_RAW) */

	return ret;
}

int bt_apollo_vnd_setup(void)
{
	int ret;

	/* Set the NVDS parameters to BLE controller */
	ret = bt_apollo_set_nvds();

	return ret;
}

int bt_apollo_dev_init(void)
{
	if (!gpio_is_ready_dt(&irq_gpio)) {
		LOG_ERR("IRQ GPIO device not ready");
		return -ENODEV;
	}

	if (!gpio_is_ready_dt(&rst_gpio)) {
		LOG_ERR("Reset GPIO device not ready");
		return -ENODEV;
	}

	if (!gpio_is_ready_dt(&clkreq_gpio)) {
		LOG_ERR("CLKREQ GPIO device not ready");
		return -ENODEV;
	}

	return 0;
}
