// SPDX-License-Identifier: GPL-2.0
/*
 * sgp30.c - Support for Sensirion SGP Gas Sensors
 *
 * Copyright (C) 2018 Andreas Brauchli <andreas.brauchli@sensirion.com>
 *
 * I2C slave address: 0x58
 *
 * Datasheets:
 * https://www.sensirion.com/file/datasheet_sgp30
 * https://www.sensirion.com/file/datasheet_sgpc3
 *
 * TODO:
 * - baseline support
 * - humidity compensation
 * - power mode switching (SGPC3)
 */

#include <linux/crc8.h>
#include <linux/delay.h>
#include <linux/kthread.h>
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/mutex.h>
#include <linux/i2c.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>

#define SGP_WORD_LEN				2
#define SGP_CRC8_POLYNOMIAL			0x31
#define SGP_CRC8_INIT				0xff
#define SGP_CRC8_LEN				1
#define SGP_CMD(cmd_word)			cpu_to_be16(cmd_word)
#define SGP_CMD_DURATION_US			12000
#define SGP_MEASUREMENT_DURATION_US		50000
#define SGP_CMD_LEN				SGP_WORD_LEN
#define SGP_CMD_MAX_BUF_SIZE			(SGP_CMD_LEN + 2 * SGP_WORD_LEN)
#define SGP_MEASUREMENT_LEN			2
#define SGP30_MEASURE_INTERVAL_HZ		1
#define SGPC3_MEASURE_INTERVAL_HZ		2
#define SGP_VERS_PRODUCT(data)	((((data)->feature_set) & 0xf000) >> 12)
#define SGP_VERS_RESERVED(data)	((((data)->feature_set) & 0x0800) >> 11)
#define SGP_VERS_GEN(data)	((((data)->feature_set) & 0x0600) >> 9)
#define SGP_VERS_ENG_BIT(data)	((((data)->feature_set) & 0x0100) >> 8)
#define SGP_VERS_MAJOR(data)	((((data)->feature_set) & 0x00e0) >> 5)
#define SGP_VERS_MINOR(data)	(((data)->feature_set) & 0x001f)

DECLARE_CRC8_TABLE(sgp_crc8_table);

enum sgp_product_id {
	SGP30 = 0,
	SGPC3,
};

enum sgp30_channel_idx {
	SGP30_IAQ_TVOC_IDX = 0,
	SGP30_IAQ_CO2EQ_IDX,
	SGP30_SIG_ETOH_IDX,
	SGP30_SIG_H2_IDX,
};

enum sgpc3_channel_idx {
	SGPC3_IAQ_TVOC_IDX = 10,
	SGPC3_SIG_ETOH_IDX,
};

enum sgp_cmd {
	SGP_CMD_IAQ_INIT			= SGP_CMD(0x2003),
	SGP_CMD_IAQ_MEASURE			= SGP_CMD(0x2008),
	SGP_CMD_GET_FEATURE_SET			= SGP_CMD(0x202f),
	SGP_CMD_GET_SERIAL_ID			= SGP_CMD(0x3682),

	SGP30_CMD_MEASURE_SIGNAL		= SGP_CMD(0x2050),

	SGPC3_CMD_MEASURE_RAW			= SGP_CMD(0x2046),
};

struct sgp_version {
	u8 major;
	u8 minor;
};

struct sgp_crc_word {
	__be16 value;
	u8 crc8;
} __attribute__((__packed__));

union sgp_reading {
	u8 start;
	struct sgp_crc_word raw_words[4];
};

enum _iaq_buffer_state {
	IAQ_BUFFER_EMPTY = 0,
	IAQ_BUFFER_DEFAULT_VALS,
	IAQ_BUFFER_VALID,
};

struct sgp_data {
	struct i2c_client *client;
	struct task_struct *iaq_thread;
	struct mutex data_lock;
	unsigned long iaq_init_start_jiffies;
	unsigned long iaq_defval_skip_jiffies;
	u16 product_id;
	u16 feature_set;
	unsigned long measure_interval_jiffies;
	enum sgp_cmd iaq_init_cmd;
	enum sgp_cmd measure_iaq_cmd;
	enum sgp_cmd measure_gas_signals_cmd;
	union sgp_reading buffer;
	union sgp_reading iaq_buffer;
	enum _iaq_buffer_state iaq_buffer_state;
};

struct sgp_device {
	unsigned long product_id;
	const struct iio_chan_spec *channels;
	int num_channels;
};

static const struct sgp_version supported_versions_sgp30[] = {
	{
		.major = 1,
		.minor = 0,
	},
};

static const struct sgp_version supported_versions_sgpc3[] = {
	{
		.major = 0,
		.minor = 4,
	},
};

static const struct iio_chan_spec sgp30_channels[] = {
	{
		.type = IIO_CONCENTRATION,
		.channel2 = IIO_MOD_VOC,
		.modified = 1,
		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
		.address = SGP30_IAQ_TVOC_IDX,
	},
	{
		.type = IIO_CONCENTRATION,
		.channel2 = IIO_MOD_CO2,
		.modified = 1,
		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
		.address = SGP30_IAQ_CO2EQ_IDX,
	},
	{
		.type = IIO_CONCENTRATION,
		.channel2 = IIO_MOD_ETHANOL,
		.modified = 1,
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
		.address = SGP30_SIG_ETOH_IDX,
	},
	{
		.type = IIO_CONCENTRATION,
		.channel2 = IIO_MOD_H2,
		.modified = 1,
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
		.address = SGP30_SIG_H2_IDX,
	},
};

static const struct iio_chan_spec sgpc3_channels[] = {
	{
		.type = IIO_CONCENTRATION,
		.channel2 = IIO_MOD_VOC,
		.modified = 1,
		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
		.address = SGPC3_IAQ_TVOC_IDX,
	},
	{
		.type = IIO_CONCENTRATION,
		.channel2 = IIO_MOD_ETHANOL,
		.modified = 1,
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
		.address = SGPC3_SIG_ETOH_IDX,
	},
};

static const struct sgp_device sgp_devices[] = {
	[SGP30] = {
		.product_id = SGP30,
		.channels = sgp30_channels,
		.num_channels = ARRAY_SIZE(sgp30_channels),
	},
	[SGPC3] = {
		.product_id = SGPC3,
		.channels = sgpc3_channels,
		.num_channels = ARRAY_SIZE(sgpc3_channels),
	},
};

/**
 * sgp_verify_buffer() - verify the checksums of the data buffer words
 *
 * @data:       SGP data
 * @buf:        Raw data buffer
 * @word_count: Num data words stored in the buffer, excluding CRC bytes
 *
 * Return:      0 on success, negative error otherwise.
 */
static int sgp_verify_buffer(const struct sgp_data *data,
			     union sgp_reading *buf, size_t word_count)
{
	size_t size = word_count * (SGP_WORD_LEN + SGP_CRC8_LEN);
	int i;
	u8 crc;
	u8 *data_buf = &buf->start;

	for (i = 0; i < size; i += SGP_WORD_LEN + SGP_CRC8_LEN) {
		crc = crc8(sgp_crc8_table, &data_buf[i], SGP_WORD_LEN,
			   SGP_CRC8_INIT);
		if (crc != data_buf[i + SGP_WORD_LEN]) {
			dev_err(&data->client->dev, "CRC error\n");
			return -EIO;
		}
	}

	return 0;
}

/**
 * sgp_read_cmd() - reads data from sensor after issuing a command
 * The caller must hold data->data_lock for the duration of the call.
 * @data:        SGP data
 * @cmd:         SGP Command to issue
 * @buf:         Raw data buffer to use
 * @word_count:  Num words to read, excluding CRC bytes
 * @duration_us: Time taken to sensor to take a reading and data to be ready.
 *
 * Return:       0 on success, negative error otherwise.
 */
static int sgp_read_cmd(struct sgp_data *data, enum sgp_cmd cmd,
			union sgp_reading *buf, size_t word_count,
			unsigned long duration_us)
{
	int ret;
	struct i2c_client *client = data->client;
	size_t size = word_count * (SGP_WORD_LEN + SGP_CRC8_LEN);
	u8 *data_buf;

	ret = i2c_master_send(client, (const char *)&cmd, SGP_CMD_LEN);
	if (ret != SGP_CMD_LEN)
		return -EIO;
	usleep_range(duration_us, duration_us + 1000);

	if (word_count == 0)
		return 0;

	data_buf = &buf->start;
	ret = i2c_master_recv(client, data_buf, size);
	if (ret < 0)
		return ret;
	if (ret != size)
		return -EIO;

	return sgp_verify_buffer(data, buf, word_count);
}

/**
 * sgp_measure_iaq() - measure and retrieve IAQ values from sensor
 * The caller must hold data->data_lock for the duration of the call.
 * @data:       SGP data
 *
 * Return:      0 on success, -EBUSY on default values, negative error
 *              otherwise.
 */

static int sgp_measure_iaq(struct sgp_data *data)
{
	int ret;
	/* data contains default values */
	bool default_vals = !time_after(jiffies, data->iaq_init_start_jiffies +
						 data->iaq_defval_skip_jiffies);

	ret = sgp_read_cmd(data, data->measure_iaq_cmd, &data->iaq_buffer,
			   SGP_MEASUREMENT_LEN, SGP_MEASUREMENT_DURATION_US);
	if (ret < 0)
		return ret;

	data->iaq_buffer_state = IAQ_BUFFER_DEFAULT_VALS;

	if (default_vals)
		return -EBUSY;

	data->iaq_buffer_state = IAQ_BUFFER_VALID;

	return 0;
}

static void sgp_iaq_thread_sleep_until(const struct sgp_data *data,
				       unsigned long sleep_jiffies)
{
	const long IAQ_POLL = 50000;

	while (!time_after(jiffies, sleep_jiffies)) {
		usleep_range(IAQ_POLL, IAQ_POLL + 10000);
		if (kthread_should_stop() || data->iaq_init_start_jiffies == 0)
			return;
	}
}

static int sgp_iaq_threadfn(void *p)
{
	struct sgp_data *data = (struct sgp_data *)p;
	unsigned long next_update_jiffies;
	int ret;

	while (!kthread_should_stop()) {
		mutex_lock(&data->data_lock);
		if (data->iaq_init_start_jiffies == 0) {
			ret = sgp_read_cmd(data, data->iaq_init_cmd, NULL, 0,
					   SGP_CMD_DURATION_US);
			if (ret < 0)
				goto unlock_sleep_continue;
			data->iaq_init_start_jiffies = jiffies;
		}

		ret = sgp_measure_iaq(data);
		if (ret && ret != -EBUSY) {
			dev_warn(&data->client->dev,
				 "IAQ measurement error [%d]\n", ret);
		}
unlock_sleep_continue:
		next_update_jiffies = jiffies + data->measure_interval_jiffies;
		mutex_unlock(&data->data_lock);
		sgp_iaq_thread_sleep_until(data, next_update_jiffies);
	}

	return 0;
}

static int sgp_read_raw(struct iio_dev *indio_dev,
			struct iio_chan_spec const *chan, int *val,
			int *val2, long mask)
{
	struct sgp_data *data = iio_priv(indio_dev);
	struct sgp_crc_word *words;
	int ret;

	switch (mask) {
	case IIO_CHAN_INFO_PROCESSED:
		mutex_lock(&data->data_lock);
		if (data->iaq_buffer_state != IAQ_BUFFER_VALID) {
			mutex_unlock(&data->data_lock);
			return -EBUSY;
		}
		words = data->iaq_buffer.raw_words;
		switch (chan->address) {
		case SGP30_IAQ_TVOC_IDX:
		case SGPC3_IAQ_TVOC_IDX:
			*val = 0;
			*val2 = be16_to_cpu(words[1].value);
			ret = IIO_VAL_INT_PLUS_NANO;
			break;
		case SGP30_IAQ_CO2EQ_IDX:
			*val = 0;
			*val2 = be16_to_cpu(words[0].value);
			ret = IIO_VAL_INT_PLUS_MICRO;
			break;
		default:
			ret = -EINVAL;
			break;
		}
		mutex_unlock(&data->data_lock);
		break;
	case IIO_CHAN_INFO_RAW:
		mutex_lock(&data->data_lock);
		if (chan->address == SGPC3_SIG_ETOH_IDX) {
			if (data->iaq_buffer_state == IAQ_BUFFER_EMPTY)
				ret = -EBUSY;
			else
				ret = 0;
			words = data->iaq_buffer.raw_words;
		} else {
			ret = sgp_read_cmd(data, data->measure_gas_signals_cmd,
					   &data->buffer, SGP_MEASUREMENT_LEN,
					   SGP_MEASUREMENT_DURATION_US);
			words = data->buffer.raw_words;
		}
		if (ret) {
			mutex_unlock(&data->data_lock);
			return ret;
		}

		switch (chan->address) {
		case SGP30_SIG_ETOH_IDX:
			*val = be16_to_cpu(words[1].value);
			ret = IIO_VAL_INT;
			break;
		case SGPC3_SIG_ETOH_IDX:
		case SGP30_SIG_H2_IDX:
			*val = be16_to_cpu(words[0].value);
			ret = IIO_VAL_INT;
			break;
		default:
			ret = -EINVAL;
			break;
		}
		mutex_unlock(&data->data_lock);
		break;
	default:
		return -EINVAL;
	}

	return ret;
}

static int sgp_check_compat(struct sgp_data *data,
			    unsigned int product_id)
{
	struct device *dev = &data->client->dev;
	const struct sgp_version *supported_versions;
	u16 ix, num_fs;
	u16 product, generation, major, minor;

	/* driver does not match product */
	generation = SGP_VERS_GEN(data);
	if (generation != 0) {
		dev_err(dev,
			"incompatible product generation %d != 0", generation);
		return -ENODEV;
	}

	product = SGP_VERS_PRODUCT(data);
	if (product != product_id) {
		dev_err(dev, "sensor reports a different product: 0x%04x\n",
			product);
		return -ENODEV;
	}

	if (SGP_VERS_RESERVED(data))
		dev_warn(dev, "reserved bit is set\n");

	/* engineering samples are not supported: no interface guarantees */
	if (SGP_VERS_ENG_BIT(data))
		return -ENODEV;

	switch (product) {
	case SGP30:
		supported_versions = supported_versions_sgp30;
		num_fs = ARRAY_SIZE(supported_versions_sgp30);
		break;
	case SGPC3:
		supported_versions = supported_versions_sgpc3;
		num_fs = ARRAY_SIZE(supported_versions_sgpc3);
		break;
	default:
		return -ENODEV;
	}

	major = SGP_VERS_MAJOR(data);
	minor = SGP_VERS_MINOR(data);
	for (ix = 0; ix < num_fs; ix++) {
		if (major == supported_versions[ix].major &&
		    minor >= supported_versions[ix].minor)
			return 0;
	}
	dev_err(dev, "unsupported sgp version: %d.%d\n", major, minor);

	return -ENODEV;
}

static void sgp_init(struct sgp_data *data)
{
	data->iaq_init_cmd = SGP_CMD_IAQ_INIT;
	data->iaq_init_start_jiffies = 0;
	data->iaq_buffer_state = IAQ_BUFFER_EMPTY;
	switch (SGP_VERS_PRODUCT(data)) {
	case SGP30:
		data->measure_interval_jiffies = SGP30_MEASURE_INTERVAL_HZ * HZ;
		data->measure_iaq_cmd = SGP_CMD_IAQ_MEASURE;
		data->measure_gas_signals_cmd = SGP30_CMD_MEASURE_SIGNAL;
		data->product_id = SGP30;
		data->iaq_defval_skip_jiffies = 15 * HZ;
		break;
	case SGPC3:
		data->measure_interval_jiffies = SGPC3_MEASURE_INTERVAL_HZ * HZ;
		data->measure_iaq_cmd = SGPC3_CMD_MEASURE_RAW;
		data->measure_gas_signals_cmd = SGPC3_CMD_MEASURE_RAW;
		data->product_id = SGPC3;
		data->iaq_defval_skip_jiffies =
			43 * data->measure_interval_jiffies;
		break;
	}
}

static const struct iio_info sgp_info = {
	.read_raw	= sgp_read_raw,
};

static const struct of_device_id sgp_dt_ids[] = {
	{ .compatible = "sensirion,sgp30", .data = &sgp_devices[SGP30] },
	{ .compatible = "sensirion,sgpc3", .data = &sgp_devices[SGPC3] },
	{ }
};

static int sgp_probe(struct i2c_client *client)
{
	const struct i2c_device_id *id = i2c_client_get_device_id(client);
	const struct sgp_device *match_data;
	struct device *dev = &client->dev;
	struct iio_dev *indio_dev;
	struct sgp_data *data;
	int ret;

	indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
	if (!indio_dev)
		return -ENOMEM;

	match_data = i2c_get_match_data(client);

	data = iio_priv(indio_dev);
	i2c_set_clientdata(client, indio_dev);
	data->client = client;
	crc8_populate_msb(sgp_crc8_table, SGP_CRC8_POLYNOMIAL);
	mutex_init(&data->data_lock);

	/* get feature set version and write it to client data */
	ret = sgp_read_cmd(data, SGP_CMD_GET_FEATURE_SET, &data->buffer, 1,
			   SGP_CMD_DURATION_US);
	if (ret < 0)
		return ret;

	data->feature_set = be16_to_cpu(data->buffer.raw_words[0].value);

	ret = sgp_check_compat(data, match_data->product_id);
	if (ret)
		return ret;

	indio_dev->info = &sgp_info;
	indio_dev->name = id->name;
	indio_dev->modes = INDIO_DIRECT_MODE;
	indio_dev->channels = match_data->channels;
	indio_dev->num_channels = match_data->num_channels;

	sgp_init(data);

	ret = devm_iio_device_register(dev, indio_dev);
	if (ret) {
		dev_err(dev, "failed to register iio device\n");
		return ret;
	}

	data->iaq_thread = kthread_run(sgp_iaq_threadfn, data,
				       "%s-iaq", data->client->name);

	return 0;
}

static void sgp_remove(struct i2c_client *client)
{
	struct iio_dev *indio_dev = i2c_get_clientdata(client);
	struct sgp_data *data = iio_priv(indio_dev);

	if (data->iaq_thread)
		kthread_stop(data->iaq_thread);
}

static const struct i2c_device_id sgp_id[] = {
	{ "sgp30", (kernel_ulong_t)&sgp_devices[SGP30] },
	{ "sgpc3", (kernel_ulong_t)&sgp_devices[SGPC3] },
	{ }
};

MODULE_DEVICE_TABLE(i2c, sgp_id);
MODULE_DEVICE_TABLE(of, sgp_dt_ids);

static struct i2c_driver sgp_driver = {
	.driver = {
		.name = "sgp30",
		.of_match_table = sgp_dt_ids,
	},
	.probe = sgp_probe,
	.remove = sgp_remove,
	.id_table = sgp_id,
};
module_i2c_driver(sgp_driver);

MODULE_AUTHOR("Andreas Brauchli <andreas.brauchli@sensirion.com>");
MODULE_AUTHOR("Pascal Sachs <pascal.sachs@sensirion.com>");
MODULE_DESCRIPTION("Sensirion SGP gas sensors");
MODULE_LICENSE("GPL v2");
