/*
 * 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 __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 = 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 == 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 = 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);
