root/drivers/iio/adc/ti-ads8344.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ads8344_adc_conversion
  2. ads8344_read_raw
  3. ads8344_probe
  4. ads8344_remove

   1 // SPDX-License-Identifier: GPL-2.0+
   2 /*
   3  * ADS8344 16-bit 8-Channel ADC driver
   4  *
   5  * Author: Gregory CLEMENT <gregory.clement@bootlin.com>
   6  *
   7  * Datasheet: http://www.ti.com/lit/ds/symlink/ads8344.pdf
   8  */
   9 
  10 #include <linux/delay.h>
  11 #include <linux/iio/buffer.h>
  12 #include <linux/iio/iio.h>
  13 #include <linux/module.h>
  14 #include <linux/regulator/consumer.h>
  15 #include <linux/spi/spi.h>
  16 
  17 #define ADS8344_START BIT(7)
  18 #define ADS8344_SINGLE_END BIT(2)
  19 #define ADS8344_CHANNEL(channel) ((channel) << 4)
  20 #define ADS8344_CLOCK_INTERNAL 0x2 /* PD1 = 1 and PD0 = 0 */
  21 
  22 struct ads8344 {
  23         struct spi_device *spi;
  24         struct regulator *reg;
  25         /*
  26          * Lock protecting access to adc->tx_buff and rx_buff,
  27          * especially from concurrent read on sysfs file.
  28          */
  29         struct mutex lock;
  30 
  31         u8 tx_buf ____cacheline_aligned;
  32         u8 rx_buf[3];
  33 };
  34 
  35 #define ADS8344_VOLTAGE_CHANNEL(chan, addr)                             \
  36         {                                                               \
  37                 .type = IIO_VOLTAGE,                                    \
  38                 .indexed = 1,                                           \
  39                 .channel = chan,                                        \
  40                 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),           \
  41                 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),   \
  42                 .address = addr,                                        \
  43         }
  44 
  45 #define ADS8344_VOLTAGE_CHANNEL_DIFF(chan1, chan2, addr)                \
  46         {                                                               \
  47                 .type = IIO_VOLTAGE,                                    \
  48                 .indexed = 1,                                           \
  49                 .channel = (chan1),                                     \
  50                 .channel2 = (chan2),                                    \
  51                 .differential = 1,                                      \
  52                 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),           \
  53                 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),   \
  54                 .address = addr,                                        \
  55         }
  56 
  57 static const struct iio_chan_spec ads8344_channels[] = {
  58         ADS8344_VOLTAGE_CHANNEL(0, 0),
  59         ADS8344_VOLTAGE_CHANNEL(1, 4),
  60         ADS8344_VOLTAGE_CHANNEL(2, 1),
  61         ADS8344_VOLTAGE_CHANNEL(3, 5),
  62         ADS8344_VOLTAGE_CHANNEL(4, 2),
  63         ADS8344_VOLTAGE_CHANNEL(5, 6),
  64         ADS8344_VOLTAGE_CHANNEL(6, 3),
  65         ADS8344_VOLTAGE_CHANNEL(7, 7),
  66         ADS8344_VOLTAGE_CHANNEL_DIFF(0, 1, 8),
  67         ADS8344_VOLTAGE_CHANNEL_DIFF(2, 3, 9),
  68         ADS8344_VOLTAGE_CHANNEL_DIFF(4, 5, 10),
  69         ADS8344_VOLTAGE_CHANNEL_DIFF(6, 7, 11),
  70         ADS8344_VOLTAGE_CHANNEL_DIFF(1, 0, 12),
  71         ADS8344_VOLTAGE_CHANNEL_DIFF(3, 2, 13),
  72         ADS8344_VOLTAGE_CHANNEL_DIFF(5, 4, 14),
  73         ADS8344_VOLTAGE_CHANNEL_DIFF(7, 6, 15),
  74 };
  75 
  76 static int ads8344_adc_conversion(struct ads8344 *adc, int channel,
  77                                   bool differential)
  78 {
  79         struct spi_device *spi = adc->spi;
  80         int ret;
  81 
  82         adc->tx_buf = ADS8344_START;
  83         if (!differential)
  84                 adc->tx_buf |= ADS8344_SINGLE_END;
  85         adc->tx_buf |= ADS8344_CHANNEL(channel);
  86         adc->tx_buf |= ADS8344_CLOCK_INTERNAL;
  87 
  88         ret = spi_write(spi, &adc->tx_buf, 1);
  89         if (ret)
  90                 return ret;
  91 
  92         udelay(9);
  93 
  94         ret = spi_read(spi, adc->rx_buf, sizeof(adc->rx_buf));
  95         if (ret)
  96                 return ret;
  97 
  98         return adc->rx_buf[0] << 9 | adc->rx_buf[1] << 1 | adc->rx_buf[2] >> 7;
  99 }
 100 
 101 static int ads8344_read_raw(struct iio_dev *iio,
 102                             struct iio_chan_spec const *channel, int *value,
 103                             int *shift, long mask)
 104 {
 105         struct ads8344 *adc = iio_priv(iio);
 106 
 107         switch (mask) {
 108         case IIO_CHAN_INFO_RAW:
 109                 mutex_lock(&adc->lock);
 110                 *value = ads8344_adc_conversion(adc, channel->address,
 111                                                 channel->differential);
 112                 mutex_unlock(&adc->lock);
 113                 if (*value < 0)
 114                         return *value;
 115 
 116                 return IIO_VAL_INT;
 117         case IIO_CHAN_INFO_SCALE:
 118                 *value = regulator_get_voltage(adc->reg);
 119                 if (*value < 0)
 120                         return *value;
 121 
 122                 /* convert regulator output voltage to mV */
 123                 *value /= 1000;
 124                 *shift = 16;
 125 
 126                 return IIO_VAL_FRACTIONAL_LOG2;
 127         default:
 128                 return -EINVAL;
 129         }
 130 }
 131 
 132 static const struct iio_info ads8344_info = {
 133         .read_raw = ads8344_read_raw,
 134 };
 135 
 136 static int ads8344_probe(struct spi_device *spi)
 137 {
 138         struct iio_dev *indio_dev;
 139         struct ads8344 *adc;
 140         int ret;
 141 
 142         indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adc));
 143         if (!indio_dev)
 144                 return -ENOMEM;
 145 
 146         adc = iio_priv(indio_dev);
 147         adc->spi = spi;
 148         mutex_init(&adc->lock);
 149 
 150         indio_dev->name = dev_name(&spi->dev);
 151         indio_dev->dev.parent = &spi->dev;
 152         indio_dev->dev.of_node = spi->dev.of_node;
 153         indio_dev->info = &ads8344_info;
 154         indio_dev->modes = INDIO_DIRECT_MODE;
 155         indio_dev->channels = ads8344_channels;
 156         indio_dev->num_channels = ARRAY_SIZE(ads8344_channels);
 157 
 158         adc->reg = devm_regulator_get(&spi->dev, "vref");
 159         if (IS_ERR(adc->reg))
 160                 return PTR_ERR(adc->reg);
 161 
 162         ret = regulator_enable(adc->reg);
 163         if (ret)
 164                 return ret;
 165 
 166         spi_set_drvdata(spi, indio_dev);
 167 
 168         ret = iio_device_register(indio_dev);
 169         if (ret) {
 170                 regulator_disable(adc->reg);
 171                 return ret;
 172         }
 173 
 174         return 0;
 175 }
 176 
 177 static int ads8344_remove(struct spi_device *spi)
 178 {
 179         struct iio_dev *indio_dev = spi_get_drvdata(spi);
 180         struct ads8344 *adc = iio_priv(indio_dev);
 181 
 182         iio_device_unregister(indio_dev);
 183         regulator_disable(adc->reg);
 184 
 185         return 0;
 186 }
 187 
 188 static const struct of_device_id ads8344_of_match[] = {
 189         { .compatible = "ti,ads8344", },
 190         {}
 191 };
 192 MODULE_DEVICE_TABLE(of, ads8344_of_match);
 193 
 194 static struct spi_driver ads8344_driver = {
 195         .driver = {
 196                 .name = "ads8344",
 197                 .of_match_table = ads8344_of_match,
 198         },
 199         .probe = ads8344_probe,
 200         .remove = ads8344_remove,
 201 };
 202 module_spi_driver(ads8344_driver);
 203 
 204 MODULE_AUTHOR("Gregory CLEMENT <gregory.clement@bootlin.com>");
 205 MODULE_DESCRIPTION("ADS8344 driver");
 206 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */