// SPDX-License-Identifier: GPL-2.0

/*
 * System Control and Management Interface(SCMI) based IIO sensor driver
 *
 * Copyright (C) 2021 Google LLC
 */

#include <linux/delay.h>
#include <linux/err.h>
#include <linux/iio/buffer.h>
#include <linux/iio/iio.h>
#include <linux/iio/kfifo_buf.h>
#include <linux/iio/sysfs.h>
#include <linux/kernel.h>
#include <linux/kthread.h>
#include <linux/module.h>
#include <linux/scmi_protocol.h>
#include <linux/time.h>
#include <linux/types.h>

#define SCMI_IIO_NUM_OF_AXIS 3

struct scmi_iio_priv {
	const struct scmi_sensor_proto_ops *sensor_ops;
	struct scmi_protocol_handle *ph;
	const struct scmi_sensor_info *sensor_info;
	struct iio_dev *indio_dev;
	/* adding one additional channel for timestamp */
	s64 iio_buf[SCMI_IIO_NUM_OF_AXIS + 1];
	struct notifier_block sensor_update_nb;
	u32 *freq_avail;
};

static int scmi_iio_sensor_update_cb(struct notifier_block *nb,
				     unsigned long event, void *data)
{
	struct scmi_sensor_update_report *sensor_update = data;
	struct iio_dev *scmi_iio_dev;
	struct scmi_iio_priv *sensor;
	s8 tstamp_scale;
	u64 time, time_ns;
	int i;

	if (sensor_update->readings_count == 0)
		return NOTIFY_DONE;

	sensor = container_of(nb, struct scmi_iio_priv, sensor_update_nb);

	for (i = 0; i < sensor_update->readings_count; i++)
		sensor->iio_buf[i] = sensor_update->readings[i].value;

	if (!sensor->sensor_info->timestamped) {
		time_ns = ktime_to_ns(sensor_update->timestamp);
	} else {
		/*
		 *  All the axes are supposed to have the same value for timestamp.
		 *  We are just using the values from the Axis 0 here.
		 */
		time = sensor_update->readings[0].timestamp;

		/*
		 *  Timestamp returned by SCMI is in seconds and is equal to
		 *  time * power-of-10 multiplier(tstamp_scale) seconds.
		 *  Converting the timestamp to nanoseconds below.
		 */
		tstamp_scale = sensor->sensor_info->tstamp_scale +
			       const_ilog2(NSEC_PER_SEC) / const_ilog2(10);
		if (tstamp_scale < 0) {
			do_div(time, int_pow(10, abs(tstamp_scale)));
			time_ns = time;
		} else {
			time_ns = time * int_pow(10, tstamp_scale);
		}
	}

	scmi_iio_dev = sensor->indio_dev;
	iio_push_to_buffers_with_timestamp(scmi_iio_dev, sensor->iio_buf,
					   time_ns);
	return NOTIFY_OK;
}

static int scmi_iio_buffer_preenable(struct iio_dev *iio_dev)
{
	struct scmi_iio_priv *sensor = iio_priv(iio_dev);
	u32 sensor_config = 0;
	int err;

	if (sensor->sensor_info->timestamped)
		sensor_config |= FIELD_PREP(SCMI_SENS_CFG_TSTAMP_ENABLED_MASK,
					    SCMI_SENS_CFG_TSTAMP_ENABLE);

	sensor_config |= FIELD_PREP(SCMI_SENS_CFG_SENSOR_ENABLED_MASK,
				    SCMI_SENS_CFG_SENSOR_ENABLE);
	err = sensor->sensor_ops->config_set(sensor->ph,
					     sensor->sensor_info->id,
					     sensor_config);
	if (err)
		dev_err(&iio_dev->dev, "Error in enabling sensor %s err %d",
			sensor->sensor_info->name, err);

	return err;
}

static int scmi_iio_buffer_postdisable(struct iio_dev *iio_dev)
{
	struct scmi_iio_priv *sensor = iio_priv(iio_dev);
	u32 sensor_config = 0;
	int err;

	sensor_config |= FIELD_PREP(SCMI_SENS_CFG_SENSOR_ENABLED_MASK,
				    SCMI_SENS_CFG_SENSOR_DISABLE);
	err = sensor->sensor_ops->config_set(sensor->ph,
					     sensor->sensor_info->id,
					     sensor_config);
	if (err) {
		dev_err(&iio_dev->dev,
			"Error in disabling sensor %s with err %d",
			sensor->sensor_info->name, err);
	}

	return err;
}

static const struct iio_buffer_setup_ops scmi_iio_buffer_ops = {
	.preenable = scmi_iio_buffer_preenable,
	.postdisable = scmi_iio_buffer_postdisable,
};

static int scmi_iio_set_odr_val(struct iio_dev *iio_dev, int val, int val2)
{
	struct scmi_iio_priv *sensor = iio_priv(iio_dev);
	const unsigned long UHZ_PER_HZ = 1000000UL;
	u64 sec, mult, uHz, sf;
	u32 sensor_config;
	char buf[32];

	int err = sensor->sensor_ops->config_get(sensor->ph,
						 sensor->sensor_info->id,
						 &sensor_config);
	if (err) {
		dev_err(&iio_dev->dev,
			"Error in getting sensor config for sensor %s err %d",
			sensor->sensor_info->name, err);
		return err;
	}

	uHz = val * UHZ_PER_HZ + val2;

	/*
	 * The seconds field in the sensor interval in SCMI is 16 bits long
	 * Therefore seconds  = 1/Hz <= 0xFFFF. As floating point calculations are
	 * discouraged in the kernel driver code, to calculate the scale factor (sf)
	 * (1* 1000000 * sf)/uHz <= 0xFFFF. Therefore, sf <= (uHz * 0xFFFF)/1000000
	 * To calculate the multiplier,we convert the sf into char string  and
	 * count the number of characters
	 */
	sf = (u64)uHz * 0xFFFF;
	do_div(sf,  UHZ_PER_HZ);
	mult = scnprintf(buf, sizeof(buf), "%llu", sf) - 1;

	sec = int_pow(10, mult) * UHZ_PER_HZ;
	do_div(sec, uHz);
	if (sec == 0) {
		dev_err(&iio_dev->dev,
			"Trying to set invalid sensor update value for sensor %s",
			sensor->sensor_info->name);
		return -EINVAL;
	}

	sensor_config &= ~SCMI_SENS_CFG_UPDATE_SECS_MASK;
	sensor_config |= FIELD_PREP(SCMI_SENS_CFG_UPDATE_SECS_MASK, sec);
	sensor_config &= ~SCMI_SENS_CFG_UPDATE_EXP_MASK;
	sensor_config |= FIELD_PREP(SCMI_SENS_CFG_UPDATE_EXP_MASK, -mult);

	if (sensor->sensor_info->timestamped) {
		sensor_config &= ~SCMI_SENS_CFG_TSTAMP_ENABLED_MASK;
		sensor_config |= FIELD_PREP(SCMI_SENS_CFG_TSTAMP_ENABLED_MASK,
					    SCMI_SENS_CFG_TSTAMP_ENABLE);
	}

	sensor_config &= ~SCMI_SENS_CFG_ROUND_MASK;
	sensor_config |=
		FIELD_PREP(SCMI_SENS_CFG_ROUND_MASK, SCMI_SENS_CFG_ROUND_AUTO);

	err = sensor->sensor_ops->config_set(sensor->ph,
					     sensor->sensor_info->id,
					     sensor_config);
	if (err)
		dev_err(&iio_dev->dev,
			"Error in setting sensor update interval for sensor %s value %u err %d",
			sensor->sensor_info->name, sensor_config, err);

	return err;
}

static int scmi_iio_write_raw(struct iio_dev *iio_dev,
			      struct iio_chan_spec const *chan, int val,
			      int val2, long mask)
{
	int err;

	switch (mask) {
	case IIO_CHAN_INFO_SAMP_FREQ:
		mutex_lock(&iio_dev->mlock);
		err = scmi_iio_set_odr_val(iio_dev, val, val2);
		mutex_unlock(&iio_dev->mlock);
		return err;
	default:
		return -EINVAL;
	}
}

static int scmi_iio_read_avail(struct iio_dev *iio_dev,
			       struct iio_chan_spec const *chan,
			       const int **vals, int *type, int *length,
			       long mask)
{
	struct scmi_iio_priv *sensor = iio_priv(iio_dev);

	switch (mask) {
	case IIO_CHAN_INFO_SAMP_FREQ:
		*vals = sensor->freq_avail;
		*type = IIO_VAL_INT_PLUS_MICRO;
		*length = sensor->sensor_info->intervals.count * 2;
		if (sensor->sensor_info->intervals.segmented)
			return IIO_AVAIL_RANGE;
		else
			return IIO_AVAIL_LIST;
	default:
		return -EINVAL;
	}
}

static void convert_ns_to_freq(u64 interval_ns, u64 *hz, u64 *uhz)
{
	u64 rem, freq;

	freq = NSEC_PER_SEC;
	rem = do_div(freq, interval_ns);
	*hz = freq;
	*uhz = rem * 1000000UL;
	do_div(*uhz, interval_ns);
}

static int scmi_iio_get_odr_val(struct iio_dev *iio_dev, int *val, int *val2)
{
	u64 sensor_update_interval, sensor_interval_mult, hz, uhz;
	struct scmi_iio_priv *sensor = iio_priv(iio_dev);
	u32 sensor_config;
	int mult;

	int err = sensor->sensor_ops->config_get(sensor->ph,
						 sensor->sensor_info->id,
						 &sensor_config);
	if (err) {
		dev_err(&iio_dev->dev,
			"Error in getting sensor config for sensor %s err %d",
			sensor->sensor_info->name, err);
		return err;
	}

	sensor_update_interval =
		SCMI_SENS_CFG_GET_UPDATE_SECS(sensor_config) * NSEC_PER_SEC;

	mult = SCMI_SENS_CFG_GET_UPDATE_EXP(sensor_config);
	if (mult < 0) {
		sensor_interval_mult = int_pow(10, abs(mult));
		do_div(sensor_update_interval, sensor_interval_mult);
	} else {
		sensor_interval_mult = int_pow(10, mult);
		sensor_update_interval =
			sensor_update_interval * sensor_interval_mult;
	}

	convert_ns_to_freq(sensor_update_interval, &hz, &uhz);
	*val = hz;
	*val2 = uhz;
	return 0;
}

static int scmi_iio_read_raw(struct iio_dev *iio_dev,
			     struct iio_chan_spec const *ch, int *val,
			     int *val2, long mask)
{
	struct scmi_iio_priv *sensor = iio_priv(iio_dev);
	s8 scale;
	int ret;

	switch (mask) {
	case IIO_CHAN_INFO_SCALE:
		scale = sensor->sensor_info->axis[ch->scan_index].scale;
		if (scale < 0) {
			*val = 1;
			*val2 = int_pow(10, abs(scale));
			return IIO_VAL_FRACTIONAL;
		}
		*val = int_pow(10, scale);
		return IIO_VAL_INT;
	case IIO_CHAN_INFO_SAMP_FREQ:
		ret = scmi_iio_get_odr_val(iio_dev, val, val2);
		return ret ? ret : IIO_VAL_INT_PLUS_MICRO;
	default:
		return -EINVAL;
	}
}

static const struct iio_info scmi_iio_info = {
	.read_raw = scmi_iio_read_raw,
	.read_avail = scmi_iio_read_avail,
	.write_raw = scmi_iio_write_raw,
};

static ssize_t scmi_iio_get_raw_available(struct iio_dev *iio_dev,
					  uintptr_t private,
					  const struct iio_chan_spec *chan,
					  char *buf)
{
	struct scmi_iio_priv *sensor = iio_priv(iio_dev);
	u64 resolution, rem;
	s64 min_range, max_range;
	s8 exponent, scale;
	int len = 0;

	/*
	 * All the axes are supposed to have the same value for range and resolution.
	 * We are just using the values from the Axis 0 here.
	 */
	if (sensor->sensor_info->axis[0].extended_attrs) {
		min_range = sensor->sensor_info->axis[0].attrs.min_range;
		max_range = sensor->sensor_info->axis[0].attrs.max_range;
		resolution = sensor->sensor_info->axis[0].resolution;
		exponent = sensor->sensor_info->axis[0].exponent;
		scale = sensor->sensor_info->axis[0].scale;

		/*
		 * To provide the raw value for the resolution to the userspace,
		 * need to divide the resolution exponent by the sensor scale
		 */
		exponent = exponent - scale;
		if (exponent < 0) {
			rem = do_div(resolution,
				     int_pow(10, abs(exponent))
				     );
			len = scnprintf(buf, PAGE_SIZE,
					"[%lld %llu.%llu %lld]\n", min_range,
					resolution, rem, max_range);
		} else {
			resolution = resolution * int_pow(10, exponent);
			len = scnprintf(buf, PAGE_SIZE, "[%lld %llu %lld]\n",
					min_range, resolution, max_range);
		}
	}
	return len;
}

static const struct iio_chan_spec_ext_info scmi_iio_ext_info[] = {
	{
		.name = "raw_available",
		.read = scmi_iio_get_raw_available,
		.shared = IIO_SHARED_BY_TYPE,
	},
	{},
};

static void scmi_iio_set_timestamp_channel(struct iio_chan_spec *iio_chan,
					   int scan_index)
{
	iio_chan->type = IIO_TIMESTAMP;
	iio_chan->channel = -1;
	iio_chan->scan_index = scan_index;
	iio_chan->scan_type.sign = 'u';
	iio_chan->scan_type.realbits = 64;
	iio_chan->scan_type.storagebits = 64;
}

static void scmi_iio_set_data_channel(struct iio_chan_spec *iio_chan,
				      enum iio_chan_type type,
				      enum iio_modifier mod, int scan_index)
{
	iio_chan->type = type;
	iio_chan->modified = 1;
	iio_chan->channel2 = mod;
	iio_chan->info_mask_separate = BIT(IIO_CHAN_INFO_SCALE);
	iio_chan->info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ);
	iio_chan->info_mask_shared_by_type_available =
		BIT(IIO_CHAN_INFO_SAMP_FREQ);
	iio_chan->scan_index = scan_index;
	iio_chan->scan_type.sign = 's';
	iio_chan->scan_type.realbits = 64;
	iio_chan->scan_type.storagebits = 64;
	iio_chan->scan_type.endianness = IIO_LE;
	iio_chan->ext_info = scmi_iio_ext_info;
}

static int scmi_iio_get_chan_modifier(const char *name,
				      enum iio_modifier *modifier)
{
	char *pch, mod;

	if (!name)
		return -EINVAL;

	pch = strrchr(name, '_');
	if (!pch)
		return -EINVAL;

	mod = *(pch + 1);
	switch (mod) {
	case 'X':
		*modifier = IIO_MOD_X;
		return 0;
	case 'Y':
		*modifier = IIO_MOD_Y;
		return 0;
	case 'Z':
		*modifier = IIO_MOD_Z;
		return 0;
	default:
		return -EINVAL;
	}
}

static int scmi_iio_get_chan_type(u8 scmi_type, enum iio_chan_type *iio_type)
{
	switch (scmi_type) {
	case METERS_SEC_SQUARED:
		*iio_type = IIO_ACCEL;
		return 0;
	case RADIANS_SEC:
		*iio_type = IIO_ANGL_VEL;
		return 0;
	default:
		return -EINVAL;
	}
}

static u64 scmi_iio_convert_interval_to_ns(u32 val)
{
	u64 sensor_update_interval =
		SCMI_SENS_INTVL_GET_SECS(val) * NSEC_PER_SEC;
	u64 sensor_interval_mult;
	int mult;

	mult = SCMI_SENS_INTVL_GET_EXP(val);
	if (mult < 0) {
		sensor_interval_mult = int_pow(10, abs(mult));
		do_div(sensor_update_interval, sensor_interval_mult);
	} else {
		sensor_interval_mult = int_pow(10, mult);
		sensor_update_interval =
			sensor_update_interval * sensor_interval_mult;
	}
	return sensor_update_interval;
}

static int scmi_iio_set_sampling_freq_avail(struct iio_dev *iio_dev)
{
	u64 cur_interval_ns, low_interval_ns, high_interval_ns, step_size_ns,
		hz, uhz;
	unsigned int cur_interval, low_interval, high_interval, step_size;
	struct scmi_iio_priv *sensor = iio_priv(iio_dev);
	int i;

	sensor->freq_avail =
		devm_kzalloc(&iio_dev->dev,
			     sizeof(*sensor->freq_avail) *
				     (sensor->sensor_info->intervals.count * 2),
			     GFP_KERNEL);
	if (!sensor->freq_avail)
		return -ENOMEM;

	if (sensor->sensor_info->intervals.segmented) {
		low_interval = sensor->sensor_info->intervals
				       .desc[SCMI_SENS_INTVL_SEGMENT_LOW];
		low_interval_ns = scmi_iio_convert_interval_to_ns(low_interval);
		convert_ns_to_freq(low_interval_ns, &hz, &uhz);
		sensor->freq_avail[0] = hz;
		sensor->freq_avail[1] = uhz;

		step_size = sensor->sensor_info->intervals
				    .desc[SCMI_SENS_INTVL_SEGMENT_STEP];
		step_size_ns = scmi_iio_convert_interval_to_ns(step_size);
		convert_ns_to_freq(step_size_ns, &hz, &uhz);
		sensor->freq_avail[2] = hz;
		sensor->freq_avail[3] = uhz;

		high_interval = sensor->sensor_info->intervals
					.desc[SCMI_SENS_INTVL_SEGMENT_HIGH];
		high_interval_ns =
			scmi_iio_convert_interval_to_ns(high_interval);
		convert_ns_to_freq(high_interval_ns, &hz, &uhz);
		sensor->freq_avail[4] = hz;
		sensor->freq_avail[5] = uhz;
	} else {
		for (i = 0; i < sensor->sensor_info->intervals.count; i++) {
			cur_interval = sensor->sensor_info->intervals.desc[i];
			cur_interval_ns =
				scmi_iio_convert_interval_to_ns(cur_interval);
			convert_ns_to_freq(cur_interval_ns, &hz, &uhz);
			sensor->freq_avail[i * 2] = hz;
			sensor->freq_avail[i * 2 + 1] = uhz;
		}
	}
	return 0;
}

static struct iio_dev *
scmi_alloc_iiodev(struct scmi_device *sdev,
		  const struct scmi_sensor_proto_ops *ops,
		  struct scmi_protocol_handle *ph,
		  const struct scmi_sensor_info *sensor_info)
{
	struct iio_chan_spec *iio_channels;
	struct scmi_iio_priv *sensor;
	enum iio_modifier modifier;
	enum iio_chan_type type;
	struct iio_dev *iiodev;
	struct device *dev = &sdev->dev;
	const struct scmi_handle *handle = sdev->handle;
	int i, ret;

	iiodev = devm_iio_device_alloc(dev, sizeof(*sensor));
	if (!iiodev)
		return ERR_PTR(-ENOMEM);

	iiodev->modes = INDIO_DIRECT_MODE;
	sensor = iio_priv(iiodev);
	sensor->sensor_ops = ops;
	sensor->ph = ph;
	sensor->sensor_info = sensor_info;
	sensor->sensor_update_nb.notifier_call = scmi_iio_sensor_update_cb;
	sensor->indio_dev = iiodev;

	/* adding one additional channel for timestamp */
	iiodev->num_channels = sensor_info->num_axis + 1;
	iiodev->name = sensor_info->name;
	iiodev->info = &scmi_iio_info;

	iio_channels =
		devm_kzalloc(dev,
			     sizeof(*iio_channels) * (iiodev->num_channels),
			     GFP_KERNEL);
	if (!iio_channels)
		return ERR_PTR(-ENOMEM);

	ret = scmi_iio_set_sampling_freq_avail(iiodev);
	if (ret < 0)
		return ERR_PTR(ret);

	for (i = 0; i < sensor_info->num_axis; i++) {
		ret = scmi_iio_get_chan_type(sensor_info->axis[i].type, &type);
		if (ret < 0)
			return ERR_PTR(ret);

		ret = scmi_iio_get_chan_modifier(sensor_info->axis[i].name,
						 &modifier);
		if (ret < 0)
			return ERR_PTR(ret);

		scmi_iio_set_data_channel(&iio_channels[i], type, modifier,
					  sensor_info->axis[i].id);
	}

	ret = handle->notify_ops->devm_event_notifier_register(sdev,
				SCMI_PROTOCOL_SENSOR, SCMI_EVENT_SENSOR_UPDATE,
				&sensor->sensor_info->id,
				&sensor->sensor_update_nb);
	if (ret) {
		dev_err(&iiodev->dev,
			"Error in registering sensor update notifier for sensor %s err %d",
			sensor->sensor_info->name, ret);
		return ERR_PTR(ret);
	}

	scmi_iio_set_timestamp_channel(&iio_channels[i], i);
	iiodev->channels = iio_channels;
	return iiodev;
}

static int scmi_iio_dev_probe(struct scmi_device *sdev)
{
	const struct scmi_sensor_info *sensor_info;
	struct scmi_handle *handle = sdev->handle;
	const struct scmi_sensor_proto_ops *sensor_ops;
	struct scmi_protocol_handle *ph;
	struct device *dev = &sdev->dev;
	struct iio_dev *scmi_iio_dev;
	u16 nr_sensors;
	int err = -ENODEV, i;

	if (!handle)
		return -ENODEV;

	sensor_ops = handle->devm_protocol_get(sdev, SCMI_PROTOCOL_SENSOR, &ph);
	if (IS_ERR(sensor_ops)) {
		dev_err(dev, "SCMI device has no sensor interface\n");
		return PTR_ERR(sensor_ops);
	}

	nr_sensors = sensor_ops->count_get(ph);
	if (!nr_sensors) {
		dev_dbg(dev, "0 sensors found via SCMI bus\n");
		return -ENODEV;
	}

	for (i = 0; i < nr_sensors; i++) {
		sensor_info = sensor_ops->info_get(ph, i);
		if (!sensor_info) {
			dev_err(dev, "SCMI sensor %d has missing info\n", i);
			return -EINVAL;
		}

		/* This driver only supports 3-axis accel and gyro, skipping other sensors */
		if (sensor_info->num_axis != SCMI_IIO_NUM_OF_AXIS)
			continue;

		/* This driver only supports 3-axis accel and gyro, skipping other sensors */
		if (sensor_info->axis[0].type != METERS_SEC_SQUARED &&
		    sensor_info->axis[0].type != RADIANS_SEC)
			continue;

		scmi_iio_dev = scmi_alloc_iiodev(sdev, sensor_ops, ph,
						 sensor_info);
		if (IS_ERR(scmi_iio_dev)) {
			dev_err(dev,
				"failed to allocate IIO device for sensor %s: %ld\n",
				sensor_info->name, PTR_ERR(scmi_iio_dev));
			return PTR_ERR(scmi_iio_dev);
		}

		err = devm_iio_kfifo_buffer_setup(&scmi_iio_dev->dev,
						  scmi_iio_dev,
						  INDIO_BUFFER_SOFTWARE,
						  &scmi_iio_buffer_ops);
		if (err < 0) {
			dev_err(dev,
				"IIO buffer setup error at sensor %s: %d\n",
				sensor_info->name, err);
			return err;
		}

		err = devm_iio_device_register(dev, scmi_iio_dev);
		if (err) {
			dev_err(dev,
				"IIO device registration failed at sensor %s: %d\n",
				sensor_info->name, err);
			return err;
		}
	}
	return err;
}

static const struct scmi_device_id scmi_id_table[] = {
	{ SCMI_PROTOCOL_SENSOR, "iiodev" },
	{},
};

MODULE_DEVICE_TABLE(scmi, scmi_id_table);

static struct scmi_driver scmi_iiodev_driver = {
	.name = "scmi-sensor-iiodev",
	.probe = scmi_iio_dev_probe,
	.id_table = scmi_id_table,
};

module_scmi_driver(scmi_iiodev_driver);

MODULE_AUTHOR("Jyoti Bhayana <jbhayana@google.com>");
MODULE_DESCRIPTION("SCMI IIO Driver");
MODULE_LICENSE("GPL v2");
