// SPDX-License-Identifier: GPL-2.0+
/*
 * ams-iaq-core.c - Support for AMS iAQ-Core VOC sensors
 *
 * Copyright (C) 2015, 2018
 * Author: Matt Ranostay <matt.ranostay@konsulko.com>
 */

#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/mutex.h>
#include <linux/init.h>
#include <linux/i2c.h>
#include <linux/iio/iio.h>

#define AMS_IAQCORE_DATA_SIZE		9

#define AMS_IAQCORE_VOC_CO2_IDX		0
#define AMS_IAQCORE_VOC_RESISTANCE_IDX	1
#define AMS_IAQCORE_VOC_TVOC_IDX	2

struct ams_iaqcore_reading {
	__be16 co2_ppm;
	u8 status;
	__be32 resistance;
	__be16 voc_ppb;
} __attribute__((__packed__));

struct ams_iaqcore_data {
	struct i2c_client *client;
	struct mutex lock;
	unsigned long last_update;

	struct ams_iaqcore_reading buffer;
};

static const struct iio_chan_spec ams_iaqcore_channels[] = {
	{
		.type = IIO_CONCENTRATION,
		.channel2 = IIO_MOD_CO2,
		.modified = 1,
		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
		.address = AMS_IAQCORE_VOC_CO2_IDX,
	},
	{
		.type = IIO_RESISTANCE,
		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
		.address = AMS_IAQCORE_VOC_RESISTANCE_IDX,
	},
	{
		.type = IIO_CONCENTRATION,
		.channel2 = IIO_MOD_VOC,
		.modified = 1,
		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
		.address = AMS_IAQCORE_VOC_TVOC_IDX,
	},
};

static int ams_iaqcore_read_measurement(struct ams_iaqcore_data *data)
{
	struct i2c_client *client = data->client;
	int ret;

	struct i2c_msg msg = {
		.addr = client->addr,
		.flags = client->flags | I2C_M_RD,
		.len = AMS_IAQCORE_DATA_SIZE,
		.buf = (char *) &data->buffer,
	};

	ret = i2c_transfer(client->adapter, &msg, 1);

	return (ret == AMS_IAQCORE_DATA_SIZE) ? 0 : ret;
}

static int ams_iaqcore_get_measurement(struct ams_iaqcore_data *data)
{
	int ret;

	/* sensor can only be polled once a second max per datasheet */
	if (!time_after(jiffies, data->last_update + HZ))
		return 0;

	ret = ams_iaqcore_read_measurement(data);
	if (ret < 0)
		return ret;

	data->last_update = jiffies;

	return 0;
}

static int ams_iaqcore_read_raw(struct iio_dev *indio_dev,
				struct iio_chan_spec const *chan, int *val,
				int *val2, long mask)
{
	struct ams_iaqcore_data *data = iio_priv(indio_dev);
	int ret;

	if (mask != IIO_CHAN_INFO_PROCESSED)
		return -EINVAL;

	mutex_lock(&data->lock);
	ret = ams_iaqcore_get_measurement(data);

	if (ret)
		goto err_out;

	switch (chan->address) {
	case AMS_IAQCORE_VOC_CO2_IDX:
		*val = 0;
		*val2 = be16_to_cpu(data->buffer.co2_ppm);
		ret = IIO_VAL_INT_PLUS_MICRO;
		break;
	case AMS_IAQCORE_VOC_RESISTANCE_IDX:
		*val = be32_to_cpu(data->buffer.resistance);
		ret = IIO_VAL_INT;
		break;
	case AMS_IAQCORE_VOC_TVOC_IDX:
		*val = 0;
		*val2 = be16_to_cpu(data->buffer.voc_ppb);
		ret = IIO_VAL_INT_PLUS_NANO;
		break;
	default:
		ret = -EINVAL;
	}

err_out:
	mutex_unlock(&data->lock);

	return ret;
}

static const struct iio_info ams_iaqcore_info = {
	.read_raw	= ams_iaqcore_read_raw,
};

static int ams_iaqcore_probe(struct i2c_client *client,
			     const struct i2c_device_id *id)
{
	struct iio_dev *indio_dev;
	struct ams_iaqcore_data *data;

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

	data = iio_priv(indio_dev);
	i2c_set_clientdata(client, indio_dev);
	data->client = client;

	/* so initial reading will complete */
	data->last_update = jiffies - HZ;
	mutex_init(&data->lock);

	indio_dev->info = &ams_iaqcore_info;
	indio_dev->name = dev_name(&client->dev);
	indio_dev->modes = INDIO_DIRECT_MODE;

	indio_dev->channels = ams_iaqcore_channels;
	indio_dev->num_channels = ARRAY_SIZE(ams_iaqcore_channels);

	return devm_iio_device_register(&client->dev, indio_dev);
}

static const struct i2c_device_id ams_iaqcore_id[] = {
	{ "ams-iaq-core", 0 },
	{ }
};
MODULE_DEVICE_TABLE(i2c, ams_iaqcore_id);

static const struct of_device_id ams_iaqcore_dt_ids[] = {
	{ .compatible = "ams,iaq-core" },
	{ }
};
MODULE_DEVICE_TABLE(of, ams_iaqcore_dt_ids);

static struct i2c_driver ams_iaqcore_driver = {
	.driver = {
		.name	= "ams-iaq-core",
		.of_match_table = ams_iaqcore_dt_ids,
	},
	.probe = ams_iaqcore_probe,
	.id_table = ams_iaqcore_id,
};
module_i2c_driver(ams_iaqcore_driver);

MODULE_AUTHOR("Matt Ranostay <matt.ranostay@konsulko.com>");
MODULE_DESCRIPTION("AMS iAQ-Core VOC sensors");
MODULE_LICENSE("GPL v2");
