/*
 * Copyright (c) 2022 Nick Ward <nix.ward@gmail.com>
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT nxp_pca9685_pwm

#include <zephyr/device.h>
#include <zephyr/drivers/i2c.h>
#include <zephyr/drivers/pwm.h>
#include <zephyr/sys/util_macro.h>
#include <zephyr/kernel.h>

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(pwm_pca9685, CONFIG_PWM_LOG_LEVEL);

#define OSC_CLOCK_MAX	  50000000
#define CHANNEL_CNT	  16

#define ADDR_MODE1	  0x00
#define SLEEP		  BIT(4)
#define AUTO_INC	  BIT(5)
#define RESTART		  BIT(7)

#define ADDR_MODE2	  0x01
#define OUTDRV_TOTEM_POLE BIT(2)
#define OCH_ON_ACK	  BIT(3)

#define ADDR_LED0_ON_L	  0x06
#define ADDR_LED_ON_L(n)  (ADDR_LED0_ON_L + (4 * n))
#define LED_FULL_ON	  BIT(4)
#define LED_FULL_OFF	  BIT(4)
#define BYTE_N(word, n)	  ((word >> (8 * n)) & 0xFF)

#define ADDR_PRE_SCALE	  0xFE


/* See PCA9585 datasheet Rev. 4 - 16 April 2015 section 7.3.5 */
#define OSC_CLOCK_INTERNAL 25000000

#define PWM_STEPS 4096

#define PRE_SCALE_MIN 0x03
#define PRE_SCALE_MAX 0xFF

#define PRE_SCALE_DEFAULT 0x1E

#define PWM_PERIOD_COUNT_PS(pre_scale) (PWM_STEPS * (pre_scale + 1))

/*
 * When using the internal oscillator this corresponds to an
 * update rate of 1526 Hz
 */
#define PWM_PERIOD_COUNT_MIN PWM_PERIOD_COUNT_PS(PRE_SCALE_MIN)

/*
 * When using the internal oscillator this corresponds to an
 * update rate of 24 Hz
 */
#define PWM_PERIOD_COUNT_MAX PWM_PERIOD_COUNT_PS(PRE_SCALE_MAX)

/*
 * When using the internal oscillator this corresponds to an
 * update rate of 200 Hz
 */
#define PWM_PERIOD_COUNT_DEFAULT PWM_PERIOD_COUNT_PS(PRE_SCALE_DEFAULT)


/*
 * Time allowed for the oscillator to stabilize after the PCA9685's
 * RESTART mode is used to wake the chip from SLEEP.
 * See PCA9685 datasheet section 7.3.1.1
 */
#define OSCILLATOR_STABILIZE K_USEC(500)

struct pca9685_config {
	struct i2c_dt_spec i2c;
	bool outdrv_open_drain;
	bool och_on_ack;
	bool invrt;
};

struct pca9685_data {
	struct k_mutex mutex;
	uint8_t pre_scale;
};

static int set_reg(const struct device *dev, uint8_t addr, uint8_t value)
{
	const struct pca9685_config *config = dev->config;
	uint8_t buf[] = {addr, value};
	int ret;

	ret = i2c_write_dt(&config->i2c, buf, sizeof(buf));
	if (ret != 0) {
		LOG_ERR("I2C write [0x%02X]=0x%02X: %d", addr, value, ret);
	} else {
		LOG_DBG("[0x%02X]=0x%02X", addr, value);
	}
	return ret;
}

static int get_reg(const struct device *dev, uint8_t addr, uint8_t *value)
{
	const struct pca9685_config *config = dev->config;
	int ret;

	ret = i2c_write_read_dt(&config->i2c, &addr, sizeof(addr), value,
				sizeof(*value));
	if (ret != 0) {
		LOG_ERR("I2C write [0x%02X]=0x%02X: %d", addr, *value, ret);
	}
	return ret;
}

static int set_pre_scale(const struct device *dev, uint8_t value)
{
	struct pca9685_data *data = dev->data;
	uint8_t mode1;
	int ret;

	k_mutex_lock(&data->mutex, K_FOREVER);

	/* Unblock write to PRE_SCALE by setting SLEEP bit to logic 1 */
	ret = set_reg(dev, ADDR_MODE1, AUTO_INC | SLEEP);
	if (ret != 0) {
		goto out;
	}

	ret = get_reg(dev, ADDR_MODE1, &mode1);
	if (ret != 0) {
		goto out;
	}

	if ((mode1 & RESTART) == 0x00) {
		LOG_ERR("RESTART bit should be set");
		ret = -EIO;
		goto out;
	}

	ret = set_reg(dev, ADDR_PRE_SCALE, value);
	if (ret != 0) {
		goto out;
	}

	/* Clear SLEEP bit - See datasheet section 7.3.1.1 */
	ret = set_reg(dev, ADDR_MODE1, AUTO_INC);
	if (ret != 0) {
		goto out;
	}

	k_sleep(OSCILLATOR_STABILIZE);

	ret = set_reg(dev, ADDR_MODE1, AUTO_INC | RESTART);
	if (ret != 0) {
		goto out;
	}

out:
	k_mutex_unlock(&data->mutex);

	return ret;
}

static int pca9685_set_cycles(const struct device *dev,
			      uint32_t channel, uint32_t period_count,
			      uint32_t pulse_count, pwm_flags_t flags)
{
	const struct pca9685_config *config = dev->config;
	struct pca9685_data *data = dev->data;
	uint8_t buf[5] = { 0 };
	uint32_t led_off_count;
	int32_t pre_scale;
	int ret;

	ARG_UNUSED(flags);

	if (channel >= CHANNEL_CNT) {
		LOG_WRN("channel out of range: %u", channel);
		return -EINVAL;
	}

	pre_scale = DIV_ROUND_UP((int64_t)period_count, PWM_STEPS) - 1;

	if (pre_scale < PRE_SCALE_MIN) {
		LOG_ERR("period_count %u < %u (min)", period_count,
			PWM_PERIOD_COUNT_MIN);
		return -ENOTSUP;
	} else if (pre_scale > PRE_SCALE_MAX) {
		LOG_ERR("period_count %u > %u (max)", period_count,
			PWM_PERIOD_COUNT_MAX);
		return -ENOTSUP;
	}

	/* Only one output frequency - simple conversion to equivalent PWM */
	if (pre_scale != data->pre_scale) {
		data->pre_scale = pre_scale;
		ret = set_pre_scale(dev, pre_scale);
		if (ret != 0) {
			return ret;
		}
	}

	/* Adjust PWM output for the resolution of the PCA9685 */
	led_off_count = DIV_ROUND_UP(pulse_count * PWM_STEPS, period_count);

	buf[0] = ADDR_LED_ON_L(channel);
	if (led_off_count == 0) {
		buf[4] = LED_FULL_OFF;
	} else if (led_off_count < PWM_STEPS) {
		/* LED turns on at count 0 */
		buf[3] = BYTE_N(led_off_count, 0);
		buf[4] = BYTE_N(led_off_count, 1);
	} else {
		buf[2] = LED_FULL_ON;
	}

	return i2c_write_dt(&config->i2c, buf, sizeof(buf));
}

static int pca9685_get_cycles_per_sec(const struct device *dev,
				      uint32_t channel, uint64_t *cycles)
{
	ARG_UNUSED(dev);
	ARG_UNUSED(channel);

	*cycles = OSC_CLOCK_INTERNAL;

	return 0;
}

static const struct pwm_driver_api pca9685_api = {
	.set_cycles = pca9685_set_cycles,
	.get_cycles_per_sec = pca9685_get_cycles_per_sec,
};

static int pca9685_init(const struct device *dev)
{
	const struct pca9685_config *config = dev->config;
	struct pca9685_data *data = dev->data;
	uint8_t value;
	int ret;

	(void)k_mutex_init(&data->mutex);

	if (!i2c_is_ready_dt(&config->i2c)) {
		LOG_ERR("I2C device not ready");
		return -ENODEV;
	}

	ret = set_reg(dev, ADDR_MODE1, AUTO_INC);
	if (ret != 0) {
		LOG_ERR("set_reg MODE1: %d", ret);
		return ret;
	}

	value = 0x00;
	if (!config->outdrv_open_drain) {
		value |= OUTDRV_TOTEM_POLE;
	}
	if (config->och_on_ack) {
		value |= OCH_ON_ACK;
	}
	ret = set_reg(dev, ADDR_MODE2, value);
	if (ret != 0) {
		LOG_ERR("set_reg MODE2: %d", ret);
		return ret;
	}

	return 0;
}

#define PCA9685_INIT(inst)                                              \
	static const struct pca9685_config pca9685_##inst##_config = {  \
		.i2c = I2C_DT_SPEC_INST_GET(inst),                      \
		.outdrv_open_drain = DT_INST_PROP(inst, open_drain),    \
		.och_on_ack = DT_INST_PROP(inst, och_on_ack),           \
		.invrt = DT_INST_PROP(inst, invert),                    \
	};                                                              \
                                                                        \
	static struct pca9685_data pca9685_##inst##_data;               \
                                                                        \
	DEVICE_DT_INST_DEFINE(inst, pca9685_init, NULL,                 \
			      &pca9685_##inst##_data,                   \
			      &pca9685_##inst##_config, POST_KERNEL,    \
			      CONFIG_PWM_INIT_PRIORITY,                 \
			      &pca9685_api);

DT_INST_FOREACH_STATUS_OKAY(PCA9685_INIT);
