root/drivers/iio/dac/ti-dac5571.c

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

DEFINITIONS

This source file includes following definitions.
  1. dac5571_cmd_single
  2. dac5571_cmd_quad
  3. dac5571_pwrdwn_single
  4. dac5571_pwrdwn_quad
  5. dac5571_get_powerdown_mode
  6. dac5571_set_powerdown_mode
  7. dac5571_read_powerdown
  8. dac5571_write_powerdown
  9. dac5571_read_raw
  10. dac5571_write_raw
  11. dac5571_write_raw_get_fmt
  12. dac5571_probe
  13. dac5571_remove

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * ti-dac5571.c - Texas Instruments 8/10/12-bit 1/4-channel DAC driver
   4  *
   5  * Copyright (C) 2018 Prevas A/S
   6  *
   7  * http://www.ti.com/lit/ds/symlink/dac5571.pdf
   8  * http://www.ti.com/lit/ds/symlink/dac6571.pdf
   9  * http://www.ti.com/lit/ds/symlink/dac7571.pdf
  10  * http://www.ti.com/lit/ds/symlink/dac5574.pdf
  11  * http://www.ti.com/lit/ds/symlink/dac6574.pdf
  12  * http://www.ti.com/lit/ds/symlink/dac7574.pdf
  13  * http://www.ti.com/lit/ds/symlink/dac5573.pdf
  14  * http://www.ti.com/lit/ds/symlink/dac6573.pdf
  15  * http://www.ti.com/lit/ds/symlink/dac7573.pdf
  16  */
  17 
  18 #include <linux/iio/iio.h>
  19 #include <linux/i2c.h>
  20 #include <linux/module.h>
  21 #include <linux/of_device.h>
  22 #include <linux/of.h>
  23 #include <linux/regulator/consumer.h>
  24 
  25 enum chip_id {
  26         single_8bit, single_10bit, single_12bit,
  27         quad_8bit, quad_10bit, quad_12bit
  28 };
  29 
  30 struct dac5571_spec {
  31         u8 num_channels;
  32         u8 resolution;
  33 };
  34 
  35 static const struct dac5571_spec dac5571_spec[] = {
  36         [single_8bit]  = {.num_channels = 1, .resolution =  8},
  37         [single_10bit] = {.num_channels = 1, .resolution = 10},
  38         [single_12bit] = {.num_channels = 1, .resolution = 12},
  39         [quad_8bit]    = {.num_channels = 4, .resolution =  8},
  40         [quad_10bit]   = {.num_channels = 4, .resolution = 10},
  41         [quad_12bit]   = {.num_channels = 4, .resolution = 12},
  42 };
  43 
  44 struct dac5571_data {
  45         struct i2c_client *client;
  46         int id;
  47         struct mutex lock;
  48         struct regulator *vref;
  49         u16 val[4];
  50         bool powerdown;
  51         u8 powerdown_mode;
  52         struct dac5571_spec const *spec;
  53         int (*dac5571_cmd)(struct dac5571_data *data, int channel, u16 val);
  54         int (*dac5571_pwrdwn)(struct dac5571_data *data, int channel, u8 pwrdwn);
  55         u8 buf[3] ____cacheline_aligned;
  56 };
  57 
  58 #define DAC5571_POWERDOWN(mode)         ((mode) + 1)
  59 #define DAC5571_POWERDOWN_FLAG          BIT(0)
  60 #define DAC5571_CHANNEL_SELECT          1
  61 #define DAC5571_LOADMODE_DIRECT         BIT(4)
  62 #define DAC5571_SINGLE_PWRDWN_BITS      4
  63 #define DAC5571_QUAD_PWRDWN_BITS        6
  64 
  65 static int dac5571_cmd_single(struct dac5571_data *data, int channel, u16 val)
  66 {
  67         unsigned int shift;
  68 
  69         shift = 12 - data->spec->resolution;
  70         data->buf[1] = val << shift;
  71         data->buf[0] = val >> (8 - shift);
  72 
  73         if (i2c_master_send(data->client, data->buf, 2) != 2)
  74                 return -EIO;
  75 
  76         return 0;
  77 }
  78 
  79 static int dac5571_cmd_quad(struct dac5571_data *data, int channel, u16 val)
  80 {
  81         unsigned int shift;
  82 
  83         shift = 16 - data->spec->resolution;
  84         data->buf[2] = val << shift;
  85         data->buf[1] = (val >> (8 - shift));
  86         data->buf[0] = (channel << DAC5571_CHANNEL_SELECT) |
  87                        DAC5571_LOADMODE_DIRECT;
  88 
  89         if (i2c_master_send(data->client, data->buf, 3) != 3)
  90                 return -EIO;
  91 
  92         return 0;
  93 }
  94 
  95 static int dac5571_pwrdwn_single(struct dac5571_data *data, int channel, u8 pwrdwn)
  96 {
  97         data->buf[1] = 0;
  98         data->buf[0] = pwrdwn << DAC5571_SINGLE_PWRDWN_BITS;
  99 
 100         if (i2c_master_send(data->client, data->buf, 2) != 2)
 101                 return -EIO;
 102 
 103         return 0;
 104 }
 105 
 106 static int dac5571_pwrdwn_quad(struct dac5571_data *data, int channel, u8 pwrdwn)
 107 {
 108         data->buf[2] = 0;
 109         data->buf[1] = pwrdwn << DAC5571_QUAD_PWRDWN_BITS;
 110         data->buf[0] = (channel << DAC5571_CHANNEL_SELECT) |
 111                        DAC5571_LOADMODE_DIRECT | DAC5571_POWERDOWN_FLAG;
 112 
 113         if (i2c_master_send(data->client, data->buf, 3) != 3)
 114                 return -EIO;
 115 
 116         return 0;
 117 }
 118 
 119 static const char *const dac5571_powerdown_modes[] = {
 120         "1kohm_to_gnd", "100kohm_to_gnd", "three_state",
 121 };
 122 
 123 static int dac5571_get_powerdown_mode(struct iio_dev *indio_dev,
 124                                       const struct iio_chan_spec *chan)
 125 {
 126         struct dac5571_data *data = iio_priv(indio_dev);
 127 
 128         return data->powerdown_mode;
 129 }
 130 
 131 static int dac5571_set_powerdown_mode(struct iio_dev *indio_dev,
 132                                       const struct iio_chan_spec *chan,
 133                                       unsigned int mode)
 134 {
 135         struct dac5571_data *data = iio_priv(indio_dev);
 136         int ret = 0;
 137 
 138         if (data->powerdown_mode == mode)
 139                 return 0;
 140 
 141         mutex_lock(&data->lock);
 142         if (data->powerdown) {
 143                 ret = data->dac5571_pwrdwn(data, chan->channel,
 144                                            DAC5571_POWERDOWN(mode));
 145                 if (ret)
 146                         goto out;
 147         }
 148         data->powerdown_mode = mode;
 149 
 150  out:
 151         mutex_unlock(&data->lock);
 152 
 153         return ret;
 154 }
 155 
 156 static const struct iio_enum dac5571_powerdown_mode = {
 157         .items = dac5571_powerdown_modes,
 158         .num_items = ARRAY_SIZE(dac5571_powerdown_modes),
 159         .get = dac5571_get_powerdown_mode,
 160         .set = dac5571_set_powerdown_mode,
 161 };
 162 
 163 static ssize_t dac5571_read_powerdown(struct iio_dev *indio_dev,
 164                                       uintptr_t private,
 165                                       const struct iio_chan_spec *chan,
 166                                       char *buf)
 167 {
 168         struct dac5571_data *data = iio_priv(indio_dev);
 169 
 170         return sprintf(buf, "%d\n", data->powerdown);
 171 }
 172 
 173 static ssize_t dac5571_write_powerdown(struct iio_dev *indio_dev,
 174                                        uintptr_t private,
 175                                        const struct iio_chan_spec *chan,
 176                                        const char *buf, size_t len)
 177 {
 178         struct dac5571_data *data = iio_priv(indio_dev);
 179         bool powerdown;
 180         int ret;
 181 
 182         ret = strtobool(buf, &powerdown);
 183         if (ret)
 184                 return ret;
 185 
 186         if (data->powerdown == powerdown)
 187                 return len;
 188 
 189         mutex_lock(&data->lock);
 190         if (powerdown)
 191                 ret = data->dac5571_pwrdwn(data, chan->channel,
 192                             DAC5571_POWERDOWN(data->powerdown_mode));
 193         else
 194                 ret = data->dac5571_cmd(data, chan->channel, data->val[0]);
 195         if (ret)
 196                 goto out;
 197 
 198         data->powerdown = powerdown;
 199 
 200  out:
 201         mutex_unlock(&data->lock);
 202 
 203         return ret ? ret : len;
 204 }
 205 
 206 
 207 static const struct iio_chan_spec_ext_info dac5571_ext_info[] = {
 208         {
 209                 .name      = "powerdown",
 210                 .read      = dac5571_read_powerdown,
 211                 .write     = dac5571_write_powerdown,
 212                 .shared    = IIO_SHARED_BY_TYPE,
 213         },
 214         IIO_ENUM("powerdown_mode", IIO_SHARED_BY_TYPE, &dac5571_powerdown_mode),
 215         IIO_ENUM_AVAILABLE("powerdown_mode", &dac5571_powerdown_mode),
 216         {},
 217 };
 218 
 219 #define dac5571_CHANNEL(chan, name) {                           \
 220         .type = IIO_VOLTAGE,                                    \
 221         .channel = (chan),                                      \
 222         .address = (chan),                                      \
 223         .indexed = true,                                        \
 224         .output = true,                                         \
 225         .datasheet_name = name,                                 \
 226         .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),           \
 227         .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),   \
 228         .ext_info = dac5571_ext_info,                           \
 229 }
 230 
 231 static const struct iio_chan_spec dac5571_channels[] = {
 232         dac5571_CHANNEL(0, "A"),
 233         dac5571_CHANNEL(1, "B"),
 234         dac5571_CHANNEL(2, "C"),
 235         dac5571_CHANNEL(3, "D"),
 236 };
 237 
 238 static int dac5571_read_raw(struct iio_dev *indio_dev,
 239                             struct iio_chan_spec const *chan,
 240                             int *val, int *val2, long mask)
 241 {
 242         struct dac5571_data *data = iio_priv(indio_dev);
 243         int ret;
 244 
 245         switch (mask) {
 246         case IIO_CHAN_INFO_RAW:
 247                 *val = data->val[chan->channel];
 248                 return IIO_VAL_INT;
 249 
 250         case IIO_CHAN_INFO_SCALE:
 251                 ret = regulator_get_voltage(data->vref);
 252                 if (ret < 0)
 253                         return ret;
 254 
 255                 *val = ret / 1000;
 256                 *val2 = data->spec->resolution;
 257                 return IIO_VAL_FRACTIONAL_LOG2;
 258 
 259         default:
 260                 return -EINVAL;
 261         }
 262 }
 263 
 264 static int dac5571_write_raw(struct iio_dev *indio_dev,
 265                              struct iio_chan_spec const *chan,
 266                              int val, int val2, long mask)
 267 {
 268         struct dac5571_data *data = iio_priv(indio_dev);
 269         int ret;
 270 
 271         switch (mask) {
 272         case IIO_CHAN_INFO_RAW:
 273                 if (data->val[chan->channel] == val)
 274                         return 0;
 275 
 276                 if (val >= (1 << data->spec->resolution) || val < 0)
 277                         return -EINVAL;
 278 
 279                 if (data->powerdown)
 280                         return -EBUSY;
 281 
 282                 mutex_lock(&data->lock);
 283                 ret = data->dac5571_cmd(data, chan->channel, val);
 284                 if (ret == 0)
 285                         data->val[chan->channel] = val;
 286                 mutex_unlock(&data->lock);
 287                 return ret;
 288 
 289         default:
 290                 return -EINVAL;
 291         }
 292 }
 293 
 294 static int dac5571_write_raw_get_fmt(struct iio_dev *indio_dev,
 295                                      struct iio_chan_spec const *chan,
 296                                      long mask)
 297 {
 298         return IIO_VAL_INT;
 299 }
 300 
 301 static const struct iio_info dac5571_info = {
 302         .read_raw = dac5571_read_raw,
 303         .write_raw = dac5571_write_raw,
 304         .write_raw_get_fmt = dac5571_write_raw_get_fmt,
 305 };
 306 
 307 static int dac5571_probe(struct i2c_client *client,
 308                          const struct i2c_device_id *id)
 309 {
 310         struct device *dev = &client->dev;
 311         const struct dac5571_spec *spec;
 312         struct dac5571_data *data;
 313         struct iio_dev *indio_dev;
 314         int ret, i;
 315 
 316         indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
 317         if (!indio_dev)
 318                 return -ENOMEM;
 319 
 320         data = iio_priv(indio_dev);
 321         i2c_set_clientdata(client, indio_dev);
 322         data->client = client;
 323 
 324         indio_dev->dev.parent = dev;
 325         indio_dev->dev.of_node = client->dev.of_node;
 326         indio_dev->info = &dac5571_info;
 327         indio_dev->name = id->name;
 328         indio_dev->modes = INDIO_DIRECT_MODE;
 329         indio_dev->channels = dac5571_channels;
 330 
 331         spec = &dac5571_spec[id->driver_data];
 332         indio_dev->num_channels = spec->num_channels;
 333         data->spec = spec;
 334 
 335         data->vref = devm_regulator_get(dev, "vref");
 336         if (IS_ERR(data->vref))
 337                 return PTR_ERR(data->vref);
 338 
 339         ret = regulator_enable(data->vref);
 340         if (ret < 0)
 341                 return ret;
 342 
 343         mutex_init(&data->lock);
 344 
 345         switch (spec->num_channels) {
 346         case 1:
 347                 data->dac5571_cmd = dac5571_cmd_single;
 348                 data->dac5571_pwrdwn = dac5571_pwrdwn_single;
 349                 break;
 350         case 4:
 351                 data->dac5571_cmd = dac5571_cmd_quad;
 352                 data->dac5571_pwrdwn = dac5571_pwrdwn_quad;
 353                 break;
 354         default:
 355                 goto err;
 356         }
 357 
 358         for (i = 0; i < spec->num_channels; i++) {
 359                 ret = data->dac5571_cmd(data, i, 0);
 360                 if (ret) {
 361                         dev_err(dev, "failed to initialize channel %d to 0\n", i);
 362                         goto err;
 363                 }
 364         }
 365 
 366         ret = iio_device_register(indio_dev);
 367         if (ret)
 368                 goto err;
 369 
 370         return 0;
 371 
 372  err:
 373         regulator_disable(data->vref);
 374         return ret;
 375 }
 376 
 377 static int dac5571_remove(struct i2c_client *i2c)
 378 {
 379         struct iio_dev *indio_dev = i2c_get_clientdata(i2c);
 380         struct dac5571_data *data = iio_priv(indio_dev);
 381 
 382         iio_device_unregister(indio_dev);
 383         regulator_disable(data->vref);
 384 
 385         return 0;
 386 }
 387 
 388 #ifdef CONFIG_OF
 389 static const struct of_device_id dac5571_of_id[] = {
 390         {.compatible = "ti,dac5571"},
 391         {.compatible = "ti,dac6571"},
 392         {.compatible = "ti,dac7571"},
 393         {.compatible = "ti,dac5574"},
 394         {.compatible = "ti,dac6574"},
 395         {.compatible = "ti,dac7574"},
 396         {.compatible = "ti,dac5573"},
 397         {.compatible = "ti,dac6573"},
 398         {.compatible = "ti,dac7573"},
 399         {}
 400 };
 401 MODULE_DEVICE_TABLE(of, dac5571_of_id);
 402 #endif
 403 
 404 static const struct i2c_device_id dac5571_id[] = {
 405         {"dac5571", single_8bit},
 406         {"dac6571", single_10bit},
 407         {"dac7571", single_12bit},
 408         {"dac5574", quad_8bit},
 409         {"dac6574", quad_10bit},
 410         {"dac7574", quad_12bit},
 411         {"dac5573", quad_8bit},
 412         {"dac6573", quad_10bit},
 413         {"dac7573", quad_12bit},
 414         {}
 415 };
 416 MODULE_DEVICE_TABLE(i2c, dac5571_id);
 417 
 418 static struct i2c_driver dac5571_driver = {
 419         .driver = {
 420                    .name = "ti-dac5571",
 421                    .of_match_table = of_match_ptr(dac5571_of_id),
 422         },
 423         .probe    = dac5571_probe,
 424         .remove   = dac5571_remove,
 425         .id_table = dac5571_id,
 426 };
 427 module_i2c_driver(dac5571_driver);
 428 
 429 MODULE_AUTHOR("Sean Nyekjaer <sean@geanix.dk>");
 430 MODULE_DESCRIPTION("Texas Instruments 8/10/12-bit 1/4-channel DAC driver");
 431 MODULE_LICENSE("GPL v2");

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