diff --git a/Documentation/devicetree/bindings/hwmon/ads1015.txt b/Documentation/devicetree/bindings/iio/adc/ads1015.txt similarity index 100% rename from Documentation/devicetree/bindings/hwmon/ads1015.txt rename to Documentation/devicetree/bindings/iio/adc/ads1015.txt 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 - -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 9cbcf167bdd0..c7035ce2460b 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 -L: linux-hwmon@vger.kernel.org -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 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 - * - * Based on the ads7828 driver by Steve Hardy. - * - * Datasheet available at: http://focus.ti.com/lit/ds/symlink/ads1015.pdf - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -/* 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 "); -MODULE_DESCRIPTION("ADS1015 driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 7e3286265a38..f0af3a42f53c 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