aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorStephen Rothwell <sfr@canb.auug.org.au>2017-05-29 09:04:31 +1000
committerStephen Rothwell <sfr@canb.auug.org.au>2017-05-29 09:04:31 +1000
commite5a61d68115373eb65224733361438f500223e3b (patch)
treeca3034662347a8aa2a3d4676d8c0a2bc1e41186f /drivers
parent102510a21d4d2f4fff7e112c642690b857680566 (diff)
parentf3ace4b8cf5b634c983521e3e6dd433c26423c00 (diff)
Merge remote-tracking branch 'hwmon-staging/hwmon-next'
Diffstat (limited to 'drivers')
-rw-r--r--drivers/hwmon/Kconfig1
-rw-r--r--drivers/hwmon/ads1015.c2
-rw-r--r--drivers/hwmon/adt7475.c184
-rw-r--r--drivers/hwmon/ds620.c2
-rw-r--r--drivers/hwmon/ltc4245.c2
-rw-r--r--drivers/hwmon/max6639.c2
-rw-r--r--drivers/hwmon/nct6775.c325
-rw-r--r--drivers/hwmon/pmbus/Kconfig10
-rw-r--r--drivers/hwmon/pmbus/Makefile1
-rw-r--r--drivers/hwmon/pmbus/ir35221.c337
-rw-r--r--drivers/hwmon/pmbus/pmbus.c2
-rw-r--r--drivers/hwmon/pmbus/pmbus_core.c2
-rw-r--r--drivers/hwmon/pmbus/ucd9000.c2
-rw-r--r--drivers/hwmon/pmbus/ucd9200.c2
-rw-r--r--drivers/iio/adc/ti-ads1015.c2
15 files changed, 730 insertions, 146 deletions
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 22d5eafd6815..5ef2814345ef 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -343,6 +343,7 @@ config SENSORS_ASB100
config SENSORS_ASPEED
tristate "ASPEED AST2400/AST2500 PWM and Fan tach driver"
+ select REGMAP
help
This driver provides support for ASPEED AST2400/AST2500 PWM
and Fan Tacho controllers.
diff --git a/drivers/hwmon/ads1015.c b/drivers/hwmon/ads1015.c
index 5140c27d16dd..357b42607164 100644
--- a/drivers/hwmon/ads1015.c
+++ b/drivers/hwmon/ads1015.c
@@ -34,7 +34,7 @@
#include <linux/of_device.h>
#include <linux/of.h>
-#include <linux/i2c/ads1015.h>
+#include <linux/platform_data/ads1015.h>
/* ADS1015 registers */
enum {
diff --git a/drivers/hwmon/adt7475.c b/drivers/hwmon/adt7475.c
index c803e3c5fcd4..1baa213a60bd 100644
--- a/drivers/hwmon/adt7475.c
+++ b/drivers/hwmon/adt7475.c
@@ -22,6 +22,7 @@
#include <linux/hwmon-vid.h>
#include <linux/err.h>
#include <linux/jiffies.h>
+#include <linux/util_macros.h>
/* Indexes for the sysfs hooks */
@@ -78,6 +79,9 @@
#define REG_TEMP_TRANGE_BASE 0x5F
+#define REG_ENHANCE_ACOUSTICS1 0x62
+#define REG_ENHANCE_ACOUSTICS2 0x63
+
#define REG_PWM_MIN_BASE 0x64
#define REG_TEMP_TMIN_BASE 0x67
@@ -208,6 +212,7 @@ struct adt7475_data {
u8 range[3];
u8 pwmctl[3];
u8 pwmchan[3];
+ u8 enh_acoustics[2];
u8 vid;
u8 vrm;
@@ -314,35 +319,6 @@ static void adt7475_write_word(struct i2c_client *client, int reg, u16 val)
i2c_smbus_write_byte_data(client, reg, val & 0xFF);
}
-/*
- * Find the nearest value in a table - used for pwm frequency and
- * auto temp range
- */
-static int find_nearest(long val, const int *array, int size)
-{
- int i;
-
- if (val < array[0])
- return 0;
-
- if (val > array[size - 1])
- return size - 1;
-
- for (i = 0; i < size - 1; i++) {
- int a, b;
-
- if (val > array[i + 1])
- continue;
-
- a = val - array[i];
- b = array[i + 1] - val;
-
- return (a <= b) ? i : i + 1;
- }
-
- return 0;
-}
-
static ssize_t show_voltage(struct device *dev, struct device_attribute *attr,
char *buf)
{
@@ -550,6 +526,88 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *attr,
return count;
}
+/* Assuming CONFIG6[SLOW] is 0 */
+static const int ad7475_st_map[] = {
+ 37500, 18800, 12500, 7500, 4700, 3100, 1600, 800,
+};
+
+static ssize_t show_temp_st(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
+ struct i2c_client *client = to_i2c_client(dev);
+ struct adt7475_data *data = i2c_get_clientdata(client);
+ long val;
+
+ switch (sattr->index) {
+ case 0:
+ val = data->enh_acoustics[0] & 0xf;
+ break;
+ case 1:
+ val = (data->enh_acoustics[1] >> 4) & 0xf;
+ break;
+ case 2:
+ default:
+ val = data->enh_acoustics[1] & 0xf;
+ break;
+ }
+
+ if (val & 0x8)
+ return sprintf(buf, "%d\n", ad7475_st_map[val & 0x7]);
+ else
+ return sprintf(buf, "0\n");
+}
+
+static ssize_t set_temp_st(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
+ struct i2c_client *client = to_i2c_client(dev);
+ struct adt7475_data *data = i2c_get_clientdata(client);
+ unsigned char reg;
+ int shift, idx;
+ ulong val;
+
+ if (kstrtoul(buf, 10, &val))
+ return -EINVAL;
+
+ switch (sattr->index) {
+ case 0:
+ reg = REG_ENHANCE_ACOUSTICS1;
+ shift = 0;
+ idx = 0;
+ break;
+ case 1:
+ reg = REG_ENHANCE_ACOUSTICS2;
+ shift = 0;
+ idx = 1;
+ break;
+ case 2:
+ default:
+ reg = REG_ENHANCE_ACOUSTICS2;
+ shift = 4;
+ idx = 1;
+ break;
+ }
+
+ if (val > 0) {
+ val = find_closest_descending(val, ad7475_st_map,
+ ARRAY_SIZE(ad7475_st_map));
+ val |= 0x8;
+ }
+
+ mutex_lock(&data->lock);
+
+ data->enh_acoustics[idx] &= ~(0xf << shift);
+ data->enh_acoustics[idx] |= (val << shift);
+
+ i2c_smbus_write_byte_data(client, reg, data->enh_acoustics[idx]);
+
+ mutex_unlock(&data->lock);
+
+ return count;
+}
+
/*
* Table of autorange values - the user will write the value in millidegrees,
* and we'll convert it
@@ -606,7 +664,7 @@ static ssize_t set_point2(struct device *dev, struct device_attribute *attr,
val -= temp;
/* Find the nearest table entry to what the user wrote */
- val = find_nearest(val, autorange_table, ARRAY_SIZE(autorange_table));
+ val = find_closest(val, autorange_table, ARRAY_SIZE(autorange_table));
data->range[sattr->index] &= ~0xF0;
data->range[sattr->index] |= val << 4;
@@ -728,6 +786,43 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
data->pwm[sattr->nr][sattr->index] = clamp_val(val, 0, 0xFF);
i2c_smbus_write_byte_data(client, reg,
data->pwm[sattr->nr][sattr->index]);
+ mutex_unlock(&data->lock);
+
+ return count;
+}
+
+static ssize_t show_stall_disable(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
+ struct i2c_client *client = to_i2c_client(dev);
+ struct adt7475_data *data = i2c_get_clientdata(client);
+ u8 mask = BIT(5 + sattr->index);
+
+ return sprintf(buf, "%d\n", !!(data->enh_acoustics[0] & mask));
+}
+
+static ssize_t set_stall_disable(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t count)
+{
+ struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
+ struct i2c_client *client = to_i2c_client(dev);
+ struct adt7475_data *data = i2c_get_clientdata(client);
+ long val;
+ u8 mask = BIT(5 + sattr->index);
+
+ if (kstrtol(buf, 10, &val))
+ return -EINVAL;
+
+ mutex_lock(&data->lock);
+
+ data->enh_acoustics[0] &= ~mask;
+ if (val)
+ data->enh_acoustics[0] |= mask;
+
+ i2c_smbus_write_byte_data(client, REG_ENHANCE_ACOUSTICS1,
+ data->enh_acoustics[0]);
mutex_unlock(&data->lock);
@@ -839,7 +934,7 @@ static ssize_t set_pwmctrl(struct device *dev, struct device_attribute *attr,
/* List of frequencies for the PWM */
static const int pwmfreq_table[] = {
- 11, 14, 22, 29, 35, 44, 58, 88
+ 11, 14, 22, 29, 35, 44, 58, 88, 22500
};
static ssize_t show_pwmfreq(struct device *dev, struct device_attribute *attr,
@@ -847,9 +942,10 @@ static ssize_t show_pwmfreq(struct device *dev, struct device_attribute *attr,
{
struct adt7475_data *data = adt7475_update_device(dev);
struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
+ int i = clamp_val(data->range[sattr->index] & 0xf, 0,
+ ARRAY_SIZE(pwmfreq_table) - 1);
- return sprintf(buf, "%d\n",
- pwmfreq_table[data->range[sattr->index] & 7]);
+ return sprintf(buf, "%d\n", pwmfreq_table[i]);
}
static ssize_t set_pwmfreq(struct device *dev, struct device_attribute *attr,
@@ -864,13 +960,13 @@ static ssize_t set_pwmfreq(struct device *dev, struct device_attribute *attr,
if (kstrtol(buf, 10, &val))
return -EINVAL;
- out = find_nearest(val, pwmfreq_table, ARRAY_SIZE(pwmfreq_table));
+ out = find_closest(val, pwmfreq_table, ARRAY_SIZE(pwmfreq_table));
mutex_lock(&data->lock);
data->range[sattr->index] =
adt7475_read(TEMP_TRANGE_REG(sattr->index));
- data->range[sattr->index] &= ~7;
+ data->range[sattr->index] &= ~0xf;
data->range[sattr->index] |= out;
i2c_smbus_write_byte_data(client, TEMP_TRANGE_REG(sattr->index),
@@ -995,6 +1091,8 @@ static SENSOR_DEVICE_ATTR_2(temp1_crit, S_IRUGO | S_IWUSR, show_temp, set_temp,
THERM, 0);
static SENSOR_DEVICE_ATTR_2(temp1_crit_hyst, S_IRUGO | S_IWUSR, show_temp,
set_temp, HYSTERSIS, 0);
+static SENSOR_DEVICE_ATTR_2(temp1_smoothing, S_IRUGO | S_IWUSR, show_temp_st,
+ set_temp_st, 0, 0);
static SENSOR_DEVICE_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, INPUT, 1);
static SENSOR_DEVICE_ATTR_2(temp2_alarm, S_IRUGO, show_temp, NULL, ALARM, 1);
static SENSOR_DEVICE_ATTR_2(temp2_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
@@ -1011,6 +1109,8 @@ static SENSOR_DEVICE_ATTR_2(temp2_crit, S_IRUGO | S_IWUSR, show_temp, set_temp,
THERM, 1);
static SENSOR_DEVICE_ATTR_2(temp2_crit_hyst, S_IRUGO | S_IWUSR, show_temp,
set_temp, HYSTERSIS, 1);
+static SENSOR_DEVICE_ATTR_2(temp2_smoothing, S_IRUGO | S_IWUSR, show_temp_st,
+ set_temp_st, 0, 1);
static SENSOR_DEVICE_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, INPUT, 2);
static SENSOR_DEVICE_ATTR_2(temp3_alarm, S_IRUGO, show_temp, NULL, ALARM, 2);
static SENSOR_DEVICE_ATTR_2(temp3_fault, S_IRUGO, show_temp, NULL, FAULT, 2);
@@ -1028,6 +1128,8 @@ static SENSOR_DEVICE_ATTR_2(temp3_crit, S_IRUGO | S_IWUSR, show_temp, set_temp,
THERM, 2);
static SENSOR_DEVICE_ATTR_2(temp3_crit_hyst, S_IRUGO | S_IWUSR, show_temp,
set_temp, HYSTERSIS, 2);
+static SENSOR_DEVICE_ATTR_2(temp3_smoothing, S_IRUGO | S_IWUSR, show_temp_st,
+ set_temp_st, 0, 2);
static SENSOR_DEVICE_ATTR_2(fan1_input, S_IRUGO, show_tach, NULL, INPUT, 0);
static SENSOR_DEVICE_ATTR_2(fan1_min, S_IRUGO | S_IWUSR, show_tach, set_tach,
MIN, 0);
@@ -1056,6 +1158,8 @@ static SENSOR_DEVICE_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO | S_IWUSR, show_pwm,
set_pwm, MIN, 0);
static SENSOR_DEVICE_ATTR_2(pwm1_auto_point2_pwm, S_IRUGO | S_IWUSR, show_pwm,
set_pwm, MAX, 0);
+static SENSOR_DEVICE_ATTR_2(pwm1_stall_disable, S_IRUGO | S_IWUSR,
+ show_stall_disable, set_stall_disable, 0, 0);
static SENSOR_DEVICE_ATTR_2(pwm2, S_IRUGO | S_IWUSR, show_pwm, set_pwm, INPUT,
1);
static SENSOR_DEVICE_ATTR_2(pwm2_freq, S_IRUGO | S_IWUSR, show_pwmfreq,
@@ -1068,6 +1172,8 @@ static SENSOR_DEVICE_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO | S_IWUSR, show_pwm,
set_pwm, MIN, 1);
static SENSOR_DEVICE_ATTR_2(pwm2_auto_point2_pwm, S_IRUGO | S_IWUSR, show_pwm,
set_pwm, MAX, 1);
+static SENSOR_DEVICE_ATTR_2(pwm2_stall_disable, S_IRUGO | S_IWUSR,
+ show_stall_disable, set_stall_disable, 0, 1);
static SENSOR_DEVICE_ATTR_2(pwm3, S_IRUGO | S_IWUSR, show_pwm, set_pwm, INPUT,
2);
static SENSOR_DEVICE_ATTR_2(pwm3_freq, S_IRUGO | S_IWUSR, show_pwmfreq,
@@ -1080,6 +1186,8 @@ static SENSOR_DEVICE_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO | S_IWUSR, show_pwm,
set_pwm, MIN, 2);
static SENSOR_DEVICE_ATTR_2(pwm3_auto_point2_pwm, S_IRUGO | S_IWUSR, show_pwm,
set_pwm, MAX, 2);
+static SENSOR_DEVICE_ATTR_2(pwm3_stall_disable, S_IRUGO | S_IWUSR,
+ show_stall_disable, set_stall_disable, 0, 2);
/* Non-standard name, might need revisiting */
static DEVICE_ATTR_RW(pwm_use_point2_pwm_at_crit);
@@ -1106,6 +1214,7 @@ static struct attribute *adt7475_attrs[] = {
&sensor_dev_attr_temp1_auto_point2_temp.dev_attr.attr,
&sensor_dev_attr_temp1_crit.dev_attr.attr,
&sensor_dev_attr_temp1_crit_hyst.dev_attr.attr,
+ &sensor_dev_attr_temp1_smoothing.dev_attr.attr,
&sensor_dev_attr_temp2_input.dev_attr.attr,
&sensor_dev_attr_temp2_alarm.dev_attr.attr,
&sensor_dev_attr_temp2_max.dev_attr.attr,
@@ -1115,6 +1224,7 @@ static struct attribute *adt7475_attrs[] = {
&sensor_dev_attr_temp2_auto_point2_temp.dev_attr.attr,
&sensor_dev_attr_temp2_crit.dev_attr.attr,
&sensor_dev_attr_temp2_crit_hyst.dev_attr.attr,
+ &sensor_dev_attr_temp2_smoothing.dev_attr.attr,
&sensor_dev_attr_temp3_input.dev_attr.attr,
&sensor_dev_attr_temp3_fault.dev_attr.attr,
&sensor_dev_attr_temp3_alarm.dev_attr.attr,
@@ -1125,6 +1235,7 @@ static struct attribute *adt7475_attrs[] = {
&sensor_dev_attr_temp3_auto_point2_temp.dev_attr.attr,
&sensor_dev_attr_temp3_crit.dev_attr.attr,
&sensor_dev_attr_temp3_crit_hyst.dev_attr.attr,
+ &sensor_dev_attr_temp3_smoothing.dev_attr.attr,
&sensor_dev_attr_fan1_input.dev_attr.attr,
&sensor_dev_attr_fan1_min.dev_attr.attr,
&sensor_dev_attr_fan1_alarm.dev_attr.attr,
@@ -1140,12 +1251,14 @@ static struct attribute *adt7475_attrs[] = {
&sensor_dev_attr_pwm1_auto_channels_temp.dev_attr.attr,
&sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr,
&sensor_dev_attr_pwm1_auto_point2_pwm.dev_attr.attr,
+ &sensor_dev_attr_pwm1_stall_disable.dev_attr.attr,
&sensor_dev_attr_pwm3.dev_attr.attr,
&sensor_dev_attr_pwm3_freq.dev_attr.attr,
&sensor_dev_attr_pwm3_enable.dev_attr.attr,
&sensor_dev_attr_pwm3_auto_channels_temp.dev_attr.attr,
&sensor_dev_attr_pwm3_auto_point1_pwm.dev_attr.attr,
&sensor_dev_attr_pwm3_auto_point2_pwm.dev_attr.attr,
+ &sensor_dev_attr_pwm3_stall_disable.dev_attr.attr,
&dev_attr_pwm_use_point2_pwm_at_crit.attr,
NULL,
};
@@ -1164,6 +1277,7 @@ static struct attribute *pwm2_attrs[] = {
&sensor_dev_attr_pwm2_auto_channels_temp.dev_attr.attr,
&sensor_dev_attr_pwm2_auto_point1_pwm.dev_attr.attr,
&sensor_dev_attr_pwm2_auto_point2_pwm.dev_attr.attr,
+ &sensor_dev_attr_pwm2_stall_disable.dev_attr.attr,
NULL
};
diff --git a/drivers/hwmon/ds620.c b/drivers/hwmon/ds620.c
index 0043a4c02b85..57d6958c74b8 100644
--- a/drivers/hwmon/ds620.c
+++ b/drivers/hwmon/ds620.c
@@ -30,7 +30,7 @@
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/sysfs.h>
-#include <linux/i2c/ds620.h>
+#include <linux/platform_data/ds620.h>
/*
* Many DS620 constants specified below
diff --git a/drivers/hwmon/ltc4245.c b/drivers/hwmon/ltc4245.c
index 4680d89556ce..082f0a0bd8a0 100644
--- a/drivers/hwmon/ltc4245.c
+++ b/drivers/hwmon/ltc4245.c
@@ -23,7 +23,7 @@
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/jiffies.h>
-#include <linux/i2c/ltc4245.h>
+#include <linux/platform_data/ltc4245.h>
/* Here are names of the chip's registers (a.k.a. commands) */
enum ltc4245_cmd {
diff --git a/drivers/hwmon/max6639.c b/drivers/hwmon/max6639.c
index dac6d85f2fd9..f98a83c79ff1 100644
--- a/drivers/hwmon/max6639.c
+++ b/drivers/hwmon/max6639.c
@@ -32,7 +32,7 @@
#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
#include <linux/mutex.h>
-#include <linux/i2c/max6639.h>
+#include <linux/platform_data/max6639.h>
/* Addresses to scan */
static const unsigned short normal_i2c[] = { 0x2c, 0x2e, 0x2f, I2C_CLIENT_END };
diff --git a/drivers/hwmon/nct6775.c b/drivers/hwmon/nct6775.c
index 2458b406f6aa..c219e43b8f02 100644
--- a/drivers/hwmon/nct6775.c
+++ b/drivers/hwmon/nct6775.c
@@ -40,6 +40,8 @@
* nct6791d 15 6 6 2+6 0xc800 0xc1 0x5ca3
* nct6792d 15 6 6 2+6 0xc910 0xc1 0x5ca3
* nct6793d 15 6 6 2+6 0xd120 0xc1 0x5ca3
+ * nct6795d 14 6 6 2+6 0xd350 0xc1 0x5ca3
+ *
*
* #temp lists the number of monitored temperature sources (first value) plus
* the number of directly connectable temperature sensors (second value).
@@ -58,13 +60,15 @@
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/acpi.h>
+#include <linux/bitops.h>
#include <linux/dmi.h>
#include <linux/io.h>
#include "lm75.h"
#define USE_ALTERNATE
-enum kinds { nct6106, nct6775, nct6776, nct6779, nct6791, nct6792, nct6793 };
+enum kinds { nct6106, nct6775, nct6776, nct6779, nct6791, nct6792, nct6793,
+ nct6795 };
/* used to set data->name = nct6775_device_names[data->sio_kind] */
static const char * const nct6775_device_names[] = {
@@ -75,6 +79,7 @@ static const char * const nct6775_device_names[] = {
"nct6791",
"nct6792",
"nct6793",
+ "nct6795",
};
static const char * const nct6775_sio_names[] __initconst = {
@@ -85,6 +90,7 @@ static const char * const nct6775_sio_names[] __initconst = {
"NCT6791D",
"NCT6792D",
"NCT6793D",
+ "NCT6795D",
};
static unsigned short force_id;
@@ -104,6 +110,7 @@ MODULE_PARM_DESC(fan_debounce, "Enable debouncing for fan RPM signal");
#define NCT6775_LD_ACPI 0x0a
#define NCT6775_LD_HWM 0x0b
#define NCT6775_LD_VID 0x0d
+#define NCT6775_LD_12 0x12
#define SIO_REG_LDSEL 0x07 /* Logical device select */
#define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */
@@ -117,6 +124,7 @@ MODULE_PARM_DESC(fan_debounce, "Enable debouncing for fan RPM signal");
#define SIO_NCT6791_ID 0xc800
#define SIO_NCT6792_ID 0xc910
#define SIO_NCT6793_ID 0xd120
+#define SIO_NCT6795_ID 0xd350
#define SIO_ID_MASK 0xFFF0
enum pwm_enable { off, manual, thermal_cruise, speed_cruise, sf3, sf4 };
@@ -360,12 +368,24 @@ static const char *const nct6775_temp_label[] = {
"PCH_DIM3_TEMP"
};
-static const u16 NCT6775_REG_TEMP_ALTERNATE[ARRAY_SIZE(nct6775_temp_label) - 1]
- = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x661, 0x662, 0x664 };
+#define NCT6775_TEMP_MASK 0x001ffffe
+
+static const u16 NCT6775_REG_TEMP_ALTERNATE[32] = {
+ [13] = 0x661,
+ [14] = 0x662,
+ [15] = 0x664,
+};
-static const u16 NCT6775_REG_TEMP_CRIT[ARRAY_SIZE(nct6775_temp_label) - 1]
- = { 0, 0, 0, 0, 0xa00, 0xa01, 0xa02, 0xa03, 0xa04, 0xa05, 0xa06,
- 0xa07 };
+static const u16 NCT6775_REG_TEMP_CRIT[32] = {
+ [4] = 0xa00,
+ [5] = 0xa01,
+ [6] = 0xa02,
+ [7] = 0xa03,
+ [8] = 0xa04,
+ [9] = 0xa05,
+ [10] = 0xa06,
+ [11] = 0xa07
+};
/* NCT6776 specific data */
@@ -434,11 +454,18 @@ static const char *const nct6776_temp_label[] = {
"BYTE_TEMP"
};
-static const u16 NCT6776_REG_TEMP_ALTERNATE[ARRAY_SIZE(nct6776_temp_label) - 1]
- = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x401, 0x402, 0x404 };
+#define NCT6776_TEMP_MASK 0x007ffffe
-static const u16 NCT6776_REG_TEMP_CRIT[ARRAY_SIZE(nct6776_temp_label) - 1]
- = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x709, 0x70a };
+static const u16 NCT6776_REG_TEMP_ALTERNATE[32] = {
+ [14] = 0x401,
+ [15] = 0x402,
+ [16] = 0x404,
+};
+
+static const u16 NCT6776_REG_TEMP_CRIT[32] = {
+ [11] = 0x709,
+ [12] = 0x70a,
+};
/* NCT6779 specific data */
@@ -525,17 +552,19 @@ static const char *const nct6779_temp_label[] = {
"Virtual_TEMP"
};
-#define NCT6779_NUM_LABELS (ARRAY_SIZE(nct6779_temp_label) - 5)
-#define NCT6791_NUM_LABELS ARRAY_SIZE(nct6779_temp_label)
+#define NCT6779_TEMP_MASK 0x07ffff7e
+#define NCT6791_TEMP_MASK 0x87ffff7e
-static const u16 NCT6779_REG_TEMP_ALTERNATE[NCT6791_NUM_LABELS - 1]
+static const u16 NCT6779_REG_TEMP_ALTERNATE[32]
= { 0x490, 0x491, 0x492, 0x493, 0x494, 0x495, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0x400, 0x401, 0x402, 0x404, 0x405, 0x406, 0x407,
0x408, 0 };
-static const u16 NCT6779_REG_TEMP_CRIT[NCT6791_NUM_LABELS - 1]
- = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x709, 0x70a };
+static const u16 NCT6779_REG_TEMP_CRIT[32] = {
+ [15] = 0x709,
+ [16] = 0x70a,
+};
/* NCT6791 specific data */
@@ -602,6 +631,8 @@ static const char *const nct6792_temp_label[] = {
"Virtual_TEMP"
};
+#define NCT6792_TEMP_MASK 0x9fffff7e
+
static const char *const nct6793_temp_label[] = {
"",
"SYSTIN",
@@ -637,6 +668,45 @@ static const char *const nct6793_temp_label[] = {
"Virtual_TEMP"
};
+#define NCT6793_TEMP_MASK 0xbfff037e
+
+static const char *const nct6795_temp_label[] = {
+ "",
+ "SYSTIN",
+ "CPUTIN",
+ "AUXTIN0",
+ "AUXTIN1",
+ "AUXTIN2",
+ "AUXTIN3",
+ "",
+ "SMBUSMASTER 0",
+ "SMBUSMASTER 1",
+ "SMBUSMASTER 2",
+ "SMBUSMASTER 3",
+ "SMBUSMASTER 4",
+ "SMBUSMASTER 5",
+ "SMBUSMASTER 6",
+ "SMBUSMASTER 7",
+ "PECI Agent 0",
+ "PECI Agent 1",
+ "PCH_CHIP_CPU_MAX_TEMP",
+ "PCH_CHIP_TEMP",
+ "PCH_CPU_TEMP",
+ "PCH_MCH_TEMP",
+ "PCH_DIM0_TEMP",
+ "PCH_DIM1_TEMP",
+ "PCH_DIM2_TEMP",
+ "PCH_DIM3_TEMP",
+ "BYTE_TEMP0",
+ "BYTE_TEMP1",
+ "PECI Agent 0 Calibration",
+ "PECI Agent 1 Calibration",
+ "",
+ "Virtual_TEMP"
+};
+
+#define NCT6795_TEMP_MASK 0xbfffff7e
+
/* NCT6102D/NCT6106D specific data */
#define NCT6106_REG_VBAT 0x318
@@ -731,11 +801,16 @@ static const s8 NCT6106_BEEP_BITS[] = {
34, -1 /* intrusion0, intrusion1 */
};
-static const u16 NCT6106_REG_TEMP_ALTERNATE[ARRAY_SIZE(nct6776_temp_label) - 1]
- = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x51, 0x52, 0x54 };
+static const u16 NCT6106_REG_TEMP_ALTERNATE[32] = {
+ [14] = 0x51,
+ [15] = 0x52,
+ [16] = 0x54,
+};
-static const u16 NCT6106_REG_TEMP_CRIT[ARRAY_SIZE(nct6776_temp_label) - 1]
- = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x204, 0x205 };
+static const u16 NCT6106_REG_TEMP_CRIT[32] = {
+ [11] = 0x204,
+ [12] = 0x205,
+};
static enum pwm_enable reg_to_pwm_enable(int pwm, int mode)
{
@@ -810,7 +885,7 @@ static u16 fan_to_reg(u32 fan, unsigned int divreg)
static inline unsigned int
div_from_reg(u8 reg)
{
- return 1 << reg;
+ return BIT(reg);
}
/*
@@ -850,7 +925,7 @@ struct nct6775_data {
u8 temp_src[NUM_TEMP];
u16 reg_temp_config[NUM_TEMP];
const char * const *temp_label;
- int temp_label_num;
+ u32 temp_mask;
u16 REG_CONFIG;
u16 REG_VBAT;
@@ -1155,6 +1230,7 @@ static bool is_word_sized(struct nct6775_data *data, u16 reg)
case nct6791:
case nct6792:
case nct6793:
+ case nct6795:
return reg == 0x150 || reg == 0x153 || reg == 0x155 ||
((reg & 0xfff0) == 0x4b0 && (reg & 0x000f) < 0x0b) ||
reg == 0x402 ||
@@ -1276,7 +1352,7 @@ static void nct6775_update_fan_div(struct nct6775_data *data)
data->fan_div[1] = (i & 0x70) >> 4;
i = nct6775_read_value(data, NCT6775_REG_FANDIV2);
data->fan_div[2] = i & 0x7;
- if (data->has_fan & (1 << 3))
+ if (data->has_fan & BIT(3))
data->fan_div[3] = (i & 0x70) >> 4;
}
@@ -1298,7 +1374,7 @@ static void nct6775_init_fan_div(struct nct6775_data *data)
* We'll compute a better divider later on.
*/
for (i = 0; i < ARRAY_SIZE(data->fan_div); i++) {
- if (!(data->has_fan & (1 << i)))
+ if (!(data->has_fan & BIT(i)))
continue;
if (data->fan_div[i] == 0) {
data->fan_div[i] = 7;
@@ -1321,7 +1397,7 @@ static void nct6775_init_fan_common(struct device *dev,
* prevents the unnecessary warning when fanX_min is reported as 0.
*/
for (i = 0; i < ARRAY_SIZE(data->fan_min); i++) {
- if (data->has_fan_min & (1 << i)) {
+ if (data->has_fan_min & BIT(i)) {
reg = nct6775_read_value(data, data->REG_FAN_MIN[i]);
if (!reg)
nct6775_write_value(data, data->REG_FAN_MIN[i],
@@ -1356,7 +1432,7 @@ static void nct6775_select_fan_div(struct device *dev,
div_from_reg(fan_div));
/* Preserve min limit if possible */
- if (data->has_fan_min & (1 << nr)) {
+ if (data->has_fan_min & BIT(nr)) {
fan_min = data->fan_min[nr];
if (fan_div > data->fan_div[nr]) {
if (fan_min != 255 && fan_min > 1)
@@ -1387,7 +1463,7 @@ static void nct6775_update_pwm(struct device *dev)
bool duty_is_dc;
for (i = 0; i < data->pwm_num; i++) {
- if (!(data->has_pwm & (1 << i)))
+ if (!(data->has_pwm & BIT(i)))
continue;
duty_is_dc = data->REG_PWM_MODE[i] &&
@@ -1457,7 +1533,7 @@ static void nct6775_update_pwm_limits(struct device *dev)
u16 reg_t;
for (i = 0; i < data->pwm_num; i++) {
- if (!(data->has_pwm & (1 << i)))
+ if (!(data->has_pwm & BIT(i)))
continue;
for (j = 0; j < ARRAY_SIZE(data->fan_time); j++) {
@@ -1507,6 +1583,7 @@ static void nct6775_update_pwm_limits(struct device *dev)
case nct6791:
case nct6792:
case nct6793:
+ case nct6795:
reg = nct6775_read_value(data,
data->REG_CRITICAL_PWM_ENABLE[i]);
if (reg & data->CRITICAL_PWM_ENABLE_MASK)
@@ -1534,7 +1611,7 @@ static struct nct6775_data *nct6775_update_device(struct device *dev)
/* Measured voltages and limits */
for (i = 0; i < data->in_num; i++) {
- if (!(data->have_in & (1 << i)))
+ if (!(data->have_in & BIT(i)))
continue;
data->in[i][0] = nct6775_read_value(data,
@@ -1549,14 +1626,14 @@ static struct nct6775_data *nct6775_update_device(struct device *dev)
for (i = 0; i < ARRAY_SIZE(data->rpm); i++) {
u16 reg;
- if (!(data->has_fan & (1 << i)))
+ if (!(data->has_fan & BIT(i)))
continue;
reg = nct6775_read_value(data, data->REG_FAN[i]);
data->rpm[i] = data->fan_from_reg(reg,
data->fan_div[i]);
- if (data->has_fan_min & (1 << i))
+ if (data->has_fan_min & BIT(i))
data->fan_min[i] = nct6775_read_value(data,
data->REG_FAN_MIN[i]);
data->fan_pulses[i] =
@@ -1571,7 +1648,7 @@ static struct nct6775_data *nct6775_update_device(struct device *dev)
/* Measured temperatures and limits */
for (i = 0; i < NUM_TEMP; i++) {
- if (!(data->have_temp & (1 << i)))
+ if (!(data->have_temp & BIT(i)))
continue;
for (j = 0; j < ARRAY_SIZE(data->reg_temp); j++) {
if (data->reg_temp[j][i])
@@ -1580,7 +1657,7 @@ static struct nct6775_data *nct6775_update_device(struct device *dev)
data->reg_temp[j][i]);
}
if (i >= NUM_TEMP_FIXED ||
- !(data->have_temp_fixed & (1 << i)))
+ !(data->have_temp_fixed & BIT(i)))
continue;
data->temp_offset[i]
= nct6775_read_value(data, data->REG_TEMP_OFFSET[i]);
@@ -1801,7 +1878,7 @@ static umode_t nct6775_in_is_visible(struct kobject *kobj,
struct nct6775_data *data = dev_get_drvdata(dev);
int in = index / 5; /* voltage index */
- if (!(data->have_in & (1 << in)))
+ if (!(data->have_in & BIT(in)))
return 0;
return attr->mode;
@@ -1911,7 +1988,7 @@ store_fan_min(struct device *dev, struct device_attribute *attr,
* even with the highest divider (128)
*/
data->fan_min[nr] = 254;
- new_div = 7; /* 128 == (1 << 7) */
+ new_div = 7; /* 128 == BIT(7) */
dev_warn(dev,
"fan%u low limit %lu below minimum %u, set to minimum\n",
nr + 1, val, data->fan_from_reg_min(254, 7));
@@ -1921,7 +1998,7 @@ store_fan_min(struct device *dev, struct device_attribute *attr,
* even with the lowest divider (1)
*/
data->fan_min[nr] = 1;
- new_div = 0; /* 1 == (1 << 0) */
+ new_div = 0; /* 1 == BIT(0) */
dev_warn(dev,
"fan%u low limit %lu above maximum %u, set to maximum\n",
nr + 1, val, data->fan_from_reg_min(1, 0));
@@ -2008,14 +2085,14 @@ static umode_t nct6775_fan_is_visible(struct kobject *kobj,
int fan = index / 6; /* fan index */
int nr = index % 6; /* attribute index */
- if (!(data->has_fan & (1 << fan)))
+ if (!(data->has_fan & BIT(fan)))
return 0;
if (nr == 1 && data->ALARM_BITS[FAN_ALARM_BASE + fan] == -1)
return 0;
if (nr == 2 && data->BEEP_BITS[FAN_ALARM_BASE + fan] == -1)
return 0;
- if (nr == 4 && !(data->has_fan_min & (1 << fan)))
+ if (nr == 4 && !(data->has_fan_min & BIT(fan)))
return 0;
if (nr == 5 && data->kind != nct6775)
return 0;
@@ -2193,7 +2270,10 @@ static umode_t nct6775_temp_is_visible(struct kobject *kobj,
int temp = index / 10; /* temp index */
int nr = index % 10; /* attribute index */
- if (!(data->have_temp & (1 << temp)))
+ if (!(data->have_temp & BIT(temp)))
+ return 0;
+
+ if (nr == 1 && !data->temp_label)
return 0;
if (nr == 2 && find_temp_source(data, temp, data->num_temp_alarms) < 0)
@@ -2215,7 +2295,7 @@ static umode_t nct6775_temp_is_visible(struct kobject *kobj,
return 0;
/* offset and type only apply to fixed sensors */
- if (nr > 7 && !(data->have_temp_fixed & (1 << temp)))
+ if (nr > 7 && !(data->have_temp_fixed & BIT(temp)))
return 0;
return attr->mode;
@@ -2484,7 +2564,7 @@ show_pwm_temp_sel_common(struct nct6775_data *data, char *buf, int src)
int i, sel = 0;
for (i = 0; i < NUM_TEMP; i++) {
- if (!(data->have_temp & (1 << i)))
+ if (!(data->have_temp & BIT(i)))
continue;
if (src == data->temp_src[i]) {
sel = i + 1;
@@ -2520,7 +2600,7 @@ store_pwm_temp_sel(struct device *dev, struct device_attribute *attr,
return err;
if (val == 0 || val > NUM_TEMP)
return -EINVAL;
- if (!(data->have_temp & (1 << (val - 1))) || !data->temp_src[val - 1])
+ if (!(data->have_temp & BIT(val - 1)) || !data->temp_src[val - 1])
return -EINVAL;
mutex_lock(&data->update_lock);
@@ -2562,7 +2642,7 @@ store_pwm_weight_temp_sel(struct device *dev, struct device_attribute *attr,
return err;
if (val > NUM_TEMP)
return -EINVAL;
- if (val && (!(data->have_temp & (1 << (val - 1))) ||
+ if (val && (!(data->have_temp & BIT(val - 1)) ||
!data->temp_src[val - 1]))
return -EINVAL;
@@ -2923,6 +3003,7 @@ store_auto_pwm(struct device *dev, struct device_attribute *attr,
case nct6791:
case nct6792:
case nct6793:
+ case nct6795:
nct6775_write_value(data, data->REG_CRITICAL_PWM[nr],
val);
reg = nct6775_read_value(data,
@@ -2995,7 +3076,7 @@ static umode_t nct6775_pwm_is_visible(struct kobject *kobj,
int pwm = index / 36; /* pwm index */
int nr = index % 36; /* attribute index */
- if (!(data->has_pwm & (1 << pwm)))
+ if (!(data->has_pwm & BIT(pwm)))
return 0;
if ((nr >= 14 && nr <= 18) || nr == 21) /* weight */
@@ -3246,7 +3327,7 @@ static inline void nct6775_init_device(struct nct6775_data *data)
/* Enable temperature sensors if needed */
for (i = 0; i < NUM_TEMP; i++) {
- if (!(data->have_temp & (1 << i)))
+ if (!(data->have_temp & BIT(i)))
continue;
if (!data->reg_temp_config[i])
continue;
@@ -3264,7 +3345,7 @@ static inline void nct6775_init_device(struct nct6775_data *data)
diode = nct6775_read_value(data, data->REG_DIODE);
for (i = 0; i < data->temp_fixed_num; i++) {
- if (!(data->have_temp_fixed & (1 << i)))
+ if (!(data->have_temp_fixed & BIT(i)))
continue;
if ((tmp & (data->DIODE_MASK << i))) /* diode */
data->temp_type[i]
@@ -3290,8 +3371,8 @@ nct6775_check_fan_inputs(struct nct6775_data *data)
if (data->kind == nct6775) {
regval = superio_inb(sioreg, 0x2c);
- fan3pin = regval & (1 << 6);
- pwm3pin = regval & (1 << 7);
+ fan3pin = regval & BIT(6);
+ pwm3pin = regval & BIT(7);
/* On NCT6775, fan4 shares pins with the fdc interface */
fan4pin = !(superio_inb(sioreg, 0x2A) & 0x80);
@@ -3357,28 +3438,57 @@ nct6775_check_fan_inputs(struct nct6775_data *data)
pwm4pin = false;
pwm5pin = false;
pwm6pin = false;
- } else { /* NCT6779D, NCT6791D, NCT6792D, or NCT6793D */
- regval = superio_inb(sioreg, 0x1c);
+ } else { /* NCT6779D, NCT6791D, NCT6792D, NCT6793D, or NCT6795D */
+ int regval_1b, regval_2a, regval_eb;
- fan3pin = !(regval & (1 << 5));
- fan4pin = !(regval & (1 << 6));
- fan5pin = !(regval & (1 << 7));
+ regval = superio_inb(sioreg, 0x1c);
- pwm3pin = !(regval & (1 << 0));
- pwm4pin = !(regval & (1 << 1));
- pwm5pin = !(regval & (1 << 2));
+ fan3pin = !(regval & BIT(5));
+ fan4pin = !(regval & BIT(6));
+ fan5pin = !(regval & BIT(7));
- fan4min = fan4pin;
+ pwm3pin = !(regval & BIT(0));
+ pwm4pin = !(regval & BIT(1));
+ pwm5pin = !(regval & BIT(2));
- if (data->kind == nct6791 || data->kind == nct6792 ||
- data->kind == nct6793) {
- regval = superio_inb(sioreg, 0x2d);
- fan6pin = (regval & (1 << 1));
- pwm6pin = (regval & (1 << 0));
- } else { /* NCT6779D */
+ regval = superio_inb(sioreg, 0x2d);
+ switch (data->kind) {
+ case nct6791:
+ case nct6792:
+ fan6pin = regval & BIT(1);
+ pwm6pin = regval & BIT(0);
+ break;
+ case nct6793:
+ case nct6795:
+ regval_1b = superio_inb(sioreg, 0x1b);
+ regval_2a = superio_inb(sioreg, 0x2a);
+
+ if (!pwm5pin)
+ pwm5pin = regval & BIT(7);
+ fan6pin = regval & BIT(1);
+ pwm6pin = regval & BIT(0);
+ if (!fan5pin)
+ fan5pin = regval_1b & BIT(5);
+
+ superio_select(sioreg, NCT6775_LD_12);
+ regval_eb = superio_inb(sioreg, 0xeb);
+ if (!fan5pin)
+ fan5pin = regval_eb & BIT(5);
+ if (!pwm5pin)
+ pwm5pin = (regval_eb & BIT(4)) &&
+ !(regval_2a & BIT(0));
+ if (!fan6pin)
+ fan6pin = regval_eb & BIT(3);
+ if (!pwm6pin)
+ pwm6pin = regval_eb & BIT(2);
+ break;
+ default: /* NCT6779D */
fan6pin = false;
pwm6pin = false;
+ break;
}
+
+ fan4min = fan4pin;
}
/* fan 1 and 2 (0x03) are always present */
@@ -3403,16 +3513,15 @@ static void add_temp_sensors(struct nct6775_data *data, const u16 *regp,
continue;
src = nct6775_read_value(data, regp[i]);
src &= 0x1f;
- if (!src || (*mask & (1 << src)))
+ if (!src || (*mask & BIT(src)))
continue;
- if (src >= data->temp_label_num ||
- !strlen(data->temp_label[src]))
+ if (!(data->temp_mask & BIT(src)))
continue;
index = __ffs(*available);
nct6775_write_value(data, data->REG_TEMP_SOURCE[index], src);
- *available &= ~(1 << index);
- *mask |= 1 << src;
+ *available &= ~BIT(index);
+ *mask |= BIT(src);
}
}
@@ -3464,7 +3573,7 @@ static int nct6775_probe(struct platform_device *pdev)
data->fan_from_reg_min = fan_from_reg13;
data->temp_label = nct6776_temp_label;
- data->temp_label_num = ARRAY_SIZE(nct6776_temp_label);
+ data->temp_mask = NCT6776_TEMP_MASK;
data->REG_VBAT = NCT6106_REG_VBAT;
data->REG_DIODE = NCT6106_REG_DIODE;
@@ -3542,7 +3651,7 @@ static int nct6775_probe(struct platform_device *pdev)
data->speed_tolerance_limit = 15;
data->temp_label = nct6775_temp_label;
- data->temp_label_num = ARRAY_SIZE(nct6775_temp_label);
+ data->temp_mask = NCT6775_TEMP_MASK;
data->REG_CONFIG = NCT6775_REG_CONFIG;
data->REG_VBAT = NCT6775_REG_VBAT;
@@ -3614,7 +3723,7 @@ static int nct6775_probe(struct platform_device *pdev)
data->speed_tolerance_limit = 63;
data->temp_label = nct6776_temp_label;
- data->temp_label_num = ARRAY_SIZE(nct6776_temp_label);
+ data->temp_mask = NCT6776_TEMP_MASK;
data->REG_CONFIG = NCT6775_REG_CONFIG;
data->REG_VBAT = NCT6775_REG_VBAT;
@@ -3686,7 +3795,7 @@ static int nct6775_probe(struct platform_device *pdev)
data->speed_tolerance_limit = 63;
data->temp_label = nct6779_temp_label;
- data->temp_label_num = NCT6779_NUM_LABELS;
+ data->temp_mask = NCT6779_TEMP_MASK;
data->REG_CONFIG = NCT6775_REG_CONFIG;
data->REG_VBAT = NCT6775_REG_VBAT;
@@ -3746,6 +3855,7 @@ static int nct6775_probe(struct platform_device *pdev)
case nct6791:
case nct6792:
case nct6793:
+ case nct6795:
data->in_num = 15;
data->pwm_num = 6;
data->auto_pwm_num = 4;
@@ -3767,15 +3877,21 @@ static int nct6775_probe(struct platform_device *pdev)
default:
case nct6791:
data->temp_label = nct6779_temp_label;
+ data->temp_mask = NCT6791_TEMP_MASK;
break;
case nct6792:
data->temp_label = nct6792_temp_label;
+ data->temp_mask = NCT6792_TEMP_MASK;
break;
case nct6793:
data->temp_label = nct6793_temp_label;
+ data->temp_mask = NCT6793_TEMP_MASK;
+ break;
+ case nct6795:
+ data->temp_label = nct6795_temp_label;
+ data->temp_mask = NCT6795_TEMP_MASK;
break;
}
- data->temp_label_num = NCT6791_NUM_LABELS;
data->REG_CONFIG = NCT6775_REG_CONFIG;
data->REG_VBAT = NCT6775_REG_VBAT;
@@ -3843,7 +3959,7 @@ static int nct6775_probe(struct platform_device *pdev)
default:
return -ENODEV;
}
- data->have_in = (1 << data->in_num) - 1;
+ data->have_in = BIT(data->in_num) - 1;
data->have_temp = 0;
/*
@@ -3861,10 +3977,10 @@ static int nct6775_probe(struct platform_device *pdev)
continue;
src = nct6775_read_value(data, data->REG_TEMP_SOURCE[i]) & 0x1f;
- if (!src || (mask & (1 << src)))
- available |= 1 << i;
+ if (!src || (mask & BIT(src)))
+ available |= BIT(i);
- mask |= 1 << src;
+ mask |= BIT(src);
}
/*
@@ -3881,23 +3997,22 @@ static int nct6775_probe(struct platform_device *pdev)
continue;
src = nct6775_read_value(data, data->REG_TEMP_SOURCE[i]) & 0x1f;
- if (!src || (mask & (1 << src)))
+ if (!src || (mask & BIT(src)))
continue;
- if (src >= data->temp_label_num ||
- !strlen(data->temp_label[src])) {
+ if (!(data->temp_mask & BIT(src))) {
dev_info(dev,
"Invalid temperature source %d at index %d, source register 0x%x, temp register 0x%x\n",
src, i, data->REG_TEMP_SOURCE[i], reg_temp[i]);
continue;
}
- mask |= 1 << src;
+ mask |= BIT(src);
/* Use fixed index for SYSTIN(1), CPUTIN(2), AUXTIN(3) */
if (src <= data->temp_fixed_num) {
- data->have_temp |= 1 << (src - 1);
- data->have_temp_fixed |= 1 << (src - 1);
+ data->have_temp |= BIT(src - 1);
+ data->have_temp_fixed |= BIT(src - 1);
data->reg_temp[0][src - 1] = reg_temp[i];
data->reg_temp[1][src - 1] = reg_temp_over[i];
data->reg_temp[2][src - 1] = reg_temp_hyst[i];
@@ -3917,7 +4032,7 @@ static int nct6775_probe(struct platform_device *pdev)
continue;
/* Use dynamic index for other sources */
- data->have_temp |= 1 << s;
+ data->have_temp |= BIT(s);
data->reg_temp[0][s] = reg_temp[i];
data->reg_temp[1][s] = reg_temp_over[i];
data->reg_temp[2][s] = reg_temp_hyst[i];
@@ -3945,8 +4060,7 @@ static int nct6775_probe(struct platform_device *pdev)
if (!src)
continue;
- if (src >= data->temp_label_num ||
- !strlen(data->temp_label[src])) {
+ if (!(data->temp_mask & BIT(src))) {
dev_info(dev,
"Invalid temperature source %d at index %d, source register 0x%x, temp register 0x%x\n",
src, i, data->REG_TEMP_SEL[i],
@@ -3960,17 +4074,17 @@ static int nct6775_probe(struct platform_device *pdev)
* are no duplicates.
*/
if (src != TEMP_SOURCE_VIRTUAL) {
- if (mask & (1 << src))
+ if (mask & BIT(src))
continue;
- mask |= 1 << src;
+ mask |= BIT(src);
}
/* Use fixed index for SYSTIN(1), CPUTIN(2), AUXTIN(3) */
if (src <= data->temp_fixed_num) {
- if (data->have_temp & (1 << (src - 1)))
+ if (data->have_temp & BIT(src - 1))
continue;
- data->have_temp |= 1 << (src - 1);
- data->have_temp_fixed |= 1 << (src - 1);
+ data->have_temp |= BIT(src - 1);
+ data->have_temp_fixed |= BIT(src - 1);
data->reg_temp[0][src - 1] = reg_temp_mon[i];
data->temp_src[src - 1] = src;
continue;
@@ -3980,7 +4094,7 @@ static int nct6775_probe(struct platform_device *pdev)
continue;
/* Use dynamic index for other sources */
- data->have_temp |= 1 << s;
+ data->have_temp |= BIT(s);
data->reg_temp[0][s] = reg_temp_mon[i];
data->temp_src[s] = src;
s++;
@@ -3993,16 +4107,18 @@ static int nct6775_probe(struct platform_device *pdev)
* The temperature is already monitored if the respective bit in <mask>
* is set.
*/
- for (i = 0; i < data->temp_label_num - 1; i++) {
+ for (i = 0; i < 32; i++) {
+ if (!(data->temp_mask & BIT(i + 1)))
+ continue;
if (!reg_temp_alternate[i])
continue;
- if (mask & (1 << (i + 1)))
+ if (mask & BIT(i + 1))
continue;
if (i < data->temp_fixed_num) {
- if (data->have_temp & (1 << i))
+ if (data->have_temp & BIT(i))
continue;
- data->have_temp |= 1 << i;
- data->have_temp_fixed |= 1 << i;
+ data->have_temp |= BIT(i);
+ data->have_temp_fixed |= BIT(i);
data->reg_temp[0][i] = reg_temp_alternate[i];
if (i < num_reg_temp) {
data->reg_temp[1][i] = reg_temp_over[i];
@@ -4015,7 +4131,7 @@ static int nct6775_probe(struct platform_device *pdev)
if (s >= NUM_TEMP) /* Abort if no more space */
break;
- data->have_temp |= 1 << s;
+ data->have_temp |= BIT(s);
data->reg_temp[0][s] = reg_temp_alternate[i];
data->temp_src[s] = i + 1;
s++;
@@ -4042,6 +4158,7 @@ static int nct6775_probe(struct platform_device *pdev)
case nct6791:
case nct6792:
case nct6793:
+ case nct6795:
break;
}
@@ -4075,6 +4192,7 @@ static int nct6775_probe(struct platform_device *pdev)
case nct6791:
case nct6792:
case nct6793:
+ case nct6795:
tmp |= 0x7e;
break;
}
@@ -4173,14 +4291,14 @@ static int __maybe_unused nct6775_resume(struct device *dev)
superio_outb(sioreg, SIO_REG_ENABLE, data->sio_reg_enable);
if (data->kind == nct6791 || data->kind == nct6792 ||
- data->kind == nct6793)
+ data->kind == nct6793 || data->kind == nct6795)
nct6791_enable_io_mapping(sioreg);
superio_exit(sioreg);
/* Restore limits */
for (i = 0; i < data->in_num; i++) {
- if (!(data->have_in & (1 << i)))
+ if (!(data->have_in & BIT(i)))
continue;
nct6775_write_value(data, data->REG_IN_MINMAX[0][i],
@@ -4190,7 +4308,7 @@ static int __maybe_unused nct6775_resume(struct device *dev)
}
for (i = 0; i < ARRAY_SIZE(data->fan_min); i++) {
- if (!(data->has_fan_min & (1 << i)))
+ if (!(data->has_fan_min & BIT(i)))
continue;
nct6775_write_value(data, data->REG_FAN_MIN[i],
@@ -4198,7 +4316,7 @@ static int __maybe_unused nct6775_resume(struct device *dev)
}
for (i = 0; i < NUM_TEMP; i++) {
- if (!(data->have_temp & (1 << i)))
+ if (!(data->have_temp & BIT(i)))
continue;
for (j = 1; j < ARRAY_SIZE(data->reg_temp); j++)
@@ -4270,6 +4388,9 @@ static int __init nct6775_find(int sioaddr, struct nct6775_sio_data *sio_data)
case SIO_NCT6793_ID:
sio_data->kind = nct6793;
break;
+ case SIO_NCT6795_ID:
+ sio_data->kind = nct6795;
+ break;
default:
if (val != 0xffff)
pr_debug("unsupported chip ID: 0x%04x\n", val);
@@ -4296,7 +4417,7 @@ static int __init nct6775_find(int sioaddr, struct nct6775_sio_data *sio_data)
}
if (sio_data->kind == nct6791 || sio_data->kind == nct6792 ||
- sio_data->kind == nct6793)
+ sio_data->kind == nct6793 || sio_data->kind == nct6795)
nct6791_enable_io_mapping(sioaddr);
superio_exit(sioaddr);
diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig
index cad1229b7e17..68d717a3fd59 100644
--- a/drivers/hwmon/pmbus/Kconfig
+++ b/drivers/hwmon/pmbus/Kconfig
@@ -37,6 +37,16 @@ config SENSORS_ADM1275
This driver can also be built as a module. If so, the module will
be called adm1275.
+config SENSORS_IR35221
+ tristate "Infineon IR35221"
+ default n
+ help
+ If you say yes here you get hardware monitoring support for the
+ Infineon IR35221 controller.
+
+ This driver can also be built as a module. If so, the module will
+ be called ir35521.
+
config SENSORS_LM25066
tristate "National Semiconductor LM25066 and compatibles"
default n
diff --git a/drivers/hwmon/pmbus/Makefile b/drivers/hwmon/pmbus/Makefile
index 562132054aaf..75bb7ca619d9 100644
--- a/drivers/hwmon/pmbus/Makefile
+++ b/drivers/hwmon/pmbus/Makefile
@@ -5,6 +5,7 @@
obj-$(CONFIG_PMBUS) += pmbus_core.o
obj-$(CONFIG_SENSORS_PMBUS) += pmbus.o
obj-$(CONFIG_SENSORS_ADM1275) += adm1275.o
+obj-$(CONFIG_SENSORS_IR35221) += ir35221.o
obj-$(CONFIG_SENSORS_LM25066) += lm25066.o
obj-$(CONFIG_SENSORS_LTC2978) += ltc2978.o
obj-$(CONFIG_SENSORS_LTC3815) += ltc3815.o
diff --git a/drivers/hwmon/pmbus/ir35221.c b/drivers/hwmon/pmbus/ir35221.c
new file mode 100644
index 000000000000..8b906b44484b
--- /dev/null
+++ b/drivers/hwmon/pmbus/ir35221.c
@@ -0,0 +1,337 @@
+/*
+ * Hardware monitoring driver for IR35221
+ *
+ * Copyright (C) IBM Corporation 2017.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include "pmbus.h"
+
+#define IR35221_MFR_VIN_PEAK 0xc5
+#define IR35221_MFR_VOUT_PEAK 0xc6
+#define IR35221_MFR_IOUT_PEAK 0xc7
+#define IR35221_MFR_TEMP_PEAK 0xc8
+#define IR35221_MFR_VIN_VALLEY 0xc9
+#define IR35221_MFR_VOUT_VALLEY 0xca
+#define IR35221_MFR_IOUT_VALLEY 0xcb
+#define IR35221_MFR_TEMP_VALLEY 0xcc
+
+static long ir35221_reg2data(int data, enum pmbus_sensor_classes class)
+{
+ s16 exponent;
+ s32 mantissa;
+ long val;
+
+ /* We only modify LINEAR11 formats */
+ exponent = ((s16)data) >> 11;
+ mantissa = ((s16)((data & 0x7ff) << 5)) >> 5;
+
+ val = mantissa * 1000L;
+
+ /* scale result to micro-units for power sensors */
+ if (class == PSC_POWER)
+ val = val * 1000L;
+
+ if (exponent >= 0)
+ val <<= exponent;
+ else
+ val >>= -exponent;
+
+ return val;
+}
+
+#define MAX_MANTISSA (1023 * 1000)
+#define MIN_MANTISSA (511 * 1000)
+
+static u16 ir35221_data2reg(long val, enum pmbus_sensor_classes class)
+{
+ s16 exponent = 0, mantissa;
+ bool negative = false;
+
+ if (val == 0)
+ return 0;
+
+ if (val < 0) {
+ negative = true;
+ val = -val;
+ }
+
+ /* Power is in uW. Convert to mW before converting. */
+ if (class == PSC_POWER)
+ val = DIV_ROUND_CLOSEST(val, 1000L);
+
+ /* Reduce large mantissa until it fits into 10 bit */
+ while (val >= MAX_MANTISSA && exponent < 15) {
+ exponent++;
+ val >>= 1;
+ }
+ /* Increase small mantissa to improve precision */
+ while (val < MIN_MANTISSA && exponent > -15) {
+ exponent--;
+ val <<= 1;
+ }
+
+ /* Convert mantissa from milli-units to units */
+ mantissa = DIV_ROUND_CLOSEST(val, 1000);
+
+ /* Ensure that resulting number is within range */
+ if (mantissa > 0x3ff)
+ mantissa = 0x3ff;
+
+ /* restore sign */
+ if (negative)
+ mantissa = -mantissa;
+
+ /* Convert to 5 bit exponent, 11 bit mantissa */
+ return (mantissa & 0x7ff) | ((exponent << 11) & 0xf800);
+}
+
+static u16 ir35221_scale_result(s16 data, int shift,
+ enum pmbus_sensor_classes class)
+{
+ long val;
+
+ val = ir35221_reg2data(data, class);
+
+ if (shift < 0)
+ val >>= -shift;
+ else
+ val <<= shift;
+
+ return ir35221_data2reg(val, class);
+}
+
+static int ir35221_read_word_data(struct i2c_client *client, int page, int reg)
+{
+ int ret;
+
+ switch (reg) {
+ case PMBUS_IOUT_OC_FAULT_LIMIT:
+ case PMBUS_IOUT_OC_WARN_LIMIT:
+ ret = pmbus_read_word_data(client, page, reg);
+ if (ret < 0)
+ break;
+ ret = ir35221_scale_result(ret, 1, PSC_CURRENT_OUT);
+ break;
+ case PMBUS_VIN_OV_FAULT_LIMIT:
+ case PMBUS_VIN_OV_WARN_LIMIT:
+ case PMBUS_VIN_UV_WARN_LIMIT:
+ ret = pmbus_read_word_data(client, page, reg);
+ ret = ir35221_scale_result(ret, -4, PSC_VOLTAGE_IN);
+ break;
+ case PMBUS_IIN_OC_WARN_LIMIT:
+ ret = pmbus_read_word_data(client, page, reg);
+ if (ret < 0)
+ break;
+ ret = ir35221_scale_result(ret, -1, PSC_CURRENT_IN);
+ break;
+ case PMBUS_READ_VIN:
+ ret = pmbus_read_word_data(client, page, PMBUS_READ_VIN);
+ if (ret < 0)
+ break;
+ ret = ir35221_scale_result(ret, -5, PSC_VOLTAGE_IN);
+ break;
+ case PMBUS_READ_IIN:
+ ret = pmbus_read_word_data(client, page, PMBUS_READ_IIN);
+ if (ret < 0)
+ break;
+ if (page == 0)
+ ret = ir35221_scale_result(ret, -4, PSC_CURRENT_IN);
+ else
+ ret = ir35221_scale_result(ret, -5, PSC_CURRENT_IN);
+ break;
+ case PMBUS_READ_POUT:
+ ret = pmbus_read_word_data(client, page, PMBUS_READ_POUT);
+ if (ret < 0)
+ break;
+ ret = ir35221_scale_result(ret, -1, PSC_POWER);
+ break;
+ case PMBUS_READ_PIN:
+ ret = pmbus_read_word_data(client, page, PMBUS_READ_PIN);
+ if (ret < 0)
+ break;
+ ret = ir35221_scale_result(ret, -1, PSC_POWER);
+ break;
+ case PMBUS_READ_IOUT:
+ ret = pmbus_read_word_data(client, page, PMBUS_READ_IOUT);
+ if (ret < 0)
+ break;
+ if (page == 0)
+ ret = ir35221_scale_result(ret, -1, PSC_CURRENT_OUT);
+ else
+ ret = ir35221_scale_result(ret, -2, PSC_CURRENT_OUT);
+ break;
+ case PMBUS_VIRT_READ_VIN_MAX:
+ ret = pmbus_read_word_data(client, page, IR35221_MFR_VIN_PEAK);
+ if (ret < 0)
+ break;
+ ret = ir35221_scale_result(ret, -5, PSC_VOLTAGE_IN);
+ break;
+ case PMBUS_VIRT_READ_VOUT_MAX:
+ ret = pmbus_read_word_data(client, page, IR35221_MFR_VOUT_PEAK);
+ break;
+ case PMBUS_VIRT_READ_IOUT_MAX:
+ ret = pmbus_read_word_data(client, page, IR35221_MFR_IOUT_PEAK);
+ if (ret < 0)
+ break;
+ if (page == 0)
+ ret = ir35221_scale_result(ret, -1, PSC_CURRENT_IN);
+ else
+ ret = ir35221_scale_result(ret, -2, PSC_CURRENT_IN);
+ break;
+ case PMBUS_VIRT_READ_TEMP_MAX:
+ ret = pmbus_read_word_data(client, page, IR35221_MFR_TEMP_PEAK);
+ break;
+ case PMBUS_VIRT_READ_VIN_MIN:
+ ret = pmbus_read_word_data(client, page,
+ IR35221_MFR_VIN_VALLEY);
+ if (ret < 0)
+ break;
+ ret = ir35221_scale_result(ret, -5, PSC_VOLTAGE_IN);
+ break;
+ case PMBUS_VIRT_READ_VOUT_MIN:
+ ret = pmbus_read_word_data(client, page,
+ IR35221_MFR_VOUT_VALLEY);
+ break;
+ case PMBUS_VIRT_READ_IOUT_MIN:
+ ret = pmbus_read_word_data(client, page,
+ IR35221_MFR_IOUT_VALLEY);
+ if (ret < 0)
+ break;
+ if (page == 0)
+ ret = ir35221_scale_result(ret, -1, PSC_CURRENT_IN);
+ else
+ ret = ir35221_scale_result(ret, -2, PSC_CURRENT_IN);
+ break;
+ case PMBUS_VIRT_READ_TEMP_MIN:
+ ret = pmbus_read_word_data(client, page,
+ IR35221_MFR_TEMP_VALLEY);
+ break;
+ default:
+ ret = -ENODATA;
+ break;
+ }
+
+ return ret;
+}
+
+static int ir35221_write_word_data(struct i2c_client *client, int page, int reg,
+ u16 word)
+{
+ int ret;
+ u16 val;
+
+ switch (reg) {
+ case PMBUS_IOUT_OC_FAULT_LIMIT:
+ case PMBUS_IOUT_OC_WARN_LIMIT:
+ val = ir35221_scale_result(word, -1, PSC_CURRENT_OUT);
+ ret = pmbus_write_word_data(client, page, reg, val);
+ break;
+ case PMBUS_VIN_OV_FAULT_LIMIT:
+ case PMBUS_VIN_OV_WARN_LIMIT:
+ case PMBUS_VIN_UV_WARN_LIMIT:
+ val = ir35221_scale_result(word, 4, PSC_VOLTAGE_IN);
+ ret = pmbus_write_word_data(client, page, reg, val);
+ break;
+ case PMBUS_IIN_OC_WARN_LIMIT:
+ val = ir35221_scale_result(word, 1, PSC_CURRENT_IN);
+ ret = pmbus_write_word_data(client, page, reg, val);
+ break;
+ default:
+ ret = -ENODATA;
+ break;
+ }
+
+ return ret;
+}
+
+static int ir35221_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct pmbus_driver_info *info;
+ u8 buf[I2C_SMBUS_BLOCK_MAX];
+ int ret;
+
+ if (!i2c_check_functionality(client->adapter,
+ I2C_FUNC_SMBUS_READ_BYTE_DATA
+ | I2C_FUNC_SMBUS_READ_WORD_DATA
+ | I2C_FUNC_SMBUS_READ_BLOCK_DATA))
+ return -ENODEV;
+
+ ret = i2c_smbus_read_block_data(client, PMBUS_MFR_ID, buf);
+ if (ret < 0) {
+ dev_err(&client->dev, "Failed to read PMBUS_MFR_ID\n");
+ return ret;
+ }
+ if (ret != 2 || strncmp(buf, "RI", strlen("RI"))) {
+ dev_err(&client->dev, "MFR_ID unrecognised\n");
+ return -ENODEV;
+ }
+
+ ret = i2c_smbus_read_block_data(client, PMBUS_MFR_MODEL, buf);
+ if (ret < 0) {
+ dev_err(&client->dev, "Failed to read PMBUS_MFR_MODEL\n");
+ return ret;
+ }
+ if (ret != 2 || !(buf[0] == 0x6c && buf[1] == 0x00)) {
+ dev_err(&client->dev, "MFR_MODEL unrecognised\n");
+ return -ENODEV;
+ }
+
+ info = devm_kzalloc(&client->dev, sizeof(struct pmbus_driver_info),
+ GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+
+ info->write_word_data = ir35221_write_word_data;
+ info->read_word_data = ir35221_read_word_data;
+
+ info->pages = 2;
+ info->format[PSC_VOLTAGE_IN] = linear;
+ info->format[PSC_VOLTAGE_OUT] = linear;
+ info->format[PSC_CURRENT_IN] = linear;
+ info->format[PSC_CURRENT_OUT] = linear;
+ info->format[PSC_POWER] = linear;
+ info->format[PSC_TEMPERATURE] = linear;
+
+ info->func[0] = PMBUS_HAVE_VIN
+ | PMBUS_HAVE_VOUT | PMBUS_HAVE_IIN
+ | PMBUS_HAVE_IOUT | PMBUS_HAVE_PIN
+ | PMBUS_HAVE_POUT | PMBUS_HAVE_TEMP
+ | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_STATUS_IOUT
+ | PMBUS_HAVE_STATUS_INPUT | PMBUS_HAVE_STATUS_TEMP;
+ info->func[1] = info->func[0];
+
+ return pmbus_do_probe(client, id, info);
+}
+
+static const struct i2c_device_id ir35221_id[] = {
+ {"ir35221", 0},
+ {}
+};
+
+MODULE_DEVICE_TABLE(i2c, ir35221_id);
+
+static struct i2c_driver ir35221_driver = {
+ .driver = {
+ .name = "ir35221",
+ },
+ .probe = ir35221_probe,
+ .remove = pmbus_do_remove,
+ .id_table = ir35221_id,
+};
+
+module_i2c_driver(ir35221_driver);
+
+MODULE_AUTHOR("Samuel Mendoza-Jonas <sam@mendozajonas.com");
+MODULE_DESCRIPTION("PMBus driver for IR35221");
+MODULE_LICENSE("GPL");
diff --git a/drivers/hwmon/pmbus/pmbus.c b/drivers/hwmon/pmbus/pmbus.c
index 44ca8a94873d..7718e58dbda5 100644
--- a/drivers/hwmon/pmbus/pmbus.c
+++ b/drivers/hwmon/pmbus/pmbus.c
@@ -25,7 +25,7 @@
#include <linux/slab.h>
#include <linux/mutex.h>
#include <linux/i2c.h>
-#include <linux/i2c/pmbus.h>
+#include <linux/pmbus.h>
#include "pmbus.h"
/*
diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c
index ba59eaef2e07..f1eff6b6c798 100644
--- a/drivers/hwmon/pmbus/pmbus_core.c
+++ b/drivers/hwmon/pmbus/pmbus_core.c
@@ -28,7 +28,7 @@
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/jiffies.h>
-#include <linux/i2c/pmbus.h>
+#include <linux/pmbus.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include "pmbus.h"
diff --git a/drivers/hwmon/pmbus/ucd9000.c b/drivers/hwmon/pmbus/ucd9000.c
index 3518f0c08934..b74dbeca2e8d 100644
--- a/drivers/hwmon/pmbus/ucd9000.c
+++ b/drivers/hwmon/pmbus/ucd9000.c
@@ -26,7 +26,7 @@
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/i2c.h>
-#include <linux/i2c/pmbus.h>
+#include <linux/pmbus.h>
#include "pmbus.h"
enum chips { ucd9000, ucd90120, ucd90124, ucd90160, ucd9090, ucd90910 };
diff --git a/drivers/hwmon/pmbus/ucd9200.c b/drivers/hwmon/pmbus/ucd9200.c
index a8712c5ded4e..3ed94585837a 100644
--- a/drivers/hwmon/pmbus/ucd9200.c
+++ b/drivers/hwmon/pmbus/ucd9200.c
@@ -25,7 +25,7 @@
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/i2c.h>
-#include <linux/i2c/pmbus.h>
+#include <linux/pmbus.h>
#include "pmbus.h"
#define UCD9200_PHASE_INFO 0xd2
diff --git a/drivers/iio/adc/ti-ads1015.c b/drivers/iio/adc/ti-ads1015.c
index f76d979fb7e8..884b8e461b17 100644
--- a/drivers/iio/adc/ti-ads1015.c
+++ b/drivers/iio/adc/ti-ads1015.c
@@ -23,7 +23,7 @@
#include <linux/mutex.h>
#include <linux/delay.h>
-#include <linux/i2c/ads1015.h>
+#include <linux/platform_data/ads1015.h>
#include <linux/iio/iio.h>
#include <linux/iio/types.h>