1 /*************************************************************************** 2 * Copyright (C) 2006 by Hans Edgington <hans@edgington.nl> * 3 * Copyright (C) 2007,2008 by Hans de Goede <hdegoede@redhat.com> * 4 * * 5 * This program is free software; you can redistribute it and/or modify * 6 * it under the terms of the GNU General Public License as published by * 7 * the Free Software Foundation; either version 2 of the License, or * 8 * (at your option) any later version. * 9 * * 10 * This program is distributed in the hope that it will be useful, * 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 13 * GNU General Public License for more details. * 14 * * 15 * You should have received a copy of the GNU General Public License * 16 * along with this program; if not, write to the * 17 * Free Software Foundation, Inc., * 18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 19 ***************************************************************************/ 20 21 #include <linux/module.h> 22 #include <linux/init.h> 23 #include <linux/slab.h> 24 #include <linux/jiffies.h> 25 #include <linux/platform_device.h> 26 #include <linux/hwmon.h> 27 #include <linux/hwmon-sysfs.h> 28 #include <linux/err.h> 29 #include <linux/mutex.h> 30 #include <linux/io.h> 31 #include <linux/acpi.h> 32 33 #define DRVNAME "f71882fg" 34 35 #define SIO_F71882FG_LD_HWM 0x04 /* Hardware monitor logical device */ 36 #define SIO_UNLOCK_KEY 0x87 /* Key to enable Super-I/O */ 37 #define SIO_LOCK_KEY 0xAA /* Key to diasble Super-I/O */ 38 39 #define SIO_REG_LDSEL 0x07 /* Logical device select */ 40 #define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */ 41 #define SIO_REG_DEVREV 0x22 /* Device revision */ 42 #define SIO_REG_MANID 0x23 /* Fintek ID (2 bytes) */ 43 #define SIO_REG_ENABLE 0x30 /* Logical device enable */ 44 #define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */ 45 46 #define SIO_FINTEK_ID 0x1934 /* Manufacturers ID */ 47 #define SIO_F71862_ID 0x0601 /* Chipset ID */ 48 #define SIO_F71882_ID 0x0541 /* Chipset ID */ 49 #define SIO_F8000_ID 0x0581 /* Chipset ID */ 50 51 #define REGION_LENGTH 8 52 #define ADDR_REG_OFFSET 5 53 #define DATA_REG_OFFSET 6 54 55 #define F71882FG_REG_PECI 0x0A 56 57 #define F71882FG_REG_IN_STATUS 0x12 /* f71882fg only */ 58 #define F71882FG_REG_IN_BEEP 0x13 /* f71882fg only */ 59 #define F71882FG_REG_IN(nr) (0x20 + (nr)) 60 #define F71882FG_REG_IN1_HIGH 0x32 /* f71882fg only */ 61 62 #define F71882FG_REG_FAN(nr) (0xA0 + (16 * (nr))) 63 #define F71882FG_REG_FAN_TARGET(nr) (0xA2 + (16 * (nr))) 64 #define F71882FG_REG_FAN_FULL_SPEED(nr) (0xA4 + (16 * (nr))) 65 #define F71882FG_REG_FAN_STATUS 0x92 66 #define F71882FG_REG_FAN_BEEP 0x93 67 68 #define F71882FG_REG_TEMP(nr) (0x70 + 2 * (nr)) 69 #define F71882FG_REG_TEMP_OVT(nr) (0x80 + 2 * (nr)) 70 #define F71882FG_REG_TEMP_HIGH(nr) (0x81 + 2 * (nr)) 71 #define F71882FG_REG_TEMP_STATUS 0x62 72 #define F71882FG_REG_TEMP_BEEP 0x63 73 #define F71882FG_REG_TEMP_HYST(nr) (0x6C + (nr)) 74 #define F71882FG_REG_TEMP_TYPE 0x6B 75 #define F71882FG_REG_TEMP_DIODE_OPEN 0x6F 76 77 #define F71882FG_REG_PWM(nr) (0xA3 + (16 * (nr))) 78 #define F71882FG_REG_PWM_TYPE 0x94 79 #define F71882FG_REG_PWM_ENABLE 0x96 80 81 #define F71882FG_REG_FAN_HYST(nr) (0x98 + (nr)) 82 83 #define F71882FG_REG_POINT_PWM(pwm, point) (0xAA + (point) + (16 * (pwm))) 84 #define F71882FG_REG_POINT_TEMP(pwm, point) (0xA6 + (point) + (16 * (pwm))) 85 #define F71882FG_REG_POINT_MAPPING(nr) (0xAF + 16 * (nr)) 86 87 #define F71882FG_REG_START 0x01 88 89 #define FAN_MIN_DETECT 366 /* Lowest detectable fanspeed */ 90 91 static unsigned short force_id; 92 module_param(force_id, ushort, 0); 93 MODULE_PARM_DESC(force_id, "Override the detected device ID"); 94 95 enum chips { f71862fg, f71882fg, f8000 }; 96 97 static const char *f71882fg_names[] = { 98 "f71862fg", 99 "f71882fg", 100 "f8000", 101 }; 102 103 static struct platform_device *f71882fg_pdev; 104 105 /* Super-I/O Function prototypes */ 106 static inline int superio_inb(int base, int reg); 107 static inline int superio_inw(int base, int reg); 108 static inline void superio_enter(int base); 109 static inline void superio_select(int base, int ld); 110 static inline void superio_exit(int base); 111 112 struct f71882fg_sio_data { 113 enum chips type; 114 }; 115 116 struct f71882fg_data { 117 unsigned short addr; 118 enum chips type; 119 struct device *hwmon_dev; 120 121 struct mutex update_lock; 122 char valid; /* !=0 if following fields are valid */ 123 unsigned long last_updated; /* In jiffies */ 124 unsigned long last_limits; /* In jiffies */ 125 126 /* Register Values */ 127 u8 in[9]; 128 u8 in1_max; 129 u8 in_status; 130 u8 in_beep; 131 u16 fan[4]; 132 u16 fan_target[4]; 133 u16 fan_full_speed[4]; 134 u8 fan_status; 135 u8 fan_beep; 136 /* Note: all models have only 3 temperature channels, but on some 137 they are addressed as 0-2 and on others as 1-3, so for coding 138 convenience we reserve space for 4 channels */ 139 u8 temp[4]; 140 u8 temp_ovt[4]; 141 u8 temp_high[4]; 142 u8 temp_hyst[2]; /* 2 hysts stored per reg */ 143 u8 temp_type[4]; 144 u8 temp_status; 145 u8 temp_beep; 146 u8 temp_diode_open; 147 u8 pwm[4]; 148 u8 pwm_enable; 149 u8 pwm_auto_point_hyst[2]; 150 u8 pwm_auto_point_mapping[4]; 151 u8 pwm_auto_point_pwm[4][5]; 152 u8 pwm_auto_point_temp[4][4]; 153 }; 154 155 /* Sysfs in */ 156 static ssize_t show_in(struct device *dev, struct device_attribute *devattr, 157 char *buf); 158 static ssize_t show_in_max(struct device *dev, struct device_attribute 159 *devattr, char *buf); 160 static ssize_t store_in_max(struct device *dev, struct device_attribute 161 *devattr, const char *buf, size_t count); 162 static ssize_t show_in_beep(struct device *dev, struct device_attribute 163 *devattr, char *buf); 164 static ssize_t store_in_beep(struct device *dev, struct device_attribute 165 *devattr, const char *buf, size_t count); 166 static ssize_t show_in_alarm(struct device *dev, struct device_attribute 167 *devattr, char *buf); 168 /* Sysfs Fan */ 169 static ssize_t show_fan(struct device *dev, struct device_attribute *devattr, 170 char *buf); 171 static ssize_t show_fan_full_speed(struct device *dev, 172 struct device_attribute *devattr, char *buf); 173 static ssize_t store_fan_full_speed(struct device *dev, 174 struct device_attribute *devattr, const char *buf, size_t count); 175 static ssize_t show_fan_beep(struct device *dev, struct device_attribute 176 *devattr, char *buf); 177 static ssize_t store_fan_beep(struct device *dev, struct device_attribute 178 *devattr, const char *buf, size_t count); 179 static ssize_t show_fan_alarm(struct device *dev, struct device_attribute 180 *devattr, char *buf); 181 /* Sysfs Temp */ 182 static ssize_t show_temp(struct device *dev, struct device_attribute 183 *devattr, char *buf); 184 static ssize_t show_temp_max(struct device *dev, struct device_attribute 185 *devattr, char *buf); 186 static ssize_t store_temp_max(struct device *dev, struct device_attribute 187 *devattr, const char *buf, size_t count); 188 static ssize_t show_temp_max_hyst(struct device *dev, struct device_attribute 189 *devattr, char *buf); 190 static ssize_t store_temp_max_hyst(struct device *dev, struct device_attribute 191 *devattr, const char *buf, size_t count); 192 static ssize_t show_temp_crit(struct device *dev, struct device_attribute 193 *devattr, char *buf); 194 static ssize_t store_temp_crit(struct device *dev, struct device_attribute 195 *devattr, const char *buf, size_t count); 196 static ssize_t show_temp_crit_hyst(struct device *dev, struct device_attribute 197 *devattr, char *buf); 198 static ssize_t show_temp_type(struct device *dev, struct device_attribute 199 *devattr, char *buf); 200 static ssize_t show_temp_beep(struct device *dev, struct device_attribute 201 *devattr, char *buf); 202 static ssize_t store_temp_beep(struct device *dev, struct device_attribute 203 *devattr, const char *buf, size_t count); 204 static ssize_t show_temp_alarm(struct device *dev, struct device_attribute 205 *devattr, char *buf); 206 static ssize_t show_temp_fault(struct device *dev, struct device_attribute 207 *devattr, char *buf); 208 /* PWM and Auto point control */ 209 static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr, 210 char *buf); 211 static ssize_t store_pwm(struct device *dev, struct device_attribute *devattr, 212 const char *buf, size_t count); 213 static ssize_t show_pwm_enable(struct device *dev, 214 struct device_attribute *devattr, char *buf); 215 static ssize_t store_pwm_enable(struct device *dev, 216 struct device_attribute *devattr, const char *buf, size_t count); 217 static ssize_t show_pwm_interpolate(struct device *dev, 218 struct device_attribute *devattr, char *buf); 219 static ssize_t store_pwm_interpolate(struct device *dev, 220 struct device_attribute *devattr, const char *buf, size_t count); 221 static ssize_t show_pwm_auto_point_channel(struct device *dev, 222 struct device_attribute *devattr, char *buf); 223 static ssize_t store_pwm_auto_point_channel(struct device *dev, 224 struct device_attribute *devattr, const char *buf, size_t count); 225 static ssize_t show_pwm_auto_point_temp_hyst(struct device *dev, 226 struct device_attribute *devattr, char *buf); 227 static ssize_t store_pwm_auto_point_temp_hyst(struct device *dev, 228 struct device_attribute *devattr, const char *buf, size_t count); 229 static ssize_t show_pwm_auto_point_pwm(struct device *dev, 230 struct device_attribute *devattr, char *buf); 231 static ssize_t store_pwm_auto_point_pwm(struct device *dev, 232 struct device_attribute *devattr, const char *buf, size_t count); 233 static ssize_t show_pwm_auto_point_temp(struct device *dev, 234 struct device_attribute *devattr, char *buf); 235 static ssize_t store_pwm_auto_point_temp(struct device *dev, 236 struct device_attribute *devattr, const char *buf, size_t count); 237 /* Sysfs misc */ 238 static ssize_t show_name(struct device *dev, struct device_attribute *devattr, 239 char *buf); 240 241 static int __devinit f71882fg_probe(struct platform_device * pdev); 242 static int f71882fg_remove(struct platform_device *pdev); 243 244 static struct platform_driver f71882fg_driver = { 245 .driver = { 246 .owner = THIS_MODULE, 247 .name = DRVNAME, 248 }, 249 .probe = f71882fg_probe, 250 .remove = __devexit_p(f71882fg_remove), 251 }; 252 253 static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); 254 255 /* Temp and in attr common to both the f71862fg and f71882fg */ 256 static struct sensor_device_attribute_2 f718x2fg_in_temp_attr[] = { 257 SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0), 258 SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1), 259 SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2), 260 SENSOR_ATTR_2(in3_input, S_IRUGO, show_in, NULL, 0, 3), 261 SENSOR_ATTR_2(in4_input, S_IRUGO, show_in, NULL, 0, 4), 262 SENSOR_ATTR_2(in5_input, S_IRUGO, show_in, NULL, 0, 5), 263 SENSOR_ATTR_2(in6_input, S_IRUGO, show_in, NULL, 0, 6), 264 SENSOR_ATTR_2(in7_input, S_IRUGO, show_in, NULL, 0, 7), 265 SENSOR_ATTR_2(in8_input, S_IRUGO, show_in, NULL, 0, 8), 266 SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 1), 267 SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_max, 268 store_temp_max, 0, 1), 269 SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst, 270 store_temp_max_hyst, 0, 1), 271 /* Should really be temp1_max_alarm, but older versions did not handle 272 the max and crit alarms separately and lm_sensors v2 depends on the 273 presence of temp#_alarm files. The same goes for temp2/3 _alarm. */ 274 SENSOR_ATTR_2(temp1_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 1), 275 SENSOR_ATTR_2(temp1_max_beep, S_IRUGO|S_IWUSR, show_temp_beep, 276 store_temp_beep, 0, 1), 277 SENSOR_ATTR_2(temp1_crit, S_IRUGO|S_IWUSR, show_temp_crit, 278 store_temp_crit, 0, 1), 279 SENSOR_ATTR_2(temp1_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL, 280 0, 1), 281 SENSOR_ATTR_2(temp1_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 5), 282 SENSOR_ATTR_2(temp1_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep, 283 store_temp_beep, 0, 5), 284 SENSOR_ATTR_2(temp1_type, S_IRUGO, show_temp_type, NULL, 0, 1), 285 SENSOR_ATTR_2(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0, 1), 286 SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 2), 287 SENSOR_ATTR_2(temp2_max, S_IRUGO|S_IWUSR, show_temp_max, 288 store_temp_max, 0, 2), 289 SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst, 290 store_temp_max_hyst, 0, 2), 291 /* Should be temp2_max_alarm, see temp1_alarm note */ 292 SENSOR_ATTR_2(temp2_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 2), 293 SENSOR_ATTR_2(temp2_max_beep, S_IRUGO|S_IWUSR, show_temp_beep, 294 store_temp_beep, 0, 2), 295 SENSOR_ATTR_2(temp2_crit, S_IRUGO|S_IWUSR, show_temp_crit, 296 store_temp_crit, 0, 2), 297 SENSOR_ATTR_2(temp2_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL, 298 0, 2), 299 SENSOR_ATTR_2(temp2_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 6), 300 SENSOR_ATTR_2(temp2_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep, 301 store_temp_beep, 0, 6), 302 SENSOR_ATTR_2(temp2_type, S_IRUGO, show_temp_type, NULL, 0, 2), 303 SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 2), 304 SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 3), 305 SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_max, 306 store_temp_max, 0, 3), 307 SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst, 308 store_temp_max_hyst, 0, 3), 309 /* Should be temp3_max_alarm, see temp1_alarm note */ 310 SENSOR_ATTR_2(temp3_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 3), 311 SENSOR_ATTR_2(temp3_max_beep, S_IRUGO|S_IWUSR, show_temp_beep, 312 store_temp_beep, 0, 3), 313 SENSOR_ATTR_2(temp3_crit, S_IRUGO|S_IWUSR, show_temp_crit, 314 store_temp_crit, 0, 3), 315 SENSOR_ATTR_2(temp3_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL, 316 0, 3), 317 SENSOR_ATTR_2(temp3_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 7), 318 SENSOR_ATTR_2(temp3_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep, 319 store_temp_beep, 0, 7), 320 SENSOR_ATTR_2(temp3_type, S_IRUGO, show_temp_type, NULL, 0, 3), 321 SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 3), 322 }; 323 324 /* Temp and in attr found only on the f71882fg */ 325 static struct sensor_device_attribute_2 f71882fg_in_temp_attr[] = { 326 SENSOR_ATTR_2(in1_max, S_IRUGO|S_IWUSR, show_in_max, store_in_max, 327 0, 1), 328 SENSOR_ATTR_2(in1_beep, S_IRUGO|S_IWUSR, show_in_beep, store_in_beep, 329 0, 1), 330 SENSOR_ATTR_2(in1_alarm, S_IRUGO, show_in_alarm, NULL, 0, 1), 331 }; 332 333 /* Temp and in attr for the f8000 334 Note on the f8000 temp_ovt (crit) is used as max, and temp_high (max) 335 is used as hysteresis value to clear alarms 336 */ 337 static struct sensor_device_attribute_2 f8000_in_temp_attr[] = { 338 SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0), 339 SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1), 340 SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2), 341 SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0), 342 SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_crit, 343 store_temp_crit, 0, 0), 344 SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO|S_IWUSR, show_temp_max, 345 store_temp_max, 0, 0), 346 SENSOR_ATTR_2(temp1_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 4), 347 SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 1), 348 SENSOR_ATTR_2(temp2_max, S_IRUGO|S_IWUSR, show_temp_crit, 349 store_temp_crit, 0, 1), 350 SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO|S_IWUSR, show_temp_max, 351 store_temp_max, 0, 1), 352 SENSOR_ATTR_2(temp2_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 5), 353 SENSOR_ATTR_2(temp2_type, S_IRUGO, show_temp_type, NULL, 0, 1), 354 SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 2), 355 SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_crit, 356 store_temp_crit, 0, 2), 357 SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO|S_IWUSR, show_temp_max, 358 store_temp_max, 0, 2), 359 SENSOR_ATTR_2(temp3_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 6), 360 }; 361 362 /* Fan / PWM attr common to all models */ 363 static struct sensor_device_attribute_2 fxxxx_fan_attr[] = { 364 SENSOR_ATTR_2(fan1_input, S_IRUGO, show_fan, NULL, 0, 0), 365 SENSOR_ATTR_2(fan1_full_speed, S_IRUGO|S_IWUSR, 366 show_fan_full_speed, 367 store_fan_full_speed, 0, 0), 368 SENSOR_ATTR_2(fan1_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 0), 369 SENSOR_ATTR_2(fan2_input, S_IRUGO, show_fan, NULL, 0, 1), 370 SENSOR_ATTR_2(fan2_full_speed, S_IRUGO|S_IWUSR, 371 show_fan_full_speed, 372 store_fan_full_speed, 0, 1), 373 SENSOR_ATTR_2(fan2_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 1), 374 SENSOR_ATTR_2(fan3_input, S_IRUGO, show_fan, NULL, 0, 2), 375 SENSOR_ATTR_2(fan3_full_speed, S_IRUGO|S_IWUSR, 376 show_fan_full_speed, 377 store_fan_full_speed, 0, 2), 378 SENSOR_ATTR_2(fan3_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 2), 379 380 SENSOR_ATTR_2(pwm1, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 0), 381 SENSOR_ATTR_2(pwm1_enable, S_IRUGO|S_IWUSR, show_pwm_enable, 382 store_pwm_enable, 0, 0), 383 SENSOR_ATTR_2(pwm1_interpolate, S_IRUGO|S_IWUSR, 384 show_pwm_interpolate, store_pwm_interpolate, 0, 0), 385 SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR, 386 show_pwm_auto_point_channel, 387 store_pwm_auto_point_channel, 0, 0), 388 389 SENSOR_ATTR_2(pwm2, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 1), 390 SENSOR_ATTR_2(pwm2_enable, S_IRUGO|S_IWUSR, show_pwm_enable, 391 store_pwm_enable, 0, 1), 392 SENSOR_ATTR_2(pwm2_interpolate, S_IRUGO|S_IWUSR, 393 show_pwm_interpolate, store_pwm_interpolate, 0, 1), 394 SENSOR_ATTR_2(pwm2_auto_channels_temp, S_IRUGO|S_IWUSR, 395 show_pwm_auto_point_channel, 396 store_pwm_auto_point_channel, 0, 1), 397 398 SENSOR_ATTR_2(pwm3_interpolate, S_IRUGO|S_IWUSR, 399 show_pwm_interpolate, store_pwm_interpolate, 0, 2), 400 SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR, 401 show_pwm_auto_point_channel, 402 store_pwm_auto_point_channel, 0, 2), 403 }; 404 405 /* Fan / PWM attr for the f71862fg, less pwms and less zones per pwm than the 406 f71882fg */ 407 static struct sensor_device_attribute_2 f71862fg_fan_attr[] = { 408 SENSOR_ATTR_2(fan1_beep, S_IRUGO|S_IWUSR, show_fan_beep, 409 store_fan_beep, 0, 0), 410 SENSOR_ATTR_2(fan2_beep, S_IRUGO|S_IWUSR, show_fan_beep, 411 store_fan_beep, 0, 1), 412 SENSOR_ATTR_2(fan3_beep, S_IRUGO|S_IWUSR, show_fan_beep, 413 store_fan_beep, 0, 2), 414 415 SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO|S_IWUSR, 416 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 417 1, 0), 418 SENSOR_ATTR_2(pwm1_auto_point2_pwm, S_IRUGO|S_IWUSR, 419 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 420 4, 0), 421 SENSOR_ATTR_2(pwm1_auto_point1_temp, S_IRUGO|S_IWUSR, 422 show_pwm_auto_point_temp, store_pwm_auto_point_temp, 423 0, 0), 424 SENSOR_ATTR_2(pwm1_auto_point2_temp, S_IRUGO|S_IWUSR, 425 show_pwm_auto_point_temp, store_pwm_auto_point_temp, 426 3, 0), 427 SENSOR_ATTR_2(pwm1_auto_point1_temp_hyst, S_IRUGO|S_IWUSR, 428 show_pwm_auto_point_temp_hyst, 429 store_pwm_auto_point_temp_hyst, 430 0, 0), 431 SENSOR_ATTR_2(pwm1_auto_point2_temp_hyst, S_IRUGO, 432 show_pwm_auto_point_temp_hyst, NULL, 3, 0), 433 434 SENSOR_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO|S_IWUSR, 435 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 436 1, 1), 437 SENSOR_ATTR_2(pwm2_auto_point2_pwm, S_IRUGO|S_IWUSR, 438 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 439 4, 1), 440 SENSOR_ATTR_2(pwm2_auto_point1_temp, S_IRUGO|S_IWUSR, 441 show_pwm_auto_point_temp, store_pwm_auto_point_temp, 442 0, 1), 443 SENSOR_ATTR_2(pwm2_auto_point2_temp, S_IRUGO|S_IWUSR, 444 show_pwm_auto_point_temp, store_pwm_auto_point_temp, 445 3, 1), 446 SENSOR_ATTR_2(pwm2_auto_point1_temp_hyst, S_IRUGO|S_IWUSR, 447 show_pwm_auto_point_temp_hyst, 448 store_pwm_auto_point_temp_hyst, 449 0, 1), 450 SENSOR_ATTR_2(pwm2_auto_point2_temp_hyst, S_IRUGO, 451 show_pwm_auto_point_temp_hyst, NULL, 3, 1), 452 453 SENSOR_ATTR_2(pwm3, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 2), 454 SENSOR_ATTR_2(pwm3_enable, S_IRUGO|S_IWUSR, show_pwm_enable, 455 store_pwm_enable, 0, 2), 456 SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO|S_IWUSR, 457 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 458 1, 2), 459 SENSOR_ATTR_2(pwm3_auto_point2_pwm, S_IRUGO|S_IWUSR, 460 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 461 4, 2), 462 SENSOR_ATTR_2(pwm3_auto_point1_temp, S_IRUGO|S_IWUSR, 463 show_pwm_auto_point_temp, store_pwm_auto_point_temp, 464 0, 2), 465 SENSOR_ATTR_2(pwm3_auto_point2_temp, S_IRUGO|S_IWUSR, 466 show_pwm_auto_point_temp, store_pwm_auto_point_temp, 467 3, 2), 468 SENSOR_ATTR_2(pwm3_auto_point1_temp_hyst, S_IRUGO|S_IWUSR, 469 show_pwm_auto_point_temp_hyst, 470 store_pwm_auto_point_temp_hyst, 471 0, 2), 472 SENSOR_ATTR_2(pwm3_auto_point2_temp_hyst, S_IRUGO, 473 show_pwm_auto_point_temp_hyst, NULL, 3, 2), 474 }; 475 476 /* Fan / PWM attr for the f71882fg */ 477 static struct sensor_device_attribute_2 f71882fg_fan_attr[] = { 478 SENSOR_ATTR_2(fan1_beep, S_IRUGO|S_IWUSR, show_fan_beep, 479 store_fan_beep, 0, 0), 480 SENSOR_ATTR_2(fan2_beep, S_IRUGO|S_IWUSR, show_fan_beep, 481 store_fan_beep, 0, 1), 482 SENSOR_ATTR_2(fan3_beep, S_IRUGO|S_IWUSR, show_fan_beep, 483 store_fan_beep, 0, 2), 484 SENSOR_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 0, 3), 485 SENSOR_ATTR_2(fan4_full_speed, S_IRUGO|S_IWUSR, 486 show_fan_full_speed, 487 store_fan_full_speed, 0, 3), 488 SENSOR_ATTR_2(fan4_beep, S_IRUGO|S_IWUSR, show_fan_beep, 489 store_fan_beep, 0, 3), 490 SENSOR_ATTR_2(fan4_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 3), 491 492 SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO|S_IWUSR, 493 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 494 0, 0), 495 SENSOR_ATTR_2(pwm1_auto_point2_pwm, S_IRUGO|S_IWUSR, 496 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 497 1, 0), 498 SENSOR_ATTR_2(pwm1_auto_point3_pwm, S_IRUGO|S_IWUSR, 499 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 500 2, 0), 501 SENSOR_ATTR_2(pwm1_auto_point4_pwm, S_IRUGO|S_IWUSR, 502 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 503 3, 0), 504 SENSOR_ATTR_2(pwm1_auto_point5_pwm, S_IRUGO|S_IWUSR, 505 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 506 4, 0), 507 SENSOR_ATTR_2(pwm1_auto_point1_temp, S_IRUGO|S_IWUSR, 508 show_pwm_auto_point_temp, store_pwm_auto_point_temp, 509 0, 0), 510 SENSOR_ATTR_2(pwm1_auto_point2_temp, S_IRUGO|S_IWUSR, 511 show_pwm_auto_point_temp, store_pwm_auto_point_temp, 512 1, 0), 513 SENSOR_ATTR_2(pwm1_auto_point3_temp, S_IRUGO|S_IWUSR, 514 show_pwm_auto_point_temp, store_pwm_auto_point_temp, 515 2, 0), 516 SENSOR_ATTR_2(pwm1_auto_point4_temp, S_IRUGO|S_IWUSR, 517 show_pwm_auto_point_temp, store_pwm_auto_point_temp, 518 3, 0), 519 SENSOR_ATTR_2(pwm1_auto_point1_temp_hyst, S_IRUGO|S_IWUSR, 520 show_pwm_auto_point_temp_hyst, 521 store_pwm_auto_point_temp_hyst, 522 0, 0), 523 SENSOR_ATTR_2(pwm1_auto_point2_temp_hyst, S_IRUGO, 524 show_pwm_auto_point_temp_hyst, NULL, 1, 0), 525 SENSOR_ATTR_2(pwm1_auto_point3_temp_hyst, S_IRUGO, 526 show_pwm_auto_point_temp_hyst, NULL, 2, 0), 527 SENSOR_ATTR_2(pwm1_auto_point4_temp_hyst, S_IRUGO, 528 show_pwm_auto_point_temp_hyst, NULL, 3, 0), 529 530 SENSOR_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO|S_IWUSR, 531 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 532 0, 1), 533 SENSOR_ATTR_2(pwm2_auto_point2_pwm, S_IRUGO|S_IWUSR, 534 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 535 1, 1), 536 SENSOR_ATTR_2(pwm2_auto_point3_pwm, S_IRUGO|S_IWUSR, 537 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 538 2, 1), 539 SENSOR_ATTR_2(pwm2_auto_point4_pwm, S_IRUGO|S_IWUSR, 540 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 541 3, 1), 542 SENSOR_ATTR_2(pwm2_auto_point5_pwm, S_IRUGO|S_IWUSR, 543 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 544 4, 1), 545 SENSOR_ATTR_2(pwm2_auto_point1_temp, S_IRUGO|S_IWUSR, 546 show_pwm_auto_point_temp, store_pwm_auto_point_temp, 547 0, 1), 548 SENSOR_ATTR_2(pwm2_auto_point2_temp, S_IRUGO|S_IWUSR, 549 show_pwm_auto_point_temp, store_pwm_auto_point_temp, 550 1, 1), 551 SENSOR_ATTR_2(pwm2_auto_point3_temp, S_IRUGO|S_IWUSR, 552 show_pwm_auto_point_temp, store_pwm_auto_point_temp, 553 2, 1), 554 SENSOR_ATTR_2(pwm2_auto_point4_temp, S_IRUGO|S_IWUSR, 555 show_pwm_auto_point_temp, store_pwm_auto_point_temp, 556 3, 1), 557 SENSOR_ATTR_2(pwm2_auto_point1_temp_hyst, S_IRUGO|S_IWUSR, 558 show_pwm_auto_point_temp_hyst, 559 store_pwm_auto_point_temp_hyst, 560 0, 1), 561 SENSOR_ATTR_2(pwm2_auto_point2_temp_hyst, S_IRUGO, 562 show_pwm_auto_point_temp_hyst, NULL, 1, 1), 563 SENSOR_ATTR_2(pwm2_auto_point3_temp_hyst, S_IRUGO, 564 show_pwm_auto_point_temp_hyst, NULL, 2, 1), 565 SENSOR_ATTR_2(pwm2_auto_point4_temp_hyst, S_IRUGO, 566 show_pwm_auto_point_temp_hyst, NULL, 3, 1), 567 568 SENSOR_ATTR_2(pwm3, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 2), 569 SENSOR_ATTR_2(pwm3_enable, S_IRUGO|S_IWUSR, show_pwm_enable, 570 store_pwm_enable, 0, 2), 571 SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO|S_IWUSR, 572 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 573 0, 2), 574 SENSOR_ATTR_2(pwm3_auto_point2_pwm, S_IRUGO|S_IWUSR, 575 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 576 1, 2), 577 SENSOR_ATTR_2(pwm3_auto_point3_pwm, S_IRUGO|S_IWUSR, 578 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 579 2, 2), 580 SENSOR_ATTR_2(pwm3_auto_point4_pwm, S_IRUGO|S_IWUSR, 581 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 582 3, 2), 583 SENSOR_ATTR_2(pwm3_auto_point5_pwm, S_IRUGO|S_IWUSR, 584 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 585 4, 2), 586 SENSOR_ATTR_2(pwm3_auto_point1_temp, S_IRUGO|S_IWUSR, 587 show_pwm_auto_point_temp, store_pwm_auto_point_temp, 588 0, 2), 589 SENSOR_ATTR_2(pwm3_auto_point2_temp, S_IRUGO|S_IWUSR, 590 show_pwm_auto_point_temp, store_pwm_auto_point_temp, 591 1, 2), 592 SENSOR_ATTR_2(pwm3_auto_point3_temp, S_IRUGO|S_IWUSR, 593 show_pwm_auto_point_temp, store_pwm_auto_point_temp, 594 2, 2), 595 SENSOR_ATTR_2(pwm3_auto_point4_temp, S_IRUGO|S_IWUSR, 596 show_pwm_auto_point_temp, store_pwm_auto_point_temp, 597 3, 2), 598 SENSOR_ATTR_2(pwm3_auto_point1_temp_hyst, S_IRUGO|S_IWUSR, 599 show_pwm_auto_point_temp_hyst, 600 store_pwm_auto_point_temp_hyst, 601 0, 2), 602 SENSOR_ATTR_2(pwm3_auto_point2_temp_hyst, S_IRUGO, 603 show_pwm_auto_point_temp_hyst, NULL, 1, 2), 604 SENSOR_ATTR_2(pwm3_auto_point3_temp_hyst, S_IRUGO, 605 show_pwm_auto_point_temp_hyst, NULL, 2, 2), 606 SENSOR_ATTR_2(pwm3_auto_point4_temp_hyst, S_IRUGO, 607 show_pwm_auto_point_temp_hyst, NULL, 3, 2), 608 609 SENSOR_ATTR_2(pwm4, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 3), 610 SENSOR_ATTR_2(pwm4_enable, S_IRUGO|S_IWUSR, show_pwm_enable, 611 store_pwm_enable, 0, 3), 612 SENSOR_ATTR_2(pwm4_interpolate, S_IRUGO|S_IWUSR, 613 show_pwm_interpolate, store_pwm_interpolate, 0, 3), 614 SENSOR_ATTR_2(pwm4_auto_channels_temp, S_IRUGO|S_IWUSR, 615 show_pwm_auto_point_channel, 616 store_pwm_auto_point_channel, 0, 3), 617 SENSOR_ATTR_2(pwm4_auto_point1_pwm, S_IRUGO|S_IWUSR, 618 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 619 0, 3), 620 SENSOR_ATTR_2(pwm4_auto_point2_pwm, S_IRUGO|S_IWUSR, 621 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 622 1, 3), 623 SENSOR_ATTR_2(pwm4_auto_point3_pwm, S_IRUGO|S_IWUSR, 624 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 625 2, 3), 626 SENSOR_ATTR_2(pwm4_auto_point4_pwm, S_IRUGO|S_IWUSR, 627 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 628 3, 3), 629 SENSOR_ATTR_2(pwm4_auto_point5_pwm, S_IRUGO|S_IWUSR, 630 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 631 4, 3), 632 SENSOR_ATTR_2(pwm4_auto_point1_temp, S_IRUGO|S_IWUSR, 633 show_pwm_auto_point_temp, store_pwm_auto_point_temp, 634 0, 3), 635 SENSOR_ATTR_2(pwm4_auto_point2_temp, S_IRUGO|S_IWUSR, 636 show_pwm_auto_point_temp, store_pwm_auto_point_temp, 637 1, 3), 638 SENSOR_ATTR_2(pwm4_auto_point3_temp, S_IRUGO|S_IWUSR, 639 show_pwm_auto_point_temp, store_pwm_auto_point_temp, 640 2, 3), 641 SENSOR_ATTR_2(pwm4_auto_point4_temp, S_IRUGO|S_IWUSR, 642 show_pwm_auto_point_temp, store_pwm_auto_point_temp, 643 3, 3), 644 SENSOR_ATTR_2(pwm4_auto_point1_temp_hyst, S_IRUGO|S_IWUSR, 645 show_pwm_auto_point_temp_hyst, 646 store_pwm_auto_point_temp_hyst, 647 0, 3), 648 SENSOR_ATTR_2(pwm4_auto_point2_temp_hyst, S_IRUGO, 649 show_pwm_auto_point_temp_hyst, NULL, 1, 3), 650 SENSOR_ATTR_2(pwm4_auto_point3_temp_hyst, S_IRUGO, 651 show_pwm_auto_point_temp_hyst, NULL, 2, 3), 652 SENSOR_ATTR_2(pwm4_auto_point4_temp_hyst, S_IRUGO, 653 show_pwm_auto_point_temp_hyst, NULL, 3, 3), 654 }; 655 656 /* Fan / PWM attr for the f8000, zones mapped to temp instead of to pwm! 657 Also the register block at offset A0 maps to TEMP1 (so our temp2, as the 658 F8000 starts counting temps at 0), B0 maps the TEMP2 and C0 maps to TEMP0 */ 659 static struct sensor_device_attribute_2 f8000_fan_attr[] = { 660 SENSOR_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 0, 3), 661 662 SENSOR_ATTR_2(pwm3, S_IRUGO, show_pwm, NULL, 0, 2), 663 664 SENSOR_ATTR_2(temp1_auto_point1_pwm, S_IRUGO|S_IWUSR, 665 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 666 0, 2), 667 SENSOR_ATTR_2(temp1_auto_point2_pwm, S_IRUGO|S_IWUSR, 668 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 669 1, 2), 670 SENSOR_ATTR_2(temp1_auto_point3_pwm, S_IRUGO|S_IWUSR, 671 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 672 2, 2), 673 SENSOR_ATTR_2(temp1_auto_point4_pwm, S_IRUGO|S_IWUSR, 674 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 675 3, 2), 676 SENSOR_ATTR_2(temp1_auto_point5_pwm, S_IRUGO|S_IWUSR, 677 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 678 4, 2), 679 SENSOR_ATTR_2(temp1_auto_point1_temp, S_IRUGO|S_IWUSR, 680 show_pwm_auto_point_temp, store_pwm_auto_point_temp, 681 0, 2), 682 SENSOR_ATTR_2(temp1_auto_point2_temp, S_IRUGO|S_IWUSR, 683 show_pwm_auto_point_temp, store_pwm_auto_point_temp, 684 1, 2), 685 SENSOR_ATTR_2(temp1_auto_point3_temp, S_IRUGO|S_IWUSR, 686 show_pwm_auto_point_temp, store_pwm_auto_point_temp, 687 2, 2), 688 SENSOR_ATTR_2(temp1_auto_point4_temp, S_IRUGO|S_IWUSR, 689 show_pwm_auto_point_temp, store_pwm_auto_point_temp, 690 3, 2), 691 SENSOR_ATTR_2(temp1_auto_point1_temp_hyst, S_IRUGO|S_IWUSR, 692 show_pwm_auto_point_temp_hyst, 693 store_pwm_auto_point_temp_hyst, 694 0, 2), 695 SENSOR_ATTR_2(temp1_auto_point2_temp_hyst, S_IRUGO, 696 show_pwm_auto_point_temp_hyst, NULL, 1, 2), 697 SENSOR_ATTR_2(temp1_auto_point3_temp_hyst, S_IRUGO, 698 show_pwm_auto_point_temp_hyst, NULL, 2, 2), 699 SENSOR_ATTR_2(temp1_auto_point4_temp_hyst, S_IRUGO, 700 show_pwm_auto_point_temp_hyst, NULL, 3, 2), 701 702 SENSOR_ATTR_2(temp2_auto_point1_pwm, S_IRUGO|S_IWUSR, 703 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 704 0, 0), 705 SENSOR_ATTR_2(temp2_auto_point2_pwm, S_IRUGO|S_IWUSR, 706 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 707 1, 0), 708 SENSOR_ATTR_2(temp2_auto_point3_pwm, S_IRUGO|S_IWUSR, 709 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 710 2, 0), 711 SENSOR_ATTR_2(temp2_auto_point4_pwm, S_IRUGO|S_IWUSR, 712 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 713 3, 0), 714 SENSOR_ATTR_2(temp2_auto_point5_pwm, S_IRUGO|S_IWUSR, 715 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 716 4, 0), 717 SENSOR_ATTR_2(temp2_auto_point1_temp, S_IRUGO|S_IWUSR, 718 show_pwm_auto_point_temp, store_pwm_auto_point_temp, 719 0, 0), 720 SENSOR_ATTR_2(temp2_auto_point2_temp, S_IRUGO|S_IWUSR, 721 show_pwm_auto_point_temp, store_pwm_auto_point_temp, 722 1, 0), 723 SENSOR_ATTR_2(temp2_auto_point3_temp, S_IRUGO|S_IWUSR, 724 show_pwm_auto_point_temp, store_pwm_auto_point_temp, 725 2, 0), 726 SENSOR_ATTR_2(temp2_auto_point4_temp, S_IRUGO|S_IWUSR, 727 show_pwm_auto_point_temp, store_pwm_auto_point_temp, 728 3, 0), 729 SENSOR_ATTR_2(temp2_auto_point1_temp_hyst, S_IRUGO|S_IWUSR, 730 show_pwm_auto_point_temp_hyst, 731 store_pwm_auto_point_temp_hyst, 732 0, 0), 733 SENSOR_ATTR_2(temp2_auto_point2_temp_hyst, S_IRUGO, 734 show_pwm_auto_point_temp_hyst, NULL, 1, 0), 735 SENSOR_ATTR_2(temp2_auto_point3_temp_hyst, S_IRUGO, 736 show_pwm_auto_point_temp_hyst, NULL, 2, 0), 737 SENSOR_ATTR_2(temp2_auto_point4_temp_hyst, S_IRUGO, 738 show_pwm_auto_point_temp_hyst, NULL, 3, 0), 739 740 SENSOR_ATTR_2(temp3_auto_point1_pwm, S_IRUGO|S_IWUSR, 741 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 742 0, 1), 743 SENSOR_ATTR_2(temp3_auto_point2_pwm, S_IRUGO|S_IWUSR, 744 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 745 1, 1), 746 SENSOR_ATTR_2(temp3_auto_point3_pwm, S_IRUGO|S_IWUSR, 747 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 748 2, 1), 749 SENSOR_ATTR_2(temp3_auto_point4_pwm, S_IRUGO|S_IWUSR, 750 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 751 3, 1), 752 SENSOR_ATTR_2(temp3_auto_point5_pwm, S_IRUGO|S_IWUSR, 753 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 754 4, 1), 755 SENSOR_ATTR_2(temp3_auto_point1_temp, S_IRUGO|S_IWUSR, 756 show_pwm_auto_point_temp, store_pwm_auto_point_temp, 757 0, 1), 758 SENSOR_ATTR_2(temp3_auto_point2_temp, S_IRUGO|S_IWUSR, 759 show_pwm_auto_point_temp, store_pwm_auto_point_temp, 760 1, 1), 761 SENSOR_ATTR_2(temp3_auto_point3_temp, S_IRUGO|S_IWUSR, 762 show_pwm_auto_point_temp, store_pwm_auto_point_temp, 763 2, 1), 764 SENSOR_ATTR_2(temp3_auto_point4_temp, S_IRUGO|S_IWUSR, 765 show_pwm_auto_point_temp, store_pwm_auto_point_temp, 766 3, 1), 767 SENSOR_ATTR_2(temp3_auto_point1_temp_hyst, S_IRUGO|S_IWUSR, 768 show_pwm_auto_point_temp_hyst, 769 store_pwm_auto_point_temp_hyst, 770 0, 1), 771 SENSOR_ATTR_2(temp3_auto_point2_temp_hyst, S_IRUGO, 772 show_pwm_auto_point_temp_hyst, NULL, 1, 1), 773 SENSOR_ATTR_2(temp3_auto_point3_temp_hyst, S_IRUGO, 774 show_pwm_auto_point_temp_hyst, NULL, 2, 1), 775 SENSOR_ATTR_2(temp3_auto_point4_temp_hyst, S_IRUGO, 776 show_pwm_auto_point_temp_hyst, NULL, 3, 1), 777 }; 778 779 /* Super I/O functions */ 780 static inline int superio_inb(int base, int reg) 781 { 782 outb(reg, base); 783 return inb(base + 1); 784 } 785 786 static int superio_inw(int base, int reg) 787 { 788 int val; 789 outb(reg++, base); 790 val = inb(base + 1) << 8; 791 outb(reg, base); 792 val |= inb(base + 1); 793 return val; 794 } 795 796 static inline void superio_enter(int base) 797 { 798 /* according to the datasheet the key must be send twice! */ 799 outb( SIO_UNLOCK_KEY, base); 800 outb( SIO_UNLOCK_KEY, base); 801 } 802 803 static inline void superio_select( int base, int ld) 804 { 805 outb(SIO_REG_LDSEL, base); 806 outb(ld, base + 1); 807 } 808 809 static inline void superio_exit(int base) 810 { 811 outb(SIO_LOCK_KEY, base); 812 } 813 814 static inline int fan_from_reg(u16 reg) 815 { 816 return reg ? (1500000 / reg) : 0; 817 } 818 819 static inline u16 fan_to_reg(int fan) 820 { 821 return fan ? (1500000 / fan) : 0; 822 } 823 824 static u8 f71882fg_read8(struct f71882fg_data *data, u8 reg) 825 { 826 u8 val; 827 828 outb(reg, data->addr + ADDR_REG_OFFSET); 829 val = inb(data->addr + DATA_REG_OFFSET); 830 831 return val; 832 } 833 834 static u16 f71882fg_read16(struct f71882fg_data *data, u8 reg) 835 { 836 u16 val; 837 838 outb(reg++, data->addr + ADDR_REG_OFFSET); 839 val = inb(data->addr + DATA_REG_OFFSET) << 8; 840 outb(reg, data->addr + ADDR_REG_OFFSET); 841 val |= inb(data->addr + DATA_REG_OFFSET); 842 843 return val; 844 } 845 846 static void f71882fg_write8(struct f71882fg_data *data, u8 reg, u8 val) 847 { 848 outb(reg, data->addr + ADDR_REG_OFFSET); 849 outb(val, data->addr + DATA_REG_OFFSET); 850 } 851 852 static void f71882fg_write16(struct f71882fg_data *data, u8 reg, u16 val) 853 { 854 outb(reg++, data->addr + ADDR_REG_OFFSET); 855 outb(val >> 8, data->addr + DATA_REG_OFFSET); 856 outb(reg, data->addr + ADDR_REG_OFFSET); 857 outb(val & 255, data->addr + DATA_REG_OFFSET); 858 } 859 860 static struct f71882fg_data *f71882fg_update_device(struct device *dev) 861 { 862 struct f71882fg_data *data = dev_get_drvdata(dev); 863 int nr, reg = 0, reg2; 864 int nr_fans = (data->type == f71882fg) ? 4 : 3; 865 int nr_ins = (data->type == f8000) ? 3 : 9; 866 int temp_start = (data->type == f8000) ? 0 : 1; 867 868 mutex_lock(&data->update_lock); 869 870 /* Update once every 60 seconds */ 871 if ( time_after(jiffies, data->last_limits + 60 * HZ ) || 872 !data->valid) { 873 if (data->type == f71882fg) { 874 data->in1_max = 875 f71882fg_read8(data, F71882FG_REG_IN1_HIGH); 876 data->in_beep = 877 f71882fg_read8(data, F71882FG_REG_IN_BEEP); 878 } 879 880 /* Get High & boundary temps*/ 881 for (nr = temp_start; nr < 3 + temp_start; nr++) { 882 data->temp_ovt[nr] = f71882fg_read8(data, 883 F71882FG_REG_TEMP_OVT(nr)); 884 data->temp_high[nr] = f71882fg_read8(data, 885 F71882FG_REG_TEMP_HIGH(nr)); 886 } 887 888 if (data->type != f8000) { 889 data->fan_beep = f71882fg_read8(data, 890 F71882FG_REG_FAN_BEEP); 891 data->temp_beep = f71882fg_read8(data, 892 F71882FG_REG_TEMP_BEEP); 893 data->temp_hyst[0] = f71882fg_read8(data, 894 F71882FG_REG_TEMP_HYST(0)); 895 data->temp_hyst[1] = f71882fg_read8(data, 896 F71882FG_REG_TEMP_HYST(1)); 897 /* Have to hardcode type, because temp1 is special */ 898 reg = f71882fg_read8(data, F71882FG_REG_TEMP_TYPE); 899 data->temp_type[2] = (reg & 0x04) ? 2 : 4; 900 data->temp_type[3] = (reg & 0x08) ? 2 : 4; 901 } 902 reg2 = f71882fg_read8(data, F71882FG_REG_PECI); 903 if ((reg2 & 0x03) == 0x01) 904 data->temp_type[1] = 6 /* PECI */; 905 else if ((reg2 & 0x03) == 0x02) 906 data->temp_type[1] = 5 /* AMDSI */; 907 else if (data->type != f8000) 908 data->temp_type[1] = (reg & 0x02) ? 2 : 4; 909 else 910 data->temp_type[1] = 2; /* F8000 only supports BJT */ 911 912 data->pwm_enable = f71882fg_read8(data, 913 F71882FG_REG_PWM_ENABLE); 914 data->pwm_auto_point_hyst[0] = 915 f71882fg_read8(data, F71882FG_REG_FAN_HYST(0)); 916 data->pwm_auto_point_hyst[1] = 917 f71882fg_read8(data, F71882FG_REG_FAN_HYST(1)); 918 919 for (nr = 0; nr < nr_fans; nr++) { 920 data->pwm_auto_point_mapping[nr] = 921 f71882fg_read8(data, 922 F71882FG_REG_POINT_MAPPING(nr)); 923 924 if (data->type != f71862fg) { 925 int point; 926 for (point = 0; point < 5; point++) { 927 data->pwm_auto_point_pwm[nr][point] = 928 f71882fg_read8(data, 929 F71882FG_REG_POINT_PWM 930 (nr, point)); 931 } 932 for (point = 0; point < 4; point++) { 933 data->pwm_auto_point_temp[nr][point] = 934 f71882fg_read8(data, 935 F71882FG_REG_POINT_TEMP 936 (nr, point)); 937 } 938 } else { 939 data->pwm_auto_point_pwm[nr][1] = 940 f71882fg_read8(data, 941 F71882FG_REG_POINT_PWM 942 (nr, 1)); 943 data->pwm_auto_point_pwm[nr][4] = 944 f71882fg_read8(data, 945 F71882FG_REG_POINT_PWM 946 (nr, 4)); 947 data->pwm_auto_point_temp[nr][0] = 948 f71882fg_read8(data, 949 F71882FG_REG_POINT_TEMP 950 (nr, 0)); 951 data->pwm_auto_point_temp[nr][3] = 952 f71882fg_read8(data, 953 F71882FG_REG_POINT_TEMP 954 (nr, 3)); 955 } 956 } 957 data->last_limits = jiffies; 958 } 959 960 /* Update every second */ 961 if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { 962 data->temp_status = f71882fg_read8(data, 963 F71882FG_REG_TEMP_STATUS); 964 data->temp_diode_open = f71882fg_read8(data, 965 F71882FG_REG_TEMP_DIODE_OPEN); 966 for (nr = temp_start; nr < 3 + temp_start; nr++) 967 data->temp[nr] = f71882fg_read8(data, 968 F71882FG_REG_TEMP(nr)); 969 970 data->fan_status = f71882fg_read8(data, 971 F71882FG_REG_FAN_STATUS); 972 for (nr = 0; nr < nr_fans; nr++) { 973 data->fan[nr] = f71882fg_read16(data, 974 F71882FG_REG_FAN(nr)); 975 data->fan_target[nr] = 976 f71882fg_read16(data, F71882FG_REG_FAN_TARGET(nr)); 977 data->fan_full_speed[nr] = 978 f71882fg_read16(data, 979 F71882FG_REG_FAN_FULL_SPEED(nr)); 980 data->pwm[nr] = 981 f71882fg_read8(data, F71882FG_REG_PWM(nr)); 982 } 983 984 /* The f8000 can monitor 1 more fan, but has no pwm for it */ 985 if (data->type == f8000) 986 data->fan[3] = f71882fg_read16(data, 987 F71882FG_REG_FAN(3)); 988 if (data->type == f71882fg) 989 data->in_status = f71882fg_read8(data, 990 F71882FG_REG_IN_STATUS); 991 for (nr = 0; nr < nr_ins; nr++) 992 data->in[nr] = f71882fg_read8(data, 993 F71882FG_REG_IN(nr)); 994 995 data->last_updated = jiffies; 996 data->valid = 1; 997 } 998 999 mutex_unlock(&data->update_lock); 1000 1001 return data; 1002 } 1003 1004 /* Sysfs Interface */ 1005 static ssize_t show_fan(struct device *dev, struct device_attribute *devattr, 1006 char *buf) 1007 { 1008 struct f71882fg_data *data = f71882fg_update_device(dev); 1009 int nr = to_sensor_dev_attr_2(devattr)->index; 1010 int speed = fan_from_reg(data->fan[nr]); 1011 1012 if (speed == FAN_MIN_DETECT) 1013 speed = 0; 1014 1015 return sprintf(buf, "%d\n", speed); 1016 } 1017 1018 static ssize_t show_fan_full_speed(struct device *dev, 1019 struct device_attribute *devattr, char *buf) 1020 { 1021 struct f71882fg_data *data = f71882fg_update_device(dev); 1022 int nr = to_sensor_dev_attr_2(devattr)->index; 1023 int speed = fan_from_reg(data->fan_full_speed[nr]); 1024 return sprintf(buf, "%d\n", speed); 1025 } 1026 1027 static ssize_t store_fan_full_speed(struct device *dev, 1028 struct device_attribute *devattr, 1029 const char *buf, size_t count) 1030 { 1031 struct f71882fg_data *data = dev_get_drvdata(dev); 1032 int nr = to_sensor_dev_attr_2(devattr)->index; 1033 long val = simple_strtol(buf, NULL, 10); 1034 1035 val = SENSORS_LIMIT(val, 23, 1500000); 1036 val = fan_to_reg(val); 1037 1038 mutex_lock(&data->update_lock); 1039 f71882fg_write16(data, F71882FG_REG_FAN_FULL_SPEED(nr), val); 1040 data->fan_full_speed[nr] = val; 1041 mutex_unlock(&data->update_lock); 1042 1043 return count; 1044 } 1045 1046 static ssize_t show_fan_beep(struct device *dev, struct device_attribute 1047 *devattr, char *buf) 1048 { 1049 struct f71882fg_data *data = f71882fg_update_device(dev); 1050 int nr = to_sensor_dev_attr_2(devattr)->index; 1051 1052 if (data->fan_beep & (1 << nr)) 1053 return sprintf(buf, "1\n"); 1054 else 1055 return sprintf(buf, "0\n"); 1056 } 1057 1058 static ssize_t store_fan_beep(struct device *dev, struct device_attribute 1059 *devattr, const char *buf, size_t count) 1060 { 1061 struct f71882fg_data *data = dev_get_drvdata(dev); 1062 int nr = to_sensor_dev_attr_2(devattr)->index; 1063 unsigned long val = simple_strtoul(buf, NULL, 10); 1064 1065 mutex_lock(&data->update_lock); 1066 data->fan_beep = f71882fg_read8(data, F71882FG_REG_FAN_BEEP); 1067 if (val) 1068 data->fan_beep |= 1 << nr; 1069 else 1070 data->fan_beep &= ~(1 << nr); 1071 1072 f71882fg_write8(data, F71882FG_REG_FAN_BEEP, data->fan_beep); 1073 mutex_unlock(&data->update_lock); 1074 1075 return count; 1076 } 1077 1078 static ssize_t show_fan_alarm(struct device *dev, struct device_attribute 1079 *devattr, char *buf) 1080 { 1081 struct f71882fg_data *data = f71882fg_update_device(dev); 1082 int nr = to_sensor_dev_attr_2(devattr)->index; 1083 1084 if (data->fan_status & (1 << nr)) 1085 return sprintf(buf, "1\n"); 1086 else 1087 return sprintf(buf, "0\n"); 1088 } 1089 1090 static ssize_t show_in(struct device *dev, struct device_attribute *devattr, 1091 char *buf) 1092 { 1093 struct f71882fg_data *data = f71882fg_update_device(dev); 1094 int nr = to_sensor_dev_attr_2(devattr)->index; 1095 1096 return sprintf(buf, "%d\n", data->in[nr] * 8); 1097 } 1098 1099 static ssize_t show_in_max(struct device *dev, struct device_attribute 1100 *devattr, char *buf) 1101 { 1102 struct f71882fg_data *data = f71882fg_update_device(dev); 1103 1104 return sprintf(buf, "%d\n", data->in1_max * 8); 1105 } 1106 1107 static ssize_t store_in_max(struct device *dev, struct device_attribute 1108 *devattr, const char *buf, size_t count) 1109 { 1110 struct f71882fg_data *data = dev_get_drvdata(dev); 1111 long val = simple_strtol(buf, NULL, 10) / 8; 1112 val = SENSORS_LIMIT(val, 0, 255); 1113 1114 mutex_lock(&data->update_lock); 1115 f71882fg_write8(data, F71882FG_REG_IN1_HIGH, val); 1116 data->in1_max = val; 1117 mutex_unlock(&data->update_lock); 1118 1119 return count; 1120 } 1121 1122 static ssize_t show_in_beep(struct device *dev, struct device_attribute 1123 *devattr, char *buf) 1124 { 1125 struct f71882fg_data *data = f71882fg_update_device(dev); 1126 int nr = to_sensor_dev_attr_2(devattr)->index; 1127 1128 if (data->in_beep & (1 << nr)) 1129 return sprintf(buf, "1\n"); 1130 else 1131 return sprintf(buf, "0\n"); 1132 } 1133 1134 static ssize_t store_in_beep(struct device *dev, struct device_attribute 1135 *devattr, const char *buf, size_t count) 1136 { 1137 struct f71882fg_data *data = dev_get_drvdata(dev); 1138 int nr = to_sensor_dev_attr_2(devattr)->index; 1139 unsigned long val = simple_strtoul(buf, NULL, 10); 1140 1141 mutex_lock(&data->update_lock); 1142 data->in_beep = f71882fg_read8(data, F71882FG_REG_IN_BEEP); 1143 if (val) 1144 data->in_beep |= 1 << nr; 1145 else 1146 data->in_beep &= ~(1 << nr); 1147 1148 f71882fg_write8(data, F71882FG_REG_IN_BEEP, data->in_beep); 1149 mutex_unlock(&data->update_lock); 1150 1151 return count; 1152 } 1153 1154 static ssize_t show_in_alarm(struct device *dev, struct device_attribute 1155 *devattr, char *buf) 1156 { 1157 struct f71882fg_data *data = f71882fg_update_device(dev); 1158 int nr = to_sensor_dev_attr_2(devattr)->index; 1159 1160 if (data->in_status & (1 << nr)) 1161 return sprintf(buf, "1\n"); 1162 else 1163 return sprintf(buf, "0\n"); 1164 } 1165 1166 static ssize_t show_temp(struct device *dev, struct device_attribute *devattr, 1167 char *buf) 1168 { 1169 struct f71882fg_data *data = f71882fg_update_device(dev); 1170 int nr = to_sensor_dev_attr_2(devattr)->index; 1171 1172 return sprintf(buf, "%d\n", data->temp[nr] * 1000); 1173 } 1174 1175 static ssize_t show_temp_max(struct device *dev, struct device_attribute 1176 *devattr, char *buf) 1177 { 1178 struct f71882fg_data *data = f71882fg_update_device(dev); 1179 int nr = to_sensor_dev_attr_2(devattr)->index; 1180 1181 return sprintf(buf, "%d\n", data->temp_high[nr] * 1000); 1182 } 1183 1184 static ssize_t store_temp_max(struct device *dev, struct device_attribute 1185 *devattr, const char *buf, size_t count) 1186 { 1187 struct f71882fg_data *data = dev_get_drvdata(dev); 1188 int nr = to_sensor_dev_attr_2(devattr)->index; 1189 long val = simple_strtol(buf, NULL, 10) / 1000; 1190 val = SENSORS_LIMIT(val, 0, 255); 1191 1192 mutex_lock(&data->update_lock); 1193 f71882fg_write8(data, F71882FG_REG_TEMP_HIGH(nr), val); 1194 data->temp_high[nr] = val; 1195 mutex_unlock(&data->update_lock); 1196 1197 return count; 1198 } 1199 1200 static ssize_t show_temp_max_hyst(struct device *dev, struct device_attribute 1201 *devattr, char *buf) 1202 { 1203 struct f71882fg_data *data = f71882fg_update_device(dev); 1204 int nr = to_sensor_dev_attr_2(devattr)->index; 1205 int temp_max_hyst; 1206 1207 mutex_lock(&data->update_lock); 1208 if (nr & 1) 1209 temp_max_hyst = data->temp_hyst[nr / 2] >> 4; 1210 else 1211 temp_max_hyst = data->temp_hyst[nr / 2] & 0x0f; 1212 temp_max_hyst = (data->temp_high[nr] - temp_max_hyst) * 1000; 1213 mutex_unlock(&data->update_lock); 1214 1215 return sprintf(buf, "%d\n", temp_max_hyst); 1216 } 1217 1218 static ssize_t store_temp_max_hyst(struct device *dev, struct device_attribute 1219 *devattr, const char *buf, size_t count) 1220 { 1221 struct f71882fg_data *data = dev_get_drvdata(dev); 1222 int nr = to_sensor_dev_attr_2(devattr)->index; 1223 long val = simple_strtol(buf, NULL, 10) / 1000; 1224 ssize_t ret = count; 1225 u8 reg; 1226 1227 mutex_lock(&data->update_lock); 1228 1229 /* convert abs to relative and check */ 1230 data->temp_high[nr] = f71882fg_read8(data, F71882FG_REG_TEMP_HIGH(nr)); 1231 val = SENSORS_LIMIT(val, data->temp_high[nr] - 15, 1232 data->temp_high[nr]); 1233 val = data->temp_high[nr] - val; 1234 1235 /* convert value to register contents */ 1236 reg = f71882fg_read8(data, F71882FG_REG_TEMP_HYST(nr / 2)); 1237 if (nr & 1) 1238 reg = (reg & 0x0f) | (val << 4); 1239 else 1240 reg = (reg & 0xf0) | val; 1241 f71882fg_write8(data, F71882FG_REG_TEMP_HYST(nr / 2), reg); 1242 data->temp_hyst[nr / 2] = reg; 1243 1244 mutex_unlock(&data->update_lock); 1245 return ret; 1246 } 1247 1248 static ssize_t show_temp_crit(struct device *dev, struct device_attribute 1249 *devattr, char *buf) 1250 { 1251 struct f71882fg_data *data = f71882fg_update_device(dev); 1252 int nr = to_sensor_dev_attr_2(devattr)->index; 1253 1254 return sprintf(buf, "%d\n", data->temp_ovt[nr] * 1000); 1255 } 1256 1257 static ssize_t store_temp_crit(struct device *dev, struct device_attribute 1258 *devattr, const char *buf, size_t count) 1259 { 1260 struct f71882fg_data *data = dev_get_drvdata(dev); 1261 int nr = to_sensor_dev_attr_2(devattr)->index; 1262 long val = simple_strtol(buf, NULL, 10) / 1000; 1263 val = SENSORS_LIMIT(val, 0, 255); 1264 1265 mutex_lock(&data->update_lock); 1266 f71882fg_write8(data, F71882FG_REG_TEMP_OVT(nr), val); 1267 data->temp_ovt[nr] = val; 1268 mutex_unlock(&data->update_lock); 1269 1270 return count; 1271 } 1272 1273 static ssize_t show_temp_crit_hyst(struct device *dev, struct device_attribute 1274 *devattr, char *buf) 1275 { 1276 struct f71882fg_data *data = f71882fg_update_device(dev); 1277 int nr = to_sensor_dev_attr_2(devattr)->index; 1278 int temp_crit_hyst; 1279 1280 mutex_lock(&data->update_lock); 1281 if (nr & 1) 1282 temp_crit_hyst = data->temp_hyst[nr / 2] >> 4; 1283 else 1284 temp_crit_hyst = data->temp_hyst[nr / 2] & 0x0f; 1285 temp_crit_hyst = (data->temp_ovt[nr] - temp_crit_hyst) * 1000; 1286 mutex_unlock(&data->update_lock); 1287 1288 return sprintf(buf, "%d\n", temp_crit_hyst); 1289 } 1290 1291 static ssize_t show_temp_type(struct device *dev, struct device_attribute 1292 *devattr, char *buf) 1293 { 1294 struct f71882fg_data *data = f71882fg_update_device(dev); 1295 int nr = to_sensor_dev_attr_2(devattr)->index; 1296 1297 return sprintf(buf, "%d\n", data->temp_type[nr]); 1298 } 1299 1300 static ssize_t show_temp_beep(struct device *dev, struct device_attribute 1301 *devattr, char *buf) 1302 { 1303 struct f71882fg_data *data = f71882fg_update_device(dev); 1304 int nr = to_sensor_dev_attr_2(devattr)->index; 1305 1306 if (data->temp_beep & (1 << nr)) 1307 return sprintf(buf, "1\n"); 1308 else 1309 return sprintf(buf, "0\n"); 1310 } 1311 1312 static ssize_t store_temp_beep(struct device *dev, struct device_attribute 1313 *devattr, const char *buf, size_t count) 1314 { 1315 struct f71882fg_data *data = dev_get_drvdata(dev); 1316 int nr = to_sensor_dev_attr_2(devattr)->index; 1317 unsigned long val = simple_strtoul(buf, NULL, 10); 1318 1319 mutex_lock(&data->update_lock); 1320 data->temp_beep = f71882fg_read8(data, F71882FG_REG_TEMP_BEEP); 1321 if (val) 1322 data->temp_beep |= 1 << nr; 1323 else 1324 data->temp_beep &= ~(1 << nr); 1325 1326 f71882fg_write8(data, F71882FG_REG_TEMP_BEEP, data->temp_beep); 1327 mutex_unlock(&data->update_lock); 1328 1329 return count; 1330 } 1331 1332 static ssize_t show_temp_alarm(struct device *dev, struct device_attribute 1333 *devattr, char *buf) 1334 { 1335 struct f71882fg_data *data = f71882fg_update_device(dev); 1336 int nr = to_sensor_dev_attr_2(devattr)->index; 1337 1338 if (data->temp_status & (1 << nr)) 1339 return sprintf(buf, "1\n"); 1340 else 1341 return sprintf(buf, "0\n"); 1342 } 1343 1344 static ssize_t show_temp_fault(struct device *dev, struct device_attribute 1345 *devattr, char *buf) 1346 { 1347 struct f71882fg_data *data = f71882fg_update_device(dev); 1348 int nr = to_sensor_dev_attr_2(devattr)->index; 1349 1350 if (data->temp_diode_open & (1 << nr)) 1351 return sprintf(buf, "1\n"); 1352 else 1353 return sprintf(buf, "0\n"); 1354 } 1355 1356 static ssize_t show_pwm(struct device *dev, 1357 struct device_attribute *devattr, char *buf) 1358 { 1359 struct f71882fg_data *data = f71882fg_update_device(dev); 1360 int val, nr = to_sensor_dev_attr_2(devattr)->index; 1361 mutex_lock(&data->update_lock); 1362 if (data->pwm_enable & (1 << (2 * nr))) 1363 /* PWM mode */ 1364 val = data->pwm[nr]; 1365 else { 1366 /* RPM mode */ 1367 val = 255 * fan_from_reg(data->fan_target[nr]) 1368 / fan_from_reg(data->fan_full_speed[nr]); 1369 } 1370 mutex_unlock(&data->update_lock); 1371 return sprintf(buf, "%d\n", val); 1372 } 1373 1374 static ssize_t store_pwm(struct device *dev, 1375 struct device_attribute *devattr, const char *buf, 1376 size_t count) 1377 { 1378 struct f71882fg_data *data = dev_get_drvdata(dev); 1379 int nr = to_sensor_dev_attr_2(devattr)->index; 1380 long val = simple_strtol(buf, NULL, 10); 1381 val = SENSORS_LIMIT(val, 0, 255); 1382 1383 mutex_lock(&data->update_lock); 1384 data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE); 1385 if ((data->type == f8000 && ((data->pwm_enable >> 2 * nr) & 3) != 2) || 1386 (data->type != f8000 && !((data->pwm_enable >> 2 * nr) & 2))) { 1387 count = -EROFS; 1388 goto leave; 1389 } 1390 if (data->pwm_enable & (1 << (2 * nr))) { 1391 /* PWM mode */ 1392 f71882fg_write8(data, F71882FG_REG_PWM(nr), val); 1393 data->pwm[nr] = val; 1394 } else { 1395 /* RPM mode */ 1396 int target, full_speed; 1397 full_speed = f71882fg_read16(data, 1398 F71882FG_REG_FAN_FULL_SPEED(nr)); 1399 target = fan_to_reg(val * fan_from_reg(full_speed) / 255); 1400 f71882fg_write16(data, F71882FG_REG_FAN_TARGET(nr), target); 1401 data->fan_target[nr] = target; 1402 data->fan_full_speed[nr] = full_speed; 1403 } 1404 leave: 1405 mutex_unlock(&data->update_lock); 1406 1407 return count; 1408 } 1409 1410 static ssize_t show_pwm_enable(struct device *dev, 1411 struct device_attribute *devattr, char *buf) 1412 { 1413 int result = 0; 1414 struct f71882fg_data *data = f71882fg_update_device(dev); 1415 int nr = to_sensor_dev_attr_2(devattr)->index; 1416 1417 switch ((data->pwm_enable >> 2 * nr) & 3) { 1418 case 0: 1419 case 1: 1420 result = 2; /* Normal auto mode */ 1421 break; 1422 case 2: 1423 result = 1; /* Manual mode */ 1424 break; 1425 case 3: 1426 if (data->type == f8000) 1427 result = 3; /* Thermostat mode */ 1428 else 1429 result = 1; /* Manual mode */ 1430 break; 1431 } 1432 1433 return sprintf(buf, "%d\n", result); 1434 } 1435 1436 static ssize_t store_pwm_enable(struct device *dev, struct device_attribute 1437 *devattr, const char *buf, size_t count) 1438 { 1439 struct f71882fg_data *data = dev_get_drvdata(dev); 1440 int nr = to_sensor_dev_attr_2(devattr)->index; 1441 long val = simple_strtol(buf, NULL, 10); 1442 1443 mutex_lock(&data->update_lock); 1444 data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE); 1445 /* Special case for F8000 auto PWM mode / Thermostat mode */ 1446 if (data->type == f8000 && ((data->pwm_enable >> 2 * nr) & 1)) { 1447 switch (val) { 1448 case 2: 1449 data->pwm_enable &= ~(2 << (2 * nr)); 1450 break; /* Normal auto mode */ 1451 case 3: 1452 data->pwm_enable |= 2 << (2 * nr); 1453 break; /* Thermostat mode */ 1454 default: 1455 count = -EINVAL; 1456 goto leave; 1457 } 1458 } else { 1459 switch (val) { 1460 case 1: 1461 data->pwm_enable |= 2 << (2 * nr); 1462 break; /* Manual */ 1463 case 2: 1464 data->pwm_enable &= ~(2 << (2 * nr)); 1465 break; /* Normal auto mode */ 1466 default: 1467 count = -EINVAL; 1468 goto leave; 1469 } 1470 } 1471 f71882fg_write8(data, F71882FG_REG_PWM_ENABLE, data->pwm_enable); 1472 leave: 1473 mutex_unlock(&data->update_lock); 1474 1475 return count; 1476 } 1477 1478 static ssize_t show_pwm_auto_point_pwm(struct device *dev, 1479 struct device_attribute *devattr, 1480 char *buf) 1481 { 1482 int result; 1483 struct f71882fg_data *data = f71882fg_update_device(dev); 1484 int pwm = to_sensor_dev_attr_2(devattr)->index; 1485 int point = to_sensor_dev_attr_2(devattr)->nr; 1486 1487 mutex_lock(&data->update_lock); 1488 if (data->pwm_enable & (1 << (2 * pwm))) { 1489 /* PWM mode */ 1490 result = data->pwm_auto_point_pwm[pwm][point]; 1491 } else { 1492 /* RPM mode */ 1493 result = 32 * 255 / (32 + data->pwm_auto_point_pwm[pwm][point]); 1494 } 1495 mutex_unlock(&data->update_lock); 1496 1497 return sprintf(buf, "%d\n", result); 1498 } 1499 1500 static ssize_t store_pwm_auto_point_pwm(struct device *dev, 1501 struct device_attribute *devattr, 1502 const char *buf, size_t count) 1503 { 1504 struct f71882fg_data *data = dev_get_drvdata(dev); 1505 int pwm = to_sensor_dev_attr_2(devattr)->index; 1506 int point = to_sensor_dev_attr_2(devattr)->nr; 1507 long val = simple_strtol(buf, NULL, 10); 1508 val = SENSORS_LIMIT(val, 0, 255); 1509 1510 mutex_lock(&data->update_lock); 1511 data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE); 1512 if (data->pwm_enable & (1 << (2 * pwm))) { 1513 /* PWM mode */ 1514 } else { 1515 /* RPM mode */ 1516 if (val < 29) /* Prevent negative numbers */ 1517 val = 255; 1518 else 1519 val = (255 - val) * 32 / val; 1520 } 1521 f71882fg_write8(data, F71882FG_REG_POINT_PWM(pwm, point), val); 1522 data->pwm_auto_point_pwm[pwm][point] = val; 1523 mutex_unlock(&data->update_lock); 1524 1525 return count; 1526 } 1527 1528 static ssize_t show_pwm_auto_point_temp_hyst(struct device *dev, 1529 struct device_attribute *devattr, 1530 char *buf) 1531 { 1532 int result = 0; 1533 struct f71882fg_data *data = f71882fg_update_device(dev); 1534 int nr = to_sensor_dev_attr_2(devattr)->index; 1535 int point = to_sensor_dev_attr_2(devattr)->nr; 1536 1537 mutex_lock(&data->update_lock); 1538 if (nr & 1) 1539 result = data->pwm_auto_point_hyst[nr / 2] >> 4; 1540 else 1541 result = data->pwm_auto_point_hyst[nr / 2] & 0x0f; 1542 result = 1000 * (data->pwm_auto_point_temp[nr][point] - result); 1543 mutex_unlock(&data->update_lock); 1544 1545 return sprintf(buf, "%d\n", result); 1546 } 1547 1548 static ssize_t store_pwm_auto_point_temp_hyst(struct device *dev, 1549 struct device_attribute *devattr, 1550 const char *buf, size_t count) 1551 { 1552 struct f71882fg_data *data = dev_get_drvdata(dev); 1553 int nr = to_sensor_dev_attr_2(devattr)->index; 1554 int point = to_sensor_dev_attr_2(devattr)->nr; 1555 long val = simple_strtol(buf, NULL, 10) / 1000; 1556 u8 reg; 1557 1558 mutex_lock(&data->update_lock); 1559 data->pwm_auto_point_temp[nr][point] = 1560 f71882fg_read8(data, F71882FG_REG_POINT_TEMP(nr, point)); 1561 val = SENSORS_LIMIT(val, data->pwm_auto_point_temp[nr][point] - 15, 1562 data->pwm_auto_point_temp[nr][point]); 1563 val = data->pwm_auto_point_temp[nr][point] - val; 1564 1565 reg = f71882fg_read8(data, F71882FG_REG_FAN_HYST(nr / 2)); 1566 if (nr & 1) 1567 reg = (reg & 0x0f) | (val << 4); 1568 else 1569 reg = (reg & 0xf0) | val; 1570 1571 f71882fg_write8(data, F71882FG_REG_FAN_HYST(nr / 2), reg); 1572 data->pwm_auto_point_hyst[nr / 2] = reg; 1573 mutex_unlock(&data->update_lock); 1574 1575 return count; 1576 } 1577 1578 static ssize_t show_pwm_interpolate(struct device *dev, 1579 struct device_attribute *devattr, char *buf) 1580 { 1581 int result; 1582 struct f71882fg_data *data = f71882fg_update_device(dev); 1583 int nr = to_sensor_dev_attr_2(devattr)->index; 1584 1585 result = (data->pwm_auto_point_mapping[nr] >> 4) & 1; 1586 1587 return sprintf(buf, "%d\n", result); 1588 } 1589 1590 static ssize_t store_pwm_interpolate(struct device *dev, 1591 struct device_attribute *devattr, 1592 const char *buf, size_t count) 1593 { 1594 struct f71882fg_data *data = dev_get_drvdata(dev); 1595 int nr = to_sensor_dev_attr_2(devattr)->index; 1596 unsigned long val = simple_strtoul(buf, NULL, 10); 1597 1598 mutex_lock(&data->update_lock); 1599 data->pwm_auto_point_mapping[nr] = 1600 f71882fg_read8(data, F71882FG_REG_POINT_MAPPING(nr)); 1601 if (val) 1602 val = data->pwm_auto_point_mapping[nr] | (1 << 4); 1603 else 1604 val = data->pwm_auto_point_mapping[nr] & (~(1 << 4)); 1605 f71882fg_write8(data, F71882FG_REG_POINT_MAPPING(nr), val); 1606 data->pwm_auto_point_mapping[nr] = val; 1607 mutex_unlock(&data->update_lock); 1608 1609 return count; 1610 } 1611 1612 static ssize_t show_pwm_auto_point_channel(struct device *dev, 1613 struct device_attribute *devattr, 1614 char *buf) 1615 { 1616 int result; 1617 struct f71882fg_data *data = f71882fg_update_device(dev); 1618 int nr = to_sensor_dev_attr_2(devattr)->index; 1619 int temp_start = (data->type == f8000) ? 0 : 1; 1620 1621 result = 1 << ((data->pwm_auto_point_mapping[nr] & 3) - temp_start); 1622 1623 return sprintf(buf, "%d\n", result); 1624 } 1625 1626 static ssize_t store_pwm_auto_point_channel(struct device *dev, 1627 struct device_attribute *devattr, 1628 const char *buf, size_t count) 1629 { 1630 struct f71882fg_data *data = dev_get_drvdata(dev); 1631 int nr = to_sensor_dev_attr_2(devattr)->index; 1632 int temp_start = (data->type == f8000) ? 0 : 1; 1633 long val = simple_strtol(buf, NULL, 10); 1634 1635 switch (val) { 1636 case 1: 1637 val = 0; 1638 break; 1639 case 2: 1640 val = 1; 1641 break; 1642 case 4: 1643 val = 2; 1644 break; 1645 default: 1646 return -EINVAL; 1647 } 1648 val += temp_start; 1649 mutex_lock(&data->update_lock); 1650 data->pwm_auto_point_mapping[nr] = 1651 f71882fg_read8(data, F71882FG_REG_POINT_MAPPING(nr)); 1652 val = (data->pwm_auto_point_mapping[nr] & 0xfc) | val; 1653 f71882fg_write8(data, F71882FG_REG_POINT_MAPPING(nr), val); 1654 data->pwm_auto_point_mapping[nr] = val; 1655 mutex_unlock(&data->update_lock); 1656 1657 return count; 1658 } 1659 1660 static ssize_t show_pwm_auto_point_temp(struct device *dev, 1661 struct device_attribute *devattr, 1662 char *buf) 1663 { 1664 int result; 1665 struct f71882fg_data *data = f71882fg_update_device(dev); 1666 int pwm = to_sensor_dev_attr_2(devattr)->index; 1667 int point = to_sensor_dev_attr_2(devattr)->nr; 1668 1669 result = data->pwm_auto_point_temp[pwm][point]; 1670 return sprintf(buf, "%d\n", 1000 * result); 1671 } 1672 1673 static ssize_t store_pwm_auto_point_temp(struct device *dev, 1674 struct device_attribute *devattr, 1675 const char *buf, size_t count) 1676 { 1677 struct f71882fg_data *data = dev_get_drvdata(dev); 1678 int pwm = to_sensor_dev_attr_2(devattr)->index; 1679 int point = to_sensor_dev_attr_2(devattr)->nr; 1680 long val = simple_strtol(buf, NULL, 10) / 1000; 1681 val = SENSORS_LIMIT(val, 0, 255); 1682 1683 mutex_lock(&data->update_lock); 1684 f71882fg_write8(data, F71882FG_REG_POINT_TEMP(pwm, point), val); 1685 data->pwm_auto_point_temp[pwm][point] = val; 1686 mutex_unlock(&data->update_lock); 1687 1688 return count; 1689 } 1690 1691 static ssize_t show_name(struct device *dev, struct device_attribute *devattr, 1692 char *buf) 1693 { 1694 struct f71882fg_data *data = dev_get_drvdata(dev); 1695 return sprintf(buf, "%s\n", f71882fg_names[data->type]); 1696 } 1697 1698 static int __devinit f71882fg_create_sysfs_files(struct platform_device *pdev, 1699 struct sensor_device_attribute_2 *attr, int count) 1700 { 1701 int err, i; 1702 1703 for (i = 0; i < count; i++) { 1704 err = device_create_file(&pdev->dev, &attr[i].dev_attr); 1705 if (err) 1706 return err; 1707 } 1708 return 0; 1709 } 1710 1711 static int __devinit f71882fg_probe(struct platform_device *pdev) 1712 { 1713 struct f71882fg_data *data; 1714 struct f71882fg_sio_data *sio_data = pdev->dev.platform_data; 1715 int err, i, nr_fans = (sio_data->type == f71882fg) ? 4 : 3; 1716 u8 start_reg; 1717 1718 data = kzalloc(sizeof(struct f71882fg_data), GFP_KERNEL); 1719 if (!data) 1720 return -ENOMEM; 1721 1722 data->addr = platform_get_resource(pdev, IORESOURCE_IO, 0)->start; 1723 data->type = sio_data->type; 1724 mutex_init(&data->update_lock); 1725 platform_set_drvdata(pdev, data); 1726 1727 start_reg = f71882fg_read8(data, F71882FG_REG_START); 1728 if (start_reg & 0x04) { 1729 dev_warn(&pdev->dev, "Hardware monitor is powered down\n"); 1730 err = -ENODEV; 1731 goto exit_free; 1732 } 1733 if (!(start_reg & 0x03)) { 1734 dev_warn(&pdev->dev, "Hardware monitoring not activated\n"); 1735 err = -ENODEV; 1736 goto exit_free; 1737 } 1738 1739 data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE); 1740 /* If it is a 71862 and the fan / pwm part is enabled sanity check 1741 the pwm settings */ 1742 if (data->type == f71862fg && (start_reg & 0x02)) { 1743 if ((data->pwm_enable & 0x15) != 0x15) { 1744 dev_err(&pdev->dev, 1745 "Invalid (reserved) pwm settings: 0x%02x\n", 1746 (unsigned int)data->pwm_enable); 1747 err = -ENODEV; 1748 goto exit_free; 1749 } 1750 } 1751 1752 /* Register sysfs interface files */ 1753 err = device_create_file(&pdev->dev, &dev_attr_name); 1754 if (err) 1755 goto exit_unregister_sysfs; 1756 1757 if (start_reg & 0x01) { 1758 switch (data->type) { 1759 case f71882fg: 1760 err = f71882fg_create_sysfs_files(pdev, 1761 f71882fg_in_temp_attr, 1762 ARRAY_SIZE(f71882fg_in_temp_attr)); 1763 if (err) 1764 goto exit_unregister_sysfs; 1765 /* fall through! */ 1766 case f71862fg: 1767 err = f71882fg_create_sysfs_files(pdev, 1768 f718x2fg_in_temp_attr, 1769 ARRAY_SIZE(f718x2fg_in_temp_attr)); 1770 break; 1771 case f8000: 1772 err = f71882fg_create_sysfs_files(pdev, 1773 f8000_in_temp_attr, 1774 ARRAY_SIZE(f8000_in_temp_attr)); 1775 break; 1776 } 1777 if (err) 1778 goto exit_unregister_sysfs; 1779 } 1780 1781 if (start_reg & 0x02) { 1782 err = f71882fg_create_sysfs_files(pdev, fxxxx_fan_attr, 1783 ARRAY_SIZE(fxxxx_fan_attr)); 1784 if (err) 1785 goto exit_unregister_sysfs; 1786 1787 switch (data->type) { 1788 case f71862fg: 1789 err = f71882fg_create_sysfs_files(pdev, 1790 f71862fg_fan_attr, 1791 ARRAY_SIZE(f71862fg_fan_attr)); 1792 break; 1793 case f71882fg: 1794 err = f71882fg_create_sysfs_files(pdev, 1795 f71882fg_fan_attr, 1796 ARRAY_SIZE(f71882fg_fan_attr)); 1797 break; 1798 case f8000: 1799 err = f71882fg_create_sysfs_files(pdev, 1800 f8000_fan_attr, 1801 ARRAY_SIZE(f8000_fan_attr)); 1802 break; 1803 } 1804 if (err) 1805 goto exit_unregister_sysfs; 1806 1807 for (i = 0; i < nr_fans; i++) 1808 dev_info(&pdev->dev, "Fan: %d is in %s mode\n", i + 1, 1809 (data->pwm_enable & (1 << 2 * i)) ? 1810 "duty-cycle" : "RPM"); 1811 } 1812 1813 data->hwmon_dev = hwmon_device_register(&pdev->dev); 1814 if (IS_ERR(data->hwmon_dev)) { 1815 err = PTR_ERR(data->hwmon_dev); 1816 data->hwmon_dev = NULL; 1817 goto exit_unregister_sysfs; 1818 } 1819 1820 return 0; 1821 1822 exit_unregister_sysfs: 1823 f71882fg_remove(pdev); /* Will unregister the sysfs files for us */ 1824 return err; /* f71882fg_remove() also frees our data */ 1825 exit_free: 1826 kfree(data); 1827 return err; 1828 } 1829 1830 static int f71882fg_remove(struct platform_device *pdev) 1831 { 1832 int i; 1833 struct f71882fg_data *data = platform_get_drvdata(pdev); 1834 1835 platform_set_drvdata(pdev, NULL); 1836 if (data->hwmon_dev) 1837 hwmon_device_unregister(data->hwmon_dev); 1838 1839 /* Note we are not looping over all attr arrays we have as the ones 1840 below are supersets of the ones skipped. */ 1841 device_remove_file(&pdev->dev, &dev_attr_name); 1842 1843 for (i = 0; i < ARRAY_SIZE(f718x2fg_in_temp_attr); i++) 1844 device_remove_file(&pdev->dev, 1845 &f718x2fg_in_temp_attr[i].dev_attr); 1846 1847 for (i = 0; i < ARRAY_SIZE(f71882fg_in_temp_attr); i++) 1848 device_remove_file(&pdev->dev, 1849 &f71882fg_in_temp_attr[i].dev_attr); 1850 1851 for (i = 0; i < ARRAY_SIZE(fxxxx_fan_attr); i++) 1852 device_remove_file(&pdev->dev, &fxxxx_fan_attr[i].dev_attr); 1853 1854 for (i = 0; i < ARRAY_SIZE(f71882fg_fan_attr); i++) 1855 device_remove_file(&pdev->dev, &f71882fg_fan_attr[i].dev_attr); 1856 1857 for (i = 0; i < ARRAY_SIZE(f8000_fan_attr); i++) 1858 device_remove_file(&pdev->dev, &f8000_fan_attr[i].dev_attr); 1859 1860 kfree(data); 1861 1862 return 0; 1863 } 1864 1865 static int __init f71882fg_find(int sioaddr, unsigned short *address, 1866 struct f71882fg_sio_data *sio_data) 1867 { 1868 int err = -ENODEV; 1869 u16 devid; 1870 1871 superio_enter(sioaddr); 1872 1873 devid = superio_inw(sioaddr, SIO_REG_MANID); 1874 if (devid != SIO_FINTEK_ID) { 1875 pr_debug(DRVNAME ": Not a Fintek device\n"); 1876 goto exit; 1877 } 1878 1879 devid = force_id ? force_id : superio_inw(sioaddr, SIO_REG_DEVID); 1880 switch (devid) { 1881 case SIO_F71862_ID: 1882 sio_data->type = f71862fg; 1883 break; 1884 case SIO_F71882_ID: 1885 sio_data->type = f71882fg; 1886 break; 1887 case SIO_F8000_ID: 1888 sio_data->type = f8000; 1889 break; 1890 default: 1891 printk(KERN_INFO DRVNAME ": Unsupported Fintek device\n"); 1892 goto exit; 1893 } 1894 1895 superio_select(sioaddr, SIO_F71882FG_LD_HWM); 1896 if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) { 1897 printk(KERN_WARNING DRVNAME ": Device not activated\n"); 1898 goto exit; 1899 } 1900 1901 *address = superio_inw(sioaddr, SIO_REG_ADDR); 1902 if (*address == 0) 1903 { 1904 printk(KERN_WARNING DRVNAME ": Base address not set\n"); 1905 goto exit; 1906 } 1907 *address &= ~(REGION_LENGTH - 1); /* Ignore 3 LSB */ 1908 1909 err = 0; 1910 printk(KERN_INFO DRVNAME ": Found %s chip at %#x, revision %d\n", 1911 f71882fg_names[sio_data->type], (unsigned int)*address, 1912 (int)superio_inb(sioaddr, SIO_REG_DEVREV)); 1913 exit: 1914 superio_exit(sioaddr); 1915 return err; 1916 } 1917 1918 static int __init f71882fg_device_add(unsigned short address, 1919 const struct f71882fg_sio_data *sio_data) 1920 { 1921 struct resource res = { 1922 .start = address, 1923 .end = address + REGION_LENGTH - 1, 1924 .flags = IORESOURCE_IO, 1925 }; 1926 int err; 1927 1928 f71882fg_pdev = platform_device_alloc(DRVNAME, address); 1929 if (!f71882fg_pdev) 1930 return -ENOMEM; 1931 1932 res.name = f71882fg_pdev->name; 1933 err = acpi_check_resource_conflict(&res); 1934 if (err) 1935 goto exit_device_put; 1936 1937 err = platform_device_add_resources(f71882fg_pdev, &res, 1); 1938 if (err) { 1939 printk(KERN_ERR DRVNAME ": Device resource addition failed\n"); 1940 goto exit_device_put; 1941 } 1942 1943 err = platform_device_add_data(f71882fg_pdev, sio_data, 1944 sizeof(struct f71882fg_sio_data)); 1945 if (err) { 1946 printk(KERN_ERR DRVNAME ": Platform data allocation failed\n"); 1947 goto exit_device_put; 1948 } 1949 1950 err = platform_device_add(f71882fg_pdev); 1951 if (err) { 1952 printk(KERN_ERR DRVNAME ": Device addition failed\n"); 1953 goto exit_device_put; 1954 } 1955 1956 return 0; 1957 1958 exit_device_put: 1959 platform_device_put(f71882fg_pdev); 1960 1961 return err; 1962 } 1963 1964 static int __init f71882fg_init(void) 1965 { 1966 int err = -ENODEV; 1967 unsigned short address; 1968 struct f71882fg_sio_data sio_data; 1969 1970 memset(&sio_data, 0, sizeof(sio_data)); 1971 1972 if (f71882fg_find(0x2e, &address, &sio_data) && 1973 f71882fg_find(0x4e, &address, &sio_data)) 1974 goto exit; 1975 1976 err = platform_driver_register(&f71882fg_driver); 1977 if (err) 1978 goto exit; 1979 1980 err = f71882fg_device_add(address, &sio_data); 1981 if (err) 1982 goto exit_driver; 1983 1984 return 0; 1985 1986 exit_driver: 1987 platform_driver_unregister(&f71882fg_driver); 1988 exit: 1989 return err; 1990 } 1991 1992 static void __exit f71882fg_exit(void) 1993 { 1994 platform_device_unregister(f71882fg_pdev); 1995 platform_driver_unregister(&f71882fg_driver); 1996 } 1997 1998 MODULE_DESCRIPTION("F71882FG Hardware Monitoring Driver"); 1999 MODULE_AUTHOR("Hans Edgington, Hans de Goede (hdegoede@redhat.com)"); 2000 MODULE_LICENSE("GPL"); 2001 2002 module_init(f71882fg_init); 2003 module_exit(f71882fg_exit); 2004