Commit 60c1f31f authored by Evgeniy Dushistov's avatar Evgeniy Dushistov Committed by Guenter Roeck

hwmon: (ads1015) Add support for ADS1115

This patch adds support for ads1115 device to ads1015 driver.
Based on work of Emiliano Carnati <carnatiatebneuro.com>.
Tested on ARM CPU based board.
Signed-off-by: default avatarEvgeniy A. Dushistov <dushistov@mail.ru>
Signed-off-by: default avatarGuenter Roeck <linux@roeck-us.net>
parent e3b20b3f
...@@ -6,6 +6,10 @@ Supported chips: ...@@ -6,6 +6,10 @@ Supported chips:
Prefix: 'ads1015' Prefix: 'ads1015'
Datasheet: Publicly available at the Texas Instruments website : Datasheet: Publicly available at the Texas Instruments website :
http://focus.ti.com/lit/ds/symlink/ads1015.pdf http://focus.ti.com/lit/ds/symlink/ads1015.pdf
* Texas Instruments ADS1115
Prefix: 'ads1115'
Datasheet: Publicly available at the Texas Instruments website :
http://focus.ti.com/lit/ds/symlink/ads1115.pdf
Authors: Authors:
Dirk Eibach, Guntermann & Drunck GmbH <eibach@gdsys.de> Dirk Eibach, Guntermann & Drunck GmbH <eibach@gdsys.de>
...@@ -13,9 +17,9 @@ Authors: ...@@ -13,9 +17,9 @@ Authors:
Description Description
----------- -----------
This driver implements support for the Texas Instruments ADS1015. This driver implements support for the Texas Instruments ADS1015/ADS1115.
This device is a 12-bit A-D converter with 4 inputs. This device is a 12/16-bit A-D converter with 4 inputs.
The inputs can be used single ended or in certain differential combinations. The inputs can be used single ended or in certain differential combinations.
......
...@@ -1202,8 +1202,8 @@ config SENSORS_ADS1015 ...@@ -1202,8 +1202,8 @@ config SENSORS_ADS1015
tristate "Texas Instruments ADS1015" tristate "Texas Instruments ADS1015"
depends on I2C depends on I2C
help help
If you say yes here you get support for Texas Instruments ADS1015 If you say yes here you get support for Texas Instruments
12-bit 4-input ADC device. ADS1015/ADS1115 12/16-bit 4-input ADC device.
This driver can also be built as a module. If so, the module This driver can also be built as a module. If so, the module
will be called ads1015. will be called ads1015.
......
...@@ -46,17 +46,28 @@ static const unsigned int fullscale_table[8] = { ...@@ -46,17 +46,28 @@ static const unsigned int fullscale_table[8] = {
6144, 4096, 2048, 1024, 512, 256, 256, 256 }; 6144, 4096, 2048, 1024, 512, 256, 256, 256 };
/* Data rates in samples per second */ /* Data rates in samples per second */
static const unsigned int data_rate_table[8] = { static const unsigned int data_rate_table_1015[8] = {
128, 250, 490, 920, 1600, 2400, 3300, 3300 }; 128, 250, 490, 920, 1600, 2400, 3300, 3300
};
static const unsigned int data_rate_table_1115[8] = {
8, 16, 32, 64, 128, 250, 475, 860
};
#define ADS1015_DEFAULT_CHANNELS 0xff #define ADS1015_DEFAULT_CHANNELS 0xff
#define ADS1015_DEFAULT_PGA 2 #define ADS1015_DEFAULT_PGA 2
#define ADS1015_DEFAULT_DATA_RATE 4 #define ADS1015_DEFAULT_DATA_RATE 4
enum ads1015_chips {
ads1015,
ads1115,
};
struct ads1015_data { struct ads1015_data {
struct device *hwmon_dev; struct device *hwmon_dev;
struct mutex update_lock; /* mutex protect updates */ struct mutex update_lock; /* mutex protect updates */
struct ads1015_channel_data channel_data[ADS1015_CHANNELS]; struct ads1015_channel_data channel_data[ADS1015_CHANNELS];
enum ads1015_chips id;
}; };
static int ads1015_read_adc(struct i2c_client *client, unsigned int channel) static int ads1015_read_adc(struct i2c_client *client, unsigned int channel)
...@@ -66,6 +77,8 @@ static int ads1015_read_adc(struct i2c_client *client, unsigned int channel) ...@@ -66,6 +77,8 @@ static int ads1015_read_adc(struct i2c_client *client, unsigned int channel)
unsigned int pga = data->channel_data[channel].pga; unsigned int pga = data->channel_data[channel].pga;
unsigned int data_rate = data->channel_data[channel].data_rate; unsigned int data_rate = data->channel_data[channel].data_rate;
unsigned int conversion_time_ms; unsigned int conversion_time_ms;
const unsigned int * const rate_table = data->id == ads1115 ?
data_rate_table_1115 : data_rate_table_1015;
int res; int res;
mutex_lock(&data->update_lock); mutex_lock(&data->update_lock);
...@@ -75,7 +88,7 @@ static int ads1015_read_adc(struct i2c_client *client, unsigned int channel) ...@@ -75,7 +88,7 @@ static int ads1015_read_adc(struct i2c_client *client, unsigned int channel)
if (res < 0) if (res < 0)
goto err_unlock; goto err_unlock;
config = res; config = res;
conversion_time_ms = DIV_ROUND_UP(1000, data_rate_table[data_rate]); conversion_time_ms = DIV_ROUND_UP(1000, rate_table[data_rate]);
/* setup and start single conversion */ /* setup and start single conversion */
config &= 0x001f; config &= 0x001f;
...@@ -113,8 +126,9 @@ static int ads1015_reg_to_mv(struct i2c_client *client, unsigned int channel, ...@@ -113,8 +126,9 @@ static int ads1015_reg_to_mv(struct i2c_client *client, unsigned int channel,
struct ads1015_data *data = i2c_get_clientdata(client); struct ads1015_data *data = i2c_get_clientdata(client);
unsigned int pga = data->channel_data[channel].pga; unsigned int pga = data->channel_data[channel].pga;
int fullscale = fullscale_table[pga]; int fullscale = fullscale_table[pga];
const unsigned mask = data->id == ads1115 ? 0x7fff : 0x7ff0;
return DIV_ROUND_CLOSEST(reg * fullscale, 0x7ff0); return DIV_ROUND_CLOSEST(reg * fullscale, mask);
} }
/* sysfs callback function */ /* sysfs callback function */
...@@ -257,7 +271,7 @@ static int ads1015_probe(struct i2c_client *client, ...@@ -257,7 +271,7 @@ static int ads1015_probe(struct i2c_client *client,
GFP_KERNEL); GFP_KERNEL);
if (!data) if (!data)
return -ENOMEM; return -ENOMEM;
data->id = id->driver_data;
i2c_set_clientdata(client, data); i2c_set_clientdata(client, data);
mutex_init(&data->update_lock); mutex_init(&data->update_lock);
...@@ -286,7 +300,8 @@ static int ads1015_probe(struct i2c_client *client, ...@@ -286,7 +300,8 @@ static int ads1015_probe(struct i2c_client *client,
} }
static const struct i2c_device_id ads1015_id[] = { static const struct i2c_device_id ads1015_id[] = {
{ "ads1015", 0 }, { "ads1015", ads1015},
{ "ads1115", ads1115},
{ } { }
}; };
MODULE_DEVICE_TABLE(i2c, ads1015_id); MODULE_DEVICE_TABLE(i2c, ads1015_id);
......
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