1af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen/*
2af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen * Support code for Analog Devices Sigma-Delta ADCs
3af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen *
4af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen * Copyright 2012 Analog Devices Inc.
5af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen *  Author: Lars-Peter Clausen <lars@metafoo.de>
6af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen *
7af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen * Licensed under the GPL-2.
8af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen */
9af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen#ifndef __AD_SIGMA_DELTA_H__
10af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen#define __AD_SIGMA_DELTA_H__
11af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen
12af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausenenum ad_sigma_delta_mode {
13af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen	AD_SD_MODE_CONTINUOUS = 0,
14af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen	AD_SD_MODE_SINGLE = 1,
15af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen	AD_SD_MODE_IDLE = 2,
16af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen	AD_SD_MODE_POWERDOWN = 3,
17af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen};
18af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen
19af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen/**
20af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen * struct ad_sigma_delta_calib_data - Calibration data for Sigma Delta devices
21af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen * @mode: Calibration mode.
22af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen * @channel: Calibration channel.
23af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen */
24af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausenstruct ad_sd_calib_data {
25af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen	unsigned int mode;
26af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen	unsigned int channel;
27af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen};
28af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen
29af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausenstruct ad_sigma_delta;
30af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausenstruct iio_dev;
31af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen
32af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen/**
33af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen * struct ad_sigma_delta_info - Sigma Delta driver specific callbacks and options
34af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen * @set_channel: Will be called to select the current channel, may be NULL.
35af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen * @set_mode: Will be called to select the current mode, may be NULL.
36af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen * @postprocess_sample: Is called for each sampled data word, can be used to
37af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen *		modify or drop the sample data, it, may be NULL.
38af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen * @has_registers: true if the device has writable and readable registers, false
39af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen *		if there is just one read-only sample data shift register.
40af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen * @addr_shift: Shift of the register address in the communications register.
41af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen * @read_mask: Mask for the communications register having the read bit set.
42af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen */
43af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausenstruct ad_sigma_delta_info {
44af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen	int (*set_channel)(struct ad_sigma_delta *, unsigned int channel);
45af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen	int (*set_mode)(struct ad_sigma_delta *, enum ad_sigma_delta_mode mode);
46af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen	int (*postprocess_sample)(struct ad_sigma_delta *, unsigned int raw_sample);
47af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen	bool has_registers;
48af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen	unsigned int addr_shift;
49af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen	unsigned int read_mask;
50af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen};
51af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen
52af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen/**
53af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen * struct ad_sigma_delta - Sigma Delta device struct
54af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen * @spi: The spi device associated with the Sigma Delta device.
55af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen * @trig: The IIO trigger associated with the Sigma Delta device.
56af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen *
57af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen * Most of the fields are private to the sigma delta library code and should not
58af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen * be accessed by individual drivers.
59af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen */
60af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausenstruct ad_sigma_delta {
61af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen	struct spi_device	*spi;
62af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen	struct iio_trigger	*trig;
63af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen
64af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen/* private: */
65af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen	struct completion	completion;
66af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen	bool			irq_dis;
67af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen
68af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen	bool			bus_locked;
69af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen
70af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen	uint8_t			comm;
71af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen
72af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen	const struct ad_sigma_delta_info *info;
73af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen
74af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen	/*
75af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen	 * DMA (thus cache coherency maintenance) requires the
76af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen	 * transfer buffers to live in their own cache lines.
77af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen	 */
78af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen	uint8_t				data[4] ____cacheline_aligned;
79af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen};
80af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen
81af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausenstatic inline int ad_sigma_delta_set_channel(struct ad_sigma_delta *sd,
82af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen	unsigned int channel)
83af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen{
84af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen	if (sd->info->set_channel)
85af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen		return sd->info->set_channel(sd, channel);
86af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen
87af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen	return 0;
88af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen}
89af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen
90af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausenstatic inline int ad_sigma_delta_set_mode(struct ad_sigma_delta *sd,
91af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen	unsigned int mode)
92af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen{
93af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen	if (sd->info->set_mode)
94af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen		return sd->info->set_mode(sd, mode);
95af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen
96af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen	return 0;
97af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen}
98af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen
99af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausenstatic inline int ad_sigma_delta_postprocess_sample(struct ad_sigma_delta *sd,
100af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen	unsigned int raw_sample)
101af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen{
102af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen	if (sd->info->postprocess_sample)
103af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen		return sd->info->postprocess_sample(sd, raw_sample);
104af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen
105af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen	return 0;
106af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen}
107af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen
108af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausenvoid ad_sd_set_comm(struct ad_sigma_delta *sigma_delta, uint8_t comm);
109af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausenint ad_sd_write_reg(struct ad_sigma_delta *sigma_delta, unsigned int reg,
110af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen	unsigned int size, unsigned int val);
111af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausenint ad_sd_read_reg(struct ad_sigma_delta *sigma_delta, unsigned int reg,
112af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen	unsigned int size, unsigned int *val);
113af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen
114af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausenint ad_sigma_delta_single_conversion(struct iio_dev *indio_dev,
115af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen	const struct iio_chan_spec *chan, int *val);
116af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausenint ad_sd_calibrate_all(struct ad_sigma_delta *sigma_delta,
117af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen	const struct ad_sd_calib_data *cd, unsigned int n);
118af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausenint ad_sd_init(struct ad_sigma_delta *sigma_delta, struct iio_dev *indio_dev,
119af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen	struct spi_device *spi, const struct ad_sigma_delta_info *info);
120af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen
121af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausenint ad_sd_setup_buffer_and_trigger(struct iio_dev *indio_dev);
122af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausenvoid ad_sd_cleanup_buffer_and_trigger(struct iio_dev *indio_dev);
123af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen
124af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausenint ad_sd_validate_trigger(struct iio_dev *indio_dev, struct iio_trigger *trig);
125af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen
126af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen#define __AD_SD_CHANNEL(_si, _channel1, _channel2, _address, _bits, \
127af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen	_storagebits, _shift, _extend_name, _type) \
128af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen	{ \
129af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen		.type = (_type), \
130af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen		.differential = (_channel2 == -1 ? 0 : 1), \
131af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen		.indexed = 1, \
132af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen		.channel = (_channel1), \
133af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen		.channel2 = (_channel2), \
134af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen		.address = (_address), \
135af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen		.extend_name = (_extend_name), \
136ea0c68006321eea78a3702a9d68ff9395e06da38Jonathan Cameron		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
137ea0c68006321eea78a3702a9d68ff9395e06da38Jonathan Cameron			BIT(IIO_CHAN_INFO_OFFSET), \
138ea0c68006321eea78a3702a9d68ff9395e06da38Jonathan Cameron		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
139af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen		.scan_index = (_si), \
140af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen		.scan_type = { \
141af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen			.sign = 'u', \
142af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen			.realbits = (_bits), \
143af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen			.storagebits = (_storagebits), \
144af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen			.shift = (_shift), \
145af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen			.endianness = IIO_BE, \
146af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen		}, \
147af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen	}
148af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen
149af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen#define AD_SD_DIFF_CHANNEL(_si, _channel1, _channel2, _address, _bits, \
150af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen	_storagebits, _shift) \
151af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen	__AD_SD_CHANNEL(_si, _channel1, _channel2, _address, _bits, \
152af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen		_storagebits, _shift, NULL, IIO_VOLTAGE)
153af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen
154af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen#define AD_SD_SHORTED_CHANNEL(_si, _channel, _address, _bits, \
155af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen	_storagebits, _shift) \
156af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen	__AD_SD_CHANNEL(_si, _channel, _channel, _address, _bits, \
157af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen		_storagebits, _shift, "shorted", IIO_VOLTAGE)
158af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen
159af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen#define AD_SD_CHANNEL(_si, _channel, _address, _bits, \
160af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen	_storagebits, _shift) \
161af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen	__AD_SD_CHANNEL(_si, _channel, -1, _address, _bits, \
162af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen		_storagebits, _shift, NULL, IIO_VOLTAGE)
163af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen
164af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen#define AD_SD_TEMP_CHANNEL(_si, _address, _bits, _storagebits, _shift) \
165af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen	__AD_SD_CHANNEL(_si, 0, -1, _address, _bits, \
166af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen		_storagebits, _shift, NULL, IIO_TEMP)
167af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen
168af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen#define AD_SD_SUPPLY_CHANNEL(_si, _channel, _address, _bits, _storagebits, \
169af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen	_shift) \
170af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen	__AD_SD_CHANNEL(_si, _channel, -1, _address, _bits, \
171af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen		_storagebits, _shift, "supply", IIO_VOLTAGE)
172af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen
173af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen#endif
174