| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * iio/adc/ad799x.c |
|---|
| 3 | 4 | * Copyright (C) 2010-2011 Michael Hennerich, Analog Devices Inc. |
|---|
| .. | .. |
|---|
| 11 | 12 | * based on linux/drivers/acron/char/pcf8583.c |
|---|
| 12 | 13 | * Copyright (C) 2000 Russell King |
|---|
| 13 | 14 | * |
|---|
| 14 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 15 | | - * it under the terms of the GNU General Public License version 2 as |
|---|
| 16 | | - * published by the Free Software Foundation. |
|---|
| 17 | | - * |
|---|
| 18 | 15 | * ad799x.c |
|---|
| 19 | 16 | * |
|---|
| 20 | 17 | * Support for ad7991, ad7995, ad7999, ad7992, ad7993, ad7994, ad7997, |
|---|
| 21 | 18 | * ad7998 and similar chips. |
|---|
| 22 | | - * |
|---|
| 23 | 19 | */ |
|---|
| 24 | 20 | |
|---|
| 25 | 21 | #include <linux/interrupt.h> |
|---|
| .. | .. |
|---|
| 171 | 167 | } |
|---|
| 172 | 168 | } |
|---|
| 173 | 169 | |
|---|
| 174 | | -/** |
|---|
| 170 | +static int ad799x_update_config(struct ad799x_state *st, u16 config) |
|---|
| 171 | +{ |
|---|
| 172 | + int ret; |
|---|
| 173 | + |
|---|
| 174 | + ret = ad799x_write_config(st, config); |
|---|
| 175 | + if (ret < 0) |
|---|
| 176 | + return ret; |
|---|
| 177 | + ret = ad799x_read_config(st); |
|---|
| 178 | + if (ret < 0) |
|---|
| 179 | + return ret; |
|---|
| 180 | + st->config = ret; |
|---|
| 181 | + |
|---|
| 182 | + return 0; |
|---|
| 183 | +} |
|---|
| 184 | + |
|---|
| 185 | +/* |
|---|
| 175 | 186 | * ad799x_trigger_handler() bh of trigger launched polling to ring buffer |
|---|
| 176 | 187 | * |
|---|
| 177 | 188 | * Currently there is no option in this driver to disable the saving of |
|---|
| .. | .. |
|---|
| 803 | 814 | |
|---|
| 804 | 815 | st->client = client; |
|---|
| 805 | 816 | |
|---|
| 806 | | - indio_dev->dev.parent = &client->dev; |
|---|
| 807 | | - indio_dev->dev.of_node = client->dev.of_node; |
|---|
| 808 | 817 | indio_dev->name = id->name; |
|---|
| 809 | 818 | indio_dev->info = st->chip_config->info; |
|---|
| 810 | 819 | |
|---|
| .. | .. |
|---|
| 812 | 821 | indio_dev->channels = st->chip_config->channel; |
|---|
| 813 | 822 | indio_dev->num_channels = chip_info->num_channels; |
|---|
| 814 | 823 | |
|---|
| 815 | | - ret = ad799x_write_config(st, st->chip_config->default_config); |
|---|
| 816 | | - if (ret < 0) |
|---|
| 824 | + ret = ad799x_update_config(st, st->chip_config->default_config); |
|---|
| 825 | + if (ret) |
|---|
| 817 | 826 | goto error_disable_vref; |
|---|
| 818 | | - ret = ad799x_read_config(st); |
|---|
| 819 | | - if (ret < 0) |
|---|
| 820 | | - goto error_disable_vref; |
|---|
| 821 | | - st->config = ret; |
|---|
| 822 | 827 | |
|---|
| 823 | 828 | ret = iio_triggered_buffer_setup(indio_dev, NULL, |
|---|
| 824 | 829 | &ad799x_trigger_handler, NULL); |
|---|
| .. | .. |
|---|
| 868 | 873 | return 0; |
|---|
| 869 | 874 | } |
|---|
| 870 | 875 | |
|---|
| 876 | +static int __maybe_unused ad799x_suspend(struct device *dev) |
|---|
| 877 | +{ |
|---|
| 878 | + struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); |
|---|
| 879 | + struct ad799x_state *st = iio_priv(indio_dev); |
|---|
| 880 | + |
|---|
| 881 | + regulator_disable(st->vref); |
|---|
| 882 | + regulator_disable(st->reg); |
|---|
| 883 | + |
|---|
| 884 | + return 0; |
|---|
| 885 | +} |
|---|
| 886 | + |
|---|
| 887 | +static int __maybe_unused ad799x_resume(struct device *dev) |
|---|
| 888 | +{ |
|---|
| 889 | + struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); |
|---|
| 890 | + struct ad799x_state *st = iio_priv(indio_dev); |
|---|
| 891 | + int ret; |
|---|
| 892 | + |
|---|
| 893 | + ret = regulator_enable(st->reg); |
|---|
| 894 | + if (ret) { |
|---|
| 895 | + dev_err(dev, "Unable to enable vcc regulator\n"); |
|---|
| 896 | + return ret; |
|---|
| 897 | + } |
|---|
| 898 | + ret = regulator_enable(st->vref); |
|---|
| 899 | + if (ret) { |
|---|
| 900 | + regulator_disable(st->reg); |
|---|
| 901 | + dev_err(dev, "Unable to enable vref regulator\n"); |
|---|
| 902 | + return ret; |
|---|
| 903 | + } |
|---|
| 904 | + |
|---|
| 905 | + /* resync config */ |
|---|
| 906 | + ret = ad799x_update_config(st, st->config); |
|---|
| 907 | + if (ret) { |
|---|
| 908 | + regulator_disable(st->vref); |
|---|
| 909 | + regulator_disable(st->reg); |
|---|
| 910 | + return ret; |
|---|
| 911 | + } |
|---|
| 912 | + |
|---|
| 913 | + return 0; |
|---|
| 914 | +} |
|---|
| 915 | + |
|---|
| 916 | +static SIMPLE_DEV_PM_OPS(ad799x_pm_ops, ad799x_suspend, ad799x_resume); |
|---|
| 917 | + |
|---|
| 871 | 918 | static const struct i2c_device_id ad799x_id[] = { |
|---|
| 872 | 919 | { "ad7991", ad7991 }, |
|---|
| 873 | 920 | { "ad7995", ad7995 }, |
|---|
| .. | .. |
|---|
| 885 | 932 | static struct i2c_driver ad799x_driver = { |
|---|
| 886 | 933 | .driver = { |
|---|
| 887 | 934 | .name = "ad799x", |
|---|
| 935 | + .pm = &ad799x_pm_ops, |
|---|
| 888 | 936 | }, |
|---|
| 889 | 937 | .probe = ad799x_probe, |
|---|
| 890 | 938 | .remove = ad799x_remove, |
|---|
| .. | .. |
|---|
| 892 | 940 | }; |
|---|
| 893 | 941 | module_i2c_driver(ad799x_driver); |
|---|
| 894 | 942 | |
|---|
| 895 | | -MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); |
|---|
| 943 | +MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>"); |
|---|
| 896 | 944 | MODULE_DESCRIPTION("Analog Devices AD799x ADC"); |
|---|
| 897 | 945 | MODULE_LICENSE("GPL v2"); |
|---|