Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * AD5686R, AD5685R, AD5684R Digital to analog converters  driver
0004  *
0005  * Copyright 2011 Analog Devices Inc.
0006  */
0007 
0008 #include <linux/interrupt.h>
0009 #include <linux/fs.h>
0010 #include <linux/device.h>
0011 #include <linux/module.h>
0012 #include <linux/kernel.h>
0013 #include <linux/slab.h>
0014 #include <linux/sysfs.h>
0015 #include <linux/regulator/consumer.h>
0016 
0017 #include <linux/iio/iio.h>
0018 #include <linux/iio/sysfs.h>
0019 
0020 #include "ad5686.h"
0021 
0022 static const char * const ad5686_powerdown_modes[] = {
0023     "1kohm_to_gnd",
0024     "100kohm_to_gnd",
0025     "three_state"
0026 };
0027 
0028 static int ad5686_get_powerdown_mode(struct iio_dev *indio_dev,
0029                      const struct iio_chan_spec *chan)
0030 {
0031     struct ad5686_state *st = iio_priv(indio_dev);
0032 
0033     return ((st->pwr_down_mode >> (chan->channel * 2)) & 0x3) - 1;
0034 }
0035 
0036 static int ad5686_set_powerdown_mode(struct iio_dev *indio_dev,
0037                      const struct iio_chan_spec *chan,
0038                      unsigned int mode)
0039 {
0040     struct ad5686_state *st = iio_priv(indio_dev);
0041 
0042     st->pwr_down_mode &= ~(0x3 << (chan->channel * 2));
0043     st->pwr_down_mode |= ((mode + 1) << (chan->channel * 2));
0044 
0045     return 0;
0046 }
0047 
0048 static const struct iio_enum ad5686_powerdown_mode_enum = {
0049     .items = ad5686_powerdown_modes,
0050     .num_items = ARRAY_SIZE(ad5686_powerdown_modes),
0051     .get = ad5686_get_powerdown_mode,
0052     .set = ad5686_set_powerdown_mode,
0053 };
0054 
0055 static ssize_t ad5686_read_dac_powerdown(struct iio_dev *indio_dev,
0056         uintptr_t private, const struct iio_chan_spec *chan, char *buf)
0057 {
0058     struct ad5686_state *st = iio_priv(indio_dev);
0059 
0060     return sysfs_emit(buf, "%d\n", !!(st->pwr_down_mask &
0061                        (0x3 << (chan->channel * 2))));
0062 }
0063 
0064 static ssize_t ad5686_write_dac_powerdown(struct iio_dev *indio_dev,
0065                       uintptr_t private,
0066                       const struct iio_chan_spec *chan,
0067                       const char *buf,
0068                       size_t len)
0069 {
0070     bool readin;
0071     int ret;
0072     struct ad5686_state *st = iio_priv(indio_dev);
0073     unsigned int val, ref_bit_msk;
0074     u8 shift, address = 0;
0075 
0076     ret = kstrtobool(buf, &readin);
0077     if (ret)
0078         return ret;
0079 
0080     if (readin)
0081         st->pwr_down_mask |= (0x3 << (chan->channel * 2));
0082     else
0083         st->pwr_down_mask &= ~(0x3 << (chan->channel * 2));
0084 
0085     switch (st->chip_info->regmap_type) {
0086     case AD5310_REGMAP:
0087         shift = 9;
0088         ref_bit_msk = AD5310_REF_BIT_MSK;
0089         break;
0090     case AD5683_REGMAP:
0091         shift = 13;
0092         ref_bit_msk = AD5683_REF_BIT_MSK;
0093         break;
0094     case AD5686_REGMAP:
0095         shift = 0;
0096         ref_bit_msk = 0;
0097         /* AD5674R/AD5679R have 16 channels and 2 powerdown registers */
0098         if (chan->channel > 0x7)
0099             address = 0x8;
0100         break;
0101     case AD5693_REGMAP:
0102         shift = 13;
0103         ref_bit_msk = AD5693_REF_BIT_MSK;
0104         break;
0105     default:
0106         return -EINVAL;
0107     }
0108 
0109     val = ((st->pwr_down_mask & st->pwr_down_mode) << shift);
0110     if (!st->use_internal_vref)
0111         val |= ref_bit_msk;
0112 
0113     ret = st->write(st, AD5686_CMD_POWERDOWN_DAC,
0114             address, val >> (address * 2));
0115 
0116     return ret ? ret : len;
0117 }
0118 
0119 static int ad5686_read_raw(struct iio_dev *indio_dev,
0120                struct iio_chan_spec const *chan,
0121                int *val,
0122                int *val2,
0123                long m)
0124 {
0125     struct ad5686_state *st = iio_priv(indio_dev);
0126     int ret;
0127 
0128     switch (m) {
0129     case IIO_CHAN_INFO_RAW:
0130         mutex_lock(&st->lock);
0131         ret = st->read(st, chan->address);
0132         mutex_unlock(&st->lock);
0133         if (ret < 0)
0134             return ret;
0135         *val = (ret >> chan->scan_type.shift) &
0136             GENMASK(chan->scan_type.realbits - 1, 0);
0137         return IIO_VAL_INT;
0138     case IIO_CHAN_INFO_SCALE:
0139         *val = st->vref_mv;
0140         *val2 = chan->scan_type.realbits;
0141         return IIO_VAL_FRACTIONAL_LOG2;
0142     }
0143     return -EINVAL;
0144 }
0145 
0146 static int ad5686_write_raw(struct iio_dev *indio_dev,
0147                 struct iio_chan_spec const *chan,
0148                 int val,
0149                 int val2,
0150                 long mask)
0151 {
0152     struct ad5686_state *st = iio_priv(indio_dev);
0153     int ret;
0154 
0155     switch (mask) {
0156     case IIO_CHAN_INFO_RAW:
0157         if (val > (1 << chan->scan_type.realbits) || val < 0)
0158             return -EINVAL;
0159 
0160         mutex_lock(&st->lock);
0161         ret = st->write(st,
0162                 AD5686_CMD_WRITE_INPUT_N_UPDATE_N,
0163                 chan->address,
0164                 val << chan->scan_type.shift);
0165         mutex_unlock(&st->lock);
0166         break;
0167     default:
0168         ret = -EINVAL;
0169     }
0170 
0171     return ret;
0172 }
0173 
0174 static const struct iio_info ad5686_info = {
0175     .read_raw = ad5686_read_raw,
0176     .write_raw = ad5686_write_raw,
0177 };
0178 
0179 static const struct iio_chan_spec_ext_info ad5686_ext_info[] = {
0180     {
0181         .name = "powerdown",
0182         .read = ad5686_read_dac_powerdown,
0183         .write = ad5686_write_dac_powerdown,
0184         .shared = IIO_SEPARATE,
0185     },
0186     IIO_ENUM("powerdown_mode", IIO_SEPARATE, &ad5686_powerdown_mode_enum),
0187     IIO_ENUM_AVAILABLE("powerdown_mode", IIO_SHARED_BY_TYPE, &ad5686_powerdown_mode_enum),
0188     { },
0189 };
0190 
0191 #define AD5868_CHANNEL(chan, addr, bits, _shift) {      \
0192         .type = IIO_VOLTAGE,                \
0193         .indexed = 1,                   \
0194         .output = 1,                    \
0195         .channel = chan,                \
0196         .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),   \
0197         .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),\
0198         .address = addr,                \
0199         .scan_type = {                  \
0200             .sign = 'u',                \
0201             .realbits = (bits),         \
0202             .storagebits = 16,          \
0203             .shift = (_shift),          \
0204         },                      \
0205         .ext_info = ad5686_ext_info,            \
0206 }
0207 
0208 #define DECLARE_AD5693_CHANNELS(name, bits, _shift)     \
0209 static const struct iio_chan_spec name[] = {            \
0210         AD5868_CHANNEL(0, 0, bits, _shift),     \
0211 }
0212 
0213 #define DECLARE_AD5338_CHANNELS(name, bits, _shift)     \
0214 static const struct iio_chan_spec name[] = {            \
0215         AD5868_CHANNEL(0, 1, bits, _shift),     \
0216         AD5868_CHANNEL(1, 8, bits, _shift),     \
0217 }
0218 
0219 #define DECLARE_AD5686_CHANNELS(name, bits, _shift)     \
0220 static const struct iio_chan_spec name[] = {            \
0221         AD5868_CHANNEL(0, 1, bits, _shift),     \
0222         AD5868_CHANNEL(1, 2, bits, _shift),     \
0223         AD5868_CHANNEL(2, 4, bits, _shift),     \
0224         AD5868_CHANNEL(3, 8, bits, _shift),     \
0225 }
0226 
0227 #define DECLARE_AD5676_CHANNELS(name, bits, _shift)     \
0228 static const struct iio_chan_spec name[] = {            \
0229         AD5868_CHANNEL(0, 0, bits, _shift),     \
0230         AD5868_CHANNEL(1, 1, bits, _shift),     \
0231         AD5868_CHANNEL(2, 2, bits, _shift),     \
0232         AD5868_CHANNEL(3, 3, bits, _shift),     \
0233         AD5868_CHANNEL(4, 4, bits, _shift),     \
0234         AD5868_CHANNEL(5, 5, bits, _shift),     \
0235         AD5868_CHANNEL(6, 6, bits, _shift),     \
0236         AD5868_CHANNEL(7, 7, bits, _shift),     \
0237 }
0238 
0239 #define DECLARE_AD5679_CHANNELS(name, bits, _shift)     \
0240 static const struct iio_chan_spec name[] = {            \
0241         AD5868_CHANNEL(0, 0, bits, _shift),     \
0242         AD5868_CHANNEL(1, 1, bits, _shift),     \
0243         AD5868_CHANNEL(2, 2, bits, _shift),     \
0244         AD5868_CHANNEL(3, 3, bits, _shift),     \
0245         AD5868_CHANNEL(4, 4, bits, _shift),     \
0246         AD5868_CHANNEL(5, 5, bits, _shift),     \
0247         AD5868_CHANNEL(6, 6, bits, _shift),     \
0248         AD5868_CHANNEL(7, 7, bits, _shift),     \
0249         AD5868_CHANNEL(8, 8, bits, _shift),     \
0250         AD5868_CHANNEL(9, 9, bits, _shift),     \
0251         AD5868_CHANNEL(10, 10, bits, _shift),       \
0252         AD5868_CHANNEL(11, 11, bits, _shift),       \
0253         AD5868_CHANNEL(12, 12, bits, _shift),       \
0254         AD5868_CHANNEL(13, 13, bits, _shift),       \
0255         AD5868_CHANNEL(14, 14, bits, _shift),       \
0256         AD5868_CHANNEL(15, 15, bits, _shift),       \
0257 }
0258 
0259 DECLARE_AD5693_CHANNELS(ad5310r_channels, 10, 2);
0260 DECLARE_AD5693_CHANNELS(ad5311r_channels, 10, 6);
0261 DECLARE_AD5338_CHANNELS(ad5338r_channels, 10, 6);
0262 DECLARE_AD5676_CHANNELS(ad5672_channels, 12, 4);
0263 DECLARE_AD5679_CHANNELS(ad5674r_channels, 12, 4);
0264 DECLARE_AD5676_CHANNELS(ad5676_channels, 16, 0);
0265 DECLARE_AD5679_CHANNELS(ad5679r_channels, 16, 0);
0266 DECLARE_AD5686_CHANNELS(ad5684_channels, 12, 4);
0267 DECLARE_AD5686_CHANNELS(ad5685r_channels, 14, 2);
0268 DECLARE_AD5686_CHANNELS(ad5686_channels, 16, 0);
0269 DECLARE_AD5693_CHANNELS(ad5693_channels, 16, 0);
0270 DECLARE_AD5693_CHANNELS(ad5692r_channels, 14, 2);
0271 DECLARE_AD5693_CHANNELS(ad5691r_channels, 12, 4);
0272 
0273 static const struct ad5686_chip_info ad5686_chip_info_tbl[] = {
0274     [ID_AD5310R] = {
0275         .channels = ad5310r_channels,
0276         .int_vref_mv = 2500,
0277         .num_channels = 1,
0278         .regmap_type = AD5310_REGMAP,
0279     },
0280     [ID_AD5311R] = {
0281         .channels = ad5311r_channels,
0282         .int_vref_mv = 2500,
0283         .num_channels = 1,
0284         .regmap_type = AD5693_REGMAP,
0285     },
0286     [ID_AD5338R] = {
0287         .channels = ad5338r_channels,
0288         .int_vref_mv = 2500,
0289         .num_channels = 2,
0290         .regmap_type = AD5686_REGMAP,
0291     },
0292     [ID_AD5671R] = {
0293         .channels = ad5672_channels,
0294         .int_vref_mv = 2500,
0295         .num_channels = 8,
0296         .regmap_type = AD5686_REGMAP,
0297     },
0298     [ID_AD5672R] = {
0299         .channels = ad5672_channels,
0300         .int_vref_mv = 2500,
0301         .num_channels = 8,
0302         .regmap_type = AD5686_REGMAP,
0303     },
0304     [ID_AD5673R] = {
0305         .channels = ad5674r_channels,
0306         .int_vref_mv = 2500,
0307         .num_channels = 16,
0308         .regmap_type = AD5686_REGMAP,
0309     },
0310     [ID_AD5674R] = {
0311         .channels = ad5674r_channels,
0312         .int_vref_mv = 2500,
0313         .num_channels = 16,
0314         .regmap_type = AD5686_REGMAP,
0315     },
0316     [ID_AD5675R] = {
0317         .channels = ad5676_channels,
0318         .int_vref_mv = 2500,
0319         .num_channels = 8,
0320         .regmap_type = AD5686_REGMAP,
0321     },
0322     [ID_AD5676] = {
0323         .channels = ad5676_channels,
0324         .num_channels = 8,
0325         .regmap_type = AD5686_REGMAP,
0326     },
0327     [ID_AD5676R] = {
0328         .channels = ad5676_channels,
0329         .int_vref_mv = 2500,
0330         .num_channels = 8,
0331         .regmap_type = AD5686_REGMAP,
0332     },
0333     [ID_AD5677R] = {
0334         .channels = ad5679r_channels,
0335         .int_vref_mv = 2500,
0336         .num_channels = 16,
0337         .regmap_type = AD5686_REGMAP,
0338     },
0339     [ID_AD5679R] = {
0340         .channels = ad5679r_channels,
0341         .int_vref_mv = 2500,
0342         .num_channels = 16,
0343         .regmap_type = AD5686_REGMAP,
0344     },
0345     [ID_AD5681R] = {
0346         .channels = ad5691r_channels,
0347         .int_vref_mv = 2500,
0348         .num_channels = 1,
0349         .regmap_type = AD5683_REGMAP,
0350     },
0351     [ID_AD5682R] = {
0352         .channels = ad5692r_channels,
0353         .int_vref_mv = 2500,
0354         .num_channels = 1,
0355         .regmap_type = AD5683_REGMAP,
0356     },
0357     [ID_AD5683] = {
0358         .channels = ad5693_channels,
0359         .num_channels = 1,
0360         .regmap_type = AD5683_REGMAP,
0361     },
0362     [ID_AD5683R] = {
0363         .channels = ad5693_channels,
0364         .int_vref_mv = 2500,
0365         .num_channels = 1,
0366         .regmap_type = AD5683_REGMAP,
0367     },
0368     [ID_AD5684] = {
0369         .channels = ad5684_channels,
0370         .num_channels = 4,
0371         .regmap_type = AD5686_REGMAP,
0372     },
0373     [ID_AD5684R] = {
0374         .channels = ad5684_channels,
0375         .int_vref_mv = 2500,
0376         .num_channels = 4,
0377         .regmap_type = AD5686_REGMAP,
0378     },
0379     [ID_AD5685R] = {
0380         .channels = ad5685r_channels,
0381         .int_vref_mv = 2500,
0382         .num_channels = 4,
0383         .regmap_type = AD5686_REGMAP,
0384     },
0385     [ID_AD5686] = {
0386         .channels = ad5686_channels,
0387         .num_channels = 4,
0388         .regmap_type = AD5686_REGMAP,
0389     },
0390     [ID_AD5686R] = {
0391         .channels = ad5686_channels,
0392         .int_vref_mv = 2500,
0393         .num_channels = 4,
0394         .regmap_type = AD5686_REGMAP,
0395     },
0396     [ID_AD5691R] = {
0397         .channels = ad5691r_channels,
0398         .int_vref_mv = 2500,
0399         .num_channels = 1,
0400         .regmap_type = AD5693_REGMAP,
0401     },
0402     [ID_AD5692R] = {
0403         .channels = ad5692r_channels,
0404         .int_vref_mv = 2500,
0405         .num_channels = 1,
0406         .regmap_type = AD5693_REGMAP,
0407     },
0408     [ID_AD5693] = {
0409         .channels = ad5693_channels,
0410         .num_channels = 1,
0411         .regmap_type = AD5693_REGMAP,
0412     },
0413     [ID_AD5693R] = {
0414         .channels = ad5693_channels,
0415         .int_vref_mv = 2500,
0416         .num_channels = 1,
0417         .regmap_type = AD5693_REGMAP,
0418     },
0419     [ID_AD5694] = {
0420         .channels = ad5684_channels,
0421         .num_channels = 4,
0422         .regmap_type = AD5686_REGMAP,
0423     },
0424     [ID_AD5694R] = {
0425         .channels = ad5684_channels,
0426         .int_vref_mv = 2500,
0427         .num_channels = 4,
0428         .regmap_type = AD5686_REGMAP,
0429     },
0430     [ID_AD5696] = {
0431         .channels = ad5686_channels,
0432         .num_channels = 4,
0433         .regmap_type = AD5686_REGMAP,
0434     },
0435     [ID_AD5696R] = {
0436         .channels = ad5686_channels,
0437         .int_vref_mv = 2500,
0438         .num_channels = 4,
0439         .regmap_type = AD5686_REGMAP,
0440     },
0441 };
0442 
0443 int ad5686_probe(struct device *dev,
0444          enum ad5686_supported_device_ids chip_type,
0445          const char *name, ad5686_write_func write,
0446          ad5686_read_func read)
0447 {
0448     struct ad5686_state *st;
0449     struct iio_dev *indio_dev;
0450     unsigned int val, ref_bit_msk;
0451     u8 cmd;
0452     int ret, i, voltage_uv = 0;
0453 
0454     indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
0455     if (indio_dev == NULL)
0456         return  -ENOMEM;
0457 
0458     st = iio_priv(indio_dev);
0459     dev_set_drvdata(dev, indio_dev);
0460 
0461     st->dev = dev;
0462     st->write = write;
0463     st->read = read;
0464 
0465     st->reg = devm_regulator_get_optional(dev, "vcc");
0466     if (!IS_ERR(st->reg)) {
0467         ret = regulator_enable(st->reg);
0468         if (ret)
0469             return ret;
0470 
0471         ret = regulator_get_voltage(st->reg);
0472         if (ret < 0)
0473             goto error_disable_reg;
0474 
0475         voltage_uv = ret;
0476     }
0477 
0478     st->chip_info = &ad5686_chip_info_tbl[chip_type];
0479 
0480     if (voltage_uv)
0481         st->vref_mv = voltage_uv / 1000;
0482     else
0483         st->vref_mv = st->chip_info->int_vref_mv;
0484 
0485     /* Set all the power down mode for all channels to 1K pulldown */
0486     for (i = 0; i < st->chip_info->num_channels; i++)
0487         st->pwr_down_mode |= (0x01 << (i * 2));
0488 
0489     indio_dev->name = name;
0490     indio_dev->info = &ad5686_info;
0491     indio_dev->modes = INDIO_DIRECT_MODE;
0492     indio_dev->channels = st->chip_info->channels;
0493     indio_dev->num_channels = st->chip_info->num_channels;
0494 
0495     mutex_init(&st->lock);
0496 
0497     switch (st->chip_info->regmap_type) {
0498     case AD5310_REGMAP:
0499         cmd = AD5686_CMD_CONTROL_REG;
0500         ref_bit_msk = AD5310_REF_BIT_MSK;
0501         st->use_internal_vref = !voltage_uv;
0502         break;
0503     case AD5683_REGMAP:
0504         cmd = AD5686_CMD_CONTROL_REG;
0505         ref_bit_msk = AD5683_REF_BIT_MSK;
0506         st->use_internal_vref = !voltage_uv;
0507         break;
0508     case AD5686_REGMAP:
0509         cmd = AD5686_CMD_INTERNAL_REFER_SETUP;
0510         ref_bit_msk = 0;
0511         break;
0512     case AD5693_REGMAP:
0513         cmd = AD5686_CMD_CONTROL_REG;
0514         ref_bit_msk = AD5693_REF_BIT_MSK;
0515         st->use_internal_vref = !voltage_uv;
0516         break;
0517     default:
0518         ret = -EINVAL;
0519         goto error_disable_reg;
0520     }
0521 
0522     val = (voltage_uv | ref_bit_msk);
0523 
0524     ret = st->write(st, cmd, 0, !!val);
0525     if (ret)
0526         goto error_disable_reg;
0527 
0528     ret = iio_device_register(indio_dev);
0529     if (ret)
0530         goto error_disable_reg;
0531 
0532     return 0;
0533 
0534 error_disable_reg:
0535     if (!IS_ERR(st->reg))
0536         regulator_disable(st->reg);
0537     return ret;
0538 }
0539 EXPORT_SYMBOL_NS_GPL(ad5686_probe, IIO_AD5686);
0540 
0541 void ad5686_remove(struct device *dev)
0542 {
0543     struct iio_dev *indio_dev = dev_get_drvdata(dev);
0544     struct ad5686_state *st = iio_priv(indio_dev);
0545 
0546     iio_device_unregister(indio_dev);
0547     if (!IS_ERR(st->reg))
0548         regulator_disable(st->reg);
0549 }
0550 EXPORT_SYMBOL_NS_GPL(ad5686_remove, IIO_AD5686);
0551 
0552 MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
0553 MODULE_DESCRIPTION("Analog Devices AD5686/85/84 DAC");
0554 MODULE_LICENSE("GPL v2");