326 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Maxim Integrated4 * 7-bit, Multi-Channel Sink/Source Current DAC Driver5 * Copyright (C) 2017 Maxim Integrated6 */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 220#define DS4424_MAX_DAC_CHANNELS 421 22#define DS4424_DAC_ADDR(chan) ((chan) + 0xf8)23#define DS4424_SOURCE_I 124#define DS4424_SINK_I 025 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 bits36 * [7] 0: to sink; 1: to source37 * [6:0] steps to sink/source38 * bit[7] looks like a sign bit, but the value of the register is39 * not a two's complement code considering the bit[6:0] is a absolute40 * distance from the zero point.41 */42union ds4424_raw_data {43 struct {44 u8 dx:7;45 u8 source_bit:1;46 };47 u8 bits;48};49 50enum ds4424_device_ids {51 ID_DS4422,52 ID_DS4424,53};54 55struct 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 63static 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 70static 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 83fail:84 mutex_unlock(&data->lock);85 return ret;86}87 88static 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 102fail:103 mutex_unlock(&data->lock);104 return ret;105}106 107static 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 133static 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 162static 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 174static int 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 192static int 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 209static DEFINE_SIMPLE_DEV_PM_OPS(ds4424_pm_ops, ds4424_suspend, ds4424_resume);210 211static const struct iio_info ds4424_info = {212 .read_raw = ds4424_read_raw,213 .write_raw = ds4424_write_raw,214};215 216static int ds4424_probe(struct i2c_client *client)217{218 const struct i2c_device_id *id = i2c_client_get_device_id(client);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 234 data->vcc_reg = devm_regulator_get(&client->dev, "vcc");235 if (IS_ERR(data->vcc_reg))236 return dev_err_probe(&client->dev, PTR_ERR(data->vcc_reg),237 "Failed to get vcc-supply regulator.\n");238 239 mutex_init(&data->lock);240 ret = regulator_enable(data->vcc_reg);241 if (ret < 0) {242 dev_err(&client->dev,243 "Unable to enable the regulator.\n");244 return ret;245 }246 247 usleep_range(1000, 1200);248 ret = ds4424_verify_chip(indio_dev);249 if (ret < 0)250 goto fail;251 252 switch (id->driver_data) {253 case ID_DS4422:254 indio_dev->num_channels = DS4422_MAX_DAC_CHANNELS;255 break;256 case ID_DS4424:257 indio_dev->num_channels = DS4424_MAX_DAC_CHANNELS;258 break;259 default:260 dev_err(&client->dev,261 "ds4424: Invalid chip id.\n");262 ret = -ENXIO;263 goto fail;264 }265 266 indio_dev->channels = ds4424_channels;267 indio_dev->modes = INDIO_DIRECT_MODE;268 indio_dev->info = &ds4424_info;269 270 ret = iio_device_register(indio_dev);271 if (ret < 0) {272 dev_err(&client->dev,273 "iio_device_register failed. ret: %d\n", ret);274 goto fail;275 }276 277 return ret;278 279fail:280 regulator_disable(data->vcc_reg);281 return ret;282}283 284static void ds4424_remove(struct i2c_client *client)285{286 struct iio_dev *indio_dev = i2c_get_clientdata(client);287 struct ds4424_data *data = iio_priv(indio_dev);288 289 iio_device_unregister(indio_dev);290 regulator_disable(data->vcc_reg);291}292 293static const struct i2c_device_id ds4424_id[] = {294 { "ds4422", ID_DS4422 },295 { "ds4424", ID_DS4424 },296 { }297};298 299MODULE_DEVICE_TABLE(i2c, ds4424_id);300 301static const struct of_device_id ds4424_of_match[] = {302 { .compatible = "maxim,ds4422" },303 { .compatible = "maxim,ds4424" },304 { },305};306 307MODULE_DEVICE_TABLE(of, ds4424_of_match);308 309static struct i2c_driver ds4424_driver = {310 .driver = {311 .name = "ds4424",312 .of_match_table = ds4424_of_match,313 .pm = pm_sleep_ptr(&ds4424_pm_ops),314 },315 .probe = ds4424_probe,316 .remove = ds4424_remove,317 .id_table = ds4424_id,318};319module_i2c_driver(ds4424_driver);320 321MODULE_DESCRIPTION("Maxim DS4424 DAC Driver");322MODULE_AUTHOR("Ismail H. Kose <ismail.kose@maximintegrated.com>");323MODULE_AUTHOR("Vishal Sood <vishal.sood@maximintegrated.com>");324MODULE_AUTHOR("David Jung <david.jung@maximintegrated.com>");325MODULE_LICENSE("GPL v2");326