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

#include <errno.h>

#include <drivers/pwm.h>
#include <device.h>
#include <kernel.h>
#include <init.h>
#include <power/power.h>
#include <sys/util.h>

#include "qm_pwm.h"
#include "clk.h"

#define HW_CLOCK_CYCLES_PER_USEC  (sys_clock_hw_cycles_per_sec() / \
				   USEC_PER_SEC)

/* pwm uses 32 bits counter to control low and high period */
#define MAX_LOW_PERIOD_IN_HW_CLOCK_CYCLES (((u64_t)1) << 32)
#define MAX_HIGH_PERIOD_IN_HW_CLOCK_CYCLES (((u64_t)1) << 32)

#define MAX_PERIOD_IN_HW_CLOCK_CYCLES (MAX_LOW_PERIOD_IN_HW_CLOCK_CYCLES + \
				       MAX_HIGH_PERIOD_IN_HW_CLOCK_CYCLES)

/* in micro seconds. */
#define MAX_PERIOD (MAX_PERIOD_IN_HW_CLOCK_CYCLES / HW_CLOCK_CYCLES_PER_USEC)

/**
 * in micro seconds. To be able to get 1% granularity, MIN_PERIOD should
 * have at least 100 HW clock cycles.
 */
#define MIN_PERIOD ((100 + (HW_CLOCK_CYCLES_PER_USEC - 1)) / \
		    HW_CLOCK_CYCLES_PER_USEC)

/* in micro seconds */
#define DEFAULT_PERIOD 2000

struct pwm_data {
#ifdef CONFIG_PWM_QMSI_API_REENTRANCY
	struct k_sem sem;
#endif
#ifdef CONFIG_DEVICE_POWER_MANAGEMENT
	u32_t device_power_state;
#endif
	u32_t channel_period[CONFIG_PWM_QMSI_NUM_PORTS];
};

static struct pwm_data pwm_context;

#ifdef CONFIG_PWM_QMSI_API_REENTRANCY
#define RP_GET(dev) (&((struct pwm_data *)(dev->driver_data))->sem)
#else
#define RP_GET(dev) (NULL)
#endif

static int __set_one_port(struct device *dev, qm_pwm_t id, u32_t pwm,
				u32_t on, u32_t off)
{
	qm_pwm_config_t cfg;
	int ret_val = 0;

	if (IS_ENABLED(CONFIG_PWM_QMSI_API_REENTRANCY)) {
		k_sem_take(RP_GET(dev), K_FOREVER);
	}

	/* Disable timer to prevent any output */
	qm_pwm_stop(id, pwm);

	if (on == 0U) {
		/* stop PWM if so specified */
		goto pwm_set_port_return;
	}

	/**
	 * off period must be more than zero. Otherwise, the PWM pin will be
	 * turned off. Let's use the minimum value which is 1 for this case.
	 */
	if (off == 0U) {
		off = 1U;
	}

	/* PWM mode, user-defined count mode, timer disabled */
	cfg.mode = QM_PWM_MODE_PWM;

	/* No interrupts */
	cfg.mask_interrupt = true;
	cfg.callback = NULL;
	cfg.callback_data = NULL;

	/* Data for the timer to stay high and low */
	cfg.hi_count = on;
	cfg.lo_count = off;

	if (qm_pwm_set_config(id, pwm, &cfg) != 0) {
		ret_val = -EIO;
		goto pwm_set_port_return;
	}

	/* Enable timer so it starts running and counting */
	qm_pwm_start(id, pwm);

pwm_set_port_return:
	if (IS_ENABLED(CONFIG_PWM_QMSI_API_REENTRANCY)) {
		k_sem_give(RP_GET(dev));
	}

	return ret_val;
}

/*
 * Set the period and pulse width for a PWM pin.
 *
 * For example, with a nominal system clock of 32MHz, each count represents
 * 31.25ns (e.g. period = 100 means the pulse is to repeat every 3125ns). The
 * duration of one count depends on system clock. Refer to the hardware manual
 * for more information.
 *
 * Parameters
 * dev: Pointer to PWM device structure
 * pwm: PWM port number to set
 * period_cycles: Period (in timer count)
 * pulse_cycles: Pulse width (in timer count).
 *
 * return 0, or negative errno code
 */
static int pwm_qmsi_pin_set(struct device *dev, u32_t pwm,
			    u32_t period_cycles, u32_t pulse_cycles)
{
	u32_t high, low;

	if (pwm >= CONFIG_PWM_QMSI_NUM_PORTS) {
		return -EINVAL;
	}

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

	high = pulse_cycles;
	low = period_cycles - pulse_cycles;

	/*
	 * low must be more than zero. Otherwise, the PWM pin will be
	 * turned off. Let's make sure low is always more than zero.
	 */
	if (low == 0U) {
		high--;
		low = 1U;
	}

	return __set_one_port(dev, QM_PWM_0, pwm, high, low);
}

/*
 * Get the clock rate (cycles per second) for a PWM pin.
 *
 * Parameters
 * dev: Pointer to PWM device structure
 * pwm: PWM port number
 * cycles: Pointer to the memory to store clock rate (cycles per second)
 *
 * return 0, or negative errno code
 */
static int pwm_qmsi_get_cycles_per_sec(struct device *dev, u32_t pwm,
				       u64_t *cycles)
{
	if (cycles == NULL) {
		return -EINVAL;
	}

	*cycles = (u64_t)clk_sys_get_ticks_per_us() * USEC_PER_SEC;

	return 0;
}

static const struct pwm_driver_api pwm_qmsi_drv_api_funcs = {
	.pin_set = pwm_qmsi_pin_set,
	.get_cycles_per_sec = pwm_qmsi_get_cycles_per_sec,
};

#ifdef CONFIG_DEVICE_POWER_MANAGEMENT
static void pwm_qmsi_set_power_state(struct device *dev, u32_t power_state)
{
	struct pwm_data *context = dev->driver_data;

	context->device_power_state = power_state;
}
#else
#define pwm_qmsi_set_power_state(...)
#endif

static int pwm_qmsi_init(struct device *dev)
{
	struct pwm_data *context = dev->driver_data;
	u32_t *channel_period = context->channel_period;

	for (int i = 0; i < CONFIG_PWM_QMSI_NUM_PORTS; i++) {
		channel_period[i] = DEFAULT_PERIOD *
				    HW_CLOCK_CYCLES_PER_USEC;
	}

	clk_periph_enable(CLK_PERIPH_PWM_REGISTER | CLK_PERIPH_CLK);

	if (IS_ENABLED(CONFIG_PWM_QMSI_API_REENTRANCY)) {
		k_sem_init(RP_GET(dev), 1, UINT_MAX);
	}

	pwm_qmsi_set_power_state(dev, DEVICE_PM_ACTIVE_STATE);

	return 0;
}

#ifdef CONFIG_DEVICE_POWER_MANAGEMENT
static qm_pwm_context_t pwm_ctx;

static u32_t pwm_qmsi_get_power_state(struct device *dev)
{
	struct pwm_data *context = dev->driver_data;

	return context->device_power_state;
}

static int pwm_qmsi_suspend(struct device *dev)
{
	qm_pwm_save_context(QM_PWM_0, &pwm_ctx);

	pwm_qmsi_set_power_state(dev, DEVICE_PM_SUSPEND_STATE);

	return 0;
}

static int pwm_qmsi_resume_from_suspend(struct device *dev)
{
	qm_pwm_restore_context(QM_PWM_0, &pwm_ctx);

	pwm_qmsi_set_power_state(dev, DEVICE_PM_ACTIVE_STATE);

	return 0;
}

/*
* Implements the driver control management functionality
* the *context may include IN data or/and OUT data
*/
static int pwm_qmsi_device_ctrl(struct device *dev, u32_t ctrl_command,
				void *context, device_pm_cb cb, void *arg)
{
	int ret = 0;

	if (ctrl_command == DEVICE_PM_SET_POWER_STATE) {
		if (*((u32_t *)context) == DEVICE_PM_SUSPEND_STATE) {
			ret = pwm_qmsi_suspend(dev);
		} else if (*((u32_t *)context) == DEVICE_PM_ACTIVE_STATE) {
			ret = pwm_qmsi_resume_from_suspend(dev);
		}
	} else if (ctrl_command == DEVICE_PM_GET_POWER_STATE) {
		*((u32_t *)context) = pwm_qmsi_get_power_state(dev);
	}

	if (cb) {
		cb(dev, ret, context, arg);
	}
	return ret;
}
#endif

DEVICE_DEFINE(pwm_qmsi_0, CONFIG_PWM_QMSI_DEV_NAME, pwm_qmsi_init,
	      pwm_qmsi_device_ctrl, &pwm_context, NULL,
	      POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE,
	      &pwm_qmsi_drv_api_funcs);
