/*
 * Copyright (c) 2022 Andrei-Edward Popa
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT raspberrypi_pico_reset

#include <zephyr/device.h>
#include <zephyr/drivers/reset.h>

struct reset_rpi_config {
	DEVICE_MMIO_ROM;
	uint8_t reg_width;
	uint8_t active_low;
	uintptr_t base_address;
};

static int reset_rpi_read_register(const struct device *dev, uint16_t offset, uint32_t *value)
{
	const struct reset_rpi_config *config = dev->config;
	uint32_t base_address = config->base_address;

	switch (config->reg_width) {
	case 1:
		*value = sys_read8(base_address + offset);
		break;
	case 2:
		*value = sys_read16(base_address + offset);
		break;
	case 4:
		*value = sys_read32(base_address + offset);
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

static int reset_rpi_write_register(const struct device *dev, uint16_t offset, uint32_t value)
{
	const struct reset_rpi_config *config = dev->config;
	uint32_t base_address = config->base_address;

	switch (config->reg_width) {
	case 1:
		sys_write8(value, base_address + offset);
		break;
	case 2:
		sys_write16(value, base_address + offset);
		break;
	case 4:
		sys_write32(value, base_address + offset);
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

static int reset_rpi_status(const struct device *dev, uint32_t id, uint8_t *status)
{
	const struct reset_rpi_config *config = dev->config;
	uint16_t offset;
	uint32_t value;
	uint8_t regbit;
	int ret;

	offset = id / (config->reg_width * CHAR_BIT);
	regbit = id % (config->reg_width * CHAR_BIT);

	ret = reset_rpi_read_register(dev, offset, &value);
	if (ret) {
		return ret;
	}

	*status = !(value & BIT(regbit)) ^ !config->active_low;

	return ret;
}

static int reset_rpi_update(const struct device *dev, uint32_t id, uint8_t assert)
{
	const struct reset_rpi_config *config = dev->config;
	uint16_t offset;
	uint32_t value;
	uint8_t regbit;
	int ret;

	offset = id / (config->reg_width * CHAR_BIT);
	regbit = id % (config->reg_width * CHAR_BIT);

	ret = reset_rpi_read_register(dev, offset, &value);
	if (ret) {
		return ret;
	}

	if (assert ^ config->active_low) {
		value |= BIT(regbit);
	} else {
		value &= ~BIT(regbit);
	}

	return reset_rpi_write_register(dev, offset, value);
}

static int reset_rpi_line_assert(const struct device *dev, uint32_t id)
{
	return reset_rpi_update(dev, id, 1);
}

static int reset_rpi_line_deassert(const struct device *dev, uint32_t id)
{
	return reset_rpi_update(dev, id, 0);
}

static int reset_rpi_line_toggle(const struct device *dev, uint32_t id)
{
	int ret;

	ret = reset_rpi_line_assert(dev, id);
	if (ret) {
		return ret;
	}

	return reset_rpi_line_deassert(dev, id);
}

static int reset_rpi_init(const struct device *dev)
{
	DEVICE_MMIO_MAP(dev, K_MEM_CACHE_NONE);

	return 0;
}

static const struct reset_driver_api reset_rpi_driver_api = {
	.status = reset_rpi_status,
	.line_assert = reset_rpi_line_assert,
	.line_deassert = reset_rpi_line_deassert,
	.line_toggle = reset_rpi_line_toggle,
};

#define RPI_RESET_INIT(idx)							\
	static const struct reset_rpi_config reset_rpi_config_##idx = {		\
		DEVICE_MMIO_ROM_INIT(DT_DRV_INST(idx)),				\
		.reg_width = DT_INST_PROP_OR(idx, reg_width, 4),		\
		.active_low = DT_INST_PROP_OR(idx, active_low, 0),		\
		.base_address = DT_INST_REG_ADDR(idx),				\
	};									\
										\
	DEVICE_DT_INST_DEFINE(idx, reset_rpi_init,				\
			      NULL, NULL,					\
			      &reset_rpi_config_##idx, PRE_KERNEL_1,		\
			      CONFIG_RESET_INIT_PRIORITY,			\
			      &reset_rpi_driver_api);

DT_INST_FOREACH_STATUS_OKAY(RPI_RESET_INIT);
