/*
 * Copyright (c) 2022 Thomas Stranger
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @brief 1-Wire network related functions.
 *
 * The following procedures wrap basic w1 syscalls, they should be callable
 * from user mode as well as supervisor mode, therefore _ZEPHYR_SUPERVISOR__
 * is not defined for this file such that inline macros do not skip
 * the arch_is_user_context() check.
 */

#include <zephyr/logging/log.h>
#include <zephyr/drivers/w1.h>

LOG_MODULE_REGISTER(w1, CONFIG_W1_LOG_LEVEL);

#define W1_SEARCH_DISCREPANCY_INIT 0
#define W1_SEARCH_LAST_SLAVE	   65
#define W1_SEARCH_NO_SLAVE	   66

/* @brief Search bus for next slave.
 *
 * This function searches the next 1-Wire slave on the bus.
 * It sets the found ROM and the last discrepancy in case more than one
 * slave took part in the search.
 * In case only one slave took part in the search, the discrepancy is set to
 * W1_SEARCH_LAST_SLAVE, and in case no slave participated in the search,
 * the discrepancy is set to W1_SEARCH_NO_SLAVE.
 *
 * The implementation is similar to that suggested in the Maxim Integrated
 * application note 187.
 * @see https://www.analog.com/media/en/technical-documentation/app-notes/1wire-search-algorithm.pdf
 * The master reads the first ROM bit and its complementary value of all slaves.
 * Due to physical characteristics, the value received is a
 * logical AND of all slaves' 1st bit. Slaves only continue to
 * participate in the search procedure if the next bit the master sends matches
 * their own addresses' bit. This allows the master to branch through 64-bit
 * addresses in order to detect all slaves.

 * The 1st bit received is stored in bit 1 of rom_inv_64, the 2nd in bit 2 and so
 * on, until bit 64.
 * As a result, each byte of the ROM has the correct bit order, but the received
 * bytes (big-endian) stored in rom_inv_64 are in inverse byte order.
 *
 * Note: Filtering by families is currently not supported.
 *
 * @param dev              Pointer to the device structure for the w1 instance.
 * @param command          Command to chose between normal and alarm search.
 * @param family           This parameter is currently not supported.
 * @param last_discrepancy This must be set to W1_SEARCH_DISCREPANCY_INIT before
 *                         the first call, it carries the search progress for
 *                         further calls.
 * @param rom_inv_64       The found ROM: It must be set to zero before first
 *                         call and carries the last found ROM for furter calls.
 *                         The ROM is stored in inverse byte order.
 *
 * @retval 0      If successful.
 * @retval -errno Negative error code in case of 1-wire read/write error.
 */
static int search_slave(const struct device *dev, uint8_t command,
			 uint8_t family, size_t *last_discrepancy,
			 uint64_t *rom_inv_64)
{
	int ret;
	size_t next_discrepancy;
	bool last_id_bit;
	bool last_complement_id_bit;

	ARG_UNUSED(family);
	__ASSERT_NO_MSG(command == W1_CMD_SEARCH_ROM ||
			command == W1_CMD_SEARCH_ALARM);

	ret = w1_reset_bus(dev);
	if (ret < 0) {
		return ret;
	}
	if (ret == 0) {
		*last_discrepancy = W1_SEARCH_NO_SLAVE;
		return 0;
	}

	ret = w1_write_byte(dev, command);
	if (ret < 0) {
		return ret;
	}
	next_discrepancy = W1_SEARCH_LAST_SLAVE;

	for (size_t id_bit_nr = 1; id_bit_nr < W1_SEARCH_LAST_SLAVE; id_bit_nr++) {
		ret = w1_read_bit(dev);
		if (ret < 0) {
			return ret;
		}
		last_id_bit = (bool)ret;
		ret = w1_read_bit(dev);
		if (ret < 0) {
			return ret;
		}
		last_complement_id_bit = (bool)ret;

		if (last_id_bit && last_complement_id_bit) {
			/*
			 * No slave participating:
			 * We can stop following the branch.
			 */
			LOG_DBG("No slave paricipating");
			*last_discrepancy = W1_SEARCH_NO_SLAVE;
			return 0;
		} else if (last_id_bit != last_complement_id_bit) {
			/*
			 * All slaves connected have same ROM bit value:
			 * We can directly follow last_id_bit branch.
			 */
		} else {
			/*
			 * Discrepancy detected: bit value at id_bit_nr does
			 * not match for all slaves on the bus.
			 */
			if ((id_bit_nr > *last_discrepancy) ||
			    ((id_bit_nr < *last_discrepancy) &&
			     (*rom_inv_64 & BIT64(id_bit_nr - 1)))) {
				/*
				 * - id_bit_nr > last_discrepancy:
				 *     Start always w/ branch of 1s
				 * - id_bit_nr < last_discrepancy:
				 *     Follow same branch as before
				 */
				last_id_bit = true;
				next_discrepancy = id_bit_nr;
			} else {
				/*
				 * - id_bit_nr == last_discrepancy:
				 *     1-path already done, therefore go 0 path
				 * - id_bit_nr < last_discrepancy:
				 *     Follow same branch as before
				 */
			}
		}

		/*
		 * Send and store the chosen bit: all not matching slaves will
		 * no longer participate in this search until they are reset.
		 */
		ret = w1_write_bit(dev, last_id_bit);
		if (ret < 0) {
			return ret;
		}
		*rom_inv_64 &= ~BIT64(id_bit_nr - 1);
		*rom_inv_64 |= last_id_bit ? BIT64(id_bit_nr - 1) : 0;
	}

	*last_discrepancy = next_discrepancy;
	return 0;
}

int z_impl_w1_search_bus(const struct device *dev, uint8_t command,
			 uint8_t family, w1_search_callback_t callback,
			 void *user_data)
{
	size_t last_discrepancy = W1_SEARCH_DISCREPANCY_INIT;
	uint64_t found_rom_inv_64 = 0;
	struct w1_rom found_rom = { 0 };
	int found_cnt = 0;
	int ret;

	(void)w1_lock_bus(dev);

	do {
		ret = search_slave(dev, command, family, &last_discrepancy,
				    &found_rom_inv_64);
		if (ret < 0) {
			found_cnt = ret;
			break;
		}
		if (last_discrepancy == W1_SEARCH_NO_SLAVE) {
			break;
		}

		found_cnt++;
		/*
		 * ROM is stored in found_rom_inv_64 in "inverse byte order" =>
		 * Only big-endian targets need to swap, such that struct's
		 * bytes are stored in big-endian byte order.
		 */
		if (IS_ENABLED(CONFIG_BIG_ENDIAN)) {
			sys_memcpy_swap(&found_rom, &found_rom_inv_64, 8);
		} else {
			*(uint64_t *)&found_rom = found_rom_inv_64;
		}
		LOG_DBG("ROM found: nr %u, %016llx", found_cnt,
			w1_rom_to_uint64(&found_rom));

		if (callback != NULL) {
			callback(found_rom, user_data);
		}

	} while (last_discrepancy != W1_SEARCH_LAST_SLAVE);

	(void)w1_unlock_bus(dev);
	return found_cnt;
}

int w1_read_rom(const struct device *dev, struct w1_rom *rom)
{
	int ret;

	(void)w1_lock_bus(dev);
	ret = w1_reset_bus(dev);
	if (ret == 0) {
		ret = -ENODEV;
		goto out;
	}
	if (ret < 0) {
		goto out;
	}

	ret = w1_write_byte(dev, W1_CMD_READ_ROM);
	if (ret < 0) {
		goto out;
	}
	ret = w1_read_block(dev, (uint8_t *)rom, sizeof(struct w1_rom));
	if (ret < 0) {
		goto out;
	}
	if (w1_crc8((uint8_t *)rom, sizeof(struct w1_rom)) != 0) {
		ret = -EIO;
	}

out:
	(void)w1_unlock_bus(dev);
	return ret;
};

static int match_rom(const struct device *dev, const struct w1_slave_config *config)
{
	int ret;
	uint8_t cmd;

	if (!config->overdrive) {
		if (w1_configure(dev, W1_SETTING_SPEED, 0) < 0) {
			return -EIO;
		}
	}

	ret = w1_reset_bus(dev);
	if (ret == 0) {
		return -ENODEV;
	}
	if (ret < 0) {
		return ret;
	}

	cmd = config->overdrive ? W1_CMD_OVERDRIVE_MATCH_ROM : W1_CMD_MATCH_ROM;
	ret = w1_write_byte(dev, cmd);
	if (ret < 0) {
		return ret;
	}
	ret = w1_write_block(dev, (uint8_t *)&config->rom, 8);
	if (ret < 0) {
		return ret;
	}

	if (config->overdrive) {
		if (w1_configure(dev, W1_SETTING_SPEED, 1) < 0) {
			return -EIO;
		}
	}

	return 0;
};

int w1_match_rom(const struct device *dev, const struct w1_slave_config *config)
{
	int ret;

	(void)w1_lock_bus(dev);
	ret = match_rom(dev, config);
	(void)w1_unlock_bus(dev);
	return ret;
}

int w1_resume_command(const struct device *dev)
{
	int ret;

	(void)w1_lock_bus(dev);
	ret = w1_reset_bus(dev);
	if (ret == 0) {
		ret = -ENODEV;
		goto out;
	}
	if (ret < 0) {
		goto out;
	}

	ret = w1_write_byte(dev, W1_CMD_RESUME);
out:
	(void)w1_unlock_bus(dev);
	return ret;
}

static int skip_rom(const struct device *dev, const struct w1_slave_config *config)
{
	int ret;
	uint8_t cmd;

	if (!config->overdrive) {
		if (w1_configure(dev, W1_SETTING_SPEED, 0) < 0) {
			return -EIO;
		}
	}

	ret = w1_reset_bus(dev);
	if (ret == 0) {
		return -ENODEV;
	}
	if (ret < 0) {
		return ret;
	}

	cmd = config->overdrive ? W1_CMD_OVERDRIVE_SKIP_ROM : W1_CMD_SKIP_ROM;
	ret = w1_write_byte(dev, cmd);
	if (ret < 0) {
		return ret;
	}

	if (config->overdrive) {
		if (w1_configure(dev, W1_SETTING_SPEED, 1) < 0) {
			return -EIO;
		}
	}

	return 0;
}

int w1_skip_rom(const struct device *dev, const struct w1_slave_config *config)
{
	int ret;

	(void)w1_lock_bus(dev);
	ret = skip_rom(dev, config);
	(void)w1_unlock_bus(dev);
	return ret;
}

static int reset_select(const struct device *dev, const struct w1_slave_config *config)
{
	if (IS_ENABLED(CONFIG_W1_NET_FORCE_MULTIDROP_ADDRESSING) || w1_get_slave_count(dev) > 1) {
		return match_rom(dev, config);
	}

	return skip_rom(dev, config);
}

int w1_reset_select(const struct device *dev, const struct w1_slave_config *config)
{
	int ret;

	(void)w1_lock_bus(dev);
	ret = reset_select(dev, config);
	(void)w1_unlock_bus(dev);
	return ret;
}

static int write_read(const struct device *dev, const struct w1_slave_config *config,
		      const uint8_t *write_buf, size_t write_len,
		      uint8_t *read_buf, size_t read_len)
{
	int ret;

	ret = reset_select(dev, config);
	if (ret != 0) {
		return ret;
	}

	ret = w1_write_block(dev, write_buf, write_len);
	if (ret < 0) {
		return ret;
	}

	if (read_buf == NULL && read_len > 0) {
		return -EIO;
	}
	return w1_read_block(dev, read_buf, read_len);
};

int w1_write_read(const struct device *dev, const struct w1_slave_config *config,
		  const uint8_t *write_buf, size_t write_len,
		  uint8_t *read_buf, size_t read_len)
{
	int ret;

	(void)w1_lock_bus(dev);
	ret = write_read(dev, config, write_buf, write_len, read_buf, read_len);
	(void)w1_unlock_bus(dev);
	return ret;
};
