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

#define DT_DRV_COMPAT ambiq_clkctrl

#include <errno.h>
#include <zephyr/init.h>
#include <zephyr/drivers/clock_control.h>
#include <zephyr/drivers/pinctrl.h>
#include <zephyr/drivers/clock_control/clock_control_ambiq.h>
#include <am_mcu_apollo.h>

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(clock_control_ambiq, CONFIG_CLOCK_CONTROL_LOG_LEVEL);

struct ambiq_clock_config {
	uint32_t clock_freq;
	const struct pinctrl_dev_config *pcfg;
};

static int ambiq_clock_on(const struct device *dev, clock_control_subsys_t sub_system)
{
	ARG_UNUSED(dev);

	int ret;
	uint32_t clock_name = (uint32_t)sub_system;
	am_hal_mcuctrl_control_arg_t arg = {
		.b_arg_hfxtal_in_use = true,
		.b_arg_apply_ext_source = false,
		.b_arg_force_update = false,
	};

	if (clock_name >= CLOCK_CONTROL_AMBIQ_TYPE_MAX) {
		return -EINVAL;
	}

	switch (clock_name) {
	case CLOCK_CONTROL_AMBIQ_TYPE_HFXTAL_BLE:
		arg.ui32_arg_hfxtal_user_mask = BIT(AM_HAL_HFXTAL_BLE_CONTROLLER_EN);
		arg.b_arg_enable_HfXtalClockout = true;
		ret = am_hal_mcuctrl_control(AM_HAL_MCUCTRL_CONTROL_EXTCLK32M_KICK_START, &arg);
		break;
	case CLOCK_CONTROL_AMBIQ_TYPE_LFXTAL:
		ret = am_hal_mcuctrl_control(AM_HAL_MCUCTRL_CONTROL_EXTCLK32K_ENABLE, 0);
	default:
		ret = -ENOTSUP;
		break;
	}

	return ret;
}

static int ambiq_clock_off(const struct device *dev, clock_control_subsys_t sub_system)
{
	ARG_UNUSED(dev);

	int ret;
	uint32_t clock_name = (uint32_t)sub_system;
	am_hal_mcuctrl_control_arg_t arg = {
		.b_arg_hfxtal_in_use = true,
		.b_arg_apply_ext_source = false,
		.b_arg_force_update = false,
	};

	if (clock_name >= CLOCK_CONTROL_AMBIQ_TYPE_MAX) {
		return -EINVAL;
	}

	switch (clock_name) {
	case CLOCK_CONTROL_AMBIQ_TYPE_HFXTAL_BLE:
		arg.ui32_arg_hfxtal_user_mask = BIT(AM_HAL_HFXTAL_BLE_CONTROLLER_EN);
		arg.b_arg_enable_HfXtalClockout = true;
		ret = am_hal_mcuctrl_control(AM_HAL_MCUCTRL_CONTROL_EXTCLK32M_DISABLE, &arg);
		break;
	case CLOCK_CONTROL_AMBIQ_TYPE_LFXTAL:
		ret = am_hal_mcuctrl_control(AM_HAL_MCUCTRL_CONTROL_EXTCLK32K_DISABLE, 0);
		break;
	default:
		ret = -ENOTSUP;
		break;
	}

	return ret;
}

static inline int ambiq_clock_get_rate(const struct device *dev, clock_control_subsys_t sub_system,
				       uint32_t *rate)
{
	ARG_UNUSED(sub_system);

	const struct ambiq_clock_config *cfg = dev->config;
	*rate = cfg->clock_freq;

	return 0;
}

static inline int ambiq_clock_configure(const struct device *dev, clock_control_subsys_t sub_system,
					void *data)
{
	ARG_UNUSED(sub_system);
	ARG_UNUSED(data);

	const struct ambiq_clock_config *cfg = dev->config;
	int ret;

	ret = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT);

	return ret;
}

static int ambiq_clock_init(const struct device *dev)
{
	ARG_UNUSED(dev);

	/* Nothing to do.*/
	return 0;
}

static const struct clock_control_driver_api ambiq_clock_driver_api = {
	.on = ambiq_clock_on,
	.off = ambiq_clock_off,
	.get_rate = ambiq_clock_get_rate,
	.configure = ambiq_clock_configure,
};

#define AMBIQ_CLOCK_INIT(n)                                                                        \
	PINCTRL_DT_INST_DEFINE(n);                                                                 \
	static const struct ambiq_clock_config ambiq_clock_config##n = {                           \
		.clock_freq = DT_INST_PROP(n, clock_frequency),                                    \
		.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n)};                                        \
	DEVICE_DT_INST_DEFINE(n, ambiq_clock_init, NULL, NULL, &ambiq_clock_config##n,             \
			      POST_KERNEL, CONFIG_CLOCK_CONTROL_INIT_PRIORITY,                     \
			      &ambiq_clock_driver_api);

DT_INST_FOREACH_STATUS_OKAY(AMBIQ_CLOCK_INIT)
