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

#define DT_DRV_COMPAT amd_sb_tsi

#include <zephyr/device.h>
#include <zephyr/drivers/emul.h>
#include <zephyr/drivers/emul_sensor.h>
#include <zephyr/drivers/i2c.h>
#include <zephyr/drivers/i2c_emul.h>
#include <zephyr/logging/log.h>
#include "sb_tsi.h"

LOG_MODULE_DECLARE(AMD_SB_TSI, CONFIG_SENSOR_LOG_LEVEL);

#define NUM_REGS 128

struct sb_tsi_emul_data {
	uint8_t reg[NUM_REGS];
};

static void sb_tsi_emul_set_reg(const struct emul *target, uint8_t reg, uint8_t val)
{
	struct sb_tsi_emul_data *data = target->data;

	__ASSERT_NO_MSG(reg < NUM_REGS);
	data->reg[reg] = val;
}

static uint8_t sb_tsi_emul_get_reg(const struct emul *target, uint8_t reg)
{
	struct sb_tsi_emul_data *data = target->data;

	__ASSERT_NO_MSG(reg < NUM_REGS);
	return data->reg[reg];
}

static void sb_tsi_emul_reset(const struct emul *target)
{
	struct sb_tsi_emul_data *data = target->data;

	memset(data->reg, 0, NUM_REGS);
}

static int sb_tsi_emul_transfer_i2c(const struct emul *target, struct i2c_msg *msgs,
				    int num_msgs, int addr)
{
	/* Largely copied from emul_bmi160.c */
	unsigned int val;
	int reg;

	__ASSERT_NO_MSG(msgs && num_msgs);

	i2c_dump_msgs_rw(target->dev, msgs, num_msgs, addr, false);
	switch (num_msgs) {
	case 2:
		if (msgs->flags & I2C_MSG_READ) {
			LOG_ERR("Unexpected read");
			return -EIO;
		}
		if (msgs->len != 1) {
			LOG_ERR("Unexpected msg0 length %d", msgs->len);
			return -EIO;
		}
		reg = msgs->buf[0];

		/* Now process the 'read' part of the message */
		msgs++;
		if (msgs->flags & I2C_MSG_READ) {
			switch (msgs->len) {
			case 1:
				val = sb_tsi_emul_get_reg(target, reg);
				msgs->buf[0] = val;
				break;
			default:
				LOG_ERR("Unexpected msg1 length %d", msgs->len);
				return -EIO;
			}
		} else {
			if (msgs->len != 1) {
				LOG_ERR("Unexpected msg1 length %d", msgs->len);
			}
			sb_tsi_emul_set_reg(target, reg, msgs->buf[0]);
		}
		break;
	default:
		LOG_ERR("Invalid number of messages: %d", num_msgs);
		return -EIO;
	}

	return 0;
}

static int sb_tsi_emul_init(const struct emul *target, const struct device *parent)
{
	sb_tsi_emul_reset(target);
	return 0;
}

static int sb_tsi_emul_set_channel(const struct emul *target, enum sensor_channel chan,
				   const q31_t *value, int8_t shift)
{
	struct sb_tsi_emul_data *data = target->data;
	int64_t scaled_value;
	int32_t millicelsius;
	int32_t reg_value;

	if (chan != SENSOR_CHAN_AMBIENT_TEMP) {
		return -ENOTSUP;
	}

	scaled_value = (int64_t)*value << shift;
	millicelsius = scaled_value * 1000 / ((int64_t)INT32_MAX + 1);
	reg_value = CLAMP(millicelsius / 125, 0, 0x7ff);

	data->reg[SB_TSI_TEMP_INT] = reg_value >> 3;
	data->reg[SB_TSI_TEMP_DEC] = (reg_value & 0x7) << 5;

	return 0;
}

static int sb_tsi_emul_get_sample_range(const struct emul *target, enum sensor_channel chan,
					q31_t *lower, q31_t *upper, q31_t *epsilon, int8_t *shift)
{
	if (chan != SENSOR_CHAN_AMBIENT_TEMP) {
		return -ENOTSUP;
	}

	*shift = 8;
	*lower = 0;
	*upper = (int64_t)(255.875 * ((int64_t)INT32_MAX + 1)) >> *shift;
	*epsilon = (int64_t)(0.125 * ((int64_t)INT32_MAX + 1)) >> *shift;

	return 0;
}

static const struct i2c_emul_api sb_tsi_emul_api_i2c = {
	.transfer = sb_tsi_emul_transfer_i2c,
};

static const struct emul_sensor_backend_api sb_tsi_emul_api_sensor = {
	.set_channel = sb_tsi_emul_set_channel,
	.get_sample_range = sb_tsi_emul_get_sample_range,
};

#define SB_TSI_EMUL(n)								\
	struct sb_tsi_emul_data sb_tsi_emul_data_##n;				\
	EMUL_DT_INST_DEFINE(n, sb_tsi_emul_init, &sb_tsi_emul_data_##n,	NULL,	\
			    &sb_tsi_emul_api_i2c, &sb_tsi_emul_api_sensor)

DT_INST_FOREACH_STATUS_OKAY(SB_TSI_EMUL)
