/*
 * Copyright (c) 2022 Intel Corporation
 * Copyright (c) 2023 SILA Embedded Solutions GmbH
 * SPDX-License-Identifier: Apache-2.0
 */

#include "smbus_utils.h"

#include <zephyr/logging/log.h>
#include <zephyr/sys/__assert.h>
#include <zephyr/sys/crc.h>
#include <zephyr/sys/util.h>

LOG_MODULE_REGISTER(smbus_utils, CONFIG_SMBUS_LOG_LEVEL);

void smbus_loop_alert_devices(const struct device *dev, sys_slist_t *callbacks)
{
	int result;
	uint8_t address;

	/**
	 * There might be several peripheral devices which could have triggered the alert and
	 * the one with the highest priority (lowest address) device wins the arbitration. In
	 * any case, we will have to loop through all of them.
	 *
	 * The format of the transaction is:
	 *
	 *  0                   1                   2
	 *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |S|  Alert Addr |R|A|   Address   |X|N|P|
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 */
	while (true) {
		result = smbus_byte_read(dev, SMBUS_ADDRESS_ARA, &address);
		if (result != 0) {
			LOG_DBG("%s: no more peripheral devices left which triggered an alert",
				dev->name);
			return;
		}

		LOG_DBG("%s: address 0x%02X triggered an alert", dev->name, address);

		smbus_fire_callbacks(callbacks, dev, address);
	}
}

#if defined(CONFIG_SMBUS_SOFT_PEC)

uint8_t smbus_pec_num_msgs(uint32_t flags, uint8_t num_msgs)
{
	__ASSERT_NO_MSG(num_msgs != 0);

	if ((flags & SMBUS_MODE_PEC) == 0) {
		return num_msgs - 1;
	}

	return num_msgs;
}

uint8_t smbus_pec(uint16_t addr, const struct i2c_msg *msgs, uint8_t num_msgs)
{
	uint8_t pec = 0;
	uint8_t prior_direction = 0;
	uint8_t addr8 = addr & BIT_MASK(7);

	for (uint8_t i = 0; i < num_msgs; i++) {
		/* When direction changes, there is a repeated start byte. */
		uint8_t start_byte;
		uint8_t direction = msgs[i].flags & I2C_MSG_RW_MASK;

		if ((i == 0) || (direction != prior_direction)) {
			prior_direction = direction;
			start_byte = (addr8 << 1) | direction;
			pec = crc8_ccitt(pec, &start_byte, sizeof(start_byte));
		}

		pec = crc8_ccitt(pec, msgs[i].buf, msgs[i].len);
	}

	return pec;
}

void smbus_write_prepare_pec(uint32_t flags, uint16_t addr, struct i2c_msg *msgs, uint8_t num_msgs)
{
	if ((flags & SMBUS_MODE_PEC) == 0) {
		return;
	}

	__ASSERT_NO_MSG(msgs != NULL);
	__ASSERT_NO_MSG(num_msgs != 0);
	__ASSERT_NO_MSG(msgs[num_msgs - 1].buf != NULL);

	msgs[num_msgs - 1].buf[0] = smbus_pec(addr, msgs, num_msgs - 1);
}

int smbus_read_check_pec(uint32_t flags, uint16_t addr, const struct i2c_msg *msgs,
			 uint8_t num_msgs)
{
	if ((flags & SMBUS_MODE_PEC) == 0) {
		return 0;
	}

	__ASSERT_NO_MSG(num_msgs != 0);
	__ASSERT_NO_MSG(msgs != NULL);
	__ASSERT_NO_MSG(msgs[num_msgs - 1].buf != NULL);

	uint8_t reported_pec = msgs[num_msgs - 1].buf[0];
	uint8_t computed_pec = smbus_pec(addr, msgs, num_msgs - 1);

	if (reported_pec != computed_pec) {
		return -EIO;
	}

	return 0;
}

#endif /* defined(CONFIG_SMBUS_SOFT_PEC) */
