.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0 |
---|
1 | 2 | /* |
---|
2 | 3 | * AD5933 AD5934 Impedance Converter, Network Analyzer |
---|
3 | 4 | * |
---|
4 | 5 | * Copyright 2011 Analog Devices Inc. |
---|
5 | | - * |
---|
6 | | - * Licensed under the GPL-2. |
---|
7 | 6 | */ |
---|
8 | 7 | |
---|
9 | | -#include <linux/interrupt.h> |
---|
10 | | -#include <linux/device.h> |
---|
11 | | -#include <linux/kernel.h> |
---|
12 | | -#include <linux/sysfs.h> |
---|
13 | | -#include <linux/i2c.h> |
---|
14 | | -#include <linux/regulator/consumer.h> |
---|
15 | | -#include <linux/types.h> |
---|
16 | | -#include <linux/err.h> |
---|
| 8 | +#include <linux/clk.h> |
---|
17 | 9 | #include <linux/delay.h> |
---|
| 10 | +#include <linux/device.h> |
---|
| 11 | +#include <linux/err.h> |
---|
| 12 | +#include <linux/i2c.h> |
---|
| 13 | +#include <linux/interrupt.h> |
---|
| 14 | +#include <linux/kernel.h> |
---|
18 | 15 | #include <linux/module.h> |
---|
| 16 | +#include <linux/regulator/consumer.h> |
---|
| 17 | +#include <linux/sysfs.h> |
---|
| 18 | +#include <linux/types.h> |
---|
19 | 19 | |
---|
20 | | -#include <linux/iio/iio.h> |
---|
21 | | -#include <linux/iio/sysfs.h> |
---|
22 | 20 | #include <linux/iio/buffer.h> |
---|
| 21 | +#include <linux/iio/iio.h> |
---|
23 | 22 | #include <linux/iio/kfifo_buf.h> |
---|
| 23 | +#include <linux/iio/sysfs.h> |
---|
24 | 24 | |
---|
25 | 25 | /* AD5933/AD5934 Registers */ |
---|
26 | 26 | #define AD5933_REG_CONTROL_HB 0x80 /* R/W, 1 byte */ |
---|
.. | .. |
---|
82 | 82 | #define AD5933_POLL_TIME_ms 10 |
---|
83 | 83 | #define AD5933_INIT_EXCITATION_TIME_ms 100 |
---|
84 | 84 | |
---|
85 | | -/** |
---|
86 | | - * struct ad5933_platform_data - platform specific data |
---|
87 | | - * @ext_clk_Hz: the external clock frequency in Hz, if not set |
---|
88 | | - * the driver uses the internal clock (16.776 MHz) |
---|
89 | | - * @vref_mv: the external reference voltage in millivolt |
---|
90 | | - */ |
---|
91 | | - |
---|
92 | | -struct ad5933_platform_data { |
---|
93 | | - unsigned long ext_clk_Hz; |
---|
94 | | - unsigned short vref_mv; |
---|
95 | | -}; |
---|
96 | | - |
---|
97 | 85 | struct ad5933_state { |
---|
98 | 86 | struct i2c_client *client; |
---|
99 | 87 | struct regulator *reg; |
---|
| 88 | + struct clk *mclk; |
---|
100 | 89 | struct delayed_work work; |
---|
101 | 90 | struct mutex lock; /* Protect sensor state */ |
---|
102 | 91 | unsigned long mclk_hz; |
---|
.. | .. |
---|
110 | 99 | unsigned int freq_inc; |
---|
111 | 100 | unsigned int state; |
---|
112 | 101 | unsigned int poll_time_jiffies; |
---|
113 | | -}; |
---|
114 | | - |
---|
115 | | -static struct ad5933_platform_data ad5933_default_pdata = { |
---|
116 | | - .vref_mv = 3300, |
---|
117 | 102 | }; |
---|
118 | 103 | |
---|
119 | 104 | #define AD5933_CHANNEL(_type, _extend_name, _info_mask_separate, _address, \ |
---|
.. | .. |
---|
210 | 195 | u8 d8[4]; |
---|
211 | 196 | } dat; |
---|
212 | 197 | |
---|
213 | | - freqreg = (u64) freq * (u64) (1 << 27); |
---|
| 198 | + freqreg = (u64)freq * (u64)(1 << 27); |
---|
214 | 199 | do_div(freqreg, st->mclk_hz / 4); |
---|
215 | 200 | |
---|
216 | 201 | switch (reg) { |
---|
.. | .. |
---|
267 | 252 | |
---|
268 | 253 | for (i = 0; i < 4; i++) |
---|
269 | 254 | st->range_avail[i] = normalized_3v3[i] * st->vref_mv / 3300; |
---|
270 | | - |
---|
271 | 255 | } |
---|
272 | 256 | |
---|
273 | 257 | /* |
---|
.. | .. |
---|
299 | 283 | freqreg = be32_to_cpu(dat.d32) & 0xFFFFFF; |
---|
300 | 284 | |
---|
301 | 285 | freqreg = (u64)freqreg * (u64)(st->mclk_hz / 4); |
---|
302 | | - do_div(freqreg, 1 << 27); |
---|
| 286 | + do_div(freqreg, BIT(27)); |
---|
303 | 287 | |
---|
304 | 288 | return sprintf(buf, "%d\n", (int)freqreg); |
---|
305 | 289 | } |
---|
.. | .. |
---|
331 | 315 | return ret ? ret : len; |
---|
332 | 316 | } |
---|
333 | 317 | |
---|
334 | | -static IIO_DEVICE_ATTR(out_voltage0_freq_start, 0644, |
---|
| 318 | +static IIO_DEVICE_ATTR(out_altvoltage0_frequency_start, 0644, |
---|
335 | 319 | ad5933_show_frequency, |
---|
336 | 320 | ad5933_store_frequency, |
---|
337 | 321 | AD5933_REG_FREQ_START); |
---|
338 | 322 | |
---|
339 | | -static IIO_DEVICE_ATTR(out_voltage0_freq_increment, 0644, |
---|
| 323 | +static IIO_DEVICE_ATTR(out_altvoltage0_frequency_increment, 0644, |
---|
340 | 324 | ad5933_show_frequency, |
---|
341 | 325 | ad5933_store_frequency, |
---|
342 | 326 | AD5933_REG_FREQ_INC); |
---|
.. | .. |
---|
435 | 419 | if (val > 1022) |
---|
436 | 420 | val = (val >> 2) | (3 << 9); |
---|
437 | 421 | else if (val > 511) |
---|
438 | | - val = (val >> 1) | (1 << 9); |
---|
| 422 | + val = (val >> 1) | BIT(9); |
---|
439 | 423 | |
---|
440 | 424 | dat = cpu_to_be16(val); |
---|
441 | 425 | ret = ad5933_i2c_write(st->client, |
---|
.. | .. |
---|
459 | 443 | return ret ? ret : len; |
---|
460 | 444 | } |
---|
461 | 445 | |
---|
462 | | -static IIO_DEVICE_ATTR(out_voltage0_scale, 0644, |
---|
| 446 | +static IIO_DEVICE_ATTR(out_altvoltage0_raw, 0644, |
---|
463 | 447 | ad5933_show, |
---|
464 | 448 | ad5933_store, |
---|
465 | 449 | AD5933_OUT_RANGE); |
---|
466 | 450 | |
---|
467 | | -static IIO_DEVICE_ATTR(out_voltage0_scale_available, 0444, |
---|
| 451 | +static IIO_DEVICE_ATTR(out_altvoltage0_scale_available, 0444, |
---|
468 | 452 | ad5933_show, |
---|
469 | 453 | NULL, |
---|
470 | 454 | AD5933_OUT_RANGE_AVAIL); |
---|
.. | .. |
---|
479 | 463 | NULL, |
---|
480 | 464 | AD5933_IN_PGA_GAIN_AVAIL); |
---|
481 | 465 | |
---|
482 | | -static IIO_DEVICE_ATTR(out_voltage0_freq_points, 0644, |
---|
| 466 | +static IIO_DEVICE_ATTR(out_altvoltage0_frequency_points, 0644, |
---|
483 | 467 | ad5933_show, |
---|
484 | 468 | ad5933_store, |
---|
485 | 469 | AD5933_FREQ_POINTS); |
---|
486 | 470 | |
---|
487 | | -static IIO_DEVICE_ATTR(out_voltage0_settling_cycles, 0644, |
---|
| 471 | +static IIO_DEVICE_ATTR(out_altvoltage0_settling_cycles, 0644, |
---|
488 | 472 | ad5933_show, |
---|
489 | 473 | ad5933_store, |
---|
490 | 474 | AD5933_OUT_SETTLING_CYCLES); |
---|
491 | 475 | |
---|
492 | | -/* note: |
---|
| 476 | +/* |
---|
| 477 | + * note: |
---|
493 | 478 | * ideally we would handle the scale attributes via the iio_info |
---|
494 | 479 | * (read|write)_raw methods, however this part is a untypical since we |
---|
495 | 480 | * don't create dedicated sysfs channel attributes for out0 and in0. |
---|
496 | 481 | */ |
---|
497 | 482 | static struct attribute *ad5933_attributes[] = { |
---|
498 | | - &iio_dev_attr_out_voltage0_scale.dev_attr.attr, |
---|
499 | | - &iio_dev_attr_out_voltage0_scale_available.dev_attr.attr, |
---|
500 | | - &iio_dev_attr_out_voltage0_freq_start.dev_attr.attr, |
---|
501 | | - &iio_dev_attr_out_voltage0_freq_increment.dev_attr.attr, |
---|
502 | | - &iio_dev_attr_out_voltage0_freq_points.dev_attr.attr, |
---|
503 | | - &iio_dev_attr_out_voltage0_settling_cycles.dev_attr.attr, |
---|
| 483 | + &iio_dev_attr_out_altvoltage0_raw.dev_attr.attr, |
---|
| 484 | + &iio_dev_attr_out_altvoltage0_scale_available.dev_attr.attr, |
---|
| 485 | + &iio_dev_attr_out_altvoltage0_frequency_start.dev_attr.attr, |
---|
| 486 | + &iio_dev_attr_out_altvoltage0_frequency_increment.dev_attr.attr, |
---|
| 487 | + &iio_dev_attr_out_altvoltage0_frequency_points.dev_attr.attr, |
---|
| 488 | + &iio_dev_attr_out_altvoltage0_settling_cycles.dev_attr.attr, |
---|
504 | 489 | &iio_dev_attr_in_voltage0_scale.dev_attr.attr, |
---|
505 | 490 | &iio_dev_attr_in_voltage0_scale_available.dev_attr.attr, |
---|
506 | 491 | NULL |
---|
.. | .. |
---|
587 | 572 | { |
---|
588 | 573 | struct ad5933_state *st = iio_priv(indio_dev); |
---|
589 | 574 | |
---|
590 | | - /* AD5933_CTRL_INIT_START_FREQ: |
---|
| 575 | + /* |
---|
| 576 | + * AD5933_CTRL_INIT_START_FREQ: |
---|
591 | 577 | * High Q complex circuits require a long time to reach steady state. |
---|
592 | 578 | * To facilitate the measurement of such impedances, this mode allows |
---|
593 | 579 | * the user full control of the settling time requirement before |
---|
.. | .. |
---|
616 | 602 | .postdisable = ad5933_ring_postdisable, |
---|
617 | 603 | }; |
---|
618 | 604 | |
---|
619 | | -static int ad5933_register_ring_funcs_and_init(struct iio_dev *indio_dev) |
---|
| 605 | +static int ad5933_register_ring_funcs_and_init(struct device *dev, |
---|
| 606 | + struct iio_dev *indio_dev) |
---|
620 | 607 | { |
---|
621 | 608 | struct iio_buffer *buffer; |
---|
622 | 609 | |
---|
623 | | - buffer = iio_kfifo_allocate(); |
---|
| 610 | + buffer = devm_iio_kfifo_allocate(dev); |
---|
624 | 611 | if (!buffer) |
---|
625 | 612 | return -ENOMEM; |
---|
626 | 613 | |
---|
.. | .. |
---|
678 | 665 | } |
---|
679 | 666 | |
---|
680 | 667 | if (status & AD5933_STAT_SWEEP_DONE) { |
---|
681 | | - /* last sample received - power down do |
---|
| 668 | + /* |
---|
| 669 | + * last sample received - power down do |
---|
682 | 670 | * nothing until the ring enable is toggled |
---|
683 | 671 | */ |
---|
684 | 672 | ad5933_cmd(st, AD5933_CTRL_POWER_DOWN); |
---|
.. | .. |
---|
689 | 677 | } |
---|
690 | 678 | } |
---|
691 | 679 | |
---|
| 680 | +static void ad5933_reg_disable(void *data) |
---|
| 681 | +{ |
---|
| 682 | + struct ad5933_state *st = data; |
---|
| 683 | + |
---|
| 684 | + regulator_disable(st->reg); |
---|
| 685 | +} |
---|
| 686 | + |
---|
| 687 | +static void ad5933_clk_disable(void *data) |
---|
| 688 | +{ |
---|
| 689 | + struct ad5933_state *st = data; |
---|
| 690 | + |
---|
| 691 | + clk_disable_unprepare(st->mclk); |
---|
| 692 | +} |
---|
| 693 | + |
---|
692 | 694 | static int ad5933_probe(struct i2c_client *client, |
---|
693 | 695 | const struct i2c_device_id *id) |
---|
694 | 696 | { |
---|
695 | | - int ret, voltage_uv = 0; |
---|
696 | | - struct ad5933_platform_data *pdata = dev_get_platdata(&client->dev); |
---|
| 697 | + int ret; |
---|
697 | 698 | struct ad5933_state *st; |
---|
698 | 699 | struct iio_dev *indio_dev; |
---|
| 700 | + unsigned long ext_clk_hz = 0; |
---|
699 | 701 | |
---|
700 | 702 | indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*st)); |
---|
701 | 703 | if (!indio_dev) |
---|
.. | .. |
---|
707 | 709 | |
---|
708 | 710 | mutex_init(&st->lock); |
---|
709 | 711 | |
---|
710 | | - if (!pdata) |
---|
711 | | - pdata = &ad5933_default_pdata; |
---|
712 | | - |
---|
713 | 712 | st->reg = devm_regulator_get(&client->dev, "vdd"); |
---|
714 | 713 | if (IS_ERR(st->reg)) |
---|
715 | 714 | return PTR_ERR(st->reg); |
---|
.. | .. |
---|
719 | 718 | dev_err(&client->dev, "Failed to enable specified VDD supply\n"); |
---|
720 | 719 | return ret; |
---|
721 | 720 | } |
---|
722 | | - voltage_uv = regulator_get_voltage(st->reg); |
---|
723 | 721 | |
---|
724 | | - if (voltage_uv) |
---|
725 | | - st->vref_mv = voltage_uv / 1000; |
---|
726 | | - else |
---|
727 | | - st->vref_mv = pdata->vref_mv; |
---|
| 722 | + ret = devm_add_action_or_reset(&client->dev, ad5933_reg_disable, st); |
---|
| 723 | + if (ret) |
---|
| 724 | + return ret; |
---|
728 | 725 | |
---|
729 | | - if (pdata->ext_clk_Hz) { |
---|
730 | | - st->mclk_hz = pdata->ext_clk_Hz; |
---|
| 726 | + ret = regulator_get_voltage(st->reg); |
---|
| 727 | + if (ret < 0) |
---|
| 728 | + return ret; |
---|
| 729 | + |
---|
| 730 | + st->vref_mv = ret / 1000; |
---|
| 731 | + |
---|
| 732 | + st->mclk = devm_clk_get(&client->dev, "mclk"); |
---|
| 733 | + if (IS_ERR(st->mclk) && PTR_ERR(st->mclk) != -ENOENT) |
---|
| 734 | + return PTR_ERR(st->mclk); |
---|
| 735 | + |
---|
| 736 | + if (!IS_ERR(st->mclk)) { |
---|
| 737 | + ret = clk_prepare_enable(st->mclk); |
---|
| 738 | + if (ret < 0) |
---|
| 739 | + return ret; |
---|
| 740 | + |
---|
| 741 | + ret = devm_add_action_or_reset(&client->dev, |
---|
| 742 | + ad5933_clk_disable, |
---|
| 743 | + st); |
---|
| 744 | + if (ret) |
---|
| 745 | + return ret; |
---|
| 746 | + |
---|
| 747 | + ext_clk_hz = clk_get_rate(st->mclk); |
---|
| 748 | + } |
---|
| 749 | + |
---|
| 750 | + if (ext_clk_hz) { |
---|
| 751 | + st->mclk_hz = ext_clk_hz; |
---|
731 | 752 | st->ctrl_lb = AD5933_CTRL_EXT_SYSCLK; |
---|
732 | 753 | } else { |
---|
733 | 754 | st->mclk_hz = AD5933_INT_OSC_FREQ_Hz; |
---|
.. | .. |
---|
738 | 759 | INIT_DELAYED_WORK(&st->work, ad5933_work); |
---|
739 | 760 | st->poll_time_jiffies = msecs_to_jiffies(AD5933_POLL_TIME_ms); |
---|
740 | 761 | |
---|
741 | | - indio_dev->dev.parent = &client->dev; |
---|
742 | 762 | indio_dev->info = &ad5933_info; |
---|
743 | 763 | indio_dev->name = id->name; |
---|
744 | 764 | indio_dev->modes = (INDIO_BUFFER_SOFTWARE | INDIO_DIRECT_MODE); |
---|
745 | 765 | indio_dev->channels = ad5933_channels; |
---|
746 | 766 | indio_dev->num_channels = ARRAY_SIZE(ad5933_channels); |
---|
747 | 767 | |
---|
748 | | - ret = ad5933_register_ring_funcs_and_init(indio_dev); |
---|
| 768 | + ret = ad5933_register_ring_funcs_and_init(&client->dev, indio_dev); |
---|
749 | 769 | if (ret) |
---|
750 | | - goto error_disable_reg; |
---|
| 770 | + return ret; |
---|
751 | 771 | |
---|
752 | 772 | ret = ad5933_setup(st); |
---|
753 | 773 | if (ret) |
---|
754 | | - goto error_unreg_ring; |
---|
| 774 | + return ret; |
---|
755 | 775 | |
---|
756 | | - ret = iio_device_register(indio_dev); |
---|
757 | | - if (ret) |
---|
758 | | - goto error_unreg_ring; |
---|
759 | | - |
---|
760 | | - return 0; |
---|
761 | | - |
---|
762 | | -error_unreg_ring: |
---|
763 | | - iio_kfifo_free(indio_dev->buffer); |
---|
764 | | -error_disable_reg: |
---|
765 | | - regulator_disable(st->reg); |
---|
766 | | - |
---|
767 | | - return ret; |
---|
768 | | -} |
---|
769 | | - |
---|
770 | | -static int ad5933_remove(struct i2c_client *client) |
---|
771 | | -{ |
---|
772 | | - struct iio_dev *indio_dev = i2c_get_clientdata(client); |
---|
773 | | - struct ad5933_state *st = iio_priv(indio_dev); |
---|
774 | | - |
---|
775 | | - iio_device_unregister(indio_dev); |
---|
776 | | - iio_kfifo_free(indio_dev->buffer); |
---|
777 | | - regulator_disable(st->reg); |
---|
778 | | - |
---|
779 | | - return 0; |
---|
| 776 | + return devm_iio_device_register(&client->dev, indio_dev); |
---|
780 | 777 | } |
---|
781 | 778 | |
---|
782 | 779 | static const struct i2c_device_id ad5933_id[] = { |
---|
.. | .. |
---|
787 | 784 | |
---|
788 | 785 | MODULE_DEVICE_TABLE(i2c, ad5933_id); |
---|
789 | 786 | |
---|
| 787 | +static const struct of_device_id ad5933_of_match[] = { |
---|
| 788 | + { .compatible = "adi,ad5933" }, |
---|
| 789 | + { .compatible = "adi,ad5934" }, |
---|
| 790 | + { }, |
---|
| 791 | +}; |
---|
| 792 | + |
---|
| 793 | +MODULE_DEVICE_TABLE(of, ad5933_of_match); |
---|
| 794 | + |
---|
790 | 795 | static struct i2c_driver ad5933_driver = { |
---|
791 | 796 | .driver = { |
---|
792 | 797 | .name = "ad5933", |
---|
| 798 | + .of_match_table = ad5933_of_match, |
---|
793 | 799 | }, |
---|
794 | 800 | .probe = ad5933_probe, |
---|
795 | | - .remove = ad5933_remove, |
---|
796 | 801 | .id_table = ad5933_id, |
---|
797 | 802 | }; |
---|
798 | 803 | module_i2c_driver(ad5933_driver); |
---|
799 | 804 | |
---|
800 | | -MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); |
---|
| 805 | +MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>"); |
---|
801 | 806 | MODULE_DESCRIPTION("Analog Devices AD5933 Impedance Conv. Network Analyzer"); |
---|
802 | 807 | MODULE_LICENSE("GPL v2"); |
---|