| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * AD9523 SPI Low Jitter Clock Generator |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright 2012 Analog Devices Inc. |
|---|
| 5 | | - * |
|---|
| 6 | | - * Licensed under the GPL-2. |
|---|
| 7 | 6 | */ |
|---|
| 8 | 7 | |
|---|
| 9 | 8 | #include <linux/device.h> |
|---|
| .. | .. |
|---|
| 862 | 861 | if (ret < 0) |
|---|
| 863 | 862 | return ret; |
|---|
| 864 | 863 | |
|---|
| 865 | | - st->vco_freq = (pdata->vcxo_freq * (pdata->pll2_freq_doubler_en ? 2 : 1) |
|---|
| 866 | | - / pdata->pll2_r2_div) * AD9523_PLL2_FB_NDIV(pdata-> |
|---|
| 867 | | - pll2_ndiv_a_cnt, pdata->pll2_ndiv_b_cnt); |
|---|
| 864 | + st->vco_freq = div_u64((unsigned long long)pdata->vcxo_freq * |
|---|
| 865 | + (pdata->pll2_freq_doubler_en ? 2 : 1) * |
|---|
| 866 | + AD9523_PLL2_FB_NDIV(pdata->pll2_ndiv_a_cnt, |
|---|
| 867 | + pdata->pll2_ndiv_b_cnt), |
|---|
| 868 | + pdata->pll2_r2_div); |
|---|
| 868 | 869 | |
|---|
| 869 | 870 | ret = ad9523_write(indio_dev, AD9523_PLL2_VCO_CTRL, |
|---|
| 870 | 871 | AD9523_PLL2_VCO_CALIBRATE); |
|---|
| .. | .. |
|---|
| 872 | 873 | return ret; |
|---|
| 873 | 874 | |
|---|
| 874 | 875 | ret = ad9523_write(indio_dev, AD9523_PLL2_VCO_DIVIDER, |
|---|
| 875 | | - AD9523_PLL2_VCO_DIV_M1(pdata->pll2_vco_diff_m1) | |
|---|
| 876 | | - AD9523_PLL2_VCO_DIV_M2(pdata->pll2_vco_diff_m2) | |
|---|
| 877 | | - AD_IFE(pll2_vco_diff_m1, 0, |
|---|
| 876 | + AD9523_PLL2_VCO_DIV_M1(pdata->pll2_vco_div_m1) | |
|---|
| 877 | + AD9523_PLL2_VCO_DIV_M2(pdata->pll2_vco_div_m2) | |
|---|
| 878 | + AD_IFE(pll2_vco_div_m1, 0, |
|---|
| 878 | 879 | AD9523_PLL2_VCO_DIV_M1_PWR_DOWN_EN) | |
|---|
| 879 | | - AD_IFE(pll2_vco_diff_m2, 0, |
|---|
| 880 | + AD_IFE(pll2_vco_div_m2, 0, |
|---|
| 880 | 881 | AD9523_PLL2_VCO_DIV_M2_PWR_DOWN_EN)); |
|---|
| 881 | 882 | if (ret < 0) |
|---|
| 882 | 883 | return ret; |
|---|
| 883 | 884 | |
|---|
| 884 | | - if (pdata->pll2_vco_diff_m1) |
|---|
| 885 | + if (pdata->pll2_vco_div_m1) |
|---|
| 885 | 886 | st->vco_out_freq[AD9523_VCO1] = |
|---|
| 886 | | - st->vco_freq / pdata->pll2_vco_diff_m1; |
|---|
| 887 | + st->vco_freq / pdata->pll2_vco_div_m1; |
|---|
| 887 | 888 | |
|---|
| 888 | | - if (pdata->pll2_vco_diff_m2) |
|---|
| 889 | + if (pdata->pll2_vco_div_m2) |
|---|
| 889 | 890 | st->vco_out_freq[AD9523_VCO2] = |
|---|
| 890 | | - st->vco_freq / pdata->pll2_vco_diff_m2; |
|---|
| 891 | + st->vco_freq / pdata->pll2_vco_div_m2; |
|---|
| 891 | 892 | |
|---|
| 892 | 893 | st->vco_out_freq[AD9523_VCXO] = pdata->vcxo_freq; |
|---|
| 893 | 894 | |
|---|
| .. | .. |
|---|
| 943 | 944 | } |
|---|
| 944 | 945 | } |
|---|
| 945 | 946 | |
|---|
| 946 | | - for_each_clear_bit(i, &active_mask, AD9523_NUM_CHAN) |
|---|
| 947 | | - ad9523_write(indio_dev, |
|---|
| 947 | + for_each_clear_bit(i, &active_mask, AD9523_NUM_CHAN) { |
|---|
| 948 | + ret = ad9523_write(indio_dev, |
|---|
| 948 | 949 | AD9523_CHANNEL_CLOCK_DIST(i), |
|---|
| 949 | 950 | AD9523_CLK_DIST_DRIVER_MODE(TRISTATE) | |
|---|
| 950 | 951 | AD9523_CLK_DIST_PWR_DOWN_EN); |
|---|
| 952 | + if (ret < 0) |
|---|
| 953 | + return ret; |
|---|
| 954 | + } |
|---|
| 951 | 955 | |
|---|
| 952 | 956 | ret = ad9523_write(indio_dev, AD9523_POWER_DOWN_CTRL, 0); |
|---|
| 953 | 957 | if (ret < 0) |
|---|
| .. | .. |
|---|
| 963 | 967 | return ret; |
|---|
| 964 | 968 | |
|---|
| 965 | 969 | return 0; |
|---|
| 970 | +} |
|---|
| 971 | + |
|---|
| 972 | +static void ad9523_reg_disable(void *data) |
|---|
| 973 | +{ |
|---|
| 974 | + struct regulator *reg = data; |
|---|
| 975 | + |
|---|
| 976 | + regulator_disable(reg); |
|---|
| 966 | 977 | } |
|---|
| 967 | 978 | |
|---|
| 968 | 979 | static int ad9523_probe(struct spi_device *spi) |
|---|
| .. | .. |
|---|
| 990 | 1001 | ret = regulator_enable(st->reg); |
|---|
| 991 | 1002 | if (ret) |
|---|
| 992 | 1003 | return ret; |
|---|
| 1004 | + |
|---|
| 1005 | + ret = devm_add_action_or_reset(&spi->dev, ad9523_reg_disable, |
|---|
| 1006 | + st->reg); |
|---|
| 1007 | + if (ret) |
|---|
| 1008 | + return ret; |
|---|
| 993 | 1009 | } |
|---|
| 994 | 1010 | |
|---|
| 995 | 1011 | st->pwrdown_gpio = devm_gpiod_get_optional(&spi->dev, "powerdown", |
|---|
| 996 | 1012 | GPIOD_OUT_HIGH); |
|---|
| 997 | | - if (IS_ERR(st->pwrdown_gpio)) { |
|---|
| 998 | | - ret = PTR_ERR(st->pwrdown_gpio); |
|---|
| 999 | | - goto error_disable_reg; |
|---|
| 1000 | | - } |
|---|
| 1013 | + if (IS_ERR(st->pwrdown_gpio)) |
|---|
| 1014 | + return PTR_ERR(st->pwrdown_gpio); |
|---|
| 1001 | 1015 | |
|---|
| 1002 | 1016 | st->reset_gpio = devm_gpiod_get_optional(&spi->dev, "reset", |
|---|
| 1003 | 1017 | GPIOD_OUT_LOW); |
|---|
| 1004 | | - if (IS_ERR(st->reset_gpio)) { |
|---|
| 1005 | | - ret = PTR_ERR(st->reset_gpio); |
|---|
| 1006 | | - goto error_disable_reg; |
|---|
| 1007 | | - } |
|---|
| 1018 | + if (IS_ERR(st->reset_gpio)) |
|---|
| 1019 | + return PTR_ERR(st->reset_gpio); |
|---|
| 1008 | 1020 | |
|---|
| 1009 | 1021 | if (st->reset_gpio) { |
|---|
| 1010 | 1022 | udelay(1); |
|---|
| .. | .. |
|---|
| 1013 | 1025 | |
|---|
| 1014 | 1026 | st->sync_gpio = devm_gpiod_get_optional(&spi->dev, "sync", |
|---|
| 1015 | 1027 | GPIOD_OUT_HIGH); |
|---|
| 1016 | | - if (IS_ERR(st->sync_gpio)) { |
|---|
| 1017 | | - ret = PTR_ERR(st->sync_gpio); |
|---|
| 1018 | | - goto error_disable_reg; |
|---|
| 1019 | | - } |
|---|
| 1028 | + if (IS_ERR(st->sync_gpio)) |
|---|
| 1029 | + return PTR_ERR(st->sync_gpio); |
|---|
| 1020 | 1030 | |
|---|
| 1021 | 1031 | spi_set_drvdata(spi, indio_dev); |
|---|
| 1022 | 1032 | st->spi = spi; |
|---|
| 1023 | 1033 | st->pdata = pdata; |
|---|
| 1024 | 1034 | |
|---|
| 1025 | | - indio_dev->dev.parent = &spi->dev; |
|---|
| 1026 | 1035 | indio_dev->name = (pdata->name[0] != 0) ? pdata->name : |
|---|
| 1027 | 1036 | spi_get_device_id(spi)->name; |
|---|
| 1028 | 1037 | indio_dev->info = &ad9523_info; |
|---|
| .. | .. |
|---|
| 1032 | 1041 | |
|---|
| 1033 | 1042 | ret = ad9523_setup(indio_dev); |
|---|
| 1034 | 1043 | if (ret < 0) |
|---|
| 1035 | | - goto error_disable_reg; |
|---|
| 1044 | + return ret; |
|---|
| 1036 | 1045 | |
|---|
| 1037 | | - ret = iio_device_register(indio_dev); |
|---|
| 1038 | | - if (ret) |
|---|
| 1039 | | - goto error_disable_reg; |
|---|
| 1040 | | - |
|---|
| 1041 | | - dev_info(&spi->dev, "probed %s\n", indio_dev->name); |
|---|
| 1042 | | - |
|---|
| 1043 | | - return 0; |
|---|
| 1044 | | - |
|---|
| 1045 | | -error_disable_reg: |
|---|
| 1046 | | - if (!IS_ERR(st->reg)) |
|---|
| 1047 | | - regulator_disable(st->reg); |
|---|
| 1048 | | - |
|---|
| 1049 | | - return ret; |
|---|
| 1050 | | -} |
|---|
| 1051 | | - |
|---|
| 1052 | | -static int ad9523_remove(struct spi_device *spi) |
|---|
| 1053 | | -{ |
|---|
| 1054 | | - struct iio_dev *indio_dev = spi_get_drvdata(spi); |
|---|
| 1055 | | - struct ad9523_state *st = iio_priv(indio_dev); |
|---|
| 1056 | | - |
|---|
| 1057 | | - iio_device_unregister(indio_dev); |
|---|
| 1058 | | - |
|---|
| 1059 | | - if (!IS_ERR(st->reg)) |
|---|
| 1060 | | - regulator_disable(st->reg); |
|---|
| 1061 | | - |
|---|
| 1062 | | - return 0; |
|---|
| 1046 | + return devm_iio_device_register(&spi->dev, indio_dev); |
|---|
| 1063 | 1047 | } |
|---|
| 1064 | 1048 | |
|---|
| 1065 | 1049 | static const struct spi_device_id ad9523_id[] = { |
|---|
| .. | .. |
|---|
| 1073 | 1057 | .name = "ad9523", |
|---|
| 1074 | 1058 | }, |
|---|
| 1075 | 1059 | .probe = ad9523_probe, |
|---|
| 1076 | | - .remove = ad9523_remove, |
|---|
| 1077 | 1060 | .id_table = ad9523_id, |
|---|
| 1078 | 1061 | }; |
|---|
| 1079 | 1062 | module_spi_driver(ad9523_driver); |
|---|
| 1080 | 1063 | |
|---|
| 1081 | | -MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); |
|---|
| 1064 | +MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>"); |
|---|
| 1082 | 1065 | MODULE_DESCRIPTION("Analog Devices AD9523 CLOCKDIST/PLL"); |
|---|
| 1083 | 1066 | MODULE_LICENSE("GPL v2"); |
|---|