* 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
+ * nct6796d 14 7 7 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).
#define USE_ALTERNATE
enum kinds { nct6106, nct6775, nct6776, nct6779, nct6791, nct6792, nct6793,
- nct6795 };
+ nct6795, nct6796 };
/* used to set data->name = nct6775_device_names[data->sio_kind] */
static const char * const nct6775_device_names[] = {
"nct6792",
"nct6793",
"nct6795",
+ "nct6796",
};
static const char * const nct6775_sio_names[] __initconst = {
"NCT6792D",
"NCT6793D",
"NCT6795D",
+ "NCT6796D",
};
static unsigned short force_id;
#define SIO_NCT6792_ID 0xc910
#define SIO_NCT6793_ID 0xd120
#define SIO_NCT6795_ID 0xd350
+#define SIO_NCT6796_ID 0xd420
#define SIO_ID_MASK 0xFFF0
enum pwm_enable { off, manual, thermal_cruise, speed_cruise, sf3, sf4 };
#define NUM_REG_ALARM 7 /* Max number of alarm registers */
#define NUM_REG_BEEP 5 /* Max number of beep registers */
-#define NUM_FAN 6
+#define NUM_FAN 7
#define TEMP_SOURCE_VIRTUAL 0x1f
/* Advanced Fan control, some values are common for all fans */
static const u16 NCT6775_REG_TARGET[] = {
- 0x101, 0x201, 0x301, 0x801, 0x901, 0xa01 };
+ 0x101, 0x201, 0x301, 0x801, 0x901, 0xa01, 0xb01 };
static const u16 NCT6775_REG_FAN_MODE[] = {
- 0x102, 0x202, 0x302, 0x802, 0x902, 0xa02 };
+ 0x102, 0x202, 0x302, 0x802, 0x902, 0xa02, 0xb02 };
static const u16 NCT6775_REG_FAN_STEP_DOWN_TIME[] = {
- 0x103, 0x203, 0x303, 0x803, 0x903, 0xa03 };
+ 0x103, 0x203, 0x303, 0x803, 0x903, 0xa03, 0xb03 };
static const u16 NCT6775_REG_FAN_STEP_UP_TIME[] = {
- 0x104, 0x204, 0x304, 0x804, 0x904, 0xa04 };
+ 0x104, 0x204, 0x304, 0x804, 0x904, 0xa04, 0xb04 };
static const u16 NCT6775_REG_FAN_STOP_OUTPUT[] = {
- 0x105, 0x205, 0x305, 0x805, 0x905, 0xa05 };
+ 0x105, 0x205, 0x305, 0x805, 0x905, 0xa05, 0xb05 };
static const u16 NCT6775_REG_FAN_START_OUTPUT[] = {
- 0x106, 0x206, 0x306, 0x806, 0x906, 0xa06 };
+ 0x106, 0x206, 0x306, 0x806, 0x906, 0xa06, 0xb06 };
static const u16 NCT6775_REG_FAN_MAX_OUTPUT[] = { 0x10a, 0x20a, 0x30a };
static const u16 NCT6775_REG_FAN_STEP_OUTPUT[] = { 0x10b, 0x20b, 0x30b };
static const u16 NCT6775_REG_FAN_STOP_TIME[] = {
- 0x107, 0x207, 0x307, 0x807, 0x907, 0xa07 };
+ 0x107, 0x207, 0x307, 0x807, 0x907, 0xa07, 0xb07 };
static const u16 NCT6775_REG_PWM[] = {
- 0x109, 0x209, 0x309, 0x809, 0x909, 0xa09 };
+ 0x109, 0x209, 0x309, 0x809, 0x909, 0xa09, 0xb09 };
static const u16 NCT6775_REG_PWM_READ[] = {
- 0x01, 0x03, 0x11, 0x13, 0x15, 0xa09 };
+ 0x01, 0x03, 0x11, 0x13, 0x15, 0xa09, 0xb09 };
static const u16 NCT6775_REG_FAN[] = { 0x630, 0x632, 0x634, 0x636, 0x638 };
static const u16 NCT6775_REG_FAN_MIN[] = { 0x3b, 0x3c, 0x3d };
0x621, 0x622, 0x623, 0x624, 0x625, 0x626 };
static const u16 NCT6775_REG_TEMP_SEL[] = {
- 0x100, 0x200, 0x300, 0x800, 0x900, 0xa00 };
+ 0x100, 0x200, 0x300, 0x800, 0x900, 0xa00, 0xb00 };
static const u16 NCT6775_REG_WEIGHT_TEMP_SEL[] = {
0x139, 0x239, 0x339, 0x839, 0x939, 0xa39 };
static const u16 NCT6775_REG_TEMP_OFFSET[] = { 0x454, 0x455, 0x456 };
static const u16 NCT6775_REG_AUTO_TEMP[] = {
- 0x121, 0x221, 0x321, 0x821, 0x921, 0xa21 };
+ 0x121, 0x221, 0x321, 0x821, 0x921, 0xa21, 0xb21 };
static const u16 NCT6775_REG_AUTO_PWM[] = {
- 0x127, 0x227, 0x327, 0x827, 0x927, 0xa27 };
+ 0x127, 0x227, 0x327, 0x827, 0x927, 0xa27, 0xb27 };
#define NCT6775_AUTO_TEMP(data, nr, p) ((data)->REG_AUTO_TEMP[nr] + (p))
#define NCT6775_AUTO_PWM(data, nr, p) ((data)->REG_AUTO_PWM[nr] + (p))
static const u16 NCT6775_REG_CRITICAL_ENAB[] = { 0x134, 0x234, 0x334 };
static const u16 NCT6775_REG_CRITICAL_TEMP[] = {
- 0x135, 0x235, 0x335, 0x835, 0x935, 0xa35 };
+ 0x135, 0x235, 0x335, 0x835, 0x935, 0xa35, 0xb35 };
static const u16 NCT6775_REG_CRITICAL_TEMP_TOLERANCE[] = {
- 0x138, 0x238, 0x338, 0x838, 0x938, 0xa38 };
+ 0x138, 0x238, 0x338, 0x838, 0x938, 0xa38, 0xb38 };
static const char *const nct6775_temp_label[] = {
"",
30, 31 }; /* intrusion0, intrusion1 */
static const u16 NCT6776_REG_TOLERANCE_H[] = {
- 0x10c, 0x20c, 0x30c, 0x80c, 0x90c, 0xa0c };
+ 0x10c, 0x20c, 0x30c, 0x80c, 0x90c, 0xa0c, 0xb0c };
static const u8 NCT6776_REG_PWM_MODE[] = { 0x04, 0, 0, 0, 0, 0 };
static const u8 NCT6776_PWM_MODE_MASK[] = { 0x01, 0, 0, 0, 0, 0 };
static const u16 NCT6776_REG_FAN_MIN[] = {
- 0x63a, 0x63c, 0x63e, 0x640, 0x642, 0x64a };
+ 0x63a, 0x63c, 0x63e, 0x640, 0x642, 0x64a, 0x64c };
static const u16 NCT6776_REG_FAN_PULSES[] = {
- 0x644, 0x645, 0x646, 0x647, 0x648, 0x649 };
+ 0x644, 0x645, 0x646, 0x647, 0x648, 0x649, 0 };
static const u16 NCT6776_REG_WEIGHT_DUTY_BASE[] = {
0x13e, 0x23e, 0x33e, 0x83e, 0x93e, 0xa3e };
30, 31 }; /* intrusion0, intrusion1 */
static const u16 NCT6779_REG_FAN[] = {
- 0x4b0, 0x4b2, 0x4b4, 0x4b6, 0x4b8, 0x4ba };
+ 0x4b0, 0x4b2, 0x4b4, 0x4b6, 0x4b8, 0x4ba, 0x660 };
static const u16 NCT6779_REG_FAN_PULSES[] = {
- 0x644, 0x645, 0x646, 0x647, 0x648, 0x649 };
+ 0x644, 0x645, 0x646, 0x647, 0x648, 0x649, 0 };
static const u16 NCT6779_REG_CRITICAL_PWM_ENABLE[] = {
- 0x136, 0x236, 0x336, 0x836, 0x936, 0xa36 };
+ 0x136, 0x236, 0x336, 0x836, 0x936, 0xa36, 0xb36 };
#define NCT6779_CRITICAL_PWM_ENABLE_MASK 0x01
static const u16 NCT6779_REG_CRITICAL_PWM[] = {
- 0x137, 0x237, 0x337, 0x837, 0x937, 0xa37 };
+ 0x137, 0x237, 0x337, 0x837, 0x937, 0xa37, 0xb37 };
static const u16 NCT6779_REG_TEMP[] = { 0x27, 0x150 };
static const u16 NCT6779_REG_TEMP_MON[] = { 0x73, 0x75, 0x77, 0x79, 0x7b };
#define NCT6791_REG_HM_IO_SPACE_LOCK_ENABLE 0x28
-static const u16 NCT6791_REG_WEIGHT_TEMP_SEL[6] = { 0, 0x239 };
-static const u16 NCT6791_REG_WEIGHT_TEMP_STEP[6] = { 0, 0x23a };
-static const u16 NCT6791_REG_WEIGHT_TEMP_STEP_TOL[6] = { 0, 0x23b };
-static const u16 NCT6791_REG_WEIGHT_DUTY_STEP[6] = { 0, 0x23c };
-static const u16 NCT6791_REG_WEIGHT_TEMP_BASE[6] = { 0, 0x23d };
-static const u16 NCT6791_REG_WEIGHT_DUTY_BASE[6] = { 0, 0x23e };
+static const u16 NCT6791_REG_WEIGHT_TEMP_SEL[NUM_FAN] = { 0, 0x239 };
+static const u16 NCT6791_REG_WEIGHT_TEMP_STEP[NUM_FAN] = { 0, 0x23a };
+static const u16 NCT6791_REG_WEIGHT_TEMP_STEP_TOL[NUM_FAN] = { 0, 0x23b };
+static const u16 NCT6791_REG_WEIGHT_DUTY_STEP[NUM_FAN] = { 0, 0x23c };
+static const u16 NCT6791_REG_WEIGHT_TEMP_BASE[NUM_FAN] = { 0, 0x23d };
+static const u16 NCT6791_REG_WEIGHT_DUTY_BASE[NUM_FAN] = { 0, 0x23e };
static const u16 NCT6791_REG_ALARM[NUM_REG_ALARM] = {
0x459, 0x45A, 0x45B, 0x568, 0x45D };
#define NCT6795_TEMP_MASK 0xbfffff7e
+static const char *const nct6796_temp_label[] = {
+ "",
+ "SYSTIN",
+ "CPUTIN",
+ "AUXTIN0",
+ "AUXTIN1",
+ "AUXTIN2",
+ "AUXTIN3",
+ "AUXTIN4",
+ "SMBUSMASTER 0",
+ "SMBUSMASTER 1",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "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 NCT6796_TEMP_MASK 0xbfff03fe
+
/* NCT6102D/NCT6106D specific data */
#define NCT6106_REG_VBAT 0x318
case nct6792:
case nct6793:
case nct6795:
+ case nct6796:
return reg == 0x150 || reg == 0x153 || reg == 0x155 ||
((reg & 0xfff0) == 0x4b0 && (reg & 0x000f) < 0x0b) ||
reg == 0x402 ||
reg == 0x63a || reg == 0x63c || reg == 0x63e ||
reg == 0x640 || reg == 0x642 || reg == 0x64a ||
+ reg == 0x64c || reg == 0x660 ||
reg == 0x73 || reg == 0x75 || reg == 0x77 || reg == 0x79 ||
reg == 0x7b || reg == 0x7d;
}
case nct6792:
case nct6793:
case nct6795:
+ case nct6796:
reg = nct6775_read_value(data,
data->REG_CRITICAL_PWM_ENABLE[i]);
if (reg & data->CRITICAL_PWM_ENABLE_MASK)
return 0;
if (nr == 2 && data->BEEP_BITS[FAN_ALARM_BASE + fan] == -1)
return 0;
+ if (nr == 3 && !data->REG_FAN_PULSES[fan])
+ return 0;
if (nr == 4 && !(data->has_fan_min & BIT(fan)))
return 0;
if (nr == 5 && data->kind != nct6775)
case nct6792:
case nct6793:
case nct6795:
+ case nct6796:
nct6775_write_value(data, data->REG_CRITICAL_PWM[nr],
val);
reg = nct6775_read_value(data,
static void
nct6775_check_fan_inputs(struct nct6775_data *data)
{
- bool fan3pin, fan4pin, fan4min, fan5pin, fan6pin;
- bool pwm3pin, pwm4pin, pwm5pin, pwm6pin;
+ bool fan3pin = false, fan4pin = false, fan4min = false;
+ bool fan5pin = false, fan6pin = false, fan7pin = false;
+ bool pwm3pin = false, pwm4pin = false, pwm5pin = false;
+ bool pwm6pin = false, pwm7pin = false;
int sioreg = data->sioreg;
int regval;
/* On NCT6775, fan4 shares pins with the fdc interface */
fan4pin = !(superio_inb(sioreg, 0x2A) & 0x80);
- fan4min = false;
- fan5pin = false;
- fan6pin = false;
- pwm4pin = false;
- pwm5pin = false;
- pwm6pin = false;
} else if (data->kind == nct6776) {
bool gpok = superio_inb(sioreg, 0x27) & 0x80;
const char *board_vendor, *board_name;
fan5pin = superio_inb(sioreg, 0x1C) & 0x02;
fan4min = fan4pin;
- fan6pin = false;
pwm3pin = fan3pin;
- pwm4pin = false;
- pwm5pin = false;
- pwm6pin = false;
} else if (data->kind == nct6106) {
regval = superio_inb(sioreg, 0x24);
fan3pin = !(regval & 0x80);
pwm3pin = regval & 0x08;
-
- fan4pin = false;
- fan4min = false;
- fan5pin = false;
- fan6pin = false;
- pwm4pin = false;
- pwm5pin = false;
- pwm6pin = false;
- } else { /* NCT6779D, NCT6791D, NCT6792D, NCT6793D, NCT6795D */
- int regval_1b, regval_2a, regval_2f, regval_eb;
+ } else {
+ /* NCT6779D, NCT6791D, NCT6792D, NCT6793D, NCT6795D, NCT6796D */
+ int regval_1b, regval_2a, regval_2f;
bool dsw_en;
regval = superio_inb(sioreg, 0x1c);
break;
case nct6793:
case nct6795:
+ case nct6796:
regval_1b = superio_inb(sioreg, 0x1b);
regval_2a = superio_inb(sioreg, 0x2a);
regval_2f = superio_inb(sioreg, 0x2f);
if (!fan5pin)
fan5pin = regval_1b & BIT(5);
- fan6pin = false;
- pwm6pin = false;
- if (!dsw_en) {
- fan6pin = regval & BIT(1);
- pwm6pin = regval & BIT(0);
+ superio_select(sioreg, NCT6775_LD_12);
+ if (data->kind != nct6796) {
+ int regval_eb = superio_inb(sioreg, 0xeb);
+
+ if (!dsw_en) {
+ fan6pin = regval & BIT(1);
+ pwm6pin = regval & BIT(0);
+ }
+
+ 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);
}
- 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);
-
- if (data->kind == nct6795) {
+ if (data->kind == nct6795 || data->kind == nct6796) {
int regval_ed = superio_inb(sioreg, 0xed);
if (!fan6pin)
pwm6pin = (regval_2a & BIT(3)) &&
(regval_ed & BIT(2));
}
+
+ if (data->kind == nct6796) {
+ int regval_1d = superio_inb(sioreg, 0x1d);
+ int regval_2b = superio_inb(sioreg, 0x2b);
+
+ fan7pin = !(regval_2b & BIT(2));
+ pwm7pin = !(regval_1d & (BIT(2) | BIT(3)));
+ }
+
break;
default: /* NCT6779D */
- fan6pin = false;
- pwm6pin = false;
break;
}
/* fan 1 and 2 (0x03) are always present */
data->has_fan = 0x03 | (fan3pin << 2) | (fan4pin << 3) |
- (fan5pin << 4) | (fan6pin << 5);
+ (fan5pin << 4) | (fan6pin << 5) | (fan7pin << 6);
data->has_fan_min = 0x03 | (fan3pin << 2) | (fan4min << 3) |
- (fan5pin << 4) | (fan6pin << 5);
+ (fan5pin << 4) | (fan6pin << 5) | (fan7pin << 6);
data->has_pwm = 0x03 | (pwm3pin << 2) | (pwm4pin << 3) |
- (pwm5pin << 4) | (pwm6pin << 5);
+ (pwm5pin << 4) | (pwm6pin << 5) | (pwm7pin << 6);
}
static void add_temp_sensors(struct nct6775_data *data, const u16 *regp,
case nct6792:
case nct6793:
case nct6795:
+ case nct6796:
data->in_num = 15;
- data->pwm_num = 6;
+ data->pwm_num = (data->kind == nct6796) ? 7 : 6;
data->auto_pwm_num = 4;
data->has_fan_div = false;
data->temp_fixed_num = 6;
data->temp_label = nct6795_temp_label;
data->temp_mask = NCT6795_TEMP_MASK;
break;
+ case nct6796:
+ data->temp_label = nct6795_temp_label;
+ data->temp_mask = NCT6795_TEMP_MASK;
+ break;
}
data->REG_CONFIG = NCT6775_REG_CONFIG;
case nct6792:
case nct6793:
case nct6795:
+ case nct6796:
break;
}
case nct6792:
case nct6793:
case nct6795:
+ case nct6796:
tmp |= 0x7e;
break;
}
case SIO_NCT6795_ID:
sio_data->kind = nct6795;
break;
+ case SIO_NCT6796_ID:
+ sio_data->kind = nct6796;
+ break;
default:
if (val != 0xffff)
pr_debug("unsupported chip ID: 0x%04x\n", val);