On Mon, 1 Jul 2019 11:12:38 -0700 Guenter Roeck <linux@xxxxxxxxxxxx> wrote: > A driver for ADS1015 with more functionality is available in the iio > subsystem. > > Remove the hwmon driver as duplicate. If the chip is used for hardware > monitoring, the iio->hwmon bridge should be used. > > Cc: Dirk Eibach <eibach@xxxxxxxx> > Signed-off-by: Guenter Roeck <linux@xxxxxxxxxxxx> On the basis I agree with the concept of dropping this driver: Acked-by: Jonathan Cameron <Jonathan.Cameron@xxxxxxxxxx> Thanks for tidying this up. Jonathan > --- > Current plan is to queue this removal for v5.4 (not v5.3) in the hwmon > tree. > > .../devicetree/bindings/hwmon/ads1015.txt | 73 ----- > .../devicetree/bindings/iio/adc/ads1015.txt | 73 +++++ > Documentation/hwmon/ads1015.rst | 90 ------ > Documentation/hwmon/index.rst | 1 - > MAINTAINERS | 8 - > drivers/hwmon/Kconfig | 10 - > drivers/hwmon/Makefile | 1 - > drivers/hwmon/ads1015.c | 324 --------------------- > drivers/iio/adc/Kconfig | 2 +- > 9 files changed, 74 insertions(+), 508 deletions(-) > delete mode 100644 Documentation/devicetree/bindings/hwmon/ads1015.txt > create mode 100644 Documentation/devicetree/bindings/iio/adc/ads1015.txt > delete mode 100644 Documentation/hwmon/ads1015.rst > delete mode 100644 drivers/hwmon/ads1015.c > > diff --git a/Documentation/devicetree/bindings/hwmon/ads1015.txt b/Documentation/devicetree/bindings/hwmon/ads1015.txt > deleted file mode 100644 > index 918a507d1159..000000000000 > --- a/Documentation/devicetree/bindings/hwmon/ads1015.txt > +++ /dev/null > @@ -1,73 +0,0 @@ > -ADS1015 (I2C) > - > -This device is a 12-bit A-D converter with 4 inputs. > - > -The inputs can be used single ended or in certain differential combinations. > - > -For configuration all possible combinations are mapped to 8 channels: > - 0: Voltage over AIN0 and AIN1. > - 1: Voltage over AIN0 and AIN3. > - 2: Voltage over AIN1 and AIN3. > - 3: Voltage over AIN2 and AIN3. > - 4: Voltage over AIN0 and GND. > - 5: Voltage over AIN1 and GND. > - 6: Voltage over AIN2 and GND. > - 7: Voltage over AIN3 and GND. > - > -Each channel can be configured individually: > - - pga is the programmable gain amplifier (values are full scale) > - 0: +/- 6.144 V > - 1: +/- 4.096 V > - 2: +/- 2.048 V (default) > - 3: +/- 1.024 V > - 4: +/- 0.512 V > - 5: +/- 0.256 V > - - data_rate in samples per second > - 0: 128 > - 1: 250 > - 2: 490 > - 3: 920 > - 4: 1600 (default) > - 5: 2400 > - 6: 3300 > - > -1) The /ads1015 node > - > - Required properties: > - > - - compatible : must be "ti,ads1015" > - - reg : I2C bus address of the device > - - #address-cells : must be <1> > - - #size-cells : must be <0> > - > - The node contains child nodes for each channel that the platform uses. > - > - Example ADS1015 node: > - > - ads1015@49 { > - compatible = "ti,ads1015"; > - reg = <0x49>; > - #address-cells = <1>; > - #size-cells = <0>; > - > - [ child node definitions... ] > - } > - > -2) channel nodes > - > - Required properties: > - > - - reg : the channel number > - > - Optional properties: > - > - - ti,gain : the programmable gain amplifier setting > - - ti,datarate : the converter data rate > - > - Example ADS1015 channel node: > - > - channel@4 { > - reg = <4>; > - ti,gain = <3>; > - ti,datarate = <5>; > - }; > diff --git a/Documentation/devicetree/bindings/iio/adc/ads1015.txt b/Documentation/devicetree/bindings/iio/adc/ads1015.txt > new file mode 100644 > index 000000000000..918a507d1159 > --- /dev/null > +++ b/Documentation/devicetree/bindings/iio/adc/ads1015.txt > @@ -0,0 +1,73 @@ > +ADS1015 (I2C) > + > +This device is a 12-bit A-D converter with 4 inputs. > + > +The inputs can be used single ended or in certain differential combinations. > + > +For configuration all possible combinations are mapped to 8 channels: > + 0: Voltage over AIN0 and AIN1. > + 1: Voltage over AIN0 and AIN3. > + 2: Voltage over AIN1 and AIN3. > + 3: Voltage over AIN2 and AIN3. > + 4: Voltage over AIN0 and GND. > + 5: Voltage over AIN1 and GND. > + 6: Voltage over AIN2 and GND. > + 7: Voltage over AIN3 and GND. > + > +Each channel can be configured individually: > + - pga is the programmable gain amplifier (values are full scale) > + 0: +/- 6.144 V > + 1: +/- 4.096 V > + 2: +/- 2.048 V (default) > + 3: +/- 1.024 V > + 4: +/- 0.512 V > + 5: +/- 0.256 V > + - data_rate in samples per second > + 0: 128 > + 1: 250 > + 2: 490 > + 3: 920 > + 4: 1600 (default) > + 5: 2400 > + 6: 3300 > + > +1) The /ads1015 node > + > + Required properties: > + > + - compatible : must be "ti,ads1015" > + - reg : I2C bus address of the device > + - #address-cells : must be <1> > + - #size-cells : must be <0> > + > + The node contains child nodes for each channel that the platform uses. > + > + Example ADS1015 node: > + > + ads1015@49 { > + compatible = "ti,ads1015"; > + reg = <0x49>; > + #address-cells = <1>; > + #size-cells = <0>; > + > + [ child node definitions... ] > + } > + > +2) channel nodes > + > + Required properties: > + > + - reg : the channel number > + > + Optional properties: > + > + - ti,gain : the programmable gain amplifier setting > + - ti,datarate : the converter data rate > + > + Example ADS1015 channel node: > + > + channel@4 { > + reg = <4>; > + ti,gain = <3>; > + ti,datarate = <5>; > + }; > diff --git a/Documentation/hwmon/ads1015.rst b/Documentation/hwmon/ads1015.rst > deleted file mode 100644 > index e0951c4e57bb..000000000000 > --- a/Documentation/hwmon/ads1015.rst > +++ /dev/null > @@ -1,90 +0,0 @@ > -Kernel driver ads1015 > -===================== > - > -Supported chips: > - > - * Texas Instruments ADS1015 > - > - Prefix: 'ads1015' > - > - Datasheet: Publicly available at the Texas Instruments website: > - > - 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: > - Dirk Eibach, Guntermann & Drunck GmbH <eibach@xxxxxxxx> > - > -Description > ------------ > - > -This driver implements support for the Texas Instruments ADS1015/ADS1115. > - > -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 made available by 8 sysfs input files in0_input - in7_input: > - > - - in0: Voltage over AIN0 and AIN1. > - - in1: Voltage over AIN0 and AIN3. > - - in2: Voltage over AIN1 and AIN3. > - - in3: Voltage over AIN2 and AIN3. > - - in4: Voltage over AIN0 and GND. > - - in5: Voltage over AIN1 and GND. > - - in6: Voltage over AIN2 and GND. > - - in7: Voltage over AIN3 and GND. > - > -Which inputs are available can be configured using platform data or devicetree. > - > -By default all inputs are exported. > - > -Platform Data > -------------- > - > -In linux/platform_data/ads1015.h platform data is defined, channel_data contains > -configuration data for the used input combinations: > - > -- pga is the programmable gain amplifier (values are full scale) > - > - - 0: +/- 6.144 V > - - 1: +/- 4.096 V > - - 2: +/- 2.048 V > - - 3: +/- 1.024 V > - - 4: +/- 0.512 V > - - 5: +/- 0.256 V > - > -- data_rate in samples per second > - > - - 0: 128 > - - 1: 250 > - - 2: 490 > - - 3: 920 > - - 4: 1600 > - - 5: 2400 > - - 6: 3300 > - > -Example:: > - > - struct ads1015_platform_data data = { > - .channel_data = { > - [2] = { .enabled = true, .pga = 1, .data_rate = 0 }, > - [4] = { .enabled = true, .pga = 4, .data_rate = 5 }, > - } > - }; > - > -In this case only in2_input (FS +/- 4.096 V, 128 SPS) and in4_input > -(FS +/- 0.512 V, 2400 SPS) would be created. > - > -Devicetree > ----------- > - > -Configuration is also possible via devicetree: > -Documentation/devicetree/bindings/hwmon/ads1015.txt > diff --git a/Documentation/hwmon/index.rst b/Documentation/hwmon/index.rst > index ee090e51653a..1d301d0e6f4d 100644 > --- a/Documentation/hwmon/index.rst > +++ b/Documentation/hwmon/index.rst > @@ -30,7 +30,6 @@ Hardware Monitoring Kernel Drivers > adm1031 > adm1275 > adm9240 > - ads1015 > ads7828 > adt7410 > adt7411 > diff --git a/MAINTAINERS b/MAINTAINERS > index 01a52fc964da..11744a3735f0 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -517,14 +517,6 @@ W: http://ez.analog.com/community/linux-device-drivers > S: Supported > F: drivers/video/backlight/adp8860_bl.c > > -ADS1015 HARDWARE MONITOR DRIVER > -M: Dirk Eibach <eibach@xxxxxxxx> > -L: linux-hwmon@xxxxxxxxxxxxxxx > -S: Maintained > -F: Documentation/hwmon/ads1015.rst > -F: drivers/hwmon/ads1015.c > -F: include/linux/platform_data/ads1015.h > - > ADT746X FAN DRIVER > M: Colin Leroy <colin@xxxxxxxxxx> > S: Maintained > diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig > index 650dd71f9724..76cd0647ee2c 100644 > --- a/drivers/hwmon/Kconfig > +++ b/drivers/hwmon/Kconfig > @@ -1570,16 +1570,6 @@ config SENSORS_ADC128D818 > This driver can also be built as a module. If so, the module > will be called adc128d818. > > -config SENSORS_ADS1015 > - tristate "Texas Instruments ADS1015" > - depends on I2C > - help > - If you say yes here you get support for Texas Instruments > - ADS1015/ADS1115 12/16-bit 4-input ADC device. > - > - This driver can also be built as a module. If so, the module > - will be called ads1015. > - > config SENSORS_ADS7828 > tristate "Texas Instruments ADS7828 and compatibles" > depends on I2C > diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile > index 8db472ea04f0..6a52a964038b 100644 > --- a/drivers/hwmon/Makefile > +++ b/drivers/hwmon/Makefile > @@ -35,7 +35,6 @@ obj-$(CONFIG_SENSORS_ADM1026) += adm1026.o > obj-$(CONFIG_SENSORS_ADM1029) += adm1029.o > obj-$(CONFIG_SENSORS_ADM1031) += adm1031.o > obj-$(CONFIG_SENSORS_ADM9240) += adm9240.o > -obj-$(CONFIG_SENSORS_ADS1015) += ads1015.o > obj-$(CONFIG_SENSORS_ADS7828) += ads7828.o > obj-$(CONFIG_SENSORS_ADS7871) += ads7871.o > obj-$(CONFIG_SENSORS_ADT7X10) += adt7x10.o > diff --git a/drivers/hwmon/ads1015.c b/drivers/hwmon/ads1015.c > deleted file mode 100644 > index 3727a3762eb8..000000000000 > --- a/drivers/hwmon/ads1015.c > +++ /dev/null > @@ -1,324 +0,0 @@ > -// SPDX-License-Identifier: GPL-2.0-or-later > -/* > - * ads1015.c - lm_sensors driver for ads1015 12-bit 4-input ADC > - * (C) Copyright 2010 > - * Dirk Eibach, Guntermann & Drunck GmbH <eibach@xxxxxxxx> > - * > - * Based on the ads7828 driver by Steve Hardy. > - * > - * Datasheet available at: http://focus.ti.com/lit/ds/symlink/ads1015.pdf > - */ > - > -#include <linux/module.h> > -#include <linux/init.h> > -#include <linux/slab.h> > -#include <linux/delay.h> > -#include <linux/i2c.h> > -#include <linux/hwmon.h> > -#include <linux/hwmon-sysfs.h> > -#include <linux/err.h> > -#include <linux/mutex.h> > -#include <linux/of_device.h> > -#include <linux/of.h> > - > -#include <linux/platform_data/ads1015.h> > - > -/* ADS1015 registers */ > -enum { > - ADS1015_CONVERSION = 0, > - ADS1015_CONFIG = 1, > -}; > - > -/* PGA fullscale voltages in mV */ > -static const unsigned int fullscale_table[8] = { > - 6144, 4096, 2048, 1024, 512, 256, 256, 256 }; > - > -/* Data rates in samples per second */ > -static const unsigned int data_rate_table_1015[8] = { > - 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_PGA 2 > -#define ADS1015_DEFAULT_DATA_RATE 4 > - > -enum ads1015_chips { > - ads1015, > - ads1115, > -}; > - > -struct ads1015_data { > - struct device *hwmon_dev; > - struct mutex update_lock; /* mutex protect updates */ > - struct ads1015_channel_data channel_data[ADS1015_CHANNELS]; > - enum ads1015_chips id; > -}; > - > -static int ads1015_read_adc(struct i2c_client *client, unsigned int channel) > -{ > - u16 config; > - struct ads1015_data *data = i2c_get_clientdata(client); > - unsigned int pga = data->channel_data[channel].pga; > - unsigned int data_rate = data->channel_data[channel].data_rate; > - unsigned int conversion_time_ms; > - const unsigned int * const rate_table = data->id == ads1115 ? > - data_rate_table_1115 : data_rate_table_1015; > - int res; > - > - mutex_lock(&data->update_lock); > - > - /* get channel parameters */ > - res = i2c_smbus_read_word_swapped(client, ADS1015_CONFIG); > - if (res < 0) > - goto err_unlock; > - config = res; > - conversion_time_ms = DIV_ROUND_UP(1000, rate_table[data_rate]); > - > - /* setup and start single conversion */ > - config &= 0x001f; > - config |= (1 << 15) | (1 << 8); > - config |= (channel & 0x0007) << 12; > - config |= (pga & 0x0007) << 9; > - config |= (data_rate & 0x0007) << 5; > - > - res = i2c_smbus_write_word_swapped(client, ADS1015_CONFIG, config); > - if (res < 0) > - goto err_unlock; > - > - /* wait until conversion finished */ > - msleep(conversion_time_ms); > - res = i2c_smbus_read_word_swapped(client, ADS1015_CONFIG); > - if (res < 0) > - goto err_unlock; > - config = res; > - if (!(config & (1 << 15))) { > - /* conversion not finished in time */ > - res = -EIO; > - goto err_unlock; > - } > - > - res = i2c_smbus_read_word_swapped(client, ADS1015_CONVERSION); > - > -err_unlock: > - mutex_unlock(&data->update_lock); > - return res; > -} > - > -static int ads1015_reg_to_mv(struct i2c_client *client, unsigned int channel, > - s16 reg) > -{ > - struct ads1015_data *data = i2c_get_clientdata(client); > - unsigned int pga = data->channel_data[channel].pga; > - int fullscale = fullscale_table[pga]; > - const int mask = data->id == ads1115 ? 0x7fff : 0x7ff0; > - > - return DIV_ROUND_CLOSEST(reg * fullscale, mask); > -} > - > -/* sysfs callback function */ > -static ssize_t in_show(struct device *dev, struct device_attribute *da, > - char *buf) > -{ > - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); > - struct i2c_client *client = to_i2c_client(dev); > - int res; > - int index = attr->index; > - > - res = ads1015_read_adc(client, index); > - if (res < 0) > - return res; > - > - return sprintf(buf, "%d\n", ads1015_reg_to_mv(client, index, res)); > -} > - > -static const struct sensor_device_attribute ads1015_in[] = { > - SENSOR_ATTR_RO(in0_input, in, 0), > - SENSOR_ATTR_RO(in1_input, in, 1), > - SENSOR_ATTR_RO(in2_input, in, 2), > - SENSOR_ATTR_RO(in3_input, in, 3), > - SENSOR_ATTR_RO(in4_input, in, 4), > - SENSOR_ATTR_RO(in5_input, in, 5), > - SENSOR_ATTR_RO(in6_input, in, 6), > - SENSOR_ATTR_RO(in7_input, in, 7), > -}; > - > -/* > - * Driver interface > - */ > - > -static int ads1015_remove(struct i2c_client *client) > -{ > - struct ads1015_data *data = i2c_get_clientdata(client); > - int k; > - > - hwmon_device_unregister(data->hwmon_dev); > - for (k = 0; k < ADS1015_CHANNELS; ++k) > - device_remove_file(&client->dev, &ads1015_in[k].dev_attr); > - return 0; > -} > - > -#ifdef CONFIG_OF > -static int ads1015_get_channels_config_of(struct i2c_client *client) > -{ > - struct ads1015_data *data = i2c_get_clientdata(client); > - struct device_node *node; > - > - if (!client->dev.of_node > - || !of_get_next_child(client->dev.of_node, NULL)) > - return -EINVAL; > - > - for_each_child_of_node(client->dev.of_node, node) { > - u32 pval; > - unsigned int channel; > - unsigned int pga = ADS1015_DEFAULT_PGA; > - unsigned int data_rate = ADS1015_DEFAULT_DATA_RATE; > - > - if (of_property_read_u32(node, "reg", &pval)) { > - dev_err(&client->dev, "invalid reg on %pOF\n", node); > - continue; > - } > - > - channel = pval; > - if (channel >= ADS1015_CHANNELS) { > - dev_err(&client->dev, > - "invalid channel index %d on %pOF\n", > - channel, node); > - continue; > - } > - > - if (!of_property_read_u32(node, "ti,gain", &pval)) { > - pga = pval; > - if (pga > 6) { > - dev_err(&client->dev, "invalid gain on %pOF\n", > - node); > - return -EINVAL; > - } > - } > - > - if (!of_property_read_u32(node, "ti,datarate", &pval)) { > - data_rate = pval; > - if (data_rate > 7) { > - dev_err(&client->dev, > - "invalid data_rate on %pOF\n", node); > - return -EINVAL; > - } > - } > - > - data->channel_data[channel].enabled = true; > - data->channel_data[channel].pga = pga; > - data->channel_data[channel].data_rate = data_rate; > - } > - > - return 0; > -} > -#endif > - > -static void ads1015_get_channels_config(struct i2c_client *client) > -{ > - unsigned int k; > - struct ads1015_data *data = i2c_get_clientdata(client); > - struct ads1015_platform_data *pdata = dev_get_platdata(&client->dev); > - > - /* prefer platform data */ > - if (pdata) { > - memcpy(data->channel_data, pdata->channel_data, > - sizeof(data->channel_data)); > - return; > - } > - > -#ifdef CONFIG_OF > - if (!ads1015_get_channels_config_of(client)) > - return; > -#endif > - > - /* fallback on default configuration */ > - for (k = 0; k < ADS1015_CHANNELS; ++k) { > - data->channel_data[k].enabled = true; > - data->channel_data[k].pga = ADS1015_DEFAULT_PGA; > - data->channel_data[k].data_rate = ADS1015_DEFAULT_DATA_RATE; > - } > -} > - > -static int ads1015_probe(struct i2c_client *client, > - const struct i2c_device_id *id) > -{ > - struct ads1015_data *data; > - int err; > - unsigned int k; > - > - data = devm_kzalloc(&client->dev, sizeof(struct ads1015_data), > - GFP_KERNEL); > - if (!data) > - return -ENOMEM; > - > - if (client->dev.of_node) > - data->id = (enum ads1015_chips) > - of_device_get_match_data(&client->dev); > - else > - data->id = id->driver_data; > - i2c_set_clientdata(client, data); > - mutex_init(&data->update_lock); > - > - /* build sysfs attribute group */ > - ads1015_get_channels_config(client); > - for (k = 0; k < ADS1015_CHANNELS; ++k) { > - if (!data->channel_data[k].enabled) > - continue; > - err = device_create_file(&client->dev, &ads1015_in[k].dev_attr); > - if (err) > - goto exit_remove; > - } > - > - data->hwmon_dev = hwmon_device_register(&client->dev); > - if (IS_ERR(data->hwmon_dev)) { > - err = PTR_ERR(data->hwmon_dev); > - goto exit_remove; > - } > - > - return 0; > - > -exit_remove: > - for (k = 0; k < ADS1015_CHANNELS; ++k) > - device_remove_file(&client->dev, &ads1015_in[k].dev_attr); > - return err; > -} > - > -static const struct i2c_device_id ads1015_id[] = { > - { "ads1015", ads1015}, > - { "ads1115", ads1115}, > - { } > -}; > -MODULE_DEVICE_TABLE(i2c, ads1015_id); > - > -static const struct of_device_id __maybe_unused ads1015_of_match[] = { > - { > - .compatible = "ti,ads1015", > - .data = (void *)ads1015 > - }, > - { > - .compatible = "ti,ads1115", > - .data = (void *)ads1115 > - }, > - { }, > -}; > -MODULE_DEVICE_TABLE(of, ads1015_of_match); > - > -static struct i2c_driver ads1015_driver = { > - .driver = { > - .name = "ads1015", > - .of_match_table = of_match_ptr(ads1015_of_match), > - }, > - .probe = ads1015_probe, > - .remove = ads1015_remove, > - .id_table = ads1015_id, > -}; > - > -module_i2c_driver(ads1015_driver); > - > -MODULE_AUTHOR("Dirk Eibach <eibach@xxxxxxxx>"); > -MODULE_DESCRIPTION("ADS1015 driver"); > -MODULE_LICENSE("GPL"); > diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig > index f96a7702b020..47d073006a13 100644 > --- a/drivers/iio/adc/Kconfig > +++ b/drivers/iio/adc/Kconfig > @@ -958,7 +958,7 @@ config TI_ADC161S626 > > config TI_ADS1015 > tristate "Texas Instruments ADS1015 ADC" > - depends on I2C && !SENSORS_ADS1015 > + depends on I2C > select REGMAP_I2C > select IIO_BUFFER > select IIO_TRIGGERED_BUFFER