1b7ffd0faSTrevor Gamblin // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
2b7ffd0faSTrevor Gamblin /*
3b7ffd0faSTrevor Gamblin * Analog Devices Inc. AD7625 ADC driver
4b7ffd0faSTrevor Gamblin *
5b7ffd0faSTrevor Gamblin * Copyright 2024 Analog Devices Inc.
6b7ffd0faSTrevor Gamblin * Copyright 2024 BayLibre, SAS
7b7ffd0faSTrevor Gamblin *
8b7ffd0faSTrevor Gamblin * Note that this driver requires the AXI ADC IP block configured for
9b7ffd0faSTrevor Gamblin * LVDS to function. See Documentation/iio/ad7625.rst for more
10b7ffd0faSTrevor Gamblin * information.
11b7ffd0faSTrevor Gamblin */
12b7ffd0faSTrevor Gamblin
13b7ffd0faSTrevor Gamblin #include <linux/clk.h>
14b7ffd0faSTrevor Gamblin #include <linux/device.h>
15b7ffd0faSTrevor Gamblin #include <linux/err.h>
16b7ffd0faSTrevor Gamblin #include <linux/gpio/consumer.h>
17b7ffd0faSTrevor Gamblin #include <linux/iio/backend.h>
18b7ffd0faSTrevor Gamblin #include <linux/iio/iio.h>
19b7ffd0faSTrevor Gamblin #include <linux/kernel.h>
20b7ffd0faSTrevor Gamblin #include <linux/mod_devicetable.h>
21b7ffd0faSTrevor Gamblin #include <linux/module.h>
22b7ffd0faSTrevor Gamblin #include <linux/platform_device.h>
23b7ffd0faSTrevor Gamblin #include <linux/pwm.h>
24b7ffd0faSTrevor Gamblin #include <linux/regulator/consumer.h>
25b7ffd0faSTrevor Gamblin #include <linux/units.h>
26b7ffd0faSTrevor Gamblin
27b7ffd0faSTrevor Gamblin #define AD7625_INTERNAL_REF_MV 4096
28b7ffd0faSTrevor Gamblin #define AD7960_MAX_NBW_FREQ (2 * MEGA)
29b7ffd0faSTrevor Gamblin
30b7ffd0faSTrevor Gamblin struct ad7625_timing_spec {
31b7ffd0faSTrevor Gamblin /* Max conversion high time (t_{CNVH}). */
32b7ffd0faSTrevor Gamblin unsigned int conv_high_ns;
33b7ffd0faSTrevor Gamblin /* Max conversion to MSB delay (t_{MSB}). */
34b7ffd0faSTrevor Gamblin unsigned int conv_msb_ns;
35b7ffd0faSTrevor Gamblin };
36b7ffd0faSTrevor Gamblin
37b7ffd0faSTrevor Gamblin struct ad7625_chip_info {
38b7ffd0faSTrevor Gamblin const char *name;
39b7ffd0faSTrevor Gamblin const unsigned int max_sample_freq_hz;
40b7ffd0faSTrevor Gamblin const struct ad7625_timing_spec *timing_spec;
41b7ffd0faSTrevor Gamblin const struct iio_chan_spec chan_spec;
42b7ffd0faSTrevor Gamblin const bool has_power_down_state;
43b7ffd0faSTrevor Gamblin const bool has_bandwidth_control;
44b7ffd0faSTrevor Gamblin const bool has_internal_vref;
45b7ffd0faSTrevor Gamblin };
46b7ffd0faSTrevor Gamblin
47b7ffd0faSTrevor Gamblin /* AD7625_CHAN_SPEC - Define a chan spec structure for a specific chip */
48b7ffd0faSTrevor Gamblin #define AD7625_CHAN_SPEC(_bits) { \
49b7ffd0faSTrevor Gamblin .type = IIO_VOLTAGE, \
50b7ffd0faSTrevor Gamblin .indexed = 1, \
51b7ffd0faSTrevor Gamblin .differential = 1, \
52b7ffd0faSTrevor Gamblin .channel = 0, \
53b7ffd0faSTrevor Gamblin .channel2 = 1, \
54b7ffd0faSTrevor Gamblin .info_mask_separate = BIT(IIO_CHAN_INFO_SCALE), \
55b7ffd0faSTrevor Gamblin .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
56b7ffd0faSTrevor Gamblin .scan_index = 0, \
57b7ffd0faSTrevor Gamblin .scan_type.sign = 's', \
58b7ffd0faSTrevor Gamblin .scan_type.storagebits = (_bits) > 16 ? 32 : 16, \
59b7ffd0faSTrevor Gamblin .scan_type.realbits = (_bits), \
60b7ffd0faSTrevor Gamblin }
61b7ffd0faSTrevor Gamblin
62b7ffd0faSTrevor Gamblin struct ad7625_state {
63b7ffd0faSTrevor Gamblin const struct ad7625_chip_info *info;
64b7ffd0faSTrevor Gamblin struct iio_backend *back;
65b7ffd0faSTrevor Gamblin /* rate of the clock gated by the "clk_gate" PWM */
66b7ffd0faSTrevor Gamblin u32 ref_clk_rate_hz;
67b7ffd0faSTrevor Gamblin /* PWM burst signal for transferring acquired data to the host */
68b7ffd0faSTrevor Gamblin struct pwm_device *clk_gate_pwm;
69b7ffd0faSTrevor Gamblin /*
70b7ffd0faSTrevor Gamblin * PWM control signal for initiating data conversion. Analog
71b7ffd0faSTrevor Gamblin * inputs are sampled beginning on this signal's rising edge.
72b7ffd0faSTrevor Gamblin */
73b7ffd0faSTrevor Gamblin struct pwm_device *cnv_pwm;
74b7ffd0faSTrevor Gamblin /*
75b7ffd0faSTrevor Gamblin * Waveforms containing the last-requested and rounded
76b7ffd0faSTrevor Gamblin * properties for the clk_gate and cnv PWMs
77b7ffd0faSTrevor Gamblin */
78b7ffd0faSTrevor Gamblin struct pwm_waveform clk_gate_wf;
79b7ffd0faSTrevor Gamblin struct pwm_waveform cnv_wf;
80b7ffd0faSTrevor Gamblin unsigned int vref_mv;
81b7ffd0faSTrevor Gamblin u32 sampling_freq_hz;
82b7ffd0faSTrevor Gamblin /*
83b7ffd0faSTrevor Gamblin * Optional GPIOs for controlling device state. EN0 and EN1
84b7ffd0faSTrevor Gamblin * determine voltage reference configuration and on/off state.
85b7ffd0faSTrevor Gamblin * EN2 controls the device -3dB bandwidth (and by extension, max
86b7ffd0faSTrevor Gamblin * sample rate). EN3 controls the VCM reference output. EN2 and
87b7ffd0faSTrevor Gamblin * EN3 are only present for the AD796x devices.
88b7ffd0faSTrevor Gamblin */
89b7ffd0faSTrevor Gamblin struct gpio_desc *en_gpios[4];
90b7ffd0faSTrevor Gamblin bool can_power_down;
91b7ffd0faSTrevor Gamblin bool can_refin;
92b7ffd0faSTrevor Gamblin bool can_ref_4v096;
93b7ffd0faSTrevor Gamblin /*
94b7ffd0faSTrevor Gamblin * Indicate whether the bandwidth can be narrow (9MHz).
95b7ffd0faSTrevor Gamblin * When true, device sample rate must also be < 2MSPS.
96b7ffd0faSTrevor Gamblin */
97b7ffd0faSTrevor Gamblin bool can_narrow_bandwidth;
98b7ffd0faSTrevor Gamblin /* Indicate whether the bandwidth can be wide (28MHz). */
99b7ffd0faSTrevor Gamblin bool can_wide_bandwidth;
100b7ffd0faSTrevor Gamblin bool can_ref_5v;
101b7ffd0faSTrevor Gamblin bool can_snooze;
102b7ffd0faSTrevor Gamblin bool can_test_pattern;
103b7ffd0faSTrevor Gamblin /* Indicate whether there is a REFIN supply connected */
104b7ffd0faSTrevor Gamblin bool have_refin;
105b7ffd0faSTrevor Gamblin };
106b7ffd0faSTrevor Gamblin
107b7ffd0faSTrevor Gamblin static const struct ad7625_timing_spec ad7625_timing_spec = {
108b7ffd0faSTrevor Gamblin .conv_high_ns = 40,
109b7ffd0faSTrevor Gamblin .conv_msb_ns = 145,
110b7ffd0faSTrevor Gamblin };
111b7ffd0faSTrevor Gamblin
112b7ffd0faSTrevor Gamblin static const struct ad7625_timing_spec ad7626_timing_spec = {
113b7ffd0faSTrevor Gamblin .conv_high_ns = 40,
114b7ffd0faSTrevor Gamblin .conv_msb_ns = 80,
115b7ffd0faSTrevor Gamblin };
116b7ffd0faSTrevor Gamblin
117b7ffd0faSTrevor Gamblin /*
118b7ffd0faSTrevor Gamblin * conv_msb_ns is set to 0 instead of the datasheet maximum of 200ns to
119b7ffd0faSTrevor Gamblin * avoid exceeding the minimum conversion time, i.e. it is effectively
120b7ffd0faSTrevor Gamblin * modulo 200 and offset by a full period. Values greater than or equal
121b7ffd0faSTrevor Gamblin * to the period would be rejected by the PWM API.
122b7ffd0faSTrevor Gamblin */
123b7ffd0faSTrevor Gamblin static const struct ad7625_timing_spec ad7960_timing_spec = {
124b7ffd0faSTrevor Gamblin .conv_high_ns = 80,
125b7ffd0faSTrevor Gamblin .conv_msb_ns = 0,
126b7ffd0faSTrevor Gamblin };
127b7ffd0faSTrevor Gamblin
128b7ffd0faSTrevor Gamblin static const struct ad7625_chip_info ad7625_chip_info = {
129b7ffd0faSTrevor Gamblin .name = "ad7625",
130b7ffd0faSTrevor Gamblin .max_sample_freq_hz = 6 * MEGA,
131b7ffd0faSTrevor Gamblin .timing_spec = &ad7625_timing_spec,
132b7ffd0faSTrevor Gamblin .chan_spec = AD7625_CHAN_SPEC(16),
133b7ffd0faSTrevor Gamblin .has_power_down_state = false,
134b7ffd0faSTrevor Gamblin .has_bandwidth_control = false,
135b7ffd0faSTrevor Gamblin .has_internal_vref = true,
136b7ffd0faSTrevor Gamblin };
137b7ffd0faSTrevor Gamblin
138b7ffd0faSTrevor Gamblin static const struct ad7625_chip_info ad7626_chip_info = {
139b7ffd0faSTrevor Gamblin .name = "ad7626",
140b7ffd0faSTrevor Gamblin .max_sample_freq_hz = 10 * MEGA,
141b7ffd0faSTrevor Gamblin .timing_spec = &ad7626_timing_spec,
142b7ffd0faSTrevor Gamblin .chan_spec = AD7625_CHAN_SPEC(16),
143b7ffd0faSTrevor Gamblin .has_power_down_state = true,
144b7ffd0faSTrevor Gamblin .has_bandwidth_control = false,
145b7ffd0faSTrevor Gamblin .has_internal_vref = true,
146b7ffd0faSTrevor Gamblin };
147b7ffd0faSTrevor Gamblin
148b7ffd0faSTrevor Gamblin static const struct ad7625_chip_info ad7960_chip_info = {
149b7ffd0faSTrevor Gamblin .name = "ad7960",
150b7ffd0faSTrevor Gamblin .max_sample_freq_hz = 5 * MEGA,
151b7ffd0faSTrevor Gamblin .timing_spec = &ad7960_timing_spec,
152b7ffd0faSTrevor Gamblin .chan_spec = AD7625_CHAN_SPEC(18),
153b7ffd0faSTrevor Gamblin .has_power_down_state = true,
154b7ffd0faSTrevor Gamblin .has_bandwidth_control = true,
155b7ffd0faSTrevor Gamblin .has_internal_vref = false,
156b7ffd0faSTrevor Gamblin };
157b7ffd0faSTrevor Gamblin
158b7ffd0faSTrevor Gamblin static const struct ad7625_chip_info ad7961_chip_info = {
159b7ffd0faSTrevor Gamblin .name = "ad7961",
160b7ffd0faSTrevor Gamblin .max_sample_freq_hz = 5 * MEGA,
161b7ffd0faSTrevor Gamblin .timing_spec = &ad7960_timing_spec,
162b7ffd0faSTrevor Gamblin .chan_spec = AD7625_CHAN_SPEC(16),
163b7ffd0faSTrevor Gamblin .has_power_down_state = true,
164b7ffd0faSTrevor Gamblin .has_bandwidth_control = true,
165b7ffd0faSTrevor Gamblin .has_internal_vref = false,
166b7ffd0faSTrevor Gamblin };
167b7ffd0faSTrevor Gamblin
168b7ffd0faSTrevor Gamblin enum ad7960_mode {
169b7ffd0faSTrevor Gamblin AD7960_MODE_POWER_DOWN,
170b7ffd0faSTrevor Gamblin AD7960_MODE_SNOOZE,
171b7ffd0faSTrevor Gamblin AD7960_MODE_NARROW_BANDWIDTH,
172b7ffd0faSTrevor Gamblin AD7960_MODE_WIDE_BANDWIDTH,
173b7ffd0faSTrevor Gamblin AD7960_MODE_TEST_PATTERN,
174b7ffd0faSTrevor Gamblin };
175b7ffd0faSTrevor Gamblin
ad7625_set_sampling_freq(struct ad7625_state * st,u32 freq)176b7ffd0faSTrevor Gamblin static int ad7625_set_sampling_freq(struct ad7625_state *st, u32 freq)
177b7ffd0faSTrevor Gamblin {
178b7ffd0faSTrevor Gamblin u32 target;
179b7ffd0faSTrevor Gamblin struct pwm_waveform clk_gate_wf = { }, cnv_wf = { };
180b7ffd0faSTrevor Gamblin int ret;
181b7ffd0faSTrevor Gamblin
182b7ffd0faSTrevor Gamblin target = DIV_ROUND_UP(NSEC_PER_SEC, freq);
183b7ffd0faSTrevor Gamblin cnv_wf.period_length_ns = clamp(target, 100, 10 * KILO);
184b7ffd0faSTrevor Gamblin
185b7ffd0faSTrevor Gamblin /*
186b7ffd0faSTrevor Gamblin * Use the maximum conversion time t_CNVH from the datasheet as
187b7ffd0faSTrevor Gamblin * the duty_cycle for ref_clk, cnv, and clk_gate
188b7ffd0faSTrevor Gamblin */
189b7ffd0faSTrevor Gamblin cnv_wf.duty_length_ns = st->info->timing_spec->conv_high_ns;
190b7ffd0faSTrevor Gamblin
191b7ffd0faSTrevor Gamblin ret = pwm_round_waveform_might_sleep(st->cnv_pwm, &cnv_wf);
192b7ffd0faSTrevor Gamblin if (ret)
193b7ffd0faSTrevor Gamblin return ret;
194b7ffd0faSTrevor Gamblin
195b7ffd0faSTrevor Gamblin /*
196b7ffd0faSTrevor Gamblin * Set up the burst signal for transferring data. period and
197b7ffd0faSTrevor Gamblin * offset should mirror the CNV signal
198b7ffd0faSTrevor Gamblin */
199b7ffd0faSTrevor Gamblin clk_gate_wf.period_length_ns = cnv_wf.period_length_ns;
200b7ffd0faSTrevor Gamblin
201b7ffd0faSTrevor Gamblin clk_gate_wf.duty_length_ns = DIV_ROUND_UP_ULL((u64)NSEC_PER_SEC *
202b7ffd0faSTrevor Gamblin st->info->chan_spec.scan_type.realbits,
203b7ffd0faSTrevor Gamblin st->ref_clk_rate_hz);
204b7ffd0faSTrevor Gamblin
205b7ffd0faSTrevor Gamblin /* max t_MSB from datasheet */
206b7ffd0faSTrevor Gamblin clk_gate_wf.duty_offset_ns = st->info->timing_spec->conv_msb_ns;
207b7ffd0faSTrevor Gamblin
208b7ffd0faSTrevor Gamblin ret = pwm_round_waveform_might_sleep(st->clk_gate_pwm, &clk_gate_wf);
209b7ffd0faSTrevor Gamblin if (ret)
210b7ffd0faSTrevor Gamblin return ret;
211b7ffd0faSTrevor Gamblin
212b7ffd0faSTrevor Gamblin st->cnv_wf = cnv_wf;
213b7ffd0faSTrevor Gamblin st->clk_gate_wf = clk_gate_wf;
214b7ffd0faSTrevor Gamblin
215b7ffd0faSTrevor Gamblin /* TODO: Add a rounding API for PWMs that can simplify this */
216b7ffd0faSTrevor Gamblin target = DIV_ROUND_CLOSEST(st->ref_clk_rate_hz, freq);
217b7ffd0faSTrevor Gamblin st->sampling_freq_hz = DIV_ROUND_CLOSEST(st->ref_clk_rate_hz,
218b7ffd0faSTrevor Gamblin target);
219b7ffd0faSTrevor Gamblin
220b7ffd0faSTrevor Gamblin return 0;
221b7ffd0faSTrevor Gamblin }
222b7ffd0faSTrevor Gamblin
ad7625_read_raw(struct iio_dev * indio_dev,const struct iio_chan_spec * chan,int * val,int * val2,long info)223b7ffd0faSTrevor Gamblin static int ad7625_read_raw(struct iio_dev *indio_dev,
224b7ffd0faSTrevor Gamblin const struct iio_chan_spec *chan,
225b7ffd0faSTrevor Gamblin int *val, int *val2, long info)
226b7ffd0faSTrevor Gamblin {
227b7ffd0faSTrevor Gamblin struct ad7625_state *st = iio_priv(indio_dev);
228b7ffd0faSTrevor Gamblin
229b7ffd0faSTrevor Gamblin switch (info) {
230b7ffd0faSTrevor Gamblin case IIO_CHAN_INFO_SAMP_FREQ:
231b7ffd0faSTrevor Gamblin *val = st->sampling_freq_hz;
232b7ffd0faSTrevor Gamblin
233b7ffd0faSTrevor Gamblin return IIO_VAL_INT;
234b7ffd0faSTrevor Gamblin
235b7ffd0faSTrevor Gamblin case IIO_CHAN_INFO_SCALE:
236b7ffd0faSTrevor Gamblin *val = st->vref_mv;
237b7ffd0faSTrevor Gamblin *val2 = chan->scan_type.realbits - 1;
238b7ffd0faSTrevor Gamblin
239b7ffd0faSTrevor Gamblin return IIO_VAL_FRACTIONAL_LOG2;
240b7ffd0faSTrevor Gamblin
241b7ffd0faSTrevor Gamblin default:
242b7ffd0faSTrevor Gamblin return -EINVAL;
243b7ffd0faSTrevor Gamblin }
244b7ffd0faSTrevor Gamblin }
245b7ffd0faSTrevor Gamblin
ad7625_write_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int val,int val2,long info)246b7ffd0faSTrevor Gamblin static int ad7625_write_raw(struct iio_dev *indio_dev,
247b7ffd0faSTrevor Gamblin struct iio_chan_spec const *chan,
248b7ffd0faSTrevor Gamblin int val, int val2, long info)
249b7ffd0faSTrevor Gamblin {
250b7ffd0faSTrevor Gamblin struct ad7625_state *st = iio_priv(indio_dev);
251b7ffd0faSTrevor Gamblin
252b7ffd0faSTrevor Gamblin switch (info) {
253b7ffd0faSTrevor Gamblin case IIO_CHAN_INFO_SAMP_FREQ:
254b7ffd0faSTrevor Gamblin iio_device_claim_direct_scoped(return -EBUSY, indio_dev)
255b7ffd0faSTrevor Gamblin return ad7625_set_sampling_freq(st, val);
256b7ffd0faSTrevor Gamblin unreachable();
257b7ffd0faSTrevor Gamblin default:
258b7ffd0faSTrevor Gamblin return -EINVAL;
259b7ffd0faSTrevor Gamblin }
260b7ffd0faSTrevor Gamblin }
261b7ffd0faSTrevor Gamblin
ad7625_parse_mode(struct device * dev,struct ad7625_state * st,int num_gpios)262b7ffd0faSTrevor Gamblin static int ad7625_parse_mode(struct device *dev, struct ad7625_state *st,
263b7ffd0faSTrevor Gamblin int num_gpios)
264b7ffd0faSTrevor Gamblin {
265b7ffd0faSTrevor Gamblin bool en_always_on[4], en_always_off[4];
266b7ffd0faSTrevor Gamblin bool en_may_be_on[4], en_may_be_off[4];
267b7ffd0faSTrevor Gamblin char en_gpio_buf[4];
268b7ffd0faSTrevor Gamblin char always_on_buf[18];
269b7ffd0faSTrevor Gamblin int i;
270b7ffd0faSTrevor Gamblin
271b7ffd0faSTrevor Gamblin for (i = 0; i < num_gpios; i++) {
272b7ffd0faSTrevor Gamblin snprintf(en_gpio_buf, sizeof(en_gpio_buf), "en%d", i);
273b7ffd0faSTrevor Gamblin snprintf(always_on_buf, sizeof(always_on_buf),
274b7ffd0faSTrevor Gamblin "adi,en%d-always-on", i);
275b7ffd0faSTrevor Gamblin /* Set the device to 0b0000 (power-down mode) by default */
276b7ffd0faSTrevor Gamblin st->en_gpios[i] = devm_gpiod_get_optional(dev, en_gpio_buf,
277b7ffd0faSTrevor Gamblin GPIOD_OUT_LOW);
278b7ffd0faSTrevor Gamblin if (IS_ERR(st->en_gpios[i]))
279b7ffd0faSTrevor Gamblin return dev_err_probe(dev, PTR_ERR(st->en_gpios[i]),
280b7ffd0faSTrevor Gamblin "failed to get EN%d GPIO\n", i);
281b7ffd0faSTrevor Gamblin
282b7ffd0faSTrevor Gamblin en_always_on[i] = device_property_read_bool(dev, always_on_buf);
283b7ffd0faSTrevor Gamblin if (st->en_gpios[i] && en_always_on[i])
284b7ffd0faSTrevor Gamblin return dev_err_probe(dev, -EINVAL,
285b7ffd0faSTrevor Gamblin "cannot have adi,en%d-always-on and en%d-gpios\n", i, i);
286b7ffd0faSTrevor Gamblin
287b7ffd0faSTrevor Gamblin en_may_be_off[i] = !en_always_on[i];
288b7ffd0faSTrevor Gamblin en_may_be_on[i] = en_always_on[i] || st->en_gpios[i];
289b7ffd0faSTrevor Gamblin en_always_off[i] = !en_always_on[i] && !st->en_gpios[i];
290b7ffd0faSTrevor Gamblin }
291b7ffd0faSTrevor Gamblin
292b7ffd0faSTrevor Gamblin /*
293b7ffd0faSTrevor Gamblin * Power down is mode 0bXX00, but not all devices have a valid
294b7ffd0faSTrevor Gamblin * power down state.
295b7ffd0faSTrevor Gamblin */
296b7ffd0faSTrevor Gamblin st->can_power_down = en_may_be_off[1] && en_may_be_off[0] &&
297b7ffd0faSTrevor Gamblin st->info->has_power_down_state;
298b7ffd0faSTrevor Gamblin /*
299b7ffd0faSTrevor Gamblin * The REFIN pin can take a 1.2V (AD762x) or 2.048V (AD796x)
300b7ffd0faSTrevor Gamblin * external reference when the mode is 0bXX01.
301b7ffd0faSTrevor Gamblin */
302b7ffd0faSTrevor Gamblin st->can_refin = en_may_be_off[1] && en_may_be_on[0];
303b7ffd0faSTrevor Gamblin /* 4.096V can be applied to REF when the EN mode is 0bXX10. */
304b7ffd0faSTrevor Gamblin st->can_ref_4v096 = en_may_be_on[1] && en_may_be_off[0];
305b7ffd0faSTrevor Gamblin
306b7ffd0faSTrevor Gamblin /* Avoid AD796x-specific setup if the part is an AD762x */
307b7ffd0faSTrevor Gamblin if (num_gpios == 2)
308b7ffd0faSTrevor Gamblin return 0;
309b7ffd0faSTrevor Gamblin
310b7ffd0faSTrevor Gamblin /* mode 0b1100 (AD796x) is invalid */
311b7ffd0faSTrevor Gamblin if (en_always_on[3] && en_always_on[2] &&
312b7ffd0faSTrevor Gamblin en_always_off[1] && en_always_off[0])
313b7ffd0faSTrevor Gamblin return dev_err_probe(dev, -EINVAL,
314b7ffd0faSTrevor Gamblin "EN GPIOs set to invalid mode 0b1100\n");
315b7ffd0faSTrevor Gamblin /*
316b7ffd0faSTrevor Gamblin * 5V can be applied to the AD796x REF pin when the EN mode is
317b7ffd0faSTrevor Gamblin * the same (0bX001 or 0bX101) as for can_refin, and REFIN is
318b7ffd0faSTrevor Gamblin * 0V.
319b7ffd0faSTrevor Gamblin */
320b7ffd0faSTrevor Gamblin st->can_ref_5v = st->can_refin;
321b7ffd0faSTrevor Gamblin /*
322b7ffd0faSTrevor Gamblin * Bandwidth (AD796x) is controlled solely by EN2. If it's
323b7ffd0faSTrevor Gamblin * specified and not hard-wired, then we can configure it to
324b7ffd0faSTrevor Gamblin * change the bandwidth between 28MHz and 9MHz.
325b7ffd0faSTrevor Gamblin */
326b7ffd0faSTrevor Gamblin st->can_narrow_bandwidth = en_may_be_on[2];
327b7ffd0faSTrevor Gamblin /* Wide bandwidth mode is possible if EN2 can be 0. */
328b7ffd0faSTrevor Gamblin st->can_wide_bandwidth = en_may_be_off[2];
329b7ffd0faSTrevor Gamblin /* Snooze mode (AD796x) is 0bXX11 when REFIN = 0V. */
330b7ffd0faSTrevor Gamblin st->can_snooze = en_may_be_on[1] && en_may_be_on[0];
331b7ffd0faSTrevor Gamblin /* Test pattern mode (AD796x) is 0b0100. */
332b7ffd0faSTrevor Gamblin st->can_test_pattern = en_may_be_off[3] && en_may_be_on[2] &&
333b7ffd0faSTrevor Gamblin en_may_be_off[1] && en_may_be_off[0];
334b7ffd0faSTrevor Gamblin
335b7ffd0faSTrevor Gamblin return 0;
336b7ffd0faSTrevor Gamblin }
337b7ffd0faSTrevor Gamblin
338b7ffd0faSTrevor Gamblin /* Set EN1 and EN0 based on reference voltage source */
ad7625_set_en_gpios_for_vref(struct ad7625_state * st,bool have_refin,int ref_mv)339b7ffd0faSTrevor Gamblin static void ad7625_set_en_gpios_for_vref(struct ad7625_state *st,
340b7ffd0faSTrevor Gamblin bool have_refin, int ref_mv)
341b7ffd0faSTrevor Gamblin {
342b7ffd0faSTrevor Gamblin if (have_refin || ref_mv == 5000) {
343b7ffd0faSTrevor Gamblin gpiod_set_value_cansleep(st->en_gpios[1], 0);
344b7ffd0faSTrevor Gamblin gpiod_set_value_cansleep(st->en_gpios[0], 1);
345b7ffd0faSTrevor Gamblin } else if (ref_mv == 4096) {
346b7ffd0faSTrevor Gamblin gpiod_set_value_cansleep(st->en_gpios[1], 1);
347b7ffd0faSTrevor Gamblin gpiod_set_value_cansleep(st->en_gpios[0], 0);
348b7ffd0faSTrevor Gamblin } else {
349b7ffd0faSTrevor Gamblin /*
350b7ffd0faSTrevor Gamblin * Unreachable by AD796x, since the driver will error if
351b7ffd0faSTrevor Gamblin * neither REF nor REFIN is provided
352b7ffd0faSTrevor Gamblin */
353b7ffd0faSTrevor Gamblin gpiod_set_value_cansleep(st->en_gpios[1], 1);
354b7ffd0faSTrevor Gamblin gpiod_set_value_cansleep(st->en_gpios[0], 1);
355b7ffd0faSTrevor Gamblin }
356b7ffd0faSTrevor Gamblin }
357b7ffd0faSTrevor Gamblin
ad7960_set_mode(struct ad7625_state * st,enum ad7960_mode mode,bool have_refin,int ref_mv)358b7ffd0faSTrevor Gamblin static int ad7960_set_mode(struct ad7625_state *st, enum ad7960_mode mode,
359b7ffd0faSTrevor Gamblin bool have_refin, int ref_mv)
360b7ffd0faSTrevor Gamblin {
361b7ffd0faSTrevor Gamblin switch (mode) {
362b7ffd0faSTrevor Gamblin case AD7960_MODE_POWER_DOWN:
363b7ffd0faSTrevor Gamblin if (!st->can_power_down)
364b7ffd0faSTrevor Gamblin return -EINVAL;
365b7ffd0faSTrevor Gamblin
366b7ffd0faSTrevor Gamblin gpiod_set_value_cansleep(st->en_gpios[2], 0);
367b7ffd0faSTrevor Gamblin gpiod_set_value_cansleep(st->en_gpios[1], 0);
368b7ffd0faSTrevor Gamblin gpiod_set_value_cansleep(st->en_gpios[0], 0);
369b7ffd0faSTrevor Gamblin
370b7ffd0faSTrevor Gamblin return 0;
371b7ffd0faSTrevor Gamblin
372b7ffd0faSTrevor Gamblin case AD7960_MODE_SNOOZE:
373b7ffd0faSTrevor Gamblin if (!st->can_snooze)
374b7ffd0faSTrevor Gamblin return -EINVAL;
375b7ffd0faSTrevor Gamblin
376b7ffd0faSTrevor Gamblin gpiod_set_value_cansleep(st->en_gpios[1], 1);
377b7ffd0faSTrevor Gamblin gpiod_set_value_cansleep(st->en_gpios[0], 1);
378b7ffd0faSTrevor Gamblin
379b7ffd0faSTrevor Gamblin return 0;
380b7ffd0faSTrevor Gamblin
381b7ffd0faSTrevor Gamblin case AD7960_MODE_NARROW_BANDWIDTH:
382b7ffd0faSTrevor Gamblin if (!st->can_narrow_bandwidth)
383b7ffd0faSTrevor Gamblin return -EINVAL;
384b7ffd0faSTrevor Gamblin
385b7ffd0faSTrevor Gamblin gpiod_set_value_cansleep(st->en_gpios[2], 1);
386b7ffd0faSTrevor Gamblin ad7625_set_en_gpios_for_vref(st, have_refin, ref_mv);
387b7ffd0faSTrevor Gamblin
388b7ffd0faSTrevor Gamblin return 0;
389b7ffd0faSTrevor Gamblin
390b7ffd0faSTrevor Gamblin case AD7960_MODE_WIDE_BANDWIDTH:
391b7ffd0faSTrevor Gamblin if (!st->can_wide_bandwidth)
392b7ffd0faSTrevor Gamblin return -EINVAL;
393b7ffd0faSTrevor Gamblin
394b7ffd0faSTrevor Gamblin gpiod_set_value_cansleep(st->en_gpios[2], 0);
395b7ffd0faSTrevor Gamblin ad7625_set_en_gpios_for_vref(st, have_refin, ref_mv);
396b7ffd0faSTrevor Gamblin
397b7ffd0faSTrevor Gamblin return 0;
398b7ffd0faSTrevor Gamblin
399b7ffd0faSTrevor Gamblin case AD7960_MODE_TEST_PATTERN:
400b7ffd0faSTrevor Gamblin if (!st->can_test_pattern)
401b7ffd0faSTrevor Gamblin return -EINVAL;
402b7ffd0faSTrevor Gamblin
403b7ffd0faSTrevor Gamblin gpiod_set_value_cansleep(st->en_gpios[3], 0);
404b7ffd0faSTrevor Gamblin gpiod_set_value_cansleep(st->en_gpios[2], 1);
405b7ffd0faSTrevor Gamblin gpiod_set_value_cansleep(st->en_gpios[1], 0);
406b7ffd0faSTrevor Gamblin gpiod_set_value_cansleep(st->en_gpios[0], 0);
407b7ffd0faSTrevor Gamblin
408b7ffd0faSTrevor Gamblin return 0;
409b7ffd0faSTrevor Gamblin
410b7ffd0faSTrevor Gamblin default:
411b7ffd0faSTrevor Gamblin return -EINVAL;
412b7ffd0faSTrevor Gamblin }
413b7ffd0faSTrevor Gamblin }
414b7ffd0faSTrevor Gamblin
ad7625_buffer_preenable(struct iio_dev * indio_dev)415b7ffd0faSTrevor Gamblin static int ad7625_buffer_preenable(struct iio_dev *indio_dev)
416b7ffd0faSTrevor Gamblin {
417b7ffd0faSTrevor Gamblin struct ad7625_state *st = iio_priv(indio_dev);
418b7ffd0faSTrevor Gamblin int ret;
419b7ffd0faSTrevor Gamblin
420b7ffd0faSTrevor Gamblin ret = pwm_set_waveform_might_sleep(st->cnv_pwm, &st->cnv_wf, false);
421b7ffd0faSTrevor Gamblin if (ret)
422b7ffd0faSTrevor Gamblin return ret;
423b7ffd0faSTrevor Gamblin
424b7ffd0faSTrevor Gamblin ret = pwm_set_waveform_might_sleep(st->clk_gate_pwm,
425b7ffd0faSTrevor Gamblin &st->clk_gate_wf, false);
426b7ffd0faSTrevor Gamblin if (ret) {
427b7ffd0faSTrevor Gamblin /* Disable cnv PWM if clk_gate setup failed */
428b7ffd0faSTrevor Gamblin pwm_disable(st->cnv_pwm);
429b7ffd0faSTrevor Gamblin return ret;
430b7ffd0faSTrevor Gamblin }
431b7ffd0faSTrevor Gamblin
432b7ffd0faSTrevor Gamblin return 0;
433b7ffd0faSTrevor Gamblin }
434b7ffd0faSTrevor Gamblin
ad7625_buffer_postdisable(struct iio_dev * indio_dev)435b7ffd0faSTrevor Gamblin static int ad7625_buffer_postdisable(struct iio_dev *indio_dev)
436b7ffd0faSTrevor Gamblin {
437b7ffd0faSTrevor Gamblin struct ad7625_state *st = iio_priv(indio_dev);
438b7ffd0faSTrevor Gamblin
439b7ffd0faSTrevor Gamblin pwm_disable(st->clk_gate_pwm);
440b7ffd0faSTrevor Gamblin pwm_disable(st->cnv_pwm);
441b7ffd0faSTrevor Gamblin
442b7ffd0faSTrevor Gamblin return 0;
443b7ffd0faSTrevor Gamblin }
444b7ffd0faSTrevor Gamblin
445b7ffd0faSTrevor Gamblin static const struct iio_info ad7625_info = {
446b7ffd0faSTrevor Gamblin .read_raw = ad7625_read_raw,
447b7ffd0faSTrevor Gamblin .write_raw = ad7625_write_raw,
448b7ffd0faSTrevor Gamblin };
449b7ffd0faSTrevor Gamblin
450b7ffd0faSTrevor Gamblin static const struct iio_buffer_setup_ops ad7625_buffer_setup_ops = {
451b7ffd0faSTrevor Gamblin .preenable = &ad7625_buffer_preenable,
452b7ffd0faSTrevor Gamblin .postdisable = &ad7625_buffer_postdisable,
453b7ffd0faSTrevor Gamblin };
454b7ffd0faSTrevor Gamblin
devm_ad7625_pwm_get(struct device * dev,struct ad7625_state * st)455b7ffd0faSTrevor Gamblin static int devm_ad7625_pwm_get(struct device *dev,
456b7ffd0faSTrevor Gamblin struct ad7625_state *st)
457b7ffd0faSTrevor Gamblin {
458b7ffd0faSTrevor Gamblin struct clk *ref_clk;
459b7ffd0faSTrevor Gamblin u32 ref_clk_rate_hz;
460b7ffd0faSTrevor Gamblin
461b7ffd0faSTrevor Gamblin st->cnv_pwm = devm_pwm_get(dev, "cnv");
462b7ffd0faSTrevor Gamblin if (IS_ERR(st->cnv_pwm))
463b7ffd0faSTrevor Gamblin return dev_err_probe(dev, PTR_ERR(st->cnv_pwm),
464b7ffd0faSTrevor Gamblin "failed to get cnv pwm\n");
465b7ffd0faSTrevor Gamblin
466b7ffd0faSTrevor Gamblin /* Preemptively disable the PWM in case it was enabled at boot */
467b7ffd0faSTrevor Gamblin pwm_disable(st->cnv_pwm);
468b7ffd0faSTrevor Gamblin
469b7ffd0faSTrevor Gamblin st->clk_gate_pwm = devm_pwm_get(dev, "clk_gate");
470b7ffd0faSTrevor Gamblin if (IS_ERR(st->clk_gate_pwm))
471b7ffd0faSTrevor Gamblin return dev_err_probe(dev, PTR_ERR(st->clk_gate_pwm),
472b7ffd0faSTrevor Gamblin "failed to get clk_gate pwm\n");
473b7ffd0faSTrevor Gamblin
474b7ffd0faSTrevor Gamblin /* Preemptively disable the PWM in case it was enabled at boot */
475b7ffd0faSTrevor Gamblin pwm_disable(st->clk_gate_pwm);
476b7ffd0faSTrevor Gamblin
477b7ffd0faSTrevor Gamblin ref_clk = devm_clk_get_enabled(dev, NULL);
478b7ffd0faSTrevor Gamblin if (IS_ERR(ref_clk))
479b7ffd0faSTrevor Gamblin return dev_err_probe(dev, PTR_ERR(ref_clk),
480b7ffd0faSTrevor Gamblin "failed to get ref_clk");
481b7ffd0faSTrevor Gamblin
482b7ffd0faSTrevor Gamblin ref_clk_rate_hz = clk_get_rate(ref_clk);
483b7ffd0faSTrevor Gamblin if (!ref_clk_rate_hz)
484b7ffd0faSTrevor Gamblin return dev_err_probe(dev, -EINVAL,
485b7ffd0faSTrevor Gamblin "failed to get ref_clk rate");
486b7ffd0faSTrevor Gamblin
487b7ffd0faSTrevor Gamblin st->ref_clk_rate_hz = ref_clk_rate_hz;
488b7ffd0faSTrevor Gamblin
489b7ffd0faSTrevor Gamblin return 0;
490b7ffd0faSTrevor Gamblin }
491b7ffd0faSTrevor Gamblin
492b7ffd0faSTrevor Gamblin /*
493b7ffd0faSTrevor Gamblin * There are three required input voltages for each device, plus two
494b7ffd0faSTrevor Gamblin * conditionally-optional (depending on part) REF and REFIN voltages
495b7ffd0faSTrevor Gamblin * where their validity depends upon the EN pin configuration.
496b7ffd0faSTrevor Gamblin *
497b7ffd0faSTrevor Gamblin * Power-up info for the device says to bring up vio, then vdd2, then
498b7ffd0faSTrevor Gamblin * vdd1, so list them in that order in the regulator_names array.
499b7ffd0faSTrevor Gamblin *
500b7ffd0faSTrevor Gamblin * The reference voltage source is determined like so:
501b7ffd0faSTrevor Gamblin * - internal reference: neither REF or REFIN is connected (invalid for
502b7ffd0faSTrevor Gamblin * AD796x)
503b7ffd0faSTrevor Gamblin * - internal buffer, external reference: REF not connected, REFIN
504b7ffd0faSTrevor Gamblin * connected
505b7ffd0faSTrevor Gamblin * - external reference: REF connected, REFIN not connected
506b7ffd0faSTrevor Gamblin */
devm_ad7625_regulator_setup(struct device * dev,struct ad7625_state * st)507b7ffd0faSTrevor Gamblin static int devm_ad7625_regulator_setup(struct device *dev,
508b7ffd0faSTrevor Gamblin struct ad7625_state *st)
509b7ffd0faSTrevor Gamblin {
510b7ffd0faSTrevor Gamblin static const char * const regulator_names[] = { "vio", "vdd2", "vdd1" };
511b7ffd0faSTrevor Gamblin int ret, ref_mv;
512b7ffd0faSTrevor Gamblin
513b7ffd0faSTrevor Gamblin ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(regulator_names),
514b7ffd0faSTrevor Gamblin regulator_names);
515b7ffd0faSTrevor Gamblin if (ret)
516b7ffd0faSTrevor Gamblin return ret;
517b7ffd0faSTrevor Gamblin
518b7ffd0faSTrevor Gamblin ret = devm_regulator_get_enable_read_voltage(dev, "ref");
519b7ffd0faSTrevor Gamblin if (ret < 0 && ret != -ENODEV)
520b7ffd0faSTrevor Gamblin return dev_err_probe(dev, ret, "failed to get REF voltage\n");
521b7ffd0faSTrevor Gamblin
522b7ffd0faSTrevor Gamblin ref_mv = ret == -ENODEV ? 0 : ret / 1000;
523b7ffd0faSTrevor Gamblin
524b7ffd0faSTrevor Gamblin ret = devm_regulator_get_enable_optional(dev, "refin");
525b7ffd0faSTrevor Gamblin if (ret < 0 && ret != -ENODEV)
526b7ffd0faSTrevor Gamblin return dev_err_probe(dev, ret, "failed to get REFIN voltage\n");
527b7ffd0faSTrevor Gamblin
528b7ffd0faSTrevor Gamblin st->have_refin = ret != -ENODEV;
529b7ffd0faSTrevor Gamblin
530b7ffd0faSTrevor Gamblin if (st->have_refin && !st->can_refin)
531b7ffd0faSTrevor Gamblin return dev_err_probe(dev, -EINVAL,
532b7ffd0faSTrevor Gamblin "REFIN provided in unsupported mode\n");
533b7ffd0faSTrevor Gamblin
534b7ffd0faSTrevor Gamblin if (!st->info->has_internal_vref && !st->have_refin && !ref_mv)
535b7ffd0faSTrevor Gamblin return dev_err_probe(dev, -EINVAL,
536b7ffd0faSTrevor Gamblin "Need either REFIN or REF");
537b7ffd0faSTrevor Gamblin
538b7ffd0faSTrevor Gamblin if (st->have_refin && ref_mv)
539b7ffd0faSTrevor Gamblin return dev_err_probe(dev, -EINVAL,
540b7ffd0faSTrevor Gamblin "cannot have both REFIN and REF supplies\n");
541b7ffd0faSTrevor Gamblin
542b7ffd0faSTrevor Gamblin if (ref_mv == 4096 && !st->can_ref_4v096)
543b7ffd0faSTrevor Gamblin return dev_err_probe(dev, -EINVAL,
544b7ffd0faSTrevor Gamblin "REF is 4.096V in unsupported mode\n");
545b7ffd0faSTrevor Gamblin
546b7ffd0faSTrevor Gamblin if (ref_mv == 5000 && !st->can_ref_5v)
547b7ffd0faSTrevor Gamblin return dev_err_probe(dev, -EINVAL,
548b7ffd0faSTrevor Gamblin "REF is 5V in unsupported mode\n");
549b7ffd0faSTrevor Gamblin
550b7ffd0faSTrevor Gamblin st->vref_mv = ref_mv ?: AD7625_INTERNAL_REF_MV;
551b7ffd0faSTrevor Gamblin
552b7ffd0faSTrevor Gamblin return 0;
553b7ffd0faSTrevor Gamblin }
554b7ffd0faSTrevor Gamblin
ad7625_probe(struct platform_device * pdev)555b7ffd0faSTrevor Gamblin static int ad7625_probe(struct platform_device *pdev)
556b7ffd0faSTrevor Gamblin {
557b7ffd0faSTrevor Gamblin struct device *dev = &pdev->dev;
558b7ffd0faSTrevor Gamblin struct iio_dev *indio_dev;
559b7ffd0faSTrevor Gamblin struct ad7625_state *st;
560b7ffd0faSTrevor Gamblin int ret;
561b7ffd0faSTrevor Gamblin u32 default_sample_freq;
562b7ffd0faSTrevor Gamblin
563b7ffd0faSTrevor Gamblin indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
564b7ffd0faSTrevor Gamblin if (!indio_dev)
565b7ffd0faSTrevor Gamblin return -ENOMEM;
566b7ffd0faSTrevor Gamblin
567b7ffd0faSTrevor Gamblin st = iio_priv(indio_dev);
568b7ffd0faSTrevor Gamblin
569b7ffd0faSTrevor Gamblin st->info = device_get_match_data(dev);
570b7ffd0faSTrevor Gamblin if (!st->info)
571b7ffd0faSTrevor Gamblin return dev_err_probe(dev, -EINVAL, "no chip info\n");
572b7ffd0faSTrevor Gamblin
573b7ffd0faSTrevor Gamblin if (device_property_read_bool(dev, "adi,no-dco"))
574b7ffd0faSTrevor Gamblin return dev_err_probe(dev, -EINVAL,
575b7ffd0faSTrevor Gamblin "self-clocked mode not supported\n");
576b7ffd0faSTrevor Gamblin
577b7ffd0faSTrevor Gamblin if (st->info->has_bandwidth_control)
578b7ffd0faSTrevor Gamblin ret = ad7625_parse_mode(dev, st, 4);
579b7ffd0faSTrevor Gamblin else
580b7ffd0faSTrevor Gamblin ret = ad7625_parse_mode(dev, st, 2);
581b7ffd0faSTrevor Gamblin
582b7ffd0faSTrevor Gamblin if (ret)
583b7ffd0faSTrevor Gamblin return ret;
584b7ffd0faSTrevor Gamblin
585b7ffd0faSTrevor Gamblin ret = devm_ad7625_regulator_setup(dev, st);
586b7ffd0faSTrevor Gamblin if (ret)
587b7ffd0faSTrevor Gamblin return ret;
588b7ffd0faSTrevor Gamblin
589b7ffd0faSTrevor Gamblin /* Set the device mode based on detected EN configuration. */
590b7ffd0faSTrevor Gamblin if (!st->info->has_bandwidth_control) {
591b7ffd0faSTrevor Gamblin ad7625_set_en_gpios_for_vref(st, st->have_refin, st->vref_mv);
592b7ffd0faSTrevor Gamblin } else {
593b7ffd0faSTrevor Gamblin /*
594b7ffd0faSTrevor Gamblin * If neither sampling mode is available, then report an error,
595b7ffd0faSTrevor Gamblin * since the other modes are not useful defaults.
596b7ffd0faSTrevor Gamblin */
597b7ffd0faSTrevor Gamblin if (st->can_wide_bandwidth) {
598b7ffd0faSTrevor Gamblin ret = ad7960_set_mode(st, AD7960_MODE_WIDE_BANDWIDTH,
599b7ffd0faSTrevor Gamblin st->have_refin, st->vref_mv);
600b7ffd0faSTrevor Gamblin } else if (st->can_narrow_bandwidth) {
601b7ffd0faSTrevor Gamblin ret = ad7960_set_mode(st, AD7960_MODE_NARROW_BANDWIDTH,
602b7ffd0faSTrevor Gamblin st->have_refin, st->vref_mv);
603b7ffd0faSTrevor Gamblin } else {
604b7ffd0faSTrevor Gamblin return dev_err_probe(dev, -EINVAL,
605b7ffd0faSTrevor Gamblin "couldn't set device to wide or narrow bandwidth modes\n");
606b7ffd0faSTrevor Gamblin }
607b7ffd0faSTrevor Gamblin
608b7ffd0faSTrevor Gamblin if (ret)
609b7ffd0faSTrevor Gamblin return dev_err_probe(dev, -EINVAL,
610b7ffd0faSTrevor Gamblin "failed to set EN pins\n");
611b7ffd0faSTrevor Gamblin }
612b7ffd0faSTrevor Gamblin
613b7ffd0faSTrevor Gamblin ret = devm_ad7625_pwm_get(dev, st);
614b7ffd0faSTrevor Gamblin if (ret)
615b7ffd0faSTrevor Gamblin return ret;
616b7ffd0faSTrevor Gamblin
617b7ffd0faSTrevor Gamblin indio_dev->channels = &st->info->chan_spec;
618b7ffd0faSTrevor Gamblin indio_dev->num_channels = 1;
619b7ffd0faSTrevor Gamblin indio_dev->name = st->info->name;
620b7ffd0faSTrevor Gamblin indio_dev->info = &ad7625_info;
621b7ffd0faSTrevor Gamblin indio_dev->setup_ops = &ad7625_buffer_setup_ops;
622b7ffd0faSTrevor Gamblin
623b7ffd0faSTrevor Gamblin st->back = devm_iio_backend_get(dev, NULL);
624b7ffd0faSTrevor Gamblin if (IS_ERR(st->back))
625b7ffd0faSTrevor Gamblin return dev_err_probe(dev, PTR_ERR(st->back),
626b7ffd0faSTrevor Gamblin "failed to get IIO backend");
627b7ffd0faSTrevor Gamblin
628b7ffd0faSTrevor Gamblin ret = devm_iio_backend_request_buffer(dev, st->back, indio_dev);
629b7ffd0faSTrevor Gamblin if (ret)
630b7ffd0faSTrevor Gamblin return ret;
631b7ffd0faSTrevor Gamblin
632b7ffd0faSTrevor Gamblin ret = devm_iio_backend_enable(dev, st->back);
633b7ffd0faSTrevor Gamblin if (ret)
634b7ffd0faSTrevor Gamblin return ret;
635b7ffd0faSTrevor Gamblin
636b7ffd0faSTrevor Gamblin /*
637b7ffd0faSTrevor Gamblin * Set the initial sampling frequency to the maximum, unless the
638b7ffd0faSTrevor Gamblin * AD796x device is limited to narrow bandwidth by EN2 == 1, in
639b7ffd0faSTrevor Gamblin * which case the sampling frequency should be limited to 2MSPS
640b7ffd0faSTrevor Gamblin */
641b7ffd0faSTrevor Gamblin default_sample_freq = st->info->max_sample_freq_hz;
642b7ffd0faSTrevor Gamblin if (st->info->has_bandwidth_control && !st->can_wide_bandwidth)
643b7ffd0faSTrevor Gamblin default_sample_freq = AD7960_MAX_NBW_FREQ;
644b7ffd0faSTrevor Gamblin
645b7ffd0faSTrevor Gamblin ret = ad7625_set_sampling_freq(st, default_sample_freq);
646b7ffd0faSTrevor Gamblin if (ret)
647b7ffd0faSTrevor Gamblin dev_err_probe(dev, ret,
648b7ffd0faSTrevor Gamblin "failed to set valid sampling frequency\n");
649b7ffd0faSTrevor Gamblin
650b7ffd0faSTrevor Gamblin return devm_iio_device_register(dev, indio_dev);
651b7ffd0faSTrevor Gamblin }
652b7ffd0faSTrevor Gamblin
653b7ffd0faSTrevor Gamblin static const struct of_device_id ad7625_of_match[] = {
654b7ffd0faSTrevor Gamblin { .compatible = "adi,ad7625", .data = &ad7625_chip_info },
655b7ffd0faSTrevor Gamblin { .compatible = "adi,ad7626", .data = &ad7626_chip_info },
656b7ffd0faSTrevor Gamblin { .compatible = "adi,ad7960", .data = &ad7960_chip_info },
657b7ffd0faSTrevor Gamblin { .compatible = "adi,ad7961", .data = &ad7961_chip_info },
658b7ffd0faSTrevor Gamblin { }
659b7ffd0faSTrevor Gamblin };
660b7ffd0faSTrevor Gamblin MODULE_DEVICE_TABLE(of, ad7625_of_match);
661b7ffd0faSTrevor Gamblin
662b7ffd0faSTrevor Gamblin static const struct platform_device_id ad7625_device_ids[] = {
663b7ffd0faSTrevor Gamblin { .name = "ad7625", .driver_data = (kernel_ulong_t)&ad7625_chip_info },
664b7ffd0faSTrevor Gamblin { .name = "ad7626", .driver_data = (kernel_ulong_t)&ad7626_chip_info },
665b7ffd0faSTrevor Gamblin { .name = "ad7960", .driver_data = (kernel_ulong_t)&ad7960_chip_info },
666b7ffd0faSTrevor Gamblin { .name = "ad7961", .driver_data = (kernel_ulong_t)&ad7961_chip_info },
667b7ffd0faSTrevor Gamblin { }
668b7ffd0faSTrevor Gamblin };
669b7ffd0faSTrevor Gamblin MODULE_DEVICE_TABLE(platform, ad7625_device_ids);
670b7ffd0faSTrevor Gamblin
671b7ffd0faSTrevor Gamblin static struct platform_driver ad7625_driver = {
672b7ffd0faSTrevor Gamblin .probe = ad7625_probe,
673b7ffd0faSTrevor Gamblin .driver = {
674b7ffd0faSTrevor Gamblin .name = "ad7625",
675b7ffd0faSTrevor Gamblin .of_match_table = ad7625_of_match,
676b7ffd0faSTrevor Gamblin },
677b7ffd0faSTrevor Gamblin .id_table = ad7625_device_ids,
678b7ffd0faSTrevor Gamblin };
679b7ffd0faSTrevor Gamblin module_platform_driver(ad7625_driver);
680b7ffd0faSTrevor Gamblin
681b7ffd0faSTrevor Gamblin MODULE_AUTHOR("Trevor Gamblin <tgamblin@baylibre.com>");
682b7ffd0faSTrevor Gamblin MODULE_DESCRIPTION("Analog Devices AD7625 ADC");
683b7ffd0faSTrevor Gamblin MODULE_LICENSE("Dual BSD/GPL");
684*cdd30ebbSPeter Zijlstra MODULE_IMPORT_NS("IIO_BACKEND");
685