[v1,1/1] hwmon: (nct7904) Fix the incorrect rang of temperature limitation registers.

2020-05-12 Thread Amy.Shih
From: Amy Shih 

The format of temperature limitation registers are 8-bit 2's complement
and the range is -128~127.
Converts the reading value to signed char to fix the incorrect range
of temperature limitation registers.

Signed-off-by: Amy Shih 
---
 drivers/hwmon/nct7904.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/hwmon/nct7904.c b/drivers/hwmon/nct7904.c
index 6fb06f7..04f2a8e 100644
--- a/drivers/hwmon/nct7904.c
+++ b/drivers/hwmon/nct7904.c
@@ -390,6 +390,7 @@ static int nct7904_read_temp(struct device *dev, u32 attr, 
int channel,
struct nct7904_data *data = dev_get_drvdata(dev);
int ret, temp;
unsigned int reg1, reg2, reg3;
+   s8 temps;
 
switch (attr) {
case hwmon_temp_input:
@@ -495,7 +496,8 @@ static int nct7904_read_temp(struct device *dev, u32 attr, 
int channel,
 
if (ret < 0)
return ret;
-   *val = ret * 1000;
+   temps = ret;
+   *val = temps * 1000;
return 0;
 }
 
-- 
1.8.3.1



[v1,1/1] hwmon: (nct7904) Add to read all of the SMI status registers in probe function.

2020-05-11 Thread Amy.Shih
From: Amy Shih 

When nct7904 power up, it compares current sensor readings within the
default threshold immediately, thus some of SMI status registers would
get non zero values cause the false alarms on first reading. Add to
read all of the SMI status registers in probe function to clear the
alarms.

Signed-off-by: Amy Shih 
---
 drivers/hwmon/nct7904.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/hwmon/nct7904.c b/drivers/hwmon/nct7904.c
index 571a649..6fb06f7 100644
--- a/drivers/hwmon/nct7904.c
+++ b/drivers/hwmon/nct7904.c
@@ -45,6 +45,7 @@
 #define FANCTL_MAX 4   /* Counted from 1 */
 #define TCPU_MAX   8   /* Counted from 1 */
 #define TEMP_MAX   4   /* Counted from 1 */
+#define SMI_STS_MAX10  /* Counted from 1 */
 
 #define VT_ADC_CTRL0_REG   0x20/* Bank 0 */
 #define VT_ADC_CTRL1_REG   0x21/* Bank 0 */
@@ -1126,6 +1127,13 @@ static int nct7904_probe(struct i2c_client *client,
data->fan_mode[i] = ret;
}
 
+   /* Read all of SMI status register to clear alarms */
+   for (i = 0; i < SMI_STS_MAX; i++) {
+   ret = nct7904_read_reg(data, BANK_0, SMI_STS1_REG + i);
+   if (ret < 0)
+   return ret;
+   }
+
hwmon_dev =
devm_hwmon_device_register_with_info(dev, client->name, data,
 _chip_info, NULL);
-- 
1.8.3.1



[v6,1/1] hwmon: (nct7904) Fix incorrect temperature limitation register setting of LTD.

2019-09-02 Thread Amy.Shih
From: "amy.shih" 

According to kernel hwmon sysfs-interface documentation, temperature
critical max value, typically greater than corresponding temp_max values.
Thus, reads the LTD_HV_HL (LTD HIGH VALUE HIGH LIMITATION) and LTD_LV_HL
(LTD LOW VALUE HIGH LIMITATION) for case hwmon_temp_crit and
hwmon_temp_crit_hyst. Reads the LTD_HV_LL (HIGH VALUE LOW LIMITATION)
and LTD_LV_LL (LOW VALUE LOW LIMITATION) for case hwmon_temp_max
and hwmon_temp_max_hyst.

Signed-off-by: amy.shih 
---

Changes in v6:
- Fix incorrect temperature limitation register setting of LTD.
Changes in v5:
- Squashed subsequent fixes of three patches into one patch.
Changes in v4:
- Fix the incorrect return value of case hwmon_fan_min in function 
"nct7904_write_fan".
- Fix the confused calculation of case hwmon_fan_min in function
Changes in v3:
- Squashed subsequent fixes of patches into one patch.

-- Fix bad fallthrough in various switch statements.
-- Fix the wrong declared of tmp as u8 in nct7904_write_in, declared tmp to int.
-- Fix incorrect register setting of voltage.
-- Fix incorrect register bit mapping of temperature alarm.
-- Fix wrong return code 0x1fff in function nct7904_write_fan.
-- Delete wrong comment in function nct7904_write_in.
-- Fix wrong attribute names for temperature.
-- Fix wrong registers setting for temperature.

Changes in v2:
- Fix bad fallthrough in various switch statements.
- Fix the wrong declared of tmp as u8 in nct7904_write_in, declared tmp to int.
---
 drivers/hwmon/nct7904.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/hwmon/nct7904.c b/drivers/hwmon/nct7904.c
index 76372f20d71a..ce688ab4fce2 100644
--- a/drivers/hwmon/nct7904.c
+++ b/drivers/hwmon/nct7904.c
@@ -398,22 +398,22 @@ static int nct7904_read_temp(struct device *dev, u32 
attr, int channel,
}
return 0;
case hwmon_temp_max:
-   reg1 = LTD_HV_HL_REG;
+   reg1 = LTD_HV_LL_REG;
reg2 = TEMP_CH1_W_REG;
reg3 = DTS_T_CPU1_W_REG;
break;
case hwmon_temp_max_hyst:
-   reg1 = LTD_LV_HL_REG;
+   reg1 = LTD_LV_LL_REG;
reg2 = TEMP_CH1_WH_REG;
reg3 = DTS_T_CPU1_WH_REG;
break;
case hwmon_temp_crit:
-   reg1 = LTD_HV_LL_REG;
+   reg1 = LTD_HV_HL_REG;
reg2 = TEMP_CH1_C_REG;
reg3 = DTS_T_CPU1_C_REG;
break;
case hwmon_temp_crit_hyst:
-   reg1 = LTD_LV_LL_REG;
+   reg1 = LTD_LV_HL_REG;
reg2 = TEMP_CH1_CH_REG;
reg3 = DTS_T_CPU1_CH_REG;
break;
@@ -507,22 +507,22 @@ static int nct7904_write_temp(struct device *dev, u32 
attr, int channel,
 
switch (attr) {
case hwmon_temp_max:
-   reg1 = LTD_HV_HL_REG;
+   reg1 = LTD_HV_LL_REG;
reg2 = TEMP_CH1_W_REG;
reg3 = DTS_T_CPU1_W_REG;
break;
case hwmon_temp_max_hyst:
-   reg1 = LTD_LV_HL_REG;
+   reg1 = LTD_LV_LL_REG;
reg2 = TEMP_CH1_WH_REG;
reg3 = DTS_T_CPU1_WH_REG;
break;
case hwmon_temp_crit:
-   reg1 = LTD_HV_LL_REG;
+   reg1 = LTD_HV_HL_REG;
reg2 = TEMP_CH1_C_REG;
reg3 = DTS_T_CPU1_C_REG;
break;
case hwmon_temp_crit_hyst:
-   reg1 = LTD_LV_LL_REG;
+   reg1 = LTD_LV_HL_REG;
reg2 = TEMP_CH1_CH_REG;
reg3 = DTS_T_CPU1_CH_REG;
break;
-- 
2.17.1



[v2 3/3] hwmon: (nct7904) Add extra sysfs support for fan, voltage and temperature.

2019-06-30 Thread Amy.Shih
From: "amy.shih" 

NCT-7904D also supports reading of channel limitation registers
and SMI status registers for fan, voltage and temperature monitoring,
and also supports reading of temperature sensor type which is thermal diode,
thermistor, AMD SB-TSI or Intel PECI, thus add below sysfs nodes:

-fan[1-*]_min
-fan[1-*]_alarm
-in[1-*]_min
-in[1-*]_max
-in[1-*]_alarm
-temp[1-*]_max
-temp[1-*]_max_hyst
-temp[1-*]_emergency
-temp[1-*]_emergency_hyst
-temp[1-*]_alarm
-temp[1-*]_type

Signed-off-by: amy.shih 
---
Changes in v2:
- Fix bad fallthrough in various switch statements.
- Fix the wrong declared of tmp as u8 in nct7904_write_in, declared tmp to int.
- Fix incorrect register setting of voltage.
- Fix incorrect register bit mapping of temperature alarm.
- Fix wrong return code 0x1fff in function nct7904_write_fan.
- Delete wrong comment in function nct7904_write_in.
- Fix wrong attribute names for temperature.
- Fix wrong registers setting for temperature.
---
 drivers/hwmon/nct7904.c | 469 
 1 file changed, 424 insertions(+), 45 deletions(-)

diff --git a/drivers/hwmon/nct7904.c b/drivers/hwmon/nct7904.c
index 710c30562fc1..d842c10ba11f 100644
--- a/drivers/hwmon/nct7904.c
+++ b/drivers/hwmon/nct7904.c
@@ -46,10 +46,33 @@
 #define DTS_T_CTRL1_REG0x27
 #define VT_ADC_MD_REG  0x2E
 
+#define VSEN1_HV_LL_REG0x02/* Bank 1; 2 regs (HV/LV) per 
sensor */
+#define VSEN1_LV_LL_REG0x03/* Bank 1; 2 regs (HV/LV) per 
sensor */
+#define VSEN1_HV_HL_REG0x00/* Bank 1; 2 regs (HV/LV) per 
sensor */
+#define VSEN1_LV_HL_REG0x01/* Bank 1; 2 regs (HV/LV) per 
sensor */
+#define SMI_STS1_REG   0xC1/* Bank 0; SMI Status Register */
+#define SMI_STS5_REG   0xC5/* Bank 0; SMI Status Register */
+#define SMI_STS7_REG   0xC7/* Bank 0; SMI Status Register */
+#define SMI_STS8_REG   0xC8/* Bank 0; SMI Status Register */
+
 #define VSEN1_HV_REG   0x40/* Bank 0; 2 regs (HV/LV) per sensor */
 #define TEMP_CH1_HV_REG0x42/* Bank 0; same as VSEN2_HV */
 #define LTD_HV_REG 0x62/* Bank 0; 2 regs in VSEN range */
+#define LTD_HV_HL_REG  0x44/* Bank 1; 1 reg for LTD */
+#define LTD_LV_HL_REG  0x45/* Bank 1; 1 reg for LTD */
+#define LTD_HV_LL_REG  0x46/* Bank 1; 1 reg for LTD */
+#define LTD_LV_LL_REG  0x47/* Bank 1; 1 reg for LTD */
+#define TEMP_CH1_CH_REG0x05/* Bank 1; 1 reg for LTD */
+#define TEMP_CH1_W_REG 0x06/* Bank 1; 1 reg for LTD */
+#define TEMP_CH1_WH_REG0x07/* Bank 1; 1 reg for LTD */
+#define TEMP_CH1_C_REG 0x04/* Bank 1; 1 reg per sensor */
+#define DTS_T_CPU1_C_REG   0x90/* Bank 1; 1 reg per sensor */
+#define DTS_T_CPU1_CH_REG  0x91/* Bank 1; 1 reg per sensor */
+#define DTS_T_CPU1_W_REG   0x92/* Bank 1; 1 reg per sensor */
+#define DTS_T_CPU1_WH_REG  0x93/* Bank 1; 1 reg per sensor */
 #define FANIN1_HV_REG  0x80/* Bank 0; 2 regs (HV/LV) per sensor */
+#define FANIN1_HV_HL_REG   0x60/* Bank 1; 2 regs (HV/LV) per sensor */
+#define FANIN1_LV_HL_REG   0x61/* Bank 1; 2 regs (HV/LV) per sensor */
 #define T_CPU1_HV_REG  0xA0/* Bank 0; 2 regs (HV/LV) per sensor */
 
 #define PRTS_REG   0x03/* Bank 2 */
@@ -58,6 +81,8 @@
 #define FANCTL1_FMR_REG0x00/* Bank 3; 1 reg per channel */
 #define FANCTL1_OUT_REG0x10/* Bank 3; 1 reg per channel */
 
+#define ENABLE_TSI BIT(1)
+
 static const unsigned short normal_i2c[] = {
0x2d, 0x2e, I2C_CLIENT_END
 };
@@ -72,6 +97,7 @@ struct nct7904_data {
u8 fan_mode[FANCTL_MAX];
u8 enable_dts;
u8 has_dts;
+   u8 temp_mode; /* 0: TR mode, 1: TD mode */
 };
 
 /* Access functions */
@@ -170,6 +196,25 @@ static int nct7904_read_fan(struct device *dev, u32 attr, 
int channel,
rpm = 135 / cnt;
*val = rpm;
return 0;
+   case hwmon_fan_min:
+   ret = nct7904_read_reg16(data, BANK_1,
+FANIN1_HV_HL_REG + channel * 2);
+   if (ret < 0)
+   return ret;
+   cnt = ((ret & 0xff00) >> 3) | (ret & 0x1f);
+   if (cnt == 0x1fff)
+   rpm = 0;
+   else
+   rpm = 135 / cnt;
+   *val = rpm;
+   return 0;
+   case hwmon_fan_alarm:
+   ret = nct7904_read_reg(data, BANK_0,
+  SMI_STS7_REG + (channel >> 3));
+   if (ret < 0)
+   return ret;
+   *val = (ret >> (channel & 0x07)) & 1;
+   return 0;
 

[v4,1/1] hwmon: (nct7904) Add extra sysfs support for fan, voltage and temperature.

2019-06-12 Thread Amy.Shih
From: "amy.shih" 

NCT-7904D also supports reading of channel limitation registers
and SMI status registers for fan, voltage and temperature monitoring,
and also supports reading of temperature sensor type which is thermal diode,
thermistor, AMD SB-TSI or Intel PECI, thus add below sysfs nodes:

-fan[1-*]_min
-fan[1-*]_alarm
-in[1-*]_min
-in[1-*]_max
-in[1-*]_alarm
-temp[1-*]_max
-temp[1-*]_max_hyst
-temp[1-*]_crit
-temp[1-*]_crit_hyst
-temp[1-*]_alarm
-temp[1-*]_type

Signed-off-by: amy.shih 
---
 drivers/hwmon/nct7904.c | 496 +++-
 1 file changed, 444 insertions(+), 52 deletions(-)

diff --git a/drivers/hwmon/nct7904.c b/drivers/hwmon/nct7904.c
index 5708171197e7..1e6b81f12ecb 100644
--- a/drivers/hwmon/nct7904.c
+++ b/drivers/hwmon/nct7904.c
@@ -46,10 +46,33 @@
 #define DTS_T_CTRL1_REG0x27
 #define VT_ADC_MD_REG  0x2E
 
+#define VSEN1_HV_LL_REG0x02/* Bank 1; 2 regs (HV/LV) per 
sensor */
+#define VSEN1_LV_LL_REG0x03/* Bank 1; 2 regs (HV/LV) per 
sensor */
+#define VSEN1_HV_HL_REG0x00/* Bank 1; 2 regs (HV/LV) per 
sensor */
+#define VSEN1_LV_HL_REG0x01/* Bank 1; 2 regs (HV/LV) per 
sensor */
+#define SMI_STS1_REG   0xC1/* Bank 0; SMI Status Register */
+#define SMI_STS5_REG   0xC5/* Bank 0; SMI Status Register */
+#define SMI_STS7_REG   0xC7/* Bank 0; SMI Status Register */
+#define SMI_STS8_REG   0xC8/* Bank 0; SMI Status Register */
+
 #define VSEN1_HV_REG   0x40/* Bank 0; 2 regs (HV/LV) per sensor */
 #define TEMP_CH1_HV_REG0x42/* Bank 0; same as VSEN2_HV */
 #define LTD_HV_REG 0x62/* Bank 0; 2 regs in VSEN range */
+#define LTD_HV_HL_REG  0x44/* Bank 1; 1 reg for LTD */
+#define LTD_LV_HL_REG  0x45/* Bank 1; 1 reg for LTD */
+#define LTD_HV_LL_REG  0x46/* Bank 1; 1 reg for LTD */
+#define LTD_LV_LL_REG  0x47/* Bank 1; 1 reg for LTD */
+#define TEMP_CH1_CH_REG0x05/* Bank 1; 1 reg for LTD */
+#define TEMP_CH1_W_REG 0x06/* Bank 1; 1 reg for LTD */
+#define TEMP_CH1_WH_REG0x07/* Bank 1; 1 reg for LTD */
+#define TEMP_CH1_C_REG 0x04/* Bank 1; 1 reg per sensor */
+#define DTS_T_CPU1_C_REG   0x90/* Bank 1; 1 reg per sensor */
+#define DTS_T_CPU1_CH_REG  0x91/* Bank 1; 1 reg per sensor */
+#define DTS_T_CPU1_W_REG   0x92/* Bank 1; 1 reg per sensor */
+#define DTS_T_CPU1_WH_REG  0x93/* Bank 1; 1 reg per sensor */
 #define FANIN1_HV_REG  0x80/* Bank 0; 2 regs (HV/LV) per sensor */
+#define FANIN1_HV_HL_REG   0x60/* Bank 1; 2 regs (HV/LV) per sensor */
+#define FANIN1_LV_HL_REG   0x61/* Bank 1; 2 regs (HV/LV) per sensor */
 #define T_CPU1_HV_REG  0xA0/* Bank 0; 2 regs (HV/LV) per sensor */
 
 #define PRTS_REG   0x03/* Bank 2 */
@@ -58,6 +81,8 @@
 #define FANCTL1_FMR_REG0x00/* Bank 3; 1 reg per channel */
 #define FANCTL1_OUT_REG0x10/* Bank 3; 1 reg per channel */
 
+#define ENABLE_TSI BIT(1)
+
 static const unsigned short normal_i2c[] = {
0x2d, 0x2e, I2C_CLIENT_END
 };
@@ -72,6 +97,7 @@ struct nct7904_data {
u8 fan_mode[FANCTL_MAX];
u8 enable_dts;
u8 has_dts;
+   u8 temp_mode; /* 0: TR mode, 1: TD mode */
 };
 
 /* Access functions */
@@ -170,6 +196,25 @@ static int nct7904_read_fan(struct device *dev, u32 attr, 
int channel,
rpm = 135 / cnt;
*val = rpm;
return 0;
+   case hwmon_fan_min:
+   ret = nct7904_read_reg16(data, BANK_1,
+FANIN1_HV_HL_REG + channel * 2);
+   if (ret < 0)
+   return ret;
+   cnt = ((ret & 0xff00) >> 3) | (ret & 0x1f);
+   if (cnt == 0x1fff)
+   rpm = 0;
+   else
+   rpm = 135 / cnt;
+   *val = rpm;
+   return 0;
+   case hwmon_fan_alarm:
+   ret = nct7904_read_reg(data, BANK_0,
+  SMI_STS7_REG + (channel >> 3));
+   if (ret < 0)
+   return ret;
+   *val = (ret >> (channel & 0x07)) & 1;
+   return 0;
default:
return -EOPNOTSUPP;
}
@@ -179,8 +224,20 @@ static umode_t nct7904_fan_is_visible(const void *_data, 
u32 attr, int channel)
 {
const struct nct7904_data *data = _data;
 
-   if (attr == hwmon_fan_input && data->fanin_mask & (1 << channel))
-   return 0444;
+   switch (attr) {
+   case hwmon_fan_input:
+   case hwmon_fan_alarm:
+   if (data->fanin_mask & (1 <<

[PATCH] hwmon: (nct7904) Add extra sysfs support for fan, voltage and temperature.

2019-05-31 Thread Amy.Shih
From: "amy.shih" 

This patch do 2 jobs as described in below:

1. NCT-7904D also supports reading of channel limitation registers
and SMI status registers for fan, voltage and temperature monitoring,
add below sysfs nodes:

-fan[1-*]_min
-fan[1-*]_alarm
-in[0-*]_min
-in[0-*]_max
-in[0-*]_alarm
-temp[1-*]_max
-temp[1-*]_max_hyst
-temp[1-*]_emergency
-temp[1-*]_emergency_hyst
-temp[1-*]_alarm

2. Add the temp[1-*]_type sysfs to show type of temperature sensor is
thermal diode, thermistor, AMD SB-TSI or Intel PECI.

Signed-off-by: amy.shih 
---
 drivers/hwmon/nct7904.c | 492 +++-
 1 file changed, 440 insertions(+), 52 deletions(-)

diff --git a/drivers/hwmon/nct7904.c b/drivers/hwmon/nct7904.c
index 6a74df6841f0..91d1eb822707 100644
--- a/drivers/hwmon/nct7904.c
+++ b/drivers/hwmon/nct7904.c
@@ -55,10 +55,33 @@
 #define DTS_T_CTRL1_REG0x27
 #define VT_ADC_MD_REG  0x2E
 
+#define VSEN1_HV_LL_REG0x02/* Bank 1; 2 regs (HV/LV) per 
sensor */
+#define VSEN1_LV_LL_REG0x03/* Bank 1; 2 regs (HV/LV) per 
sensor */
+#define VSEN1_HV_HL_REG0x00/* Bank 1; 2 regs (HV/LV) per 
sensor */
+#define VSEN1_LV_HL_REG0x01/* Bank 1; 2 regs (HV/LV) per 
sensor */
+#define SMI_STS1_REG   0xC1/* Bank 0; SMI Status Register */
+#define SMI_STS5_REG   0xC5/* Bank 0; SMI Status Register */
+#define SMI_STS7_REG   0xC7/* Bank 0; SMI Status Register */
+#define SMI_STS8_REG   0xC8/* Bank 0; SMI Status Register */
+
 #define VSEN1_HV_REG   0x40/* Bank 0; 2 regs (HV/LV) per sensor */
 #define TEMP_CH1_HV_REG0x42/* Bank 0; same as VSEN2_HV */
 #define LTD_HV_REG 0x62/* Bank 0; 2 regs in VSEN range */
+#define LTD_HV_HL_REG  0x44/* Bank 1; 1 reg for LTD */
+#define LTD_LV_HL_REG  0x45/* Bank 1; 1 reg for LTD */
+#define LTD_HV_LL_REG  0x46/* Bank 1; 1 reg for LTD */
+#define LTD_LV_LL_REG  0x47/* Bank 1; 1 reg for LTD */
+#define TEMP_CH1_CH_REG0x05/* Bank 1; 1 reg for LTD */
+#define TEMP_CH1_W_REG 0x06/* Bank 1; 1 reg for LTD */
+#define TEMP_CH1_WH_REG0x07/* Bank 1; 1 reg for LTD */
+#define TEMP_CH1_C_REG 0x04/* Bank 1; 1 reg per sensor */
+#define DTS_T_CPU1_C_REG   0x90/* Bank 1; 1 reg per sensor */
+#define DTS_T_CPU1_CH_REG  0x91/* Bank 1; 1 reg per sensor */
+#define DTS_T_CPU1_W_REG   0x92/* Bank 1; 1 reg per sensor */
+#define DTS_T_CPU1_WH_REG  0x93/* Bank 1; 1 reg per sensor */
 #define FANIN1_HV_REG  0x80/* Bank 0; 2 regs (HV/LV) per sensor */
+#define FANIN1_HV_HL_REG   0x60/* Bank 1; 2 regs (HV/LV) per sensor */
+#define FANIN1_LV_HL_REG   0x61/* Bank 1; 2 regs (HV/LV) per sensor */
 #define T_CPU1_HV_REG  0xA0/* Bank 0; 2 regs (HV/LV) per sensor */
 
 #define PRTS_REG   0x03/* Bank 2 */
@@ -67,6 +90,8 @@
 #define FANCTL1_FMR_REG0x00/* Bank 3; 1 reg per channel */
 #define FANCTL1_OUT_REG0x10/* Bank 3; 1 reg per channel */
 
+#define ENABLE_TSI BIT(1)
+
 static const unsigned short normal_i2c[] = {
0x2d, 0x2e, I2C_CLIENT_END
 };
@@ -81,6 +106,7 @@ struct nct7904_data {
u8 fan_mode[FANCTL_MAX];
u8 enable_dts;
u8 has_dts;
+   u8 temp_mode; /* 0: TR mode, 1: TD mode */
 };
 
 /* Access functions */
@@ -179,6 +205,25 @@ static int nct7904_read_fan(struct device *dev, u32 attr, 
int channel,
rpm = 135 / cnt;
*val = rpm;
return 0;
+   case hwmon_fan_min:
+   ret = nct7904_read_reg16(data, BANK_1,
+FANIN1_HV_HL_REG + channel * 2);
+   if (ret < 0)
+   return ret;
+   cnt = ((ret & 0xff00) >> 3) | (ret & 0x1f);
+   if (cnt == 0x1fff)
+   rpm = 0;
+   else
+   rpm = 135 / cnt;
+   *val = rpm;
+   return 0;
+   case hwmon_fan_alarm:
+   ret = nct7904_read_reg(data, BANK_0,
+  SMI_STS7_REG + (channel >> 3));
+   if (ret < 0)
+   return ret;
+   *val = (ret >> (channel & 0x07)) & 1;
+   return 0;
default:
return -EOPNOTSUPP;
}
@@ -188,8 +233,18 @@ static umode_t nct7904_fan_is_visible(const void *_data, 
u32 attr, int channel)
 {
const struct nct7904_data *data = _data;
 
-   if (attr == hwmon_fan_input && data->fanin_mask & (1 << channel))
-   return 0444;
+   switch (attr) {
+   case hwmon_fan_input:
+   cas

[PATCH] hwmon: (nct7904) Add extra sysfs support for fan, voltage and tempearture. Fix the incorrect value of tcpu_mask in nct7904_data struct.

2019-05-30 Thread Amy.Shih
From: "amy.shih" 

This patch do 3 jobs as described in below:

1. NCT-7904D also supports reading of channel limitation registers
and SMI status registers for fan, voltage and tempearture monitoring,
add below sysfs nodes:

-fan[1-*]_min
-fan[1-*]_alarm
-in[0-*]_min
-in[0-*]_max
-in[0-*]_alarm
-temp[1-*]_max
-temp[1-*]_max_hyst
-temp[1-*]_emergency
-temp[1-*]_emergency_hyst
-temp[1-*]_alarm

2. Add the temp[1-*]_type sysfs to show type of tempearture sensor is
thermal diode, thermistor, AMD SB-TSI or Intel PECI.

3. Detect the multi-function of voltage, thermal diode and thermistor
from register VT_ADC_MD_REG to set value of tcpu_mask in nct7904_data
struct, set temp[1-5]_input the input values TEMP_CH1~4 and LTD of
temperature. Set temp[6~13]_input the input values of DTS temperature
that correspond to sensors TCPU1~8.

Signed-off-by: amy.shih 
---
 drivers/hwmon/nct7904.c | 527 
 1 file changed, 474 insertions(+), 53 deletions(-)

diff --git a/drivers/hwmon/nct7904.c b/drivers/hwmon/nct7904.c
index 04516789b070..a7592305f297 100644
--- a/drivers/hwmon/nct7904.c
+++ b/drivers/hwmon/nct7904.c
@@ -4,6 +4,9 @@
  * Copyright (c) 2015 Kontron
  * Author: Vadim V. Vlasov 
  *
+ * Copyright (c) 2019 Advantech
+ * Author: Amy.Shih 
+ *
  * 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
@@ -52,13 +55,38 @@
 #define DTS_T_CTRL1_REG0x27
 #define VT_ADC_MD_REG  0x2E
 
+#define VSEN1_HV_LL_REG0x02/* Bank 1; 2 regs (HV/LV) per 
sensor */
+#define VSEN1_LV_LL_REG0x03/* Bank 1; 2 regs (HV/LV) per 
sensor */
+#define VSEN1_HV_HL_REG0x00/* Bank 1; 2 regs (HV/LV) per 
sensor */
+#define VSEN1_LV_HL_REG0x01/* Bank 1; 2 regs (HV/LV) per 
sensor */
+#define SMI_STS1_REG   0xC1/* Bank 0; SMI Status Register */
+#define SMI_STS5_REG   0xC5/* Bank 0; SMI Status Register */
+#define SMI_STS7_REG   0xC7/* Bank 0; SMI Status Register */
+#define SMI_STS8_REG   0xC8/* Bank 0; SMI Status Register */
+
 #define VSEN1_HV_REG   0x40/* Bank 0; 2 regs (HV/LV) per sensor */
 #define TEMP_CH1_HV_REG0x42/* Bank 0; same as VSEN2_HV */
 #define LTD_HV_REG 0x62/* Bank 0; 2 regs in VSEN range */
+#define LTD_HV_HL_REG  0x44/* Bank 1; 1 reg for LTD */
+#define LTD_LV_HL_REG  0x45/* Bank 1; 1 reg for LTD */
+#define LTD_HV_LL_REG  0x46/* Bank 1; 1 reg for LTD */
+#define LTD_LV_LL_REG  0x47/* Bank 1; 1 reg for LTD */
+#define TEMP_CH1_CH_REG0x05/* Bank 1; 1 reg for LTD */
+#define TEMP_CH1_W_REG 0x06/* Bank 1; 1 reg for LTD */
+#define TEMP_CH1_WH_REG0x07/* Bank 1; 1 reg for LTD */
+#define TEMP_CH1_C_REG 0x04/* Bank 1; 1 reg per sensor */
+#define DTS_T_CPU1_C_REG   0x90/* Bank 1; 1 reg per sensor */
+#define DTS_T_CPU1_CH_REG  0x91/* Bank 1; 1 reg per sensor */
+#define DTS_T_CPU1_W_REG   0x92/* Bank 1; 1 reg per sensor */
+#define DTS_T_CPU1_WH_REG  0x93/* Bank 1; 1 reg per sensor */
 #define FANIN1_HV_REG  0x80/* Bank 0; 2 regs (HV/LV) per sensor */
+#define FANIN1_HV_HL_REG   0x60/* Bank 1; 2 regs (HV/LV) per sensor */
+#define FANIN1_LV_HL_REG   0x61/* Bank 1; 2 regs (HV/LV) per sensor */
 #define T_CPU1_HV_REG  0xA0/* Bank 0; 2 regs (HV/LV) per sensor */
 
 #define PRTS_REG   0x03/* Bank 2 */
+#define PFE_REG0x00/* Bank 2; PECI Function Enable 
*/
+#define TSI_CTRL_REG   0x50/* Bank 2; TSI Control Register */
 #define FANCTL1_FMR_REG0x00/* Bank 3; 1 reg per channel */
 #define FANCTL1_OUT_REG0x10/* Bank 3; 1 reg per channel */
 
@@ -74,6 +102,9 @@ struct nct7904_data {
u32 vsen_mask;
u32 tcpu_mask;
u8 fan_mode[FANCTL_MAX];
+   u8 enable_dts;
+   u8 has_dts;
+   u8 temp_mode; /* 0: TR mode, 1: TD mode */
 };
 
 /* Access functions */
@@ -172,6 +203,25 @@ static int nct7904_read_fan(struct device *dev, u32 attr, 
int channel,
rpm = 135 / cnt;
*val = rpm;
return 0;
+   case hwmon_fan_min:
+   ret = nct7904_read_reg16(data, BANK_1,
+FANIN1_HV_HL_REG + channel * 2);
+   if (ret < 0)
+   return ret;
+   cnt = ((ret & 0xff00) >> 3) | (ret & 0x1f);
+   if (cnt == 0x1fff)
+   rpm = 0;
+   else
+   rpm = 135 / cnt;
+   *val = rpm;
+   return 0;
+   case hwmon_fan