summaryrefslogtreecommitdiffstats
path: root/drivers/hwmon
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-06-03 11:09:43 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2014-06-03 11:09:43 -0700
commitf456205265a61f1d649f8378eceaa163850cba4e (patch)
treec974aafac8fad9bf1322f2ec66aaf01d01adfaf8 /drivers/hwmon
parent8f5759aeb88a47448cd92ab55a016d013b154a98 (diff)
parent9d311eddf3565ed0e05b3cb5a22db41fa74d9d86 (diff)
Merge tag 'hwmon-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging into next
Pull hwmon updates from Guenter Roeck: "New driver for NCT6683D New chip support to existing drivers: - add support for STTS2004 and AT30TSE004 to jc42 driver - add support for EMC1402/EMC1412/EMC1422 to emc1403 driver Other notable changes: - document hwmon kernel API - convert jc42, lm70, lm75, lm77, lm83, lm92, max1619, tmp421, and tmp102 drivers to use new hwmon API functions - replace function macros in lm80, lm92, and jc42 drivers with real code - convert emc1403 driver to use regmap, add support for additional attributes, and add device IDs for EMC1412, EMC1413, and EMC1414 - various additional cleanup and minor bug fixes in several drivers" * tag 'hwmon-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging: (60 commits) hwmon: (nct6775) Fix probe unwind paths to properly unregister platform devices hwmon: (nct6683) Fix probe unwind paths to properly unregister platform devices hwmon: (ultra45_env) Introduce managed version of kzalloc hwmon: Driver for NCT6683D hwmon: (lm80) Rearrange code to avoid forward declarations hwmon: (lm80) Convert fan display function macros into functions hwmon: (lm80) Convert voltage display function macros into functions hwmon: (lm80) Convert temperature display function macros into functions hwmon: (lm80) Normalize all temperature values to 16 bit hwmon: (lm80) Simplify TEMP_FROM_REG hwmon: (lm83) Convert to use devm_hwmon_device_register_with_groups hwmon: (lm83) Rearange code to avoid forward declarations hwmon: (lm83) Drop FSF address hwmon: (max1619) Convert to use devm_hwmon_device_register_with_groups hwmon: (max1619) Drop function macros hwmon: (max1619) Rearrange code to avoid forward declarations hwmon: (max1619) Drop FSF address hwmon: (max1619) Fix critical alarm display hwmon: (jc42) Add support for STTS2004 and AT30TSE004 hwmon: (jc42) Convert function macros into functions ...
Diffstat (limited to 'drivers/hwmon')
-rw-r--r--drivers/hwmon/Kconfig10
-rw-r--r--drivers/hwmon/Makefile1
-rw-r--r--drivers/hwmon/adm1029.c4
-rw-r--r--drivers/hwmon/emc1403.c267
-rw-r--r--drivers/hwmon/f71805f.c4
-rw-r--r--drivers/hwmon/g762.c2
-rw-r--r--drivers/hwmon/gpio-fan.c2
-rw-r--r--drivers/hwmon/ibmpex.c4
-rw-r--r--drivers/hwmon/iio_hwmon.c2
-rw-r--r--drivers/hwmon/jc42.c315
-rw-r--r--drivers/hwmon/lm70.c62
-rw-r--r--drivers/hwmon/lm75.c51
-rw-r--r--drivers/hwmon/lm77.c374
-rw-r--r--drivers/hwmon/lm80.c640
-rw-r--r--drivers/hwmon/lm83.c168
-rw-r--r--drivers/hwmon/lm92.c224
-rw-r--r--drivers/hwmon/lm93.c4
-rw-r--r--drivers/hwmon/ltc2945.c2
-rw-r--r--drivers/hwmon/max1111.c4
-rw-r--r--drivers/hwmon/max1619.c304
-rw-r--r--drivers/hwmon/max197.c4
-rw-r--r--drivers/hwmon/nct6683.c1457
-rw-r--r--drivers/hwmon/nct6775.c8
-rw-r--r--drivers/hwmon/pc87427.c4
-rw-r--r--drivers/hwmon/s3c-hwmon.c4
-rw-r--r--drivers/hwmon/tmp102.c62
-rw-r--r--drivers/hwmon/tmp421.c47
-rw-r--r--drivers/hwmon/ultra45_env.c7
-rw-r--r--drivers/hwmon/vt1211.c4
29 files changed, 2633 insertions, 1408 deletions
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 4af0da96c2e2..00343166feb1 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -1065,6 +1065,16 @@ config SENSORS_NTC_THERMISTOR
This driver can also be built as a module. If so, the module
will be called ntc-thermistor.
+config SENSORS_NCT6683
+ tristate "Nuvoton NCT6683D"
+ depends on !PPC
+ help
+ If you say yes here you get support for the hardware monitoring
+ functionality of the Nuvoton NCT6683D eSIO chip.
+
+ This driver can also be built as a module. If so, the module
+ will be called nct6683.
+
config SENSORS_NCT6775
tristate "Nuvoton NCT6775F and compatibles"
depends on !PPC
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index c48f9873ac73..11798ad7e801 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -114,6 +114,7 @@ obj-$(CONFIG_SENSORS_MAX6650) += max6650.o
obj-$(CONFIG_SENSORS_MAX6697) += max6697.o
obj-$(CONFIG_SENSORS_MC13783_ADC)+= mc13783-adc.o
obj-$(CONFIG_SENSORS_MCP3021) += mcp3021.o
+obj-$(CONFIG_SENSORS_NCT6683) += nct6683.o
obj-$(CONFIG_SENSORS_NCT6775) += nct6775.o
obj-$(CONFIG_SENSORS_NTC_THERMISTOR) += ntc_thermistor.o
obj-$(CONFIG_SENSORS_PC87360) += pc87360.o
diff --git a/drivers/hwmon/adm1029.c b/drivers/hwmon/adm1029.c
index d19c790e410a..78339e880bd6 100644
--- a/drivers/hwmon/adm1029.c
+++ b/drivers/hwmon/adm1029.c
@@ -1,7 +1,7 @@
/*
* adm1029.c - Part of lm_sensors, Linux kernel modules for hardware monitoring
*
- * Copyright (C) 2006 Corentin LABBE <corentin.labbe@geomatys.fr>
+ * Copyright (C) 2006 Corentin LABBE <clabbe.montjoie@gmail.com>
*
* Based on LM83 Driver by Jean Delvare <jdelvare@suse.de>
*
@@ -449,6 +449,6 @@ static struct adm1029_data *adm1029_update_device(struct device *dev)
module_i2c_driver(adm1029_driver);
-MODULE_AUTHOR("Corentin LABBE <corentin.labbe@geomatys.fr>");
+MODULE_AUTHOR("Corentin LABBE <clabbe.montjoie@gmail.com>");
MODULE_DESCRIPTION("adm1029 driver");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/hwmon/emc1403.c b/drivers/hwmon/emc1403.c
index 01723f04fe45..a37b2204a418 100644
--- a/drivers/hwmon/emc1403.c
+++ b/drivers/hwmon/emc1403.c
@@ -18,9 +18,6 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * TODO
- * - cache alarm and critical limit registers
*/
#include <linux/module.h>
@@ -32,22 +29,18 @@
#include <linux/err.h>
#include <linux/sysfs.h>
#include <linux/mutex.h>
-#include <linux/jiffies.h>
+#include <linux/regmap.h>
#define THERMAL_PID_REG 0xfd
#define THERMAL_SMSC_ID_REG 0xfe
#define THERMAL_REVISION_REG 0xff
+enum emc1403_chip { emc1402, emc1403, emc1404 };
+
struct thermal_data {
- struct i2c_client *client;
- const struct attribute_group *groups[3];
+ struct regmap *regmap;
struct mutex mutex;
- /*
- * Cache the hyst value so we don't keep re-reading it. In theory
- * we could cache it forever as nobody else should be writing it.
- */
- u8 cached_hyst;
- unsigned long hyst_valid;
+ const struct attribute_group *groups[4];
};
static ssize_t show_temp(struct device *dev,
@@ -55,12 +48,13 @@ static ssize_t show_temp(struct device *dev,
{
struct sensor_device_attribute *sda = to_sensor_dev_attr(attr);
struct thermal_data *data = dev_get_drvdata(dev);
+ unsigned int val;
int retval;
- retval = i2c_smbus_read_byte_data(data->client, sda->index);
+ retval = regmap_read(data->regmap, sda->index, &val);
if (retval < 0)
return retval;
- return sprintf(buf, "%d000\n", retval);
+ return sprintf(buf, "%d000\n", val);
}
static ssize_t show_bit(struct device *dev,
@@ -68,12 +62,13 @@ static ssize_t show_bit(struct device *dev,
{
struct sensor_device_attribute_2 *sda = to_sensor_dev_attr_2(attr);
struct thermal_data *data = dev_get_drvdata(dev);
+ unsigned int val;
int retval;
- retval = i2c_smbus_read_byte_data(data->client, sda->nr);
+ retval = regmap_read(data->regmap, sda->nr, &val);
if (retval < 0)
return retval;
- return sprintf(buf, "%d\n", !!(retval & sda->index));
+ return sprintf(buf, "%d\n", !!(val & sda->index));
}
static ssize_t store_temp(struct device *dev,
@@ -86,8 +81,8 @@ static ssize_t store_temp(struct device *dev,
if (kstrtoul(buf, 10, &val))
return -EINVAL;
- retval = i2c_smbus_write_byte_data(data->client, sda->index,
- DIV_ROUND_CLOSEST(val, 1000));
+ retval = regmap_write(data->regmap, sda->index,
+ DIV_ROUND_CLOSEST(val, 1000));
if (retval < 0)
return retval;
return count;
@@ -98,51 +93,51 @@ static ssize_t store_bit(struct device *dev,
{
struct sensor_device_attribute_2 *sda = to_sensor_dev_attr_2(attr);
struct thermal_data *data = dev_get_drvdata(dev);
- struct i2c_client *client = data->client;
unsigned long val;
int retval;
if (kstrtoul(buf, 10, &val))
return -EINVAL;
- mutex_lock(&data->mutex);
- retval = i2c_smbus_read_byte_data(client, sda->nr);
+ retval = regmap_update_bits(data->regmap, sda->nr, sda->index,
+ val ? sda->index : 0);
if (retval < 0)
- goto fail;
-
- retval &= ~sda->index;
- if (val)
- retval |= sda->index;
-
- retval = i2c_smbus_write_byte_data(client, sda->index, retval);
- if (retval == 0)
- retval = count;
-fail:
- mutex_unlock(&data->mutex);
- return retval;
+ return retval;
+ return count;
}
-static ssize_t show_hyst(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t show_hyst_common(struct device *dev,
+ struct device_attribute *attr, char *buf,
+ bool is_min)
{
struct sensor_device_attribute *sda = to_sensor_dev_attr(attr);
struct thermal_data *data = dev_get_drvdata(dev);
- struct i2c_client *client = data->client;
+ struct regmap *regmap = data->regmap;
+ unsigned int limit;
+ unsigned int hyst;
int retval;
- int hyst;
- retval = i2c_smbus_read_byte_data(client, sda->index);
+ retval = regmap_read(regmap, sda->index, &limit);
if (retval < 0)
return retval;
- if (time_after(jiffies, data->hyst_valid)) {
- hyst = i2c_smbus_read_byte_data(client, 0x21);
- if (hyst < 0)
- return retval;
- data->cached_hyst = hyst;
- data->hyst_valid = jiffies + HZ;
- }
- return sprintf(buf, "%d000\n", retval - data->cached_hyst);
+ retval = regmap_read(regmap, 0x21, &hyst);
+ if (retval < 0)
+ return retval;
+
+ return sprintf(buf, "%d000\n", is_min ? limit + hyst : limit - hyst);
+}
+
+static ssize_t show_hyst(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return show_hyst_common(dev, attr, buf, false);
+}
+
+static ssize_t show_min_hyst(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return show_hyst_common(dev, attr, buf, true);
}
static ssize_t store_hyst(struct device *dev,
@@ -150,7 +145,8 @@ static ssize_t store_hyst(struct device *dev,
{
struct sensor_device_attribute *sda = to_sensor_dev_attr(attr);
struct thermal_data *data = dev_get_drvdata(dev);
- struct i2c_client *client = data->client;
+ struct regmap *regmap = data->regmap;
+ unsigned int limit;
int retval;
int hyst;
unsigned long val;
@@ -159,23 +155,15 @@ static ssize_t store_hyst(struct device *dev,
return -EINVAL;
mutex_lock(&data->mutex);
- retval = i2c_smbus_read_byte_data(client, sda->index);
+ retval = regmap_read(regmap, sda->index, &limit);
if (retval < 0)
goto fail;
- hyst = retval * 1000 - val;
- hyst = DIV_ROUND_CLOSEST(hyst, 1000);
- if (hyst < 0 || hyst > 255) {
- retval = -ERANGE;
- goto fail;
- }
-
- retval = i2c_smbus_write_byte_data(client, 0x21, hyst);
- if (retval == 0) {
+ hyst = limit * 1000 - val;
+ hyst = clamp_val(DIV_ROUND_CLOSEST(hyst, 1000), 0, 255);
+ retval = regmap_write(regmap, 0x21, hyst);
+ if (retval == 0)
retval = count;
- data->cached_hyst = hyst;
- data->hyst_valid = jiffies + HZ;
- }
fail:
mutex_unlock(&data->mutex);
return retval;
@@ -198,6 +186,8 @@ static SENSOR_DEVICE_ATTR_2(temp1_max_alarm, S_IRUGO,
show_bit, NULL, 0x35, 0x01);
static SENSOR_DEVICE_ATTR_2(temp1_crit_alarm, S_IRUGO,
show_bit, NULL, 0x37, 0x01);
+static SENSOR_DEVICE_ATTR(temp1_min_hyst, S_IRUGO, show_min_hyst, NULL, 0x06);
+static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IRUGO, show_hyst, NULL, 0x05);
static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IRUGO | S_IWUSR,
show_hyst, store_hyst, 0x20);
@@ -208,14 +198,16 @@ static SENSOR_DEVICE_ATTR(temp2_max, S_IRUGO | S_IWUSR,
static SENSOR_DEVICE_ATTR(temp2_crit, S_IRUGO | S_IWUSR,
show_temp, store_temp, 0x19);
static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 0x01);
+static SENSOR_DEVICE_ATTR_2(temp2_fault, S_IRUGO, show_bit, NULL, 0x1b, 0x02);
static SENSOR_DEVICE_ATTR_2(temp2_min_alarm, S_IRUGO,
show_bit, NULL, 0x36, 0x02);
static SENSOR_DEVICE_ATTR_2(temp2_max_alarm, S_IRUGO,
show_bit, NULL, 0x35, 0x02);
static SENSOR_DEVICE_ATTR_2(temp2_crit_alarm, S_IRUGO,
show_bit, NULL, 0x37, 0x02);
-static SENSOR_DEVICE_ATTR(temp2_crit_hyst, S_IRUGO | S_IWUSR,
- show_hyst, store_hyst, 0x19);
+static SENSOR_DEVICE_ATTR(temp2_min_hyst, S_IRUGO, show_min_hyst, NULL, 0x08);
+static SENSOR_DEVICE_ATTR(temp2_max_hyst, S_IRUGO, show_hyst, NULL, 0x07);
+static SENSOR_DEVICE_ATTR(temp2_crit_hyst, S_IRUGO, show_hyst, NULL, 0x19);
static SENSOR_DEVICE_ATTR(temp3_min, S_IRUGO | S_IWUSR,
show_temp, store_temp, 0x16);
@@ -224,14 +216,16 @@ static SENSOR_DEVICE_ATTR(temp3_max, S_IRUGO | S_IWUSR,
static SENSOR_DEVICE_ATTR(temp3_crit, S_IRUGO | S_IWUSR,
show_temp, store_temp, 0x1A);
static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 0x23);
+static SENSOR_DEVICE_ATTR_2(temp3_fault, S_IRUGO, show_bit, NULL, 0x1b, 0x04);
static SENSOR_DEVICE_ATTR_2(temp3_min_alarm, S_IRUGO,
show_bit, NULL, 0x36, 0x04);
static SENSOR_DEVICE_ATTR_2(temp3_max_alarm, S_IRUGO,
show_bit, NULL, 0x35, 0x04);
static SENSOR_DEVICE_ATTR_2(temp3_crit_alarm, S_IRUGO,
show_bit, NULL, 0x37, 0x04);
-static SENSOR_DEVICE_ATTR(temp3_crit_hyst, S_IRUGO | S_IWUSR,
- show_hyst, store_hyst, 0x1A);
+static SENSOR_DEVICE_ATTR(temp3_min_hyst, S_IRUGO, show_min_hyst, NULL, 0x16);
+static SENSOR_DEVICE_ATTR(temp3_max_hyst, S_IRUGO, show_hyst, NULL, 0x15);
+static SENSOR_DEVICE_ATTR(temp3_crit_hyst, S_IRUGO, show_hyst, NULL, 0x1A);
static SENSOR_DEVICE_ATTR(temp4_min, S_IRUGO | S_IWUSR,
show_temp, store_temp, 0x2D);
@@ -240,44 +234,66 @@ static SENSOR_DEVICE_ATTR(temp4_max, S_IRUGO | S_IWUSR,
static SENSOR_DEVICE_ATTR(temp4_crit, S_IRUGO | S_IWUSR,
show_temp, store_temp, 0x30);
static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_temp, NULL, 0x2A);
+static SENSOR_DEVICE_ATTR_2(temp4_fault, S_IRUGO, show_bit, NULL, 0x1b, 0x08);
static SENSOR_DEVICE_ATTR_2(temp4_min_alarm, S_IRUGO,
show_bit, NULL, 0x36, 0x08);
static SENSOR_DEVICE_ATTR_2(temp4_max_alarm, S_IRUGO,
show_bit, NULL, 0x35, 0x08);
static SENSOR_DEVICE_ATTR_2(temp4_crit_alarm, S_IRUGO,
show_bit, NULL, 0x37, 0x08);
-static SENSOR_DEVICE_ATTR(temp4_crit_hyst, S_IRUGO | S_IWUSR,
- show_hyst, store_hyst, 0x30);
+static SENSOR_DEVICE_ATTR(temp4_min_hyst, S_IRUGO, show_min_hyst, NULL, 0x2D);
+static SENSOR_DEVICE_ATTR(temp4_max_hyst, S_IRUGO, show_hyst, NULL, 0x2C);
+static SENSOR_DEVICE_ATTR(temp4_crit_hyst, S_IRUGO, show_hyst, NULL, 0x30);
static SENSOR_DEVICE_ATTR_2(power_state, S_IRUGO | S_IWUSR,
show_bit, store_bit, 0x03, 0x40);
-static struct attribute *emc1403_attrs[] = {
+static struct attribute *emc1402_attrs[] = {
&sensor_dev_attr_temp1_min.dev_attr.attr,
&sensor_dev_attr_temp1_max.dev_attr.attr,
&sensor_dev_attr_temp1_crit.dev_attr.attr,
&sensor_dev_attr_temp1_input.dev_attr.attr,
- &sensor_dev_attr_temp1_min_alarm.dev_attr.attr,
- &sensor_dev_attr_temp1_max_alarm.dev_attr.attr,
- &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr,
+ &sensor_dev_attr_temp1_min_hyst.dev_attr.attr,
+ &sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
&sensor_dev_attr_temp1_crit_hyst.dev_attr.attr,
+
&sensor_dev_attr_temp2_min.dev_attr.attr,
&sensor_dev_attr_temp2_max.dev_attr.attr,
&sensor_dev_attr_temp2_crit.dev_attr.attr,
&sensor_dev_attr_temp2_input.dev_attr.attr,
+ &sensor_dev_attr_temp2_min_hyst.dev_attr.attr,
+ &sensor_dev_attr_temp2_max_hyst.dev_attr.attr,
+ &sensor_dev_attr_temp2_crit_hyst.dev_attr.attr,
+
+ &sensor_dev_attr_power_state.dev_attr.attr,
+ NULL
+};
+
+static const struct attribute_group emc1402_group = {
+ .attrs = emc1402_attrs,
+};
+
+static struct attribute *emc1403_attrs[] = {
+ &sensor_dev_attr_temp1_min_alarm.dev_attr.attr,
+ &sensor_dev_attr_temp1_max_alarm.dev_attr.attr,
+ &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr,
+
+ &sensor_dev_attr_temp2_fault.dev_attr.attr,
&sensor_dev_attr_temp2_min_alarm.dev_attr.attr,
&sensor_dev_attr_temp2_max_alarm.dev_attr.attr,
&sensor_dev_attr_temp2_crit_alarm.dev_attr.attr,
- &sensor_dev_attr_temp2_crit_hyst.dev_attr.attr,
+
&sensor_dev_attr_temp3_min.dev_attr.attr,
&sensor_dev_attr_temp3_max.dev_attr.attr,
&sensor_dev_attr_temp3_crit.dev_attr.attr,
&sensor_dev_attr_temp3_input.dev_attr.attr,
+ &sensor_dev_attr_temp3_fault.dev_attr.attr,
&sensor_dev_attr_temp3_min_alarm.dev_attr.attr,
&sensor_dev_attr_temp3_max_alarm.dev_attr.attr,
&sensor_dev_attr_temp3_crit_alarm.dev_attr.attr,
+ &sensor_dev_attr_temp3_min_hyst.dev_attr.attr,
+ &sensor_dev_attr_temp3_max_hyst.dev_attr.attr,
&sensor_dev_attr_temp3_crit_hyst.dev_attr.attr,
- &sensor_dev_attr_power_state.dev_attr.attr,
NULL
};
@@ -290,9 +306,12 @@ static struct attribute *emc1404_attrs[] = {
&sensor_dev_attr_temp4_max.dev_attr.attr,
&sensor_dev_attr_temp4_crit.dev_attr.attr,
&sensor_dev_attr_temp4_input.dev_attr.attr,
+ &sensor_dev_attr_temp4_fault.dev_attr.attr,
&sensor_dev_attr_temp4_min_alarm.dev_attr.attr,
&sensor_dev_attr_temp4_max_alarm.dev_attr.attr,
&sensor_dev_attr_temp4_crit_alarm.dev_attr.attr,
+ &sensor_dev_attr_temp4_min_hyst.dev_attr.attr,
+ &sensor_dev_attr_temp4_max_hyst.dev_attr.attr,
&sensor_dev_attr_temp4_crit_hyst.dev_attr.attr,
NULL
};
@@ -301,6 +320,39 @@ static const struct attribute_group emc1404_group = {
.attrs = emc1404_attrs,
};
+/*
+ * EMC14x2 uses a different register and different bits to report alarm and
+ * fault status. For simplicity, provide a separate attribute group for this
+ * chip series.
+ * Since we can not re-use the same attribute names, create a separate attribute
+ * array.
+ */
+static struct sensor_device_attribute_2 emc1402_alarms[] = {
+ SENSOR_ATTR_2(temp1_min_alarm, S_IRUGO, show_bit, NULL, 0x02, 0x20),
+ SENSOR_ATTR_2(temp1_max_alarm, S_IRUGO, show_bit, NULL, 0x02, 0x40),
+ SENSOR_ATTR_2(temp1_crit_alarm, S_IRUGO, show_bit, NULL, 0x02, 0x01),
+
+ SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_bit, NULL, 0x02, 0x04),
+ SENSOR_ATTR_2(temp2_min_alarm, S_IRUGO, show_bit, NULL, 0x02, 0x08),
+ SENSOR_ATTR_2(temp2_max_alarm, S_IRUGO, show_bit, NULL, 0x02, 0x10),
+ SENSOR_ATTR_2(temp2_crit_alarm, S_IRUGO, show_bit, NULL, 0x02, 0x02),
+};
+
+static struct attribute *emc1402_alarm_attrs[] = {
+ &emc1402_alarms[0].dev_attr.attr,
+ &emc1402_alarms[1].dev_attr.attr,
+ &emc1402_alarms[2].dev_attr.attr,
+ &emc1402_alarms[3].dev_attr.attr,
+ &emc1402_alarms[4].dev_attr.attr,
+ &emc1402_alarms[5].dev_attr.attr,
+ &emc1402_alarms[6].dev_attr.attr,
+ NULL,
+};
+
+static const struct attribute_group emc1402_alarm_group = {
+ .attrs = emc1402_alarm_attrs,
+};
+
static int emc1403_detect(struct i2c_client *client,
struct i2c_board_info *info)
{
@@ -313,9 +365,15 @@ static int emc1403_detect(struct i2c_client *client,
id = i2c_smbus_read_byte_data(client, THERMAL_PID_REG);
switch (id) {
+ case 0x20:
+ strlcpy(info->type, "emc1402", I2C_NAME_SIZE);
+ break;
case 0x21:
strlcpy(info->type, "emc1403", I2C_NAME_SIZE);
break;
+ case 0x22:
+ strlcpy(info->type, "emc1422", I2C_NAME_SIZE);
+ break;
case 0x23:
strlcpy(info->type, "emc1423", I2C_NAME_SIZE);
break;
@@ -336,6 +394,35 @@ static int emc1403_detect(struct i2c_client *client,
return 0;
}
+static bool emc1403_regmap_is_volatile(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case 0x00: /* internal diode high byte */
+ case 0x01: /* external diode 1 high byte */
+ case 0x02: /* status */
+ case 0x10: /* external diode 1 low byte */
+ case 0x1b: /* external diode fault */
+ case 0x23: /* external diode 2 high byte */
+ case 0x24: /* external diode 2 low byte */
+ case 0x29: /* internal diode low byte */
+ case 0x2a: /* externl diode 3 high byte */
+ case 0x2b: /* external diode 3 low byte */
+ case 0x35: /* high limit status */
+ case 0x36: /* low limit status */
+ case 0x37: /* therm limit status */
+ return true;
+ default:
+ return false;
+ }
+}
+
+static struct regmap_config emc1403_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .cache_type = REGCACHE_RBTREE,
+ .volatile_reg = emc1403_regmap_is_volatile,
+};
+
static int emc1403_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
@@ -347,13 +434,23 @@ static int emc1403_probe(struct i2c_client *client,
if (data == NULL)
return -ENOMEM;
- data->client = client;
+ data->regmap = devm_regmap_init_i2c(client, &emc1403_regmap_config);
+ if (IS_ERR(data->regmap))
+ return PTR_ERR(data->regmap);
+
mutex_init(&data->mutex);
- data->hyst_valid = jiffies - 1; /* Expired */
- data->groups[0] = &emc1403_group;
- if (id->driver_data)
- data->groups[1] = &emc1404_group;
+ switch (id->driver_data) {
+ case emc1404:
+ data->groups[2] = &emc1404_group;
+ case emc1403:
+ data->groups[1] = &emc1403_group;
+ case emc1402:
+ data->groups[0] = &emc1402_group;
+ }
+
+ if (id->driver_data == emc1402)
+ data->groups[1] = &emc1402_alarm_group;
hwmon_dev = devm_hwmon_device_register_with_groups(&client->dev,
client->name, data,
@@ -366,14 +463,20 @@ static int emc1403_probe(struct i2c_client *client,
}
static const unsigned short emc1403_address_list[] = {
- 0x18, 0x29, 0x4c, 0x4d, I2C_CLIENT_END
+ 0x18, 0x1c, 0x29, 0x4c, 0x4d, 0x5c, I2C_CLIENT_END
};
+/* Last digit of chip name indicates number of channels */
static const struct i2c_device_id emc1403_idtable[] = {
- { "emc1403", 0 },
- { "emc1404", 1 },
- { "emc1423", 0 },
- { "emc1424", 1 },
+ { "emc1402", emc1402 },
+ { "emc1403", emc1403 },
+ { "emc1404", emc1404 },
+ { "emc1412", emc1402 },
+ { "emc1413", emc1403 },
+ { "emc1414", emc1404 },
+ { "emc1422", emc1402 },
+ { "emc1423", emc1403 },
+ { "emc1424", emc1404 },
{ }
};
MODULE_DEVICE_TABLE(i2c, emc1403_idtable);
diff --git a/drivers/hwmon/f71805f.c b/drivers/hwmon/f71805f.c
index 32f5132c4652..9e57b77ecd34 100644
--- a/drivers/hwmon/f71805f.c
+++ b/drivers/hwmon/f71805f.c
@@ -1387,10 +1387,8 @@ static int f71805f_probe(struct platform_device *pdev)
data = devm_kzalloc(&pdev->dev, sizeof(struct f71805f_data),
GFP_KERNEL);
- if (!data) {
- pr_err("Out of memory\n");
+ if (!data)
return -ENOMEM;
- }
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
if (!devm_request_region(&pdev->dev, res->start + ADDR_REG_OFFSET, 2,
diff --git a/drivers/hwmon/g762.c b/drivers/hwmon/g762.c
index b4b8b5bef718..98a8618d8fbf 100644
--- a/drivers/hwmon/g762.c
+++ b/drivers/hwmon/g762.c
@@ -586,7 +586,7 @@ static int do_set_fan_startv(struct device *dev, unsigned long val)
*/
#ifdef CONFIG_OF
-static struct of_device_id g762_dt_match[] = {
+static const struct of_device_id g762_dt_match[] = {
{ .compatible = "gmt,g762" },
{ .compatible = "gmt,g763" },
{ },
diff --git a/drivers/hwmon/gpio-fan.c b/drivers/hwmon/gpio-fan.c
index 73181be5b30b..ba35e4d530b5 100644
--- a/drivers/hwmon/gpio-fan.c
+++ b/drivers/hwmon/gpio-fan.c
@@ -482,7 +482,7 @@ static int gpio_fan_get_of_pdata(struct device *dev,
return 0;
}
-static struct of_device_id of_gpio_fan_match[] = {
+static const struct of_device_id of_gpio_fan_match[] = {
{ .compatible = "gpio-fan", },
{},
};
diff --git a/drivers/hwmon/ibmpex.c b/drivers/hwmon/ibmpex.c
index 20ab0fb85395..030e7ff589be 100644
--- a/drivers/hwmon/ibmpex.c
+++ b/drivers/hwmon/ibmpex.c
@@ -463,10 +463,8 @@ static void ibmpex_register_bmc(int iface, struct device *dev)
int err;
data = kzalloc(sizeof(*data), GFP_KERNEL);
- if (!data) {
- dev_err(dev, "Insufficient memory for BMC interface.\n");
+ if (!data)
return;
- }
data->address.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
data->address.channel = IPMI_BMC_CHANNEL;
diff --git a/drivers/hwmon/iio_hwmon.c b/drivers/hwmon/iio_hwmon.c
index 9fbb1b1fdff3..14c82daab019 100644
--- a/drivers/hwmon/iio_hwmon.c
+++ b/drivers/hwmon/iio_hwmon.c
@@ -163,7 +163,7 @@ static int iio_hwmon_remove(struct platform_device *pdev)
return 0;
}
-static struct of_device_id iio_hwmon_of_match[] = {
+static const struct of_device_id iio_hwmon_of_match[] = {
{ .compatible = "iio-hwmon", },
{ }
};
diff --git a/drivers/hwmon/jc42.c b/drivers/hwmon/jc42.c
index 6013611e4f21..388f8bcd898e 100644
--- a/drivers/hwmon/jc42.c
+++ b/drivers/hwmon/jc42.c
@@ -65,6 +65,7 @@ static const unsigned short normal_i2c[] = {
/* Manufacturer IDs */
#define ADT_MANID 0x11d4 /* Analog Devices */
#define ATMEL_MANID 0x001f /* Atmel */
+#define ATMEL_MANID2 0x1114 /* Atmel */
#define MAX_MANID 0x004d /* Maxim */
#define IDT_MANID 0x00b3 /* IDT */
#define MCP_MANID 0x0054 /* Microchip */
@@ -82,6 +83,9 @@ static const unsigned short normal_i2c[] = {
#define AT30TS00_DEVID 0x8201
#define AT30TS00_DEVID_MASK 0xffff
+#define AT30TSE004_DEVID 0x2200
+#define AT30TSE004_DEVID_MASK 0xffff
+
/* IDT */
#define TS3000B3_DEVID 0x2903 /* Also matches TSE2002B3 */
#define TS3000B3_DEVID_MASK 0xffff
@@ -130,6 +134,9 @@ static const unsigned short normal_i2c[] = {
#define STTS2002_DEVID 0x0300
#define STTS2002_DEVID_MASK 0xffff
+#define STTS2004_DEVID 0x2201
+#define STTS2004_DEVID_MASK 0xffff
+
#define STTS3000_DEVID 0x0200
#define STTS3000_DEVID_MASK 0xffff
@@ -144,6 +151,7 @@ struct jc42_chips {
static struct jc42_chips jc42_chips[] = {
{ ADT_MANID, ADT7408_DEVID, ADT7408_DEVID_MASK },
{ ATMEL_MANID, AT30TS00_DEVID, AT30TS00_DEVID_MASK },
+ { ATMEL_MANID2, AT30TSE004_DEVID, AT30TSE004_DEVID_MASK },
{ IDT_MANID, TS3000B3_DEVID, TS3000B3_DEVID_MASK },
{ IDT_MANID, TS3000GB2_DEVID, TS3000GB2_DEVID_MASK },
{ MAX_MANID, MAX6604_DEVID, MAX6604_DEVID_MASK },
@@ -158,9 +166,25 @@ static struct jc42_chips jc42_chips[] = {
{ STM_MANID, STTS424_DEVID, STTS424_DEVID_MASK },
{ STM_MANID, STTS424E_DEVID, STTS424E_DEVID_MASK },
{ STM_MANID, STTS2002_DEVID, STTS2002_DEVID_MASK },
+ { STM_MANID, STTS2004_DEVID, STTS2004_DEVID_MASK },
{ STM_MANID, STTS3000_DEVID, STTS3000_DEVID_MASK },
};
+enum temp_index {
+ t_input = 0,
+ t_crit,
+ t_min,
+ t_max,
+ t_num_temp
+};
+
+static const u8 temp_regs[t_num_temp] = {
+ [t_input] = JC42_REG_TEMP,
+ [t_crit] = JC42_REG_TEMP_CRITICAL,
+ [t_min] = JC42_REG_TEMP_LOWER,
+ [t_max] = JC42_REG_TEMP_UPPER,
+};
+
/* Each client has this additional data */
struct jc42_data {
struct i2c_client *client;
@@ -170,69 +194,7 @@ struct jc42_data {
unsigned long last_updated; /* In jiffies */
u16 orig_config; /* original configuration */
u16 config; /* current configuration */
- u16 temp_input; /* Temperatures */
- u16 temp_crit;
- u16 temp_min;
- u16 temp_max;
-};
-
-static int jc42_probe(struct i2c_client *client,
- const struct i2c_device_id *id);
-static int jc42_detect(struct i2c_client *client, struct i2c_board_info *info);
-static int jc42_remove(struct i2c_client *client);
-
-static struct jc42_data *jc42_update_device(struct device *dev);
-
-static const struct i2c_device_id jc42_id[] = {
- { "jc42", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, jc42_id);
-
-#ifdef CONFIG_PM
-
-static int jc42_suspend(struct device *dev)
-{
- struct jc42_data *data = dev_get_drvdata(dev);
-
- data->config |= JC42_CFG_SHUTDOWN;
- i2c_smbus_write_word_swapped(data->client, JC42_REG_CONFIG,
- data->config);
- return 0;
-}
-
-static int jc42_resume(struct device *dev)
-{
- struct jc42_data *data = dev_get_drvdata(dev);
-
- data->config &= ~JC42_CFG_SHUTDOWN;
- i2c_smbus_write_word_swapped(data->client, JC42_REG_CONFIG,
- data->config);
- return 0;
-}
-
-static const struct dev_pm_ops jc42_dev_pm_ops = {
- .suspend = jc42_suspend,
- .resume = jc42_resume,
-};
-
-#define JC42_DEV_PM_OPS (&jc42_dev_pm_ops)
-#else
-#define JC42_DEV_PM_OPS NULL
-#endif /* CONFIG_PM */
-
-/* This is the driver that will be inserted */
-static struct i2c_driver jc42_driver = {
- .class = I2C_CLASS_SPD,
- .driver = {
- .name = "jc42",
- .pm = JC42_DEV_PM_OPS,
- },
- .probe = jc42_probe,
- .remove = jc42_remove,
- .id_table = jc42_id,
- .detect = jc42_detect,
- .address_list = normal_i2c,
+ u16 temp[t_num_temp];/* Temperatures */
};
#define JC42_TEMP_MIN_EXTENDED (-40000)
@@ -261,79 +223,81 @@ static int jc42_temp_from_reg(s16 reg)
return reg * 125 / 2;
}
-/* sysfs stuff */
-
-/* read routines for temperature limits */
-#define show(value) \
-static ssize_t show_##value(struct device *dev, \
- struct device_attribute *attr, \
- char *buf) \
-{ \
- struct jc42_data *data = jc42_update_device(dev); \
- if (IS_ERR(data)) \
- return PTR_ERR(data); \
- return sprintf(buf, "%d\n", jc42_temp_from_reg(data->value)); \
+static struct jc42_data *jc42_update_device(struct device *dev)
+{
+ struct jc42_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
+ struct jc42_data *ret = data;
+ int i, val;
+
+ mutex_lock(&data->update_lock);
+
+ if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
+ for (i = 0; i < t_num_temp; i++) {
+ val = i2c_smbus_read_word_swapped(client, temp_regs[i]);
+ if (val < 0) {
+ ret = ERR_PTR(val);
+ goto abort;
+ }
+ data->temp[i] = val;
+ }
+ data->last_updated = jiffies;
+ data->valid = true;
+ }
+abort:
+ mutex_unlock(&data->update_lock);
+ return ret;
}
-show(temp_input);
-show(temp_crit);
-show(temp_min);