Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * ti-dac5571.c - Texas Instruments 8/10/12-bit 1/4-channel DAC driver
0004  *
0005  * Copyright (C) 2018 Prevas A/S
0006  *
0007  * https://www.ti.com/lit/ds/symlink/dac5571.pdf
0008  * https://www.ti.com/lit/ds/symlink/dac6571.pdf
0009  * https://www.ti.com/lit/ds/symlink/dac7571.pdf
0010  * https://www.ti.com/lit/ds/symlink/dac5574.pdf
0011  * https://www.ti.com/lit/ds/symlink/dac6574.pdf
0012  * https://www.ti.com/lit/ds/symlink/dac7574.pdf
0013  * https://www.ti.com/lit/ds/symlink/dac5573.pdf
0014  * https://www.ti.com/lit/ds/symlink/dac6573.pdf
0015  * https://www.ti.com/lit/ds/symlink/dac7573.pdf
0016  * https://www.ti.com/lit/ds/symlink/dac121c081.pdf
0017  */
0018 
0019 #include <linux/iio/iio.h>
0020 #include <linux/i2c.h>
0021 #include <linux/module.h>
0022 #include <linux/mod_devicetable.h>
0023 #include <linux/property.h>
0024 #include <linux/regulator/consumer.h>
0025 
0026 enum chip_id {
0027     single_8bit, single_10bit, single_12bit,
0028     quad_8bit, quad_10bit, quad_12bit
0029 };
0030 
0031 struct dac5571_spec {
0032     u8 num_channels;
0033     u8 resolution;
0034 };
0035 
0036 static const struct dac5571_spec dac5571_spec[] = {
0037     [single_8bit]  = {.num_channels = 1, .resolution =  8},
0038     [single_10bit] = {.num_channels = 1, .resolution = 10},
0039     [single_12bit] = {.num_channels = 1, .resolution = 12},
0040     [quad_8bit]    = {.num_channels = 4, .resolution =  8},
0041     [quad_10bit]   = {.num_channels = 4, .resolution = 10},
0042     [quad_12bit]   = {.num_channels = 4, .resolution = 12},
0043 };
0044 
0045 struct dac5571_data {
0046     struct i2c_client *client;
0047     int id;
0048     struct mutex lock;
0049     struct regulator *vref;
0050     u16 val[4];
0051     bool powerdown[4];
0052     u8 powerdown_mode[4];
0053     struct dac5571_spec const *spec;
0054     int (*dac5571_cmd)(struct dac5571_data *data, int channel, u16 val);
0055     int (*dac5571_pwrdwn)(struct dac5571_data *data, int channel, u8 pwrdwn);
0056     u8 buf[3] __aligned(IIO_DMA_MINALIGN);
0057 };
0058 
0059 #define DAC5571_POWERDOWN(mode)     ((mode) + 1)
0060 #define DAC5571_POWERDOWN_FLAG      BIT(0)
0061 #define DAC5571_CHANNEL_SELECT      1
0062 #define DAC5571_LOADMODE_DIRECT     BIT(4)
0063 #define DAC5571_SINGLE_PWRDWN_BITS  4
0064 #define DAC5571_QUAD_PWRDWN_BITS    6
0065 
0066 static int dac5571_cmd_single(struct dac5571_data *data, int channel, u16 val)
0067 {
0068     unsigned int shift;
0069 
0070     shift = 12 - data->spec->resolution;
0071     data->buf[1] = val << shift;
0072     data->buf[0] = val >> (8 - shift);
0073 
0074     if (i2c_master_send(data->client, data->buf, 2) != 2)
0075         return -EIO;
0076 
0077     return 0;
0078 }
0079 
0080 static int dac5571_cmd_quad(struct dac5571_data *data, int channel, u16 val)
0081 {
0082     unsigned int shift;
0083 
0084     shift = 16 - data->spec->resolution;
0085     data->buf[2] = val << shift;
0086     data->buf[1] = (val >> (8 - shift));
0087     data->buf[0] = (channel << DAC5571_CHANNEL_SELECT) |
0088                DAC5571_LOADMODE_DIRECT;
0089 
0090     if (i2c_master_send(data->client, data->buf, 3) != 3)
0091         return -EIO;
0092 
0093     return 0;
0094 }
0095 
0096 static int dac5571_pwrdwn_single(struct dac5571_data *data, int channel, u8 pwrdwn)
0097 {
0098     data->buf[1] = 0;
0099     data->buf[0] = pwrdwn << DAC5571_SINGLE_PWRDWN_BITS;
0100 
0101     if (i2c_master_send(data->client, data->buf, 2) != 2)
0102         return -EIO;
0103 
0104     return 0;
0105 }
0106 
0107 static int dac5571_pwrdwn_quad(struct dac5571_data *data, int channel, u8 pwrdwn)
0108 {
0109     data->buf[2] = 0;
0110     data->buf[1] = pwrdwn << DAC5571_QUAD_PWRDWN_BITS;
0111     data->buf[0] = (channel << DAC5571_CHANNEL_SELECT) |
0112                DAC5571_LOADMODE_DIRECT | DAC5571_POWERDOWN_FLAG;
0113 
0114     if (i2c_master_send(data->client, data->buf, 3) != 3)
0115         return -EIO;
0116 
0117     return 0;
0118 }
0119 
0120 static const char *const dac5571_powerdown_modes[] = {
0121     "1kohm_to_gnd", "100kohm_to_gnd", "three_state",
0122 };
0123 
0124 static int dac5571_get_powerdown_mode(struct iio_dev *indio_dev,
0125                       const struct iio_chan_spec *chan)
0126 {
0127     struct dac5571_data *data = iio_priv(indio_dev);
0128 
0129     return data->powerdown_mode[chan->channel];
0130 }
0131 
0132 static int dac5571_set_powerdown_mode(struct iio_dev *indio_dev,
0133                       const struct iio_chan_spec *chan,
0134                       unsigned int mode)
0135 {
0136     struct dac5571_data *data = iio_priv(indio_dev);
0137     int ret = 0;
0138 
0139     if (data->powerdown_mode[chan->channel] == mode)
0140         return 0;
0141 
0142     mutex_lock(&data->lock);
0143     if (data->powerdown[chan->channel]) {
0144         ret = data->dac5571_pwrdwn(data, chan->channel,
0145                        DAC5571_POWERDOWN(mode));
0146         if (ret)
0147             goto out;
0148     }
0149     data->powerdown_mode[chan->channel] = mode;
0150 
0151  out:
0152     mutex_unlock(&data->lock);
0153 
0154     return ret;
0155 }
0156 
0157 static const struct iio_enum dac5571_powerdown_mode = {
0158     .items = dac5571_powerdown_modes,
0159     .num_items = ARRAY_SIZE(dac5571_powerdown_modes),
0160     .get = dac5571_get_powerdown_mode,
0161     .set = dac5571_set_powerdown_mode,
0162 };
0163 
0164 static ssize_t dac5571_read_powerdown(struct iio_dev *indio_dev,
0165                       uintptr_t private,
0166                       const struct iio_chan_spec *chan,
0167                       char *buf)
0168 {
0169     struct dac5571_data *data = iio_priv(indio_dev);
0170 
0171     return sysfs_emit(buf, "%d\n", data->powerdown[chan->channel]);
0172 }
0173 
0174 static ssize_t dac5571_write_powerdown(struct iio_dev *indio_dev,
0175                        uintptr_t private,
0176                        const struct iio_chan_spec *chan,
0177                        const char *buf, size_t len)
0178 {
0179     struct dac5571_data *data = iio_priv(indio_dev);
0180     bool powerdown;
0181     int ret;
0182 
0183     ret = kstrtobool(buf, &powerdown);
0184     if (ret)
0185         return ret;
0186 
0187     if (data->powerdown[chan->channel] == powerdown)
0188         return len;
0189 
0190     mutex_lock(&data->lock);
0191     if (powerdown)
0192         ret = data->dac5571_pwrdwn(data, chan->channel,
0193                 DAC5571_POWERDOWN(data->powerdown_mode[chan->channel]));
0194     else
0195         ret = data->dac5571_cmd(data, chan->channel,
0196                 data->val[chan->channel]);
0197     if (ret)
0198         goto out;
0199 
0200     data->powerdown[chan->channel] = powerdown;
0201 
0202  out:
0203     mutex_unlock(&data->lock);
0204 
0205     return ret ? ret : len;
0206 }
0207 
0208 
0209 static const struct iio_chan_spec_ext_info dac5571_ext_info[] = {
0210     {
0211         .name      = "powerdown",
0212         .read      = dac5571_read_powerdown,
0213         .write     = dac5571_write_powerdown,
0214         .shared    = IIO_SEPARATE,
0215     },
0216     IIO_ENUM("powerdown_mode", IIO_SEPARATE, &dac5571_powerdown_mode),
0217     IIO_ENUM_AVAILABLE("powerdown_mode", IIO_SHARED_BY_TYPE, &dac5571_powerdown_mode),
0218     {},
0219 };
0220 
0221 #define dac5571_CHANNEL(chan, name) {               \
0222     .type = IIO_VOLTAGE,                    \
0223     .channel = (chan),                  \
0224     .address = (chan),                  \
0225     .indexed = true,                    \
0226     .output = true,                     \
0227     .datasheet_name = name,                 \
0228     .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),       \
0229     .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),   \
0230     .ext_info = dac5571_ext_info,               \
0231 }
0232 
0233 static const struct iio_chan_spec dac5571_channels[] = {
0234     dac5571_CHANNEL(0, "A"),
0235     dac5571_CHANNEL(1, "B"),
0236     dac5571_CHANNEL(2, "C"),
0237     dac5571_CHANNEL(3, "D"),
0238 };
0239 
0240 static int dac5571_read_raw(struct iio_dev *indio_dev,
0241                 struct iio_chan_spec const *chan,
0242                 int *val, int *val2, long mask)
0243 {
0244     struct dac5571_data *data = iio_priv(indio_dev);
0245     int ret;
0246 
0247     switch (mask) {
0248     case IIO_CHAN_INFO_RAW:
0249         *val = data->val[chan->channel];
0250         return IIO_VAL_INT;
0251 
0252     case IIO_CHAN_INFO_SCALE:
0253         ret = regulator_get_voltage(data->vref);
0254         if (ret < 0)
0255             return ret;
0256 
0257         *val = ret / 1000;
0258         *val2 = data->spec->resolution;
0259         return IIO_VAL_FRACTIONAL_LOG2;
0260 
0261     default:
0262         return -EINVAL;
0263     }
0264 }
0265 
0266 static int dac5571_write_raw(struct iio_dev *indio_dev,
0267                  struct iio_chan_spec const *chan,
0268                  int val, int val2, long mask)
0269 {
0270     struct dac5571_data *data = iio_priv(indio_dev);
0271     int ret;
0272 
0273     switch (mask) {
0274     case IIO_CHAN_INFO_RAW:
0275         if (data->val[chan->channel] == val)
0276             return 0;
0277 
0278         if (val >= (1 << data->spec->resolution) || val < 0)
0279             return -EINVAL;
0280 
0281         if (data->powerdown[chan->channel])
0282             return -EBUSY;
0283 
0284         mutex_lock(&data->lock);
0285         ret = data->dac5571_cmd(data, chan->channel, val);
0286         if (ret == 0)
0287             data->val[chan->channel] = val;
0288         mutex_unlock(&data->lock);
0289         return ret;
0290 
0291     default:
0292         return -EINVAL;
0293     }
0294 }
0295 
0296 static int dac5571_write_raw_get_fmt(struct iio_dev *indio_dev,
0297                      struct iio_chan_spec const *chan,
0298                      long mask)
0299 {
0300     return IIO_VAL_INT;
0301 }
0302 
0303 static const struct iio_info dac5571_info = {
0304     .read_raw = dac5571_read_raw,
0305     .write_raw = dac5571_write_raw,
0306     .write_raw_get_fmt = dac5571_write_raw_get_fmt,
0307 };
0308 
0309 static int dac5571_probe(struct i2c_client *client,
0310              const struct i2c_device_id *id)
0311 {
0312     struct device *dev = &client->dev;
0313     const struct dac5571_spec *spec;
0314     struct dac5571_data *data;
0315     struct iio_dev *indio_dev;
0316     enum chip_id chip_id;
0317     int ret, i;
0318 
0319     indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
0320     if (!indio_dev)
0321         return -ENOMEM;
0322 
0323     data = iio_priv(indio_dev);
0324     i2c_set_clientdata(client, indio_dev);
0325     data->client = client;
0326 
0327     indio_dev->info = &dac5571_info;
0328     indio_dev->name = id->name;
0329     indio_dev->modes = INDIO_DIRECT_MODE;
0330     indio_dev->channels = dac5571_channels;
0331 
0332     if (dev_fwnode(dev))
0333         chip_id = (uintptr_t)device_get_match_data(dev);
0334     else
0335         chip_id = id->driver_data;
0336 
0337     spec = &dac5571_spec[chip_id];
0338 
0339     indio_dev->num_channels = spec->num_channels;
0340     data->spec = spec;
0341 
0342     data->vref = devm_regulator_get(dev, "vref");
0343     if (IS_ERR(data->vref))
0344         return PTR_ERR(data->vref);
0345 
0346     ret = regulator_enable(data->vref);
0347     if (ret < 0)
0348         return ret;
0349 
0350     mutex_init(&data->lock);
0351 
0352     switch (spec->num_channels) {
0353     case 1:
0354         data->dac5571_cmd = dac5571_cmd_single;
0355         data->dac5571_pwrdwn = dac5571_pwrdwn_single;
0356         break;
0357     case 4:
0358         data->dac5571_cmd = dac5571_cmd_quad;
0359         data->dac5571_pwrdwn = dac5571_pwrdwn_quad;
0360         break;
0361     default:
0362         ret = -EINVAL;
0363         goto err;
0364     }
0365 
0366     for (i = 0; i < spec->num_channels; i++) {
0367         ret = data->dac5571_cmd(data, i, 0);
0368         if (ret) {
0369             dev_err(dev, "failed to initialize channel %d to 0\n", i);
0370             goto err;
0371         }
0372     }
0373 
0374     ret = iio_device_register(indio_dev);
0375     if (ret)
0376         goto err;
0377 
0378     return 0;
0379 
0380  err:
0381     regulator_disable(data->vref);
0382     return ret;
0383 }
0384 
0385 static int dac5571_remove(struct i2c_client *i2c)
0386 {
0387     struct iio_dev *indio_dev = i2c_get_clientdata(i2c);
0388     struct dac5571_data *data = iio_priv(indio_dev);
0389 
0390     iio_device_unregister(indio_dev);
0391     regulator_disable(data->vref);
0392 
0393     return 0;
0394 }
0395 
0396 static const struct of_device_id dac5571_of_id[] = {
0397     {.compatible = "ti,dac5571", .data = (void *)single_8bit},
0398     {.compatible = "ti,dac6571", .data = (void *)single_10bit},
0399     {.compatible = "ti,dac7571", .data = (void *)single_12bit},
0400     {.compatible = "ti,dac5574", .data = (void *)quad_8bit},
0401     {.compatible = "ti,dac6574", .data = (void *)quad_10bit},
0402     {.compatible = "ti,dac7574", .data = (void *)quad_12bit},
0403     {.compatible = "ti,dac5573", .data = (void *)quad_8bit},
0404     {.compatible = "ti,dac6573", .data = (void *)quad_10bit},
0405     {.compatible = "ti,dac7573", .data = (void *)quad_12bit},
0406     {.compatible = "ti,dac121c081", .data = (void *)single_12bit},
0407     {}
0408 };
0409 MODULE_DEVICE_TABLE(of, dac5571_of_id);
0410 
0411 static const struct i2c_device_id dac5571_id[] = {
0412     {"dac5571", single_8bit},
0413     {"dac6571", single_10bit},
0414     {"dac7571", single_12bit},
0415     {"dac5574", quad_8bit},
0416     {"dac6574", quad_10bit},
0417     {"dac7574", quad_12bit},
0418     {"dac5573", quad_8bit},
0419     {"dac6573", quad_10bit},
0420     {"dac7573", quad_12bit},
0421     {"dac121c081", single_12bit},
0422     {}
0423 };
0424 MODULE_DEVICE_TABLE(i2c, dac5571_id);
0425 
0426 static struct i2c_driver dac5571_driver = {
0427     .driver = {
0428            .name = "ti-dac5571",
0429            .of_match_table = dac5571_of_id,
0430     },
0431     .probe    = dac5571_probe,
0432     .remove   = dac5571_remove,
0433     .id_table = dac5571_id,
0434 };
0435 module_i2c_driver(dac5571_driver);
0436 
0437 MODULE_AUTHOR("Sean Nyekjaer <sean@geanix.dk>");
0438 MODULE_DESCRIPTION("Texas Instruments 8/10/12-bit 1/4-channel DAC driver");
0439 MODULE_LICENSE("GPL v2");