// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2016 Marek Vasut <marex@denx.de>
 *
 * Driver for Hope RF HP03 digital temperature and pressure sensor.
 */

#define pr_fmt(fmt) "hp03: " fmt

#include <linux/module.h>
#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/regmap.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>

/*
 * The HP03 sensor occupies two fixed I2C addresses:
 *  0x50 ... read-only EEPROM with calibration data
 *  0x77 ... read-write ADC for pressure and temperature
 */
#define HP03_EEPROM_ADDR		0x50
#define HP03_ADC_ADDR			0x77

#define HP03_EEPROM_CX_OFFSET		0x10
#define HP03_EEPROM_AB_OFFSET		0x1e
#define HP03_EEPROM_CD_OFFSET		0x20

#define HP03_ADC_WRITE_REG		0xff
#define HP03_ADC_READ_REG		0xfd
#define HP03_ADC_READ_PRESSURE		0xf0	/* D1 in datasheet */
#define HP03_ADC_READ_TEMP		0xe8	/* D2 in datasheet */

struct hp03_priv {
	struct i2c_client	*client;
	struct mutex		lock;
	struct gpio_desc	*xclr_gpio;

	struct i2c_client	*eeprom_client;
	struct regmap		*eeprom_regmap;

	s32			pressure;	/* kPa */
	s32			temp;		/* Deg. C */
};

static const struct iio_chan_spec hp03_channels[] = {
	{
		.type = IIO_PRESSURE,
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
	},
	{
		.type = IIO_TEMP,
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
	},
};

static bool hp03_is_writeable_reg(struct device *dev, unsigned int reg)
{
	return false;
}

static bool hp03_is_volatile_reg(struct device *dev, unsigned int reg)
{
	return false;
}

static const struct regmap_config hp03_regmap_config = {
	.reg_bits	= 8,
	.val_bits	= 8,

	.max_register	= HP03_EEPROM_CD_OFFSET + 1,
	.cache_type	= REGCACHE_RBTREE,

	.writeable_reg	= hp03_is_writeable_reg,
	.volatile_reg	= hp03_is_volatile_reg,
};

static int hp03_get_temp_pressure(struct hp03_priv *priv, const u8 reg)
{
	int ret;

	ret = i2c_smbus_write_byte_data(priv->client, HP03_ADC_WRITE_REG, reg);
	if (ret < 0)
		return ret;

	msleep(50);	/* Wait for conversion to finish */

	return i2c_smbus_read_word_data(priv->client, HP03_ADC_READ_REG);
}

static int hp03_update_temp_pressure(struct hp03_priv *priv)
{
	struct device *dev = &priv->client->dev;
	u8 coefs[18];
	u16 cx_val[7];
	int ab_val, d1_val, d2_val, diff_val, dut, off, sens, x;
	int i, ret;

	/* Sample coefficients from EEPROM */
	ret = regmap_bulk_read(priv->eeprom_regmap, HP03_EEPROM_CX_OFFSET,
			       coefs, sizeof(coefs));
	if (ret < 0) {
		dev_err(dev, "Failed to read EEPROM (reg=%02x)\n",
			HP03_EEPROM_CX_OFFSET);
		return ret;
	}

	/* Sample Temperature and Pressure */
	gpiod_set_value_cansleep(priv->xclr_gpio, 1);

	ret = hp03_get_temp_pressure(priv, HP03_ADC_READ_PRESSURE);
	if (ret < 0) {
		dev_err(dev, "Failed to read pressure\n");
		goto err_adc;
	}
	d1_val = ret;

	ret = hp03_get_temp_pressure(priv, HP03_ADC_READ_TEMP);
	if (ret < 0) {
		dev_err(dev, "Failed to read temperature\n");
		goto err_adc;
	}
	d2_val = ret;

	gpiod_set_value_cansleep(priv->xclr_gpio, 0);

	/* The Cx coefficients and Temp/Pressure values are MSB first. */
	for (i = 0; i < 7; i++)
		cx_val[i] = (coefs[2 * i] << 8) | (coefs[(2 * i) + 1] << 0);
	d1_val = ((d1_val >> 8) & 0xff) | ((d1_val & 0xff) << 8);
	d2_val = ((d2_val >> 8) & 0xff) | ((d2_val & 0xff) << 8);

	/* Coefficient voodoo from the HP03 datasheet. */
	if (d2_val >= cx_val[4])
		ab_val = coefs[14];	/* A-value */
	else
		ab_val = coefs[15];	/* B-value */

	diff_val = d2_val - cx_val[4];
	dut = (ab_val * (diff_val >> 7) * (diff_val >> 7)) >> coefs[16];
	dut = diff_val - dut;

	off = (cx_val[1] + (((cx_val[3] - 1024) * dut) >> 14)) * 4;
	sens = cx_val[0] + ((cx_val[2] * dut) >> 10);
	x = ((sens * (d1_val - 7168)) >> 14) - off;

	priv->pressure = ((x * 100) >> 5) + (cx_val[6] * 10);
	priv->temp = 250 + ((dut * cx_val[5]) >> 16) - (dut >> coefs[17]);

	return 0;

err_adc:
	gpiod_set_value_cansleep(priv->xclr_gpio, 0);
	return ret;
}

static int hp03_read_raw(struct iio_dev *indio_dev,
			 struct iio_chan_spec const *chan,
			 int *val, int *val2, long mask)
{
	struct hp03_priv *priv = iio_priv(indio_dev);
	int ret;

	mutex_lock(&priv->lock);
	ret = hp03_update_temp_pressure(priv);
	mutex_unlock(&priv->lock);

	if (ret)
		return ret;

	switch (mask) {
	case IIO_CHAN_INFO_RAW:
		switch (chan->type) {
		case IIO_PRESSURE:
			*val = priv->pressure;
			return IIO_VAL_INT;
		case IIO_TEMP:
			*val = priv->temp;
			return IIO_VAL_INT;
		default:
			return -EINVAL;
		}
		break;
	case IIO_CHAN_INFO_SCALE:
		switch (chan->type) {
		case IIO_PRESSURE:
			*val = 0;
			*val2 = 1000;
			return IIO_VAL_INT_PLUS_MICRO;
		case IIO_TEMP:
			*val = 10;
			return IIO_VAL_INT;
		default:
			return -EINVAL;
		}
		break;
	default:
		return -EINVAL;
	}

	return -EINVAL;
}

static const struct iio_info hp03_info = {
	.read_raw	= &hp03_read_raw,
};

static int hp03_probe(struct i2c_client *client,
		      const struct i2c_device_id *id)
{
	struct device *dev = &client->dev;
	struct iio_dev *indio_dev;
	struct hp03_priv *priv;
	int ret;

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

	priv = iio_priv(indio_dev);
	priv->client = client;
	mutex_init(&priv->lock);

	indio_dev->name = id->name;
	indio_dev->channels = hp03_channels;
	indio_dev->num_channels = ARRAY_SIZE(hp03_channels);
	indio_dev->info = &hp03_info;
	indio_dev->modes = INDIO_DIRECT_MODE;

	priv->xclr_gpio = devm_gpiod_get_index(dev, "xclr", 0, GPIOD_OUT_HIGH);
	if (IS_ERR(priv->xclr_gpio)) {
		dev_err(dev, "Failed to claim XCLR GPIO\n");
		ret = PTR_ERR(priv->xclr_gpio);
		return ret;
	}

	/*
	 * Allocate another device for the on-sensor EEPROM,
	 * which has it's dedicated I2C address and contains
	 * the calibration constants for the sensor.
	 */
	priv->eeprom_client = devm_i2c_new_dummy_device(dev, client->adapter,
							HP03_EEPROM_ADDR);
	if (IS_ERR(priv->eeprom_client)) {
		dev_err(dev, "New EEPROM I2C device failed\n");
		return PTR_ERR(priv->eeprom_client);
	}

	priv->eeprom_regmap = devm_regmap_init_i2c(priv->eeprom_client,
						   &hp03_regmap_config);
	if (IS_ERR(priv->eeprom_regmap)) {
		dev_err(dev, "Failed to allocate EEPROM regmap\n");
		return PTR_ERR(priv->eeprom_regmap);
	}

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

	return 0;
}

static const struct i2c_device_id hp03_id[] = {
	{ "hp03", 0 },
	{ },
};
MODULE_DEVICE_TABLE(i2c, hp03_id);

static const struct of_device_id hp03_of_match[] = {
	{ .compatible = "hoperf,hp03" },
	{ },
};
MODULE_DEVICE_TABLE(of, hp03_of_match);

static struct i2c_driver hp03_driver = {
	.driver = {
		.name	= "hp03",
		.of_match_table = hp03_of_match,
	},
	.probe		= hp03_probe,
	.id_table	= hp03_id,
};
module_i2c_driver(hp03_driver);

MODULE_AUTHOR("Marek Vasut <marex@denx.de>");
MODULE_DESCRIPTION("Driver for Hope RF HP03 pressure and temperature sensor");
MODULE_LICENSE("GPL v2");
