1dbdc025bSLars-Peter Clausen /* 2dbdc025bSLars-Peter Clausen * AD5421 Digital to analog converters driver 3dbdc025bSLars-Peter Clausen * 4dbdc025bSLars-Peter Clausen * Copyright 2011 Analog Devices Inc. 5dbdc025bSLars-Peter Clausen * 6dbdc025bSLars-Peter Clausen * Licensed under the GPL-2. 7dbdc025bSLars-Peter Clausen */ 8dbdc025bSLars-Peter Clausen 9dbdc025bSLars-Peter Clausen #include <linux/device.h> 10dbdc025bSLars-Peter Clausen #include <linux/delay.h> 11dbdc025bSLars-Peter Clausen #include <linux/err.h> 12dbdc025bSLars-Peter Clausen #include <linux/module.h> 13dbdc025bSLars-Peter Clausen #include <linux/interrupt.h> 14dbdc025bSLars-Peter Clausen #include <linux/kernel.h> 15dbdc025bSLars-Peter Clausen #include <linux/spi/spi.h> 16dbdc025bSLars-Peter Clausen #include <linux/slab.h> 17dbdc025bSLars-Peter Clausen #include <linux/sysfs.h> 18dbdc025bSLars-Peter Clausen 19dbdc025bSLars-Peter Clausen #include <linux/iio/iio.h> 20dbdc025bSLars-Peter Clausen #include <linux/iio/sysfs.h> 21dbdc025bSLars-Peter Clausen #include <linux/iio/events.h> 22dbdc025bSLars-Peter Clausen #include <linux/iio/dac/ad5421.h> 23dbdc025bSLars-Peter Clausen 24dbdc025bSLars-Peter Clausen 25dbdc025bSLars-Peter Clausen #define AD5421_REG_DAC_DATA 0x1 26dbdc025bSLars-Peter Clausen #define AD5421_REG_CTRL 0x2 27dbdc025bSLars-Peter Clausen #define AD5421_REG_OFFSET 0x3 28dbdc025bSLars-Peter Clausen #define AD5421_REG_GAIN 0x4 29dbdc025bSLars-Peter Clausen /* load dac and fault shared the same register number. Writing to it will cause 30dbdc025bSLars-Peter Clausen * a dac load command, reading from it will return the fault status register */ 31dbdc025bSLars-Peter Clausen #define AD5421_REG_LOAD_DAC 0x5 32dbdc025bSLars-Peter Clausen #define AD5421_REG_FAULT 0x5 33dbdc025bSLars-Peter Clausen #define AD5421_REG_FORCE_ALARM_CURRENT 0x6 34dbdc025bSLars-Peter Clausen #define AD5421_REG_RESET 0x7 35dbdc025bSLars-Peter Clausen #define AD5421_REG_START_CONVERSION 0x8 36dbdc025bSLars-Peter Clausen #define AD5421_REG_NOOP 0x9 37dbdc025bSLars-Peter Clausen 38dbdc025bSLars-Peter Clausen #define AD5421_CTRL_WATCHDOG_DISABLE BIT(12) 39dbdc025bSLars-Peter Clausen #define AD5421_CTRL_AUTO_FAULT_READBACK BIT(11) 40dbdc025bSLars-Peter Clausen #define AD5421_CTRL_MIN_CURRENT BIT(9) 41dbdc025bSLars-Peter Clausen #define AD5421_CTRL_ADC_SOURCE_TEMP BIT(8) 42dbdc025bSLars-Peter Clausen #define AD5421_CTRL_ADC_ENABLE BIT(7) 43dbdc025bSLars-Peter Clausen #define AD5421_CTRL_PWR_DOWN_INT_VREF BIT(6) 44dbdc025bSLars-Peter Clausen 45dbdc025bSLars-Peter Clausen #define AD5421_FAULT_SPI BIT(15) 46dbdc025bSLars-Peter Clausen #define AD5421_FAULT_PEC BIT(14) 47dbdc025bSLars-Peter Clausen #define AD5421_FAULT_OVER_CURRENT BIT(13) 48dbdc025bSLars-Peter Clausen #define AD5421_FAULT_UNDER_CURRENT BIT(12) 49dbdc025bSLars-Peter Clausen #define AD5421_FAULT_TEMP_OVER_140 BIT(11) 50dbdc025bSLars-Peter Clausen #define AD5421_FAULT_TEMP_OVER_100 BIT(10) 51dbdc025bSLars-Peter Clausen #define AD5421_FAULT_UNDER_VOLTAGE_6V BIT(9) 52dbdc025bSLars-Peter Clausen #define AD5421_FAULT_UNDER_VOLTAGE_12V BIT(8) 53dbdc025bSLars-Peter Clausen 54dbdc025bSLars-Peter Clausen /* These bits will cause the fault pin to go high */ 55dbdc025bSLars-Peter Clausen #define AD5421_FAULT_TRIGGER_IRQ \ 56dbdc025bSLars-Peter Clausen (AD5421_FAULT_SPI | AD5421_FAULT_PEC | AD5421_FAULT_OVER_CURRENT | \ 57dbdc025bSLars-Peter Clausen AD5421_FAULT_UNDER_CURRENT | AD5421_FAULT_TEMP_OVER_140) 58dbdc025bSLars-Peter Clausen 59dbdc025bSLars-Peter Clausen /** 60dbdc025bSLars-Peter Clausen * struct ad5421_state - driver instance specific data 61dbdc025bSLars-Peter Clausen * @spi: spi_device 62dbdc025bSLars-Peter Clausen * @ctrl: control register cache 63dbdc025bSLars-Peter Clausen * @current_range: current range which the device is configured for 64dbdc025bSLars-Peter Clausen * @data: spi transfer buffers 65dbdc025bSLars-Peter Clausen * @fault_mask: software masking of events 66dbdc025bSLars-Peter Clausen */ 67dbdc025bSLars-Peter Clausen struct ad5421_state { 68dbdc025bSLars-Peter Clausen struct spi_device *spi; 69dbdc025bSLars-Peter Clausen unsigned int ctrl; 70dbdc025bSLars-Peter Clausen enum ad5421_current_range current_range; 71dbdc025bSLars-Peter Clausen unsigned int fault_mask; 72dbdc025bSLars-Peter Clausen 73dbdc025bSLars-Peter Clausen /* 74dbdc025bSLars-Peter Clausen * DMA (thus cache coherency maintenance) requires the 75dbdc025bSLars-Peter Clausen * transfer buffers to live in their own cache lines. 76dbdc025bSLars-Peter Clausen */ 77dbdc025bSLars-Peter Clausen union { 78dbdc025bSLars-Peter Clausen u32 d32; 79dbdc025bSLars-Peter Clausen u8 d8[4]; 80dbdc025bSLars-Peter Clausen } data[2] ____cacheline_aligned; 81dbdc025bSLars-Peter Clausen }; 82dbdc025bSLars-Peter Clausen 83dbdc025bSLars-Peter Clausen static const struct iio_chan_spec ad5421_channels[] = { 84dbdc025bSLars-Peter Clausen { 85dbdc025bSLars-Peter Clausen .type = IIO_CURRENT, 86dbdc025bSLars-Peter Clausen .indexed = 1, 87dbdc025bSLars-Peter Clausen .output = 1, 88dbdc025bSLars-Peter Clausen .channel = 0, 89dbdc025bSLars-Peter Clausen .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | 90dbdc025bSLars-Peter Clausen IIO_CHAN_INFO_SCALE_SHARED_BIT | 91dbdc025bSLars-Peter Clausen IIO_CHAN_INFO_OFFSET_SHARED_BIT | 92dbdc025bSLars-Peter Clausen IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | 93dbdc025bSLars-Peter Clausen IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, 94dbdc025bSLars-Peter Clausen .scan_type = IIO_ST('u', 16, 16, 0), 95dbdc025bSLars-Peter Clausen .event_mask = IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) | 96dbdc025bSLars-Peter Clausen IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING), 97dbdc025bSLars-Peter Clausen }, 98dbdc025bSLars-Peter Clausen { 99dbdc025bSLars-Peter Clausen .type = IIO_TEMP, 100dbdc025bSLars-Peter Clausen .channel = -1, 101dbdc025bSLars-Peter Clausen .event_mask = IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING), 102dbdc025bSLars-Peter Clausen }, 103dbdc025bSLars-Peter Clausen }; 104dbdc025bSLars-Peter Clausen 105dbdc025bSLars-Peter Clausen static int ad5421_write_unlocked(struct iio_dev *indio_dev, 106dbdc025bSLars-Peter Clausen unsigned int reg, unsigned int val) 107dbdc025bSLars-Peter Clausen { 108dbdc025bSLars-Peter Clausen struct ad5421_state *st = iio_priv(indio_dev); 109dbdc025bSLars-Peter Clausen 110dbdc025bSLars-Peter Clausen st->data[0].d32 = cpu_to_be32((reg << 16) | val); 111dbdc025bSLars-Peter Clausen 112dbdc025bSLars-Peter Clausen return spi_write(st->spi, &st->data[0].d8[1], 3); 113dbdc025bSLars-Peter Clausen } 114dbdc025bSLars-Peter Clausen 115dbdc025bSLars-Peter Clausen static int ad5421_write(struct iio_dev *indio_dev, unsigned int reg, 116dbdc025bSLars-Peter Clausen unsigned int val) 117dbdc025bSLars-Peter Clausen { 118dbdc025bSLars-Peter Clausen int ret; 119dbdc025bSLars-Peter Clausen 120dbdc025bSLars-Peter Clausen mutex_lock(&indio_dev->mlock); 121dbdc025bSLars-Peter Clausen ret = ad5421_write_unlocked(indio_dev, reg, val); 122dbdc025bSLars-Peter Clausen mutex_unlock(&indio_dev->mlock); 123dbdc025bSLars-Peter Clausen 124dbdc025bSLars-Peter Clausen return ret; 125dbdc025bSLars-Peter Clausen } 126dbdc025bSLars-Peter Clausen 127dbdc025bSLars-Peter Clausen static int ad5421_read(struct iio_dev *indio_dev, unsigned int reg) 128dbdc025bSLars-Peter Clausen { 129dbdc025bSLars-Peter Clausen struct ad5421_state *st = iio_priv(indio_dev); 130dbdc025bSLars-Peter Clausen int ret; 131dbdc025bSLars-Peter Clausen struct spi_transfer t[] = { 132dbdc025bSLars-Peter Clausen { 133dbdc025bSLars-Peter Clausen .tx_buf = &st->data[0].d8[1], 134dbdc025bSLars-Peter Clausen .len = 3, 135dbdc025bSLars-Peter Clausen .cs_change = 1, 136dbdc025bSLars-Peter Clausen }, { 137dbdc025bSLars-Peter Clausen .rx_buf = &st->data[1].d8[1], 138dbdc025bSLars-Peter Clausen .len = 3, 139dbdc025bSLars-Peter Clausen }, 140dbdc025bSLars-Peter Clausen }; 141dbdc025bSLars-Peter Clausen 142dbdc025bSLars-Peter Clausen mutex_lock(&indio_dev->mlock); 143dbdc025bSLars-Peter Clausen 144dbdc025bSLars-Peter Clausen st->data[0].d32 = cpu_to_be32((1 << 23) | (reg << 16)); 145dbdc025bSLars-Peter Clausen 14614543a00SLars-Peter Clausen ret = spi_sync_transfer(st->spi, t, ARRAY_SIZE(t)); 147dbdc025bSLars-Peter Clausen if (ret >= 0) 148dbdc025bSLars-Peter Clausen ret = be32_to_cpu(st->data[1].d32) & 0xffff; 149dbdc025bSLars-Peter Clausen 150dbdc025bSLars-Peter Clausen mutex_unlock(&indio_dev->mlock); 151dbdc025bSLars-Peter Clausen 152dbdc025bSLars-Peter Clausen return ret; 153dbdc025bSLars-Peter Clausen } 154dbdc025bSLars-Peter Clausen 155dbdc025bSLars-Peter Clausen static int ad5421_update_ctrl(struct iio_dev *indio_dev, unsigned int set, 156dbdc025bSLars-Peter Clausen unsigned int clr) 157dbdc025bSLars-Peter Clausen { 158dbdc025bSLars-Peter Clausen struct ad5421_state *st = iio_priv(indio_dev); 159dbdc025bSLars-Peter Clausen unsigned int ret; 160dbdc025bSLars-Peter Clausen 161dbdc025bSLars-Peter Clausen mutex_lock(&indio_dev->mlock); 162dbdc025bSLars-Peter Clausen 163dbdc025bSLars-Peter Clausen st->ctrl &= ~clr; 164dbdc025bSLars-Peter Clausen st->ctrl |= set; 165dbdc025bSLars-Peter Clausen 166dbdc025bSLars-Peter Clausen ret = ad5421_write_unlocked(indio_dev, AD5421_REG_CTRL, st->ctrl); 167dbdc025bSLars-Peter Clausen 168dbdc025bSLars-Peter Clausen mutex_unlock(&indio_dev->mlock); 169dbdc025bSLars-Peter Clausen 170dbdc025bSLars-Peter Clausen return ret; 171dbdc025bSLars-Peter Clausen } 172dbdc025bSLars-Peter Clausen 173dbdc025bSLars-Peter Clausen static irqreturn_t ad5421_fault_handler(int irq, void *data) 174dbdc025bSLars-Peter Clausen { 175dbdc025bSLars-Peter Clausen struct iio_dev *indio_dev = data; 176dbdc025bSLars-Peter Clausen struct ad5421_state *st = iio_priv(indio_dev); 177dbdc025bSLars-Peter Clausen unsigned int fault; 178dbdc025bSLars-Peter Clausen unsigned int old_fault = 0; 179dbdc025bSLars-Peter Clausen unsigned int events; 180dbdc025bSLars-Peter Clausen 181dbdc025bSLars-Peter Clausen fault = ad5421_read(indio_dev, AD5421_REG_FAULT); 182dbdc025bSLars-Peter Clausen if (!fault) 183dbdc025bSLars-Peter Clausen return IRQ_NONE; 184dbdc025bSLars-Peter Clausen 185dbdc025bSLars-Peter Clausen /* If we had a fault, this might mean that the DAC has lost its state 186dbdc025bSLars-Peter Clausen * and has been reset. Make sure that the control register actually 187dbdc025bSLars-Peter Clausen * contains what we expect it to contain. Otherwise the watchdog might 188dbdc025bSLars-Peter Clausen * be enabled and we get watchdog timeout faults, which will render the 189dbdc025bSLars-Peter Clausen * DAC unusable. */ 190dbdc025bSLars-Peter Clausen ad5421_update_ctrl(indio_dev, 0, 0); 191dbdc025bSLars-Peter Clausen 192dbdc025bSLars-Peter Clausen 193dbdc025bSLars-Peter Clausen /* The fault pin stays high as long as a fault condition is present and 194dbdc025bSLars-Peter Clausen * it is not possible to mask fault conditions. For certain fault 195dbdc025bSLars-Peter Clausen * conditions for example like over-temperature it takes some time 196dbdc025bSLars-Peter Clausen * until the fault condition disappears. If we would exit the interrupt 197dbdc025bSLars-Peter Clausen * handler immediately after handling the event it would be entered 198dbdc025bSLars-Peter Clausen * again instantly. Thus we fall back to polling in case we detect that 199dbdc025bSLars-Peter Clausen * a interrupt condition is still present. 200dbdc025bSLars-Peter Clausen */ 201dbdc025bSLars-Peter Clausen do { 202dbdc025bSLars-Peter Clausen /* 0xffff is a invalid value for the register and will only be 203dbdc025bSLars-Peter Clausen * read if there has been a communication error */ 204dbdc025bSLars-Peter Clausen if (fault == 0xffff) 205dbdc025bSLars-Peter Clausen fault = 0; 206dbdc025bSLars-Peter Clausen 207dbdc025bSLars-Peter Clausen /* we are only interested in new events */ 208dbdc025bSLars-Peter Clausen events = (old_fault ^ fault) & fault; 209dbdc025bSLars-Peter Clausen events &= st->fault_mask; 210dbdc025bSLars-Peter Clausen 211dbdc025bSLars-Peter Clausen if (events & AD5421_FAULT_OVER_CURRENT) { 212dbdc025bSLars-Peter Clausen iio_push_event(indio_dev, 213dbdc025bSLars-Peter Clausen IIO_UNMOD_EVENT_CODE(IIO_CURRENT, 214dbdc025bSLars-Peter Clausen 0, 215dbdc025bSLars-Peter Clausen IIO_EV_TYPE_THRESH, 216dbdc025bSLars-Peter Clausen IIO_EV_DIR_RISING), 217dbdc025bSLars-Peter Clausen iio_get_time_ns()); 218dbdc025bSLars-Peter Clausen } 219dbdc025bSLars-Peter Clausen 220dbdc025bSLars-Peter Clausen if (events & AD5421_FAULT_UNDER_CURRENT) { 221dbdc025bSLars-Peter Clausen iio_push_event(indio_dev, 222dbdc025bSLars-Peter Clausen IIO_UNMOD_EVENT_CODE(IIO_CURRENT, 223dbdc025bSLars-Peter Clausen 0, 224dbdc025bSLars-Peter Clausen IIO_EV_TYPE_THRESH, 225dbdc025bSLars-Peter Clausen IIO_EV_DIR_FALLING), 226dbdc025bSLars-Peter Clausen iio_get_time_ns()); 227dbdc025bSLars-Peter Clausen } 228dbdc025bSLars-Peter Clausen 229dbdc025bSLars-Peter Clausen if (events & AD5421_FAULT_TEMP_OVER_140) { 230dbdc025bSLars-Peter Clausen iio_push_event(indio_dev, 231dbdc025bSLars-Peter Clausen IIO_UNMOD_EVENT_CODE(IIO_TEMP, 232dbdc025bSLars-Peter Clausen 0, 233dbdc025bSLars-Peter Clausen IIO_EV_TYPE_MAG, 234dbdc025bSLars-Peter Clausen IIO_EV_DIR_RISING), 235dbdc025bSLars-Peter Clausen iio_get_time_ns()); 236dbdc025bSLars-Peter Clausen } 237dbdc025bSLars-Peter Clausen 238dbdc025bSLars-Peter Clausen old_fault = fault; 239dbdc025bSLars-Peter Clausen fault = ad5421_read(indio_dev, AD5421_REG_FAULT); 240dbdc025bSLars-Peter Clausen 241dbdc025bSLars-Peter Clausen /* still active? go to sleep for some time */ 242dbdc025bSLars-Peter Clausen if (fault & AD5421_FAULT_TRIGGER_IRQ) 243dbdc025bSLars-Peter Clausen msleep(1000); 244dbdc025bSLars-Peter Clausen 245dbdc025bSLars-Peter Clausen } while (fault & AD5421_FAULT_TRIGGER_IRQ); 246dbdc025bSLars-Peter Clausen 247dbdc025bSLars-Peter Clausen 248dbdc025bSLars-Peter Clausen return IRQ_HANDLED; 249dbdc025bSLars-Peter Clausen } 250dbdc025bSLars-Peter Clausen 251dbdc025bSLars-Peter Clausen static void ad5421_get_current_min_max(struct ad5421_state *st, 252dbdc025bSLars-Peter Clausen unsigned int *min, unsigned int *max) 253dbdc025bSLars-Peter Clausen { 254dbdc025bSLars-Peter Clausen /* The current range is configured using external pins, which are 255dbdc025bSLars-Peter Clausen * usually hard-wired and not run-time switchable. */ 256dbdc025bSLars-Peter Clausen switch (st->current_range) { 257dbdc025bSLars-Peter Clausen case AD5421_CURRENT_RANGE_4mA_20mA: 258dbdc025bSLars-Peter Clausen *min = 4000; 259dbdc025bSLars-Peter Clausen *max = 20000; 260dbdc025bSLars-Peter Clausen break; 261dbdc025bSLars-Peter Clausen case AD5421_CURRENT_RANGE_3mA8_21mA: 262dbdc025bSLars-Peter Clausen *min = 3800; 263dbdc025bSLars-Peter Clausen *max = 21000; 264dbdc025bSLars-Peter Clausen break; 265dbdc025bSLars-Peter Clausen case AD5421_CURRENT_RANGE_3mA2_24mA: 266dbdc025bSLars-Peter Clausen *min = 3200; 267dbdc025bSLars-Peter Clausen *max = 24000; 268dbdc025bSLars-Peter Clausen break; 269dbdc025bSLars-Peter Clausen default: 270dbdc025bSLars-Peter Clausen *min = 0; 271dbdc025bSLars-Peter Clausen *max = 1; 272dbdc025bSLars-Peter Clausen break; 273dbdc025bSLars-Peter Clausen } 274dbdc025bSLars-Peter Clausen } 275dbdc025bSLars-Peter Clausen 276dbdc025bSLars-Peter Clausen static inline unsigned int ad5421_get_offset(struct ad5421_state *st) 277dbdc025bSLars-Peter Clausen { 278dbdc025bSLars-Peter Clausen unsigned int min, max; 279dbdc025bSLars-Peter Clausen 280dbdc025bSLars-Peter Clausen ad5421_get_current_min_max(st, &min, &max); 281dbdc025bSLars-Peter Clausen return (min * (1 << 16)) / (max - min); 282dbdc025bSLars-Peter Clausen } 283dbdc025bSLars-Peter Clausen 284dbdc025bSLars-Peter Clausen static inline unsigned int ad5421_get_scale(struct ad5421_state *st) 285dbdc025bSLars-Peter Clausen { 286dbdc025bSLars-Peter Clausen unsigned int min, max; 287dbdc025bSLars-Peter Clausen 288dbdc025bSLars-Peter Clausen ad5421_get_current_min_max(st, &min, &max); 289dbdc025bSLars-Peter Clausen return ((max - min) * 1000) / (1 << 16); 290dbdc025bSLars-Peter Clausen } 291dbdc025bSLars-Peter Clausen 292dbdc025bSLars-Peter Clausen static int ad5421_read_raw(struct iio_dev *indio_dev, 293dbdc025bSLars-Peter Clausen struct iio_chan_spec const *chan, int *val, int *val2, long m) 294dbdc025bSLars-Peter Clausen { 295dbdc025bSLars-Peter Clausen struct ad5421_state *st = iio_priv(indio_dev); 296dbdc025bSLars-Peter Clausen int ret; 297dbdc025bSLars-Peter Clausen 298dbdc025bSLars-Peter Clausen if (chan->type != IIO_CURRENT) 299dbdc025bSLars-Peter Clausen return -EINVAL; 300dbdc025bSLars-Peter Clausen 301dbdc025bSLars-Peter Clausen switch (m) { 302dbdc025bSLars-Peter Clausen case IIO_CHAN_INFO_RAW: 303dbdc025bSLars-Peter Clausen ret = ad5421_read(indio_dev, AD5421_REG_DAC_DATA); 304dbdc025bSLars-Peter Clausen if (ret < 0) 305dbdc025bSLars-Peter Clausen return ret; 306dbdc025bSLars-Peter Clausen *val = ret; 307dbdc025bSLars-Peter Clausen return IIO_VAL_INT; 308dbdc025bSLars-Peter Clausen case IIO_CHAN_INFO_SCALE: 309dbdc025bSLars-Peter Clausen *val = 0; 310dbdc025bSLars-Peter Clausen *val2 = ad5421_get_scale(st); 311dbdc025bSLars-Peter Clausen return IIO_VAL_INT_PLUS_MICRO; 312dbdc025bSLars-Peter Clausen case IIO_CHAN_INFO_OFFSET: 313dbdc025bSLars-Peter Clausen *val = ad5421_get_offset(st); 314dbdc025bSLars-Peter Clausen return IIO_VAL_INT; 315dbdc025bSLars-Peter Clausen case IIO_CHAN_INFO_CALIBBIAS: 316dbdc025bSLars-Peter Clausen ret = ad5421_read(indio_dev, AD5421_REG_OFFSET); 317dbdc025bSLars-Peter Clausen if (ret < 0) 318dbdc025bSLars-Peter Clausen return ret; 319dbdc025bSLars-Peter Clausen *val = ret - 32768; 320dbdc025bSLars-Peter Clausen return IIO_VAL_INT; 321dbdc025bSLars-Peter Clausen case IIO_CHAN_INFO_CALIBSCALE: 322dbdc025bSLars-Peter Clausen ret = ad5421_read(indio_dev, AD5421_REG_GAIN); 323dbdc025bSLars-Peter Clausen if (ret < 0) 324dbdc025bSLars-Peter Clausen return ret; 325dbdc025bSLars-Peter Clausen *val = ret; 326dbdc025bSLars-Peter Clausen return IIO_VAL_INT; 327dbdc025bSLars-Peter Clausen } 328dbdc025bSLars-Peter Clausen 329dbdc025bSLars-Peter Clausen return -EINVAL; 330dbdc025bSLars-Peter Clausen } 331dbdc025bSLars-Peter Clausen 332dbdc025bSLars-Peter Clausen static int ad5421_write_raw(struct iio_dev *indio_dev, 333dbdc025bSLars-Peter Clausen struct iio_chan_spec const *chan, int val, int val2, long mask) 334dbdc025bSLars-Peter Clausen { 335dbdc025bSLars-Peter Clausen const unsigned int max_val = 1 << 16; 336dbdc025bSLars-Peter Clausen 337dbdc025bSLars-Peter Clausen switch (mask) { 338dbdc025bSLars-Peter Clausen case IIO_CHAN_INFO_RAW: 339dbdc025bSLars-Peter Clausen if (val >= max_val || val < 0) 340dbdc025bSLars-Peter Clausen return -EINVAL; 341dbdc025bSLars-Peter Clausen 342dbdc025bSLars-Peter Clausen return ad5421_write(indio_dev, AD5421_REG_DAC_DATA, val); 343dbdc025bSLars-Peter Clausen case IIO_CHAN_INFO_CALIBBIAS: 344dbdc025bSLars-Peter Clausen val += 32768; 345dbdc025bSLars-Peter Clausen if (val >= max_val || val < 0) 346dbdc025bSLars-Peter Clausen return -EINVAL; 347dbdc025bSLars-Peter Clausen 348dbdc025bSLars-Peter Clausen return ad5421_write(indio_dev, AD5421_REG_OFFSET, val); 349dbdc025bSLars-Peter Clausen case IIO_CHAN_INFO_CALIBSCALE: 350dbdc025bSLars-Peter Clausen if (val >= max_val || val < 0) 351dbdc025bSLars-Peter Clausen return -EINVAL; 352dbdc025bSLars-Peter Clausen 353dbdc025bSLars-Peter Clausen return ad5421_write(indio_dev, AD5421_REG_GAIN, val); 354dbdc025bSLars-Peter Clausen default: 355dbdc025bSLars-Peter Clausen break; 356dbdc025bSLars-Peter Clausen } 357dbdc025bSLars-Peter Clausen 358dbdc025bSLars-Peter Clausen return -EINVAL; 359dbdc025bSLars-Peter Clausen } 360dbdc025bSLars-Peter Clausen 361dbdc025bSLars-Peter Clausen static int ad5421_write_event_config(struct iio_dev *indio_dev, 362dbdc025bSLars-Peter Clausen u64 event_code, int state) 363dbdc025bSLars-Peter Clausen { 364dbdc025bSLars-Peter Clausen struct ad5421_state *st = iio_priv(indio_dev); 365dbdc025bSLars-Peter Clausen unsigned int mask; 366dbdc025bSLars-Peter Clausen 367dbdc025bSLars-Peter Clausen switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) { 368dbdc025bSLars-Peter Clausen case IIO_CURRENT: 369dbdc025bSLars-Peter Clausen if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == 370dbdc025bSLars-Peter Clausen IIO_EV_DIR_RISING) 371dbdc025bSLars-Peter Clausen mask = AD5421_FAULT_OVER_CURRENT; 372dbdc025bSLars-Peter Clausen else 373dbdc025bSLars-Peter Clausen mask = AD5421_FAULT_UNDER_CURRENT; 374dbdc025bSLars-Peter Clausen break; 375dbdc025bSLars-Peter Clausen case IIO_TEMP: 376dbdc025bSLars-Peter Clausen mask = AD5421_FAULT_TEMP_OVER_140; 377dbdc025bSLars-Peter Clausen break; 378dbdc025bSLars-Peter Clausen default: 379dbdc025bSLars-Peter Clausen return -EINVAL; 380dbdc025bSLars-Peter Clausen } 381dbdc025bSLars-Peter Clausen 382dbdc025bSLars-Peter Clausen mutex_lock(&indio_dev->mlock); 383dbdc025bSLars-Peter Clausen if (state) 384dbdc025bSLars-Peter Clausen st->fault_mask |= mask; 385dbdc025bSLars-Peter Clausen else 386dbdc025bSLars-Peter Clausen st->fault_mask &= ~mask; 387dbdc025bSLars-Peter Clausen mutex_unlock(&indio_dev->mlock); 388dbdc025bSLars-Peter Clausen 389dbdc025bSLars-Peter Clausen return 0; 390dbdc025bSLars-Peter Clausen } 391dbdc025bSLars-Peter Clausen 392dbdc025bSLars-Peter Clausen static int ad5421_read_event_config(struct iio_dev *indio_dev, 393dbdc025bSLars-Peter Clausen u64 event_code) 394dbdc025bSLars-Peter Clausen { 395dbdc025bSLars-Peter Clausen struct ad5421_state *st = iio_priv(indio_dev); 396dbdc025bSLars-Peter Clausen unsigned int mask; 397dbdc025bSLars-Peter Clausen 398dbdc025bSLars-Peter Clausen switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) { 399dbdc025bSLars-Peter Clausen case IIO_CURRENT: 400dbdc025bSLars-Peter Clausen if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == 401dbdc025bSLars-Peter Clausen IIO_EV_DIR_RISING) 402dbdc025bSLars-Peter Clausen mask = AD5421_FAULT_OVER_CURRENT; 403dbdc025bSLars-Peter Clausen else 404dbdc025bSLars-Peter Clausen mask = AD5421_FAULT_UNDER_CURRENT; 405dbdc025bSLars-Peter Clausen break; 406dbdc025bSLars-Peter Clausen case IIO_TEMP: 407dbdc025bSLars-Peter Clausen mask = AD5421_FAULT_TEMP_OVER_140; 408dbdc025bSLars-Peter Clausen break; 409dbdc025bSLars-Peter Clausen default: 410dbdc025bSLars-Peter Clausen return -EINVAL; 411dbdc025bSLars-Peter Clausen } 412dbdc025bSLars-Peter Clausen 413dbdc025bSLars-Peter Clausen return (bool)(st->fault_mask & mask); 414dbdc025bSLars-Peter Clausen } 415dbdc025bSLars-Peter Clausen 416dbdc025bSLars-Peter Clausen static int ad5421_read_event_value(struct iio_dev *indio_dev, u64 event_code, 417dbdc025bSLars-Peter Clausen int *val) 418dbdc025bSLars-Peter Clausen { 419dbdc025bSLars-Peter Clausen int ret; 420dbdc025bSLars-Peter Clausen 421dbdc025bSLars-Peter Clausen switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) { 422dbdc025bSLars-Peter Clausen case IIO_CURRENT: 423dbdc025bSLars-Peter Clausen ret = ad5421_read(indio_dev, AD5421_REG_DAC_DATA); 424dbdc025bSLars-Peter Clausen if (ret < 0) 425dbdc025bSLars-Peter Clausen return ret; 426dbdc025bSLars-Peter Clausen *val = ret; 427dbdc025bSLars-Peter Clausen break; 428dbdc025bSLars-Peter Clausen case IIO_TEMP: 429dbdc025bSLars-Peter Clausen *val = 140000; 430dbdc025bSLars-Peter Clausen break; 431dbdc025bSLars-Peter Clausen default: 432dbdc025bSLars-Peter Clausen return -EINVAL; 433dbdc025bSLars-Peter Clausen } 434dbdc025bSLars-Peter Clausen 435dbdc025bSLars-Peter Clausen return 0; 436dbdc025bSLars-Peter Clausen } 437dbdc025bSLars-Peter Clausen 438dbdc025bSLars-Peter Clausen static const struct iio_info ad5421_info = { 439dbdc025bSLars-Peter Clausen .read_raw = ad5421_read_raw, 440dbdc025bSLars-Peter Clausen .write_raw = ad5421_write_raw, 441dbdc025bSLars-Peter Clausen .read_event_config = ad5421_read_event_config, 442dbdc025bSLars-Peter Clausen .write_event_config = ad5421_write_event_config, 443dbdc025bSLars-Peter Clausen .read_event_value = ad5421_read_event_value, 444dbdc025bSLars-Peter Clausen .driver_module = THIS_MODULE, 445dbdc025bSLars-Peter Clausen }; 446dbdc025bSLars-Peter Clausen 447fc52692cSGreg Kroah-Hartman static int ad5421_probe(struct spi_device *spi) 448dbdc025bSLars-Peter Clausen { 449dbdc025bSLars-Peter Clausen struct ad5421_platform_data *pdata = dev_get_platdata(&spi->dev); 450dbdc025bSLars-Peter Clausen struct iio_dev *indio_dev; 451dbdc025bSLars-Peter Clausen struct ad5421_state *st; 452dbdc025bSLars-Peter Clausen int ret; 453dbdc025bSLars-Peter Clausen 454dbdc025bSLars-Peter Clausen indio_dev = iio_device_alloc(sizeof(*st)); 455dbdc025bSLars-Peter Clausen if (indio_dev == NULL) { 456dbdc025bSLars-Peter Clausen dev_err(&spi->dev, "Failed to allocate iio device\n"); 457dbdc025bSLars-Peter Clausen return -ENOMEM; 458dbdc025bSLars-Peter Clausen } 459dbdc025bSLars-Peter Clausen 460dbdc025bSLars-Peter Clausen st = iio_priv(indio_dev); 461dbdc025bSLars-Peter Clausen spi_set_drvdata(spi, indio_dev); 462dbdc025bSLars-Peter Clausen 463dbdc025bSLars-Peter Clausen st->spi = spi; 464dbdc025bSLars-Peter Clausen 465dbdc025bSLars-Peter Clausen indio_dev->dev.parent = &spi->dev; 466dbdc025bSLars-Peter Clausen indio_dev->name = "ad5421"; 467dbdc025bSLars-Peter Clausen indio_dev->info = &ad5421_info; 468dbdc025bSLars-Peter Clausen indio_dev->modes = INDIO_DIRECT_MODE; 469dbdc025bSLars-Peter Clausen indio_dev->channels = ad5421_channels; 470dbdc025bSLars-Peter Clausen indio_dev->num_channels = ARRAY_SIZE(ad5421_channels); 471dbdc025bSLars-Peter Clausen 472dbdc025bSLars-Peter Clausen st->ctrl = AD5421_CTRL_WATCHDOG_DISABLE | 473dbdc025bSLars-Peter Clausen AD5421_CTRL_AUTO_FAULT_READBACK; 474dbdc025bSLars-Peter Clausen 475dbdc025bSLars-Peter Clausen if (pdata) { 476dbdc025bSLars-Peter Clausen st->current_range = pdata->current_range; 477dbdc025bSLars-Peter Clausen if (pdata->external_vref) 478dbdc025bSLars-Peter Clausen st->ctrl |= AD5421_CTRL_PWR_DOWN_INT_VREF; 479dbdc025bSLars-Peter Clausen } else { 480dbdc025bSLars-Peter Clausen st->current_range = AD5421_CURRENT_RANGE_4mA_20mA; 481dbdc025bSLars-Peter Clausen } 482dbdc025bSLars-Peter Clausen 483dbdc025bSLars-Peter Clausen /* write initial ctrl register value */ 484dbdc025bSLars-Peter Clausen ad5421_update_ctrl(indio_dev, 0, 0); 485dbdc025bSLars-Peter Clausen 486dbdc025bSLars-Peter Clausen if (spi->irq) { 487dbdc025bSLars-Peter Clausen ret = request_threaded_irq(spi->irq, 488dbdc025bSLars-Peter Clausen NULL, 489dbdc025bSLars-Peter Clausen ad5421_fault_handler, 490dbdc025bSLars-Peter Clausen IRQF_TRIGGER_HIGH | IRQF_ONESHOT, 491dbdc025bSLars-Peter Clausen "ad5421 fault", 492dbdc025bSLars-Peter Clausen indio_dev); 493dbdc025bSLars-Peter Clausen if (ret) 494dbdc025bSLars-Peter Clausen goto error_free; 495dbdc025bSLars-Peter Clausen } 496dbdc025bSLars-Peter Clausen 497dbdc025bSLars-Peter Clausen ret = iio_device_register(indio_dev); 498dbdc025bSLars-Peter Clausen if (ret) { 499dbdc025bSLars-Peter Clausen dev_err(&spi->dev, "Failed to register iio device: %d\n", ret); 500dbdc025bSLars-Peter Clausen goto error_free_irq; 501dbdc025bSLars-Peter Clausen } 502dbdc025bSLars-Peter Clausen 503dbdc025bSLars-Peter Clausen return 0; 504dbdc025bSLars-Peter Clausen 505dbdc025bSLars-Peter Clausen error_free_irq: 506dbdc025bSLars-Peter Clausen if (spi->irq) 507dbdc025bSLars-Peter Clausen free_irq(spi->irq, indio_dev); 508dbdc025bSLars-Peter Clausen error_free: 509dbdc025bSLars-Peter Clausen iio_device_free(indio_dev); 510dbdc025bSLars-Peter Clausen 511dbdc025bSLars-Peter Clausen return ret; 512dbdc025bSLars-Peter Clausen } 513dbdc025bSLars-Peter Clausen 514fc52692cSGreg Kroah-Hartman static int ad5421_remove(struct spi_device *spi) 515dbdc025bSLars-Peter Clausen { 516dbdc025bSLars-Peter Clausen struct iio_dev *indio_dev = spi_get_drvdata(spi); 517dbdc025bSLars-Peter Clausen 518dbdc025bSLars-Peter Clausen iio_device_unregister(indio_dev); 519dbdc025bSLars-Peter Clausen if (spi->irq) 520dbdc025bSLars-Peter Clausen free_irq(spi->irq, indio_dev); 521dbdc025bSLars-Peter Clausen iio_device_free(indio_dev); 522dbdc025bSLars-Peter Clausen 523dbdc025bSLars-Peter Clausen return 0; 524dbdc025bSLars-Peter Clausen } 525dbdc025bSLars-Peter Clausen 526dbdc025bSLars-Peter Clausen static struct spi_driver ad5421_driver = { 527dbdc025bSLars-Peter Clausen .driver = { 528dbdc025bSLars-Peter Clausen .name = "ad5421", 529dbdc025bSLars-Peter Clausen .owner = THIS_MODULE, 530dbdc025bSLars-Peter Clausen }, 531dbdc025bSLars-Peter Clausen .probe = ad5421_probe, 532fc52692cSGreg Kroah-Hartman .remove = ad5421_remove, 533dbdc025bSLars-Peter Clausen }; 534dbdc025bSLars-Peter Clausen module_spi_driver(ad5421_driver); 535dbdc025bSLars-Peter Clausen 536dbdc025bSLars-Peter Clausen MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); 537dbdc025bSLars-Peter Clausen MODULE_DESCRIPTION("Analog Devices AD5421 DAC"); 538dbdc025bSLars-Peter Clausen MODULE_LICENSE("GPL v2"); 539dbdc025bSLars-Peter Clausen MODULE_ALIAS("spi:ad5421"); 540