21 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
23 #include <linux/module.h>
25 #include <linux/slab.h>
35 #define DRVNAME "f71882fg"
37 #define SIO_F71858FG_LD_HWM 0x02
38 #define SIO_F71882FG_LD_HWM 0x04
39 #define SIO_UNLOCK_KEY 0x87
40 #define SIO_LOCK_KEY 0xAA
42 #define SIO_REG_LDSEL 0x07
43 #define SIO_REG_DEVID 0x20
44 #define SIO_REG_DEVREV 0x22
45 #define SIO_REG_MANID 0x23
46 #define SIO_REG_ENABLE 0x30
47 #define SIO_REG_ADDR 0x60
49 #define SIO_FINTEK_ID 0x1934
50 #define SIO_F71808E_ID 0x0901
51 #define SIO_F71808A_ID 0x1001
52 #define SIO_F71858_ID 0x0507
53 #define SIO_F71862_ID 0x0601
54 #define SIO_F71869_ID 0x0814
55 #define SIO_F71869A_ID 0x1007
56 #define SIO_F71882_ID 0x0541
57 #define SIO_F71889_ID 0x0723
58 #define SIO_F71889E_ID 0x0909
59 #define SIO_F71889A_ID 0x1005
60 #define SIO_F8000_ID 0x0581
61 #define SIO_F81865_ID 0x0704
63 #define REGION_LENGTH 8
64 #define ADDR_REG_OFFSET 5
65 #define DATA_REG_OFFSET 6
67 #define F71882FG_REG_IN_STATUS 0x12
68 #define F71882FG_REG_IN_BEEP 0x13
69 #define F71882FG_REG_IN(nr) (0x20 + (nr))
70 #define F71882FG_REG_IN1_HIGH 0x32
72 #define F71882FG_REG_FAN(nr) (0xA0 + (16 * (nr)))
73 #define F71882FG_REG_FAN_TARGET(nr) (0xA2 + (16 * (nr)))
74 #define F71882FG_REG_FAN_FULL_SPEED(nr) (0xA4 + (16 * (nr)))
75 #define F71882FG_REG_FAN_STATUS 0x92
76 #define F71882FG_REG_FAN_BEEP 0x93
78 #define F71882FG_REG_TEMP(nr) (0x70 + 2 * (nr))
79 #define F71882FG_REG_TEMP_OVT(nr) (0x80 + 2 * (nr))
80 #define F71882FG_REG_TEMP_HIGH(nr) (0x81 + 2 * (nr))
81 #define F71882FG_REG_TEMP_STATUS 0x62
82 #define F71882FG_REG_TEMP_BEEP 0x63
83 #define F71882FG_REG_TEMP_CONFIG 0x69
84 #define F71882FG_REG_TEMP_HYST(nr) (0x6C + (nr))
85 #define F71882FG_REG_TEMP_TYPE 0x6B
86 #define F71882FG_REG_TEMP_DIODE_OPEN 0x6F
88 #define F71882FG_REG_PWM(nr) (0xA3 + (16 * (nr)))
89 #define F71882FG_REG_PWM_TYPE 0x94
90 #define F71882FG_REG_PWM_ENABLE 0x96
92 #define F71882FG_REG_FAN_HYST(nr) (0x98 + (nr))
94 #define F71882FG_REG_FAN_FAULT_T 0x9F
95 #define F71882FG_FAN_NEG_TEMP_EN 0x20
96 #define F71882FG_FAN_PROG_SEL 0x80
98 #define F71882FG_REG_POINT_PWM(pwm, point) (0xAA + (point) + (16 * (pwm)))
99 #define F71882FG_REG_POINT_TEMP(pwm, point) (0xA6 + (point) + (16 * (pwm)))
100 #define F71882FG_REG_POINT_MAPPING(nr) (0xAF + 16 * (nr))
102 #define F71882FG_REG_START 0x01
104 #define F71882FG_MAX_INS 9
106 #define FAN_MIN_DETECT 366
108 static unsigned short force_id;
115 static const char *
const f71882fg_names[] = {
131 [
f71808e] = { 1, 1, 1, 1, 1, 1, 0, 1, 1 },
132 [
f71808a] = { 1, 1, 1, 1, 0, 0, 0, 1, 1 },
133 [
f71858fg] = { 1, 1, 1, 0, 0, 0, 0, 0, 0 },
134 [
f71862fg] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
135 [
f71869] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
136 [
f71869a] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
137 [
f71882fg] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
138 [
f71889fg] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
139 [
f71889ed] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
140 [
f71889a] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
141 [
f8000] = { 1, 1, 1, 0, 0, 0, 0, 0, 0 },
142 [
f81865f] = { 1, 1, 1, 1, 1, 1, 1, 0, 0 },
145 static const char f71882fg_has_in1_alarm[] = {
160 static const char f71882fg_fan_has_beep[] = {
175 static const char f71882fg_nr_fans[] = {
190 static const char f71882fg_temp_has_beep[] = {
205 static const char f71882fg_nr_temps[] = {
223 static inline int superio_inb(
int base,
int reg);
224 static inline int superio_inw(
int base,
int reg);
225 static inline int superio_enter(
int base);
227 static inline void superio_exit(
int base);
281 *devattr,
char *
buf);
283 *devattr,
const char *
buf,
size_t count);
285 *devattr,
char *
buf);
287 *devattr,
const char *
buf,
size_t count);
289 *devattr,
char *
buf);
298 *devattr,
char *
buf);
300 *devattr,
const char *
buf,
size_t count);
302 *devattr,
char *
buf);
305 *devattr,
char *
buf);
307 *devattr,
char *
buf);
309 *devattr,
const char *
buf,
size_t count);
311 *devattr,
char *
buf);
313 *devattr,
const char *
buf,
size_t count);
315 *devattr,
char *
buf);
317 *devattr,
const char *
buf,
size_t count);
319 *devattr,
char *
buf);
321 *devattr,
char *
buf);
323 *devattr,
char *
buf);
325 *devattr,
const char *
buf,
size_t count);
327 *devattr,
char *
buf);
329 *devattr,
char *
buf);
375 .probe = f71882fg_probe,
376 .remove = f71882fg_remove,
388 store_temp_max, 0, 0),
390 store_temp_max_hyst, 0, 0),
393 store_temp_crit, 0, 0),
400 store_temp_max, 0, 1),
402 store_temp_max_hyst, 0, 1),
405 store_temp_crit, 0, 1),
412 store_temp_max, 0, 2),
414 store_temp_max_hyst, 0, 2),
417 store_temp_crit, 0, 2),
428 store_temp_max, 0, 1),
430 store_temp_max_hyst, 0, 1),
438 store_temp_crit, 0, 1),
447 store_temp_max, 0, 2),
449 store_temp_max_hyst, 0, 2),
453 store_temp_crit, 0, 2),
462 store_temp_max, 0, 3),
464 store_temp_max_hyst, 0, 3),
468 store_temp_crit, 0, 3),
479 store_temp_beep, 0, 1),
481 store_temp_beep, 0, 5),
484 store_temp_beep, 0, 2),
486 store_temp_beep, 0, 6),
489 store_temp_beep, 0, 3),
491 store_temp_beep, 0, 7),
503 store_temp_crit, 0, 0),
505 store_temp_max, 0, 0),
510 store_temp_crit, 0, 1),
512 store_temp_max, 0, 1),
517 store_temp_crit, 0, 2),
519 store_temp_max, 0, 2),
551 store_fan_full_speed, 0, 0),
555 store_pwm_enable, 0, 0),
557 show_pwm_interpolate, store_pwm_interpolate, 0, 0),
562 store_fan_full_speed, 0, 1),
566 store_pwm_enable, 0, 1),
568 show_pwm_interpolate, store_pwm_interpolate, 0, 1),
573 store_fan_full_speed, 0, 2),
577 store_pwm_enable, 0, 2),
579 show_pwm_interpolate, store_pwm_interpolate, 0, 2),
584 store_fan_full_speed, 0, 3),
588 store_pwm_enable, 0, 3),
590 show_pwm_interpolate, store_pwm_interpolate, 0, 3),
598 show_simple_pwm, store_simple_pwm, 0, 2),
604 store_fan_beep, 0, 0),
606 store_fan_beep, 0, 1),
608 store_fan_beep, 0, 2),
610 store_fan_beep, 0, 3),
619 show_pwm_auto_point_channel,
620 store_pwm_auto_point_channel, 0, 0),
622 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
625 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
628 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
631 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
634 show_pwm_auto_point_temp_hyst,
635 store_pwm_auto_point_temp_hyst,
638 show_pwm_auto_point_temp_hyst,
NULL, 3, 0),
641 show_pwm_auto_point_channel,
642 store_pwm_auto_point_channel, 0, 1),
644 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
647 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
650 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
653 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
656 show_pwm_auto_point_temp_hyst,
657 store_pwm_auto_point_temp_hyst,
660 show_pwm_auto_point_temp_hyst,
NULL, 3, 1),
663 show_pwm_auto_point_channel,
664 store_pwm_auto_point_channel, 0, 2),
666 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
669 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
672 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
675 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
678 show_pwm_auto_point_temp_hyst,
679 store_pwm_auto_point_temp_hyst,
682 show_pwm_auto_point_temp_hyst,
NULL, 3, 2),
692 show_pwm_auto_point_channel,
693 store_pwm_auto_point_channel, 0, 0),
695 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
698 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
701 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
704 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
707 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
710 show_pwm_auto_point_temp_hyst,
711 store_pwm_auto_point_temp_hyst,
714 show_pwm_auto_point_temp_hyst,
NULL, 3, 0),
717 show_pwm_auto_point_channel,
718 store_pwm_auto_point_channel, 0, 1),
720 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
723 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
726 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
729 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
732 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
735 show_pwm_auto_point_temp_hyst,
736 store_pwm_auto_point_temp_hyst,
739 show_pwm_auto_point_temp_hyst,
NULL, 3, 1),
742 show_pwm_auto_point_channel,
743 store_pwm_auto_point_channel, 0, 2),
745 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
748 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
751 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
754 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
757 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
760 show_pwm_auto_point_temp_hyst,
761 store_pwm_auto_point_temp_hyst,
764 show_pwm_auto_point_temp_hyst,
NULL, 3, 2),
770 show_pwm_auto_point_channel,
771 store_pwm_auto_point_channel, 0, 0),
773 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
776 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
779 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
782 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
785 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
788 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
791 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
794 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
797 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
800 show_pwm_auto_point_temp_hyst,
801 store_pwm_auto_point_temp_hyst,
804 show_pwm_auto_point_temp_hyst,
NULL, 1, 0),
806 show_pwm_auto_point_temp_hyst,
NULL, 2, 0),
808 show_pwm_auto_point_temp_hyst,
NULL, 3, 0),
811 show_pwm_auto_point_channel,
812 store_pwm_auto_point_channel, 0, 1),
814 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
817 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
820 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
823 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
826 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
829 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
832 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
835 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
838 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
841 show_pwm_auto_point_temp_hyst,
842 store_pwm_auto_point_temp_hyst,
845 show_pwm_auto_point_temp_hyst,
NULL, 1, 1),
847 show_pwm_auto_point_temp_hyst,
NULL, 2, 1),
849 show_pwm_auto_point_temp_hyst,
NULL, 3, 1),
852 show_pwm_auto_point_channel,
853 store_pwm_auto_point_channel, 0, 2),
855 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
858 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
861 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
864 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
867 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
870 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
873 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
876 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
879 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
882 show_pwm_auto_point_temp_hyst,
883 store_pwm_auto_point_temp_hyst,
886 show_pwm_auto_point_temp_hyst,
NULL, 1, 2),
888 show_pwm_auto_point_temp_hyst,
NULL, 2, 2),
890 show_pwm_auto_point_temp_hyst,
NULL, 3, 2),
893 show_pwm_auto_point_channel,
894 store_pwm_auto_point_channel, 0, 3),
896 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
899 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
902 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
905 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
908 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
911 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
914 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
917 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
920 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
923 show_pwm_auto_point_temp_hyst,
924 store_pwm_auto_point_temp_hyst,
927 show_pwm_auto_point_temp_hyst,
NULL, 1, 3),
929 show_pwm_auto_point_temp_hyst,
NULL, 2, 3),
931 show_pwm_auto_point_temp_hyst,
NULL, 3, 3),
946 show_pwm_auto_point_channel,
947 store_pwm_auto_point_channel, 0, 0),
949 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
952 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
955 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
958 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
961 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
964 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
967 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
970 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
973 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
976 show_pwm_auto_point_temp_hyst,
977 store_pwm_auto_point_temp_hyst,
980 show_pwm_auto_point_temp_hyst,
NULL, 1, 2),
982 show_pwm_auto_point_temp_hyst,
NULL, 2, 2),
984 show_pwm_auto_point_temp_hyst,
NULL, 3, 2),
987 show_pwm_auto_point_channel,
988 store_pwm_auto_point_channel, 0, 1),
990 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
993 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
996 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
999 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
1002 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
1005 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
1008 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
1011 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
1014 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
1017 show_pwm_auto_point_temp_hyst,
1018 store_pwm_auto_point_temp_hyst,
1021 show_pwm_auto_point_temp_hyst,
NULL, 1, 0),
1023 show_pwm_auto_point_temp_hyst,
NULL, 2, 0),
1025 show_pwm_auto_point_temp_hyst,
NULL, 3, 0),
1028 show_pwm_auto_point_channel,
1029 store_pwm_auto_point_channel, 0, 2),
1031 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
1034 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
1037 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
1040 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
1043 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
1046 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
1049 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
1052 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
1055 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
1058 show_pwm_auto_point_temp_hyst,
1059 store_pwm_auto_point_temp_hyst,
1062 show_pwm_auto_point_temp_hyst,
NULL, 1, 1),
1064 show_pwm_auto_point_temp_hyst,
NULL, 2, 1),
1066 show_pwm_auto_point_temp_hyst,
NULL, 3, 1),
1070 static inline int superio_inb(
int base,
int reg)
1073 return inb(base + 1);
1076 static int superio_inw(
int base,
int reg)
1079 val = superio_inb(base, reg) << 8;
1080 val |= superio_inb(base, reg + 1);
1084 static inline int superio_enter(
int base)
1088 pr_err(
"I/O address 0x%04x already in use\n", base);
1105 static inline void superio_exit(
int base)
1111 static inline int fan_from_reg(
u16 reg)
1113 return reg ? (1500000 /
reg) : 0;
1116 static inline u16 fan_to_reg(
int fan)
1118 return fan ? (1500000 /
fan) : 0;
1135 val = f71882fg_read8(data, reg) << 8;
1136 val |= f71882fg_read8(data, reg + 1);
1149 f71882fg_write8(data, reg, val >> 8);
1150 f71882fg_write8(data, reg + 1, val & 0xff);
1164 int nr_fans = f71882fg_nr_fans[data->
type];
1165 int nr_temps = f71882fg_nr_temps[data->
type];
1173 if (f71882fg_has_in1_alarm[data->
type]) {
1190 data->
temp_hyst[0] = f71882fg_read8(data,
1192 data->
temp_hyst[1] = f71882fg_read8(data,
1198 data->
temp_type[1] = (reg & 0x02) ? 2 : 4;
1199 data->
temp_type[2] = (reg & 0x04) ? 2 : 4;
1200 data->
temp_type[3] = (reg & 0x08) ? 2 : 4;
1203 if (f71882fg_fan_has_beep[data->
type])
1204 data->
fan_beep = f71882fg_read8(data,
1207 if (f71882fg_temp_has_beep[data->
type])
1218 for (nr = 0; nr < nr_fans; nr++) {
1220 f71882fg_read8(data,
1223 switch (data->
type) {
1225 for (point = 0; point < 5; point++) {
1227 f71882fg_read8(data,
1231 for (point = 0; point < 4; point++) {
1233 f71882fg_read8(data,
1241 f71882fg_read8(data,
1246 f71882fg_read8(data,
1250 f71882fg_read8(data,
1254 f71882fg_read8(data,
1258 f71882fg_read8(data,
1275 data->
temp[
nr] = f71882fg_read_temp(data, nr);
1279 for (nr = 0; nr < nr_fans; nr++) {
1280 data->
fan[
nr] = f71882fg_read16(data,
1285 f71882fg_read16(data,
1292 data->
fan[2] = f71882fg_read16(data,
1294 data->
pwm[2] = f71882fg_read8(data,
1298 data->
fan[3] = f71882fg_read16(data,
1301 if (f71882fg_has_in1_alarm[data->
type])
1305 if (f71882fg_has_in[data->
type][nr])
1306 data->
in[
nr] = f71882fg_read8(data,
1324 int speed = fan_from_reg(data->
fan[nr]);
1329 return sprintf(buf,
"%d\n", speed);
1338 return sprintf(buf,
"%d\n", speed);
1343 const char *buf,
size_t count)
1349 err = kstrtol(buf, 10, &val);
1353 val = SENSORS_LIMIT(val, 23, 1500000);
1354 val = fan_to_reg(val);
1365 *devattr,
char *buf)
1377 *devattr,
const char *buf,
size_t count)
1383 err = kstrtoul(buf, 10, &val);
1401 *devattr,
char *buf)
1418 return sprintf(buf,
"%d\n", data->
in[nr] * 8);
1422 *devattr,
char *buf)
1430 *devattr,
const char *buf,
size_t count)
1436 err = kstrtol(buf, 10, &val);
1441 val = SENSORS_LIMIT(val, 0, 255);
1452 *devattr,
char *buf)
1457 if (data->
in_beep & (1 << nr))
1464 *devattr,
const char *buf,
size_t count)
1470 err = kstrtoul(buf, 10, &val);
1488 *devattr,
char *buf)
1509 sign = data->
temp[
nr] & 0x0001;
1510 temp = (data->
temp[
nr] >> 5) & 0x7ff;
1512 sign = data->
temp[
nr] & 0x8000;
1513 temp = (data->
temp[
nr] >> 5) & 0x3ff;
1519 temp = data->
temp[
nr] * 1000;
1521 return sprintf(buf,
"%d\n", temp);
1525 *devattr,
char *buf)
1534 *devattr,
const char *buf,
size_t count)
1540 err = kstrtol(buf, 10, &val);
1545 val = SENSORS_LIMIT(val, 0, 255);
1556 *devattr,
char *buf)
1564 temp_max_hyst = data->
temp_hyst[nr / 2] >> 4;
1566 temp_max_hyst = data->
temp_hyst[nr / 2] & 0x0f;
1567 temp_max_hyst = (data->
temp_high[
nr] - temp_max_hyst) * 1000;
1570 return sprintf(buf,
"%d\n", temp_max_hyst);
1574 *devattr,
const char *buf,
size_t count)
1582 err = kstrtol(buf, 10, &val);
1592 val = SENSORS_LIMIT(val, data->
temp_high[nr] - 15,
1599 reg = (reg & 0x0f) | (val << 4);
1601 reg = (reg & 0xf0) | val;
1610 *devattr,
char *buf)
1619 *devattr,
const char *buf,
size_t count)
1625 err = kstrtol(buf, 10, &val);
1630 val = SENSORS_LIMIT(val, 0, 255);
1641 *devattr,
char *buf)
1649 temp_crit_hyst = data->
temp_hyst[nr / 2] >> 4;
1651 temp_crit_hyst = data->
temp_hyst[nr / 2] & 0x0f;
1652 temp_crit_hyst = (data->
temp_ovt[
nr] - temp_crit_hyst) * 1000;
1655 return sprintf(buf,
"%d\n", temp_crit_hyst);
1659 *devattr,
char *buf)
1668 *devattr,
char *buf)
1680 *devattr,
const char *buf,
size_t count)
1686 err = kstrtoul(buf, 10, &val);
1704 *devattr,
char *buf)
1716 *devattr,
char *buf)
1735 val = data->
pwm[
nr];
1738 val = 255 * fan_from_reg(data->
fan_target[nr])
1742 return sprintf(buf,
"%d\n", val);
1753 err = kstrtol(buf, 10, &val);
1757 val = SENSORS_LIMIT(val, 0, 255);
1773 full_speed = f71882fg_read16(data,
1775 target = fan_to_reg(val * fan_from_reg(full_speed) / 255);
1792 val = data->
pwm[
nr];
1793 return sprintf(buf,
"%d\n", val);
1798 const char *buf,
size_t count)
1804 err = kstrtol(buf, 10, &val);
1808 val = SENSORS_LIMIT(val, 0, 255);
1841 return sprintf(buf,
"%d\n", result);
1845 *devattr,
const char *buf,
size_t count)
1851 err = kstrtol(buf, 10, &val);
1856 if (data->
type ==
f8000 && nr == 2 && val != 2)
1919 return sprintf(buf,
"%d\n", result);
1924 const char *buf,
size_t count)
1931 err = kstrtol(buf, 10, &val);
1935 val = SENSORS_LIMIT(val, 0, 255);
1946 val = (255 -
val) * 32 / val;
1955 static ssize_t show_pwm_auto_point_temp_hyst(
struct device *dev,
1972 return sprintf(buf,
"%d\n", result);
1975 static ssize_t store_pwm_auto_point_temp_hyst(
struct device *dev,
1977 const char *buf,
size_t count)
1985 err = kstrtol(buf, 10, &val);
2000 reg = (reg & 0x0f) | (val << 4);
2002 reg = (reg & 0xf0) | val;
2020 return sprintf(buf,
"%d\n", result);
2025 const char *buf,
size_t count)
2031 err = kstrtoul(buf, 10, &val);
2049 static ssize_t show_pwm_auto_point_channel(
struct device *dev,
2060 return sprintf(buf,
"%d\n", result);
2063 static ssize_t store_pwm_auto_point_channel(
struct device *dev,
2065 const char *buf,
size_t count)
2071 err = kstrtol(buf, 10, &val);
2110 return sprintf(buf,
"%d\n", 1000 * result);
2113 static ssize_t store_pwm_auto_point_temp(
struct device *dev,
2115 const char *buf,
size_t count)
2122 err = kstrtol(buf, 10, &val);
2129 val = SENSORS_LIMIT(val, -128, 127);
2131 val = SENSORS_LIMIT(val, 0, 127);
2145 return sprintf(buf,
"%s\n", f71882fg_names[data->
type]);
2153 for (i = 0; i <
count; i++) {
2166 for (i = 0; i <
count; i++)
2170 static int __devinit f71882fg_create_fan_sysfs_files(
2178 switch (data->
type) {
2180 if (((data->
pwm_enable >> (idx * 2)) & 3) == 3)
2184 if (((data->
pwm_enable >> (idx * 2)) & 1) != 1)
2196 "Invalid (reserved) pwm settings: 0x%02x, "
2197 "skipping fan %d\n",
2198 (data->
pwm_enable >> (idx * 2)) & 3, idx + 1);
2202 err = f71882fg_create_sysfs_files(pdev, &fxxxx_fan_attr[idx][0],
2207 if (f71882fg_fan_has_beep[data->
type]) {
2208 err = f71882fg_create_sysfs_files(pdev,
2209 &fxxxx_fan_beep_attr[idx],
2215 dev_info(&pdev->
dev,
"Fan: %d is in %s mode\n", idx + 1,
2216 (data->
pwm_enable & (1 << (2 * idx))) ?
"duty-cycle" :
"RPM");
2219 switch (data->
type) {
2232 "Auto pwm controlled by raw digital "
2233 "data, disabling pwm auto_point "
2234 "sysfs attributes for fan %d\n", idx + 1);
2242 switch (data->
type) {
2244 err = f71882fg_create_sysfs_files(pdev,
2245 &f71862fg_auto_pwm_attr[idx][0],
2250 err = f71882fg_create_sysfs_files(pdev,
2251 &f71869_auto_pwm_attr[idx][0],
2255 err = f71882fg_create_sysfs_files(pdev,
2256 &f8000_auto_pwm_attr[idx][0],
2260 err = f71882fg_create_sysfs_files(pdev,
2261 &fxxxx_auto_pwm_attr[idx][0],
2272 int nr_fans = f71882fg_nr_fans[sio_data->
type];
2273 int nr_temps = f71882fg_nr_temps[sio_data->
type];
2287 platform_set_drvdata(pdev, data);
2290 if (start_reg & 0x04) {
2291 dev_warn(&pdev->
dev,
"Hardware monitor is powered down\n");
2294 if (!(start_reg & 0x03)) {
2295 dev_warn(&pdev->
dev,
"Hardware monitoring not activated\n");
2302 goto exit_unregister_sysfs;
2304 if (start_reg & 0x01) {
2305 switch (data->
type) {
2314 err = f71882fg_create_sysfs_files(pdev,
2318 err = f71882fg_create_sysfs_files(pdev,
2323 err = f71882fg_create_sysfs_files(pdev,
2328 err = f71882fg_create_sysfs_files(pdev,
2329 &fxxxx_temp_attr[0][0],
2333 goto exit_unregister_sysfs;
2335 if (f71882fg_temp_has_beep[data->
type]) {
2336 err = f71882fg_create_sysfs_files(pdev,
2337 &fxxxx_temp_beep_attr[0][0],
2341 goto exit_unregister_sysfs;
2345 if (f71882fg_has_in[data->
type][i]) {
2349 goto exit_unregister_sysfs;
2352 if (f71882fg_has_in1_alarm[data->
type]) {
2353 err = f71882fg_create_sysfs_files(pdev,
2354 fxxxx_in1_alarm_attr,
2357 goto exit_unregister_sysfs;
2361 if (start_reg & 0x02) {
2362 switch (data->
type) {
2387 for (i = 0; i < nr_fans; i++) {
2388 err = f71882fg_create_fan_sysfs_files(pdev, i);
2390 goto exit_unregister_sysfs;
2394 switch (data->
type) {
2396 err = f71882fg_create_sysfs_files(pdev,
2401 err = f71882fg_create_sysfs_files(pdev,
2409 goto exit_unregister_sysfs;
2416 goto exit_unregister_sysfs;
2421 exit_unregister_sysfs:
2422 f71882fg_remove(pdev);
2430 int nr_fans = f71882fg_nr_fans[data->
type];
2431 int nr_temps = f71882fg_nr_temps[data->
type];
2440 if (start_reg & 0x01) {
2441 switch (data->
type) {
2444 f71882fg_remove_sysfs_files(pdev,
2448 f71882fg_remove_sysfs_files(pdev,
2453 f71882fg_remove_sysfs_files(pdev,
2458 f71882fg_remove_sysfs_files(pdev,
2459 &fxxxx_temp_attr[0][0],
2462 if (f71882fg_temp_has_beep[data->
type]) {
2463 f71882fg_remove_sysfs_files(pdev,
2464 &fxxxx_temp_beep_attr[0][0],
2465 ARRAY_SIZE(fxxxx_temp_beep_attr[0]) * nr_temps);
2469 if (f71882fg_has_in[data->
type][i]) {
2474 if (f71882fg_has_in1_alarm[data->
type]) {
2475 f71882fg_remove_sysfs_files(pdev,
2476 fxxxx_in1_alarm_attr,
2481 if (start_reg & 0x02) {
2482 f71882fg_remove_sysfs_files(pdev, &fxxxx_fan_attr[0][0],
2485 if (f71882fg_fan_has_beep[data->
type]) {
2486 f71882fg_remove_sysfs_files(pdev,
2487 fxxxx_fan_beep_attr, nr_fans);
2490 switch (data->
type) {
2492 f71882fg_remove_sysfs_files(pdev,
2493 &fxxxx_auto_pwm_attr[0][0],
2494 ARRAY_SIZE(fxxxx_auto_pwm_attr[0]) * nr_fans);
2495 f71882fg_remove_sysfs_files(pdev,
2500 f71882fg_remove_sysfs_files(pdev,
2501 &f71862fg_auto_pwm_attr[0][0],
2507 f71882fg_remove_sysfs_files(pdev,
2508 &f71869_auto_pwm_attr[0][0],
2509 ARRAY_SIZE(f71869_auto_pwm_attr[0]) * nr_fans);
2512 f71882fg_remove_sysfs_files(pdev,
2515 f71882fg_remove_sysfs_files(pdev,
2516 &f8000_auto_pwm_attr[0][0],
2517 ARRAY_SIZE(f8000_auto_pwm_attr[0]) * nr_fans);
2520 f71882fg_remove_sysfs_files(pdev,
2521 &fxxxx_auto_pwm_attr[0][0],
2522 ARRAY_SIZE(fxxxx_auto_pwm_attr[0]) * nr_fans);
2532 int err = superio_enter(sioaddr);
2543 devid = force_id ? force_id : superio_inw(sioaddr,
SIO_REG_DEVID);
2582 pr_info(
"Unsupported Fintek device: %04x\n",
2583 (
unsigned int)devid);
2594 pr_warn(
"Device not activated\n");
2601 pr_warn(
"Base address not set\n");
2608 pr_info(
"Found %s chip at %#x, revision %d\n",
2609 f71882fg_names[sio_data->
type], (
unsigned int)address,
2612 superio_exit(sioaddr);
2616 static int __init f71882fg_device_add(
int address,
2633 goto exit_device_put;
2637 pr_err(
"Device resource addition failed\n");
2638 goto exit_device_put;
2644 pr_err(
"Platform data allocation failed\n");
2645 goto exit_device_put;
2650 pr_err(
"Device addition failed\n");
2651 goto exit_device_put;
2662 static int __init f71882fg_init(
void)
2668 memset(&sio_data, 0,
sizeof(sio_data));
2670 address = f71882fg_find(0x2e, &sio_data);
2672 address = f71882fg_find(0x4e, &sio_data);
2680 err = f71882fg_device_add(address, &sio_data);
2691 static void __exit f71882fg_exit(
void)