/*
 * Copyright (c) 2020 Google LLC.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/*
 * PWM driver using the SAM0 Timer/Counter (TCC) in Normal PWM (NPWM) mode.
 * Supports the SAMD21 and SAMD5x series.
 */

#define DT_DRV_COMPAT atmel_sam0_tcc_pwm

#include <device.h>
#include <errno.h>
#include <drivers/pwm.h>
#include <soc.h>

/* Static configuration */
struct pwm_sam0_config {
	Tcc *regs;
	uint8_t channels;
	uint8_t counter_size;
	uint16_t prescaler;
	uint32_t freq;

#ifdef MCLK
	volatile uint32_t *mclk;
	uint32_t mclk_mask;
	uint16_t gclk_id;
#else
	uint32_t pm_apbcmask;
	uint16_t gclk_clkctrl_id;
#endif
};

#define DEV_CFG(dev) ((const struct pwm_sam0_config *const)(dev)->config)

/* Wait for the peripheral to finish all commands */
static void wait_synchronization(Tcc *regs)
{
	while (regs->SYNCBUSY.reg != 0) {
	}
}

static int pwm_sam0_get_cycles_per_sec(const struct device *dev, uint32_t ch,
				       uint64_t *cycles)
{
	const struct pwm_sam0_config *const cfg = DEV_CFG(dev);

	if (ch >= cfg->channels) {
		return -EINVAL;
	}
	*cycles = cfg->freq;

	return 0;
}

static int pwm_sam0_pin_set(const struct device *dev, uint32_t ch,
			    uint32_t period_cycles, uint32_t pulse_cycles,
			    pwm_flags_t flags)
{
	const struct pwm_sam0_config *const cfg = DEV_CFG(dev);
	Tcc *regs = cfg->regs;
	uint32_t top = 1 << cfg->counter_size;
	uint32_t invert_mask = 1 << ch;
	bool invert = ((flags & PWM_POLARITY_INVERTED) != 0);
	bool inverted = ((regs->DRVCTRL.vec.INVEN & invert_mask) != 0);

	if (ch >= cfg->channels) {
		return -EINVAL;
	}
	if (period_cycles >= top || pulse_cycles >= top) {
		return -EINVAL;
	}

	/*
	 * Update the buffered width and period.  These will be automatically
	 * loaded on the next cycle.
	 */
#ifdef TCC_PERBUF_PERBUF
	/* SAME51 naming */
	regs->CCBUF[ch].reg = TCC_CCBUF_CCBUF(pulse_cycles);
	regs->PERBUF.reg = TCC_PERBUF_PERBUF(period_cycles);
#else
	/* SAMD21 naming */
	regs->CCB[ch].reg = TCC_CCB_CCB(pulse_cycles);
	regs->PERB.reg = TCC_PERB_PERB(period_cycles);
#endif

	if (invert != inverted) {
		regs->CTRLA.bit.ENABLE = 0;
		wait_synchronization(regs);

		regs->DRVCTRL.vec.INVEN ^= invert_mask;
		regs->CTRLA.bit.ENABLE = 1;
		wait_synchronization(regs);
	}

	return 0;
}

static int pwm_sam0_init(const struct device *dev)
{
	const struct pwm_sam0_config *const cfg = DEV_CFG(dev);
	Tcc *regs = cfg->regs;

	/* Enable the clocks */
#ifdef MCLK
	GCLK->PCHCTRL[cfg->gclk_id].reg =
		GCLK_PCHCTRL_GEN_GCLK0 | GCLK_PCHCTRL_CHEN;
	*cfg->mclk |= cfg->mclk_mask;
#else
	GCLK->CLKCTRL.reg = cfg->gclk_clkctrl_id | GCLK_CLKCTRL_GEN_GCLK0 |
			    GCLK_CLKCTRL_CLKEN;
	PM->APBCMASK.reg |= cfg->pm_apbcmask;
#endif

	regs->CTRLA.bit.SWRST = 1;
	wait_synchronization(regs);

	regs->CTRLA.reg = cfg->prescaler;
	regs->WAVE.reg = TCC_WAVE_WAVEGEN_NPWM;
	regs->PER.reg = TCC_PER_PER(1);

	regs->CTRLA.bit.ENABLE = 1;
	wait_synchronization(regs);

	return 0;
}

static const struct pwm_driver_api pwm_sam0_driver_api = {
	.pin_set = pwm_sam0_pin_set,
	.get_cycles_per_sec = pwm_sam0_get_cycles_per_sec,
};

#ifdef MCLK
#define PWM_SAM0_INIT_CLOCKS(inst)					       \
	.mclk = (volatile uint32_t *)MCLK_MASK_DT_INT_REG_ADDR(inst),	       \
	.mclk_mask = BIT(DT_INST_CLOCKS_CELL_BY_NAME(inst, mclk, bit)),	       \
	.gclk_id = DT_INST_CLOCKS_CELL_BY_NAME(inst, gclk, periph_ch)
#else
#define PWM_SAM0_INIT_CLOCKS(inst)					       \
	.pm_apbcmask = BIT(DT_INST_CLOCKS_CELL_BY_NAME(inst, pm, bit)),	       \
	.gclk_clkctrl_id = DT_INST_CLOCKS_CELL_BY_NAME(inst, gclk, clkctrl_id)
#endif

#define PWM_SAM0_INIT(inst)						       \
	static const struct pwm_sam0_config pwm_sam0_config_##inst = {	       \
		.regs = (Tcc *)DT_INST_REG_ADDR(inst),			       \
		.channels = DT_INST_PROP(inst, channels),		       \
		.counter_size = DT_INST_PROP(inst, counter_size),	       \
		.prescaler = UTIL_CAT(TCC_CTRLA_PRESCALER_DIV,		       \
				      DT_INST_PROP(inst, prescaler)),	       \
		.freq = SOC_ATMEL_SAM0_GCLK0_FREQ_HZ /			       \
			DT_INST_PROP(inst, prescaler),			       \
		PWM_SAM0_INIT_CLOCKS(inst),				       \
	};								       \
									       \
	DEVICE_DT_INST_DEFINE(inst, &pwm_sam0_init, NULL,		       \
			    NULL, &pwm_sam0_config_##inst,		       \
			    POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE,   \
			    &pwm_sam0_driver_api);

DT_INST_FOREACH_STATUS_OKAY(PWM_SAM0_INIT)
