/*
 * Copyright (c) 2022 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <string.h>

#include <zephyr/toolchain.h>
#include <zephyr/sys/__assert.h>
#include <zephyr/sys/slist.h>

#include <zephyr/drivers/i3c.h>

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(i3c, CONFIG_I3C_LOG_LEVEL);

void i3c_dump_msgs(const char *name, const struct i3c_msg *msgs,
		   uint8_t num_msgs, struct i3c_device_desc *target)
{
	LOG_DBG("I3C msg: %s, addr=%x", name, target->dynamic_addr);
	for (unsigned int i = 0; i < num_msgs; i++) {
		const struct i3c_msg *msg = &msgs[i];

		LOG_DBG("   %c len=%02x: ",
			msg->flags & I3C_MSG_READ ? 'R' : 'W', msg->len);
		if (!(msg->flags & I3C_MSG_READ)) {
			LOG_HEXDUMP_DBG(msg->buf, msg->len, "contents:");
		}
	}
}

void i3c_addr_slots_set(struct i3c_addr_slots *slots,
			uint8_t dev_addr,
			enum i3c_addr_slot_status status)
{
	int bitpos;
	int idx;

	__ASSERT_NO_MSG(slots != NULL);

	if (dev_addr > I3C_MAX_ADDR) {
		/* Invalid address. Do nothing. */
		return;
	}

	bitpos = dev_addr * 2;
	idx = bitpos / BITS_PER_LONG;

	slots->slots[idx] &= ~((unsigned long)I3C_ADDR_SLOT_STATUS_MASK <<
			       (bitpos % BITS_PER_LONG));
	slots->slots[idx] |= status << (bitpos % BITS_PER_LONG);
}

enum i3c_addr_slot_status
i3c_addr_slots_status(struct i3c_addr_slots *slots,
		      uint8_t dev_addr)
{
	unsigned long status;
	int bitpos;
	int idx;

	__ASSERT_NO_MSG(slots != NULL);

	if (dev_addr > I3C_MAX_ADDR) {
		/* Invalid address.
		 * Simply says it's reserved so it will not be
		 * used for anything.
		 */
		return I3C_ADDR_SLOT_STATUS_RSVD;
	}

	bitpos = dev_addr * 2;
	idx = bitpos / BITS_PER_LONG;

	status = slots->slots[idx] >> (bitpos % BITS_PER_LONG);
	status &= I3C_ADDR_SLOT_STATUS_MASK;

	return status;
}


int i3c_addr_slots_init(const struct device *dev)
{
	struct i3c_driver_data *data =
		(struct i3c_driver_data *)dev->data;
	const struct i3c_driver_config *config =
		(const struct i3c_driver_config *)dev->config;
	int i, ret = 0;
	struct i3c_device_desc *i3c_dev;
	struct i3c_i2c_device_desc *i2c_dev;

	__ASSERT_NO_MSG(dev != NULL);

	(void)memset(&data->attached_dev.addr_slots, 0, sizeof(data->attached_dev.addr_slots));
	sys_slist_init(&data->attached_dev.devices.i3c);
	sys_slist_init(&data->attached_dev.devices.i2c);

	for (i = 0; i <= 7; i++) {
		/* Addresses 0 to 7 are reserved */
		i3c_addr_slots_set(&data->attached_dev.addr_slots, i, I3C_ADDR_SLOT_STATUS_RSVD);

		/*
		 * Addresses within a single bit error of broadcast address
		 * are also reserved.
		 */
		i3c_addr_slots_set(&data->attached_dev.addr_slots, I3C_BROADCAST_ADDR ^ BIT(i),
				   I3C_ADDR_SLOT_STATUS_RSVD);

	}

	/* The broadcast address is reserved */
	i3c_addr_slots_set(&data->attached_dev.addr_slots, I3C_BROADCAST_ADDR,
			   I3C_ADDR_SLOT_STATUS_RSVD);

	/*
	 * Mark all I2C addresses first.
	 */
	for (i = 0; i < config->dev_list.num_i2c; i++) {
		i2c_dev = &config->dev_list.i2c[i];
		ret = i3c_attach_i2c_device(i2c_dev);
		if (ret != 0) {
			/* Address slot is not free */
			ret = -EINVAL;
			goto out;
		}
	}

	/*
	 * If there is a static address for the I3C devices, check
	 * if this address is free, and there is no other devices of
	 * the same (pre-assigned) address on the bus.
	 */
	for (i = 0; i < config->dev_list.num_i3c; i++) {
		i3c_dev = &config->dev_list.i3c[i];
		ret = i3c_attach_i3c_device(i3c_dev);
		if (ret != 0) {
			/* Address slot is not free */
			ret = -EINVAL;
			goto out;
		}
	}

out:
	return ret;
}

bool i3c_addr_slots_is_free(struct i3c_addr_slots *slots,
			    uint8_t dev_addr)
{
	enum i3c_addr_slot_status status;

	__ASSERT_NO_MSG(slots != NULL);

	status = i3c_addr_slots_status(slots, dev_addr);

	return (status == I3C_ADDR_SLOT_STATUS_FREE);
}

uint8_t i3c_addr_slots_next_free_find(struct i3c_addr_slots *slots)
{
	uint8_t addr;
	enum i3c_addr_slot_status status;

	/* Addresses 0 to 7 are reserved. So start at 8. */
	for (addr = 8; addr < I3C_MAX_ADDR; addr++) {
		status = i3c_addr_slots_status(slots, addr);
		if (status == I3C_ADDR_SLOT_STATUS_FREE) {
			return addr;
		}
	}

	return 0;
}

struct i3c_device_desc *i3c_dev_list_find(const struct i3c_dev_list *dev_list,
					  const struct i3c_device_id *id)
{
	int i;
	struct i3c_device_desc *ret = NULL;

	__ASSERT_NO_MSG(dev_list != NULL);

	/* this only searches known I3C PIDs */
	for (i = 0; i < dev_list->num_i3c; i++) {
		struct i3c_device_desc *desc = &dev_list->i3c[i];

		if (desc->pid == id->pid) {
			ret = desc;
			break;
		}
	}

	return ret;
}

struct i3c_device_desc *i3c_dev_list_i3c_addr_find(struct i3c_dev_attached_list *dev_list,
						   uint8_t addr)
{
	sys_snode_t *node;
	struct i3c_device_desc *ret = NULL;

	__ASSERT_NO_MSG(dev_list != NULL);

	SYS_SLIST_FOR_EACH_NODE(&dev_list->devices.i3c, node) {
		struct i3c_device_desc *desc = (void *)node;

		if (desc->dynamic_addr == addr) {
			ret = desc;
			break;
		}
	}

	return ret;
}

struct i3c_i2c_device_desc *i3c_dev_list_i2c_addr_find(struct i3c_dev_attached_list *dev_list,
							   uint16_t addr)
{
	sys_snode_t *node;
	struct i3c_i2c_device_desc *ret = NULL;

	__ASSERT_NO_MSG(dev_list != NULL);

	SYS_SLIST_FOR_EACH_NODE(&dev_list->devices.i2c, node) {
		struct i3c_i2c_device_desc *desc = (void *)node;

		if (desc->addr == addr) {
			ret = desc;
			break;
		}
	}

	return ret;
}

int i3c_determine_default_addr(struct i3c_device_desc *target, uint8_t *addr)
{
	struct i3c_driver_data *data = (struct i3c_driver_data *)target->bus->data;

	/* If dynamic addr is set, then it assumed that it was assigned by a primary controller */
	if (target->dynamic_addr == 0) {
		/* It is assumed that SETDASA or ENTDAA will be run after this */
		if (target->init_dynamic_addr != 0U) {
			/* initial dynamic address is requested */
			if (target->static_addr == 0) {
				/* SA is set to 0, so DA will be set with ENTDAA */
				if (i3c_addr_slots_is_free(&data->attached_dev.addr_slots,
							   target->init_dynamic_addr)) {
					/* Set DA during ENTDAA */
					*addr = target->init_dynamic_addr;
				} else {
					/* address is not free, get the next one */
					*addr = i3c_addr_slots_next_free_find(
						&data->attached_dev.addr_slots);
				}
			} else {
				/* Use the init dynamic address as it's DA, but the RR will need to
				 * be first set with it's SA to run SETDASA, the RR address will
				 * need be updated after SETDASA with the request dynamic address
				 */
				if (i3c_addr_slots_is_free(&data->attached_dev.addr_slots,
							   target->static_addr)) {
					*addr = target->static_addr;
				} else {
					/* static address has already been taken */
					return -EINVAL;
				}
			}
		} else {
			/* no init dynamic address is requested */
			if (target->static_addr != 0) {
				if (i3c_addr_slots_is_free(&data->attached_dev.addr_slots,
							   target->static_addr)) {
					/* static exists, set DA with same SA during SETDASA*/
					*addr = target->static_addr;
				} else {
					/* static address has already been taken */
					return -EINVAL;
				}
			} else {
				/* pick a DA to use */
				*addr = i3c_addr_slots_next_free_find(
					&data->attached_dev.addr_slots);
			}
		}
	} else {
		*addr = target->dynamic_addr;
	}

	return 0;
}

int i3c_attach_i3c_device(struct i3c_device_desc *target)
{
	struct i3c_driver_data *data = (struct i3c_driver_data *)target->bus->data;
	const struct i3c_driver_api *api = (const struct i3c_driver_api *)target->bus->api;
	sys_snode_t *node;
	uint8_t addr = 0;
	int status = 0;

	/* check to see if the device has already been attached */
	if (!sys_slist_is_empty(&data->attached_dev.devices.i3c)) {
		SYS_SLIST_FOR_EACH_NODE(&data->attached_dev.devices.i3c, node) {
			if (node == &target->node) {
				return -EINVAL;
			}
		}
	}

	status = i3c_determine_default_addr(target, &addr);
	if (status != 0) {
		return status;
	}

	sys_slist_append(&data->attached_dev.devices.i3c, &target->node);

	if (api->attach_i3c_device != NULL) {
		status = api->attach_i3c_device(target->bus, target, addr);
	}

	i3c_addr_slots_mark_i3c(&data->attached_dev.addr_slots, addr);

	return status;
}

int i3c_reattach_i3c_device(struct i3c_device_desc *target, uint8_t old_dyn_addr)
{
	struct i3c_driver_data *data = (struct i3c_driver_data *)target->bus->data;
	const struct i3c_driver_api *api = (const struct i3c_driver_api *)target->bus->api;
	int status = 0;

	if (!i3c_addr_slots_is_free(&data->attached_dev.addr_slots, target->dynamic_addr)) {
		return -EINVAL;
	}

	if (api->reattach_i3c_device != NULL) {
		status = api->reattach_i3c_device(target->bus, target, old_dyn_addr);
	}

	if (old_dyn_addr) {
		/* mark the old address as free */
		i3c_addr_slots_mark_free(&data->attached_dev.addr_slots, old_dyn_addr);
	}

	i3c_addr_slots_mark_i3c(&data->attached_dev.addr_slots, target->dynamic_addr);

	return status;
}

int i3c_detach_i3c_device(struct i3c_device_desc *target)
{
	struct i3c_driver_data *data = (struct i3c_driver_data *)target->bus->data;
	const struct i3c_driver_api *api = (const struct i3c_driver_api *)target->bus->api;
	int status = 0;

	if (!sys_slist_is_empty(&data->attached_dev.devices.i3c)) {
		if (!sys_slist_find_and_remove(&data->attached_dev.devices.i3c, &target->node)) {
			return -EINVAL;
		}
	} else {
		return -EINVAL;
	}

	if (api->detach_i3c_device != NULL) {
		status = api->detach_i3c_device(target->bus, target);
	}

	i3c_addr_slots_mark_free(&data->attached_dev.addr_slots,
				 target->dynamic_addr ? target->dynamic_addr : target->static_addr);

	return status;
}

int i3c_attach_i2c_device(struct i3c_i2c_device_desc *target)
{
	struct i3c_driver_data *data = (struct i3c_driver_data *)target->bus->data;
	const struct i3c_driver_api *api = (const struct i3c_driver_api *)target->bus->api;
	sys_snode_t *node;
	int status = 0;

	/* check to see if the device has already been attached */
	if (!sys_slist_is_empty(&data->attached_dev.devices.i2c)) {
		SYS_SLIST_FOR_EACH_NODE(&data->attached_dev.devices.i2c, node) {
			if (node == &target->node) {
				return -EINVAL;
			}
		}
	}

	if (!i3c_addr_slots_is_free(&data->attached_dev.addr_slots, target->addr)) {
		return -EINVAL;
	}

	sys_slist_append(&data->attached_dev.devices.i2c, &target->node);

	if (api->attach_i2c_device != NULL) {
		status = api->attach_i2c_device(target->bus, target);
	}

	i3c_addr_slots_mark_i2c(&data->attached_dev.addr_slots, target->addr);

	return status;
}

int i3c_detach_i2c_device(struct i3c_i2c_device_desc *target)
{
	struct i3c_driver_data *data = (struct i3c_driver_data *)target->bus->data;
	const struct i3c_driver_api *api = (const struct i3c_driver_api *)target->bus->api;
	int status = 0;

	if (!sys_slist_is_empty(&data->attached_dev.devices.i2c)) {
		if (!sys_slist_find_and_remove(&data->attached_dev.devices.i2c, &target->node)) {
			return -EINVAL;
		}
	} else {
		return -EINVAL;
	}

	if (api->detach_i2c_device != NULL) {
		status = api->detach_i2c_device(target->bus, target);
	}

	i3c_addr_slots_mark_free(&data->attached_dev.addr_slots, target->addr);

	return status;
}

int i3c_dev_list_daa_addr_helper(struct i3c_addr_slots *addr_slots,
				 const struct i3c_dev_list *dev_list,
				 uint64_t pid, bool must_match,
				 bool assigned_okay,
				 struct i3c_device_desc **target,
				 uint8_t *addr)
{
	struct i3c_device_desc *desc;
	const uint16_t vendor_id = (uint16_t)(pid >> 32);
	const uint32_t part_no = (uint32_t)(pid & 0xFFFFFFFFU);
	uint8_t dyn_addr = 0;
	int ret = 0;
	const struct i3c_device_id i3c_id = I3C_DEVICE_ID(pid);

	desc = i3c_dev_list_find(dev_list, &i3c_id);
	if (must_match && (desc == NULL)) {
		/*
		 * No device descriptor matching incoming PID and
		 * that we want an exact match.
		 */
		ret = -ENODEV;

		LOG_DBG("PID 0x%04x%08x is not in registered device list",
			vendor_id, part_no);

		goto out;
	}

	if (desc->dynamic_addr != 0U) {
		if (assigned_okay) {
			/* Return the already assigned address if desired so. */
			dyn_addr = desc->dynamic_addr;
			goto out;
		} else {
			/*
			 * Bail If target already has an assigned address.
			 * This is probably due to having the same PIDs for multiple targets
			 * in the device tree.
			 */
			LOG_ERR("PID 0x%04x%08x already has "
				"dynamic address (0x%02x) assigned",
				vendor_id, part_no, desc->dynamic_addr);
			ret = -EINVAL;
			goto err;
		}
	}

	/*
	 * Use the desired dynamic address as the new dynamic address
	 * if the slot is free.
	 */
	if (desc->init_dynamic_addr != 0U) {
		if (i3c_addr_slots_is_free(addr_slots,
					   desc->init_dynamic_addr)) {
			dyn_addr = desc->init_dynamic_addr;
			goto out;
		}
	}

	/*
	 * Find the next available address.
	 */
	dyn_addr = i3c_addr_slots_next_free_find(addr_slots);

	if (dyn_addr == 0U) {
		/* No free addresses available */
		LOG_DBG("No more free addresses available.");
		ret = -ENOSPC;
	}

out:
	*addr = dyn_addr;
	*target = desc;

err:
	return ret;
}

int i3c_device_basic_info_get(struct i3c_device_desc *target)
{
	int ret;
	uint8_t tmp_bcr;

	struct i3c_ccc_getbcr bcr = {0};
	struct i3c_ccc_getdcr dcr = {0};
	struct i3c_ccc_mrl mrl = {0};
	struct i3c_ccc_mwl mwl = {0};

	/*
	 * Since some CCC functions requires BCR to function
	 * correctly, we save the BCR here and update the BCR
	 * in the descriptor. If any following operations fails,
	 * we can restore the BCR.
	 */
	tmp_bcr = target->bcr;

	/* GETBCR */
	ret = i3c_ccc_do_getbcr(target, &bcr);
	if (ret != 0) {
		goto out;
	}

	target->bcr = bcr.bcr;

	/* GETDCR */
	ret = i3c_ccc_do_getdcr(target, &dcr);
	if (ret != 0) {
		goto out;
	}

	/* GETMRL */
	if (i3c_ccc_do_getmrl(target, &mrl) != 0) {
		/* GETMRL may be optionally supported if no settable limit */
		LOG_DBG("No settable limit for GETMRL");
	}

	/* GETMWL */
	if (i3c_ccc_do_getmwl(target, &mwl) != 0) {
		/* GETMWL may be optionally supported if no settable limit */
		LOG_DBG("No settable limit for GETMWL");
	}

	target->dcr = dcr.dcr;
	target->data_length.mrl = mrl.len;
	target->data_length.mwl = mwl.len;
	target->data_length.max_ibi = mrl.ibi_len;

out:
	if (ret != 0) {
		/* Restore BCR is any CCC fails. */
		target->bcr = tmp_bcr;
	}
	return ret;
}

/**
 * @brief Do SETDASA to set static address as dynamic address.
 *
 * @param dev Pointer to the device driver instance.
 * @param[out] True if DAA is still needed. False if all registered
 *             devices have static addresses.
 *
 * @retval 0 if successful.
 */
static int i3c_bus_setdasa(const struct device *dev,
			   const struct i3c_dev_list *dev_list,
			   bool *need_daa)
{
	int i, ret;

	*need_daa = false;

	/* Loop through the registered I3C devices */
	for (i = 0; i < dev_list->num_i3c; i++) {
		struct i3c_device_desc *desc = &dev_list->i3c[i];

		/*
		 * A device without static address => need to do
		 * dynamic address assignment.
		 */
		if (desc->static_addr == 0U) {
			*need_daa = true;
			continue;
		}

		LOG_DBG("SETDASA for 0x%x", desc->static_addr);

		ret = i3c_ccc_do_setdasa(desc);
		if (ret == 0) {
			desc->dynamic_addr = (desc->init_dynamic_addr ? desc->init_dynamic_addr
								      : desc->static_addr);
			if (desc->dynamic_addr != desc->static_addr) {
				if (i3c_reattach_i3c_device(desc, desc->static_addr) != 0) {
					LOG_ERR("Failed to reattach %s (%d)", desc->dev->name, ret);
				}
			}
		} else {
			/* SETDASA failed, detach it from the controller */
			if (i3c_detach_i3c_device(desc) != 0) {
				LOG_ERR("Failed to detach %s (%d)", desc->dev->name, ret);
			}
			LOG_ERR("SETDASA error on address 0x%x (%d)",
				desc->static_addr, ret);
			continue;
		}
	}

	return 0;
}

int i3c_bus_init(const struct device *dev, const struct i3c_dev_list *dev_list)
{
	int i, ret = 0;
	bool need_daa = true;
	struct i3c_ccc_events i3c_events;

	/*
	 * Reset all connected targets. Also reset dynamic
	 * addresses for all devices as we have no idea what
	 * dynamic addresses the connected devices have
	 * (e.g. assigned during previous power cycle).
	 *
	 * Note that we ignore error for both RSTACT and RSTDAA
	 * as there may not be any connected devices responding
	 * to these CCCs.
	 */
	if (i3c_ccc_do_rstact_all(dev, I3C_CCC_RSTACT_RESET_WHOLE_TARGET) != 0) {
		/*
		 * Reset Whole Target support is not required so
		 * if there is any NACK, we want to at least reset
		 * the I3C peripheral of targets.
		 */
		LOG_DBG("Broadcast RSTACT (whole target) was NACK.");

		if (i3c_ccc_do_rstact_all(dev, I3C_CCC_RSTACT_PERIPHERAL_ONLY) != 0) {
			LOG_DBG("Broadcast RSTACT (peripehral) was NACK.");
		}
	}

	if (i3c_ccc_do_rstdaa_all(dev) != 0) {
		LOG_DBG("Broadcast RSTDAA was NACK.");
	}

	/*
	 * Disable all events from targets to avoid them
	 * interfering with bus initialization,
	 * especially during DAA.
	 */
	i3c_events.events = I3C_CCC_EVT_ALL;
	ret = i3c_ccc_do_events_all_set(dev, false, &i3c_events);
	if (ret != 0) {
		LOG_DBG("Broadcast DISEC was NACK.");
	}

	/*
	 * Set static addresses as dynamic addresses.
	 */
	ret = i3c_bus_setdasa(dev, dev_list, &need_daa);
	if (ret != 0) {
		goto err_out;
	}

	/*
	 * Perform Dynamic Address Assignment if needed.
	 */
	if (need_daa) {
		ret = i3c_do_daa(dev);
		if (ret != 0) {
			/*
			 * Spec says to try once more
			 * if DAA fails the first time.
			 */
			ret = i3c_do_daa(dev);
			if (ret != 0) {
				/*
				 * Failure to finish dynamic address assignment
				 * is not the end of world... hopefully.
				 * Continue on so the devices already have
				 * addresses can still function.
				 */
				LOG_ERR("DAA was not successful.");
			}
		}
	}

	/*
	 * Loop through the registered I3C devices to retrieve
	 * basic target information.
	 */
	for (i = 0; i < dev_list->num_i3c; i++) {
		struct i3c_device_desc *desc = &dev_list->i3c[i];

		if (desc->dynamic_addr == 0U) {
			continue;
		}

		ret = i3c_device_basic_info_get(desc);
		if (ret != 0) {
			LOG_ERR("Error getting basic device info for 0x%02x",
				desc->static_addr);
		} else {
			LOG_DBG("Target 0x%02x, BCR 0x%02x, DCR 0x%02x, MRL %d, MWL %d, IBI %d",
				desc->dynamic_addr, desc->bcr, desc->dcr,
				desc->data_length.mrl, desc->data_length.mwl,
				desc->data_length.max_ibi);
		}
	}

	/*
	 * Only re-enable Hot-Join from targets.
	 * Target interrupts will be enabled when IBI is enabled.
	 * And transferring controller role is not supported so not need to
	 * enable the event.
	 */
	i3c_events.events = I3C_CCC_EVT_HJ;
	ret = i3c_ccc_do_events_all_set(dev, true, &i3c_events);
	if (ret != 0) {
		LOG_DBG("Broadcast ENEC was NACK.");
	}

err_out:
	return ret;
}
