/*
 * Copyright (c) 2020 Intel Corporation
 * Copyright (c) 2022 Microchip Technology Inc.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT microchip_xec_tach

#include <errno.h>
#include <zephyr/device.h>
#ifdef CONFIG_SOC_SERIES_MEC172X
#include <zephyr/drivers/clock_control/mchp_xec_clock_control.h>
#include <zephyr/drivers/interrupt_controller/intc_mchp_xec_ecia.h>
#endif
#ifdef CONFIG_PINCTRL
#include <zephyr/drivers/pinctrl.h>
#endif
#include <zephyr/drivers/sensor.h>
#include <soc.h>
#include <zephyr/sys/sys_io.h>
#include <zephyr/logging/log.h>

LOG_MODULE_REGISTER(tach_xec, CONFIG_SENSOR_LOG_LEVEL);

struct tach_xec_config {
	struct tach_regs * const regs;
	uint8_t girq;
	uint8_t girq_pos;
	uint8_t pcr_idx;
	uint8_t pcr_pos;
#ifdef CONFIG_PINCTRL
	const struct pinctrl_dev_config *pcfg;
#endif
};

struct tach_xec_data {
	uint16_t count;
};

#define FAN_STOPPED		0xFFFFU
#define COUNT_100KHZ_SEC	100000U
#define SEC_TO_MINUTE		60U
#define PIN_STS_TIMEOUT		20U
#define TACH_CTRL_EDGES		(CONFIG_TACH_XEC_EDGES << \
				 MCHP_TACH_CTRL_NUM_EDGES_POS)

int tach_xec_sample_fetch(const struct device *dev, enum sensor_channel chan)
{
	ARG_UNUSED(chan);

	const struct tach_xec_config * const cfg = dev->config;
	struct tach_xec_data * const data = dev->data;
	struct tach_regs * const tach = cfg->regs;
	uint8_t poll_count = 0;

	while (poll_count < PIN_STS_TIMEOUT) {
		/* See whether internal counter is already latched */
		if (tach->STATUS & MCHP_TACH_STS_CNT_RDY) {
			data->count =
				tach->CONTROL >> MCHP_TACH_CTRL_COUNTER_POS;
			break;
		}

		poll_count++;

		/* Allow other threads to run while we sleep */
		k_usleep(USEC_PER_MSEC);
	}

	if (poll_count == PIN_STS_TIMEOUT) {
		return -EINVAL;
	}

	/* We interpret a fan stopped or jammed as 0 */
	if (data->count == FAN_STOPPED) {
		data->count = 0U;
	}

	return 0;
}

static int tach_xec_channel_get(const struct device *dev,
				enum sensor_channel chan,
				struct sensor_value *val)
{
	struct tach_xec_data * const data = dev->data;

	if (chan != SENSOR_CHAN_RPM) {
		return -ENOTSUP;
	}

	/* Convert the count per 100khz cycles to rpm */
	if (data->count != FAN_STOPPED && data->count != 0U) {
		val->val1 = (SEC_TO_MINUTE * COUNT_100KHZ_SEC)/data->count;
		val->val2 = 0U;
	} else {
		val->val1 =  0U;
	}

	val->val2 = 0U;

	return 0;
}

static void tach_xec_sleep_clr(const struct device *dev)
{
	const struct tach_xec_config * const cfg = dev->config;
	struct pcr_regs * const pcr = (struct pcr_regs * const)(
		DT_REG_ADDR_BY_IDX(DT_NODELABEL(pcr), 0));

#ifdef CONFIG_SOC_SERIES_MEC172X
	pcr->SLP_EN[cfg->pcr_idx] &= ~BIT(cfg->pcr_pos);
#else
	uintptr_t addr = (uintptr_t)&pcr->SLP_EN0 + (4u * cfg->pcr_idx);
	uint32_t pcr_val = sys_read32(addr) & ~BIT(cfg->pcr_pos);

	sys_write32(pcr_val, addr);
#endif
}

static int tach_xec_init(const struct device *dev)
{
	const struct tach_xec_config * const cfg = dev->config;
	struct tach_regs * const tach = cfg->regs;

#ifdef CONFIG_PINCTRL
	int ret = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT);

	if (ret != 0) {
		LOG_ERR("XEC TACH pinctrl init failed (%d)", ret);
		return ret;
	}
#endif

	tach_xec_sleep_clr(dev);

	tach->CONTROL = MCHP_TACH_CTRL_READ_MODE_100K_CLOCK	|
			TACH_CTRL_EDGES	                        |
			MCHP_TACH_CTRL_FILTER_EN		|
			MCHP_TACH_CTRL_EN;

	return 0;
}

static const struct sensor_driver_api tach_xec_driver_api = {
	.sample_fetch = tach_xec_sample_fetch,
	.channel_get = tach_xec_channel_get,
};

#ifdef CONFIG_PINCTRL
#define XEC_TACH_PINCTRL_DEF(inst) PINCTRL_DT_INST_DEFINE(inst)
#define XEC_TACH_CONFIG(inst)						\
	static const struct tach_xec_config tach_xec_config_##inst = {	\
		.regs = (struct tach_regs * const)DT_INST_REG_ADDR(inst),	\
		.girq = DT_INST_PROP_BY_IDX(inst, girqs, 0),		\
		.girq_pos = DT_INST_PROP_BY_IDX(inst, girqs, 1),	\
		.pcr_idx = DT_INST_PROP_BY_IDX(inst, pcrs, 0),		\
		.pcr_pos = DT_INST_PROP_BY_IDX(inst, pcrs, 1),		\
		.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst),		\
	}
#else
#define XEC_TACH_PINCTRL_DEF(inst)
#define XEC_TACH_CONFIG(inst)						\
	static const struct tach_xec_config tach_xec_config_##inst = {	\
		.regs = (struct tach_regs * const)DT_INST_REG_ADDR(inst),	\
		.girq = DT_INST_PROP_BY_IDX(inst, girqs, 0),		\
		.girq_pos = DT_INST_PROP_BY_IDX(inst, girqs, 1),	\
		.pcr_idx = DT_INST_PROP_BY_IDX(inst, pcrs, 0),		\
		.pcr_pos = DT_INST_PROP_BY_IDX(inst, pcrs, 1),		\
	}
#endif

#define TACH_XEC_DEVICE(id)						\
	static struct tach_xec_data tach_xec_data_##id;			\
									\
	XEC_TACH_PINCTRL_DEF(id);					\
									\
	XEC_TACH_CONFIG(id);						\
									\
	DEVICE_DT_INST_DEFINE(id,					\
			    tach_xec_init,				\
			    NULL,					\
			    &tach_xec_data_##id,			\
			    &tach_xec_config_##id,			\
			    POST_KERNEL,				\
			    CONFIG_SENSOR_INIT_PRIORITY,		\
			    &tach_xec_driver_api);

DT_INST_FOREACH_STATUS_OKAY(TACH_XEC_DEVICE)
