ds4424.c (7176B)
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 */ 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 __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 192static 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 209static 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 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 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 int 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 return 0; 293} 294 295static const struct i2c_device_id ds4424_id[] = { 296 { "ds4422", ID_DS4422 }, 297 { "ds4424", ID_DS4424 }, 298 { } 299}; 300 301MODULE_DEVICE_TABLE(i2c, ds4424_id); 302 303static const struct of_device_id ds4424_of_match[] = { 304 { .compatible = "maxim,ds4422" }, 305 { .compatible = "maxim,ds4424" }, 306 { }, 307}; 308 309MODULE_DEVICE_TABLE(of, ds4424_of_match); 310 311static struct i2c_driver ds4424_driver = { 312 .driver = { 313 .name = "ds4424", 314 .of_match_table = ds4424_of_match, 315 .pm = &ds4424_pm_ops, 316 }, 317 .probe = ds4424_probe, 318 .remove = ds4424_remove, 319 .id_table = ds4424_id, 320}; 321module_i2c_driver(ds4424_driver); 322 323MODULE_DESCRIPTION("Maxim DS4424 DAC Driver"); 324MODULE_AUTHOR("Ismail H. Kose <ismail.kose@maximintegrated.com>"); 325MODULE_AUTHOR("Vishal Sood <vishal.sood@maximintegrated.com>"); 326MODULE_AUTHOR("David Jung <david.jung@maximintegrated.com>"); 327MODULE_LICENSE("GPL v2");