17d7209f0SDavid Lechner // SPDX-License-Identifier: GPL-2.0 2902c4b24SDavid Lechner /* 3902c4b24SDavid Lechner * Texas Instruments ADS7950 SPI ADC driver 4902c4b24SDavid Lechner * 5902c4b24SDavid Lechner * Copyright 2016 David Lechner <david@lechnology.com> 6902c4b24SDavid Lechner * 7902c4b24SDavid Lechner * Based on iio/ad7923.c: 8902c4b24SDavid Lechner * Copyright 2011 Analog Devices Inc 9902c4b24SDavid Lechner * Copyright 2012 CS Systemes d'Information 10902c4b24SDavid Lechner * 11902c4b24SDavid Lechner * And also on hwmon/ads79xx.c 12902c4b24SDavid Lechner * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ 13902c4b24SDavid Lechner * Nishanth Menon 14902c4b24SDavid Lechner */ 15902c4b24SDavid Lechner 168cfa26a7SAndy Shevchenko #include <linux/acpi.h> 17902c4b24SDavid Lechner #include <linux/bitops.h> 18902c4b24SDavid Lechner #include <linux/device.h> 19902c4b24SDavid Lechner #include <linux/err.h> 20902c4b24SDavid Lechner #include <linux/interrupt.h> 21902c4b24SDavid Lechner #include <linux/kernel.h> 22902c4b24SDavid Lechner #include <linux/module.h> 23902c4b24SDavid Lechner #include <linux/regulator/consumer.h> 24902c4b24SDavid Lechner #include <linux/slab.h> 25902c4b24SDavid Lechner #include <linux/spi/spi.h> 26902c4b24SDavid Lechner 27902c4b24SDavid Lechner #include <linux/iio/buffer.h> 28902c4b24SDavid Lechner #include <linux/iio/iio.h> 29902c4b24SDavid Lechner #include <linux/iio/sysfs.h> 30902c4b24SDavid Lechner #include <linux/iio/trigger_consumer.h> 31902c4b24SDavid Lechner #include <linux/iio/triggered_buffer.h> 32902c4b24SDavid Lechner 338cfa26a7SAndy Shevchenko /* 348cfa26a7SAndy Shevchenko * In case of ACPI, we use the 5000 mV as default for the reference pin. 358cfa26a7SAndy Shevchenko * Device tree users encode that via the vref-supply regulator. 368cfa26a7SAndy Shevchenko */ 378cfa26a7SAndy Shevchenko #define TI_ADS7950_VA_MV_ACPI_DEFAULT 5000 388cfa26a7SAndy Shevchenko 39902c4b24SDavid Lechner #define TI_ADS7950_CR_MANUAL BIT(12) 40902c4b24SDavid Lechner #define TI_ADS7950_CR_WRITE BIT(11) 41902c4b24SDavid Lechner #define TI_ADS7950_CR_CHAN(ch) ((ch) << 7) 42902c4b24SDavid Lechner #define TI_ADS7950_CR_RANGE_5V BIT(6) 43902c4b24SDavid Lechner 44902c4b24SDavid Lechner #define TI_ADS7950_MAX_CHAN 16 45902c4b24SDavid Lechner 46902c4b24SDavid Lechner #define TI_ADS7950_TIMESTAMP_SIZE (sizeof(int64_t) / sizeof(__be16)) 47902c4b24SDavid Lechner 48902c4b24SDavid Lechner /* val = value, dec = left shift, bits = number of bits of the mask */ 49902c4b24SDavid Lechner #define TI_ADS7950_EXTRACT(val, dec, bits) \ 50902c4b24SDavid Lechner (((val) >> (dec)) & ((1 << (bits)) - 1)) 51902c4b24SDavid Lechner 52902c4b24SDavid Lechner struct ti_ads7950_state { 53902c4b24SDavid Lechner struct spi_device *spi; 54902c4b24SDavid Lechner struct spi_transfer ring_xfer[TI_ADS7950_MAX_CHAN + 2]; 55902c4b24SDavid Lechner struct spi_transfer scan_single_xfer[3]; 56902c4b24SDavid Lechner struct spi_message ring_msg; 57902c4b24SDavid Lechner struct spi_message scan_single_msg; 58902c4b24SDavid Lechner 59902c4b24SDavid Lechner struct regulator *reg; 608cfa26a7SAndy Shevchenko unsigned int vref_mv; 61902c4b24SDavid Lechner 62902c4b24SDavid Lechner unsigned int settings; 63902c4b24SDavid Lechner 64902c4b24SDavid Lechner /* 65902c4b24SDavid Lechner * DMA (thus cache coherency maintenance) requires the 66902c4b24SDavid Lechner * transfer buffers to live in their own cache lines. 67902c4b24SDavid Lechner */ 68902c4b24SDavid Lechner __be16 rx_buf[TI_ADS7950_MAX_CHAN + TI_ADS7950_TIMESTAMP_SIZE] 69902c4b24SDavid Lechner ____cacheline_aligned; 70902c4b24SDavid Lechner __be16 tx_buf[TI_ADS7950_MAX_CHAN]; 718134b613SDavid Lechner __be16 single_tx; 728134b613SDavid Lechner __be16 single_rx; 738134b613SDavid Lechner 74902c4b24SDavid Lechner }; 75902c4b24SDavid Lechner 76902c4b24SDavid Lechner struct ti_ads7950_chip_info { 77902c4b24SDavid Lechner const struct iio_chan_spec *channels; 78902c4b24SDavid Lechner unsigned int num_channels; 79902c4b24SDavid Lechner }; 80902c4b24SDavid Lechner 81902c4b24SDavid Lechner enum ti_ads7950_id { 82902c4b24SDavid Lechner TI_ADS7950, 83902c4b24SDavid Lechner TI_ADS7951, 84902c4b24SDavid Lechner TI_ADS7952, 85902c4b24SDavid Lechner TI_ADS7953, 86902c4b24SDavid Lechner TI_ADS7954, 87902c4b24SDavid Lechner TI_ADS7955, 88902c4b24SDavid Lechner TI_ADS7956, 89902c4b24SDavid Lechner TI_ADS7957, 90902c4b24SDavid Lechner TI_ADS7958, 91902c4b24SDavid Lechner TI_ADS7959, 92902c4b24SDavid Lechner TI_ADS7960, 93902c4b24SDavid Lechner TI_ADS7961, 94902c4b24SDavid Lechner }; 95902c4b24SDavid Lechner 96902c4b24SDavid Lechner #define TI_ADS7950_V_CHAN(index, bits) \ 97902c4b24SDavid Lechner { \ 98902c4b24SDavid Lechner .type = IIO_VOLTAGE, \ 99902c4b24SDavid Lechner .indexed = 1, \ 100902c4b24SDavid Lechner .channel = index, \ 101902c4b24SDavid Lechner .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 102902c4b24SDavid Lechner .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ 103902c4b24SDavid Lechner .address = index, \ 104902c4b24SDavid Lechner .datasheet_name = "CH##index", \ 105902c4b24SDavid Lechner .scan_index = index, \ 106902c4b24SDavid Lechner .scan_type = { \ 107902c4b24SDavid Lechner .sign = 'u', \ 108902c4b24SDavid Lechner .realbits = bits, \ 109902c4b24SDavid Lechner .storagebits = 16, \ 110902c4b24SDavid Lechner .shift = 12 - (bits), \ 111902c4b24SDavid Lechner .endianness = IIO_BE, \ 112902c4b24SDavid Lechner }, \ 113902c4b24SDavid Lechner } 114902c4b24SDavid Lechner 115902c4b24SDavid Lechner #define DECLARE_TI_ADS7950_4_CHANNELS(name, bits) \ 116902c4b24SDavid Lechner const struct iio_chan_spec name ## _channels[] = { \ 117902c4b24SDavid Lechner TI_ADS7950_V_CHAN(0, bits), \ 118902c4b24SDavid Lechner TI_ADS7950_V_CHAN(1, bits), \ 119902c4b24SDavid Lechner TI_ADS7950_V_CHAN(2, bits), \ 120902c4b24SDavid Lechner TI_ADS7950_V_CHAN(3, bits), \ 121902c4b24SDavid Lechner IIO_CHAN_SOFT_TIMESTAMP(4), \ 122902c4b24SDavid Lechner } 123902c4b24SDavid Lechner 124902c4b24SDavid Lechner #define DECLARE_TI_ADS7950_8_CHANNELS(name, bits) \ 125902c4b24SDavid Lechner const struct iio_chan_spec name ## _channels[] = { \ 126902c4b24SDavid Lechner TI_ADS7950_V_CHAN(0, bits), \ 127902c4b24SDavid Lechner TI_ADS7950_V_CHAN(1, bits), \ 128902c4b24SDavid Lechner TI_ADS7950_V_CHAN(2, bits), \ 129902c4b24SDavid Lechner TI_ADS7950_V_CHAN(3, bits), \ 130902c4b24SDavid Lechner TI_ADS7950_V_CHAN(4, bits), \ 131902c4b24SDavid Lechner TI_ADS7950_V_CHAN(5, bits), \ 132902c4b24SDavid Lechner TI_ADS7950_V_CHAN(6, bits), \ 133902c4b24SDavid Lechner TI_ADS7950_V_CHAN(7, bits), \ 134902c4b24SDavid Lechner IIO_CHAN_SOFT_TIMESTAMP(8), \ 135902c4b24SDavid Lechner } 136902c4b24SDavid Lechner 137902c4b24SDavid Lechner #define DECLARE_TI_ADS7950_12_CHANNELS(name, bits) \ 138902c4b24SDavid Lechner const struct iio_chan_spec name ## _channels[] = { \ 139902c4b24SDavid Lechner TI_ADS7950_V_CHAN(0, bits), \ 140902c4b24SDavid Lechner TI_ADS7950_V_CHAN(1, bits), \ 141902c4b24SDavid Lechner TI_ADS7950_V_CHAN(2, bits), \ 142902c4b24SDavid Lechner TI_ADS7950_V_CHAN(3, bits), \ 143902c4b24SDavid Lechner TI_ADS7950_V_CHAN(4, bits), \ 144902c4b24SDavid Lechner TI_ADS7950_V_CHAN(5, bits), \ 145902c4b24SDavid Lechner TI_ADS7950_V_CHAN(6, bits), \ 146902c4b24SDavid Lechner TI_ADS7950_V_CHAN(7, bits), \ 147902c4b24SDavid Lechner TI_ADS7950_V_CHAN(8, bits), \ 148902c4b24SDavid Lechner TI_ADS7950_V_CHAN(9, bits), \ 149902c4b24SDavid Lechner TI_ADS7950_V_CHAN(10, bits), \ 150902c4b24SDavid Lechner TI_ADS7950_V_CHAN(11, bits), \ 151902c4b24SDavid Lechner IIO_CHAN_SOFT_TIMESTAMP(12), \ 152902c4b24SDavid Lechner } 153902c4b24SDavid Lechner 154902c4b24SDavid Lechner #define DECLARE_TI_ADS7950_16_CHANNELS(name, bits) \ 155902c4b24SDavid Lechner const struct iio_chan_spec name ## _channels[] = { \ 156902c4b24SDavid Lechner TI_ADS7950_V_CHAN(0, bits), \ 157902c4b24SDavid Lechner TI_ADS7950_V_CHAN(1, bits), \ 158902c4b24SDavid Lechner TI_ADS7950_V_CHAN(2, bits), \ 159902c4b24SDavid Lechner TI_ADS7950_V_CHAN(3, bits), \ 160902c4b24SDavid Lechner TI_ADS7950_V_CHAN(4, bits), \ 161902c4b24SDavid Lechner TI_ADS7950_V_CHAN(5, bits), \ 162902c4b24SDavid Lechner TI_ADS7950_V_CHAN(6, bits), \ 163902c4b24SDavid Lechner TI_ADS7950_V_CHAN(7, bits), \ 164902c4b24SDavid Lechner TI_ADS7950_V_CHAN(8, bits), \ 165902c4b24SDavid Lechner TI_ADS7950_V_CHAN(9, bits), \ 166902c4b24SDavid Lechner TI_ADS7950_V_CHAN(10, bits), \ 167902c4b24SDavid Lechner TI_ADS7950_V_CHAN(11, bits), \ 168902c4b24SDavid Lechner TI_ADS7950_V_CHAN(12, bits), \ 169902c4b24SDavid Lechner TI_ADS7950_V_CHAN(13, bits), \ 170902c4b24SDavid Lechner TI_ADS7950_V_CHAN(14, bits), \ 171902c4b24SDavid Lechner TI_ADS7950_V_CHAN(15, bits), \ 172902c4b24SDavid Lechner IIO_CHAN_SOFT_TIMESTAMP(16), \ 173902c4b24SDavid Lechner } 174902c4b24SDavid Lechner 175902c4b24SDavid Lechner static DECLARE_TI_ADS7950_4_CHANNELS(ti_ads7950, 12); 176902c4b24SDavid Lechner static DECLARE_TI_ADS7950_8_CHANNELS(ti_ads7951, 12); 177902c4b24SDavid Lechner static DECLARE_TI_ADS7950_12_CHANNELS(ti_ads7952, 12); 178902c4b24SDavid Lechner static DECLARE_TI_ADS7950_16_CHANNELS(ti_ads7953, 12); 179902c4b24SDavid Lechner static DECLARE_TI_ADS7950_4_CHANNELS(ti_ads7954, 10); 180902c4b24SDavid Lechner static DECLARE_TI_ADS7950_8_CHANNELS(ti_ads7955, 10); 181902c4b24SDavid Lechner static DECLARE_TI_ADS7950_12_CHANNELS(ti_ads7956, 10); 182902c4b24SDavid Lechner static DECLARE_TI_ADS7950_16_CHANNELS(ti_ads7957, 10); 183902c4b24SDavid Lechner static DECLARE_TI_ADS7950_4_CHANNELS(ti_ads7958, 8); 184902c4b24SDavid Lechner static DECLARE_TI_ADS7950_8_CHANNELS(ti_ads7959, 8); 185902c4b24SDavid Lechner static DECLARE_TI_ADS7950_12_CHANNELS(ti_ads7960, 8); 186902c4b24SDavid Lechner static DECLARE_TI_ADS7950_16_CHANNELS(ti_ads7961, 8); 187902c4b24SDavid Lechner 188902c4b24SDavid Lechner static const struct ti_ads7950_chip_info ti_ads7950_chip_info[] = { 189902c4b24SDavid Lechner [TI_ADS7950] = { 190902c4b24SDavid Lechner .channels = ti_ads7950_channels, 191902c4b24SDavid Lechner .num_channels = ARRAY_SIZE(ti_ads7950_channels), 192902c4b24SDavid Lechner }, 193902c4b24SDavid Lechner [TI_ADS7951] = { 194902c4b24SDavid Lechner .channels = ti_ads7951_channels, 195902c4b24SDavid Lechner .num_channels = ARRAY_SIZE(ti_ads7951_channels), 196902c4b24SDavid Lechner }, 197902c4b24SDavid Lechner [TI_ADS7952] = { 198902c4b24SDavid Lechner .channels = ti_ads7952_channels, 199902c4b24SDavid Lechner .num_channels = ARRAY_SIZE(ti_ads7952_channels), 200902c4b24SDavid Lechner }, 201902c4b24SDavid Lechner [TI_ADS7953] = { 202902c4b24SDavid Lechner .channels = ti_ads7953_channels, 203902c4b24SDavid Lechner .num_channels = ARRAY_SIZE(ti_ads7953_channels), 204902c4b24SDavid Lechner }, 205902c4b24SDavid Lechner [TI_ADS7954] = { 206902c4b24SDavid Lechner .channels = ti_ads7954_channels, 207902c4b24SDavid Lechner .num_channels = ARRAY_SIZE(ti_ads7954_channels), 208902c4b24SDavid Lechner }, 209902c4b24SDavid Lechner [TI_ADS7955] = { 210902c4b24SDavid Lechner .channels = ti_ads7955_channels, 211902c4b24SDavid Lechner .num_channels = ARRAY_SIZE(ti_ads7955_channels), 212902c4b24SDavid Lechner }, 213902c4b24SDavid Lechner [TI_ADS7956] = { 214902c4b24SDavid Lechner .channels = ti_ads7956_channels, 215902c4b24SDavid Lechner .num_channels = ARRAY_SIZE(ti_ads7956_channels), 216902c4b24SDavid Lechner }, 217902c4b24SDavid Lechner [TI_ADS7957] = { 218902c4b24SDavid Lechner .channels = ti_ads7957_channels, 219902c4b24SDavid Lechner .num_channels = ARRAY_SIZE(ti_ads7957_channels), 220902c4b24SDavid Lechner }, 221902c4b24SDavid Lechner [TI_ADS7958] = { 222902c4b24SDavid Lechner .channels = ti_ads7958_channels, 223902c4b24SDavid Lechner .num_channels = ARRAY_SIZE(ti_ads7958_channels), 224902c4b24SDavid Lechner }, 225902c4b24SDavid Lechner [TI_ADS7959] = { 226902c4b24SDavid Lechner .channels = ti_ads7959_channels, 227902c4b24SDavid Lechner .num_channels = ARRAY_SIZE(ti_ads7959_channels), 228902c4b24SDavid Lechner }, 229902c4b24SDavid Lechner [TI_ADS7960] = { 230902c4b24SDavid Lechner .channels = ti_ads7960_channels, 231902c4b24SDavid Lechner .num_channels = ARRAY_SIZE(ti_ads7960_channels), 232902c4b24SDavid Lechner }, 233902c4b24SDavid Lechner [TI_ADS7961] = { 234902c4b24SDavid Lechner .channels = ti_ads7961_channels, 235902c4b24SDavid Lechner .num_channels = ARRAY_SIZE(ti_ads7961_channels), 236902c4b24SDavid Lechner }, 237902c4b24SDavid Lechner }; 238902c4b24SDavid Lechner 239902c4b24SDavid Lechner /* 240902c4b24SDavid Lechner * ti_ads7950_update_scan_mode() setup the spi transfer buffer for the new 241902c4b24SDavid Lechner * scan mask 242902c4b24SDavid Lechner */ 243902c4b24SDavid Lechner static int ti_ads7950_update_scan_mode(struct iio_dev *indio_dev, 244902c4b24SDavid Lechner const unsigned long *active_scan_mask) 245902c4b24SDavid Lechner { 246902c4b24SDavid Lechner struct ti_ads7950_state *st = iio_priv(indio_dev); 247902c4b24SDavid Lechner int i, cmd, len; 248902c4b24SDavid Lechner 249902c4b24SDavid Lechner len = 0; 250902c4b24SDavid Lechner for_each_set_bit(i, active_scan_mask, indio_dev->num_channels) { 251902c4b24SDavid Lechner cmd = TI_ADS7950_CR_WRITE | TI_ADS7950_CR_CHAN(i) | st->settings; 252902c4b24SDavid Lechner st->tx_buf[len++] = cpu_to_be16(cmd); 253902c4b24SDavid Lechner } 254902c4b24SDavid Lechner 255902c4b24SDavid Lechner /* Data for the 1st channel is not returned until the 3rd transfer */ 256902c4b24SDavid Lechner len += 2; 257902c4b24SDavid Lechner for (i = 0; i < len; i++) { 258902c4b24SDavid Lechner if ((i + 2) < len) 259902c4b24SDavid Lechner st->ring_xfer[i].tx_buf = &st->tx_buf[i]; 260902c4b24SDavid Lechner if (i >= 2) 261902c4b24SDavid Lechner st->ring_xfer[i].rx_buf = &st->rx_buf[i - 2]; 262902c4b24SDavid Lechner st->ring_xfer[i].len = 2; 263902c4b24SDavid Lechner st->ring_xfer[i].cs_change = 1; 264902c4b24SDavid Lechner } 265902c4b24SDavid Lechner /* make sure last transfer's cs_change is not set */ 266902c4b24SDavid Lechner st->ring_xfer[len - 1].cs_change = 0; 267902c4b24SDavid Lechner 268902c4b24SDavid Lechner spi_message_init_with_transfers(&st->ring_msg, st->ring_xfer, len); 269902c4b24SDavid Lechner 270902c4b24SDavid Lechner return 0; 271902c4b24SDavid Lechner } 272902c4b24SDavid Lechner 273902c4b24SDavid Lechner static irqreturn_t ti_ads7950_trigger_handler(int irq, void *p) 274902c4b24SDavid Lechner { 275902c4b24SDavid Lechner struct iio_poll_func *pf = p; 276902c4b24SDavid Lechner struct iio_dev *indio_dev = pf->indio_dev; 277902c4b24SDavid Lechner struct ti_ads7950_state *st = iio_priv(indio_dev); 278902c4b24SDavid Lechner int ret; 279902c4b24SDavid Lechner 280902c4b24SDavid Lechner ret = spi_sync(st->spi, &st->ring_msg); 281902c4b24SDavid Lechner if (ret < 0) 282902c4b24SDavid Lechner goto out; 283902c4b24SDavid Lechner 284902c4b24SDavid Lechner iio_push_to_buffers_with_timestamp(indio_dev, st->rx_buf, 285902c4b24SDavid Lechner iio_get_time_ns(indio_dev)); 286902c4b24SDavid Lechner 287902c4b24SDavid Lechner out: 288902c4b24SDavid Lechner iio_trigger_notify_done(indio_dev->trig); 289902c4b24SDavid Lechner 290902c4b24SDavid Lechner return IRQ_HANDLED; 291902c4b24SDavid Lechner } 292902c4b24SDavid Lechner 2938134b613SDavid Lechner static int ti_ads7950_scan_direct(struct iio_dev *indio_dev, unsigned int ch) 294902c4b24SDavid Lechner { 2958134b613SDavid Lechner struct ti_ads7950_state *st = iio_priv(indio_dev); 296902c4b24SDavid Lechner int ret, cmd; 297902c4b24SDavid Lechner 2988134b613SDavid Lechner mutex_lock(&indio_dev->mlock); 2998134b613SDavid Lechner 300902c4b24SDavid Lechner cmd = TI_ADS7950_CR_WRITE | TI_ADS7950_CR_CHAN(ch) | st->settings; 3018134b613SDavid Lechner st->single_tx = cpu_to_be16(cmd); 302902c4b24SDavid Lechner 303902c4b24SDavid Lechner ret = spi_sync(st->spi, &st->scan_single_msg); 304902c4b24SDavid Lechner if (ret) 3058134b613SDavid Lechner goto out; 306902c4b24SDavid Lechner 3078134b613SDavid Lechner ret = be16_to_cpu(st->single_rx); 3088134b613SDavid Lechner 3098134b613SDavid Lechner out: 3108134b613SDavid Lechner mutex_unlock(&indio_dev->mlock); 3118134b613SDavid Lechner 3128134b613SDavid Lechner return ret; 313902c4b24SDavid Lechner } 314902c4b24SDavid Lechner 315902c4b24SDavid Lechner static int ti_ads7950_get_range(struct ti_ads7950_state *st) 316902c4b24SDavid Lechner { 317902c4b24SDavid Lechner int vref; 318902c4b24SDavid Lechner 3198cfa26a7SAndy Shevchenko if (st->vref_mv) { 3208cfa26a7SAndy Shevchenko vref = st->vref_mv; 3218cfa26a7SAndy Shevchenko } else { 322902c4b24SDavid Lechner vref = regulator_get_voltage(st->reg); 323902c4b24SDavid Lechner if (vref < 0) 324902c4b24SDavid Lechner return vref; 325902c4b24SDavid Lechner 326902c4b24SDavid Lechner vref /= 1000; 3278cfa26a7SAndy Shevchenko } 328902c4b24SDavid Lechner 329902c4b24SDavid Lechner if (st->settings & TI_ADS7950_CR_RANGE_5V) 330902c4b24SDavid Lechner vref *= 2; 331902c4b24SDavid Lechner 332902c4b24SDavid Lechner return vref; 333902c4b24SDavid Lechner } 334902c4b24SDavid Lechner 335902c4b24SDavid Lechner static int ti_ads7950_read_raw(struct iio_dev *indio_dev, 336902c4b24SDavid Lechner struct iio_chan_spec const *chan, 337902c4b24SDavid Lechner int *val, int *val2, long m) 338902c4b24SDavid Lechner { 339902c4b24SDavid Lechner struct ti_ads7950_state *st = iio_priv(indio_dev); 340902c4b24SDavid Lechner int ret; 341902c4b24SDavid Lechner 342902c4b24SDavid Lechner switch (m) { 343902c4b24SDavid Lechner case IIO_CHAN_INFO_RAW: 3448134b613SDavid Lechner ret = ti_ads7950_scan_direct(indio_dev, chan->address); 345902c4b24SDavid Lechner if (ret < 0) 346902c4b24SDavid Lechner return ret; 347902c4b24SDavid Lechner 348902c4b24SDavid Lechner if (chan->address != TI_ADS7950_EXTRACT(ret, 12, 4)) 349902c4b24SDavid Lechner return -EIO; 350902c4b24SDavid Lechner 351902c4b24SDavid Lechner *val = TI_ADS7950_EXTRACT(ret, chan->scan_type.shift, 352902c4b24SDavid Lechner chan->scan_type.realbits); 353902c4b24SDavid Lechner 354902c4b24SDavid Lechner return IIO_VAL_INT; 355902c4b24SDavid Lechner case IIO_CHAN_INFO_SCALE: 356902c4b24SDavid Lechner ret = ti_ads7950_get_range(st); 357902c4b24SDavid Lechner if (ret < 0) 358902c4b24SDavid Lechner return ret; 359902c4b24SDavid Lechner 360902c4b24SDavid Lechner *val = ret; 361902c4b24SDavid Lechner *val2 = (1 << chan->scan_type.realbits) - 1; 362902c4b24SDavid Lechner 363902c4b24SDavid Lechner return IIO_VAL_FRACTIONAL; 364902c4b24SDavid Lechner } 365902c4b24SDavid Lechner 366902c4b24SDavid Lechner return -EINVAL; 367902c4b24SDavid Lechner } 368902c4b24SDavid Lechner 369902c4b24SDavid Lechner static const struct iio_info ti_ads7950_info = { 370902c4b24SDavid Lechner .read_raw = &ti_ads7950_read_raw, 371902c4b24SDavid Lechner .update_scan_mode = ti_ads7950_update_scan_mode, 372902c4b24SDavid Lechner }; 373902c4b24SDavid Lechner 374902c4b24SDavid Lechner static int ti_ads7950_probe(struct spi_device *spi) 375902c4b24SDavid Lechner { 376902c4b24SDavid Lechner struct ti_ads7950_state *st; 377902c4b24SDavid Lechner struct iio_dev *indio_dev; 378902c4b24SDavid Lechner const struct ti_ads7950_chip_info *info; 379902c4b24SDavid Lechner int ret; 380902c4b24SDavid Lechner 381902c4b24SDavid Lechner indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); 382902c4b24SDavid Lechner if (!indio_dev) 383902c4b24SDavid Lechner return -ENOMEM; 384902c4b24SDavid Lechner 385902c4b24SDavid Lechner st = iio_priv(indio_dev); 386902c4b24SDavid Lechner 387902c4b24SDavid Lechner spi_set_drvdata(spi, indio_dev); 388902c4b24SDavid Lechner 389902c4b24SDavid Lechner st->spi = spi; 390902c4b24SDavid Lechner st->settings = TI_ADS7950_CR_MANUAL | TI_ADS7950_CR_RANGE_5V; 391902c4b24SDavid Lechner 392902c4b24SDavid Lechner info = &ti_ads7950_chip_info[spi_get_device_id(spi)->driver_data]; 393902c4b24SDavid Lechner 394902c4b24SDavid Lechner indio_dev->name = spi_get_device_id(spi)->name; 395902c4b24SDavid Lechner indio_dev->dev.parent = &spi->dev; 396902c4b24SDavid Lechner indio_dev->modes = INDIO_DIRECT_MODE; 397902c4b24SDavid Lechner indio_dev->channels = info->channels; 398902c4b24SDavid Lechner indio_dev->num_channels = info->num_channels; 399902c4b24SDavid Lechner indio_dev->info = &ti_ads7950_info; 400902c4b24SDavid Lechner 401902c4b24SDavid Lechner /* 402902c4b24SDavid Lechner * Setup default message. The sample is read at the end of the first 403902c4b24SDavid Lechner * transfer, then it takes one full cycle to convert the sample and one 404902c4b24SDavid Lechner * more cycle to send the value. The conversion process is driven by 405902c4b24SDavid Lechner * the SPI clock, which is why we have 3 transfers. The middle one is 406902c4b24SDavid Lechner * just dummy data sent while the chip is converting the sample that 407902c4b24SDavid Lechner * was read at the end of the first transfer. 408902c4b24SDavid Lechner */ 409902c4b24SDavid Lechner 4108134b613SDavid Lechner st->scan_single_xfer[0].tx_buf = &st->single_tx; 411902c4b24SDavid Lechner st->scan_single_xfer[0].len = 2; 412902c4b24SDavid Lechner st->scan_single_xfer[0].cs_change = 1; 4138134b613SDavid Lechner st->scan_single_xfer[1].tx_buf = &st->single_tx; 414902c4b24SDavid Lechner st->scan_single_xfer[1].len = 2; 415902c4b24SDavid Lechner st->scan_single_xfer[1].cs_change = 1; 4168134b613SDavid Lechner st->scan_single_xfer[2].rx_buf = &st->single_rx; 417902c4b24SDavid Lechner st->scan_single_xfer[2].len = 2; 418902c4b24SDavid Lechner 419902c4b24SDavid Lechner spi_message_init_with_transfers(&st->scan_single_msg, 420902c4b24SDavid Lechner st->scan_single_xfer, 3); 421902c4b24SDavid Lechner 4228cfa26a7SAndy Shevchenko /* Use hard coded value for reference voltage in ACPI case */ 4238cfa26a7SAndy Shevchenko if (ACPI_COMPANION(&spi->dev)) 4248cfa26a7SAndy Shevchenko st->vref_mv = TI_ADS7950_VA_MV_ACPI_DEFAULT; 4258cfa26a7SAndy Shevchenko 4260bf1a2aaSDavid Lechner st->reg = devm_regulator_get(&spi->dev, "vref"); 427902c4b24SDavid Lechner if (IS_ERR(st->reg)) { 4280bf1a2aaSDavid Lechner dev_err(&spi->dev, "Failed get get regulator \"vref\"\n"); 429902c4b24SDavid Lechner return PTR_ERR(st->reg); 430902c4b24SDavid Lechner } 431902c4b24SDavid Lechner 432902c4b24SDavid Lechner ret = regulator_enable(st->reg); 433902c4b24SDavid Lechner if (ret) { 4340bf1a2aaSDavid Lechner dev_err(&spi->dev, "Failed to enable regulator \"vref\"\n"); 435902c4b24SDavid Lechner return ret; 436902c4b24SDavid Lechner } 437902c4b24SDavid Lechner 438902c4b24SDavid Lechner ret = iio_triggered_buffer_setup(indio_dev, NULL, 439902c4b24SDavid Lechner &ti_ads7950_trigger_handler, NULL); 440902c4b24SDavid Lechner if (ret) { 441902c4b24SDavid Lechner dev_err(&spi->dev, "Failed to setup triggered buffer\n"); 442902c4b24SDavid Lechner goto error_disable_reg; 443902c4b24SDavid Lechner } 444902c4b24SDavid Lechner 445902c4b24SDavid Lechner ret = iio_device_register(indio_dev); 446902c4b24SDavid Lechner if (ret) { 447902c4b24SDavid Lechner dev_err(&spi->dev, "Failed to register iio device\n"); 448902c4b24SDavid Lechner goto error_cleanup_ring; 449902c4b24SDavid Lechner } 450902c4b24SDavid Lechner 451902c4b24SDavid Lechner return 0; 452902c4b24SDavid Lechner 453902c4b24SDavid Lechner error_cleanup_ring: 454902c4b24SDavid Lechner iio_triggered_buffer_cleanup(indio_dev); 455902c4b24SDavid Lechner error_disable_reg: 456902c4b24SDavid Lechner regulator_disable(st->reg); 457902c4b24SDavid Lechner 458902c4b24SDavid Lechner return ret; 459902c4b24SDavid Lechner } 460902c4b24SDavid Lechner 461902c4b24SDavid Lechner static int ti_ads7950_remove(struct spi_device *spi) 462902c4b24SDavid Lechner { 463902c4b24SDavid Lechner struct iio_dev *indio_dev = spi_get_drvdata(spi); 464902c4b24SDavid Lechner struct ti_ads7950_state *st = iio_priv(indio_dev); 465902c4b24SDavid Lechner 466902c4b24SDavid Lechner iio_device_unregister(indio_dev); 467902c4b24SDavid Lechner iio_triggered_buffer_cleanup(indio_dev); 468902c4b24SDavid Lechner regulator_disable(st->reg); 469902c4b24SDavid Lechner 470902c4b24SDavid Lechner return 0; 471902c4b24SDavid Lechner } 472902c4b24SDavid Lechner 473902c4b24SDavid Lechner static const struct spi_device_id ti_ads7950_id[] = { 4742b84f4deSDavid Lechner { "ads7950", TI_ADS7950 }, 4752b84f4deSDavid Lechner { "ads7951", TI_ADS7951 }, 4762b84f4deSDavid Lechner { "ads7952", TI_ADS7952 }, 4772b84f4deSDavid Lechner { "ads7953", TI_ADS7953 }, 4782b84f4deSDavid Lechner { "ads7954", TI_ADS7954 }, 4792b84f4deSDavid Lechner { "ads7955", TI_ADS7955 }, 4802b84f4deSDavid Lechner { "ads7956", TI_ADS7956 }, 4812b84f4deSDavid Lechner { "ads7957", TI_ADS7957 }, 4822b84f4deSDavid Lechner { "ads7958", TI_ADS7958 }, 4832b84f4deSDavid Lechner { "ads7959", TI_ADS7959 }, 4842b84f4deSDavid Lechner { "ads7960", TI_ADS7960 }, 4852b84f4deSDavid Lechner { "ads7961", TI_ADS7961 }, 486902c4b24SDavid Lechner { } 487902c4b24SDavid Lechner }; 488902c4b24SDavid Lechner MODULE_DEVICE_TABLE(spi, ti_ads7950_id); 489902c4b24SDavid Lechner 490fb4b6f92SAndy Shevchenko static const struct of_device_id ads7950_of_table[] = { 491fb4b6f92SAndy Shevchenko { .compatible = "ti,ads7950", .data = &ti_ads7950_chip_info[TI_ADS7950] }, 492fb4b6f92SAndy Shevchenko { .compatible = "ti,ads7951", .data = &ti_ads7950_chip_info[TI_ADS7951] }, 493fb4b6f92SAndy Shevchenko { .compatible = "ti,ads7952", .data = &ti_ads7950_chip_info[TI_ADS7952] }, 494fb4b6f92SAndy Shevchenko { .compatible = "ti,ads7953", .data = &ti_ads7950_chip_info[TI_ADS7953] }, 495fb4b6f92SAndy Shevchenko { .compatible = "ti,ads7954", .data = &ti_ads7950_chip_info[TI_ADS7954] }, 496fb4b6f92SAndy Shevchenko { .compatible = "ti,ads7955", .data = &ti_ads7950_chip_info[TI_ADS7955] }, 497fb4b6f92SAndy Shevchenko { .compatible = "ti,ads7956", .data = &ti_ads7950_chip_info[TI_ADS7956] }, 498fb4b6f92SAndy Shevchenko { .compatible = "ti,ads7957", .data = &ti_ads7950_chip_info[TI_ADS7957] }, 499fb4b6f92SAndy Shevchenko { .compatible = "ti,ads7958", .data = &ti_ads7950_chip_info[TI_ADS7958] }, 500fb4b6f92SAndy Shevchenko { .compatible = "ti,ads7959", .data = &ti_ads7950_chip_info[TI_ADS7959] }, 501fb4b6f92SAndy Shevchenko { .compatible = "ti,ads7960", .data = &ti_ads7950_chip_info[TI_ADS7960] }, 502fb4b6f92SAndy Shevchenko { .compatible = "ti,ads7961", .data = &ti_ads7950_chip_info[TI_ADS7961] }, 503fb4b6f92SAndy Shevchenko { }, 504fb4b6f92SAndy Shevchenko }; 505fb4b6f92SAndy Shevchenko MODULE_DEVICE_TABLE(of, ads7950_of_table); 506fb4b6f92SAndy Shevchenko 507902c4b24SDavid Lechner static struct spi_driver ti_ads7950_driver = { 508902c4b24SDavid Lechner .driver = { 5092b84f4deSDavid Lechner .name = "ads7950", 510fb4b6f92SAndy Shevchenko .of_match_table = ads7950_of_table, 511902c4b24SDavid Lechner }, 512902c4b24SDavid Lechner .probe = ti_ads7950_probe, 513902c4b24SDavid Lechner .remove = ti_ads7950_remove, 514902c4b24SDavid Lechner .id_table = ti_ads7950_id, 515902c4b24SDavid Lechner }; 516902c4b24SDavid Lechner module_spi_driver(ti_ads7950_driver); 517902c4b24SDavid Lechner 518902c4b24SDavid Lechner MODULE_AUTHOR("David Lechner <david@lechnology.com>"); 519902c4b24SDavid Lechner MODULE_DESCRIPTION("TI TI_ADS7950 ADC"); 520902c4b24SDavid Lechner MODULE_LICENSE("GPL v2"); 521