root/drivers/iio/dac/ltc1660.c

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

DEFINITIONS

This source file includes following definitions.
  1. ltc1660_read_raw
  2. ltc1660_write_raw
  3. ltc1660_suspend
  4. ltc1660_resume
  5. ltc1660_probe
  6. ltc1660_remove

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * Driver for Linear Technology LTC1665/LTC1660, 8 channels DAC
   4  *
   5  * Copyright (C) 2018 Marcus Folkesson <marcus.folkesson@gmail.com>
   6  */
   7 #include <linux/bitops.h>
   8 #include <linux/iio/iio.h>
   9 #include <linux/iio/sysfs.h>
  10 #include <linux/init.h>
  11 #include <linux/module.h>
  12 #include <linux/regulator/consumer.h>
  13 #include <linux/regmap.h>
  14 #include <linux/spi/spi.h>
  15 
  16 #define LTC1660_REG_WAKE        0x0
  17 #define LTC1660_REG_DAC_A       0x1
  18 #define LTC1660_REG_DAC_B       0x2
  19 #define LTC1660_REG_DAC_C       0x3
  20 #define LTC1660_REG_DAC_D       0x4
  21 #define LTC1660_REG_DAC_E       0x5
  22 #define LTC1660_REG_DAC_F       0x6
  23 #define LTC1660_REG_DAC_G       0x7
  24 #define LTC1660_REG_DAC_H       0x8
  25 #define LTC1660_REG_SLEEP       0xe
  26 
  27 #define LTC1660_NUM_CHANNELS    8
  28 
  29 static const struct regmap_config ltc1660_regmap_config = {
  30         .reg_bits = 4,
  31         .val_bits = 12,
  32 };
  33 
  34 enum ltc1660_supported_device_ids {
  35         ID_LTC1660,
  36         ID_LTC1665,
  37 };
  38 
  39 struct ltc1660_priv {
  40         struct spi_device *spi;
  41         struct regmap *regmap;
  42         struct regulator *vref_reg;
  43         unsigned int value[LTC1660_NUM_CHANNELS];
  44         unsigned int vref_mv;
  45 };
  46 
  47 static int ltc1660_read_raw(struct iio_dev *indio_dev,
  48                 struct iio_chan_spec const *chan,
  49                 int *val,
  50                 int *val2,
  51                 long mask)
  52 {
  53         struct ltc1660_priv *priv = iio_priv(indio_dev);
  54 
  55         switch (mask) {
  56         case IIO_CHAN_INFO_RAW:
  57                 *val = priv->value[chan->channel];
  58                 return IIO_VAL_INT;
  59         case IIO_CHAN_INFO_SCALE:
  60                 *val = regulator_get_voltage(priv->vref_reg);
  61                 if (*val < 0) {
  62                         dev_err(&priv->spi->dev, "failed to read vref regulator: %d\n",
  63                                         *val);
  64                         return *val;
  65                 }
  66 
  67                 /* Convert to mV */
  68                 *val /= 1000;
  69                 *val2 = chan->scan_type.realbits;
  70                 return IIO_VAL_FRACTIONAL_LOG2;
  71         default:
  72                 return -EINVAL;
  73         }
  74 }
  75 
  76 static int ltc1660_write_raw(struct iio_dev *indio_dev,
  77                 struct iio_chan_spec const *chan,
  78                 int val,
  79                 int val2,
  80                 long mask)
  81 {
  82         struct ltc1660_priv *priv = iio_priv(indio_dev);
  83         int ret;
  84 
  85         switch (mask) {
  86         case IIO_CHAN_INFO_RAW:
  87                 if (val2 != 0)
  88                         return -EINVAL;
  89 
  90                 if (val < 0 || val > GENMASK(chan->scan_type.realbits - 1, 0))
  91                         return -EINVAL;
  92 
  93                 ret = regmap_write(priv->regmap, chan->channel,
  94                                         (val << chan->scan_type.shift));
  95                 if (!ret)
  96                         priv->value[chan->channel] = val;
  97 
  98                 return ret;
  99         default:
 100                 return -EINVAL;
 101         }
 102 }
 103 
 104 #define LTC1660_CHAN(chan, bits) {                      \
 105         .type = IIO_VOLTAGE,                            \
 106         .indexed = 1,                                   \
 107         .output = 1,                                    \
 108         .channel = chan,                                \
 109         .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),   \
 110         .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),   \
 111         .scan_type = {                                  \
 112                 .sign = 'u',                            \
 113                 .realbits = (bits),                     \
 114                 .storagebits = 16,                      \
 115                 .shift = 12 - (bits),                   \
 116         },                                              \
 117 }
 118 
 119 #define  LTC1660_OCTAL_CHANNELS(bits) {                 \
 120                 LTC1660_CHAN(LTC1660_REG_DAC_A, bits),  \
 121                 LTC1660_CHAN(LTC1660_REG_DAC_B, bits),  \
 122                 LTC1660_CHAN(LTC1660_REG_DAC_C, bits),  \
 123                 LTC1660_CHAN(LTC1660_REG_DAC_D, bits),  \
 124                 LTC1660_CHAN(LTC1660_REG_DAC_E, bits),  \
 125                 LTC1660_CHAN(LTC1660_REG_DAC_F, bits),  \
 126                 LTC1660_CHAN(LTC1660_REG_DAC_G, bits),  \
 127                 LTC1660_CHAN(LTC1660_REG_DAC_H, bits),  \
 128 }
 129 
 130 static const struct iio_chan_spec ltc1660_channels[][LTC1660_NUM_CHANNELS] = {
 131         [ID_LTC1660] = LTC1660_OCTAL_CHANNELS(10),
 132         [ID_LTC1665] = LTC1660_OCTAL_CHANNELS(8),
 133 };
 134 
 135 static const struct iio_info ltc1660_info = {
 136         .read_raw = &ltc1660_read_raw,
 137         .write_raw = &ltc1660_write_raw,
 138 };
 139 
 140 static int __maybe_unused ltc1660_suspend(struct device *dev)
 141 {
 142         struct ltc1660_priv *priv = iio_priv(spi_get_drvdata(
 143                                                 to_spi_device(dev)));
 144         return regmap_write(priv->regmap, LTC1660_REG_SLEEP, 0x00);
 145 }
 146 
 147 static int __maybe_unused ltc1660_resume(struct device *dev)
 148 {
 149         struct ltc1660_priv *priv = iio_priv(spi_get_drvdata(
 150                                                 to_spi_device(dev)));
 151         return regmap_write(priv->regmap, LTC1660_REG_WAKE, 0x00);
 152 }
 153 static SIMPLE_DEV_PM_OPS(ltc1660_pm_ops, ltc1660_suspend, ltc1660_resume);
 154 
 155 static int ltc1660_probe(struct spi_device *spi)
 156 {
 157         struct iio_dev *indio_dev;
 158         struct ltc1660_priv *priv;
 159         const struct spi_device_id *id = spi_get_device_id(spi);
 160         int ret;
 161 
 162         indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*priv));
 163         if (indio_dev == NULL)
 164                 return -ENOMEM;
 165 
 166         priv = iio_priv(indio_dev);
 167         priv->regmap = devm_regmap_init_spi(spi, &ltc1660_regmap_config);
 168         if (IS_ERR(priv->regmap)) {
 169                 dev_err(&spi->dev, "failed to register spi regmap %ld\n",
 170                         PTR_ERR(priv->regmap));
 171                 return PTR_ERR(priv->regmap);
 172         }
 173 
 174         priv->vref_reg = devm_regulator_get(&spi->dev, "vref");
 175         if (IS_ERR(priv->vref_reg)) {
 176                 dev_err(&spi->dev, "vref regulator not specified\n");
 177                 return PTR_ERR(priv->vref_reg);
 178         }
 179 
 180         ret = regulator_enable(priv->vref_reg);
 181         if (ret) {
 182                 dev_err(&spi->dev, "failed to enable vref regulator: %d\n",
 183                                 ret);
 184                 return ret;
 185         }
 186 
 187         priv->spi = spi;
 188         spi_set_drvdata(spi, indio_dev);
 189         indio_dev->dev.parent = &spi->dev;
 190         indio_dev->info = &ltc1660_info;
 191         indio_dev->modes = INDIO_DIRECT_MODE;
 192         indio_dev->channels = ltc1660_channels[id->driver_data];
 193         indio_dev->num_channels = LTC1660_NUM_CHANNELS;
 194         indio_dev->name = id->name;
 195 
 196         ret = iio_device_register(indio_dev);
 197         if (ret) {
 198                 dev_err(&spi->dev, "failed to register iio device: %d\n",
 199                                 ret);
 200                 goto error_disable_reg;
 201         }
 202 
 203         return 0;
 204 
 205 error_disable_reg:
 206         regulator_disable(priv->vref_reg);
 207 
 208         return ret;
 209 }
 210 
 211 static int ltc1660_remove(struct spi_device *spi)
 212 {
 213         struct iio_dev *indio_dev = spi_get_drvdata(spi);
 214         struct ltc1660_priv *priv = iio_priv(indio_dev);
 215 
 216         iio_device_unregister(indio_dev);
 217         regulator_disable(priv->vref_reg);
 218 
 219         return 0;
 220 }
 221 
 222 static const struct of_device_id ltc1660_dt_ids[] = {
 223         { .compatible = "lltc,ltc1660", .data = (void *)ID_LTC1660 },
 224         { .compatible = "lltc,ltc1665", .data = (void *)ID_LTC1665 },
 225         { /* sentinel */ }
 226 };
 227 MODULE_DEVICE_TABLE(of, ltc1660_dt_ids);
 228 
 229 static const struct spi_device_id ltc1660_id[] = {
 230         {"ltc1660", ID_LTC1660},
 231         {"ltc1665", ID_LTC1665},
 232         { /* sentinel */ }
 233 };
 234 MODULE_DEVICE_TABLE(spi, ltc1660_id);
 235 
 236 static struct spi_driver ltc1660_driver = {
 237         .driver = {
 238                 .name = "ltc1660",
 239                 .of_match_table = ltc1660_dt_ids,
 240                 .pm = &ltc1660_pm_ops,
 241         },
 242         .probe  = ltc1660_probe,
 243         .remove = ltc1660_remove,
 244         .id_table = ltc1660_id,
 245 };
 246 module_spi_driver(ltc1660_driver);
 247 
 248 MODULE_AUTHOR("Marcus Folkesson <marcus.folkesson@gmail.com>");
 249 MODULE_DESCRIPTION("Linear Technology LTC1660/LTC1665 DAC");
 250 MODULE_LICENSE("GPL v2");

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