// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2016 Golden Delicious Comp. GmbH&Co. KG
 *	Nikolaus Schaller <hns@goldelico.com>
 */

#include <linux/i2c.h>
#include <linux/iio/iio.h>
#include "tsc2007.h"

struct tsc2007_iio {
	struct tsc2007 *ts;
};

#define TSC2007_CHAN_IIO(_chan, _name, _type, _chan_info) \
{ \
	.datasheet_name = _name, \
	.type = _type, \
	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |	\
			BIT(_chan_info), \
	.indexed = 1, \
	.channel = _chan, \
}

static const struct iio_chan_spec tsc2007_iio_channel[] = {
	TSC2007_CHAN_IIO(0, "x", IIO_VOLTAGE, IIO_CHAN_INFO_RAW),
	TSC2007_CHAN_IIO(1, "y", IIO_VOLTAGE, IIO_CHAN_INFO_RAW),
	TSC2007_CHAN_IIO(2, "z1", IIO_VOLTAGE, IIO_CHAN_INFO_RAW),
	TSC2007_CHAN_IIO(3, "z2", IIO_VOLTAGE, IIO_CHAN_INFO_RAW),
	TSC2007_CHAN_IIO(4, "adc", IIO_VOLTAGE, IIO_CHAN_INFO_RAW),
	TSC2007_CHAN_IIO(5, "rt", IIO_VOLTAGE, IIO_CHAN_INFO_RAW), /* Ohms? */
	TSC2007_CHAN_IIO(6, "pen", IIO_PRESSURE, IIO_CHAN_INFO_RAW),
	TSC2007_CHAN_IIO(7, "temp0", IIO_TEMP, IIO_CHAN_INFO_RAW),
	TSC2007_CHAN_IIO(8, "temp1", IIO_TEMP, IIO_CHAN_INFO_RAW),
};

static int tsc2007_read_raw(struct iio_dev *indio_dev,
			    struct iio_chan_spec const *chan,
			    int *val, int *val2, long mask)
{
	struct tsc2007_iio *iio = iio_priv(indio_dev);
	struct tsc2007 *tsc = iio->ts;
	int adc_chan = chan->channel;
	int ret = 0;

	if (adc_chan >= ARRAY_SIZE(tsc2007_iio_channel))
		return -EINVAL;

	if (mask != IIO_CHAN_INFO_RAW)
		return -EINVAL;

	mutex_lock(&tsc->mlock);

	switch (chan->channel) {
	case 0:
		*val = tsc2007_xfer(tsc, READ_X);
		break;
	case 1:
		*val = tsc2007_xfer(tsc, READ_Y);
		break;
	case 2:
		*val = tsc2007_xfer(tsc, READ_Z1);
		break;
	case 3:
		*val = tsc2007_xfer(tsc, READ_Z2);
		break;
	case 4:
		*val = tsc2007_xfer(tsc, (ADC_ON_12BIT | TSC2007_MEASURE_AUX));
		break;
	case 5: {
		struct ts_event tc;

		tc.x = tsc2007_xfer(tsc, READ_X);
		tc.z1 = tsc2007_xfer(tsc, READ_Z1);
		tc.z2 = tsc2007_xfer(tsc, READ_Z2);
		*val = tsc2007_calculate_resistance(tsc, &tc);
		break;
	}
	case 6:
		*val = tsc2007_is_pen_down(tsc);
		break;
	case 7:
		*val = tsc2007_xfer(tsc,
				    (ADC_ON_12BIT | TSC2007_MEASURE_TEMP0));
		break;
	case 8:
		*val = tsc2007_xfer(tsc,
				    (ADC_ON_12BIT | TSC2007_MEASURE_TEMP1));
		break;
	}

	/* Prepare for next touch reading - power down ADC, enable PENIRQ */
	tsc2007_xfer(tsc, PWRDOWN);

	mutex_unlock(&tsc->mlock);

	ret = IIO_VAL_INT;

	return ret;
}

static const struct iio_info tsc2007_iio_info = {
	.read_raw = tsc2007_read_raw,
};

int tsc2007_iio_configure(struct tsc2007 *ts)
{
	struct iio_dev *indio_dev;
	struct tsc2007_iio *iio;
	int error;

	indio_dev = devm_iio_device_alloc(&ts->client->dev, sizeof(*iio));
	if (!indio_dev) {
		dev_err(&ts->client->dev, "iio_device_alloc failed\n");
		return -ENOMEM;
	}

	iio = iio_priv(indio_dev);
	iio->ts = ts;

	indio_dev->name = "tsc2007";
	indio_dev->dev.parent = &ts->client->dev;
	indio_dev->info = &tsc2007_iio_info;
	indio_dev->modes = INDIO_DIRECT_MODE;
	indio_dev->channels = tsc2007_iio_channel;
	indio_dev->num_channels = ARRAY_SIZE(tsc2007_iio_channel);

	error = devm_iio_device_register(&ts->client->dev, indio_dev);
	if (error) {
		dev_err(&ts->client->dev,
			"iio_device_register() failed: %d\n", error);
		return error;
	}

	return 0;
}
