// SPDX-License-Identifier: GPL-2.0-only
/*
 * Measurements Specialties driver common i2c functions
 *
 * Copyright (c) 2015 Measurement-Specialties
 */

#include <linux/module.h>
#include <linux/iio/iio.h>
#include <linux/device.h>
#include <linux/delay.h>

#include "ms_sensors_i2c.h"

/* Conversion times in us */
static const u16 ms_sensors_ht_t_conversion_time[] = { 50000, 25000,
						       13000, 7000 };
static const u16 ms_sensors_ht_h_conversion_time[] = { 16000, 3000,
						       5000, 8000 };
static const u16 ms_sensors_tp_conversion_time[] = { 500, 1100, 2100,
						     4100, 8220, 16440 };

#define MS_SENSORS_SERIAL_READ_MSB		0xFA0F
#define MS_SENSORS_SERIAL_READ_LSB		0xFCC9
#define MS_SENSORS_CONFIG_REG_WRITE		0xE6
#define MS_SENSORS_CONFIG_REG_READ		0xE7
#define MS_SENSORS_HT_T_CONVERSION_START	0xF3
#define MS_SENSORS_HT_H_CONVERSION_START	0xF5

#define MS_SENSORS_TP_PROM_READ			0xA0
#define MS_SENSORS_TP_T_CONVERSION_START	0x50
#define MS_SENSORS_TP_P_CONVERSION_START	0x40
#define MS_SENSORS_TP_ADC_READ			0x00

#define MS_SENSORS_NO_READ_CMD			0xFF

/**
 * ms_sensors_reset() - Reset function
 * @cli:	pointer to device client
 * @cmd:	reset cmd. Depends on device in use
 * @delay:	usleep minimal delay after reset command is issued
 *
 * Generic I2C reset function for Measurement Specialties devices.
 *
 * Return: 0 on success, negative errno otherwise.
 */
int ms_sensors_reset(void *cli, u8 cmd, unsigned int delay)
{
	int ret;
	struct i2c_client *client = cli;

	ret = i2c_smbus_write_byte(client, cmd);
	if (ret) {
		dev_err(&client->dev, "Failed to reset device\n");
		return ret;
	}
	usleep_range(delay, delay + 1000);

	return 0;
}
EXPORT_SYMBOL(ms_sensors_reset);

/**
 * ms_sensors_read_prom_word() - PROM word read function
 * @cli:	pointer to device client
 * @cmd:	PROM read cmd. Depends on device and prom id
 * @word:	pointer to word destination value
 *
 * Generic i2c prom word read function for Measurement Specialties devices.
 *
 * Return: 0 on success, negative errno otherwise.
 */
int ms_sensors_read_prom_word(void *cli, int cmd, u16 *word)
{
	int ret;
	struct i2c_client *client = cli;

	ret = i2c_smbus_read_word_swapped(client, cmd);
	if (ret < 0) {
		dev_err(&client->dev, "Failed to read prom word\n");
		return ret;
	}
	*word = ret;

	return 0;
}
EXPORT_SYMBOL(ms_sensors_read_prom_word);

/**
 * ms_sensors_convert_and_read() - ADC conversion & read function
 * @cli:	pointer to device client
 * @conv:	ADC conversion command. Depends on device in use
 * @rd:		ADC read command. Depends on device in use
 * @delay:	usleep minimal delay after conversion command is issued
 * @adc:	pointer to ADC destination value
 *
 * Generic ADC conversion & read function for Measurement Specialties
 * devices.
 * The function will issue conversion command, sleep appopriate delay, and
 * issue command to read ADC.
 *
 * Return: 0 on success, negative errno otherwise.
 */
int ms_sensors_convert_and_read(void *cli, u8 conv, u8 rd,
				unsigned int delay, u32 *adc)
{
	int ret;
	__be32 buf = 0;
	struct i2c_client *client = cli;

	/* Trigger conversion */
	ret = i2c_smbus_write_byte(client, conv);
	if (ret)
		goto err;
	usleep_range(delay, delay + 1000);

	/* Retrieve ADC value */
	if (rd != MS_SENSORS_NO_READ_CMD)
		ret = i2c_smbus_read_i2c_block_data(client, rd, 3, (u8 *)&buf);
	else
		ret = i2c_master_recv(client, (u8 *)&buf, 3);
	if (ret < 0)
		goto err;

	dev_dbg(&client->dev, "ADC raw value : %x\n", be32_to_cpu(buf) >> 8);
	*adc = be32_to_cpu(buf) >> 8;

	return 0;
err:
	dev_err(&client->dev, "Unable to make sensor adc conversion\n");
	return ret;
}
EXPORT_SYMBOL(ms_sensors_convert_and_read);

/**
 * ms_sensors_crc_valid() - CRC check function
 * @value:	input and CRC compare value
 *
 * Cyclic Redundancy Check function used in TSYS02D, HTU21, MS8607.
 * This function performs a x^8 + x^5 + x^4 + 1 polynomial CRC.
 * The argument contains CRC value in LSB byte while the bytes 1 and 2
 * are used for CRC computation.
 *
 * Return: 1 if CRC is valid, 0 otherwise.
 */
static bool ms_sensors_crc_valid(u32 value)
{
	u32 polynom = 0x988000;	/* x^8 + x^5 + x^4 + 1 */
	u32 msb = 0x800000;
	u32 mask = 0xFF8000;
	u32 result = value & 0xFFFF00;
	u8 crc = value & 0xFF;

	while (msb != 0x80) {
		if (result & msb)
			result = ((result ^ polynom) & mask)
				| (result & ~mask);
		msb >>= 1;
		mask >>= 1;
		polynom >>= 1;
	}

	return result == crc;
}

/**
 * ms_sensors_read_serial() - Serial number read function
 * @cli:	pointer to i2c client
 * @sn:		pointer to 64-bits destination value
 *
 * Generic i2c serial number read function for Measurement Specialties devices.
 * This function is used for TSYS02d, HTU21, MS8607 chipset.
 * Refer to datasheet:
 *	http://www.meas-spec.com/downloads/HTU2X_Serial_Number_Reading.pdf
 *
 * Sensor raw MSB serial number format is the following :
 *	[ SNB3, CRC, SNB2, CRC, SNB1, CRC, SNB0, CRC]
 * Sensor raw LSB serial number format is the following :
 *	[ X, X, SNC1, SNC0, CRC, SNA1, SNA0, CRC]
 * The resulting serial number is following :
 *	[ SNA1, SNA0, SNB3, SNB2, SNB1, SNB0, SNC1, SNC0]
 *
 * Return: 0 on success, negative errno otherwise.
 */
int ms_sensors_read_serial(struct i2c_client *client, u64 *sn)
{
	u8 i;
	__be64 rcv_buf = 0;
	u64 rcv_val;
	__be16 send_buf;
	int ret;

	struct i2c_msg msg[2] = {
		{
		 .addr = client->addr,
		 .flags = client->flags,
		 .len = 2,
		 .buf = (__u8 *)&send_buf,
		 },
		{
		 .addr = client->addr,
		 .flags = client->flags | I2C_M_RD,
		 .buf = (__u8 *)&rcv_buf,
		 },
	};

	/* Read MSB part of serial number */
	send_buf = cpu_to_be16(MS_SENSORS_SERIAL_READ_MSB);
	msg[1].len = 8;
	ret = i2c_transfer(client->adapter, msg, 2);
	if (ret < 0) {
		dev_err(&client->dev, "Unable to read device serial number");
		return ret;
	}

	rcv_val = be64_to_cpu(rcv_buf);
	dev_dbg(&client->dev, "Serial MSB raw : %llx\n", rcv_val);

	for (i = 0; i < 64; i += 16) {
		if (!ms_sensors_crc_valid((rcv_val >> i) & 0xFFFF))
			return -ENODEV;
	}

	*sn = (((rcv_val >> 32) & 0xFF000000) |
	       ((rcv_val >> 24) & 0x00FF0000) |
	       ((rcv_val >> 16) & 0x0000FF00) |
	       ((rcv_val >> 8) & 0x000000FF)) << 16;

	/* Read LSB part of serial number */
	send_buf = cpu_to_be16(MS_SENSORS_SERIAL_READ_LSB);
	msg[1].len = 6;
	rcv_buf = 0;
	ret = i2c_transfer(client->adapter, msg, 2);
	if (ret < 0) {
		dev_err(&client->dev, "Unable to read device serial number");
		return ret;
	}

	rcv_val = be64_to_cpu(rcv_buf) >> 16;
	dev_dbg(&client->dev, "Serial MSB raw : %llx\n", rcv_val);

	for (i = 0; i < 48; i += 24) {
		if (!ms_sensors_crc_valid((rcv_val >> i) & 0xFFFFFF))
			return -ENODEV;
	}

	*sn |= (rcv_val & 0xFFFF00) << 40 | (rcv_val >> 32);

	return 0;
}
EXPORT_SYMBOL(ms_sensors_read_serial);

static int ms_sensors_read_config_reg(struct i2c_client *client,
				      u8 *config_reg)
{
	int ret;

	ret = i2c_smbus_write_byte(client, MS_SENSORS_CONFIG_REG_READ);
	if (ret) {
		dev_err(&client->dev, "Unable to read config register");
		return ret;
	}

	ret = i2c_master_recv(client, config_reg, 1);
	if (ret < 0) {
		dev_err(&client->dev, "Unable to read config register");
		return ret;
	}
	dev_dbg(&client->dev, "Config register :%x\n", *config_reg);

	return 0;
}

/**
 * ms_sensors_write_resolution() - Set resolution function
 * @dev_data:	pointer to temperature/humidity device data
 * @i:		resolution index to set
 *
 * This function will program the appropriate resolution based on the index
 * provided when user space will set samp_freq channel.
 * This function is used for TSYS02D, HTU21 and MS8607 chipsets.
 *
 * Return: 0 on success, negative errno otherwise.
 */
ssize_t ms_sensors_write_resolution(struct ms_ht_dev *dev_data,
				    u8 i)
{
	u8 config_reg;
	int ret;

	ret = ms_sensors_read_config_reg(dev_data->client, &config_reg);
	if (ret)
		return ret;

	config_reg &= 0x7E;
	config_reg |= ((i & 1) << 7) + ((i & 2) >> 1);

	return i2c_smbus_write_byte_data(dev_data->client,
					 MS_SENSORS_CONFIG_REG_WRITE,
					 config_reg);
}
EXPORT_SYMBOL(ms_sensors_write_resolution);

/**
 * ms_sensors_show_battery_low() - Show device battery low indicator
 * @dev_data:	pointer to temperature/humidity device data
 * @buf:	pointer to char buffer to write result
 *
 * This function will read battery indicator value in the device and
 * return 1 if the device voltage is below 2.25V.
 * This function is used for TSYS02D, HTU21 and MS8607 chipsets.
 *
 * Return: length of sprintf on success, negative errno otherwise.
 */
ssize_t ms_sensors_show_battery_low(struct ms_ht_dev *dev_data,
				    char *buf)
{
	int ret;
	u8 config_reg;

	mutex_lock(&dev_data->lock);
	ret = ms_sensors_read_config_reg(dev_data->client, &config_reg);
	mutex_unlock(&dev_data->lock);
	if (ret)
		return ret;

	return sprintf(buf, "%d\n", (config_reg & 0x40) >> 6);
}
EXPORT_SYMBOL(ms_sensors_show_battery_low);

/**
 * ms_sensors_show_heater() - Show device heater
 * @dev_data:	pointer to temperature/humidity device data
 * @buf:	pointer to char buffer to write result
 *
 * This function will read heater enable value in the device and
 * return 1 if the heater is enabled.
 * This function is used for HTU21 and MS8607 chipsets.
 *
 * Return: length of sprintf on success, negative errno otherwise.
 */
ssize_t ms_sensors_show_heater(struct ms_ht_dev *dev_data,
			       char *buf)
{
	u8 config_reg;
	int ret;

	mutex_lock(&dev_data->lock);
	ret = ms_sensors_read_config_reg(dev_data->client, &config_reg);
	mutex_unlock(&dev_data->lock);
	if (ret)
		return ret;

	return sprintf(buf, "%d\n", (config_reg & 0x4) >> 2);
}
EXPORT_SYMBOL(ms_sensors_show_heater);

/**
 * ms_sensors_write_heater() - Write device heater
 * @dev_data:	pointer to temperature/humidity device data
 * @buf:	pointer to char buffer from user space
 * @len:	length of buf
 *
 * This function will write 1 or 0 value in the device
 * to enable or disable heater.
 * This function is used for HTU21 and MS8607 chipsets.
 *
 * Return: length of buffer, negative errno otherwise.
 */
ssize_t ms_sensors_write_heater(struct ms_ht_dev *dev_data,
				const char *buf, size_t len)
{
	u8 val, config_reg;
	int ret;

	ret = kstrtou8(buf, 10, &val);
	if (ret)
		return ret;

	if (val > 1)
		return -EINVAL;

	mutex_lock(&dev_data->lock);
	ret = ms_sensors_read_config_reg(dev_data->client, &config_reg);
	if (ret) {
		mutex_unlock(&dev_data->lock);
		return ret;
	}

	config_reg &= 0xFB;
	config_reg |= val << 2;

	ret = i2c_smbus_write_byte_data(dev_data->client,
					MS_SENSORS_CONFIG_REG_WRITE,
					config_reg);
	mutex_unlock(&dev_data->lock);
	if (ret) {
		dev_err(&dev_data->client->dev, "Unable to write config register\n");
		return ret;
	}

	return len;
}
EXPORT_SYMBOL(ms_sensors_write_heater);

/**
 * ms_sensors_ht_read_temperature() - Read temperature
 * @dev_data:	pointer to temperature/humidity device data
 * @temperature:pointer to temperature destination value
 *
 * This function will get temperature ADC value from the device,
 * check the CRC and compute the temperature value.
 * This function is used for TSYS02D, HTU21 and MS8607 chipsets.
 *
 * Return: 0 on success, negative errno otherwise.
 */
int ms_sensors_ht_read_temperature(struct ms_ht_dev *dev_data,
				   s32 *temperature)
{
	int ret;
	u32 adc;
	u16 delay;

	mutex_lock(&dev_data->lock);
	delay = ms_sensors_ht_t_conversion_time[dev_data->res_index];
	ret = ms_sensors_convert_and_read(dev_data->client,
					  MS_SENSORS_HT_T_CONVERSION_START,
					  MS_SENSORS_NO_READ_CMD,
					  delay, &adc);
	mutex_unlock(&dev_data->lock);
	if (ret)
		return ret;

	if (!ms_sensors_crc_valid(adc)) {
		dev_err(&dev_data->client->dev,
			"Temperature read crc check error\n");
		return -ENODEV;
	}

	/* Temperature algorithm */
	*temperature = (((s64)(adc >> 8) * 175720) >> 16) - 46850;

	return 0;
}
EXPORT_SYMBOL(ms_sensors_ht_read_temperature);

/**
 * ms_sensors_ht_read_humidity() - Read humidity
 * @dev_data:	pointer to temperature/humidity device data
 * @humidity:	pointer to humidity destination value
 *
 * This function will get humidity ADC value from the device,
 * check the CRC and compute the temperature value.
 * This function is used for HTU21 and MS8607 chipsets.
 *
 * Return: 0 on success, negative errno otherwise.
 */
int ms_sensors_ht_read_humidity(struct ms_ht_dev *dev_data,
				u32 *humidity)
{
	int ret;
	u32 adc;
	u16 delay;

	mutex_lock(&dev_data->lock);
	delay = ms_sensors_ht_h_conversion_time[dev_data->res_index];
	ret = ms_sensors_convert_and_read(dev_data->client,
					  MS_SENSORS_HT_H_CONVERSION_START,
					  MS_SENSORS_NO_READ_CMD,
					  delay, &adc);
	mutex_unlock(&dev_data->lock);
	if (ret)
		return ret;

	if (!ms_sensors_crc_valid(adc)) {
		dev_err(&dev_data->client->dev,
			"Humidity read crc check error\n");
		return -ENODEV;
	}

	/* Humidity algorithm */
	*humidity = (((s32)(adc >> 8) * 12500) >> 16) * 10 - 6000;
	if (*humidity >= 100000)
		*humidity = 100000;

	return 0;
}
EXPORT_SYMBOL(ms_sensors_ht_read_humidity);

/**
 * ms_sensors_tp_crc_valid() - CRC check function for
 *     Temperature and pressure devices.
 *     This function is only used when reading PROM coefficients
 *
 * @prom:	pointer to PROM coefficients array
 * @len:	length of PROM coefficients array
 *
 * Return: True if CRC is ok.
 */
static bool ms_sensors_tp_crc_valid(u16 *prom, u8 len)
{
	unsigned int cnt, n_bit;
	u16 n_rem = 0x0000, crc_read = prom[0], crc = (*prom & 0xF000) >> 12;

	prom[len - 1] = 0;
	prom[0] &= 0x0FFF;      /* Clear the CRC computation part */

	for (cnt = 0; cnt < len * 2; cnt++) {
		if (cnt % 2 == 1)
			n_rem ^= prom[cnt >> 1] & 0x00FF;
		else
			n_rem ^= prom[cnt >> 1] >> 8;

		for (n_bit = 8; n_bit > 0; n_bit--) {
			if (n_rem & 0x8000)
				n_rem = (n_rem << 1) ^ 0x3000;
			else
				n_rem <<= 1;
		}
	}
	n_rem >>= 12;
	prom[0] = crc_read;

	return n_rem == crc;
}

/**
 * ms_sensors_tp_read_prom() - prom coeff read function
 * @dev_data:	pointer to temperature/pressure device data
 *
 * This function will read prom coefficients and check CRC.
 * This function is used for MS5637 and MS8607 chipsets.
 *
 * Return: 0 on success, negative errno otherwise.
 */
int ms_sensors_tp_read_prom(struct ms_tp_dev *dev_data)
{
	int i, ret;

	for (i = 0; i < MS_SENSORS_TP_PROM_WORDS_NB; i++) {
		ret = ms_sensors_read_prom_word(
			dev_data->client,
			MS_SENSORS_TP_PROM_READ + (i << 1),
			&dev_data->prom[i]);

		if (ret)
			return ret;
	}

	if (!ms_sensors_tp_crc_valid(dev_data->prom,
				     MS_SENSORS_TP_PROM_WORDS_NB + 1)) {
		dev_err(&dev_data->client->dev,
			"Calibration coefficients crc check error\n");
		return -ENODEV;
	}

	return 0;
}
EXPORT_SYMBOL(ms_sensors_tp_read_prom);

/**
 * ms_sensors_read_temp_and_pressure() - read temp and pressure
 * @dev_data:	pointer to temperature/pressure device data
 * @temperature:pointer to temperature destination value
 * @pressure:	pointer to pressure destination value
 *
 * This function will read ADC and compute pressure and temperature value.
 * This function is used for MS5637 and MS8607 chipsets.
 *
 * Return: 0 on success, negative errno otherwise.
 */
int ms_sensors_read_temp_and_pressure(struct ms_tp_dev *dev_data,
				      int *temperature,
				      unsigned int *pressure)
{
	int ret;
	u32 t_adc, p_adc;
	s32 dt, temp;
	s64 off, sens, t2, off2, sens2;
	u16 *prom = dev_data->prom, delay;

	mutex_lock(&dev_data->lock);
	delay = ms_sensors_tp_conversion_time[dev_data->res_index];

	ret = ms_sensors_convert_and_read(
					dev_data->client,
					MS_SENSORS_TP_T_CONVERSION_START +
						dev_data->res_index * 2,
					MS_SENSORS_TP_ADC_READ,
					delay, &t_adc);
	if (ret) {
		mutex_unlock(&dev_data->lock);
		return ret;
	}

	ret = ms_sensors_convert_and_read(
					dev_data->client,
					MS_SENSORS_TP_P_CONVERSION_START +
						dev_data->res_index * 2,
					MS_SENSORS_TP_ADC_READ,
					delay, &p_adc);
	mutex_unlock(&dev_data->lock);
	if (ret)
		return ret;

	dt = (s32)t_adc - (prom[5] << 8);

	/* Actual temperature = 2000 + dT * TEMPSENS */
	temp = 2000 + (((s64)dt * prom[6]) >> 23);

	/* Second order temperature compensation */
	if (temp < 2000) {
		s64 tmp = (s64)temp - 2000;

		t2 = (3 * ((s64)dt * (s64)dt)) >> 33;
		off2 = (61 * tmp * tmp) >> 4;
		sens2 = (29 * tmp * tmp) >> 4;

		if (temp < -1500) {
			s64 tmp = (s64)temp + 1500;

			off2 += 17 * tmp * tmp;
			sens2 += 9 * tmp * tmp;
		}
	} else {
		t2 = (5 * ((s64)dt * (s64)dt)) >> 38;
		off2 = 0;
		sens2 = 0;
	}

	/* OFF = OFF_T1 + TCO * dT */
	off = (((s64)prom[2]) << 17) + ((((s64)prom[4]) * (s64)dt) >> 6);
	off -= off2;

	/* Sensitivity at actual temperature = SENS_T1 + TCS * dT */
	sens = (((s64)prom[1]) << 16) + (((s64)prom[3] * dt) >> 7);
	sens -= sens2;

	/* Temperature compensated pressure = D1 * SENS - OFF */
	*temperature = (temp - t2) * 10;
	*pressure = (u32)(((((s64)p_adc * sens) >> 21) - off) >> 15);

	return 0;
}
EXPORT_SYMBOL(ms_sensors_read_temp_and_pressure);

MODULE_DESCRIPTION("Measurement-Specialties common i2c driver");
MODULE_AUTHOR("William Markezana <william.markezana@meas-spec.com>");
MODULE_AUTHOR("Ludovic Tancerel <ludovic.tancerel@maplehightech.com>");
MODULE_LICENSE("GPL v2");

