/*
 * Copyright (c) 2023 Google LLC
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT fintek_f75303

#include <zephyr/device.h>
#include <zephyr/drivers/i2c.h>
#include <zephyr/drivers/sensor.h>
#include <zephyr/pm/device.h>
#include <zephyr/pm/device_runtime.h>
#include <zephyr/logging/log.h>
#include <zephyr/drivers/sensor/f75303.h>
#include "f75303.h"

#define F75303_SAMPLE_INT_SHIFT 3
#define F75303_SAMPLE_FRAC_MASK GENMASK(2, 0)
#define F75303_SAMPLE_MICROCELSIUS_PER_BIT 125000

LOG_MODULE_REGISTER(F75303, CONFIG_SENSOR_LOG_LEVEL);

static int f75303_fetch(const struct i2c_dt_spec *i2c,
			uint8_t off_h, uint8_t off_l, uint16_t *sample)
{
	uint8_t val_h;
	uint8_t val_l;
	int res;

	res = i2c_reg_read_byte_dt(i2c, off_h, &val_h);
	if (res) {
		return res;
	}

	res = i2c_reg_read_byte_dt(i2c, off_l, &val_l);
	if (res) {
		return res;
	}

	*sample = val_h << 3 | val_l >> 5;

	return 0;
}

static int f75303_fetch_local(const struct device *dev)
{
	struct f75303_data *data = dev->data;
	const struct f75303_config *config = dev->config;

	return f75303_fetch(&config->i2c,
			    F75303_LOCAL_TEMP_H,
			    F75303_LOCAL_TEMP_L,
			    &data->sample_local);
}

static int f75303_fetch_remote1(const struct device *dev)
{
	struct f75303_data *data = dev->data;
	const struct f75303_config *config = dev->config;

	return f75303_fetch(&config->i2c,
			    F75303_REMOTE1_TEMP_H,
			    F75303_REMOTE1_TEMP_L,
			    &data->sample_remote1);
}

static int f75303_fetch_remote2(const struct device *dev)
{
	struct f75303_data *data = dev->data;
	const struct f75303_config *config = dev->config;

	return f75303_fetch(&config->i2c,
			    F75303_REMOTE2_TEMP_H,
			    F75303_REMOTE2_TEMP_L,
			    &data->sample_remote2);
}

static int f75303_sample_fetch(const struct device *dev,
			       enum sensor_channel chan)
{
	enum pm_device_state pm_state;
	int res;

	(void)pm_device_state_get(dev, &pm_state);
	if (pm_state != PM_DEVICE_STATE_ACTIVE) {
		return -EIO;
	}

	switch ((uint32_t)chan) {
	case SENSOR_CHAN_ALL:
		res = f75303_fetch_local(dev);
		if (res) {
			break;
		}
		res = f75303_fetch_remote1(dev);
		if (res) {
			break;
		}
		res = f75303_fetch_remote2(dev);
		break;
	case SENSOR_CHAN_AMBIENT_TEMP:
		return f75303_fetch_local(dev);
	case SENSOR_CHAN_F75303_REMOTE1:
		return f75303_fetch_remote1(dev);
	case SENSOR_CHAN_F75303_REMOTE2:
		return f75303_fetch_remote2(dev);
	default:
		return -ENOTSUP;
	}

	return res;
}

static int f75303_channel_get(const struct device *dev,
			      enum sensor_channel chan,
			      struct sensor_value *val)
{
	struct f75303_data *data = dev->data;
	uint16_t sample;

	switch ((uint32_t)chan) {
	case SENSOR_CHAN_AMBIENT_TEMP:
		sample = data->sample_local;
		break;
	case SENSOR_CHAN_F75303_REMOTE1:
		sample = data->sample_remote1;
		break;
	case SENSOR_CHAN_F75303_REMOTE2:
		sample = data->sample_remote2;
		break;
	default:
		return -ENOTSUP;
	}

	/*
	 * The reading is given in steps of 0.125 degrees celsius, i.e. the
	 * temperature in degrees celsius is equal to sample / 8.
	 */
	val->val1 = sample >> F75303_SAMPLE_INT_SHIFT;
	val->val2 = (sample & F75303_SAMPLE_FRAC_MASK) * F75303_SAMPLE_MICROCELSIUS_PER_BIT;

	return 0;
}

static const struct sensor_driver_api f75303_driver_api = {
	.sample_fetch = f75303_sample_fetch,
	.channel_get = f75303_channel_get,
};

static int f75303_init(const struct device *dev)
{
	const struct f75303_config *config = dev->config;
	int res = 0;

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

#ifdef CONFIG_PM_DEVICE_RUNTIME
	pm_device_init_suspended(dev);

	res = pm_device_runtime_enable(dev);
	if (res) {
		LOG_ERR("Failed to enable runtime power management");
	}
#endif

	return res;
}

#ifdef CONFIG_PM_DEVICE
static int f75303_pm_action(const struct device *dev, enum pm_device_action action)
{
	switch (action) {
	case PM_DEVICE_ACTION_TURN_ON:
	case PM_DEVICE_ACTION_RESUME:
	case PM_DEVICE_ACTION_TURN_OFF:
	case PM_DEVICE_ACTION_SUSPEND:
		return 0;
	default:
		return -ENOTSUP;
	}
}
#endif

#define F75303_INST(inst)								\
	static struct f75303_data f75303_data_##inst;					\
	static const struct f75303_config f75303_config_##inst = {			\
		.i2c = I2C_DT_SPEC_INST_GET(inst),					\
	};										\
	PM_DEVICE_DT_INST_DEFINE(inst, f75303_pm_action);				\
	SENSOR_DEVICE_DT_INST_DEFINE(inst, f75303_init, PM_DEVICE_DT_INST_GET(inst),	\
			      &f75303_data_##inst, &f75303_config_##inst, POST_KERNEL,	\
			      CONFIG_SENSOR_INIT_PRIORITY, &f75303_driver_api);

DT_INST_FOREACH_STATUS_OKAY(F75303_INST)
