aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon
diff options
context:
space:
mode:
authorGuenter Roeck <linux@roeck-us.net>2012-12-04 10:56:24 -0500
committerGuenter Roeck <linux@roeck-us.net>2013-04-08 00:16:39 -0400
commit1c65dc365ed38d6839fcc231ea38a6163fb9d343 (patch)
tree98bab52616fa4fbd955179416eaaf118a1616542 /drivers/hwmon
parentaa136e5dad9fbec9e98867278555a81f2d75ea10 (diff)
hwmon: (nct6775) Add support for fan speed attributes
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Diffstat (limited to 'drivers/hwmon')
-rw-r--r--drivers/hwmon/nct6775.c516
1 files changed, 515 insertions, 1 deletions
diff --git a/drivers/hwmon/nct6775.c b/drivers/hwmon/nct6775.c
index fd0dd15ae4b6..bafcae55e255 100644
--- a/drivers/hwmon/nct6775.c
+++ b/drivers/hwmon/nct6775.c
@@ -180,6 +180,9 @@ static const u16 NCT6775_REG_IN[] = {
180#define NCT6775_REG_VBAT 0x5D 180#define NCT6775_REG_VBAT 0x5D
181#define NCT6775_REG_DIODE 0x5E 181#define NCT6775_REG_DIODE 0x5E
182 182
183#define NCT6775_REG_FANDIV1 0x506
184#define NCT6775_REG_FANDIV2 0x507
185
183static const u16 NCT6775_REG_ALARM[NUM_REG_ALARM] = { 0x459, 0x45A, 0x45B }; 186static const u16 NCT6775_REG_ALARM[NUM_REG_ALARM] = { 0x459, 0x45A, 0x45B };
184 187
185/* 0..15 voltages, 16..23 fans, 24..31 temperatures */ 188/* 0..15 voltages, 16..23 fans, 24..31 temperatures */
@@ -193,12 +196,16 @@ static const s8 NCT6775_ALARM_BITS[] = {
193 4, 5, 13, -1, -1, -1, /* temp1..temp6 */ 196 4, 5, 13, -1, -1, -1, /* temp1..temp6 */
194 12, -1 }; /* intrusion0, intrusion1 */ 197 12, -1 }; /* intrusion0, intrusion1 */
195 198
199#define FAN_ALARM_BASE 16
196#define TEMP_ALARM_BASE 24 200#define TEMP_ALARM_BASE 24
197#define INTRUSION_ALARM_BASE 30 201#define INTRUSION_ALARM_BASE 30
198 202
199static const u8 NCT6775_REG_CR_CASEOPEN_CLR[] = { 0xe6, 0xee }; 203static const u8 NCT6775_REG_CR_CASEOPEN_CLR[] = { 0xe6, 0xee };
200static const u8 NCT6775_CR_CASEOPEN_CLR_MASK[] = { 0x20, 0x01 }; 204static const u8 NCT6775_CR_CASEOPEN_CLR_MASK[] = { 0x20, 0x01 };
201 205
206static const u16 NCT6775_REG_FAN[] = { 0x630, 0x632, 0x634, 0x636, 0x638 };
207static const u16 NCT6775_REG_FAN_MIN[] = { 0x3b, 0x3c, 0x3d };
208
202static const u16 NCT6775_REG_TEMP[] = { 209static const u16 NCT6775_REG_TEMP[] = {
203 0x27, 0x150, 0x250, 0x62b, 0x62c, 0x62d }; 210 0x27, 0x150, 0x250, 0x62b, 0x62c, 0x62d };
204 211
@@ -256,6 +263,8 @@ static const s8 NCT6776_ALARM_BITS[] = {
256 4, 5, 13, -1, -1, -1, /* temp1..temp6 */ 263 4, 5, 13, -1, -1, -1, /* temp1..temp6 */
257 12, 9 }; /* intrusion0, intrusion1 */ 264 12, 9 }; /* intrusion0, intrusion1 */
258 265
266static const u16 NCT6776_REG_FAN_MIN[] = { 0x63a, 0x63c, 0x63e, 0x640, 0x642 };
267
259static const u16 NCT6776_REG_TEMP_CONFIG[ARRAY_SIZE(NCT6775_REG_TEMP)] = { 268static const u16 NCT6776_REG_TEMP_CONFIG[ARRAY_SIZE(NCT6775_REG_TEMP)] = {
260 0x18, 0x152, 0x252, 0x628, 0x629, 0x62A }; 269 0x18, 0x152, 0x252, 0x628, 0x629, 0x62A };
261 270
@@ -309,6 +318,8 @@ static const s8 NCT6779_ALARM_BITS[] = {
309 4, 5, 13, -1, -1, -1, /* temp1..temp6 */ 318 4, 5, 13, -1, -1, -1, /* temp1..temp6 */
310 12, 9 }; /* intrusion0, intrusion1 */ 319 12, 9 }; /* intrusion0, intrusion1 */
311 320
321static const u16 NCT6779_REG_FAN[] = { 0x4b0, 0x4b2, 0x4b4, 0x4b6, 0x4b8 };
322
312static const u16 NCT6779_REG_TEMP[] = { 0x27, 0x150 }; 323static const u16 NCT6779_REG_TEMP[] = { 0x27, 0x150 };
313static const u16 NCT6779_REG_TEMP_CONFIG[ARRAY_SIZE(NCT6779_REG_TEMP)] = { 324static const u16 NCT6779_REG_TEMP_CONFIG[ARRAY_SIZE(NCT6779_REG_TEMP)] = {
314 0x18, 0x152 }; 325 0x18, 0x152 };
@@ -363,6 +374,44 @@ static const u16 NCT6779_REG_TEMP_CRIT[ARRAY_SIZE(nct6779_temp_label) - 1]
363 * Conversions 374 * Conversions
364 */ 375 */
365 376
377static unsigned int fan_from_reg8(u16 reg, unsigned int divreg)
378{
379 if (reg == 0 || reg == 255)
380 return 0;
381 return 1350000U / (reg << divreg);
382}
383
384static unsigned int fan_from_reg13(u16 reg, unsigned int divreg)
385{
386 if ((reg & 0xff1f) == 0xff1f)
387 return 0;
388
389 reg = (reg & 0x1f) | ((reg & 0xff00) >> 3);
390
391 if (reg == 0)
392 return 0;
393
394 return 1350000U / reg;
395}
396
397static unsigned int fan_from_reg16(u16 reg, unsigned int divreg)
398{
399 if (reg == 0 || reg == 0xffff)
400 return 0;
401
402 /*
403 * Even though the registers are 16 bit wide, the fan divisor
404 * still applies.
405 */
406 return 1350000U / (reg << divreg);
407}
408
409static inline unsigned int
410div_from_reg(u8 reg)
411{
412 return 1 << reg;
413}
414
366/* 415/*
367 * Some of the voltage inputs have internal scaling, the tables below 416 * Some of the voltage inputs have internal scaling, the tables below
368 * contain 8 (the ADC LSB in mV) * scaling factor * 100 417 * contain 8 (the ADC LSB in mV) * scaling factor * 100
@@ -411,12 +460,17 @@ struct nct6775_data {
411 const u16 *REG_VIN; 460 const u16 *REG_VIN;
412 const u16 *REG_IN_MINMAX[2]; 461 const u16 *REG_IN_MINMAX[2];
413 462
414 const u16 *REG_TEMP_SOURCE; /* temp register sources */ 463 const u16 *REG_FAN;
464 const u16 *REG_FAN_MIN;
415 465
466 const u16 *REG_TEMP_SOURCE; /* temp register sources */
416 const u16 *REG_TEMP_OFFSET; 467 const u16 *REG_TEMP_OFFSET;
417 468
418 const u16 *REG_ALARM; 469 const u16 *REG_ALARM;
419 470
471 unsigned int (*fan_from_reg)(u16 reg, unsigned int divreg);
472 unsigned int (*fan_from_reg_min)(u16 reg, unsigned int divreg);
473
420 struct mutex update_lock; 474 struct mutex update_lock;
421 bool valid; /* true if following fields are valid */ 475 bool valid; /* true if following fields are valid */
422 unsigned long last_updated; /* In jiffies */ 476 unsigned long last_updated; /* In jiffies */
@@ -425,6 +479,12 @@ struct nct6775_data {
425 u8 bank; /* current register bank */ 479 u8 bank; /* current register bank */
426 u8 in_num; /* number of in inputs we have */ 480 u8 in_num; /* number of in inputs we have */
427 u8 in[15][3]; /* [0]=in, [1]=in_max, [2]=in_min */ 481 u8 in[15][3]; /* [0]=in, [1]=in_max, [2]=in_min */
482 unsigned int rpm[5];
483 u16 fan_min[5];
484 u8 fan_div[5];
485 u8 has_fan; /* some fan inputs can be disabled */
486 u8 has_fan_min; /* some fans don't have min register */
487 bool has_fan_div;
428 488
429 u8 temp_fixed_num; /* 3 or 6 */ 489 u8 temp_fixed_num; /* 3 or 6 */
430 u8 temp_type[NUM_TEMP_FIXED]; 490 u8 temp_type[NUM_TEMP_FIXED];
@@ -556,6 +616,153 @@ static int nct6775_write_temp(struct nct6775_data *data, u16 reg, u16 value)
556 return nct6775_write_value(data, reg, value); 616 return nct6775_write_value(data, reg, value);
557} 617}
558 618
619/* This function assumes that the caller holds data->update_lock */
620static void nct6775_write_fan_div(struct nct6775_data *data, int nr)
621{
622 u8 reg;
623
624 switch (nr) {
625 case 0:
626 reg = (nct6775_read_value(data, NCT6775_REG_FANDIV1) & 0x70)
627 | (data->fan_div[0] & 0x7);
628 nct6775_write_value(data, NCT6775_REG_FANDIV1, reg);
629 break;
630 case 1:
631 reg = (nct6775_read_value(data, NCT6775_REG_FANDIV1) & 0x7)
632 | ((data->fan_div[1] << 4) & 0x70);
633 nct6775_write_value(data, NCT6775_REG_FANDIV1, reg);
634 break;
635 case 2:
636 reg = (nct6775_read_value(data, NCT6775_REG_FANDIV2) & 0x70)
637 | (data->fan_div[2] & 0x7);
638 nct6775_write_value(data, NCT6775_REG_FANDIV2, reg);
639 break;
640 case 3:
641 reg = (nct6775_read_value(data, NCT6775_REG_FANDIV2) & 0x7)
642 | ((data->fan_div[3] << 4) & 0x70);
643 nct6775_write_value(data, NCT6775_REG_FANDIV2, reg);
644 break;
645 }
646}
647
648static void nct6775_write_fan_div_common(struct nct6775_data *data, int nr)
649{
650 if (data->kind == nct6775)
651 nct6775_write_fan_div(data, nr);
652}
653
654static void nct6775_update_fan_div(struct nct6775_data *data)
655{
656 u8 i;
657
658 i = nct6775_read_value(data, NCT6775_REG_FANDIV1);
659 data->fan_div[0] = i & 0x7;
660 data->fan_div[1] = (i & 0x70) >> 4;
661 i = nct6775_read_value(data, NCT6775_REG_FANDIV2);
662 data->fan_div[2] = i & 0x7;
663 if (data->has_fan & (1<<3))
664 data->fan_div[3] = (i & 0x70) >> 4;
665}
666
667static void nct6775_update_fan_div_common(struct nct6775_data *data)
668{
669 if (data->kind == nct6775)
670 nct6775_update_fan_div(data);
671}
672
673static void nct6775_init_fan_div(struct nct6775_data *data)
674{
675 int i;
676
677 nct6775_update_fan_div_common(data);
678 /*
679 * For all fans, start with highest divider value if the divider
680 * register is not initialized. This ensures that we get a
681 * reading from the fan count register, even if it is not optimal.
682 * We'll compute a better divider later on.
683 */
684 for (i = 0; i < 3; i++) {
685 if (!(data->has_fan & (1 << i)))
686 continue;
687 if (data->fan_div[i] == 0) {
688 data->fan_div[i] = 7;
689 nct6775_write_fan_div_common(data, i);
690 }
691 }
692}
693
694static void nct6775_init_fan_common(struct device *dev,
695 struct nct6775_data *data)
696{
697 int i;
698 u8 reg;
699
700 if (data->has_fan_div)
701 nct6775_init_fan_div(data);
702
703 /*
704 * If fan_min is not set (0), set it to 0xff to disable it. This
705 * prevents the unnecessary warning when fanX_min is reported as 0.
706 */
707 for (i = 0; i < 5; i++) {
708 if (data->has_fan_min & (1 << i)) {
709 reg = nct6775_read_value(data, data->REG_FAN_MIN[i]);
710 if (!reg)
711 nct6775_write_value(data, data->REG_FAN_MIN[i],
712 data->has_fan_div ? 0xff
713 : 0xff1f);
714 }
715 }
716}
717
718static void nct6775_select_fan_div(struct device *dev,
719 struct nct6775_data *data, int nr, u16 reg)
720{
721 u8 fan_div = data->fan_div[nr];
722 u16 fan_min;
723
724 if (!data->has_fan_div)
725 return;
726
727 /*
728 * If we failed to measure the fan speed, or the reported value is not
729 * in the optimal range, and the clock divider can be modified,
730 * let's try that for next time.
731 */
732 if (reg == 0x00 && fan_div < 0x07)
733 fan_div++;
734 else if (reg != 0x00 && reg < 0x30 && fan_div > 0)
735 fan_div--;
736
737 if (fan_div != data->fan_div[nr]) {
738 dev_dbg(dev, "Modifying fan%d clock divider from %u to %u\n",
739 nr + 1, div_from_reg(data->fan_div[nr]),
740 div_from_reg(fan_div));
741
742 /* Preserve min limit if possible */
743 if (data->has_fan_min & (1 << nr)) {
744 fan_min = data->fan_min[nr];
745 if (fan_div > data->fan_div[nr]) {
746 if (fan_min != 255 && fan_min > 1)
747 fan_min >>= 1;
748 } else {
749 if (fan_min != 255) {
750 fan_min <<= 1;
751 if (fan_min > 254)
752 fan_min = 254;
753 }
754 }
755 if (fan_min != data->fan_min[nr]) {
756 data->fan_min[nr] = fan_min;
757 nct6775_write_value(data, data->REG_FAN_MIN[nr],
758 fan_min);
759 }
760 }
761 data->fan_div[nr] = fan_div;
762 nct6775_write_fan_div_common(data, nr);
763 }
764}
765
559static struct nct6775_data *nct6775_update_device(struct device *dev) 766static struct nct6775_data *nct6775_update_device(struct device *dev)
560{ 767{
561 struct nct6775_data *data = dev_get_drvdata(dev); 768 struct nct6775_data *data = dev_get_drvdata(dev);
@@ -565,6 +772,9 @@ static struct nct6775_data *nct6775_update_device(struct device *dev)
565 772
566 if (time_after(jiffies, data->last_updated + HZ + HZ/2) 773 if (time_after(jiffies, data->last_updated + HZ + HZ/2)
567 || !data->valid) { 774 || !data->valid) {
775 /* Fan clock dividers */
776 nct6775_update_fan_div_common(data);
777
568 /* Measured voltages and limits */ 778 /* Measured voltages and limits */
569 for (i = 0; i < data->in_num; i++) { 779 for (i = 0; i < data->in_num; i++) {
570 if (!(data->have_in & (1 << i))) 780 if (!(data->have_in & (1 << i)))
@@ -578,6 +788,24 @@ static struct nct6775_data *nct6775_update_device(struct device *dev)
578 data->REG_IN_MINMAX[1][i]); 788 data->REG_IN_MINMAX[1][i]);
579 } 789 }
580 790
791 /* Measured fan speeds and limits */
792 for (i = 0; i < 5; i++) {
793 u16 reg;
794
795 if (!(data->has_fan & (1 << i)))
796 continue;
797
798 reg = nct6775_read_value(data, data->REG_FAN[i]);
799 data->rpm[i] = data->fan_from_reg(reg,
800 data->fan_div[i]);
801
802 if (data->has_fan_min & (1 << i))
803 data->fan_min[i] = nct6775_read_value(data,
804 data->REG_FAN_MIN[i]);
805
806 nct6775_select_fan_div(dev, data, i, reg);
807 }
808
581 /* Measured temperatures and limits */ 809 /* Measured temperatures and limits */
582 for (i = 0; i < NUM_TEMP; i++) { 810 for (i = 0; i < NUM_TEMP; i++) {
583 if (!(data->have_temp & (1 << i))) 811 if (!(data->have_temp & (1 << i)))
@@ -875,6 +1103,166 @@ static const struct attribute_group nct6775_group_in[15] = {
875}; 1103};
876 1104
877static ssize_t 1105static ssize_t
1106show_fan(struct device *dev, struct device_attribute *attr, char *buf)
1107{
1108 struct nct6775_data *data = nct6775_update_device(dev);
1109 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1110 int nr = sattr->index;
1111 return sprintf(buf, "%d\n", data->rpm[nr]);
1112}
1113
1114static ssize_t
1115show_fan_min(struct device *dev, struct device_attribute *attr, char *buf)
1116{
1117 struct nct6775_data *data = nct6775_update_device(dev);
1118 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1119 int nr = sattr->index;
1120 return sprintf(buf, "%d\n",
1121 data->fan_from_reg_min(data->fan_min[nr],
1122 data->fan_div[nr]));
1123}
1124
1125static ssize_t
1126show_fan_div(struct device *dev, struct device_attribute *attr, char *buf)
1127{
1128 struct nct6775_data *data = nct6775_update_device(dev);
1129 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1130 int nr = sattr->index;
1131 return sprintf(buf, "%u\n", div_from_reg(data->fan_div[nr]));
1132}
1133
1134static ssize_t
1135store_fan_min(struct device *dev, struct device_attribute *attr,
1136 const char *buf, size_t count)
1137{
1138 struct nct6775_data *data = dev_get_drvdata(dev);
1139 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1140 int nr = sattr->index;
1141 unsigned long val;
1142 int err;
1143 unsigned int reg;
1144 u8 new_div;
1145
1146 err = kstrtoul(buf, 10, &val);
1147 if (err < 0)
1148 return err;
1149
1150 mutex_lock(&data->update_lock);
1151 if (!data->has_fan_div) {
1152 /* NCT6776F or NCT6779D; we know this is a 13 bit register */
1153 if (!val) {
1154 val = 0xff1f;
1155 } else {
1156 if (val > 1350000U)
1157 val = 135000U;
1158 val = 1350000U / val;
1159 val = (val & 0x1f) | ((val << 3) & 0xff00);
1160 }
1161 data->fan_min[nr] = val;
1162 goto write_min; /* Leave fan divider alone */
1163 }
1164 if (!val) {
1165 /* No min limit, alarm disabled */
1166 data->fan_min[nr] = 255;
1167 new_div = data->fan_div[nr]; /* No change */
1168 dev_info(dev, "fan%u low limit and alarm disabled\n", nr + 1);
1169 goto write_div;
1170 }
1171 reg = 1350000U / val;
1172 if (reg >= 128 * 255) {
1173 /*
1174 * Speed below this value cannot possibly be represented,
1175 * even with the highest divider (128)
1176 */
1177 data->fan_min[nr] = 254;
1178 new_div = 7; /* 128 == (1 << 7) */
1179 dev_warn(dev,
1180 "fan%u low limit %lu below minimum %u, set to minimum\n",
1181 nr + 1, val, data->fan_from_reg_min(254, 7));
1182 } else if (!reg) {
1183 /*
1184 * Speed above this value cannot possibly be represented,
1185 * even with the lowest divider (1)
1186 */
1187 data->fan_min[nr] = 1;
1188 new_div = 0; /* 1 == (1 << 0) */
1189 dev_warn(dev,
1190 "fan%u low limit %lu above maximum %u, set to maximum\n",
1191 nr + 1, val, data->fan_from_reg_min(1, 0));
1192 } else {
1193 /*
1194 * Automatically pick the best divider, i.e. the one such
1195 * that the min limit will correspond to a register value
1196 * in the 96..192 range
1197 */
1198 new_div = 0;
1199 while (reg > 192 && new_div < 7) {
1200 reg >>= 1;
1201 new_div++;
1202 }
1203 data->fan_min[nr] = reg;
1204 }
1205
1206write_div:
1207 /*
1208 * Write both the fan clock divider (if it changed) and the new
1209 * fan min (unconditionally)
1210 */
1211 if (new_div != data->fan_div[nr]) {
1212 dev_dbg(dev, "fan%u clock divider changed from %u to %u\n",
1213 nr + 1, div_from_reg(data->fan_div[nr]),
1214 div_from_reg(new_div));
1215 data->fan_div[nr] = new_div;
1216 nct6775_write_fan_div_common(data, nr);
1217 /* Give the chip time to sample a new speed value */
1218 data->last_updated = jiffies;
1219 }
1220
1221write_min:
1222 nct6775_write_value(data, data->REG_FAN_MIN[nr], data->fan_min[nr]);
1223 mutex_unlock(&data->update_lock);
1224
1225 return count;
1226}
1227
1228static struct sensor_device_attribute sda_fan_input[] = {
1229 SENSOR_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0),
1230 SENSOR_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1),
1231 SENSOR_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2),
1232 SENSOR_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 3),
1233 SENSOR_ATTR(fan5_input, S_IRUGO, show_fan, NULL, 4),
1234};
1235
1236static struct sensor_device_attribute sda_fan_alarm[] = {
1237 SENSOR_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, FAN_ALARM_BASE),
1238 SENSOR_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, FAN_ALARM_BASE + 1),
1239 SENSOR_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, FAN_ALARM_BASE + 2),
1240 SENSOR_ATTR(fan4_alarm, S_IRUGO, show_alarm, NULL, FAN_ALARM_BASE + 3),
1241 SENSOR_ATTR(fan5_alarm, S_IRUGO, show_alarm, NULL, FAN_ALARM_BASE + 4),
1242};
1243
1244static struct sensor_device_attribute sda_fan_min[] = {
1245 SENSOR_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan_min,
1246 store_fan_min, 0),
1247 SENSOR_ATTR(fan2_min, S_IWUSR | S_IRUGO, show_fan_min,
1248 store_fan_min, 1),
1249 SENSOR_ATTR(fan3_min, S_IWUSR | S_IRUGO, show_fan_min,
1250 store_fan_min, 2),
1251 SENSOR_ATTR(fan4_min, S_IWUSR | S_IRUGO, show_fan_min,
1252 store_fan_min, 3),
1253 SENSOR_ATTR(fan5_min, S_IWUSR | S_IRUGO, show_fan_min,
1254 store_fan_min, 4),
1255};
1256
1257static struct sensor_device_attribute sda_fan_div[] = {
1258 SENSOR_ATTR(fan1_div, S_IRUGO, show_fan_div, NULL, 0),
1259 SENSOR_ATTR(fan2_div, S_IRUGO, show_fan_div, NULL, 1),
1260 SENSOR_ATTR(fan3_div, S_IRUGO, show_fan_div, NULL, 2),
1261 SENSOR_ATTR(fan4_div, S_IRUGO, show_fan_div, NULL, 3),
1262 SENSOR_ATTR(fan5_div, S_IRUGO, show_fan_div, NULL, 4),
1263};
1264
1265static ssize_t
878show_temp_label(struct device *dev, struct device_attribute *attr, char *buf) 1266show_temp_label(struct device *dev, struct device_attribute *attr, char *buf)
879{ 1267{
880 struct nct6775_data *data = nct6775_update_device(dev); 1268 struct nct6775_data *data = nct6775_update_device(dev);
@@ -1228,6 +1616,12 @@ static void nct6775_device_remove_files(struct device *dev)
1228 for (i = 0; i < data->in_num; i++) 1616 for (i = 0; i < data->in_num; i++)
1229 sysfs_remove_group(&dev->kobj, &nct6775_group_in[i]); 1617 sysfs_remove_group(&dev->kobj, &nct6775_group_in[i]);
1230 1618
1619 for (i = 0; i < 5; i++) {
1620 device_remove_file(dev, &sda_fan_input[i].dev_attr);
1621 device_remove_file(dev, &sda_fan_alarm[i].dev_attr);
1622 device_remove_file(dev, &sda_fan_div[i].dev_attr);
1623 device_remove_file(dev, &sda_fan_min[i].dev_attr);
1624 }
1231 for (i = 0; i < NUM_TEMP; i++) { 1625 for (i = 0; i < NUM_TEMP; i++) {
1232 if (!(data->have_temp & (1 << i))) 1626 if (!(data->have_temp & (1 << i)))
1233 continue; 1627 continue;
@@ -1294,6 +1688,75 @@ static inline void nct6775_init_device(struct nct6775_data *data)
1294 } 1688 }
1295} 1689}
1296 1690
1691static int
1692nct6775_check_fan_inputs(const struct nct6775_sio_data *sio_data,
1693 struct nct6775_data *data)
1694{
1695 int regval;
1696 bool fan3pin, fan3min, fan4pin, fan4min, fan5pin;
1697 int ret;
1698
1699 ret = superio_enter(sio_data->sioreg);
1700 if (ret)
1701 return ret;
1702
1703 /* fan4 and fan5 share some pins with the GPIO and serial flash */
1704 if (data->kind == nct6775) {
1705 regval = superio_inb(sio_data->sioreg, 0x2c);
1706
1707 fan3pin = regval & (1 << 6);
1708 fan3min = fan3pin;
1709
1710 /* On NCT6775, fan4 shares pins with the fdc interface */
1711 fan4pin = !(superio_inb(sio_data->sioreg, 0x2A) & 0x80);
1712 fan4min = 0;
1713 fan5pin = 0;
1714 } else if (data->kind == nct6776) {
1715 bool gpok = superio_inb(sio_data->sioreg, 0x27) & 0x80;
1716
1717 superio_select(sio_data->sioreg, NCT6775_LD_HWM);
1718 regval = superio_inb(sio_data->sioreg, SIO_REG_ENABLE);
1719
1720 if (regval & 0x80)
1721 fan3pin = gpok;
1722 else
1723 fan3pin = !(superio_inb(sio_data->sioreg, 0x24) & 0x40);
1724
1725 if (regval & 0x40)
1726 fan4pin = gpok;
1727 else
1728 fan4pin = superio_inb(sio_data->sioreg, 0x1C) & 0x01;
1729
1730 if (regval & 0x20)
1731 fan5pin = gpok;
1732 else
1733 fan5pin = superio_inb(sio_data->sioreg, 0x1C) & 0x02;
1734
1735 fan4min = fan4pin;
1736 fan3min = fan3pin;
1737 } else { /* NCT6779D */
1738 regval = superio_inb(sio_data->sioreg, 0x1c);
1739
1740 fan3pin = !(regval & (1 << 5));
1741 fan4pin = !(regval & (1 << 6));
1742 fan5pin = !(regval & (1 << 7));
1743
1744 fan3min = fan3pin;
1745 fan4min = fan4pin;
1746 }
1747
1748 superio_exit(sio_data->sioreg);
1749
1750 data->has_fan = data->has_fan_min = 0x03; /* fan1 and fan2 */
1751 data->has_fan |= fan3pin << 2;
1752 data->has_fan_min |= fan3min << 2;
1753
1754 data->has_fan |= (fan4pin << 3) | (fan5pin << 4);
1755 data->has_fan_min |= (fan4min << 3) | (fan5pin << 4);
1756
1757 return 0;
1758}
1759
1297static int nct6775_probe(struct platform_device *pdev) 1760static int nct6775_probe(struct platform_device *pdev)
1298{ 1761{
1299 struct device *dev = &pdev->dev; 1762 struct device *dev = &pdev->dev;
@@ -1327,10 +1790,14 @@ static int nct6775_probe(struct platform_device *pdev)
1327 switch (data->kind) { 1790 switch (data->kind) {
1328 case nct6775: 1791 case nct6775:
1329 data->in_num = 9; 1792 data->in_num = 9;
1793 data->has_fan_div = true;
1330 data->temp_fixed_num = 3; 1794 data->temp_fixed_num = 3;
1331 1795
1332 data->ALARM_BITS = NCT6775_ALARM_BITS; 1796 data->ALARM_BITS = NCT6775_ALARM_BITS;
1333 1797
1798 data->fan_from_reg = fan_from_reg16;
1799 data->fan_from_reg_min = fan_from_reg8;
1800
1334 data->temp_label = nct6775_temp_label; 1801 data->temp_label = nct6775_temp_label;
1335 data->temp_label_num = ARRAY_SIZE(nct6775_temp_label); 1802 data->temp_label_num = ARRAY_SIZE(nct6775_temp_label);
1336 1803
@@ -1340,6 +1807,8 @@ static int nct6775_probe(struct platform_device *pdev)
1340 data->REG_VIN = NCT6775_REG_IN; 1807 data->REG_VIN = NCT6775_REG_IN;
1341 data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN; 1808 data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN;
1342 data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX; 1809 data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX;
1810 data->REG_FAN = NCT6775_REG_FAN;
1811 data->REG_FAN_MIN = NCT6775_REG_FAN_MIN;
1343 data->REG_TEMP_OFFSET = NCT6775_REG_TEMP_OFFSET; 1812 data->REG_TEMP_OFFSET = NCT6775_REG_TEMP_OFFSET;
1344 data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE; 1813 data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE;
1345 data->REG_ALARM = NCT6775_REG_ALARM; 1814 data->REG_ALARM = NCT6775_REG_ALARM;
@@ -1355,10 +1824,14 @@ static int nct6775_probe(struct platform_device *pdev)
1355 break; 1824 break;
1356 case nct6776: 1825 case nct6776:
1357 data->in_num = 9; 1826 data->in_num = 9;
1827 data->has_fan_div = false;
1358 data->temp_fixed_num = 3; 1828 data->temp_fixed_num = 3;
1359 1829
1360 data->ALARM_BITS = NCT6776_ALARM_BITS; 1830 data->ALARM_BITS = NCT6776_ALARM_BITS;
1361 1831
1832 data->fan_from_reg = fan_from_reg13;
1833 data->fan_from_reg_min = fan_from_reg13;
1834
1362 data->temp_label = nct6776_temp_label; 1835 data->temp_label = nct6776_temp_label;
1363 data->temp_label_num = ARRAY_SIZE(nct6776_temp_label); 1836 data->temp_label_num = ARRAY_SIZE(nct6776_temp_label);
1364 1837
@@ -1368,6 +1841,8 @@ static int nct6775_probe(struct platform_device *pdev)
1368 data->REG_VIN = NCT6775_REG_IN; 1841 data->REG_VIN = NCT6775_REG_IN;
1369 data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN; 1842 data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN;
1370 data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX; 1843 data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX;
1844 data->REG_FAN = NCT6775_REG_FAN;
1845 data->REG_FAN_MIN = NCT6776_REG_FAN_MIN;
1371 data->REG_TEMP_OFFSET = NCT6775_REG_TEMP_OFFSET; 1846 data->REG_TEMP_OFFSET = NCT6775_REG_TEMP_OFFSET;
1372 data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE; 1847 data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE;
1373 data->REG_ALARM = NCT6775_REG_ALARM; 1848 data->REG_ALARM = NCT6775_REG_ALARM;
@@ -1383,10 +1858,14 @@ static int nct6775_probe(struct platform_device *pdev)
1383 break; 1858 break;
1384 case nct6779: 1859 case nct6779:
1385 data->in_num = 15; 1860 data->in_num = 15;
1861 data->has_fan_div = false;
1386 data->temp_fixed_num = 6; 1862 data->temp_fixed_num = 6;
1387 1863
1388 data->ALARM_BITS = NCT6779_ALARM_BITS; 1864 data->ALARM_BITS = NCT6779_ALARM_BITS;
1389 1865
1866 data->fan_from_reg = fan_from_reg13;
1867 data->fan_from_reg_min = fan_from_reg13;
1868
1390 data->temp_label = nct6779_temp_label; 1869 data->temp_label = nct6779_temp_label;
1391 data->temp_label_num = ARRAY_SIZE(nct6779_temp_label); 1870 data->temp_label_num = ARRAY_SIZE(nct6779_temp_label);
1392 1871
@@ -1396,6 +1875,8 @@ static int nct6775_probe(struct platform_device *pdev)
1396 data->REG_VIN = NCT6779_REG_IN; 1875 data->REG_VIN = NCT6779_REG_IN;
1397 data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN; 1876 data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN;
1398 data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX; 1877 data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX;
1878 data->REG_FAN = NCT6779_REG_FAN;
1879 data->REG_FAN_MIN = NCT6776_REG_FAN_MIN;
1399 data->REG_TEMP_OFFSET = NCT6779_REG_TEMP_OFFSET; 1880 data->REG_TEMP_OFFSET = NCT6779_REG_TEMP_OFFSET;
1400 data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE; 1881 data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE;
1401 data->REG_ALARM = NCT6779_REG_ALARM; 1882 data->REG_ALARM = NCT6779_REG_ALARM;
@@ -1575,6 +2056,13 @@ static int nct6775_probe(struct platform_device *pdev)
1575 if (err) 2056 if (err)
1576 return err; 2057 return err;
1577 2058
2059 err = nct6775_check_fan_inputs(sio_data, data);
2060 if (err)
2061 goto exit_remove;
2062
2063 /* Read fan clock dividers immediately */
2064 nct6775_init_fan_common(dev, data);
2065
1578 for (i = 0; i < data->in_num; i++) { 2066 for (i = 0; i < data->in_num; i++) {
1579 if (!(data->have_in & (1 << i))) 2067 if (!(data->have_in & (1 << i)))
1580 continue; 2068 continue;
@@ -1583,6 +2071,32 @@ static int nct6775_probe(struct platform_device *pdev)
1583 goto exit_remove; 2071 goto exit_remove;
1584 } 2072 }
1585 2073
2074 for (i = 0; i < 5; i++) {
2075 if (data->has_fan & (1 << i)) {
2076 err = device_create_file(dev,
2077 &sda_fan_input[i].dev_attr);
2078 if (err)
2079 goto exit_remove;
2080 err = device_create_file(dev,
2081 &sda_fan_alarm[i].dev_attr);
2082 if (err)
2083 goto exit_remove;
2084 if (data->kind != nct6776 &&
2085 data->kind != nct6779) {
2086 err = device_create_file(dev,
2087 &sda_fan_div[i].dev_attr);
2088 if (err)
2089 goto exit_remove;
2090 }
2091 if (data->has_fan_min & (1 << i)) {
2092 err = device_create_file(dev,
2093 &sda_fan_min[i].dev_attr);
2094 if (err)
2095 goto exit_remove;
2096 }
2097 }
2098 }
2099
1586 for (i = 0; i < NUM_TEMP; i++) { 2100 for (i = 0; i < NUM_TEMP; i++) {
1587 if (!(data->have_temp & (1 << i))) 2101 if (!(data->have_temp & (1 << i)))
1588 continue; 2102 continue;