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