162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci /*
362306a36Sopenharmony_ci  * iio/adc/max1363.c
462306a36Sopenharmony_ci  * Copyright (C) 2008-2010 Jonathan Cameron
562306a36Sopenharmony_ci  *
662306a36Sopenharmony_ci  * based on linux/drivers/i2c/chips/max123x
762306a36Sopenharmony_ci  * Copyright (C) 2002-2004 Stefan Eletzhofer
862306a36Sopenharmony_ci  *
962306a36Sopenharmony_ci  * based on linux/drivers/acron/char/pcf8583.c
1062306a36Sopenharmony_ci  * Copyright (C) 2000 Russell King
1162306a36Sopenharmony_ci  *
1262306a36Sopenharmony_ci  * Driver for max1363 and similar chips.
1362306a36Sopenharmony_ci  */
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci#include <linux/interrupt.h>
1662306a36Sopenharmony_ci#include <linux/device.h>
1762306a36Sopenharmony_ci#include <linux/kernel.h>
1862306a36Sopenharmony_ci#include <linux/sysfs.h>
1962306a36Sopenharmony_ci#include <linux/list.h>
2062306a36Sopenharmony_ci#include <linux/i2c.h>
2162306a36Sopenharmony_ci#include <linux/regulator/consumer.h>
2262306a36Sopenharmony_ci#include <linux/slab.h>
2362306a36Sopenharmony_ci#include <linux/err.h>
2462306a36Sopenharmony_ci#include <linux/module.h>
2562306a36Sopenharmony_ci#include <linux/mod_devicetable.h>
2662306a36Sopenharmony_ci#include <linux/property.h>
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ci#include <linux/iio/iio.h>
2962306a36Sopenharmony_ci#include <linux/iio/sysfs.h>
3062306a36Sopenharmony_ci#include <linux/iio/events.h>
3162306a36Sopenharmony_ci#include <linux/iio/buffer.h>
3262306a36Sopenharmony_ci#include <linux/iio/kfifo_buf.h>
3362306a36Sopenharmony_ci#include <linux/iio/trigger_consumer.h>
3462306a36Sopenharmony_ci#include <linux/iio/triggered_buffer.h>
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ci#define MAX1363_SETUP_BYTE(a) ((a) | 0x80)
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci/* There is a fair bit more defined here than currently
3962306a36Sopenharmony_ci * used, but the intention is to support everything these
4062306a36Sopenharmony_ci * chips do in the long run */
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ci/* see data sheets */
4362306a36Sopenharmony_ci/* max1363 and max1236, max1237, max1238, max1239 */
4462306a36Sopenharmony_ci#define MAX1363_SETUP_AIN3_IS_AIN3_REF_IS_VDD	0x00
4562306a36Sopenharmony_ci#define MAX1363_SETUP_AIN3_IS_REF_EXT_TO_REF	0x20
4662306a36Sopenharmony_ci#define MAX1363_SETUP_AIN3_IS_AIN3_REF_IS_INT	0x40
4762306a36Sopenharmony_ci#define MAX1363_SETUP_AIN3_IS_REF_REF_IS_INT	0x60
4862306a36Sopenharmony_ci#define MAX1363_SETUP_POWER_UP_INT_REF		0x10
4962306a36Sopenharmony_ci#define MAX1363_SETUP_POWER_DOWN_INT_REF	0x00
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ci/* think about including max11600 etc - more settings */
5262306a36Sopenharmony_ci#define MAX1363_SETUP_EXT_CLOCK			0x08
5362306a36Sopenharmony_ci#define MAX1363_SETUP_INT_CLOCK			0x00
5462306a36Sopenharmony_ci#define MAX1363_SETUP_UNIPOLAR			0x00
5562306a36Sopenharmony_ci#define MAX1363_SETUP_BIPOLAR			0x04
5662306a36Sopenharmony_ci#define MAX1363_SETUP_RESET			0x00
5762306a36Sopenharmony_ci#define MAX1363_SETUP_NORESET			0x02
5862306a36Sopenharmony_ci/* max1363 only - though don't care on others.
5962306a36Sopenharmony_ci * For now monitor modes are not implemented as the relevant
6062306a36Sopenharmony_ci * line is not connected on my test board.
6162306a36Sopenharmony_ci * The definitions are here as I intend to add this soon.
6262306a36Sopenharmony_ci */
6362306a36Sopenharmony_ci#define MAX1363_SETUP_MONITOR_SETUP		0x01
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_ci/* Specific to the max1363 */
6662306a36Sopenharmony_ci#define MAX1363_MON_RESET_CHAN(a) (1 << ((a) + 4))
6762306a36Sopenharmony_ci#define MAX1363_MON_INT_ENABLE			0x01
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_ci/* defined for readability reasons */
7062306a36Sopenharmony_ci/* All chips */
7162306a36Sopenharmony_ci#define MAX1363_CONFIG_BYTE(a) ((a))
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ci#define MAX1363_CONFIG_SE			0x01
7462306a36Sopenharmony_ci#define MAX1363_CONFIG_DE			0x00
7562306a36Sopenharmony_ci#define MAX1363_CONFIG_SCAN_TO_CS		0x00
7662306a36Sopenharmony_ci#define MAX1363_CONFIG_SCAN_SINGLE_8		0x20
7762306a36Sopenharmony_ci#define MAX1363_CONFIG_SCAN_MONITOR_MODE	0x40
7862306a36Sopenharmony_ci#define MAX1363_CONFIG_SCAN_SINGLE_1		0x60
7962306a36Sopenharmony_ci/* max123{6-9} only */
8062306a36Sopenharmony_ci#define MAX1236_SCAN_MID_TO_CHANNEL		0x40
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_ci/* max1363 only - merely part of channel selects or don't care for others */
8362306a36Sopenharmony_ci#define MAX1363_CONFIG_EN_MON_MODE_READ 0x18
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ci#define MAX1363_CHANNEL_SEL(a) ((a) << 1)
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_ci/* max1363 strictly 0x06 - but doesn't matter */
8862306a36Sopenharmony_ci#define MAX1363_CHANNEL_SEL_MASK		0x1E
8962306a36Sopenharmony_ci#define MAX1363_SCAN_MASK			0x60
9062306a36Sopenharmony_ci#define MAX1363_SE_DE_MASK			0x01
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_ci#define MAX1363_MAX_CHANNELS 25
9362306a36Sopenharmony_ci/**
9462306a36Sopenharmony_ci * struct max1363_mode - scan mode information
9562306a36Sopenharmony_ci * @conf:	The corresponding value of the configuration register
9662306a36Sopenharmony_ci * @modemask:	Bit mask corresponding to channels enabled in this mode
9762306a36Sopenharmony_ci */
9862306a36Sopenharmony_cistruct max1363_mode {
9962306a36Sopenharmony_ci	int8_t		conf;
10062306a36Sopenharmony_ci	DECLARE_BITMAP(modemask, MAX1363_MAX_CHANNELS);
10162306a36Sopenharmony_ci};
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_ci/* This must be maintained along side the max1363_mode_table in max1363_core */
10462306a36Sopenharmony_cienum max1363_modes {
10562306a36Sopenharmony_ci	/* Single read of a single channel */
10662306a36Sopenharmony_ci	_s0, _s1, _s2, _s3, _s4, _s5, _s6, _s7, _s8, _s9, _s10, _s11,
10762306a36Sopenharmony_ci	/* Differential single read */
10862306a36Sopenharmony_ci	d0m1, d2m3, d4m5, d6m7, d8m9, d10m11,
10962306a36Sopenharmony_ci	d1m0, d3m2, d5m4, d7m6, d9m8, d11m10,
11062306a36Sopenharmony_ci	/* Scan to channel and mid to channel where overlapping */
11162306a36Sopenharmony_ci	s0to1, s0to2, s2to3, s0to3, s0to4, s0to5, s0to6,
11262306a36Sopenharmony_ci	s6to7, s0to7, s6to8, s0to8, s6to9,
11362306a36Sopenharmony_ci	s0to9, s6to10, s0to10, s6to11, s0to11,
11462306a36Sopenharmony_ci	/* Differential scan to channel and mid to channel where overlapping */
11562306a36Sopenharmony_ci	d0m1to2m3, d0m1to4m5, d0m1to6m7, d6m7to8m9,
11662306a36Sopenharmony_ci	d0m1to8m9, d6m7to10m11, d0m1to10m11, d1m0to3m2,
11762306a36Sopenharmony_ci	d1m0to5m4, d1m0to7m6, d7m6to9m8, d1m0to9m8,
11862306a36Sopenharmony_ci	d7m6to11m10, d1m0to11m10,
11962306a36Sopenharmony_ci};
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_ci/**
12262306a36Sopenharmony_ci * struct max1363_chip_info - chip specifc information
12362306a36Sopenharmony_ci * @info:		iio core function callbacks structure
12462306a36Sopenharmony_ci * @channels:		channel specification
12562306a36Sopenharmony_ci * @num_channels:       number of channels
12662306a36Sopenharmony_ci * @mode_list:		array of available scan modes
12762306a36Sopenharmony_ci * @default_mode:	the scan mode in which the chip starts up
12862306a36Sopenharmony_ci * @int_vref_mv:	the internal reference voltage
12962306a36Sopenharmony_ci * @num_modes:		number of modes
13062306a36Sopenharmony_ci * @bits:		accuracy of the adc in bits
13162306a36Sopenharmony_ci */
13262306a36Sopenharmony_cistruct max1363_chip_info {
13362306a36Sopenharmony_ci	const struct iio_info		*info;
13462306a36Sopenharmony_ci	const struct iio_chan_spec	*channels;
13562306a36Sopenharmony_ci	int				num_channels;
13662306a36Sopenharmony_ci	const enum max1363_modes	*mode_list;
13762306a36Sopenharmony_ci	enum max1363_modes		default_mode;
13862306a36Sopenharmony_ci	u16				int_vref_mv;
13962306a36Sopenharmony_ci	u8				num_modes;
14062306a36Sopenharmony_ci	u8				bits;
14162306a36Sopenharmony_ci};
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_ci/**
14462306a36Sopenharmony_ci * struct max1363_state - driver instance specific data
14562306a36Sopenharmony_ci * @client:		i2c_client
14662306a36Sopenharmony_ci * @setupbyte:		cache of current device setup byte
14762306a36Sopenharmony_ci * @configbyte:		cache of current device config byte
14862306a36Sopenharmony_ci * @chip_info:		chip model specific constants, available modes, etc.
14962306a36Sopenharmony_ci * @current_mode:	the scan mode of this chip
15062306a36Sopenharmony_ci * @requestedmask:	a valid requested set of channels
15162306a36Sopenharmony_ci * @lock:		lock to ensure state is consistent
15262306a36Sopenharmony_ci * @monitor_on:		whether monitor mode is enabled
15362306a36Sopenharmony_ci * @monitor_speed:	parameter corresponding to device monitor speed setting
15462306a36Sopenharmony_ci * @mask_high:		bitmask for enabled high thresholds
15562306a36Sopenharmony_ci * @mask_low:		bitmask for enabled low thresholds
15662306a36Sopenharmony_ci * @thresh_high:	high threshold values
15762306a36Sopenharmony_ci * @thresh_low:		low threshold values
15862306a36Sopenharmony_ci * @vref:		Reference voltage regulator
15962306a36Sopenharmony_ci * @vref_uv:		Actual (external or internal) reference voltage
16062306a36Sopenharmony_ci * @send:		function used to send data to the chip
16162306a36Sopenharmony_ci * @recv:		function used to receive data from the chip
16262306a36Sopenharmony_ci */
16362306a36Sopenharmony_cistruct max1363_state {
16462306a36Sopenharmony_ci	struct i2c_client		*client;
16562306a36Sopenharmony_ci	u8				setupbyte;
16662306a36Sopenharmony_ci	u8				configbyte;
16762306a36Sopenharmony_ci	const struct max1363_chip_info	*chip_info;
16862306a36Sopenharmony_ci	const struct max1363_mode	*current_mode;
16962306a36Sopenharmony_ci	u32				requestedmask;
17062306a36Sopenharmony_ci	struct mutex			lock;
17162306a36Sopenharmony_ci
17262306a36Sopenharmony_ci	/* Using monitor modes and buffer at the same time is
17362306a36Sopenharmony_ci	   currently not supported */
17462306a36Sopenharmony_ci	bool				monitor_on;
17562306a36Sopenharmony_ci	unsigned int			monitor_speed:3;
17662306a36Sopenharmony_ci	u8				mask_high;
17762306a36Sopenharmony_ci	u8				mask_low;
17862306a36Sopenharmony_ci	/* 4x unipolar first then the fours bipolar ones */
17962306a36Sopenharmony_ci	s16				thresh_high[8];
18062306a36Sopenharmony_ci	s16				thresh_low[8];
18162306a36Sopenharmony_ci	struct regulator		*vref;
18262306a36Sopenharmony_ci	u32				vref_uv;
18362306a36Sopenharmony_ci	int				(*send)(const struct i2c_client *client,
18462306a36Sopenharmony_ci						const char *buf, int count);
18562306a36Sopenharmony_ci	int				(*recv)(const struct i2c_client *client,
18662306a36Sopenharmony_ci						char *buf, int count);
18762306a36Sopenharmony_ci};
18862306a36Sopenharmony_ci
18962306a36Sopenharmony_ci#define MAX1363_MODE_SINGLE(_num, _mask) {				\
19062306a36Sopenharmony_ci		.conf = MAX1363_CHANNEL_SEL(_num)			\
19162306a36Sopenharmony_ci			| MAX1363_CONFIG_SCAN_SINGLE_1			\
19262306a36Sopenharmony_ci			| MAX1363_CONFIG_SE,				\
19362306a36Sopenharmony_ci			.modemask[0] = _mask,				\
19462306a36Sopenharmony_ci			}
19562306a36Sopenharmony_ci
19662306a36Sopenharmony_ci#define MAX1363_MODE_SCAN_TO_CHANNEL(_num, _mask) {			\
19762306a36Sopenharmony_ci		.conf = MAX1363_CHANNEL_SEL(_num)			\
19862306a36Sopenharmony_ci			| MAX1363_CONFIG_SCAN_TO_CS			\
19962306a36Sopenharmony_ci			| MAX1363_CONFIG_SE,				\
20062306a36Sopenharmony_ci			.modemask[0] = _mask,				\
20162306a36Sopenharmony_ci			}
20262306a36Sopenharmony_ci
20362306a36Sopenharmony_ci/* note not available for max1363 hence naming */
20462306a36Sopenharmony_ci#define MAX1236_MODE_SCAN_MID_TO_CHANNEL(_mid, _num, _mask) {		\
20562306a36Sopenharmony_ci		.conf = MAX1363_CHANNEL_SEL(_num)			\
20662306a36Sopenharmony_ci			| MAX1236_SCAN_MID_TO_CHANNEL			\
20762306a36Sopenharmony_ci			| MAX1363_CONFIG_SE,				\
20862306a36Sopenharmony_ci			.modemask[0] = _mask				\
20962306a36Sopenharmony_ci}
21062306a36Sopenharmony_ci
21162306a36Sopenharmony_ci#define MAX1363_MODE_DIFF_SINGLE(_nump, _numm, _mask) {			\
21262306a36Sopenharmony_ci		.conf = MAX1363_CHANNEL_SEL(_nump)			\
21362306a36Sopenharmony_ci			| MAX1363_CONFIG_SCAN_SINGLE_1			\
21462306a36Sopenharmony_ci			| MAX1363_CONFIG_DE,				\
21562306a36Sopenharmony_ci			.modemask[0] = _mask				\
21662306a36Sopenharmony_ci			}
21762306a36Sopenharmony_ci
21862306a36Sopenharmony_ci/* Can't think how to automate naming so specify for now */
21962306a36Sopenharmony_ci#define MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(_num, _numvals, _mask) {	\
22062306a36Sopenharmony_ci		.conf = MAX1363_CHANNEL_SEL(_num)			\
22162306a36Sopenharmony_ci			| MAX1363_CONFIG_SCAN_TO_CS			\
22262306a36Sopenharmony_ci			| MAX1363_CONFIG_DE,				\
22362306a36Sopenharmony_ci			.modemask[0] = _mask				\
22462306a36Sopenharmony_ci			}
22562306a36Sopenharmony_ci
22662306a36Sopenharmony_ci/* note only available for max1363 hence naming */
22762306a36Sopenharmony_ci#define MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL(_num, _numvals, _mask) {	\
22862306a36Sopenharmony_ci		.conf = MAX1363_CHANNEL_SEL(_num)			\
22962306a36Sopenharmony_ci			| MAX1236_SCAN_MID_TO_CHANNEL			\
23062306a36Sopenharmony_ci			| MAX1363_CONFIG_SE,				\
23162306a36Sopenharmony_ci			.modemask[0] = _mask				\
23262306a36Sopenharmony_ci}
23362306a36Sopenharmony_ci
23462306a36Sopenharmony_cistatic const struct max1363_mode max1363_mode_table[] = {
23562306a36Sopenharmony_ci	/* All of the single channel options first */
23662306a36Sopenharmony_ci	MAX1363_MODE_SINGLE(0, 1 << 0),
23762306a36Sopenharmony_ci	MAX1363_MODE_SINGLE(1, 1 << 1),
23862306a36Sopenharmony_ci	MAX1363_MODE_SINGLE(2, 1 << 2),
23962306a36Sopenharmony_ci	MAX1363_MODE_SINGLE(3, 1 << 3),
24062306a36Sopenharmony_ci	MAX1363_MODE_SINGLE(4, 1 << 4),
24162306a36Sopenharmony_ci	MAX1363_MODE_SINGLE(5, 1 << 5),
24262306a36Sopenharmony_ci	MAX1363_MODE_SINGLE(6, 1 << 6),
24362306a36Sopenharmony_ci	MAX1363_MODE_SINGLE(7, 1 << 7),
24462306a36Sopenharmony_ci	MAX1363_MODE_SINGLE(8, 1 << 8),
24562306a36Sopenharmony_ci	MAX1363_MODE_SINGLE(9, 1 << 9),
24662306a36Sopenharmony_ci	MAX1363_MODE_SINGLE(10, 1 << 10),
24762306a36Sopenharmony_ci	MAX1363_MODE_SINGLE(11, 1 << 11),
24862306a36Sopenharmony_ci
24962306a36Sopenharmony_ci	MAX1363_MODE_DIFF_SINGLE(0, 1, 1 << 12),
25062306a36Sopenharmony_ci	MAX1363_MODE_DIFF_SINGLE(2, 3, 1 << 13),
25162306a36Sopenharmony_ci	MAX1363_MODE_DIFF_SINGLE(4, 5, 1 << 14),
25262306a36Sopenharmony_ci	MAX1363_MODE_DIFF_SINGLE(6, 7, 1 << 15),
25362306a36Sopenharmony_ci	MAX1363_MODE_DIFF_SINGLE(8, 9, 1 << 16),
25462306a36Sopenharmony_ci	MAX1363_MODE_DIFF_SINGLE(10, 11, 1 << 17),
25562306a36Sopenharmony_ci	MAX1363_MODE_DIFF_SINGLE(1, 0, 1 << 18),
25662306a36Sopenharmony_ci	MAX1363_MODE_DIFF_SINGLE(3, 2, 1 << 19),
25762306a36Sopenharmony_ci	MAX1363_MODE_DIFF_SINGLE(5, 4, 1 << 20),
25862306a36Sopenharmony_ci	MAX1363_MODE_DIFF_SINGLE(7, 6, 1 << 21),
25962306a36Sopenharmony_ci	MAX1363_MODE_DIFF_SINGLE(9, 8, 1 << 22),
26062306a36Sopenharmony_ci	MAX1363_MODE_DIFF_SINGLE(11, 10, 1 << 23),
26162306a36Sopenharmony_ci
26262306a36Sopenharmony_ci	/* The multichannel scans next */
26362306a36Sopenharmony_ci	MAX1363_MODE_SCAN_TO_CHANNEL(1, 0x003),
26462306a36Sopenharmony_ci	MAX1363_MODE_SCAN_TO_CHANNEL(2, 0x007),
26562306a36Sopenharmony_ci	MAX1236_MODE_SCAN_MID_TO_CHANNEL(2, 3, 0x00C),
26662306a36Sopenharmony_ci	MAX1363_MODE_SCAN_TO_CHANNEL(3, 0x00F),
26762306a36Sopenharmony_ci	MAX1363_MODE_SCAN_TO_CHANNEL(4, 0x01F),
26862306a36Sopenharmony_ci	MAX1363_MODE_SCAN_TO_CHANNEL(5, 0x03F),
26962306a36Sopenharmony_ci	MAX1363_MODE_SCAN_TO_CHANNEL(6, 0x07F),
27062306a36Sopenharmony_ci	MAX1236_MODE_SCAN_MID_TO_CHANNEL(6, 7, 0x0C0),
27162306a36Sopenharmony_ci	MAX1363_MODE_SCAN_TO_CHANNEL(7, 0x0FF),
27262306a36Sopenharmony_ci	MAX1236_MODE_SCAN_MID_TO_CHANNEL(6, 8, 0x1C0),
27362306a36Sopenharmony_ci	MAX1363_MODE_SCAN_TO_CHANNEL(8, 0x1FF),
27462306a36Sopenharmony_ci	MAX1236_MODE_SCAN_MID_TO_CHANNEL(6, 9, 0x3C0),
27562306a36Sopenharmony_ci	MAX1363_MODE_SCAN_TO_CHANNEL(9, 0x3FF),
27662306a36Sopenharmony_ci	MAX1236_MODE_SCAN_MID_TO_CHANNEL(6, 10, 0x7C0),
27762306a36Sopenharmony_ci	MAX1363_MODE_SCAN_TO_CHANNEL(10, 0x7FF),
27862306a36Sopenharmony_ci	MAX1236_MODE_SCAN_MID_TO_CHANNEL(6, 11, 0xFC0),
27962306a36Sopenharmony_ci	MAX1363_MODE_SCAN_TO_CHANNEL(11, 0xFFF),
28062306a36Sopenharmony_ci
28162306a36Sopenharmony_ci	MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(2, 2, 0x003000),
28262306a36Sopenharmony_ci	MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(4, 3, 0x007000),
28362306a36Sopenharmony_ci	MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(6, 4, 0x00F000),
28462306a36Sopenharmony_ci	MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL(8, 2, 0x018000),
28562306a36Sopenharmony_ci	MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(8, 5, 0x01F000),
28662306a36Sopenharmony_ci	MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL(10, 3, 0x038000),
28762306a36Sopenharmony_ci	MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(10, 6, 0x3F000),
28862306a36Sopenharmony_ci	MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(3, 2, 0x0C0000),
28962306a36Sopenharmony_ci	MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(5, 3, 0x1C0000),
29062306a36Sopenharmony_ci	MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(7, 4, 0x3C0000),
29162306a36Sopenharmony_ci	MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL(9, 2, 0x600000),
29262306a36Sopenharmony_ci	MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(9, 5, 0x7C0000),
29362306a36Sopenharmony_ci	MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL(11, 3, 0xE00000),
29462306a36Sopenharmony_ci	MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(11, 6, 0xFC0000),
29562306a36Sopenharmony_ci};
29662306a36Sopenharmony_ci
29762306a36Sopenharmony_cistatic const struct max1363_mode
29862306a36Sopenharmony_ci*max1363_match_mode(const unsigned long *mask,
29962306a36Sopenharmony_ci	const struct max1363_chip_info *ci)
30062306a36Sopenharmony_ci{
30162306a36Sopenharmony_ci	int i;
30262306a36Sopenharmony_ci	if (mask)
30362306a36Sopenharmony_ci		for (i = 0; i < ci->num_modes; i++)
30462306a36Sopenharmony_ci			if (bitmap_subset(mask,
30562306a36Sopenharmony_ci					  max1363_mode_table[ci->mode_list[i]].
30662306a36Sopenharmony_ci					  modemask,
30762306a36Sopenharmony_ci					  MAX1363_MAX_CHANNELS))
30862306a36Sopenharmony_ci				return &max1363_mode_table[ci->mode_list[i]];
30962306a36Sopenharmony_ci	return NULL;
31062306a36Sopenharmony_ci}
31162306a36Sopenharmony_ci
31262306a36Sopenharmony_cistatic int max1363_smbus_send(const struct i2c_client *client, const char *buf,
31362306a36Sopenharmony_ci		int count)
31462306a36Sopenharmony_ci{
31562306a36Sopenharmony_ci	int i, err;
31662306a36Sopenharmony_ci
31762306a36Sopenharmony_ci	for (i = err = 0; err == 0 && i < count; ++i)
31862306a36Sopenharmony_ci		err = i2c_smbus_write_byte(client, buf[i]);
31962306a36Sopenharmony_ci
32062306a36Sopenharmony_ci	return err ? err : count;
32162306a36Sopenharmony_ci}
32262306a36Sopenharmony_ci
32362306a36Sopenharmony_cistatic int max1363_smbus_recv(const struct i2c_client *client, char *buf,
32462306a36Sopenharmony_ci		int count)
32562306a36Sopenharmony_ci{
32662306a36Sopenharmony_ci	int i, ret;
32762306a36Sopenharmony_ci
32862306a36Sopenharmony_ci	for (i = 0; i < count; ++i) {
32962306a36Sopenharmony_ci		ret = i2c_smbus_read_byte(client);
33062306a36Sopenharmony_ci		if (ret < 0)
33162306a36Sopenharmony_ci			return ret;
33262306a36Sopenharmony_ci		buf[i] = ret;
33362306a36Sopenharmony_ci	}
33462306a36Sopenharmony_ci
33562306a36Sopenharmony_ci	return count;
33662306a36Sopenharmony_ci}
33762306a36Sopenharmony_ci
33862306a36Sopenharmony_cistatic int max1363_write_basic_config(struct max1363_state *st)
33962306a36Sopenharmony_ci{
34062306a36Sopenharmony_ci	u8 tx_buf[2] = { st->setupbyte, st->configbyte };
34162306a36Sopenharmony_ci
34262306a36Sopenharmony_ci	return st->send(st->client, tx_buf, 2);
34362306a36Sopenharmony_ci}
34462306a36Sopenharmony_ci
34562306a36Sopenharmony_cistatic int max1363_set_scan_mode(struct max1363_state *st)
34662306a36Sopenharmony_ci{
34762306a36Sopenharmony_ci	st->configbyte &= ~(MAX1363_CHANNEL_SEL_MASK
34862306a36Sopenharmony_ci			    | MAX1363_SCAN_MASK
34962306a36Sopenharmony_ci			    | MAX1363_SE_DE_MASK);
35062306a36Sopenharmony_ci	st->configbyte |= st->current_mode->conf;
35162306a36Sopenharmony_ci
35262306a36Sopenharmony_ci	return max1363_write_basic_config(st);
35362306a36Sopenharmony_ci}
35462306a36Sopenharmony_ci
35562306a36Sopenharmony_cistatic int max1363_read_single_chan(struct iio_dev *indio_dev,
35662306a36Sopenharmony_ci				    struct iio_chan_spec const *chan,
35762306a36Sopenharmony_ci				    int *val,
35862306a36Sopenharmony_ci				    long m)
35962306a36Sopenharmony_ci{
36062306a36Sopenharmony_ci	int ret = 0;
36162306a36Sopenharmony_ci	s32 data;
36262306a36Sopenharmony_ci	u8 rxbuf[2];
36362306a36Sopenharmony_ci	struct max1363_state *st = iio_priv(indio_dev);
36462306a36Sopenharmony_ci	struct i2c_client *client = st->client;
36562306a36Sopenharmony_ci
36662306a36Sopenharmony_ci	ret = iio_device_claim_direct_mode(indio_dev);
36762306a36Sopenharmony_ci	if (ret)
36862306a36Sopenharmony_ci		return ret;
36962306a36Sopenharmony_ci	mutex_lock(&st->lock);
37062306a36Sopenharmony_ci
37162306a36Sopenharmony_ci	/*
37262306a36Sopenharmony_ci	 * If monitor mode is enabled, the method for reading a single
37362306a36Sopenharmony_ci	 * channel will have to be rather different and has not yet
37462306a36Sopenharmony_ci	 * been implemented.
37562306a36Sopenharmony_ci	 *
37662306a36Sopenharmony_ci	 * Also, cannot read directly if buffered capture enabled.
37762306a36Sopenharmony_ci	 */
37862306a36Sopenharmony_ci	if (st->monitor_on) {
37962306a36Sopenharmony_ci		ret = -EBUSY;
38062306a36Sopenharmony_ci		goto error_ret;
38162306a36Sopenharmony_ci	}
38262306a36Sopenharmony_ci
38362306a36Sopenharmony_ci	/* Check to see if current scan mode is correct */
38462306a36Sopenharmony_ci	if (st->current_mode != &max1363_mode_table[chan->address]) {
38562306a36Sopenharmony_ci		/* Update scan mode if needed */
38662306a36Sopenharmony_ci		st->current_mode = &max1363_mode_table[chan->address];
38762306a36Sopenharmony_ci		ret = max1363_set_scan_mode(st);
38862306a36Sopenharmony_ci		if (ret < 0)
38962306a36Sopenharmony_ci			goto error_ret;
39062306a36Sopenharmony_ci	}
39162306a36Sopenharmony_ci	if (st->chip_info->bits != 8) {
39262306a36Sopenharmony_ci		/* Get reading */
39362306a36Sopenharmony_ci		data = st->recv(client, rxbuf, 2);
39462306a36Sopenharmony_ci		if (data < 0) {
39562306a36Sopenharmony_ci			ret = data;
39662306a36Sopenharmony_ci			goto error_ret;
39762306a36Sopenharmony_ci		}
39862306a36Sopenharmony_ci		data = (rxbuf[1] | rxbuf[0] << 8) &
39962306a36Sopenharmony_ci		  ((1 << st->chip_info->bits) - 1);
40062306a36Sopenharmony_ci	} else {
40162306a36Sopenharmony_ci		/* Get reading */
40262306a36Sopenharmony_ci		data = st->recv(client, rxbuf, 1);
40362306a36Sopenharmony_ci		if (data < 0) {
40462306a36Sopenharmony_ci			ret = data;
40562306a36Sopenharmony_ci			goto error_ret;
40662306a36Sopenharmony_ci		}
40762306a36Sopenharmony_ci		data = rxbuf[0];
40862306a36Sopenharmony_ci	}
40962306a36Sopenharmony_ci	*val = data;
41062306a36Sopenharmony_ci
41162306a36Sopenharmony_cierror_ret:
41262306a36Sopenharmony_ci	mutex_unlock(&st->lock);
41362306a36Sopenharmony_ci	iio_device_release_direct_mode(indio_dev);
41462306a36Sopenharmony_ci	return ret;
41562306a36Sopenharmony_ci
41662306a36Sopenharmony_ci}
41762306a36Sopenharmony_ci
41862306a36Sopenharmony_cistatic int max1363_read_raw(struct iio_dev *indio_dev,
41962306a36Sopenharmony_ci			    struct iio_chan_spec const *chan,
42062306a36Sopenharmony_ci			    int *val,
42162306a36Sopenharmony_ci			    int *val2,
42262306a36Sopenharmony_ci			    long m)
42362306a36Sopenharmony_ci{
42462306a36Sopenharmony_ci	struct max1363_state *st = iio_priv(indio_dev);
42562306a36Sopenharmony_ci	int ret;
42662306a36Sopenharmony_ci
42762306a36Sopenharmony_ci	switch (m) {
42862306a36Sopenharmony_ci	case IIO_CHAN_INFO_RAW:
42962306a36Sopenharmony_ci		ret = max1363_read_single_chan(indio_dev, chan, val, m);
43062306a36Sopenharmony_ci		if (ret < 0)
43162306a36Sopenharmony_ci			return ret;
43262306a36Sopenharmony_ci		return IIO_VAL_INT;
43362306a36Sopenharmony_ci	case IIO_CHAN_INFO_SCALE:
43462306a36Sopenharmony_ci		*val = st->vref_uv / 1000;
43562306a36Sopenharmony_ci		*val2 = st->chip_info->bits;
43662306a36Sopenharmony_ci		return IIO_VAL_FRACTIONAL_LOG2;
43762306a36Sopenharmony_ci	default:
43862306a36Sopenharmony_ci		return -EINVAL;
43962306a36Sopenharmony_ci	}
44062306a36Sopenharmony_ci	return 0;
44162306a36Sopenharmony_ci}
44262306a36Sopenharmony_ci
44362306a36Sopenharmony_ci/* Applies to max1363 */
44462306a36Sopenharmony_cistatic const enum max1363_modes max1363_mode_list[] = {
44562306a36Sopenharmony_ci	_s0, _s1, _s2, _s3,
44662306a36Sopenharmony_ci	s0to1, s0to2, s0to3,
44762306a36Sopenharmony_ci	d0m1, d2m3, d1m0, d3m2,
44862306a36Sopenharmony_ci	d0m1to2m3, d1m0to3m2,
44962306a36Sopenharmony_ci};
45062306a36Sopenharmony_ci
45162306a36Sopenharmony_cistatic const struct iio_event_spec max1363_events[] = {
45262306a36Sopenharmony_ci	{
45362306a36Sopenharmony_ci		.type = IIO_EV_TYPE_THRESH,
45462306a36Sopenharmony_ci		.dir = IIO_EV_DIR_RISING,
45562306a36Sopenharmony_ci		.mask_separate = BIT(IIO_EV_INFO_VALUE) |
45662306a36Sopenharmony_ci			BIT(IIO_EV_INFO_ENABLE),
45762306a36Sopenharmony_ci	}, {
45862306a36Sopenharmony_ci		.type = IIO_EV_TYPE_THRESH,
45962306a36Sopenharmony_ci		.dir = IIO_EV_DIR_FALLING,
46062306a36Sopenharmony_ci		.mask_separate = BIT(IIO_EV_INFO_VALUE) |
46162306a36Sopenharmony_ci			BIT(IIO_EV_INFO_ENABLE),
46262306a36Sopenharmony_ci	},
46362306a36Sopenharmony_ci};
46462306a36Sopenharmony_ci
46562306a36Sopenharmony_ci#define MAX1363_CHAN_U(num, addr, si, bits, ev_spec, num_ev_spec)	\
46662306a36Sopenharmony_ci	{								\
46762306a36Sopenharmony_ci		.type = IIO_VOLTAGE,					\
46862306a36Sopenharmony_ci		.indexed = 1,						\
46962306a36Sopenharmony_ci		.channel = num,						\
47062306a36Sopenharmony_ci		.address = addr,					\
47162306a36Sopenharmony_ci		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\
47262306a36Sopenharmony_ci		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),	\
47362306a36Sopenharmony_ci		.datasheet_name = "AIN"#num,				\
47462306a36Sopenharmony_ci		.scan_type = {						\
47562306a36Sopenharmony_ci			.sign = 'u',					\
47662306a36Sopenharmony_ci			.realbits = bits,				\
47762306a36Sopenharmony_ci			.storagebits = (bits > 8) ? 16 : 8,		\
47862306a36Sopenharmony_ci			.endianness = IIO_BE,				\
47962306a36Sopenharmony_ci		},							\
48062306a36Sopenharmony_ci		.scan_index = si,					\
48162306a36Sopenharmony_ci		.event_spec = ev_spec,					\
48262306a36Sopenharmony_ci		.num_event_specs = num_ev_spec,				\
48362306a36Sopenharmony_ci	}
48462306a36Sopenharmony_ci
48562306a36Sopenharmony_ci/* bipolar channel */
48662306a36Sopenharmony_ci#define MAX1363_CHAN_B(num, num2, addr, si, bits, ev_spec, num_ev_spec)	\
48762306a36Sopenharmony_ci	{								\
48862306a36Sopenharmony_ci		.type = IIO_VOLTAGE,					\
48962306a36Sopenharmony_ci		.differential = 1,					\
49062306a36Sopenharmony_ci		.indexed = 1,						\
49162306a36Sopenharmony_ci		.channel = num,						\
49262306a36Sopenharmony_ci		.channel2 = num2,					\
49362306a36Sopenharmony_ci		.address = addr,					\
49462306a36Sopenharmony_ci		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\
49562306a36Sopenharmony_ci		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),	\
49662306a36Sopenharmony_ci		.datasheet_name = "AIN"#num"-AIN"#num2,			\
49762306a36Sopenharmony_ci		.scan_type = {						\
49862306a36Sopenharmony_ci			.sign = 's',					\
49962306a36Sopenharmony_ci			.realbits = bits,				\
50062306a36Sopenharmony_ci			.storagebits = (bits > 8) ? 16 : 8,		\
50162306a36Sopenharmony_ci			.endianness = IIO_BE,				\
50262306a36Sopenharmony_ci		},							\
50362306a36Sopenharmony_ci		.scan_index = si,					\
50462306a36Sopenharmony_ci		.event_spec = ev_spec,					\
50562306a36Sopenharmony_ci		.num_event_specs = num_ev_spec,				\
50662306a36Sopenharmony_ci	}
50762306a36Sopenharmony_ci
50862306a36Sopenharmony_ci#define MAX1363_4X_CHANS(bits, ev_spec, num_ev_spec) {			\
50962306a36Sopenharmony_ci	MAX1363_CHAN_U(0, _s0, 0, bits, ev_spec, num_ev_spec),		\
51062306a36Sopenharmony_ci	MAX1363_CHAN_U(1, _s1, 1, bits, ev_spec, num_ev_spec),		\
51162306a36Sopenharmony_ci	MAX1363_CHAN_U(2, _s2, 2, bits, ev_spec, num_ev_spec),		\
51262306a36Sopenharmony_ci	MAX1363_CHAN_U(3, _s3, 3, bits, ev_spec, num_ev_spec),		\
51362306a36Sopenharmony_ci	MAX1363_CHAN_B(0, 1, d0m1, 4, bits, ev_spec, num_ev_spec),	\
51462306a36Sopenharmony_ci	MAX1363_CHAN_B(2, 3, d2m3, 5, bits, ev_spec, num_ev_spec),	\
51562306a36Sopenharmony_ci	MAX1363_CHAN_B(1, 0, d1m0, 6, bits, ev_spec, num_ev_spec),	\
51662306a36Sopenharmony_ci	MAX1363_CHAN_B(3, 2, d3m2, 7, bits, ev_spec, num_ev_spec),	\
51762306a36Sopenharmony_ci	IIO_CHAN_SOFT_TIMESTAMP(8)					\
51862306a36Sopenharmony_ci	}
51962306a36Sopenharmony_ci
52062306a36Sopenharmony_cistatic const struct iio_chan_spec max1036_channels[] =
52162306a36Sopenharmony_ci	MAX1363_4X_CHANS(8, NULL, 0);
52262306a36Sopenharmony_cistatic const struct iio_chan_spec max1136_channels[] =
52362306a36Sopenharmony_ci	MAX1363_4X_CHANS(10, NULL, 0);
52462306a36Sopenharmony_cistatic const struct iio_chan_spec max1236_channels[] =
52562306a36Sopenharmony_ci	MAX1363_4X_CHANS(12, NULL, 0);
52662306a36Sopenharmony_cistatic const struct iio_chan_spec max1361_channels[] =
52762306a36Sopenharmony_ci	MAX1363_4X_CHANS(10, max1363_events, ARRAY_SIZE(max1363_events));
52862306a36Sopenharmony_cistatic const struct iio_chan_spec max1363_channels[] =
52962306a36Sopenharmony_ci	MAX1363_4X_CHANS(12, max1363_events, ARRAY_SIZE(max1363_events));
53062306a36Sopenharmony_ci
53162306a36Sopenharmony_ci/* Applies to max1236, max1237 */
53262306a36Sopenharmony_cistatic const enum max1363_modes max1236_mode_list[] = {
53362306a36Sopenharmony_ci	_s0, _s1, _s2, _s3,
53462306a36Sopenharmony_ci	s0to1, s0to2, s0to3,
53562306a36Sopenharmony_ci	d0m1, d2m3, d1m0, d3m2,
53662306a36Sopenharmony_ci	d0m1to2m3, d1m0to3m2,
53762306a36Sopenharmony_ci	s2to3,
53862306a36Sopenharmony_ci};
53962306a36Sopenharmony_ci
54062306a36Sopenharmony_ci/* Applies to max1238, max1239 */
54162306a36Sopenharmony_cistatic const enum max1363_modes max1238_mode_list[] = {
54262306a36Sopenharmony_ci	_s0, _s1, _s2, _s3, _s4, _s5, _s6, _s7, _s8, _s9, _s10, _s11,
54362306a36Sopenharmony_ci	s0to1, s0to2, s0to3, s0to4, s0to5, s0to6,
54462306a36Sopenharmony_ci	s0to7, s0to8, s0to9, s0to10, s0to11,
54562306a36Sopenharmony_ci	d0m1, d2m3, d4m5, d6m7, d8m9, d10m11,
54662306a36Sopenharmony_ci	d1m0, d3m2, d5m4, d7m6, d9m8, d11m10,
54762306a36Sopenharmony_ci	d0m1to2m3, d0m1to4m5, d0m1to6m7, d0m1to8m9, d0m1to10m11,
54862306a36Sopenharmony_ci	d1m0to3m2, d1m0to5m4, d1m0to7m6, d1m0to9m8, d1m0to11m10,
54962306a36Sopenharmony_ci	s6to7, s6to8, s6to9, s6to10, s6to11,
55062306a36Sopenharmony_ci	d6m7to8m9, d6m7to10m11, d7m6to9m8, d7m6to11m10,
55162306a36Sopenharmony_ci};
55262306a36Sopenharmony_ci
55362306a36Sopenharmony_ci#define MAX1363_12X_CHANS(bits) {				\
55462306a36Sopenharmony_ci	MAX1363_CHAN_U(0, _s0, 0, bits, NULL, 0),		\
55562306a36Sopenharmony_ci	MAX1363_CHAN_U(1, _s1, 1, bits, NULL, 0),		\
55662306a36Sopenharmony_ci	MAX1363_CHAN_U(2, _s2, 2, bits, NULL, 0),		\
55762306a36Sopenharmony_ci	MAX1363_CHAN_U(3, _s3, 3, bits, NULL, 0),		\
55862306a36Sopenharmony_ci	MAX1363_CHAN_U(4, _s4, 4, bits, NULL, 0),		\
55962306a36Sopenharmony_ci	MAX1363_CHAN_U(5, _s5, 5, bits, NULL, 0),		\
56062306a36Sopenharmony_ci	MAX1363_CHAN_U(6, _s6, 6, bits, NULL, 0),		\
56162306a36Sopenharmony_ci	MAX1363_CHAN_U(7, _s7, 7, bits, NULL, 0),		\
56262306a36Sopenharmony_ci	MAX1363_CHAN_U(8, _s8, 8, bits, NULL, 0),		\
56362306a36Sopenharmony_ci	MAX1363_CHAN_U(9, _s9, 9, bits, NULL, 0),		\
56462306a36Sopenharmony_ci	MAX1363_CHAN_U(10, _s10, 10, bits, NULL, 0),		\
56562306a36Sopenharmony_ci	MAX1363_CHAN_U(11, _s11, 11, bits, NULL, 0),		\
56662306a36Sopenharmony_ci	MAX1363_CHAN_B(0, 1, d0m1, 12, bits, NULL, 0),		\
56762306a36Sopenharmony_ci	MAX1363_CHAN_B(2, 3, d2m3, 13, bits, NULL, 0),		\
56862306a36Sopenharmony_ci	MAX1363_CHAN_B(4, 5, d4m5, 14, bits, NULL, 0),		\
56962306a36Sopenharmony_ci	MAX1363_CHAN_B(6, 7, d6m7, 15, bits, NULL, 0),		\
57062306a36Sopenharmony_ci	MAX1363_CHAN_B(8, 9, d8m9, 16, bits, NULL, 0),		\
57162306a36Sopenharmony_ci	MAX1363_CHAN_B(10, 11, d10m11, 17, bits, NULL, 0),	\
57262306a36Sopenharmony_ci	MAX1363_CHAN_B(1, 0, d1m0, 18, bits, NULL, 0),		\
57362306a36Sopenharmony_ci	MAX1363_CHAN_B(3, 2, d3m2, 19, bits, NULL, 0),		\
57462306a36Sopenharmony_ci	MAX1363_CHAN_B(5, 4, d5m4, 20, bits, NULL, 0),		\
57562306a36Sopenharmony_ci	MAX1363_CHAN_B(7, 6, d7m6, 21, bits, NULL, 0),		\
57662306a36Sopenharmony_ci	MAX1363_CHAN_B(9, 8, d9m8, 22, bits, NULL, 0),		\
57762306a36Sopenharmony_ci	MAX1363_CHAN_B(11, 10, d11m10, 23, bits, NULL, 0),	\
57862306a36Sopenharmony_ci	IIO_CHAN_SOFT_TIMESTAMP(24)				\
57962306a36Sopenharmony_ci	}
58062306a36Sopenharmony_cistatic const struct iio_chan_spec max1038_channels[] = MAX1363_12X_CHANS(8);
58162306a36Sopenharmony_cistatic const struct iio_chan_spec max1138_channels[] = MAX1363_12X_CHANS(10);
58262306a36Sopenharmony_cistatic const struct iio_chan_spec max1238_channels[] = MAX1363_12X_CHANS(12);
58362306a36Sopenharmony_ci
58462306a36Sopenharmony_cistatic const enum max1363_modes max11607_mode_list[] = {
58562306a36Sopenharmony_ci	_s0, _s1, _s2, _s3,
58662306a36Sopenharmony_ci	s0to1, s0to2, s0to3,
58762306a36Sopenharmony_ci	s2to3,
58862306a36Sopenharmony_ci	d0m1, d2m3, d1m0, d3m2,
58962306a36Sopenharmony_ci	d0m1to2m3, d1m0to3m2,
59062306a36Sopenharmony_ci};
59162306a36Sopenharmony_ci
59262306a36Sopenharmony_cistatic const enum max1363_modes max11608_mode_list[] = {
59362306a36Sopenharmony_ci	_s0, _s1, _s2, _s3, _s4, _s5, _s6, _s7,
59462306a36Sopenharmony_ci	s0to1, s0to2, s0to3, s0to4, s0to5, s0to6, s0to7,
59562306a36Sopenharmony_ci	s6to7,
59662306a36Sopenharmony_ci	d0m1, d2m3, d4m5, d6m7,
59762306a36Sopenharmony_ci	d1m0, d3m2, d5m4, d7m6,
59862306a36Sopenharmony_ci	d0m1to2m3, d0m1to4m5, d0m1to6m7,
59962306a36Sopenharmony_ci	d1m0to3m2, d1m0to5m4, d1m0to7m6,
60062306a36Sopenharmony_ci};
60162306a36Sopenharmony_ci
60262306a36Sopenharmony_ci#define MAX1363_8X_CHANS(bits) {			\
60362306a36Sopenharmony_ci	MAX1363_CHAN_U(0, _s0, 0, bits, NULL, 0),	\
60462306a36Sopenharmony_ci	MAX1363_CHAN_U(1, _s1, 1, bits, NULL, 0),	\
60562306a36Sopenharmony_ci	MAX1363_CHAN_U(2, _s2, 2, bits, NULL, 0),	\
60662306a36Sopenharmony_ci	MAX1363_CHAN_U(3, _s3, 3, bits, NULL, 0),	\
60762306a36Sopenharmony_ci	MAX1363_CHAN_U(4, _s4, 4, bits, NULL, 0),	\
60862306a36Sopenharmony_ci	MAX1363_CHAN_U(5, _s5, 5, bits, NULL, 0),	\
60962306a36Sopenharmony_ci	MAX1363_CHAN_U(6, _s6, 6, bits, NULL, 0),	\
61062306a36Sopenharmony_ci	MAX1363_CHAN_U(7, _s7, 7, bits, NULL, 0),	\
61162306a36Sopenharmony_ci	MAX1363_CHAN_B(0, 1, d0m1, 8, bits, NULL, 0),	\
61262306a36Sopenharmony_ci	MAX1363_CHAN_B(2, 3, d2m3, 9, bits, NULL, 0),	\
61362306a36Sopenharmony_ci	MAX1363_CHAN_B(4, 5, d4m5, 10, bits, NULL, 0),	\
61462306a36Sopenharmony_ci	MAX1363_CHAN_B(6, 7, d6m7, 11, bits, NULL, 0),	\
61562306a36Sopenharmony_ci	MAX1363_CHAN_B(1, 0, d1m0, 12, bits, NULL, 0),	\
61662306a36Sopenharmony_ci	MAX1363_CHAN_B(3, 2, d3m2, 13, bits, NULL, 0),	\
61762306a36Sopenharmony_ci	MAX1363_CHAN_B(5, 4, d5m4, 14, bits, NULL, 0),	\
61862306a36Sopenharmony_ci	MAX1363_CHAN_B(7, 6, d7m6, 15, bits, NULL, 0),	\
61962306a36Sopenharmony_ci	IIO_CHAN_SOFT_TIMESTAMP(16)			\
62062306a36Sopenharmony_ci}
62162306a36Sopenharmony_cistatic const struct iio_chan_spec max11602_channels[] = MAX1363_8X_CHANS(8);
62262306a36Sopenharmony_cistatic const struct iio_chan_spec max11608_channels[] = MAX1363_8X_CHANS(10);
62362306a36Sopenharmony_cistatic const struct iio_chan_spec max11614_channels[] = MAX1363_8X_CHANS(12);
62462306a36Sopenharmony_ci
62562306a36Sopenharmony_cistatic const enum max1363_modes max11644_mode_list[] = {
62662306a36Sopenharmony_ci	_s0, _s1, s0to1, d0m1, d1m0,
62762306a36Sopenharmony_ci};
62862306a36Sopenharmony_ci
62962306a36Sopenharmony_ci#define MAX1363_2X_CHANS(bits) {			\
63062306a36Sopenharmony_ci	MAX1363_CHAN_U(0, _s0, 0, bits, NULL, 0),	\
63162306a36Sopenharmony_ci	MAX1363_CHAN_U(1, _s1, 1, bits, NULL, 0),	\
63262306a36Sopenharmony_ci	MAX1363_CHAN_B(0, 1, d0m1, 2, bits, NULL, 0),	\
63362306a36Sopenharmony_ci	MAX1363_CHAN_B(1, 0, d1m0, 3, bits, NULL, 0),	\
63462306a36Sopenharmony_ci	IIO_CHAN_SOFT_TIMESTAMP(4)			\
63562306a36Sopenharmony_ci	}
63662306a36Sopenharmony_ci
63762306a36Sopenharmony_cistatic const struct iio_chan_spec max11646_channels[] = MAX1363_2X_CHANS(10);
63862306a36Sopenharmony_cistatic const struct iio_chan_spec max11644_channels[] = MAX1363_2X_CHANS(12);
63962306a36Sopenharmony_ci
64062306a36Sopenharmony_cienum { max1361,
64162306a36Sopenharmony_ci       max1362,
64262306a36Sopenharmony_ci       max1363,
64362306a36Sopenharmony_ci       max1364,
64462306a36Sopenharmony_ci       max1036,
64562306a36Sopenharmony_ci       max1037,
64662306a36Sopenharmony_ci       max1038,
64762306a36Sopenharmony_ci       max1039,
64862306a36Sopenharmony_ci       max1136,
64962306a36Sopenharmony_ci       max1137,
65062306a36Sopenharmony_ci       max1138,
65162306a36Sopenharmony_ci       max1139,
65262306a36Sopenharmony_ci       max1236,
65362306a36Sopenharmony_ci       max1237,
65462306a36Sopenharmony_ci       max1238,
65562306a36Sopenharmony_ci       max1239,
65662306a36Sopenharmony_ci       max11600,
65762306a36Sopenharmony_ci       max11601,
65862306a36Sopenharmony_ci       max11602,
65962306a36Sopenharmony_ci       max11603,
66062306a36Sopenharmony_ci       max11604,
66162306a36Sopenharmony_ci       max11605,
66262306a36Sopenharmony_ci       max11606,
66362306a36Sopenharmony_ci       max11607,
66462306a36Sopenharmony_ci       max11608,
66562306a36Sopenharmony_ci       max11609,
66662306a36Sopenharmony_ci       max11610,
66762306a36Sopenharmony_ci       max11611,
66862306a36Sopenharmony_ci       max11612,
66962306a36Sopenharmony_ci       max11613,
67062306a36Sopenharmony_ci       max11614,
67162306a36Sopenharmony_ci       max11615,
67262306a36Sopenharmony_ci       max11616,
67362306a36Sopenharmony_ci       max11617,
67462306a36Sopenharmony_ci       max11644,
67562306a36Sopenharmony_ci       max11645,
67662306a36Sopenharmony_ci       max11646,
67762306a36Sopenharmony_ci       max11647
67862306a36Sopenharmony_ci};
67962306a36Sopenharmony_ci
68062306a36Sopenharmony_cistatic const int max1363_monitor_speeds[] = { 133000, 665000, 33300, 16600,
68162306a36Sopenharmony_ci					      8300, 4200, 2000, 1000 };
68262306a36Sopenharmony_ci
68362306a36Sopenharmony_cistatic ssize_t max1363_monitor_show_freq(struct device *dev,
68462306a36Sopenharmony_ci					struct device_attribute *attr,
68562306a36Sopenharmony_ci					char *buf)
68662306a36Sopenharmony_ci{
68762306a36Sopenharmony_ci	struct max1363_state *st = iio_priv(dev_to_iio_dev(dev));
68862306a36Sopenharmony_ci	return sprintf(buf, "%d\n", max1363_monitor_speeds[st->monitor_speed]);
68962306a36Sopenharmony_ci}
69062306a36Sopenharmony_ci
69162306a36Sopenharmony_cistatic ssize_t max1363_monitor_store_freq(struct device *dev,
69262306a36Sopenharmony_ci					struct device_attribute *attr,
69362306a36Sopenharmony_ci					const char *buf,
69462306a36Sopenharmony_ci					size_t len)
69562306a36Sopenharmony_ci{
69662306a36Sopenharmony_ci	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
69762306a36Sopenharmony_ci	struct max1363_state *st = iio_priv(indio_dev);
69862306a36Sopenharmony_ci	int i, ret;
69962306a36Sopenharmony_ci	unsigned long val;
70062306a36Sopenharmony_ci	bool found = false;
70162306a36Sopenharmony_ci
70262306a36Sopenharmony_ci	ret = kstrtoul(buf, 10, &val);
70362306a36Sopenharmony_ci	if (ret)
70462306a36Sopenharmony_ci		return -EINVAL;
70562306a36Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(max1363_monitor_speeds); i++)
70662306a36Sopenharmony_ci		if (val == max1363_monitor_speeds[i]) {
70762306a36Sopenharmony_ci			found = true;
70862306a36Sopenharmony_ci			break;
70962306a36Sopenharmony_ci		}
71062306a36Sopenharmony_ci	if (!found)
71162306a36Sopenharmony_ci		return -EINVAL;
71262306a36Sopenharmony_ci
71362306a36Sopenharmony_ci	mutex_lock(&st->lock);
71462306a36Sopenharmony_ci	st->monitor_speed = i;
71562306a36Sopenharmony_ci	mutex_unlock(&st->lock);
71662306a36Sopenharmony_ci
71762306a36Sopenharmony_ci	return 0;
71862306a36Sopenharmony_ci}
71962306a36Sopenharmony_ci
72062306a36Sopenharmony_cistatic IIO_DEV_ATTR_SAMP_FREQ(S_IRUGO | S_IWUSR,
72162306a36Sopenharmony_ci			max1363_monitor_show_freq,
72262306a36Sopenharmony_ci			max1363_monitor_store_freq);
72362306a36Sopenharmony_ci
72462306a36Sopenharmony_cistatic IIO_CONST_ATTR(sampling_frequency_available,
72562306a36Sopenharmony_ci		"133000 665000 33300 16600 8300 4200 2000 1000");
72662306a36Sopenharmony_ci
72762306a36Sopenharmony_cistatic int max1363_read_thresh(struct iio_dev *indio_dev,
72862306a36Sopenharmony_ci	const struct iio_chan_spec *chan, enum iio_event_type type,
72962306a36Sopenharmony_ci	enum iio_event_direction dir, enum iio_event_info info, int *val,
73062306a36Sopenharmony_ci	int *val2)
73162306a36Sopenharmony_ci{
73262306a36Sopenharmony_ci	struct max1363_state *st = iio_priv(indio_dev);
73362306a36Sopenharmony_ci	if (dir == IIO_EV_DIR_FALLING)
73462306a36Sopenharmony_ci		*val = st->thresh_low[chan->channel];
73562306a36Sopenharmony_ci	else
73662306a36Sopenharmony_ci		*val = st->thresh_high[chan->channel];
73762306a36Sopenharmony_ci	return IIO_VAL_INT;
73862306a36Sopenharmony_ci}
73962306a36Sopenharmony_ci
74062306a36Sopenharmony_cistatic int max1363_write_thresh(struct iio_dev *indio_dev,
74162306a36Sopenharmony_ci	const struct iio_chan_spec *chan, enum iio_event_type type,
74262306a36Sopenharmony_ci	enum iio_event_direction dir, enum iio_event_info info, int val,
74362306a36Sopenharmony_ci	int val2)
74462306a36Sopenharmony_ci{
74562306a36Sopenharmony_ci	struct max1363_state *st = iio_priv(indio_dev);
74662306a36Sopenharmony_ci	/* make it handle signed correctly as well */
74762306a36Sopenharmony_ci	switch (st->chip_info->bits) {
74862306a36Sopenharmony_ci	case 10:
74962306a36Sopenharmony_ci		if (val > 0x3FF)
75062306a36Sopenharmony_ci			return -EINVAL;
75162306a36Sopenharmony_ci		break;
75262306a36Sopenharmony_ci	case 12:
75362306a36Sopenharmony_ci		if (val > 0xFFF)
75462306a36Sopenharmony_ci			return -EINVAL;
75562306a36Sopenharmony_ci		break;
75662306a36Sopenharmony_ci	}
75762306a36Sopenharmony_ci
75862306a36Sopenharmony_ci	switch (dir) {
75962306a36Sopenharmony_ci	case IIO_EV_DIR_FALLING:
76062306a36Sopenharmony_ci		st->thresh_low[chan->channel] = val;
76162306a36Sopenharmony_ci		break;
76262306a36Sopenharmony_ci	case IIO_EV_DIR_RISING:
76362306a36Sopenharmony_ci		st->thresh_high[chan->channel] = val;
76462306a36Sopenharmony_ci		break;
76562306a36Sopenharmony_ci	default:
76662306a36Sopenharmony_ci		return -EINVAL;
76762306a36Sopenharmony_ci	}
76862306a36Sopenharmony_ci
76962306a36Sopenharmony_ci	return 0;
77062306a36Sopenharmony_ci}
77162306a36Sopenharmony_ci
77262306a36Sopenharmony_cistatic const u64 max1363_event_codes[] = {
77362306a36Sopenharmony_ci	IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 0,
77462306a36Sopenharmony_ci			     IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING),
77562306a36Sopenharmony_ci	IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 1,
77662306a36Sopenharmony_ci			     IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING),
77762306a36Sopenharmony_ci	IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 2,
77862306a36Sopenharmony_ci			     IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING),
77962306a36Sopenharmony_ci	IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 3,
78062306a36Sopenharmony_ci			     IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING),
78162306a36Sopenharmony_ci	IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 0,
78262306a36Sopenharmony_ci			     IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING),
78362306a36Sopenharmony_ci	IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 1,
78462306a36Sopenharmony_ci			     IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING),
78562306a36Sopenharmony_ci	IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 2,
78662306a36Sopenharmony_ci			     IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING),
78762306a36Sopenharmony_ci	IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 3,
78862306a36Sopenharmony_ci			     IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING),
78962306a36Sopenharmony_ci};
79062306a36Sopenharmony_ci
79162306a36Sopenharmony_cistatic irqreturn_t max1363_event_handler(int irq, void *private)
79262306a36Sopenharmony_ci{
79362306a36Sopenharmony_ci	struct iio_dev *indio_dev = private;
79462306a36Sopenharmony_ci	struct max1363_state *st = iio_priv(indio_dev);
79562306a36Sopenharmony_ci	s64 timestamp = iio_get_time_ns(indio_dev);
79662306a36Sopenharmony_ci	unsigned long mask, loc;
79762306a36Sopenharmony_ci	u8 rx;
79862306a36Sopenharmony_ci	u8 tx[2] = { st->setupbyte,
79962306a36Sopenharmony_ci		     MAX1363_MON_INT_ENABLE | (st->monitor_speed << 1) | 0xF0 };
80062306a36Sopenharmony_ci
80162306a36Sopenharmony_ci	st->recv(st->client, &rx, 1);
80262306a36Sopenharmony_ci	mask = rx;
80362306a36Sopenharmony_ci	for_each_set_bit(loc, &mask, 8)
80462306a36Sopenharmony_ci		iio_push_event(indio_dev, max1363_event_codes[loc], timestamp);
80562306a36Sopenharmony_ci	st->send(st->client, tx, 2);
80662306a36Sopenharmony_ci
80762306a36Sopenharmony_ci	return IRQ_HANDLED;
80862306a36Sopenharmony_ci}
80962306a36Sopenharmony_ci
81062306a36Sopenharmony_cistatic int max1363_read_event_config(struct iio_dev *indio_dev,
81162306a36Sopenharmony_ci	const struct iio_chan_spec *chan, enum iio_event_type type,
81262306a36Sopenharmony_ci	enum iio_event_direction dir)
81362306a36Sopenharmony_ci{
81462306a36Sopenharmony_ci	struct max1363_state *st = iio_priv(indio_dev);
81562306a36Sopenharmony_ci	int val;
81662306a36Sopenharmony_ci	int number = chan->channel;
81762306a36Sopenharmony_ci
81862306a36Sopenharmony_ci	mutex_lock(&st->lock);
81962306a36Sopenharmony_ci	if (dir == IIO_EV_DIR_FALLING)
82062306a36Sopenharmony_ci		val = (1 << number) & st->mask_low;
82162306a36Sopenharmony_ci	else
82262306a36Sopenharmony_ci		val = (1 << number) & st->mask_high;
82362306a36Sopenharmony_ci	mutex_unlock(&st->lock);
82462306a36Sopenharmony_ci
82562306a36Sopenharmony_ci	return val;
82662306a36Sopenharmony_ci}
82762306a36Sopenharmony_ci
82862306a36Sopenharmony_cistatic int max1363_monitor_mode_update(struct max1363_state *st, int enabled)
82962306a36Sopenharmony_ci{
83062306a36Sopenharmony_ci	u8 *tx_buf;
83162306a36Sopenharmony_ci	int ret, i = 3, j;
83262306a36Sopenharmony_ci	unsigned long numelements;
83362306a36Sopenharmony_ci	int len;
83462306a36Sopenharmony_ci	const long *modemask;
83562306a36Sopenharmony_ci
83662306a36Sopenharmony_ci	if (!enabled) {
83762306a36Sopenharmony_ci		/* transition to buffered capture is not currently supported */
83862306a36Sopenharmony_ci		st->setupbyte &= ~MAX1363_SETUP_MONITOR_SETUP;
83962306a36Sopenharmony_ci		st->configbyte &= ~MAX1363_SCAN_MASK;
84062306a36Sopenharmony_ci		st->monitor_on = false;
84162306a36Sopenharmony_ci		return max1363_write_basic_config(st);
84262306a36Sopenharmony_ci	}
84362306a36Sopenharmony_ci
84462306a36Sopenharmony_ci	/* Ensure we are in the relevant mode */
84562306a36Sopenharmony_ci	st->setupbyte |= MAX1363_SETUP_MONITOR_SETUP;
84662306a36Sopenharmony_ci	st->configbyte &= ~(MAX1363_CHANNEL_SEL_MASK
84762306a36Sopenharmony_ci			    | MAX1363_SCAN_MASK
84862306a36Sopenharmony_ci			| MAX1363_SE_DE_MASK);
84962306a36Sopenharmony_ci	st->configbyte |= MAX1363_CONFIG_SCAN_MONITOR_MODE;
85062306a36Sopenharmony_ci	if ((st->mask_low | st->mask_high) & 0x0F) {
85162306a36Sopenharmony_ci		st->configbyte |= max1363_mode_table[s0to3].conf;
85262306a36Sopenharmony_ci		modemask = max1363_mode_table[s0to3].modemask;
85362306a36Sopenharmony_ci	} else if ((st->mask_low | st->mask_high) & 0x30) {
85462306a36Sopenharmony_ci		st->configbyte |= max1363_mode_table[d0m1to2m3].conf;
85562306a36Sopenharmony_ci		modemask = max1363_mode_table[d0m1to2m3].modemask;
85662306a36Sopenharmony_ci	} else {
85762306a36Sopenharmony_ci		st->configbyte |= max1363_mode_table[d1m0to3m2].conf;
85862306a36Sopenharmony_ci		modemask = max1363_mode_table[d1m0to3m2].modemask;
85962306a36Sopenharmony_ci	}
86062306a36Sopenharmony_ci	numelements = bitmap_weight(modemask, MAX1363_MAX_CHANNELS);
86162306a36Sopenharmony_ci	len = 3 * numelements + 3;
86262306a36Sopenharmony_ci	tx_buf = kmalloc(len, GFP_KERNEL);
86362306a36Sopenharmony_ci	if (!tx_buf) {
86462306a36Sopenharmony_ci		ret = -ENOMEM;
86562306a36Sopenharmony_ci		goto error_ret;
86662306a36Sopenharmony_ci	}
86762306a36Sopenharmony_ci	tx_buf[0] = st->configbyte;
86862306a36Sopenharmony_ci	tx_buf[1] = st->setupbyte;
86962306a36Sopenharmony_ci	tx_buf[2] = (st->monitor_speed << 1);
87062306a36Sopenharmony_ci
87162306a36Sopenharmony_ci	/*
87262306a36Sopenharmony_ci	 * So we need to do yet another bit of nefarious scan mode
87362306a36Sopenharmony_ci	 * setup to match what we need.
87462306a36Sopenharmony_ci	 */
87562306a36Sopenharmony_ci	for (j = 0; j < 8; j++)
87662306a36Sopenharmony_ci		if (test_bit(j, modemask)) {
87762306a36Sopenharmony_ci			/* Establish the mode is in the scan */
87862306a36Sopenharmony_ci			if (st->mask_low & (1 << j)) {
87962306a36Sopenharmony_ci				tx_buf[i] = (st->thresh_low[j] >> 4) & 0xFF;
88062306a36Sopenharmony_ci				tx_buf[i + 1] = (st->thresh_low[j] << 4) & 0xF0;
88162306a36Sopenharmony_ci			} else if (j < 4) {
88262306a36Sopenharmony_ci				tx_buf[i] = 0;
88362306a36Sopenharmony_ci				tx_buf[i + 1] = 0;
88462306a36Sopenharmony_ci			} else {
88562306a36Sopenharmony_ci				tx_buf[i] = 0x80;
88662306a36Sopenharmony_ci				tx_buf[i + 1] = 0;
88762306a36Sopenharmony_ci			}
88862306a36Sopenharmony_ci			if (st->mask_high & (1 << j)) {
88962306a36Sopenharmony_ci				tx_buf[i + 1] |=
89062306a36Sopenharmony_ci					(st->thresh_high[j] >> 8) & 0x0F;
89162306a36Sopenharmony_ci				tx_buf[i + 2] = st->thresh_high[j] & 0xFF;
89262306a36Sopenharmony_ci			} else if (j < 4) {
89362306a36Sopenharmony_ci				tx_buf[i + 1] |= 0x0F;
89462306a36Sopenharmony_ci				tx_buf[i + 2] = 0xFF;
89562306a36Sopenharmony_ci			} else {
89662306a36Sopenharmony_ci				tx_buf[i + 1] |= 0x07;
89762306a36Sopenharmony_ci				tx_buf[i + 2] = 0xFF;
89862306a36Sopenharmony_ci			}
89962306a36Sopenharmony_ci			i += 3;
90062306a36Sopenharmony_ci		}
90162306a36Sopenharmony_ci
90262306a36Sopenharmony_ci
90362306a36Sopenharmony_ci	ret = st->send(st->client, tx_buf, len);
90462306a36Sopenharmony_ci	if (ret < 0)
90562306a36Sopenharmony_ci		goto error_ret;
90662306a36Sopenharmony_ci	if (ret != len) {
90762306a36Sopenharmony_ci		ret = -EIO;
90862306a36Sopenharmony_ci		goto error_ret;
90962306a36Sopenharmony_ci	}
91062306a36Sopenharmony_ci
91162306a36Sopenharmony_ci	/*
91262306a36Sopenharmony_ci	 * Now that we hopefully have sensible thresholds in place it is
91362306a36Sopenharmony_ci	 * time to turn the interrupts on.
91462306a36Sopenharmony_ci	 * It is unclear from the data sheet if this should be necessary
91562306a36Sopenharmony_ci	 * (i.e. whether monitor mode setup is atomic) but it appears to
91662306a36Sopenharmony_ci	 * be in practice.
91762306a36Sopenharmony_ci	 */
91862306a36Sopenharmony_ci	tx_buf[0] = st->setupbyte;
91962306a36Sopenharmony_ci	tx_buf[1] = MAX1363_MON_INT_ENABLE | (st->monitor_speed << 1) | 0xF0;
92062306a36Sopenharmony_ci	ret = st->send(st->client, tx_buf, 2);
92162306a36Sopenharmony_ci	if (ret < 0)
92262306a36Sopenharmony_ci		goto error_ret;
92362306a36Sopenharmony_ci	if (ret != 2) {
92462306a36Sopenharmony_ci		ret = -EIO;
92562306a36Sopenharmony_ci		goto error_ret;
92662306a36Sopenharmony_ci	}
92762306a36Sopenharmony_ci	ret = 0;
92862306a36Sopenharmony_ci	st->monitor_on = true;
92962306a36Sopenharmony_cierror_ret:
93062306a36Sopenharmony_ci
93162306a36Sopenharmony_ci	kfree(tx_buf);
93262306a36Sopenharmony_ci
93362306a36Sopenharmony_ci	return ret;
93462306a36Sopenharmony_ci}
93562306a36Sopenharmony_ci
93662306a36Sopenharmony_ci/*
93762306a36Sopenharmony_ci * To keep this manageable we always use one of 3 scan modes.
93862306a36Sopenharmony_ci * Scan 0...3, 0-1,2-3 and 1-0,3-2
93962306a36Sopenharmony_ci */
94062306a36Sopenharmony_ci
94162306a36Sopenharmony_cistatic inline int __max1363_check_event_mask(int thismask, int checkmask)
94262306a36Sopenharmony_ci{
94362306a36Sopenharmony_ci	int ret = 0;
94462306a36Sopenharmony_ci	/* Is it unipolar */
94562306a36Sopenharmony_ci	if (thismask < 4) {
94662306a36Sopenharmony_ci		if (checkmask & ~0x0F) {
94762306a36Sopenharmony_ci			ret = -EBUSY;
94862306a36Sopenharmony_ci			goto error_ret;
94962306a36Sopenharmony_ci		}
95062306a36Sopenharmony_ci	} else if (thismask < 6) {
95162306a36Sopenharmony_ci		if (checkmask & ~0x30) {
95262306a36Sopenharmony_ci			ret = -EBUSY;
95362306a36Sopenharmony_ci			goto error_ret;
95462306a36Sopenharmony_ci		}
95562306a36Sopenharmony_ci	} else if (checkmask & ~0xC0)
95662306a36Sopenharmony_ci		ret = -EBUSY;
95762306a36Sopenharmony_cierror_ret:
95862306a36Sopenharmony_ci	return ret;
95962306a36Sopenharmony_ci}
96062306a36Sopenharmony_ci
96162306a36Sopenharmony_cistatic int max1363_write_event_config(struct iio_dev *indio_dev,
96262306a36Sopenharmony_ci	const struct iio_chan_spec *chan, enum iio_event_type type,
96362306a36Sopenharmony_ci	enum iio_event_direction dir, int state)
96462306a36Sopenharmony_ci{
96562306a36Sopenharmony_ci	int ret = 0;
96662306a36Sopenharmony_ci	struct max1363_state *st = iio_priv(indio_dev);
96762306a36Sopenharmony_ci	u16 unifiedmask;
96862306a36Sopenharmony_ci	int number = chan->channel;
96962306a36Sopenharmony_ci
97062306a36Sopenharmony_ci	ret = iio_device_claim_direct_mode(indio_dev);
97162306a36Sopenharmony_ci	if (ret)
97262306a36Sopenharmony_ci		return ret;
97362306a36Sopenharmony_ci	mutex_lock(&st->lock);
97462306a36Sopenharmony_ci
97562306a36Sopenharmony_ci	unifiedmask = st->mask_low | st->mask_high;
97662306a36Sopenharmony_ci	if (dir == IIO_EV_DIR_FALLING) {
97762306a36Sopenharmony_ci
97862306a36Sopenharmony_ci		if (state == 0)
97962306a36Sopenharmony_ci			st->mask_low &= ~(1 << number);
98062306a36Sopenharmony_ci		else {
98162306a36Sopenharmony_ci			ret = __max1363_check_event_mask((1 << number),
98262306a36Sopenharmony_ci							 unifiedmask);
98362306a36Sopenharmony_ci			if (ret)
98462306a36Sopenharmony_ci				goto error_ret;
98562306a36Sopenharmony_ci			st->mask_low |= (1 << number);
98662306a36Sopenharmony_ci		}
98762306a36Sopenharmony_ci	} else {
98862306a36Sopenharmony_ci		if (state == 0)
98962306a36Sopenharmony_ci			st->mask_high &= ~(1 << number);
99062306a36Sopenharmony_ci		else {
99162306a36Sopenharmony_ci			ret = __max1363_check_event_mask((1 << number),
99262306a36Sopenharmony_ci							 unifiedmask);
99362306a36Sopenharmony_ci			if (ret)
99462306a36Sopenharmony_ci				goto error_ret;
99562306a36Sopenharmony_ci			st->mask_high |= (1 << number);
99662306a36Sopenharmony_ci		}
99762306a36Sopenharmony_ci	}
99862306a36Sopenharmony_ci
99962306a36Sopenharmony_ci	max1363_monitor_mode_update(st, !!(st->mask_high | st->mask_low));
100062306a36Sopenharmony_cierror_ret:
100162306a36Sopenharmony_ci	mutex_unlock(&st->lock);
100262306a36Sopenharmony_ci	iio_device_release_direct_mode(indio_dev);
100362306a36Sopenharmony_ci
100462306a36Sopenharmony_ci	return ret;
100562306a36Sopenharmony_ci}
100662306a36Sopenharmony_ci
100762306a36Sopenharmony_ci/*
100862306a36Sopenharmony_ci * As with scan_elements, only certain sets of these can
100962306a36Sopenharmony_ci * be combined.
101062306a36Sopenharmony_ci */
101162306a36Sopenharmony_cistatic struct attribute *max1363_event_attributes[] = {
101262306a36Sopenharmony_ci	&iio_dev_attr_sampling_frequency.dev_attr.attr,
101362306a36Sopenharmony_ci	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
101462306a36Sopenharmony_ci	NULL,
101562306a36Sopenharmony_ci};
101662306a36Sopenharmony_ci
101762306a36Sopenharmony_cistatic const struct attribute_group max1363_event_attribute_group = {
101862306a36Sopenharmony_ci	.attrs = max1363_event_attributes,
101962306a36Sopenharmony_ci};
102062306a36Sopenharmony_ci
102162306a36Sopenharmony_cistatic int max1363_update_scan_mode(struct iio_dev *indio_dev,
102262306a36Sopenharmony_ci				    const unsigned long *scan_mask)
102362306a36Sopenharmony_ci{
102462306a36Sopenharmony_ci	struct max1363_state *st = iio_priv(indio_dev);
102562306a36Sopenharmony_ci
102662306a36Sopenharmony_ci	/*
102762306a36Sopenharmony_ci	 * Need to figure out the current mode based upon the requested
102862306a36Sopenharmony_ci	 * scan mask in iio_dev
102962306a36Sopenharmony_ci	 */
103062306a36Sopenharmony_ci	st->current_mode = max1363_match_mode(scan_mask, st->chip_info);
103162306a36Sopenharmony_ci	if (!st->current_mode)
103262306a36Sopenharmony_ci		return -EINVAL;
103362306a36Sopenharmony_ci	max1363_set_scan_mode(st);
103462306a36Sopenharmony_ci	return 0;
103562306a36Sopenharmony_ci}
103662306a36Sopenharmony_ci
103762306a36Sopenharmony_cistatic const struct iio_info max1238_info = {
103862306a36Sopenharmony_ci	.read_raw = &max1363_read_raw,
103962306a36Sopenharmony_ci	.update_scan_mode = &max1363_update_scan_mode,
104062306a36Sopenharmony_ci};
104162306a36Sopenharmony_ci
104262306a36Sopenharmony_cistatic const struct iio_info max1363_info = {
104362306a36Sopenharmony_ci	.read_event_value = &max1363_read_thresh,
104462306a36Sopenharmony_ci	.write_event_value = &max1363_write_thresh,
104562306a36Sopenharmony_ci	.read_event_config = &max1363_read_event_config,
104662306a36Sopenharmony_ci	.write_event_config = &max1363_write_event_config,
104762306a36Sopenharmony_ci	.read_raw = &max1363_read_raw,
104862306a36Sopenharmony_ci	.update_scan_mode = &max1363_update_scan_mode,
104962306a36Sopenharmony_ci	.event_attrs = &max1363_event_attribute_group,
105062306a36Sopenharmony_ci};
105162306a36Sopenharmony_ci
105262306a36Sopenharmony_ci/* max1363 and max1368 tested - rest from data sheet */
105362306a36Sopenharmony_cistatic const struct max1363_chip_info max1363_chip_info_tbl[] = {
105462306a36Sopenharmony_ci	[max1361] = {
105562306a36Sopenharmony_ci		.bits = 10,
105662306a36Sopenharmony_ci		.int_vref_mv = 2048,
105762306a36Sopenharmony_ci		.mode_list = max1363_mode_list,
105862306a36Sopenharmony_ci		.num_modes = ARRAY_SIZE(max1363_mode_list),
105962306a36Sopenharmony_ci		.default_mode = s0to3,
106062306a36Sopenharmony_ci		.channels = max1361_channels,
106162306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(max1361_channels),
106262306a36Sopenharmony_ci		.info = &max1363_info,
106362306a36Sopenharmony_ci	},
106462306a36Sopenharmony_ci	[max1362] = {
106562306a36Sopenharmony_ci		.bits = 10,
106662306a36Sopenharmony_ci		.int_vref_mv = 4096,
106762306a36Sopenharmony_ci		.mode_list = max1363_mode_list,
106862306a36Sopenharmony_ci		.num_modes = ARRAY_SIZE(max1363_mode_list),
106962306a36Sopenharmony_ci		.default_mode = s0to3,
107062306a36Sopenharmony_ci		.channels = max1361_channels,
107162306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(max1361_channels),
107262306a36Sopenharmony_ci		.info = &max1363_info,
107362306a36Sopenharmony_ci	},
107462306a36Sopenharmony_ci	[max1363] = {
107562306a36Sopenharmony_ci		.bits = 12,
107662306a36Sopenharmony_ci		.int_vref_mv = 2048,
107762306a36Sopenharmony_ci		.mode_list = max1363_mode_list,
107862306a36Sopenharmony_ci		.num_modes = ARRAY_SIZE(max1363_mode_list),
107962306a36Sopenharmony_ci		.default_mode = s0to3,
108062306a36Sopenharmony_ci		.channels = max1363_channels,
108162306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(max1363_channels),
108262306a36Sopenharmony_ci		.info = &max1363_info,
108362306a36Sopenharmony_ci	},
108462306a36Sopenharmony_ci	[max1364] = {
108562306a36Sopenharmony_ci		.bits = 12,
108662306a36Sopenharmony_ci		.int_vref_mv = 4096,
108762306a36Sopenharmony_ci		.mode_list = max1363_mode_list,
108862306a36Sopenharmony_ci		.num_modes = ARRAY_SIZE(max1363_mode_list),
108962306a36Sopenharmony_ci		.default_mode = s0to3,
109062306a36Sopenharmony_ci		.channels = max1363_channels,
109162306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(max1363_channels),
109262306a36Sopenharmony_ci		.info = &max1363_info,
109362306a36Sopenharmony_ci	},
109462306a36Sopenharmony_ci	[max1036] = {
109562306a36Sopenharmony_ci		.bits = 8,
109662306a36Sopenharmony_ci		.int_vref_mv = 4096,
109762306a36Sopenharmony_ci		.mode_list = max1236_mode_list,
109862306a36Sopenharmony_ci		.num_modes = ARRAY_SIZE(max1236_mode_list),
109962306a36Sopenharmony_ci		.default_mode = s0to3,
110062306a36Sopenharmony_ci		.info = &max1238_info,
110162306a36Sopenharmony_ci		.channels = max1036_channels,
110262306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(max1036_channels),
110362306a36Sopenharmony_ci	},
110462306a36Sopenharmony_ci	[max1037] = {
110562306a36Sopenharmony_ci		.bits = 8,
110662306a36Sopenharmony_ci		.int_vref_mv = 2048,
110762306a36Sopenharmony_ci		.mode_list = max1236_mode_list,
110862306a36Sopenharmony_ci		.num_modes = ARRAY_SIZE(max1236_mode_list),
110962306a36Sopenharmony_ci		.default_mode = s0to3,
111062306a36Sopenharmony_ci		.info = &max1238_info,
111162306a36Sopenharmony_ci		.channels = max1036_channels,
111262306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(max1036_channels),
111362306a36Sopenharmony_ci	},
111462306a36Sopenharmony_ci	[max1038] = {
111562306a36Sopenharmony_ci		.bits = 8,
111662306a36Sopenharmony_ci		.int_vref_mv = 4096,
111762306a36Sopenharmony_ci		.mode_list = max1238_mode_list,
111862306a36Sopenharmony_ci		.num_modes = ARRAY_SIZE(max1238_mode_list),
111962306a36Sopenharmony_ci		.default_mode = s0to11,
112062306a36Sopenharmony_ci		.info = &max1238_info,
112162306a36Sopenharmony_ci		.channels = max1038_channels,
112262306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(max1038_channels),
112362306a36Sopenharmony_ci	},
112462306a36Sopenharmony_ci	[max1039] = {
112562306a36Sopenharmony_ci		.bits = 8,
112662306a36Sopenharmony_ci		.int_vref_mv = 2048,
112762306a36Sopenharmony_ci		.mode_list = max1238_mode_list,
112862306a36Sopenharmony_ci		.num_modes = ARRAY_SIZE(max1238_mode_list),
112962306a36Sopenharmony_ci		.default_mode = s0to11,
113062306a36Sopenharmony_ci		.info = &max1238_info,
113162306a36Sopenharmony_ci		.channels = max1038_channels,
113262306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(max1038_channels),
113362306a36Sopenharmony_ci	},
113462306a36Sopenharmony_ci	[max1136] = {
113562306a36Sopenharmony_ci		.bits = 10,
113662306a36Sopenharmony_ci		.int_vref_mv = 4096,
113762306a36Sopenharmony_ci		.mode_list = max1236_mode_list,
113862306a36Sopenharmony_ci		.num_modes = ARRAY_SIZE(max1236_mode_list),
113962306a36Sopenharmony_ci		.default_mode = s0to3,
114062306a36Sopenharmony_ci		.info = &max1238_info,
114162306a36Sopenharmony_ci		.channels = max1136_channels,
114262306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(max1136_channels),
114362306a36Sopenharmony_ci	},
114462306a36Sopenharmony_ci	[max1137] = {
114562306a36Sopenharmony_ci		.bits = 10,
114662306a36Sopenharmony_ci		.int_vref_mv = 2048,
114762306a36Sopenharmony_ci		.mode_list = max1236_mode_list,
114862306a36Sopenharmony_ci		.num_modes = ARRAY_SIZE(max1236_mode_list),
114962306a36Sopenharmony_ci		.default_mode = s0to3,
115062306a36Sopenharmony_ci		.info = &max1238_info,
115162306a36Sopenharmony_ci		.channels = max1136_channels,
115262306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(max1136_channels),
115362306a36Sopenharmony_ci	},
115462306a36Sopenharmony_ci	[max1138] = {
115562306a36Sopenharmony_ci		.bits = 10,
115662306a36Sopenharmony_ci		.int_vref_mv = 4096,
115762306a36Sopenharmony_ci		.mode_list = max1238_mode_list,
115862306a36Sopenharmony_ci		.num_modes = ARRAY_SIZE(max1238_mode_list),
115962306a36Sopenharmony_ci		.default_mode = s0to11,
116062306a36Sopenharmony_ci		.info = &max1238_info,
116162306a36Sopenharmony_ci		.channels = max1138_channels,
116262306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(max1138_channels),
116362306a36Sopenharmony_ci	},
116462306a36Sopenharmony_ci	[max1139] = {
116562306a36Sopenharmony_ci		.bits = 10,
116662306a36Sopenharmony_ci		.int_vref_mv = 2048,
116762306a36Sopenharmony_ci		.mode_list = max1238_mode_list,
116862306a36Sopenharmony_ci		.num_modes = ARRAY_SIZE(max1238_mode_list),
116962306a36Sopenharmony_ci		.default_mode = s0to11,
117062306a36Sopenharmony_ci		.info = &max1238_info,
117162306a36Sopenharmony_ci		.channels = max1138_channels,
117262306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(max1138_channels),
117362306a36Sopenharmony_ci	},
117462306a36Sopenharmony_ci	[max1236] = {
117562306a36Sopenharmony_ci		.bits = 12,
117662306a36Sopenharmony_ci		.int_vref_mv = 4096,
117762306a36Sopenharmony_ci		.mode_list = max1236_mode_list,
117862306a36Sopenharmony_ci		.num_modes = ARRAY_SIZE(max1236_mode_list),
117962306a36Sopenharmony_ci		.default_mode = s0to3,
118062306a36Sopenharmony_ci		.info = &max1238_info,
118162306a36Sopenharmony_ci		.channels = max1236_channels,
118262306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(max1236_channels),
118362306a36Sopenharmony_ci	},
118462306a36Sopenharmony_ci	[max1237] = {
118562306a36Sopenharmony_ci		.bits = 12,
118662306a36Sopenharmony_ci		.int_vref_mv = 2048,
118762306a36Sopenharmony_ci		.mode_list = max1236_mode_list,
118862306a36Sopenharmony_ci		.num_modes = ARRAY_SIZE(max1236_mode_list),
118962306a36Sopenharmony_ci		.default_mode = s0to3,
119062306a36Sopenharmony_ci		.info = &max1238_info,
119162306a36Sopenharmony_ci		.channels = max1236_channels,
119262306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(max1236_channels),
119362306a36Sopenharmony_ci	},
119462306a36Sopenharmony_ci	[max1238] = {
119562306a36Sopenharmony_ci		.bits = 12,
119662306a36Sopenharmony_ci		.int_vref_mv = 4096,
119762306a36Sopenharmony_ci		.mode_list = max1238_mode_list,
119862306a36Sopenharmony_ci		.num_modes = ARRAY_SIZE(max1238_mode_list),
119962306a36Sopenharmony_ci		.default_mode = s0to11,
120062306a36Sopenharmony_ci		.info = &max1238_info,
120162306a36Sopenharmony_ci		.channels = max1238_channels,
120262306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(max1238_channels),
120362306a36Sopenharmony_ci	},
120462306a36Sopenharmony_ci	[max1239] = {
120562306a36Sopenharmony_ci		.bits = 12,
120662306a36Sopenharmony_ci		.int_vref_mv = 2048,
120762306a36Sopenharmony_ci		.mode_list = max1238_mode_list,
120862306a36Sopenharmony_ci		.num_modes = ARRAY_SIZE(max1238_mode_list),
120962306a36Sopenharmony_ci		.default_mode = s0to11,
121062306a36Sopenharmony_ci		.info = &max1238_info,
121162306a36Sopenharmony_ci		.channels = max1238_channels,
121262306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(max1238_channels),
121362306a36Sopenharmony_ci	},
121462306a36Sopenharmony_ci	[max11600] = {
121562306a36Sopenharmony_ci		.bits = 8,
121662306a36Sopenharmony_ci		.int_vref_mv = 4096,
121762306a36Sopenharmony_ci		.mode_list = max11607_mode_list,
121862306a36Sopenharmony_ci		.num_modes = ARRAY_SIZE(max11607_mode_list),
121962306a36Sopenharmony_ci		.default_mode = s0to3,
122062306a36Sopenharmony_ci		.info = &max1238_info,
122162306a36Sopenharmony_ci		.channels = max1036_channels,
122262306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(max1036_channels),
122362306a36Sopenharmony_ci	},
122462306a36Sopenharmony_ci	[max11601] = {
122562306a36Sopenharmony_ci		.bits = 8,
122662306a36Sopenharmony_ci		.int_vref_mv = 2048,
122762306a36Sopenharmony_ci		.mode_list = max11607_mode_list,
122862306a36Sopenharmony_ci		.num_modes = ARRAY_SIZE(max11607_mode_list),
122962306a36Sopenharmony_ci		.default_mode = s0to3,
123062306a36Sopenharmony_ci		.info = &max1238_info,
123162306a36Sopenharmony_ci		.channels = max1036_channels,
123262306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(max1036_channels),
123362306a36Sopenharmony_ci	},
123462306a36Sopenharmony_ci	[max11602] = {
123562306a36Sopenharmony_ci		.bits = 8,
123662306a36Sopenharmony_ci		.int_vref_mv = 4096,
123762306a36Sopenharmony_ci		.mode_list = max11608_mode_list,
123862306a36Sopenharmony_ci		.num_modes = ARRAY_SIZE(max11608_mode_list),
123962306a36Sopenharmony_ci		.default_mode = s0to7,
124062306a36Sopenharmony_ci		.info = &max1238_info,
124162306a36Sopenharmony_ci		.channels = max11602_channels,
124262306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(max11602_channels),
124362306a36Sopenharmony_ci	},
124462306a36Sopenharmony_ci	[max11603] = {
124562306a36Sopenharmony_ci		.bits = 8,
124662306a36Sopenharmony_ci		.int_vref_mv = 2048,
124762306a36Sopenharmony_ci		.mode_list = max11608_mode_list,
124862306a36Sopenharmony_ci		.num_modes = ARRAY_SIZE(max11608_mode_list),
124962306a36Sopenharmony_ci		.default_mode = s0to7,
125062306a36Sopenharmony_ci		.info = &max1238_info,
125162306a36Sopenharmony_ci		.channels = max11602_channels,
125262306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(max11602_channels),
125362306a36Sopenharmony_ci	},
125462306a36Sopenharmony_ci	[max11604] = {
125562306a36Sopenharmony_ci		.bits = 8,
125662306a36Sopenharmony_ci		.int_vref_mv = 4096,
125762306a36Sopenharmony_ci		.mode_list = max1238_mode_list,
125862306a36Sopenharmony_ci		.num_modes = ARRAY_SIZE(max1238_mode_list),
125962306a36Sopenharmony_ci		.default_mode = s0to11,
126062306a36Sopenharmony_ci		.info = &max1238_info,
126162306a36Sopenharmony_ci		.channels = max1038_channels,
126262306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(max1038_channels),
126362306a36Sopenharmony_ci	},
126462306a36Sopenharmony_ci	[max11605] = {
126562306a36Sopenharmony_ci		.bits = 8,
126662306a36Sopenharmony_ci		.int_vref_mv = 2048,
126762306a36Sopenharmony_ci		.mode_list = max1238_mode_list,
126862306a36Sopenharmony_ci		.num_modes = ARRAY_SIZE(max1238_mode_list),
126962306a36Sopenharmony_ci		.default_mode = s0to11,
127062306a36Sopenharmony_ci		.info = &max1238_info,
127162306a36Sopenharmony_ci		.channels = max1038_channels,
127262306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(max1038_channels),
127362306a36Sopenharmony_ci	},
127462306a36Sopenharmony_ci	[max11606] = {
127562306a36Sopenharmony_ci		.bits = 10,
127662306a36Sopenharmony_ci		.int_vref_mv = 4096,
127762306a36Sopenharmony_ci		.mode_list = max11607_mode_list,
127862306a36Sopenharmony_ci		.num_modes = ARRAY_SIZE(max11607_mode_list),
127962306a36Sopenharmony_ci		.default_mode = s0to3,
128062306a36Sopenharmony_ci		.info = &max1238_info,
128162306a36Sopenharmony_ci		.channels = max1136_channels,
128262306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(max1136_channels),
128362306a36Sopenharmony_ci	},
128462306a36Sopenharmony_ci	[max11607] = {
128562306a36Sopenharmony_ci		.bits = 10,
128662306a36Sopenharmony_ci		.int_vref_mv = 2048,
128762306a36Sopenharmony_ci		.mode_list = max11607_mode_list,
128862306a36Sopenharmony_ci		.num_modes = ARRAY_SIZE(max11607_mode_list),
128962306a36Sopenharmony_ci		.default_mode = s0to3,
129062306a36Sopenharmony_ci		.info = &max1238_info,
129162306a36Sopenharmony_ci		.channels = max1136_channels,
129262306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(max1136_channels),
129362306a36Sopenharmony_ci	},
129462306a36Sopenharmony_ci	[max11608] = {
129562306a36Sopenharmony_ci		.bits = 10,
129662306a36Sopenharmony_ci		.int_vref_mv = 4096,
129762306a36Sopenharmony_ci		.mode_list = max11608_mode_list,
129862306a36Sopenharmony_ci		.num_modes = ARRAY_SIZE(max11608_mode_list),
129962306a36Sopenharmony_ci		.default_mode = s0to7,
130062306a36Sopenharmony_ci		.info = &max1238_info,
130162306a36Sopenharmony_ci		.channels = max11608_channels,
130262306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(max11608_channels),
130362306a36Sopenharmony_ci	},
130462306a36Sopenharmony_ci	[max11609] = {
130562306a36Sopenharmony_ci		.bits = 10,
130662306a36Sopenharmony_ci		.int_vref_mv = 2048,
130762306a36Sopenharmony_ci		.mode_list = max11608_mode_list,
130862306a36Sopenharmony_ci		.num_modes = ARRAY_SIZE(max11608_mode_list),
130962306a36Sopenharmony_ci		.default_mode = s0to7,
131062306a36Sopenharmony_ci		.info = &max1238_info,
131162306a36Sopenharmony_ci		.channels = max11608_channels,
131262306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(max11608_channels),
131362306a36Sopenharmony_ci	},
131462306a36Sopenharmony_ci	[max11610] = {
131562306a36Sopenharmony_ci		.bits = 10,
131662306a36Sopenharmony_ci		.int_vref_mv = 4096,
131762306a36Sopenharmony_ci		.mode_list = max1238_mode_list,
131862306a36Sopenharmony_ci		.num_modes = ARRAY_SIZE(max1238_mode_list),
131962306a36Sopenharmony_ci		.default_mode = s0to11,
132062306a36Sopenharmony_ci		.info = &max1238_info,
132162306a36Sopenharmony_ci		.channels = max1138_channels,
132262306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(max1138_channels),
132362306a36Sopenharmony_ci	},
132462306a36Sopenharmony_ci	[max11611] = {
132562306a36Sopenharmony_ci		.bits = 10,
132662306a36Sopenharmony_ci		.int_vref_mv = 2048,
132762306a36Sopenharmony_ci		.mode_list = max1238_mode_list,
132862306a36Sopenharmony_ci		.num_modes = ARRAY_SIZE(max1238_mode_list),
132962306a36Sopenharmony_ci		.default_mode = s0to11,
133062306a36Sopenharmony_ci		.info = &max1238_info,
133162306a36Sopenharmony_ci		.channels = max1138_channels,
133262306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(max1138_channels),
133362306a36Sopenharmony_ci	},
133462306a36Sopenharmony_ci	[max11612] = {
133562306a36Sopenharmony_ci		.bits = 12,
133662306a36Sopenharmony_ci		.int_vref_mv = 4096,
133762306a36Sopenharmony_ci		.mode_list = max11607_mode_list,
133862306a36Sopenharmony_ci		.num_modes = ARRAY_SIZE(max11607_mode_list),
133962306a36Sopenharmony_ci		.default_mode = s0to3,
134062306a36Sopenharmony_ci		.info = &max1238_info,
134162306a36Sopenharmony_ci		.channels = max1363_channels,
134262306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(max1363_channels),
134362306a36Sopenharmony_ci	},
134462306a36Sopenharmony_ci	[max11613] = {
134562306a36Sopenharmony_ci		.bits = 12,
134662306a36Sopenharmony_ci		.int_vref_mv = 2048,
134762306a36Sopenharmony_ci		.mode_list = max11607_mode_list,
134862306a36Sopenharmony_ci		.num_modes = ARRAY_SIZE(max11607_mode_list),
134962306a36Sopenharmony_ci		.default_mode = s0to3,
135062306a36Sopenharmony_ci		.info = &max1238_info,
135162306a36Sopenharmony_ci		.channels = max1363_channels,
135262306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(max1363_channels),
135362306a36Sopenharmony_ci	},
135462306a36Sopenharmony_ci	[max11614] = {
135562306a36Sopenharmony_ci		.bits = 12,
135662306a36Sopenharmony_ci		.int_vref_mv = 4096,
135762306a36Sopenharmony_ci		.mode_list = max11608_mode_list,
135862306a36Sopenharmony_ci		.num_modes = ARRAY_SIZE(max11608_mode_list),
135962306a36Sopenharmony_ci		.default_mode = s0to7,
136062306a36Sopenharmony_ci		.info = &max1238_info,
136162306a36Sopenharmony_ci		.channels = max11614_channels,
136262306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(max11614_channels),
136362306a36Sopenharmony_ci	},
136462306a36Sopenharmony_ci	[max11615] = {
136562306a36Sopenharmony_ci		.bits = 12,
136662306a36Sopenharmony_ci		.int_vref_mv = 2048,
136762306a36Sopenharmony_ci		.mode_list = max11608_mode_list,
136862306a36Sopenharmony_ci		.num_modes = ARRAY_SIZE(max11608_mode_list),
136962306a36Sopenharmony_ci		.default_mode = s0to7,
137062306a36Sopenharmony_ci		.info = &max1238_info,
137162306a36Sopenharmony_ci		.channels = max11614_channels,
137262306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(max11614_channels),
137362306a36Sopenharmony_ci	},
137462306a36Sopenharmony_ci	[max11616] = {
137562306a36Sopenharmony_ci		.bits = 12,
137662306a36Sopenharmony_ci		.int_vref_mv = 4096,
137762306a36Sopenharmony_ci		.mode_list = max1238_mode_list,
137862306a36Sopenharmony_ci		.num_modes = ARRAY_SIZE(max1238_mode_list),
137962306a36Sopenharmony_ci		.default_mode = s0to11,
138062306a36Sopenharmony_ci		.info = &max1238_info,
138162306a36Sopenharmony_ci		.channels = max1238_channels,
138262306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(max1238_channels),
138362306a36Sopenharmony_ci	},
138462306a36Sopenharmony_ci	[max11617] = {
138562306a36Sopenharmony_ci		.bits = 12,
138662306a36Sopenharmony_ci		.int_vref_mv = 2048,
138762306a36Sopenharmony_ci		.mode_list = max1238_mode_list,
138862306a36Sopenharmony_ci		.num_modes = ARRAY_SIZE(max1238_mode_list),
138962306a36Sopenharmony_ci		.default_mode = s0to11,
139062306a36Sopenharmony_ci		.info = &max1238_info,
139162306a36Sopenharmony_ci		.channels = max1238_channels,
139262306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(max1238_channels),
139362306a36Sopenharmony_ci	},
139462306a36Sopenharmony_ci	[max11644] = {
139562306a36Sopenharmony_ci		.bits = 12,
139662306a36Sopenharmony_ci		.int_vref_mv = 4096,
139762306a36Sopenharmony_ci		.mode_list = max11644_mode_list,
139862306a36Sopenharmony_ci		.num_modes = ARRAY_SIZE(max11644_mode_list),
139962306a36Sopenharmony_ci		.default_mode = s0to1,
140062306a36Sopenharmony_ci		.info = &max1238_info,
140162306a36Sopenharmony_ci		.channels = max11644_channels,
140262306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(max11644_channels),
140362306a36Sopenharmony_ci	},
140462306a36Sopenharmony_ci	[max11645] = {
140562306a36Sopenharmony_ci		.bits = 12,
140662306a36Sopenharmony_ci		.int_vref_mv = 2048,
140762306a36Sopenharmony_ci		.mode_list = max11644_mode_list,
140862306a36Sopenharmony_ci		.num_modes = ARRAY_SIZE(max11644_mode_list),
140962306a36Sopenharmony_ci		.default_mode = s0to1,
141062306a36Sopenharmony_ci		.info = &max1238_info,
141162306a36Sopenharmony_ci		.channels = max11644_channels,
141262306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(max11644_channels),
141362306a36Sopenharmony_ci	},
141462306a36Sopenharmony_ci	[max11646] = {
141562306a36Sopenharmony_ci		.bits = 10,
141662306a36Sopenharmony_ci		.int_vref_mv = 4096,
141762306a36Sopenharmony_ci		.mode_list = max11644_mode_list,
141862306a36Sopenharmony_ci		.num_modes = ARRAY_SIZE(max11644_mode_list),
141962306a36Sopenharmony_ci		.default_mode = s0to1,
142062306a36Sopenharmony_ci		.info = &max1238_info,
142162306a36Sopenharmony_ci		.channels = max11646_channels,
142262306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(max11646_channels),
142362306a36Sopenharmony_ci	},
142462306a36Sopenharmony_ci	[max11647] = {
142562306a36Sopenharmony_ci		.bits = 10,
142662306a36Sopenharmony_ci		.int_vref_mv = 2048,
142762306a36Sopenharmony_ci		.mode_list = max11644_mode_list,
142862306a36Sopenharmony_ci		.num_modes = ARRAY_SIZE(max11644_mode_list),
142962306a36Sopenharmony_ci		.default_mode = s0to1,
143062306a36Sopenharmony_ci		.info = &max1238_info,
143162306a36Sopenharmony_ci		.channels = max11646_channels,
143262306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(max11646_channels),
143362306a36Sopenharmony_ci	},
143462306a36Sopenharmony_ci};
143562306a36Sopenharmony_ci
143662306a36Sopenharmony_cistatic int max1363_initial_setup(struct max1363_state *st)
143762306a36Sopenharmony_ci{
143862306a36Sopenharmony_ci	st->setupbyte = MAX1363_SETUP_INT_CLOCK
143962306a36Sopenharmony_ci		| MAX1363_SETUP_UNIPOLAR
144062306a36Sopenharmony_ci		| MAX1363_SETUP_NORESET;
144162306a36Sopenharmony_ci
144262306a36Sopenharmony_ci	if (st->vref)
144362306a36Sopenharmony_ci		st->setupbyte |= MAX1363_SETUP_AIN3_IS_REF_EXT_TO_REF;
144462306a36Sopenharmony_ci	else
144562306a36Sopenharmony_ci		st->setupbyte |= MAX1363_SETUP_POWER_UP_INT_REF
144662306a36Sopenharmony_ci		  | MAX1363_SETUP_AIN3_IS_AIN3_REF_IS_INT;
144762306a36Sopenharmony_ci
144862306a36Sopenharmony_ci	/* Set scan mode writes the config anyway so wait until then */
144962306a36Sopenharmony_ci	st->setupbyte = MAX1363_SETUP_BYTE(st->setupbyte);
145062306a36Sopenharmony_ci	st->current_mode = &max1363_mode_table[st->chip_info->default_mode];
145162306a36Sopenharmony_ci	st->configbyte = MAX1363_CONFIG_BYTE(st->configbyte);
145262306a36Sopenharmony_ci
145362306a36Sopenharmony_ci	return max1363_set_scan_mode(st);
145462306a36Sopenharmony_ci}
145562306a36Sopenharmony_ci
145662306a36Sopenharmony_cistatic int max1363_alloc_scan_masks(struct iio_dev *indio_dev)
145762306a36Sopenharmony_ci{
145862306a36Sopenharmony_ci	struct max1363_state *st = iio_priv(indio_dev);
145962306a36Sopenharmony_ci	unsigned long *masks;
146062306a36Sopenharmony_ci	int i;
146162306a36Sopenharmony_ci
146262306a36Sopenharmony_ci	masks = devm_kzalloc(&indio_dev->dev,
146362306a36Sopenharmony_ci			array3_size(BITS_TO_LONGS(MAX1363_MAX_CHANNELS),
146462306a36Sopenharmony_ci				    sizeof(long),
146562306a36Sopenharmony_ci				    st->chip_info->num_modes + 1),
146662306a36Sopenharmony_ci			GFP_KERNEL);
146762306a36Sopenharmony_ci	if (!masks)
146862306a36Sopenharmony_ci		return -ENOMEM;
146962306a36Sopenharmony_ci
147062306a36Sopenharmony_ci	for (i = 0; i < st->chip_info->num_modes; i++)
147162306a36Sopenharmony_ci		bitmap_copy(masks + BITS_TO_LONGS(MAX1363_MAX_CHANNELS)*i,
147262306a36Sopenharmony_ci			    max1363_mode_table[st->chip_info->mode_list[i]]
147362306a36Sopenharmony_ci			    .modemask, MAX1363_MAX_CHANNELS);
147462306a36Sopenharmony_ci
147562306a36Sopenharmony_ci	indio_dev->available_scan_masks = masks;
147662306a36Sopenharmony_ci
147762306a36Sopenharmony_ci	return 0;
147862306a36Sopenharmony_ci}
147962306a36Sopenharmony_ci
148062306a36Sopenharmony_cistatic irqreturn_t max1363_trigger_handler(int irq, void *p)
148162306a36Sopenharmony_ci{
148262306a36Sopenharmony_ci	struct iio_poll_func *pf = p;
148362306a36Sopenharmony_ci	struct iio_dev *indio_dev = pf->indio_dev;
148462306a36Sopenharmony_ci	struct max1363_state *st = iio_priv(indio_dev);
148562306a36Sopenharmony_ci	__u8 *rxbuf;
148662306a36Sopenharmony_ci	int b_sent;
148762306a36Sopenharmony_ci	size_t d_size;
148862306a36Sopenharmony_ci	unsigned long numvals = bitmap_weight(st->current_mode->modemask,
148962306a36Sopenharmony_ci					      MAX1363_MAX_CHANNELS);
149062306a36Sopenharmony_ci
149162306a36Sopenharmony_ci	/* Ensure the timestamp is 8 byte aligned */
149262306a36Sopenharmony_ci	if (st->chip_info->bits != 8)
149362306a36Sopenharmony_ci		d_size = numvals*2;
149462306a36Sopenharmony_ci	else
149562306a36Sopenharmony_ci		d_size = numvals;
149662306a36Sopenharmony_ci	if (indio_dev->scan_timestamp) {
149762306a36Sopenharmony_ci		d_size += sizeof(s64);
149862306a36Sopenharmony_ci		if (d_size % sizeof(s64))
149962306a36Sopenharmony_ci			d_size += sizeof(s64) - (d_size % sizeof(s64));
150062306a36Sopenharmony_ci	}
150162306a36Sopenharmony_ci	/* Monitor mode prevents reading. Whilst not currently implemented
150262306a36Sopenharmony_ci	 * might as well have this test in here in the meantime as it does
150362306a36Sopenharmony_ci	 * no harm.
150462306a36Sopenharmony_ci	 */
150562306a36Sopenharmony_ci	if (numvals == 0)
150662306a36Sopenharmony_ci		goto done;
150762306a36Sopenharmony_ci
150862306a36Sopenharmony_ci	rxbuf = kmalloc(d_size,	GFP_KERNEL);
150962306a36Sopenharmony_ci	if (rxbuf == NULL)
151062306a36Sopenharmony_ci		goto done;
151162306a36Sopenharmony_ci	if (st->chip_info->bits != 8)
151262306a36Sopenharmony_ci		b_sent = st->recv(st->client, rxbuf, numvals * 2);
151362306a36Sopenharmony_ci	else
151462306a36Sopenharmony_ci		b_sent = st->recv(st->client, rxbuf, numvals);
151562306a36Sopenharmony_ci	if (b_sent < 0)
151662306a36Sopenharmony_ci		goto done_free;
151762306a36Sopenharmony_ci
151862306a36Sopenharmony_ci	iio_push_to_buffers_with_timestamp(indio_dev, rxbuf,
151962306a36Sopenharmony_ci					   iio_get_time_ns(indio_dev));
152062306a36Sopenharmony_ci
152162306a36Sopenharmony_cidone_free:
152262306a36Sopenharmony_ci	kfree(rxbuf);
152362306a36Sopenharmony_cidone:
152462306a36Sopenharmony_ci	iio_trigger_notify_done(indio_dev->trig);
152562306a36Sopenharmony_ci
152662306a36Sopenharmony_ci	return IRQ_HANDLED;
152762306a36Sopenharmony_ci}
152862306a36Sopenharmony_ci
152962306a36Sopenharmony_ci#define MAX1363_COMPATIBLE(of_compatible, cfg) {		\
153062306a36Sopenharmony_ci			.compatible = of_compatible,		\
153162306a36Sopenharmony_ci			.data = &max1363_chip_info_tbl[cfg],	\
153262306a36Sopenharmony_ci}
153362306a36Sopenharmony_ci
153462306a36Sopenharmony_cistatic const struct of_device_id max1363_of_match[] = {
153562306a36Sopenharmony_ci	MAX1363_COMPATIBLE("maxim,max1361", max1361),
153662306a36Sopenharmony_ci	MAX1363_COMPATIBLE("maxim,max1362", max1362),
153762306a36Sopenharmony_ci	MAX1363_COMPATIBLE("maxim,max1363", max1363),
153862306a36Sopenharmony_ci	MAX1363_COMPATIBLE("maxim,max1364", max1364),
153962306a36Sopenharmony_ci	MAX1363_COMPATIBLE("maxim,max1036", max1036),
154062306a36Sopenharmony_ci	MAX1363_COMPATIBLE("maxim,max1037", max1037),
154162306a36Sopenharmony_ci	MAX1363_COMPATIBLE("maxim,max1038", max1038),
154262306a36Sopenharmony_ci	MAX1363_COMPATIBLE("maxim,max1039", max1039),
154362306a36Sopenharmony_ci	MAX1363_COMPATIBLE("maxim,max1136", max1136),
154462306a36Sopenharmony_ci	MAX1363_COMPATIBLE("maxim,max1137", max1137),
154562306a36Sopenharmony_ci	MAX1363_COMPATIBLE("maxim,max1138", max1138),
154662306a36Sopenharmony_ci	MAX1363_COMPATIBLE("maxim,max1139", max1139),
154762306a36Sopenharmony_ci	MAX1363_COMPATIBLE("maxim,max1236", max1236),
154862306a36Sopenharmony_ci	MAX1363_COMPATIBLE("maxim,max1237", max1237),
154962306a36Sopenharmony_ci	MAX1363_COMPATIBLE("maxim,max1238", max1238),
155062306a36Sopenharmony_ci	MAX1363_COMPATIBLE("maxim,max1239", max1239),
155162306a36Sopenharmony_ci	MAX1363_COMPATIBLE("maxim,max11600", max11600),
155262306a36Sopenharmony_ci	MAX1363_COMPATIBLE("maxim,max11601", max11601),
155362306a36Sopenharmony_ci	MAX1363_COMPATIBLE("maxim,max11602", max11602),
155462306a36Sopenharmony_ci	MAX1363_COMPATIBLE("maxim,max11603", max11603),
155562306a36Sopenharmony_ci	MAX1363_COMPATIBLE("maxim,max11604", max11604),
155662306a36Sopenharmony_ci	MAX1363_COMPATIBLE("maxim,max11605", max11605),
155762306a36Sopenharmony_ci	MAX1363_COMPATIBLE("maxim,max11606", max11606),
155862306a36Sopenharmony_ci	MAX1363_COMPATIBLE("maxim,max11607", max11607),
155962306a36Sopenharmony_ci	MAX1363_COMPATIBLE("maxim,max11608", max11608),
156062306a36Sopenharmony_ci	MAX1363_COMPATIBLE("maxim,max11609", max11609),
156162306a36Sopenharmony_ci	MAX1363_COMPATIBLE("maxim,max11610", max11610),
156262306a36Sopenharmony_ci	MAX1363_COMPATIBLE("maxim,max11611", max11611),
156362306a36Sopenharmony_ci	MAX1363_COMPATIBLE("maxim,max11612", max11612),
156462306a36Sopenharmony_ci	MAX1363_COMPATIBLE("maxim,max11613", max11613),
156562306a36Sopenharmony_ci	MAX1363_COMPATIBLE("maxim,max11614", max11614),
156662306a36Sopenharmony_ci	MAX1363_COMPATIBLE("maxim,max11615", max11615),
156762306a36Sopenharmony_ci	MAX1363_COMPATIBLE("maxim,max11616", max11616),
156862306a36Sopenharmony_ci	MAX1363_COMPATIBLE("maxim,max11617", max11617),
156962306a36Sopenharmony_ci	MAX1363_COMPATIBLE("maxim,max11644", max11644),
157062306a36Sopenharmony_ci	MAX1363_COMPATIBLE("maxim,max11645", max11645),
157162306a36Sopenharmony_ci	MAX1363_COMPATIBLE("maxim,max11646", max11646),
157262306a36Sopenharmony_ci	MAX1363_COMPATIBLE("maxim,max11647", max11647),
157362306a36Sopenharmony_ci	{ /* sentinel */ }
157462306a36Sopenharmony_ci};
157562306a36Sopenharmony_ciMODULE_DEVICE_TABLE(of, max1363_of_match);
157662306a36Sopenharmony_ci
157762306a36Sopenharmony_cistatic void max1363_reg_disable(void *reg)
157862306a36Sopenharmony_ci{
157962306a36Sopenharmony_ci	regulator_disable(reg);
158062306a36Sopenharmony_ci}
158162306a36Sopenharmony_ci
158262306a36Sopenharmony_cistatic int max1363_probe(struct i2c_client *client)
158362306a36Sopenharmony_ci{
158462306a36Sopenharmony_ci	const struct i2c_device_id *id = i2c_client_get_device_id(client);
158562306a36Sopenharmony_ci	int ret;
158662306a36Sopenharmony_ci	struct max1363_state *st;
158762306a36Sopenharmony_ci	struct iio_dev *indio_dev;
158862306a36Sopenharmony_ci	struct regulator *vref;
158962306a36Sopenharmony_ci
159062306a36Sopenharmony_ci	indio_dev = devm_iio_device_alloc(&client->dev,
159162306a36Sopenharmony_ci					  sizeof(struct max1363_state));
159262306a36Sopenharmony_ci	if (!indio_dev)
159362306a36Sopenharmony_ci		return -ENOMEM;
159462306a36Sopenharmony_ci
159562306a36Sopenharmony_ci	st = iio_priv(indio_dev);
159662306a36Sopenharmony_ci
159762306a36Sopenharmony_ci	mutex_init(&st->lock);
159862306a36Sopenharmony_ci	ret = devm_regulator_get_enable(&client->dev, "vcc");
159962306a36Sopenharmony_ci	if (ret)
160062306a36Sopenharmony_ci		return ret;
160162306a36Sopenharmony_ci
160262306a36Sopenharmony_ci	st->chip_info = device_get_match_data(&client->dev);
160362306a36Sopenharmony_ci	if (!st->chip_info)
160462306a36Sopenharmony_ci		st->chip_info = &max1363_chip_info_tbl[id->driver_data];
160562306a36Sopenharmony_ci	st->client = client;
160662306a36Sopenharmony_ci
160762306a36Sopenharmony_ci	st->vref_uv = st->chip_info->int_vref_mv * 1000;
160862306a36Sopenharmony_ci	vref = devm_regulator_get_optional(&client->dev, "vref");
160962306a36Sopenharmony_ci	if (!IS_ERR(vref)) {
161062306a36Sopenharmony_ci		int vref_uv;
161162306a36Sopenharmony_ci
161262306a36Sopenharmony_ci		ret = regulator_enable(vref);
161362306a36Sopenharmony_ci		if (ret)
161462306a36Sopenharmony_ci			return ret;
161562306a36Sopenharmony_ci
161662306a36Sopenharmony_ci		ret = devm_add_action_or_reset(&client->dev, max1363_reg_disable, vref);
161762306a36Sopenharmony_ci		if (ret)
161862306a36Sopenharmony_ci			return ret;
161962306a36Sopenharmony_ci
162062306a36Sopenharmony_ci		st->vref = vref;
162162306a36Sopenharmony_ci		vref_uv = regulator_get_voltage(vref);
162262306a36Sopenharmony_ci		if (vref_uv <= 0)
162362306a36Sopenharmony_ci			return -EINVAL;
162462306a36Sopenharmony_ci
162562306a36Sopenharmony_ci		st->vref_uv = vref_uv;
162662306a36Sopenharmony_ci	}
162762306a36Sopenharmony_ci
162862306a36Sopenharmony_ci	if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
162962306a36Sopenharmony_ci		st->send = i2c_master_send;
163062306a36Sopenharmony_ci		st->recv = i2c_master_recv;
163162306a36Sopenharmony_ci	} else if (i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE)
163262306a36Sopenharmony_ci			&& st->chip_info->bits == 8) {
163362306a36Sopenharmony_ci		st->send = max1363_smbus_send;
163462306a36Sopenharmony_ci		st->recv = max1363_smbus_recv;
163562306a36Sopenharmony_ci	} else {
163662306a36Sopenharmony_ci		return -EOPNOTSUPP;
163762306a36Sopenharmony_ci	}
163862306a36Sopenharmony_ci
163962306a36Sopenharmony_ci	ret = max1363_alloc_scan_masks(indio_dev);
164062306a36Sopenharmony_ci	if (ret)
164162306a36Sopenharmony_ci		return ret;
164262306a36Sopenharmony_ci
164362306a36Sopenharmony_ci	indio_dev->name = id->name;
164462306a36Sopenharmony_ci	indio_dev->channels = st->chip_info->channels;
164562306a36Sopenharmony_ci	indio_dev->num_channels = st->chip_info->num_channels;
164662306a36Sopenharmony_ci	indio_dev->info = st->chip_info->info;
164762306a36Sopenharmony_ci	indio_dev->modes = INDIO_DIRECT_MODE;
164862306a36Sopenharmony_ci	ret = max1363_initial_setup(st);
164962306a36Sopenharmony_ci	if (ret < 0)
165062306a36Sopenharmony_ci		return ret;
165162306a36Sopenharmony_ci
165262306a36Sopenharmony_ci	ret = devm_iio_triggered_buffer_setup(&client->dev, indio_dev, NULL,
165362306a36Sopenharmony_ci					      &max1363_trigger_handler, NULL);
165462306a36Sopenharmony_ci	if (ret)
165562306a36Sopenharmony_ci		return ret;
165662306a36Sopenharmony_ci
165762306a36Sopenharmony_ci	if (client->irq) {
165862306a36Sopenharmony_ci		ret = devm_request_threaded_irq(&client->dev, st->client->irq,
165962306a36Sopenharmony_ci					   NULL,
166062306a36Sopenharmony_ci					   &max1363_event_handler,
166162306a36Sopenharmony_ci					   IRQF_TRIGGER_RISING | IRQF_ONESHOT,
166262306a36Sopenharmony_ci					   "max1363_event",
166362306a36Sopenharmony_ci					   indio_dev);
166462306a36Sopenharmony_ci
166562306a36Sopenharmony_ci		if (ret)
166662306a36Sopenharmony_ci			return ret;
166762306a36Sopenharmony_ci	}
166862306a36Sopenharmony_ci
166962306a36Sopenharmony_ci	return devm_iio_device_register(&client->dev, indio_dev);
167062306a36Sopenharmony_ci}
167162306a36Sopenharmony_ci
167262306a36Sopenharmony_cistatic const struct i2c_device_id max1363_id[] = {
167362306a36Sopenharmony_ci	{ "max1361", max1361 },
167462306a36Sopenharmony_ci	{ "max1362", max1362 },
167562306a36Sopenharmony_ci	{ "max1363", max1363 },
167662306a36Sopenharmony_ci	{ "max1364", max1364 },
167762306a36Sopenharmony_ci	{ "max1036", max1036 },
167862306a36Sopenharmony_ci	{ "max1037", max1037 },
167962306a36Sopenharmony_ci	{ "max1038", max1038 },
168062306a36Sopenharmony_ci	{ "max1039", max1039 },
168162306a36Sopenharmony_ci	{ "max1136", max1136 },
168262306a36Sopenharmony_ci	{ "max1137", max1137 },
168362306a36Sopenharmony_ci	{ "max1138", max1138 },
168462306a36Sopenharmony_ci	{ "max1139", max1139 },
168562306a36Sopenharmony_ci	{ "max1236", max1236 },
168662306a36Sopenharmony_ci	{ "max1237", max1237 },
168762306a36Sopenharmony_ci	{ "max1238", max1238 },
168862306a36Sopenharmony_ci	{ "max1239", max1239 },
168962306a36Sopenharmony_ci	{ "max11600", max11600 },
169062306a36Sopenharmony_ci	{ "max11601", max11601 },
169162306a36Sopenharmony_ci	{ "max11602", max11602 },
169262306a36Sopenharmony_ci	{ "max11603", max11603 },
169362306a36Sopenharmony_ci	{ "max11604", max11604 },
169462306a36Sopenharmony_ci	{ "max11605", max11605 },
169562306a36Sopenharmony_ci	{ "max11606", max11606 },
169662306a36Sopenharmony_ci	{ "max11607", max11607 },
169762306a36Sopenharmony_ci	{ "max11608", max11608 },
169862306a36Sopenharmony_ci	{ "max11609", max11609 },
169962306a36Sopenharmony_ci	{ "max11610", max11610 },
170062306a36Sopenharmony_ci	{ "max11611", max11611 },
170162306a36Sopenharmony_ci	{ "max11612", max11612 },
170262306a36Sopenharmony_ci	{ "max11613", max11613 },
170362306a36Sopenharmony_ci	{ "max11614", max11614 },
170462306a36Sopenharmony_ci	{ "max11615", max11615 },
170562306a36Sopenharmony_ci	{ "max11616", max11616 },
170662306a36Sopenharmony_ci	{ "max11617", max11617 },
170762306a36Sopenharmony_ci	{ "max11644", max11644 },
170862306a36Sopenharmony_ci	{ "max11645", max11645 },
170962306a36Sopenharmony_ci	{ "max11646", max11646 },
171062306a36Sopenharmony_ci	{ "max11647", max11647 },
171162306a36Sopenharmony_ci	{}
171262306a36Sopenharmony_ci};
171362306a36Sopenharmony_ci
171462306a36Sopenharmony_ciMODULE_DEVICE_TABLE(i2c, max1363_id);
171562306a36Sopenharmony_ci
171662306a36Sopenharmony_cistatic struct i2c_driver max1363_driver = {
171762306a36Sopenharmony_ci	.driver = {
171862306a36Sopenharmony_ci		.name = "max1363",
171962306a36Sopenharmony_ci		.of_match_table = max1363_of_match,
172062306a36Sopenharmony_ci	},
172162306a36Sopenharmony_ci	.probe = max1363_probe,
172262306a36Sopenharmony_ci	.id_table = max1363_id,
172362306a36Sopenharmony_ci};
172462306a36Sopenharmony_cimodule_i2c_driver(max1363_driver);
172562306a36Sopenharmony_ci
172662306a36Sopenharmony_ciMODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>");
172762306a36Sopenharmony_ciMODULE_DESCRIPTION("Maxim 1363 ADC");
172862306a36Sopenharmony_ciMODULE_LICENSE("GPL v2");
1729