0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <linux/module.h>
0014 #include <linux/mod_devicetable.h>
0015 #include <linux/init.h>
0016 #include <linux/err.h>
0017 #include <linux/spi/spi.h>
0018 #include <linux/iio/iio.h>
0019 #include <linux/iio/trigger.h>
0020 #include <linux/iio/buffer.h>
0021 #include <linux/iio/trigger_consumer.h>
0022 #include <linux/iio/triggered_buffer.h>
0023 #include <linux/regulator/consumer.h>
0024
0025 #define TI_ADC_DRV_NAME "ti-adc161s626"
0026
0027 enum {
0028 TI_ADC141S626,
0029 TI_ADC161S626,
0030 };
0031
0032 static const struct iio_chan_spec ti_adc141s626_channels[] = {
0033 {
0034 .type = IIO_VOLTAGE,
0035 .channel = 0,
0036 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
0037 BIT(IIO_CHAN_INFO_SCALE) |
0038 BIT(IIO_CHAN_INFO_OFFSET),
0039 .scan_index = 0,
0040 .scan_type = {
0041 .sign = 's',
0042 .realbits = 14,
0043 .storagebits = 16,
0044 },
0045 },
0046 IIO_CHAN_SOFT_TIMESTAMP(1),
0047 };
0048
0049 static const struct iio_chan_spec ti_adc161s626_channels[] = {
0050 {
0051 .type = IIO_VOLTAGE,
0052 .channel = 0,
0053 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
0054 BIT(IIO_CHAN_INFO_SCALE) |
0055 BIT(IIO_CHAN_INFO_OFFSET),
0056 .scan_index = 0,
0057 .scan_type = {
0058 .sign = 's',
0059 .realbits = 16,
0060 .storagebits = 16,
0061 },
0062 },
0063 IIO_CHAN_SOFT_TIMESTAMP(1),
0064 };
0065
0066 struct ti_adc_data {
0067 struct iio_dev *indio_dev;
0068 struct spi_device *spi;
0069 struct regulator *ref;
0070
0071 u8 read_size;
0072 u8 shift;
0073
0074 u8 buffer[16] __aligned(IIO_DMA_MINALIGN);
0075 };
0076
0077 static int ti_adc_read_measurement(struct ti_adc_data *data,
0078 struct iio_chan_spec const *chan, int *val)
0079 {
0080 int ret;
0081
0082 switch (data->read_size) {
0083 case 2: {
0084 __be16 buf;
0085
0086 ret = spi_read(data->spi, (void *) &buf, 2);
0087 if (ret)
0088 return ret;
0089
0090 *val = be16_to_cpu(buf);
0091 break;
0092 }
0093 case 3: {
0094 __be32 buf;
0095
0096 ret = spi_read(data->spi, (void *) &buf, 3);
0097 if (ret)
0098 return ret;
0099
0100 *val = be32_to_cpu(buf) >> 8;
0101 break;
0102 }
0103 default:
0104 return -EINVAL;
0105 }
0106
0107 *val = sign_extend32(*val >> data->shift, chan->scan_type.realbits - 1);
0108
0109 return 0;
0110 }
0111
0112 static irqreturn_t ti_adc_trigger_handler(int irq, void *private)
0113 {
0114 struct iio_poll_func *pf = private;
0115 struct iio_dev *indio_dev = pf->indio_dev;
0116 struct ti_adc_data *data = iio_priv(indio_dev);
0117 int ret;
0118
0119 ret = ti_adc_read_measurement(data, &indio_dev->channels[0],
0120 (int *) &data->buffer);
0121 if (!ret)
0122 iio_push_to_buffers_with_timestamp(indio_dev,
0123 data->buffer,
0124 iio_get_time_ns(indio_dev));
0125
0126 iio_trigger_notify_done(indio_dev->trig);
0127
0128 return IRQ_HANDLED;
0129 }
0130
0131 static int ti_adc_read_raw(struct iio_dev *indio_dev,
0132 struct iio_chan_spec const *chan,
0133 int *val, int *val2, long mask)
0134 {
0135 struct ti_adc_data *data = iio_priv(indio_dev);
0136 int ret;
0137
0138 switch (mask) {
0139 case IIO_CHAN_INFO_RAW:
0140 ret = iio_device_claim_direct_mode(indio_dev);
0141 if (ret)
0142 return ret;
0143
0144 ret = ti_adc_read_measurement(data, chan, val);
0145 iio_device_release_direct_mode(indio_dev);
0146
0147 if (ret)
0148 return ret;
0149
0150 return IIO_VAL_INT;
0151 case IIO_CHAN_INFO_SCALE:
0152 ret = regulator_get_voltage(data->ref);
0153 if (ret < 0)
0154 return ret;
0155
0156 *val = ret / 1000;
0157 *val2 = chan->scan_type.realbits;
0158
0159 return IIO_VAL_FRACTIONAL_LOG2;
0160 case IIO_CHAN_INFO_OFFSET:
0161 *val = 1 << (chan->scan_type.realbits - 1);
0162 return IIO_VAL_INT;
0163 }
0164
0165 return 0;
0166 }
0167
0168 static const struct iio_info ti_adc_info = {
0169 .read_raw = ti_adc_read_raw,
0170 };
0171
0172 static void ti_adc_reg_disable(void *reg)
0173 {
0174 regulator_disable(reg);
0175 }
0176
0177 static int ti_adc_probe(struct spi_device *spi)
0178 {
0179 struct iio_dev *indio_dev;
0180 struct ti_adc_data *data;
0181 int ret;
0182
0183 indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*data));
0184 if (!indio_dev)
0185 return -ENOMEM;
0186
0187 indio_dev->info = &ti_adc_info;
0188 indio_dev->name = TI_ADC_DRV_NAME;
0189 indio_dev->modes = INDIO_DIRECT_MODE;
0190
0191 data = iio_priv(indio_dev);
0192 data->spi = spi;
0193
0194 switch (spi_get_device_id(spi)->driver_data) {
0195 case TI_ADC141S626:
0196 indio_dev->channels = ti_adc141s626_channels;
0197 indio_dev->num_channels = ARRAY_SIZE(ti_adc141s626_channels);
0198 data->shift = 0;
0199 data->read_size = 2;
0200 break;
0201 case TI_ADC161S626:
0202 indio_dev->channels = ti_adc161s626_channels;
0203 indio_dev->num_channels = ARRAY_SIZE(ti_adc161s626_channels);
0204 data->shift = 6;
0205 data->read_size = 3;
0206 break;
0207 }
0208
0209 data->ref = devm_regulator_get(&spi->dev, "vdda");
0210 if (IS_ERR(data->ref))
0211 return PTR_ERR(data->ref);
0212
0213 ret = regulator_enable(data->ref);
0214 if (ret < 0)
0215 return ret;
0216
0217 ret = devm_add_action_or_reset(&spi->dev, ti_adc_reg_disable,
0218 data->ref);
0219 if (ret)
0220 return ret;
0221
0222 ret = devm_iio_triggered_buffer_setup(&spi->dev, indio_dev, NULL,
0223 ti_adc_trigger_handler, NULL);
0224 if (ret)
0225 return ret;
0226
0227 return devm_iio_device_register(&spi->dev, indio_dev);
0228 }
0229
0230 static const struct of_device_id ti_adc_dt_ids[] = {
0231 { .compatible = "ti,adc141s626", },
0232 { .compatible = "ti,adc161s626", },
0233 {}
0234 };
0235 MODULE_DEVICE_TABLE(of, ti_adc_dt_ids);
0236
0237 static const struct spi_device_id ti_adc_id[] = {
0238 {"adc141s626", TI_ADC141S626},
0239 {"adc161s626", TI_ADC161S626},
0240 {},
0241 };
0242 MODULE_DEVICE_TABLE(spi, ti_adc_id);
0243
0244 static struct spi_driver ti_adc_driver = {
0245 .driver = {
0246 .name = TI_ADC_DRV_NAME,
0247 .of_match_table = ti_adc_dt_ids,
0248 },
0249 .probe = ti_adc_probe,
0250 .id_table = ti_adc_id,
0251 };
0252 module_spi_driver(ti_adc_driver);
0253
0254 MODULE_AUTHOR("Matt Ranostay <matt.ranostay@konsulko.com>");
0255 MODULE_DESCRIPTION("Texas Instruments ADC1x1S 1-channel differential ADC");
0256 MODULE_LICENSE("GPL");