/*
 * Copyright (c) 2015 Intel Corporation.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @file Driver for DesignWare PWM driver.
 *
 * The timer IP block can act as both timer and PWM. Under PWM mode, each port
 * has two registers to specify how long to stay low, and how long to stay high.
 * Care must be taken so that PWM and timer functions are not both enabled
 * on one port.
 *
 * The set of registers for each timer repeats every 0x14.
 * However, the load count 2 starts at 0xB0, and repeats every 0x04.
 * Accessing load count 2 registers, thus, requires some special treatment.
 */

#include <errno.h>

#include <kernel.h>
#include <board.h>
#include <pwm.h>

/* Register for component version */
#define REG_COMP_VER		0xAC

/* Timer Load Count register, for pin to stay low. */
#define REG_TMR_LOAD_CNT	0x00

/* Control for timer */
#define REG_TMR_CTRL		0x08

/* Offset from Timer 1 Load Count address
 * for other timers. (e.g. Timer 2 address +0x14,
 * timer 3 address + 0x28, etc.)
 *
 * This also applies to other registers for
 * different timers (except load count 2).
 */
#define REG_OFFSET		0x14

/* Timer Load Count 2 register, for pin to stay high. */
#define REG_TMR_LOAD_CNT2	0xB0

/* Offset from Timer 1 Load Count 2 address
 * for other timers. (e.g. Timer 2 address +0x04,
 * timer 3 address + 0x08, etc.)
 */
#define REG_OFFSET_LOAD_CNT2	0x04

/* Default for control register:
 * PWM mode, interrupt masked, user-defined count mode, but disabled
 */
#define TIMER_INIT_CTRL		0x0E

struct pwm_dw_config {
	/** Base address of registers */
	u32_t	addr;

	/** Number of ports */
	u32_t	num_ports;
};

/**
 * Find the base address for each timer
 *
 * @param dev Device struct
 * @param timer Which timer
 *
 * @return The base address of that particular timer
 */
static inline int pwm_dw_timer_base_addr(struct device *dev, u32_t timer)
{
	const struct pwm_dw_config * const cfg =
	    (struct pwm_dw_config *)dev->config->config_info;

	return (cfg->addr + (timer * REG_OFFSET));
}

/**
 * Find the load count 2 address for each timer
 *
 * @param dev Device struct
 * @param timer Which timer
 *
 * @return The load count 2 address of that particular timer
 */
static inline int pwm_dw_timer_ldcnt2_addr(struct device *dev, u32_t timer)
{
	const struct pwm_dw_config * const cfg =
	    (struct pwm_dw_config *)dev->config->config_info;

	return (cfg->addr + REG_TMR_LOAD_CNT2 + (timer * REG_OFFSET_LOAD_CNT2));
}


static int __set_one_port(struct device *dev, u32_t pwm,
			  u32_t on, u32_t off)
{
	u32_t reg_addr;

	reg_addr = pwm_dw_timer_base_addr(dev, pwm);

	/* Disable timer to prevent any output */
	sys_write32(TIMER_INIT_CTRL, (reg_addr + REG_TMR_CTRL));

	if ((off == 0) || (on == 0)) {
		/* stop PWM if so specified */
		return 0;
	}

	/* write timer for pin to stay low */
	sys_write32(off, (reg_addr + REG_TMR_LOAD_CNT));

	/* write timer for pin to stay high */
	sys_write32(on, pwm_dw_timer_ldcnt2_addr(dev, pwm));

	/* Enable timer so it starts running and counting */
	sys_write32((TIMER_INIT_CTRL | 0x01), (reg_addr + REG_TMR_CTRL));

	return 0;
}

/**
 * Set the period and the pulse of PWM.
 *
 *
 * Assumes a nominal system clock of 32MHz, each count of on/off represents
 * 31.25ns (e.g. on == 2 means the pin stays high for 62.5ns).
 * The duration of 1 count depends on system clock. Refer to the hardware
 * manual for more information.
 *
 * @param dev Device struct
 * @param pwm Which PWM pin to set
 * @param period_cycles Period in clock cycles of the pwm.
 * @param pulse_cycles PWM width in clock cycles
 *
 * @return 0
 */
static int pwm_dw_pin_set_cycles(struct device *dev,
			     u32_t pwm, u32_t period_cycles, u32_t pulse_cycles)
{
	const struct pwm_dw_config * const cfg =
	    (struct pwm_dw_config *)dev->config->config_info;
	int i;
	u32_t on, off;

	/* make sure the PWM port exists */
	if (pwm >= cfg->num_ports) {
		return -EIO;
	}

	if (period_cycles == 0 || pulse_cycles > period_cycles) {
		return -EINVAL;
	}
	on = pulse_cycles;
	off = period_cycles - pulse_cycles;

	if (off == 0) {
		on--;
		off++;
	}

	return __set_one_port(dev, pwm, on, off);

}

static struct pwm_driver_api pwm_dw_drv_api_funcs = {
	.pin_set = pwm_dw_pin_set_cycles,
};

/**
 * @brief Initialization function of PCA9685
 *
 * @param dev Device struct
 * @return 0 if successful, failed otherwise.
 */
int pwm_dw_init(struct device *dev)
{
	return 0;
}

/* Initialization for PWM_DW */
#if defined(CONFIG_PWM_DW)
#include <device.h>
#include <init.h>

static struct pwm_dw_config pwm_dw_cfg = {
	.addr = PWM_DW_BASE_ADDR,
	.num_ports = PWM_DW_NUM_PORTS,
};

DEVICE_AND_API_INIT(pwm_dw_0, CONFIG_PWM_DW_0_DRV_NAME, pwm_dw_init,
		    NULL, &pwm_dw_cfg,
		    POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE,
		    &pwm_dw_drv_api_funcs);

#endif /* CONFIG_PWM_DW */
