Skip to content

Commit

Permalink
ti-adc081c: Add support for adc101c and adc121c
Browse files Browse the repository at this point in the history
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.pdf

Signed-off-by: Crestez Dan Leonard <leonard.crestez@intel.com>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
  • Loading branch information
Crestez Dan Leonard authored and Jonathan Cameron committed Apr 17, 2016
1 parent 98a5253 commit a6b5ec8
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 7 deletions.
6 changes: 3 additions & 3 deletions drivers/iio/adc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -385,11 +385,11 @@ config ROCKCHIP_SARADC
module will be called rockchip_saradc.

config TI_ADC081C
tristate "Texas Instruments ADC081C021/027"
tristate "Texas Instruments ADC081C/ADC101C/ADC121C family"
depends on I2C
help
If you say yes here you get support for Texas Instruments ADC081C021
and ADC081C027 ADC chips.
If you say yes here you get support for Texas Instruments ADC081C,
ADC101C and ADC121C ADC chips.

This driver can also be built as a module. If so, the module will be
called ti-adc081c.
Expand Down
51 changes: 47 additions & 4 deletions drivers/iio/adc/ti-adc081c.c
Original file line number Diff line number Diff line change
@@ -1,9 +1,21 @@
/*
* TI ADC081C/ADC101C/ADC121C 8/10/12-bit ADC driver
*
* Copyright (C) 2012 Avionic Design GmbH
* Copyright (C) 2016 Intel
*
* 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
* 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>
Expand All @@ -17,6 +29,9 @@
struct adc081c {
struct i2c_client *i2c;
struct regulator *ref;

/* 8, 10 or 12 */
int bits;
};

#define REG_CONV_RES 0x00
Expand All @@ -34,7 +49,7 @@ static int adc081c_read_raw(struct iio_dev *iio,
if (err < 0)
return err;

*value = (err >> 4) & 0xff;
*value = (err & 0xFFF) >> (12 - adc->bits);
return IIO_VAL_INT;

case IIO_CHAN_INFO_SCALE:
Expand All @@ -43,7 +58,7 @@ static int adc081c_read_raw(struct iio_dev *iio,
return err;

*value = err / 1000;
*shift = 8;
*shift = adc->bits;

return IIO_VAL_FRACTIONAL_LOG2;

Expand All @@ -60,6 +75,28 @@ static const struct iio_chan_spec adc081c_channel = {
.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 = {
.read_raw = adc081c_read_raw,
.driver_module = THIS_MODULE,
Expand All @@ -70,6 +107,7 @@ static int adc081c_probe(struct i2c_client *client,
{
struct iio_dev *iio;
struct adc081c *adc;
struct adcxx1c_model *model = &adcxx1c_models[id->driver_data];
int err;

if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA))
Expand All @@ -81,6 +119,7 @@ static int adc081c_probe(struct i2c_client *client,

adc = iio_priv(iio);
adc->i2c = client;
adc->bits = model->bits;

adc->ref = devm_regulator_get(&client->dev, "vref");
if (IS_ERR(adc->ref))
Expand Down Expand Up @@ -124,14 +163,18 @@ static int adc081c_remove(struct i2c_client *client)
}

static const struct i2c_device_id adc081c_id[] = {
{ "adc081c", 0 },
{ "adc081c", ADC081C },
{ "adc101c", ADC101C },
{ "adc121c", ADC121C },
{ }
};
MODULE_DEVICE_TABLE(i2c, adc081c_id);

#ifdef CONFIG_OF
static const struct of_device_id adc081c_of_match[] = {
{ .compatible = "ti,adc081c" },
{ .compatible = "ti,adc101c" },
{ .compatible = "ti,adc121c" },
{ }
};
MODULE_DEVICE_TABLE(of, adc081c_of_match);
Expand All @@ -149,5 +192,5 @@ static struct i2c_driver adc081c_driver = {
module_i2c_driver(adc081c_driver);

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");

0 comments on commit a6b5ec8

Please sign in to comment.