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