Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

iio: adc: Add TI ADC128S052

This patch adds support for ADC128S052 from TI.

Signed-off-by: Angelo Compagnucci <angelo.compagnucci@gmail.com>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>

authored by

Angelo Compagnucci and committed by
Jonathan Cameron
913b8646 7144045d

+190
+10
drivers/iio/adc/Kconfig
··· 216 216 This driver can also be built as a module. If so, the module will be 217 217 called ti-adc081c. 218 218 219 + config TI_ADC128S052 220 + tristate "Texas Instruments ADC128S052" 221 + depends on SPI 222 + help 223 + If you say yes here you get support for Texas Instruments ADC128S052 224 + chip. 225 + 226 + This driver can also be built as a module. If so, the module will be 227 + called ti-adc128s052. 228 + 219 229 config TI_AM335X_ADC 220 230 tristate "TI's AM335X ADC driver" 221 231 depends on MFD_TI_AM335X_TSCADC
+1
drivers/iio/adc/Makefile
··· 23 23 obj-$(CONFIG_MEN_Z188_ADC) += men_z188_adc.o 24 24 obj-$(CONFIG_NAU7802) += nau7802.o 25 25 obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o 26 + obj-$(CONFIG_TI_ADC128S052) += ti-adc128s052.o 26 27 obj-$(CONFIG_TI_AM335X_ADC) += ti_am335x_adc.o 27 28 obj-$(CONFIG_TWL4030_MADC) += twl4030-madc.o 28 29 obj-$(CONFIG_TWL6030_GPADC) += twl6030-gpadc.o
+179
drivers/iio/adc/ti-adc128s052.c
··· 1 + /* 2 + * Copyright (C) 2014 Angelo Compagnucci <angelo.compagnucci@gmail.com> 3 + * 4 + * Driver for Texas Instruments' ADC128S052 ADC chip. 5 + * Datasheet can be found here: 6 + * http://www.ti.com/lit/ds/symlink/adc128s052.pdf 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + */ 12 + 13 + #include <linux/err.h> 14 + #include <linux/spi/spi.h> 15 + #include <linux/module.h> 16 + #include <linux/iio/iio.h> 17 + #include <linux/regulator/consumer.h> 18 + 19 + struct adc128 { 20 + struct spi_device *spi; 21 + 22 + struct regulator *reg; 23 + struct mutex lock; 24 + 25 + u8 buffer[2] ____cacheline_aligned; 26 + }; 27 + 28 + static int adc128_adc_conversion(struct adc128 *adc, u8 channel) 29 + { 30 + int ret; 31 + 32 + mutex_lock(&adc->lock); 33 + 34 + adc->buffer[0] = channel << 3; 35 + adc->buffer[1] = 0; 36 + 37 + ret = spi_write(adc->spi, &adc->buffer, 2); 38 + if (ret < 0) { 39 + mutex_unlock(&adc->lock); 40 + return ret; 41 + } 42 + 43 + ret = spi_read(adc->spi, &adc->buffer, 2); 44 + 45 + mutex_unlock(&adc->lock); 46 + 47 + if (ret < 0) 48 + return ret; 49 + 50 + return ((adc->buffer[0] << 8 | adc->buffer[1]) & 0xFFF); 51 + } 52 + 53 + static int adc128_read_raw(struct iio_dev *indio_dev, 54 + struct iio_chan_spec const *channel, int *val, 55 + int *val2, long mask) 56 + { 57 + struct adc128 *adc = iio_priv(indio_dev); 58 + int ret; 59 + 60 + switch (mask) { 61 + case IIO_CHAN_INFO_RAW: 62 + 63 + ret = adc128_adc_conversion(adc, channel->channel); 64 + if (ret < 0) 65 + return ret; 66 + 67 + *val = ret; 68 + return IIO_VAL_INT; 69 + 70 + case IIO_CHAN_INFO_SCALE: 71 + 72 + ret = regulator_get_voltage(adc->reg); 73 + if (ret < 0) 74 + return ret; 75 + 76 + *val = ret / 1000; 77 + *val2 = 12; 78 + return IIO_VAL_FRACTIONAL_LOG2; 79 + 80 + default: 81 + return -EINVAL; 82 + } 83 + 84 + } 85 + 86 + #define ADC128_VOLTAGE_CHANNEL(num) \ 87 + { \ 88 + .type = IIO_VOLTAGE, \ 89 + .indexed = 1, \ 90 + .channel = (num), \ 91 + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 92 + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) \ 93 + } 94 + 95 + static const struct iio_chan_spec adc128_channels[] = { 96 + ADC128_VOLTAGE_CHANNEL(0), 97 + ADC128_VOLTAGE_CHANNEL(1), 98 + ADC128_VOLTAGE_CHANNEL(2), 99 + ADC128_VOLTAGE_CHANNEL(3), 100 + ADC128_VOLTAGE_CHANNEL(4), 101 + ADC128_VOLTAGE_CHANNEL(5), 102 + ADC128_VOLTAGE_CHANNEL(6), 103 + ADC128_VOLTAGE_CHANNEL(7), 104 + }; 105 + 106 + static const struct iio_info adc128_info = { 107 + .read_raw = adc128_read_raw, 108 + .driver_module = THIS_MODULE, 109 + }; 110 + 111 + static int adc128_probe(struct spi_device *spi) 112 + { 113 + struct iio_dev *indio_dev; 114 + struct adc128 *adc; 115 + int ret; 116 + 117 + indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adc)); 118 + if (!indio_dev) 119 + return -ENOMEM; 120 + 121 + adc = iio_priv(indio_dev); 122 + adc->spi = spi; 123 + 124 + spi_set_drvdata(spi, indio_dev); 125 + 126 + indio_dev->dev.parent = &spi->dev; 127 + indio_dev->name = spi_get_device_id(spi)->name; 128 + indio_dev->modes = INDIO_DIRECT_MODE; 129 + indio_dev->info = &adc128_info; 130 + 131 + indio_dev->channels = adc128_channels; 132 + indio_dev->num_channels = ARRAY_SIZE(adc128_channels); 133 + 134 + adc->reg = devm_regulator_get(&spi->dev, "vref"); 135 + if (IS_ERR(adc->reg)) 136 + return PTR_ERR(adc->reg); 137 + 138 + ret = regulator_enable(adc->reg); 139 + if (ret < 0) 140 + return ret; 141 + 142 + mutex_init(&adc->lock); 143 + 144 + ret = iio_device_register(indio_dev); 145 + 146 + return ret; 147 + } 148 + 149 + static int adc128_remove(struct spi_device *spi) 150 + { 151 + struct iio_dev *indio_dev = spi_get_drvdata(spi); 152 + struct adc128 *adc = iio_priv(indio_dev); 153 + 154 + iio_device_unregister(indio_dev); 155 + regulator_disable(adc->reg); 156 + 157 + return 0; 158 + } 159 + 160 + static const struct spi_device_id adc128_id[] = { 161 + { "adc128s052", 0}, 162 + { } 163 + }; 164 + MODULE_DEVICE_TABLE(spi, adc128_id); 165 + 166 + static struct spi_driver adc128_driver = { 167 + .driver = { 168 + .name = "adc128s052", 169 + .owner = THIS_MODULE, 170 + }, 171 + .probe = adc128_probe, 172 + .remove = adc128_remove, 173 + .id_table = adc128_id, 174 + }; 175 + module_spi_driver(adc128_driver); 176 + 177 + MODULE_AUTHOR("Angelo Compagnucci <angelo.compagnucci@gmail.com>"); 178 + MODULE_DESCRIPTION("Texas Instruments ADC128S052"); 179 + MODULE_LICENSE("GPL v2");