root/drivers/iio/adc/ltc2471.c

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

DEFINITIONS

This source file includes following definitions.
  1. ltc2471_get_value
  2. ltc2471_read_raw
  3. ltc2471_i2c_probe

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Driver for Linear Technology LTC2471 and LTC2473 voltage monitors
   4  * The LTC2473 is identical to the 2471, but reports a differential signal.
   5  *
   6  * Copyright (C) 2017 Topic Embedded Products
   7  * Author: Mike Looijmans <mike.looijmans@topic.nl>
   8  */
   9 
  10 #include <linux/err.h>
  11 #include <linux/i2c.h>
  12 #include <linux/kernel.h>
  13 #include <linux/module.h>
  14 #include <linux/iio/iio.h>
  15 #include <linux/iio/sysfs.h>
  16 
  17 enum ltc2471_chips {
  18         ltc2471,
  19         ltc2473,
  20 };
  21 
  22 struct ltc2471_data {
  23         struct i2c_client *client;
  24 };
  25 
  26 /* Reference voltage is 1.25V */
  27 #define LTC2471_VREF 1250
  28 
  29 /* Read two bytes from the I2C bus to obtain the ADC result */
  30 static int ltc2471_get_value(struct i2c_client *client)
  31 {
  32         int ret;
  33         __be16 buf;
  34 
  35         ret = i2c_master_recv(client, (char *)&buf, sizeof(buf));
  36         if (ret < 0)
  37                 return ret;
  38         if (ret != sizeof(buf))
  39                 return -EIO;
  40 
  41         /* MSB first */
  42         return be16_to_cpu(buf);
  43 }
  44 
  45 static int ltc2471_read_raw(struct iio_dev *indio_dev,
  46                             struct iio_chan_spec const *chan,
  47                             int *val, int *val2, long info)
  48 {
  49         struct ltc2471_data *data = iio_priv(indio_dev);
  50         int ret;
  51 
  52         switch (info) {
  53         case IIO_CHAN_INFO_RAW:
  54                 ret = ltc2471_get_value(data->client);
  55                 if (ret < 0)
  56                         return ret;
  57                 *val = ret;
  58                 return IIO_VAL_INT;
  59 
  60         case IIO_CHAN_INFO_SCALE:
  61                 if (chan->differential)
  62                         /* Output ranges from -VREF to +VREF */
  63                         *val = 2 * LTC2471_VREF;
  64                 else
  65                         /* Output ranges from 0 to VREF */
  66                         *val = LTC2471_VREF;
  67                 *val2 = 16;     /* 16 data bits */
  68                 return IIO_VAL_FRACTIONAL_LOG2;
  69 
  70         case IIO_CHAN_INFO_OFFSET:
  71                 /* Only differential chip has this property */
  72                 *val = -LTC2471_VREF;
  73                 return IIO_VAL_INT;
  74 
  75         default:
  76                 return -EINVAL;
  77         }
  78 }
  79 
  80 static const struct iio_chan_spec ltc2471_channel[] = {
  81         {
  82                 .type = IIO_VOLTAGE,
  83                 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
  84                 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
  85         },
  86 };
  87 
  88 static const struct iio_chan_spec ltc2473_channel[] = {
  89         {
  90                 .type = IIO_VOLTAGE,
  91                 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
  92                 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |
  93                                             BIT(IIO_CHAN_INFO_OFFSET),
  94                 .differential = 1,
  95         },
  96 };
  97 
  98 static const struct iio_info ltc2471_info = {
  99         .read_raw = ltc2471_read_raw,
 100 };
 101 
 102 static int ltc2471_i2c_probe(struct i2c_client *client,
 103                              const struct i2c_device_id *id)
 104 {
 105         struct iio_dev *indio_dev;
 106         struct ltc2471_data *data;
 107         int ret;
 108 
 109         if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
 110                 return -EOPNOTSUPP;
 111 
 112         indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
 113         if (!indio_dev)
 114                 return -ENOMEM;
 115 
 116         data = iio_priv(indio_dev);
 117         data->client = client;
 118 
 119         indio_dev->dev.parent = &client->dev;
 120         indio_dev->name = id->name;
 121         indio_dev->info = &ltc2471_info;
 122         indio_dev->modes = INDIO_DIRECT_MODE;
 123         if (id->driver_data == ltc2473)
 124                 indio_dev->channels = ltc2473_channel;
 125         else
 126                 indio_dev->channels = ltc2471_channel;
 127         indio_dev->num_channels = 1;
 128 
 129         /* Trigger once to start conversion and check if chip is there */
 130         ret = ltc2471_get_value(client);
 131         if (ret < 0) {
 132                 dev_err(&client->dev, "Cannot read from device.\n");
 133                 return ret;
 134         }
 135 
 136         return devm_iio_device_register(&client->dev, indio_dev);
 137 }
 138 
 139 static const struct i2c_device_id ltc2471_i2c_id[] = {
 140         { "ltc2471", ltc2471 },
 141         { "ltc2473", ltc2473 },
 142         {}
 143 };
 144 MODULE_DEVICE_TABLE(i2c, ltc2471_i2c_id);
 145 
 146 static struct i2c_driver ltc2471_i2c_driver = {
 147         .driver = {
 148                 .name = "ltc2471",
 149         },
 150         .probe    = ltc2471_i2c_probe,
 151         .id_table = ltc2471_i2c_id,
 152 };
 153 
 154 module_i2c_driver(ltc2471_i2c_driver);
 155 
 156 MODULE_DESCRIPTION("LTC2471/LTC2473 ADC driver");
 157 MODULE_AUTHOR("Topic Embedded Products");
 158 MODULE_LICENSE("GPL v2");

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