// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * HX711: analog to digital converter for weight sensor module
 *
 * Copyright (c) 2016 Andreas Klinger <ak@it-klinger.de>
 */
#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/delay.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/buffer.h>
#include <linux/iio/trigger_consumer.h>
#include <linux/iio/triggered_buffer.h>
#include <linux/gpio/consumer.h>
#include <linux/regulator/consumer.h>

/* gain to pulse and scale conversion */
#define HX711_GAIN_MAX		3
#define HX711_RESET_GAIN	128

struct hx711_gain_to_scale {
	int			gain;
	int			gain_pulse;
	int			scale;
	int			channel;
};

/*
 * .scale depends on AVDD which in turn is known as soon as the regulator
 * is available
 * therefore we set .scale in hx711_probe()
 *
 * channel A in documentation is channel 0 in source code
 * channel B in documentation is channel 1 in source code
 */
static struct hx711_gain_to_scale hx711_gain_to_scale[HX711_GAIN_MAX] = {
	{ 128, 1, 0, 0 },
	{  32, 2, 0, 1 },
	{  64, 3, 0, 0 }
};

static int hx711_get_gain_to_pulse(int gain)
{
	int i;

	for (i = 0; i < HX711_GAIN_MAX; i++)
		if (hx711_gain_to_scale[i].gain == gain)
			return hx711_gain_to_scale[i].gain_pulse;
	return 1;
}

static int hx711_get_gain_to_scale(int gain)
{
	int i;

	for (i = 0; i < HX711_GAIN_MAX; i++)
		if (hx711_gain_to_scale[i].gain == gain)
			return hx711_gain_to_scale[i].scale;
	return 0;
}

static int hx711_get_scale_to_gain(int scale)
{
	int i;

	for (i = 0; i < HX711_GAIN_MAX; i++)
		if (hx711_gain_to_scale[i].scale == scale)
			return hx711_gain_to_scale[i].gain;
	return -EINVAL;
}

struct hx711_data {
	struct device		*dev;
	struct gpio_desc	*gpiod_pd_sck;
	struct gpio_desc	*gpiod_dout;
	int			gain_set;	/* gain set on device */
	int			gain_chan_a;	/* gain for channel A */
	struct mutex		lock;
	/*
	 * triggered buffer
	 * 2x32-bit channel + 64-bit naturally aligned timestamp
	 */
	u32			buffer[4] __aligned(8);
	/*
	 * delay after a rising edge on SCK until the data is ready DOUT
	 * this is dependent on the hx711 where the datasheet tells a
	 * maximum value of 100 ns
	 * but also on potential parasitic capacities on the wiring
	 */
	u32			data_ready_delay_ns;
	u32			clock_frequency;
};

static int hx711_cycle(struct hx711_data *hx711_data)
{
	unsigned long flags;

	/*
	 * if preempted for more then 60us while PD_SCK is high:
	 * hx711 is going in reset
	 * ==> measuring is false
	 */
	local_irq_save(flags);
	gpiod_set_value(hx711_data->gpiod_pd_sck, 1);

	/*
	 * wait until DOUT is ready
	 * it turned out that parasitic capacities are extending the time
	 * until DOUT has reached it's value
	 */
	ndelay(hx711_data->data_ready_delay_ns);

	/*
	 * here we are not waiting for 0.2 us as suggested by the datasheet,
	 * because the oscilloscope showed in a test scenario
	 * at least 1.15 us for PD_SCK high (T3 in datasheet)
	 * and 0.56 us for PD_SCK low on TI Sitara with 800 MHz
	 */
	gpiod_set_value(hx711_data->gpiod_pd_sck, 0);
	local_irq_restore(flags);

	/*
	 * make it a square wave for addressing cases with capacitance on
	 * PC_SCK
	 */
	ndelay(hx711_data->data_ready_delay_ns);

	/* sample as late as possible */
	return gpiod_get_value(hx711_data->gpiod_dout);
}

static int hx711_read(struct hx711_data *hx711_data)
{
	int i, ret;
	int value = 0;
	int val = gpiod_get_value(hx711_data->gpiod_dout);

	/* we double check if it's really down */
	if (val)
		return -EIO;

	for (i = 0; i < 24; i++) {
		value <<= 1;
		ret = hx711_cycle(hx711_data);
		if (ret)
			value++;
	}

	value ^= 0x800000;

	for (i = 0; i < hx711_get_gain_to_pulse(hx711_data->gain_set); i++)
		hx711_cycle(hx711_data);

	return value;
}

static int hx711_wait_for_ready(struct hx711_data *hx711_data)
{
	int i, val;

	/*
	 * in some rare cases the reset takes quite a long time
	 * especially when the channel is changed.
	 * Allow up to one second for it
	 */
	for (i = 0; i < 100; i++) {
		val = gpiod_get_value(hx711_data->gpiod_dout);
		if (!val)
			break;
		/* sleep at least 10 ms */
		msleep(10);
	}
	if (val)
		return -EIO;

	return 0;
}

static int hx711_reset(struct hx711_data *hx711_data)
{
	int val = hx711_wait_for_ready(hx711_data);

	if (val) {
		/*
		 * an examination with the oszilloscope indicated
		 * that the first value read after the reset is not stable
		 * if we reset too short;
		 * the shorter the reset cycle
		 * the less reliable the first value after reset is;
		 * there were no problems encountered with a value
		 * of 10 ms or higher
		 */
		gpiod_set_value(hx711_data->gpiod_pd_sck, 1);
		msleep(10);
		gpiod_set_value(hx711_data->gpiod_pd_sck, 0);

		val = hx711_wait_for_ready(hx711_data);

		/* after a reset the gain is 128 */
		hx711_data->gain_set = HX711_RESET_GAIN;
	}

	return val;
}

static int hx711_set_gain_for_channel(struct hx711_data *hx711_data, int chan)
{
	int ret;

	if (chan == 0) {
		if (hx711_data->gain_set == 32) {
			hx711_data->gain_set = hx711_data->gain_chan_a;

			ret = hx711_read(hx711_data);
			if (ret < 0)
				return ret;

			ret = hx711_wait_for_ready(hx711_data);
			if (ret)
				return ret;
		}
	} else {
		if (hx711_data->gain_set != 32) {
			hx711_data->gain_set = 32;

			ret = hx711_read(hx711_data);
			if (ret < 0)
				return ret;

			ret = hx711_wait_for_ready(hx711_data);
			if (ret)
				return ret;
		}
	}

	return 0;
}

static int hx711_reset_read(struct hx711_data *hx711_data, int chan)
{
	int ret;
	int val;

	/*
	 * hx711_reset() must be called from here
	 * because it could be calling hx711_read() by itself
	 */
	if (hx711_reset(hx711_data)) {
		dev_err(hx711_data->dev, "reset failed!");
		return -EIO;
	}

	ret = hx711_set_gain_for_channel(hx711_data, chan);
	if (ret < 0)
		return ret;

	val = hx711_read(hx711_data);

	return val;
}

static int hx711_read_raw(struct iio_dev *indio_dev,
				const struct iio_chan_spec *chan,
				int *val, int *val2, long mask)
{
	struct hx711_data *hx711_data = iio_priv(indio_dev);

	switch (mask) {
	case IIO_CHAN_INFO_RAW:
		mutex_lock(&hx711_data->lock);

		*val = hx711_reset_read(hx711_data, chan->channel);

		mutex_unlock(&hx711_data->lock);

		if (*val < 0)
			return *val;
		return IIO_VAL_INT;
	case IIO_CHAN_INFO_SCALE:
		*val = 0;
		mutex_lock(&hx711_data->lock);

		*val2 = hx711_get_gain_to_scale(hx711_data->gain_set);

		mutex_unlock(&hx711_data->lock);

		return IIO_VAL_INT_PLUS_NANO;
	default:
		return -EINVAL;
	}
}

static int hx711_write_raw(struct iio_dev *indio_dev,
				struct iio_chan_spec const *chan,
				int val,
				int val2,
				long mask)
{
	struct hx711_data *hx711_data = iio_priv(indio_dev);
	int ret;
	int gain;

	switch (mask) {
	case IIO_CHAN_INFO_SCALE:
		/*
		 * a scale greater than 1 mV per LSB is not possible
		 * with the HX711, therefore val must be 0
		 */
		if (val != 0)
			return -EINVAL;

		mutex_lock(&hx711_data->lock);

		gain = hx711_get_scale_to_gain(val2);
		if (gain < 0) {
			mutex_unlock(&hx711_data->lock);
			return gain;
		}

		if (gain != hx711_data->gain_set) {
			hx711_data->gain_set = gain;
			if (gain != 32)
				hx711_data->gain_chan_a = gain;

			ret = hx711_read(hx711_data);
			if (ret < 0) {
				mutex_unlock(&hx711_data->lock);
				return ret;
			}
		}

		mutex_unlock(&hx711_data->lock);
		return 0;
	default:
		return -EINVAL;
	}

	return 0;
}

static int hx711_write_raw_get_fmt(struct iio_dev *indio_dev,
		struct iio_chan_spec const *chan,
		long mask)
{
	return IIO_VAL_INT_PLUS_NANO;
}

static irqreturn_t hx711_trigger(int irq, void *p)
{
	struct iio_poll_func *pf = p;
	struct iio_dev *indio_dev = pf->indio_dev;
	struct hx711_data *hx711_data = iio_priv(indio_dev);
	int i, j = 0;

	mutex_lock(&hx711_data->lock);

	memset(hx711_data->buffer, 0, sizeof(hx711_data->buffer));

	iio_for_each_active_channel(indio_dev, i) {
		hx711_data->buffer[j] = hx711_reset_read(hx711_data,
					indio_dev->channels[i].channel);
		j++;
	}

	iio_push_to_buffers_with_timestamp(indio_dev, hx711_data->buffer,
							pf->timestamp);

	mutex_unlock(&hx711_data->lock);

	iio_trigger_notify_done(indio_dev->trig);

	return IRQ_HANDLED;
}

static ssize_t hx711_scale_available_show(struct device *dev,
				struct device_attribute *attr,
				char *buf)
{
	struct iio_dev_attr *iio_attr = to_iio_dev_attr(attr);
	int channel = iio_attr->address;
	int i, len = 0;

	for (i = 0; i < HX711_GAIN_MAX; i++)
		if (hx711_gain_to_scale[i].channel == channel)
			len += sprintf(buf + len, "0.%09d ",
					hx711_gain_to_scale[i].scale);

	len += sprintf(buf + len, "\n");

	return len;
}

static IIO_DEVICE_ATTR(in_voltage0_scale_available, S_IRUGO,
	hx711_scale_available_show, NULL, 0);

static IIO_DEVICE_ATTR(in_voltage1_scale_available, S_IRUGO,
	hx711_scale_available_show, NULL, 1);

static struct attribute *hx711_attributes[] = {
	&iio_dev_attr_in_voltage0_scale_available.dev_attr.attr,
	&iio_dev_attr_in_voltage1_scale_available.dev_attr.attr,
	NULL,
};

static const struct attribute_group hx711_attribute_group = {
	.attrs = hx711_attributes,
};

static const struct iio_info hx711_iio_info = {
	.read_raw		= hx711_read_raw,
	.write_raw		= hx711_write_raw,
	.write_raw_get_fmt	= hx711_write_raw_get_fmt,
	.attrs			= &hx711_attribute_group,
};

static const struct iio_chan_spec hx711_chan_spec[] = {
	{
		.type = IIO_VOLTAGE,
		.channel = 0,
		.indexed = 1,
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
		.scan_index = 0,
		.scan_type = {
			.sign = 'u',
			.realbits = 24,
			.storagebits = 32,
			.endianness = IIO_CPU,
		},
	},
	{
		.type = IIO_VOLTAGE,
		.channel = 1,
		.indexed = 1,
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
		.scan_index = 1,
		.scan_type = {
			.sign = 'u',
			.realbits = 24,
			.storagebits = 32,
			.endianness = IIO_CPU,
		},
	},
	IIO_CHAN_SOFT_TIMESTAMP(2),
};

static int hx711_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct hx711_data *hx711_data;
	struct iio_dev *indio_dev;
	int ret;
	int i;

	indio_dev = devm_iio_device_alloc(dev, sizeof(struct hx711_data));
	if (!indio_dev)
		return dev_err_probe(dev, -ENOMEM, "failed to allocate IIO device\n");

	hx711_data = iio_priv(indio_dev);
	hx711_data->dev = dev;

	mutex_init(&hx711_data->lock);

	/*
	 * PD_SCK stands for power down and serial clock input of HX711
	 * in the driver it is an output
	 */
	hx711_data->gpiod_pd_sck = devm_gpiod_get(dev, "sck", GPIOD_OUT_LOW);
	if (IS_ERR(hx711_data->gpiod_pd_sck))
		return dev_err_probe(dev, PTR_ERR(hx711_data->gpiod_pd_sck),
				     "failed to get sck-gpiod\n");

	/*
	 * DOUT stands for serial data output of HX711
	 * for the driver it is an input
	 */
	hx711_data->gpiod_dout = devm_gpiod_get(dev, "dout", GPIOD_IN);
	if (IS_ERR(hx711_data->gpiod_dout))
		return dev_err_probe(dev, PTR_ERR(hx711_data->gpiod_dout),
				     "failed to get dout-gpiod\n");

	ret = devm_regulator_get_enable_read_voltage(dev, "avdd");
	if (ret < 0)
		return ret;

	/*
	 * with
	 * full scale differential input range: AVDD / GAIN
	 * full scale output data: 2^24
	 * we can say:
	 *     AVDD / GAIN = 2^24
	 * therefore:
	 *     1 LSB = AVDD / GAIN / 2^24
	 * AVDD is in uV, but we need 10^-9 mV
	 * approximately to fit into a 32 bit number:
	 * 1 LSB = (AVDD * 100) / GAIN / 1678 [10^-9 mV]
	 */

	/* we need 10^-9 mV */
	ret *= 100;

	for (i = 0; i < HX711_GAIN_MAX; i++)
		hx711_gain_to_scale[i].scale =
			ret / hx711_gain_to_scale[i].gain / 1678;

	hx711_data->gain_set = 128;
	hx711_data->gain_chan_a = 128;

	hx711_data->clock_frequency = 400000;
	ret = device_property_read_u32(&pdev->dev, "clock-frequency",
					&hx711_data->clock_frequency);

	/*
	 * datasheet says the high level of PD_SCK has a maximum duration
	 * of 50 microseconds
	 */
	if (hx711_data->clock_frequency < 20000) {
		dev_warn(dev, "clock-frequency too low - assuming 400 kHz\n");
		hx711_data->clock_frequency = 400000;
	}

	hx711_data->data_ready_delay_ns =
				1000000000 / hx711_data->clock_frequency;

	indio_dev->name = "hx711";
	indio_dev->info = &hx711_iio_info;
	indio_dev->modes = INDIO_DIRECT_MODE;
	indio_dev->channels = hx711_chan_spec;
	indio_dev->num_channels = ARRAY_SIZE(hx711_chan_spec);

	ret = devm_iio_triggered_buffer_setup(dev, indio_dev,
					      iio_pollfunc_store_time,
					      hx711_trigger, NULL);
	if (ret < 0)
		return dev_err_probe(dev, ret,
				     "setup of iio triggered buffer failed\n");

	ret = devm_iio_device_register(dev, indio_dev);
	if (ret < 0)
		return dev_err_probe(dev, ret, "Couldn't register the device\n");

	return 0;
}

static const struct of_device_id of_hx711_match[] = {
	{ .compatible = "avia,hx711", },
	{ }
};

MODULE_DEVICE_TABLE(of, of_hx711_match);

static struct platform_driver hx711_driver = {
	.probe		= hx711_probe,
	.driver		= {
		.name		= "hx711-gpio",
		.of_match_table	= of_hx711_match,
	},
};

module_platform_driver(hx711_driver);

MODULE_AUTHOR("Andreas Klinger <ak@it-klinger.de>");
MODULE_DESCRIPTION("HX711 bitbanging driver - ADC for weight cells");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:hx711-gpio");

