Commit a6b5ec88 authored by Crestez Dan Leonard's avatar Crestez Dan Leonard Committed by Jonathan Cameron

ti-adc081c: Add support for adc101c and adc121c

These chips have an almost identical interface but support a different
number of value bits. Datasheet links for comparison:

 * http://www.ti.com/lit/ds/symlink/adc081c021.pdf
 * http://www.ti.com/lit/ds/symlink/adc101c021.pdf
 * http://www.ti.com/lit/ds/symlink/adc121c021.pdfSigned-off-by: default avatarCrestez Dan Leonard <leonard.crestez@intel.com>
Signed-off-by: default avatarJonathan Cameron <jic23@kernel.org>
parent 98a52530
...@@ -385,11 +385,11 @@ config ROCKCHIP_SARADC ...@@ -385,11 +385,11 @@ config ROCKCHIP_SARADC
module will be called rockchip_saradc. module will be called rockchip_saradc.
config TI_ADC081C config TI_ADC081C
tristate "Texas Instruments ADC081C021/027" tristate "Texas Instruments ADC081C/ADC101C/ADC121C family"
depends on I2C depends on I2C
help help
If you say yes here you get support for Texas Instruments ADC081C021 If you say yes here you get support for Texas Instruments ADC081C,
and ADC081C027 ADC chips. ADC101C and ADC121C ADC chips.
This driver can also be built as a module. If so, the module will be This driver can also be built as a module. If so, the module will be
called ti-adc081c. called ti-adc081c.
......
/* /*
* TI ADC081C/ADC101C/ADC121C 8/10/12-bit ADC driver
*
* Copyright (C) 2012 Avionic Design GmbH * Copyright (C) 2012 Avionic Design GmbH
* Copyright (C) 2016 Intel
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. * published by the Free Software Foundation.
*
* Datasheets:
* http://www.ti.com/lit/ds/symlink/adc081c021.pdf
* http://www.ti.com/lit/ds/symlink/adc101c021.pdf
* http://www.ti.com/lit/ds/symlink/adc121c021.pdf
*
* The devices have a very similar interface and differ mostly in the number of
* bits handled. For the 8-bit and 10-bit models the least-significant 4 or 2
* bits of value registers are reserved.
*/ */
#include <linux/err.h> #include <linux/err.h>
...@@ -17,6 +29,9 @@ ...@@ -17,6 +29,9 @@
struct adc081c { struct adc081c {
struct i2c_client *i2c; struct i2c_client *i2c;
struct regulator *ref; struct regulator *ref;
/* 8, 10 or 12 */
int bits;
}; };
#define REG_CONV_RES 0x00 #define REG_CONV_RES 0x00
...@@ -34,7 +49,7 @@ static int adc081c_read_raw(struct iio_dev *iio, ...@@ -34,7 +49,7 @@ static int adc081c_read_raw(struct iio_dev *iio,
if (err < 0) if (err < 0)
return err; return err;
*value = (err >> 4) & 0xff; *value = (err & 0xFFF) >> (12 - adc->bits);
return IIO_VAL_INT; return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE: case IIO_CHAN_INFO_SCALE:
...@@ -43,7 +58,7 @@ static int adc081c_read_raw(struct iio_dev *iio, ...@@ -43,7 +58,7 @@ static int adc081c_read_raw(struct iio_dev *iio,
return err; return err;
*value = err / 1000; *value = err / 1000;
*shift = 8; *shift = adc->bits;
return IIO_VAL_FRACTIONAL_LOG2; return IIO_VAL_FRACTIONAL_LOG2;
...@@ -60,6 +75,28 @@ static const struct iio_chan_spec adc081c_channel = { ...@@ -60,6 +75,28 @@ static const struct iio_chan_spec adc081c_channel = {
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
}; };
struct adcxx1c_model {
int bits;
};
#define ADCxx1C_MODEL(_bits) \
{ \
.bits = (_bits), \
}
/* Model ids are indexes in _models array */
enum adcxx1c_model_id {
ADC081C = 0,
ADC101C = 1,
ADC121C = 2,
};
static struct adcxx1c_model adcxx1c_models[] = {
ADCxx1C_MODEL( 8),
ADCxx1C_MODEL(10),
ADCxx1C_MODEL(12),
};
static const struct iio_info adc081c_info = { static const struct iio_info adc081c_info = {
.read_raw = adc081c_read_raw, .read_raw = adc081c_read_raw,
.driver_module = THIS_MODULE, .driver_module = THIS_MODULE,
...@@ -70,6 +107,7 @@ static int adc081c_probe(struct i2c_client *client, ...@@ -70,6 +107,7 @@ static int adc081c_probe(struct i2c_client *client,
{ {
struct iio_dev *iio; struct iio_dev *iio;
struct adc081c *adc; struct adc081c *adc;
struct adcxx1c_model *model = &adcxx1c_models[id->driver_data];
int err; int err;
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA)) if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA))
...@@ -81,6 +119,7 @@ static int adc081c_probe(struct i2c_client *client, ...@@ -81,6 +119,7 @@ static int adc081c_probe(struct i2c_client *client,
adc = iio_priv(iio); adc = iio_priv(iio);
adc->i2c = client; adc->i2c = client;
adc->bits = model->bits;
adc->ref = devm_regulator_get(&client->dev, "vref"); adc->ref = devm_regulator_get(&client->dev, "vref");
if (IS_ERR(adc->ref)) if (IS_ERR(adc->ref))
...@@ -124,7 +163,9 @@ static int adc081c_remove(struct i2c_client *client) ...@@ -124,7 +163,9 @@ static int adc081c_remove(struct i2c_client *client)
} }
static const struct i2c_device_id adc081c_id[] = { static const struct i2c_device_id adc081c_id[] = {
{ "adc081c", 0 }, { "adc081c", ADC081C },
{ "adc101c", ADC101C },
{ "adc121c", ADC121C },
{ } { }
}; };
MODULE_DEVICE_TABLE(i2c, adc081c_id); MODULE_DEVICE_TABLE(i2c, adc081c_id);
...@@ -132,6 +173,8 @@ MODULE_DEVICE_TABLE(i2c, adc081c_id); ...@@ -132,6 +173,8 @@ MODULE_DEVICE_TABLE(i2c, adc081c_id);
#ifdef CONFIG_OF #ifdef CONFIG_OF
static const struct of_device_id adc081c_of_match[] = { static const struct of_device_id adc081c_of_match[] = {
{ .compatible = "ti,adc081c" }, { .compatible = "ti,adc081c" },
{ .compatible = "ti,adc101c" },
{ .compatible = "ti,adc121c" },
{ } { }
}; };
MODULE_DEVICE_TABLE(of, adc081c_of_match); MODULE_DEVICE_TABLE(of, adc081c_of_match);
...@@ -149,5 +192,5 @@ static struct i2c_driver adc081c_driver = { ...@@ -149,5 +192,5 @@ static struct i2c_driver adc081c_driver = {
module_i2c_driver(adc081c_driver); module_i2c_driver(adc081c_driver);
MODULE_AUTHOR("Thierry Reding <thierry.reding@avionic-design.de>"); MODULE_AUTHOR("Thierry Reding <thierry.reding@avionic-design.de>");
MODULE_DESCRIPTION("Texas Instruments ADC081C021/027 driver"); MODULE_DESCRIPTION("Texas Instruments ADC081C/ADC101C/ADC121C driver");
MODULE_LICENSE("GPL v2"); MODULE_LICENSE("GPL v2");
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment