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