// SPDX-License-Identifier: GPL-2.0
/*
 * Sensirion SCD4X carbon dioxide sensor i2c driver
 *
 * Copyright (C) 2021 Protonic Holland
 * Author: Roan van Dijk <roan@protonic.nl>
 *
 * I2C slave address: 0x62
 *
 * Datasheets:
 * https://www.sensirion.com/file/datasheet_scd4x
 */

#include <asm/unaligned.h>
#include <linux/crc8.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/i2c.h>
#include <linux/iio/buffer.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/trigger.h>
#include <linux/iio/trigger_consumer.h>
#include <linux/iio/triggered_buffer.h>
#include <linux/iio/types.h>
#include <linux/kernel.h>
#include <linux/mutex.h>
#include <linux/string.h>
#include <linux/sysfs.h>
#include <linux/types.h>

#define SCD4X_CRC8_POLYNOMIAL 0x31
#define SCD4X_TIMEOUT_ERR 1000
#define SCD4X_READ_BUF_SIZE 9
#define SCD4X_COMMAND_BUF_SIZE 2
#define SCD4X_WRITE_BUF_SIZE 5
#define SCD4X_FRC_MIN_PPM 0
#define SCD4X_FRC_MAX_PPM 2000
#define SCD4X_READY_MASK 0x01

/*Commands SCD4X*/
enum scd4x_cmd {
	CMD_START_MEAS          = 0x21b1,
	CMD_READ_MEAS           = 0xec05,
	CMD_STOP_MEAS           = 0x3f86,
	CMD_SET_TEMP_OFFSET     = 0x241d,
	CMD_GET_TEMP_OFFSET     = 0x2318,
	CMD_FRC                 = 0x362f,
	CMD_SET_ASC             = 0x2416,
	CMD_GET_ASC             = 0x2313,
	CMD_GET_DATA_READY      = 0xe4b8,
};

enum scd4x_channel_idx {
	SCD4X_CO2,
	SCD4X_TEMP,
	SCD4X_HR,
};

struct scd4x_state {
	struct i2c_client *client;
	/* maintain access to device, to prevent concurrent reads/writes */
	struct mutex lock;
	struct regulator *vdd;
};

DECLARE_CRC8_TABLE(scd4x_crc8_table);

static int scd4x_i2c_xfer(struct scd4x_state *state, char *txbuf, int txsize,
				char *rxbuf, int rxsize)
{
	struct i2c_client *client = state->client;
	int ret;

	ret = i2c_master_send(client, txbuf, txsize);

	if (ret < 0)
		return ret;
	if (ret != txsize)
		return -EIO;

	if (rxsize == 0)
		return 0;

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

	return 0;
}

static int scd4x_send_command(struct scd4x_state *state, enum scd4x_cmd cmd)
{
	char buf[SCD4X_COMMAND_BUF_SIZE];
	int ret;

	/*
	 * Measurement needs to be stopped before sending commands.
	 * Except stop and start command.
	 */
	if ((cmd != CMD_STOP_MEAS) && (cmd != CMD_START_MEAS)) {

		ret = scd4x_send_command(state, CMD_STOP_MEAS);
		if (ret)
			return ret;

		/* execution time for stopping measurement */
		msleep_interruptible(500);
	}

	put_unaligned_be16(cmd, buf);
	ret = scd4x_i2c_xfer(state, buf, 2, buf, 0);
	if (ret)
		return ret;

	if ((cmd != CMD_STOP_MEAS) && (cmd != CMD_START_MEAS)) {
		ret = scd4x_send_command(state, CMD_START_MEAS);
		if (ret)
			return ret;
	}

	return 0;
}

static int scd4x_read(struct scd4x_state *state, enum scd4x_cmd cmd,
			void *response, int response_sz)
{
	struct i2c_client *client = state->client;
	char buf[SCD4X_READ_BUF_SIZE];
	char *rsp = response;
	int i, ret;
	char crc;

	/*
	 * Measurement needs to be stopped before sending commands.
	 * Except for reading measurement and data ready command.
	 */
	if ((cmd != CMD_GET_DATA_READY) && (cmd != CMD_READ_MEAS)) {
		ret = scd4x_send_command(state, CMD_STOP_MEAS);
		if (ret)
			return ret;

		/* execution time for stopping measurement */
		msleep_interruptible(500);
	}

	/* CRC byte for every 2 bytes of data */
	response_sz += response_sz / 2;

	put_unaligned_be16(cmd, buf);
	ret = scd4x_i2c_xfer(state, buf, 2, buf, response_sz);
	if (ret)
		return ret;

	for (i = 0; i < response_sz; i += 3) {
		crc = crc8(scd4x_crc8_table, buf + i, 2, CRC8_INIT_VALUE);
		if (crc != buf[i + 2]) {
			dev_err(&client->dev, "CRC error\n");
			return -EIO;
		}

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

	/* start measurement */
	if ((cmd != CMD_GET_DATA_READY) && (cmd != CMD_READ_MEAS)) {
		ret = scd4x_send_command(state, CMD_START_MEAS);
		if (ret)
			return ret;
	}

	return 0;
}

static int scd4x_write(struct scd4x_state *state, enum scd4x_cmd cmd, uint16_t arg)
{
	char buf[SCD4X_WRITE_BUF_SIZE];
	int ret;
	char crc;

	put_unaligned_be16(cmd, buf);
	put_unaligned_be16(arg, buf + 2);

	crc = crc8(scd4x_crc8_table, buf + 2, 2, CRC8_INIT_VALUE);
	buf[4] = crc;

	/* measurement needs to be stopped before sending commands */
	ret = scd4x_send_command(state, CMD_STOP_MEAS);
	if (ret)
		return ret;

	/* execution time */
	msleep_interruptible(500);

	ret = scd4x_i2c_xfer(state, buf, SCD4X_WRITE_BUF_SIZE, buf, 0);
	if (ret)
		return ret;

	/* start measurement, except for forced calibration command */
	if (cmd != CMD_FRC) {
		ret = scd4x_send_command(state, CMD_START_MEAS);
		if (ret)
			return ret;
	}

	return 0;
}

static int scd4x_write_and_fetch(struct scd4x_state *state, enum scd4x_cmd cmd,
				uint16_t arg, void *response, int response_sz)
{
	struct i2c_client *client = state->client;
	char buf[SCD4X_READ_BUF_SIZE];
	char *rsp = response;
	int i, ret;
	char crc;

	ret = scd4x_write(state, CMD_FRC, arg);
	if (ret)
		goto err;

	/* execution time */
	msleep_interruptible(400);

	/* CRC byte for every 2 bytes of data */
	response_sz += response_sz / 2;

	ret = i2c_master_recv(client, buf, response_sz);
	if (ret < 0)
		goto err;
	if (ret != response_sz) {
		ret = -EIO;
		goto err;
	}

	for (i = 0; i < response_sz; i += 3) {
		crc = crc8(scd4x_crc8_table, buf + i, 2, CRC8_INIT_VALUE);
		if (crc != buf[i + 2]) {
			dev_err(&client->dev, "CRC error\n");
			ret = -EIO;
			goto err;
		}

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

	return scd4x_send_command(state, CMD_START_MEAS);

err:
	/*
	 * on error try to start the measurement,
	 * puts sensor back into continuous measurement
	 */
	scd4x_send_command(state, CMD_START_MEAS);

	return ret;
}

static int scd4x_read_meas(struct scd4x_state *state, uint16_t *meas)
{
	int i, ret;
	__be16 buf[3];

	ret = scd4x_read(state, CMD_READ_MEAS, buf, sizeof(buf));
	if (ret)
		return ret;

	for (i = 0; i < ARRAY_SIZE(buf); i++)
		meas[i] = be16_to_cpu(buf[i]);

	return 0;
}

static int scd4x_wait_meas_poll(struct scd4x_state *state)
{
	struct i2c_client *client = state->client;
	int tries = 6;
	int ret;

	do {
		__be16 bval;
		uint16_t val;

		ret = scd4x_read(state, CMD_GET_DATA_READY, &bval, sizeof(bval));
		if (ret)
			return -EIO;
		val = be16_to_cpu(bval);

		/* new measurement available */
		if (val & 0x7FF)
			return 0;

		msleep_interruptible(1000);
	} while (--tries);

	/* try to start sensor on timeout */
	ret = scd4x_send_command(state, CMD_START_MEAS);
	if (ret)
		dev_err(&client->dev, "failed to start measurement: %d\n", ret);

	return -ETIMEDOUT;
}

static int scd4x_read_poll(struct scd4x_state *state, uint16_t *buf)
{
	int ret;

	ret = scd4x_wait_meas_poll(state);
	if (ret)
		return ret;

	return scd4x_read_meas(state, buf);
}

static int scd4x_read_channel(struct scd4x_state *state, int chan)
{
	int ret;
	uint16_t buf[3];

	ret = scd4x_read_poll(state, buf);
	if (ret)
		return ret;

	return buf[chan];
}

static int scd4x_read_raw(struct iio_dev *indio_dev,
			struct iio_chan_spec const *chan, int *val,
			int *val2, long mask)
{
	struct scd4x_state *state = iio_priv(indio_dev);
	int ret;
	__be16 tmp;

	switch (mask) {
	case IIO_CHAN_INFO_RAW:
		ret = iio_device_claim_direct_mode(indio_dev);
		if (ret)
			return ret;

		mutex_lock(&state->lock);
		ret = scd4x_read_channel(state, chan->address);
		mutex_unlock(&state->lock);

		iio_device_release_direct_mode(indio_dev);
		if (ret < 0)
			return ret;

		*val = ret;
		return IIO_VAL_INT;
	case IIO_CHAN_INFO_SCALE:
		if (chan->type == IIO_CONCENTRATION) {
			*val = 0;
			*val2 = 100;
			return IIO_VAL_INT_PLUS_MICRO;
		} else if (chan->type == IIO_TEMP) {
			*val = 175000;
			*val2 = 65536;
			return IIO_VAL_FRACTIONAL;
		} else if (chan->type == IIO_HUMIDITYRELATIVE) {
			*val = 100000;
			*val2 = 65536;
			return IIO_VAL_FRACTIONAL;
		}
		return -EINVAL;
	case IIO_CHAN_INFO_OFFSET:
		*val = -16852;
		*val2 = 114286;
		return IIO_VAL_INT_PLUS_MICRO;
	case IIO_CHAN_INFO_CALIBBIAS:
		mutex_lock(&state->lock);
		ret = scd4x_read(state, CMD_GET_TEMP_OFFSET, &tmp, sizeof(tmp));
		mutex_unlock(&state->lock);
		if (ret)
			return ret;

		*val = be16_to_cpu(tmp);

		return IIO_VAL_INT;
	default:
		return -EINVAL;
	}
}

static int scd4x_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan,
				int val, int val2, long mask)
{
	struct scd4x_state *state = iio_priv(indio_dev);
	int ret = 0;

	switch (mask) {
	case IIO_CHAN_INFO_CALIBBIAS:
		mutex_lock(&state->lock);
		ret = scd4x_write(state, CMD_SET_TEMP_OFFSET, val);
		mutex_unlock(&state->lock);

		return ret;
	default:
		return -EINVAL;
	}
}

static ssize_t calibration_auto_enable_show(struct device *dev,
			struct device_attribute *attr, char *buf)
{
	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
	struct scd4x_state *state = iio_priv(indio_dev);
	int ret;
	__be16 bval;
	u16 val;

	mutex_lock(&state->lock);
	ret = scd4x_read(state, CMD_GET_ASC, &bval, sizeof(bval));
	mutex_unlock(&state->lock);
	if (ret) {
		dev_err(dev, "failed to read automatic calibration");
		return ret;
	}

	val = (be16_to_cpu(bval) & SCD4X_READY_MASK) ? 1 : 0;

	return sysfs_emit(buf, "%d\n", val);
}

static ssize_t calibration_auto_enable_store(struct device *dev,
					struct device_attribute *attr,
					const char *buf, size_t len)
{
	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
	struct scd4x_state *state = iio_priv(indio_dev);
	bool val;
	int ret;
	uint16_t value;

	ret = kstrtobool(buf, &val);
	if (ret)
		return ret;

	value = val;

	mutex_lock(&state->lock);
	ret = scd4x_write(state, CMD_SET_ASC, value);
	mutex_unlock(&state->lock);
	if (ret)
		dev_err(dev, "failed to set automatic calibration");

	return ret ?: len;
}

static ssize_t calibration_forced_value_store(struct device *dev,
					struct device_attribute *attr,
					const char *buf, size_t len)
{
	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
	struct scd4x_state *state = iio_priv(indio_dev);
	uint16_t val, arg;
	int ret;

	ret = kstrtou16(buf, 0, &arg);
	if (ret)
		return ret;

	if (arg < SCD4X_FRC_MIN_PPM || arg > SCD4X_FRC_MAX_PPM)
		return -EINVAL;

	mutex_lock(&state->lock);
	ret = scd4x_write_and_fetch(state, CMD_FRC, arg, &val, sizeof(val));
	mutex_unlock(&state->lock);

	if (ret)
		return ret;

	if (val == 0xff) {
		dev_err(dev, "forced calibration has failed");
		return -EINVAL;
	}

	return len;
}

static IIO_DEVICE_ATTR_RW(calibration_auto_enable, 0);
static IIO_DEVICE_ATTR_WO(calibration_forced_value, 0);

static IIO_CONST_ATTR(calibration_forced_value_available,
	       __stringify([SCD4X_FRC_MIN_PPM 1 SCD4X_FRC_MAX_PPM]));

static struct attribute *scd4x_attrs[] = {
	&iio_dev_attr_calibration_auto_enable.dev_attr.attr,
	&iio_dev_attr_calibration_forced_value.dev_attr.attr,
	&iio_const_attr_calibration_forced_value_available.dev_attr.attr,
	NULL
};

static const struct attribute_group scd4x_attr_group = {
	.attrs = scd4x_attrs,
};

static const struct iio_info scd4x_info = {
	.attrs = &scd4x_attr_group,
	.read_raw = scd4x_read_raw,
	.write_raw = scd4x_write_raw,
};

static const struct iio_chan_spec scd4x_channels[] = {
	{
		.type = IIO_CONCENTRATION,
		.channel2 = IIO_MOD_CO2,
		.modified = 1,
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
					BIT(IIO_CHAN_INFO_SCALE),
		.address = SCD4X_CO2,
		.scan_index = SCD4X_CO2,
		.scan_type = {
			.sign = 'u',
			.realbits = 16,
			.storagebits = 16,
			.endianness = IIO_BE,
		},
	},
	{
		.type = IIO_TEMP,
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
					BIT(IIO_CHAN_INFO_SCALE) |
					BIT(IIO_CHAN_INFO_OFFSET) |
					BIT(IIO_CHAN_INFO_CALIBBIAS),
		.address = SCD4X_TEMP,
		.scan_index = SCD4X_TEMP,
		.scan_type = {
			.sign = 'u',
			.realbits = 16,
			.storagebits = 16,
			.endianness = IIO_BE,
		},
	},
	{
		.type = IIO_HUMIDITYRELATIVE,
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
					BIT(IIO_CHAN_INFO_SCALE),
		.address = SCD4X_HR,
		.scan_index = SCD4X_HR,
		.scan_type = {
			.sign = 'u',
			.realbits = 16,
			.storagebits = 16,
			.endianness = IIO_BE,
		},
	},
};

static int scd4x_suspend(struct device *dev)
{
	struct iio_dev *indio_dev = dev_get_drvdata(dev);
	struct scd4x_state *state  = iio_priv(indio_dev);
	int ret;

	ret = scd4x_send_command(state, CMD_STOP_MEAS);
	if (ret)
		return ret;

	return regulator_disable(state->vdd);
}

static int scd4x_resume(struct device *dev)
{
	struct iio_dev *indio_dev = dev_get_drvdata(dev);
	struct scd4x_state *state = iio_priv(indio_dev);
	int ret;

	ret = regulator_enable(state->vdd);
	if (ret)
		return ret;

	return scd4x_send_command(state, CMD_START_MEAS);
}

static DEFINE_SIMPLE_DEV_PM_OPS(scd4x_pm_ops, scd4x_suspend, scd4x_resume);

static void scd4x_stop_meas(void *state)
{
	scd4x_send_command(state, CMD_STOP_MEAS);
}

static void scd4x_disable_regulator(void *data)
{
	struct scd4x_state *state = data;

	regulator_disable(state->vdd);
}

static irqreturn_t scd4x_trigger_handler(int irq, void *p)
{
	struct iio_poll_func *pf = p;
	struct iio_dev *indio_dev = pf->indio_dev;
	struct scd4x_state *state = iio_priv(indio_dev);
	struct {
		uint16_t data[3];
		int64_t ts __aligned(8);
	} scan;
	int ret;

	memset(&scan, 0, sizeof(scan));
	mutex_lock(&state->lock);
	ret = scd4x_read_poll(state, scan.data);
	mutex_unlock(&state->lock);
	if (ret)
		goto out;

	iio_push_to_buffers_with_timestamp(indio_dev, &scan, iio_get_time_ns(indio_dev));
out:
	iio_trigger_notify_done(indio_dev->trig);
	return IRQ_HANDLED;
}

static int scd4x_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
	static const unsigned long scd4x_scan_masks[] = { 0x07, 0x00 };
	struct device *dev = &client->dev;
	struct iio_dev *indio_dev;
	struct scd4x_state *state;
	int ret;

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

	state = iio_priv(indio_dev);
	mutex_init(&state->lock);
	state->client = client;
	crc8_populate_msb(scd4x_crc8_table, SCD4X_CRC8_POLYNOMIAL);

	indio_dev->info = &scd4x_info;
	indio_dev->name = client->name;
	indio_dev->channels = scd4x_channels;
	indio_dev->num_channels = ARRAY_SIZE(scd4x_channels);
	indio_dev->modes = INDIO_DIRECT_MODE;
	indio_dev->available_scan_masks = scd4x_scan_masks;

	state->vdd = devm_regulator_get(dev, "vdd");
	if (IS_ERR(state->vdd))
		return dev_err_probe(dev, PTR_ERR(state->vdd), "failed to get regulator\n");

	ret = regulator_enable(state->vdd);
	if (ret)
		return ret;

	ret = devm_add_action_or_reset(dev, scd4x_disable_regulator, state);
	if (ret)
		return ret;

	ret = scd4x_send_command(state, CMD_STOP_MEAS);
	if (ret) {
		dev_err(dev, "failed to stop measurement: %d\n", ret);
		return ret;
	}

	/* execution time */
	msleep_interruptible(500);

	ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL, scd4x_trigger_handler, NULL);
	if (ret)
		return ret;

	ret = scd4x_send_command(state, CMD_START_MEAS);
	if (ret) {
		dev_err(dev, "failed to start measurement: %d\n", ret);
		return ret;
	}

	ret = devm_add_action_or_reset(dev, scd4x_stop_meas, state);
	if (ret)
		return ret;

	return devm_iio_device_register(dev, indio_dev);
}

static const struct of_device_id scd4x_dt_ids[] = {
	{ .compatible = "sensirion,scd40" },
	{ .compatible = "sensirion,scd41" },
	{ }
};
MODULE_DEVICE_TABLE(of, scd4x_dt_ids);

static struct i2c_driver scd4x_i2c_driver = {
	.driver = {
		.name = KBUILD_MODNAME,
		.of_match_table = scd4x_dt_ids,
		.pm = pm_sleep_ptr(&scd4x_pm_ops),
	},
	.probe = scd4x_probe,
};
module_i2c_driver(scd4x_i2c_driver);

MODULE_AUTHOR("Roan van Dijk <roan@protonic.nl>");
MODULE_DESCRIPTION("Sensirion SCD4X carbon dioxide sensor core driver");
MODULE_LICENSE("GPL v2");
