Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+6 −2
Original line number Original line Diff line number Diff line
@@ -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:
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.


+2 −2
Original line number Original line Diff line number Diff line
@@ -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.
+21 −6
Original line number Original line Diff line number Diff line
@@ -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)
	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)
	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,
	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,
			    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,
}
}


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