Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * AD7303 Digital to analog converters driver
0004  *
0005  * Copyright 2013 Analog Devices Inc.
0006  */
0007 
0008 #include <linux/err.h>
0009 #include <linux/module.h>
0010 #include <linux/mod_devicetable.h>
0011 #include <linux/kernel.h>
0012 #include <linux/spi/spi.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 #define AD7303_CFG_EXTERNAL_VREF BIT(15)
0021 #define AD7303_CFG_POWER_DOWN(ch) BIT(11 + (ch))
0022 #define AD7303_CFG_ADDR_OFFSET  10
0023 
0024 #define AD7303_CMD_UPDATE_DAC   (0x3 << 8)
0025 
0026 /**
0027  * struct ad7303_state - driver instance specific data
0028  * @spi:        the device for this driver instance
0029  * @config:     cached config register value
0030  * @dac_cache:      current DAC raw value (chip does not support readback)
0031  * @vdd_reg:        reference to VDD regulator
0032  * @vref_reg:       reference to VREF regulator
0033  * @lock:       protect writes and cache updates
0034  * @data:       spi transfer buffer
0035  */
0036 
0037 struct ad7303_state {
0038     struct spi_device *spi;
0039     uint16_t config;
0040     uint8_t dac_cache[2];
0041 
0042     struct regulator *vdd_reg;
0043     struct regulator *vref_reg;
0044 
0045     struct mutex lock;
0046     /*
0047      * DMA (thus cache coherency maintenance) may require the
0048      * transfer buffers to live in their own cache lines.
0049      */
0050     __be16 data __aligned(IIO_DMA_MINALIGN);
0051 };
0052 
0053 static int ad7303_write(struct ad7303_state *st, unsigned int chan,
0054     uint8_t val)
0055 {
0056     st->data = cpu_to_be16(AD7303_CMD_UPDATE_DAC |
0057         (chan << AD7303_CFG_ADDR_OFFSET) |
0058         st->config | val);
0059 
0060     return spi_write(st->spi, &st->data, sizeof(st->data));
0061 }
0062 
0063 static ssize_t ad7303_read_dac_powerdown(struct iio_dev *indio_dev,
0064     uintptr_t private, const struct iio_chan_spec *chan, char *buf)
0065 {
0066     struct ad7303_state *st = iio_priv(indio_dev);
0067 
0068     return sysfs_emit(buf, "%d\n", (bool)(st->config &
0069         AD7303_CFG_POWER_DOWN(chan->channel)));
0070 }
0071 
0072 static ssize_t ad7303_write_dac_powerdown(struct iio_dev *indio_dev,
0073      uintptr_t private, const struct iio_chan_spec *chan, const char *buf,
0074      size_t len)
0075 {
0076     struct ad7303_state *st = iio_priv(indio_dev);
0077     bool pwr_down;
0078     int ret;
0079 
0080     ret = kstrtobool(buf, &pwr_down);
0081     if (ret)
0082         return ret;
0083 
0084     mutex_lock(&st->lock);
0085 
0086     if (pwr_down)
0087         st->config |= AD7303_CFG_POWER_DOWN(chan->channel);
0088     else
0089         st->config &= ~AD7303_CFG_POWER_DOWN(chan->channel);
0090 
0091     /* There is no noop cmd which allows us to only update the powerdown
0092      * mode, so just write one of the DAC channels again */
0093     ad7303_write(st, chan->channel, st->dac_cache[chan->channel]);
0094 
0095     mutex_unlock(&st->lock);
0096     return len;
0097 }
0098 
0099 static int ad7303_get_vref(struct ad7303_state *st,
0100     struct iio_chan_spec const *chan)
0101 {
0102     int ret;
0103 
0104     if (st->config & AD7303_CFG_EXTERNAL_VREF)
0105         return regulator_get_voltage(st->vref_reg);
0106 
0107     ret = regulator_get_voltage(st->vdd_reg);
0108     if (ret < 0)
0109         return ret;
0110     return ret / 2;
0111 }
0112 
0113 static int ad7303_read_raw(struct iio_dev *indio_dev,
0114     struct iio_chan_spec const *chan, int *val, int *val2, long info)
0115 {
0116     struct ad7303_state *st = iio_priv(indio_dev);
0117     int vref_uv;
0118 
0119     switch (info) {
0120     case IIO_CHAN_INFO_RAW:
0121         mutex_lock(&st->lock);
0122         *val = st->dac_cache[chan->channel];
0123         mutex_unlock(&st->lock);
0124         return IIO_VAL_INT;
0125     case IIO_CHAN_INFO_SCALE:
0126         vref_uv = ad7303_get_vref(st, chan);
0127         if (vref_uv < 0)
0128             return vref_uv;
0129 
0130         *val = 2 * vref_uv / 1000;
0131         *val2 = chan->scan_type.realbits;
0132 
0133         return IIO_VAL_FRACTIONAL_LOG2;
0134     default:
0135         break;
0136     }
0137     return -EINVAL;
0138 }
0139 
0140 static int ad7303_write_raw(struct iio_dev *indio_dev,
0141     struct iio_chan_spec const *chan, int val, int val2, long mask)
0142 {
0143     struct ad7303_state *st = iio_priv(indio_dev);
0144     int ret;
0145 
0146     switch (mask) {
0147     case IIO_CHAN_INFO_RAW:
0148         if (val >= (1 << chan->scan_type.realbits) || val < 0)
0149             return -EINVAL;
0150 
0151         mutex_lock(&st->lock);
0152         ret = ad7303_write(st, chan->address, val);
0153         if (ret == 0)
0154             st->dac_cache[chan->channel] = val;
0155         mutex_unlock(&st->lock);
0156         break;
0157     default:
0158         ret = -EINVAL;
0159     }
0160 
0161     return ret;
0162 }
0163 
0164 static const struct iio_info ad7303_info = {
0165     .read_raw = ad7303_read_raw,
0166     .write_raw = ad7303_write_raw,
0167 };
0168 
0169 static const struct iio_chan_spec_ext_info ad7303_ext_info[] = {
0170     {
0171         .name = "powerdown",
0172         .read = ad7303_read_dac_powerdown,
0173         .write = ad7303_write_dac_powerdown,
0174         .shared = IIO_SEPARATE,
0175     },
0176     { },
0177 };
0178 
0179 #define AD7303_CHANNEL(chan) {                  \
0180     .type = IIO_VOLTAGE,                    \
0181     .indexed = 1,                       \
0182     .output = 1,                        \
0183     .channel = (chan),                  \
0184     .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),       \
0185     .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),   \
0186     .address = (chan),                  \
0187     .scan_type = {                      \
0188         .sign = 'u',                    \
0189         .realbits = 8,                  \
0190         .storagebits = 8,               \
0191         .shift = 0,                 \
0192     },                          \
0193     .ext_info = ad7303_ext_info,                \
0194 }
0195 
0196 static const struct iio_chan_spec ad7303_channels[] = {
0197     AD7303_CHANNEL(0),
0198     AD7303_CHANNEL(1),
0199 };
0200 
0201 static void ad7303_reg_disable(void *reg)
0202 {
0203     regulator_disable(reg);
0204 }
0205 
0206 static int ad7303_probe(struct spi_device *spi)
0207 {
0208     const struct spi_device_id *id = spi_get_device_id(spi);
0209     struct iio_dev *indio_dev;
0210     struct ad7303_state *st;
0211     int ret;
0212 
0213     indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
0214     if (indio_dev == NULL)
0215         return -ENOMEM;
0216 
0217     st = iio_priv(indio_dev);
0218 
0219     st->spi = spi;
0220 
0221     mutex_init(&st->lock);
0222 
0223     st->vdd_reg = devm_regulator_get(&spi->dev, "Vdd");
0224     if (IS_ERR(st->vdd_reg))
0225         return PTR_ERR(st->vdd_reg);
0226 
0227     ret = regulator_enable(st->vdd_reg);
0228     if (ret)
0229         return ret;
0230 
0231     ret = devm_add_action_or_reset(&spi->dev, ad7303_reg_disable, st->vdd_reg);
0232     if (ret)
0233         return ret;
0234 
0235     st->vref_reg = devm_regulator_get_optional(&spi->dev, "REF");
0236     if (IS_ERR(st->vref_reg)) {
0237         ret = PTR_ERR(st->vref_reg);
0238         if (ret != -ENODEV)
0239             return ret;
0240         st->vref_reg = NULL;
0241     }
0242 
0243     if (st->vref_reg) {
0244         ret = regulator_enable(st->vref_reg);
0245         if (ret)
0246             return ret;
0247 
0248         ret = devm_add_action_or_reset(&spi->dev, ad7303_reg_disable,
0249                            st->vref_reg);
0250         if (ret)
0251             return ret;
0252 
0253         st->config |= AD7303_CFG_EXTERNAL_VREF;
0254     }
0255 
0256     indio_dev->name = id->name;
0257     indio_dev->info = &ad7303_info;
0258     indio_dev->modes = INDIO_DIRECT_MODE;
0259     indio_dev->channels = ad7303_channels;
0260     indio_dev->num_channels = ARRAY_SIZE(ad7303_channels);
0261 
0262     return devm_iio_device_register(&spi->dev, indio_dev);
0263 }
0264 
0265 static const struct of_device_id ad7303_spi_of_match[] = {
0266     { .compatible = "adi,ad7303", },
0267     { /* sentinel */ },
0268 };
0269 MODULE_DEVICE_TABLE(of, ad7303_spi_of_match);
0270 
0271 static const struct spi_device_id ad7303_spi_ids[] = {
0272     { "ad7303", 0 },
0273     {}
0274 };
0275 MODULE_DEVICE_TABLE(spi, ad7303_spi_ids);
0276 
0277 static struct spi_driver ad7303_driver = {
0278     .driver = {
0279         .name = "ad7303",
0280         .of_match_table = ad7303_spi_of_match,
0281     },
0282     .probe = ad7303_probe,
0283     .id_table = ad7303_spi_ids,
0284 };
0285 module_spi_driver(ad7303_driver);
0286 
0287 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
0288 MODULE_DESCRIPTION("Analog Devices AD7303 DAC driver");
0289 MODULE_LICENSE("GPL v2");