// SPDX-License-Identifier: GPL-2.0
/*
 * Sensirion SPS30 particulate matter sensor serial driver
 *
 * Copyright (c) 2021 Tomasz Duszynski <tomasz.duszynski@octakon.com>
 */
#include <linux/completion.h>
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/iio/iio.h>
#include <linux/minmax.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/serdev.h>
#include <linux/types.h>

#include "sps30.h"

#define SPS30_SERIAL_DEV_NAME "sps30"

#define SPS30_SERIAL_SOF_EOF 0x7e
#define SPS30_SERIAL_TIMEOUT msecs_to_jiffies(20)
#define SPS30_SERIAL_MAX_BUF_SIZE 263
#define SPS30_SERIAL_ESCAPE_CHAR 0x7d

#define SPS30_SERIAL_FRAME_MIN_SIZE 7
#define SPS30_SERIAL_FRAME_ADR_OFFSET 1
#define SPS30_SERIAL_FRAME_CMD_OFFSET 2
#define SPS30_SERIAL_FRAME_MOSI_LEN_OFFSET 3
#define SPS30_SERIAL_FRAME_MISO_STATE_OFFSET 3
#define SPS30_SERIAL_FRAME_MISO_LEN_OFFSET 4
#define SPS30_SERIAL_FRAME_MISO_DATA_OFFSET 5

#define SPS30_SERIAL_START_MEAS 0x00
#define SPS30_SERIAL_STOP_MEAS 0x01
#define SPS30_SERIAL_READ_MEAS 0x03
#define SPS30_SERIAL_RESET 0xd3
#define SPS30_SERIAL_CLEAN_FAN 0x56
#define SPS30_SERIAL_PERIOD 0x80
#define SPS30_SERIAL_DEV_INFO 0xd0
#define SPS30_SERIAL_READ_VERSION 0xd1

struct sps30_serial_priv {
	struct completion new_frame;
	unsigned char buf[SPS30_SERIAL_MAX_BUF_SIZE];
	size_t num;
	bool escaped;
	bool done;
};

static int sps30_serial_xfer(struct sps30_state *state, const unsigned char *buf, size_t size)
{
	struct serdev_device *serdev = to_serdev_device(state->dev);
	struct sps30_serial_priv *priv = state->priv;
	int ret;

	priv->num = 0;
	priv->escaped = false;
	priv->done = false;

	ret = serdev_device_write(serdev, buf, size, SPS30_SERIAL_TIMEOUT);
	if (ret < 0)
		return ret;
	if (ret != size)
		return -EIO;

	ret = wait_for_completion_interruptible_timeout(&priv->new_frame, SPS30_SERIAL_TIMEOUT);
	if (ret < 0)
		return ret;
	if (!ret)
		return -ETIMEDOUT;

	return 0;
}

static const struct {
	u8 byte;
	u8 byte2;
} sps30_serial_bytes[] = {
	{ 0x11, 0x31 },
	{ 0x13, 0x33 },
	{ 0x7e, 0x5e },
	{ 0x7d, 0x5d },
};

static int sps30_serial_put_byte(u8 *buf, u8 byte)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(sps30_serial_bytes); i++) {
		if (sps30_serial_bytes[i].byte != byte)
			continue;

		buf[0] = SPS30_SERIAL_ESCAPE_CHAR;
		buf[1] = sps30_serial_bytes[i].byte2;

		return 2;
	}

	buf[0] = byte;

	return 1;
}

static u8 sps30_serial_get_byte(bool escaped, u8 byte2)
{
	int i;

	if (!escaped)
		return byte2;

	for (i = 0; i < ARRAY_SIZE(sps30_serial_bytes); i++) {
		if (sps30_serial_bytes[i].byte2 != byte2)
			continue;

		return sps30_serial_bytes[i].byte;
	}

	return 0;
}

static unsigned char sps30_serial_calc_chksum(const unsigned char *buf, size_t num)
{
	unsigned int chksum = 0;
	size_t i;

	for (i = 0; i < num; i++)
		chksum += buf[i];

	return ~chksum;
}

static int sps30_serial_prep_frame(u8 *buf, u8 cmd, const u8 *arg,
				   size_t arg_size)
{
	unsigned char chksum;
	int num = 0;
	size_t i;

	buf[num++] = SPS30_SERIAL_SOF_EOF;
	buf[num++] = 0;
	num += sps30_serial_put_byte(buf + num, cmd);
	num += sps30_serial_put_byte(buf + num, arg_size);

	for (i = 0; i < arg_size; i++)
		num += sps30_serial_put_byte(buf + num, arg[i]);

	/* SOF isn't checksummed */
	chksum = sps30_serial_calc_chksum(buf + 1, num - 1);
	num += sps30_serial_put_byte(buf + num, chksum);
	buf[num++] = SPS30_SERIAL_SOF_EOF;

	return num;
}

static bool sps30_serial_frame_valid(struct sps30_state *state, const unsigned char *buf)
{
	struct sps30_serial_priv *priv = state->priv;
	unsigned char chksum;

	if ((priv->num < SPS30_SERIAL_FRAME_MIN_SIZE) ||
	    (priv->num != SPS30_SERIAL_FRAME_MIN_SIZE +
	     priv->buf[SPS30_SERIAL_FRAME_MISO_LEN_OFFSET])) {
		dev_err(state->dev, "frame has invalid number of bytes\n");
		return false;
	}

	if ((priv->buf[SPS30_SERIAL_FRAME_ADR_OFFSET] != buf[SPS30_SERIAL_FRAME_ADR_OFFSET]) ||
	    (priv->buf[SPS30_SERIAL_FRAME_CMD_OFFSET] != buf[SPS30_SERIAL_FRAME_CMD_OFFSET])) {
		dev_err(state->dev, "frame has wrong ADR and CMD bytes\n");
		return false;
	}

	if (priv->buf[SPS30_SERIAL_FRAME_MISO_STATE_OFFSET]) {
		dev_err(state->dev, "frame with non-zero state received (0x%02x)\n",
			priv->buf[SPS30_SERIAL_FRAME_MISO_STATE_OFFSET]);
		return false;
	}

	/* SOF, checksum and EOF are not checksummed */
	chksum = sps30_serial_calc_chksum(priv->buf + 1, priv->num - 3);
	if (priv->buf[priv->num - 2] != chksum) {
		dev_err(state->dev, "frame integrity check failed\n");
		return false;
	}

	return true;
}

static int sps30_serial_command(struct sps30_state *state, unsigned char cmd,
				const void *arg, size_t arg_size, void *rsp, size_t rsp_size)
{
	struct sps30_serial_priv *priv = state->priv;
	unsigned char buf[SPS30_SERIAL_MAX_BUF_SIZE];
	int ret, size;

	size = sps30_serial_prep_frame(buf, cmd, arg, arg_size);
	ret = sps30_serial_xfer(state, buf, size);
	if (ret)
		return ret;

	if (!sps30_serial_frame_valid(state, buf))
		return -EIO;

	if (rsp) {
		rsp_size = min_t(size_t, priv->buf[SPS30_SERIAL_FRAME_MISO_LEN_OFFSET], rsp_size);
		memcpy(rsp, &priv->buf[SPS30_SERIAL_FRAME_MISO_DATA_OFFSET], rsp_size);
	}

	return rsp_size;
}

static size_t sps30_serial_receive_buf(struct serdev_device *serdev,
				       const u8 *buf, size_t size)
{
	struct iio_dev *indio_dev = dev_get_drvdata(&serdev->dev);
	struct sps30_serial_priv *priv;
	struct sps30_state *state;
	size_t i;
	u8 byte;

	if (!indio_dev)
		return 0;

	state = iio_priv(indio_dev);
	priv = state->priv;

	/* just in case device put some unexpected data on the bus */
	if (priv->done)
		return size;

	/* wait for the start of frame */
	if (!priv->num && size && buf[0] != SPS30_SERIAL_SOF_EOF)
		return 1;

	if (priv->num + size >= ARRAY_SIZE(priv->buf))
		size = ARRAY_SIZE(priv->buf) - priv->num;

	for (i = 0; i < size; i++) {
		byte = buf[i];
		/* remove stuffed bytes on-the-fly */
		if (byte == SPS30_SERIAL_ESCAPE_CHAR) {
			priv->escaped = true;
			continue;
		}

		byte = sps30_serial_get_byte(priv->escaped, byte);
		if (priv->escaped && !byte)
			dev_warn(state->dev, "unrecognized escaped char (0x%02x)\n", byte);

		priv->buf[priv->num++] = byte;

		/* EOF received */
		if (!priv->escaped && byte == SPS30_SERIAL_SOF_EOF) {
			if (priv->num < SPS30_SERIAL_FRAME_MIN_SIZE)
				continue;

			priv->done = true;
			complete(&priv->new_frame);
			i++;
			break;
		}

		priv->escaped = false;
	}

	return i;
}

static const struct serdev_device_ops sps30_serial_device_ops = {
	.receive_buf = sps30_serial_receive_buf,
	.write_wakeup = serdev_device_write_wakeup,
};

static int sps30_serial_start_meas(struct sps30_state *state)
{
	/* request BE IEEE754 formatted data */
	unsigned char buf[] = { 0x01, 0x03 };

	return sps30_serial_command(state, SPS30_SERIAL_START_MEAS, buf, sizeof(buf), NULL, 0);
}

static int sps30_serial_stop_meas(struct sps30_state *state)
{
	return sps30_serial_command(state, SPS30_SERIAL_STOP_MEAS, NULL, 0, NULL, 0);
}

static int sps30_serial_reset(struct sps30_state *state)
{
	int ret;

	ret = sps30_serial_command(state, SPS30_SERIAL_RESET, NULL, 0, NULL, 0);
	msleep(500);

	return ret;
}

static int sps30_serial_read_meas(struct sps30_state *state, __be32 *meas, size_t num)
{
	int ret;

	/* measurements are ready within a second */
	if (msleep_interruptible(1000))
		return -EINTR;

	ret = sps30_serial_command(state, SPS30_SERIAL_READ_MEAS, NULL, 0, meas, num * sizeof(num));
	if (ret < 0)
		return ret;
	/* if measurements aren't ready sensor returns empty frame */
	if (ret == SPS30_SERIAL_FRAME_MIN_SIZE)
		return -ETIMEDOUT;
	if (ret != num * sizeof(*meas))
		return -EIO;

	return 0;
}

static int sps30_serial_clean_fan(struct sps30_state *state)
{
	return sps30_serial_command(state, SPS30_SERIAL_CLEAN_FAN, NULL, 0, NULL, 0);
}

static int sps30_serial_read_cleaning_period(struct sps30_state *state, __be32 *period)
{
	unsigned char buf[] = { 0x00 };
	int ret;

	ret = sps30_serial_command(state, SPS30_SERIAL_PERIOD, buf, sizeof(buf),
				   period, sizeof(*period));
	if (ret < 0)
		return ret;
	if (ret != sizeof(*period))
		return -EIO;

	return 0;
}

static int sps30_serial_write_cleaning_period(struct sps30_state *state, __be32 period)
{
	unsigned char buf[5] = { 0x00 };

	memcpy(buf + 1, &period, sizeof(period));

	return sps30_serial_command(state, SPS30_SERIAL_PERIOD, buf, sizeof(buf), NULL, 0);
}

static int sps30_serial_show_info(struct sps30_state *state)
{
	/*
	 * tell device do return serial number and add extra nul byte just in case
	 * serial number isn't a valid string
	 */
	unsigned char buf[32 + 1] = { 0x03 };
	struct device *dev = state->dev;
	int ret;

	ret = sps30_serial_command(state, SPS30_SERIAL_DEV_INFO, buf, 1, buf, sizeof(buf) - 1);
	if (ret < 0)
		return ret;
	if (ret != sizeof(buf) - 1)
		return -EIO;

	dev_info(dev, "serial number: %s\n", buf);

	ret = sps30_serial_command(state, SPS30_SERIAL_READ_VERSION, NULL, 0, buf, sizeof(buf) - 1);
	if (ret < 0)
		return ret;
	if (ret < 2)
		return -EIO;

	dev_info(dev, "fw version: %u.%u\n", buf[0], buf[1]);

	return 0;
}

static const struct sps30_ops sps30_serial_ops = {
	.start_meas = sps30_serial_start_meas,
	.stop_meas = sps30_serial_stop_meas,
	.read_meas = sps30_serial_read_meas,
	.reset = sps30_serial_reset,
	.clean_fan = sps30_serial_clean_fan,
	.read_cleaning_period = sps30_serial_read_cleaning_period,
	.write_cleaning_period = sps30_serial_write_cleaning_period,
	.show_info = sps30_serial_show_info,
};

static int sps30_serial_probe(struct serdev_device *serdev)
{
	struct device *dev = &serdev->dev;
	struct sps30_serial_priv *priv;
	int ret;

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

	init_completion(&priv->new_frame);
	serdev_device_set_client_ops(serdev, &sps30_serial_device_ops);

	ret = devm_serdev_device_open(dev, serdev);
	if (ret)
		return ret;

	serdev_device_set_baudrate(serdev, 115200);
	serdev_device_set_flow_control(serdev, false);

	ret = serdev_device_set_parity(serdev, SERDEV_PARITY_NONE);
	if (ret)
		return ret;

	return sps30_probe(dev, SPS30_SERIAL_DEV_NAME, priv, &sps30_serial_ops);
}

static const struct of_device_id sps30_serial_of_match[] = {
	{ .compatible = "sensirion,sps30" },
	{ }
};
MODULE_DEVICE_TABLE(of, sps30_serial_of_match);

static struct serdev_device_driver sps30_serial_driver = {
	.driver = {
		.name = KBUILD_MODNAME,
		.of_match_table = sps30_serial_of_match,
	},
	.probe = sps30_serial_probe,
};
module_serdev_device_driver(sps30_serial_driver);

MODULE_AUTHOR("Tomasz Duszynski <tomasz.duszynski@octakon.com>");
MODULE_DESCRIPTION("Sensirion SPS30 particulate matter sensor serial driver");
MODULE_LICENSE("GPL v2");
MODULE_IMPORT_NS(IIO_SPS30);
