X-Git-Url: https://git.sur5r.net/?p=groeck-nct6775;a=blobdiff_plain;f=nct6775.c;h=bb2cf23b10623b82224f263e7ff36ad65605bd24;hp=3cd9a38442d55757594f0b290b04c8560fa578d5;hb=HEAD;hpb=7ec12358533b6c2637a83c1778e9b1d610200613 diff --git a/nct6775.c b/nct6775.c index 3cd9a38..bb2cf23 100644 --- a/nct6775.c +++ b/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 + * nct6796d 14 7 7 2+6 0xd420 0xc1 0x5ca3 * * #temp lists the number of monitored temperature sources (first value) plus * the number of directly connectable temperature sensors (second value). @@ -58,14 +60,17 @@ #include #include #include +#include #include #include +#include #include "lm75.h" #include "compat.h" #define USE_ALTERNATE -enum kinds { nct6106, nct6775, nct6776, nct6779, nct6791, nct6792, nct6793 }; +enum kinds { nct6106, nct6775, nct6776, nct6779, nct6791, nct6792, nct6793, + nct6795, nct6796 }; /* used to set data->name = nct6775_device_names[data->sio_kind] */ static const char * const nct6775_device_names[] = { @@ -76,6 +81,8 @@ static const char * const nct6775_device_names[] = { "nct6791", "nct6792", "nct6793", + "nct6795", + "nct6796", }; static const char * const nct6775_sio_names[] __initconst = { @@ -86,6 +93,8 @@ static const char * const nct6775_sio_names[] __initconst = { "NCT6791D", "NCT6792D", "NCT6793D", + "NCT6795D", + "NCT6796D", }; static unsigned short force_id; @@ -105,6 +114,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) */ @@ -118,6 +128,8 @@ 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_NCT6796_ID 0xd420 #define SIO_ID_MASK 0xFFF0 enum pwm_enable { off, manual, thermal_cruise, speed_cruise, sf3, sf4 }; @@ -194,7 +206,9 @@ superio_exit(int ioreg) #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 /* Common and NCT6775 specific data */ @@ -263,26 +277,26 @@ static const u8 NCT6775_PWM_MODE_MASK[] = { 0x01, 0x02, 0x01 }; /* 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 }; @@ -305,7 +319,7 @@ static const u16 NCT6775_REG_TEMP_SOURCE[ARRAY_SIZE(NCT6775_REG_TEMP)] = { 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 }; @@ -321,9 +335,9 @@ static const u16 NCT6775_REG_WEIGHT_TEMP_BASE[] = { 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)) @@ -331,9 +345,9 @@ static const u16 NCT6775_REG_AUTO_PWM[] = { 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[] = { "", @@ -359,12 +373,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_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_ALTERNATE[32] = { + [13] = 0x661, + [14] = 0x662, + [15] = 0x664, +}; + +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 */ @@ -393,13 +419,15 @@ static const s8 NCT6776_BEEP_BITS[] = { 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 }; -static const u16 NCT6776_REG_FAN_PULSES[] = { 0x644, 0x645, 0x646, 0, 0 }; +static const u16 NCT6776_REG_FAN_MIN[] = { + 0x63a, 0x63c, 0x63e, 0x640, 0x642, 0x64a, 0x64c }; +static const u16 NCT6776_REG_FAN_PULSES[] = { + 0x644, 0x645, 0x646, 0x647, 0x648, 0x649, 0 }; static const u16 NCT6776_REG_WEIGHT_DUTY_BASE[] = { 0x13e, 0x23e, 0x33e, 0x83e, 0x93e, 0xa3e }; @@ -433,11 +461,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_ALTERNATE[32] = { + [14] = 0x401, + [15] = 0x402, + [16] = 0x404, +}; -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_CRIT[32] = { + [11] = 0x709, + [12] = 0x70a, +}; /* NCT6779 specific data */ @@ -467,15 +502,15 @@ static const s8 NCT6779_BEEP_BITS[] = { 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 }; @@ -524,28 +559,30 @@ 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 */ #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 }; @@ -601,6 +638,8 @@ static const char *const nct6792_temp_label[] = { "Virtual_TEMP" }; +#define NCT6792_TEMP_MASK 0x9fffff7e + static const char *const nct6793_temp_label[] = { "", "SYSTIN", @@ -636,6 +675,82 @@ 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 + +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 @@ -730,11 +845,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) { @@ -809,7 +929,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); } /* @@ -853,7 +973,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; @@ -994,6 +1114,88 @@ struct nct6775_sio_data { enum kinds kind; }; +#ifdef CONFIG_DEBUG_FS + +static u16 nct6775_read_temp(struct nct6775_data *data, u16 reg); +static u16 nct6775_read_value(struct nct6775_data *data, u16 reg); + +static const char *temp_attr_names[5] = { + "input", + "max", + "hyst", + "crit", + "lcrit", +}; + +static int nct6775_seq_show(struct seq_file *s, void *v) +{ + struct device *dev = (struct device *)s->private; + struct nct6775_data *data = dev_get_drvdata(dev); + int i, j; + + seq_printf(s, "Temperatures:\n"); + for (i = 0; i < NUM_TEMP; i++) { + if (!(data->have_temp & BIT(i))) + continue; + seq_printf(s, " temp%d [source %d, %s]:\n", i + 1, + data->temp_src[i], + data->temp_label[data->temp_src[i]]); + for (j = 0; j < ARRAY_SIZE(data->reg_temp); j++) { + if (data->reg_temp[j][i]) { + seq_printf(s, " %s: reg=0x%x val=0x%x cached 0x%x\n", + temp_attr_names[j], + data->reg_temp[j][i], + nct6775_read_temp(data, data->reg_temp[j][i]), + (u16)data->temp[j][i]); + } + } + } + seq_printf(s, "Temperature sources:\n"); + for (i = 0; i < data->num_temp_alarms; i++) { + seq_printf(s, " index %d register 0x%x: val=0x%x\n", + i, data->REG_TEMP_SOURCE[i], + nct6775_read_value(data, data->REG_TEMP_SOURCE[i]) & 0x1f); + } + return 0; +} + +static int nct6775_debug_open(struct inode *inode, struct file *file) +{ + return single_open(file, nct6775_seq_show, inode->i_private); +} + +static const struct file_operations nct6775_debug_operations = { + .open = nct6775_debug_open, + .llseek = seq_lseek, + .read = seq_read, + .release = single_release, +}; + +static void nct6775_debugfs_exit(void *data) +{ + debugfs_remove_recursive(data); +} + +static int nct6775_debugfs_init(struct device *dev) +{ + struct dentry *rootdir; + + rootdir = debugfs_create_dir(dev_name(dev), NULL); + if (!rootdir) + return -ENOMEM; + + devm_add_action(dev, nct6775_debugfs_exit, rootdir); + + debugfs_create_file("registers", S_IFREG | 0444, rootdir, + dev, &nct6775_debug_operations); + + return 0; +} + +#else +static int nct6775_debugfs_init(struct device *dev) { return 0; } +#endif + struct sensor_device_template { struct device_attribute dev_attr; union { @@ -1158,11 +1360,14 @@ static bool is_word_sized(struct nct6775_data *data, u16 reg) case nct6791: 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 == 0x640 || reg == 0x642 || reg == 0x64a || + reg == 0x64c || reg == 0x660 || reg == 0x73 || reg == 0x75 || reg == 0x77 || reg == 0x79 || reg == 0x7b || reg == 0x7d; } @@ -1279,7 +1484,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; } @@ -1301,7 +1506,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; @@ -1324,7 +1529,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], @@ -1359,7 +1564,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) @@ -1390,13 +1595,13 @@ 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] && (nct6775_read_value(data, data->REG_PWM_MODE[i]) & data->PWM_MODE_MASK[i]); - data->pwm_mode[i] = duty_is_dc; + data->pwm_mode[i] = !duty_is_dc; fanmodecfg = nct6775_read_value(data, data->REG_FAN_MODE[i]); for (j = 0; j < ARRAY_SIZE(data->REG_PWM); j++) { @@ -1460,7 +1665,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++) { @@ -1510,6 +1715,8 @@ static void nct6775_update_pwm_limits(struct device *dev) case nct6791: 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) @@ -1537,7 +1744,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, @@ -1552,14 +1759,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] = @@ -1574,7 +1781,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]) @@ -1583,7 +1790,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]); @@ -1804,7 +2011,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; @@ -1914,7 +2121,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)); @@ -1924,7 +2131,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)); @@ -2011,14 +2218,16 @@ 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 == 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) return 0; @@ -2196,7 +2405,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) @@ -2218,7 +2430,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; @@ -2273,7 +2485,7 @@ show_pwm_mode(struct device *dev, struct device_attribute *attr, char *buf) struct nct6775_data *data = nct6775_update_device(dev); struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); - return sprintf(buf, "%d\n", !data->pwm_mode[sattr->index]); + return sprintf(buf, "%d\n", data->pwm_mode[sattr->index]); } static ssize_t @@ -2294,9 +2506,9 @@ store_pwm_mode(struct device *dev, struct device_attribute *attr, if (val > 1) return -EINVAL; - /* Setting DC mode is not supported for all chips/channels */ + /* Setting DC mode (0) is not supported for all chips/channels */ if (data->REG_PWM_MODE[nr] == 0) { - if (val) + if (!val) return -EINVAL; return count; } @@ -2305,7 +2517,7 @@ store_pwm_mode(struct device *dev, struct device_attribute *attr, data->pwm_mode[nr] = val; reg = nct6775_read_value(data, data->REG_PWM_MODE[nr]); reg &= ~data->PWM_MODE_MASK[nr]; - if (val) + if (!val) reg |= data->PWM_MODE_MASK[nr]; nct6775_write_value(data, data->REG_PWM_MODE[nr], reg); mutex_unlock(&data->update_lock); @@ -2487,7 +2699,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; @@ -2523,7 +2735,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); @@ -2565,7 +2777,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; @@ -2938,6 +3150,8 @@ store_auto_pwm(struct device *dev, struct device_attribute *attr, case nct6791: case nct6792: case nct6793: + case nct6795: + case nct6796: nct6775_write_value(data, data->REG_CRITICAL_PWM[nr], val); reg = nct6775_read_value(data, @@ -3010,7 +3224,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 */ @@ -3142,14 +3356,14 @@ static const struct sensor_template_group nct6775_pwm_template_group = { }; static ssize_t -show_vid(struct device *dev, struct device_attribute *attr, char *buf) +cpu0_vid_show(struct device *dev, struct device_attribute *attr, char *buf) { struct nct6775_data *data = dev_get_drvdata(dev); return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm)); } -static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL); +static DEVICE_ATTR_RO(cpu0_vid); /* Case open detection */ @@ -3263,7 +3477,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; @@ -3281,7 +3495,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] @@ -3294,8 +3508,10 @@ static inline void nct6775_init_device(struct nct6775_data *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; @@ -3307,17 +3523,11 @@ 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); - 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; @@ -3357,54 +3567,102 @@ nct6775_check_fan_inputs(struct nct6775_data *data) 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; + } else { + /* NCT6779D, NCT6791D, NCT6792D, NCT6793D, NCT6795D, NCT6796D */ + int regval_1b, regval_2a, regval_2f; + bool dsw_en; - fan4pin = false; - fan4min = false; - fan5pin = false; - fan6pin = false; - pwm4pin = false; - pwm5pin = false; - pwm6pin = false; - } else { /* NCT6779D, NCT6791D, NCT6792D, or NCT6793D */ regval = superio_inb(sioreg, 0x1c); - fan3pin = !(regval & (1 << 5)); - fan4pin = !(regval & (1 << 6)); - fan5pin = !(regval & (1 << 7)); + fan3pin = !(regval & BIT(5)); + fan4pin = !(regval & BIT(6)); + fan5pin = !(regval & BIT(7)); - pwm3pin = !(regval & (1 << 0)); - pwm4pin = !(regval & (1 << 1)); - pwm5pin = !(regval & (1 << 2)); + pwm3pin = !(regval & BIT(0)); + pwm4pin = !(regval & BIT(1)); + pwm5pin = !(regval & BIT(2)); - fan4min = fan4pin; + 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: + case nct6796: + regval_1b = superio_inb(sioreg, 0x1b); + regval_2a = superio_inb(sioreg, 0x2a); + regval_2f = superio_inb(sioreg, 0x2f); + dsw_en = regval_2f & BIT(3); + + if (!pwm5pin) + pwm5pin = regval & BIT(7); + + if (!fan5pin) + fan5pin = regval_1b & BIT(5); + + 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); + } - 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 */ - fan6pin = false; - pwm6pin = false; + if (data->kind == nct6795 || data->kind == nct6796) { + int regval_ed = superio_inb(sioreg, 0xed); + + if (!fan6pin) + fan6pin = (regval_2a & BIT(4)) && + (!dsw_en || + (dsw_en && (regval_ed & BIT(4)))); + if (!pwm6pin) + 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 */ + break; } + + fan4min = fan4pin; } /* 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); + (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, @@ -3420,16 +3678,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); } } @@ -3481,7 +3738,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; @@ -3559,7 +3816,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; @@ -3631,7 +3888,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; @@ -3703,7 +3960,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; @@ -3763,8 +4020,10 @@ static int nct6775_probe(struct platform_device *pdev) case nct6791: 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; @@ -3784,15 +4043,25 @@ 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; + case nct6796: + data->temp_label = nct6796_temp_label; + data->temp_mask = NCT6796_TEMP_MASK; break; } - data->temp_label_num = NCT6791_NUM_LABELS; data->REG_CONFIG = NCT6775_REG_CONFIG; data->REG_VBAT = NCT6775_REG_VBAT; @@ -3860,7 +4129,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; /* @@ -3878,10 +4147,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); } /* @@ -3898,23 +4167,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]; @@ -3934,7 +4202,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]; @@ -3959,11 +4227,10 @@ static int nct6775_probe(struct platform_device *pdev) continue; src = nct6775_read_value(data, data->REG_TEMP_SEL[i]) & 0x1f; - if (!src || (mask & (1 << src))) + 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], @@ -3971,14 +4238,23 @@ static int nct6775_probe(struct platform_device *pdev) continue; } - mask |= 1 << src; + /* + * For virtual temperature sources, the 'virtual' temperature + * for each fan reflects a different temperature, and there + * are no duplicates. + */ + if (src != TEMP_SOURCE_VIRTUAL) { + if (mask & BIT(src)) + continue; + 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; @@ -3988,7 +4264,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++; @@ -4001,16 +4277,18 @@ static int nct6775_probe(struct platform_device *pdev) * The temperature is already monitored if the respective bit in * 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]; @@ -4023,7 +4301,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++; @@ -4050,6 +4328,8 @@ static int nct6775_probe(struct platform_device *pdev) case nct6791: case nct6792: case nct6793: + case nct6795: + case nct6796: break; } @@ -4083,6 +4363,8 @@ static int nct6775_probe(struct platform_device *pdev) case nct6791: case nct6792: case nct6793: + case nct6795: + case nct6796: tmp |= 0x7e; break; } @@ -4142,6 +4424,8 @@ static int nct6775_probe(struct platform_device *pdev) #else hwmon_dev = devm_hwmon_device_register_with_groups(dev, data->name, data, data->groups); + if (!IS_ERR(hwmon_dev)) + nct6775_debugfs_init(hwmon_dev); #endif return PTR_ERR_OR_ZERO(hwmon_dev); } @@ -4204,14 +4488,15 @@ 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 || + data->kind == nct6796) 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], @@ -4221,7 +4506,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], @@ -4229,7 +4514,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++) @@ -4305,6 +4590,12 @@ 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; + case SIO_NCT6796_ID: + sio_data->kind = nct6796; + break; default: if (val != 0xffff) pr_debug("unsupported chip ID: 0x%04x\n", val); @@ -4331,7 +4622,8 @@ 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 || + sio_data->kind == nct6796) nct6791_enable_io_mapping(sioaddr); superio_exit(sioaddr);