/*
 * Copyright (c) 2018-2020 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <soc.h>
#include <zephyr/device.h>

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

#include "hal/debug.h"

/* Clock setup timeouts are unlikely, below values are experimental */
#define LFCLOCK_TIMEOUT_MS 500
#define HFCLOCK_TIMEOUT_MS 2

static uint16_t const sca_ppm_lut[] = {500, 250, 150, 100, 75, 50, 30, 20};

struct lll_clock_state {
	struct onoff_client cli;
	struct k_sem sem;
};

static struct onoff_client lf_cli;
static atomic_val_t hf_refcnt;

static void clock_ready(struct onoff_manager *mgr, struct onoff_client *cli,
			uint32_t state, int res)
{
	struct lll_clock_state *clk_state =
		CONTAINER_OF(cli, struct lll_clock_state, cli);

	k_sem_give(&clk_state->sem);
}

static int blocking_on(struct onoff_manager *mgr, uint32_t timeout)
{

	struct lll_clock_state state;
	int err;

	k_sem_init(&state.sem, 0, 1);
	sys_notify_init_callback(&state.cli.notify, clock_ready);
	err = onoff_request(mgr, &state.cli);
	if (err < 0) {
		return err;
	}

	return k_sem_take(&state.sem, K_MSEC(timeout));
}

int lll_clock_init(void)
{
	struct onoff_manager *mgr =
		z_nrf_clock_control_get_onoff(CLOCK_CONTROL_NRF_SUBSYS_LF);

	sys_notify_init_spinwait(&lf_cli.notify);

	return onoff_request(mgr, &lf_cli);
}

int lll_clock_deinit(void)
{
	struct onoff_manager *mgr =
		z_nrf_clock_control_get_onoff(CLOCK_CONTROL_NRF_SUBSYS_LF);

	return onoff_release(mgr);
}

int lll_clock_wait(void)
{
	struct onoff_manager *mgr;
	static bool done;
	int err;

	if (done) {
		return 0;
	}
	done = true;

	mgr = z_nrf_clock_control_get_onoff(CLOCK_CONTROL_NRF_SUBSYS_LF);
	err = blocking_on(mgr, LFCLOCK_TIMEOUT_MS);
	if (err) {
		return err;
	}

	err = onoff_release(mgr);
	if (err != ONOFF_STATE_ON) {
		return -EIO;
	}

	return 0;
}

int lll_hfclock_on(void)
{
	if (atomic_inc(&hf_refcnt) > 0) {
		return 0;
	}

	z_nrf_clock_bt_ctlr_hf_request();
	DEBUG_RADIO_XTAL(1);

	return 0;
}

int lll_hfclock_on_wait(void)
{
	struct onoff_manager *mgr =
		z_nrf_clock_control_get_onoff(CLOCK_CONTROL_NRF_SUBSYS_HF);
	int err;

	atomic_inc(&hf_refcnt);

	err = blocking_on(mgr, HFCLOCK_TIMEOUT_MS);
	if (err >= 0) {
		DEBUG_RADIO_XTAL(1);
	}

	return err;
}

int lll_hfclock_off(void)
{
	if (hf_refcnt < 1) {
		return -EALREADY;
	}

	if (atomic_dec(&hf_refcnt) > 1) {
		return 0;
	}

	z_nrf_clock_bt_ctlr_hf_release();
	DEBUG_RADIO_XTAL(0);

	return 0;
}

uint8_t lll_clock_sca_local_get(void)
{
	return CLOCK_CONTROL_NRF_K32SRC_ACCURACY;
}

uint32_t lll_clock_ppm_local_get(void)
{
	return sca_ppm_lut[CLOCK_CONTROL_NRF_K32SRC_ACCURACY];
}

uint32_t lll_clock_ppm_get(uint8_t sca)
{
	return sca_ppm_lut[sca];
}
