/*
 * Copyright (c) 2022 Caspar Friedrich <c.s.w.friedrich@gmail.com>
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include "w1_ds248x.h"

#include <zephyr/devicetree.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/i2c.h>
#include <zephyr/drivers/w1.h>
#include <zephyr/logging/log.h>
#include <zephyr/pm/device.h>
#include <zephyr/kernel.h>

#define DT_DRV_COMPAT maxim_ds2484

LOG_MODULE_REGISTER(ds2484, CONFIG_W1_LOG_LEVEL);

struct ds2484_config {
	struct w1_master_config w1_config;
	const struct i2c_dt_spec i2c_spec;
	const struct gpio_dt_spec slpz_spec;
	bool apu;
};

struct ds2484_data {
	struct w1_master_data w1_data;
	uint8_t reg_device_config;
};

static int ds2484_reset_bus(const struct device *dev)
{
	const struct ds2484_config *config = dev->config;

	return ds248x_reset_bus(&config->i2c_spec);
}

static int ds2484_read_bit(const struct device *dev)
{
	const struct ds2484_config *config = dev->config;

	return ds248x_read_bit(&config->i2c_spec);
}

static int ds2484_write_bit(const struct device *dev, bool bit)
{
	const struct ds2484_config *config = dev->config;

	return ds248x_write_bit(&config->i2c_spec, bit);
}

static int ds2484_read_byte(const struct device *dev)
{
	const struct ds2484_config *config = dev->config;

	return ds248x_read_byte(&config->i2c_spec);
}

static int ds2484_write_byte(const struct device *dev, uint8_t byte)
{
	const struct ds2484_config *config = dev->config;

	return ds248x_write_byte(&config->i2c_spec, byte);
}

static int ds2484_configure(const struct device *dev, enum w1_settings_type type, uint32_t value)
{
	const struct ds2484_config *config = dev->config;
	struct ds2484_data *data = dev->data;

	switch (type) {
	case W1_SETTING_SPEED:
		WRITE_BIT(data->reg_device_config, DEVICE_1WS_pos, value);
		break;
	case W1_SETTING_STRONG_PULLUP:
		WRITE_BIT(data->reg_device_config, DEVICE_SPU_pos, value);
		break;
	default:
		return -EINVAL;
	}

	return ds248x_write_config(&config->i2c_spec, data->reg_device_config);
}

#ifdef CONFIG_PM_DEVICE
static int ds2484_pm_control(const struct device *dev, enum pm_device_action action)
{
	const struct ds2484_config *config = dev->config;

	switch (action) {
	case PM_DEVICE_ACTION_SUSPEND:
		if (!config->slpz_spec.port) {
			return -ENOTSUP;
		}
		return gpio_pin_set_dt(&config->slpz_spec, 1);
	case PM_DEVICE_ACTION_RESUME:
		if (!config->slpz_spec.port) {
			return -ENOTSUP;
		}
		return gpio_pin_set_dt(&config->slpz_spec, 0);
	default:
		return -ENOTSUP;
	};

	return 0;
}
#endif /* CONFIG_PM_DEVICE */

static int ds2484_init(const struct device *dev)
{
	int ret;

	const struct ds2484_config *config = dev->config;
	struct ds2484_data *data = dev->data;

	if (config->slpz_spec.port) {
		if (!device_is_ready(config->slpz_spec.port)) {
			LOG_ERR("Port (SLPZ) not ready");
			return -ENODEV;
		}

		ret = gpio_pin_configure_dt(&config->slpz_spec, GPIO_OUTPUT_INACTIVE);
		if (ret < 0) {
			LOG_ERR("Pin configuration (SLPZ) failed: %d", ret);
			return ret;
		}
	}

	if (!device_is_ready(config->i2c_spec.bus)) {
		return -ENODEV;
	}

	ret = ds248x_reset_device(&config->i2c_spec);
	if (ret < 0) {
		LOG_ERR("Device reset failed: %d", ret);
		return ret;
	}

	WRITE_BIT(data->reg_device_config, DEVICE_APU_pos, config->apu);

	ret = ds248x_write_config(&config->i2c_spec, data->reg_device_config);
	if (ret < 0) {
		LOG_ERR("Device config update failed: %d", ret);
		return ret;
	}

	return 0;
}

static const struct w1_driver_api ds2484_driver_api = {
	.reset_bus = ds2484_reset_bus,
	.read_bit = ds2484_read_bit,
	.write_bit = ds2484_write_bit,
	.read_byte = ds2484_read_byte,
	.write_byte = ds2484_write_byte,
	.configure = ds2484_configure,
};

#define DS2484_INIT(inst)                                                                          \
	static const struct ds2484_config inst_##inst##_config = {                                 \
		.w1_config.slave_count = W1_INST_SLAVE_COUNT(inst),                                \
		.i2c_spec = I2C_DT_SPEC_INST_GET(inst),                                            \
		.slpz_spec = GPIO_DT_SPEC_INST_GET_OR(inst, slpz_gpios, {0}),                      \
		.apu = DT_INST_PROP(inst, active_pullup),                                          \
	};                                                                                         \
	static struct ds2484_data inst_##inst##_data;                                              \
	PM_DEVICE_DT_INST_DEFINE(inst, ds2484_pm_control);                                         \
	DEVICE_DT_INST_DEFINE(inst, ds2484_init, PM_DEVICE_DT_INST_GET(inst), &inst_##inst##_data, \
			      &inst_##inst##_config, POST_KERNEL, CONFIG_W1_INIT_PRIORITY,         \
			      &ds2484_driver_api);

DT_INST_FOREACH_STATUS_OKAY(DS2484_INIT)

/*
 * Make sure that this driver is not initialized before the i2c bus is available
 */
BUILD_ASSERT(CONFIG_W1_INIT_PRIORITY > CONFIG_I2C_INIT_PRIORITY);
