162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci /*
362306a36Sopenharmony_ci  * iio/adc/max1027.c
462306a36Sopenharmony_ci  * Copyright (C) 2014 Philippe Reynes
562306a36Sopenharmony_ci  *
662306a36Sopenharmony_ci  * based on linux/drivers/iio/ad7923.c
762306a36Sopenharmony_ci  * Copyright 2011 Analog Devices Inc (from AD7923 Driver)
862306a36Sopenharmony_ci  * Copyright 2012 CS Systemes d'Information
962306a36Sopenharmony_ci  *
1062306a36Sopenharmony_ci  * max1027.c
1162306a36Sopenharmony_ci  *
1262306a36Sopenharmony_ci  * Partial support for max1027 and similar chips.
1362306a36Sopenharmony_ci  */
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci#include <linux/kernel.h>
1662306a36Sopenharmony_ci#include <linux/module.h>
1762306a36Sopenharmony_ci#include <linux/mod_devicetable.h>
1862306a36Sopenharmony_ci#include <linux/spi/spi.h>
1962306a36Sopenharmony_ci#include <linux/delay.h>
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci#include <linux/iio/iio.h>
2262306a36Sopenharmony_ci#include <linux/iio/buffer.h>
2362306a36Sopenharmony_ci#include <linux/iio/trigger.h>
2462306a36Sopenharmony_ci#include <linux/iio/trigger_consumer.h>
2562306a36Sopenharmony_ci#include <linux/iio/triggered_buffer.h>
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci#define MAX1027_CONV_REG  BIT(7)
2862306a36Sopenharmony_ci#define MAX1027_SETUP_REG BIT(6)
2962306a36Sopenharmony_ci#define MAX1027_AVG_REG   BIT(5)
3062306a36Sopenharmony_ci#define MAX1027_RST_REG   BIT(4)
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci/* conversion register */
3362306a36Sopenharmony_ci#define MAX1027_TEMP      BIT(0)
3462306a36Sopenharmony_ci#define MAX1027_SCAN_0_N  (0x00 << 1)
3562306a36Sopenharmony_ci#define MAX1027_SCAN_N_M  (0x01 << 1)
3662306a36Sopenharmony_ci#define MAX1027_SCAN_N    (0x02 << 1)
3762306a36Sopenharmony_ci#define MAX1027_NOSCAN    (0x03 << 1)
3862306a36Sopenharmony_ci#define MAX1027_CHAN(n)   ((n) << 3)
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ci/* setup register */
4162306a36Sopenharmony_ci#define MAX1027_UNIPOLAR  0x02
4262306a36Sopenharmony_ci#define MAX1027_BIPOLAR   0x03
4362306a36Sopenharmony_ci#define MAX1027_REF_MODE0 (0x00 << 2)
4462306a36Sopenharmony_ci#define MAX1027_REF_MODE1 (0x01 << 2)
4562306a36Sopenharmony_ci#define MAX1027_REF_MODE2 (0x02 << 2)
4662306a36Sopenharmony_ci#define MAX1027_REF_MODE3 (0x03 << 2)
4762306a36Sopenharmony_ci#define MAX1027_CKS_MODE0 (0x00 << 4)
4862306a36Sopenharmony_ci#define MAX1027_CKS_MODE1 (0x01 << 4)
4962306a36Sopenharmony_ci#define MAX1027_CKS_MODE2 (0x02 << 4)
5062306a36Sopenharmony_ci#define MAX1027_CKS_MODE3 (0x03 << 4)
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci/* averaging register */
5362306a36Sopenharmony_ci#define MAX1027_NSCAN_4   0x00
5462306a36Sopenharmony_ci#define MAX1027_NSCAN_8   0x01
5562306a36Sopenharmony_ci#define MAX1027_NSCAN_12  0x02
5662306a36Sopenharmony_ci#define MAX1027_NSCAN_16  0x03
5762306a36Sopenharmony_ci#define MAX1027_NAVG_4    (0x00 << 2)
5862306a36Sopenharmony_ci#define MAX1027_NAVG_8    (0x01 << 2)
5962306a36Sopenharmony_ci#define MAX1027_NAVG_16   (0x02 << 2)
6062306a36Sopenharmony_ci#define MAX1027_NAVG_32   (0x03 << 2)
6162306a36Sopenharmony_ci#define MAX1027_AVG_EN    BIT(4)
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_ci/* Device can achieve 300ksps so we assume a 3.33us conversion delay */
6462306a36Sopenharmony_ci#define MAX1027_CONVERSION_UDELAY 4
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_cienum max1027_id {
6762306a36Sopenharmony_ci	max1027,
6862306a36Sopenharmony_ci	max1029,
6962306a36Sopenharmony_ci	max1031,
7062306a36Sopenharmony_ci	max1227,
7162306a36Sopenharmony_ci	max1229,
7262306a36Sopenharmony_ci	max1231,
7362306a36Sopenharmony_ci};
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_cistatic const struct spi_device_id max1027_id[] = {
7662306a36Sopenharmony_ci	{"max1027", max1027},
7762306a36Sopenharmony_ci	{"max1029", max1029},
7862306a36Sopenharmony_ci	{"max1031", max1031},
7962306a36Sopenharmony_ci	{"max1227", max1227},
8062306a36Sopenharmony_ci	{"max1229", max1229},
8162306a36Sopenharmony_ci	{"max1231", max1231},
8262306a36Sopenharmony_ci	{}
8362306a36Sopenharmony_ci};
8462306a36Sopenharmony_ciMODULE_DEVICE_TABLE(spi, max1027_id);
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_cistatic const struct of_device_id max1027_adc_dt_ids[] = {
8762306a36Sopenharmony_ci	{ .compatible = "maxim,max1027" },
8862306a36Sopenharmony_ci	{ .compatible = "maxim,max1029" },
8962306a36Sopenharmony_ci	{ .compatible = "maxim,max1031" },
9062306a36Sopenharmony_ci	{ .compatible = "maxim,max1227" },
9162306a36Sopenharmony_ci	{ .compatible = "maxim,max1229" },
9262306a36Sopenharmony_ci	{ .compatible = "maxim,max1231" },
9362306a36Sopenharmony_ci	{},
9462306a36Sopenharmony_ci};
9562306a36Sopenharmony_ciMODULE_DEVICE_TABLE(of, max1027_adc_dt_ids);
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_ci#define MAX1027_V_CHAN(index, depth)					\
9862306a36Sopenharmony_ci	{								\
9962306a36Sopenharmony_ci		.type = IIO_VOLTAGE,					\
10062306a36Sopenharmony_ci		.indexed = 1,						\
10162306a36Sopenharmony_ci		.channel = index,					\
10262306a36Sopenharmony_ci		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\
10362306a36Sopenharmony_ci		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),	\
10462306a36Sopenharmony_ci		.scan_index = index + 1,				\
10562306a36Sopenharmony_ci		.scan_type = {						\
10662306a36Sopenharmony_ci			.sign = 'u',					\
10762306a36Sopenharmony_ci			.realbits = depth,				\
10862306a36Sopenharmony_ci			.storagebits = 16,				\
10962306a36Sopenharmony_ci			.shift = (depth == 10) ? 2 : 0,			\
11062306a36Sopenharmony_ci			.endianness = IIO_BE,				\
11162306a36Sopenharmony_ci		},							\
11262306a36Sopenharmony_ci	}
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_ci#define MAX1027_T_CHAN							\
11562306a36Sopenharmony_ci	{								\
11662306a36Sopenharmony_ci		.type = IIO_TEMP,					\
11762306a36Sopenharmony_ci		.channel = 0,						\
11862306a36Sopenharmony_ci		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\
11962306a36Sopenharmony_ci		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),	\
12062306a36Sopenharmony_ci		.scan_index = 0,					\
12162306a36Sopenharmony_ci		.scan_type = {						\
12262306a36Sopenharmony_ci			.sign = 'u',					\
12362306a36Sopenharmony_ci			.realbits = 12,					\
12462306a36Sopenharmony_ci			.storagebits = 16,				\
12562306a36Sopenharmony_ci			.endianness = IIO_BE,				\
12662306a36Sopenharmony_ci		},							\
12762306a36Sopenharmony_ci	}
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_ci#define MAX1X27_CHANNELS(depth)			\
13062306a36Sopenharmony_ci	MAX1027_T_CHAN,				\
13162306a36Sopenharmony_ci	MAX1027_V_CHAN(0, depth),		\
13262306a36Sopenharmony_ci	MAX1027_V_CHAN(1, depth),		\
13362306a36Sopenharmony_ci	MAX1027_V_CHAN(2, depth),		\
13462306a36Sopenharmony_ci	MAX1027_V_CHAN(3, depth),		\
13562306a36Sopenharmony_ci	MAX1027_V_CHAN(4, depth),		\
13662306a36Sopenharmony_ci	MAX1027_V_CHAN(5, depth),		\
13762306a36Sopenharmony_ci	MAX1027_V_CHAN(6, depth),		\
13862306a36Sopenharmony_ci	MAX1027_V_CHAN(7, depth)
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ci#define MAX1X29_CHANNELS(depth)			\
14162306a36Sopenharmony_ci	MAX1X27_CHANNELS(depth),		\
14262306a36Sopenharmony_ci	MAX1027_V_CHAN(8, depth),		\
14362306a36Sopenharmony_ci	MAX1027_V_CHAN(9, depth),		\
14462306a36Sopenharmony_ci	MAX1027_V_CHAN(10, depth),		\
14562306a36Sopenharmony_ci	MAX1027_V_CHAN(11, depth)
14662306a36Sopenharmony_ci
14762306a36Sopenharmony_ci#define MAX1X31_CHANNELS(depth)			\
14862306a36Sopenharmony_ci	MAX1X29_CHANNELS(depth),		\
14962306a36Sopenharmony_ci	MAX1027_V_CHAN(12, depth),		\
15062306a36Sopenharmony_ci	MAX1027_V_CHAN(13, depth),		\
15162306a36Sopenharmony_ci	MAX1027_V_CHAN(14, depth),		\
15262306a36Sopenharmony_ci	MAX1027_V_CHAN(15, depth)
15362306a36Sopenharmony_ci
15462306a36Sopenharmony_cistatic const struct iio_chan_spec max1027_channels[] = {
15562306a36Sopenharmony_ci	MAX1X27_CHANNELS(10),
15662306a36Sopenharmony_ci};
15762306a36Sopenharmony_ci
15862306a36Sopenharmony_cistatic const struct iio_chan_spec max1029_channels[] = {
15962306a36Sopenharmony_ci	MAX1X29_CHANNELS(10),
16062306a36Sopenharmony_ci};
16162306a36Sopenharmony_ci
16262306a36Sopenharmony_cistatic const struct iio_chan_spec max1031_channels[] = {
16362306a36Sopenharmony_ci	MAX1X31_CHANNELS(10),
16462306a36Sopenharmony_ci};
16562306a36Sopenharmony_ci
16662306a36Sopenharmony_cistatic const struct iio_chan_spec max1227_channels[] = {
16762306a36Sopenharmony_ci	MAX1X27_CHANNELS(12),
16862306a36Sopenharmony_ci};
16962306a36Sopenharmony_ci
17062306a36Sopenharmony_cistatic const struct iio_chan_spec max1229_channels[] = {
17162306a36Sopenharmony_ci	MAX1X29_CHANNELS(12),
17262306a36Sopenharmony_ci};
17362306a36Sopenharmony_ci
17462306a36Sopenharmony_cistatic const struct iio_chan_spec max1231_channels[] = {
17562306a36Sopenharmony_ci	MAX1X31_CHANNELS(12),
17662306a36Sopenharmony_ci};
17762306a36Sopenharmony_ci
17862306a36Sopenharmony_ci/*
17962306a36Sopenharmony_ci * These devices are able to scan from 0 to N, N being the highest voltage
18062306a36Sopenharmony_ci * channel requested by the user. The temperature can be included or not,
18162306a36Sopenharmony_ci * but cannot be retrieved alone. Based on the below
18262306a36Sopenharmony_ci * ->available_scan_masks, the core will select the most appropriate
18362306a36Sopenharmony_ci * ->active_scan_mask and the "minimum" number of channels will be
18462306a36Sopenharmony_ci * scanned and pushed to the buffers.
18562306a36Sopenharmony_ci *
18662306a36Sopenharmony_ci * For example, if the user wants channels 1, 4 and 5, all channels from
18762306a36Sopenharmony_ci * 0 to 5 will be scanned and pushed to the IIO buffers. The core will then
18862306a36Sopenharmony_ci * filter out the unneeded samples based on the ->active_scan_mask that has
18962306a36Sopenharmony_ci * been selected and only channels 1, 4 and 5 will be available to the user
19062306a36Sopenharmony_ci * in the shared buffer.
19162306a36Sopenharmony_ci */
19262306a36Sopenharmony_ci#define MAX1X27_SCAN_MASK_TEMP BIT(0)
19362306a36Sopenharmony_ci
19462306a36Sopenharmony_ci#define MAX1X27_SCAN_MASKS(temp)					\
19562306a36Sopenharmony_ci	GENMASK(1, 1 - (temp)), GENMASK(2, 1 - (temp)),			\
19662306a36Sopenharmony_ci	GENMASK(3, 1 - (temp)), GENMASK(4, 1 - (temp)),			\
19762306a36Sopenharmony_ci	GENMASK(5, 1 - (temp)), GENMASK(6, 1 - (temp)),			\
19862306a36Sopenharmony_ci	GENMASK(7, 1 - (temp)), GENMASK(8, 1 - (temp))
19962306a36Sopenharmony_ci
20062306a36Sopenharmony_ci#define MAX1X29_SCAN_MASKS(temp)					\
20162306a36Sopenharmony_ci	MAX1X27_SCAN_MASKS(temp),					\
20262306a36Sopenharmony_ci	GENMASK(9, 1 - (temp)), GENMASK(10, 1 - (temp)),		\
20362306a36Sopenharmony_ci	GENMASK(11, 1 - (temp)), GENMASK(12, 1 - (temp))
20462306a36Sopenharmony_ci
20562306a36Sopenharmony_ci#define MAX1X31_SCAN_MASKS(temp)					\
20662306a36Sopenharmony_ci	MAX1X29_SCAN_MASKS(temp),					\
20762306a36Sopenharmony_ci	GENMASK(13, 1 - (temp)), GENMASK(14, 1 - (temp)),		\
20862306a36Sopenharmony_ci	GENMASK(15, 1 - (temp)), GENMASK(16, 1 - (temp))
20962306a36Sopenharmony_ci
21062306a36Sopenharmony_cistatic const unsigned long max1027_available_scan_masks[] = {
21162306a36Sopenharmony_ci	MAX1X27_SCAN_MASKS(0),
21262306a36Sopenharmony_ci	MAX1X27_SCAN_MASKS(1),
21362306a36Sopenharmony_ci	0x00000000,
21462306a36Sopenharmony_ci};
21562306a36Sopenharmony_ci
21662306a36Sopenharmony_cistatic const unsigned long max1029_available_scan_masks[] = {
21762306a36Sopenharmony_ci	MAX1X29_SCAN_MASKS(0),
21862306a36Sopenharmony_ci	MAX1X29_SCAN_MASKS(1),
21962306a36Sopenharmony_ci	0x00000000,
22062306a36Sopenharmony_ci};
22162306a36Sopenharmony_ci
22262306a36Sopenharmony_cistatic const unsigned long max1031_available_scan_masks[] = {
22362306a36Sopenharmony_ci	MAX1X31_SCAN_MASKS(0),
22462306a36Sopenharmony_ci	MAX1X31_SCAN_MASKS(1),
22562306a36Sopenharmony_ci	0x00000000,
22662306a36Sopenharmony_ci};
22762306a36Sopenharmony_ci
22862306a36Sopenharmony_cistruct max1027_chip_info {
22962306a36Sopenharmony_ci	const struct iio_chan_spec *channels;
23062306a36Sopenharmony_ci	unsigned int num_channels;
23162306a36Sopenharmony_ci	const unsigned long *available_scan_masks;
23262306a36Sopenharmony_ci};
23362306a36Sopenharmony_ci
23462306a36Sopenharmony_cistatic const struct max1027_chip_info max1027_chip_info_tbl[] = {
23562306a36Sopenharmony_ci	[max1027] = {
23662306a36Sopenharmony_ci		.channels = max1027_channels,
23762306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(max1027_channels),
23862306a36Sopenharmony_ci		.available_scan_masks = max1027_available_scan_masks,
23962306a36Sopenharmony_ci	},
24062306a36Sopenharmony_ci	[max1029] = {
24162306a36Sopenharmony_ci		.channels = max1029_channels,
24262306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(max1029_channels),
24362306a36Sopenharmony_ci		.available_scan_masks = max1029_available_scan_masks,
24462306a36Sopenharmony_ci	},
24562306a36Sopenharmony_ci	[max1031] = {
24662306a36Sopenharmony_ci		.channels = max1031_channels,
24762306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(max1031_channels),
24862306a36Sopenharmony_ci		.available_scan_masks = max1031_available_scan_masks,
24962306a36Sopenharmony_ci	},
25062306a36Sopenharmony_ci	[max1227] = {
25162306a36Sopenharmony_ci		.channels = max1227_channels,
25262306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(max1227_channels),
25362306a36Sopenharmony_ci		.available_scan_masks = max1027_available_scan_masks,
25462306a36Sopenharmony_ci	},
25562306a36Sopenharmony_ci	[max1229] = {
25662306a36Sopenharmony_ci		.channels = max1229_channels,
25762306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(max1229_channels),
25862306a36Sopenharmony_ci		.available_scan_masks = max1029_available_scan_masks,
25962306a36Sopenharmony_ci	},
26062306a36Sopenharmony_ci	[max1231] = {
26162306a36Sopenharmony_ci		.channels = max1231_channels,
26262306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(max1231_channels),
26362306a36Sopenharmony_ci		.available_scan_masks = max1031_available_scan_masks,
26462306a36Sopenharmony_ci	},
26562306a36Sopenharmony_ci};
26662306a36Sopenharmony_ci
26762306a36Sopenharmony_cistruct max1027_state {
26862306a36Sopenharmony_ci	const struct max1027_chip_info	*info;
26962306a36Sopenharmony_ci	struct spi_device		*spi;
27062306a36Sopenharmony_ci	struct iio_trigger		*trig;
27162306a36Sopenharmony_ci	__be16				*buffer;
27262306a36Sopenharmony_ci	struct mutex			lock;
27362306a36Sopenharmony_ci	struct completion		complete;
27462306a36Sopenharmony_ci
27562306a36Sopenharmony_ci	u8				reg __aligned(IIO_DMA_MINALIGN);
27662306a36Sopenharmony_ci};
27762306a36Sopenharmony_ci
27862306a36Sopenharmony_cistatic int max1027_wait_eoc(struct iio_dev *indio_dev)
27962306a36Sopenharmony_ci{
28062306a36Sopenharmony_ci	struct max1027_state *st = iio_priv(indio_dev);
28162306a36Sopenharmony_ci	unsigned int conversion_time = MAX1027_CONVERSION_UDELAY;
28262306a36Sopenharmony_ci	int ret;
28362306a36Sopenharmony_ci
28462306a36Sopenharmony_ci	if (st->spi->irq) {
28562306a36Sopenharmony_ci		ret = wait_for_completion_timeout(&st->complete,
28662306a36Sopenharmony_ci						  msecs_to_jiffies(1000));
28762306a36Sopenharmony_ci		reinit_completion(&st->complete);
28862306a36Sopenharmony_ci		if (!ret)
28962306a36Sopenharmony_ci			return -ETIMEDOUT;
29062306a36Sopenharmony_ci	} else {
29162306a36Sopenharmony_ci		if (indio_dev->active_scan_mask)
29262306a36Sopenharmony_ci			conversion_time *= hweight32(*indio_dev->active_scan_mask);
29362306a36Sopenharmony_ci
29462306a36Sopenharmony_ci		usleep_range(conversion_time, conversion_time * 2);
29562306a36Sopenharmony_ci	}
29662306a36Sopenharmony_ci
29762306a36Sopenharmony_ci	return 0;
29862306a36Sopenharmony_ci}
29962306a36Sopenharmony_ci
30062306a36Sopenharmony_ci/* Scan from chan 0 to the highest requested channel. Include temperature on demand. */
30162306a36Sopenharmony_cistatic int max1027_configure_chans_and_start(struct iio_dev *indio_dev)
30262306a36Sopenharmony_ci{
30362306a36Sopenharmony_ci	struct max1027_state *st = iio_priv(indio_dev);
30462306a36Sopenharmony_ci
30562306a36Sopenharmony_ci	st->reg = MAX1027_CONV_REG | MAX1027_SCAN_0_N;
30662306a36Sopenharmony_ci	st->reg |= MAX1027_CHAN(fls(*indio_dev->active_scan_mask) - 2);
30762306a36Sopenharmony_ci	if (*indio_dev->active_scan_mask & MAX1X27_SCAN_MASK_TEMP)
30862306a36Sopenharmony_ci		st->reg |= MAX1027_TEMP;
30962306a36Sopenharmony_ci
31062306a36Sopenharmony_ci	return spi_write(st->spi, &st->reg, 1);
31162306a36Sopenharmony_ci}
31262306a36Sopenharmony_ci
31362306a36Sopenharmony_cistatic int max1027_enable_trigger(struct iio_dev *indio_dev, bool enable)
31462306a36Sopenharmony_ci{
31562306a36Sopenharmony_ci	struct max1027_state *st = iio_priv(indio_dev);
31662306a36Sopenharmony_ci
31762306a36Sopenharmony_ci	st->reg = MAX1027_SETUP_REG | MAX1027_REF_MODE2;
31862306a36Sopenharmony_ci
31962306a36Sopenharmony_ci	/*
32062306a36Sopenharmony_ci	 * Start acquisition on:
32162306a36Sopenharmony_ci	 * MODE0: external hardware trigger wired to the cnvst input pin
32262306a36Sopenharmony_ci	 * MODE2: conversion register write
32362306a36Sopenharmony_ci	 */
32462306a36Sopenharmony_ci	if (enable)
32562306a36Sopenharmony_ci		st->reg |= MAX1027_CKS_MODE0;
32662306a36Sopenharmony_ci	else
32762306a36Sopenharmony_ci		st->reg |= MAX1027_CKS_MODE2;
32862306a36Sopenharmony_ci
32962306a36Sopenharmony_ci	return spi_write(st->spi, &st->reg, 1);
33062306a36Sopenharmony_ci}
33162306a36Sopenharmony_ci
33262306a36Sopenharmony_cistatic int max1027_read_single_value(struct iio_dev *indio_dev,
33362306a36Sopenharmony_ci				     struct iio_chan_spec const *chan,
33462306a36Sopenharmony_ci				     int *val)
33562306a36Sopenharmony_ci{
33662306a36Sopenharmony_ci	int ret;
33762306a36Sopenharmony_ci	struct max1027_state *st = iio_priv(indio_dev);
33862306a36Sopenharmony_ci
33962306a36Sopenharmony_ci	ret = iio_device_claim_direct_mode(indio_dev);
34062306a36Sopenharmony_ci	if (ret)
34162306a36Sopenharmony_ci		return ret;
34262306a36Sopenharmony_ci
34362306a36Sopenharmony_ci	/* Configure conversion register with the requested chan */
34462306a36Sopenharmony_ci	st->reg = MAX1027_CONV_REG | MAX1027_CHAN(chan->channel) |
34562306a36Sopenharmony_ci		  MAX1027_NOSCAN;
34662306a36Sopenharmony_ci	if (chan->type == IIO_TEMP)
34762306a36Sopenharmony_ci		st->reg |= MAX1027_TEMP;
34862306a36Sopenharmony_ci	ret = spi_write(st->spi, &st->reg, 1);
34962306a36Sopenharmony_ci	if (ret < 0) {
35062306a36Sopenharmony_ci		dev_err(&indio_dev->dev,
35162306a36Sopenharmony_ci			"Failed to configure conversion register\n");
35262306a36Sopenharmony_ci		goto release;
35362306a36Sopenharmony_ci	}
35462306a36Sopenharmony_ci
35562306a36Sopenharmony_ci	/*
35662306a36Sopenharmony_ci	 * For an unknown reason, when we use the mode "10" (write
35762306a36Sopenharmony_ci	 * conversion register), the interrupt doesn't occur every time.
35862306a36Sopenharmony_ci	 * So we just wait the maximum conversion time and deliver the value.
35962306a36Sopenharmony_ci	 */
36062306a36Sopenharmony_ci	ret = max1027_wait_eoc(indio_dev);
36162306a36Sopenharmony_ci	if (ret)
36262306a36Sopenharmony_ci		goto release;
36362306a36Sopenharmony_ci
36462306a36Sopenharmony_ci	/* Read result */
36562306a36Sopenharmony_ci	ret = spi_read(st->spi, st->buffer, (chan->type == IIO_TEMP) ? 4 : 2);
36662306a36Sopenharmony_ci
36762306a36Sopenharmony_cirelease:
36862306a36Sopenharmony_ci	iio_device_release_direct_mode(indio_dev);
36962306a36Sopenharmony_ci
37062306a36Sopenharmony_ci	if (ret < 0)
37162306a36Sopenharmony_ci		return ret;
37262306a36Sopenharmony_ci
37362306a36Sopenharmony_ci	*val = be16_to_cpu(st->buffer[0]);
37462306a36Sopenharmony_ci
37562306a36Sopenharmony_ci	return IIO_VAL_INT;
37662306a36Sopenharmony_ci}
37762306a36Sopenharmony_ci
37862306a36Sopenharmony_cistatic int max1027_read_raw(struct iio_dev *indio_dev,
37962306a36Sopenharmony_ci			    struct iio_chan_spec const *chan,
38062306a36Sopenharmony_ci			    int *val, int *val2, long mask)
38162306a36Sopenharmony_ci{
38262306a36Sopenharmony_ci	int ret = 0;
38362306a36Sopenharmony_ci	struct max1027_state *st = iio_priv(indio_dev);
38462306a36Sopenharmony_ci
38562306a36Sopenharmony_ci	mutex_lock(&st->lock);
38662306a36Sopenharmony_ci
38762306a36Sopenharmony_ci	switch (mask) {
38862306a36Sopenharmony_ci	case IIO_CHAN_INFO_RAW:
38962306a36Sopenharmony_ci		ret = max1027_read_single_value(indio_dev, chan, val);
39062306a36Sopenharmony_ci		break;
39162306a36Sopenharmony_ci	case IIO_CHAN_INFO_SCALE:
39262306a36Sopenharmony_ci		switch (chan->type) {
39362306a36Sopenharmony_ci		case IIO_TEMP:
39462306a36Sopenharmony_ci			*val = 1;
39562306a36Sopenharmony_ci			*val2 = 8;
39662306a36Sopenharmony_ci			ret = IIO_VAL_FRACTIONAL;
39762306a36Sopenharmony_ci			break;
39862306a36Sopenharmony_ci		case IIO_VOLTAGE:
39962306a36Sopenharmony_ci			*val = 2500;
40062306a36Sopenharmony_ci			*val2 = chan->scan_type.realbits;
40162306a36Sopenharmony_ci			ret = IIO_VAL_FRACTIONAL_LOG2;
40262306a36Sopenharmony_ci			break;
40362306a36Sopenharmony_ci		default:
40462306a36Sopenharmony_ci			ret = -EINVAL;
40562306a36Sopenharmony_ci			break;
40662306a36Sopenharmony_ci		}
40762306a36Sopenharmony_ci		break;
40862306a36Sopenharmony_ci	default:
40962306a36Sopenharmony_ci		ret = -EINVAL;
41062306a36Sopenharmony_ci		break;
41162306a36Sopenharmony_ci	}
41262306a36Sopenharmony_ci
41362306a36Sopenharmony_ci	mutex_unlock(&st->lock);
41462306a36Sopenharmony_ci
41562306a36Sopenharmony_ci	return ret;
41662306a36Sopenharmony_ci}
41762306a36Sopenharmony_ci
41862306a36Sopenharmony_cistatic int max1027_debugfs_reg_access(struct iio_dev *indio_dev,
41962306a36Sopenharmony_ci				      unsigned int reg, unsigned int writeval,
42062306a36Sopenharmony_ci				      unsigned int *readval)
42162306a36Sopenharmony_ci{
42262306a36Sopenharmony_ci	struct max1027_state *st = iio_priv(indio_dev);
42362306a36Sopenharmony_ci	u8 *val = (u8 *)st->buffer;
42462306a36Sopenharmony_ci
42562306a36Sopenharmony_ci	if (readval) {
42662306a36Sopenharmony_ci		int ret = spi_read(st->spi, val, 2);
42762306a36Sopenharmony_ci		*readval = be16_to_cpu(st->buffer[0]);
42862306a36Sopenharmony_ci		return ret;
42962306a36Sopenharmony_ci	}
43062306a36Sopenharmony_ci
43162306a36Sopenharmony_ci	*val = (u8)writeval;
43262306a36Sopenharmony_ci	return spi_write(st->spi, val, 1);
43362306a36Sopenharmony_ci}
43462306a36Sopenharmony_ci
43562306a36Sopenharmony_cistatic int max1027_set_cnvst_trigger_state(struct iio_trigger *trig, bool state)
43662306a36Sopenharmony_ci{
43762306a36Sopenharmony_ci	struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
43862306a36Sopenharmony_ci	int ret;
43962306a36Sopenharmony_ci
44062306a36Sopenharmony_ci	/*
44162306a36Sopenharmony_ci	 * In order to disable the convst trigger, start acquisition on
44262306a36Sopenharmony_ci	 * conversion register write, which basically disables triggering
44362306a36Sopenharmony_ci	 * conversions upon cnvst changes and thus has the effect of disabling
44462306a36Sopenharmony_ci	 * the external hardware trigger.
44562306a36Sopenharmony_ci	 */
44662306a36Sopenharmony_ci	ret = max1027_enable_trigger(indio_dev, state);
44762306a36Sopenharmony_ci	if (ret)
44862306a36Sopenharmony_ci		return ret;
44962306a36Sopenharmony_ci
45062306a36Sopenharmony_ci	if (state) {
45162306a36Sopenharmony_ci		ret = max1027_configure_chans_and_start(indio_dev);
45262306a36Sopenharmony_ci		if (ret)
45362306a36Sopenharmony_ci			return ret;
45462306a36Sopenharmony_ci	}
45562306a36Sopenharmony_ci
45662306a36Sopenharmony_ci	return 0;
45762306a36Sopenharmony_ci}
45862306a36Sopenharmony_ci
45962306a36Sopenharmony_cistatic int max1027_read_scan(struct iio_dev *indio_dev)
46062306a36Sopenharmony_ci{
46162306a36Sopenharmony_ci	struct max1027_state *st = iio_priv(indio_dev);
46262306a36Sopenharmony_ci	unsigned int scanned_chans;
46362306a36Sopenharmony_ci	int ret;
46462306a36Sopenharmony_ci
46562306a36Sopenharmony_ci	scanned_chans = fls(*indio_dev->active_scan_mask) - 1;
46662306a36Sopenharmony_ci	if (*indio_dev->active_scan_mask & MAX1X27_SCAN_MASK_TEMP)
46762306a36Sopenharmony_ci		scanned_chans++;
46862306a36Sopenharmony_ci
46962306a36Sopenharmony_ci	/* fill buffer with all channel */
47062306a36Sopenharmony_ci	ret = spi_read(st->spi, st->buffer, scanned_chans * 2);
47162306a36Sopenharmony_ci	if (ret < 0)
47262306a36Sopenharmony_ci		return ret;
47362306a36Sopenharmony_ci
47462306a36Sopenharmony_ci	iio_push_to_buffers(indio_dev, st->buffer);
47562306a36Sopenharmony_ci
47662306a36Sopenharmony_ci	return 0;
47762306a36Sopenharmony_ci}
47862306a36Sopenharmony_ci
47962306a36Sopenharmony_cistatic irqreturn_t max1027_handler(int irq, void *private)
48062306a36Sopenharmony_ci{
48162306a36Sopenharmony_ci	struct iio_dev *indio_dev = private;
48262306a36Sopenharmony_ci	struct max1027_state *st = iio_priv(indio_dev);
48362306a36Sopenharmony_ci
48462306a36Sopenharmony_ci	/*
48562306a36Sopenharmony_ci	 * If buffers are disabled (raw read) or when using external triggers,
48662306a36Sopenharmony_ci	 * we just need to unlock the waiters which will then handle the data.
48762306a36Sopenharmony_ci	 *
48862306a36Sopenharmony_ci	 * When using the internal trigger, we must hand-off the choice of the
48962306a36Sopenharmony_ci	 * handler to the core which will then lookup through the interrupt tree
49062306a36Sopenharmony_ci	 * for the right handler registered with iio_triggered_buffer_setup()
49162306a36Sopenharmony_ci	 * to execute, as this trigger might very well be used in conjunction
49262306a36Sopenharmony_ci	 * with another device. The core will then call the relevant handler to
49362306a36Sopenharmony_ci	 * perform the data processing step.
49462306a36Sopenharmony_ci	 */
49562306a36Sopenharmony_ci	if (!iio_buffer_enabled(indio_dev))
49662306a36Sopenharmony_ci		complete(&st->complete);
49762306a36Sopenharmony_ci	else
49862306a36Sopenharmony_ci		iio_trigger_poll(indio_dev->trig);
49962306a36Sopenharmony_ci
50062306a36Sopenharmony_ci	return IRQ_HANDLED;
50162306a36Sopenharmony_ci}
50262306a36Sopenharmony_ci
50362306a36Sopenharmony_cistatic irqreturn_t max1027_trigger_handler(int irq, void *private)
50462306a36Sopenharmony_ci{
50562306a36Sopenharmony_ci	struct iio_poll_func *pf = private;
50662306a36Sopenharmony_ci	struct iio_dev *indio_dev = pf->indio_dev;
50762306a36Sopenharmony_ci	int ret;
50862306a36Sopenharmony_ci
50962306a36Sopenharmony_ci	if (!iio_trigger_using_own(indio_dev)) {
51062306a36Sopenharmony_ci		ret = max1027_configure_chans_and_start(indio_dev);
51162306a36Sopenharmony_ci		if (ret)
51262306a36Sopenharmony_ci			goto out;
51362306a36Sopenharmony_ci
51462306a36Sopenharmony_ci		/* This is a threaded handler, it is fine to wait for an IRQ */
51562306a36Sopenharmony_ci		ret = max1027_wait_eoc(indio_dev);
51662306a36Sopenharmony_ci		if (ret)
51762306a36Sopenharmony_ci			goto out;
51862306a36Sopenharmony_ci	}
51962306a36Sopenharmony_ci
52062306a36Sopenharmony_ci	ret = max1027_read_scan(indio_dev);
52162306a36Sopenharmony_ciout:
52262306a36Sopenharmony_ci	if (ret)
52362306a36Sopenharmony_ci		dev_err(&indio_dev->dev,
52462306a36Sopenharmony_ci			"Cannot read scanned values (%d)\n", ret);
52562306a36Sopenharmony_ci
52662306a36Sopenharmony_ci	iio_trigger_notify_done(indio_dev->trig);
52762306a36Sopenharmony_ci
52862306a36Sopenharmony_ci	return IRQ_HANDLED;
52962306a36Sopenharmony_ci}
53062306a36Sopenharmony_ci
53162306a36Sopenharmony_cistatic const struct iio_trigger_ops max1027_trigger_ops = {
53262306a36Sopenharmony_ci	.validate_device = &iio_trigger_validate_own_device,
53362306a36Sopenharmony_ci	.set_trigger_state = &max1027_set_cnvst_trigger_state,
53462306a36Sopenharmony_ci};
53562306a36Sopenharmony_ci
53662306a36Sopenharmony_cistatic const struct iio_info max1027_info = {
53762306a36Sopenharmony_ci	.read_raw = &max1027_read_raw,
53862306a36Sopenharmony_ci	.debugfs_reg_access = &max1027_debugfs_reg_access,
53962306a36Sopenharmony_ci};
54062306a36Sopenharmony_ci
54162306a36Sopenharmony_cistatic int max1027_probe(struct spi_device *spi)
54262306a36Sopenharmony_ci{
54362306a36Sopenharmony_ci	int ret;
54462306a36Sopenharmony_ci	struct iio_dev *indio_dev;
54562306a36Sopenharmony_ci	struct max1027_state *st;
54662306a36Sopenharmony_ci
54762306a36Sopenharmony_ci	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
54862306a36Sopenharmony_ci	if (!indio_dev) {
54962306a36Sopenharmony_ci		pr_err("Can't allocate iio device\n");
55062306a36Sopenharmony_ci		return -ENOMEM;
55162306a36Sopenharmony_ci	}
55262306a36Sopenharmony_ci
55362306a36Sopenharmony_ci	st = iio_priv(indio_dev);
55462306a36Sopenharmony_ci	st->spi = spi;
55562306a36Sopenharmony_ci	st->info = &max1027_chip_info_tbl[spi_get_device_id(spi)->driver_data];
55662306a36Sopenharmony_ci
55762306a36Sopenharmony_ci	mutex_init(&st->lock);
55862306a36Sopenharmony_ci	init_completion(&st->complete);
55962306a36Sopenharmony_ci
56062306a36Sopenharmony_ci	indio_dev->name = spi_get_device_id(spi)->name;
56162306a36Sopenharmony_ci	indio_dev->info = &max1027_info;
56262306a36Sopenharmony_ci	indio_dev->modes = INDIO_DIRECT_MODE;
56362306a36Sopenharmony_ci	indio_dev->channels = st->info->channels;
56462306a36Sopenharmony_ci	indio_dev->num_channels = st->info->num_channels;
56562306a36Sopenharmony_ci	indio_dev->available_scan_masks = st->info->available_scan_masks;
56662306a36Sopenharmony_ci
56762306a36Sopenharmony_ci	st->buffer = devm_kmalloc_array(&indio_dev->dev,
56862306a36Sopenharmony_ci					indio_dev->num_channels, 2,
56962306a36Sopenharmony_ci					GFP_KERNEL);
57062306a36Sopenharmony_ci	if (!st->buffer)
57162306a36Sopenharmony_ci		return -ENOMEM;
57262306a36Sopenharmony_ci
57362306a36Sopenharmony_ci	/* Enable triggered buffers */
57462306a36Sopenharmony_ci	ret = devm_iio_triggered_buffer_setup(&spi->dev, indio_dev,
57562306a36Sopenharmony_ci					      &iio_pollfunc_store_time,
57662306a36Sopenharmony_ci					      &max1027_trigger_handler,
57762306a36Sopenharmony_ci					      NULL);
57862306a36Sopenharmony_ci	if (ret < 0) {
57962306a36Sopenharmony_ci		dev_err(&indio_dev->dev, "Failed to setup buffer\n");
58062306a36Sopenharmony_ci		return ret;
58162306a36Sopenharmony_ci	}
58262306a36Sopenharmony_ci
58362306a36Sopenharmony_ci	/* If there is an EOC interrupt, register the cnvst hardware trigger */
58462306a36Sopenharmony_ci	if (spi->irq) {
58562306a36Sopenharmony_ci		st->trig = devm_iio_trigger_alloc(&spi->dev, "%s-trigger",
58662306a36Sopenharmony_ci						  indio_dev->name);
58762306a36Sopenharmony_ci		if (!st->trig) {
58862306a36Sopenharmony_ci			ret = -ENOMEM;
58962306a36Sopenharmony_ci			dev_err(&indio_dev->dev,
59062306a36Sopenharmony_ci				"Failed to allocate iio trigger\n");
59162306a36Sopenharmony_ci			return ret;
59262306a36Sopenharmony_ci		}
59362306a36Sopenharmony_ci
59462306a36Sopenharmony_ci		st->trig->ops = &max1027_trigger_ops;
59562306a36Sopenharmony_ci		iio_trigger_set_drvdata(st->trig, indio_dev);
59662306a36Sopenharmony_ci		ret = devm_iio_trigger_register(&indio_dev->dev,
59762306a36Sopenharmony_ci						st->trig);
59862306a36Sopenharmony_ci		if (ret < 0) {
59962306a36Sopenharmony_ci			dev_err(&indio_dev->dev,
60062306a36Sopenharmony_ci				"Failed to register iio trigger\n");
60162306a36Sopenharmony_ci			return ret;
60262306a36Sopenharmony_ci		}
60362306a36Sopenharmony_ci
60462306a36Sopenharmony_ci		ret = devm_request_irq(&spi->dev, spi->irq, max1027_handler,
60562306a36Sopenharmony_ci				       IRQF_TRIGGER_FALLING,
60662306a36Sopenharmony_ci				       spi->dev.driver->name, indio_dev);
60762306a36Sopenharmony_ci		if (ret < 0) {
60862306a36Sopenharmony_ci			dev_err(&indio_dev->dev, "Failed to allocate IRQ.\n");
60962306a36Sopenharmony_ci			return ret;
61062306a36Sopenharmony_ci		}
61162306a36Sopenharmony_ci	}
61262306a36Sopenharmony_ci
61362306a36Sopenharmony_ci	/* Internal reset */
61462306a36Sopenharmony_ci	st->reg = MAX1027_RST_REG;
61562306a36Sopenharmony_ci	ret = spi_write(st->spi, &st->reg, 1);
61662306a36Sopenharmony_ci	if (ret < 0) {
61762306a36Sopenharmony_ci		dev_err(&indio_dev->dev, "Failed to reset the ADC\n");
61862306a36Sopenharmony_ci		return ret;
61962306a36Sopenharmony_ci	}
62062306a36Sopenharmony_ci
62162306a36Sopenharmony_ci	/* Disable averaging */
62262306a36Sopenharmony_ci	st->reg = MAX1027_AVG_REG;
62362306a36Sopenharmony_ci	ret = spi_write(st->spi, &st->reg, 1);
62462306a36Sopenharmony_ci	if (ret < 0) {
62562306a36Sopenharmony_ci		dev_err(&indio_dev->dev, "Failed to configure averaging register\n");
62662306a36Sopenharmony_ci		return ret;
62762306a36Sopenharmony_ci	}
62862306a36Sopenharmony_ci
62962306a36Sopenharmony_ci	/* Assume conversion on register write for now */
63062306a36Sopenharmony_ci	ret = max1027_enable_trigger(indio_dev, false);
63162306a36Sopenharmony_ci	if (ret)
63262306a36Sopenharmony_ci		return ret;
63362306a36Sopenharmony_ci
63462306a36Sopenharmony_ci	return devm_iio_device_register(&spi->dev, indio_dev);
63562306a36Sopenharmony_ci}
63662306a36Sopenharmony_ci
63762306a36Sopenharmony_cistatic struct spi_driver max1027_driver = {
63862306a36Sopenharmony_ci	.driver = {
63962306a36Sopenharmony_ci		.name	= "max1027",
64062306a36Sopenharmony_ci		.of_match_table = max1027_adc_dt_ids,
64162306a36Sopenharmony_ci	},
64262306a36Sopenharmony_ci	.probe		= max1027_probe,
64362306a36Sopenharmony_ci	.id_table	= max1027_id,
64462306a36Sopenharmony_ci};
64562306a36Sopenharmony_cimodule_spi_driver(max1027_driver);
64662306a36Sopenharmony_ci
64762306a36Sopenharmony_ciMODULE_AUTHOR("Philippe Reynes <tremyfr@yahoo.fr>");
64862306a36Sopenharmony_ciMODULE_DESCRIPTION("MAX1X27/MAX1X29/MAX1X31 ADC");
64962306a36Sopenharmony_ciMODULE_LICENSE("GPL v2");
650