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