ltc2471.c (3597B)
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 17enum ltc2471_chips { 18 ltc2471, 19 ltc2473, 20}; 21 22struct 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 */ 30static 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 45static 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 80static 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 88static 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 98static const struct iio_info ltc2471_info = { 99 .read_raw = ltc2471_read_raw, 100}; 101 102static 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->name = id->name; 120 indio_dev->info = <c2471_info; 121 indio_dev->modes = INDIO_DIRECT_MODE; 122 if (id->driver_data == ltc2473) 123 indio_dev->channels = ltc2473_channel; 124 else 125 indio_dev->channels = ltc2471_channel; 126 indio_dev->num_channels = 1; 127 128 /* Trigger once to start conversion and check if chip is there */ 129 ret = ltc2471_get_value(client); 130 if (ret < 0) { 131 dev_err(&client->dev, "Cannot read from device.\n"); 132 return ret; 133 } 134 135 return devm_iio_device_register(&client->dev, indio_dev); 136} 137 138static const struct i2c_device_id ltc2471_i2c_id[] = { 139 { "ltc2471", ltc2471 }, 140 { "ltc2473", ltc2473 }, 141 {} 142}; 143MODULE_DEVICE_TABLE(i2c, ltc2471_i2c_id); 144 145static struct i2c_driver ltc2471_i2c_driver = { 146 .driver = { 147 .name = "ltc2471", 148 }, 149 .probe = ltc2471_i2c_probe, 150 .id_table = ltc2471_i2c_id, 151}; 152 153module_i2c_driver(ltc2471_i2c_driver); 154 155MODULE_DESCRIPTION("LTC2471/LTC2473 ADC driver"); 156MODULE_AUTHOR("Topic Embedded Products"); 157MODULE_LICENSE("GPL v2");