/*
 * Copyright (c) 2022 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/*
 * Bus-specific functionality for BMI270s accessed via SPI.
 */

#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include "bmi270.h"

LOG_MODULE_DECLARE(bmi270, CONFIG_SENSOR_LOG_LEVEL);

static int bmi270_bus_check_spi(const union bmi270_bus *bus)
{
	return spi_is_ready_dt(&bus->spi) ? 0 : -ENODEV;
}

static int bmi270_reg_read_spi(const union bmi270_bus *bus,
			       uint8_t start, uint8_t *data, uint16_t len)
{
	int ret;
	uint8_t addr;
	uint8_t tmp[2];
	const struct spi_buf tx_buf = {
		.buf = &addr,
		.len = 1
	};
	const struct spi_buf_set tx = {
		.buffers = &tx_buf,
		.count = 1
	};
	struct spi_buf rx_buf[2];
	const struct spi_buf_set rx = {
		.buffers = rx_buf,
		.count = ARRAY_SIZE(rx_buf)
	};

	/* First byte we read should be discarded. */
	rx_buf[0].buf = &tmp;
	rx_buf[0].len = 2;
	rx_buf[1].len = len;
	rx_buf[1].buf = data;

	addr = start | 0x80;

	ret = spi_transceive_dt(&bus->spi, &tx, &rx);
	if (ret < 0) {
		LOG_DBG("spi_transceive failed %i", ret);
		return ret;
	}

	k_usleep(BMI270_SPI_ACC_DELAY_US);
	return 0;
}

static int bmi270_reg_write_spi(const union bmi270_bus *bus, uint8_t start,
				const uint8_t *data, uint16_t len)
{
	int ret;
	uint8_t addr;
	const struct spi_buf tx_buf[2] = {
		{.buf = &addr, .len = sizeof(addr)},
		{.buf = (uint8_t *)data, .len = len}
	};
	const struct spi_buf_set tx = {
		.buffers = tx_buf,
		.count = ARRAY_SIZE(tx_buf)
	};

	addr = start & BMI270_REG_MASK;

	ret = spi_write_dt(&bus->spi, &tx);
	if (ret < 0) {
		LOG_ERR("spi_write_dt failed %i", ret);
		return ret;
	}

	k_usleep(BMI270_SPI_ACC_DELAY_US);
	return 0;
}

static int bmi270_bus_init_spi(const union bmi270_bus *bus)
{
	uint8_t tmp;

	/* Single read of SPI initializes the chip to SPI mode
	 */
	return bmi270_reg_read_spi(bus, BMI270_REG_CHIP_ID, &tmp, 1);
}

const struct bmi270_bus_io bmi270_bus_io_spi = {
	.check = bmi270_bus_check_spi,
	.read = bmi270_reg_read_spi,
	.write = bmi270_reg_write_spi,
	.init = bmi270_bus_init_spi,
};
