162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * MAX1117/MAX1118/MAX1119 8-bit, dual-channel ADCs driver
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (c) 2017 Akinobu Mita <akinobu.mita@gmail.com>
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci * Datasheet: https://datasheets.maximintegrated.com/en/ds/MAX1117-MAX1119.pdf
862306a36Sopenharmony_ci *
962306a36Sopenharmony_ci * SPI interface connections
1062306a36Sopenharmony_ci *
1162306a36Sopenharmony_ci * SPI                MAXIM
1262306a36Sopenharmony_ci * Master  Direction  MAX1117/8/9
1362306a36Sopenharmony_ci * ------  ---------  -----------
1462306a36Sopenharmony_ci * nCS        -->     CNVST
1562306a36Sopenharmony_ci * SCK        -->     SCLK
1662306a36Sopenharmony_ci * MISO       <--     DOUT
1762306a36Sopenharmony_ci * ------  ---------  -----------
1862306a36Sopenharmony_ci */
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci#include <linux/module.h>
2162306a36Sopenharmony_ci#include <linux/mod_devicetable.h>
2262306a36Sopenharmony_ci#include <linux/spi/spi.h>
2362306a36Sopenharmony_ci#include <linux/iio/iio.h>
2462306a36Sopenharmony_ci#include <linux/iio/buffer.h>
2562306a36Sopenharmony_ci#include <linux/iio/triggered_buffer.h>
2662306a36Sopenharmony_ci#include <linux/iio/trigger_consumer.h>
2762306a36Sopenharmony_ci#include <linux/regulator/consumer.h>
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_cienum max1118_id {
3062306a36Sopenharmony_ci	max1117,
3162306a36Sopenharmony_ci	max1118,
3262306a36Sopenharmony_ci	max1119,
3362306a36Sopenharmony_ci};
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_cistruct max1118 {
3662306a36Sopenharmony_ci	struct spi_device *spi;
3762306a36Sopenharmony_ci	struct mutex lock;
3862306a36Sopenharmony_ci	struct regulator *reg;
3962306a36Sopenharmony_ci	/* Ensure natural alignment of buffer elements */
4062306a36Sopenharmony_ci	struct {
4162306a36Sopenharmony_ci		u8 channels[2];
4262306a36Sopenharmony_ci		s64 ts __aligned(8);
4362306a36Sopenharmony_ci	} scan;
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ci	u8 data __aligned(IIO_DMA_MINALIGN);
4662306a36Sopenharmony_ci};
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci#define MAX1118_CHANNEL(ch)						\
4962306a36Sopenharmony_ci	{								\
5062306a36Sopenharmony_ci		.type = IIO_VOLTAGE,					\
5162306a36Sopenharmony_ci		.indexed = 1,						\
5262306a36Sopenharmony_ci		.channel = (ch),					\
5362306a36Sopenharmony_ci		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\
5462306a36Sopenharmony_ci		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),	\
5562306a36Sopenharmony_ci		.scan_index = ch,					\
5662306a36Sopenharmony_ci		.scan_type = {						\
5762306a36Sopenharmony_ci			.sign = 'u',					\
5862306a36Sopenharmony_ci			.realbits = 8,					\
5962306a36Sopenharmony_ci			.storagebits = 8,				\
6062306a36Sopenharmony_ci		},							\
6162306a36Sopenharmony_ci	}
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_cistatic const struct iio_chan_spec max1118_channels[] = {
6462306a36Sopenharmony_ci	MAX1118_CHANNEL(0),
6562306a36Sopenharmony_ci	MAX1118_CHANNEL(1),
6662306a36Sopenharmony_ci	IIO_CHAN_SOFT_TIMESTAMP(2),
6762306a36Sopenharmony_ci};
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_cistatic int max1118_read(struct iio_dev *indio_dev, int channel)
7062306a36Sopenharmony_ci{
7162306a36Sopenharmony_ci	struct max1118 *adc = iio_priv(indio_dev);
7262306a36Sopenharmony_ci	struct spi_transfer xfers[] = {
7362306a36Sopenharmony_ci		/*
7462306a36Sopenharmony_ci		 * To select CH1 for conversion, CNVST pin must be brought high
7562306a36Sopenharmony_ci		 * and low for a second time.
7662306a36Sopenharmony_ci		 */
7762306a36Sopenharmony_ci		{
7862306a36Sopenharmony_ci			.len = 0,
7962306a36Sopenharmony_ci			.delay = {	/* > CNVST Low Time 100 ns */
8062306a36Sopenharmony_ci				.value = 1,
8162306a36Sopenharmony_ci				.unit = SPI_DELAY_UNIT_USECS
8262306a36Sopenharmony_ci			},
8362306a36Sopenharmony_ci			.cs_change = 1,
8462306a36Sopenharmony_ci		},
8562306a36Sopenharmony_ci		/*
8662306a36Sopenharmony_ci		 * The acquisition interval begins with the falling edge of
8762306a36Sopenharmony_ci		 * CNVST.  The total acquisition and conversion process takes
8862306a36Sopenharmony_ci		 * <7.5us.
8962306a36Sopenharmony_ci		 */
9062306a36Sopenharmony_ci		{
9162306a36Sopenharmony_ci			.len = 0,
9262306a36Sopenharmony_ci			.delay = {
9362306a36Sopenharmony_ci				.value = 8,
9462306a36Sopenharmony_ci				.unit = SPI_DELAY_UNIT_USECS
9562306a36Sopenharmony_ci			},
9662306a36Sopenharmony_ci		},
9762306a36Sopenharmony_ci		{
9862306a36Sopenharmony_ci			.rx_buf = &adc->data,
9962306a36Sopenharmony_ci			.len = 1,
10062306a36Sopenharmony_ci		},
10162306a36Sopenharmony_ci	};
10262306a36Sopenharmony_ci	int ret;
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ci	if (channel == 0)
10562306a36Sopenharmony_ci		ret = spi_sync_transfer(adc->spi, xfers + 1, 2);
10662306a36Sopenharmony_ci	else
10762306a36Sopenharmony_ci		ret = spi_sync_transfer(adc->spi, xfers, 3);
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_ci	if (ret)
11062306a36Sopenharmony_ci		return ret;
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_ci	return adc->data;
11362306a36Sopenharmony_ci}
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_cistatic int max1118_get_vref_mV(struct iio_dev *indio_dev)
11662306a36Sopenharmony_ci{
11762306a36Sopenharmony_ci	struct max1118 *adc = iio_priv(indio_dev);
11862306a36Sopenharmony_ci	const struct spi_device_id *id = spi_get_device_id(adc->spi);
11962306a36Sopenharmony_ci	int vref_uV;
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_ci	switch (id->driver_data) {
12262306a36Sopenharmony_ci	case max1117:
12362306a36Sopenharmony_ci		return 2048;
12462306a36Sopenharmony_ci	case max1119:
12562306a36Sopenharmony_ci		return 4096;
12662306a36Sopenharmony_ci	case max1118:
12762306a36Sopenharmony_ci		vref_uV = regulator_get_voltage(adc->reg);
12862306a36Sopenharmony_ci		if (vref_uV < 0)
12962306a36Sopenharmony_ci			return vref_uV;
13062306a36Sopenharmony_ci		return vref_uV / 1000;
13162306a36Sopenharmony_ci	}
13262306a36Sopenharmony_ci
13362306a36Sopenharmony_ci	return -ENODEV;
13462306a36Sopenharmony_ci}
13562306a36Sopenharmony_ci
13662306a36Sopenharmony_cistatic int max1118_read_raw(struct iio_dev *indio_dev,
13762306a36Sopenharmony_ci			struct iio_chan_spec const *chan,
13862306a36Sopenharmony_ci			int *val, int *val2, long mask)
13962306a36Sopenharmony_ci{
14062306a36Sopenharmony_ci	struct max1118 *adc = iio_priv(indio_dev);
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_ci	switch (mask) {
14362306a36Sopenharmony_ci	case IIO_CHAN_INFO_RAW:
14462306a36Sopenharmony_ci		mutex_lock(&adc->lock);
14562306a36Sopenharmony_ci		*val = max1118_read(indio_dev, chan->channel);
14662306a36Sopenharmony_ci		mutex_unlock(&adc->lock);
14762306a36Sopenharmony_ci		if (*val < 0)
14862306a36Sopenharmony_ci			return *val;
14962306a36Sopenharmony_ci
15062306a36Sopenharmony_ci		return IIO_VAL_INT;
15162306a36Sopenharmony_ci	case IIO_CHAN_INFO_SCALE:
15262306a36Sopenharmony_ci		*val = max1118_get_vref_mV(indio_dev);
15362306a36Sopenharmony_ci		if (*val < 0)
15462306a36Sopenharmony_ci			return *val;
15562306a36Sopenharmony_ci		*val2 = 8;
15662306a36Sopenharmony_ci
15762306a36Sopenharmony_ci		return IIO_VAL_FRACTIONAL_LOG2;
15862306a36Sopenharmony_ci	}
15962306a36Sopenharmony_ci
16062306a36Sopenharmony_ci	return -EINVAL;
16162306a36Sopenharmony_ci}
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_cistatic const struct iio_info max1118_info = {
16462306a36Sopenharmony_ci	.read_raw = max1118_read_raw,
16562306a36Sopenharmony_ci};
16662306a36Sopenharmony_ci
16762306a36Sopenharmony_cistatic irqreturn_t max1118_trigger_handler(int irq, void *p)
16862306a36Sopenharmony_ci{
16962306a36Sopenharmony_ci	struct iio_poll_func *pf = p;
17062306a36Sopenharmony_ci	struct iio_dev *indio_dev = pf->indio_dev;
17162306a36Sopenharmony_ci	struct max1118 *adc = iio_priv(indio_dev);
17262306a36Sopenharmony_ci	int scan_index;
17362306a36Sopenharmony_ci	int i = 0;
17462306a36Sopenharmony_ci
17562306a36Sopenharmony_ci	mutex_lock(&adc->lock);
17662306a36Sopenharmony_ci
17762306a36Sopenharmony_ci	for_each_set_bit(scan_index, indio_dev->active_scan_mask,
17862306a36Sopenharmony_ci			indio_dev->masklength) {
17962306a36Sopenharmony_ci		const struct iio_chan_spec *scan_chan =
18062306a36Sopenharmony_ci				&indio_dev->channels[scan_index];
18162306a36Sopenharmony_ci		int ret = max1118_read(indio_dev, scan_chan->channel);
18262306a36Sopenharmony_ci
18362306a36Sopenharmony_ci		if (ret < 0) {
18462306a36Sopenharmony_ci			dev_warn(&adc->spi->dev,
18562306a36Sopenharmony_ci				"failed to get conversion data\n");
18662306a36Sopenharmony_ci			goto out;
18762306a36Sopenharmony_ci		}
18862306a36Sopenharmony_ci
18962306a36Sopenharmony_ci		adc->scan.channels[i] = ret;
19062306a36Sopenharmony_ci		i++;
19162306a36Sopenharmony_ci	}
19262306a36Sopenharmony_ci	iio_push_to_buffers_with_timestamp(indio_dev, &adc->scan,
19362306a36Sopenharmony_ci					   iio_get_time_ns(indio_dev));
19462306a36Sopenharmony_ciout:
19562306a36Sopenharmony_ci	mutex_unlock(&adc->lock);
19662306a36Sopenharmony_ci
19762306a36Sopenharmony_ci	iio_trigger_notify_done(indio_dev->trig);
19862306a36Sopenharmony_ci
19962306a36Sopenharmony_ci	return IRQ_HANDLED;
20062306a36Sopenharmony_ci}
20162306a36Sopenharmony_ci
20262306a36Sopenharmony_cistatic void max1118_reg_disable(void *reg)
20362306a36Sopenharmony_ci{
20462306a36Sopenharmony_ci	regulator_disable(reg);
20562306a36Sopenharmony_ci}
20662306a36Sopenharmony_ci
20762306a36Sopenharmony_cistatic int max1118_probe(struct spi_device *spi)
20862306a36Sopenharmony_ci{
20962306a36Sopenharmony_ci	struct iio_dev *indio_dev;
21062306a36Sopenharmony_ci	struct max1118 *adc;
21162306a36Sopenharmony_ci	const struct spi_device_id *id = spi_get_device_id(spi);
21262306a36Sopenharmony_ci	int ret;
21362306a36Sopenharmony_ci
21462306a36Sopenharmony_ci	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adc));
21562306a36Sopenharmony_ci	if (!indio_dev)
21662306a36Sopenharmony_ci		return -ENOMEM;
21762306a36Sopenharmony_ci
21862306a36Sopenharmony_ci	adc = iio_priv(indio_dev);
21962306a36Sopenharmony_ci	adc->spi = spi;
22062306a36Sopenharmony_ci	mutex_init(&adc->lock);
22162306a36Sopenharmony_ci
22262306a36Sopenharmony_ci	if (id->driver_data == max1118) {
22362306a36Sopenharmony_ci		adc->reg = devm_regulator_get(&spi->dev, "vref");
22462306a36Sopenharmony_ci		if (IS_ERR(adc->reg))
22562306a36Sopenharmony_ci			return dev_err_probe(&spi->dev, PTR_ERR(adc->reg),
22662306a36Sopenharmony_ci					     "failed to get vref regulator\n");
22762306a36Sopenharmony_ci		ret = regulator_enable(adc->reg);
22862306a36Sopenharmony_ci		if (ret)
22962306a36Sopenharmony_ci			return ret;
23062306a36Sopenharmony_ci
23162306a36Sopenharmony_ci		ret = devm_add_action_or_reset(&spi->dev, max1118_reg_disable,
23262306a36Sopenharmony_ci					       adc->reg);
23362306a36Sopenharmony_ci		if (ret)
23462306a36Sopenharmony_ci			return ret;
23562306a36Sopenharmony_ci
23662306a36Sopenharmony_ci	}
23762306a36Sopenharmony_ci
23862306a36Sopenharmony_ci	indio_dev->name = spi_get_device_id(spi)->name;
23962306a36Sopenharmony_ci	indio_dev->info = &max1118_info;
24062306a36Sopenharmony_ci	indio_dev->modes = INDIO_DIRECT_MODE;
24162306a36Sopenharmony_ci	indio_dev->channels = max1118_channels;
24262306a36Sopenharmony_ci	indio_dev->num_channels = ARRAY_SIZE(max1118_channels);
24362306a36Sopenharmony_ci
24462306a36Sopenharmony_ci	/*
24562306a36Sopenharmony_ci	 * To reinitiate a conversion on CH0, it is necessary to allow for a
24662306a36Sopenharmony_ci	 * conversion to be complete and all of the data to be read out.  Once
24762306a36Sopenharmony_ci	 * a conversion has been completed, the MAX1117/MAX1118/MAX1119 will go
24862306a36Sopenharmony_ci	 * into AutoShutdown mode until the next conversion is initiated.
24962306a36Sopenharmony_ci	 */
25062306a36Sopenharmony_ci	max1118_read(indio_dev, 0);
25162306a36Sopenharmony_ci
25262306a36Sopenharmony_ci	ret = devm_iio_triggered_buffer_setup(&spi->dev, indio_dev, NULL,
25362306a36Sopenharmony_ci					      max1118_trigger_handler, NULL);
25462306a36Sopenharmony_ci	if (ret)
25562306a36Sopenharmony_ci		return ret;
25662306a36Sopenharmony_ci
25762306a36Sopenharmony_ci	return devm_iio_device_register(&spi->dev, indio_dev);
25862306a36Sopenharmony_ci}
25962306a36Sopenharmony_ci
26062306a36Sopenharmony_cistatic const struct spi_device_id max1118_id[] = {
26162306a36Sopenharmony_ci	{ "max1117", max1117 },
26262306a36Sopenharmony_ci	{ "max1118", max1118 },
26362306a36Sopenharmony_ci	{ "max1119", max1119 },
26462306a36Sopenharmony_ci	{}
26562306a36Sopenharmony_ci};
26662306a36Sopenharmony_ciMODULE_DEVICE_TABLE(spi, max1118_id);
26762306a36Sopenharmony_ci
26862306a36Sopenharmony_cistatic const struct of_device_id max1118_dt_ids[] = {
26962306a36Sopenharmony_ci	{ .compatible = "maxim,max1117" },
27062306a36Sopenharmony_ci	{ .compatible = "maxim,max1118" },
27162306a36Sopenharmony_ci	{ .compatible = "maxim,max1119" },
27262306a36Sopenharmony_ci	{},
27362306a36Sopenharmony_ci};
27462306a36Sopenharmony_ciMODULE_DEVICE_TABLE(of, max1118_dt_ids);
27562306a36Sopenharmony_ci
27662306a36Sopenharmony_cistatic struct spi_driver max1118_spi_driver = {
27762306a36Sopenharmony_ci	.driver = {
27862306a36Sopenharmony_ci		.name = "max1118",
27962306a36Sopenharmony_ci		.of_match_table = max1118_dt_ids,
28062306a36Sopenharmony_ci	},
28162306a36Sopenharmony_ci	.probe = max1118_probe,
28262306a36Sopenharmony_ci	.id_table = max1118_id,
28362306a36Sopenharmony_ci};
28462306a36Sopenharmony_cimodule_spi_driver(max1118_spi_driver);
28562306a36Sopenharmony_ci
28662306a36Sopenharmony_ciMODULE_AUTHOR("Akinobu Mita <akinobu.mita@gmail.com>");
28762306a36Sopenharmony_ciMODULE_DESCRIPTION("MAXIM MAX1117/MAX1118/MAX1119 ADCs driver");
28862306a36Sopenharmony_ciMODULE_LICENSE("GPL v2");
289