root/drivers/iio/dac/ad8801.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ad8801_spi_write
  2. ad8801_write_raw
  3. ad8801_read_raw
  4. ad8801_probe
  5. ad8801_remove

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * IIO DAC driver for Analog Devices AD8801 DAC
   4  *
   5  * Copyright (C) 2016 Gwenhael Goavec-Merou
   6  */
   7 
   8 #include <linux/iio/iio.h>
   9 #include <linux/module.h>
  10 #include <linux/regulator/consumer.h>
  11 #include <linux/spi/spi.h>
  12 #include <linux/sysfs.h>
  13 
  14 #define AD8801_CFG_ADDR_OFFSET 8
  15 
  16 enum ad8801_device_ids {
  17         ID_AD8801,
  18         ID_AD8803,
  19 };
  20 
  21 struct ad8801_state {
  22         struct spi_device *spi;
  23         unsigned char dac_cache[8]; /* Value write on each channel */
  24         unsigned int vrefh_mv;
  25         unsigned int vrefl_mv;
  26         struct regulator *vrefh_reg;
  27         struct regulator *vrefl_reg;
  28 
  29         __be16 data ____cacheline_aligned;
  30 };
  31 
  32 static int ad8801_spi_write(struct ad8801_state *state,
  33         u8 channel, unsigned char value)
  34 {
  35         state->data = cpu_to_be16((channel << AD8801_CFG_ADDR_OFFSET) | value);
  36         return spi_write(state->spi, &state->data, sizeof(state->data));
  37 }
  38 
  39 static int ad8801_write_raw(struct iio_dev *indio_dev,
  40         struct iio_chan_spec const *chan, int val, int val2, long mask)
  41 {
  42         struct ad8801_state *state = iio_priv(indio_dev);
  43         int ret;
  44 
  45         switch (mask) {
  46         case IIO_CHAN_INFO_RAW:
  47                 if (val >= 256 || val < 0)
  48                         return -EINVAL;
  49 
  50                 ret = ad8801_spi_write(state, chan->channel, val);
  51                 if (ret == 0)
  52                         state->dac_cache[chan->channel] = val;
  53                 break;
  54         default:
  55                 ret = -EINVAL;
  56         }
  57 
  58         return ret;
  59 }
  60 
  61 static int ad8801_read_raw(struct iio_dev *indio_dev,
  62         struct iio_chan_spec const *chan, int *val, int *val2, long info)
  63 {
  64         struct ad8801_state *state = iio_priv(indio_dev);
  65 
  66         switch (info) {
  67         case IIO_CHAN_INFO_RAW:
  68                 *val = state->dac_cache[chan->channel];
  69                 return IIO_VAL_INT;
  70         case IIO_CHAN_INFO_SCALE:
  71                 *val = state->vrefh_mv - state->vrefl_mv;
  72                 *val2 = 8;
  73                 return IIO_VAL_FRACTIONAL_LOG2;
  74         case IIO_CHAN_INFO_OFFSET:
  75                 *val = state->vrefl_mv;
  76                 return IIO_VAL_INT;
  77         default:
  78                 return -EINVAL;
  79         }
  80 
  81         return -EINVAL;
  82 }
  83 
  84 static const struct iio_info ad8801_info = {
  85         .read_raw = ad8801_read_raw,
  86         .write_raw = ad8801_write_raw,
  87 };
  88 
  89 #define AD8801_CHANNEL(chan) {          \
  90         .type = IIO_VOLTAGE,                    \
  91         .indexed = 1,                           \
  92         .output = 1,                            \
  93         .channel = chan,                        \
  94         .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
  95         .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |  \
  96                 BIT(IIO_CHAN_INFO_OFFSET), \
  97 }
  98 
  99 static const struct iio_chan_spec ad8801_channels[] = {
 100         AD8801_CHANNEL(0),
 101         AD8801_CHANNEL(1),
 102         AD8801_CHANNEL(2),
 103         AD8801_CHANNEL(3),
 104         AD8801_CHANNEL(4),
 105         AD8801_CHANNEL(5),
 106         AD8801_CHANNEL(6),
 107         AD8801_CHANNEL(7),
 108 };
 109 
 110 static int ad8801_probe(struct spi_device *spi)
 111 {
 112         struct iio_dev *indio_dev;
 113         struct ad8801_state *state;
 114         const struct spi_device_id *id;
 115         int ret;
 116 
 117         indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*state));
 118         if (indio_dev == NULL)
 119                 return -ENOMEM;
 120 
 121         state = iio_priv(indio_dev);
 122         state->spi = spi;
 123         id = spi_get_device_id(spi);
 124 
 125         state->vrefh_reg = devm_regulator_get(&spi->dev, "vrefh");
 126         if (IS_ERR(state->vrefh_reg)) {
 127                 dev_err(&spi->dev, "Vrefh regulator not specified\n");
 128                 return PTR_ERR(state->vrefh_reg);
 129         }
 130 
 131         ret = regulator_enable(state->vrefh_reg);
 132         if (ret) {
 133                 dev_err(&spi->dev, "Failed to enable vrefh regulator: %d\n",
 134                                 ret);
 135                 return ret;
 136         }
 137 
 138         ret = regulator_get_voltage(state->vrefh_reg);
 139         if (ret < 0) {
 140                 dev_err(&spi->dev, "Failed to read vrefh regulator: %d\n",
 141                                 ret);
 142                 goto error_disable_vrefh_reg;
 143         }
 144         state->vrefh_mv = ret / 1000;
 145 
 146         if (id->driver_data == ID_AD8803) {
 147                 state->vrefl_reg = devm_regulator_get(&spi->dev, "vrefl");
 148                 if (IS_ERR(state->vrefl_reg)) {
 149                         dev_err(&spi->dev, "Vrefl regulator not specified\n");
 150                         ret = PTR_ERR(state->vrefl_reg);
 151                         goto error_disable_vrefh_reg;
 152                 }
 153 
 154                 ret = regulator_enable(state->vrefl_reg);
 155                 if (ret) {
 156                         dev_err(&spi->dev, "Failed to enable vrefl regulator: %d\n",
 157                                         ret);
 158                         goto error_disable_vrefh_reg;
 159                 }
 160 
 161                 ret = regulator_get_voltage(state->vrefl_reg);
 162                 if (ret < 0) {
 163                         dev_err(&spi->dev, "Failed to read vrefl regulator: %d\n",
 164                                         ret);
 165                         goto error_disable_vrefl_reg;
 166                 }
 167                 state->vrefl_mv = ret / 1000;
 168         } else {
 169                 state->vrefl_mv = 0;
 170                 state->vrefl_reg = NULL;
 171         }
 172 
 173         spi_set_drvdata(spi, indio_dev);
 174         indio_dev->dev.parent = &spi->dev;
 175         indio_dev->info = &ad8801_info;
 176         indio_dev->modes = INDIO_DIRECT_MODE;
 177         indio_dev->channels = ad8801_channels;
 178         indio_dev->num_channels = ARRAY_SIZE(ad8801_channels);
 179         indio_dev->name = id->name;
 180 
 181         ret = iio_device_register(indio_dev);
 182         if (ret) {
 183                 dev_err(&spi->dev, "Failed to register iio device: %d\n",
 184                                 ret);
 185                 goto error_disable_vrefl_reg;
 186         }
 187 
 188         return 0;
 189 
 190 error_disable_vrefl_reg:
 191         if (state->vrefl_reg)
 192                 regulator_disable(state->vrefl_reg);
 193 error_disable_vrefh_reg:
 194         regulator_disable(state->vrefh_reg);
 195         return ret;
 196 }
 197 
 198 static int ad8801_remove(struct spi_device *spi)
 199 {
 200         struct iio_dev *indio_dev = spi_get_drvdata(spi);
 201         struct ad8801_state *state = iio_priv(indio_dev);
 202 
 203         iio_device_unregister(indio_dev);
 204         if (state->vrefl_reg)
 205                 regulator_disable(state->vrefl_reg);
 206         regulator_disable(state->vrefh_reg);
 207 
 208         return 0;
 209 }
 210 
 211 static const struct spi_device_id ad8801_ids[] = {
 212         {"ad8801", ID_AD8801},
 213         {"ad8803", ID_AD8803},
 214         {}
 215 };
 216 MODULE_DEVICE_TABLE(spi, ad8801_ids);
 217 
 218 static struct spi_driver ad8801_driver = {
 219         .driver = {
 220                 .name   = "ad8801",
 221         },
 222         .probe          = ad8801_probe,
 223         .remove         = ad8801_remove,
 224         .id_table       = ad8801_ids,
 225 };
 226 module_spi_driver(ad8801_driver);
 227 
 228 MODULE_AUTHOR("Gwenhael Goavec-Merou <gwenhael.goavec-merou@trabucayre.com>");
 229 MODULE_DESCRIPTION("Analog Devices AD8801/AD8803 DAC");
 230 MODULE_LICENSE("GPL v2");

/* [<][>][^][v][top][bottom][index][help] */