Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 | /* SPDX-License-Identifier: GPL-2.0-or-later */ #ifndef __HWMON_NCT6775_H__ #define __HWMON_NCT6775_H__ #include <linux/types.h> enum kinds { nct6106 = 1, nct6116, nct6775, nct6776, nct6779, nct6791, nct6792, nct6793, nct6795, nct6796, nct6797, nct6798, nct6799 }; enum pwm_enable { off, manual, thermal_cruise, speed_cruise, sf3, sf4 }; #define NUM_TEMP 12 /* Max number of temp attribute sets w/ limits*/ #define NUM_TEMP_FIXED 6 /* Max number of fixed temp attribute sets */ #define NUM_TSI_TEMP 8 /* Max number of TSI temp register pairs */ #define NUM_REG_ALARM 7 /* Max number of alarm registers */ #define NUM_REG_BEEP 5 /* Max number of beep registers */ #define NUM_FAN 7 #define NUM_IN 18 struct nct6775_data { int addr; /* IO base of hw monitor block */ int sioreg; /* SIO register address */ enum kinds kind; const char *name; const struct attribute_group *groups[7]; u8 num_groups; u16 reg_temp[5][NUM_TEMP]; /* 0=temp, 1=temp_over, 2=temp_hyst, * 3=temp_crit, 4=temp_lcrit */ u8 temp_src[NUM_TEMP]; u16 reg_temp_config[NUM_TEMP]; const char * const *temp_label; u32 temp_mask; u32 virt_temp_mask; u16 REG_CONFIG; u16 REG_VBAT; u16 REG_DIODE; u8 DIODE_MASK; const s8 *ALARM_BITS; const s8 *BEEP_BITS; const u16 *REG_VIN; const u16 *REG_IN_MINMAX[2]; const u16 *REG_TARGET; const u16 *REG_FAN; const u16 *REG_FAN_MODE; const u16 *REG_FAN_MIN; const u16 *REG_FAN_PULSES; const u16 *FAN_PULSE_SHIFT; const u16 *REG_FAN_TIME[3]; const u16 *REG_TOLERANCE_H; const u8 *REG_PWM_MODE; const u8 *PWM_MODE_MASK; const u16 *REG_PWM[7]; /* [0]=pwm, [1]=pwm_start, [2]=pwm_floor, * [3]=pwm_max, [4]=pwm_step, * [5]=weight_duty_step, [6]=weight_duty_base */ const u16 *REG_PWM_READ; const u16 *REG_CRITICAL_PWM_ENABLE; u8 CRITICAL_PWM_ENABLE_MASK; const u16 *REG_CRITICAL_PWM; const u16 *REG_AUTO_TEMP; const u16 *REG_AUTO_PWM; const u16 *REG_CRITICAL_TEMP; const u16 *REG_CRITICAL_TEMP_TOLERANCE; const u16 *REG_TEMP_SOURCE; /* temp register sources */ const u16 *REG_TEMP_SEL; const u16 *REG_WEIGHT_TEMP_SEL; const u16 *REG_WEIGHT_TEMP[3]; /* 0=base, 1=tolerance, 2=step */ const u16 *REG_TEMP_OFFSET; const u16 *REG_ALARM; const u16 *REG_BEEP; const u16 *REG_TSI_TEMP; unsigned int (*fan_from_reg)(u16 reg, unsigned int divreg); unsigned int (*fan_from_reg_min)(u16 reg, unsigned int divreg); struct mutex update_lock; bool valid; /* true if following fields are valid */ unsigned long last_updated; /* In jiffies */ /* Register values */ u8 bank; /* current register bank */ u8 in_num; /* number of in inputs we have */ u8 in[NUM_IN][3]; /* [0]=in, [1]=in_max, [2]=in_min */ const u16 *scale_in; /* internal scaling factors */ unsigned int rpm[NUM_FAN]; u16 fan_min[NUM_FAN]; u8 fan_pulses[NUM_FAN]; u8 fan_div[NUM_FAN]; u8 has_pwm; u8 has_fan; /* some fan inputs can be disabled */ u8 has_fan_min; /* some fans don't have min register */ bool has_fan_div; u8 num_temp_alarms; /* 2, 3, or 6 */ u8 num_temp_beeps; /* 2, 3, or 6 */ u8 temp_fixed_num; /* 3 or 6 */ u8 temp_type[NUM_TEMP_FIXED]; s8 temp_offset[NUM_TEMP_FIXED]; s16 temp[5][NUM_TEMP]; /* 0=temp, 1=temp_over, 2=temp_hyst, * 3=temp_crit, 4=temp_lcrit */ s16 tsi_temp[NUM_TSI_TEMP]; u64 alarms; u64 beeps; u8 pwm_num; /* number of pwm */ u8 pwm_mode[NUM_FAN]; /* 0->DC variable voltage, * 1->PWM variable duty cycle */ enum pwm_enable pwm_enable[NUM_FAN]; /* 0->off * 1->manual * 2->thermal cruise mode (also called SmartFan I) * 3->fan speed cruise mode * 4->SmartFan III * 5->enhanced variable thermal cruise (SmartFan IV) */ u8 pwm[7][NUM_FAN]; /* [0]=pwm, [1]=pwm_start, [2]=pwm_floor, * [3]=pwm_max, [4]=pwm_step, * [5]=weight_duty_step, [6]=weight_duty_base */ u8 target_temp[NUM_FAN]; u8 target_temp_mask; u32 target_speed[NUM_FAN]; u32 target_speed_tolerance[NUM_FAN]; u8 speed_tolerance_limit; u8 temp_tolerance[2][NUM_FAN]; u8 tolerance_mask; u8 fan_time[3][NUM_FAN]; /* 0 = stop_time, 1 = step_up, 2 = step_down */ /* Automatic fan speed control registers */ int auto_pwm_num; u8 auto_pwm[NUM_FAN][7]; u8 auto_temp[NUM_FAN][7]; u8 pwm_temp_sel[NUM_FAN]; u8 pwm_weight_temp_sel[NUM_FAN]; u8 weight_temp[3][NUM_FAN]; /* 0->temp_step, 1->temp_step_tol, * 2->temp_base */ u8 vid; u8 vrm; bool have_vid; u16 have_temp; u16 have_temp_fixed; u16 have_tsi_temp; u32 have_in; /* Remember extra register values over suspend/resume */ u8 vbat; u8 fandiv1; u8 fandiv2; u8 sio_reg_enable; struct regmap *regmap; bool read_only; /* driver-specific (platform, i2c) initialization hook and data */ int (*driver_init)(struct nct6775_data *data); void *driver_data; }; static inline int nct6775_read_value(struct nct6775_data *data, u16 reg, u16 *value) { unsigned int tmp; int ret = regmap_read(data->regmap, reg, &tmp); if (!ret) *value = tmp; return ret; } static inline int nct6775_write_value(struct nct6775_data *data, u16 reg, u16 value) { return regmap_write(data->regmap, reg, value); } struct nct6775_data *nct6775_update_device(struct device *dev); bool nct6775_reg_is_word_sized(struct nct6775_data *data, u16 reg); int nct6775_probe(struct device *dev, struct nct6775_data *data, const struct regmap_config *regmapcfg); ssize_t nct6775_show_alarm(struct device *dev, struct device_attribute *attr, char *buf); ssize_t nct6775_show_beep(struct device *dev, struct device_attribute *attr, char *buf); ssize_t nct6775_store_beep(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); static inline int nct6775_write_temp(struct nct6775_data *data, u16 reg, u16 value) { if (!nct6775_reg_is_word_sized(data, reg)) value >>= 8; return nct6775_write_value(data, reg, value); } static inline umode_t nct6775_attr_mode(struct nct6775_data *data, struct attribute *attr) { return data->read_only ? (attr->mode & ~0222) : attr->mode; } static inline int nct6775_add_attr_group(struct nct6775_data *data, const struct attribute_group *group) { /* Need to leave a NULL terminator at the end of data->groups */ if (data->num_groups == ARRAY_SIZE(data->groups) - 1) return -ENOBUFS; data->groups[data->num_groups++] = group; return 0; } #define NCT6775_REG_BANK 0x4E #define NCT6775_REG_CONFIG 0x40 #define NCT6775_REG_FANDIV1 0x506 #define NCT6775_REG_FANDIV2 0x507 #define NCT6791_REG_HM_IO_SPACE_LOCK_ENABLE 0x28 /* * ALARM_BITS and BEEP_BITS store bit-index for the mask of the registers * loaded into data->alarm and data->beep. * * Every input register (IN/TEMP/FAN) must have a corresponding * ALARM/BEEP bit at the same index BITS[BASE + index] * Set value to -1 to disable the visibility of that '*_alarm' attribute and * to pad the bits until the next BASE * * Beep has an additional GLOBAL_BEEP_ENABLE bit */ #define VIN_ALARM_BASE 0 #define FAN_ALARM_BASE 24 #define TEMP_ALARM_BASE 36 #define INTRUSION_ALARM_BASE 48 #define BEEP_ENABLE_BASE 50 #define NUM_ALARM_BITS (INTRUSION_ALARM_BASE + 4) #define NUM_BEEP_BITS (BEEP_ENABLE_BASE + 1) /* * Not currently used: * REG_MAN_ID has the value 0x5ca3 for all supported chips. * REG_CHIP_ID == 0x88/0xa1/0xc1 depending on chip model. * REG_MAN_ID is at port 0x4f * REG_CHIP_ID is at port 0x58 */ #endif /* __HWMON_NCT6775_H__ */ |