Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Driver for Linear Technology LTC1665/LTC1660, 8 channels DAC
0004  *
0005  * Copyright (C) 2018 Marcus Folkesson <marcus.folkesson@gmail.com>
0006  */
0007 #include <linux/bitops.h>
0008 #include <linux/iio/iio.h>
0009 #include <linux/iio/sysfs.h>
0010 #include <linux/init.h>
0011 #include <linux/module.h>
0012 #include <linux/regulator/consumer.h>
0013 #include <linux/regmap.h>
0014 #include <linux/spi/spi.h>
0015 
0016 #define LTC1660_REG_WAKE    0x0
0017 #define LTC1660_REG_DAC_A   0x1
0018 #define LTC1660_REG_DAC_B   0x2
0019 #define LTC1660_REG_DAC_C   0x3
0020 #define LTC1660_REG_DAC_D   0x4
0021 #define LTC1660_REG_DAC_E   0x5
0022 #define LTC1660_REG_DAC_F   0x6
0023 #define LTC1660_REG_DAC_G   0x7
0024 #define LTC1660_REG_DAC_H   0x8
0025 #define LTC1660_REG_SLEEP   0xe
0026 
0027 #define LTC1660_NUM_CHANNELS    8
0028 
0029 static const struct regmap_config ltc1660_regmap_config = {
0030     .reg_bits = 4,
0031     .val_bits = 12,
0032 };
0033 
0034 enum ltc1660_supported_device_ids {
0035     ID_LTC1660,
0036     ID_LTC1665,
0037 };
0038 
0039 struct ltc1660_priv {
0040     struct spi_device *spi;
0041     struct regmap *regmap;
0042     struct regulator *vref_reg;
0043     unsigned int value[LTC1660_NUM_CHANNELS];
0044     unsigned int vref_mv;
0045 };
0046 
0047 static int ltc1660_read_raw(struct iio_dev *indio_dev,
0048         struct iio_chan_spec const *chan,
0049         int *val,
0050         int *val2,
0051         long mask)
0052 {
0053     struct ltc1660_priv *priv = iio_priv(indio_dev);
0054 
0055     switch (mask) {
0056     case IIO_CHAN_INFO_RAW:
0057         *val = priv->value[chan->channel];
0058         return IIO_VAL_INT;
0059     case IIO_CHAN_INFO_SCALE:
0060         *val = regulator_get_voltage(priv->vref_reg);
0061         if (*val < 0) {
0062             dev_err(&priv->spi->dev, "failed to read vref regulator: %d\n",
0063                     *val);
0064             return *val;
0065         }
0066 
0067         /* Convert to mV */
0068         *val /= 1000;
0069         *val2 = chan->scan_type.realbits;
0070         return IIO_VAL_FRACTIONAL_LOG2;
0071     default:
0072         return -EINVAL;
0073     }
0074 }
0075 
0076 static int ltc1660_write_raw(struct iio_dev *indio_dev,
0077         struct iio_chan_spec const *chan,
0078         int val,
0079         int val2,
0080         long mask)
0081 {
0082     struct ltc1660_priv *priv = iio_priv(indio_dev);
0083     int ret;
0084 
0085     switch (mask) {
0086     case IIO_CHAN_INFO_RAW:
0087         if (val2 != 0)
0088             return -EINVAL;
0089 
0090         if (val < 0 || val > GENMASK(chan->scan_type.realbits - 1, 0))
0091             return -EINVAL;
0092 
0093         ret = regmap_write(priv->regmap, chan->channel,
0094                     (val << chan->scan_type.shift));
0095         if (!ret)
0096             priv->value[chan->channel] = val;
0097 
0098         return ret;
0099     default:
0100         return -EINVAL;
0101     }
0102 }
0103 
0104 #define LTC1660_CHAN(chan, bits) {          \
0105     .type = IIO_VOLTAGE,                \
0106     .indexed = 1,                   \
0107     .output = 1,                    \
0108     .channel = chan,                \
0109     .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),   \
0110     .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),   \
0111     .scan_type = {                  \
0112         .sign = 'u',                \
0113         .realbits = (bits),         \
0114         .storagebits = 16,          \
0115         .shift = 12 - (bits),           \
0116     },                      \
0117 }
0118 
0119 #define  LTC1660_OCTAL_CHANNELS(bits) {         \
0120         LTC1660_CHAN(LTC1660_REG_DAC_A, bits),  \
0121         LTC1660_CHAN(LTC1660_REG_DAC_B, bits),  \
0122         LTC1660_CHAN(LTC1660_REG_DAC_C, bits),  \
0123         LTC1660_CHAN(LTC1660_REG_DAC_D, bits),  \
0124         LTC1660_CHAN(LTC1660_REG_DAC_E, bits),  \
0125         LTC1660_CHAN(LTC1660_REG_DAC_F, bits),  \
0126         LTC1660_CHAN(LTC1660_REG_DAC_G, bits),  \
0127         LTC1660_CHAN(LTC1660_REG_DAC_H, bits),  \
0128 }
0129 
0130 static const struct iio_chan_spec ltc1660_channels[][LTC1660_NUM_CHANNELS] = {
0131     [ID_LTC1660] = LTC1660_OCTAL_CHANNELS(10),
0132     [ID_LTC1665] = LTC1660_OCTAL_CHANNELS(8),
0133 };
0134 
0135 static const struct iio_info ltc1660_info = {
0136     .read_raw = &ltc1660_read_raw,
0137     .write_raw = &ltc1660_write_raw,
0138 };
0139 
0140 static int ltc1660_suspend(struct device *dev)
0141 {
0142     struct ltc1660_priv *priv = iio_priv(spi_get_drvdata(
0143                         to_spi_device(dev)));
0144     return regmap_write(priv->regmap, LTC1660_REG_SLEEP, 0x00);
0145 }
0146 
0147 static int ltc1660_resume(struct device *dev)
0148 {
0149     struct ltc1660_priv *priv = iio_priv(spi_get_drvdata(
0150                         to_spi_device(dev)));
0151     return regmap_write(priv->regmap, LTC1660_REG_WAKE, 0x00);
0152 }
0153 static DEFINE_SIMPLE_DEV_PM_OPS(ltc1660_pm_ops, ltc1660_suspend,
0154                 ltc1660_resume);
0155 
0156 static int ltc1660_probe(struct spi_device *spi)
0157 {
0158     struct iio_dev *indio_dev;
0159     struct ltc1660_priv *priv;
0160     const struct spi_device_id *id = spi_get_device_id(spi);
0161     int ret;
0162 
0163     indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*priv));
0164     if (indio_dev == NULL)
0165         return -ENOMEM;
0166 
0167     priv = iio_priv(indio_dev);
0168     priv->regmap = devm_regmap_init_spi(spi, &ltc1660_regmap_config);
0169     if (IS_ERR(priv->regmap)) {
0170         dev_err(&spi->dev, "failed to register spi regmap %ld\n",
0171             PTR_ERR(priv->regmap));
0172         return PTR_ERR(priv->regmap);
0173     }
0174 
0175     priv->vref_reg = devm_regulator_get(&spi->dev, "vref");
0176     if (IS_ERR(priv->vref_reg))
0177         return dev_err_probe(&spi->dev, PTR_ERR(priv->vref_reg),
0178                      "vref regulator not specified\n");
0179 
0180     ret = regulator_enable(priv->vref_reg);
0181     if (ret) {
0182         dev_err(&spi->dev, "failed to enable vref regulator: %d\n",
0183                 ret);
0184         return ret;
0185     }
0186 
0187     priv->spi = spi;
0188     spi_set_drvdata(spi, indio_dev);
0189     indio_dev->info = &ltc1660_info;
0190     indio_dev->modes = INDIO_DIRECT_MODE;
0191     indio_dev->channels = ltc1660_channels[id->driver_data];
0192     indio_dev->num_channels = LTC1660_NUM_CHANNELS;
0193     indio_dev->name = id->name;
0194 
0195     ret = iio_device_register(indio_dev);
0196     if (ret) {
0197         dev_err(&spi->dev, "failed to register iio device: %d\n",
0198                 ret);
0199         goto error_disable_reg;
0200     }
0201 
0202     return 0;
0203 
0204 error_disable_reg:
0205     regulator_disable(priv->vref_reg);
0206 
0207     return ret;
0208 }
0209 
0210 static void ltc1660_remove(struct spi_device *spi)
0211 {
0212     struct iio_dev *indio_dev = spi_get_drvdata(spi);
0213     struct ltc1660_priv *priv = iio_priv(indio_dev);
0214 
0215     iio_device_unregister(indio_dev);
0216     regulator_disable(priv->vref_reg);
0217 }
0218 
0219 static const struct of_device_id ltc1660_dt_ids[] = {
0220     { .compatible = "lltc,ltc1660", .data = (void *)ID_LTC1660 },
0221     { .compatible = "lltc,ltc1665", .data = (void *)ID_LTC1665 },
0222     { /* sentinel */ }
0223 };
0224 MODULE_DEVICE_TABLE(of, ltc1660_dt_ids);
0225 
0226 static const struct spi_device_id ltc1660_id[] = {
0227     {"ltc1660", ID_LTC1660},
0228     {"ltc1665", ID_LTC1665},
0229     { /* sentinel */ }
0230 };
0231 MODULE_DEVICE_TABLE(spi, ltc1660_id);
0232 
0233 static struct spi_driver ltc1660_driver = {
0234     .driver = {
0235         .name = "ltc1660",
0236         .of_match_table = ltc1660_dt_ids,
0237         .pm = pm_sleep_ptr(&ltc1660_pm_ops),
0238     },
0239     .probe  = ltc1660_probe,
0240     .remove = ltc1660_remove,
0241     .id_table = ltc1660_id,
0242 };
0243 module_spi_driver(ltc1660_driver);
0244 
0245 MODULE_AUTHOR("Marcus Folkesson <marcus.folkesson@gmail.com>");
0246 MODULE_DESCRIPTION("Linear Technology LTC1660/LTC1665 DAC");
0247 MODULE_LICENSE("GPL v2");