Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /* ti-dac7311.c - Texas Instruments 8/10/12-bit 1-channel DAC driver
0003  *
0004  * Copyright (C) 2018 CMC NV
0005  *
0006  * https://www.ti.com/lit/ds/symlink/dac7311.pdf
0007  */
0008 
0009 #include <linux/iio/iio.h>
0010 #include <linux/module.h>
0011 #include <linux/regulator/consumer.h>
0012 #include <linux/spi/spi.h>
0013 
0014 enum {
0015     ID_DAC5311 = 0,
0016     ID_DAC6311,
0017     ID_DAC7311,
0018 };
0019 
0020 enum {
0021     POWER_1KOHM_TO_GND = 0,
0022     POWER_100KOHM_TO_GND,
0023     POWER_TRI_STATE,
0024 };
0025 
0026 struct ti_dac_spec {
0027     u8 resolution;
0028 };
0029 
0030 static const struct ti_dac_spec ti_dac_spec[] = {
0031     [ID_DAC5311] = { .resolution = 8 },
0032     [ID_DAC6311] = { .resolution = 10 },
0033     [ID_DAC7311] = { .resolution = 12 },
0034 };
0035 
0036 /**
0037  * struct ti_dac_chip - TI DAC chip
0038  * @lock: protects write sequences
0039  * @vref: regulator generating Vref
0040  * @spi: SPI device to send data to the device
0041  * @val: cached value
0042  * @powerdown: whether the chip is powered down
0043  * @powerdown_mode: selected by the user
0044  * @resolution: resolution of the chip
0045  * @buf: buffer for transfer data
0046  */
0047 struct ti_dac_chip {
0048     struct mutex lock;
0049     struct regulator *vref;
0050     struct spi_device *spi;
0051     u16 val;
0052     bool powerdown;
0053     u8 powerdown_mode;
0054     u8 resolution;
0055     u8 buf[2] __aligned(IIO_DMA_MINALIGN);
0056 };
0057 
0058 static u8 ti_dac_get_power(struct ti_dac_chip *ti_dac, bool powerdown)
0059 {
0060     if (powerdown)
0061         return ti_dac->powerdown_mode + 1;
0062 
0063     return 0;
0064 }
0065 
0066 static int ti_dac_cmd(struct ti_dac_chip *ti_dac, u8 power, u16 val)
0067 {
0068     u8 shift = 14 - ti_dac->resolution;
0069 
0070     ti_dac->buf[0] = (val << shift) & 0xFF;
0071     ti_dac->buf[1] = (power << 6) | (val >> (8 - shift));
0072     return spi_write(ti_dac->spi, ti_dac->buf, 2);
0073 }
0074 
0075 static const char * const ti_dac_powerdown_modes[] = {
0076     "1kohm_to_gnd",
0077     "100kohm_to_gnd",
0078     "three_state",
0079 };
0080 
0081 static int ti_dac_get_powerdown_mode(struct iio_dev *indio_dev,
0082                      const struct iio_chan_spec *chan)
0083 {
0084     struct ti_dac_chip *ti_dac = iio_priv(indio_dev);
0085 
0086     return ti_dac->powerdown_mode;
0087 }
0088 
0089 static int ti_dac_set_powerdown_mode(struct iio_dev *indio_dev,
0090                      const struct iio_chan_spec *chan,
0091                      unsigned int mode)
0092 {
0093     struct ti_dac_chip *ti_dac = iio_priv(indio_dev);
0094 
0095     ti_dac->powerdown_mode = mode;
0096     return 0;
0097 }
0098 
0099 static const struct iio_enum ti_dac_powerdown_mode = {
0100     .items = ti_dac_powerdown_modes,
0101     .num_items = ARRAY_SIZE(ti_dac_powerdown_modes),
0102     .get = ti_dac_get_powerdown_mode,
0103     .set = ti_dac_set_powerdown_mode,
0104 };
0105 
0106 static ssize_t ti_dac_read_powerdown(struct iio_dev *indio_dev,
0107                      uintptr_t private,
0108                      const struct iio_chan_spec *chan,
0109                      char *buf)
0110 {
0111     struct ti_dac_chip *ti_dac = iio_priv(indio_dev);
0112 
0113     return sysfs_emit(buf, "%d\n", ti_dac->powerdown);
0114 }
0115 
0116 static ssize_t ti_dac_write_powerdown(struct iio_dev *indio_dev,
0117                       uintptr_t private,
0118                       const struct iio_chan_spec *chan,
0119                       const char *buf, size_t len)
0120 {
0121     struct ti_dac_chip *ti_dac = iio_priv(indio_dev);
0122     bool powerdown;
0123     u8 power;
0124     int ret;
0125 
0126     ret = kstrtobool(buf, &powerdown);
0127     if (ret)
0128         return ret;
0129 
0130     power = ti_dac_get_power(ti_dac, powerdown);
0131 
0132     mutex_lock(&ti_dac->lock);
0133     ret = ti_dac_cmd(ti_dac, power, 0);
0134     if (!ret)
0135         ti_dac->powerdown = powerdown;
0136     mutex_unlock(&ti_dac->lock);
0137 
0138     return ret ? ret : len;
0139 }
0140 
0141 static const struct iio_chan_spec_ext_info ti_dac_ext_info[] = {
0142     {
0143         .name      = "powerdown",
0144         .read      = ti_dac_read_powerdown,
0145         .write     = ti_dac_write_powerdown,
0146         .shared    = IIO_SHARED_BY_TYPE,
0147     },
0148     IIO_ENUM("powerdown_mode", IIO_SHARED_BY_TYPE, &ti_dac_powerdown_mode),
0149     IIO_ENUM_AVAILABLE("powerdown_mode", IIO_SHARED_BY_TYPE, &ti_dac_powerdown_mode),
0150     { },
0151 };
0152 
0153 #define TI_DAC_CHANNEL(chan) {                  \
0154     .type = IIO_VOLTAGE,                    \
0155     .channel = (chan),                  \
0156     .output = true,                     \
0157     .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),       \
0158     .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),   \
0159     .ext_info = ti_dac_ext_info,                \
0160 }
0161 
0162 static const struct iio_chan_spec ti_dac_channels[] = {
0163     TI_DAC_CHANNEL(0),
0164 };
0165 
0166 static int ti_dac_read_raw(struct iio_dev *indio_dev,
0167                struct iio_chan_spec const *chan,
0168                int *val, int *val2, long mask)
0169 {
0170     struct ti_dac_chip *ti_dac = iio_priv(indio_dev);
0171     int ret;
0172 
0173     switch (mask) {
0174     case IIO_CHAN_INFO_RAW:
0175         *val = ti_dac->val;
0176         return IIO_VAL_INT;
0177 
0178     case IIO_CHAN_INFO_SCALE:
0179         ret = regulator_get_voltage(ti_dac->vref);
0180         if (ret < 0)
0181             return ret;
0182 
0183         *val = ret / 1000;
0184         *val2 = ti_dac->resolution;
0185         return IIO_VAL_FRACTIONAL_LOG2;
0186     }
0187 
0188     return -EINVAL;
0189 }
0190 
0191 static int ti_dac_write_raw(struct iio_dev *indio_dev,
0192                 struct iio_chan_spec const *chan,
0193                 int val, int val2, long mask)
0194 {
0195     struct ti_dac_chip *ti_dac = iio_priv(indio_dev);
0196     u8 power = ti_dac_get_power(ti_dac, ti_dac->powerdown);
0197     int ret;
0198 
0199     switch (mask) {
0200     case IIO_CHAN_INFO_RAW:
0201         if (ti_dac->val == val)
0202             return 0;
0203 
0204         if (val >= (1 << ti_dac->resolution) || val < 0)
0205             return -EINVAL;
0206 
0207         if (ti_dac->powerdown)
0208             return -EBUSY;
0209 
0210         mutex_lock(&ti_dac->lock);
0211         ret = ti_dac_cmd(ti_dac, power, val);
0212         if (!ret)
0213             ti_dac->val = val;
0214         mutex_unlock(&ti_dac->lock);
0215         break;
0216 
0217     default:
0218         ret = -EINVAL;
0219     }
0220 
0221     return ret;
0222 }
0223 
0224 static int ti_dac_write_raw_get_fmt(struct iio_dev *indio_dev,
0225                     struct iio_chan_spec const *chan, long mask)
0226 {
0227     return IIO_VAL_INT;
0228 }
0229 
0230 static const struct iio_info ti_dac_info = {
0231     .read_raw      = ti_dac_read_raw,
0232     .write_raw     = ti_dac_write_raw,
0233     .write_raw_get_fmt = ti_dac_write_raw_get_fmt,
0234 };
0235 
0236 static int ti_dac_probe(struct spi_device *spi)
0237 {
0238     struct device *dev = &spi->dev;
0239     const struct ti_dac_spec *spec;
0240     struct ti_dac_chip *ti_dac;
0241     struct iio_dev *indio_dev;
0242     int ret;
0243 
0244     indio_dev = devm_iio_device_alloc(dev, sizeof(*ti_dac));
0245     if (!indio_dev) {
0246         dev_err(dev, "can not allocate iio device\n");
0247         return -ENOMEM;
0248     }
0249 
0250     spi->mode = SPI_MODE_1;
0251     spi->bits_per_word = 16;
0252     spi_setup(spi);
0253 
0254     indio_dev->info = &ti_dac_info;
0255     indio_dev->name = spi_get_device_id(spi)->name;
0256     indio_dev->modes = INDIO_DIRECT_MODE;
0257     indio_dev->channels = ti_dac_channels;
0258     spi_set_drvdata(spi, indio_dev);
0259 
0260     ti_dac = iio_priv(indio_dev);
0261     ti_dac->powerdown = false;
0262     ti_dac->spi = spi;
0263 
0264     spec = &ti_dac_spec[spi_get_device_id(spi)->driver_data];
0265     indio_dev->num_channels = 1;
0266     ti_dac->resolution = spec->resolution;
0267 
0268     ti_dac->vref = devm_regulator_get(dev, "vref");
0269     if (IS_ERR(ti_dac->vref))
0270         return dev_err_probe(dev, PTR_ERR(ti_dac->vref),
0271                      "error to get regulator\n");
0272 
0273     ret = regulator_enable(ti_dac->vref);
0274     if (ret < 0) {
0275         dev_err(dev, "can not enable regulator\n");
0276         return ret;
0277     }
0278 
0279     mutex_init(&ti_dac->lock);
0280 
0281     ret = iio_device_register(indio_dev);
0282     if (ret) {
0283         dev_err(dev, "fail to register iio device: %d\n", ret);
0284         goto err;
0285     }
0286 
0287     return 0;
0288 
0289 err:
0290     mutex_destroy(&ti_dac->lock);
0291     regulator_disable(ti_dac->vref);
0292     return ret;
0293 }
0294 
0295 static void ti_dac_remove(struct spi_device *spi)
0296 {
0297     struct iio_dev *indio_dev = spi_get_drvdata(spi);
0298     struct ti_dac_chip *ti_dac = iio_priv(indio_dev);
0299 
0300     iio_device_unregister(indio_dev);
0301     mutex_destroy(&ti_dac->lock);
0302     regulator_disable(ti_dac->vref);
0303 }
0304 
0305 static const struct of_device_id ti_dac_of_id[] = {
0306     { .compatible = "ti,dac5311" },
0307     { .compatible = "ti,dac6311" },
0308     { .compatible = "ti,dac7311" },
0309     { }
0310 };
0311 MODULE_DEVICE_TABLE(of, ti_dac_of_id);
0312 
0313 static const struct spi_device_id ti_dac_spi_id[] = {
0314     { "dac5311", ID_DAC5311  },
0315     { "dac6311", ID_DAC6311 },
0316     { "dac7311", ID_DAC7311 },
0317     { }
0318 };
0319 MODULE_DEVICE_TABLE(spi, ti_dac_spi_id);
0320 
0321 static struct spi_driver ti_dac_driver = {
0322     .driver = {
0323         .name       = "ti-dac7311",
0324         .of_match_table = ti_dac_of_id,
0325     },
0326     .probe    = ti_dac_probe,
0327     .remove   = ti_dac_remove,
0328     .id_table = ti_dac_spi_id,
0329 };
0330 module_spi_driver(ti_dac_driver);
0331 
0332 MODULE_AUTHOR("Charles-Antoine Couret <charles-antoine.couret@essensium.com>");
0333 MODULE_DESCRIPTION("Texas Instruments 8/10/12-bit 1-channel DAC driver");
0334 MODULE_LICENSE("GPL v2");