aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon')
-rw-r--r--drivers/hwmon/f71882fg.c353
1 files changed, 291 insertions, 62 deletions
diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index 842592fe5aa9..a833797e96d3 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -45,6 +45,7 @@
45#define SIO_FINTEK_ID 0x1934 /* Manufacturers ID */ 45#define SIO_FINTEK_ID 0x1934 /* Manufacturers ID */
46#define SIO_F71862_ID 0x0601 /* Chipset ID */ 46#define SIO_F71862_ID 0x0601 /* Chipset ID */
47#define SIO_F71882_ID 0x0541 /* Chipset ID */ 47#define SIO_F71882_ID 0x0541 /* Chipset ID */
48#define SIO_F8000_ID 0x0581 /* Chipset ID */
48 49
49#define REGION_LENGTH 8 50#define REGION_LENGTH 8
50#define ADDR_REG_OFFSET 5 51#define ADDR_REG_OFFSET 5
@@ -90,11 +91,12 @@ static unsigned short force_id;
90module_param(force_id, ushort, 0); 91module_param(force_id, ushort, 0);
91MODULE_PARM_DESC(force_id, "Override the detected device ID"); 92MODULE_PARM_DESC(force_id, "Override the detected device ID");
92 93
93enum chips { f71862fg, f71882fg }; 94enum chips { f71862fg, f71882fg, f8000 };
94 95
95static const char *f71882fg_names[] = { 96static const char *f71882fg_names[] = {
96 "f71862fg", 97 "f71862fg",
97 "f71882fg", 98 "f71882fg",
99 "f8000",
98}; 100};
99 101
100static struct platform_device *f71882fg_pdev; 102static struct platform_device *f71882fg_pdev;
@@ -249,6 +251,7 @@ static struct platform_driver f71882fg_driver = {
249 251
250static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); 252static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
251 253
254/* Temp and in attr common to both the f71862fg and f71882fg */
252static struct sensor_device_attribute_2 f718x2fg_in_temp_attr[] = { 255static struct sensor_device_attribute_2 f718x2fg_in_temp_attr[] = {
253 SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0), 256 SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
254 SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1), 257 SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1),
@@ -317,6 +320,7 @@ static struct sensor_device_attribute_2 f718x2fg_in_temp_attr[] = {
317 SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 3), 320 SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 3),
318}; 321};
319 322
323/* Temp and in attr found only on the f71882fg */
320static struct sensor_device_attribute_2 f71882fg_in_temp_attr[] = { 324static struct sensor_device_attribute_2 f71882fg_in_temp_attr[] = {
321 SENSOR_ATTR_2(in1_max, S_IRUGO|S_IWUSR, show_in_max, store_in_max, 325 SENSOR_ATTR_2(in1_max, S_IRUGO|S_IWUSR, show_in_max, store_in_max,
322 0, 1), 326 0, 1),
@@ -325,27 +329,51 @@ static struct sensor_device_attribute_2 f71882fg_in_temp_attr[] = {
325 SENSOR_ATTR_2(in1_alarm, S_IRUGO, show_in_alarm, NULL, 0, 1), 329 SENSOR_ATTR_2(in1_alarm, S_IRUGO, show_in_alarm, NULL, 0, 1),
326}; 330};
327 331
328static struct sensor_device_attribute_2 f718x2fg_fan_attr[] = { 332/* Temp and in attr for the f8000
333 Note on the f8000 temp_ovt (crit) is used as max, and temp_high (max)
334 is used as hysteresis value to clear alarms
335 */
336static struct sensor_device_attribute_2 f8000_in_temp_attr[] = {
337 SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
338 SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1),
339 SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2),
340 SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0),
341 SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_crit,
342 store_temp_crit, 0, 0),
343 SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO|S_IWUSR, show_temp_max,
344 store_temp_max, 0, 0),
345 SENSOR_ATTR_2(temp1_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 4),
346 SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 1),
347 SENSOR_ATTR_2(temp2_max, S_IRUGO|S_IWUSR, show_temp_crit,
348 store_temp_crit, 0, 1),
349 SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO|S_IWUSR, show_temp_max,
350 store_temp_max, 0, 1),
351 SENSOR_ATTR_2(temp2_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 5),
352 SENSOR_ATTR_2(temp2_type, S_IRUGO, show_temp_type, NULL, 0, 1),
353 SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 2),
354 SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_crit,
355 store_temp_crit, 0, 2),
356 SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO|S_IWUSR, show_temp_max,
357 store_temp_max, 0, 2),
358 SENSOR_ATTR_2(temp3_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 6),
359};
360
361/* Fan / PWM attr common to all models */
362static struct sensor_device_attribute_2 fxxxx_fan_attr[] = {
329 SENSOR_ATTR_2(fan1_input, S_IRUGO, show_fan, NULL, 0, 0), 363 SENSOR_ATTR_2(fan1_input, S_IRUGO, show_fan, NULL, 0, 0),
330 SENSOR_ATTR_2(fan1_full_speed, S_IRUGO|S_IWUSR, 364 SENSOR_ATTR_2(fan1_full_speed, S_IRUGO|S_IWUSR,
331 show_fan_full_speed, 365 show_fan_full_speed,
332 store_fan_full_speed, 0, 0), 366 store_fan_full_speed, 0, 0),
333 SENSOR_ATTR_2(fan1_beep, S_IRUGO|S_IWUSR, show_fan_beep,
334 store_fan_beep, 0, 0),
335 SENSOR_ATTR_2(fan1_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 0), 367 SENSOR_ATTR_2(fan1_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 0),
336 SENSOR_ATTR_2(fan2_input, S_IRUGO, show_fan, NULL, 0, 1), 368 SENSOR_ATTR_2(fan2_input, S_IRUGO, show_fan, NULL, 0, 1),
337 SENSOR_ATTR_2(fan2_full_speed, S_IRUGO|S_IWUSR, 369 SENSOR_ATTR_2(fan2_full_speed, S_IRUGO|S_IWUSR,
338 show_fan_full_speed, 370 show_fan_full_speed,
339 store_fan_full_speed, 0, 1), 371 store_fan_full_speed, 0, 1),
340 SENSOR_ATTR_2(fan2_beep, S_IRUGO|S_IWUSR, show_fan_beep,
341 store_fan_beep, 0, 1),
342 SENSOR_ATTR_2(fan2_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 1), 372 SENSOR_ATTR_2(fan2_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 1),
343 SENSOR_ATTR_2(fan3_input, S_IRUGO, show_fan, NULL, 0, 2), 373 SENSOR_ATTR_2(fan3_input, S_IRUGO, show_fan, NULL, 0, 2),
344 SENSOR_ATTR_2(fan3_full_speed, S_IRUGO|S_IWUSR, 374 SENSOR_ATTR_2(fan3_full_speed, S_IRUGO|S_IWUSR,
345 show_fan_full_speed, 375 show_fan_full_speed,
346 store_fan_full_speed, 0, 2), 376 store_fan_full_speed, 0, 2),
347 SENSOR_ATTR_2(fan3_beep, S_IRUGO|S_IWUSR, show_fan_beep,
348 store_fan_beep, 0, 2),
349 SENSOR_ATTR_2(fan3_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 2), 377 SENSOR_ATTR_2(fan3_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 2),
350 378
351 SENSOR_ATTR_2(pwm1, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 0), 379 SENSOR_ATTR_2(pwm1, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 0),
@@ -366,9 +394,6 @@ static struct sensor_device_attribute_2 f718x2fg_fan_attr[] = {
366 show_pwm_auto_point_channel, 394 show_pwm_auto_point_channel,
367 store_pwm_auto_point_channel, 0, 1), 395 store_pwm_auto_point_channel, 0, 1),
368 396
369 SENSOR_ATTR_2(pwm3, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 2),
370 SENSOR_ATTR_2(pwm3_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
371 store_pwm_enable, 0, 2),
372 SENSOR_ATTR_2(pwm3_interpolate, S_IRUGO|S_IWUSR, 397 SENSOR_ATTR_2(pwm3_interpolate, S_IRUGO|S_IWUSR,
373 show_pwm_interpolate, store_pwm_interpolate, 0, 2), 398 show_pwm_interpolate, store_pwm_interpolate, 0, 2),
374 SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR, 399 SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR,
@@ -376,7 +401,16 @@ static struct sensor_device_attribute_2 f718x2fg_fan_attr[] = {
376 store_pwm_auto_point_channel, 0, 2), 401 store_pwm_auto_point_channel, 0, 2),
377}; 402};
378 403
404/* Fan / PWM attr for the f71862fg, less pwms and less zones per pwm than the
405 f71882fg */
379static struct sensor_device_attribute_2 f71862fg_fan_attr[] = { 406static struct sensor_device_attribute_2 f71862fg_fan_attr[] = {
407 SENSOR_ATTR_2(fan1_beep, S_IRUGO|S_IWUSR, show_fan_beep,
408 store_fan_beep, 0, 0),
409 SENSOR_ATTR_2(fan2_beep, S_IRUGO|S_IWUSR, show_fan_beep,
410 store_fan_beep, 0, 1),
411 SENSOR_ATTR_2(fan3_beep, S_IRUGO|S_IWUSR, show_fan_beep,
412 store_fan_beep, 0, 2),
413
380 SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO|S_IWUSR, 414 SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO|S_IWUSR,
381 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 415 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
382 1, 0), 416 1, 0),
@@ -416,7 +450,14 @@ static struct sensor_device_attribute_2 f71862fg_fan_attr[] = {
416 show_pwm_auto_point_temp_hyst, NULL, 3, 1), 450 show_pwm_auto_point_temp_hyst, NULL, 3, 1),
417}; 451};
418 452
453/* Fan / PWM attr for the f71882fg */
419static struct sensor_device_attribute_2 f71882fg_fan_attr[] = { 454static struct sensor_device_attribute_2 f71882fg_fan_attr[] = {
455 SENSOR_ATTR_2(fan1_beep, S_IRUGO|S_IWUSR, show_fan_beep,
456 store_fan_beep, 0, 0),
457 SENSOR_ATTR_2(fan2_beep, S_IRUGO|S_IWUSR, show_fan_beep,
458 store_fan_beep, 0, 1),
459 SENSOR_ATTR_2(fan3_beep, S_IRUGO|S_IWUSR, show_fan_beep,
460 store_fan_beep, 0, 2),
420 SENSOR_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 0, 3), 461 SENSOR_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 0, 3),
421 SENSOR_ATTR_2(fan4_full_speed, S_IRUGO|S_IWUSR, 462 SENSOR_ATTR_2(fan4_full_speed, S_IRUGO|S_IWUSR,
422 show_fan_full_speed, 463 show_fan_full_speed,
@@ -501,6 +542,9 @@ static struct sensor_device_attribute_2 f71882fg_fan_attr[] = {
501 SENSOR_ATTR_2(pwm2_auto_point4_temp_hyst, S_IRUGO, 542 SENSOR_ATTR_2(pwm2_auto_point4_temp_hyst, S_IRUGO,
502 show_pwm_auto_point_temp_hyst, NULL, 3, 1), 543 show_pwm_auto_point_temp_hyst, NULL, 3, 1),
503 544
545 SENSOR_ATTR_2(pwm3, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 2),
546 SENSOR_ATTR_2(pwm3_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
547 store_pwm_enable, 0, 2),
504 SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO|S_IWUSR, 548 SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO|S_IWUSR,
505 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 549 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
506 0, 2), 550 0, 2),
@@ -586,6 +630,128 @@ static struct sensor_device_attribute_2 f71882fg_fan_attr[] = {
586 show_pwm_auto_point_temp_hyst, NULL, 3, 3), 630 show_pwm_auto_point_temp_hyst, NULL, 3, 3),
587}; 631};
588 632
633/* Fan / PWM attr for the f8000, zones mapped to temp instead of to pwm!
634 Also the register block at offset A0 maps to TEMP1 (so our temp2, as the
635 F8000 starts counting temps at 0), B0 maps the TEMP2 and C0 maps to TEMP0 */
636static struct sensor_device_attribute_2 f8000_fan_attr[] = {
637 SENSOR_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 0, 3),
638
639 SENSOR_ATTR_2(pwm3, S_IRUGO, show_pwm, NULL, 0, 2),
640
641 SENSOR_ATTR_2(temp1_auto_point1_pwm, S_IRUGO|S_IWUSR,
642 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
643 0, 2),
644 SENSOR_ATTR_2(temp1_auto_point2_pwm, S_IRUGO|S_IWUSR,
645 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
646 1, 2),
647 SENSOR_ATTR_2(temp1_auto_point3_pwm, S_IRUGO|S_IWUSR,
648 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
649 2, 2),
650 SENSOR_ATTR_2(temp1_auto_point4_pwm, S_IRUGO|S_IWUSR,
651 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
652 3, 2),
653 SENSOR_ATTR_2(temp1_auto_point5_pwm, S_IRUGO|S_IWUSR,
654 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
655 4, 2),
656 SENSOR_ATTR_2(temp1_auto_point1_temp, S_IRUGO|S_IWUSR,
657 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
658 0, 2),
659 SENSOR_ATTR_2(temp1_auto_point2_temp, S_IRUGO|S_IWUSR,
660 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
661 1, 2),
662 SENSOR_ATTR_2(temp1_auto_point3_temp, S_IRUGO|S_IWUSR,
663 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
664 2, 2),
665 SENSOR_ATTR_2(temp1_auto_point4_temp, S_IRUGO|S_IWUSR,
666 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
667 3, 2),
668 SENSOR_ATTR_2(temp1_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
669 show_pwm_auto_point_temp_hyst,
670 store_pwm_auto_point_temp_hyst,
671 0, 2),
672 SENSOR_ATTR_2(temp1_auto_point2_temp_hyst, S_IRUGO,
673 show_pwm_auto_point_temp_hyst, NULL, 1, 2),
674 SENSOR_ATTR_2(temp1_auto_point3_temp_hyst, S_IRUGO,
675 show_pwm_auto_point_temp_hyst, NULL, 2, 2),
676 SENSOR_ATTR_2(temp1_auto_point4_temp_hyst, S_IRUGO,
677 show_pwm_auto_point_temp_hyst, NULL, 3, 2),
678
679 SENSOR_ATTR_2(temp2_auto_point1_pwm, S_IRUGO|S_IWUSR,
680 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
681 0, 0),
682 SENSOR_ATTR_2(temp2_auto_point2_pwm, S_IRUGO|S_IWUSR,
683 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
684 1, 0),
685 SENSOR_ATTR_2(temp2_auto_point3_pwm, S_IRUGO|S_IWUSR,
686 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
687 2, 0),
688 SENSOR_ATTR_2(temp2_auto_point4_pwm, S_IRUGO|S_IWUSR,
689 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
690 3, 0),
691 SENSOR_ATTR_2(temp2_auto_point5_pwm, S_IRUGO|S_IWUSR,
692 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
693 4, 0),
694 SENSOR_ATTR_2(temp2_auto_point1_temp, S_IRUGO|S_IWUSR,
695 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
696 0, 0),
697 SENSOR_ATTR_2(temp2_auto_point2_temp, S_IRUGO|S_IWUSR,
698 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
699 1, 0),
700 SENSOR_ATTR_2(temp2_auto_point3_temp, S_IRUGO|S_IWUSR,
701 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
702 2, 0),
703 SENSOR_ATTR_2(temp2_auto_point4_temp, S_IRUGO|S_IWUSR,
704 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
705 3, 0),
706 SENSOR_ATTR_2(temp2_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
707 show_pwm_auto_point_temp_hyst,
708 store_pwm_auto_point_temp_hyst,
709 0, 0),
710 SENSOR_ATTR_2(temp2_auto_point2_temp_hyst, S_IRUGO,
711 show_pwm_auto_point_temp_hyst, NULL, 1, 0),
712 SENSOR_ATTR_2(temp2_auto_point3_temp_hyst, S_IRUGO,
713 show_pwm_auto_point_temp_hyst, NULL, 2, 0),
714 SENSOR_ATTR_2(temp2_auto_point4_temp_hyst, S_IRUGO,
715 show_pwm_auto_point_temp_hyst, NULL, 3, 0),
716
717 SENSOR_ATTR_2(temp3_auto_point1_pwm, S_IRUGO|S_IWUSR,
718 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
719 0, 1),
720 SENSOR_ATTR_2(temp3_auto_point2_pwm, S_IRUGO|S_IWUSR,
721 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
722 1, 1),
723 SENSOR_ATTR_2(temp3_auto_point3_pwm, S_IRUGO|S_IWUSR,
724 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
725 2, 1),
726 SENSOR_ATTR_2(temp3_auto_point4_pwm, S_IRUGO|S_IWUSR,
727 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
728 3, 1),
729 SENSOR_ATTR_2(temp3_auto_point5_pwm, S_IRUGO|S_IWUSR,
730 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
731 4, 1),
732 SENSOR_ATTR_2(temp3_auto_point1_temp, S_IRUGO|S_IWUSR,
733 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
734 0, 1),
735 SENSOR_ATTR_2(temp3_auto_point2_temp, S_IRUGO|S_IWUSR,
736 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
737 1, 1),
738 SENSOR_ATTR_2(temp3_auto_point3_temp, S_IRUGO|S_IWUSR,
739 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
740 2, 1),
741 SENSOR_ATTR_2(temp3_auto_point4_temp, S_IRUGO|S_IWUSR,
742 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
743 3, 1),
744 SENSOR_ATTR_2(temp3_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
745 show_pwm_auto_point_temp_hyst,
746 store_pwm_auto_point_temp_hyst,
747 0, 1),
748 SENSOR_ATTR_2(temp3_auto_point2_temp_hyst, S_IRUGO,
749 show_pwm_auto_point_temp_hyst, NULL, 1, 1),
750 SENSOR_ATTR_2(temp3_auto_point3_temp_hyst, S_IRUGO,
751 show_pwm_auto_point_temp_hyst, NULL, 2, 1),
752 SENSOR_ATTR_2(temp3_auto_point4_temp_hyst, S_IRUGO,
753 show_pwm_auto_point_temp_hyst, NULL, 3, 1),
754};
589 755
590/* Super I/O functions */ 756/* Super I/O functions */
591static inline int superio_inb(int base, int reg) 757static inline int superio_inb(int base, int reg)
@@ -671,8 +837,10 @@ static void f71882fg_write16(struct f71882fg_data *data, u8 reg, u16 val)
671static struct f71882fg_data *f71882fg_update_device(struct device *dev) 837static struct f71882fg_data *f71882fg_update_device(struct device *dev)
672{ 838{
673 struct f71882fg_data *data = dev_get_drvdata(dev); 839 struct f71882fg_data *data = dev_get_drvdata(dev);
674 int nr, reg, reg2; 840 int nr, reg = 0, reg2;
675 int nr_fans = (data->type == f71862fg) ? 3 : 4; 841 int nr_fans = (data->type == f71882fg) ? 4 : 3;
842 int nr_ins = (data->type == f8000) ? 3 : 9;
843 int temp_start = (data->type == f8000) ? 0 : 1;
676 844
677 mutex_lock(&data->update_lock); 845 mutex_lock(&data->update_lock);
678 846
@@ -687,35 +855,36 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev)
687 } 855 }
688 856
689 /* Get High & boundary temps*/ 857 /* Get High & boundary temps*/
690 for (nr = 1; nr < 4; nr++) { 858 for (nr = temp_start; nr < 3 + temp_start; nr++) {
691 data->temp_ovt[nr] = f71882fg_read8(data, 859 data->temp_ovt[nr] = f71882fg_read8(data,
692 F71882FG_REG_TEMP_OVT(nr)); 860 F71882FG_REG_TEMP_OVT(nr));
693 data->temp_high[nr] = f71882fg_read8(data, 861 data->temp_high[nr] = f71882fg_read8(data,
694 F71882FG_REG_TEMP_HIGH(nr)); 862 F71882FG_REG_TEMP_HIGH(nr));
695 } 863 }
696 864
697 /* hyst */ 865 if (data->type != f8000) {
698 data->temp_hyst[0] = 866 data->fan_beep = f71882fg_read8(data,
699 f71882fg_read8(data, F71882FG_REG_TEMP_HYST(0)); 867 F71882FG_REG_FAN_BEEP);
700 data->temp_hyst[1] = 868 data->temp_beep = f71882fg_read8(data,
701 f71882fg_read8(data, F71882FG_REG_TEMP_HYST(1)); 869 F71882FG_REG_TEMP_BEEP);
702 870 data->temp_hyst[0] = f71882fg_read8(data,
703 /* Have to hardcode type, because temp1 is special */ 871 F71882FG_REG_TEMP_HYST(0));
704 reg = f71882fg_read8(data, F71882FG_REG_TEMP_TYPE); 872 data->temp_hyst[1] = f71882fg_read8(data,
873 F71882FG_REG_TEMP_HYST(1));
874 /* Have to hardcode type, because temp1 is special */
875 reg = f71882fg_read8(data, F71882FG_REG_TEMP_TYPE);
876 data->temp_type[2] = (reg & 0x04) ? 2 : 4;
877 data->temp_type[3] = (reg & 0x08) ? 2 : 4;
878 }
705 reg2 = f71882fg_read8(data, F71882FG_REG_PECI); 879 reg2 = f71882fg_read8(data, F71882FG_REG_PECI);
706 if ((reg2 & 0x03) == 0x01) 880 if ((reg2 & 0x03) == 0x01)
707 data->temp_type[1] = 6 /* PECI */; 881 data->temp_type[1] = 6 /* PECI */;
708 else if ((reg2 & 0x03) == 0x02) 882 else if ((reg2 & 0x03) == 0x02)
709 data->temp_type[1] = 5 /* AMDSI */; 883 data->temp_type[1] = 5 /* AMDSI */;
710 else 884 else if (data->type != f8000)
711 data->temp_type[1] = (reg & 0x02) ? 2 : 4; 885 data->temp_type[1] = (reg & 0x02) ? 2 : 4;
712 886 else
713 data->temp_type[2] = (reg & 0x04) ? 2 : 4; 887 data->temp_type[1] = 2; /* F8000 only supports BJT */
714 data->temp_type[3] = (reg & 0x08) ? 2 : 4;
715
716 data->temp_beep = f71882fg_read8(data, F71882FG_REG_TEMP_BEEP);
717
718 data->fan_beep = f71882fg_read8(data, F71882FG_REG_FAN_BEEP);
719 888
720 data->pwm_enable = f71882fg_read8(data, 889 data->pwm_enable = f71882fg_read8(data,
721 F71882FG_REG_PWM_ENABLE); 890 F71882FG_REG_PWM_ENABLE);
@@ -729,7 +898,7 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev)
729 f71882fg_read8(data, 898 f71882fg_read8(data,
730 F71882FG_REG_POINT_MAPPING(nr)); 899 F71882FG_REG_POINT_MAPPING(nr));
731 900
732 if (data->type == f71882fg) { 901 if (data->type != f71862fg) {
733 int point; 902 int point;
734 for (point = 0; point < 5; point++) { 903 for (point = 0; point < 5; point++) {
735 data->pwm_auto_point_pwm[nr][point] = 904 data->pwm_auto_point_pwm[nr][point] =
@@ -771,7 +940,7 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev)
771 F71882FG_REG_TEMP_STATUS); 940 F71882FG_REG_TEMP_STATUS);
772 data->temp_diode_open = f71882fg_read8(data, 941 data->temp_diode_open = f71882fg_read8(data,
773 F71882FG_REG_TEMP_DIODE_OPEN); 942 F71882FG_REG_TEMP_DIODE_OPEN);
774 for (nr = 1; nr < 4; nr++) 943 for (nr = temp_start; nr < 3 + temp_start; nr++)
775 data->temp[nr] = f71882fg_read8(data, 944 data->temp[nr] = f71882fg_read8(data,
776 F71882FG_REG_TEMP(nr)); 945 F71882FG_REG_TEMP(nr));
777 946
@@ -789,10 +958,14 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev)
789 f71882fg_read8(data, F71882FG_REG_PWM(nr)); 958 f71882fg_read8(data, F71882FG_REG_PWM(nr));
790 } 959 }
791 960
961 /* The f8000 can monitor 1 more fan, but has no pwm for it */
962 if (data->type == f8000)
963 data->fan[3] = f71882fg_read16(data,
964 F71882FG_REG_FAN(3));
792 if (data->type == f71882fg) 965 if (data->type == f71882fg)
793 data->in_status = f71882fg_read8(data, 966 data->in_status = f71882fg_read8(data,
794 F71882FG_REG_IN_STATUS); 967 F71882FG_REG_IN_STATUS);
795 for (nr = 0; nr < 9; nr++) 968 for (nr = 0; nr < nr_ins; nr++)
796 data->in[nr] = f71882fg_read8(data, 969 data->in[nr] = f71882fg_read8(data,
797 F71882FG_REG_IN(nr)); 970 F71882FG_REG_IN(nr));
798 971
@@ -1186,6 +1359,11 @@ static ssize_t store_pwm(struct device *dev,
1186 1359
1187 mutex_lock(&data->update_lock); 1360 mutex_lock(&data->update_lock);
1188 data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE); 1361 data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);
1362 if ((data->type == f8000 && ((data->pwm_enable >> 2 * nr) & 3) != 2) ||
1363 (data->type != f8000 && !((data->pwm_enable >> 2 * nr) & 2))) {
1364 count = -EROFS;
1365 goto leave;
1366 }
1189 if (data->pwm_enable & (1 << (2 * nr))) { 1367 if (data->pwm_enable & (1 << (2 * nr))) {
1190 /* PWM mode */ 1368 /* PWM mode */
1191 f71882fg_write8(data, F71882FG_REG_PWM(nr), val); 1369 f71882fg_write8(data, F71882FG_REG_PWM(nr), val);
@@ -1200,6 +1378,7 @@ static ssize_t store_pwm(struct device *dev,
1200 data->fan_target[nr] = target; 1378 data->fan_target[nr] = target;
1201 data->fan_full_speed[nr] = full_speed; 1379 data->fan_full_speed[nr] = full_speed;
1202 } 1380 }
1381leave:
1203 mutex_unlock(&data->update_lock); 1382 mutex_unlock(&data->update_lock);
1204 1383
1205 return count; 1384 return count;
@@ -1208,14 +1387,25 @@ static ssize_t store_pwm(struct device *dev,
1208static ssize_t show_pwm_enable(struct device *dev, 1387static ssize_t show_pwm_enable(struct device *dev,
1209 struct device_attribute *devattr, char *buf) 1388 struct device_attribute *devattr, char *buf)
1210{ 1389{
1211 int result; 1390 int result = 0;
1212 struct f71882fg_data *data = f71882fg_update_device(dev); 1391 struct f71882fg_data *data = f71882fg_update_device(dev);
1213 int nr = to_sensor_dev_attr_2(devattr)->index; 1392 int nr = to_sensor_dev_attr_2(devattr)->index;
1214 1393
1215 if (data->pwm_enable & (2 << (2 * nr))) 1394 switch ((data->pwm_enable >> 2 * nr) & 3) {
1216 result = 1; 1395 case 0:
1217 else 1396 case 1:
1218 result = 2; 1397 result = 2; /* Normal auto mode */
1398 break;
1399 case 2:
1400 result = 1; /* Manual mode */
1401 break;
1402 case 3:
1403 if (data->type == f8000)
1404 result = 3; /* Thermostat mode */
1405 else
1406 result = 1; /* Manual mode */
1407 break;
1408 }
1219 1409
1220 return sprintf(buf, "%d\n", result); 1410 return sprintf(buf, "%d\n", result);
1221} 1411}
@@ -1226,20 +1416,37 @@ static ssize_t store_pwm_enable(struct device *dev, struct device_attribute
1226 struct f71882fg_data *data = dev_get_drvdata(dev); 1416 struct f71882fg_data *data = dev_get_drvdata(dev);
1227 int nr = to_sensor_dev_attr_2(devattr)->index; 1417 int nr = to_sensor_dev_attr_2(devattr)->index;
1228 long val = simple_strtol(buf, NULL, 10); 1418 long val = simple_strtol(buf, NULL, 10);
1229 if (val < 1 || val > 2)
1230 return -EINVAL;
1231 1419
1232 mutex_lock(&data->update_lock); 1420 mutex_lock(&data->update_lock);
1233 data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE); 1421 data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);
1234 switch (val) { 1422 /* Special case for F8000 auto PWM mode / Thermostat mode */
1235 case 1: 1423 if (data->type == f8000 && ((data->pwm_enable >> 2 * nr) & 1)) {
1236 data->pwm_enable |= 2 << (2 * nr); 1424 switch (val) {
1237 break; /* Manual */ 1425 case 2:
1238 case 2: 1426 data->pwm_enable &= ~(2 << (2 * nr));
1239 data->pwm_enable &= ~(2 << (2 * nr)); 1427 break; /* Normal auto mode */
1240 break; /* Temperature ctrl */ 1428 case 3:
1429 data->pwm_enable |= 2 << (2 * nr);
1430 break; /* Thermostat mode */
1431 default:
1432 count = -EINVAL;
1433 goto leave;
1434 }
1435 } else {
1436 switch (val) {
1437 case 1:
1438 data->pwm_enable |= 2 << (2 * nr);
1439 break; /* Manual */
1440 case 2:
1441 data->pwm_enable &= ~(2 << (2 * nr));
1442 break; /* Normal auto mode */
1443 default:
1444 count = -EINVAL;
1445 goto leave;
1446 }
1241 } 1447 }
1242 f71882fg_write8(data, F71882FG_REG_PWM_ENABLE, data->pwm_enable); 1448 f71882fg_write8(data, F71882FG_REG_PWM_ENABLE, data->pwm_enable);
1449leave:
1243 mutex_unlock(&data->update_lock); 1450 mutex_unlock(&data->update_lock);
1244 1451
1245 return count; 1452 return count;
@@ -1521,34 +1728,51 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
1521 goto exit_unregister_sysfs; 1728 goto exit_unregister_sysfs;
1522 1729
1523 if (start_reg & 0x01) { 1730 if (start_reg & 0x01) {
1524 err = f71882fg_create_sysfs_files(pdev, f718x2fg_in_temp_attr, 1731 switch (data->type) {
1525 ARRAY_SIZE(f718x2fg_in_temp_attr)); 1732 case f71882fg:
1526 if (err)
1527 goto exit_unregister_sysfs;
1528
1529 if (data->type == f71882fg) {
1530 err = f71882fg_create_sysfs_files(pdev, 1733 err = f71882fg_create_sysfs_files(pdev,
1531 f71882fg_in_temp_attr, 1734 f71882fg_in_temp_attr,
1532 ARRAY_SIZE(f71882fg_in_temp_attr)); 1735 ARRAY_SIZE(f71882fg_in_temp_attr));
1533 if (err) 1736 if (err)
1534 goto exit_unregister_sysfs; 1737 goto exit_unregister_sysfs;
1738 /* fall through! */
1739 case f71862fg:
1740 err = f71882fg_create_sysfs_files(pdev,
1741 f718x2fg_in_temp_attr,
1742 ARRAY_SIZE(f718x2fg_in_temp_attr));
1743 break;
1744 case f8000:
1745 err = f71882fg_create_sysfs_files(pdev,
1746 f8000_in_temp_attr,
1747 ARRAY_SIZE(f8000_in_temp_attr));
1748 break;
1535 } 1749 }
1750 if (err)
1751 goto exit_unregister_sysfs;
1536 } 1752 }
1537 1753
1538 if (start_reg & 0x02) { 1754 if (start_reg & 0x02) {
1539 err = f71882fg_create_sysfs_files(pdev, f718x2fg_fan_attr, 1755 err = f71882fg_create_sysfs_files(pdev, fxxxx_fan_attr,
1540 ARRAY_SIZE(f718x2fg_fan_attr)); 1756 ARRAY_SIZE(fxxxx_fan_attr));
1541 if (err) 1757 if (err)
1542 goto exit_unregister_sysfs; 1758 goto exit_unregister_sysfs;
1543 1759
1544 if (data->type == f71862fg) { 1760 switch (data->type) {
1761 case f71862fg:
1545 err = f71882fg_create_sysfs_files(pdev, 1762 err = f71882fg_create_sysfs_files(pdev,
1546 f71862fg_fan_attr, 1763 f71862fg_fan_attr,
1547 ARRAY_SIZE(f71862fg_fan_attr)); 1764 ARRAY_SIZE(f71862fg_fan_attr));
1548 } else { 1765 break;
1766 case f71882fg:
1549 err = f71882fg_create_sysfs_files(pdev, 1767 err = f71882fg_create_sysfs_files(pdev,
1550 f71882fg_fan_attr, 1768 f71882fg_fan_attr,
1551 ARRAY_SIZE(f71882fg_fan_attr)); 1769 ARRAY_SIZE(f71882fg_fan_attr));
1770 break;
1771 case f8000:
1772 err = f71882fg_create_sysfs_files(pdev,
1773 f8000_fan_attr,
1774 ARRAY_SIZE(f8000_fan_attr));
1775 break;
1552 } 1776 }
1553 if (err) 1777 if (err)
1554 goto exit_unregister_sysfs; 1778 goto exit_unregister_sysfs;
@@ -1580,6 +1804,8 @@ static int f71882fg_remove(struct platform_device *pdev)
1580 if (data->hwmon_dev) 1804 if (data->hwmon_dev)
1581 hwmon_device_unregister(data->hwmon_dev); 1805 hwmon_device_unregister(data->hwmon_dev);
1582 1806
1807 /* Note we are not looping over all attr arrays we have as the ones
1808 below are supersets of the ones skipped. */
1583 device_remove_file(&pdev->dev, &dev_attr_name); 1809 device_remove_file(&pdev->dev, &dev_attr_name);
1584 1810
1585 for (i = 0; i < ARRAY_SIZE(f718x2fg_in_temp_attr); i++) 1811 for (i = 0; i < ARRAY_SIZE(f718x2fg_in_temp_attr); i++)
@@ -1590,15 +1816,15 @@ static int f71882fg_remove(struct platform_device *pdev)
1590 device_remove_file(&pdev->dev, 1816 device_remove_file(&pdev->dev,
1591 &f71882fg_in_temp_attr[i].dev_attr); 1817 &f71882fg_in_temp_attr[i].dev_attr);
1592 1818
1593 for (i = 0; i < ARRAY_SIZE(f718x2fg_fan_attr); i++) 1819 for (i = 0; i < ARRAY_SIZE(fxxxx_fan_attr); i++)
1594 device_remove_file(&pdev->dev, &f718x2fg_fan_attr[i].dev_attr); 1820 device_remove_file(&pdev->dev, &fxxxx_fan_attr[i].dev_attr);
1595
1596 for (i = 0; i < ARRAY_SIZE(f71862fg_fan_attr); i++)
1597 device_remove_file(&pdev->dev, &f71862fg_fan_attr[i].dev_attr);
1598 1821
1599 for (i = 0; i < ARRAY_SIZE(f71882fg_fan_attr); i++) 1822 for (i = 0; i < ARRAY_SIZE(f71882fg_fan_attr); i++)
1600 device_remove_file(&pdev->dev, &f71882fg_fan_attr[i].dev_attr); 1823 device_remove_file(&pdev->dev, &f71882fg_fan_attr[i].dev_attr);
1601 1824
1825 for (i = 0; i < ARRAY_SIZE(f8000_fan_attr); i++)
1826 device_remove_file(&pdev->dev, &f8000_fan_attr[i].dev_attr);
1827
1602 kfree(data); 1828 kfree(data);
1603 1829
1604 return 0; 1830 return 0;
@@ -1626,6 +1852,9 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
1626 case SIO_F71882_ID: 1852 case SIO_F71882_ID:
1627 sio_data->type = f71882fg; 1853 sio_data->type = f71882fg;
1628 break; 1854 break;
1855 case SIO_F8000_ID:
1856 sio_data->type = f8000;
1857 break;
1629 default: 1858 default:
1630 printk(KERN_INFO DRVNAME ": Unsupported Fintek device\n"); 1859 printk(KERN_INFO DRVNAME ": Unsupported Fintek device\n");
1631 goto exit; 1860 goto exit;