These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / iio / adc / ti-adc128s052.c
index 655cb56..ff6f7f6 100644 (file)
@@ -1,9 +1,10 @@
 /*
  * Copyright (C) 2014 Angelo Compagnucci <angelo.compagnucci@gmail.com>
  *
- * Driver for Texas Instruments' ADC128S052 ADC chip.
- * Datasheet can be found here:
+ * Driver for Texas Instruments' ADC128S052 and ADC122S021 ADC chip.
+ * Datasheets can be found here:
  * http://www.ti.com/lit/ds/symlink/adc128s052.pdf
+ * http://www.ti.com/lit/ds/symlink/adc122s021.pdf
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
 #include <linux/iio/iio.h>
 #include <linux/regulator/consumer.h>
 
+struct adc128_configuration {
+       const struct iio_chan_spec      *channels;
+       u8                              num_channels;
+};
+
 struct adc128 {
        struct spi_device *spi;
 
@@ -92,7 +98,7 @@ static int adc128_read_raw(struct iio_dev *indio_dev,
                .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) \
        }
 
-static const struct iio_chan_spec adc128_channels[] = {
+static const struct iio_chan_spec adc128s052_channels[] = {
        ADC128_VOLTAGE_CHANNEL(0),
        ADC128_VOLTAGE_CHANNEL(1),
        ADC128_VOLTAGE_CHANNEL(2),
@@ -103,6 +109,16 @@ static const struct iio_chan_spec adc128_channels[] = {
        ADC128_VOLTAGE_CHANNEL(7),
 };
 
+static const struct iio_chan_spec adc122s021_channels[] = {
+       ADC128_VOLTAGE_CHANNEL(0),
+       ADC128_VOLTAGE_CHANNEL(1),
+};
+
+static const struct adc128_configuration adc128_config[] = {
+       { adc128s052_channels, ARRAY_SIZE(adc128s052_channels) },
+       { adc122s021_channels, ARRAY_SIZE(adc122s021_channels) },
+};
+
 static const struct iio_info adc128_info = {
        .read_raw = adc128_read_raw,
        .driver_module = THIS_MODULE,
@@ -112,6 +128,7 @@ static int adc128_probe(struct spi_device *spi)
 {
        struct iio_dev *indio_dev;
        struct adc128 *adc;
+       int config = spi_get_device_id(spi)->driver_data;
        int ret;
 
        indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adc));
@@ -128,8 +145,8 @@ static int adc128_probe(struct spi_device *spi)
        indio_dev->modes = INDIO_DIRECT_MODE;
        indio_dev->info = &adc128_info;
 
-       indio_dev->channels = adc128_channels;
-       indio_dev->num_channels = ARRAY_SIZE(adc128_channels);
+       indio_dev->channels = adc128_config[config].channels;
+       indio_dev->num_channels = adc128_config[config].num_channels;
 
        adc->reg = devm_regulator_get(&spi->dev, "vref");
        if (IS_ERR(adc->reg))
@@ -157,8 +174,16 @@ static int adc128_remove(struct spi_device *spi)
        return 0;
 }
 
+static const struct of_device_id adc128_of_match[] = {
+       { .compatible = "ti,adc128s052", },
+       { .compatible = "ti,adc122s021", },
+       { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, adc128_of_match);
+
 static const struct spi_device_id adc128_id[] = {
-       { "adc128s052", 0},
+       { "adc128s052", 0},     /* index into adc128_config */
+       { "adc122s021", 1},
        { }
 };
 MODULE_DEVICE_TABLE(spi, adc128_id);
@@ -166,7 +191,7 @@ MODULE_DEVICE_TABLE(spi, adc128_id);
 static struct spi_driver adc128_driver = {
        .driver = {
                .name = "adc128s052",
-               .owner = THIS_MODULE,
+               .of_match_table = of_match_ptr(adc128_of_match),
        },
        .probe = adc128_probe,
        .remove = adc128_remove,