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

#include <errno.h>

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

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

#define HW_CLOCK_CYCLES_PER_USEC  (CONFIG_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 pwm_qmsi_configure(struct device *dev, int access_op,
				 u32_t pwm, int flags)
{
	ARG_UNUSED(dev);
	ARG_UNUSED(access_op);
	ARG_UNUSED(pwm);
	ARG_UNUSED(flags);

	return 0;
}

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 == 0) {
		/* 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 == 0) {
		off = 1;
	}

	/* 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 time to assert and de-assert the PWM pin.
 *
 * This sets the duration for the pin to stay low or high.
 *
 * For example, with a nominal system clock of 32MHz, each count of on/off
 * represents 31.25ns (e.g. off == 2 means the pin is to be de-asserted at
 * 62.5ns from the beginning of a PWM cycle). The duration of 1 count depends
 * on system clock. Refer to the hardware manual for more information.
 *
 * Parameters
 * dev: Pointer to PWM device structure
 * access_op: whether to set one pin or all
 * pwm: PWM port number to set
 * on: How far (in timer count) from the beginning of a PWM cycle the PWM
 *     pin should be asserted. Must be zero, since PWM from Quark MCU always
 *     starts from high.
 * off: How far (in timer count) from the beginning of a PWM cycle the PWM
 *	pin should be de-asserted.
 *
 * return 0, or negative errno code
 */
static int pwm_qmsi_set_values(struct device *dev, int access_op,
			       u32_t pwm, u32_t on, u32_t off)
{
	struct pwm_data *context = dev->driver_data;
	u32_t *channel_period = context->channel_period;
	int i, high, low;

	if (on) {
		return -EINVAL;
	}

	switch (access_op) {
	case PWM_ACCESS_BY_PIN:
		/* make sure the PWM port exists */
		if (pwm >= CONFIG_PWM_QMSI_NUM_PORTS) {
			return -EIO;
		}

		high = off;
		low = channel_period[pwm] - off;

		if (off >= channel_period[pwm]) {
			high = channel_period[pwm] - 1;
			low = 1;
		}

		if (off == 0) {
			high = 1;
			low = channel_period[pwm] - 1;
		}

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

	case PWM_ACCESS_ALL:
		for (i = 0; i < CONFIG_PWM_QMSI_NUM_PORTS; i++) {
			high = off;
			low = channel_period[i] - off;

			if (off >= channel_period[i]) {
				high = channel_period[i] - 1;
				low = 1;
			}

			if (off == 0) {
				high = 1;
				low = channel_period[i] - 1;
			}

			if (__set_one_port(dev, QM_PWM_0, i, high, low) != 0) {
				return -EIO;
			}
		}
		break;
	default:
		return -ENOTSUP;
	}

	return 0;

}

static int pwm_qmsi_set_period(struct device *dev, int access_op,
			       u32_t pwm, u32_t period)
{
	struct pwm_data *context = dev->driver_data;
	u32_t *channel_period = context->channel_period;
	int ret_val = 0;

	if (channel_period == NULL) {
		return -EIO;
	}

	if (period < MIN_PERIOD || period > MAX_PERIOD) {
		return -ENOTSUP;
	}

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

	switch (access_op) {
	case PWM_ACCESS_BY_PIN:
		/* make sure the PWM port exists */
		if (pwm >= CONFIG_PWM_QMSI_NUM_PORTS) {
			ret_val = -EIO;
			goto pwm_set_period_return;
		}
		channel_period[pwm] = period * HW_CLOCK_CYCLES_PER_USEC;
		break;
	case PWM_ACCESS_ALL:
		for (int i = 0; i < CONFIG_PWM_QMSI_NUM_PORTS; i++) {
			channel_period[i] = period *
					    HW_CLOCK_CYCLES_PER_USEC;
		}
		break;
	default:
		ret_val = -ENOTSUP;
	}

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

	return ret_val;
}

static int pwm_qmsi_set_duty_cycle(struct device *dev, int access_op,
				   u32_t pwm, u8_t duty)
{
	struct pwm_data *context = dev->driver_data;
	u32_t *channel_period = context->channel_period;
	u32_t on, off;

	if (channel_period == NULL) {
		return -EIO;
	}

	if (duty > 100) {
		return -ENOTSUP;
	}

	switch (access_op) {
	case PWM_ACCESS_BY_PIN:
		/* make sure the PWM port exists */
		if (pwm >= CONFIG_PWM_QMSI_NUM_PORTS) {
			return -EIO;
		}
		on = (channel_period[pwm] * duty) / 100;
		off = channel_period[pwm] - on;
		if (off == 0) {
			on--;
			off = 1;
		}
		return __set_one_port(dev, QM_PWM_0, pwm, on, off);
	case PWM_ACCESS_ALL:
		for (int i = 0; i < CONFIG_PWM_QMSI_NUM_PORTS; i++) {
			on = (channel_period[i] * duty) / 100;
			off = channel_period[i] - on;
			if (off == 0) {
				on--;
				off = 1;
			}
			if (__set_one_port(dev, QM_PWM_0, i, on, off) != 0) {
				return -EIO;
			}
		}
		break;
	default:
		return -ENOTSUP;
	}

	return 0;
}

static int pwm_qmsi_set_phase(struct device *dev, int access_op,
			      u32_t pwm, u8_t phase)
{
	ARG_UNUSED(dev);
	ARG_UNUSED(access_op);
	ARG_UNUSED(pwm);
	ARG_UNUSED(phase);

	return -ENOTSUP;
}

/*
 * 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 == 0 || 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 == 0) {
		high--;
		low = 1;
	}

	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 = {
	.config = pwm_qmsi_configure,
	.set_values = pwm_qmsi_set_values,
	.set_period = pwm_qmsi_set_period,
	.set_duty_cycle = pwm_qmsi_set_duty_cycle,
	.set_phase = pwm_qmsi_set_phase,
	.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), 0, UINT_MAX);
		k_sem_give(RP_GET(dev));
	}

	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)
{
	if (ctrl_command == DEVICE_PM_SET_POWER_STATE) {
		if (*((u32_t *)context) == DEVICE_PM_SUSPEND_STATE) {
			return pwm_qmsi_suspend(dev);
		} else if (*((u32_t *)context) == DEVICE_PM_ACTIVE_STATE) {
			return pwm_qmsi_resume_from_suspend(dev);
		}
	} else if (ctrl_command == DEVICE_PM_GET_POWER_STATE) {
		*((u32_t *)context) = pwm_qmsi_get_power_state(dev);
		return 0;
	}

	return 0;
}
#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);
