// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 2012 Invensense, Inc.
*/

#include <linux/module.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/delay.h>
#include <linux/sysfs.h>
#include <linux/jiffies.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/poll.h>
#include <linux/math64.h>

#include <linux/iio/common/inv_sensors_timestamp.h>

#include "inv_mpu_iio.h"

static int inv_reset_fifo(struct iio_dev *indio_dev)
{
	int result;
	struct inv_mpu6050_state  *st = iio_priv(indio_dev);

	/* disable fifo and reenable it */
	inv_mpu6050_prepare_fifo(st, false);
	result = inv_mpu6050_prepare_fifo(st, true);
	if (result)
		goto reset_fifo_fail;

	return 0;

reset_fifo_fail:
	dev_err(regmap_get_device(st->map), "reset fifo failed %d\n", result);
	return regmap_update_bits(st->map, st->reg->int_enable,
			INV_MPU6050_BIT_DATA_RDY_EN, INV_MPU6050_BIT_DATA_RDY_EN);
}

/*
 * inv_mpu6050_read_fifo() - Transfer data from hardware FIFO to KFIFO.
 */
irqreturn_t inv_mpu6050_read_fifo(int irq, void *p)
{
	struct iio_poll_func *pf = p;
	struct iio_dev *indio_dev = pf->indio_dev;
	struct inv_mpu6050_state *st = iio_priv(indio_dev);
	size_t bytes_per_datum;
	int result;
	u16 fifo_count;
	u32 fifo_period;
	s64 timestamp;
	u8 data[INV_MPU6050_OUTPUT_DATA_SIZE];
	size_t i, nb;

	mutex_lock(&st->lock);

	if (!(st->chip_config.accl_fifo_enable |
		st->chip_config.gyro_fifo_enable |
		st->chip_config.magn_fifo_enable))
		goto end_session;
	bytes_per_datum = 0;
	if (st->chip_config.accl_fifo_enable)
		bytes_per_datum += INV_MPU6050_BYTES_PER_3AXIS_SENSOR;

	if (st->chip_config.gyro_fifo_enable)
		bytes_per_datum += INV_MPU6050_BYTES_PER_3AXIS_SENSOR;

	if (st->chip_config.temp_fifo_enable)
		bytes_per_datum += INV_MPU6050_BYTES_PER_TEMP_SENSOR;

	if (st->chip_config.magn_fifo_enable)
		bytes_per_datum += INV_MPU9X50_BYTES_MAGN;

	/*
	 * read fifo_count register to know how many bytes are inside the FIFO
	 * right now
	 */
	result = regmap_bulk_read(st->map, st->reg->fifo_count_h,
				  st->data, INV_MPU6050_FIFO_COUNT_BYTE);
	if (result)
		goto end_session;
	fifo_count = be16_to_cpup((__be16 *)&st->data[0]);

	/*
	 * Handle fifo overflow by resetting fifo.
	 * Reset if there is only 3 data set free remaining to mitigate
	 * possible delay between reading fifo count and fifo data.
	 */
	nb = 3 * bytes_per_datum;
	if (fifo_count >= st->hw->fifo_size - nb) {
		dev_warn(regmap_get_device(st->map), "fifo overflow reset\n");
		goto flush_fifo;
	}

	/* compute and process only all complete datum */
	nb = fifo_count / bytes_per_datum;
	fifo_count = nb * bytes_per_datum;
	if (nb == 0)
		goto end_session;
	/* Each FIFO data contains all sensors, so same number for FIFO and sensor data */
	fifo_period = NSEC_PER_SEC / INV_MPU6050_DIVIDER_TO_FIFO_RATE(st->chip_config.divider);
	inv_sensors_timestamp_interrupt(&st->timestamp, 1, pf->timestamp);
	inv_sensors_timestamp_apply_odr(&st->timestamp, fifo_period, 1, 0);

	/* clear internal data buffer for avoiding kernel data leak */
	memset(data, 0, sizeof(data));

	/* read all data once and process every samples */
	result = regmap_noinc_read(st->map, st->reg->fifo_r_w, st->data, fifo_count);
	if (result)
		goto flush_fifo;
	for (i = 0; i < nb; ++i) {
		/* skip first samples if needed */
		if (st->skip_samples) {
			st->skip_samples--;
			continue;
		}
		memcpy(data, &st->data[i * bytes_per_datum], bytes_per_datum);
		timestamp = inv_sensors_timestamp_pop(&st->timestamp);
		iio_push_to_buffers_with_timestamp(indio_dev, data, timestamp);
	}

end_session:
	mutex_unlock(&st->lock);
	iio_trigger_notify_done(indio_dev->trig);

	return IRQ_HANDLED;

flush_fifo:
	/* Flush HW and SW FIFOs. */
	inv_reset_fifo(indio_dev);
	mutex_unlock(&st->lock);
	iio_trigger_notify_done(indio_dev->trig);

	return IRQ_HANDLED;
}
