// SPDX-License-Identifier: GPL-2.0
/*
 * Serial line interface for Bosh BNO055 IMU (via serdev).
 * This file implements serial communication up to the register read/write
 * level.
 *
 * Copyright (C) 2021-2022 Istituto Italiano di Tecnologia
 * Electronic Design Laboratory
 * Written by Andrea Merello <andrea.merello@iit.it>
 *
 * This driver is based on
 *	Plantower PMS7003 particulate matter sensor driver
 *	Which is
 *	Copyright (c) Tomasz Duszynski <tduszyns@gmail.com>
 */

#include <linux/completion.h>
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/jiffies.h>
#include <linux/kernel.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/regmap.h>
#include <linux/serdev.h>

#include "bno055_ser_trace.h"
#include "bno055.h"

/*
 * Register writes cmd have the following format
 * +------+------+-----+-----+----- ... ----+
 * | 0xAA | 0xOO | REG | LEN | payload[LEN] |
 * +------+------+-----+-----+----- ... ----+
 *
 * Register write responses have the following format
 * +------+----------+
 * | 0xEE | ERROCODE |
 * +------+----------+
 *
 * .. except when writing the SYS_RST bit (i.e. triggering a system reset); in
 * case the IMU accepts the command, then it resets without responding. We don't
 * handle this (yet) here (so we inform the common bno055 code not to perform
 * sw resets - bno055 on serial bus basically requires the hw reset pin).
 *
 * Register read have the following format
 * +------+------+-----+-----+
 * | 0xAA | 0xO1 | REG | LEN |
 * +------+------+-----+-----+
 *
 * Successful register read response have the following format
 * +------+-----+----- ... ----+
 * | 0xBB | LEN | payload[LEN] |
 * +------+-----+----- ... ----+
 *
 * Failed register read response have the following format
 * +------+--------+
 * | 0xEE | ERRCODE|  (ERRCODE always > 1)
 * +------+--------+
 *
 * Error codes are
 * 01: OK
 * 02: read/write FAIL
 * 04: invalid address
 * 05: write on RO
 * 06: wrong start byte
 * 07: bus overrun
 * 08: len too high
 * 09: len too low
 * 10: bus RX byte timeout (timeout is 30mS)
 *
 *
 * **WORKAROUND ALERT**
 *
 * Serial communication seems very fragile: the BNO055 buffer seems to overflow
 * very easy; BNO055 seems able to sink few bytes, then it needs a brief pause.
 * On the other hand, it is also picky on timeout: if there is a pause > 30mS in
 * between two bytes then the transaction fails (IMU internal RX FSM resets).
 *
 * BNO055 has been seen also failing to process commands in case we send them
 * too close each other (or if it is somehow busy?)
 *
 * In particular I saw these scenarios:
 * 1) If we send 2 bytes per time, then the IMU never(?) overflows.
 * 2) If we send 4 bytes per time (i.e. the full header), then the IMU could
 *    overflow, but it seem to sink all 4 bytes, then it returns error.
 * 3) If we send more than 4 bytes, the IMU could overflow, and I saw it sending
 *    error after 4 bytes are sent; we have troubles in synchronizing again,
 *    because we are still sending data, and the IMU interprets it as the 1st
 *    byte of a new command.
 *
 * While we must avoid case 3, we could send 4 bytes per time and eventually
 * retry in case of failure; this seemed convenient for reads (which requires
 * TXing exactly 4 bytes), however it has been seen that, depending by the IMU
 * settings (e.g. LPF), failures became less or more frequent; in certain IMU
 * configurations they are very rare, but in certain others we keeps failing
 * even after like 30 retries.
 *
 * So, we just split TXes in [2-bytes + delay] steps, and still keep an eye on
 * the IMU response; in case it overflows (which is now unlikely), we retry.
 */

/*
 * Read operation overhead:
 *  4 bytes req + 2byte resp hdr.
 *  6 bytes = 60 bit (considering 1start + 1stop bits).
 *  60/115200 = ~520uS + about 2500mS delay -> ~3mS
 * In 3mS we could read back about 34 bytes that means 17 samples, this means
 * that in case of scattered reads in which the gap is 17 samples or less it is
 * still convenient to go for a burst.
 * We have to take into account also IMU response time - IMU seems to be often
 * reasonably quick to respond, but sometimes it seems to be in some "critical
 * section" in which it delays handling of serial protocol. Because of this we
 * round-up to 22, which is the max number of samples, always bursting indeed.
 */
#define BNO055_SER_XFER_BURST_BREAK_THRESHOLD 22

struct bno055_ser_priv {
	enum {
		CMD_NONE,
		CMD_READ,
		CMD_WRITE,
	} expect_response;
	int expected_data_len;
	u8 *response_buf;

	/**
	 * enum cmd_status - represent the status of a command sent to the HW.
	 * @STATUS_CRIT: The command failed: the serial communication failed.
	 * @STATUS_OK:   The command executed successfully.
	 * @STATUS_FAIL: The command failed: HW responded with an error.
	 */
	enum {
		STATUS_CRIT = -1,
		STATUS_OK = 0,
		STATUS_FAIL = 1,
	} cmd_status;

	/*
	 * Protects all the above fields, which are accessed in behalf of both
	 * the serdev RX callback and the regmap side
	 */
	struct mutex lock;

	/* Only accessed in serdev RX callback context*/
	struct {
		enum {
			RX_IDLE,
			RX_START,
			RX_DATA,
		} state;
		int databuf_count;
		int expected_len;
		int type;
	} rx;

	/* Never accessed in behalf of serdev RX callback context */
	bool cmd_stale;

	struct completion cmd_complete;
	struct serdev_device *serdev;
};

static int bno055_ser_send_chunk(struct bno055_ser_priv *priv, const u8 *data, int len)
{
	int ret;

	trace_send_chunk(len, data);
	ret = serdev_device_write(priv->serdev, data, len, msecs_to_jiffies(25));
	if (ret < 0)
		return ret;

	if (ret < len)
		return -EIO;

	return 0;
}

/*
 * Send a read or write command.
 * 'data' can be NULL (used in read case). 'len' parameter is always valid; in
 * case 'data' is non-NULL then it must match 'data' size.
 */
static int bno055_ser_do_send_cmd(struct bno055_ser_priv *priv,
				  bool read, int addr, int len, const u8 *data)
{
	u8 hdr[] = {0xAA, read, addr, len};
	int chunk_len;
	int ret;

	ret = bno055_ser_send_chunk(priv, hdr, 2);
	if (ret)
		goto fail;
	usleep_range(2000, 3000);
	ret = bno055_ser_send_chunk(priv, hdr + 2, 2);
	if (ret)
		goto fail;

	if (read)
		return 0;

	while (len) {
		chunk_len = min(len, 2);
		usleep_range(2000, 3000);
		ret = bno055_ser_send_chunk(priv, data, chunk_len);
		if (ret)
			goto fail;
		data += chunk_len;
		len -= chunk_len;
	}

	return 0;
fail:
	/* waiting more than 30mS should clear the BNO055 internal state */
	usleep_range(40000, 50000);
	return ret;
}

static int bno055_ser_send_cmd(struct bno055_ser_priv *priv,
			       bool read, int addr, int len, const u8 *data)
{
	const int retry_max = 5;
	int retry = retry_max;
	int ret = 0;

	/*
	 * In case previous command was interrupted we still need to wait it to
	 * complete before we can issue new commands
	 */
	if (priv->cmd_stale) {
		ret = wait_for_completion_interruptible_timeout(&priv->cmd_complete,
								msecs_to_jiffies(100));
		if (ret == -ERESTARTSYS)
			return -ERESTARTSYS;

		priv->cmd_stale = false;
		/* if serial protocol broke, bail out */
		if (priv->cmd_status == STATUS_CRIT)
			return -EIO;
	}

	/*
	 * Try to convince the IMU to cooperate.. as explained in the comments
	 * at the top of this file, the IMU could also refuse the command (i.e.
	 * it is not ready yet); retry in this case.
	 */
	do {
		mutex_lock(&priv->lock);
		priv->expect_response = read ? CMD_READ : CMD_WRITE;
		reinit_completion(&priv->cmd_complete);
		mutex_unlock(&priv->lock);

		if (retry != retry_max)
			trace_cmd_retry(read, addr, retry_max - retry);
		ret = bno055_ser_do_send_cmd(priv, read, addr, len, data);
		if (ret)
			continue;

		ret = wait_for_completion_interruptible_timeout(&priv->cmd_complete,
								msecs_to_jiffies(100));
		if (ret == -ERESTARTSYS) {
			priv->cmd_stale = true;
			return -ERESTARTSYS;
		}

		if (!ret)
			return -ETIMEDOUT;

		if (priv->cmd_status == STATUS_OK)
			return 0;
		if (priv->cmd_status == STATUS_CRIT)
			return -EIO;

		/* loop in case priv->cmd_status == STATUS_FAIL */
	} while (--retry);

	if (ret < 0)
		return ret;
	if (priv->cmd_status == STATUS_FAIL)
		return -EINVAL;
	return 0;
}

static int bno055_ser_write_reg(void *context, const void *_data, size_t count)
{
	const u8 *data = _data;
	struct bno055_ser_priv *priv = context;

	if (count < 2) {
		dev_err(&priv->serdev->dev, "Invalid write count %zu", count);
		return -EINVAL;
	}

	trace_write_reg(data[0], data[1]);
	return bno055_ser_send_cmd(priv, 0, data[0], count - 1, data + 1);
}

static int bno055_ser_read_reg(void *context,
			       const void *_reg, size_t reg_size,
			       void *val, size_t val_size)
{
	int ret;
	int reg_addr;
	const u8 *reg = _reg;
	struct bno055_ser_priv *priv = context;

	if (val_size > 128) {
		dev_err(&priv->serdev->dev, "Invalid read valsize %zu", val_size);
		return -EINVAL;
	}

	reg_addr = *reg;
	trace_read_reg(reg_addr, val_size);
	mutex_lock(&priv->lock);
	priv->expected_data_len = val_size;
	priv->response_buf = val;
	mutex_unlock(&priv->lock);

	ret = bno055_ser_send_cmd(priv, 1, reg_addr, val_size, NULL);

	mutex_lock(&priv->lock);
	priv->response_buf = NULL;
	mutex_unlock(&priv->lock);

	return ret;
}

/*
 * Handler for received data; this is called from the receiver callback whenever
 * it got some packet from the serial bus. The status tells us whether the
 * packet is valid (i.e. header ok && received payload len consistent wrt the
 * header). It's now our responsibility to check whether this is what we
 * expected, of whether we got some unexpected, yet valid, packet.
 */
static void bno055_ser_handle_rx(struct bno055_ser_priv *priv, int status)
{
	mutex_lock(&priv->lock);
	switch (priv->expect_response) {
	case CMD_NONE:
		dev_warn(&priv->serdev->dev, "received unexpected, yet valid, data from sensor");
		mutex_unlock(&priv->lock);
		return;

	case CMD_READ:
		priv->cmd_status = status;
		if (status == STATUS_OK &&
		    priv->rx.databuf_count != priv->expected_data_len) {
			/*
			 * If we got here, then the lower layer serial protocol
			 * seems consistent with itself; if we got an unexpected
			 * amount of data then signal it as a non critical error
			 */
			priv->cmd_status = STATUS_FAIL;
			dev_warn(&priv->serdev->dev,
				 "received an unexpected amount of, yet valid, data from sensor");
		}
		break;

	case CMD_WRITE:
		priv->cmd_status = status;
		break;
	}

	priv->expect_response = CMD_NONE;
	mutex_unlock(&priv->lock);
	complete(&priv->cmd_complete);
}

/*
 * Serdev receiver FSM. This tracks the serial communication and parse the
 * header. It pushes packets to bno055_ser_handle_rx(), eventually communicating
 * failures (i.e. malformed packets).
 * Ideally it doesn't know anything about upper layer (i.e. if this is the
 * packet we were really expecting), but since we copies the payload into the
 * receiver buffer (that is not valid when i.e. we don't expect data), we
 * snoop a bit in the upper layer..
 * Also, we assume to RX one pkt per time (i.e. the HW doesn't send anything
 * unless we require to AND we don't queue more than one request per time).
 */
static ssize_t bno055_ser_receive_buf(struct serdev_device *serdev,
				      const u8 *buf, size_t size)
{
	int status;
	struct bno055_ser_priv *priv = serdev_device_get_drvdata(serdev);
	size_t remaining = size;

	if (size == 0)
		return 0;

	trace_recv(size, buf);
	switch (priv->rx.state) {
	case RX_IDLE:
		/*
		 * New packet.
		 * Check for its 1st byte that identifies the pkt type.
		 */
		if (buf[0] != 0xEE && buf[0] != 0xBB) {
			dev_err(&priv->serdev->dev,
				"Invalid packet start %x", buf[0]);
			bno055_ser_handle_rx(priv, STATUS_CRIT);
			break;
		}
		priv->rx.type = buf[0];
		priv->rx.state = RX_START;
		remaining--;
		buf++;
		priv->rx.databuf_count = 0;
		fallthrough;

	case RX_START:
		/*
		 * Packet RX in progress, we expect either 1-byte len or 1-byte
		 * status depending by the packet type.
		 */
		if (remaining == 0)
			break;

		if (priv->rx.type == 0xEE) {
			if (remaining > 1) {
				dev_err(&priv->serdev->dev, "EE pkt. Extra data received");
				status = STATUS_CRIT;
			} else {
				status = (buf[0] == 1) ? STATUS_OK : STATUS_FAIL;
			}
			bno055_ser_handle_rx(priv, status);
			priv->rx.state = RX_IDLE;
			break;

		} else {
			/*priv->rx.type == 0xBB */
			priv->rx.state = RX_DATA;
			priv->rx.expected_len = buf[0];
			remaining--;
			buf++;
		}
		fallthrough;

	case RX_DATA:
		/* Header parsed; now receiving packet data payload */
		if (remaining == 0)
			break;

		if (priv->rx.databuf_count + remaining > priv->rx.expected_len) {
			/*
			 * This is an inconsistency in serial protocol, we lost
			 * sync and we don't know how to handle further data
			 */
			dev_err(&priv->serdev->dev, "BB pkt. Extra data received");
			bno055_ser_handle_rx(priv, STATUS_CRIT);
			priv->rx.state = RX_IDLE;
			break;
		}

		mutex_lock(&priv->lock);
		/*
		 * NULL e.g. when read cmd is stale or when no read cmd is
		 * actually pending.
		 */
		if (priv->response_buf &&
		    /*
		     * Snoop on the upper layer protocol stuff to make sure not
		     * to write to an invalid memory. Apart for this, let's the
		     * upper layer manage any inconsistency wrt expected data
		     * len (as long as the serial protocol is consistent wrt
		     * itself (i.e. response header is consistent with received
		     * response len.
		     */
		    (priv->rx.databuf_count + remaining <= priv->expected_data_len))
			memcpy(priv->response_buf + priv->rx.databuf_count,
			       buf, remaining);
		mutex_unlock(&priv->lock);

		priv->rx.databuf_count += remaining;

		/*
		 * Reached expected len advertised by the IMU for the current
		 * packet. Pass it to the upper layer (for us it is just valid).
		 */
		if (priv->rx.databuf_count == priv->rx.expected_len) {
			bno055_ser_handle_rx(priv, STATUS_OK);
			priv->rx.state = RX_IDLE;
		}
		break;
	}

	return size;
}

static const struct serdev_device_ops bno055_ser_serdev_ops = {
	.receive_buf = bno055_ser_receive_buf,
	.write_wakeup = serdev_device_write_wakeup,
};

static struct regmap_bus bno055_ser_regmap_bus = {
	.write = bno055_ser_write_reg,
	.read = bno055_ser_read_reg,
};

static int bno055_ser_probe(struct serdev_device *serdev)
{
	struct bno055_ser_priv *priv;
	struct regmap *regmap;
	int ret;

	priv = devm_kzalloc(&serdev->dev, sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

	serdev_device_set_drvdata(serdev, priv);
	priv->serdev = serdev;
	mutex_init(&priv->lock);
	init_completion(&priv->cmd_complete);

	serdev_device_set_client_ops(serdev, &bno055_ser_serdev_ops);
	ret = devm_serdev_device_open(&serdev->dev, serdev);
	if (ret)
		return ret;

	if (serdev_device_set_baudrate(serdev, 115200) != 115200) {
		dev_err(&serdev->dev, "Cannot set required baud rate");
		return -EIO;
	}

	ret = serdev_device_set_parity(serdev, SERDEV_PARITY_NONE);
	if (ret) {
		dev_err(&serdev->dev, "Cannot set required parity setting");
		return ret;
	}
	serdev_device_set_flow_control(serdev, false);

	regmap = devm_regmap_init(&serdev->dev, &bno055_ser_regmap_bus,
				  priv, &bno055_regmap_config);
	if (IS_ERR(regmap))
		return dev_err_probe(&serdev->dev, PTR_ERR(regmap),
				     "Unable to init register map");

	return bno055_probe(&serdev->dev, regmap,
			    BNO055_SER_XFER_BURST_BREAK_THRESHOLD, false);
}

static const struct of_device_id bno055_ser_of_match[] = {
	{ .compatible = "bosch,bno055" },
	{ }
};
MODULE_DEVICE_TABLE(of, bno055_ser_of_match);

static struct serdev_device_driver bno055_ser_driver = {
	.driver = {
		.name = "bno055-ser",
		.of_match_table = bno055_ser_of_match,
	},
	.probe = bno055_ser_probe,
};
module_serdev_device_driver(bno055_ser_driver);

MODULE_AUTHOR("Andrea Merello <andrea.merello@iit.it>");
MODULE_DESCRIPTION("Bosch BNO055 serdev interface");
MODULE_IMPORT_NS(IIO_BNO055);
MODULE_LICENSE("GPL");
