summaryrefslogtreecommitdiff
path: root/drivers/iio/adc/ad7606.h
blob: 998814a92b8258296777c19df82f35903e7b3deb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * AD7606 ADC driver
 *
 * Copyright 2011 Analog Devices Inc.
 */

#ifndef IIO_ADC_AD7606_H_
#define IIO_ADC_AD7606_H_

#define AD760X_MAX_CHANNELS	16

#define AD760X_CHANNEL(num, mask_sep, mask_type, mask_all, bits) {	\
		.type = IIO_VOLTAGE,				\
		.indexed = 1,					\
		.channel = num,					\
		.address = num,					\
		.info_mask_separate = mask_sep,			\
		.info_mask_shared_by_type = mask_type,		\
		.info_mask_shared_by_all = mask_all,		\
		.scan_index = num,				\
		.scan_type = {					\
			.sign = 's',				\
			.realbits = (bits),			\
			.storagebits = (bits) > 16 ? 32 : 16,	\
			.endianness = IIO_CPU,			\
		},						\
}

#define AD7606_SW_CHANNEL(num, bits) {				\
		.type = IIO_VOLTAGE,				\
		.indexed = 1,					\
		.channel = num,					\
		.address = num,					\
		.info_mask_separate =				\
			BIT(IIO_CHAN_INFO_RAW) |		\
			BIT(IIO_CHAN_INFO_SCALE),		\
		.info_mask_separate_available =			\
			BIT(IIO_CHAN_INFO_SCALE),		\
		.info_mask_shared_by_all =			\
			BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),	\
		.info_mask_shared_by_all_available =		\
			BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),	\
		.scan_index = num,				\
		.scan_type = {					\
			.sign = 's',				\
			.realbits = (bits),			\
			.storagebits = (bits) > 16 ? 32 : 16,	\
			.endianness = IIO_CPU,			\
		},						\
}

#define AD7605_CHANNEL(num)				\
	AD760X_CHANNEL(num, BIT(IIO_CHAN_INFO_RAW),	\
		BIT(IIO_CHAN_INFO_SCALE), 0, 16)

#define AD7606_CHANNEL(num, bits)			\
	AD760X_CHANNEL(num, BIT(IIO_CHAN_INFO_RAW),	\
		BIT(IIO_CHAN_INFO_SCALE),		\
		BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), bits)

#define AD7616_CHANNEL(num)	AD7606_SW_CHANNEL(num, 16)

#define AD7606_BI_CHANNEL(num)				\
	AD760X_CHANNEL(num, 0,				\
		BIT(IIO_CHAN_INFO_SCALE),		\
		BIT(IIO_CHAN_INFO_SAMP_FREQ) |		\
		BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), 16)

struct ad7606_state;

typedef int (*ad7606_scale_setup_cb_t)(struct ad7606_state *st,
				       struct iio_chan_spec *chan, int ch);

/**
 * struct ad7606_chip_info - chip specific information
 * @channels:		channel specification
 * @max_samplerate:	maximum supported samplerate
 * @name		device name
 * @num_channels:	number of channels
 * @num_adc_channels	the number of channels the ADC actually inputs.
 * @scale_setup_cb:	callback to setup the scales for each channel
 * @oversampling_avail	pointer to the array which stores the available
 *			oversampling ratios.
 * @oversampling_num	number of elements stored in oversampling_avail array
 * @os_req_reset	some devices require a reset to update oversampling
 * @init_delay_ms	required delay in milliseconds for initialization
 *			after a restart
 */
struct ad7606_chip_info {
	const struct iio_chan_spec	*channels;
	unsigned int			max_samplerate;
	const char			*name;
	unsigned int			num_adc_channels;
	unsigned int			num_channels;
	ad7606_scale_setup_cb_t		scale_setup_cb;
	const unsigned int		*oversampling_avail;
	unsigned int			oversampling_num;
	bool				os_req_reset;
	unsigned long			init_delay_ms;
};

/**
 * struct ad7606_chan_scale - channel scale configuration
 * @scale_avail		pointer to the array which stores the available scales
 * @num_scales		number of elements stored in the scale_avail array
 * @range		voltage range selection, selects which scale to apply
 * @reg_offset		offset for the register value, to be applied when
 *			writing the value of 'range' to the register value
 */
struct ad7606_chan_scale {
#define AD760X_MAX_SCALES		16
	const unsigned int		(*scale_avail)[2];
	unsigned int			num_scales;
	unsigned int			range;
	unsigned int			reg_offset;
};

/**
 * struct ad7606_state - driver instance specific data
 * @dev		pointer to kernel device
 * @chip_info		entry in the table of chips that describes this device
 * @bops		bus operations (SPI or parallel)
 * @chan_scales		scale configuration for channels
 * @oversampling	oversampling selection
 * @cnvst_pwm		pointer to the PWM device connected to the cnvst pin
 * @base_address	address from where to read data in parallel operation
 * @sw_mode_en		software mode enabled
 * @oversampling_avail	pointer to the array which stores the available
 *			oversampling ratios.
 * @num_os_ratios	number of elements stored in oversampling_avail array
 * @write_scale		pointer to the function which writes the scale
 * @write_os		pointer to the function which writes the os
 * @lock		protect sensor state from concurrent accesses to GPIOs
 * @gpio_convst	GPIO descriptor for conversion start signal (CONVST)
 * @gpio_reset		GPIO descriptor for device hard-reset
 * @gpio_range		GPIO descriptor for range selection
 * @gpio_standby	GPIO descriptor for stand-by signal (STBY),
 *			controls power-down mode of device
 * @gpio_frstdata	GPIO descriptor for reading from device when data
 *			is being read on the first channel
 * @gpio_os		GPIO descriptors to control oversampling on the device
 * @complete		completion to indicate end of conversion
 * @trig		The IIO trigger associated with the device.
 * @data		buffer for reading data from the device
 * @d16			be16 buffer for reading data from the device
 */
struct ad7606_state {
	struct device			*dev;
	const struct ad7606_chip_info	*chip_info;
	const struct ad7606_bus_ops	*bops;
	struct ad7606_chan_scale	chan_scales[AD760X_MAX_CHANNELS];
	unsigned int			oversampling;
	struct pwm_device		*cnvst_pwm;
	void __iomem			*base_address;
	bool				sw_mode_en;
	const unsigned int		*oversampling_avail;
	unsigned int			num_os_ratios;
	struct iio_backend		*back;
	int (*write_scale)(struct iio_dev *indio_dev, int ch, int val);
	int (*write_os)(struct iio_dev *indio_dev, int val);

	struct mutex			lock; /* protect sensor state */
	struct gpio_desc		*gpio_convst;
	struct gpio_desc		*gpio_reset;
	struct gpio_desc		*gpio_range;
	struct gpio_desc		*gpio_standby;
	struct gpio_desc		*gpio_frstdata;
	struct gpio_descs		*gpio_os;
	struct iio_trigger		*trig;
	struct completion		completion;

	/*
	 * DMA (thus cache coherency maintenance) may require the
	 * transfer buffers to live in their own cache lines.
	 * 16 * 16-bit samples + 64-bit timestamp - for AD7616
	 * 8 * 32-bit samples + 64-bit timestamp - for AD7616C-18 (and similar)
	 */
	union {
		u16 buf16[20];
		u32 buf32[10];
	} data __aligned(IIO_DMA_MINALIGN);
	__be16				d16[2];
};

/**
 * struct ad7606_bus_ops - driver bus operations
 * @iio_backend_config	function pointer for configuring the iio_backend for
 *			the compatibles that use it
 * @read_block		function pointer for reading blocks of data
 * @sw_mode_config:	pointer to a function which configured the device
 *			for software mode
 * @reg_read	function pointer for reading spi register
 * @reg_write	function pointer for writing spi register
 * @write_mask	function pointer for write spi register with mask
 * @update_scan_mode	function pointer for handling the calls to iio_info's update_scan
 *			mode when enabling/disabling channels.
 * @rd_wr_cmd	pointer to the function which calculates the spi address
 */
struct ad7606_bus_ops {
	/* more methods added in future? */
	int (*iio_backend_config)(struct device *dev, struct iio_dev *indio_dev);
	int (*read_block)(struct device *dev, int num, void *data);
	int (*sw_mode_config)(struct iio_dev *indio_dev);
	int (*reg_read)(struct ad7606_state *st, unsigned int addr);
	int (*reg_write)(struct ad7606_state *st,
				unsigned int addr,
				unsigned int val);
	int (*write_mask)(struct ad7606_state *st,
				 unsigned int addr,
				 unsigned long mask,
				 unsigned int val);
	int (*update_scan_mode)(struct iio_dev *indio_dev, const unsigned long *scan_mask);
	u16 (*rd_wr_cmd)(int addr, char isWriteOp);
};

/**
 * struct ad7606_bus_info - agregate ad7606_chip_info and ad7606_bus_ops
 * @chip_info		entry in the table of chips that describes this device
 * @bops		bus operations (SPI or parallel)
 */
struct ad7606_bus_info {
	const struct ad7606_chip_info	*chip_info;
	const struct ad7606_bus_ops	*bops;
};

int ad7606_probe(struct device *dev, int irq, void __iomem *base_address,
		 const struct ad7606_chip_info *info,
		 const struct ad7606_bus_ops *bops);

int ad7606_reset(struct ad7606_state *st);

extern const struct ad7606_chip_info ad7605_4_info;
extern const struct ad7606_chip_info ad7606_8_info;
extern const struct ad7606_chip_info ad7606_6_info;
extern const struct ad7606_chip_info ad7606_4_info;
extern const struct ad7606_chip_info ad7606b_info;
extern const struct ad7606_chip_info ad7606c_16_info;
extern const struct ad7606_chip_info ad7606c_18_info;
extern const struct ad7606_chip_info ad7607_info;
extern const struct ad7606_chip_info ad7608_info;
extern const struct ad7606_chip_info ad7609_info;
extern const struct ad7606_chip_info ad7616_info;

#ifdef CONFIG_PM_SLEEP
extern const struct dev_pm_ops ad7606_pm_ops;
#define AD7606_PM_OPS (&ad7606_pm_ops)
#else
#define AD7606_PM_OPS NULL
#endif

#endif /* IIO_ADC_AD7606_H_ */