.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0 |
---|
1 | 2 | /* |
---|
2 | 3 | * ad2s1210.c support for the ADI Resolver to Digital Converters: AD2S1210 |
---|
3 | 4 | * |
---|
4 | 5 | * Copyright (c) 2010-2010 Analog Devices Inc. |
---|
5 | | - * |
---|
6 | | - * This program is free software; you can redistribute it and/or modify |
---|
7 | | - * it under the terms of the GNU General Public License version 2 as |
---|
8 | | - * published by the Free Software Foundation. |
---|
9 | | - * |
---|
10 | 6 | */ |
---|
11 | 7 | #include <linux/types.h> |
---|
12 | 8 | #include <linux/mutex.h> |
---|
.. | .. |
---|
15 | 11 | #include <linux/slab.h> |
---|
16 | 12 | #include <linux/sysfs.h> |
---|
17 | 13 | #include <linux/delay.h> |
---|
18 | | -#include <linux/gpio.h> |
---|
| 14 | +#include <linux/gpio/consumer.h> |
---|
19 | 15 | #include <linux/module.h> |
---|
20 | 16 | |
---|
21 | 17 | #include <linux/iio/iio.h> |
---|
22 | 18 | #include <linux/iio/sysfs.h> |
---|
23 | | -#include "ad2s1210.h" |
---|
24 | 19 | |
---|
25 | 20 | #define DRV_NAME "ad2s1210" |
---|
26 | 21 | |
---|
.. | .. |
---|
67 | 62 | MOD_RESERVED, |
---|
68 | 63 | }; |
---|
69 | 64 | |
---|
| 65 | +enum ad2s1210_gpios { |
---|
| 66 | + AD2S1210_SAMPLE, |
---|
| 67 | + AD2S1210_A0, |
---|
| 68 | + AD2S1210_A1, |
---|
| 69 | + AD2S1210_RES0, |
---|
| 70 | + AD2S1210_RES1, |
---|
| 71 | +}; |
---|
| 72 | + |
---|
| 73 | +struct ad2s1210_gpio { |
---|
| 74 | + const char *name; |
---|
| 75 | + unsigned long flags; |
---|
| 76 | +}; |
---|
| 77 | + |
---|
| 78 | +static const struct ad2s1210_gpio gpios[] = { |
---|
| 79 | + [AD2S1210_SAMPLE] = { .name = "adi,sample", .flags = GPIOD_OUT_LOW }, |
---|
| 80 | + [AD2S1210_A0] = { .name = "adi,a0", .flags = GPIOD_OUT_LOW }, |
---|
| 81 | + [AD2S1210_A1] = { .name = "adi,a1", .flags = GPIOD_OUT_LOW }, |
---|
| 82 | + [AD2S1210_RES0] = { .name = "adi,res0", .flags = GPIOD_OUT_LOW }, |
---|
| 83 | + [AD2S1210_RES1] = { .name = "adi,res1", .flags = GPIOD_OUT_LOW }, |
---|
| 84 | +}; |
---|
| 85 | + |
---|
70 | 86 | static const unsigned int ad2s1210_resolution_value[] = { 10, 12, 14, 16 }; |
---|
71 | 87 | |
---|
72 | 88 | struct ad2s1210_state { |
---|
73 | | - const struct ad2s1210_platform_data *pdata; |
---|
74 | 89 | struct mutex lock; |
---|
75 | 90 | struct spi_device *sdev; |
---|
| 91 | + struct gpio_desc *gpios[5]; |
---|
76 | 92 | unsigned int fclkin; |
---|
77 | 93 | unsigned int fexcit; |
---|
78 | 94 | bool hysteresis; |
---|
.. | .. |
---|
85 | 101 | static const int ad2s1210_mode_vals[4][2] = { |
---|
86 | 102 | [MOD_POS] = { 0, 0 }, |
---|
87 | 103 | [MOD_VEL] = { 0, 1 }, |
---|
88 | | - [MOD_CONFIG] = { 1, 0 }, |
---|
| 104 | + [MOD_CONFIG] = { 1, 1 }, |
---|
89 | 105 | }; |
---|
90 | 106 | |
---|
91 | 107 | static inline void ad2s1210_set_mode(enum ad2s1210_mode mode, |
---|
92 | 108 | struct ad2s1210_state *st) |
---|
93 | 109 | { |
---|
94 | | - gpio_set_value(st->pdata->a[0], ad2s1210_mode_vals[mode][0]); |
---|
95 | | - gpio_set_value(st->pdata->a[1], ad2s1210_mode_vals[mode][1]); |
---|
| 110 | + gpiod_set_value(st->gpios[AD2S1210_A0], ad2s1210_mode_vals[mode][0]); |
---|
| 111 | + gpiod_set_value(st->gpios[AD2S1210_A1], ad2s1210_mode_vals[mode][1]); |
---|
96 | 112 | st->mode = mode; |
---|
97 | 113 | } |
---|
98 | 114 | |
---|
.. | .. |
---|
157 | 173 | return ad2s1210_config_write(st, fcw); |
---|
158 | 174 | } |
---|
159 | 175 | |
---|
160 | | -static unsigned char ad2s1210_read_resolution_pin(struct ad2s1210_state *st) |
---|
161 | | -{ |
---|
162 | | - int resolution = (gpio_get_value(st->pdata->res[0]) << 1) | |
---|
163 | | - gpio_get_value(st->pdata->res[1]); |
---|
164 | | - |
---|
165 | | - return ad2s1210_resolution_value[resolution]; |
---|
166 | | -} |
---|
167 | | - |
---|
168 | 176 | static const int ad2s1210_res_pins[4][2] = { |
---|
169 | 177 | { 0, 0 }, {0, 1}, {1, 0}, {1, 1} |
---|
170 | 178 | }; |
---|
171 | 179 | |
---|
172 | 180 | static inline void ad2s1210_set_resolution_pin(struct ad2s1210_state *st) |
---|
173 | 181 | { |
---|
174 | | - gpio_set_value(st->pdata->res[0], |
---|
175 | | - ad2s1210_res_pins[(st->resolution - 10) / 2][0]); |
---|
176 | | - gpio_set_value(st->pdata->res[1], |
---|
177 | | - ad2s1210_res_pins[(st->resolution - 10) / 2][1]); |
---|
| 182 | + gpiod_set_value(st->gpios[AD2S1210_RES0], |
---|
| 183 | + ad2s1210_res_pins[(st->resolution - 10) / 2][0]); |
---|
| 184 | + gpiod_set_value(st->gpios[AD2S1210_RES1], |
---|
| 185 | + ad2s1210_res_pins[(st->resolution - 10) / 2][1]); |
---|
178 | 186 | } |
---|
179 | 187 | |
---|
180 | 188 | static inline int ad2s1210_soft_reset(struct ad2s1210_state *st) |
---|
.. | .. |
---|
308 | 316 | "ad2s1210: write control register fail\n"); |
---|
309 | 317 | goto error_ret; |
---|
310 | 318 | } |
---|
311 | | - st->resolution |
---|
312 | | - = ad2s1210_resolution_value[data & AD2S1210_SET_RESOLUTION]; |
---|
313 | | - if (st->pdata->gpioin) { |
---|
314 | | - data = ad2s1210_read_resolution_pin(st); |
---|
315 | | - if (data != st->resolution) |
---|
316 | | - dev_warn(dev, "ad2s1210: resolution settings not match\n"); |
---|
317 | | - } else { |
---|
318 | | - ad2s1210_set_resolution_pin(st); |
---|
319 | | - } |
---|
| 319 | + st->resolution = |
---|
| 320 | + ad2s1210_resolution_value[data & AD2S1210_SET_RESOLUTION]; |
---|
| 321 | + ad2s1210_set_resolution_pin(st); |
---|
320 | 322 | ret = len; |
---|
321 | 323 | st->hysteresis = !!(data & AD2S1210_ENABLE_HYSTERESIS); |
---|
322 | 324 | |
---|
.. | .. |
---|
370 | 372 | dev_err(dev, "ad2s1210: setting resolution fail\n"); |
---|
371 | 373 | goto error_ret; |
---|
372 | 374 | } |
---|
373 | | - st->resolution |
---|
374 | | - = ad2s1210_resolution_value[data & AD2S1210_SET_RESOLUTION]; |
---|
375 | | - if (st->pdata->gpioin) { |
---|
376 | | - data = ad2s1210_read_resolution_pin(st); |
---|
377 | | - if (data != st->resolution) |
---|
378 | | - dev_warn(dev, "ad2s1210: resolution settings not match\n"); |
---|
379 | | - } else { |
---|
380 | | - ad2s1210_set_resolution_pin(st); |
---|
381 | | - } |
---|
| 375 | + st->resolution = |
---|
| 376 | + ad2s1210_resolution_value[data & AD2S1210_SET_RESOLUTION]; |
---|
| 377 | + ad2s1210_set_resolution_pin(st); |
---|
382 | 378 | ret = len; |
---|
383 | 379 | error_ret: |
---|
384 | 380 | mutex_unlock(&st->lock); |
---|
.. | .. |
---|
408 | 404 | int ret; |
---|
409 | 405 | |
---|
410 | 406 | mutex_lock(&st->lock); |
---|
411 | | - gpio_set_value(st->pdata->sample, 0); |
---|
| 407 | + gpiod_set_value(st->gpios[AD2S1210_SAMPLE], 0); |
---|
412 | 408 | /* delay (2 * tck + 20) nano seconds */ |
---|
413 | 409 | udelay(1); |
---|
414 | | - gpio_set_value(st->pdata->sample, 1); |
---|
| 410 | + gpiod_set_value(st->gpios[AD2S1210_SAMPLE], 1); |
---|
415 | 411 | ret = ad2s1210_config_read(st, AD2S1210_REG_FAULT); |
---|
416 | 412 | if (ret < 0) |
---|
417 | 413 | goto error_ret; |
---|
418 | | - gpio_set_value(st->pdata->sample, 0); |
---|
419 | | - gpio_set_value(st->pdata->sample, 1); |
---|
| 414 | + gpiod_set_value(st->gpios[AD2S1210_SAMPLE], 0); |
---|
| 415 | + gpiod_set_value(st->gpios[AD2S1210_SAMPLE], 1); |
---|
420 | 416 | error_ret: |
---|
421 | 417 | mutex_unlock(&st->lock); |
---|
422 | 418 | |
---|
.. | .. |
---|
473 | 469 | s16 vel; |
---|
474 | 470 | |
---|
475 | 471 | mutex_lock(&st->lock); |
---|
476 | | - gpio_set_value(st->pdata->sample, 0); |
---|
| 472 | + gpiod_set_value(st->gpios[AD2S1210_SAMPLE], 0); |
---|
477 | 473 | /* delay (6 * tck + 20) nano seconds */ |
---|
478 | 474 | udelay(1); |
---|
479 | 475 | |
---|
.. | .. |
---|
519 | 515 | } |
---|
520 | 516 | |
---|
521 | 517 | error_ret: |
---|
522 | | - gpio_set_value(st->pdata->sample, 1); |
---|
| 518 | + gpiod_set_value(st->gpios[AD2S1210_SAMPLE], 1); |
---|
523 | 519 | /* delay (2 * tck + 20) nano seconds */ |
---|
524 | 520 | udelay(1); |
---|
525 | 521 | mutex_unlock(&st->lock); |
---|
.. | .. |
---|
599 | 595 | int ret; |
---|
600 | 596 | |
---|
601 | 597 | mutex_lock(&st->lock); |
---|
602 | | - if (st->pdata->gpioin) |
---|
603 | | - st->resolution = ad2s1210_read_resolution_pin(st); |
---|
604 | | - else |
---|
605 | | - ad2s1210_set_resolution_pin(st); |
---|
| 598 | + ad2s1210_set_resolution_pin(st); |
---|
606 | 599 | |
---|
607 | 600 | ret = ad2s1210_config_write(st, AD2S1210_REG_CONTROL); |
---|
608 | 601 | if (ret < 0) |
---|
.. | .. |
---|
637 | 630 | |
---|
638 | 631 | static int ad2s1210_setup_gpios(struct ad2s1210_state *st) |
---|
639 | 632 | { |
---|
640 | | - unsigned long flags = st->pdata->gpioin ? GPIOF_DIR_IN : GPIOF_DIR_OUT; |
---|
641 | | - struct gpio ad2s1210_gpios[] = { |
---|
642 | | - { st->pdata->sample, GPIOF_DIR_IN, "sample" }, |
---|
643 | | - { st->pdata->a[0], flags, "a0" }, |
---|
644 | | - { st->pdata->a[1], flags, "a1" }, |
---|
645 | | - { st->pdata->res[0], flags, "res0" }, |
---|
646 | | - { st->pdata->res[0], flags, "res1" }, |
---|
647 | | - }; |
---|
| 633 | + struct spi_device *spi = st->sdev; |
---|
| 634 | + int i, ret; |
---|
648 | 635 | |
---|
649 | | - return gpio_request_array(ad2s1210_gpios, ARRAY_SIZE(ad2s1210_gpios)); |
---|
650 | | -} |
---|
| 636 | + for (i = 0; i < ARRAY_SIZE(gpios); i++) { |
---|
| 637 | + st->gpios[i] = devm_gpiod_get(&spi->dev, gpios[i].name, |
---|
| 638 | + gpios[i].flags); |
---|
| 639 | + if (IS_ERR(st->gpios[i])) { |
---|
| 640 | + ret = PTR_ERR(st->gpios[i]); |
---|
| 641 | + dev_err(&spi->dev, |
---|
| 642 | + "ad2s1210: failed to request %s GPIO: %d\n", |
---|
| 643 | + gpios[i].name, ret); |
---|
| 644 | + return ret; |
---|
| 645 | + } |
---|
| 646 | + } |
---|
651 | 647 | |
---|
652 | | -static void ad2s1210_free_gpios(struct ad2s1210_state *st) |
---|
653 | | -{ |
---|
654 | | - unsigned long flags = st->pdata->gpioin ? GPIOF_DIR_IN : GPIOF_DIR_OUT; |
---|
655 | | - struct gpio ad2s1210_gpios[] = { |
---|
656 | | - { st->pdata->sample, GPIOF_DIR_IN, "sample" }, |
---|
657 | | - { st->pdata->a[0], flags, "a0" }, |
---|
658 | | - { st->pdata->a[1], flags, "a1" }, |
---|
659 | | - { st->pdata->res[0], flags, "res0" }, |
---|
660 | | - { st->pdata->res[0], flags, "res1" }, |
---|
661 | | - }; |
---|
662 | | - |
---|
663 | | - gpio_free_array(ad2s1210_gpios, ARRAY_SIZE(ad2s1210_gpios)); |
---|
| 648 | + return 0; |
---|
664 | 649 | } |
---|
665 | 650 | |
---|
666 | 651 | static int ad2s1210_probe(struct spi_device *spi) |
---|
.. | .. |
---|
669 | 654 | struct ad2s1210_state *st; |
---|
670 | 655 | int ret; |
---|
671 | 656 | |
---|
672 | | - if (!spi->dev.platform_data) |
---|
673 | | - return -EINVAL; |
---|
674 | | - |
---|
675 | 657 | indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); |
---|
676 | 658 | if (!indio_dev) |
---|
677 | 659 | return -ENOMEM; |
---|
678 | 660 | st = iio_priv(indio_dev); |
---|
679 | | - st->pdata = spi->dev.platform_data; |
---|
680 | 661 | ret = ad2s1210_setup_gpios(st); |
---|
681 | 662 | if (ret < 0) |
---|
682 | 663 | return ret; |
---|
.. | .. |
---|
690 | 671 | st->resolution = 12; |
---|
691 | 672 | st->fexcit = AD2S1210_DEF_EXCIT; |
---|
692 | 673 | |
---|
693 | | - indio_dev->dev.parent = &spi->dev; |
---|
694 | 674 | indio_dev->info = &ad2s1210_info; |
---|
695 | 675 | indio_dev->modes = INDIO_DIRECT_MODE; |
---|
696 | 676 | indio_dev->channels = ad2s1210_channels; |
---|
697 | 677 | indio_dev->num_channels = ARRAY_SIZE(ad2s1210_channels); |
---|
698 | 678 | indio_dev->name = spi_get_device_id(spi)->name; |
---|
699 | 679 | |
---|
700 | | - ret = iio_device_register(indio_dev); |
---|
| 680 | + ret = devm_iio_device_register(&spi->dev, indio_dev); |
---|
701 | 681 | if (ret) |
---|
702 | | - goto error_free_gpios; |
---|
| 682 | + return ret; |
---|
703 | 683 | |
---|
704 | 684 | st->fclkin = spi->max_speed_hz; |
---|
705 | 685 | spi->mode = SPI_MODE_3; |
---|
.. | .. |
---|
707 | 687 | ad2s1210_initial(st); |
---|
708 | 688 | |
---|
709 | 689 | return 0; |
---|
710 | | - |
---|
711 | | -error_free_gpios: |
---|
712 | | - ad2s1210_free_gpios(st); |
---|
713 | | - return ret; |
---|
714 | 690 | } |
---|
715 | 691 | |
---|
716 | | -static int ad2s1210_remove(struct spi_device *spi) |
---|
717 | | -{ |
---|
718 | | - struct iio_dev *indio_dev = spi_get_drvdata(spi); |
---|
719 | | - |
---|
720 | | - iio_device_unregister(indio_dev); |
---|
721 | | - ad2s1210_free_gpios(iio_priv(indio_dev)); |
---|
722 | | - |
---|
723 | | - return 0; |
---|
724 | | -} |
---|
| 692 | +static const struct of_device_id ad2s1210_of_match[] = { |
---|
| 693 | + { .compatible = "adi,ad2s1210", }, |
---|
| 694 | + { } |
---|
| 695 | +}; |
---|
| 696 | +MODULE_DEVICE_TABLE(of, ad2s1210_of_match); |
---|
725 | 697 | |
---|
726 | 698 | static const struct spi_device_id ad2s1210_id[] = { |
---|
727 | 699 | { "ad2s1210" }, |
---|
.. | .. |
---|
732 | 704 | static struct spi_driver ad2s1210_driver = { |
---|
733 | 705 | .driver = { |
---|
734 | 706 | .name = DRV_NAME, |
---|
| 707 | + .of_match_table = of_match_ptr(ad2s1210_of_match), |
---|
735 | 708 | }, |
---|
736 | 709 | .probe = ad2s1210_probe, |
---|
737 | | - .remove = ad2s1210_remove, |
---|
738 | 710 | .id_table = ad2s1210_id, |
---|
739 | 711 | }; |
---|
740 | 712 | module_spi_driver(ad2s1210_driver); |
---|