1a8e7e88dSJacopo Mondi /* 2a8e7e88dSJacopo Mondi * iio/adc/max11100.c 3a8e7e88dSJacopo Mondi * Maxim max11100 ADC Driver with IIO interface 4a8e7e88dSJacopo Mondi * 5a8e7e88dSJacopo Mondi * Copyright (C) 2016-17 Renesas Electronics Corporation 6a8e7e88dSJacopo Mondi * Copyright (C) 2016-17 Jacopo Mondi 7a8e7e88dSJacopo Mondi * 8a8e7e88dSJacopo Mondi * This program is free software; you can redistribute it and/or modify 9a8e7e88dSJacopo Mondi * it under the terms of the GNU General Public License version 2 as 10a8e7e88dSJacopo Mondi * published by the Free Software Foundation. 11a8e7e88dSJacopo Mondi */ 12a8e7e88dSJacopo Mondi #include <linux/delay.h> 13a8e7e88dSJacopo Mondi #include <linux/kernel.h> 14a8e7e88dSJacopo Mondi #include <linux/module.h> 15a8e7e88dSJacopo Mondi #include <linux/regulator/consumer.h> 16a8e7e88dSJacopo Mondi #include <linux/spi/spi.h> 17a8e7e88dSJacopo Mondi 18a8e7e88dSJacopo Mondi #include <linux/iio/iio.h> 19a8e7e88dSJacopo Mondi #include <linux/iio/driver.h> 20a8e7e88dSJacopo Mondi 21a8e7e88dSJacopo Mondi /* 22a8e7e88dSJacopo Mondi * LSB is the ADC single digital step 23a8e7e88dSJacopo Mondi * 1 LSB = (vref_mv / 2 ^ 16) 24a8e7e88dSJacopo Mondi * 25a8e7e88dSJacopo Mondi * LSB is used to calculate analog voltage value 26a8e7e88dSJacopo Mondi * from the number of ADC steps count 27a8e7e88dSJacopo Mondi * 28a8e7e88dSJacopo Mondi * Ain = (count * LSB) 29a8e7e88dSJacopo Mondi */ 30a8e7e88dSJacopo Mondi #define MAX11100_LSB_DIV (1 << 16) 31a8e7e88dSJacopo Mondi 32a8e7e88dSJacopo Mondi struct max11100_state { 33a8e7e88dSJacopo Mondi struct regulator *vref_reg; 34a8e7e88dSJacopo Mondi struct spi_device *spi; 35a8e7e88dSJacopo Mondi 36a8e7e88dSJacopo Mondi /* 37a8e7e88dSJacopo Mondi * DMA (thus cache coherency maintenance) requires the 38a8e7e88dSJacopo Mondi * transfer buffers to live in their own cache lines. 39a8e7e88dSJacopo Mondi */ 40a8e7e88dSJacopo Mondi u8 buffer[3] ____cacheline_aligned; 41a8e7e88dSJacopo Mondi }; 42a8e7e88dSJacopo Mondi 43a8e7e88dSJacopo Mondi static struct iio_chan_spec max11100_channels[] = { 44a8e7e88dSJacopo Mondi { /* [0] */ 45a8e7e88dSJacopo Mondi .type = IIO_VOLTAGE, 46a8e7e88dSJacopo Mondi .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 47a8e7e88dSJacopo Mondi BIT(IIO_CHAN_INFO_SCALE), 48a8e7e88dSJacopo Mondi }, 49a8e7e88dSJacopo Mondi }; 50a8e7e88dSJacopo Mondi 51a8e7e88dSJacopo Mondi static int max11100_read_single(struct iio_dev *indio_dev, int *val) 52a8e7e88dSJacopo Mondi { 53a8e7e88dSJacopo Mondi int ret; 54a8e7e88dSJacopo Mondi struct max11100_state *state = iio_priv(indio_dev); 55a8e7e88dSJacopo Mondi 56a8e7e88dSJacopo Mondi ret = spi_read(state->spi, state->buffer, sizeof(state->buffer)); 57a8e7e88dSJacopo Mondi if (ret) { 58a8e7e88dSJacopo Mondi dev_err(&indio_dev->dev, "SPI transfer failed\n"); 59a8e7e88dSJacopo Mondi return ret; 60a8e7e88dSJacopo Mondi } 61a8e7e88dSJacopo Mondi 62a8e7e88dSJacopo Mondi /* the first 8 bits sent out from ADC must be 0s */ 63a8e7e88dSJacopo Mondi if (state->buffer[0]) { 64a8e7e88dSJacopo Mondi dev_err(&indio_dev->dev, "Invalid value: buffer[0] != 0\n"); 65a8e7e88dSJacopo Mondi return -EINVAL; 66a8e7e88dSJacopo Mondi } 67a8e7e88dSJacopo Mondi 68a8e7e88dSJacopo Mondi *val = (state->buffer[1] << 8) | state->buffer[2]; 69a8e7e88dSJacopo Mondi 70a8e7e88dSJacopo Mondi return 0; 71a8e7e88dSJacopo Mondi } 72a8e7e88dSJacopo Mondi 73a8e7e88dSJacopo Mondi static int max11100_read_raw(struct iio_dev *indio_dev, 74a8e7e88dSJacopo Mondi struct iio_chan_spec const *chan, 75a8e7e88dSJacopo Mondi int *val, int *val2, long info) 76a8e7e88dSJacopo Mondi { 77a8e7e88dSJacopo Mondi int ret, vref_uv; 78a8e7e88dSJacopo Mondi struct max11100_state *state = iio_priv(indio_dev); 79a8e7e88dSJacopo Mondi 80a8e7e88dSJacopo Mondi switch (info) { 81a8e7e88dSJacopo Mondi case IIO_CHAN_INFO_RAW: 82a8e7e88dSJacopo Mondi ret = max11100_read_single(indio_dev, val); 83a8e7e88dSJacopo Mondi if (ret) 84a8e7e88dSJacopo Mondi return ret; 85a8e7e88dSJacopo Mondi 86a8e7e88dSJacopo Mondi return IIO_VAL_INT; 87a8e7e88dSJacopo Mondi 88a8e7e88dSJacopo Mondi case IIO_CHAN_INFO_SCALE: 89a8e7e88dSJacopo Mondi vref_uv = regulator_get_voltage(state->vref_reg); 90a8e7e88dSJacopo Mondi if (vref_uv < 0) 91a8e7e88dSJacopo Mondi /* dummy regulator "get_voltage" returns -EINVAL */ 92a8e7e88dSJacopo Mondi return -EINVAL; 93a8e7e88dSJacopo Mondi 94a8e7e88dSJacopo Mondi *val = vref_uv / 1000; 95a8e7e88dSJacopo Mondi *val2 = MAX11100_LSB_DIV; 96a8e7e88dSJacopo Mondi return IIO_VAL_FRACTIONAL; 97a8e7e88dSJacopo Mondi } 98a8e7e88dSJacopo Mondi 99a8e7e88dSJacopo Mondi return -EINVAL; 100a8e7e88dSJacopo Mondi } 101a8e7e88dSJacopo Mondi 102a8e7e88dSJacopo Mondi static const struct iio_info max11100_info = { 103a8e7e88dSJacopo Mondi .driver_module = THIS_MODULE, 104a8e7e88dSJacopo Mondi .read_raw = max11100_read_raw, 105a8e7e88dSJacopo Mondi }; 106a8e7e88dSJacopo Mondi 107a8e7e88dSJacopo Mondi static int max11100_probe(struct spi_device *spi) 108a8e7e88dSJacopo Mondi { 109a8e7e88dSJacopo Mondi int ret; 110a8e7e88dSJacopo Mondi struct iio_dev *indio_dev; 111a8e7e88dSJacopo Mondi struct max11100_state *state; 112a8e7e88dSJacopo Mondi 113a8e7e88dSJacopo Mondi indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*state)); 114a8e7e88dSJacopo Mondi if (!indio_dev) 115a8e7e88dSJacopo Mondi return -ENOMEM; 116a8e7e88dSJacopo Mondi 117a8e7e88dSJacopo Mondi spi_set_drvdata(spi, indio_dev); 118a8e7e88dSJacopo Mondi 119a8e7e88dSJacopo Mondi state = iio_priv(indio_dev); 120a8e7e88dSJacopo Mondi state->spi = spi; 121a8e7e88dSJacopo Mondi 122a8e7e88dSJacopo Mondi indio_dev->dev.parent = &spi->dev; 123a8e7e88dSJacopo Mondi indio_dev->dev.of_node = spi->dev.of_node; 124a8e7e88dSJacopo Mondi indio_dev->name = "max11100"; 125a8e7e88dSJacopo Mondi indio_dev->info = &max11100_info; 126a8e7e88dSJacopo Mondi indio_dev->modes = INDIO_DIRECT_MODE; 127*bb4787f5SArushi Singhal indio_dev->channels = max11100_channels; 128*bb4787f5SArushi Singhal indio_dev->num_channels = ARRAY_SIZE(max11100_channels); 129a8e7e88dSJacopo Mondi 130a8e7e88dSJacopo Mondi state->vref_reg = devm_regulator_get(&spi->dev, "vref"); 131a8e7e88dSJacopo Mondi if (IS_ERR(state->vref_reg)) 132a8e7e88dSJacopo Mondi return PTR_ERR(state->vref_reg); 133a8e7e88dSJacopo Mondi 134a8e7e88dSJacopo Mondi ret = regulator_enable(state->vref_reg); 135a8e7e88dSJacopo Mondi if (ret) 136a8e7e88dSJacopo Mondi return ret; 137a8e7e88dSJacopo Mondi 138a8e7e88dSJacopo Mondi ret = iio_device_register(indio_dev); 139a8e7e88dSJacopo Mondi if (ret) 140a8e7e88dSJacopo Mondi goto disable_regulator; 141a8e7e88dSJacopo Mondi 142a8e7e88dSJacopo Mondi return 0; 143a8e7e88dSJacopo Mondi 144a8e7e88dSJacopo Mondi disable_regulator: 145a8e7e88dSJacopo Mondi regulator_disable(state->vref_reg); 146a8e7e88dSJacopo Mondi 147a8e7e88dSJacopo Mondi return ret; 148a8e7e88dSJacopo Mondi } 149a8e7e88dSJacopo Mondi 150a8e7e88dSJacopo Mondi static int max11100_remove(struct spi_device *spi) 151a8e7e88dSJacopo Mondi { 152a8e7e88dSJacopo Mondi struct iio_dev *indio_dev = spi_get_drvdata(spi); 153a8e7e88dSJacopo Mondi struct max11100_state *state = iio_priv(indio_dev); 154a8e7e88dSJacopo Mondi 155a8e7e88dSJacopo Mondi iio_device_unregister(indio_dev); 156ac2bec9dSPhil Reid regulator_disable(state->vref_reg); 157a8e7e88dSJacopo Mondi 158a8e7e88dSJacopo Mondi return 0; 159a8e7e88dSJacopo Mondi } 160a8e7e88dSJacopo Mondi 161a8e7e88dSJacopo Mondi static const struct of_device_id max11100_ids[] = { 162a8e7e88dSJacopo Mondi {.compatible = "maxim,max11100"}, 163a8e7e88dSJacopo Mondi { }, 164a8e7e88dSJacopo Mondi }; 165a8e7e88dSJacopo Mondi MODULE_DEVICE_TABLE(of, max11100_ids); 166a8e7e88dSJacopo Mondi 167a8e7e88dSJacopo Mondi static struct spi_driver max11100_driver = { 168a8e7e88dSJacopo Mondi .driver = { 169a8e7e88dSJacopo Mondi .name = "max11100", 170a8e7e88dSJacopo Mondi .of_match_table = of_match_ptr(max11100_ids), 171a8e7e88dSJacopo Mondi }, 172a8e7e88dSJacopo Mondi .probe = max11100_probe, 173a8e7e88dSJacopo Mondi .remove = max11100_remove, 174a8e7e88dSJacopo Mondi }; 175a8e7e88dSJacopo Mondi 176a8e7e88dSJacopo Mondi module_spi_driver(max11100_driver); 177a8e7e88dSJacopo Mondi 178a8e7e88dSJacopo Mondi MODULE_AUTHOR("Jacopo Mondi <jacopo@jmondi.org>"); 179a8e7e88dSJacopo Mondi MODULE_DESCRIPTION("Maxim max11100 ADC Driver"); 180a8e7e88dSJacopo Mondi MODULE_LICENSE("GPL v2"); 181