// SPDX-License-Identifier: GPL-2.0
/*
 * Sensirion SPS30 particulate matter sensor i2c driver
 *
 * Copyright (c) 2020 Tomasz Duszynski <tomasz.duszynski@octakon.com>
 *
 * I2C slave address: 0x69
 */
#include <asm/unaligned.h>
#include <linux/crc8.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/i2c.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/types.h>

#include "sps30.h"

#define SPS30_I2C_CRC8_POLYNOMIAL 0x31
/* max number of bytes needed to store PM measurements or serial string */
#define SPS30_I2C_MAX_BUF_SIZE 48

DECLARE_CRC8_TABLE(sps30_i2c_crc8_table);

#define SPS30_I2C_START_MEAS 0x0010
#define SPS30_I2C_STOP_MEAS 0x0104
#define SPS30_I2C_READ_MEAS 0x0300
#define SPS30_I2C_MEAS_READY 0x0202
#define SPS30_I2C_RESET 0xd304
#define SPS30_I2C_CLEAN_FAN 0x5607
#define SPS30_I2C_PERIOD 0x8004
#define SPS30_I2C_READ_SERIAL 0xd033
#define SPS30_I2C_READ_VERSION 0xd100

static int sps30_i2c_xfer(struct sps30_state *state, unsigned char *txbuf, size_t txsize,
			  unsigned char *rxbuf, size_t rxsize)
{
	struct i2c_client *client = to_i2c_client(state->dev);
	int ret;

	/*
	 * Sensor does not support repeated start so instead of
	 * sending two i2c messages in a row we just send one by one.
	 */
	ret = i2c_master_send(client, txbuf, txsize);
	if (ret < 0)
		return ret;
	if (ret != txsize)
		return -EIO;

	if (!rxsize)
		return 0;

	ret = i2c_master_recv(client, rxbuf, rxsize);
	if (ret < 0)
		return ret;
	if (ret != rxsize)
		return -EIO;

	return 0;
}

static int sps30_i2c_command(struct sps30_state *state, u16 cmd, void *arg, size_t arg_size,
			     void *rsp, size_t rsp_size)
{
	/*
	 * Internally sensor stores measurements in a following manner:
	 *
	 * PM1:   upper two bytes, crc8, lower two bytes, crc8
	 * PM2P5: upper two bytes, crc8, lower two bytes, crc8
	 * PM4:   upper two bytes, crc8, lower two bytes, crc8
	 * PM10:  upper two bytes, crc8, lower two bytes, crc8
	 *
	 * What follows next are number concentration measurements and
	 * typical particle size measurement which we omit.
	 */
	unsigned char buf[SPS30_I2C_MAX_BUF_SIZE];
	unsigned char *tmp;
	unsigned char crc;
	size_t i;
	int ret;

	put_unaligned_be16(cmd, buf);
	i = 2;

	if (rsp) {
		/* each two bytes are followed by a crc8 */
		rsp_size += rsp_size / 2;
	} else {
		tmp = arg;

		while (arg_size) {
			buf[i] = *tmp++;
			buf[i + 1] = *tmp++;
			buf[i + 2] = crc8(sps30_i2c_crc8_table, buf + i, 2, CRC8_INIT_VALUE);
			arg_size -= 2;
			i += 3;
		}
	}

	ret = sps30_i2c_xfer(state, buf, i, buf, rsp_size);
	if (ret)
		return ret;

	/* validate received data and strip off crc bytes */
	tmp = rsp;
	for (i = 0; i < rsp_size; i += 3) {
		crc = crc8(sps30_i2c_crc8_table, buf + i, 2, CRC8_INIT_VALUE);
		if (crc != buf[i + 2]) {
			dev_err(state->dev, "data integrity check failed\n");
			return -EIO;
		}

		*tmp++ = buf[i];
		*tmp++ = buf[i + 1];
	}

	return 0;
}

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

	return sps30_i2c_command(state, SPS30_I2C_START_MEAS, buf, sizeof(buf), NULL, 0);
}

static int sps30_i2c_stop_meas(struct sps30_state *state)
{
	return sps30_i2c_command(state, SPS30_I2C_STOP_MEAS, NULL, 0, NULL, 0);
}

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

	ret = sps30_i2c_command(state, SPS30_I2C_RESET, NULL, 0, NULL, 0);
	msleep(500);
	/*
	 * Power-on-reset causes sensor to produce some glitch on i2c bus and
	 * some controllers end up in error state. Recover simply by placing
	 * some data on the bus, for example STOP_MEAS command, which
	 * is NOP in this case.
	 */
	sps30_i2c_stop_meas(state);

	return ret;
}

static bool sps30_i2c_meas_ready(struct sps30_state *state)
{
	unsigned char buf[2];
	int ret;

	ret = sps30_i2c_command(state, SPS30_I2C_MEAS_READY, NULL, 0, buf, sizeof(buf));
	if (ret)
		return false;

	return buf[1];
}

static int sps30_i2c_read_meas(struct sps30_state *state, __be32 *meas, size_t num)
{
	/* measurements are ready within a second */
	if (msleep_interruptible(1000))
		return -EINTR;

	if (!sps30_i2c_meas_ready(state))
		return -ETIMEDOUT;

	return sps30_i2c_command(state, SPS30_I2C_READ_MEAS, NULL, 0, meas, sizeof(num) * num);
}

static int sps30_i2c_clean_fan(struct sps30_state *state)
{
	return sps30_i2c_command(state, SPS30_I2C_CLEAN_FAN, NULL, 0, NULL, 0);
}

static int sps30_i2c_read_cleaning_period(struct sps30_state *state, __be32 *period)
{
	return sps30_i2c_command(state, SPS30_I2C_PERIOD, NULL, 0, period, sizeof(*period));
}

static int sps30_i2c_write_cleaning_period(struct sps30_state *state, __be32 period)
{
	return sps30_i2c_command(state, SPS30_I2C_PERIOD, &period, sizeof(period), NULL, 0);
}

static int sps30_i2c_show_info(struct sps30_state *state)
{
	/* extra nul just in case */
	unsigned char buf[32 + 1] = { 0x00 };
	int ret;

	ret = sps30_i2c_command(state, SPS30_I2C_READ_SERIAL, NULL, 0, buf, sizeof(buf) - 1);
	if (ret)
		return ret;

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

	ret = sps30_i2c_command(state, SPS30_I2C_READ_VERSION, NULL, 0, buf, 2);
	if (ret)
		return ret;

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

	return 0;
}

static const struct sps30_ops sps30_i2c_ops = {
	.start_meas = sps30_i2c_start_meas,
	.stop_meas = sps30_i2c_stop_meas,
	.read_meas = sps30_i2c_read_meas,
	.reset = sps30_i2c_reset,
	.clean_fan = sps30_i2c_clean_fan,
	.read_cleaning_period = sps30_i2c_read_cleaning_period,
	.write_cleaning_period = sps30_i2c_write_cleaning_period,
	.show_info = sps30_i2c_show_info,
};

static int sps30_i2c_probe(struct i2c_client *client)
{
	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
		return -EOPNOTSUPP;

	crc8_populate_msb(sps30_i2c_crc8_table, SPS30_I2C_CRC8_POLYNOMIAL);

	return sps30_probe(&client->dev, client->name, NULL, &sps30_i2c_ops);
}

static const struct i2c_device_id sps30_i2c_id[] = {
	{ "sps30" },
	{ }
};
MODULE_DEVICE_TABLE(i2c, sps30_i2c_id);

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

static struct i2c_driver sps30_i2c_driver = {
	.driver = {
		.name = KBUILD_MODNAME,
		.of_match_table = sps30_i2c_of_match,
	},
	.id_table = sps30_i2c_id,
	.probe = sps30_i2c_probe,
};
module_i2c_driver(sps30_i2c_driver);

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