1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * ad2s1210.c support for the ADI Resolver to Digital Converters: AD2S1210 |
4 | * |
5 | * Copyright (c) 2010-2010 Analog Devices Inc. |
6 | * Copyright (c) 2023 BayLibre, SAS |
7 | * |
8 | * Device register to IIO ABI mapping: |
9 | * |
10 | * Register | Addr | IIO ABI (sysfs) |
11 | * ----------------------------|------|------------------------------------------- |
12 | * DOS Overrange Threshold | 0x89 | events/in_altvoltage0_thresh_rising_value |
13 | * DOS Mismatch Threshold | 0x8A | events/in_altvoltage0_mag_rising_value |
14 | * DOS Reset Maximum Threshold | 0x8B | events/in_altvoltage0_mag_rising_reset_max |
15 | * DOS Reset Minimum Threshold | 0x8C | events/in_altvoltage0_mag_rising_reset_min |
16 | * LOT High Threshold | 0x8D | events/in_angl1_thresh_rising_value |
17 | * LOT Low Threshold [1] | 0x8E | events/in_angl1_thresh_rising_hysteresis |
18 | * Excitation Frequency | 0x91 | out_altvoltage0_frequency |
19 | * Control | 0x92 | *as bit fields* |
20 | * Phase lock range | D5 | events/in_phase0_mag_rising_value |
21 | * Hysteresis | D4 | in_angl0_hysteresis |
22 | * Encoder resolution | D3:2 | *not implemented* |
23 | * Resolution | D1:0 | *device tree: assigned-resolution-bits* |
24 | * Soft Reset | 0xF0 | [2] |
25 | * Fault | 0xFF | *not implemented* |
26 | * |
27 | * [1]: The value written to the LOT low register is high value minus the |
28 | * hysteresis. |
29 | * [2]: Soft reset is performed when `out_altvoltage0_frequency` is written. |
30 | * |
31 | * Fault to event mapping: |
32 | * |
33 | * Fault | | Channel | Type | Direction |
34 | * ----------------------------------------|----|--------------------------------- |
35 | * Sine/cosine inputs clipped [3] | D7 | altvoltage1 | mag | either |
36 | * Sine/cosine inputs below LOS | D6 | altvoltage0 | thresh | falling |
37 | * Sine/cosine inputs exceed DOS overrange | D5 | altvoltage0 | thresh | rising |
38 | * Sine/cosine inputs exceed DOS mismatch | D4 | altvoltage0 | mag | rising |
39 | * Tracking error exceeds LOT | D3 | angl1 | thresh | rising |
40 | * Velocity exceeds maximum tracking rate | D2 | anglvel0 | mag | rising |
41 | * Phase error exceeds phase lock range | D1 | phase0 | mag | rising |
42 | * Configuration parity error | D0 | *writes to kernel log* |
43 | * |
44 | * [3]: The chip does not differentiate between fault on sine vs. cosine so |
45 | * there will also be an event on the altvoltage2 channel. |
46 | */ |
47 | |
48 | #include <linux/bitfield.h> |
49 | #include <linux/bits.h> |
50 | #include <linux/cleanup.h> |
51 | #include <linux/clk.h> |
52 | #include <linux/delay.h> |
53 | #include <linux/device.h> |
54 | #include <linux/gpio/consumer.h> |
55 | #include <linux/module.h> |
56 | #include <linux/mutex.h> |
57 | #include <linux/regmap.h> |
58 | #include <linux/slab.h> |
59 | #include <linux/spi/spi.h> |
60 | #include <linux/sysfs.h> |
61 | #include <linux/types.h> |
62 | |
63 | #include <linux/iio/buffer.h> |
64 | #include <linux/iio/events.h> |
65 | #include <linux/iio/iio.h> |
66 | #include <linux/iio/sysfs.h> |
67 | #include <linux/iio/trigger_consumer.h> |
68 | #include <linux/iio/triggered_buffer.h> |
69 | |
70 | /* control register flags */ |
71 | #define AD2S1210_ADDRESS_DATA BIT(7) |
72 | #define AD2S1210_PHASE_LOCK_RANGE_44 BIT(5) |
73 | #define AD2S1210_ENABLE_HYSTERESIS BIT(4) |
74 | #define AD2S1210_SET_ENRES GENMASK(3, 2) |
75 | #define AD2S1210_SET_RES GENMASK(1, 0) |
76 | |
77 | /* fault register flags */ |
78 | #define AD2S1210_FAULT_CLIP BIT(7) |
79 | #define AD2S1210_FAULT_LOS BIT(6) |
80 | #define AD2S1210_FAULT_DOS_OVR BIT(5) |
81 | #define AD2S1210_FAULT_DOS_MIS BIT(4) |
82 | #define AD2S1210_FAULT_LOT BIT(3) |
83 | #define AD2S1210_FAULT_VELOCITY BIT(2) |
84 | #define AD2S1210_FAULT_PHASE BIT(1) |
85 | #define AD2S1210_FAULT_CONFIG_PARITY BIT(0) |
86 | |
87 | #define AD2S1210_REG_POSITION_MSB 0x80 |
88 | #define AD2S1210_REG_POSITION_LSB 0x81 |
89 | #define AD2S1210_REG_VELOCITY_MSB 0x82 |
90 | #define AD2S1210_REG_VELOCITY_LSB 0x83 |
91 | #define AD2S1210_REG_LOS_THRD 0x88 |
92 | #define AD2S1210_REG_DOS_OVR_THRD 0x89 |
93 | #define AD2S1210_REG_DOS_MIS_THRD 0x8A |
94 | #define AD2S1210_REG_DOS_RST_MAX_THRD 0x8B |
95 | #define AD2S1210_REG_DOS_RST_MIN_THRD 0x8C |
96 | #define AD2S1210_REG_LOT_HIGH_THRD 0x8D |
97 | #define AD2S1210_REG_LOT_LOW_THRD 0x8E |
98 | #define AD2S1210_REG_EXCIT_FREQ 0x91 |
99 | #define AD2S1210_REG_CONTROL 0x92 |
100 | #define AD2S1210_REG_SOFT_RESET 0xF0 |
101 | #define AD2S1210_REG_FAULT 0xFF |
102 | |
103 | #define AD2S1210_MIN_CLKIN 6144000 |
104 | #define AD2S1210_MAX_CLKIN 10240000 |
105 | #define AD2S1210_MIN_EXCIT 2000 |
106 | #define AD2S1210_DEF_EXCIT 10000 |
107 | #define AD2S1210_MAX_EXCIT 20000 |
108 | #define AD2S1210_MIN_FCW 0x4 |
109 | #define AD2S1210_MAX_FCW 0x50 |
110 | |
111 | /* 44 degrees ~= 0.767945 radians */ |
112 | #define PHASE_44_DEG_TO_RAD_INT 0 |
113 | #define PHASE_44_DEG_TO_RAD_MICRO 767945 |
114 | /* 360 degrees ~= 6.283185 radians */ |
115 | #define PHASE_360_DEG_TO_RAD_INT 6 |
116 | #define PHASE_360_DEG_TO_RAD_MICRO 283185 |
117 | |
118 | /* Threshold voltage registers have 1 LSB == 38 mV */ |
119 | #define THRESHOLD_MILLIVOLT_PER_LSB 38 |
120 | /* max voltage for threshold registers is 0x7F * 38 mV */ |
121 | #define THRESHOLD_RANGE_STR "[0 38 4826]" |
122 | |
123 | #define FAULT_ONESHOT(bit, new, old) (new & bit && !(old & bit)) |
124 | |
125 | enum ad2s1210_mode { |
126 | MOD_POS = 0b00, |
127 | MOD_VEL = 0b01, |
128 | MOD_RESERVED = 0b10, |
129 | MOD_CONFIG = 0b11, |
130 | }; |
131 | |
132 | enum ad2s1210_resolution { |
133 | AD2S1210_RES_10 = 0b00, |
134 | AD2S1210_RES_12 = 0b01, |
135 | AD2S1210_RES_14 = 0b10, |
136 | AD2S1210_RES_16 = 0b11, |
137 | }; |
138 | |
139 | struct ad2s1210_state { |
140 | struct mutex lock; |
141 | struct spi_device *sdev; |
142 | /** GPIO pin connected to SAMPLE line. */ |
143 | struct gpio_desc *sample_gpio; |
144 | /** GPIO pins connected to A0 and A1 lines (optional). */ |
145 | struct gpio_descs *mode_gpios; |
146 | /** Used to access config registers. */ |
147 | struct regmap *regmap; |
148 | /** The external oscillator frequency in Hz. */ |
149 | unsigned long clkin_hz; |
150 | /** Available raw hysteresis values based on resolution. */ |
151 | int hysteresis_available[2]; |
152 | /* adi,fixed-mode property - only valid when mode_gpios == NULL. */ |
153 | enum ad2s1210_mode fixed_mode; |
154 | /** The selected resolution */ |
155 | enum ad2s1210_resolution resolution; |
156 | /** Copy of fault register from the previous read. */ |
157 | u8 prev_fault_flags; |
158 | /** For reading raw sample value via SPI. */ |
159 | struct { |
160 | __be16 raw; |
161 | u8 fault; |
162 | } sample __aligned(IIO_DMA_MINALIGN); |
163 | /** Scan buffer */ |
164 | struct { |
165 | __be16 chan[2]; |
166 | /* Ensure timestamp is naturally aligned. */ |
167 | s64 timestamp __aligned(8); |
168 | } scan; |
169 | /** SPI transmit buffer. */ |
170 | u8 rx[2]; |
171 | /** SPI receive buffer. */ |
172 | u8 tx[2]; |
173 | }; |
174 | |
175 | static int ad2s1210_set_mode(struct ad2s1210_state *st, enum ad2s1210_mode mode) |
176 | { |
177 | struct gpio_descs *gpios = st->mode_gpios; |
178 | DECLARE_BITMAP(bitmap, 2); |
179 | |
180 | if (!gpios) |
181 | return mode == st->fixed_mode ? 0 : -EOPNOTSUPP; |
182 | |
183 | bitmap[0] = mode; |
184 | |
185 | return gpiod_set_array_value(array_size: gpios->ndescs, desc_array: gpios->desc, array_info: gpios->info, |
186 | value_bitmap: bitmap); |
187 | } |
188 | |
189 | /* |
190 | * Writes the given data to the given register address. |
191 | * |
192 | * If the mode is configurable, the device will first be placed in |
193 | * configuration mode. |
194 | */ |
195 | static int ad2s1210_regmap_reg_write(void *context, unsigned int reg, |
196 | unsigned int val) |
197 | { |
198 | struct ad2s1210_state *st = context; |
199 | struct spi_transfer xfers[] = { |
200 | { |
201 | .len = 1, |
202 | .rx_buf = &st->rx[0], |
203 | .tx_buf = &st->tx[0], |
204 | .cs_change = 1, |
205 | }, { |
206 | .len = 1, |
207 | .rx_buf = &st->rx[1], |
208 | .tx_buf = &st->tx[1], |
209 | }, |
210 | }; |
211 | int ret; |
212 | |
213 | /* values can only be 7 bits, the MSB indicates an address */ |
214 | if (val & ~0x7F) |
215 | return -EINVAL; |
216 | |
217 | st->tx[0] = reg; |
218 | st->tx[1] = val; |
219 | |
220 | ret = ad2s1210_set_mode(st, mode: MOD_CONFIG); |
221 | if (ret < 0) |
222 | return ret; |
223 | |
224 | ret = spi_sync_transfer(spi: st->sdev, xfers, ARRAY_SIZE(xfers)); |
225 | if (ret < 0) |
226 | return ret; |
227 | |
228 | /* soft reset also clears the fault register */ |
229 | if (reg == AD2S1210_REG_SOFT_RESET) |
230 | st->prev_fault_flags = 0; |
231 | |
232 | return 0; |
233 | } |
234 | |
235 | /* |
236 | * Reads value from one of the registers. |
237 | * |
238 | * If the mode is configurable, the device will first be placed in |
239 | * configuration mode. |
240 | */ |
241 | static int ad2s1210_regmap_reg_read(void *context, unsigned int reg, |
242 | unsigned int *val) |
243 | { |
244 | struct ad2s1210_state *st = context; |
245 | struct spi_transfer xfers[] = { |
246 | { |
247 | .len = 1, |
248 | .rx_buf = &st->rx[0], |
249 | .tx_buf = &st->tx[0], |
250 | .cs_change = 1, |
251 | }, { |
252 | .len = 1, |
253 | .rx_buf = &st->rx[1], |
254 | .tx_buf = &st->tx[1], |
255 | }, |
256 | }; |
257 | int ret; |
258 | |
259 | ret = ad2s1210_set_mode(st, mode: MOD_CONFIG); |
260 | if (ret < 0) |
261 | return ret; |
262 | |
263 | st->tx[0] = reg; |
264 | /* |
265 | * Must be valid register address here otherwise this could write data. |
266 | * It doesn't matter which one as long as reading doesn't have side- |
267 | * effects. |
268 | */ |
269 | st->tx[1] = AD2S1210_REG_CONTROL; |
270 | |
271 | ret = spi_sync_transfer(spi: st->sdev, xfers, ARRAY_SIZE(xfers)); |
272 | if (ret < 0) |
273 | return ret; |
274 | |
275 | /* reading the fault register also clears it */ |
276 | if (reg == AD2S1210_REG_FAULT) |
277 | st->prev_fault_flags = 0; |
278 | |
279 | /* |
280 | * If the D7 bit is set on any read/write register, it indicates a |
281 | * parity error. The fault register is read-only and the D7 bit means |
282 | * something else there. |
283 | */ |
284 | if ((reg > AD2S1210_REG_VELOCITY_LSB && reg != AD2S1210_REG_FAULT) |
285 | && st->rx[1] & AD2S1210_ADDRESS_DATA) |
286 | return -EBADMSG; |
287 | |
288 | *val = st->rx[1]; |
289 | |
290 | return 0; |
291 | } |
292 | |
293 | /* |
294 | * Toggles the SAMPLE line on the AD2S1210 to latch in the current position, |
295 | * velocity, and faults. |
296 | * |
297 | * Must be called with lock held. |
298 | */ |
299 | static void ad2s1210_toggle_sample_line(struct ad2s1210_state *st) |
300 | { |
301 | /* |
302 | * Datasheet specifies minimum hold time t16 = 2 * tck + 20 ns. So the |
303 | * longest time needed is when CLKIN is 6.144 MHz, in which case t16 |
304 | * ~= 350 ns. The same delay is also needed before re-asserting the |
305 | * SAMPLE line. |
306 | */ |
307 | gpiod_set_value(desc: st->sample_gpio, value: 1); |
308 | ndelay(350); |
309 | gpiod_set_value(desc: st->sample_gpio, value: 0); |
310 | ndelay(350); |
311 | } |
312 | |
313 | /* |
314 | * Sets the excitation frequency and performs software reset. |
315 | * |
316 | * Must be called with lock held. |
317 | */ |
318 | static int ad2s1210_reinit_excitation_frequency(struct ad2s1210_state *st, |
319 | u16 fexcit) |
320 | { |
321 | /* Map resolution to settle time in milliseconds. */ |
322 | static const int track_time_ms[] = { 10, 20, 25, 60 }; |
323 | unsigned int ignored; |
324 | int ret; |
325 | u8 fcw; |
326 | |
327 | fcw = fexcit * (1 << 15) / st->clkin_hz; |
328 | if (fcw < AD2S1210_MIN_FCW || fcw > AD2S1210_MAX_FCW) |
329 | return -ERANGE; |
330 | |
331 | ret = regmap_write(map: st->regmap, AD2S1210_REG_EXCIT_FREQ, val: fcw); |
332 | if (ret < 0) |
333 | return ret; |
334 | |
335 | /* |
336 | * Software reset reinitializes the excitation frequency output. |
337 | * It does not reset any of the configuration registers. |
338 | */ |
339 | ret = regmap_write(map: st->regmap, AD2S1210_REG_SOFT_RESET, val: 0); |
340 | if (ret < 0) |
341 | return ret; |
342 | |
343 | /* |
344 | * Soft reset always triggers some faults due the change in the output |
345 | * signal so clear the faults too. We need to delay for some time |
346 | * (what datasheet calls t[track]) to allow things to settle before |
347 | * clearing the faults. |
348 | */ |
349 | msleep(msecs: track_time_ms[st->resolution] * 8192000 / st->clkin_hz); |
350 | |
351 | /* Reading the fault register clears the faults. */ |
352 | ret = regmap_read(map: st->regmap, AD2S1210_REG_FAULT, val: &ignored); |
353 | if (ret < 0) |
354 | return ret; |
355 | |
356 | /* Have to toggle sample line to get fault output pins to reset. */ |
357 | ad2s1210_toggle_sample_line(st); |
358 | |
359 | return 0; |
360 | } |
361 | |
362 | static void ad2s1210_push_events(struct iio_dev *indio_dev, |
363 | u8 flags, s64 timestamp) |
364 | { |
365 | struct ad2s1210_state *st = iio_priv(indio_dev); |
366 | |
367 | /* Sine/cosine inputs clipped */ |
368 | if (FAULT_ONESHOT(AD2S1210_FAULT_CLIP, flags, st->prev_fault_flags)) { |
369 | /* |
370 | * The chip does not differentiate between fault on sine vs. |
371 | * cosine channel so we just send an event on both channels. |
372 | */ |
373 | iio_push_event(indio_dev, |
374 | IIO_UNMOD_EVENT_CODE(IIO_ALTVOLTAGE, 1, |
375 | IIO_EV_TYPE_MAG, |
376 | IIO_EV_DIR_EITHER), |
377 | timestamp); |
378 | iio_push_event(indio_dev, |
379 | IIO_UNMOD_EVENT_CODE(IIO_ALTVOLTAGE, 2, |
380 | IIO_EV_TYPE_MAG, |
381 | IIO_EV_DIR_EITHER), |
382 | timestamp); |
383 | } |
384 | |
385 | /* Sine/cosine inputs below LOS threshold */ |
386 | if (FAULT_ONESHOT(AD2S1210_FAULT_LOS, flags, st->prev_fault_flags)) |
387 | iio_push_event(indio_dev, |
388 | IIO_UNMOD_EVENT_CODE(IIO_ALTVOLTAGE, 0, |
389 | IIO_EV_TYPE_THRESH, |
390 | IIO_EV_DIR_FALLING), |
391 | timestamp); |
392 | |
393 | /* Sine/cosine inputs exceed DOS overrange threshold */ |
394 | if (FAULT_ONESHOT(AD2S1210_FAULT_DOS_OVR, flags, st->prev_fault_flags)) |
395 | iio_push_event(indio_dev, |
396 | IIO_UNMOD_EVENT_CODE(IIO_ALTVOLTAGE, 0, |
397 | IIO_EV_TYPE_THRESH, |
398 | IIO_EV_DIR_RISING), |
399 | timestamp); |
400 | |
401 | /* Sine/cosine inputs exceed DOS mismatch threshold */ |
402 | if (FAULT_ONESHOT(AD2S1210_FAULT_DOS_MIS, flags, st->prev_fault_flags)) |
403 | iio_push_event(indio_dev, |
404 | IIO_UNMOD_EVENT_CODE(IIO_ALTVOLTAGE, 0, |
405 | IIO_EV_TYPE_MAG, |
406 | IIO_EV_DIR_RISING), |
407 | timestamp); |
408 | |
409 | /* Tracking error exceeds LOT threshold */ |
410 | if (FAULT_ONESHOT(AD2S1210_FAULT_LOT, flags, st->prev_fault_flags)) |
411 | iio_push_event(indio_dev, |
412 | IIO_UNMOD_EVENT_CODE(IIO_ANGL, 1, |
413 | IIO_EV_TYPE_THRESH, |
414 | IIO_EV_DIR_RISING), |
415 | timestamp); |
416 | |
417 | /* Velocity exceeds maximum tracking rate */ |
418 | if (FAULT_ONESHOT(AD2S1210_FAULT_VELOCITY, flags, st->prev_fault_flags)) |
419 | iio_push_event(indio_dev, |
420 | IIO_UNMOD_EVENT_CODE(IIO_ANGL_VEL, 0, |
421 | IIO_EV_TYPE_THRESH, |
422 | IIO_EV_DIR_RISING), |
423 | timestamp); |
424 | |
425 | /* Phase error exceeds phase lock range */ |
426 | if (FAULT_ONESHOT(AD2S1210_FAULT_PHASE, flags, st->prev_fault_flags)) |
427 | iio_push_event(indio_dev, |
428 | IIO_UNMOD_EVENT_CODE(IIO_PHASE, 0, |
429 | IIO_EV_TYPE_MAG, |
430 | IIO_EV_DIR_RISING), |
431 | timestamp); |
432 | |
433 | /* Configuration parity error */ |
434 | if (FAULT_ONESHOT(AD2S1210_FAULT_CONFIG_PARITY, flags, |
435 | st->prev_fault_flags)) |
436 | /* |
437 | * Userspace should also get notified of this via error return |
438 | * when trying to write to any attribute that writes a register. |
439 | */ |
440 | dev_err_ratelimited(&indio_dev->dev, |
441 | "Configuration parity error\n" ); |
442 | |
443 | st->prev_fault_flags = flags; |
444 | } |
445 | |
446 | static int ad2s1210_single_conversion(struct iio_dev *indio_dev, |
447 | struct iio_chan_spec const *chan, |
448 | int *val) |
449 | { |
450 | struct ad2s1210_state *st = iio_priv(indio_dev); |
451 | s64 timestamp; |
452 | int ret; |
453 | |
454 | guard(mutex)(T: &st->lock); |
455 | |
456 | ad2s1210_toggle_sample_line(st); |
457 | timestamp = iio_get_time_ns(indio_dev); |
458 | |
459 | if (st->fixed_mode == MOD_CONFIG) { |
460 | unsigned int reg_val; |
461 | |
462 | switch (chan->type) { |
463 | case IIO_ANGL: |
464 | ret = regmap_bulk_read(map: st->regmap, |
465 | AD2S1210_REG_POSITION_MSB, |
466 | val: &st->sample.raw, val_count: 2); |
467 | if (ret < 0) |
468 | return ret; |
469 | |
470 | break; |
471 | case IIO_ANGL_VEL: |
472 | ret = regmap_bulk_read(map: st->regmap, |
473 | AD2S1210_REG_VELOCITY_MSB, |
474 | val: &st->sample.raw, val_count: 2); |
475 | if (ret < 0) |
476 | return ret; |
477 | |
478 | break; |
479 | default: |
480 | return -EINVAL; |
481 | } |
482 | |
483 | ret = regmap_read(map: st->regmap, AD2S1210_REG_FAULT, val: ®_val); |
484 | if (ret < 0) |
485 | return ret; |
486 | |
487 | st->sample.fault = reg_val; |
488 | } else { |
489 | switch (chan->type) { |
490 | case IIO_ANGL: |
491 | ret = ad2s1210_set_mode(st, mode: MOD_POS); |
492 | break; |
493 | case IIO_ANGL_VEL: |
494 | ret = ad2s1210_set_mode(st, mode: MOD_VEL); |
495 | break; |
496 | default: |
497 | return -EINVAL; |
498 | } |
499 | if (ret < 0) |
500 | return ret; |
501 | |
502 | ret = spi_read(spi: st->sdev, buf: &st->sample, len: 3); |
503 | if (ret < 0) |
504 | return ret; |
505 | } |
506 | |
507 | switch (chan->type) { |
508 | case IIO_ANGL: |
509 | *val = be16_to_cpu(st->sample.raw); |
510 | ret = IIO_VAL_INT; |
511 | break; |
512 | case IIO_ANGL_VEL: |
513 | *val = (s16)be16_to_cpu(st->sample.raw); |
514 | ret = IIO_VAL_INT; |
515 | break; |
516 | default: |
517 | return -EINVAL; |
518 | } |
519 | |
520 | ad2s1210_push_events(indio_dev, flags: st->sample.fault, timestamp); |
521 | |
522 | return ret; |
523 | } |
524 | |
525 | static int ad2s1210_get_hysteresis(struct ad2s1210_state *st, int *val) |
526 | { |
527 | int ret; |
528 | |
529 | guard(mutex)(T: &st->lock); |
530 | ret = regmap_test_bits(map: st->regmap, AD2S1210_REG_CONTROL, |
531 | AD2S1210_ENABLE_HYSTERESIS); |
532 | if (ret < 0) |
533 | return ret; |
534 | |
535 | *val = ret << (2 * (AD2S1210_RES_16 - st->resolution)); |
536 | return IIO_VAL_INT; |
537 | } |
538 | |
539 | static int ad2s1210_set_hysteresis(struct ad2s1210_state *st, int val) |
540 | { |
541 | guard(mutex)(T: &st->lock); |
542 | return regmap_update_bits(map: st->regmap, AD2S1210_REG_CONTROL, |
543 | AD2S1210_ENABLE_HYSTERESIS, |
544 | val: val ? AD2S1210_ENABLE_HYSTERESIS : 0); |
545 | } |
546 | |
547 | static int ad2s1210_get_phase_lock_range(struct ad2s1210_state *st, |
548 | int *val, int *val2) |
549 | { |
550 | int ret; |
551 | |
552 | guard(mutex)(T: &st->lock); |
553 | ret = regmap_test_bits(map: st->regmap, AD2S1210_REG_CONTROL, |
554 | AD2S1210_PHASE_LOCK_RANGE_44); |
555 | if (ret < 0) |
556 | return ret; |
557 | |
558 | if (ret) { |
559 | /* 44 degrees as radians */ |
560 | *val = PHASE_44_DEG_TO_RAD_INT; |
561 | *val2 = PHASE_44_DEG_TO_RAD_MICRO; |
562 | } else { |
563 | /* 360 degrees as radians */ |
564 | *val = PHASE_360_DEG_TO_RAD_INT; |
565 | *val2 = PHASE_360_DEG_TO_RAD_MICRO; |
566 | } |
567 | |
568 | return IIO_VAL_INT_PLUS_MICRO; |
569 | } |
570 | |
571 | static int ad2s1210_set_phase_lock_range(struct ad2s1210_state *st, |
572 | int val, int val2) |
573 | { |
574 | int deg; |
575 | |
576 | /* convert radians to degrees - only two allowable values */ |
577 | if (val == PHASE_44_DEG_TO_RAD_INT && val2 == PHASE_44_DEG_TO_RAD_MICRO) |
578 | deg = 44; |
579 | else if (val == PHASE_360_DEG_TO_RAD_INT && |
580 | val2 == PHASE_360_DEG_TO_RAD_MICRO) |
581 | deg = 360; |
582 | else |
583 | return -EINVAL; |
584 | |
585 | guard(mutex)(T: &st->lock); |
586 | return regmap_update_bits(map: st->regmap, AD2S1210_REG_CONTROL, |
587 | AD2S1210_PHASE_LOCK_RANGE_44, |
588 | val: deg == 44 ? AD2S1210_PHASE_LOCK_RANGE_44 : 0); |
589 | } |
590 | |
591 | /* map resolution to microradians/LSB for LOT registers */ |
592 | static const int ad2s1210_lot_threshold_urad_per_lsb[] = { |
593 | 6184, /* 10-bit: ~0.35 deg/LSB, 45 deg max */ |
594 | 2473, /* 12-bit: ~0.14 deg/LSB, 18 deg max */ |
595 | 1237, /* 14-bit: ~0.07 deg/LSB, 9 deg max */ |
596 | 1237, /* 16-bit: same as 14-bit */ |
597 | }; |
598 | |
599 | static int ad2s1210_get_voltage_threshold(struct ad2s1210_state *st, |
600 | unsigned int reg, int *val) |
601 | { |
602 | unsigned int reg_val; |
603 | int ret; |
604 | |
605 | guard(mutex)(T: &st->lock); |
606 | ret = regmap_read(map: st->regmap, reg, val: ®_val); |
607 | if (ret < 0) |
608 | return ret; |
609 | |
610 | *val = reg_val * THRESHOLD_MILLIVOLT_PER_LSB; |
611 | return IIO_VAL_INT; |
612 | } |
613 | |
614 | static int ad2s1210_set_voltage_threshold(struct ad2s1210_state *st, |
615 | unsigned int reg, int val) |
616 | { |
617 | unsigned int reg_val; |
618 | |
619 | reg_val = val / THRESHOLD_MILLIVOLT_PER_LSB; |
620 | |
621 | guard(mutex)(T: &st->lock); |
622 | return regmap_write(map: st->regmap, reg, val: reg_val); |
623 | } |
624 | |
625 | static int ad2s1210_get_lot_high_threshold(struct ad2s1210_state *st, |
626 | int *val, int *val2) |
627 | { |
628 | unsigned int reg_val; |
629 | int ret; |
630 | |
631 | guard(mutex)(T: &st->lock); |
632 | ret = regmap_read(map: st->regmap, AD2S1210_REG_LOT_HIGH_THRD, val: ®_val); |
633 | if (ret < 0) |
634 | return ret; |
635 | |
636 | *val = 0; |
637 | *val2 = reg_val * ad2s1210_lot_threshold_urad_per_lsb[st->resolution]; |
638 | return IIO_VAL_INT_PLUS_MICRO; |
639 | } |
640 | |
641 | static int ad2s1210_set_lot_high_threshold(struct ad2s1210_state *st, |
642 | int val, int val2) |
643 | { |
644 | unsigned int high_reg_val, low_reg_val, hysteresis; |
645 | int ret; |
646 | |
647 | /* all valid values are between 0 and pi/4 radians */ |
648 | if (val != 0) |
649 | return -EINVAL; |
650 | |
651 | guard(mutex)(T: &st->lock); |
652 | /* |
653 | * We need to read both high and low registers first so we can preserve |
654 | * the hysteresis. |
655 | */ |
656 | ret = regmap_read(map: st->regmap, AD2S1210_REG_LOT_HIGH_THRD, val: &high_reg_val); |
657 | if (ret < 0) |
658 | return ret; |
659 | |
660 | ret = regmap_read(map: st->regmap, AD2S1210_REG_LOT_LOW_THRD, val: &low_reg_val); |
661 | if (ret < 0) |
662 | return ret; |
663 | |
664 | hysteresis = high_reg_val - low_reg_val; |
665 | high_reg_val = val2 / ad2s1210_lot_threshold_urad_per_lsb[st->resolution]; |
666 | low_reg_val = high_reg_val - hysteresis; |
667 | |
668 | ret = regmap_write(map: st->regmap, AD2S1210_REG_LOT_HIGH_THRD, val: high_reg_val); |
669 | if (ret < 0) |
670 | return ret; |
671 | |
672 | return regmap_write(map: st->regmap, AD2S1210_REG_LOT_LOW_THRD, val: low_reg_val); |
673 | } |
674 | |
675 | static int ad2s1210_get_lot_low_threshold(struct ad2s1210_state *st, |
676 | int *val, int *val2) |
677 | { |
678 | unsigned int high_reg_val, low_reg_val; |
679 | int ret; |
680 | |
681 | guard(mutex)(T: &st->lock); |
682 | |
683 | ret = regmap_read(map: st->regmap, AD2S1210_REG_LOT_HIGH_THRD, val: &high_reg_val); |
684 | if (ret < 0) |
685 | return ret; |
686 | |
687 | ret = regmap_read(map: st->regmap, AD2S1210_REG_LOT_LOW_THRD, val: &low_reg_val); |
688 | if (ret < 0) |
689 | return ret; |
690 | |
691 | /* sysfs value is hysteresis rather than actual low value */ |
692 | *val = 0; |
693 | *val2 = (high_reg_val - low_reg_val) * |
694 | ad2s1210_lot_threshold_urad_per_lsb[st->resolution]; |
695 | return IIO_VAL_INT_PLUS_MICRO; |
696 | } |
697 | |
698 | static int ad2s1210_set_lot_low_threshold(struct ad2s1210_state *st, |
699 | int val, int val2) |
700 | { |
701 | unsigned int reg_val, hysteresis; |
702 | int ret; |
703 | |
704 | /* all valid values are between 0 and pi/4 radians */ |
705 | if (val != 0) |
706 | return -EINVAL; |
707 | |
708 | hysteresis = val2 / ad2s1210_lot_threshold_urad_per_lsb[st->resolution]; |
709 | |
710 | guard(mutex)(T: &st->lock); |
711 | |
712 | ret = regmap_read(map: st->regmap, AD2S1210_REG_LOT_HIGH_THRD, val: ®_val); |
713 | if (ret < 0) |
714 | return ret; |
715 | |
716 | return regmap_write(map: st->regmap, AD2S1210_REG_LOT_LOW_THRD, |
717 | val: reg_val - hysteresis); |
718 | } |
719 | |
720 | static int ad2s1210_get_excitation_frequency(struct ad2s1210_state *st, int *val) |
721 | { |
722 | unsigned int reg_val; |
723 | int ret; |
724 | |
725 | guard(mutex)(T: &st->lock); |
726 | |
727 | ret = regmap_read(map: st->regmap, AD2S1210_REG_EXCIT_FREQ, val: ®_val); |
728 | if (ret < 0) |
729 | return ret; |
730 | |
731 | *val = reg_val * st->clkin_hz / (1 << 15); |
732 | return IIO_VAL_INT; |
733 | } |
734 | |
735 | static int ad2s1210_set_excitation_frequency(struct ad2s1210_state *st, int val) |
736 | { |
737 | if (val < AD2S1210_MIN_EXCIT || val > AD2S1210_MAX_EXCIT) |
738 | return -EINVAL; |
739 | |
740 | guard(mutex)(T: &st->lock); |
741 | return ad2s1210_reinit_excitation_frequency(st, fexcit: val); |
742 | } |
743 | |
744 | static const int ad2s1210_velocity_scale[] = { |
745 | 17089132, /* 8.192MHz / (2*pi * 2500 / 2^15) */ |
746 | 42722830, /* 8.192MHz / (2*pi * 1000 / 2^15) */ |
747 | 85445659, /* 8.192MHz / (2*pi * 500 / 2^15) */ |
748 | 341782638, /* 8.192MHz / (2*pi * 125 / 2^15) */ |
749 | }; |
750 | |
751 | static int ad2s1210_read_raw(struct iio_dev *indio_dev, |
752 | struct iio_chan_spec const *chan, |
753 | int *val, |
754 | int *val2, |
755 | long mask) |
756 | { |
757 | struct ad2s1210_state *st = iio_priv(indio_dev); |
758 | |
759 | switch (mask) { |
760 | case IIO_CHAN_INFO_RAW: |
761 | return ad2s1210_single_conversion(indio_dev, chan, val); |
762 | case IIO_CHAN_INFO_SCALE: |
763 | switch (chan->type) { |
764 | case IIO_ANGL: |
765 | /* approx 0.3 arc min converted to radians */ |
766 | *val = 0; |
767 | *val2 = 95874; |
768 | return IIO_VAL_INT_PLUS_NANO; |
769 | case IIO_ANGL_VEL: |
770 | *val = st->clkin_hz; |
771 | *val2 = ad2s1210_velocity_scale[st->resolution]; |
772 | return IIO_VAL_FRACTIONAL; |
773 | default: |
774 | return -EINVAL; |
775 | } |
776 | case IIO_CHAN_INFO_FREQUENCY: |
777 | switch (chan->type) { |
778 | case IIO_ALTVOLTAGE: |
779 | return ad2s1210_get_excitation_frequency(st, val); |
780 | default: |
781 | return -EINVAL; |
782 | } |
783 | case IIO_CHAN_INFO_HYSTERESIS: |
784 | switch (chan->type) { |
785 | case IIO_ANGL: |
786 | return ad2s1210_get_hysteresis(st, val); |
787 | default: |
788 | return -EINVAL; |
789 | } |
790 | default: |
791 | return -EINVAL; |
792 | } |
793 | } |
794 | |
795 | static int ad2s1210_read_avail(struct iio_dev *indio_dev, |
796 | struct iio_chan_spec const *chan, |
797 | const int **vals, int *type, |
798 | int *length, long mask) |
799 | { |
800 | static const int excitation_frequency_available[] = { |
801 | AD2S1210_MIN_EXCIT, |
802 | 250, /* step */ |
803 | AD2S1210_MAX_EXCIT, |
804 | }; |
805 | |
806 | struct ad2s1210_state *st = iio_priv(indio_dev); |
807 | |
808 | switch (mask) { |
809 | case IIO_CHAN_INFO_FREQUENCY: |
810 | switch (chan->type) { |
811 | case IIO_ALTVOLTAGE: |
812 | *type = IIO_VAL_INT; |
813 | *vals = excitation_frequency_available; |
814 | return IIO_AVAIL_RANGE; |
815 | default: |
816 | return -EINVAL; |
817 | } |
818 | case IIO_CHAN_INFO_HYSTERESIS: |
819 | switch (chan->type) { |
820 | case IIO_ANGL: |
821 | *vals = st->hysteresis_available; |
822 | *type = IIO_VAL_INT; |
823 | *length = ARRAY_SIZE(st->hysteresis_available); |
824 | return IIO_AVAIL_LIST; |
825 | default: |
826 | return -EINVAL; |
827 | } |
828 | default: |
829 | return -EINVAL; |
830 | } |
831 | } |
832 | |
833 | static int ad2s1210_write_raw(struct iio_dev *indio_dev, |
834 | struct iio_chan_spec const *chan, |
835 | int val, int val2, long mask) |
836 | { |
837 | struct ad2s1210_state *st = iio_priv(indio_dev); |
838 | |
839 | switch (mask) { |
840 | case IIO_CHAN_INFO_FREQUENCY: |
841 | switch (chan->type) { |
842 | case IIO_ALTVOLTAGE: |
843 | return ad2s1210_set_excitation_frequency(st, val); |
844 | default: |
845 | return -EINVAL; |
846 | } |
847 | case IIO_CHAN_INFO_HYSTERESIS: |
848 | switch (chan->type) { |
849 | case IIO_ANGL: |
850 | return ad2s1210_set_hysteresis(st, val); |
851 | default: |
852 | return -EINVAL; |
853 | } |
854 | default: |
855 | return -EINVAL; |
856 | } |
857 | } |
858 | |
859 | static const struct iio_event_spec ad2s1210_position_event_spec[] = { |
860 | { |
861 | /* Tracking error exceeds LOT threshold fault. */ |
862 | .type = IIO_EV_TYPE_THRESH, |
863 | .dir = IIO_EV_DIR_RISING, |
864 | .mask_separate = |
865 | /* Loss of tracking high threshold. */ |
866 | BIT(IIO_EV_INFO_VALUE) | |
867 | /* Loss of tracking low threshold. */ |
868 | BIT(IIO_EV_INFO_HYSTERESIS), |
869 | }, |
870 | }; |
871 | |
872 | static const struct iio_event_spec ad2s1210_velocity_event_spec[] = { |
873 | { |
874 | /* Velocity exceeds maximum tracking rate fault. */ |
875 | .type = IIO_EV_TYPE_MAG, |
876 | .dir = IIO_EV_DIR_RISING, |
877 | }, |
878 | }; |
879 | |
880 | static const struct iio_event_spec ad2s1210_phase_event_spec[] = { |
881 | { |
882 | /* Phase error fault. */ |
883 | .type = IIO_EV_TYPE_MAG, |
884 | .dir = IIO_EV_DIR_RISING, |
885 | /* Phase lock range. */ |
886 | .mask_separate = BIT(IIO_EV_INFO_VALUE), |
887 | }, |
888 | }; |
889 | |
890 | static const struct iio_event_spec ad2s1210_monitor_signal_event_spec[] = { |
891 | { |
892 | /* Sine/cosine below LOS threshold fault. */ |
893 | .type = IIO_EV_TYPE_THRESH, |
894 | .dir = IIO_EV_DIR_FALLING, |
895 | /* Loss of signal threshold. */ |
896 | .mask_separate = BIT(IIO_EV_INFO_VALUE), |
897 | }, |
898 | { |
899 | /* Sine/cosine DOS overrange fault.*/ |
900 | .type = IIO_EV_TYPE_THRESH, |
901 | .dir = IIO_EV_DIR_RISING, |
902 | /* Degredation of signal overrange threshold. */ |
903 | .mask_separate = BIT(IIO_EV_INFO_VALUE), |
904 | }, |
905 | { |
906 | /* Sine/cosine DOS mismatch fault.*/ |
907 | .type = IIO_EV_TYPE_MAG, |
908 | .dir = IIO_EV_DIR_RISING, |
909 | .mask_separate = BIT(IIO_EV_INFO_VALUE), |
910 | }, |
911 | }; |
912 | |
913 | static const struct iio_event_spec ad2s1210_sin_cos_event_spec[] = { |
914 | { |
915 | /* Sine/cosine clipping fault. */ |
916 | .type = IIO_EV_TYPE_MAG, |
917 | .dir = IIO_EV_DIR_EITHER, |
918 | }, |
919 | }; |
920 | |
921 | static const struct iio_chan_spec ad2s1210_channels[] = { |
922 | { |
923 | .type = IIO_ANGL, |
924 | .indexed = 1, |
925 | .channel = 0, |
926 | .scan_index = 0, |
927 | .scan_type = { |
928 | .sign = 'u', |
929 | .realbits = 16, |
930 | .storagebits = 16, |
931 | .endianness = IIO_BE, |
932 | }, |
933 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | |
934 | BIT(IIO_CHAN_INFO_SCALE) | |
935 | BIT(IIO_CHAN_INFO_HYSTERESIS), |
936 | .info_mask_separate_available = |
937 | BIT(IIO_CHAN_INFO_HYSTERESIS), |
938 | }, { |
939 | .type = IIO_ANGL_VEL, |
940 | .indexed = 1, |
941 | .channel = 0, |
942 | .scan_index = 1, |
943 | .scan_type = { |
944 | .sign = 's', |
945 | .realbits = 16, |
946 | .storagebits = 16, |
947 | .endianness = IIO_BE, |
948 | }, |
949 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | |
950 | BIT(IIO_CHAN_INFO_SCALE), |
951 | .event_spec = ad2s1210_velocity_event_spec, |
952 | .num_event_specs = ARRAY_SIZE(ad2s1210_velocity_event_spec), |
953 | }, |
954 | IIO_CHAN_SOFT_TIMESTAMP(2), |
955 | { |
956 | /* used to configure LOT thresholds and get tracking error */ |
957 | .type = IIO_ANGL, |
958 | .indexed = 1, |
959 | .channel = 1, |
960 | .scan_index = -1, |
961 | .event_spec = ad2s1210_position_event_spec, |
962 | .num_event_specs = ARRAY_SIZE(ad2s1210_position_event_spec), |
963 | }, |
964 | { |
965 | /* used to configure phase lock range and get phase lock error */ |
966 | .type = IIO_PHASE, |
967 | .indexed = 1, |
968 | .channel = 0, |
969 | .scan_index = -1, |
970 | .event_spec = ad2s1210_phase_event_spec, |
971 | .num_event_specs = ARRAY_SIZE(ad2s1210_phase_event_spec), |
972 | }, { |
973 | /* excitation frequency output */ |
974 | .type = IIO_ALTVOLTAGE, |
975 | .indexed = 1, |
976 | .channel = 0, |
977 | .output = 1, |
978 | .scan_index = -1, |
979 | .info_mask_separate = BIT(IIO_CHAN_INFO_FREQUENCY), |
980 | .info_mask_separate_available = BIT(IIO_CHAN_INFO_FREQUENCY), |
981 | }, { |
982 | /* monitor signal */ |
983 | .type = IIO_ALTVOLTAGE, |
984 | .indexed = 1, |
985 | .channel = 0, |
986 | .scan_index = -1, |
987 | .event_spec = ad2s1210_monitor_signal_event_spec, |
988 | .num_event_specs = ARRAY_SIZE(ad2s1210_monitor_signal_event_spec), |
989 | }, { |
990 | /* sine input */ |
991 | .type = IIO_ALTVOLTAGE, |
992 | .indexed = 1, |
993 | .channel = 1, |
994 | .scan_index = -1, |
995 | .event_spec = ad2s1210_sin_cos_event_spec, |
996 | .num_event_specs = ARRAY_SIZE(ad2s1210_sin_cos_event_spec), |
997 | }, { |
998 | /* cosine input */ |
999 | .type = IIO_ALTVOLTAGE, |
1000 | .indexed = 1, |
1001 | .channel = 2, |
1002 | .scan_index = -1, |
1003 | .event_spec = ad2s1210_sin_cos_event_spec, |
1004 | .num_event_specs = ARRAY_SIZE(ad2s1210_sin_cos_event_spec), |
1005 | }, |
1006 | }; |
1007 | |
1008 | static ssize_t event_attr_voltage_reg_show(struct device *dev, |
1009 | struct device_attribute *attr, |
1010 | char *buf) |
1011 | { |
1012 | struct ad2s1210_state *st = iio_priv(indio_dev: dev_to_iio_dev(dev)); |
1013 | struct iio_dev_attr *iattr = to_iio_dev_attr(attr); |
1014 | unsigned int value; |
1015 | int ret; |
1016 | |
1017 | guard(mutex)(T: &st->lock); |
1018 | ret = regmap_read(map: st->regmap, reg: iattr->address, val: &value); |
1019 | if (ret < 0) |
1020 | return ret; |
1021 | |
1022 | return sprintf(buf, fmt: "%d\n" , value * THRESHOLD_MILLIVOLT_PER_LSB); |
1023 | } |
1024 | |
1025 | static ssize_t event_attr_voltage_reg_store(struct device *dev, |
1026 | struct device_attribute *attr, |
1027 | const char *buf, size_t len) |
1028 | { |
1029 | struct ad2s1210_state *st = iio_priv(indio_dev: dev_to_iio_dev(dev)); |
1030 | struct iio_dev_attr *iattr = to_iio_dev_attr(attr); |
1031 | u16 data; |
1032 | int ret; |
1033 | |
1034 | ret = kstrtou16(s: buf, base: 10, res: &data); |
1035 | if (ret) |
1036 | return -EINVAL; |
1037 | |
1038 | guard(mutex)(T: &st->lock); |
1039 | ret = regmap_write(map: st->regmap, reg: iattr->address, |
1040 | val: data / THRESHOLD_MILLIVOLT_PER_LSB); |
1041 | if (ret < 0) |
1042 | return ret; |
1043 | |
1044 | return len; |
1045 | } |
1046 | |
1047 | static ssize_t |
1048 | in_angl1_thresh_rising_value_available_show(struct device *dev, |
1049 | struct device_attribute *attr, |
1050 | char *buf) |
1051 | { |
1052 | struct ad2s1210_state *st = iio_priv(indio_dev: dev_to_iio_dev(dev)); |
1053 | int step = ad2s1210_lot_threshold_urad_per_lsb[st->resolution]; |
1054 | |
1055 | return sysfs_emit(buf, fmt: "[0 0.%06d 0.%06d]\n" , step, step * 0x7F); |
1056 | } |
1057 | |
1058 | static ssize_t |
1059 | in_angl1_thresh_rising_hysteresis_available_show(struct device *dev, |
1060 | struct device_attribute *attr, |
1061 | char *buf) |
1062 | { |
1063 | struct ad2s1210_state *st = iio_priv(indio_dev: dev_to_iio_dev(dev)); |
1064 | int step = ad2s1210_lot_threshold_urad_per_lsb[st->resolution]; |
1065 | |
1066 | return sysfs_emit(buf, fmt: "[0 0.%06d 0.%06d]\n" , step, step * 0x7F); |
1067 | } |
1068 | |
1069 | static IIO_CONST_ATTR(in_phase0_mag_rising_value_available, |
1070 | __stringify(PHASE_44_DEG_TO_RAD_INT) "." |
1071 | __stringify(PHASE_44_DEG_TO_RAD_MICRO) " " |
1072 | __stringify(PHASE_360_DEG_TO_RAD_INT) "." |
1073 | __stringify(PHASE_360_DEG_TO_RAD_MICRO)); |
1074 | static IIO_CONST_ATTR(in_altvoltage0_thresh_falling_value_available, |
1075 | THRESHOLD_RANGE_STR); |
1076 | static IIO_CONST_ATTR(in_altvoltage0_thresh_rising_value_available, |
1077 | THRESHOLD_RANGE_STR); |
1078 | static IIO_CONST_ATTR(in_altvoltage0_mag_rising_value_available, |
1079 | THRESHOLD_RANGE_STR); |
1080 | static IIO_DEVICE_ATTR(in_altvoltage0_mag_rising_reset_max, 0644, |
1081 | event_attr_voltage_reg_show, event_attr_voltage_reg_store, |
1082 | AD2S1210_REG_DOS_RST_MAX_THRD); |
1083 | static IIO_CONST_ATTR(in_altvoltage0_mag_rising_reset_max_available, THRESHOLD_RANGE_STR); |
1084 | static IIO_DEVICE_ATTR(in_altvoltage0_mag_rising_reset_min, 0644, |
1085 | event_attr_voltage_reg_show, event_attr_voltage_reg_store, |
1086 | AD2S1210_REG_DOS_RST_MIN_THRD); |
1087 | static IIO_CONST_ATTR(in_altvoltage0_mag_rising_reset_min_available, THRESHOLD_RANGE_STR); |
1088 | static IIO_DEVICE_ATTR_RO(in_angl1_thresh_rising_value_available, 0); |
1089 | static IIO_DEVICE_ATTR_RO(in_angl1_thresh_rising_hysteresis_available, 0); |
1090 | |
1091 | static struct attribute *ad2s1210_event_attributes[] = { |
1092 | &iio_const_attr_in_phase0_mag_rising_value_available.dev_attr.attr, |
1093 | &iio_const_attr_in_altvoltage0_thresh_falling_value_available.dev_attr.attr, |
1094 | &iio_const_attr_in_altvoltage0_thresh_rising_value_available.dev_attr.attr, |
1095 | &iio_const_attr_in_altvoltage0_mag_rising_value_available.dev_attr.attr, |
1096 | &iio_dev_attr_in_altvoltage0_mag_rising_reset_max.dev_attr.attr, |
1097 | &iio_const_attr_in_altvoltage0_mag_rising_reset_max_available.dev_attr.attr, |
1098 | &iio_dev_attr_in_altvoltage0_mag_rising_reset_min.dev_attr.attr, |
1099 | &iio_const_attr_in_altvoltage0_mag_rising_reset_min_available.dev_attr.attr, |
1100 | &iio_dev_attr_in_angl1_thresh_rising_value_available.dev_attr.attr, |
1101 | &iio_dev_attr_in_angl1_thresh_rising_hysteresis_available.dev_attr.attr, |
1102 | NULL, |
1103 | }; |
1104 | |
1105 | static const struct attribute_group ad2s1210_event_attribute_group = { |
1106 | .attrs = ad2s1210_event_attributes, |
1107 | }; |
1108 | |
1109 | static int ad2s1210_initial(struct ad2s1210_state *st) |
1110 | { |
1111 | unsigned int data; |
1112 | int ret; |
1113 | |
1114 | guard(mutex)(T: &st->lock); |
1115 | |
1116 | /* Use default config register value plus resolution from devicetree. */ |
1117 | data = FIELD_PREP(AD2S1210_PHASE_LOCK_RANGE_44, 1); |
1118 | data |= FIELD_PREP(AD2S1210_ENABLE_HYSTERESIS, 1); |
1119 | data |= FIELD_PREP(AD2S1210_SET_ENRES, 0x3); |
1120 | data |= FIELD_PREP(AD2S1210_SET_RES, st->resolution); |
1121 | |
1122 | ret = regmap_write(map: st->regmap, AD2S1210_REG_CONTROL, val: data); |
1123 | if (ret < 0) |
1124 | return ret; |
1125 | |
1126 | return ad2s1210_reinit_excitation_frequency(st, AD2S1210_DEF_EXCIT); |
1127 | } |
1128 | |
1129 | static int ad2s1210_read_label(struct iio_dev *indio_dev, |
1130 | struct iio_chan_spec const *chan, |
1131 | char *label) |
1132 | { |
1133 | if (chan->type == IIO_ANGL) { |
1134 | if (chan->channel == 0) |
1135 | return sprintf(buf: label, fmt: "position\n" ); |
1136 | if (chan->channel == 1) |
1137 | return sprintf(buf: label, fmt: "tracking error\n" ); |
1138 | } |
1139 | if (chan->type == IIO_ANGL_VEL) |
1140 | return sprintf(buf: label, fmt: "velocity\n" ); |
1141 | if (chan->type == IIO_PHASE) |
1142 | return sprintf(buf: label, fmt: "synthetic reference\n" ); |
1143 | if (chan->type == IIO_ALTVOLTAGE) { |
1144 | if (chan->output) |
1145 | return sprintf(buf: label, fmt: "excitation\n" ); |
1146 | if (chan->channel == 0) |
1147 | return sprintf(buf: label, fmt: "monitor signal\n" ); |
1148 | if (chan->channel == 1) |
1149 | return sprintf(buf: label, fmt: "cosine\n" ); |
1150 | if (chan->channel == 2) |
1151 | return sprintf(buf: label, fmt: "sine\n" ); |
1152 | } |
1153 | |
1154 | return -EINVAL; |
1155 | } |
1156 | |
1157 | static int ad2s1210_read_event_value(struct iio_dev *indio_dev, |
1158 | const struct iio_chan_spec *chan, |
1159 | enum iio_event_type type, |
1160 | enum iio_event_direction dir, |
1161 | enum iio_event_info info, |
1162 | int *val, int *val2) |
1163 | { |
1164 | struct ad2s1210_state *st = iio_priv(indio_dev); |
1165 | |
1166 | switch (chan->type) { |
1167 | case IIO_ANGL: |
1168 | switch (info) { |
1169 | case IIO_EV_INFO_VALUE: |
1170 | return ad2s1210_get_lot_high_threshold(st, val, val2); |
1171 | case IIO_EV_INFO_HYSTERESIS: |
1172 | return ad2s1210_get_lot_low_threshold(st, val, val2); |
1173 | default: |
1174 | return -EINVAL; |
1175 | } |
1176 | case IIO_ALTVOLTAGE: |
1177 | if (chan->output) |
1178 | return -EINVAL; |
1179 | if (type == IIO_EV_TYPE_THRESH && dir == IIO_EV_DIR_FALLING) |
1180 | return ad2s1210_get_voltage_threshold(st, |
1181 | AD2S1210_REG_LOS_THRD, val); |
1182 | if (type == IIO_EV_TYPE_THRESH && dir == IIO_EV_DIR_RISING) |
1183 | return ad2s1210_get_voltage_threshold(st, |
1184 | AD2S1210_REG_DOS_OVR_THRD, val); |
1185 | if (type == IIO_EV_TYPE_MAG) |
1186 | return ad2s1210_get_voltage_threshold(st, |
1187 | AD2S1210_REG_DOS_MIS_THRD, val); |
1188 | return -EINVAL; |
1189 | case IIO_PHASE: |
1190 | return ad2s1210_get_phase_lock_range(st, val, val2); |
1191 | default: |
1192 | return -EINVAL; |
1193 | } |
1194 | } |
1195 | |
1196 | static int ad2s1210_write_event_value(struct iio_dev *indio_dev, |
1197 | const struct iio_chan_spec *chan, |
1198 | enum iio_event_type type, |
1199 | enum iio_event_direction dir, |
1200 | enum iio_event_info info, |
1201 | int val, int val2) |
1202 | { |
1203 | struct ad2s1210_state *st = iio_priv(indio_dev); |
1204 | |
1205 | switch (chan->type) { |
1206 | case IIO_ANGL: |
1207 | switch (info) { |
1208 | case IIO_EV_INFO_VALUE: |
1209 | return ad2s1210_set_lot_high_threshold(st, val, val2); |
1210 | case IIO_EV_INFO_HYSTERESIS: |
1211 | return ad2s1210_set_lot_low_threshold(st, val, val2); |
1212 | default: |
1213 | return -EINVAL; |
1214 | } |
1215 | case IIO_ALTVOLTAGE: |
1216 | if (chan->output) |
1217 | return -EINVAL; |
1218 | if (type == IIO_EV_TYPE_THRESH && dir == IIO_EV_DIR_FALLING) |
1219 | return ad2s1210_set_voltage_threshold(st, |
1220 | AD2S1210_REG_LOS_THRD, val); |
1221 | if (type == IIO_EV_TYPE_THRESH && dir == IIO_EV_DIR_RISING) |
1222 | return ad2s1210_set_voltage_threshold(st, |
1223 | AD2S1210_REG_DOS_OVR_THRD, val); |
1224 | if (type == IIO_EV_TYPE_MAG) |
1225 | return ad2s1210_set_voltage_threshold(st, |
1226 | AD2S1210_REG_DOS_MIS_THRD, val); |
1227 | return -EINVAL; |
1228 | case IIO_PHASE: |
1229 | return ad2s1210_set_phase_lock_range(st, val, val2); |
1230 | default: |
1231 | return -EINVAL; |
1232 | } |
1233 | } |
1234 | |
1235 | static int ad2s1210_read_event_label(struct iio_dev *indio_dev, |
1236 | struct iio_chan_spec const *chan, |
1237 | enum iio_event_type type, |
1238 | enum iio_event_direction dir, |
1239 | char *label) |
1240 | { |
1241 | if (chan->type == IIO_ANGL) |
1242 | return sprintf(buf: label, fmt: "LOT\n" ); |
1243 | if (chan->type == IIO_ANGL_VEL) |
1244 | return sprintf(buf: label, fmt: "max tracking rate\n" ); |
1245 | if (chan->type == IIO_PHASE) |
1246 | return sprintf(buf: label, fmt: "phase lock\n" ); |
1247 | if (chan->type == IIO_ALTVOLTAGE) { |
1248 | if (chan->channel == 0) { |
1249 | if (type == IIO_EV_TYPE_THRESH && |
1250 | dir == IIO_EV_DIR_FALLING) |
1251 | return sprintf(buf: label, fmt: "LOS\n" ); |
1252 | if (type == IIO_EV_TYPE_THRESH && |
1253 | dir == IIO_EV_DIR_RISING) |
1254 | return sprintf(buf: label, fmt: "DOS overrange\n" ); |
1255 | if (type == IIO_EV_TYPE_MAG) |
1256 | return sprintf(buf: label, fmt: "DOS mismatch\n" ); |
1257 | } |
1258 | if (chan->channel == 1 || chan->channel == 2) |
1259 | return sprintf(buf: label, fmt: "clipped\n" ); |
1260 | } |
1261 | |
1262 | return -EINVAL; |
1263 | } |
1264 | |
1265 | static int ad2s1210_debugfs_reg_access(struct iio_dev *indio_dev, |
1266 | unsigned int reg, unsigned int writeval, |
1267 | unsigned int *readval) |
1268 | { |
1269 | struct ad2s1210_state *st = iio_priv(indio_dev); |
1270 | |
1271 | guard(mutex)(T: &st->lock); |
1272 | |
1273 | if (readval) |
1274 | return regmap_read(map: st->regmap, reg, val: readval); |
1275 | |
1276 | return regmap_write(map: st->regmap, reg, val: writeval); |
1277 | } |
1278 | |
1279 | static irqreturn_t ad2s1210_trigger_handler(int irq, void *p) |
1280 | { |
1281 | struct iio_poll_func *pf = p; |
1282 | struct iio_dev *indio_dev = pf->indio_dev; |
1283 | struct ad2s1210_state *st = iio_priv(indio_dev); |
1284 | size_t chan = 0; |
1285 | int ret; |
1286 | |
1287 | guard(mutex)(T: &st->lock); |
1288 | |
1289 | memset(&st->scan, 0, sizeof(st->scan)); |
1290 | ad2s1210_toggle_sample_line(st); |
1291 | |
1292 | if (test_bit(0, indio_dev->active_scan_mask)) { |
1293 | if (st->fixed_mode == MOD_CONFIG) { |
1294 | ret = regmap_bulk_read(map: st->regmap, |
1295 | AD2S1210_REG_POSITION_MSB, |
1296 | val: &st->sample.raw, val_count: 2); |
1297 | if (ret < 0) |
1298 | goto error_ret; |
1299 | } else { |
1300 | ret = ad2s1210_set_mode(st, mode: MOD_POS); |
1301 | if (ret < 0) |
1302 | goto error_ret; |
1303 | |
1304 | ret = spi_read(spi: st->sdev, buf: &st->sample, len: 3); |
1305 | if (ret < 0) |
1306 | goto error_ret; |
1307 | } |
1308 | |
1309 | memcpy(&st->scan.chan[chan++], &st->sample.raw, 2); |
1310 | } |
1311 | |
1312 | if (test_bit(1, indio_dev->active_scan_mask)) { |
1313 | if (st->fixed_mode == MOD_CONFIG) { |
1314 | ret = regmap_bulk_read(map: st->regmap, |
1315 | AD2S1210_REG_VELOCITY_MSB, |
1316 | val: &st->sample.raw, val_count: 2); |
1317 | if (ret < 0) |
1318 | goto error_ret; |
1319 | } else { |
1320 | ret = ad2s1210_set_mode(st, mode: MOD_VEL); |
1321 | if (ret < 0) |
1322 | goto error_ret; |
1323 | |
1324 | ret = spi_read(spi: st->sdev, buf: &st->sample, len: 3); |
1325 | if (ret < 0) |
1326 | goto error_ret; |
1327 | } |
1328 | |
1329 | memcpy(&st->scan.chan[chan++], &st->sample.raw, 2); |
1330 | } |
1331 | |
1332 | if (st->fixed_mode == MOD_CONFIG) { |
1333 | unsigned int reg_val; |
1334 | |
1335 | ret = regmap_read(map: st->regmap, AD2S1210_REG_FAULT, val: ®_val); |
1336 | if (ret < 0) |
1337 | return ret; |
1338 | |
1339 | st->sample.fault = reg_val; |
1340 | } |
1341 | |
1342 | ad2s1210_push_events(indio_dev, flags: st->sample.fault, timestamp: pf->timestamp); |
1343 | iio_push_to_buffers_with_timestamp(indio_dev, data: &st->scan, timestamp: pf->timestamp); |
1344 | |
1345 | error_ret: |
1346 | iio_trigger_notify_done(trig: indio_dev->trig); |
1347 | |
1348 | return IRQ_HANDLED; |
1349 | } |
1350 | |
1351 | static const struct iio_info ad2s1210_info = { |
1352 | .event_attrs = &ad2s1210_event_attribute_group, |
1353 | .read_raw = ad2s1210_read_raw, |
1354 | .read_avail = ad2s1210_read_avail, |
1355 | .write_raw = ad2s1210_write_raw, |
1356 | .read_label = ad2s1210_read_label, |
1357 | .read_event_value = ad2s1210_read_event_value, |
1358 | .write_event_value = ad2s1210_write_event_value, |
1359 | .read_event_label = ad2s1210_read_event_label, |
1360 | .debugfs_reg_access = &ad2s1210_debugfs_reg_access, |
1361 | }; |
1362 | |
1363 | static int ad2s1210_setup_properties(struct ad2s1210_state *st) |
1364 | { |
1365 | struct device *dev = &st->sdev->dev; |
1366 | const char *str_val; |
1367 | u32 val; |
1368 | int ret; |
1369 | |
1370 | ret = device_property_read_string(dev, propname: "adi,fixed-mode" , val: &str_val); |
1371 | if (ret == -EINVAL) |
1372 | st->fixed_mode = -1; |
1373 | else if (ret < 0) |
1374 | return dev_err_probe(dev, err: ret, |
1375 | fmt: "failed to read adi,fixed-mode property\n" ); |
1376 | else { |
1377 | if (strcmp(str_val, "config" )) |
1378 | return dev_err_probe(dev, err: -EINVAL, |
1379 | fmt: "only adi,fixed-mode=\"config\" is supported\n" ); |
1380 | |
1381 | st->fixed_mode = MOD_CONFIG; |
1382 | } |
1383 | |
1384 | ret = device_property_read_u32(dev, propname: "assigned-resolution-bits" , val: &val); |
1385 | if (ret < 0) |
1386 | return dev_err_probe(dev, err: ret, |
1387 | fmt: "failed to read assigned-resolution-bits property\n" ); |
1388 | |
1389 | if (val < 10 || val > 16) |
1390 | return dev_err_probe(dev, err: -EINVAL, |
1391 | fmt: "resolution out of range: %u\n" , val); |
1392 | |
1393 | st->resolution = (val - 10) >> 1; |
1394 | /* |
1395 | * These are values that correlate to the hysteresis bit in the Control |
1396 | * register. 0 = disabled, 1 = enabled. When enabled, the actual |
1397 | * hysteresis is +/- 1 LSB of the raw position value. Which bit is the |
1398 | * LSB depends on the specified resolution. |
1399 | */ |
1400 | st->hysteresis_available[0] = 0; |
1401 | st->hysteresis_available[1] = 1 << (2 * (AD2S1210_RES_16 - |
1402 | st->resolution)); |
1403 | |
1404 | return 0; |
1405 | } |
1406 | |
1407 | static int ad2s1210_setup_clocks(struct ad2s1210_state *st) |
1408 | { |
1409 | struct device *dev = &st->sdev->dev; |
1410 | struct clk *clk; |
1411 | |
1412 | clk = devm_clk_get_enabled(dev, NULL); |
1413 | if (IS_ERR(ptr: clk)) |
1414 | return dev_err_probe(dev, err: PTR_ERR(ptr: clk), fmt: "failed to get clock\n" ); |
1415 | |
1416 | st->clkin_hz = clk_get_rate(clk); |
1417 | if (st->clkin_hz < AD2S1210_MIN_CLKIN || st->clkin_hz > AD2S1210_MAX_CLKIN) |
1418 | return dev_err_probe(dev, err: -EINVAL, |
1419 | fmt: "clock frequency out of range: %lu\n" , |
1420 | st->clkin_hz); |
1421 | |
1422 | return 0; |
1423 | } |
1424 | |
1425 | static int ad2s1210_setup_gpios(struct ad2s1210_state *st) |
1426 | { |
1427 | struct device *dev = &st->sdev->dev; |
1428 | struct gpio_descs *resolution_gpios; |
1429 | struct gpio_desc *reset_gpio; |
1430 | DECLARE_BITMAP(bitmap, 2); |
1431 | int ret; |
1432 | |
1433 | /* should not be sampling on startup */ |
1434 | st->sample_gpio = devm_gpiod_get(dev, con_id: "sample" , flags: GPIOD_OUT_LOW); |
1435 | if (IS_ERR(ptr: st->sample_gpio)) |
1436 | return dev_err_probe(dev, err: PTR_ERR(ptr: st->sample_gpio), |
1437 | fmt: "failed to request sample GPIO\n" ); |
1438 | |
1439 | /* both pins high means that we start in config mode */ |
1440 | st->mode_gpios = devm_gpiod_get_array_optional(dev, con_id: "mode" , |
1441 | flags: GPIOD_OUT_HIGH); |
1442 | if (IS_ERR(ptr: st->mode_gpios)) |
1443 | return dev_err_probe(dev, err: PTR_ERR(ptr: st->mode_gpios), |
1444 | fmt: "failed to request mode GPIOs\n" ); |
1445 | |
1446 | if (!st->mode_gpios && st->fixed_mode == -1) |
1447 | return dev_err_probe(dev, err: -EINVAL, |
1448 | fmt: "must specify either adi,fixed-mode or mode-gpios\n" ); |
1449 | |
1450 | if (st->mode_gpios && st->fixed_mode != -1) |
1451 | return dev_err_probe(dev, err: -EINVAL, |
1452 | fmt: "must specify only one of adi,fixed-mode or mode-gpios\n" ); |
1453 | |
1454 | if (st->mode_gpios && st->mode_gpios->ndescs != 2) |
1455 | return dev_err_probe(dev, err: -EINVAL, |
1456 | fmt: "requires exactly 2 mode-gpios\n" ); |
1457 | |
1458 | /* |
1459 | * If resolution gpios are provided, they get set to the required |
1460 | * resolution, otherwise it is assumed the RES0 and RES1 pins are |
1461 | * hard-wired to match the resolution indicated in the devicetree. |
1462 | */ |
1463 | resolution_gpios = devm_gpiod_get_array_optional(dev, con_id: "resolution" , |
1464 | flags: GPIOD_ASIS); |
1465 | if (IS_ERR(ptr: resolution_gpios)) |
1466 | return dev_err_probe(dev, err: PTR_ERR(ptr: resolution_gpios), |
1467 | fmt: "failed to request resolution GPIOs\n" ); |
1468 | |
1469 | if (resolution_gpios) { |
1470 | if (resolution_gpios->ndescs != 2) |
1471 | return dev_err_probe(dev, err: -EINVAL, |
1472 | fmt: "requires exactly 2 resolution-gpios\n" ); |
1473 | |
1474 | bitmap[0] = st->resolution; |
1475 | |
1476 | ret = gpiod_set_array_value(array_size: resolution_gpios->ndescs, |
1477 | desc_array: resolution_gpios->desc, |
1478 | array_info: resolution_gpios->info, |
1479 | value_bitmap: bitmap); |
1480 | if (ret < 0) |
1481 | return dev_err_probe(dev, err: ret, |
1482 | fmt: "failed to set resolution gpios\n" ); |
1483 | } |
1484 | |
1485 | /* If the optional reset GPIO is present, toggle it to do a hard reset. */ |
1486 | reset_gpio = devm_gpiod_get_optional(dev, con_id: "reset" , flags: GPIOD_OUT_HIGH); |
1487 | if (IS_ERR(ptr: reset_gpio)) |
1488 | return dev_err_probe(dev, err: PTR_ERR(ptr: reset_gpio), |
1489 | fmt: "failed to request reset GPIO\n" ); |
1490 | |
1491 | if (reset_gpio) { |
1492 | udelay(10); |
1493 | gpiod_set_value(desc: reset_gpio, value: 0); |
1494 | } |
1495 | |
1496 | return 0; |
1497 | } |
1498 | |
1499 | static const struct regmap_range ad2s1210_regmap_readable_ranges[] = { |
1500 | regmap_reg_range(AD2S1210_REG_POSITION_MSB, AD2S1210_REG_VELOCITY_LSB), |
1501 | regmap_reg_range(AD2S1210_REG_LOS_THRD, AD2S1210_REG_LOT_LOW_THRD), |
1502 | regmap_reg_range(AD2S1210_REG_EXCIT_FREQ, AD2S1210_REG_CONTROL), |
1503 | regmap_reg_range(AD2S1210_REG_FAULT, AD2S1210_REG_FAULT), |
1504 | }; |
1505 | |
1506 | static const struct regmap_access_table ad2s1210_regmap_rd_table = { |
1507 | .yes_ranges = ad2s1210_regmap_readable_ranges, |
1508 | .n_yes_ranges = ARRAY_SIZE(ad2s1210_regmap_readable_ranges), |
1509 | }; |
1510 | |
1511 | static const struct regmap_range ad2s1210_regmap_writeable_ranges[] = { |
1512 | regmap_reg_range(AD2S1210_REG_LOS_THRD, AD2S1210_REG_LOT_LOW_THRD), |
1513 | regmap_reg_range(AD2S1210_REG_EXCIT_FREQ, AD2S1210_REG_CONTROL), |
1514 | regmap_reg_range(AD2S1210_REG_SOFT_RESET, AD2S1210_REG_SOFT_RESET), |
1515 | regmap_reg_range(AD2S1210_REG_FAULT, AD2S1210_REG_FAULT), |
1516 | }; |
1517 | |
1518 | static const struct regmap_access_table ad2s1210_regmap_wr_table = { |
1519 | .yes_ranges = ad2s1210_regmap_writeable_ranges, |
1520 | .n_yes_ranges = ARRAY_SIZE(ad2s1210_regmap_writeable_ranges), |
1521 | }; |
1522 | |
1523 | static int ad2s1210_setup_regmap(struct ad2s1210_state *st) |
1524 | { |
1525 | struct device *dev = &st->sdev->dev; |
1526 | const struct regmap_config config = { |
1527 | .reg_bits = 8, |
1528 | .val_bits = 8, |
1529 | .disable_locking = true, |
1530 | .reg_read = ad2s1210_regmap_reg_read, |
1531 | .reg_write = ad2s1210_regmap_reg_write, |
1532 | .rd_table = &ad2s1210_regmap_rd_table, |
1533 | .wr_table = &ad2s1210_regmap_wr_table, |
1534 | .can_sleep = true, |
1535 | }; |
1536 | |
1537 | st->regmap = devm_regmap_init(dev, NULL, st, &config); |
1538 | if (IS_ERR(ptr: st->regmap)) |
1539 | return dev_err_probe(dev, err: PTR_ERR(ptr: st->regmap), |
1540 | fmt: "failed to allocate register map\n" ); |
1541 | |
1542 | return 0; |
1543 | } |
1544 | |
1545 | static int ad2s1210_probe(struct spi_device *spi) |
1546 | { |
1547 | struct iio_dev *indio_dev; |
1548 | struct ad2s1210_state *st; |
1549 | int ret; |
1550 | |
1551 | indio_dev = devm_iio_device_alloc(parent: &spi->dev, sizeof_priv: sizeof(*st)); |
1552 | if (!indio_dev) |
1553 | return -ENOMEM; |
1554 | st = iio_priv(indio_dev); |
1555 | |
1556 | mutex_init(&st->lock); |
1557 | st->sdev = spi; |
1558 | |
1559 | ret = ad2s1210_setup_properties(st); |
1560 | if (ret < 0) |
1561 | return ret; |
1562 | |
1563 | ret = ad2s1210_setup_clocks(st); |
1564 | if (ret < 0) |
1565 | return ret; |
1566 | |
1567 | ret = ad2s1210_setup_gpios(st); |
1568 | if (ret < 0) |
1569 | return ret; |
1570 | |
1571 | ret = ad2s1210_setup_regmap(st); |
1572 | if (ret < 0) |
1573 | return ret; |
1574 | |
1575 | ret = ad2s1210_initial(st); |
1576 | if (ret < 0) |
1577 | return ret; |
1578 | |
1579 | indio_dev->info = &ad2s1210_info; |
1580 | indio_dev->modes = INDIO_DIRECT_MODE; |
1581 | indio_dev->channels = ad2s1210_channels; |
1582 | indio_dev->num_channels = ARRAY_SIZE(ad2s1210_channels); |
1583 | indio_dev->name = spi_get_device_id(sdev: spi)->name; |
1584 | |
1585 | ret = devm_iio_triggered_buffer_setup(&spi->dev, indio_dev, |
1586 | &iio_pollfunc_store_time, |
1587 | &ad2s1210_trigger_handler, NULL); |
1588 | if (ret < 0) |
1589 | return dev_err_probe(dev: &spi->dev, err: ret, |
1590 | fmt: "iio triggered buffer setup failed\n" ); |
1591 | |
1592 | return devm_iio_device_register(&spi->dev, indio_dev); |
1593 | } |
1594 | |
1595 | static const struct of_device_id ad2s1210_of_match[] = { |
1596 | { .compatible = "adi,ad2s1210" , }, |
1597 | { } |
1598 | }; |
1599 | MODULE_DEVICE_TABLE(of, ad2s1210_of_match); |
1600 | |
1601 | static const struct spi_device_id ad2s1210_id[] = { |
1602 | { "ad2s1210" }, |
1603 | {} |
1604 | }; |
1605 | MODULE_DEVICE_TABLE(spi, ad2s1210_id); |
1606 | |
1607 | static struct spi_driver ad2s1210_driver = { |
1608 | .driver = { |
1609 | .name = "ad2s1210" , |
1610 | .of_match_table = ad2s1210_of_match, |
1611 | }, |
1612 | .probe = ad2s1210_probe, |
1613 | .id_table = ad2s1210_id, |
1614 | }; |
1615 | module_spi_driver(ad2s1210_driver); |
1616 | |
1617 | MODULE_AUTHOR("Graff Yang <graff.yang@gmail.com>" ); |
1618 | MODULE_DESCRIPTION("Analog Devices AD2S1210 Resolver to Digital SPI driver" ); |
1619 | MODULE_LICENSE("GPL v2" ); |
1620 | |