/*
 * hdc20x0.c - Support for the TI HDC20x0 temperature + humidity sensors
 *
 * Copyright (C) 2019 Google LLC
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 */

#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/regmap.h>

#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>

#define HDC20X0_REG_TEMP_LOW 0x00
#define HDC20X0_REG_TEMP_HIGH 0x01
#define HDC20X0_REG_HUMID_LOW 0x02
#define HDC20X0_REG_HUMID_HIGH 0x03
#define HDC20X0_REG_INTERRUPT_DRDY 0x04
#define HDC20X0_REG_TEMP_MAX 0x05
#define HDC20X0_REG_HUMID_MAX 0x06
#define HDC20X0_REG_INTERRUPT_CONFIG 0x07
#define HDC20X0_REG_TEMP_OFFSET_ADJUST 0x08
#define HDC20X0_REG_HUM_OFFSET_ADJUST 0x09
#define HDC20X0_REG_TEMP_THR_L 0x0A
#define HDC20X0_REG_TEMP_THR_H 0x0B
#define HDC20X0_REG_HUMID_THR_L 0x0C
#define HDC20X0_REG_HUMID_THR_H 0x0D
#define HDC20X0_REG_CONFIG 0x0E
#define HDC20X0_REG_MEASUREMENT_CONFIG 0x0F
#define HDC20X0_REG_MID_L 0xFC
#define HDC20X0_REG_MID_H 0xFD
#define HDC20X0_REG_DEVICE_ID_L 0xFE
#define HDC20X0_REG_DEVICE_ID_H 0xFF

#define HDC20X0_REG_CONFIG_HEATER_EN 0x8
#define HDC20X0_REG_MEASUREMENT_CONFIG_TRIGGER 0x1

#define HDC20X0_DRV_NAME "hdc20x0"

struct hdc20x0_data {
	struct regmap *regmap;
	/* Mutex should be used on read/write operations to prevent bus
	 * contention */
	struct mutex lock;
	u16 config;
};

static const struct regmap_config hdc20x0_regmap_config = {
	.reg_bits = 8,
	.val_bits = 8,
	.max_register = HDC20X0_REG_DEVICE_ID_H,
};

static IIO_CONST_ATTR(out_current_heater_raw_available, "0 1");

static struct attribute *hdc20x0_attributes[] = {
	&iio_const_attr_out_current_heater_raw_available.dev_attr.attr, NULL
};

static struct attribute_group hdc20x0_attribute_group = {
	.attrs = hdc20x0_attributes,
};

static const struct iio_chan_spec hdc20x0_channels[] = {
	{
		.type = IIO_TEMP,
		.address = HDC20X0_REG_TEMP_LOW,
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
		.info_mask_shared_by_type =
			BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_OFFSET),
	},
	{
		.type = IIO_HUMIDITYRELATIVE,
		.address = HDC20X0_REG_HUMID_LOW,
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
	},
	{
		.type = IIO_CURRENT,
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
		.extend_name = "heater",
		.output = 1,
	},
};

static int hdc20x0_update_config(struct hdc20x0_data *data, int mask, int val)
{
	int tmp = (~mask & data->config) | val;
	int ret;

	ret = regmap_update_bits(data->regmap, HDC20X0_REG_CONFIG, mask, val);
	if (!ret)
		data->config = tmp;

	return ret;
}

static int hdc20x0_get_measurement(
	struct hdc20x0_data *data, struct iio_chan_spec const *chan)
{
	struct device *dev = regmap_get_device(data->regmap);
	int ret;
	int val, reg;

	/* Trigger measurement by setting bit in measurement config */
	ret = regmap_update_bits(data->regmap, HDC20X0_REG_MEASUREMENT_CONFIG,
		HDC20X0_REG_MEASUREMENT_CONFIG_TRIGGER, 1);

	/* Read low byte of measurement */
	ret = regmap_read(data->regmap, chan->address, &reg);
	if (ret < 0) {
		dev_err(dev, "cannot read low byte");
		return ret;
	}
	val = reg;

	/* High byte is address + 1 */
	ret = regmap_read(data->regmap, chan->address + 1, &reg);
	if (ret < 0) {
		dev_err(dev, "cannot read high byte");
		return ret;
	}
	val |= reg << 8;

	return val;
}

static int hdc20x0_get_heater_status(struct hdc20x0_data *data)
{
	return !!(data->config & HDC20X0_REG_CONFIG_HEATER_EN);
}

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

	switch (mask) {
	case IIO_CHAN_INFO_RAW:
		mutex_lock(&data->lock);
		if (chan->type == IIO_CURRENT) {
			*val = hdc20x0_get_heater_status(data);
			ret = IIO_VAL_INT;
		} else {
			ret = hdc20x0_get_measurement(data, chan);
			if (ret >= 0) {
				*val = ret;
				ret = IIO_VAL_INT;
			}
		}
		mutex_unlock(&data->lock);
		return ret;
	case IIO_CHAN_INFO_SCALE:
		if (chan->type == IIO_TEMP) {
			*val = 165;
			*val2 = 65536;
			return IIO_VAL_FRACTIONAL;
		} else if (chan->type == IIO_HUMIDITYRELATIVE) {
			*val = 100;
			*val2 = 65536;
			return IIO_VAL_FRACTIONAL;
		} else {
			return -EINVAL;
		}
	case IIO_CHAN_INFO_OFFSET:
		if (chan->type == IIO_TEMP) {
			/* IIO offset happens before scaling so values are -40 *
			 * scaling */
			*val = -15887;
			*val2 = 515151;
			return IIO_VAL_INT_PLUS_MICRO;
		} else {
			return -EINVAL;
		}
	default:
		return -EINVAL;
	}
}

static int hdc20x0_write_raw(struct iio_dev *indio_dev,
	struct iio_chan_spec const *chan, int val, int val2, long mask)
{
	struct hdc20x0_data *data = iio_priv(indio_dev);
	int ret = -EINVAL;

	if (mask == IIO_CHAN_INFO_RAW) {
		if (chan->type != IIO_CURRENT || val2 != 0)
			return -EINVAL;

		mutex_lock(&data->lock);
		ret = hdc20x0_update_config(data, HDC20X0_REG_CONFIG_HEATER_EN,
			val ? HDC20X0_REG_CONFIG_HEATER_EN : 0);
		mutex_unlock(&data->lock);
		return ret;
	} else {
		return -EINVAL;
	}
}

static const struct iio_info hdc20x0_info = {
	.read_raw = hdc20x0_read_raw,
	.write_raw = hdc20x0_write_raw,
	.attrs = &hdc20x0_attribute_group,
	.driver_module = THIS_MODULE,
};

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

	if (!i2c_check_functionality(client->adapter,
		    I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_BYTE))
		return -ENODEV;

	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->regmap = devm_regmap_init_i2c(client, &hdc20x0_regmap_config);
	mutex_init(&data->lock);

	indio_dev->dev.parent = &client->dev;
	indio_dev->name = HDC20X0_DRV_NAME;
	indio_dev->modes = INDIO_DIRECT_MODE;
	indio_dev->info = &hdc20x0_info;

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

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

static int hdc20x0_remove(struct i2c_client *client)
{
	struct iio_dev *indio_dev = i2c_get_clientdata(client);
	struct hdc20x0_data *data = iio_priv(indio_dev);

	iio_device_unregister(indio_dev);
}

static const struct i2c_device_id hdc20x0_id[] = { { HDC20X0_DRV_NAME, 0 },
	{} };
MODULE_DEVICE_TABLE(i2c, hdc20x0_id);

static struct i2c_driver hdc20x0_driver = {
	.driver = {
		.name	= HDC20X0_DRV_NAME,
	},
	.probe = hdc20x0_probe,
	.remove	= hdc20x0_remove,
	.id_table = hdc20x0_id,
};

module_i2c_driver(hdc20x0_driver);

MODULE_AUTHOR("Michael Brooks <mrbrooks@google.com>");
MODULE_DESCRIPTION("TI HDC20x0 Humidity and Temperature Sensor Driver");
MODULE_LICENSE("GPL");
