/*
 * Copyright (c) 2023 Antmicro <www.antmicro.com>
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/drivers/bluetooth/hci_driver.h>

#include <sl_btctrl_linklayer.h>
#include <sl_hci_common_transport.h>
#include <pa_conversions_efr32.h>
#include <sl_bt_ll_zephyr.h>
#include <rail.h>

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

#define SL_BT_CONFIG_ACCEPT_LIST_SIZE				1
#define SL_BT_CONFIG_MAX_CONNECTIONS				1
#define SL_BT_CONFIG_USER_ADVERTISERS				1
#define SL_BT_CONTROLLER_BUFFER_MEMORY				CONFIG_BT_SILABS_HCI_BUFFER_MEMORY
#define SL_BT_CONTROLLER_LE_BUFFER_SIZE_MAX			CONFIG_BT_BUF_ACL_TX_COUNT
#define SL_BT_CONTROLLER_COMPLETED_PACKETS_THRESHOLD		1
#define SL_BT_CONTROLLER_COMPLETED_PACKETS_EVENTS_TIMEOUT	3
#define SL_BT_SILABS_LL_STACK_SIZE				1024

static K_KERNEL_STACK_DEFINE(slz_ll_stack, SL_BT_SILABS_LL_STACK_SIZE);
static struct k_thread slz_ll_thread;

void rail_isr_installer(void)
{
#ifdef CONFIG_SOC_SERIES_EFR32MG24
	IRQ_CONNECT(SYNTH_IRQn, 0, SYNTH_IRQHandler, NULL, 0);
#else
	IRQ_CONNECT(RDMAILBOX_IRQn, 0, RDMAILBOX_IRQHandler, NULL, 0);
#endif
	IRQ_CONNECT(RAC_SEQ_IRQn, 0, RAC_SEQ_IRQHandler, NULL, 0);
	IRQ_CONNECT(RAC_RSM_IRQn, 0, RAC_RSM_IRQHandler, NULL, 0);
	IRQ_CONNECT(PROTIMER_IRQn, 0, PROTIMER_IRQHandler, NULL, 0);
	IRQ_CONNECT(MODEM_IRQn, 0, MODEM_IRQHandler, NULL, 0);
	IRQ_CONNECT(FRC_IRQn, 0, FRC_IRQHandler, NULL, 0);
	IRQ_CONNECT(BUFC_IRQn, 0, BUFC_IRQHandler, NULL, 0);
	IRQ_CONNECT(AGC_IRQn, 0, AGC_IRQHandler, NULL, 0);
}

/**
 * @brief Transmit HCI message using the currently used transport layer.
 * The HCI calls this function to transmit a full HCI message.
 * @param[in] data Packet type followed by HCI packet data.
 * @param[in] len Length of the `data` parameter
 * @return 0 - on success, or non-zero on failure.
 */
uint32_t hci_common_transport_transmit(uint8_t *data, int16_t len)
{
	struct net_buf *buf;
	uint8_t packet_type = data[0];
	uint8_t event_code;

	LOG_HEXDUMP_DBG(data, len, "host packet data:");

	/* drop packet type from the frame buffer - it is no longer needed */
	data = &data[1];
	len -= 1;

	switch (packet_type) {
	case h4_event:
		event_code = data[0];
		buf = bt_buf_get_evt(event_code, false, K_FOREVER);
		break;
	case h4_acl:
		buf = bt_buf_get_rx(BT_BUF_ACL_IN, K_FOREVER);
		break;
	default:
		LOG_ERR("Unknown HCI type: %d", packet_type);
		return -EINVAL;
	}

	net_buf_add_mem(buf, data, len);
	bt_recv(buf);

	sl_btctrl_hci_transmit_complete(0);

	return 0;
}

static int slz_bt_send(struct net_buf *buf)
{
	int rv = 0;

	switch (bt_buf_get_type(buf)) {
	case BT_BUF_ACL_OUT:
		net_buf_push_u8(buf, h4_acl);
		break;
	case BT_BUF_CMD:
		net_buf_push_u8(buf, h4_command);
		break;
	default:
		rv = -EINVAL;
		goto done;
	}

	rv = hci_common_transport_receive(buf->data, buf->len, true);
	if (!rv) {
		goto done;
	}

done:
	net_buf_unref(buf);
	return rv;
}

static void slz_thread_func(void *p1, void *p2, void *p3)
{
	ARG_UNUSED(p1);
	ARG_UNUSED(p2);
	ARG_UNUSED(p3);

	slz_ll_thread_func();
}

static int slz_bt_open(void)
{
	int ret;

	/* Start RX thread */
	k_thread_create(&slz_ll_thread, slz_ll_stack,
			K_KERNEL_STACK_SIZEOF(slz_ll_stack),
			slz_thread_func, NULL, NULL, NULL,
			K_PRIO_COOP(CONFIG_BT_DRIVER_RX_HIGH_PRIO), 0,
			K_NO_WAIT);

	rail_isr_installer();
	sl_rail_util_pa_init();

	/* sl_btctrl_init_mem returns the number of memory buffers allocated */
	ret = sl_btctrl_init_mem(SL_BT_CONTROLLER_BUFFER_MEMORY);
	if (!ret) {
		LOG_ERR("Failed to allocate memory %d", ret);
		return -ENOMEM;
	}

	sl_btctrl_configure_le_buffer_size(SL_BT_CONTROLLER_LE_BUFFER_SIZE_MAX);

	ret = sl_btctrl_init_ll();
	if (ret) {
		LOG_ERR("Bluetooth link layer init failed %d", ret);
		goto deinit;
	}

	sl_btctrl_init_adv();
	sl_btctrl_init_scan();
	sl_btctrl_init_conn();
	sl_btctrl_init_adv_ext();
	sl_btctrl_init_scan_ext();

	ret = sl_btctrl_init_basic(SL_BT_CONFIG_MAX_CONNECTIONS,
			SL_BT_CONFIG_USER_ADVERTISERS,
			SL_BT_CONFIG_ACCEPT_LIST_SIZE);
	if (ret) {
		LOG_ERR("Failed to initialize the controller %d", ret);
		goto deinit;
	}

	sl_btctrl_configure_completed_packets_reporting(
		SL_BT_CONTROLLER_COMPLETED_PACKETS_THRESHOLD,
		SL_BT_CONTROLLER_COMPLETED_PACKETS_EVENTS_TIMEOUT);

	sl_bthci_init_upper();
	sl_btctrl_hci_parser_init_default();
	sl_btctrl_hci_parser_init_conn();
	sl_btctrl_hci_parser_init_adv();
	sl_btctrl_hci_parser_init_phy();

#ifdef CONFIG_PM
	{
		RAIL_Status_t status = RAIL_InitPowerManager();

		if (status != RAIL_STATUS_NO_ERROR) {
			LOG_ERR("RAIL: failed to initialize power management, status=%d",
					status);
			ret = -EIO;
			goto deinit;
		}
	}
#endif

	LOG_DBG("SiLabs BT HCI started");

	return 0;
deinit:
	sli_btctrl_deinit_mem();
	return ret;
}

static const struct bt_hci_driver drv = {
	.name           = "sl:bt",
	.bus            = BT_HCI_DRIVER_BUS_UART,
	.open           = slz_bt_open,
	.send           = slz_bt_send,
	.quirks         = BT_QUIRK_NO_RESET
};

static int slz_bt_init(void)
{
	int ret;

	ret = bt_hci_driver_register(&drv);
	if (ret) {
		LOG_ERR("Failed to register SiLabs BT HCI %d", ret);
	}

	return ret;
}

SYS_INIT(slz_bt_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE);
