ti-dac082s085.c (9051B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * ti-dac082s085.c - Texas Instruments 8/10/12-bit 2/4-channel DAC driver 4 * 5 * Copyright (C) 2017 KUNBUS GmbH 6 * 7 * https://www.ti.com/lit/ds/symlink/dac082s085.pdf 8 * https://www.ti.com/lit/ds/symlink/dac102s085.pdf 9 * https://www.ti.com/lit/ds/symlink/dac122s085.pdf 10 * https://www.ti.com/lit/ds/symlink/dac084s085.pdf 11 * https://www.ti.com/lit/ds/symlink/dac104s085.pdf 12 * https://www.ti.com/lit/ds/symlink/dac124s085.pdf 13 */ 14 15#include <linux/iio/iio.h> 16#include <linux/module.h> 17#include <linux/mod_devicetable.h> 18#include <linux/regulator/consumer.h> 19#include <linux/spi/spi.h> 20 21enum { dual_8bit, dual_10bit, dual_12bit, quad_8bit, quad_10bit, quad_12bit }; 22 23struct ti_dac_spec { 24 u8 num_channels; 25 u8 resolution; 26}; 27 28static const struct ti_dac_spec ti_dac_spec[] = { 29 [dual_8bit] = { .num_channels = 2, .resolution = 8 }, 30 [dual_10bit] = { .num_channels = 2, .resolution = 10 }, 31 [dual_12bit] = { .num_channels = 2, .resolution = 12 }, 32 [quad_8bit] = { .num_channels = 4, .resolution = 8 }, 33 [quad_10bit] = { .num_channels = 4, .resolution = 10 }, 34 [quad_12bit] = { .num_channels = 4, .resolution = 12 }, 35}; 36 37/** 38 * struct ti_dac_chip - TI DAC chip 39 * @lock: protects write sequences 40 * @vref: regulator generating Vref 41 * @mesg: SPI message to perform a write 42 * @xfer: SPI transfer used by @mesg 43 * @val: cached value of each output 44 * @powerdown: whether the chip is powered down 45 * @powerdown_mode: selected by the user 46 * @resolution: resolution of the chip 47 * @buf: buffer for @xfer 48 */ 49struct ti_dac_chip { 50 struct mutex lock; 51 struct regulator *vref; 52 struct spi_message mesg; 53 struct spi_transfer xfer; 54 u16 val[4]; 55 bool powerdown; 56 u8 powerdown_mode; 57 u8 resolution; 58 u8 buf[2] ____cacheline_aligned; 59}; 60 61#define WRITE_NOT_UPDATE(chan) (0x00 | (chan) << 6) 62#define WRITE_AND_UPDATE(chan) (0x10 | (chan) << 6) 63#define WRITE_ALL_UPDATE 0x20 64#define POWERDOWN(mode) (0x30 | ((mode) + 1) << 6) 65 66static int ti_dac_cmd(struct ti_dac_chip *ti_dac, u8 cmd, u16 val) 67{ 68 u8 shift = 12 - ti_dac->resolution; 69 70 ti_dac->buf[0] = cmd | (val >> (8 - shift)); 71 ti_dac->buf[1] = (val << shift) & 0xff; 72 return spi_sync(ti_dac->mesg.spi, &ti_dac->mesg); 73} 74 75static const char * const ti_dac_powerdown_modes[] = { 76 "2.5kohm_to_gnd", "100kohm_to_gnd", "three_state", 77}; 78 79static int ti_dac_get_powerdown_mode(struct iio_dev *indio_dev, 80 const struct iio_chan_spec *chan) 81{ 82 struct ti_dac_chip *ti_dac = iio_priv(indio_dev); 83 84 return ti_dac->powerdown_mode; 85} 86 87static int ti_dac_set_powerdown_mode(struct iio_dev *indio_dev, 88 const struct iio_chan_spec *chan, 89 unsigned int mode) 90{ 91 struct ti_dac_chip *ti_dac = iio_priv(indio_dev); 92 int ret = 0; 93 94 if (ti_dac->powerdown_mode == mode) 95 return 0; 96 97 mutex_lock(&ti_dac->lock); 98 if (ti_dac->powerdown) { 99 ret = ti_dac_cmd(ti_dac, POWERDOWN(mode), 0); 100 if (ret) 101 goto out; 102 } 103 ti_dac->powerdown_mode = mode; 104 105out: 106 mutex_unlock(&ti_dac->lock); 107 return ret; 108} 109 110static const struct iio_enum ti_dac_powerdown_mode = { 111 .items = ti_dac_powerdown_modes, 112 .num_items = ARRAY_SIZE(ti_dac_powerdown_modes), 113 .get = ti_dac_get_powerdown_mode, 114 .set = ti_dac_set_powerdown_mode, 115}; 116 117static ssize_t ti_dac_read_powerdown(struct iio_dev *indio_dev, 118 uintptr_t private, 119 const struct iio_chan_spec *chan, 120 char *buf) 121{ 122 struct ti_dac_chip *ti_dac = iio_priv(indio_dev); 123 124 return sysfs_emit(buf, "%d\n", ti_dac->powerdown); 125} 126 127static ssize_t ti_dac_write_powerdown(struct iio_dev *indio_dev, 128 uintptr_t private, 129 const struct iio_chan_spec *chan, 130 const char *buf, size_t len) 131{ 132 struct ti_dac_chip *ti_dac = iio_priv(indio_dev); 133 bool powerdown; 134 int ret; 135 136 ret = kstrtobool(buf, &powerdown); 137 if (ret) 138 return ret; 139 140 if (ti_dac->powerdown == powerdown) 141 return len; 142 143 mutex_lock(&ti_dac->lock); 144 if (powerdown) 145 ret = ti_dac_cmd(ti_dac, POWERDOWN(ti_dac->powerdown_mode), 0); 146 else 147 ret = ti_dac_cmd(ti_dac, WRITE_AND_UPDATE(0), ti_dac->val[0]); 148 if (!ret) 149 ti_dac->powerdown = powerdown; 150 mutex_unlock(&ti_dac->lock); 151 152 return ret ? ret : len; 153} 154 155static const struct iio_chan_spec_ext_info ti_dac_ext_info[] = { 156 { 157 .name = "powerdown", 158 .read = ti_dac_read_powerdown, 159 .write = ti_dac_write_powerdown, 160 .shared = IIO_SHARED_BY_TYPE, 161 }, 162 IIO_ENUM("powerdown_mode", IIO_SHARED_BY_TYPE, &ti_dac_powerdown_mode), 163 IIO_ENUM_AVAILABLE("powerdown_mode", IIO_SHARED_BY_TYPE, &ti_dac_powerdown_mode), 164 { }, 165}; 166 167#define TI_DAC_CHANNEL(chan) { \ 168 .type = IIO_VOLTAGE, \ 169 .channel = (chan), \ 170 .address = (chan), \ 171 .indexed = true, \ 172 .output = true, \ 173 .datasheet_name = (const char[]){ 'A' + (chan), 0 }, \ 174 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 175 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ 176 .ext_info = ti_dac_ext_info, \ 177} 178 179static const struct iio_chan_spec ti_dac_channels[] = { 180 TI_DAC_CHANNEL(0), 181 TI_DAC_CHANNEL(1), 182 TI_DAC_CHANNEL(2), 183 TI_DAC_CHANNEL(3), 184}; 185 186static int ti_dac_read_raw(struct iio_dev *indio_dev, 187 struct iio_chan_spec const *chan, 188 int *val, int *val2, long mask) 189{ 190 struct ti_dac_chip *ti_dac = iio_priv(indio_dev); 191 int ret; 192 193 switch (mask) { 194 case IIO_CHAN_INFO_RAW: 195 *val = ti_dac->val[chan->channel]; 196 ret = IIO_VAL_INT; 197 break; 198 199 case IIO_CHAN_INFO_SCALE: 200 ret = regulator_get_voltage(ti_dac->vref); 201 if (ret < 0) 202 return ret; 203 204 *val = ret / 1000; 205 *val2 = ti_dac->resolution; 206 ret = IIO_VAL_FRACTIONAL_LOG2; 207 break; 208 209 default: 210 ret = -EINVAL; 211 } 212 213 return ret; 214} 215 216static int ti_dac_write_raw(struct iio_dev *indio_dev, 217 struct iio_chan_spec const *chan, 218 int val, int val2, long mask) 219{ 220 struct ti_dac_chip *ti_dac = iio_priv(indio_dev); 221 int ret; 222 223 switch (mask) { 224 case IIO_CHAN_INFO_RAW: 225 if (ti_dac->val[chan->channel] == val) 226 return 0; 227 228 if (val >= (1 << ti_dac->resolution) || val < 0) 229 return -EINVAL; 230 231 if (ti_dac->powerdown) 232 return -EBUSY; 233 234 mutex_lock(&ti_dac->lock); 235 ret = ti_dac_cmd(ti_dac, WRITE_AND_UPDATE(chan->channel), val); 236 if (!ret) 237 ti_dac->val[chan->channel] = val; 238 mutex_unlock(&ti_dac->lock); 239 break; 240 241 default: 242 ret = -EINVAL; 243 } 244 245 return ret; 246} 247 248static int ti_dac_write_raw_get_fmt(struct iio_dev *indio_dev, 249 struct iio_chan_spec const *chan, long mask) 250{ 251 return IIO_VAL_INT; 252} 253 254static const struct iio_info ti_dac_info = { 255 .read_raw = ti_dac_read_raw, 256 .write_raw = ti_dac_write_raw, 257 .write_raw_get_fmt = ti_dac_write_raw_get_fmt, 258}; 259 260static int ti_dac_probe(struct spi_device *spi) 261{ 262 struct device *dev = &spi->dev; 263 const struct ti_dac_spec *spec; 264 struct ti_dac_chip *ti_dac; 265 struct iio_dev *indio_dev; 266 int ret; 267 268 indio_dev = devm_iio_device_alloc(dev, sizeof(*ti_dac)); 269 if (!indio_dev) 270 return -ENOMEM; 271 272 indio_dev->info = &ti_dac_info; 273 indio_dev->name = spi->modalias; 274 indio_dev->modes = INDIO_DIRECT_MODE; 275 indio_dev->channels = ti_dac_channels; 276 spi_set_drvdata(spi, indio_dev); 277 278 ti_dac = iio_priv(indio_dev); 279 ti_dac->xfer.tx_buf = &ti_dac->buf; 280 ti_dac->xfer.len = sizeof(ti_dac->buf); 281 spi_message_init_with_transfers(&ti_dac->mesg, &ti_dac->xfer, 1); 282 ti_dac->mesg.spi = spi; 283 284 spec = &ti_dac_spec[spi_get_device_id(spi)->driver_data]; 285 indio_dev->num_channels = spec->num_channels; 286 ti_dac->resolution = spec->resolution; 287 288 ti_dac->vref = devm_regulator_get(dev, "vref"); 289 if (IS_ERR(ti_dac->vref)) 290 return PTR_ERR(ti_dac->vref); 291 292 ret = regulator_enable(ti_dac->vref); 293 if (ret < 0) 294 return ret; 295 296 mutex_init(&ti_dac->lock); 297 298 ret = ti_dac_cmd(ti_dac, WRITE_ALL_UPDATE, 0); 299 if (ret) { 300 dev_err(dev, "failed to initialize outputs to 0\n"); 301 goto err; 302 } 303 304 ret = iio_device_register(indio_dev); 305 if (ret) 306 goto err; 307 308 return 0; 309 310err: 311 mutex_destroy(&ti_dac->lock); 312 regulator_disable(ti_dac->vref); 313 return ret; 314} 315 316static void ti_dac_remove(struct spi_device *spi) 317{ 318 struct iio_dev *indio_dev = spi_get_drvdata(spi); 319 struct ti_dac_chip *ti_dac = iio_priv(indio_dev); 320 321 iio_device_unregister(indio_dev); 322 mutex_destroy(&ti_dac->lock); 323 regulator_disable(ti_dac->vref); 324} 325 326static const struct of_device_id ti_dac_of_id[] = { 327 { .compatible = "ti,dac082s085" }, 328 { .compatible = "ti,dac102s085" }, 329 { .compatible = "ti,dac122s085" }, 330 { .compatible = "ti,dac084s085" }, 331 { .compatible = "ti,dac104s085" }, 332 { .compatible = "ti,dac124s085" }, 333 { } 334}; 335MODULE_DEVICE_TABLE(of, ti_dac_of_id); 336 337static const struct spi_device_id ti_dac_spi_id[] = { 338 { "dac082s085", dual_8bit }, 339 { "dac102s085", dual_10bit }, 340 { "dac122s085", dual_12bit }, 341 { "dac084s085", quad_8bit }, 342 { "dac104s085", quad_10bit }, 343 { "dac124s085", quad_12bit }, 344 { } 345}; 346MODULE_DEVICE_TABLE(spi, ti_dac_spi_id); 347 348static struct spi_driver ti_dac_driver = { 349 .driver = { 350 .name = "ti-dac082s085", 351 .of_match_table = ti_dac_of_id, 352 }, 353 .probe = ti_dac_probe, 354 .remove = ti_dac_remove, 355 .id_table = ti_dac_spi_id, 356}; 357module_spi_driver(ti_dac_driver); 358 359MODULE_AUTHOR("Lukas Wunner <lukas@wunner.de>"); 360MODULE_DESCRIPTION("Texas Instruments 8/10/12-bit 2/4-channel DAC driver"); 361MODULE_LICENSE("GPL v2");