xref: /openbmc/linux/drivers/iio/adc/max1363.c (revision 2612e3bbc0386368a850140a6c9b990cd496a5ec)
1d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2168c9d95SJonathan Cameron  /*
3168c9d95SJonathan Cameron   * iio/adc/max1363.c
4168c9d95SJonathan Cameron   * Copyright (C) 2008-2010 Jonathan Cameron
5168c9d95SJonathan Cameron   *
6168c9d95SJonathan Cameron   * based on linux/drivers/i2c/chips/max123x
7168c9d95SJonathan Cameron   * Copyright (C) 2002-2004 Stefan Eletzhofer
8168c9d95SJonathan Cameron   *
9168c9d95SJonathan Cameron   * based on linux/drivers/acron/char/pcf8583.c
10168c9d95SJonathan Cameron   * Copyright (C) 2000 Russell King
11168c9d95SJonathan Cameron   *
1282b7afbcSVivien Didelot   * Driver for max1363 and similar chips.
13168c9d95SJonathan Cameron   */
14168c9d95SJonathan Cameron 
15168c9d95SJonathan Cameron #include <linux/interrupt.h>
16168c9d95SJonathan Cameron #include <linux/device.h>
17168c9d95SJonathan Cameron #include <linux/kernel.h>
18168c9d95SJonathan Cameron #include <linux/sysfs.h>
19168c9d95SJonathan Cameron #include <linux/list.h>
20168c9d95SJonathan Cameron #include <linux/i2c.h>
21168c9d95SJonathan Cameron #include <linux/regulator/consumer.h>
22168c9d95SJonathan Cameron #include <linux/slab.h>
23168c9d95SJonathan Cameron #include <linux/err.h>
24168c9d95SJonathan Cameron #include <linux/module.h>
25f84ff467SJonathan Cameron #include <linux/mod_devicetable.h>
26f84ff467SJonathan Cameron #include <linux/property.h>
27168c9d95SJonathan Cameron 
28168c9d95SJonathan Cameron #include <linux/iio/iio.h>
29168c9d95SJonathan Cameron #include <linux/iio/sysfs.h>
30168c9d95SJonathan Cameron #include <linux/iio/events.h>
31168c9d95SJonathan Cameron #include <linux/iio/buffer.h>
32168c9d95SJonathan Cameron #include <linux/iio/kfifo_buf.h>
33168c9d95SJonathan Cameron #include <linux/iio/trigger_consumer.h>
344389fbecSPeter Meerwald #include <linux/iio/triggered_buffer.h>
35168c9d95SJonathan Cameron 
36168c9d95SJonathan Cameron #define MAX1363_SETUP_BYTE(a) ((a) | 0x80)
37168c9d95SJonathan Cameron 
38168c9d95SJonathan Cameron /* There is a fair bit more defined here than currently
39168c9d95SJonathan Cameron  * used, but the intention is to support everything these
40168c9d95SJonathan Cameron  * chips do in the long run */
41168c9d95SJonathan Cameron 
42168c9d95SJonathan Cameron /* see data sheets */
43168c9d95SJonathan Cameron /* max1363 and max1236, max1237, max1238, max1239 */
44168c9d95SJonathan Cameron #define MAX1363_SETUP_AIN3_IS_AIN3_REF_IS_VDD	0x00
45168c9d95SJonathan Cameron #define MAX1363_SETUP_AIN3_IS_REF_EXT_TO_REF	0x20
46168c9d95SJonathan Cameron #define MAX1363_SETUP_AIN3_IS_AIN3_REF_IS_INT	0x40
47168c9d95SJonathan Cameron #define MAX1363_SETUP_AIN3_IS_REF_REF_IS_INT	0x60
48168c9d95SJonathan Cameron #define MAX1363_SETUP_POWER_UP_INT_REF		0x10
49168c9d95SJonathan Cameron #define MAX1363_SETUP_POWER_DOWN_INT_REF	0x00
50168c9d95SJonathan Cameron 
5171d2c120SPeter Meerwald /* think about including max11600 etc - more settings */
52168c9d95SJonathan Cameron #define MAX1363_SETUP_EXT_CLOCK			0x08
53168c9d95SJonathan Cameron #define MAX1363_SETUP_INT_CLOCK			0x00
54168c9d95SJonathan Cameron #define MAX1363_SETUP_UNIPOLAR			0x00
55168c9d95SJonathan Cameron #define MAX1363_SETUP_BIPOLAR			0x04
56168c9d95SJonathan Cameron #define MAX1363_SETUP_RESET			0x00
57168c9d95SJonathan Cameron #define MAX1363_SETUP_NORESET			0x02
58168c9d95SJonathan Cameron /* max1363 only - though don't care on others.
59168c9d95SJonathan Cameron  * For now monitor modes are not implemented as the relevant
60168c9d95SJonathan Cameron  * line is not connected on my test board.
61168c9d95SJonathan Cameron  * The definitions are here as I intend to add this soon.
62168c9d95SJonathan Cameron  */
63168c9d95SJonathan Cameron #define MAX1363_SETUP_MONITOR_SETUP		0x01
64168c9d95SJonathan Cameron 
65168c9d95SJonathan Cameron /* Specific to the max1363 */
66168c9d95SJonathan Cameron #define MAX1363_MON_RESET_CHAN(a) (1 << ((a) + 4))
67168c9d95SJonathan Cameron #define MAX1363_MON_INT_ENABLE			0x01
68168c9d95SJonathan Cameron 
69168c9d95SJonathan Cameron /* defined for readability reasons */
70168c9d95SJonathan Cameron /* All chips */
71168c9d95SJonathan Cameron #define MAX1363_CONFIG_BYTE(a) ((a))
72168c9d95SJonathan Cameron 
73168c9d95SJonathan Cameron #define MAX1363_CONFIG_SE			0x01
74168c9d95SJonathan Cameron #define MAX1363_CONFIG_DE			0x00
75168c9d95SJonathan Cameron #define MAX1363_CONFIG_SCAN_TO_CS		0x00
76168c9d95SJonathan Cameron #define MAX1363_CONFIG_SCAN_SINGLE_8		0x20
77168c9d95SJonathan Cameron #define MAX1363_CONFIG_SCAN_MONITOR_MODE	0x40
78168c9d95SJonathan Cameron #define MAX1363_CONFIG_SCAN_SINGLE_1		0x60
79168c9d95SJonathan Cameron /* max123{6-9} only */
80168c9d95SJonathan Cameron #define MAX1236_SCAN_MID_TO_CHANNEL		0x40
81168c9d95SJonathan Cameron 
82168c9d95SJonathan Cameron /* max1363 only - merely part of channel selects or don't care for others */
83168c9d95SJonathan Cameron #define MAX1363_CONFIG_EN_MON_MODE_READ 0x18
84168c9d95SJonathan Cameron 
85168c9d95SJonathan Cameron #define MAX1363_CHANNEL_SEL(a) ((a) << 1)
86168c9d95SJonathan Cameron 
87168c9d95SJonathan Cameron /* max1363 strictly 0x06 - but doesn't matter */
88168c9d95SJonathan Cameron #define MAX1363_CHANNEL_SEL_MASK		0x1E
89168c9d95SJonathan Cameron #define MAX1363_SCAN_MASK			0x60
90168c9d95SJonathan Cameron #define MAX1363_SE_DE_MASK			0x01
91168c9d95SJonathan Cameron 
92168c9d95SJonathan Cameron #define MAX1363_MAX_CHANNELS 25
93168c9d95SJonathan Cameron /**
94168c9d95SJonathan Cameron  * struct max1363_mode - scan mode information
95168c9d95SJonathan Cameron  * @conf:	The corresponding value of the configuration register
96168c9d95SJonathan Cameron  * @modemask:	Bit mask corresponding to channels enabled in this mode
97168c9d95SJonathan Cameron  */
98168c9d95SJonathan Cameron struct max1363_mode {
99168c9d95SJonathan Cameron 	int8_t		conf;
100168c9d95SJonathan Cameron 	DECLARE_BITMAP(modemask, MAX1363_MAX_CHANNELS);
101168c9d95SJonathan Cameron };
102168c9d95SJonathan Cameron 
103168c9d95SJonathan Cameron /* This must be maintained along side the max1363_mode_table in max1363_core */
104168c9d95SJonathan Cameron enum max1363_modes {
105168c9d95SJonathan Cameron 	/* Single read of a single channel */
106168c9d95SJonathan Cameron 	_s0, _s1, _s2, _s3, _s4, _s5, _s6, _s7, _s8, _s9, _s10, _s11,
107168c9d95SJonathan Cameron 	/* Differential single read */
108168c9d95SJonathan Cameron 	d0m1, d2m3, d4m5, d6m7, d8m9, d10m11,
109168c9d95SJonathan Cameron 	d1m0, d3m2, d5m4, d7m6, d9m8, d11m10,
110168c9d95SJonathan Cameron 	/* Scan to channel and mid to channel where overlapping */
111168c9d95SJonathan Cameron 	s0to1, s0to2, s2to3, s0to3, s0to4, s0to5, s0to6,
112168c9d95SJonathan Cameron 	s6to7, s0to7, s6to8, s0to8, s6to9,
113168c9d95SJonathan Cameron 	s0to9, s6to10, s0to10, s6to11, s0to11,
114168c9d95SJonathan Cameron 	/* Differential scan to channel and mid to channel where overlapping */
115168c9d95SJonathan Cameron 	d0m1to2m3, d0m1to4m5, d0m1to6m7, d6m7to8m9,
116168c9d95SJonathan Cameron 	d0m1to8m9, d6m7to10m11, d0m1to10m11, d1m0to3m2,
117168c9d95SJonathan Cameron 	d1m0to5m4, d1m0to7m6, d7m6to9m8, d1m0to9m8,
118168c9d95SJonathan Cameron 	d7m6to11m10, d1m0to11m10,
119168c9d95SJonathan Cameron };
120168c9d95SJonathan Cameron 
121168c9d95SJonathan Cameron /**
122168c9d95SJonathan Cameron  * struct max1363_chip_info - chip specifc information
123168c9d95SJonathan Cameron  * @info:		iio core function callbacks structure
124168c9d95SJonathan Cameron  * @channels:		channel specification
125168c9d95SJonathan Cameron  * @num_channels:       number of channels
126168c9d95SJonathan Cameron  * @mode_list:		array of available scan modes
127168c9d95SJonathan Cameron  * @default_mode:	the scan mode in which the chip starts up
128168c9d95SJonathan Cameron  * @int_vref_mv:	the internal reference voltage
12971d2c120SPeter Meerwald  * @num_modes:		number of modes
130168c9d95SJonathan Cameron  * @bits:		accuracy of the adc in bits
131168c9d95SJonathan Cameron  */
132168c9d95SJonathan Cameron struct max1363_chip_info {
133168c9d95SJonathan Cameron 	const struct iio_info		*info;
134168c9d95SJonathan Cameron 	const struct iio_chan_spec	*channels;
135168c9d95SJonathan Cameron 	int				num_channels;
136168c9d95SJonathan Cameron 	const enum max1363_modes	*mode_list;
137168c9d95SJonathan Cameron 	enum max1363_modes		default_mode;
138168c9d95SJonathan Cameron 	u16				int_vref_mv;
139168c9d95SJonathan Cameron 	u8				num_modes;
140168c9d95SJonathan Cameron 	u8				bits;
141168c9d95SJonathan Cameron };
142168c9d95SJonathan Cameron 
143168c9d95SJonathan Cameron /**
144168c9d95SJonathan Cameron  * struct max1363_state - driver instance specific data
145168c9d95SJonathan Cameron  * @client:		i2c_client
146168c9d95SJonathan Cameron  * @setupbyte:		cache of current device setup byte
147168c9d95SJonathan Cameron  * @configbyte:		cache of current device config byte
14871d2c120SPeter Meerwald  * @chip_info:		chip model specific constants, available modes, etc.
149168c9d95SJonathan Cameron  * @current_mode:	the scan mode of this chip
150168c9d95SJonathan Cameron  * @requestedmask:	a valid requested set of channels
151ea448671SLee Jones  * @lock:		lock to ensure state is consistent
152168c9d95SJonathan Cameron  * @monitor_on:		whether monitor mode is enabled
153168c9d95SJonathan Cameron  * @monitor_speed:	parameter corresponding to device monitor speed setting
154168c9d95SJonathan Cameron  * @mask_high:		bitmask for enabled high thresholds
155168c9d95SJonathan Cameron  * @mask_low:		bitmask for enabled low thresholds
156168c9d95SJonathan Cameron  * @thresh_high:	high threshold values
157168c9d95SJonathan Cameron  * @thresh_low:		low threshold values
158a405b00eSGuenter Roeck  * @vref:		Reference voltage regulator
159a405b00eSGuenter Roeck  * @vref_uv:		Actual (external or internal) reference voltage
16061bdda69SVivien Didelot  * @send:		function used to send data to the chip
16161bdda69SVivien Didelot  * @recv:		function used to receive data from the chip
162168c9d95SJonathan Cameron  */
163168c9d95SJonathan Cameron struct max1363_state {
164168c9d95SJonathan Cameron 	struct i2c_client		*client;
165168c9d95SJonathan Cameron 	u8				setupbyte;
166168c9d95SJonathan Cameron 	u8				configbyte;
167168c9d95SJonathan Cameron 	const struct max1363_chip_info	*chip_info;
168168c9d95SJonathan Cameron 	const struct max1363_mode	*current_mode;
169168c9d95SJonathan Cameron 	u32				requestedmask;
170bf09cddbSRohit Sarkar 	struct mutex			lock;
171168c9d95SJonathan Cameron 
172168c9d95SJonathan Cameron 	/* Using monitor modes and buffer at the same time is
173168c9d95SJonathan Cameron 	   currently not supported */
174168c9d95SJonathan Cameron 	bool				monitor_on;
175168c9d95SJonathan Cameron 	unsigned int			monitor_speed:3;
176168c9d95SJonathan Cameron 	u8				mask_high;
177168c9d95SJonathan Cameron 	u8				mask_low;
178168c9d95SJonathan Cameron 	/* 4x unipolar first then the fours bipolar ones */
179168c9d95SJonathan Cameron 	s16				thresh_high[8];
180168c9d95SJonathan Cameron 	s16				thresh_low[8];
181a405b00eSGuenter Roeck 	struct regulator		*vref;
182a405b00eSGuenter Roeck 	u32				vref_uv;
18361bdda69SVivien Didelot 	int				(*send)(const struct i2c_client *client,
18461bdda69SVivien Didelot 						const char *buf, int count);
18561bdda69SVivien Didelot 	int				(*recv)(const struct i2c_client *client,
18661bdda69SVivien Didelot 						char *buf, int count);
187168c9d95SJonathan Cameron };
188168c9d95SJonathan Cameron 
189168c9d95SJonathan Cameron #define MAX1363_MODE_SINGLE(_num, _mask) {				\
190168c9d95SJonathan Cameron 		.conf = MAX1363_CHANNEL_SEL(_num)			\
191168c9d95SJonathan Cameron 			| MAX1363_CONFIG_SCAN_SINGLE_1			\
192168c9d95SJonathan Cameron 			| MAX1363_CONFIG_SE,				\
193168c9d95SJonathan Cameron 			.modemask[0] = _mask,				\
194168c9d95SJonathan Cameron 			}
195168c9d95SJonathan Cameron 
196168c9d95SJonathan Cameron #define MAX1363_MODE_SCAN_TO_CHANNEL(_num, _mask) {			\
197168c9d95SJonathan Cameron 		.conf = MAX1363_CHANNEL_SEL(_num)			\
198168c9d95SJonathan Cameron 			| MAX1363_CONFIG_SCAN_TO_CS			\
199168c9d95SJonathan Cameron 			| MAX1363_CONFIG_SE,				\
200168c9d95SJonathan Cameron 			.modemask[0] = _mask,				\
201168c9d95SJonathan Cameron 			}
202168c9d95SJonathan Cameron 
203168c9d95SJonathan Cameron /* note not available for max1363 hence naming */
204168c9d95SJonathan Cameron #define MAX1236_MODE_SCAN_MID_TO_CHANNEL(_mid, _num, _mask) {		\
205168c9d95SJonathan Cameron 		.conf = MAX1363_CHANNEL_SEL(_num)			\
206168c9d95SJonathan Cameron 			| MAX1236_SCAN_MID_TO_CHANNEL			\
207168c9d95SJonathan Cameron 			| MAX1363_CONFIG_SE,				\
208168c9d95SJonathan Cameron 			.modemask[0] = _mask				\
209168c9d95SJonathan Cameron }
210168c9d95SJonathan Cameron 
211168c9d95SJonathan Cameron #define MAX1363_MODE_DIFF_SINGLE(_nump, _numm, _mask) {			\
212168c9d95SJonathan Cameron 		.conf = MAX1363_CHANNEL_SEL(_nump)			\
213168c9d95SJonathan Cameron 			| MAX1363_CONFIG_SCAN_SINGLE_1			\
214168c9d95SJonathan Cameron 			| MAX1363_CONFIG_DE,				\
215168c9d95SJonathan Cameron 			.modemask[0] = _mask				\
216168c9d95SJonathan Cameron 			}
217168c9d95SJonathan Cameron 
218168c9d95SJonathan Cameron /* Can't think how to automate naming so specify for now */
219168c9d95SJonathan Cameron #define MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(_num, _numvals, _mask) {	\
220168c9d95SJonathan Cameron 		.conf = MAX1363_CHANNEL_SEL(_num)			\
221168c9d95SJonathan Cameron 			| MAX1363_CONFIG_SCAN_TO_CS			\
222168c9d95SJonathan Cameron 			| MAX1363_CONFIG_DE,				\
223168c9d95SJonathan Cameron 			.modemask[0] = _mask				\
224168c9d95SJonathan Cameron 			}
225168c9d95SJonathan Cameron 
226168c9d95SJonathan Cameron /* note only available for max1363 hence naming */
227168c9d95SJonathan Cameron #define MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL(_num, _numvals, _mask) {	\
228168c9d95SJonathan Cameron 		.conf = MAX1363_CHANNEL_SEL(_num)			\
229168c9d95SJonathan Cameron 			| MAX1236_SCAN_MID_TO_CHANNEL			\
230168c9d95SJonathan Cameron 			| MAX1363_CONFIG_SE,				\
231168c9d95SJonathan Cameron 			.modemask[0] = _mask				\
232168c9d95SJonathan Cameron }
233168c9d95SJonathan Cameron 
234168c9d95SJonathan Cameron static const struct max1363_mode max1363_mode_table[] = {
235168c9d95SJonathan Cameron 	/* All of the single channel options first */
236168c9d95SJonathan Cameron 	MAX1363_MODE_SINGLE(0, 1 << 0),
237168c9d95SJonathan Cameron 	MAX1363_MODE_SINGLE(1, 1 << 1),
238168c9d95SJonathan Cameron 	MAX1363_MODE_SINGLE(2, 1 << 2),
239168c9d95SJonathan Cameron 	MAX1363_MODE_SINGLE(3, 1 << 3),
240168c9d95SJonathan Cameron 	MAX1363_MODE_SINGLE(4, 1 << 4),
241168c9d95SJonathan Cameron 	MAX1363_MODE_SINGLE(5, 1 << 5),
242168c9d95SJonathan Cameron 	MAX1363_MODE_SINGLE(6, 1 << 6),
243168c9d95SJonathan Cameron 	MAX1363_MODE_SINGLE(7, 1 << 7),
244168c9d95SJonathan Cameron 	MAX1363_MODE_SINGLE(8, 1 << 8),
245168c9d95SJonathan Cameron 	MAX1363_MODE_SINGLE(9, 1 << 9),
246168c9d95SJonathan Cameron 	MAX1363_MODE_SINGLE(10, 1 << 10),
247168c9d95SJonathan Cameron 	MAX1363_MODE_SINGLE(11, 1 << 11),
248168c9d95SJonathan Cameron 
249168c9d95SJonathan Cameron 	MAX1363_MODE_DIFF_SINGLE(0, 1, 1 << 12),
250168c9d95SJonathan Cameron 	MAX1363_MODE_DIFF_SINGLE(2, 3, 1 << 13),
251168c9d95SJonathan Cameron 	MAX1363_MODE_DIFF_SINGLE(4, 5, 1 << 14),
252168c9d95SJonathan Cameron 	MAX1363_MODE_DIFF_SINGLE(6, 7, 1 << 15),
253168c9d95SJonathan Cameron 	MAX1363_MODE_DIFF_SINGLE(8, 9, 1 << 16),
254168c9d95SJonathan Cameron 	MAX1363_MODE_DIFF_SINGLE(10, 11, 1 << 17),
255168c9d95SJonathan Cameron 	MAX1363_MODE_DIFF_SINGLE(1, 0, 1 << 18),
256168c9d95SJonathan Cameron 	MAX1363_MODE_DIFF_SINGLE(3, 2, 1 << 19),
257168c9d95SJonathan Cameron 	MAX1363_MODE_DIFF_SINGLE(5, 4, 1 << 20),
258168c9d95SJonathan Cameron 	MAX1363_MODE_DIFF_SINGLE(7, 6, 1 << 21),
259168c9d95SJonathan Cameron 	MAX1363_MODE_DIFF_SINGLE(9, 8, 1 << 22),
260168c9d95SJonathan Cameron 	MAX1363_MODE_DIFF_SINGLE(11, 10, 1 << 23),
261168c9d95SJonathan Cameron 
262168c9d95SJonathan Cameron 	/* The multichannel scans next */
263168c9d95SJonathan Cameron 	MAX1363_MODE_SCAN_TO_CHANNEL(1, 0x003),
264168c9d95SJonathan Cameron 	MAX1363_MODE_SCAN_TO_CHANNEL(2, 0x007),
265168c9d95SJonathan Cameron 	MAX1236_MODE_SCAN_MID_TO_CHANNEL(2, 3, 0x00C),
266168c9d95SJonathan Cameron 	MAX1363_MODE_SCAN_TO_CHANNEL(3, 0x00F),
267168c9d95SJonathan Cameron 	MAX1363_MODE_SCAN_TO_CHANNEL(4, 0x01F),
268168c9d95SJonathan Cameron 	MAX1363_MODE_SCAN_TO_CHANNEL(5, 0x03F),
269168c9d95SJonathan Cameron 	MAX1363_MODE_SCAN_TO_CHANNEL(6, 0x07F),
270168c9d95SJonathan Cameron 	MAX1236_MODE_SCAN_MID_TO_CHANNEL(6, 7, 0x0C0),
271168c9d95SJonathan Cameron 	MAX1363_MODE_SCAN_TO_CHANNEL(7, 0x0FF),
272168c9d95SJonathan Cameron 	MAX1236_MODE_SCAN_MID_TO_CHANNEL(6, 8, 0x1C0),
273168c9d95SJonathan Cameron 	MAX1363_MODE_SCAN_TO_CHANNEL(8, 0x1FF),
274168c9d95SJonathan Cameron 	MAX1236_MODE_SCAN_MID_TO_CHANNEL(6, 9, 0x3C0),
275168c9d95SJonathan Cameron 	MAX1363_MODE_SCAN_TO_CHANNEL(9, 0x3FF),
276168c9d95SJonathan Cameron 	MAX1236_MODE_SCAN_MID_TO_CHANNEL(6, 10, 0x7C0),
277168c9d95SJonathan Cameron 	MAX1363_MODE_SCAN_TO_CHANNEL(10, 0x7FF),
278168c9d95SJonathan Cameron 	MAX1236_MODE_SCAN_MID_TO_CHANNEL(6, 11, 0xFC0),
279168c9d95SJonathan Cameron 	MAX1363_MODE_SCAN_TO_CHANNEL(11, 0xFFF),
280168c9d95SJonathan Cameron 
281168c9d95SJonathan Cameron 	MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(2, 2, 0x003000),
282168c9d95SJonathan Cameron 	MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(4, 3, 0x007000),
283168c9d95SJonathan Cameron 	MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(6, 4, 0x00F000),
284168c9d95SJonathan Cameron 	MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL(8, 2, 0x018000),
285168c9d95SJonathan Cameron 	MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(8, 5, 0x01F000),
286168c9d95SJonathan Cameron 	MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL(10, 3, 0x038000),
287168c9d95SJonathan Cameron 	MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(10, 6, 0x3F000),
288168c9d95SJonathan Cameron 	MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(3, 2, 0x0C0000),
289168c9d95SJonathan Cameron 	MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(5, 3, 0x1C0000),
290168c9d95SJonathan Cameron 	MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(7, 4, 0x3C0000),
291168c9d95SJonathan Cameron 	MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL(9, 2, 0x600000),
292168c9d95SJonathan Cameron 	MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(9, 5, 0x7C0000),
293168c9d95SJonathan Cameron 	MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL(11, 3, 0xE00000),
294168c9d95SJonathan Cameron 	MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(11, 6, 0xFC0000),
295168c9d95SJonathan Cameron };
296168c9d95SJonathan Cameron 
297168c9d95SJonathan Cameron static const struct max1363_mode
max1363_match_mode(const unsigned long * mask,const struct max1363_chip_info * ci)298168c9d95SJonathan Cameron *max1363_match_mode(const unsigned long *mask,
299168c9d95SJonathan Cameron 	const struct max1363_chip_info *ci)
300168c9d95SJonathan Cameron {
301168c9d95SJonathan Cameron 	int i;
302168c9d95SJonathan Cameron 	if (mask)
303168c9d95SJonathan Cameron 		for (i = 0; i < ci->num_modes; i++)
304168c9d95SJonathan Cameron 			if (bitmap_subset(mask,
305168c9d95SJonathan Cameron 					  max1363_mode_table[ci->mode_list[i]].
306168c9d95SJonathan Cameron 					  modemask,
307168c9d95SJonathan Cameron 					  MAX1363_MAX_CHANNELS))
308168c9d95SJonathan Cameron 				return &max1363_mode_table[ci->mode_list[i]];
309168c9d95SJonathan Cameron 	return NULL;
310168c9d95SJonathan Cameron }
311168c9d95SJonathan Cameron 
max1363_smbus_send(const struct i2c_client * client,const char * buf,int count)31261bdda69SVivien Didelot static int max1363_smbus_send(const struct i2c_client *client, const char *buf,
31361bdda69SVivien Didelot 		int count)
314168c9d95SJonathan Cameron {
31561bdda69SVivien Didelot 	int i, err;
316168c9d95SJonathan Cameron 
31761bdda69SVivien Didelot 	for (i = err = 0; err == 0 && i < count; ++i)
31861bdda69SVivien Didelot 		err = i2c_smbus_write_byte(client, buf[i]);
31961bdda69SVivien Didelot 
32061bdda69SVivien Didelot 	return err ? err : count;
32161bdda69SVivien Didelot }
32261bdda69SVivien Didelot 
max1363_smbus_recv(const struct i2c_client * client,char * buf,int count)32361bdda69SVivien Didelot static int max1363_smbus_recv(const struct i2c_client *client, char *buf,
32461bdda69SVivien Didelot 		int count)
32561bdda69SVivien Didelot {
32661bdda69SVivien Didelot 	int i, ret;
32761bdda69SVivien Didelot 
32861bdda69SVivien Didelot 	for (i = 0; i < count; ++i) {
32961bdda69SVivien Didelot 		ret = i2c_smbus_read_byte(client);
33061bdda69SVivien Didelot 		if (ret < 0)
33161bdda69SVivien Didelot 			return ret;
33261bdda69SVivien Didelot 		buf[i] = ret;
33361bdda69SVivien Didelot 	}
33461bdda69SVivien Didelot 
33561bdda69SVivien Didelot 	return count;
33661bdda69SVivien Didelot }
33761bdda69SVivien Didelot 
max1363_write_basic_config(struct max1363_state * st)33861bdda69SVivien Didelot static int max1363_write_basic_config(struct max1363_state *st)
33961bdda69SVivien Didelot {
34061bdda69SVivien Didelot 	u8 tx_buf[2] = { st->setupbyte, st->configbyte };
34161bdda69SVivien Didelot 
34261bdda69SVivien Didelot 	return st->send(st->client, tx_buf, 2);
343168c9d95SJonathan Cameron }
344168c9d95SJonathan Cameron 
max1363_set_scan_mode(struct max1363_state * st)345168c9d95SJonathan Cameron static int max1363_set_scan_mode(struct max1363_state *st)
346168c9d95SJonathan Cameron {
347168c9d95SJonathan Cameron 	st->configbyte &= ~(MAX1363_CHANNEL_SEL_MASK
348168c9d95SJonathan Cameron 			    | MAX1363_SCAN_MASK
349168c9d95SJonathan Cameron 			    | MAX1363_SE_DE_MASK);
350168c9d95SJonathan Cameron 	st->configbyte |= st->current_mode->conf;
351168c9d95SJonathan Cameron 
35261bdda69SVivien Didelot 	return max1363_write_basic_config(st);
353168c9d95SJonathan Cameron }
354168c9d95SJonathan Cameron 
max1363_read_single_chan(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int * val,long m)355168c9d95SJonathan Cameron static int max1363_read_single_chan(struct iio_dev *indio_dev,
356168c9d95SJonathan Cameron 				    struct iio_chan_spec const *chan,
357168c9d95SJonathan Cameron 				    int *val,
358168c9d95SJonathan Cameron 				    long m)
359168c9d95SJonathan Cameron {
360168c9d95SJonathan Cameron 	int ret = 0;
361168c9d95SJonathan Cameron 	s32 data;
362482bb4e6SGuenter Roeck 	u8 rxbuf[2];
363168c9d95SJonathan Cameron 	struct max1363_state *st = iio_priv(indio_dev);
364168c9d95SJonathan Cameron 	struct i2c_client *client = st->client;
365168c9d95SJonathan Cameron 
366bf09cddbSRohit Sarkar 	ret = iio_device_claim_direct_mode(indio_dev);
367bf09cddbSRohit Sarkar 	if (ret)
368bf09cddbSRohit Sarkar 		return ret;
369bf09cddbSRohit Sarkar 	mutex_lock(&st->lock);
370bf09cddbSRohit Sarkar 
371168c9d95SJonathan Cameron 	/*
372168c9d95SJonathan Cameron 	 * If monitor mode is enabled, the method for reading a single
373168c9d95SJonathan Cameron 	 * channel will have to be rather different and has not yet
374168c9d95SJonathan Cameron 	 * been implemented.
375168c9d95SJonathan Cameron 	 *
376168c9d95SJonathan Cameron 	 * Also, cannot read directly if buffered capture enabled.
377168c9d95SJonathan Cameron 	 */
378bf09cddbSRohit Sarkar 	if (st->monitor_on) {
379168c9d95SJonathan Cameron 		ret = -EBUSY;
380168c9d95SJonathan Cameron 		goto error_ret;
381168c9d95SJonathan Cameron 	}
382168c9d95SJonathan Cameron 
383168c9d95SJonathan Cameron 	/* Check to see if current scan mode is correct */
384168c9d95SJonathan Cameron 	if (st->current_mode != &max1363_mode_table[chan->address]) {
385168c9d95SJonathan Cameron 		/* Update scan mode if needed */
386168c9d95SJonathan Cameron 		st->current_mode = &max1363_mode_table[chan->address];
387168c9d95SJonathan Cameron 		ret = max1363_set_scan_mode(st);
388168c9d95SJonathan Cameron 		if (ret < 0)
389168c9d95SJonathan Cameron 			goto error_ret;
390168c9d95SJonathan Cameron 	}
391168c9d95SJonathan Cameron 	if (st->chip_info->bits != 8) {
392168c9d95SJonathan Cameron 		/* Get reading */
39361bdda69SVivien Didelot 		data = st->recv(client, rxbuf, 2);
394168c9d95SJonathan Cameron 		if (data < 0) {
395168c9d95SJonathan Cameron 			ret = data;
396168c9d95SJonathan Cameron 			goto error_ret;
397168c9d95SJonathan Cameron 		}
398482bb4e6SGuenter Roeck 		data = (rxbuf[1] | rxbuf[0] << 8) &
399482bb4e6SGuenter Roeck 		  ((1 << st->chip_info->bits) - 1);
400168c9d95SJonathan Cameron 	} else {
401168c9d95SJonathan Cameron 		/* Get reading */
40261bdda69SVivien Didelot 		data = st->recv(client, rxbuf, 1);
403168c9d95SJonathan Cameron 		if (data < 0) {
404168c9d95SJonathan Cameron 			ret = data;
405168c9d95SJonathan Cameron 			goto error_ret;
406168c9d95SJonathan Cameron 		}
407168c9d95SJonathan Cameron 		data = rxbuf[0];
408168c9d95SJonathan Cameron 	}
409168c9d95SJonathan Cameron 	*val = data;
410bf09cddbSRohit Sarkar 
411168c9d95SJonathan Cameron error_ret:
412bf09cddbSRohit Sarkar 	mutex_unlock(&st->lock);
413bf09cddbSRohit Sarkar 	iio_device_release_direct_mode(indio_dev);
414168c9d95SJonathan Cameron 	return ret;
415168c9d95SJonathan Cameron 
416168c9d95SJonathan Cameron }
417168c9d95SJonathan Cameron 
max1363_read_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int * val,int * val2,long m)418168c9d95SJonathan Cameron static int max1363_read_raw(struct iio_dev *indio_dev,
419168c9d95SJonathan Cameron 			    struct iio_chan_spec const *chan,
420168c9d95SJonathan Cameron 			    int *val,
421168c9d95SJonathan Cameron 			    int *val2,
422168c9d95SJonathan Cameron 			    long m)
423168c9d95SJonathan Cameron {
424168c9d95SJonathan Cameron 	struct max1363_state *st = iio_priv(indio_dev);
425168c9d95SJonathan Cameron 	int ret;
426a405b00eSGuenter Roeck 
427168c9d95SJonathan Cameron 	switch (m) {
428168c9d95SJonathan Cameron 	case IIO_CHAN_INFO_RAW:
429168c9d95SJonathan Cameron 		ret = max1363_read_single_chan(indio_dev, chan, val, m);
430168c9d95SJonathan Cameron 		if (ret < 0)
431168c9d95SJonathan Cameron 			return ret;
432168c9d95SJonathan Cameron 		return IIO_VAL_INT;
433168c9d95SJonathan Cameron 	case IIO_CHAN_INFO_SCALE:
434b2171677SLars-Peter Clausen 		*val = st->vref_uv / 1000;
435b2171677SLars-Peter Clausen 		*val2 = st->chip_info->bits;
436b2171677SLars-Peter Clausen 		return IIO_VAL_FRACTIONAL_LOG2;
437168c9d95SJonathan Cameron 	default:
438168c9d95SJonathan Cameron 		return -EINVAL;
439168c9d95SJonathan Cameron 	}
440168c9d95SJonathan Cameron 	return 0;
441168c9d95SJonathan Cameron }
442168c9d95SJonathan Cameron 
443168c9d95SJonathan Cameron /* Applies to max1363 */
444168c9d95SJonathan Cameron static const enum max1363_modes max1363_mode_list[] = {
445168c9d95SJonathan Cameron 	_s0, _s1, _s2, _s3,
446168c9d95SJonathan Cameron 	s0to1, s0to2, s0to3,
447168c9d95SJonathan Cameron 	d0m1, d2m3, d1m0, d3m2,
448168c9d95SJonathan Cameron 	d0m1to2m3, d1m0to3m2,
449168c9d95SJonathan Cameron };
450168c9d95SJonathan Cameron 
451e4ec84f8SLars-Peter Clausen static const struct iio_event_spec max1363_events[] = {
452e4ec84f8SLars-Peter Clausen 	{
453e4ec84f8SLars-Peter Clausen 		.type = IIO_EV_TYPE_THRESH,
454e4ec84f8SLars-Peter Clausen 		.dir = IIO_EV_DIR_RISING,
455e4ec84f8SLars-Peter Clausen 		.mask_separate = BIT(IIO_EV_INFO_VALUE) |
456e4ec84f8SLars-Peter Clausen 			BIT(IIO_EV_INFO_ENABLE),
457e4ec84f8SLars-Peter Clausen 	}, {
458e4ec84f8SLars-Peter Clausen 		.type = IIO_EV_TYPE_THRESH,
459e4ec84f8SLars-Peter Clausen 		.dir = IIO_EV_DIR_FALLING,
460e4ec84f8SLars-Peter Clausen 		.mask_separate = BIT(IIO_EV_INFO_VALUE) |
461e4ec84f8SLars-Peter Clausen 			BIT(IIO_EV_INFO_ENABLE),
462e4ec84f8SLars-Peter Clausen 	},
463e4ec84f8SLars-Peter Clausen };
464f6e52e59SJonathan Cameron 
465e4ec84f8SLars-Peter Clausen #define MAX1363_CHAN_U(num, addr, si, bits, ev_spec, num_ev_spec)	\
466168c9d95SJonathan Cameron 	{								\
467168c9d95SJonathan Cameron 		.type = IIO_VOLTAGE,					\
468168c9d95SJonathan Cameron 		.indexed = 1,						\
469168c9d95SJonathan Cameron 		.channel = num,						\
470168c9d95SJonathan Cameron 		.address = addr,					\
471f6e52e59SJonathan Cameron 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\
472f6e52e59SJonathan Cameron 		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),	\
473168c9d95SJonathan Cameron 		.datasheet_name = "AIN"#num,				\
474168c9d95SJonathan Cameron 		.scan_type = {						\
475168c9d95SJonathan Cameron 			.sign = 'u',					\
476168c9d95SJonathan Cameron 			.realbits = bits,				\
477168c9d95SJonathan Cameron 			.storagebits = (bits > 8) ? 16 : 8,		\
478168c9d95SJonathan Cameron 			.endianness = IIO_BE,				\
479168c9d95SJonathan Cameron 		},							\
480168c9d95SJonathan Cameron 		.scan_index = si,					\
481e4ec84f8SLars-Peter Clausen 		.event_spec = ev_spec,					\
482e4ec84f8SLars-Peter Clausen 		.num_event_specs = num_ev_spec,				\
483168c9d95SJonathan Cameron 	}
484168c9d95SJonathan Cameron 
485168c9d95SJonathan Cameron /* bipolar channel */
486e4ec84f8SLars-Peter Clausen #define MAX1363_CHAN_B(num, num2, addr, si, bits, ev_spec, num_ev_spec)	\
487168c9d95SJonathan Cameron 	{								\
488168c9d95SJonathan Cameron 		.type = IIO_VOLTAGE,					\
489168c9d95SJonathan Cameron 		.differential = 1,					\
490168c9d95SJonathan Cameron 		.indexed = 1,						\
491168c9d95SJonathan Cameron 		.channel = num,						\
492168c9d95SJonathan Cameron 		.channel2 = num2,					\
493168c9d95SJonathan Cameron 		.address = addr,					\
494f6e52e59SJonathan Cameron 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\
495f6e52e59SJonathan Cameron 		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),	\
496168c9d95SJonathan Cameron 		.datasheet_name = "AIN"#num"-AIN"#num2,			\
497168c9d95SJonathan Cameron 		.scan_type = {						\
498168c9d95SJonathan Cameron 			.sign = 's',					\
499168c9d95SJonathan Cameron 			.realbits = bits,				\
500168c9d95SJonathan Cameron 			.storagebits = (bits > 8) ? 16 : 8,		\
501168c9d95SJonathan Cameron 			.endianness = IIO_BE,				\
502168c9d95SJonathan Cameron 		},							\
503168c9d95SJonathan Cameron 		.scan_index = si,					\
504e4ec84f8SLars-Peter Clausen 		.event_spec = ev_spec,					\
505e4ec84f8SLars-Peter Clausen 		.num_event_specs = num_ev_spec,				\
506168c9d95SJonathan Cameron 	}
507168c9d95SJonathan Cameron 
508e4ec84f8SLars-Peter Clausen #define MAX1363_4X_CHANS(bits, ev_spec, num_ev_spec) {			\
509e4ec84f8SLars-Peter Clausen 	MAX1363_CHAN_U(0, _s0, 0, bits, ev_spec, num_ev_spec),		\
510e4ec84f8SLars-Peter Clausen 	MAX1363_CHAN_U(1, _s1, 1, bits, ev_spec, num_ev_spec),		\
511e4ec84f8SLars-Peter Clausen 	MAX1363_CHAN_U(2, _s2, 2, bits, ev_spec, num_ev_spec),		\
512e4ec84f8SLars-Peter Clausen 	MAX1363_CHAN_U(3, _s3, 3, bits, ev_spec, num_ev_spec),		\
513e4ec84f8SLars-Peter Clausen 	MAX1363_CHAN_B(0, 1, d0m1, 4, bits, ev_spec, num_ev_spec),	\
514e4ec84f8SLars-Peter Clausen 	MAX1363_CHAN_B(2, 3, d2m3, 5, bits, ev_spec, num_ev_spec),	\
515e4ec84f8SLars-Peter Clausen 	MAX1363_CHAN_B(1, 0, d1m0, 6, bits, ev_spec, num_ev_spec),	\
516e4ec84f8SLars-Peter Clausen 	MAX1363_CHAN_B(3, 2, d3m2, 7, bits, ev_spec, num_ev_spec),	\
517168c9d95SJonathan Cameron 	IIO_CHAN_SOFT_TIMESTAMP(8)					\
518168c9d95SJonathan Cameron 	}
519168c9d95SJonathan Cameron 
520e4ec84f8SLars-Peter Clausen static const struct iio_chan_spec max1036_channels[] =
521e4ec84f8SLars-Peter Clausen 	MAX1363_4X_CHANS(8, NULL, 0);
522e4ec84f8SLars-Peter Clausen static const struct iio_chan_spec max1136_channels[] =
523e4ec84f8SLars-Peter Clausen 	MAX1363_4X_CHANS(10, NULL, 0);
524e4ec84f8SLars-Peter Clausen static const struct iio_chan_spec max1236_channels[] =
525e4ec84f8SLars-Peter Clausen 	MAX1363_4X_CHANS(12, NULL, 0);
526168c9d95SJonathan Cameron static const struct iio_chan_spec max1361_channels[] =
527e4ec84f8SLars-Peter Clausen 	MAX1363_4X_CHANS(10, max1363_events, ARRAY_SIZE(max1363_events));
528168c9d95SJonathan Cameron static const struct iio_chan_spec max1363_channels[] =
529e4ec84f8SLars-Peter Clausen 	MAX1363_4X_CHANS(12, max1363_events, ARRAY_SIZE(max1363_events));
530168c9d95SJonathan Cameron 
531168c9d95SJonathan Cameron /* Applies to max1236, max1237 */
532168c9d95SJonathan Cameron static const enum max1363_modes max1236_mode_list[] = {
533168c9d95SJonathan Cameron 	_s0, _s1, _s2, _s3,
534168c9d95SJonathan Cameron 	s0to1, s0to2, s0to3,
535168c9d95SJonathan Cameron 	d0m1, d2m3, d1m0, d3m2,
536168c9d95SJonathan Cameron 	d0m1to2m3, d1m0to3m2,
537168c9d95SJonathan Cameron 	s2to3,
538168c9d95SJonathan Cameron };
539168c9d95SJonathan Cameron 
540168c9d95SJonathan Cameron /* Applies to max1238, max1239 */
541168c9d95SJonathan Cameron static const enum max1363_modes max1238_mode_list[] = {
542168c9d95SJonathan Cameron 	_s0, _s1, _s2, _s3, _s4, _s5, _s6, _s7, _s8, _s9, _s10, _s11,
543168c9d95SJonathan Cameron 	s0to1, s0to2, s0to3, s0to4, s0to5, s0to6,
544168c9d95SJonathan Cameron 	s0to7, s0to8, s0to9, s0to10, s0to11,
545168c9d95SJonathan Cameron 	d0m1, d2m3, d4m5, d6m7, d8m9, d10m11,
546168c9d95SJonathan Cameron 	d1m0, d3m2, d5m4, d7m6, d9m8, d11m10,
547168c9d95SJonathan Cameron 	d0m1to2m3, d0m1to4m5, d0m1to6m7, d0m1to8m9, d0m1to10m11,
548168c9d95SJonathan Cameron 	d1m0to3m2, d1m0to5m4, d1m0to7m6, d1m0to9m8, d1m0to11m10,
549168c9d95SJonathan Cameron 	s6to7, s6to8, s6to9, s6to10, s6to11,
550168c9d95SJonathan Cameron 	d6m7to8m9, d6m7to10m11, d7m6to9m8, d7m6to11m10,
551168c9d95SJonathan Cameron };
552168c9d95SJonathan Cameron 
553168c9d95SJonathan Cameron #define MAX1363_12X_CHANS(bits) {				\
554e4ec84f8SLars-Peter Clausen 	MAX1363_CHAN_U(0, _s0, 0, bits, NULL, 0),		\
555e4ec84f8SLars-Peter Clausen 	MAX1363_CHAN_U(1, _s1, 1, bits, NULL, 0),		\
556e4ec84f8SLars-Peter Clausen 	MAX1363_CHAN_U(2, _s2, 2, bits, NULL, 0),		\
557e4ec84f8SLars-Peter Clausen 	MAX1363_CHAN_U(3, _s3, 3, bits, NULL, 0),		\
558e4ec84f8SLars-Peter Clausen 	MAX1363_CHAN_U(4, _s4, 4, bits, NULL, 0),		\
559e4ec84f8SLars-Peter Clausen 	MAX1363_CHAN_U(5, _s5, 5, bits, NULL, 0),		\
560e4ec84f8SLars-Peter Clausen 	MAX1363_CHAN_U(6, _s6, 6, bits, NULL, 0),		\
561e4ec84f8SLars-Peter Clausen 	MAX1363_CHAN_U(7, _s7, 7, bits, NULL, 0),		\
562e4ec84f8SLars-Peter Clausen 	MAX1363_CHAN_U(8, _s8, 8, bits, NULL, 0),		\
563e4ec84f8SLars-Peter Clausen 	MAX1363_CHAN_U(9, _s9, 9, bits, NULL, 0),		\
564e4ec84f8SLars-Peter Clausen 	MAX1363_CHAN_U(10, _s10, 10, bits, NULL, 0),		\
565e4ec84f8SLars-Peter Clausen 	MAX1363_CHAN_U(11, _s11, 11, bits, NULL, 0),		\
566e4ec84f8SLars-Peter Clausen 	MAX1363_CHAN_B(0, 1, d0m1, 12, bits, NULL, 0),		\
567e4ec84f8SLars-Peter Clausen 	MAX1363_CHAN_B(2, 3, d2m3, 13, bits, NULL, 0),		\
568e4ec84f8SLars-Peter Clausen 	MAX1363_CHAN_B(4, 5, d4m5, 14, bits, NULL, 0),		\
569e4ec84f8SLars-Peter Clausen 	MAX1363_CHAN_B(6, 7, d6m7, 15, bits, NULL, 0),		\
570e4ec84f8SLars-Peter Clausen 	MAX1363_CHAN_B(8, 9, d8m9, 16, bits, NULL, 0),		\
571e4ec84f8SLars-Peter Clausen 	MAX1363_CHAN_B(10, 11, d10m11, 17, bits, NULL, 0),	\
572e4ec84f8SLars-Peter Clausen 	MAX1363_CHAN_B(1, 0, d1m0, 18, bits, NULL, 0),		\
573e4ec84f8SLars-Peter Clausen 	MAX1363_CHAN_B(3, 2, d3m2, 19, bits, NULL, 0),		\
574e4ec84f8SLars-Peter Clausen 	MAX1363_CHAN_B(5, 4, d5m4, 20, bits, NULL, 0),		\
575e4ec84f8SLars-Peter Clausen 	MAX1363_CHAN_B(7, 6, d7m6, 21, bits, NULL, 0),		\
576e4ec84f8SLars-Peter Clausen 	MAX1363_CHAN_B(9, 8, d9m8, 22, bits, NULL, 0),		\
577e4ec84f8SLars-Peter Clausen 	MAX1363_CHAN_B(11, 10, d11m10, 23, bits, NULL, 0),	\
578168c9d95SJonathan Cameron 	IIO_CHAN_SOFT_TIMESTAMP(24)				\
579168c9d95SJonathan Cameron 	}
580168c9d95SJonathan Cameron static const struct iio_chan_spec max1038_channels[] = MAX1363_12X_CHANS(8);
581168c9d95SJonathan Cameron static const struct iio_chan_spec max1138_channels[] = MAX1363_12X_CHANS(10);
582168c9d95SJonathan Cameron static const struct iio_chan_spec max1238_channels[] = MAX1363_12X_CHANS(12);
583168c9d95SJonathan Cameron 
584168c9d95SJonathan Cameron static const enum max1363_modes max11607_mode_list[] = {
585168c9d95SJonathan Cameron 	_s0, _s1, _s2, _s3,
586168c9d95SJonathan Cameron 	s0to1, s0to2, s0to3,
587168c9d95SJonathan Cameron 	s2to3,
588168c9d95SJonathan Cameron 	d0m1, d2m3, d1m0, d3m2,
589168c9d95SJonathan Cameron 	d0m1to2m3, d1m0to3m2,
590168c9d95SJonathan Cameron };
591168c9d95SJonathan Cameron 
592168c9d95SJonathan Cameron static const enum max1363_modes max11608_mode_list[] = {
593168c9d95SJonathan Cameron 	_s0, _s1, _s2, _s3, _s4, _s5, _s6, _s7,
594168c9d95SJonathan Cameron 	s0to1, s0to2, s0to3, s0to4, s0to5, s0to6, s0to7,
595168c9d95SJonathan Cameron 	s6to7,
596168c9d95SJonathan Cameron 	d0m1, d2m3, d4m5, d6m7,
597168c9d95SJonathan Cameron 	d1m0, d3m2, d5m4, d7m6,
598168c9d95SJonathan Cameron 	d0m1to2m3, d0m1to4m5, d0m1to6m7,
599168c9d95SJonathan Cameron 	d1m0to3m2, d1m0to5m4, d1m0to7m6,
600168c9d95SJonathan Cameron };
601168c9d95SJonathan Cameron 
602168c9d95SJonathan Cameron #define MAX1363_8X_CHANS(bits) {			\
603e4ec84f8SLars-Peter Clausen 	MAX1363_CHAN_U(0, _s0, 0, bits, NULL, 0),	\
604e4ec84f8SLars-Peter Clausen 	MAX1363_CHAN_U(1, _s1, 1, bits, NULL, 0),	\
605e4ec84f8SLars-Peter Clausen 	MAX1363_CHAN_U(2, _s2, 2, bits, NULL, 0),	\
606e4ec84f8SLars-Peter Clausen 	MAX1363_CHAN_U(3, _s3, 3, bits, NULL, 0),	\
607e4ec84f8SLars-Peter Clausen 	MAX1363_CHAN_U(4, _s4, 4, bits, NULL, 0),	\
608e4ec84f8SLars-Peter Clausen 	MAX1363_CHAN_U(5, _s5, 5, bits, NULL, 0),	\
609e4ec84f8SLars-Peter Clausen 	MAX1363_CHAN_U(6, _s6, 6, bits, NULL, 0),	\
610e4ec84f8SLars-Peter Clausen 	MAX1363_CHAN_U(7, _s7, 7, bits, NULL, 0),	\
611e4ec84f8SLars-Peter Clausen 	MAX1363_CHAN_B(0, 1, d0m1, 8, bits, NULL, 0),	\
612e4ec84f8SLars-Peter Clausen 	MAX1363_CHAN_B(2, 3, d2m3, 9, bits, NULL, 0),	\
613e4ec84f8SLars-Peter Clausen 	MAX1363_CHAN_B(4, 5, d4m5, 10, bits, NULL, 0),	\
614e4ec84f8SLars-Peter Clausen 	MAX1363_CHAN_B(6, 7, d6m7, 11, bits, NULL, 0),	\
615e4ec84f8SLars-Peter Clausen 	MAX1363_CHAN_B(1, 0, d1m0, 12, bits, NULL, 0),	\
616e4ec84f8SLars-Peter Clausen 	MAX1363_CHAN_B(3, 2, d3m2, 13, bits, NULL, 0),	\
617e4ec84f8SLars-Peter Clausen 	MAX1363_CHAN_B(5, 4, d5m4, 14, bits, NULL, 0),	\
618e4ec84f8SLars-Peter Clausen 	MAX1363_CHAN_B(7, 6, d7m6, 15, bits, NULL, 0),	\
619168c9d95SJonathan Cameron 	IIO_CHAN_SOFT_TIMESTAMP(16)			\
620168c9d95SJonathan Cameron }
621168c9d95SJonathan Cameron static const struct iio_chan_spec max11602_channels[] = MAX1363_8X_CHANS(8);
622168c9d95SJonathan Cameron static const struct iio_chan_spec max11608_channels[] = MAX1363_8X_CHANS(10);
623168c9d95SJonathan Cameron static const struct iio_chan_spec max11614_channels[] = MAX1363_8X_CHANS(12);
624168c9d95SJonathan Cameron 
625168c9d95SJonathan Cameron static const enum max1363_modes max11644_mode_list[] = {
626168c9d95SJonathan Cameron 	_s0, _s1, s0to1, d0m1, d1m0,
627168c9d95SJonathan Cameron };
628168c9d95SJonathan Cameron 
629168c9d95SJonathan Cameron #define MAX1363_2X_CHANS(bits) {			\
630e4ec84f8SLars-Peter Clausen 	MAX1363_CHAN_U(0, _s0, 0, bits, NULL, 0),	\
631e4ec84f8SLars-Peter Clausen 	MAX1363_CHAN_U(1, _s1, 1, bits, NULL, 0),	\
632e4ec84f8SLars-Peter Clausen 	MAX1363_CHAN_B(0, 1, d0m1, 2, bits, NULL, 0),	\
633e4ec84f8SLars-Peter Clausen 	MAX1363_CHAN_B(1, 0, d1m0, 3, bits, NULL, 0),	\
634168c9d95SJonathan Cameron 	IIO_CHAN_SOFT_TIMESTAMP(4)			\
635168c9d95SJonathan Cameron 	}
636168c9d95SJonathan Cameron 
637168c9d95SJonathan Cameron static const struct iio_chan_spec max11646_channels[] = MAX1363_2X_CHANS(10);
638168c9d95SJonathan Cameron static const struct iio_chan_spec max11644_channels[] = MAX1363_2X_CHANS(12);
639168c9d95SJonathan Cameron 
640168c9d95SJonathan Cameron enum { max1361,
641168c9d95SJonathan Cameron        max1362,
642168c9d95SJonathan Cameron        max1363,
643168c9d95SJonathan Cameron        max1364,
644168c9d95SJonathan Cameron        max1036,
645168c9d95SJonathan Cameron        max1037,
646168c9d95SJonathan Cameron        max1038,
647168c9d95SJonathan Cameron        max1039,
648168c9d95SJonathan Cameron        max1136,
649168c9d95SJonathan Cameron        max1137,
650168c9d95SJonathan Cameron        max1138,
651168c9d95SJonathan Cameron        max1139,
652168c9d95SJonathan Cameron        max1236,
653168c9d95SJonathan Cameron        max1237,
654168c9d95SJonathan Cameron        max1238,
655168c9d95SJonathan Cameron        max1239,
656168c9d95SJonathan Cameron        max11600,
657168c9d95SJonathan Cameron        max11601,
658168c9d95SJonathan Cameron        max11602,
659168c9d95SJonathan Cameron        max11603,
660168c9d95SJonathan Cameron        max11604,
661168c9d95SJonathan Cameron        max11605,
662168c9d95SJonathan Cameron        max11606,
663168c9d95SJonathan Cameron        max11607,
664168c9d95SJonathan Cameron        max11608,
665168c9d95SJonathan Cameron        max11609,
666168c9d95SJonathan Cameron        max11610,
667168c9d95SJonathan Cameron        max11611,
668168c9d95SJonathan Cameron        max11612,
669168c9d95SJonathan Cameron        max11613,
670168c9d95SJonathan Cameron        max11614,
671168c9d95SJonathan Cameron        max11615,
672168c9d95SJonathan Cameron        max11616,
673168c9d95SJonathan Cameron        max11617,
674168c9d95SJonathan Cameron        max11644,
675168c9d95SJonathan Cameron        max11645,
676168c9d95SJonathan Cameron        max11646,
677168c9d95SJonathan Cameron        max11647
678168c9d95SJonathan Cameron };
679168c9d95SJonathan Cameron 
680168c9d95SJonathan Cameron static const int max1363_monitor_speeds[] = { 133000, 665000, 33300, 16600,
681168c9d95SJonathan Cameron 					      8300, 4200, 2000, 1000 };
682168c9d95SJonathan Cameron 
max1363_monitor_show_freq(struct device * dev,struct device_attribute * attr,char * buf)683168c9d95SJonathan Cameron static ssize_t max1363_monitor_show_freq(struct device *dev,
684168c9d95SJonathan Cameron 					struct device_attribute *attr,
685168c9d95SJonathan Cameron 					char *buf)
686168c9d95SJonathan Cameron {
687168c9d95SJonathan Cameron 	struct max1363_state *st = iio_priv(dev_to_iio_dev(dev));
688168c9d95SJonathan Cameron 	return sprintf(buf, "%d\n", max1363_monitor_speeds[st->monitor_speed]);
689168c9d95SJonathan Cameron }
690168c9d95SJonathan Cameron 
max1363_monitor_store_freq(struct device * dev,struct device_attribute * attr,const char * buf,size_t len)691168c9d95SJonathan Cameron static ssize_t max1363_monitor_store_freq(struct device *dev,
692168c9d95SJonathan Cameron 					struct device_attribute *attr,
693168c9d95SJonathan Cameron 					const char *buf,
694168c9d95SJonathan Cameron 					size_t len)
695168c9d95SJonathan Cameron {
696168c9d95SJonathan Cameron 	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
697168c9d95SJonathan Cameron 	struct max1363_state *st = iio_priv(indio_dev);
698168c9d95SJonathan Cameron 	int i, ret;
699168c9d95SJonathan Cameron 	unsigned long val;
700168c9d95SJonathan Cameron 	bool found = false;
701168c9d95SJonathan Cameron 
702ddeb64f3SJingoo Han 	ret = kstrtoul(buf, 10, &val);
703168c9d95SJonathan Cameron 	if (ret)
704168c9d95SJonathan Cameron 		return -EINVAL;
705168c9d95SJonathan Cameron 	for (i = 0; i < ARRAY_SIZE(max1363_monitor_speeds); i++)
706168c9d95SJonathan Cameron 		if (val == max1363_monitor_speeds[i]) {
707168c9d95SJonathan Cameron 			found = true;
708168c9d95SJonathan Cameron 			break;
709168c9d95SJonathan Cameron 		}
710168c9d95SJonathan Cameron 	if (!found)
711168c9d95SJonathan Cameron 		return -EINVAL;
712168c9d95SJonathan Cameron 
713bf09cddbSRohit Sarkar 	mutex_lock(&st->lock);
714168c9d95SJonathan Cameron 	st->monitor_speed = i;
715bf09cddbSRohit Sarkar 	mutex_unlock(&st->lock);
716168c9d95SJonathan Cameron 
717168c9d95SJonathan Cameron 	return 0;
718168c9d95SJonathan Cameron }
719168c9d95SJonathan Cameron 
720168c9d95SJonathan Cameron static IIO_DEV_ATTR_SAMP_FREQ(S_IRUGO | S_IWUSR,
721168c9d95SJonathan Cameron 			max1363_monitor_show_freq,
722168c9d95SJonathan Cameron 			max1363_monitor_store_freq);
723168c9d95SJonathan Cameron 
724168c9d95SJonathan Cameron static IIO_CONST_ATTR(sampling_frequency_available,
725168c9d95SJonathan Cameron 		"133000 665000 33300 16600 8300 4200 2000 1000");
726168c9d95SJonathan Cameron 
max1363_read_thresh(struct iio_dev * indio_dev,const struct iio_chan_spec * chan,enum iio_event_type type,enum iio_event_direction dir,enum iio_event_info info,int * val,int * val2)727168c9d95SJonathan Cameron static int max1363_read_thresh(struct iio_dev *indio_dev,
728e4ec84f8SLars-Peter Clausen 	const struct iio_chan_spec *chan, enum iio_event_type type,
729e4ec84f8SLars-Peter Clausen 	enum iio_event_direction dir, enum iio_event_info info, int *val,
730e4ec84f8SLars-Peter Clausen 	int *val2)
731168c9d95SJonathan Cameron {
732168c9d95SJonathan Cameron 	struct max1363_state *st = iio_priv(indio_dev);
733e4ec84f8SLars-Peter Clausen 	if (dir == IIO_EV_DIR_FALLING)
734e4ec84f8SLars-Peter Clausen 		*val = st->thresh_low[chan->channel];
735168c9d95SJonathan Cameron 	else
736e4ec84f8SLars-Peter Clausen 		*val = st->thresh_high[chan->channel];
737e4ec84f8SLars-Peter Clausen 	return IIO_VAL_INT;
738168c9d95SJonathan Cameron }
739168c9d95SJonathan Cameron 
max1363_write_thresh(struct iio_dev * indio_dev,const struct iio_chan_spec * chan,enum iio_event_type type,enum iio_event_direction dir,enum iio_event_info info,int val,int val2)740168c9d95SJonathan Cameron static int max1363_write_thresh(struct iio_dev *indio_dev,
741e4ec84f8SLars-Peter Clausen 	const struct iio_chan_spec *chan, enum iio_event_type type,
742e4ec84f8SLars-Peter Clausen 	enum iio_event_direction dir, enum iio_event_info info, int val,
743e4ec84f8SLars-Peter Clausen 	int val2)
744168c9d95SJonathan Cameron {
745168c9d95SJonathan Cameron 	struct max1363_state *st = iio_priv(indio_dev);
746168c9d95SJonathan Cameron 	/* make it handle signed correctly as well */
747168c9d95SJonathan Cameron 	switch (st->chip_info->bits) {
748168c9d95SJonathan Cameron 	case 10:
749168c9d95SJonathan Cameron 		if (val > 0x3FF)
750168c9d95SJonathan Cameron 			return -EINVAL;
751168c9d95SJonathan Cameron 		break;
752168c9d95SJonathan Cameron 	case 12:
753168c9d95SJonathan Cameron 		if (val > 0xFFF)
754168c9d95SJonathan Cameron 			return -EINVAL;
755168c9d95SJonathan Cameron 		break;
756168c9d95SJonathan Cameron 	}
757168c9d95SJonathan Cameron 
758e4ec84f8SLars-Peter Clausen 	switch (dir) {
759168c9d95SJonathan Cameron 	case IIO_EV_DIR_FALLING:
760e4ec84f8SLars-Peter Clausen 		st->thresh_low[chan->channel] = val;
761168c9d95SJonathan Cameron 		break;
762168c9d95SJonathan Cameron 	case IIO_EV_DIR_RISING:
763e4ec84f8SLars-Peter Clausen 		st->thresh_high[chan->channel] = val;
764168c9d95SJonathan Cameron 		break;
765e4ec84f8SLars-Peter Clausen 	default:
766e4ec84f8SLars-Peter Clausen 		return -EINVAL;
767168c9d95SJonathan Cameron 	}
768168c9d95SJonathan Cameron 
769168c9d95SJonathan Cameron 	return 0;
770168c9d95SJonathan Cameron }
771168c9d95SJonathan Cameron 
772168c9d95SJonathan Cameron static const u64 max1363_event_codes[] = {
773168c9d95SJonathan Cameron 	IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 0,
774168c9d95SJonathan Cameron 			     IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING),
775168c9d95SJonathan Cameron 	IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 1,
776168c9d95SJonathan Cameron 			     IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING),
777168c9d95SJonathan Cameron 	IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 2,
778168c9d95SJonathan Cameron 			     IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING),
779168c9d95SJonathan Cameron 	IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 3,
780168c9d95SJonathan Cameron 			     IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING),
781168c9d95SJonathan Cameron 	IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 0,
782168c9d95SJonathan Cameron 			     IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING),
783168c9d95SJonathan Cameron 	IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 1,
784168c9d95SJonathan Cameron 			     IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING),
785168c9d95SJonathan Cameron 	IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 2,
786168c9d95SJonathan Cameron 			     IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING),
787168c9d95SJonathan Cameron 	IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 3,
788168c9d95SJonathan Cameron 			     IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING),
789168c9d95SJonathan Cameron };
790168c9d95SJonathan Cameron 
max1363_event_handler(int irq,void * private)791168c9d95SJonathan Cameron static irqreturn_t max1363_event_handler(int irq, void *private)
792168c9d95SJonathan Cameron {
793168c9d95SJonathan Cameron 	struct iio_dev *indio_dev = private;
794168c9d95SJonathan Cameron 	struct max1363_state *st = iio_priv(indio_dev);
795bc2b7dabSGregor Boirie 	s64 timestamp = iio_get_time_ns(indio_dev);
796168c9d95SJonathan Cameron 	unsigned long mask, loc;
797168c9d95SJonathan Cameron 	u8 rx;
798168c9d95SJonathan Cameron 	u8 tx[2] = { st->setupbyte,
799168c9d95SJonathan Cameron 		     MAX1363_MON_INT_ENABLE | (st->monitor_speed << 1) | 0xF0 };
800168c9d95SJonathan Cameron 
80161bdda69SVivien Didelot 	st->recv(st->client, &rx, 1);
802168c9d95SJonathan Cameron 	mask = rx;
803168c9d95SJonathan Cameron 	for_each_set_bit(loc, &mask, 8)
804168c9d95SJonathan Cameron 		iio_push_event(indio_dev, max1363_event_codes[loc], timestamp);
80561bdda69SVivien Didelot 	st->send(st->client, tx, 2);
806168c9d95SJonathan Cameron 
807168c9d95SJonathan Cameron 	return IRQ_HANDLED;
808168c9d95SJonathan Cameron }
809168c9d95SJonathan Cameron 
max1363_read_event_config(struct iio_dev * indio_dev,const struct iio_chan_spec * chan,enum iio_event_type type,enum iio_event_direction dir)810168c9d95SJonathan Cameron static int max1363_read_event_config(struct iio_dev *indio_dev,
811e4ec84f8SLars-Peter Clausen 	const struct iio_chan_spec *chan, enum iio_event_type type,
812e4ec84f8SLars-Peter Clausen 	enum iio_event_direction dir)
813168c9d95SJonathan Cameron {
814168c9d95SJonathan Cameron 	struct max1363_state *st = iio_priv(indio_dev);
815168c9d95SJonathan Cameron 	int val;
816e4ec84f8SLars-Peter Clausen 	int number = chan->channel;
817168c9d95SJonathan Cameron 
818bf09cddbSRohit Sarkar 	mutex_lock(&st->lock);
819e4ec84f8SLars-Peter Clausen 	if (dir == IIO_EV_DIR_FALLING)
820168c9d95SJonathan Cameron 		val = (1 << number) & st->mask_low;
821168c9d95SJonathan Cameron 	else
822168c9d95SJonathan Cameron 		val = (1 << number) & st->mask_high;
823bf09cddbSRohit Sarkar 	mutex_unlock(&st->lock);
824168c9d95SJonathan Cameron 
825168c9d95SJonathan Cameron 	return val;
826168c9d95SJonathan Cameron }
827168c9d95SJonathan Cameron 
max1363_monitor_mode_update(struct max1363_state * st,int enabled)828168c9d95SJonathan Cameron static int max1363_monitor_mode_update(struct max1363_state *st, int enabled)
829168c9d95SJonathan Cameron {
830168c9d95SJonathan Cameron 	u8 *tx_buf;
831168c9d95SJonathan Cameron 	int ret, i = 3, j;
832168c9d95SJonathan Cameron 	unsigned long numelements;
833168c9d95SJonathan Cameron 	int len;
834168c9d95SJonathan Cameron 	const long *modemask;
835168c9d95SJonathan Cameron 
836168c9d95SJonathan Cameron 	if (!enabled) {
837168c9d95SJonathan Cameron 		/* transition to buffered capture is not currently supported */
838168c9d95SJonathan Cameron 		st->setupbyte &= ~MAX1363_SETUP_MONITOR_SETUP;
839168c9d95SJonathan Cameron 		st->configbyte &= ~MAX1363_SCAN_MASK;
840168c9d95SJonathan Cameron 		st->monitor_on = false;
84161bdda69SVivien Didelot 		return max1363_write_basic_config(st);
842168c9d95SJonathan Cameron 	}
843168c9d95SJonathan Cameron 
844168c9d95SJonathan Cameron 	/* Ensure we are in the relevant mode */
845168c9d95SJonathan Cameron 	st->setupbyte |= MAX1363_SETUP_MONITOR_SETUP;
846168c9d95SJonathan Cameron 	st->configbyte &= ~(MAX1363_CHANNEL_SEL_MASK
847168c9d95SJonathan Cameron 			    | MAX1363_SCAN_MASK
848168c9d95SJonathan Cameron 			| MAX1363_SE_DE_MASK);
849168c9d95SJonathan Cameron 	st->configbyte |= MAX1363_CONFIG_SCAN_MONITOR_MODE;
850168c9d95SJonathan Cameron 	if ((st->mask_low | st->mask_high) & 0x0F) {
851168c9d95SJonathan Cameron 		st->configbyte |= max1363_mode_table[s0to3].conf;
852168c9d95SJonathan Cameron 		modemask = max1363_mode_table[s0to3].modemask;
853168c9d95SJonathan Cameron 	} else if ((st->mask_low | st->mask_high) & 0x30) {
854168c9d95SJonathan Cameron 		st->configbyte |= max1363_mode_table[d0m1to2m3].conf;
855168c9d95SJonathan Cameron 		modemask = max1363_mode_table[d0m1to2m3].modemask;
856168c9d95SJonathan Cameron 	} else {
857168c9d95SJonathan Cameron 		st->configbyte |= max1363_mode_table[d1m0to3m2].conf;
858168c9d95SJonathan Cameron 		modemask = max1363_mode_table[d1m0to3m2].modemask;
859168c9d95SJonathan Cameron 	}
860168c9d95SJonathan Cameron 	numelements = bitmap_weight(modemask, MAX1363_MAX_CHANNELS);
861168c9d95SJonathan Cameron 	len = 3 * numelements + 3;
862168c9d95SJonathan Cameron 	tx_buf = kmalloc(len, GFP_KERNEL);
863168c9d95SJonathan Cameron 	if (!tx_buf) {
864168c9d95SJonathan Cameron 		ret = -ENOMEM;
865168c9d95SJonathan Cameron 		goto error_ret;
866168c9d95SJonathan Cameron 	}
867168c9d95SJonathan Cameron 	tx_buf[0] = st->configbyte;
868168c9d95SJonathan Cameron 	tx_buf[1] = st->setupbyte;
869168c9d95SJonathan Cameron 	tx_buf[2] = (st->monitor_speed << 1);
870168c9d95SJonathan Cameron 
871168c9d95SJonathan Cameron 	/*
872168c9d95SJonathan Cameron 	 * So we need to do yet another bit of nefarious scan mode
873168c9d95SJonathan Cameron 	 * setup to match what we need.
874168c9d95SJonathan Cameron 	 */
875168c9d95SJonathan Cameron 	for (j = 0; j < 8; j++)
876168c9d95SJonathan Cameron 		if (test_bit(j, modemask)) {
877168c9d95SJonathan Cameron 			/* Establish the mode is in the scan */
878168c9d95SJonathan Cameron 			if (st->mask_low & (1 << j)) {
879168c9d95SJonathan Cameron 				tx_buf[i] = (st->thresh_low[j] >> 4) & 0xFF;
880168c9d95SJonathan Cameron 				tx_buf[i + 1] = (st->thresh_low[j] << 4) & 0xF0;
881168c9d95SJonathan Cameron 			} else if (j < 4) {
882168c9d95SJonathan Cameron 				tx_buf[i] = 0;
883168c9d95SJonathan Cameron 				tx_buf[i + 1] = 0;
884168c9d95SJonathan Cameron 			} else {
885168c9d95SJonathan Cameron 				tx_buf[i] = 0x80;
886168c9d95SJonathan Cameron 				tx_buf[i + 1] = 0;
887168c9d95SJonathan Cameron 			}
888168c9d95SJonathan Cameron 			if (st->mask_high & (1 << j)) {
889168c9d95SJonathan Cameron 				tx_buf[i + 1] |=
890168c9d95SJonathan Cameron 					(st->thresh_high[j] >> 8) & 0x0F;
891168c9d95SJonathan Cameron 				tx_buf[i + 2] = st->thresh_high[j] & 0xFF;
892168c9d95SJonathan Cameron 			} else if (j < 4) {
893168c9d95SJonathan Cameron 				tx_buf[i + 1] |= 0x0F;
894168c9d95SJonathan Cameron 				tx_buf[i + 2] = 0xFF;
895168c9d95SJonathan Cameron 			} else {
896168c9d95SJonathan Cameron 				tx_buf[i + 1] |= 0x07;
897168c9d95SJonathan Cameron 				tx_buf[i + 2] = 0xFF;
898168c9d95SJonathan Cameron 			}
899168c9d95SJonathan Cameron 			i += 3;
900168c9d95SJonathan Cameron 		}
901168c9d95SJonathan Cameron 
902168c9d95SJonathan Cameron 
90361bdda69SVivien Didelot 	ret = st->send(st->client, tx_buf, len);
904168c9d95SJonathan Cameron 	if (ret < 0)
905168c9d95SJonathan Cameron 		goto error_ret;
906168c9d95SJonathan Cameron 	if (ret != len) {
907168c9d95SJonathan Cameron 		ret = -EIO;
908168c9d95SJonathan Cameron 		goto error_ret;
909168c9d95SJonathan Cameron 	}
910168c9d95SJonathan Cameron 
911168c9d95SJonathan Cameron 	/*
912168c9d95SJonathan Cameron 	 * Now that we hopefully have sensible thresholds in place it is
913168c9d95SJonathan Cameron 	 * time to turn the interrupts on.
914168c9d95SJonathan Cameron 	 * It is unclear from the data sheet if this should be necessary
915168c9d95SJonathan Cameron 	 * (i.e. whether monitor mode setup is atomic) but it appears to
916168c9d95SJonathan Cameron 	 * be in practice.
917168c9d95SJonathan Cameron 	 */
918168c9d95SJonathan Cameron 	tx_buf[0] = st->setupbyte;
919168c9d95SJonathan Cameron 	tx_buf[1] = MAX1363_MON_INT_ENABLE | (st->monitor_speed << 1) | 0xF0;
92061bdda69SVivien Didelot 	ret = st->send(st->client, tx_buf, 2);
921168c9d95SJonathan Cameron 	if (ret < 0)
922168c9d95SJonathan Cameron 		goto error_ret;
923168c9d95SJonathan Cameron 	if (ret != 2) {
924168c9d95SJonathan Cameron 		ret = -EIO;
925168c9d95SJonathan Cameron 		goto error_ret;
926168c9d95SJonathan Cameron 	}
927168c9d95SJonathan Cameron 	ret = 0;
928168c9d95SJonathan Cameron 	st->monitor_on = true;
929168c9d95SJonathan Cameron error_ret:
930168c9d95SJonathan Cameron 
931168c9d95SJonathan Cameron 	kfree(tx_buf);
932168c9d95SJonathan Cameron 
933168c9d95SJonathan Cameron 	return ret;
934168c9d95SJonathan Cameron }
935168c9d95SJonathan Cameron 
936168c9d95SJonathan Cameron /*
937168c9d95SJonathan Cameron  * To keep this manageable we always use one of 3 scan modes.
938168c9d95SJonathan Cameron  * Scan 0...3, 0-1,2-3 and 1-0,3-2
939168c9d95SJonathan Cameron  */
940168c9d95SJonathan Cameron 
__max1363_check_event_mask(int thismask,int checkmask)941168c9d95SJonathan Cameron static inline int __max1363_check_event_mask(int thismask, int checkmask)
942168c9d95SJonathan Cameron {
943168c9d95SJonathan Cameron 	int ret = 0;
944168c9d95SJonathan Cameron 	/* Is it unipolar */
945168c9d95SJonathan Cameron 	if (thismask < 4) {
946168c9d95SJonathan Cameron 		if (checkmask & ~0x0F) {
947168c9d95SJonathan Cameron 			ret = -EBUSY;
948168c9d95SJonathan Cameron 			goto error_ret;
949168c9d95SJonathan Cameron 		}
950168c9d95SJonathan Cameron 	} else if (thismask < 6) {
951168c9d95SJonathan Cameron 		if (checkmask & ~0x30) {
952168c9d95SJonathan Cameron 			ret = -EBUSY;
953168c9d95SJonathan Cameron 			goto error_ret;
954168c9d95SJonathan Cameron 		}
955168c9d95SJonathan Cameron 	} else if (checkmask & ~0xC0)
956168c9d95SJonathan Cameron 		ret = -EBUSY;
957168c9d95SJonathan Cameron error_ret:
958168c9d95SJonathan Cameron 	return ret;
959168c9d95SJonathan Cameron }
960168c9d95SJonathan Cameron 
max1363_write_event_config(struct iio_dev * indio_dev,const struct iio_chan_spec * chan,enum iio_event_type type,enum iio_event_direction dir,int state)961168c9d95SJonathan Cameron static int max1363_write_event_config(struct iio_dev *indio_dev,
962e4ec84f8SLars-Peter Clausen 	const struct iio_chan_spec *chan, enum iio_event_type type,
963e4ec84f8SLars-Peter Clausen 	enum iio_event_direction dir, int state)
964168c9d95SJonathan Cameron {
965168c9d95SJonathan Cameron 	int ret = 0;
966168c9d95SJonathan Cameron 	struct max1363_state *st = iio_priv(indio_dev);
967168c9d95SJonathan Cameron 	u16 unifiedmask;
968e4ec84f8SLars-Peter Clausen 	int number = chan->channel;
969168c9d95SJonathan Cameron 
970bf09cddbSRohit Sarkar 	ret = iio_device_claim_direct_mode(indio_dev);
971bf09cddbSRohit Sarkar 	if (ret)
972bf09cddbSRohit Sarkar 		return ret;
973bf09cddbSRohit Sarkar 	mutex_lock(&st->lock);
974bf09cddbSRohit Sarkar 
975168c9d95SJonathan Cameron 	unifiedmask = st->mask_low | st->mask_high;
976e4ec84f8SLars-Peter Clausen 	if (dir == IIO_EV_DIR_FALLING) {
977168c9d95SJonathan Cameron 
978168c9d95SJonathan Cameron 		if (state == 0)
979168c9d95SJonathan Cameron 			st->mask_low &= ~(1 << number);
980168c9d95SJonathan Cameron 		else {
981168c9d95SJonathan Cameron 			ret = __max1363_check_event_mask((1 << number),
982168c9d95SJonathan Cameron 							 unifiedmask);
983168c9d95SJonathan Cameron 			if (ret)
984168c9d95SJonathan Cameron 				goto error_ret;
985168c9d95SJonathan Cameron 			st->mask_low |= (1 << number);
986168c9d95SJonathan Cameron 		}
987168c9d95SJonathan Cameron 	} else {
988168c9d95SJonathan Cameron 		if (state == 0)
989168c9d95SJonathan Cameron 			st->mask_high &= ~(1 << number);
990168c9d95SJonathan Cameron 		else {
991168c9d95SJonathan Cameron 			ret = __max1363_check_event_mask((1 << number),
992168c9d95SJonathan Cameron 							 unifiedmask);
993168c9d95SJonathan Cameron 			if (ret)
994168c9d95SJonathan Cameron 				goto error_ret;
995168c9d95SJonathan Cameron 			st->mask_high |= (1 << number);
996168c9d95SJonathan Cameron 		}
997168c9d95SJonathan Cameron 	}
998168c9d95SJonathan Cameron 
999168c9d95SJonathan Cameron 	max1363_monitor_mode_update(st, !!(st->mask_high | st->mask_low));
1000168c9d95SJonathan Cameron error_ret:
1001bf09cddbSRohit Sarkar 	mutex_unlock(&st->lock);
1002bf09cddbSRohit Sarkar 	iio_device_release_direct_mode(indio_dev);
1003168c9d95SJonathan Cameron 
1004168c9d95SJonathan Cameron 	return ret;
1005168c9d95SJonathan Cameron }
1006168c9d95SJonathan Cameron 
1007168c9d95SJonathan Cameron /*
1008168c9d95SJonathan Cameron  * As with scan_elements, only certain sets of these can
1009168c9d95SJonathan Cameron  * be combined.
1010168c9d95SJonathan Cameron  */
1011168c9d95SJonathan Cameron static struct attribute *max1363_event_attributes[] = {
1012168c9d95SJonathan Cameron 	&iio_dev_attr_sampling_frequency.dev_attr.attr,
1013168c9d95SJonathan Cameron 	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
1014168c9d95SJonathan Cameron 	NULL,
1015168c9d95SJonathan Cameron };
1016168c9d95SJonathan Cameron 
1017c94645b1Ssimran singhal static const struct attribute_group max1363_event_attribute_group = {
1018168c9d95SJonathan Cameron 	.attrs = max1363_event_attributes,
1019168c9d95SJonathan Cameron };
1020168c9d95SJonathan Cameron 
max1363_update_scan_mode(struct iio_dev * indio_dev,const unsigned long * scan_mask)1021168c9d95SJonathan Cameron static int max1363_update_scan_mode(struct iio_dev *indio_dev,
1022168c9d95SJonathan Cameron 				    const unsigned long *scan_mask)
1023168c9d95SJonathan Cameron {
1024168c9d95SJonathan Cameron 	struct max1363_state *st = iio_priv(indio_dev);
1025168c9d95SJonathan Cameron 
1026168c9d95SJonathan Cameron 	/*
1027168c9d95SJonathan Cameron 	 * Need to figure out the current mode based upon the requested
1028168c9d95SJonathan Cameron 	 * scan mask in iio_dev
1029168c9d95SJonathan Cameron 	 */
1030168c9d95SJonathan Cameron 	st->current_mode = max1363_match_mode(scan_mask, st->chip_info);
1031168c9d95SJonathan Cameron 	if (!st->current_mode)
1032168c9d95SJonathan Cameron 		return -EINVAL;
1033168c9d95SJonathan Cameron 	max1363_set_scan_mode(st);
1034168c9d95SJonathan Cameron 	return 0;
1035168c9d95SJonathan Cameron }
1036168c9d95SJonathan Cameron 
1037168c9d95SJonathan Cameron static const struct iio_info max1238_info = {
1038168c9d95SJonathan Cameron 	.read_raw = &max1363_read_raw,
1039168c9d95SJonathan Cameron 	.update_scan_mode = &max1363_update_scan_mode,
1040168c9d95SJonathan Cameron };
1041168c9d95SJonathan Cameron 
1042168c9d95SJonathan Cameron static const struct iio_info max1363_info = {
1043cb955852SLars-Peter Clausen 	.read_event_value = &max1363_read_thresh,
1044cb955852SLars-Peter Clausen 	.write_event_value = &max1363_write_thresh,
1045cb955852SLars-Peter Clausen 	.read_event_config = &max1363_read_event_config,
1046cb955852SLars-Peter Clausen 	.write_event_config = &max1363_write_event_config,
1047168c9d95SJonathan Cameron 	.read_raw = &max1363_read_raw,
1048168c9d95SJonathan Cameron 	.update_scan_mode = &max1363_update_scan_mode,
1049168c9d95SJonathan Cameron 	.event_attrs = &max1363_event_attribute_group,
1050168c9d95SJonathan Cameron };
1051168c9d95SJonathan Cameron 
1052168c9d95SJonathan Cameron /* max1363 and max1368 tested - rest from data sheet */
1053168c9d95SJonathan Cameron static const struct max1363_chip_info max1363_chip_info_tbl[] = {
1054168c9d95SJonathan Cameron 	[max1361] = {
1055168c9d95SJonathan Cameron 		.bits = 10,
1056168c9d95SJonathan Cameron 		.int_vref_mv = 2048,
1057168c9d95SJonathan Cameron 		.mode_list = max1363_mode_list,
1058168c9d95SJonathan Cameron 		.num_modes = ARRAY_SIZE(max1363_mode_list),
1059168c9d95SJonathan Cameron 		.default_mode = s0to3,
1060168c9d95SJonathan Cameron 		.channels = max1361_channels,
1061168c9d95SJonathan Cameron 		.num_channels = ARRAY_SIZE(max1361_channels),
1062168c9d95SJonathan Cameron 		.info = &max1363_info,
1063168c9d95SJonathan Cameron 	},
1064168c9d95SJonathan Cameron 	[max1362] = {
1065168c9d95SJonathan Cameron 		.bits = 10,
1066168c9d95SJonathan Cameron 		.int_vref_mv = 4096,
1067168c9d95SJonathan Cameron 		.mode_list = max1363_mode_list,
1068168c9d95SJonathan Cameron 		.num_modes = ARRAY_SIZE(max1363_mode_list),
1069168c9d95SJonathan Cameron 		.default_mode = s0to3,
1070168c9d95SJonathan Cameron 		.channels = max1361_channels,
1071168c9d95SJonathan Cameron 		.num_channels = ARRAY_SIZE(max1361_channels),
1072168c9d95SJonathan Cameron 		.info = &max1363_info,
1073168c9d95SJonathan Cameron 	},
1074168c9d95SJonathan Cameron 	[max1363] = {
1075168c9d95SJonathan Cameron 		.bits = 12,
1076168c9d95SJonathan Cameron 		.int_vref_mv = 2048,
1077168c9d95SJonathan Cameron 		.mode_list = max1363_mode_list,
1078168c9d95SJonathan Cameron 		.num_modes = ARRAY_SIZE(max1363_mode_list),
1079168c9d95SJonathan Cameron 		.default_mode = s0to3,
1080168c9d95SJonathan Cameron 		.channels = max1363_channels,
1081168c9d95SJonathan Cameron 		.num_channels = ARRAY_SIZE(max1363_channels),
1082168c9d95SJonathan Cameron 		.info = &max1363_info,
1083168c9d95SJonathan Cameron 	},
1084168c9d95SJonathan Cameron 	[max1364] = {
1085168c9d95SJonathan Cameron 		.bits = 12,
1086168c9d95SJonathan Cameron 		.int_vref_mv = 4096,
1087168c9d95SJonathan Cameron 		.mode_list = max1363_mode_list,
1088168c9d95SJonathan Cameron 		.num_modes = ARRAY_SIZE(max1363_mode_list),
1089168c9d95SJonathan Cameron 		.default_mode = s0to3,
1090168c9d95SJonathan Cameron 		.channels = max1363_channels,
1091168c9d95SJonathan Cameron 		.num_channels = ARRAY_SIZE(max1363_channels),
1092168c9d95SJonathan Cameron 		.info = &max1363_info,
1093168c9d95SJonathan Cameron 	},
1094168c9d95SJonathan Cameron 	[max1036] = {
1095168c9d95SJonathan Cameron 		.bits = 8,
1096168c9d95SJonathan Cameron 		.int_vref_mv = 4096,
1097168c9d95SJonathan Cameron 		.mode_list = max1236_mode_list,
1098168c9d95SJonathan Cameron 		.num_modes = ARRAY_SIZE(max1236_mode_list),
1099168c9d95SJonathan Cameron 		.default_mode = s0to3,
1100168c9d95SJonathan Cameron 		.info = &max1238_info,
1101168c9d95SJonathan Cameron 		.channels = max1036_channels,
1102168c9d95SJonathan Cameron 		.num_channels = ARRAY_SIZE(max1036_channels),
1103168c9d95SJonathan Cameron 	},
1104168c9d95SJonathan Cameron 	[max1037] = {
1105168c9d95SJonathan Cameron 		.bits = 8,
1106168c9d95SJonathan Cameron 		.int_vref_mv = 2048,
1107168c9d95SJonathan Cameron 		.mode_list = max1236_mode_list,
1108168c9d95SJonathan Cameron 		.num_modes = ARRAY_SIZE(max1236_mode_list),
1109168c9d95SJonathan Cameron 		.default_mode = s0to3,
1110168c9d95SJonathan Cameron 		.info = &max1238_info,
1111168c9d95SJonathan Cameron 		.channels = max1036_channels,
1112168c9d95SJonathan Cameron 		.num_channels = ARRAY_SIZE(max1036_channels),
1113168c9d95SJonathan Cameron 	},
1114168c9d95SJonathan Cameron 	[max1038] = {
1115168c9d95SJonathan Cameron 		.bits = 8,
1116168c9d95SJonathan Cameron 		.int_vref_mv = 4096,
1117168c9d95SJonathan Cameron 		.mode_list = max1238_mode_list,
1118168c9d95SJonathan Cameron 		.num_modes = ARRAY_SIZE(max1238_mode_list),
1119168c9d95SJonathan Cameron 		.default_mode = s0to11,
1120168c9d95SJonathan Cameron 		.info = &max1238_info,
1121168c9d95SJonathan Cameron 		.channels = max1038_channels,
1122168c9d95SJonathan Cameron 		.num_channels = ARRAY_SIZE(max1038_channels),
1123168c9d95SJonathan Cameron 	},
1124168c9d95SJonathan Cameron 	[max1039] = {
1125168c9d95SJonathan Cameron 		.bits = 8,
1126168c9d95SJonathan Cameron 		.int_vref_mv = 2048,
1127168c9d95SJonathan Cameron 		.mode_list = max1238_mode_list,
1128168c9d95SJonathan Cameron 		.num_modes = ARRAY_SIZE(max1238_mode_list),
1129168c9d95SJonathan Cameron 		.default_mode = s0to11,
1130168c9d95SJonathan Cameron 		.info = &max1238_info,
1131168c9d95SJonathan Cameron 		.channels = max1038_channels,
1132168c9d95SJonathan Cameron 		.num_channels = ARRAY_SIZE(max1038_channels),
1133168c9d95SJonathan Cameron 	},
1134168c9d95SJonathan Cameron 	[max1136] = {
1135168c9d95SJonathan Cameron 		.bits = 10,
1136168c9d95SJonathan Cameron 		.int_vref_mv = 4096,
1137168c9d95SJonathan Cameron 		.mode_list = max1236_mode_list,
1138168c9d95SJonathan Cameron 		.num_modes = ARRAY_SIZE(max1236_mode_list),
1139168c9d95SJonathan Cameron 		.default_mode = s0to3,
1140168c9d95SJonathan Cameron 		.info = &max1238_info,
1141168c9d95SJonathan Cameron 		.channels = max1136_channels,
1142168c9d95SJonathan Cameron 		.num_channels = ARRAY_SIZE(max1136_channels),
1143168c9d95SJonathan Cameron 	},
1144168c9d95SJonathan Cameron 	[max1137] = {
1145168c9d95SJonathan Cameron 		.bits = 10,
1146168c9d95SJonathan Cameron 		.int_vref_mv = 2048,
1147168c9d95SJonathan Cameron 		.mode_list = max1236_mode_list,
1148168c9d95SJonathan Cameron 		.num_modes = ARRAY_SIZE(max1236_mode_list),
1149168c9d95SJonathan Cameron 		.default_mode = s0to3,
1150168c9d95SJonathan Cameron 		.info = &max1238_info,
1151168c9d95SJonathan Cameron 		.channels = max1136_channels,
1152168c9d95SJonathan Cameron 		.num_channels = ARRAY_SIZE(max1136_channels),
1153168c9d95SJonathan Cameron 	},
1154168c9d95SJonathan Cameron 	[max1138] = {
1155168c9d95SJonathan Cameron 		.bits = 10,
1156168c9d95SJonathan Cameron 		.int_vref_mv = 4096,
1157168c9d95SJonathan Cameron 		.mode_list = max1238_mode_list,
1158168c9d95SJonathan Cameron 		.num_modes = ARRAY_SIZE(max1238_mode_list),
1159168c9d95SJonathan Cameron 		.default_mode = s0to11,
1160168c9d95SJonathan Cameron 		.info = &max1238_info,
1161168c9d95SJonathan Cameron 		.channels = max1138_channels,
1162168c9d95SJonathan Cameron 		.num_channels = ARRAY_SIZE(max1138_channels),
1163168c9d95SJonathan Cameron 	},
1164168c9d95SJonathan Cameron 	[max1139] = {
1165168c9d95SJonathan Cameron 		.bits = 10,
1166168c9d95SJonathan Cameron 		.int_vref_mv = 2048,
1167168c9d95SJonathan Cameron 		.mode_list = max1238_mode_list,
1168168c9d95SJonathan Cameron 		.num_modes = ARRAY_SIZE(max1238_mode_list),
1169168c9d95SJonathan Cameron 		.default_mode = s0to11,
1170168c9d95SJonathan Cameron 		.info = &max1238_info,
1171168c9d95SJonathan Cameron 		.channels = max1138_channels,
1172168c9d95SJonathan Cameron 		.num_channels = ARRAY_SIZE(max1138_channels),
1173168c9d95SJonathan Cameron 	},
1174168c9d95SJonathan Cameron 	[max1236] = {
1175168c9d95SJonathan Cameron 		.bits = 12,
1176168c9d95SJonathan Cameron 		.int_vref_mv = 4096,
1177168c9d95SJonathan Cameron 		.mode_list = max1236_mode_list,
1178168c9d95SJonathan Cameron 		.num_modes = ARRAY_SIZE(max1236_mode_list),
1179168c9d95SJonathan Cameron 		.default_mode = s0to3,
1180168c9d95SJonathan Cameron 		.info = &max1238_info,
1181168c9d95SJonathan Cameron 		.channels = max1236_channels,
1182168c9d95SJonathan Cameron 		.num_channels = ARRAY_SIZE(max1236_channels),
1183168c9d95SJonathan Cameron 	},
1184168c9d95SJonathan Cameron 	[max1237] = {
1185168c9d95SJonathan Cameron 		.bits = 12,
1186168c9d95SJonathan Cameron 		.int_vref_mv = 2048,
1187168c9d95SJonathan Cameron 		.mode_list = max1236_mode_list,
1188168c9d95SJonathan Cameron 		.num_modes = ARRAY_SIZE(max1236_mode_list),
1189168c9d95SJonathan Cameron 		.default_mode = s0to3,
1190168c9d95SJonathan Cameron 		.info = &max1238_info,
1191168c9d95SJonathan Cameron 		.channels = max1236_channels,
1192168c9d95SJonathan Cameron 		.num_channels = ARRAY_SIZE(max1236_channels),
1193168c9d95SJonathan Cameron 	},
1194168c9d95SJonathan Cameron 	[max1238] = {
1195168c9d95SJonathan Cameron 		.bits = 12,
1196168c9d95SJonathan Cameron 		.int_vref_mv = 4096,
1197168c9d95SJonathan Cameron 		.mode_list = max1238_mode_list,
1198168c9d95SJonathan Cameron 		.num_modes = ARRAY_SIZE(max1238_mode_list),
1199168c9d95SJonathan Cameron 		.default_mode = s0to11,
1200168c9d95SJonathan Cameron 		.info = &max1238_info,
1201168c9d95SJonathan Cameron 		.channels = max1238_channels,
1202168c9d95SJonathan Cameron 		.num_channels = ARRAY_SIZE(max1238_channels),
1203168c9d95SJonathan Cameron 	},
1204168c9d95SJonathan Cameron 	[max1239] = {
1205168c9d95SJonathan Cameron 		.bits = 12,
1206168c9d95SJonathan Cameron 		.int_vref_mv = 2048,
1207168c9d95SJonathan Cameron 		.mode_list = max1238_mode_list,
1208168c9d95SJonathan Cameron 		.num_modes = ARRAY_SIZE(max1238_mode_list),
1209168c9d95SJonathan Cameron 		.default_mode = s0to11,
1210168c9d95SJonathan Cameron 		.info = &max1238_info,
1211168c9d95SJonathan Cameron 		.channels = max1238_channels,
1212168c9d95SJonathan Cameron 		.num_channels = ARRAY_SIZE(max1238_channels),
1213168c9d95SJonathan Cameron 	},
1214168c9d95SJonathan Cameron 	[max11600] = {
1215168c9d95SJonathan Cameron 		.bits = 8,
1216168c9d95SJonathan Cameron 		.int_vref_mv = 4096,
1217168c9d95SJonathan Cameron 		.mode_list = max11607_mode_list,
1218168c9d95SJonathan Cameron 		.num_modes = ARRAY_SIZE(max11607_mode_list),
1219168c9d95SJonathan Cameron 		.default_mode = s0to3,
1220168c9d95SJonathan Cameron 		.info = &max1238_info,
1221168c9d95SJonathan Cameron 		.channels = max1036_channels,
1222168c9d95SJonathan Cameron 		.num_channels = ARRAY_SIZE(max1036_channels),
1223168c9d95SJonathan Cameron 	},
1224168c9d95SJonathan Cameron 	[max11601] = {
1225168c9d95SJonathan Cameron 		.bits = 8,
1226168c9d95SJonathan Cameron 		.int_vref_mv = 2048,
1227168c9d95SJonathan Cameron 		.mode_list = max11607_mode_list,
1228168c9d95SJonathan Cameron 		.num_modes = ARRAY_SIZE(max11607_mode_list),
1229168c9d95SJonathan Cameron 		.default_mode = s0to3,
1230168c9d95SJonathan Cameron 		.info = &max1238_info,
1231168c9d95SJonathan Cameron 		.channels = max1036_channels,
1232168c9d95SJonathan Cameron 		.num_channels = ARRAY_SIZE(max1036_channels),
1233168c9d95SJonathan Cameron 	},
1234168c9d95SJonathan Cameron 	[max11602] = {
1235168c9d95SJonathan Cameron 		.bits = 8,
1236168c9d95SJonathan Cameron 		.int_vref_mv = 4096,
1237168c9d95SJonathan Cameron 		.mode_list = max11608_mode_list,
1238168c9d95SJonathan Cameron 		.num_modes = ARRAY_SIZE(max11608_mode_list),
1239168c9d95SJonathan Cameron 		.default_mode = s0to7,
1240168c9d95SJonathan Cameron 		.info = &max1238_info,
1241168c9d95SJonathan Cameron 		.channels = max11602_channels,
1242168c9d95SJonathan Cameron 		.num_channels = ARRAY_SIZE(max11602_channels),
1243168c9d95SJonathan Cameron 	},
1244168c9d95SJonathan Cameron 	[max11603] = {
1245168c9d95SJonathan Cameron 		.bits = 8,
1246168c9d95SJonathan Cameron 		.int_vref_mv = 2048,
1247168c9d95SJonathan Cameron 		.mode_list = max11608_mode_list,
1248168c9d95SJonathan Cameron 		.num_modes = ARRAY_SIZE(max11608_mode_list),
1249168c9d95SJonathan Cameron 		.default_mode = s0to7,
1250168c9d95SJonathan Cameron 		.info = &max1238_info,
1251168c9d95SJonathan Cameron 		.channels = max11602_channels,
1252168c9d95SJonathan Cameron 		.num_channels = ARRAY_SIZE(max11602_channels),
1253168c9d95SJonathan Cameron 	},
1254168c9d95SJonathan Cameron 	[max11604] = {
1255168c9d95SJonathan Cameron 		.bits = 8,
1256b8a70aefSHartmut Knaack 		.int_vref_mv = 4096,
1257168c9d95SJonathan Cameron 		.mode_list = max1238_mode_list,
1258168c9d95SJonathan Cameron 		.num_modes = ARRAY_SIZE(max1238_mode_list),
1259168c9d95SJonathan Cameron 		.default_mode = s0to11,
1260168c9d95SJonathan Cameron 		.info = &max1238_info,
1261a91a73c8SJonathan Cameron 		.channels = max1038_channels,
1262a91a73c8SJonathan Cameron 		.num_channels = ARRAY_SIZE(max1038_channels),
1263168c9d95SJonathan Cameron 	},
1264168c9d95SJonathan Cameron 	[max11605] = {
1265168c9d95SJonathan Cameron 		.bits = 8,
1266168c9d95SJonathan Cameron 		.int_vref_mv = 2048,
1267168c9d95SJonathan Cameron 		.mode_list = max1238_mode_list,
1268168c9d95SJonathan Cameron 		.num_modes = ARRAY_SIZE(max1238_mode_list),
1269168c9d95SJonathan Cameron 		.default_mode = s0to11,
1270168c9d95SJonathan Cameron 		.info = &max1238_info,
1271a91a73c8SJonathan Cameron 		.channels = max1038_channels,
1272a91a73c8SJonathan Cameron 		.num_channels = ARRAY_SIZE(max1038_channels),
1273168c9d95SJonathan Cameron 	},
1274168c9d95SJonathan Cameron 	[max11606] = {
1275168c9d95SJonathan Cameron 		.bits = 10,
1276168c9d95SJonathan Cameron 		.int_vref_mv = 4096,
1277168c9d95SJonathan Cameron 		.mode_list = max11607_mode_list,
1278168c9d95SJonathan Cameron 		.num_modes = ARRAY_SIZE(max11607_mode_list),
1279168c9d95SJonathan Cameron 		.default_mode = s0to3,
1280168c9d95SJonathan Cameron 		.info = &max1238_info,
1281168c9d95SJonathan Cameron 		.channels = max1136_channels,
1282168c9d95SJonathan Cameron 		.num_channels = ARRAY_SIZE(max1136_channels),
1283168c9d95SJonathan Cameron 	},
1284168c9d95SJonathan Cameron 	[max11607] = {
1285168c9d95SJonathan Cameron 		.bits = 10,
1286168c9d95SJonathan Cameron 		.int_vref_mv = 2048,
1287168c9d95SJonathan Cameron 		.mode_list = max11607_mode_list,
1288168c9d95SJonathan Cameron 		.num_modes = ARRAY_SIZE(max11607_mode_list),
1289168c9d95SJonathan Cameron 		.default_mode = s0to3,
1290168c9d95SJonathan Cameron 		.info = &max1238_info,
1291168c9d95SJonathan Cameron 		.channels = max1136_channels,
1292168c9d95SJonathan Cameron 		.num_channels = ARRAY_SIZE(max1136_channels),
1293168c9d95SJonathan Cameron 	},
1294168c9d95SJonathan Cameron 	[max11608] = {
1295168c9d95SJonathan Cameron 		.bits = 10,
1296168c9d95SJonathan Cameron 		.int_vref_mv = 4096,
1297168c9d95SJonathan Cameron 		.mode_list = max11608_mode_list,
1298168c9d95SJonathan Cameron 		.num_modes = ARRAY_SIZE(max11608_mode_list),
1299168c9d95SJonathan Cameron 		.default_mode = s0to7,
1300168c9d95SJonathan Cameron 		.info = &max1238_info,
1301168c9d95SJonathan Cameron 		.channels = max11608_channels,
1302168c9d95SJonathan Cameron 		.num_channels = ARRAY_SIZE(max11608_channels),
1303168c9d95SJonathan Cameron 	},
1304168c9d95SJonathan Cameron 	[max11609] = {
1305168c9d95SJonathan Cameron 		.bits = 10,
1306168c9d95SJonathan Cameron 		.int_vref_mv = 2048,
1307168c9d95SJonathan Cameron 		.mode_list = max11608_mode_list,
1308168c9d95SJonathan Cameron 		.num_modes = ARRAY_SIZE(max11608_mode_list),
1309168c9d95SJonathan Cameron 		.default_mode = s0to7,
1310168c9d95SJonathan Cameron 		.info = &max1238_info,
1311168c9d95SJonathan Cameron 		.channels = max11608_channels,
1312168c9d95SJonathan Cameron 		.num_channels = ARRAY_SIZE(max11608_channels),
1313168c9d95SJonathan Cameron 	},
1314168c9d95SJonathan Cameron 	[max11610] = {
1315168c9d95SJonathan Cameron 		.bits = 10,
1316b8a70aefSHartmut Knaack 		.int_vref_mv = 4096,
1317168c9d95SJonathan Cameron 		.mode_list = max1238_mode_list,
1318168c9d95SJonathan Cameron 		.num_modes = ARRAY_SIZE(max1238_mode_list),
1319168c9d95SJonathan Cameron 		.default_mode = s0to11,
1320168c9d95SJonathan Cameron 		.info = &max1238_info,
1321a91a73c8SJonathan Cameron 		.channels = max1138_channels,
1322a91a73c8SJonathan Cameron 		.num_channels = ARRAY_SIZE(max1138_channels),
1323168c9d95SJonathan Cameron 	},
1324168c9d95SJonathan Cameron 	[max11611] = {
1325168c9d95SJonathan Cameron 		.bits = 10,
1326168c9d95SJonathan Cameron 		.int_vref_mv = 2048,
1327168c9d95SJonathan Cameron 		.mode_list = max1238_mode_list,
1328168c9d95SJonathan Cameron 		.num_modes = ARRAY_SIZE(max1238_mode_list),
1329168c9d95SJonathan Cameron 		.default_mode = s0to11,
1330168c9d95SJonathan Cameron 		.info = &max1238_info,
1331a91a73c8SJonathan Cameron 		.channels = max1138_channels,
1332a91a73c8SJonathan Cameron 		.num_channels = ARRAY_SIZE(max1138_channels),
1333168c9d95SJonathan Cameron 	},
1334168c9d95SJonathan Cameron 	[max11612] = {
1335168c9d95SJonathan Cameron 		.bits = 12,
1336168c9d95SJonathan Cameron 		.int_vref_mv = 4096,
1337168c9d95SJonathan Cameron 		.mode_list = max11607_mode_list,
1338168c9d95SJonathan Cameron 		.num_modes = ARRAY_SIZE(max11607_mode_list),
1339168c9d95SJonathan Cameron 		.default_mode = s0to3,
1340168c9d95SJonathan Cameron 		.info = &max1238_info,
1341168c9d95SJonathan Cameron 		.channels = max1363_channels,
1342168c9d95SJonathan Cameron 		.num_channels = ARRAY_SIZE(max1363_channels),
1343168c9d95SJonathan Cameron 	},
1344168c9d95SJonathan Cameron 	[max11613] = {
1345168c9d95SJonathan Cameron 		.bits = 12,
1346168c9d95SJonathan Cameron 		.int_vref_mv = 2048,
1347168c9d95SJonathan Cameron 		.mode_list = max11607_mode_list,
1348168c9d95SJonathan Cameron 		.num_modes = ARRAY_SIZE(max11607_mode_list),
1349168c9d95SJonathan Cameron 		.default_mode = s0to3,
1350168c9d95SJonathan Cameron 		.info = &max1238_info,
1351168c9d95SJonathan Cameron 		.channels = max1363_channels,
1352168c9d95SJonathan Cameron 		.num_channels = ARRAY_SIZE(max1363_channels),
1353168c9d95SJonathan Cameron 	},
1354168c9d95SJonathan Cameron 	[max11614] = {
1355168c9d95SJonathan Cameron 		.bits = 12,
1356168c9d95SJonathan Cameron 		.int_vref_mv = 4096,
1357168c9d95SJonathan Cameron 		.mode_list = max11608_mode_list,
1358168c9d95SJonathan Cameron 		.num_modes = ARRAY_SIZE(max11608_mode_list),
1359168c9d95SJonathan Cameron 		.default_mode = s0to7,
1360168c9d95SJonathan Cameron 		.info = &max1238_info,
1361168c9d95SJonathan Cameron 		.channels = max11614_channels,
1362168c9d95SJonathan Cameron 		.num_channels = ARRAY_SIZE(max11614_channels),
1363168c9d95SJonathan Cameron 	},
1364168c9d95SJonathan Cameron 	[max11615] = {
1365168c9d95SJonathan Cameron 		.bits = 12,
1366168c9d95SJonathan Cameron 		.int_vref_mv = 2048,
1367168c9d95SJonathan Cameron 		.mode_list = max11608_mode_list,
1368168c9d95SJonathan Cameron 		.num_modes = ARRAY_SIZE(max11608_mode_list),
1369168c9d95SJonathan Cameron 		.default_mode = s0to7,
1370168c9d95SJonathan Cameron 		.info = &max1238_info,
1371168c9d95SJonathan Cameron 		.channels = max11614_channels,
1372168c9d95SJonathan Cameron 		.num_channels = ARRAY_SIZE(max11614_channels),
1373168c9d95SJonathan Cameron 	},
1374168c9d95SJonathan Cameron 	[max11616] = {
1375168c9d95SJonathan Cameron 		.bits = 12,
1376b8a70aefSHartmut Knaack 		.int_vref_mv = 4096,
1377168c9d95SJonathan Cameron 		.mode_list = max1238_mode_list,
1378168c9d95SJonathan Cameron 		.num_modes = ARRAY_SIZE(max1238_mode_list),
1379168c9d95SJonathan Cameron 		.default_mode = s0to11,
1380168c9d95SJonathan Cameron 		.info = &max1238_info,
1381168c9d95SJonathan Cameron 		.channels = max1238_channels,
1382168c9d95SJonathan Cameron 		.num_channels = ARRAY_SIZE(max1238_channels),
1383168c9d95SJonathan Cameron 	},
1384168c9d95SJonathan Cameron 	[max11617] = {
1385168c9d95SJonathan Cameron 		.bits = 12,
1386168c9d95SJonathan Cameron 		.int_vref_mv = 2048,
1387168c9d95SJonathan Cameron 		.mode_list = max1238_mode_list,
1388168c9d95SJonathan Cameron 		.num_modes = ARRAY_SIZE(max1238_mode_list),
1389168c9d95SJonathan Cameron 		.default_mode = s0to11,
1390168c9d95SJonathan Cameron 		.info = &max1238_info,
1391168c9d95SJonathan Cameron 		.channels = max1238_channels,
1392168c9d95SJonathan Cameron 		.num_channels = ARRAY_SIZE(max1238_channels),
1393168c9d95SJonathan Cameron 	},
1394168c9d95SJonathan Cameron 	[max11644] = {
1395168c9d95SJonathan Cameron 		.bits = 12,
13965c913eb9SStefan Eichenberger 		.int_vref_mv = 4096,
1397168c9d95SJonathan Cameron 		.mode_list = max11644_mode_list,
1398168c9d95SJonathan Cameron 		.num_modes = ARRAY_SIZE(max11644_mode_list),
1399168c9d95SJonathan Cameron 		.default_mode = s0to1,
1400168c9d95SJonathan Cameron 		.info = &max1238_info,
1401168c9d95SJonathan Cameron 		.channels = max11644_channels,
1402168c9d95SJonathan Cameron 		.num_channels = ARRAY_SIZE(max11644_channels),
1403168c9d95SJonathan Cameron 	},
1404168c9d95SJonathan Cameron 	[max11645] = {
1405168c9d95SJonathan Cameron 		.bits = 12,
14065c913eb9SStefan Eichenberger 		.int_vref_mv = 2048,
1407168c9d95SJonathan Cameron 		.mode_list = max11644_mode_list,
1408168c9d95SJonathan Cameron 		.num_modes = ARRAY_SIZE(max11644_mode_list),
1409168c9d95SJonathan Cameron 		.default_mode = s0to1,
1410168c9d95SJonathan Cameron 		.info = &max1238_info,
1411168c9d95SJonathan Cameron 		.channels = max11644_channels,
1412168c9d95SJonathan Cameron 		.num_channels = ARRAY_SIZE(max11644_channels),
1413168c9d95SJonathan Cameron 	},
1414168c9d95SJonathan Cameron 	[max11646] = {
1415168c9d95SJonathan Cameron 		.bits = 10,
14165c913eb9SStefan Eichenberger 		.int_vref_mv = 4096,
1417168c9d95SJonathan Cameron 		.mode_list = max11644_mode_list,
1418168c9d95SJonathan Cameron 		.num_modes = ARRAY_SIZE(max11644_mode_list),
1419168c9d95SJonathan Cameron 		.default_mode = s0to1,
1420168c9d95SJonathan Cameron 		.info = &max1238_info,
1421168c9d95SJonathan Cameron 		.channels = max11646_channels,
1422168c9d95SJonathan Cameron 		.num_channels = ARRAY_SIZE(max11646_channels),
1423168c9d95SJonathan Cameron 	},
1424168c9d95SJonathan Cameron 	[max11647] = {
1425168c9d95SJonathan Cameron 		.bits = 10,
14265c913eb9SStefan Eichenberger 		.int_vref_mv = 2048,
1427168c9d95SJonathan Cameron 		.mode_list = max11644_mode_list,
1428168c9d95SJonathan Cameron 		.num_modes = ARRAY_SIZE(max11644_mode_list),
1429168c9d95SJonathan Cameron 		.default_mode = s0to1,
1430168c9d95SJonathan Cameron 		.info = &max1238_info,
1431168c9d95SJonathan Cameron 		.channels = max11646_channels,
1432168c9d95SJonathan Cameron 		.num_channels = ARRAY_SIZE(max11646_channels),
1433168c9d95SJonathan Cameron 	},
1434168c9d95SJonathan Cameron };
1435168c9d95SJonathan Cameron 
max1363_initial_setup(struct max1363_state * st)1436168c9d95SJonathan Cameron static int max1363_initial_setup(struct max1363_state *st)
1437168c9d95SJonathan Cameron {
1438a405b00eSGuenter Roeck 	st->setupbyte = MAX1363_SETUP_INT_CLOCK
1439168c9d95SJonathan Cameron 		| MAX1363_SETUP_UNIPOLAR
1440168c9d95SJonathan Cameron 		| MAX1363_SETUP_NORESET;
1441168c9d95SJonathan Cameron 
1442a405b00eSGuenter Roeck 	if (st->vref)
1443a405b00eSGuenter Roeck 		st->setupbyte |= MAX1363_SETUP_AIN3_IS_REF_EXT_TO_REF;
1444a405b00eSGuenter Roeck 	else
1445a405b00eSGuenter Roeck 		st->setupbyte |= MAX1363_SETUP_POWER_UP_INT_REF
1446a405b00eSGuenter Roeck 		  | MAX1363_SETUP_AIN3_IS_AIN3_REF_IS_INT;
1447a405b00eSGuenter Roeck 
1448168c9d95SJonathan Cameron 	/* Set scan mode writes the config anyway so wait until then */
1449168c9d95SJonathan Cameron 	st->setupbyte = MAX1363_SETUP_BYTE(st->setupbyte);
1450168c9d95SJonathan Cameron 	st->current_mode = &max1363_mode_table[st->chip_info->default_mode];
1451168c9d95SJonathan Cameron 	st->configbyte = MAX1363_CONFIG_BYTE(st->configbyte);
1452168c9d95SJonathan Cameron 
1453168c9d95SJonathan Cameron 	return max1363_set_scan_mode(st);
1454168c9d95SJonathan Cameron }
1455168c9d95SJonathan Cameron 
max1363_alloc_scan_masks(struct iio_dev * indio_dev)1456fc52692cSGreg Kroah-Hartman static int max1363_alloc_scan_masks(struct iio_dev *indio_dev)
1457168c9d95SJonathan Cameron {
1458168c9d95SJonathan Cameron 	struct max1363_state *st = iio_priv(indio_dev);
1459168c9d95SJonathan Cameron 	unsigned long *masks;
1460168c9d95SJonathan Cameron 	int i;
1461168c9d95SJonathan Cameron 
14627c3e8675SGuenter Roeck 	masks = devm_kzalloc(&indio_dev->dev,
1463a86854d0SKees Cook 			array3_size(BITS_TO_LONGS(MAX1363_MAX_CHANNELS),
1464a86854d0SKees Cook 				    sizeof(long),
1465a86854d0SKees Cook 				    st->chip_info->num_modes + 1),
1466a86854d0SKees Cook 			GFP_KERNEL);
1467168c9d95SJonathan Cameron 	if (!masks)
1468168c9d95SJonathan Cameron 		return -ENOMEM;
1469168c9d95SJonathan Cameron 
1470168c9d95SJonathan Cameron 	for (i = 0; i < st->chip_info->num_modes; i++)
1471168c9d95SJonathan Cameron 		bitmap_copy(masks + BITS_TO_LONGS(MAX1363_MAX_CHANNELS)*i,
1472168c9d95SJonathan Cameron 			    max1363_mode_table[st->chip_info->mode_list[i]]
1473168c9d95SJonathan Cameron 			    .modemask, MAX1363_MAX_CHANNELS);
1474168c9d95SJonathan Cameron 
1475168c9d95SJonathan Cameron 	indio_dev->available_scan_masks = masks;
1476168c9d95SJonathan Cameron 
1477168c9d95SJonathan Cameron 	return 0;
1478168c9d95SJonathan Cameron }
1479168c9d95SJonathan Cameron 
max1363_trigger_handler(int irq,void * p)1480168c9d95SJonathan Cameron static irqreturn_t max1363_trigger_handler(int irq, void *p)
1481168c9d95SJonathan Cameron {
1482168c9d95SJonathan Cameron 	struct iio_poll_func *pf = p;
1483168c9d95SJonathan Cameron 	struct iio_dev *indio_dev = pf->indio_dev;
1484168c9d95SJonathan Cameron 	struct max1363_state *st = iio_priv(indio_dev);
1485168c9d95SJonathan Cameron 	__u8 *rxbuf;
1486168c9d95SJonathan Cameron 	int b_sent;
1487168c9d95SJonathan Cameron 	size_t d_size;
1488168c9d95SJonathan Cameron 	unsigned long numvals = bitmap_weight(st->current_mode->modemask,
1489168c9d95SJonathan Cameron 					      MAX1363_MAX_CHANNELS);
1490168c9d95SJonathan Cameron 
1491168c9d95SJonathan Cameron 	/* Ensure the timestamp is 8 byte aligned */
1492168c9d95SJonathan Cameron 	if (st->chip_info->bits != 8)
1493168c9d95SJonathan Cameron 		d_size = numvals*2;
1494168c9d95SJonathan Cameron 	else
1495168c9d95SJonathan Cameron 		d_size = numvals;
1496168c9d95SJonathan Cameron 	if (indio_dev->scan_timestamp) {
1497168c9d95SJonathan Cameron 		d_size += sizeof(s64);
1498168c9d95SJonathan Cameron 		if (d_size % sizeof(s64))
1499168c9d95SJonathan Cameron 			d_size += sizeof(s64) - (d_size % sizeof(s64));
1500168c9d95SJonathan Cameron 	}
1501168c9d95SJonathan Cameron 	/* Monitor mode prevents reading. Whilst not currently implemented
1502168c9d95SJonathan Cameron 	 * might as well have this test in here in the meantime as it does
1503168c9d95SJonathan Cameron 	 * no harm.
1504168c9d95SJonathan Cameron 	 */
1505168c9d95SJonathan Cameron 	if (numvals == 0)
1506168c9d95SJonathan Cameron 		goto done;
1507168c9d95SJonathan Cameron 
1508168c9d95SJonathan Cameron 	rxbuf = kmalloc(d_size,	GFP_KERNEL);
1509168c9d95SJonathan Cameron 	if (rxbuf == NULL)
1510168c9d95SJonathan Cameron 		goto done;
1511168c9d95SJonathan Cameron 	if (st->chip_info->bits != 8)
151261bdda69SVivien Didelot 		b_sent = st->recv(st->client, rxbuf, numvals * 2);
1513168c9d95SJonathan Cameron 	else
151461bdda69SVivien Didelot 		b_sent = st->recv(st->client, rxbuf, numvals);
1515168c9d95SJonathan Cameron 	if (b_sent < 0)
1516168c9d95SJonathan Cameron 		goto done_free;
1517168c9d95SJonathan Cameron 
1518bc2b7dabSGregor Boirie 	iio_push_to_buffers_with_timestamp(indio_dev, rxbuf,
1519bc2b7dabSGregor Boirie 					   iio_get_time_ns(indio_dev));
1520168c9d95SJonathan Cameron 
1521168c9d95SJonathan Cameron done_free:
1522168c9d95SJonathan Cameron 	kfree(rxbuf);
1523168c9d95SJonathan Cameron done:
1524168c9d95SJonathan Cameron 	iio_trigger_notify_done(indio_dev->trig);
1525168c9d95SJonathan Cameron 
1526168c9d95SJonathan Cameron 	return IRQ_HANDLED;
1527168c9d95SJonathan Cameron }
1528168c9d95SJonathan Cameron 
1529152c9aa0SFlorian Vaussard #define MAX1363_COMPATIBLE(of_compatible, cfg) {		\
1530152c9aa0SFlorian Vaussard 			.compatible = of_compatible,		\
1531152c9aa0SFlorian Vaussard 			.data = &max1363_chip_info_tbl[cfg],	\
1532152c9aa0SFlorian Vaussard }
1533152c9aa0SFlorian Vaussard 
1534152c9aa0SFlorian Vaussard static const struct of_device_id max1363_of_match[] = {
1535152c9aa0SFlorian Vaussard 	MAX1363_COMPATIBLE("maxim,max1361", max1361),
1536152c9aa0SFlorian Vaussard 	MAX1363_COMPATIBLE("maxim,max1362", max1362),
1537152c9aa0SFlorian Vaussard 	MAX1363_COMPATIBLE("maxim,max1363", max1363),
1538152c9aa0SFlorian Vaussard 	MAX1363_COMPATIBLE("maxim,max1364", max1364),
1539152c9aa0SFlorian Vaussard 	MAX1363_COMPATIBLE("maxim,max1036", max1036),
1540152c9aa0SFlorian Vaussard 	MAX1363_COMPATIBLE("maxim,max1037", max1037),
1541152c9aa0SFlorian Vaussard 	MAX1363_COMPATIBLE("maxim,max1038", max1038),
1542152c9aa0SFlorian Vaussard 	MAX1363_COMPATIBLE("maxim,max1039", max1039),
1543152c9aa0SFlorian Vaussard 	MAX1363_COMPATIBLE("maxim,max1136", max1136),
1544152c9aa0SFlorian Vaussard 	MAX1363_COMPATIBLE("maxim,max1137", max1137),
1545152c9aa0SFlorian Vaussard 	MAX1363_COMPATIBLE("maxim,max1138", max1138),
1546152c9aa0SFlorian Vaussard 	MAX1363_COMPATIBLE("maxim,max1139", max1139),
1547152c9aa0SFlorian Vaussard 	MAX1363_COMPATIBLE("maxim,max1236", max1236),
1548152c9aa0SFlorian Vaussard 	MAX1363_COMPATIBLE("maxim,max1237", max1237),
1549152c9aa0SFlorian Vaussard 	MAX1363_COMPATIBLE("maxim,max1238", max1238),
1550152c9aa0SFlorian Vaussard 	MAX1363_COMPATIBLE("maxim,max1239", max1239),
1551152c9aa0SFlorian Vaussard 	MAX1363_COMPATIBLE("maxim,max11600", max11600),
1552152c9aa0SFlorian Vaussard 	MAX1363_COMPATIBLE("maxim,max11601", max11601),
1553152c9aa0SFlorian Vaussard 	MAX1363_COMPATIBLE("maxim,max11602", max11602),
1554152c9aa0SFlorian Vaussard 	MAX1363_COMPATIBLE("maxim,max11603", max11603),
1555152c9aa0SFlorian Vaussard 	MAX1363_COMPATIBLE("maxim,max11604", max11604),
1556152c9aa0SFlorian Vaussard 	MAX1363_COMPATIBLE("maxim,max11605", max11605),
1557152c9aa0SFlorian Vaussard 	MAX1363_COMPATIBLE("maxim,max11606", max11606),
1558152c9aa0SFlorian Vaussard 	MAX1363_COMPATIBLE("maxim,max11607", max11607),
1559152c9aa0SFlorian Vaussard 	MAX1363_COMPATIBLE("maxim,max11608", max11608),
1560152c9aa0SFlorian Vaussard 	MAX1363_COMPATIBLE("maxim,max11609", max11609),
1561152c9aa0SFlorian Vaussard 	MAX1363_COMPATIBLE("maxim,max11610", max11610),
1562152c9aa0SFlorian Vaussard 	MAX1363_COMPATIBLE("maxim,max11611", max11611),
1563152c9aa0SFlorian Vaussard 	MAX1363_COMPATIBLE("maxim,max11612", max11612),
1564152c9aa0SFlorian Vaussard 	MAX1363_COMPATIBLE("maxim,max11613", max11613),
1565152c9aa0SFlorian Vaussard 	MAX1363_COMPATIBLE("maxim,max11614", max11614),
1566152c9aa0SFlorian Vaussard 	MAX1363_COMPATIBLE("maxim,max11615", max11615),
1567152c9aa0SFlorian Vaussard 	MAX1363_COMPATIBLE("maxim,max11616", max11616),
1568152c9aa0SFlorian Vaussard 	MAX1363_COMPATIBLE("maxim,max11617", max11617),
1569152c9aa0SFlorian Vaussard 	MAX1363_COMPATIBLE("maxim,max11644", max11644),
1570152c9aa0SFlorian Vaussard 	MAX1363_COMPATIBLE("maxim,max11645", max11645),
1571152c9aa0SFlorian Vaussard 	MAX1363_COMPATIBLE("maxim,max11646", max11646),
1572152c9aa0SFlorian Vaussard 	MAX1363_COMPATIBLE("maxim,max11647", max11647),
1573152c9aa0SFlorian Vaussard 	{ /* sentinel */ }
1574152c9aa0SFlorian Vaussard };
157599be230dSJavier Martinez Canillas MODULE_DEVICE_TABLE(of, max1363_of_match);
1576152c9aa0SFlorian Vaussard 
max1363_reg_disable(void * reg)1577a1ff6d25SAlexandru Ardelean static void max1363_reg_disable(void *reg)
1578a1ff6d25SAlexandru Ardelean {
1579a1ff6d25SAlexandru Ardelean 	regulator_disable(reg);
1580a1ff6d25SAlexandru Ardelean }
1581a1ff6d25SAlexandru Ardelean 
max1363_probe(struct i2c_client * client)1582a69e45a4SUwe Kleine-König static int max1363_probe(struct i2c_client *client)
1583168c9d95SJonathan Cameron {
1584a69e45a4SUwe Kleine-König 	const struct i2c_device_id *id = i2c_client_get_device_id(client);
1585168c9d95SJonathan Cameron 	int ret;
1586168c9d95SJonathan Cameron 	struct max1363_state *st;
1587168c9d95SJonathan Cameron 	struct iio_dev *indio_dev;
1588a405b00eSGuenter Roeck 	struct regulator *vref;
1589168c9d95SJonathan Cameron 
15906917e1d9SSachin Kamat 	indio_dev = devm_iio_device_alloc(&client->dev,
15916917e1d9SSachin Kamat 					  sizeof(struct max1363_state));
15926917e1d9SSachin Kamat 	if (!indio_dev)
15936917e1d9SSachin Kamat 		return -ENOMEM;
1594168c9d95SJonathan Cameron 
1595168c9d95SJonathan Cameron 	st = iio_priv(indio_dev);
1596168c9d95SJonathan Cameron 
1597bf09cddbSRohit Sarkar 	mutex_init(&st->lock);
15983dfa1d4fSMatti Vaittinen 	ret = devm_regulator_get_enable(&client->dev, "vcc");
1599a1ff6d25SAlexandru Ardelean 	if (ret)
1600a1ff6d25SAlexandru Ardelean 		return ret;
1601168c9d95SJonathan Cameron 
1602f84ff467SJonathan Cameron 	st->chip_info = device_get_match_data(&client->dev);
1603794ac821SJulia Lawall 	if (!st->chip_info)
1604168c9d95SJonathan Cameron 		st->chip_info = &max1363_chip_info_tbl[id->driver_data];
1605168c9d95SJonathan Cameron 	st->client = client;
1606168c9d95SJonathan Cameron 
1607a405b00eSGuenter Roeck 	st->vref_uv = st->chip_info->int_vref_mv * 1000;
160855b40d37SGuenter Roeck 	vref = devm_regulator_get_optional(&client->dev, "vref");
1609a405b00eSGuenter Roeck 	if (!IS_ERR(vref)) {
1610a405b00eSGuenter Roeck 		int vref_uv;
1611a405b00eSGuenter Roeck 
1612a405b00eSGuenter Roeck 		ret = regulator_enable(vref);
1613a405b00eSGuenter Roeck 		if (ret)
1614a1ff6d25SAlexandru Ardelean 			return ret;
1615a1ff6d25SAlexandru Ardelean 
1616a1ff6d25SAlexandru Ardelean 		ret = devm_add_action_or_reset(&client->dev, max1363_reg_disable, vref);
1617a1ff6d25SAlexandru Ardelean 		if (ret)
1618a1ff6d25SAlexandru Ardelean 			return ret;
1619a1ff6d25SAlexandru Ardelean 
1620a405b00eSGuenter Roeck 		st->vref = vref;
1621a405b00eSGuenter Roeck 		vref_uv = regulator_get_voltage(vref);
1622a1ff6d25SAlexandru Ardelean 		if (vref_uv <= 0)
1623a1ff6d25SAlexandru Ardelean 			return -EINVAL;
1624a1ff6d25SAlexandru Ardelean 
1625a405b00eSGuenter Roeck 		st->vref_uv = vref_uv;
1626a405b00eSGuenter Roeck 	}
1627a405b00eSGuenter Roeck 
162861bdda69SVivien Didelot 	if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
162961bdda69SVivien Didelot 		st->send = i2c_master_send;
163061bdda69SVivien Didelot 		st->recv = i2c_master_recv;
163161bdda69SVivien Didelot 	} else if (i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE)
163261bdda69SVivien Didelot 			&& st->chip_info->bits == 8) {
163361bdda69SVivien Didelot 		st->send = max1363_smbus_send;
163461bdda69SVivien Didelot 		st->recv = max1363_smbus_recv;
163561bdda69SVivien Didelot 	} else {
1636a1ff6d25SAlexandru Ardelean 		return -EOPNOTSUPP;
163761bdda69SVivien Didelot 	}
163861bdda69SVivien Didelot 
1639168c9d95SJonathan Cameron 	ret = max1363_alloc_scan_masks(indio_dev);
1640168c9d95SJonathan Cameron 	if (ret)
1641a1ff6d25SAlexandru Ardelean 		return ret;
1642168c9d95SJonathan Cameron 
1643168c9d95SJonathan Cameron 	indio_dev->name = id->name;
1644168c9d95SJonathan Cameron 	indio_dev->channels = st->chip_info->channels;
1645168c9d95SJonathan Cameron 	indio_dev->num_channels = st->chip_info->num_channels;
1646168c9d95SJonathan Cameron 	indio_dev->info = st->chip_info->info;
1647168c9d95SJonathan Cameron 	indio_dev->modes = INDIO_DIRECT_MODE;
1648168c9d95SJonathan Cameron 	ret = max1363_initial_setup(st);
1649168c9d95SJonathan Cameron 	if (ret < 0)
1650a1ff6d25SAlexandru Ardelean 		return ret;
1651168c9d95SJonathan Cameron 
1652a1ff6d25SAlexandru Ardelean 	ret = devm_iio_triggered_buffer_setup(&client->dev, indio_dev, NULL,
16537a1aeba7SLars-Peter Clausen 					      &max1363_trigger_handler, NULL);
1654168c9d95SJonathan Cameron 	if (ret)
1655a1ff6d25SAlexandru Ardelean 		return ret;
1656168c9d95SJonathan Cameron 
1657168c9d95SJonathan Cameron 	if (client->irq) {
16587c3e8675SGuenter Roeck 		ret = devm_request_threaded_irq(&client->dev, st->client->irq,
1659168c9d95SJonathan Cameron 					   NULL,
1660168c9d95SJonathan Cameron 					   &max1363_event_handler,
1661168c9d95SJonathan Cameron 					   IRQF_TRIGGER_RISING | IRQF_ONESHOT,
1662168c9d95SJonathan Cameron 					   "max1363_event",
1663168c9d95SJonathan Cameron 					   indio_dev);
1664168c9d95SJonathan Cameron 
1665168c9d95SJonathan Cameron 		if (ret)
1666168c9d95SJonathan Cameron 			return ret;
1667168c9d95SJonathan Cameron 	}
1668168c9d95SJonathan Cameron 
1669a1ff6d25SAlexandru Ardelean 	return devm_iio_device_register(&client->dev, indio_dev);
1670168c9d95SJonathan Cameron }
1671168c9d95SJonathan Cameron 
1672168c9d95SJonathan Cameron static const struct i2c_device_id max1363_id[] = {
1673168c9d95SJonathan Cameron 	{ "max1361", max1361 },
1674168c9d95SJonathan Cameron 	{ "max1362", max1362 },
1675168c9d95SJonathan Cameron 	{ "max1363", max1363 },
1676168c9d95SJonathan Cameron 	{ "max1364", max1364 },
1677168c9d95SJonathan Cameron 	{ "max1036", max1036 },
1678168c9d95SJonathan Cameron 	{ "max1037", max1037 },
1679168c9d95SJonathan Cameron 	{ "max1038", max1038 },
1680168c9d95SJonathan Cameron 	{ "max1039", max1039 },
1681168c9d95SJonathan Cameron 	{ "max1136", max1136 },
1682168c9d95SJonathan Cameron 	{ "max1137", max1137 },
1683168c9d95SJonathan Cameron 	{ "max1138", max1138 },
1684168c9d95SJonathan Cameron 	{ "max1139", max1139 },
1685168c9d95SJonathan Cameron 	{ "max1236", max1236 },
1686168c9d95SJonathan Cameron 	{ "max1237", max1237 },
1687168c9d95SJonathan Cameron 	{ "max1238", max1238 },
1688168c9d95SJonathan Cameron 	{ "max1239", max1239 },
1689168c9d95SJonathan Cameron 	{ "max11600", max11600 },
1690168c9d95SJonathan Cameron 	{ "max11601", max11601 },
1691168c9d95SJonathan Cameron 	{ "max11602", max11602 },
1692168c9d95SJonathan Cameron 	{ "max11603", max11603 },
1693168c9d95SJonathan Cameron 	{ "max11604", max11604 },
1694168c9d95SJonathan Cameron 	{ "max11605", max11605 },
1695168c9d95SJonathan Cameron 	{ "max11606", max11606 },
1696168c9d95SJonathan Cameron 	{ "max11607", max11607 },
1697168c9d95SJonathan Cameron 	{ "max11608", max11608 },
1698168c9d95SJonathan Cameron 	{ "max11609", max11609 },
1699168c9d95SJonathan Cameron 	{ "max11610", max11610 },
1700168c9d95SJonathan Cameron 	{ "max11611", max11611 },
1701168c9d95SJonathan Cameron 	{ "max11612", max11612 },
1702168c9d95SJonathan Cameron 	{ "max11613", max11613 },
1703168c9d95SJonathan Cameron 	{ "max11614", max11614 },
1704168c9d95SJonathan Cameron 	{ "max11615", max11615 },
1705168c9d95SJonathan Cameron 	{ "max11616", max11616 },
1706168c9d95SJonathan Cameron 	{ "max11617", max11617 },
17073fb77e29SStefan Eichenberger 	{ "max11644", max11644 },
17083fb77e29SStefan Eichenberger 	{ "max11645", max11645 },
17093fb77e29SStefan Eichenberger 	{ "max11646", max11646 },
17103fb77e29SStefan Eichenberger 	{ "max11647", max11647 },
1711168c9d95SJonathan Cameron 	{}
1712168c9d95SJonathan Cameron };
1713168c9d95SJonathan Cameron 
1714168c9d95SJonathan Cameron MODULE_DEVICE_TABLE(i2c, max1363_id);
1715168c9d95SJonathan Cameron 
1716168c9d95SJonathan Cameron static struct i2c_driver max1363_driver = {
1717168c9d95SJonathan Cameron 	.driver = {
1718168c9d95SJonathan Cameron 		.name = "max1363",
1719f84ff467SJonathan Cameron 		.of_match_table = max1363_of_match,
1720168c9d95SJonathan Cameron 	},
1721*7cf15f42SUwe Kleine-König 	.probe = max1363_probe,
1722168c9d95SJonathan Cameron 	.id_table = max1363_id,
1723168c9d95SJonathan Cameron };
1724168c9d95SJonathan Cameron module_i2c_driver(max1363_driver);
1725168c9d95SJonathan Cameron 
1726168c9d95SJonathan Cameron MODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>");
1727168c9d95SJonathan Cameron MODULE_DESCRIPTION("Maxim 1363 ADC");
1728168c9d95SJonathan Cameron MODULE_LICENSE("GPL v2");
1729