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 { 788ef411b7SLars-Peter Clausen __be32 d32; 79dbdc025bSLars-Peter Clausen u8 d8[4]; 80dbdc025bSLars-Peter Clausen } data[2] ____cacheline_aligned; 81dbdc025bSLars-Peter Clausen }; 82dbdc025bSLars-Peter Clausen 831eefd62bSLars-Peter Clausen static const struct iio_event_spec ad5421_current_event[] = { 841eefd62bSLars-Peter Clausen { 851eefd62bSLars-Peter Clausen .type = IIO_EV_TYPE_THRESH, 861eefd62bSLars-Peter Clausen .dir = IIO_EV_DIR_RISING, 871eefd62bSLars-Peter Clausen .mask_separate = BIT(IIO_EV_INFO_VALUE) | 881eefd62bSLars-Peter Clausen BIT(IIO_EV_INFO_ENABLE), 891eefd62bSLars-Peter Clausen }, { 901eefd62bSLars-Peter Clausen .type = IIO_EV_TYPE_THRESH, 911eefd62bSLars-Peter Clausen .dir = IIO_EV_DIR_FALLING, 921eefd62bSLars-Peter Clausen .mask_separate = BIT(IIO_EV_INFO_VALUE) | 931eefd62bSLars-Peter Clausen BIT(IIO_EV_INFO_ENABLE), 941eefd62bSLars-Peter Clausen }, 951eefd62bSLars-Peter Clausen }; 961eefd62bSLars-Peter Clausen 971eefd62bSLars-Peter Clausen static const struct iio_event_spec ad5421_temp_event[] = { 981eefd62bSLars-Peter Clausen { 991eefd62bSLars-Peter Clausen .type = IIO_EV_TYPE_THRESH, 1001eefd62bSLars-Peter Clausen .dir = IIO_EV_DIR_RISING, 1011eefd62bSLars-Peter Clausen .mask_separate = BIT(IIO_EV_INFO_VALUE) | 1021eefd62bSLars-Peter Clausen BIT(IIO_EV_INFO_ENABLE), 1031eefd62bSLars-Peter Clausen }, 1041eefd62bSLars-Peter Clausen }; 1051eefd62bSLars-Peter Clausen 106dbdc025bSLars-Peter Clausen static const struct iio_chan_spec ad5421_channels[] = { 107dbdc025bSLars-Peter Clausen { 108dbdc025bSLars-Peter Clausen .type = IIO_CURRENT, 109dbdc025bSLars-Peter Clausen .indexed = 1, 110dbdc025bSLars-Peter Clausen .output = 1, 111dbdc025bSLars-Peter Clausen .channel = 0, 11231311c2aSJonathan Cameron .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 11331311c2aSJonathan Cameron BIT(IIO_CHAN_INFO_CALIBSCALE) | 11431311c2aSJonathan Cameron BIT(IIO_CHAN_INFO_CALIBBIAS), 11531311c2aSJonathan Cameron .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | 11631311c2aSJonathan Cameron BIT(IIO_CHAN_INFO_OFFSET), 11749f82897SJonathan Cameron .scan_type = { 11849f82897SJonathan Cameron .sign = 'u', 11949f82897SJonathan Cameron .realbits = 16, 12049f82897SJonathan Cameron .storagebits = 16, 12149f82897SJonathan Cameron }, 1221eefd62bSLars-Peter Clausen .event_spec = ad5421_current_event, 1231eefd62bSLars-Peter Clausen .num_event_specs = ARRAY_SIZE(ad5421_current_event), 124dbdc025bSLars-Peter Clausen }, 125dbdc025bSLars-Peter Clausen { 126dbdc025bSLars-Peter Clausen .type = IIO_TEMP, 127dbdc025bSLars-Peter Clausen .channel = -1, 1281eefd62bSLars-Peter Clausen .event_spec = ad5421_temp_event, 1291eefd62bSLars-Peter Clausen .num_event_specs = ARRAY_SIZE(ad5421_temp_event), 130dbdc025bSLars-Peter Clausen }, 131dbdc025bSLars-Peter Clausen }; 132dbdc025bSLars-Peter Clausen 133dbdc025bSLars-Peter Clausen static int ad5421_write_unlocked(struct iio_dev *indio_dev, 134dbdc025bSLars-Peter Clausen unsigned int reg, unsigned int val) 135dbdc025bSLars-Peter Clausen { 136dbdc025bSLars-Peter Clausen struct ad5421_state *st = iio_priv(indio_dev); 137dbdc025bSLars-Peter Clausen 138dbdc025bSLars-Peter Clausen st->data[0].d32 = cpu_to_be32((reg << 16) | val); 139dbdc025bSLars-Peter Clausen 140dbdc025bSLars-Peter Clausen return spi_write(st->spi, &st->data[0].d8[1], 3); 141dbdc025bSLars-Peter Clausen } 142dbdc025bSLars-Peter Clausen 143dbdc025bSLars-Peter Clausen static int ad5421_write(struct iio_dev *indio_dev, unsigned int reg, 144dbdc025bSLars-Peter Clausen unsigned int val) 145dbdc025bSLars-Peter Clausen { 146dbdc025bSLars-Peter Clausen int ret; 147dbdc025bSLars-Peter Clausen 148dbdc025bSLars-Peter Clausen mutex_lock(&indio_dev->mlock); 149dbdc025bSLars-Peter Clausen ret = ad5421_write_unlocked(indio_dev, reg, val); 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_read(struct iio_dev *indio_dev, unsigned int reg) 156dbdc025bSLars-Peter Clausen { 157dbdc025bSLars-Peter Clausen struct ad5421_state *st = iio_priv(indio_dev); 158dbdc025bSLars-Peter Clausen int ret; 159dbdc025bSLars-Peter Clausen struct spi_transfer t[] = { 160dbdc025bSLars-Peter Clausen { 161dbdc025bSLars-Peter Clausen .tx_buf = &st->data[0].d8[1], 162dbdc025bSLars-Peter Clausen .len = 3, 163dbdc025bSLars-Peter Clausen .cs_change = 1, 164dbdc025bSLars-Peter Clausen }, { 165dbdc025bSLars-Peter Clausen .rx_buf = &st->data[1].d8[1], 166dbdc025bSLars-Peter Clausen .len = 3, 167dbdc025bSLars-Peter Clausen }, 168dbdc025bSLars-Peter Clausen }; 169dbdc025bSLars-Peter Clausen 170dbdc025bSLars-Peter Clausen mutex_lock(&indio_dev->mlock); 171dbdc025bSLars-Peter Clausen 172dbdc025bSLars-Peter Clausen st->data[0].d32 = cpu_to_be32((1 << 23) | (reg << 16)); 173dbdc025bSLars-Peter Clausen 17414543a00SLars-Peter Clausen ret = spi_sync_transfer(st->spi, t, ARRAY_SIZE(t)); 175dbdc025bSLars-Peter Clausen if (ret >= 0) 176dbdc025bSLars-Peter Clausen ret = be32_to_cpu(st->data[1].d32) & 0xffff; 177dbdc025bSLars-Peter Clausen 178dbdc025bSLars-Peter Clausen mutex_unlock(&indio_dev->mlock); 179dbdc025bSLars-Peter Clausen 180dbdc025bSLars-Peter Clausen return ret; 181dbdc025bSLars-Peter Clausen } 182dbdc025bSLars-Peter Clausen 183dbdc025bSLars-Peter Clausen static int ad5421_update_ctrl(struct iio_dev *indio_dev, unsigned int set, 184dbdc025bSLars-Peter Clausen unsigned int clr) 185dbdc025bSLars-Peter Clausen { 186dbdc025bSLars-Peter Clausen struct ad5421_state *st = iio_priv(indio_dev); 187dbdc025bSLars-Peter Clausen unsigned int ret; 188dbdc025bSLars-Peter Clausen 189dbdc025bSLars-Peter Clausen mutex_lock(&indio_dev->mlock); 190dbdc025bSLars-Peter Clausen 191dbdc025bSLars-Peter Clausen st->ctrl &= ~clr; 192dbdc025bSLars-Peter Clausen st->ctrl |= set; 193dbdc025bSLars-Peter Clausen 194dbdc025bSLars-Peter Clausen ret = ad5421_write_unlocked(indio_dev, AD5421_REG_CTRL, st->ctrl); 195dbdc025bSLars-Peter Clausen 196dbdc025bSLars-Peter Clausen mutex_unlock(&indio_dev->mlock); 197dbdc025bSLars-Peter Clausen 198dbdc025bSLars-Peter Clausen return ret; 199dbdc025bSLars-Peter Clausen } 200dbdc025bSLars-Peter Clausen 201dbdc025bSLars-Peter Clausen static irqreturn_t ad5421_fault_handler(int irq, void *data) 202dbdc025bSLars-Peter Clausen { 203dbdc025bSLars-Peter Clausen struct iio_dev *indio_dev = data; 204dbdc025bSLars-Peter Clausen struct ad5421_state *st = iio_priv(indio_dev); 205dbdc025bSLars-Peter Clausen unsigned int fault; 206dbdc025bSLars-Peter Clausen unsigned int old_fault = 0; 207dbdc025bSLars-Peter Clausen unsigned int events; 208dbdc025bSLars-Peter Clausen 209dbdc025bSLars-Peter Clausen fault = ad5421_read(indio_dev, AD5421_REG_FAULT); 210dbdc025bSLars-Peter Clausen if (!fault) 211dbdc025bSLars-Peter Clausen return IRQ_NONE; 212dbdc025bSLars-Peter Clausen 213dbdc025bSLars-Peter Clausen /* If we had a fault, this might mean that the DAC has lost its state 214dbdc025bSLars-Peter Clausen * and has been reset. Make sure that the control register actually 215dbdc025bSLars-Peter Clausen * contains what we expect it to contain. Otherwise the watchdog might 216dbdc025bSLars-Peter Clausen * be enabled and we get watchdog timeout faults, which will render the 217dbdc025bSLars-Peter Clausen * DAC unusable. */ 218dbdc025bSLars-Peter Clausen ad5421_update_ctrl(indio_dev, 0, 0); 219dbdc025bSLars-Peter Clausen 220dbdc025bSLars-Peter Clausen 221dbdc025bSLars-Peter Clausen /* The fault pin stays high as long as a fault condition is present and 222dbdc025bSLars-Peter Clausen * it is not possible to mask fault conditions. For certain fault 223dbdc025bSLars-Peter Clausen * conditions for example like over-temperature it takes some time 224dbdc025bSLars-Peter Clausen * until the fault condition disappears. If we would exit the interrupt 225dbdc025bSLars-Peter Clausen * handler immediately after handling the event it would be entered 226dbdc025bSLars-Peter Clausen * again instantly. Thus we fall back to polling in case we detect that 227dbdc025bSLars-Peter Clausen * a interrupt condition is still present. 228dbdc025bSLars-Peter Clausen */ 229dbdc025bSLars-Peter Clausen do { 230dbdc025bSLars-Peter Clausen /* 0xffff is a invalid value for the register and will only be 231dbdc025bSLars-Peter Clausen * read if there has been a communication error */ 232dbdc025bSLars-Peter Clausen if (fault == 0xffff) 233dbdc025bSLars-Peter Clausen fault = 0; 234dbdc025bSLars-Peter Clausen 235dbdc025bSLars-Peter Clausen /* we are only interested in new events */ 236dbdc025bSLars-Peter Clausen events = (old_fault ^ fault) & fault; 237dbdc025bSLars-Peter Clausen events &= st->fault_mask; 238dbdc025bSLars-Peter Clausen 239dbdc025bSLars-Peter Clausen if (events & AD5421_FAULT_OVER_CURRENT) { 240dbdc025bSLars-Peter Clausen iio_push_event(indio_dev, 241dbdc025bSLars-Peter Clausen IIO_UNMOD_EVENT_CODE(IIO_CURRENT, 242dbdc025bSLars-Peter Clausen 0, 243dbdc025bSLars-Peter Clausen IIO_EV_TYPE_THRESH, 244dbdc025bSLars-Peter Clausen IIO_EV_DIR_RISING), 245dbdc025bSLars-Peter Clausen iio_get_time_ns()); 246dbdc025bSLars-Peter Clausen } 247dbdc025bSLars-Peter Clausen 248dbdc025bSLars-Peter Clausen if (events & AD5421_FAULT_UNDER_CURRENT) { 249dbdc025bSLars-Peter Clausen iio_push_event(indio_dev, 250dbdc025bSLars-Peter Clausen IIO_UNMOD_EVENT_CODE(IIO_CURRENT, 251dbdc025bSLars-Peter Clausen 0, 252dbdc025bSLars-Peter Clausen IIO_EV_TYPE_THRESH, 253dbdc025bSLars-Peter Clausen IIO_EV_DIR_FALLING), 254dbdc025bSLars-Peter Clausen iio_get_time_ns()); 255dbdc025bSLars-Peter Clausen } 256dbdc025bSLars-Peter Clausen 257dbdc025bSLars-Peter Clausen if (events & AD5421_FAULT_TEMP_OVER_140) { 258dbdc025bSLars-Peter Clausen iio_push_event(indio_dev, 259dbdc025bSLars-Peter Clausen IIO_UNMOD_EVENT_CODE(IIO_TEMP, 260dbdc025bSLars-Peter Clausen 0, 261dbdc025bSLars-Peter Clausen IIO_EV_TYPE_MAG, 262dbdc025bSLars-Peter Clausen IIO_EV_DIR_RISING), 263dbdc025bSLars-Peter Clausen iio_get_time_ns()); 264dbdc025bSLars-Peter Clausen } 265dbdc025bSLars-Peter Clausen 266dbdc025bSLars-Peter Clausen old_fault = fault; 267dbdc025bSLars-Peter Clausen fault = ad5421_read(indio_dev, AD5421_REG_FAULT); 268dbdc025bSLars-Peter Clausen 269dbdc025bSLars-Peter Clausen /* still active? go to sleep for some time */ 270dbdc025bSLars-Peter Clausen if (fault & AD5421_FAULT_TRIGGER_IRQ) 271dbdc025bSLars-Peter Clausen msleep(1000); 272dbdc025bSLars-Peter Clausen 273dbdc025bSLars-Peter Clausen } while (fault & AD5421_FAULT_TRIGGER_IRQ); 274dbdc025bSLars-Peter Clausen 275dbdc025bSLars-Peter Clausen 276dbdc025bSLars-Peter Clausen return IRQ_HANDLED; 277dbdc025bSLars-Peter Clausen } 278dbdc025bSLars-Peter Clausen 279dbdc025bSLars-Peter Clausen static void ad5421_get_current_min_max(struct ad5421_state *st, 280dbdc025bSLars-Peter Clausen unsigned int *min, unsigned int *max) 281dbdc025bSLars-Peter Clausen { 282dbdc025bSLars-Peter Clausen /* The current range is configured using external pins, which are 283dbdc025bSLars-Peter Clausen * usually hard-wired and not run-time switchable. */ 284dbdc025bSLars-Peter Clausen switch (st->current_range) { 285dbdc025bSLars-Peter Clausen case AD5421_CURRENT_RANGE_4mA_20mA: 286dbdc025bSLars-Peter Clausen *min = 4000; 287dbdc025bSLars-Peter Clausen *max = 20000; 288dbdc025bSLars-Peter Clausen break; 289dbdc025bSLars-Peter Clausen case AD5421_CURRENT_RANGE_3mA8_21mA: 290dbdc025bSLars-Peter Clausen *min = 3800; 291dbdc025bSLars-Peter Clausen *max = 21000; 292dbdc025bSLars-Peter Clausen break; 293dbdc025bSLars-Peter Clausen case AD5421_CURRENT_RANGE_3mA2_24mA: 294dbdc025bSLars-Peter Clausen *min = 3200; 295dbdc025bSLars-Peter Clausen *max = 24000; 296dbdc025bSLars-Peter Clausen break; 297dbdc025bSLars-Peter Clausen default: 298dbdc025bSLars-Peter Clausen *min = 0; 299dbdc025bSLars-Peter Clausen *max = 1; 300dbdc025bSLars-Peter Clausen break; 301dbdc025bSLars-Peter Clausen } 302dbdc025bSLars-Peter Clausen } 303dbdc025bSLars-Peter Clausen 304dbdc025bSLars-Peter Clausen static inline unsigned int ad5421_get_offset(struct ad5421_state *st) 305dbdc025bSLars-Peter Clausen { 306dbdc025bSLars-Peter Clausen unsigned int min, max; 307dbdc025bSLars-Peter Clausen 308dbdc025bSLars-Peter Clausen ad5421_get_current_min_max(st, &min, &max); 309dbdc025bSLars-Peter Clausen return (min * (1 << 16)) / (max - min); 310dbdc025bSLars-Peter Clausen } 311dbdc025bSLars-Peter Clausen 312dbdc025bSLars-Peter Clausen static int ad5421_read_raw(struct iio_dev *indio_dev, 313dbdc025bSLars-Peter Clausen struct iio_chan_spec const *chan, int *val, int *val2, long m) 314dbdc025bSLars-Peter Clausen { 315dbdc025bSLars-Peter Clausen struct ad5421_state *st = iio_priv(indio_dev); 316bc7c49bcSLars-Peter Clausen unsigned int min, max; 317dbdc025bSLars-Peter Clausen int ret; 318dbdc025bSLars-Peter Clausen 319dbdc025bSLars-Peter Clausen if (chan->type != IIO_CURRENT) 320dbdc025bSLars-Peter Clausen return -EINVAL; 321dbdc025bSLars-Peter Clausen 322dbdc025bSLars-Peter Clausen switch (m) { 323dbdc025bSLars-Peter Clausen case IIO_CHAN_INFO_RAW: 324dbdc025bSLars-Peter Clausen ret = ad5421_read(indio_dev, AD5421_REG_DAC_DATA); 325dbdc025bSLars-Peter Clausen if (ret < 0) 326dbdc025bSLars-Peter Clausen return ret; 327dbdc025bSLars-Peter Clausen *val = ret; 328dbdc025bSLars-Peter Clausen return IIO_VAL_INT; 329dbdc025bSLars-Peter Clausen case IIO_CHAN_INFO_SCALE: 330bc7c49bcSLars-Peter Clausen ad5421_get_current_min_max(st, &min, &max); 331bc7c49bcSLars-Peter Clausen *val = max - min; 332bc7c49bcSLars-Peter Clausen *val2 = (1 << 16) * 1000; 333bc7c49bcSLars-Peter Clausen return IIO_VAL_FRACTIONAL; 334dbdc025bSLars-Peter Clausen case IIO_CHAN_INFO_OFFSET: 335dbdc025bSLars-Peter Clausen *val = ad5421_get_offset(st); 336dbdc025bSLars-Peter Clausen return IIO_VAL_INT; 337dbdc025bSLars-Peter Clausen case IIO_CHAN_INFO_CALIBBIAS: 338dbdc025bSLars-Peter Clausen ret = ad5421_read(indio_dev, AD5421_REG_OFFSET); 339dbdc025bSLars-Peter Clausen if (ret < 0) 340dbdc025bSLars-Peter Clausen return ret; 341dbdc025bSLars-Peter Clausen *val = ret - 32768; 342dbdc025bSLars-Peter Clausen return IIO_VAL_INT; 343dbdc025bSLars-Peter Clausen case IIO_CHAN_INFO_CALIBSCALE: 344dbdc025bSLars-Peter Clausen ret = ad5421_read(indio_dev, AD5421_REG_GAIN); 345dbdc025bSLars-Peter Clausen if (ret < 0) 346dbdc025bSLars-Peter Clausen return ret; 347dbdc025bSLars-Peter Clausen *val = ret; 348dbdc025bSLars-Peter Clausen return IIO_VAL_INT; 349dbdc025bSLars-Peter Clausen } 350dbdc025bSLars-Peter Clausen 351dbdc025bSLars-Peter Clausen return -EINVAL; 352dbdc025bSLars-Peter Clausen } 353dbdc025bSLars-Peter Clausen 354dbdc025bSLars-Peter Clausen static int ad5421_write_raw(struct iio_dev *indio_dev, 355dbdc025bSLars-Peter Clausen struct iio_chan_spec const *chan, int val, int val2, long mask) 356dbdc025bSLars-Peter Clausen { 357dbdc025bSLars-Peter Clausen const unsigned int max_val = 1 << 16; 358dbdc025bSLars-Peter Clausen 359dbdc025bSLars-Peter Clausen switch (mask) { 360dbdc025bSLars-Peter Clausen case IIO_CHAN_INFO_RAW: 361dbdc025bSLars-Peter Clausen if (val >= max_val || val < 0) 362dbdc025bSLars-Peter Clausen return -EINVAL; 363dbdc025bSLars-Peter Clausen 364dbdc025bSLars-Peter Clausen return ad5421_write(indio_dev, AD5421_REG_DAC_DATA, val); 365dbdc025bSLars-Peter Clausen case IIO_CHAN_INFO_CALIBBIAS: 366dbdc025bSLars-Peter Clausen val += 32768; 367dbdc025bSLars-Peter Clausen if (val >= max_val || val < 0) 368dbdc025bSLars-Peter Clausen return -EINVAL; 369dbdc025bSLars-Peter Clausen 370dbdc025bSLars-Peter Clausen return ad5421_write(indio_dev, AD5421_REG_OFFSET, val); 371dbdc025bSLars-Peter Clausen case IIO_CHAN_INFO_CALIBSCALE: 372dbdc025bSLars-Peter Clausen if (val >= max_val || val < 0) 373dbdc025bSLars-Peter Clausen return -EINVAL; 374dbdc025bSLars-Peter Clausen 375dbdc025bSLars-Peter Clausen return ad5421_write(indio_dev, AD5421_REG_GAIN, val); 376dbdc025bSLars-Peter Clausen default: 377dbdc025bSLars-Peter Clausen break; 378dbdc025bSLars-Peter Clausen } 379dbdc025bSLars-Peter Clausen 380dbdc025bSLars-Peter Clausen return -EINVAL; 381dbdc025bSLars-Peter Clausen } 382dbdc025bSLars-Peter Clausen 383dbdc025bSLars-Peter Clausen static int ad5421_write_event_config(struct iio_dev *indio_dev, 3841eefd62bSLars-Peter Clausen const struct iio_chan_spec *chan, enum iio_event_type type, 3851eefd62bSLars-Peter Clausen enum iio_event_direction dir, int state) 386dbdc025bSLars-Peter Clausen { 387dbdc025bSLars-Peter Clausen struct ad5421_state *st = iio_priv(indio_dev); 388dbdc025bSLars-Peter Clausen unsigned int mask; 389dbdc025bSLars-Peter Clausen 3901eefd62bSLars-Peter Clausen switch (chan->type) { 391dbdc025bSLars-Peter Clausen case IIO_CURRENT: 3921eefd62bSLars-Peter Clausen if (dir == IIO_EV_DIR_RISING) 393dbdc025bSLars-Peter Clausen mask = AD5421_FAULT_OVER_CURRENT; 394dbdc025bSLars-Peter Clausen else 395dbdc025bSLars-Peter Clausen mask = AD5421_FAULT_UNDER_CURRENT; 396dbdc025bSLars-Peter Clausen break; 397dbdc025bSLars-Peter Clausen case IIO_TEMP: 398dbdc025bSLars-Peter Clausen mask = AD5421_FAULT_TEMP_OVER_140; 399dbdc025bSLars-Peter Clausen break; 400dbdc025bSLars-Peter Clausen default: 401dbdc025bSLars-Peter Clausen return -EINVAL; 402dbdc025bSLars-Peter Clausen } 403dbdc025bSLars-Peter Clausen 404dbdc025bSLars-Peter Clausen mutex_lock(&indio_dev->mlock); 405dbdc025bSLars-Peter Clausen if (state) 406dbdc025bSLars-Peter Clausen st->fault_mask |= mask; 407dbdc025bSLars-Peter Clausen else 408dbdc025bSLars-Peter Clausen st->fault_mask &= ~mask; 409dbdc025bSLars-Peter Clausen mutex_unlock(&indio_dev->mlock); 410dbdc025bSLars-Peter Clausen 411dbdc025bSLars-Peter Clausen return 0; 412dbdc025bSLars-Peter Clausen } 413dbdc025bSLars-Peter Clausen 414dbdc025bSLars-Peter Clausen static int ad5421_read_event_config(struct iio_dev *indio_dev, 4151eefd62bSLars-Peter Clausen const struct iio_chan_spec *chan, enum iio_event_type type, 4161eefd62bSLars-Peter Clausen enum iio_event_direction dir) 417dbdc025bSLars-Peter Clausen { 418dbdc025bSLars-Peter Clausen struct ad5421_state *st = iio_priv(indio_dev); 419dbdc025bSLars-Peter Clausen unsigned int mask; 420dbdc025bSLars-Peter Clausen 4211eefd62bSLars-Peter Clausen switch (chan->type) { 422dbdc025bSLars-Peter Clausen case IIO_CURRENT: 4231eefd62bSLars-Peter Clausen if (dir == IIO_EV_DIR_RISING) 424dbdc025bSLars-Peter Clausen mask = AD5421_FAULT_OVER_CURRENT; 425dbdc025bSLars-Peter Clausen else 426dbdc025bSLars-Peter Clausen mask = AD5421_FAULT_UNDER_CURRENT; 427dbdc025bSLars-Peter Clausen break; 428dbdc025bSLars-Peter Clausen case IIO_TEMP: 429dbdc025bSLars-Peter Clausen mask = AD5421_FAULT_TEMP_OVER_140; 430dbdc025bSLars-Peter Clausen break; 431dbdc025bSLars-Peter Clausen default: 432dbdc025bSLars-Peter Clausen return -EINVAL; 433dbdc025bSLars-Peter Clausen } 434dbdc025bSLars-Peter Clausen 435dbdc025bSLars-Peter Clausen return (bool)(st->fault_mask & mask); 436dbdc025bSLars-Peter Clausen } 437dbdc025bSLars-Peter Clausen 4381eefd62bSLars-Peter Clausen static int ad5421_read_event_value(struct iio_dev *indio_dev, 4391eefd62bSLars-Peter Clausen const struct iio_chan_spec *chan, enum iio_event_type type, 4401eefd62bSLars-Peter Clausen enum iio_event_direction dir, enum iio_event_info info, int *val, 4411eefd62bSLars-Peter Clausen int *val2) 442dbdc025bSLars-Peter Clausen { 443dbdc025bSLars-Peter Clausen int ret; 444dbdc025bSLars-Peter Clausen 4451eefd62bSLars-Peter Clausen switch (chan->type) { 446dbdc025bSLars-Peter Clausen case IIO_CURRENT: 447dbdc025bSLars-Peter Clausen ret = ad5421_read(indio_dev, AD5421_REG_DAC_DATA); 448dbdc025bSLars-Peter Clausen if (ret < 0) 449dbdc025bSLars-Peter Clausen return ret; 450dbdc025bSLars-Peter Clausen *val = ret; 451dbdc025bSLars-Peter Clausen break; 452dbdc025bSLars-Peter Clausen case IIO_TEMP: 453dbdc025bSLars-Peter Clausen *val = 140000; 454dbdc025bSLars-Peter Clausen break; 455dbdc025bSLars-Peter Clausen default: 456dbdc025bSLars-Peter Clausen return -EINVAL; 457dbdc025bSLars-Peter Clausen } 458dbdc025bSLars-Peter Clausen 4591eefd62bSLars-Peter Clausen return IIO_VAL_INT; 460dbdc025bSLars-Peter Clausen } 461dbdc025bSLars-Peter Clausen 462dbdc025bSLars-Peter Clausen static const struct iio_info ad5421_info = { 463dbdc025bSLars-Peter Clausen .read_raw = ad5421_read_raw, 464dbdc025bSLars-Peter Clausen .write_raw = ad5421_write_raw, 465cb955852SLars-Peter Clausen .read_event_config = ad5421_read_event_config, 466cb955852SLars-Peter Clausen .write_event_config = ad5421_write_event_config, 467cb955852SLars-Peter Clausen .read_event_value = ad5421_read_event_value, 468dbdc025bSLars-Peter Clausen .driver_module = THIS_MODULE, 469dbdc025bSLars-Peter Clausen }; 470dbdc025bSLars-Peter Clausen 471fc52692cSGreg Kroah-Hartman static int ad5421_probe(struct spi_device *spi) 472dbdc025bSLars-Peter Clausen { 473dbdc025bSLars-Peter Clausen struct ad5421_platform_data *pdata = dev_get_platdata(&spi->dev); 474dbdc025bSLars-Peter Clausen struct iio_dev *indio_dev; 475dbdc025bSLars-Peter Clausen struct ad5421_state *st; 476dbdc025bSLars-Peter Clausen int ret; 477dbdc025bSLars-Peter Clausen 47862a308a6SSachin Kamat indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); 479dbdc025bSLars-Peter Clausen if (indio_dev == NULL) { 480dbdc025bSLars-Peter Clausen dev_err(&spi->dev, "Failed to allocate iio device\n"); 481dbdc025bSLars-Peter Clausen return -ENOMEM; 482dbdc025bSLars-Peter Clausen } 483dbdc025bSLars-Peter Clausen 484dbdc025bSLars-Peter Clausen st = iio_priv(indio_dev); 485dbdc025bSLars-Peter Clausen spi_set_drvdata(spi, indio_dev); 486dbdc025bSLars-Peter Clausen 487dbdc025bSLars-Peter Clausen st->spi = spi; 488dbdc025bSLars-Peter Clausen 489dbdc025bSLars-Peter Clausen indio_dev->dev.parent = &spi->dev; 490dbdc025bSLars-Peter Clausen indio_dev->name = "ad5421"; 491dbdc025bSLars-Peter Clausen indio_dev->info = &ad5421_info; 492dbdc025bSLars-Peter Clausen indio_dev->modes = INDIO_DIRECT_MODE; 493dbdc025bSLars-Peter Clausen indio_dev->channels = ad5421_channels; 494dbdc025bSLars-Peter Clausen indio_dev->num_channels = ARRAY_SIZE(ad5421_channels); 495dbdc025bSLars-Peter Clausen 496dbdc025bSLars-Peter Clausen st->ctrl = AD5421_CTRL_WATCHDOG_DISABLE | 497dbdc025bSLars-Peter Clausen AD5421_CTRL_AUTO_FAULT_READBACK; 498dbdc025bSLars-Peter Clausen 499dbdc025bSLars-Peter Clausen if (pdata) { 500dbdc025bSLars-Peter Clausen st->current_range = pdata->current_range; 501dbdc025bSLars-Peter Clausen if (pdata->external_vref) 502dbdc025bSLars-Peter Clausen st->ctrl |= AD5421_CTRL_PWR_DOWN_INT_VREF; 503dbdc025bSLars-Peter Clausen } else { 504dbdc025bSLars-Peter Clausen st->current_range = AD5421_CURRENT_RANGE_4mA_20mA; 505dbdc025bSLars-Peter Clausen } 506dbdc025bSLars-Peter Clausen 507dbdc025bSLars-Peter Clausen /* write initial ctrl register value */ 508dbdc025bSLars-Peter Clausen ad5421_update_ctrl(indio_dev, 0, 0); 509dbdc025bSLars-Peter Clausen 510dbdc025bSLars-Peter Clausen if (spi->irq) { 51162a308a6SSachin Kamat ret = devm_request_threaded_irq(&spi->dev, spi->irq, 512dbdc025bSLars-Peter Clausen NULL, 513dbdc025bSLars-Peter Clausen ad5421_fault_handler, 514dbdc025bSLars-Peter Clausen IRQF_TRIGGER_HIGH | IRQF_ONESHOT, 515dbdc025bSLars-Peter Clausen "ad5421 fault", 516dbdc025bSLars-Peter Clausen indio_dev); 517dbdc025bSLars-Peter Clausen if (ret) 51862a308a6SSachin Kamat return ret; 519dbdc025bSLars-Peter Clausen } 520dbdc025bSLars-Peter Clausen 521365736e7SSachin Kamat return devm_iio_device_register(&spi->dev, indio_dev); 522dbdc025bSLars-Peter Clausen } 523dbdc025bSLars-Peter Clausen 524dbdc025bSLars-Peter Clausen static struct spi_driver ad5421_driver = { 525dbdc025bSLars-Peter Clausen .driver = { 526dbdc025bSLars-Peter Clausen .name = "ad5421", 527dbdc025bSLars-Peter Clausen .owner = THIS_MODULE, 528dbdc025bSLars-Peter Clausen }, 529dbdc025bSLars-Peter Clausen .probe = ad5421_probe, 530dbdc025bSLars-Peter Clausen }; 531dbdc025bSLars-Peter Clausen module_spi_driver(ad5421_driver); 532dbdc025bSLars-Peter Clausen 533dbdc025bSLars-Peter Clausen MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); 534dbdc025bSLars-Peter Clausen MODULE_DESCRIPTION("Analog Devices AD5421 DAC"); 535dbdc025bSLars-Peter Clausen MODULE_LICENSE("GPL v2"); 536dbdc025bSLars-Peter Clausen MODULE_ALIAS("spi:ad5421"); 537