1*3e87e783SSean Nyekjaer /* 2*3e87e783SSean Nyekjaer * Copyright (C) 2015 Prevas A/S 3*3e87e783SSean Nyekjaer * 4*3e87e783SSean Nyekjaer * This program is free software; you can redistribute it and/or modify 5*3e87e783SSean Nyekjaer * it under the terms of the GNU General Public License version 2 as 6*3e87e783SSean Nyekjaer * published by the Free Software Foundation. 7*3e87e783SSean Nyekjaer */ 8*3e87e783SSean Nyekjaer 9*3e87e783SSean Nyekjaer #include <linux/device.h> 10*3e87e783SSean Nyekjaer #include <linux/kernel.h> 11*3e87e783SSean Nyekjaer #include <linux/slab.h> 12*3e87e783SSean Nyekjaer #include <linux/sysfs.h> 13*3e87e783SSean Nyekjaer #include <linux/spi/spi.h> 14*3e87e783SSean Nyekjaer #include <linux/regulator/consumer.h> 15*3e87e783SSean Nyekjaer #include <linux/err.h> 16*3e87e783SSean Nyekjaer #include <linux/module.h> 17*3e87e783SSean Nyekjaer #include <linux/of.h> 18*3e87e783SSean Nyekjaer 19*3e87e783SSean Nyekjaer #include <linux/iio/iio.h> 20*3e87e783SSean Nyekjaer #include <linux/iio/sysfs.h> 21*3e87e783SSean Nyekjaer 22*3e87e783SSean Nyekjaer #define ADS8688_CMD_REG(x) (x << 8) 23*3e87e783SSean Nyekjaer #define ADS8688_CMD_REG_NOOP 0x00 24*3e87e783SSean Nyekjaer #define ADS8688_CMD_REG_RST 0x85 25*3e87e783SSean Nyekjaer #define ADS8688_CMD_REG_MAN_CH(chan) (0xC0 | (4 * chan)) 26*3e87e783SSean Nyekjaer #define ADS8688_CMD_DONT_CARE_BITS 16 27*3e87e783SSean Nyekjaer 28*3e87e783SSean Nyekjaer #define ADS8688_PROG_REG(x) (x << 9) 29*3e87e783SSean Nyekjaer #define ADS8688_PROG_REG_RANGE_CH(chan) (0x05 + chan) 30*3e87e783SSean Nyekjaer #define ADS8688_PROG_WR_BIT BIT(8) 31*3e87e783SSean Nyekjaer #define ADS8688_PROG_DONT_CARE_BITS 8 32*3e87e783SSean Nyekjaer 33*3e87e783SSean Nyekjaer #define ADS8688_REG_PLUSMINUS25VREF 0 34*3e87e783SSean Nyekjaer #define ADS8688_REG_PLUSMINUS125VREF 1 35*3e87e783SSean Nyekjaer #define ADS8688_REG_PLUSMINUS0625VREF 2 36*3e87e783SSean Nyekjaer #define ADS8688_REG_PLUS25VREF 5 37*3e87e783SSean Nyekjaer #define ADS8688_REG_PLUS125VREF 6 38*3e87e783SSean Nyekjaer 39*3e87e783SSean Nyekjaer #define ADS8688_VREF_MV 4096 40*3e87e783SSean Nyekjaer #define ADS8688_REALBITS 16 41*3e87e783SSean Nyekjaer 42*3e87e783SSean Nyekjaer /* 43*3e87e783SSean Nyekjaer * enum ads8688_range - ADS8688 reference voltage range 44*3e87e783SSean Nyekjaer * @ADS8688_PLUSMINUS25VREF: Device is configured for input range ±2.5 * VREF 45*3e87e783SSean Nyekjaer * @ADS8688_PLUSMINUS125VREF: Device is configured for input range ±1.25 * VREF 46*3e87e783SSean Nyekjaer * @ADS8688_PLUSMINUS0625VREF: Device is configured for input range ±0.625 * VREF 47*3e87e783SSean Nyekjaer * @ADS8688_PLUS25VREF: Device is configured for input range 0 - 2.5 * VREF 48*3e87e783SSean Nyekjaer * @ADS8688_PLUS125VREF: Device is configured for input range 0 - 1.25 * VREF 49*3e87e783SSean Nyekjaer */ 50*3e87e783SSean Nyekjaer enum ads8688_range { 51*3e87e783SSean Nyekjaer ADS8688_PLUSMINUS25VREF, 52*3e87e783SSean Nyekjaer ADS8688_PLUSMINUS125VREF, 53*3e87e783SSean Nyekjaer ADS8688_PLUSMINUS0625VREF, 54*3e87e783SSean Nyekjaer ADS8688_PLUS25VREF, 55*3e87e783SSean Nyekjaer ADS8688_PLUS125VREF, 56*3e87e783SSean Nyekjaer }; 57*3e87e783SSean Nyekjaer 58*3e87e783SSean Nyekjaer struct ads8688_chip_info { 59*3e87e783SSean Nyekjaer const struct iio_chan_spec *channels; 60*3e87e783SSean Nyekjaer unsigned int num_channels; 61*3e87e783SSean Nyekjaer }; 62*3e87e783SSean Nyekjaer 63*3e87e783SSean Nyekjaer struct ads8688_state { 64*3e87e783SSean Nyekjaer struct mutex lock; 65*3e87e783SSean Nyekjaer const struct ads8688_chip_info *chip_info; 66*3e87e783SSean Nyekjaer struct spi_device *spi; 67*3e87e783SSean Nyekjaer struct regulator *reg; 68*3e87e783SSean Nyekjaer unsigned int vref_mv; 69*3e87e783SSean Nyekjaer enum ads8688_range range[8]; 70*3e87e783SSean Nyekjaer union { 71*3e87e783SSean Nyekjaer __be32 d32; 72*3e87e783SSean Nyekjaer u8 d8[4]; 73*3e87e783SSean Nyekjaer } data[2] ____cacheline_aligned; 74*3e87e783SSean Nyekjaer }; 75*3e87e783SSean Nyekjaer 76*3e87e783SSean Nyekjaer enum ads8688_id { 77*3e87e783SSean Nyekjaer ID_ADS8684, 78*3e87e783SSean Nyekjaer ID_ADS8688, 79*3e87e783SSean Nyekjaer }; 80*3e87e783SSean Nyekjaer 81*3e87e783SSean Nyekjaer struct ads8688_ranges { 82*3e87e783SSean Nyekjaer enum ads8688_range range; 83*3e87e783SSean Nyekjaer unsigned int scale; 84*3e87e783SSean Nyekjaer int offset; 85*3e87e783SSean Nyekjaer u8 reg; 86*3e87e783SSean Nyekjaer }; 87*3e87e783SSean Nyekjaer 88*3e87e783SSean Nyekjaer static const struct ads8688_ranges ads8688_range_def[5] = { 89*3e87e783SSean Nyekjaer { 90*3e87e783SSean Nyekjaer .range = ADS8688_PLUSMINUS25VREF, 91*3e87e783SSean Nyekjaer .scale = 76295, 92*3e87e783SSean Nyekjaer .offset = -(1 << (ADS8688_REALBITS - 1)), 93*3e87e783SSean Nyekjaer .reg = ADS8688_REG_PLUSMINUS25VREF, 94*3e87e783SSean Nyekjaer }, { 95*3e87e783SSean Nyekjaer .range = ADS8688_PLUSMINUS125VREF, 96*3e87e783SSean Nyekjaer .scale = 38148, 97*3e87e783SSean Nyekjaer .offset = -(1 << (ADS8688_REALBITS - 1)), 98*3e87e783SSean Nyekjaer .reg = ADS8688_REG_PLUSMINUS125VREF, 99*3e87e783SSean Nyekjaer }, { 100*3e87e783SSean Nyekjaer .range = ADS8688_PLUSMINUS0625VREF, 101*3e87e783SSean Nyekjaer .scale = 19074, 102*3e87e783SSean Nyekjaer .offset = -(1 << (ADS8688_REALBITS - 1)), 103*3e87e783SSean Nyekjaer .reg = ADS8688_REG_PLUSMINUS0625VREF, 104*3e87e783SSean Nyekjaer }, { 105*3e87e783SSean Nyekjaer .range = ADS8688_PLUS25VREF, 106*3e87e783SSean Nyekjaer .scale = 38148, 107*3e87e783SSean Nyekjaer .offset = 0, 108*3e87e783SSean Nyekjaer .reg = ADS8688_REG_PLUS25VREF, 109*3e87e783SSean Nyekjaer }, { 110*3e87e783SSean Nyekjaer .range = ADS8688_PLUS125VREF, 111*3e87e783SSean Nyekjaer .scale = 19074, 112*3e87e783SSean Nyekjaer .offset = 0, 113*3e87e783SSean Nyekjaer .reg = ADS8688_REG_PLUS125VREF, 114*3e87e783SSean Nyekjaer } 115*3e87e783SSean Nyekjaer }; 116*3e87e783SSean Nyekjaer 117*3e87e783SSean Nyekjaer static ssize_t ads8688_show_scales(struct device *dev, 118*3e87e783SSean Nyekjaer struct device_attribute *attr, char *buf) 119*3e87e783SSean Nyekjaer { 120*3e87e783SSean Nyekjaer struct ads8688_state *st = iio_priv(dev_to_iio_dev(dev)); 121*3e87e783SSean Nyekjaer 122*3e87e783SSean Nyekjaer return sprintf(buf, "0.%09u 0.%09u 0.%09u\n", 123*3e87e783SSean Nyekjaer ads8688_range_def[0].scale * st->vref_mv, 124*3e87e783SSean Nyekjaer ads8688_range_def[1].scale * st->vref_mv, 125*3e87e783SSean Nyekjaer ads8688_range_def[2].scale * st->vref_mv); 126*3e87e783SSean Nyekjaer } 127*3e87e783SSean Nyekjaer 128*3e87e783SSean Nyekjaer static ssize_t ads8688_show_offsets(struct device *dev, 129*3e87e783SSean Nyekjaer struct device_attribute *attr, char *buf) 130*3e87e783SSean Nyekjaer { 131*3e87e783SSean Nyekjaer return sprintf(buf, "%d %d\n", ads8688_range_def[0].offset, 132*3e87e783SSean Nyekjaer ads8688_range_def[3].offset); 133*3e87e783SSean Nyekjaer } 134*3e87e783SSean Nyekjaer 135*3e87e783SSean Nyekjaer static IIO_DEVICE_ATTR(in_voltage_scale_available, S_IRUGO, 136*3e87e783SSean Nyekjaer ads8688_show_scales, NULL, 0); 137*3e87e783SSean Nyekjaer static IIO_DEVICE_ATTR(in_voltage_offset_available, S_IRUGO, 138*3e87e783SSean Nyekjaer ads8688_show_offsets, NULL, 0); 139*3e87e783SSean Nyekjaer 140*3e87e783SSean Nyekjaer static struct attribute *ads8688_attributes[] = { 141*3e87e783SSean Nyekjaer &iio_dev_attr_in_voltage_scale_available.dev_attr.attr, 142*3e87e783SSean Nyekjaer &iio_dev_attr_in_voltage_offset_available.dev_attr.attr, 143*3e87e783SSean Nyekjaer NULL, 144*3e87e783SSean Nyekjaer }; 145*3e87e783SSean Nyekjaer 146*3e87e783SSean Nyekjaer static const struct attribute_group ads8688_attribute_group = { 147*3e87e783SSean Nyekjaer .attrs = ads8688_attributes, 148*3e87e783SSean Nyekjaer }; 149*3e87e783SSean Nyekjaer 150*3e87e783SSean Nyekjaer #define ADS8688_CHAN(index) \ 151*3e87e783SSean Nyekjaer { \ 152*3e87e783SSean Nyekjaer .type = IIO_VOLTAGE, \ 153*3e87e783SSean Nyekjaer .indexed = 1, \ 154*3e87e783SSean Nyekjaer .channel = index, \ 155*3e87e783SSean Nyekjaer .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) \ 156*3e87e783SSean Nyekjaer | BIT(IIO_CHAN_INFO_SCALE) \ 157*3e87e783SSean Nyekjaer | BIT(IIO_CHAN_INFO_OFFSET), \ 158*3e87e783SSean Nyekjaer } 159*3e87e783SSean Nyekjaer 160*3e87e783SSean Nyekjaer static const struct iio_chan_spec ads8684_channels[] = { 161*3e87e783SSean Nyekjaer ADS8688_CHAN(0), 162*3e87e783SSean Nyekjaer ADS8688_CHAN(1), 163*3e87e783SSean Nyekjaer ADS8688_CHAN(2), 164*3e87e783SSean Nyekjaer ADS8688_CHAN(3), 165*3e87e783SSean Nyekjaer }; 166*3e87e783SSean Nyekjaer 167*3e87e783SSean Nyekjaer static const struct iio_chan_spec ads8688_channels[] = { 168*3e87e783SSean Nyekjaer ADS8688_CHAN(0), 169*3e87e783SSean Nyekjaer ADS8688_CHAN(1), 170*3e87e783SSean Nyekjaer ADS8688_CHAN(2), 171*3e87e783SSean Nyekjaer ADS8688_CHAN(3), 172*3e87e783SSean Nyekjaer ADS8688_CHAN(4), 173*3e87e783SSean Nyekjaer ADS8688_CHAN(5), 174*3e87e783SSean Nyekjaer ADS8688_CHAN(6), 175*3e87e783SSean Nyekjaer ADS8688_CHAN(7), 176*3e87e783SSean Nyekjaer }; 177*3e87e783SSean Nyekjaer 178*3e87e783SSean Nyekjaer static int ads8688_prog_write(struct iio_dev *indio_dev, unsigned int addr, 179*3e87e783SSean Nyekjaer unsigned int val) 180*3e87e783SSean Nyekjaer { 181*3e87e783SSean Nyekjaer struct ads8688_state *st = iio_priv(indio_dev); 182*3e87e783SSean Nyekjaer u32 tmp; 183*3e87e783SSean Nyekjaer 184*3e87e783SSean Nyekjaer tmp = ADS8688_PROG_REG(addr) | ADS8688_PROG_WR_BIT | val; 185*3e87e783SSean Nyekjaer tmp <<= ADS8688_PROG_DONT_CARE_BITS; 186*3e87e783SSean Nyekjaer st->data[0].d32 = cpu_to_be32(tmp); 187*3e87e783SSean Nyekjaer 188*3e87e783SSean Nyekjaer return spi_write(st->spi, &st->data[0].d8[1], 3); 189*3e87e783SSean Nyekjaer } 190*3e87e783SSean Nyekjaer 191*3e87e783SSean Nyekjaer static int ads8688_reset(struct iio_dev *indio_dev) 192*3e87e783SSean Nyekjaer { 193*3e87e783SSean Nyekjaer struct ads8688_state *st = iio_priv(indio_dev); 194*3e87e783SSean Nyekjaer u32 tmp; 195*3e87e783SSean Nyekjaer 196*3e87e783SSean Nyekjaer tmp = ADS8688_CMD_REG(ADS8688_CMD_REG_RST); 197*3e87e783SSean Nyekjaer tmp <<= ADS8688_CMD_DONT_CARE_BITS; 198*3e87e783SSean Nyekjaer st->data[0].d32 = cpu_to_be32(tmp); 199*3e87e783SSean Nyekjaer 200*3e87e783SSean Nyekjaer return spi_write(st->spi, &st->data[0].d8[0], 4); 201*3e87e783SSean Nyekjaer } 202*3e87e783SSean Nyekjaer 203*3e87e783SSean Nyekjaer static int ads8688_read(struct iio_dev *indio_dev, unsigned int chan) 204*3e87e783SSean Nyekjaer { 205*3e87e783SSean Nyekjaer struct ads8688_state *st = iio_priv(indio_dev); 206*3e87e783SSean Nyekjaer int ret; 207*3e87e783SSean Nyekjaer u32 tmp; 208*3e87e783SSean Nyekjaer struct spi_transfer t[] = { 209*3e87e783SSean Nyekjaer { 210*3e87e783SSean Nyekjaer .tx_buf = &st->data[0].d8[0], 211*3e87e783SSean Nyekjaer .len = 4, 212*3e87e783SSean Nyekjaer .cs_change = 1, 213*3e87e783SSean Nyekjaer }, { 214*3e87e783SSean Nyekjaer .tx_buf = &st->data[1].d8[0], 215*3e87e783SSean Nyekjaer .rx_buf = &st->data[1].d8[0], 216*3e87e783SSean Nyekjaer .len = 4, 217*3e87e783SSean Nyekjaer }, 218*3e87e783SSean Nyekjaer }; 219*3e87e783SSean Nyekjaer 220*3e87e783SSean Nyekjaer tmp = ADS8688_CMD_REG(ADS8688_CMD_REG_MAN_CH(chan)); 221*3e87e783SSean Nyekjaer tmp <<= ADS8688_CMD_DONT_CARE_BITS; 222*3e87e783SSean Nyekjaer st->data[0].d32 = cpu_to_be32(tmp); 223*3e87e783SSean Nyekjaer 224*3e87e783SSean Nyekjaer tmp = ADS8688_CMD_REG(ADS8688_CMD_REG_NOOP); 225*3e87e783SSean Nyekjaer tmp <<= ADS8688_CMD_DONT_CARE_BITS; 226*3e87e783SSean Nyekjaer st->data[1].d32 = cpu_to_be32(tmp); 227*3e87e783SSean Nyekjaer 228*3e87e783SSean Nyekjaer ret = spi_sync_transfer(st->spi, t, ARRAY_SIZE(t)); 229*3e87e783SSean Nyekjaer if (ret < 0) 230*3e87e783SSean Nyekjaer return ret; 231*3e87e783SSean Nyekjaer 232*3e87e783SSean Nyekjaer return be32_to_cpu(st->data[1].d32) & 0xffff; 233*3e87e783SSean Nyekjaer } 234*3e87e783SSean Nyekjaer 235*3e87e783SSean Nyekjaer static int ads8688_read_raw(struct iio_dev *indio_dev, 236*3e87e783SSean Nyekjaer struct iio_chan_spec const *chan, 237*3e87e783SSean Nyekjaer int *val, int *val2, long m) 238*3e87e783SSean Nyekjaer { 239*3e87e783SSean Nyekjaer int ret, offset; 240*3e87e783SSean Nyekjaer unsigned long scale_mv; 241*3e87e783SSean Nyekjaer 242*3e87e783SSean Nyekjaer struct ads8688_state *st = iio_priv(indio_dev); 243*3e87e783SSean Nyekjaer 244*3e87e783SSean Nyekjaer mutex_lock(&st->lock); 245*3e87e783SSean Nyekjaer switch (m) { 246*3e87e783SSean Nyekjaer case IIO_CHAN_INFO_RAW: 247*3e87e783SSean Nyekjaer ret = ads8688_read(indio_dev, chan->channel); 248*3e87e783SSean Nyekjaer mutex_unlock(&st->lock); 249*3e87e783SSean Nyekjaer if (ret < 0) 250*3e87e783SSean Nyekjaer return ret; 251*3e87e783SSean Nyekjaer *val = ret; 252*3e87e783SSean Nyekjaer return IIO_VAL_INT; 253*3e87e783SSean Nyekjaer case IIO_CHAN_INFO_SCALE: 254*3e87e783SSean Nyekjaer scale_mv = st->vref_mv; 255*3e87e783SSean Nyekjaer scale_mv *= ads8688_range_def[st->range[chan->channel]].scale; 256*3e87e783SSean Nyekjaer *val = 0; 257*3e87e783SSean Nyekjaer *val2 = scale_mv; 258*3e87e783SSean Nyekjaer mutex_unlock(&st->lock); 259*3e87e783SSean Nyekjaer return IIO_VAL_INT_PLUS_NANO; 260*3e87e783SSean Nyekjaer case IIO_CHAN_INFO_OFFSET: 261*3e87e783SSean Nyekjaer offset = ads8688_range_def[st->range[chan->channel]].offset; 262*3e87e783SSean Nyekjaer *val = offset; 263*3e87e783SSean Nyekjaer mutex_unlock(&st->lock); 264*3e87e783SSean Nyekjaer return IIO_VAL_INT; 265*3e87e783SSean Nyekjaer } 266*3e87e783SSean Nyekjaer mutex_unlock(&st->lock); 267*3e87e783SSean Nyekjaer 268*3e87e783SSean Nyekjaer return -EINVAL; 269*3e87e783SSean Nyekjaer } 270*3e87e783SSean Nyekjaer 271*3e87e783SSean Nyekjaer static int ads8688_write_reg_range(struct iio_dev *indio_dev, 272*3e87e783SSean Nyekjaer struct iio_chan_spec const *chan, 273*3e87e783SSean Nyekjaer enum ads8688_range range) 274*3e87e783SSean Nyekjaer { 275*3e87e783SSean Nyekjaer unsigned int tmp; 276*3e87e783SSean Nyekjaer int ret; 277*3e87e783SSean Nyekjaer 278*3e87e783SSean Nyekjaer tmp = ADS8688_PROG_REG_RANGE_CH(chan->channel); 279*3e87e783SSean Nyekjaer ret = ads8688_prog_write(indio_dev, tmp, range); 280*3e87e783SSean Nyekjaer 281*3e87e783SSean Nyekjaer return ret; 282*3e87e783SSean Nyekjaer } 283*3e87e783SSean Nyekjaer 284*3e87e783SSean Nyekjaer static int ads8688_write_raw(struct iio_dev *indio_dev, 285*3e87e783SSean Nyekjaer struct iio_chan_spec const *chan, 286*3e87e783SSean Nyekjaer int val, int val2, long mask) 287*3e87e783SSean Nyekjaer { 288*3e87e783SSean Nyekjaer struct ads8688_state *st = iio_priv(indio_dev); 289*3e87e783SSean Nyekjaer unsigned int scale = 0; 290*3e87e783SSean Nyekjaer int ret = -EINVAL, i, offset = 0; 291*3e87e783SSean Nyekjaer 292*3e87e783SSean Nyekjaer mutex_lock(&st->lock); 293*3e87e783SSean Nyekjaer switch (mask) { 294*3e87e783SSean Nyekjaer case IIO_CHAN_INFO_SCALE: 295*3e87e783SSean Nyekjaer /* If the offset is 0 the ±2.5 * VREF mode is not available */ 296*3e87e783SSean Nyekjaer offset = ads8688_range_def[st->range[chan->channel]].offset; 297*3e87e783SSean Nyekjaer if (offset == 0 && val2 == ads8688_range_def[0].scale * st->vref_mv) { 298*3e87e783SSean Nyekjaer mutex_unlock(&st->lock); 299*3e87e783SSean Nyekjaer return -EINVAL; 300*3e87e783SSean Nyekjaer } 301*3e87e783SSean Nyekjaer 302*3e87e783SSean Nyekjaer /* Lookup new mode */ 303*3e87e783SSean Nyekjaer for (i = 0; i < ARRAY_SIZE(ads8688_range_def); i++) 304*3e87e783SSean Nyekjaer if (val2 == ads8688_range_def[i].scale * st->vref_mv && 305*3e87e783SSean Nyekjaer offset == ads8688_range_def[i].offset) { 306*3e87e783SSean Nyekjaer ret = ads8688_write_reg_range(indio_dev, chan, 307*3e87e783SSean Nyekjaer ads8688_range_def[i].reg); 308*3e87e783SSean Nyekjaer break; 309*3e87e783SSean Nyekjaer } 310*3e87e783SSean Nyekjaer break; 311*3e87e783SSean Nyekjaer case IIO_CHAN_INFO_OFFSET: 312*3e87e783SSean Nyekjaer /* 313*3e87e783SSean Nyekjaer * There are only two available offsets: 314*3e87e783SSean Nyekjaer * 0 and -(1 << (ADS8688_REALBITS - 1)) 315*3e87e783SSean Nyekjaer */ 316*3e87e783SSean Nyekjaer if (!(ads8688_range_def[0].offset == val || 317*3e87e783SSean Nyekjaer ads8688_range_def[3].offset == val)) { 318*3e87e783SSean Nyekjaer mutex_unlock(&st->lock); 319*3e87e783SSean Nyekjaer return -EINVAL; 320*3e87e783SSean Nyekjaer } 321*3e87e783SSean Nyekjaer 322*3e87e783SSean Nyekjaer /* 323*3e87e783SSean Nyekjaer * If the device are in ±2.5 * VREF mode, it's not allowed to 324*3e87e783SSean Nyekjaer * switch to a mode where the offset is 0 325*3e87e783SSean Nyekjaer */ 326*3e87e783SSean Nyekjaer if (val == 0 && 327*3e87e783SSean Nyekjaer st->range[chan->channel] == ADS8688_PLUSMINUS25VREF) { 328*3e87e783SSean Nyekjaer mutex_unlock(&st->lock); 329*3e87e783SSean Nyekjaer return -EINVAL; 330*3e87e783SSean Nyekjaer } 331*3e87e783SSean Nyekjaer 332*3e87e783SSean Nyekjaer scale = ads8688_range_def[st->range[chan->channel]].scale; 333*3e87e783SSean Nyekjaer 334*3e87e783SSean Nyekjaer /* Lookup new mode */ 335*3e87e783SSean Nyekjaer for (i = 0; i < ARRAY_SIZE(ads8688_range_def); i++) 336*3e87e783SSean Nyekjaer if (val == ads8688_range_def[i].offset && 337*3e87e783SSean Nyekjaer scale == ads8688_range_def[i].scale) { 338*3e87e783SSean Nyekjaer ret = ads8688_write_reg_range(indio_dev, chan, 339*3e87e783SSean Nyekjaer ads8688_range_def[i].reg); 340*3e87e783SSean Nyekjaer break; 341*3e87e783SSean Nyekjaer } 342*3e87e783SSean Nyekjaer break; 343*3e87e783SSean Nyekjaer } 344*3e87e783SSean Nyekjaer 345*3e87e783SSean Nyekjaer if (!ret) 346*3e87e783SSean Nyekjaer st->range[chan->channel] = ads8688_range_def[i].range; 347*3e87e783SSean Nyekjaer 348*3e87e783SSean Nyekjaer mutex_unlock(&st->lock); 349*3e87e783SSean Nyekjaer 350*3e87e783SSean Nyekjaer return ret; 351*3e87e783SSean Nyekjaer } 352*3e87e783SSean Nyekjaer 353*3e87e783SSean Nyekjaer static int ads8688_write_raw_get_fmt(struct iio_dev *indio_dev, 354*3e87e783SSean Nyekjaer struct iio_chan_spec const *chan, 355*3e87e783SSean Nyekjaer long mask) 356*3e87e783SSean Nyekjaer { 357*3e87e783SSean Nyekjaer switch (mask) { 358*3e87e783SSean Nyekjaer case IIO_CHAN_INFO_SCALE: 359*3e87e783SSean Nyekjaer return IIO_VAL_INT_PLUS_NANO; 360*3e87e783SSean Nyekjaer case IIO_CHAN_INFO_OFFSET: 361*3e87e783SSean Nyekjaer return IIO_VAL_INT; 362*3e87e783SSean Nyekjaer } 363*3e87e783SSean Nyekjaer 364*3e87e783SSean Nyekjaer return -EINVAL; 365*3e87e783SSean Nyekjaer } 366*3e87e783SSean Nyekjaer 367*3e87e783SSean Nyekjaer static const struct iio_info ads8688_info = { 368*3e87e783SSean Nyekjaer .read_raw = &ads8688_read_raw, 369*3e87e783SSean Nyekjaer .write_raw = &ads8688_write_raw, 370*3e87e783SSean Nyekjaer .write_raw_get_fmt = &ads8688_write_raw_get_fmt, 371*3e87e783SSean Nyekjaer .attrs = &ads8688_attribute_group, 372*3e87e783SSean Nyekjaer .driver_module = THIS_MODULE, 373*3e87e783SSean Nyekjaer }; 374*3e87e783SSean Nyekjaer 375*3e87e783SSean Nyekjaer static const struct ads8688_chip_info ads8688_chip_info_tbl[] = { 376*3e87e783SSean Nyekjaer [ID_ADS8684] = { 377*3e87e783SSean Nyekjaer .channels = ads8684_channels, 378*3e87e783SSean Nyekjaer .num_channels = ARRAY_SIZE(ads8684_channels), 379*3e87e783SSean Nyekjaer }, 380*3e87e783SSean Nyekjaer [ID_ADS8688] = { 381*3e87e783SSean Nyekjaer .channels = ads8688_channels, 382*3e87e783SSean Nyekjaer .num_channels = ARRAY_SIZE(ads8688_channels), 383*3e87e783SSean Nyekjaer }, 384*3e87e783SSean Nyekjaer }; 385*3e87e783SSean Nyekjaer 386*3e87e783SSean Nyekjaer static int ads8688_probe(struct spi_device *spi) 387*3e87e783SSean Nyekjaer { 388*3e87e783SSean Nyekjaer struct ads8688_state *st; 389*3e87e783SSean Nyekjaer struct iio_dev *indio_dev; 390*3e87e783SSean Nyekjaer int ret; 391*3e87e783SSean Nyekjaer 392*3e87e783SSean Nyekjaer indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); 393*3e87e783SSean Nyekjaer if (indio_dev == NULL) 394*3e87e783SSean Nyekjaer return -ENOMEM; 395*3e87e783SSean Nyekjaer 396*3e87e783SSean Nyekjaer st = iio_priv(indio_dev); 397*3e87e783SSean Nyekjaer 398*3e87e783SSean Nyekjaer st->reg = devm_regulator_get_optional(&spi->dev, "vref"); 399*3e87e783SSean Nyekjaer if (!IS_ERR(st->reg)) { 400*3e87e783SSean Nyekjaer ret = regulator_enable(st->reg); 401*3e87e783SSean Nyekjaer if (ret) 402*3e87e783SSean Nyekjaer return ret; 403*3e87e783SSean Nyekjaer 404*3e87e783SSean Nyekjaer ret = regulator_get_voltage(st->reg); 405*3e87e783SSean Nyekjaer if (ret < 0) 406*3e87e783SSean Nyekjaer goto error_out; 407*3e87e783SSean Nyekjaer 408*3e87e783SSean Nyekjaer st->vref_mv = ret / 1000; 409*3e87e783SSean Nyekjaer } else { 410*3e87e783SSean Nyekjaer /* Use internal reference */ 411*3e87e783SSean Nyekjaer st->vref_mv = ADS8688_VREF_MV; 412*3e87e783SSean Nyekjaer } 413*3e87e783SSean Nyekjaer 414*3e87e783SSean Nyekjaer st->chip_info = &ads8688_chip_info_tbl[spi_get_device_id(spi)->driver_data]; 415*3e87e783SSean Nyekjaer 416*3e87e783SSean Nyekjaer spi->mode = SPI_MODE_1; 417*3e87e783SSean Nyekjaer 418*3e87e783SSean Nyekjaer spi_set_drvdata(spi, indio_dev); 419*3e87e783SSean Nyekjaer 420*3e87e783SSean Nyekjaer st->spi = spi; 421*3e87e783SSean Nyekjaer 422*3e87e783SSean Nyekjaer indio_dev->name = spi_get_device_id(spi)->name; 423*3e87e783SSean Nyekjaer indio_dev->dev.parent = &spi->dev; 424*3e87e783SSean Nyekjaer indio_dev->modes = INDIO_DIRECT_MODE; 425*3e87e783SSean Nyekjaer indio_dev->channels = st->chip_info->channels; 426*3e87e783SSean Nyekjaer indio_dev->num_channels = st->chip_info->num_channels; 427*3e87e783SSean Nyekjaer indio_dev->info = &ads8688_info; 428*3e87e783SSean Nyekjaer 429*3e87e783SSean Nyekjaer ads8688_reset(indio_dev); 430*3e87e783SSean Nyekjaer 431*3e87e783SSean Nyekjaer mutex_init(&st->lock); 432*3e87e783SSean Nyekjaer 433*3e87e783SSean Nyekjaer ret = iio_device_register(indio_dev); 434*3e87e783SSean Nyekjaer if (ret) 435*3e87e783SSean Nyekjaer goto error_out; 436*3e87e783SSean Nyekjaer 437*3e87e783SSean Nyekjaer return 0; 438*3e87e783SSean Nyekjaer 439*3e87e783SSean Nyekjaer error_out: 440*3e87e783SSean Nyekjaer if (!IS_ERR_OR_NULL(st->reg)) 441*3e87e783SSean Nyekjaer regulator_disable(st->reg); 442*3e87e783SSean Nyekjaer 443*3e87e783SSean Nyekjaer return ret; 444*3e87e783SSean Nyekjaer } 445*3e87e783SSean Nyekjaer 446*3e87e783SSean Nyekjaer static int ads8688_remove(struct spi_device *spi) 447*3e87e783SSean Nyekjaer { 448*3e87e783SSean Nyekjaer struct iio_dev *indio_dev = spi_get_drvdata(spi); 449*3e87e783SSean Nyekjaer struct ads8688_state *st = iio_priv(indio_dev); 450*3e87e783SSean Nyekjaer 451*3e87e783SSean Nyekjaer iio_device_unregister(indio_dev); 452*3e87e783SSean Nyekjaer 453*3e87e783SSean Nyekjaer if (!IS_ERR_OR_NULL(st->reg)) 454*3e87e783SSean Nyekjaer regulator_disable(st->reg); 455*3e87e783SSean Nyekjaer 456*3e87e783SSean Nyekjaer return 0; 457*3e87e783SSean Nyekjaer } 458*3e87e783SSean Nyekjaer 459*3e87e783SSean Nyekjaer static const struct spi_device_id ads8688_id[] = { 460*3e87e783SSean Nyekjaer {"ads8684", ID_ADS8684}, 461*3e87e783SSean Nyekjaer {"ads8688", ID_ADS8688}, 462*3e87e783SSean Nyekjaer {} 463*3e87e783SSean Nyekjaer }; 464*3e87e783SSean Nyekjaer MODULE_DEVICE_TABLE(spi, ads8688_id); 465*3e87e783SSean Nyekjaer 466*3e87e783SSean Nyekjaer static const struct of_device_id ads8688_of_match[] = { 467*3e87e783SSean Nyekjaer { .compatible = "ti,ads8684" }, 468*3e87e783SSean Nyekjaer { .compatible = "ti,ads8688" }, 469*3e87e783SSean Nyekjaer { } 470*3e87e783SSean Nyekjaer }; 471*3e87e783SSean Nyekjaer MODULE_DEVICE_TABLE(of, ads8688_of_match); 472*3e87e783SSean Nyekjaer 473*3e87e783SSean Nyekjaer static struct spi_driver ads8688_driver = { 474*3e87e783SSean Nyekjaer .driver = { 475*3e87e783SSean Nyekjaer .name = "ads8688", 476*3e87e783SSean Nyekjaer .owner = THIS_MODULE, 477*3e87e783SSean Nyekjaer }, 478*3e87e783SSean Nyekjaer .probe = ads8688_probe, 479*3e87e783SSean Nyekjaer .remove = ads8688_remove, 480*3e87e783SSean Nyekjaer .id_table = ads8688_id, 481*3e87e783SSean Nyekjaer }; 482*3e87e783SSean Nyekjaer module_spi_driver(ads8688_driver); 483*3e87e783SSean Nyekjaer 484*3e87e783SSean Nyekjaer MODULE_AUTHOR("Sean Nyekjaer <sean.nyekjaer@prevas.dk>"); 485*3e87e783SSean Nyekjaer MODULE_DESCRIPTION("Texas Instruments ADS8688 driver"); 486*3e87e783SSean Nyekjaer MODULE_LICENSE("GPL v2"); 487