root/drivers/iio/dac/ds4424.c

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

DEFINITIONS

This source file includes following definitions.
  1. ds4424_get_value
  2. ds4424_set_value
  3. ds4424_read_raw
  4. ds4424_write_raw
  5. ds4424_verify_chip
  6. ds4424_suspend
  7. ds4424_resume
  8. ds4424_probe
  9. ds4424_remove

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Maxim Integrated
   4  * 7-bit, Multi-Channel Sink/Source Current DAC Driver
   5  * Copyright (C) 2017 Maxim Integrated
   6  */
   7 
   8 #include <linux/kernel.h>
   9 #include <linux/module.h>
  10 #include <linux/i2c.h>
  11 #include <linux/regulator/consumer.h>
  12 #include <linux/err.h>
  13 #include <linux/delay.h>
  14 #include <linux/iio/iio.h>
  15 #include <linux/iio/driver.h>
  16 #include <linux/iio/machine.h>
  17 #include <linux/iio/consumer.h>
  18 
  19 #define DS4422_MAX_DAC_CHANNELS         2
  20 #define DS4424_MAX_DAC_CHANNELS         4
  21 
  22 #define DS4424_DAC_ADDR(chan)   ((chan) + 0xf8)
  23 #define DS4424_SOURCE_I         1
  24 #define DS4424_SINK_I           0
  25 
  26 #define DS4424_CHANNEL(chan) { \
  27         .type = IIO_CURRENT, \
  28         .indexed = 1, \
  29         .output = 1, \
  30         .channel = chan, \
  31         .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
  32 }
  33 
  34 /*
  35  * DS4424 DAC control register 8 bits
  36  * [7]          0: to sink; 1: to source
  37  * [6:0]        steps to sink/source
  38  * bit[7] looks like a sign bit, but the value of the register is
  39  * not a two's complement code considering the bit[6:0] is a absolute
  40  * distance from the zero point.
  41  */
  42 union ds4424_raw_data {
  43         struct {
  44                 u8 dx:7;
  45                 u8 source_bit:1;
  46         };
  47         u8 bits;
  48 };
  49 
  50 enum ds4424_device_ids {
  51         ID_DS4422,
  52         ID_DS4424,
  53 };
  54 
  55 struct ds4424_data {
  56         struct i2c_client *client;
  57         struct mutex lock;
  58         uint8_t save[DS4424_MAX_DAC_CHANNELS];
  59         struct regulator *vcc_reg;
  60         uint8_t raw[DS4424_MAX_DAC_CHANNELS];
  61 };
  62 
  63 static const struct iio_chan_spec ds4424_channels[] = {
  64         DS4424_CHANNEL(0),
  65         DS4424_CHANNEL(1),
  66         DS4424_CHANNEL(2),
  67         DS4424_CHANNEL(3),
  68 };
  69 
  70 static int ds4424_get_value(struct iio_dev *indio_dev,
  71                              int *val, int channel)
  72 {
  73         struct ds4424_data *data = iio_priv(indio_dev);
  74         int ret;
  75 
  76         mutex_lock(&data->lock);
  77         ret = i2c_smbus_read_byte_data(data->client, DS4424_DAC_ADDR(channel));
  78         if (ret < 0)
  79                 goto fail;
  80 
  81         *val = ret;
  82 
  83 fail:
  84         mutex_unlock(&data->lock);
  85         return ret;
  86 }
  87 
  88 static int ds4424_set_value(struct iio_dev *indio_dev,
  89                              int val, struct iio_chan_spec const *chan)
  90 {
  91         struct ds4424_data *data = iio_priv(indio_dev);
  92         int ret;
  93 
  94         mutex_lock(&data->lock);
  95         ret = i2c_smbus_write_byte_data(data->client,
  96                         DS4424_DAC_ADDR(chan->channel), val);
  97         if (ret < 0)
  98                 goto fail;
  99 
 100         data->raw[chan->channel] = val;
 101 
 102 fail:
 103         mutex_unlock(&data->lock);
 104         return ret;
 105 }
 106 
 107 static int ds4424_read_raw(struct iio_dev *indio_dev,
 108                            struct iio_chan_spec const *chan,
 109                            int *val, int *val2, long mask)
 110 {
 111         union ds4424_raw_data raw;
 112         int ret;
 113 
 114         switch (mask) {
 115         case IIO_CHAN_INFO_RAW:
 116                 ret = ds4424_get_value(indio_dev, val, chan->channel);
 117                 if (ret < 0) {
 118                         pr_err("%s : ds4424_get_value returned %d\n",
 119                                                         __func__, ret);
 120                         return ret;
 121                 }
 122                 raw.bits = *val;
 123                 *val = raw.dx;
 124                 if (raw.source_bit == DS4424_SINK_I)
 125                         *val = -*val;
 126                 return IIO_VAL_INT;
 127 
 128         default:
 129                 return -EINVAL;
 130         }
 131 }
 132 
 133 static int ds4424_write_raw(struct iio_dev *indio_dev,
 134                              struct iio_chan_spec const *chan,
 135                              int val, int val2, long mask)
 136 {
 137         union ds4424_raw_data raw;
 138 
 139         if (val2 != 0)
 140                 return -EINVAL;
 141 
 142         switch (mask) {
 143         case IIO_CHAN_INFO_RAW:
 144                 if (val < S8_MIN || val > S8_MAX)
 145                         return -EINVAL;
 146 
 147                 if (val > 0) {
 148                         raw.source_bit = DS4424_SOURCE_I;
 149                         raw.dx = val;
 150                 } else {
 151                         raw.source_bit = DS4424_SINK_I;
 152                         raw.dx = -val;
 153                 }
 154 
 155                 return ds4424_set_value(indio_dev, raw.bits, chan);
 156 
 157         default:
 158                 return -EINVAL;
 159         }
 160 }
 161 
 162 static int ds4424_verify_chip(struct iio_dev *indio_dev)
 163 {
 164         int ret, val;
 165 
 166         ret = ds4424_get_value(indio_dev, &val, 0);
 167         if (ret < 0)
 168                 dev_err(&indio_dev->dev,
 169                                 "%s failed. ret: %d\n", __func__, ret);
 170 
 171         return ret;
 172 }
 173 
 174 static int __maybe_unused ds4424_suspend(struct device *dev)
 175 {
 176         struct i2c_client *client = to_i2c_client(dev);
 177         struct iio_dev *indio_dev = i2c_get_clientdata(client);
 178         struct ds4424_data *data = iio_priv(indio_dev);
 179         int ret = 0;
 180         int i;
 181 
 182         for (i = 0; i < indio_dev->num_channels; i++) {
 183                 data->save[i] = data->raw[i];
 184                 ret = ds4424_set_value(indio_dev, 0,
 185                                 &indio_dev->channels[i]);
 186                 if (ret < 0)
 187                         return ret;
 188         }
 189         return ret;
 190 }
 191 
 192 static int __maybe_unused ds4424_resume(struct device *dev)
 193 {
 194         struct i2c_client *client = to_i2c_client(dev);
 195         struct iio_dev *indio_dev = i2c_get_clientdata(client);
 196         struct ds4424_data *data = iio_priv(indio_dev);
 197         int ret = 0;
 198         int i;
 199 
 200         for (i = 0; i < indio_dev->num_channels; i++) {
 201                 ret = ds4424_set_value(indio_dev, data->save[i],
 202                                 &indio_dev->channels[i]);
 203                 if (ret < 0)
 204                         return ret;
 205         }
 206         return ret;
 207 }
 208 
 209 static SIMPLE_DEV_PM_OPS(ds4424_pm_ops, ds4424_suspend, ds4424_resume);
 210 
 211 static const struct iio_info ds4424_info = {
 212         .read_raw = ds4424_read_raw,
 213         .write_raw = ds4424_write_raw,
 214 };
 215 
 216 static int ds4424_probe(struct i2c_client *client,
 217                         const struct i2c_device_id *id)
 218 {
 219         struct ds4424_data *data;
 220         struct iio_dev *indio_dev;
 221         int ret;
 222 
 223         indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
 224         if (!indio_dev) {
 225                 dev_err(&client->dev, "iio dev alloc failed.\n");
 226                 return -ENOMEM;
 227         }
 228 
 229         data = iio_priv(indio_dev);
 230         i2c_set_clientdata(client, indio_dev);
 231         data->client = client;
 232         indio_dev->name = id->name;
 233         indio_dev->dev.of_node = client->dev.of_node;
 234         indio_dev->dev.parent = &client->dev;
 235 
 236         data->vcc_reg = devm_regulator_get(&client->dev, "vcc");
 237         if (IS_ERR(data->vcc_reg)) {
 238                 dev_err(&client->dev,
 239                         "Failed to get vcc-supply regulator. err: %ld\n",
 240                                 PTR_ERR(data->vcc_reg));
 241                 return PTR_ERR(data->vcc_reg);
 242         }
 243 
 244         mutex_init(&data->lock);
 245         ret = regulator_enable(data->vcc_reg);
 246         if (ret < 0) {
 247                 dev_err(&client->dev,
 248                                 "Unable to enable the regulator.\n");
 249                 return ret;
 250         }
 251 
 252         usleep_range(1000, 1200);
 253         ret = ds4424_verify_chip(indio_dev);
 254         if (ret < 0)
 255                 goto fail;
 256 
 257         switch (id->driver_data) {
 258         case ID_DS4422:
 259                 indio_dev->num_channels = DS4422_MAX_DAC_CHANNELS;
 260                 break;
 261         case ID_DS4424:
 262                 indio_dev->num_channels = DS4424_MAX_DAC_CHANNELS;
 263                 break;
 264         default:
 265                 dev_err(&client->dev,
 266                                 "ds4424: Invalid chip id.\n");
 267                 ret = -ENXIO;
 268                 goto fail;
 269         }
 270 
 271         indio_dev->channels = ds4424_channels;
 272         indio_dev->modes = INDIO_DIRECT_MODE;
 273         indio_dev->info = &ds4424_info;
 274 
 275         ret = iio_device_register(indio_dev);
 276         if (ret < 0) {
 277                 dev_err(&client->dev,
 278                                 "iio_device_register failed. ret: %d\n", ret);
 279                 goto fail;
 280         }
 281 
 282         return ret;
 283 
 284 fail:
 285         regulator_disable(data->vcc_reg);
 286         return ret;
 287 }
 288 
 289 static int ds4424_remove(struct i2c_client *client)
 290 {
 291         struct iio_dev *indio_dev = i2c_get_clientdata(client);
 292         struct ds4424_data *data = iio_priv(indio_dev);
 293 
 294         iio_device_unregister(indio_dev);
 295         regulator_disable(data->vcc_reg);
 296 
 297         return 0;
 298 }
 299 
 300 static const struct i2c_device_id ds4424_id[] = {
 301         { "ds4422", ID_DS4422 },
 302         { "ds4424", ID_DS4424 },
 303         { }
 304 };
 305 
 306 MODULE_DEVICE_TABLE(i2c, ds4424_id);
 307 
 308 static const struct of_device_id ds4424_of_match[] = {
 309         { .compatible = "maxim,ds4422" },
 310         { .compatible = "maxim,ds4424" },
 311         { },
 312 };
 313 
 314 MODULE_DEVICE_TABLE(of, ds4424_of_match);
 315 
 316 static struct i2c_driver ds4424_driver = {
 317         .driver = {
 318                 .name   = "ds4424",
 319                 .of_match_table = ds4424_of_match,
 320                 .pm     = &ds4424_pm_ops,
 321         },
 322         .probe          = ds4424_probe,
 323         .remove         = ds4424_remove,
 324         .id_table       = ds4424_id,
 325 };
 326 module_i2c_driver(ds4424_driver);
 327 
 328 MODULE_DESCRIPTION("Maxim DS4424 DAC Driver");
 329 MODULE_AUTHOR("Ismail H. Kose <ismail.kose@maximintegrated.com>");
 330 MODULE_AUTHOR("Vishal Sood <vishal.sood@maximintegrated.com>");
 331 MODULE_AUTHOR("David Jung <david.jung@maximintegrated.com>");
 332 MODULE_LICENSE("GPL v2");

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