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

#define DT_DRV_COMPAT atmel_sam0_dac

#include <errno.h>

#include <drivers/dac.h>
#include <drivers/pinctrl.h>
#include <soc.h>

/*
 * Maps between the DTS reference property names and register values.  Note that
 * the ASF uses the 09/2015 names which differ from the 03/2020 datasheet.
 *
 * TODO(#21273): replace once improved support for enum values lands.
 */
#define SAM0_DAC_REFSEL_0 DAC_CTRLB_REFSEL_INT1V_Val
#define SAM0_DAC_REFSEL_1 DAC_CTRLB_REFSEL_AVCC_Val
#define SAM0_DAC_REFSEL_2 DAC_CTRLB_REFSEL_VREFP_Val

struct dac_sam0_cfg {
	Dac *regs;
	const struct pinctrl_dev_config *pcfg;
	uint8_t pm_apbc_bit;
	uint8_t gclk_clkctrl_id;
	uint8_t refsel;
};

/* Write to the DAC. */
static int dac_sam0_write_value(const struct device *dev, uint8_t channel,
				uint32_t value)
{
	const struct dac_sam0_cfg *const cfg = dev->config;
	Dac *regs = cfg->regs;

	regs->DATA.reg = (uint16_t)value;

	return 0;
}

/*
 * Setup the channel.  As the SAM0 has one fixed width channel, this validates
 * the input and does nothing else.
 */
static int dac_sam0_channel_setup(const struct device *dev,
				  const struct dac_channel_cfg *channel_cfg)
{
	if (channel_cfg->channel_id != 0) {
		return -EINVAL;
	}
	if (channel_cfg->resolution != 10) {
		return -ENOTSUP;
	}

	return 0;
}

/* Initialise and enable the DAC. */
static int dac_sam0_init(const struct device *dev)
{
	const struct dac_sam0_cfg *const cfg = dev->config;
	Dac *regs = cfg->regs;
	int retval;

	/* Enable the GCLK */
	GCLK->CLKCTRL.reg = cfg->gclk_clkctrl_id | GCLK_CLKCTRL_GEN_GCLK0 |
			    GCLK_CLKCTRL_CLKEN;

	retval = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT);
	if (retval < 0) {
		return retval;
	}

	/* Enable the clock in PM */
	PM->APBCMASK.reg |= 1 << cfg->pm_apbc_bit;

	/* Reset then configure the DAC */
	regs->CTRLA.bit.SWRST = 1;
	while (regs->STATUS.bit.SYNCBUSY) {
	}

	regs->CTRLB.bit.REFSEL = cfg->refsel;
	regs->CTRLB.bit.EOEN = 1;

	/* Enable */
	regs->CTRLA.bit.ENABLE = 1;
	while (regs->STATUS.bit.SYNCBUSY) {
	}

	return 0;
}

static const struct dac_driver_api api_sam0_driver_api = {
	.channel_setup = dac_sam0_channel_setup,
	.write_value = dac_sam0_write_value
};

#define SAM0_DAC_REFSEL(n)						       \
	COND_CODE_1(DT_INST_NODE_HAS_PROP(n, reference),		       \
		    (DT_INST_ENUM_IDX(n, reference)), (0))

#define SAM0_DAC_INIT(n)						       \
	PINCTRL_DT_INST_DEFINE(n);					       \
	static const struct dac_sam0_cfg dac_sam0_cfg_##n = {		       \
		.regs = (Dac *)DT_INST_REG_ADDR(n),			       \
		.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n),		       \
		.pm_apbc_bit = DT_INST_CLOCKS_CELL_BY_NAME(n, pm, bit),	       \
		.gclk_clkctrl_id =					       \
			DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, clkctrl_id),      \
		.refsel = UTIL_CAT(SAM0_DAC_REFSEL_, SAM0_DAC_REFSEL(n)),      \
	};								       \
									       \
	DEVICE_DT_INST_DEFINE(n, &dac_sam0_init, NULL, NULL,		       \
			    &dac_sam0_cfg_##n, POST_KERNEL,		       \
			    CONFIG_DAC_INIT_PRIORITY,			       \
			    &api_sam0_driver_api)

DT_INST_FOREACH_STATUS_OKAY(SAM0_DAC_INIT);
