1d935edddSTomislav Denis // SPDX-License-Identifier: GPL-2.0 2d935edddSTomislav Denis /* 3d935edddSTomislav Denis * Texas Instruments ADS131E0x 4-, 6- and 8-Channel ADCs 4d935edddSTomislav Denis * 5d935edddSTomislav Denis * Copyright (c) 2020 AVL DiTEST GmbH 6d935edddSTomislav Denis * Tomislav Denis <tomislav.denis@avl.com> 7d935edddSTomislav Denis * 8d935edddSTomislav Denis * Datasheet: https://www.ti.com/lit/ds/symlink/ads131e08.pdf 9d935edddSTomislav Denis */ 10d935edddSTomislav Denis 11d935edddSTomislav Denis #include <linux/bitfield.h> 12d935edddSTomislav Denis #include <linux/clk.h> 13d935edddSTomislav Denis #include <linux/delay.h> 14d935edddSTomislav Denis #include <linux/module.h> 15d935edddSTomislav Denis 16d935edddSTomislav Denis #include <linux/iio/buffer.h> 17d935edddSTomislav Denis #include <linux/iio/iio.h> 18d935edddSTomislav Denis #include <linux/iio/sysfs.h> 19d935edddSTomislav Denis #include <linux/iio/trigger.h> 20d935edddSTomislav Denis #include <linux/iio/trigger_consumer.h> 21d935edddSTomislav Denis #include <linux/iio/triggered_buffer.h> 22d935edddSTomislav Denis 23d935edddSTomislav Denis #include <linux/regulator/consumer.h> 24d935edddSTomislav Denis #include <linux/spi/spi.h> 25d935edddSTomislav Denis 26d935edddSTomislav Denis #include <asm/unaligned.h> 27d935edddSTomislav Denis 28d935edddSTomislav Denis /* Commands */ 29d935edddSTomislav Denis #define ADS131E08_CMD_RESET 0x06 30d935edddSTomislav Denis #define ADS131E08_CMD_START 0x08 31d935edddSTomislav Denis #define ADS131E08_CMD_STOP 0x0A 32d935edddSTomislav Denis #define ADS131E08_CMD_OFFSETCAL 0x1A 33d935edddSTomislav Denis #define ADS131E08_CMD_SDATAC 0x11 34d935edddSTomislav Denis #define ADS131E08_CMD_RDATA 0x12 35d935edddSTomislav Denis #define ADS131E08_CMD_RREG(r) (BIT(5) | (r & GENMASK(4, 0))) 36d935edddSTomislav Denis #define ADS131E08_CMD_WREG(r) (BIT(6) | (r & GENMASK(4, 0))) 37d935edddSTomislav Denis 38d935edddSTomislav Denis /* Registers */ 39d935edddSTomislav Denis #define ADS131E08_ADR_CFG1R 0x01 40d935edddSTomislav Denis #define ADS131E08_ADR_CFG3R 0x03 41d935edddSTomislav Denis #define ADS131E08_ADR_CH0R 0x05 42d935edddSTomislav Denis 43d935edddSTomislav Denis /* Configuration register 1 */ 44d935edddSTomislav Denis #define ADS131E08_CFG1R_DR_MASK GENMASK(2, 0) 45d935edddSTomislav Denis 46d935edddSTomislav Denis /* Configuration register 3 */ 47d935edddSTomislav Denis #define ADS131E08_CFG3R_PDB_REFBUF_MASK BIT(7) 48d935edddSTomislav Denis #define ADS131E08_CFG3R_VREF_4V_MASK BIT(5) 49d935edddSTomislav Denis 50d935edddSTomislav Denis /* Channel settings register */ 51d935edddSTomislav Denis #define ADS131E08_CHR_GAIN_MASK GENMASK(6, 4) 52d935edddSTomislav Denis #define ADS131E08_CHR_MUX_MASK GENMASK(2, 0) 53d935edddSTomislav Denis #define ADS131E08_CHR_PWD_MASK BIT(7) 54d935edddSTomislav Denis 55d935edddSTomislav Denis /* ADC misc */ 56d935edddSTomislav Denis #define ADS131E08_DEFAULT_DATA_RATE 1 57d935edddSTomislav Denis #define ADS131E08_DEFAULT_PGA_GAIN 1 58d935edddSTomislav Denis #define ADS131E08_DEFAULT_MUX 0 59d935edddSTomislav Denis 60d935edddSTomislav Denis #define ADS131E08_VREF_2V4_mV 2400 61d935edddSTomislav Denis #define ADS131E08_VREF_4V_mV 4000 62d935edddSTomislav Denis 63d935edddSTomislav Denis #define ADS131E08_WAIT_RESET_CYCLES 18 64d935edddSTomislav Denis #define ADS131E08_WAIT_SDECODE_CYCLES 4 65d935edddSTomislav Denis #define ADS131E08_WAIT_OFFSETCAL_MS 153 66d935edddSTomislav Denis #define ADS131E08_MAX_SETTLING_TIME_MS 6 67d935edddSTomislav Denis 68d935edddSTomislav Denis #define ADS131E08_NUM_STATUS_BYTES 3 69d935edddSTomislav Denis #define ADS131E08_NUM_DATA_BYTES_MAX 24 70d935edddSTomislav Denis #define ADS131E08_NUM_DATA_BYTES(dr) (((dr) >= 32) ? 2 : 3) 71d935edddSTomislav Denis #define ADS131E08_NUM_DATA_BITS(dr) (ADS131E08_NUM_DATA_BYTES(dr) * 8) 72d935edddSTomislav Denis #define ADS131E08_NUM_STORAGE_BYTES 4 73d935edddSTomislav Denis 74d935edddSTomislav Denis enum ads131e08_ids { 75d935edddSTomislav Denis ads131e04, 76d935edddSTomislav Denis ads131e06, 77d935edddSTomislav Denis ads131e08, 78d935edddSTomislav Denis }; 79d935edddSTomislav Denis 80d935edddSTomislav Denis struct ads131e08_info { 81d935edddSTomislav Denis unsigned int max_channels; 82d935edddSTomislav Denis const char *name; 83d935edddSTomislav Denis }; 84d935edddSTomislav Denis 85d935edddSTomislav Denis struct ads131e08_channel_config { 86d935edddSTomislav Denis unsigned int pga_gain; 87d935edddSTomislav Denis unsigned int mux; 88d935edddSTomislav Denis }; 89d935edddSTomislav Denis 90d935edddSTomislav Denis struct ads131e08_state { 91d935edddSTomislav Denis const struct ads131e08_info *info; 92d935edddSTomislav Denis struct spi_device *spi; 93d935edddSTomislav Denis struct iio_trigger *trig; 94d935edddSTomislav Denis struct clk *adc_clk; 95d935edddSTomislav Denis struct regulator *vref_reg; 96d935edddSTomislav Denis struct ads131e08_channel_config *channel_config; 97d935edddSTomislav Denis unsigned int data_rate; 98d935edddSTomislav Denis unsigned int vref_mv; 99d935edddSTomislav Denis unsigned int sdecode_delay_us; 100d935edddSTomislav Denis unsigned int reset_delay_us; 101d935edddSTomislav Denis unsigned int readback_len; 102d935edddSTomislav Denis struct completion completion; 103d935edddSTomislav Denis struct { 104d935edddSTomislav Denis u8 data[ADS131E08_NUM_DATA_BYTES_MAX]; 105d935edddSTomislav Denis s64 ts __aligned(8); 106d935edddSTomislav Denis } tmp_buf; 107d935edddSTomislav Denis 108d935edddSTomislav Denis u8 tx_buf[3] ____cacheline_aligned; 109d935edddSTomislav Denis /* 110d935edddSTomislav Denis * Add extra one padding byte to be able to access the last channel 111d935edddSTomislav Denis * value using u32 pointer 112d935edddSTomislav Denis */ 113d935edddSTomislav Denis u8 rx_buf[ADS131E08_NUM_STATUS_BYTES + 114d935edddSTomislav Denis ADS131E08_NUM_DATA_BYTES_MAX + 1]; 115d935edddSTomislav Denis }; 116d935edddSTomislav Denis 117d935edddSTomislav Denis static const struct ads131e08_info ads131e08_info_tbl[] = { 118d935edddSTomislav Denis [ads131e04] = { 119d935edddSTomislav Denis .max_channels = 4, 120d935edddSTomislav Denis .name = "ads131e04", 121d935edddSTomislav Denis }, 122d935edddSTomislav Denis [ads131e06] = { 123d935edddSTomislav Denis .max_channels = 6, 124d935edddSTomislav Denis .name = "ads131e06", 125d935edddSTomislav Denis }, 126d935edddSTomislav Denis [ads131e08] = { 127d935edddSTomislav Denis .max_channels = 8, 128d935edddSTomislav Denis .name = "ads131e08", 129d935edddSTomislav Denis }, 130d935edddSTomislav Denis }; 131d935edddSTomislav Denis 132d935edddSTomislav Denis struct ads131e08_data_rate_desc { 133d935edddSTomislav Denis unsigned int rate; /* data rate in kSPS */ 134d935edddSTomislav Denis u8 reg; /* reg value */ 135d935edddSTomislav Denis }; 136d935edddSTomislav Denis 137d935edddSTomislav Denis static const struct ads131e08_data_rate_desc ads131e08_data_rate_tbl[] = { 138d935edddSTomislav Denis { .rate = 64, .reg = 0x00 }, 139d935edddSTomislav Denis { .rate = 32, .reg = 0x01 }, 140d935edddSTomislav Denis { .rate = 16, .reg = 0x02 }, 141d935edddSTomislav Denis { .rate = 8, .reg = 0x03 }, 142d935edddSTomislav Denis { .rate = 4, .reg = 0x04 }, 143d935edddSTomislav Denis { .rate = 2, .reg = 0x05 }, 144d935edddSTomislav Denis { .rate = 1, .reg = 0x06 }, 145d935edddSTomislav Denis }; 146d935edddSTomislav Denis 147d935edddSTomislav Denis struct ads131e08_pga_gain_desc { 148d935edddSTomislav Denis unsigned int gain; /* PGA gain value */ 149d935edddSTomislav Denis u8 reg; /* field value */ 150d935edddSTomislav Denis }; 151d935edddSTomislav Denis 152d935edddSTomislav Denis static const struct ads131e08_pga_gain_desc ads131e08_pga_gain_tbl[] = { 153d935edddSTomislav Denis { .gain = 1, .reg = 0x01 }, 154d935edddSTomislav Denis { .gain = 2, .reg = 0x02 }, 155d935edddSTomislav Denis { .gain = 4, .reg = 0x04 }, 156d935edddSTomislav Denis { .gain = 8, .reg = 0x05 }, 157d935edddSTomislav Denis { .gain = 12, .reg = 0x06 }, 158d935edddSTomislav Denis }; 159d935edddSTomislav Denis 160d935edddSTomislav Denis static const u8 ads131e08_valid_channel_mux_values[] = { 0, 1, 3, 4 }; 161d935edddSTomislav Denis 162d935edddSTomislav Denis static int ads131e08_exec_cmd(struct ads131e08_state *st, u8 cmd) 163d935edddSTomislav Denis { 164d935edddSTomislav Denis int ret; 165d935edddSTomislav Denis 166d935edddSTomislav Denis ret = spi_write_then_read(st->spi, &cmd, 1, NULL, 0); 167d935edddSTomislav Denis if (ret) 168d935edddSTomislav Denis dev_err(&st->spi->dev, "Exec cmd(%02x) failed\n", cmd); 169d935edddSTomislav Denis 170d935edddSTomislav Denis return ret; 171d935edddSTomislav Denis } 172d935edddSTomislav Denis 173d935edddSTomislav Denis static int ads131e08_read_reg(struct ads131e08_state *st, u8 reg) 174d935edddSTomislav Denis { 175d935edddSTomislav Denis int ret; 176d935edddSTomislav Denis struct spi_transfer transfer[] = { 177d935edddSTomislav Denis { 178d935edddSTomislav Denis .tx_buf = &st->tx_buf, 179d935edddSTomislav Denis .len = 2, 1804a0225c3SLinus Torvalds .delay = { 1814a0225c3SLinus Torvalds .value = st->sdecode_delay_us, 1824a0225c3SLinus Torvalds .unit = SPI_DELAY_UNIT_USECS, 1834a0225c3SLinus Torvalds }, 184d935edddSTomislav Denis }, { 185d935edddSTomislav Denis .rx_buf = &st->rx_buf, 186d935edddSTomislav Denis .len = 1, 187d935edddSTomislav Denis }, 188d935edddSTomislav Denis }; 189d935edddSTomislav Denis 190d935edddSTomislav Denis st->tx_buf[0] = ADS131E08_CMD_RREG(reg); 191d935edddSTomislav Denis st->tx_buf[1] = 0; 192d935edddSTomislav Denis 193d935edddSTomislav Denis ret = spi_sync_transfer(st->spi, transfer, ARRAY_SIZE(transfer)); 194d935edddSTomislav Denis if (ret) { 195d935edddSTomislav Denis dev_err(&st->spi->dev, "Read register failed\n"); 196d935edddSTomislav Denis return ret; 197d935edddSTomislav Denis } 198d935edddSTomislav Denis 199d935edddSTomislav Denis return st->rx_buf[0]; 200d935edddSTomislav Denis } 201d935edddSTomislav Denis 202d935edddSTomislav Denis static int ads131e08_write_reg(struct ads131e08_state *st, u8 reg, u8 value) 203d935edddSTomislav Denis { 204d935edddSTomislav Denis int ret; 205d935edddSTomislav Denis struct spi_transfer transfer[] = { 206d935edddSTomislav Denis { 207d935edddSTomislav Denis .tx_buf = &st->tx_buf, 208d935edddSTomislav Denis .len = 3, 2094a0225c3SLinus Torvalds .delay = { 2104a0225c3SLinus Torvalds .value = st->sdecode_delay_us, 2114a0225c3SLinus Torvalds .unit = SPI_DELAY_UNIT_USECS, 2124a0225c3SLinus Torvalds }, 213d935edddSTomislav Denis } 214d935edddSTomislav Denis }; 215d935edddSTomislav Denis 216d935edddSTomislav Denis st->tx_buf[0] = ADS131E08_CMD_WREG(reg); 217d935edddSTomislav Denis st->tx_buf[1] = 0; 218d935edddSTomislav Denis st->tx_buf[2] = value; 219d935edddSTomislav Denis 220d935edddSTomislav Denis ret = spi_sync_transfer(st->spi, transfer, ARRAY_SIZE(transfer)); 221d935edddSTomislav Denis if (ret) 222d935edddSTomislav Denis dev_err(&st->spi->dev, "Write register failed\n"); 223d935edddSTomislav Denis 224d935edddSTomislav Denis return ret; 225d935edddSTomislav Denis } 226d935edddSTomislav Denis 227d935edddSTomislav Denis static int ads131e08_read_data(struct ads131e08_state *st, int rx_len) 228d935edddSTomislav Denis { 229d935edddSTomislav Denis int ret; 230d935edddSTomislav Denis struct spi_transfer transfer[] = { 231d935edddSTomislav Denis { 232d935edddSTomislav Denis .tx_buf = &st->tx_buf, 233d935edddSTomislav Denis .len = 1, 234d935edddSTomislav Denis }, { 235d935edddSTomislav Denis .rx_buf = &st->rx_buf, 236d935edddSTomislav Denis .len = rx_len, 237d935edddSTomislav Denis }, 238d935edddSTomislav Denis }; 239d935edddSTomislav Denis 240d935edddSTomislav Denis st->tx_buf[0] = ADS131E08_CMD_RDATA; 241d935edddSTomislav Denis 242d935edddSTomislav Denis ret = spi_sync_transfer(st->spi, transfer, ARRAY_SIZE(transfer)); 243d935edddSTomislav Denis if (ret) 244d935edddSTomislav Denis dev_err(&st->spi->dev, "Read data failed\n"); 245d935edddSTomislav Denis 246d935edddSTomislav Denis return ret; 247d935edddSTomislav Denis } 248d935edddSTomislav Denis 249d935edddSTomislav Denis static int ads131e08_set_data_rate(struct ads131e08_state *st, int data_rate) 250d935edddSTomislav Denis { 251d935edddSTomislav Denis int i, reg, ret; 252d935edddSTomislav Denis 253d935edddSTomislav Denis for (i = 0; i < ARRAY_SIZE(ads131e08_data_rate_tbl); i++) { 254d935edddSTomislav Denis if (ads131e08_data_rate_tbl[i].rate == data_rate) 255d935edddSTomislav Denis break; 256d935edddSTomislav Denis } 257d935edddSTomislav Denis 258d935edddSTomislav Denis if (i == ARRAY_SIZE(ads131e08_data_rate_tbl)) { 259d935edddSTomislav Denis dev_err(&st->spi->dev, "invalid data rate value\n"); 260d935edddSTomislav Denis return -EINVAL; 261d935edddSTomislav Denis } 262d935edddSTomislav Denis 263d935edddSTomislav Denis reg = ads131e08_read_reg(st, ADS131E08_ADR_CFG1R); 264d935edddSTomislav Denis if (reg < 0) 265d935edddSTomislav Denis return reg; 266d935edddSTomislav Denis 267d935edddSTomislav Denis reg &= ~ADS131E08_CFG1R_DR_MASK; 268d935edddSTomislav Denis reg |= FIELD_PREP(ADS131E08_CFG1R_DR_MASK, 269d935edddSTomislav Denis ads131e08_data_rate_tbl[i].reg); 270d935edddSTomislav Denis 271d935edddSTomislav Denis ret = ads131e08_write_reg(st, ADS131E08_ADR_CFG1R, reg); 272d935edddSTomislav Denis if (ret) 273d935edddSTomislav Denis return ret; 274d935edddSTomislav Denis 275d935edddSTomislav Denis st->data_rate = data_rate; 276d935edddSTomislav Denis st->readback_len = ADS131E08_NUM_STATUS_BYTES + 277d935edddSTomislav Denis ADS131E08_NUM_DATA_BYTES(st->data_rate) * 278d935edddSTomislav Denis st->info->max_channels; 279d935edddSTomislav Denis 280d935edddSTomislav Denis return 0; 281d935edddSTomislav Denis } 282d935edddSTomislav Denis 283d935edddSTomislav Denis static int ads131e08_pga_gain_to_field_value(struct ads131e08_state *st, 284d935edddSTomislav Denis unsigned int pga_gain) 285d935edddSTomislav Denis { 286d935edddSTomislav Denis int i; 287d935edddSTomislav Denis 288d935edddSTomislav Denis for (i = 0; i < ARRAY_SIZE(ads131e08_pga_gain_tbl); i++) { 289d935edddSTomislav Denis if (ads131e08_pga_gain_tbl[i].gain == pga_gain) 290d935edddSTomislav Denis break; 291d935edddSTomislav Denis } 292d935edddSTomislav Denis 293d935edddSTomislav Denis if (i == ARRAY_SIZE(ads131e08_pga_gain_tbl)) { 294d935edddSTomislav Denis dev_err(&st->spi->dev, "invalid PGA gain value\n"); 295d935edddSTomislav Denis return -EINVAL; 296d935edddSTomislav Denis } 297d935edddSTomislav Denis 298d935edddSTomislav Denis return ads131e08_pga_gain_tbl[i].reg; 299d935edddSTomislav Denis } 300d935edddSTomislav Denis 301d935edddSTomislav Denis static int ads131e08_set_pga_gain(struct ads131e08_state *st, 302d935edddSTomislav Denis unsigned int channel, unsigned int pga_gain) 303d935edddSTomislav Denis { 304d935edddSTomislav Denis int field_value, reg; 305d935edddSTomislav Denis 306d935edddSTomislav Denis field_value = ads131e08_pga_gain_to_field_value(st, pga_gain); 307d935edddSTomislav Denis if (field_value < 0) 308d935edddSTomislav Denis return field_value; 309d935edddSTomislav Denis 310d935edddSTomislav Denis reg = ads131e08_read_reg(st, ADS131E08_ADR_CH0R + channel); 311d935edddSTomislav Denis if (reg < 0) 312d935edddSTomislav Denis return reg; 313d935edddSTomislav Denis 314d935edddSTomislav Denis reg &= ~ADS131E08_CHR_GAIN_MASK; 315d935edddSTomislav Denis reg |= FIELD_PREP(ADS131E08_CHR_GAIN_MASK, field_value); 316d935edddSTomislav Denis 317d935edddSTomislav Denis return ads131e08_write_reg(st, ADS131E08_ADR_CH0R + channel, reg); 318d935edddSTomislav Denis } 319d935edddSTomislav Denis 320d935edddSTomislav Denis static int ads131e08_validate_channel_mux(struct ads131e08_state *st, 321d935edddSTomislav Denis unsigned int mux) 322d935edddSTomislav Denis { 323d935edddSTomislav Denis int i; 324d935edddSTomislav Denis 325d935edddSTomislav Denis for (i = 0; i < ARRAY_SIZE(ads131e08_valid_channel_mux_values); i++) { 326d935edddSTomislav Denis if (ads131e08_valid_channel_mux_values[i] == mux) 327d935edddSTomislav Denis break; 328d935edddSTomislav Denis } 329d935edddSTomislav Denis 330d935edddSTomislav Denis if (i == ARRAY_SIZE(ads131e08_valid_channel_mux_values)) { 331d935edddSTomislav Denis dev_err(&st->spi->dev, "invalid channel mux value\n"); 332d935edddSTomislav Denis return -EINVAL; 333d935edddSTomislav Denis } 334d935edddSTomislav Denis 335d935edddSTomislav Denis return 0; 336d935edddSTomislav Denis } 337d935edddSTomislav Denis 338d935edddSTomislav Denis static int ads131e08_set_channel_mux(struct ads131e08_state *st, 339d935edddSTomislav Denis unsigned int channel, unsigned int mux) 340d935edddSTomislav Denis { 341d935edddSTomislav Denis int reg; 342d935edddSTomislav Denis 343d935edddSTomislav Denis reg = ads131e08_read_reg(st, ADS131E08_ADR_CH0R + channel); 344d935edddSTomislav Denis if (reg < 0) 345d935edddSTomislav Denis return reg; 346d935edddSTomislav Denis 347d935edddSTomislav Denis reg &= ~ADS131E08_CHR_MUX_MASK; 348d935edddSTomislav Denis reg |= FIELD_PREP(ADS131E08_CHR_MUX_MASK, mux); 349d935edddSTomislav Denis 350d935edddSTomislav Denis return ads131e08_write_reg(st, ADS131E08_ADR_CH0R + channel, reg); 351d935edddSTomislav Denis } 352d935edddSTomislav Denis 353d935edddSTomislav Denis static int ads131e08_power_down_channel(struct ads131e08_state *st, 354d935edddSTomislav Denis unsigned int channel, bool value) 355d935edddSTomislav Denis { 356d935edddSTomislav Denis int reg; 357d935edddSTomislav Denis 358d935edddSTomislav Denis reg = ads131e08_read_reg(st, ADS131E08_ADR_CH0R + channel); 359d935edddSTomislav Denis if (reg < 0) 360d935edddSTomislav Denis return reg; 361d935edddSTomislav Denis 362d935edddSTomislav Denis reg &= ~ADS131E08_CHR_PWD_MASK; 363d935edddSTomislav Denis reg |= FIELD_PREP(ADS131E08_CHR_PWD_MASK, value); 364d935edddSTomislav Denis 365d935edddSTomislav Denis return ads131e08_write_reg(st, ADS131E08_ADR_CH0R + channel, reg); 366d935edddSTomislav Denis } 367d935edddSTomislav Denis 368d935edddSTomislav Denis static int ads131e08_config_reference_voltage(struct ads131e08_state *st) 369d935edddSTomislav Denis { 370d935edddSTomislav Denis int reg; 371d935edddSTomislav Denis 372d935edddSTomislav Denis reg = ads131e08_read_reg(st, ADS131E08_ADR_CFG3R); 373d935edddSTomislav Denis if (reg < 0) 374d935edddSTomislav Denis return reg; 375d935edddSTomislav Denis 376d935edddSTomislav Denis reg &= ~ADS131E08_CFG3R_PDB_REFBUF_MASK; 377d935edddSTomislav Denis if (!st->vref_reg) { 378d935edddSTomislav Denis reg |= FIELD_PREP(ADS131E08_CFG3R_PDB_REFBUF_MASK, 1); 379d935edddSTomislav Denis reg &= ~ADS131E08_CFG3R_VREF_4V_MASK; 380d935edddSTomislav Denis reg |= FIELD_PREP(ADS131E08_CFG3R_VREF_4V_MASK, 381d935edddSTomislav Denis st->vref_mv == ADS131E08_VREF_4V_mV); 382d935edddSTomislav Denis } 383d935edddSTomislav Denis 384d935edddSTomislav Denis return ads131e08_write_reg(st, ADS131E08_ADR_CFG3R, reg); 385d935edddSTomislav Denis } 386d935edddSTomislav Denis 387d935edddSTomislav Denis static int ads131e08_initial_config(struct iio_dev *indio_dev) 388d935edddSTomislav Denis { 389d935edddSTomislav Denis const struct iio_chan_spec *channel = indio_dev->channels; 390d935edddSTomislav Denis struct ads131e08_state *st = iio_priv(indio_dev); 391d935edddSTomislav Denis unsigned long active_channels = 0; 392d935edddSTomislav Denis int ret, i; 393d935edddSTomislav Denis 394d935edddSTomislav Denis ret = ads131e08_exec_cmd(st, ADS131E08_CMD_RESET); 395d935edddSTomislav Denis if (ret) 396d935edddSTomislav Denis return ret; 397d935edddSTomislav Denis 398d935edddSTomislav Denis udelay(st->reset_delay_us); 399d935edddSTomislav Denis 400d935edddSTomislav Denis /* Disable read data in continuous mode (enabled by default) */ 401d935edddSTomislav Denis ret = ads131e08_exec_cmd(st, ADS131E08_CMD_SDATAC); 402d935edddSTomislav Denis if (ret) 403d935edddSTomislav Denis return ret; 404d935edddSTomislav Denis 405d935edddSTomislav Denis ret = ads131e08_set_data_rate(st, ADS131E08_DEFAULT_DATA_RATE); 406d935edddSTomislav Denis if (ret) 407d935edddSTomislav Denis return ret; 408d935edddSTomislav Denis 409d935edddSTomislav Denis ret = ads131e08_config_reference_voltage(st); 410d935edddSTomislav Denis if (ret) 411d935edddSTomislav Denis return ret; 412d935edddSTomislav Denis 413d935edddSTomislav Denis for (i = 0; i < indio_dev->num_channels; i++) { 414d935edddSTomislav Denis ret = ads131e08_set_pga_gain(st, channel->channel, 415d935edddSTomislav Denis st->channel_config[i].pga_gain); 416d935edddSTomislav Denis if (ret) 417d935edddSTomislav Denis return ret; 418d935edddSTomislav Denis 419d935edddSTomislav Denis ret = ads131e08_set_channel_mux(st, channel->channel, 420d935edddSTomislav Denis st->channel_config[i].mux); 421d935edddSTomislav Denis if (ret) 422d935edddSTomislav Denis return ret; 423d935edddSTomislav Denis 424d935edddSTomislav Denis active_channels |= BIT(channel->channel); 425d935edddSTomislav Denis channel++; 426d935edddSTomislav Denis } 427d935edddSTomislav Denis 428d935edddSTomislav Denis /* Power down unused channels */ 429d935edddSTomislav Denis for_each_clear_bit(i, &active_channels, st->info->max_channels) { 430d935edddSTomislav Denis ret = ads131e08_power_down_channel(st, i, true); 431d935edddSTomislav Denis if (ret) 432d935edddSTomislav Denis return ret; 433d935edddSTomislav Denis } 434d935edddSTomislav Denis 435d935edddSTomislav Denis /* Request channel offset calibration */ 436d935edddSTomislav Denis ret = ads131e08_exec_cmd(st, ADS131E08_CMD_OFFSETCAL); 437d935edddSTomislav Denis if (ret) 438d935edddSTomislav Denis return ret; 439d935edddSTomislav Denis 440d935edddSTomislav Denis /* 441d935edddSTomislav Denis * Channel offset calibration is triggered with the first START 442d935edddSTomislav Denis * command. Since calibration takes more time than settling operation, 443d935edddSTomislav Denis * this causes timeout error when command START is sent first 444d935edddSTomislav Denis * time (e.g. first call of the ads131e08_read_direct method). 445d935edddSTomislav Denis * To avoid this problem offset calibration is triggered here. 446d935edddSTomislav Denis */ 447d935edddSTomislav Denis ret = ads131e08_exec_cmd(st, ADS131E08_CMD_START); 448d935edddSTomislav Denis if (ret) 449d935edddSTomislav Denis return ret; 450d935edddSTomislav Denis 451d935edddSTomislav Denis msleep(ADS131E08_WAIT_OFFSETCAL_MS); 452d935edddSTomislav Denis 453d935edddSTomislav Denis return ads131e08_exec_cmd(st, ADS131E08_CMD_STOP); 454d935edddSTomislav Denis } 455d935edddSTomislav Denis 456d935edddSTomislav Denis static int ads131e08_pool_data(struct ads131e08_state *st) 457d935edddSTomislav Denis { 458d935edddSTomislav Denis unsigned long timeout; 459d935edddSTomislav Denis int ret; 460d935edddSTomislav Denis 461d935edddSTomislav Denis reinit_completion(&st->completion); 462d935edddSTomislav Denis 463d935edddSTomislav Denis ret = ads131e08_exec_cmd(st, ADS131E08_CMD_START); 464d935edddSTomislav Denis if (ret) 465d935edddSTomislav Denis return ret; 466d935edddSTomislav Denis 467d935edddSTomislav Denis timeout = msecs_to_jiffies(ADS131E08_MAX_SETTLING_TIME_MS); 468d935edddSTomislav Denis ret = wait_for_completion_timeout(&st->completion, timeout); 469d935edddSTomislav Denis if (!ret) 470d935edddSTomislav Denis return -ETIMEDOUT; 471d935edddSTomislav Denis 472d935edddSTomislav Denis ret = ads131e08_read_data(st, st->readback_len); 473d935edddSTomislav Denis if (ret) 474d935edddSTomislav Denis return ret; 475d935edddSTomislav Denis 476d935edddSTomislav Denis return ads131e08_exec_cmd(st, ADS131E08_CMD_STOP); 477d935edddSTomislav Denis } 478d935edddSTomislav Denis 479d935edddSTomislav Denis static int ads131e08_read_direct(struct iio_dev *indio_dev, 480d935edddSTomislav Denis struct iio_chan_spec const *channel, int *value) 481d935edddSTomislav Denis { 482d935edddSTomislav Denis struct ads131e08_state *st = iio_priv(indio_dev); 483d935edddSTomislav Denis u8 num_bits, *src; 484d935edddSTomislav Denis int ret; 485d935edddSTomislav Denis 486d935edddSTomislav Denis ret = ads131e08_pool_data(st); 487d935edddSTomislav Denis if (ret) 488d935edddSTomislav Denis return ret; 489d935edddSTomislav Denis 490d935edddSTomislav Denis src = st->rx_buf + ADS131E08_NUM_STATUS_BYTES + 491d935edddSTomislav Denis channel->channel * ADS131E08_NUM_DATA_BYTES(st->data_rate); 492d935edddSTomislav Denis 493d935edddSTomislav Denis num_bits = ADS131E08_NUM_DATA_BITS(st->data_rate); 494d935edddSTomislav Denis *value = sign_extend32(get_unaligned_be32(src) >> (32 - num_bits), num_bits - 1); 495d935edddSTomislav Denis 496d935edddSTomislav Denis return 0; 497d935edddSTomislav Denis } 498d935edddSTomislav Denis 499d935edddSTomislav Denis static int ads131e08_read_raw(struct iio_dev *indio_dev, 500d935edddSTomislav Denis struct iio_chan_spec const *channel, int *value, 501d935edddSTomislav Denis int *value2, long mask) 502d935edddSTomislav Denis { 503d935edddSTomislav Denis struct ads131e08_state *st = iio_priv(indio_dev); 504d935edddSTomislav Denis int ret; 505d935edddSTomislav Denis 506d935edddSTomislav Denis switch (mask) { 507d935edddSTomislav Denis case IIO_CHAN_INFO_RAW: 508d935edddSTomislav Denis ret = iio_device_claim_direct_mode(indio_dev); 509d935edddSTomislav Denis if (ret) 510d935edddSTomislav Denis return ret; 511d935edddSTomislav Denis 512d935edddSTomislav Denis ret = ads131e08_read_direct(indio_dev, channel, value); 513d935edddSTomislav Denis iio_device_release_direct_mode(indio_dev); 514d935edddSTomislav Denis if (ret) 515d935edddSTomislav Denis return ret; 516d935edddSTomislav Denis 517d935edddSTomislav Denis return IIO_VAL_INT; 518d935edddSTomislav Denis 519d935edddSTomislav Denis case IIO_CHAN_INFO_SCALE: 520d935edddSTomislav Denis if (st->vref_reg) { 521d935edddSTomislav Denis ret = regulator_get_voltage(st->vref_reg); 522d935edddSTomislav Denis if (ret < 0) 523d935edddSTomislav Denis return ret; 524d935edddSTomislav Denis 525d935edddSTomislav Denis *value = ret / 1000; 526d935edddSTomislav Denis } else { 527d935edddSTomislav Denis *value = st->vref_mv; 528d935edddSTomislav Denis } 529d935edddSTomislav Denis 530d935edddSTomislav Denis *value /= st->channel_config[channel->address].pga_gain; 531d935edddSTomislav Denis *value2 = ADS131E08_NUM_DATA_BITS(st->data_rate) - 1; 532d935edddSTomislav Denis 533d935edddSTomislav Denis return IIO_VAL_FRACTIONAL_LOG2; 534d935edddSTomislav Denis 535d935edddSTomislav Denis case IIO_CHAN_INFO_SAMP_FREQ: 536d935edddSTomislav Denis *value = st->data_rate; 537d935edddSTomislav Denis 538d935edddSTomislav Denis return IIO_VAL_INT; 539d935edddSTomislav Denis 540d935edddSTomislav Denis default: 541d935edddSTomislav Denis return -EINVAL; 542d935edddSTomislav Denis } 543d935edddSTomislav Denis } 544d935edddSTomislav Denis 545d935edddSTomislav Denis static int ads131e08_write_raw(struct iio_dev *indio_dev, 546d935edddSTomislav Denis struct iio_chan_spec const *channel, int value, 547d935edddSTomislav Denis int value2, long mask) 548d935edddSTomislav Denis { 549d935edddSTomislav Denis struct ads131e08_state *st = iio_priv(indio_dev); 550d935edddSTomislav Denis int ret; 551d935edddSTomislav Denis 552d935edddSTomislav Denis switch (mask) { 553d935edddSTomislav Denis case IIO_CHAN_INFO_SAMP_FREQ: 554d935edddSTomislav Denis ret = iio_device_claim_direct_mode(indio_dev); 555d935edddSTomislav Denis if (ret) 556d935edddSTomislav Denis return ret; 557d935edddSTomislav Denis 558d935edddSTomislav Denis ret = ads131e08_set_data_rate(st, value); 559d935edddSTomislav Denis iio_device_release_direct_mode(indio_dev); 560d935edddSTomislav Denis return ret; 561d935edddSTomislav Denis 562d935edddSTomislav Denis default: 563d935edddSTomislav Denis return -EINVAL; 564d935edddSTomislav Denis } 565d935edddSTomislav Denis } 566d935edddSTomislav Denis 567d935edddSTomislav Denis static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("1 2 4 8 16 32 64"); 568d935edddSTomislav Denis 569d935edddSTomislav Denis static struct attribute *ads131e08_attributes[] = { 570d935edddSTomislav Denis &iio_const_attr_sampling_frequency_available.dev_attr.attr, 571d935edddSTomislav Denis NULL 572d935edddSTomislav Denis }; 573d935edddSTomislav Denis 574d935edddSTomislav Denis static const struct attribute_group ads131e08_attribute_group = { 575d935edddSTomislav Denis .attrs = ads131e08_attributes, 576d935edddSTomislav Denis }; 577d935edddSTomislav Denis 578d935edddSTomislav Denis static int ads131e08_debugfs_reg_access(struct iio_dev *indio_dev, 579d935edddSTomislav Denis unsigned int reg, unsigned int writeval, unsigned int *readval) 580d935edddSTomislav Denis { 581d935edddSTomislav Denis struct ads131e08_state *st = iio_priv(indio_dev); 582d935edddSTomislav Denis 583d935edddSTomislav Denis if (readval) { 584d935edddSTomislav Denis int ret = ads131e08_read_reg(st, reg); 585d935edddSTomislav Denis *readval = ret; 586d935edddSTomislav Denis return ret; 587d935edddSTomislav Denis } 588d935edddSTomislav Denis 589d935edddSTomislav Denis return ads131e08_write_reg(st, reg, writeval); 590d935edddSTomislav Denis } 591d935edddSTomislav Denis 592d935edddSTomislav Denis static const struct iio_info ads131e08_iio_info = { 593d935edddSTomislav Denis .read_raw = ads131e08_read_raw, 594d935edddSTomislav Denis .write_raw = ads131e08_write_raw, 595d935edddSTomislav Denis .attrs = &ads131e08_attribute_group, 596d935edddSTomislav Denis .debugfs_reg_access = &ads131e08_debugfs_reg_access, 597d935edddSTomislav Denis }; 598d935edddSTomislav Denis 599d935edddSTomislav Denis static int ads131e08_set_trigger_state(struct iio_trigger *trig, bool state) 600d935edddSTomislav Denis { 601d935edddSTomislav Denis struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); 602d935edddSTomislav Denis struct ads131e08_state *st = iio_priv(indio_dev); 603d935edddSTomislav Denis u8 cmd = state ? ADS131E08_CMD_START : ADS131E08_CMD_STOP; 604d935edddSTomislav Denis 605d935edddSTomislav Denis return ads131e08_exec_cmd(st, cmd); 606d935edddSTomislav Denis } 607d935edddSTomislav Denis 608d935edddSTomislav Denis static const struct iio_trigger_ops ads131e08_trigger_ops = { 609d935edddSTomislav Denis .set_trigger_state = &ads131e08_set_trigger_state, 610d935edddSTomislav Denis .validate_device = &iio_trigger_validate_own_device, 611d935edddSTomislav Denis }; 612d935edddSTomislav Denis 613d935edddSTomislav Denis static irqreturn_t ads131e08_trigger_handler(int irq, void *private) 614d935edddSTomislav Denis { 615d935edddSTomislav Denis struct iio_poll_func *pf = private; 616d935edddSTomislav Denis struct iio_dev *indio_dev = pf->indio_dev; 617d935edddSTomislav Denis struct ads131e08_state *st = iio_priv(indio_dev); 618d935edddSTomislav Denis unsigned int chn, i = 0; 619d935edddSTomislav Denis u8 *src, *dest; 620d935edddSTomislav Denis int ret; 621d935edddSTomislav Denis 622d935edddSTomislav Denis /* 623d935edddSTomislav Denis * The number of data bits per channel depends on the data rate. 624d935edddSTomislav Denis * For 32 and 64 ksps data rates, number of data bits per channel 625d935edddSTomislav Denis * is 16. This case is not compliant with used (fixed) scan element 626d935edddSTomislav Denis * type (be:s24/32>>8). So we use a little tweak to pack properly 627d935edddSTomislav Denis * 16 bits of data into the buffer. 628d935edddSTomislav Denis */ 629d935edddSTomislav Denis unsigned int num_bytes = ADS131E08_NUM_DATA_BYTES(st->data_rate); 630d935edddSTomislav Denis u8 tweek_offset = num_bytes == 2 ? 1 : 0; 631d935edddSTomislav Denis 632d935edddSTomislav Denis if (iio_trigger_using_own(indio_dev)) 633d935edddSTomislav Denis ret = ads131e08_read_data(st, st->readback_len); 634d935edddSTomislav Denis else 635d935edddSTomislav Denis ret = ads131e08_pool_data(st); 636d935edddSTomislav Denis 637d935edddSTomislav Denis if (ret) 638d935edddSTomislav Denis goto out; 639d935edddSTomislav Denis 640d935edddSTomislav Denis for_each_set_bit(chn, indio_dev->active_scan_mask, indio_dev->masklength) { 641d935edddSTomislav Denis src = st->rx_buf + ADS131E08_NUM_STATUS_BYTES + chn * num_bytes; 642d935edddSTomislav Denis dest = st->tmp_buf.data + i * ADS131E08_NUM_STORAGE_BYTES; 643d935edddSTomislav Denis 644d935edddSTomislav Denis /* 645d935edddSTomislav Denis * Tweek offset is 0: 646d935edddSTomislav Denis * +---+---+---+---+ 647d935edddSTomislav Denis * |D0 |D1 |D2 | X | (3 data bytes) 648d935edddSTomislav Denis * +---+---+---+---+ 649d935edddSTomislav Denis * a+0 a+1 a+2 a+3 650d935edddSTomislav Denis * 651d935edddSTomislav Denis * Tweek offset is 1: 652d935edddSTomislav Denis * +---+---+---+---+ 653d935edddSTomislav Denis * |P0 |D0 |D1 | X | (one padding byte and 2 data bytes) 654d935edddSTomislav Denis * +---+---+---+---+ 655d935edddSTomislav Denis * a+0 a+1 a+2 a+3 656d935edddSTomislav Denis */ 657d935edddSTomislav Denis memcpy(dest + tweek_offset, src, num_bytes); 658d935edddSTomislav Denis 659d935edddSTomislav Denis /* 660d935edddSTomislav Denis * Data conversion from 16 bits of data to 24 bits of data 661d935edddSTomislav Denis * is done by sign extension (properly filling padding byte). 662d935edddSTomislav Denis */ 663d935edddSTomislav Denis if (tweek_offset) 664d935edddSTomislav Denis *dest = *src & BIT(7) ? 0xff : 0x00; 665d935edddSTomislav Denis 666d935edddSTomislav Denis i++; 667d935edddSTomislav Denis } 668d935edddSTomislav Denis 669d935edddSTomislav Denis iio_push_to_buffers_with_timestamp(indio_dev, st->tmp_buf.data, 670d935edddSTomislav Denis iio_get_time_ns(indio_dev)); 671d935edddSTomislav Denis 672d935edddSTomislav Denis out: 673d935edddSTomislav Denis iio_trigger_notify_done(indio_dev->trig); 674d935edddSTomislav Denis 675d935edddSTomislav Denis return IRQ_HANDLED; 676d935edddSTomislav Denis } 677d935edddSTomislav Denis 678d935edddSTomislav Denis static irqreturn_t ads131e08_interrupt(int irq, void *private) 679d935edddSTomislav Denis { 680d935edddSTomislav Denis struct iio_dev *indio_dev = private; 681d935edddSTomislav Denis struct ads131e08_state *st = iio_priv(indio_dev); 682d935edddSTomislav Denis 683d935edddSTomislav Denis if (iio_buffer_enabled(indio_dev) && iio_trigger_using_own(indio_dev)) 684d935edddSTomislav Denis iio_trigger_poll(st->trig); 685d935edddSTomislav Denis else 686d935edddSTomislav Denis complete(&st->completion); 687d935edddSTomislav Denis 688d935edddSTomislav Denis return IRQ_HANDLED; 689d935edddSTomislav Denis } 690d935edddSTomislav Denis 691d935edddSTomislav Denis static int ads131e08_alloc_channels(struct iio_dev *indio_dev) 692d935edddSTomislav Denis { 693d935edddSTomislav Denis struct ads131e08_state *st = iio_priv(indio_dev); 694d935edddSTomislav Denis struct ads131e08_channel_config *channel_config; 695d935edddSTomislav Denis struct device *dev = &st->spi->dev; 696d935edddSTomislav Denis struct iio_chan_spec *channels; 697d935edddSTomislav Denis struct fwnode_handle *node; 698d935edddSTomislav Denis unsigned int channel, tmp; 699d935edddSTomislav Denis int num_channels, i, ret; 700d935edddSTomislav Denis 701d935edddSTomislav Denis ret = device_property_read_u32(dev, "ti,vref-internal", &tmp); 702d935edddSTomislav Denis if (ret) 703d935edddSTomislav Denis tmp = 0; 704d935edddSTomislav Denis 705d935edddSTomislav Denis switch (tmp) { 706d935edddSTomislav Denis case 0: 707d935edddSTomislav Denis st->vref_mv = ADS131E08_VREF_2V4_mV; 708d935edddSTomislav Denis break; 709d935edddSTomislav Denis case 1: 710d935edddSTomislav Denis st->vref_mv = ADS131E08_VREF_4V_mV; 711d935edddSTomislav Denis break; 712d935edddSTomislav Denis default: 713d935edddSTomislav Denis dev_err(&st->spi->dev, "invalid internal voltage reference\n"); 714d935edddSTomislav Denis return -EINVAL; 715d935edddSTomislav Denis } 716d935edddSTomislav Denis 717d935edddSTomislav Denis num_channels = device_get_child_node_count(dev); 718d935edddSTomislav Denis if (num_channels == 0) { 719d935edddSTomislav Denis dev_err(&st->spi->dev, "no channel children\n"); 720d935edddSTomislav Denis return -ENODEV; 721d935edddSTomislav Denis } 722d935edddSTomislav Denis 723d935edddSTomislav Denis if (num_channels > st->info->max_channels) { 724d935edddSTomislav Denis dev_err(&st->spi->dev, "num of channel children out of range\n"); 725d935edddSTomislav Denis return -EINVAL; 726d935edddSTomislav Denis } 727d935edddSTomislav Denis 728d935edddSTomislav Denis channels = devm_kcalloc(&st->spi->dev, num_channels, 729d935edddSTomislav Denis sizeof(*channels), GFP_KERNEL); 730d935edddSTomislav Denis if (!channels) 731d935edddSTomislav Denis return -ENOMEM; 732d935edddSTomislav Denis 733d935edddSTomislav Denis channel_config = devm_kcalloc(&st->spi->dev, num_channels, 734d935edddSTomislav Denis sizeof(*channel_config), GFP_KERNEL); 735d935edddSTomislav Denis if (!channel_config) 736d935edddSTomislav Denis return -ENOMEM; 737d935edddSTomislav Denis 738d935edddSTomislav Denis i = 0; 739d935edddSTomislav Denis device_for_each_child_node(dev, node) { 740d935edddSTomislav Denis ret = fwnode_property_read_u32(node, "reg", &channel); 741d935edddSTomislav Denis if (ret) 742d935edddSTomislav Denis return ret; 743d935edddSTomislav Denis 744d935edddSTomislav Denis ret = fwnode_property_read_u32(node, "ti,gain", &tmp); 745d935edddSTomislav Denis if (ret) { 746d935edddSTomislav Denis channel_config[i].pga_gain = ADS131E08_DEFAULT_PGA_GAIN; 747d935edddSTomislav Denis } else { 748d935edddSTomislav Denis ret = ads131e08_pga_gain_to_field_value(st, tmp); 749d935edddSTomislav Denis if (ret < 0) 750d935edddSTomislav Denis return ret; 751d935edddSTomislav Denis 752d935edddSTomislav Denis channel_config[i].pga_gain = tmp; 753d935edddSTomislav Denis } 754d935edddSTomislav Denis 755d935edddSTomislav Denis ret = fwnode_property_read_u32(node, "ti,mux", &tmp); 756d935edddSTomislav Denis if (ret) { 757d935edddSTomislav Denis channel_config[i].mux = ADS131E08_DEFAULT_MUX; 758d935edddSTomislav Denis } else { 759d935edddSTomislav Denis ret = ads131e08_validate_channel_mux(st, tmp); 760d935edddSTomislav Denis if (ret) 761d935edddSTomislav Denis return ret; 762d935edddSTomislav Denis 763d935edddSTomislav Denis channel_config[i].mux = tmp; 764d935edddSTomislav Denis } 765d935edddSTomislav Denis 766d935edddSTomislav Denis channels[i].type = IIO_VOLTAGE; 767d935edddSTomislav Denis channels[i].indexed = 1; 768d935edddSTomislav Denis channels[i].channel = channel; 769d935edddSTomislav Denis channels[i].address = i; 770d935edddSTomislav Denis channels[i].info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 771d935edddSTomislav Denis BIT(IIO_CHAN_INFO_SCALE); 772d935edddSTomislav Denis channels[i].info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ); 773d935edddSTomislav Denis channels[i].scan_index = channel; 774d935edddSTomislav Denis channels[i].scan_type.sign = 's'; 775d935edddSTomislav Denis channels[i].scan_type.realbits = 24; 776d935edddSTomislav Denis channels[i].scan_type.storagebits = 32; 777d935edddSTomislav Denis channels[i].scan_type.shift = 8; 778d935edddSTomislav Denis channels[i].scan_type.endianness = IIO_BE; 779d935edddSTomislav Denis i++; 780d935edddSTomislav Denis } 781d935edddSTomislav Denis 782d935edddSTomislav Denis indio_dev->channels = channels; 783d935edddSTomislav Denis indio_dev->num_channels = num_channels; 784d935edddSTomislav Denis st->channel_config = channel_config; 785d935edddSTomislav Denis 786d935edddSTomislav Denis return 0; 787d935edddSTomislav Denis } 788d935edddSTomislav Denis 789d935edddSTomislav Denis static void ads131e08_regulator_disable(void *data) 790d935edddSTomislav Denis { 791d935edddSTomislav Denis struct ads131e08_state *st = data; 792d935edddSTomislav Denis 793d935edddSTomislav Denis regulator_disable(st->vref_reg); 794d935edddSTomislav Denis } 795d935edddSTomislav Denis 796d935edddSTomislav Denis static void ads131e08_clk_disable(void *data) 797d935edddSTomislav Denis { 798d935edddSTomislav Denis struct ads131e08_state *st = data; 799d935edddSTomislav Denis 800d935edddSTomislav Denis clk_disable_unprepare(st->adc_clk); 801d935edddSTomislav Denis } 802d935edddSTomislav Denis 803d935edddSTomislav Denis static int ads131e08_probe(struct spi_device *spi) 804d935edddSTomislav Denis { 805d935edddSTomislav Denis const struct ads131e08_info *info; 806d935edddSTomislav Denis struct ads131e08_state *st; 807d935edddSTomislav Denis struct iio_dev *indio_dev; 808d935edddSTomislav Denis unsigned long adc_clk_hz; 809d935edddSTomislav Denis unsigned long adc_clk_ns; 810d935edddSTomislav Denis int ret; 811d935edddSTomislav Denis 812d935edddSTomislav Denis info = device_get_match_data(&spi->dev); 813d935edddSTomislav Denis if (!info) { 814d935edddSTomislav Denis dev_err(&spi->dev, "failed to get match data\n"); 815d935edddSTomislav Denis return -ENODEV; 816d935edddSTomislav Denis } 817d935edddSTomislav Denis 818d935edddSTomislav Denis indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); 819d935edddSTomislav Denis if (!indio_dev) { 820d935edddSTomislav Denis dev_err(&spi->dev, "failed to allocate IIO device\n"); 821d935edddSTomislav Denis return -ENOMEM; 822d935edddSTomislav Denis } 823d935edddSTomislav Denis 824d935edddSTomislav Denis st = iio_priv(indio_dev); 825d935edddSTomislav Denis st->info = info; 826d935edddSTomislav Denis st->spi = spi; 827d935edddSTomislav Denis 828d935edddSTomislav Denis ret = ads131e08_alloc_channels(indio_dev); 829d935edddSTomislav Denis if (ret) 830d935edddSTomislav Denis return ret; 831d935edddSTomislav Denis 832d935edddSTomislav Denis indio_dev->name = st->info->name; 833d935edddSTomislav Denis indio_dev->info = &ads131e08_iio_info; 834d935edddSTomislav Denis indio_dev->modes = INDIO_DIRECT_MODE; 835d935edddSTomislav Denis 836d935edddSTomislav Denis init_completion(&st->completion); 837d935edddSTomislav Denis 838d935edddSTomislav Denis if (spi->irq) { 839d935edddSTomislav Denis ret = devm_request_irq(&spi->dev, spi->irq, 840d935edddSTomislav Denis ads131e08_interrupt, 841d935edddSTomislav Denis IRQF_TRIGGER_FALLING | IRQF_ONESHOT, 842d935edddSTomislav Denis spi->dev.driver->name, indio_dev); 843d935edddSTomislav Denis if (ret) 844d935edddSTomislav Denis return dev_err_probe(&spi->dev, ret, 845d935edddSTomislav Denis "request irq failed\n"); 846d935edddSTomislav Denis } else { 847d935edddSTomislav Denis dev_err(&spi->dev, "data ready IRQ missing\n"); 848d935edddSTomislav Denis return -ENODEV; 849d935edddSTomislav Denis } 850d935edddSTomislav Denis 851d935edddSTomislav Denis st->trig = devm_iio_trigger_alloc(&spi->dev, "%s-dev%d", 852*15ea2878SJonathan Cameron indio_dev->name, iio_device_id(indio_dev)); 853d935edddSTomislav Denis if (!st->trig) { 854d935edddSTomislav Denis dev_err(&spi->dev, "failed to allocate IIO trigger\n"); 855d935edddSTomislav Denis return -ENOMEM; 856d935edddSTomislav Denis } 857d935edddSTomislav Denis 858d935edddSTomislav Denis st->trig->ops = &ads131e08_trigger_ops; 859d935edddSTomislav Denis st->trig->dev.parent = &spi->dev; 860d935edddSTomislav Denis iio_trigger_set_drvdata(st->trig, indio_dev); 861d935edddSTomislav Denis ret = devm_iio_trigger_register(&spi->dev, st->trig); 862d935edddSTomislav Denis if (ret) { 863d935edddSTomislav Denis dev_err(&spi->dev, "failed to register IIO trigger\n"); 864d935edddSTomislav Denis return -ENOMEM; 865d935edddSTomislav Denis } 866d935edddSTomislav Denis 867d935edddSTomislav Denis indio_dev->trig = iio_trigger_get(st->trig); 868d935edddSTomislav Denis 869d935edddSTomislav Denis ret = devm_iio_triggered_buffer_setup(&spi->dev, indio_dev, 870d935edddSTomislav Denis NULL, &ads131e08_trigger_handler, NULL); 871d935edddSTomislav Denis if (ret) { 872d935edddSTomislav Denis dev_err(&spi->dev, "failed to setup IIO buffer\n"); 873d935edddSTomislav Denis return ret; 874d935edddSTomislav Denis } 875d935edddSTomislav Denis 876d935edddSTomislav Denis st->vref_reg = devm_regulator_get_optional(&spi->dev, "vref"); 877d935edddSTomislav Denis if (!IS_ERR(st->vref_reg)) { 878d935edddSTomislav Denis ret = regulator_enable(st->vref_reg); 879d935edddSTomislav Denis if (ret) { 880d935edddSTomislav Denis dev_err(&spi->dev, 881d935edddSTomislav Denis "failed to enable external vref supply\n"); 882d935edddSTomislav Denis return ret; 883d935edddSTomislav Denis } 884d935edddSTomislav Denis 885d935edddSTomislav Denis ret = devm_add_action_or_reset(&spi->dev, ads131e08_regulator_disable, st); 886d935edddSTomislav Denis if (ret) 887d935edddSTomislav Denis return ret; 888d935edddSTomislav Denis } else { 889d935edddSTomislav Denis if (PTR_ERR(st->vref_reg) != -ENODEV) 890d935edddSTomislav Denis return PTR_ERR(st->vref_reg); 891d935edddSTomislav Denis 892d935edddSTomislav Denis st->vref_reg = NULL; 893d935edddSTomislav Denis } 894d935edddSTomislav Denis 895d935edddSTomislav Denis st->adc_clk = devm_clk_get(&spi->dev, "adc-clk"); 896d935edddSTomislav Denis if (IS_ERR(st->adc_clk)) 897d935edddSTomislav Denis return dev_err_probe(&spi->dev, PTR_ERR(st->adc_clk), 898d935edddSTomislav Denis "failed to get the ADC clock\n"); 899d935edddSTomislav Denis 900d935edddSTomislav Denis ret = clk_prepare_enable(st->adc_clk); 901d935edddSTomislav Denis if (ret) { 902d935edddSTomislav Denis dev_err(&spi->dev, "failed to prepare/enable the ADC clock\n"); 903d935edddSTomislav Denis return ret; 904d935edddSTomislav Denis } 905d935edddSTomislav Denis 906d935edddSTomislav Denis ret = devm_add_action_or_reset(&spi->dev, ads131e08_clk_disable, st); 907d935edddSTomislav Denis if (ret) 908d935edddSTomislav Denis return ret; 909d935edddSTomislav Denis 910d935edddSTomislav Denis adc_clk_hz = clk_get_rate(st->adc_clk); 911d935edddSTomislav Denis if (!adc_clk_hz) { 912d935edddSTomislav Denis dev_err(&spi->dev, "failed to get the ADC clock rate\n"); 913d935edddSTomislav Denis return -EINVAL; 914d935edddSTomislav Denis } 915d935edddSTomislav Denis 916d935edddSTomislav Denis adc_clk_ns = NSEC_PER_SEC / adc_clk_hz; 917d935edddSTomislav Denis st->sdecode_delay_us = DIV_ROUND_UP( 918d935edddSTomislav Denis ADS131E08_WAIT_SDECODE_CYCLES * adc_clk_ns, NSEC_PER_USEC); 919d935edddSTomislav Denis st->reset_delay_us = DIV_ROUND_UP( 920d935edddSTomislav Denis ADS131E08_WAIT_RESET_CYCLES * adc_clk_ns, NSEC_PER_USEC); 921d935edddSTomislav Denis 922d935edddSTomislav Denis ret = ads131e08_initial_config(indio_dev); 923d935edddSTomislav Denis if (ret) { 924d935edddSTomislav Denis dev_err(&spi->dev, "initial configuration failed\n"); 925d935edddSTomislav Denis return ret; 926d935edddSTomislav Denis } 927d935edddSTomislav Denis 928d935edddSTomislav Denis return devm_iio_device_register(&spi->dev, indio_dev); 929d935edddSTomislav Denis } 930d935edddSTomislav Denis 931d935edddSTomislav Denis static const struct of_device_id ads131e08_of_match[] = { 932d935edddSTomislav Denis { .compatible = "ti,ads131e04", 933d935edddSTomislav Denis .data = &ads131e08_info_tbl[ads131e04], }, 934d935edddSTomislav Denis { .compatible = "ti,ads131e06", 935d935edddSTomislav Denis .data = &ads131e08_info_tbl[ads131e06], }, 936d935edddSTomislav Denis { .compatible = "ti,ads131e08", 937d935edddSTomislav Denis .data = &ads131e08_info_tbl[ads131e08], }, 938d935edddSTomislav Denis {} 939d935edddSTomislav Denis }; 940d935edddSTomislav Denis MODULE_DEVICE_TABLE(of, ads131e08_of_match); 941d935edddSTomislav Denis 942d935edddSTomislav Denis static struct spi_driver ads131e08_driver = { 943d935edddSTomislav Denis .driver = { 944d935edddSTomislav Denis .name = "ads131e08", 945d935edddSTomislav Denis .of_match_table = ads131e08_of_match, 946d935edddSTomislav Denis }, 947d935edddSTomislav Denis .probe = ads131e08_probe, 948d935edddSTomislav Denis }; 949d935edddSTomislav Denis module_spi_driver(ads131e08_driver); 950d935edddSTomislav Denis 951d935edddSTomislav Denis MODULE_AUTHOR("Tomislav Denis <tomislav.denis@avl.com>"); 952d935edddSTomislav Denis MODULE_DESCRIPTION("Driver for ADS131E0x ADC family"); 953d935edddSTomislav Denis MODULE_LICENSE("GPL v2"); 954