aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/f71882fg.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon/f71882fg.c')
-rw-r--r--drivers/hwmon/f71882fg.c350
1 files changed, 235 insertions, 115 deletions
diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index 4146105f1a57..a95fa4256caa 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -48,6 +48,7 @@
48#define SIO_F71858_ID 0x0507 /* Chipset ID */ 48#define SIO_F71858_ID 0x0507 /* Chipset ID */
49#define SIO_F71862_ID 0x0601 /* Chipset ID */ 49#define SIO_F71862_ID 0x0601 /* Chipset ID */
50#define SIO_F71882_ID 0x0541 /* Chipset ID */ 50#define SIO_F71882_ID 0x0541 /* Chipset ID */
51#define SIO_F71889_ID 0x0723 /* Chipset ID */
51#define SIO_F8000_ID 0x0581 /* Chipset ID */ 52#define SIO_F8000_ID 0x0581 /* Chipset ID */
52 53
53#define REGION_LENGTH 8 54#define REGION_LENGTH 8
@@ -95,12 +96,13 @@ static unsigned short force_id;
95module_param(force_id, ushort, 0); 96module_param(force_id, ushort, 0);
96MODULE_PARM_DESC(force_id, "Override the detected device ID"); 97MODULE_PARM_DESC(force_id, "Override the detected device ID");
97 98
98enum chips { f71858fg, f71862fg, f71882fg, f8000 }; 99enum chips { f71858fg, f71862fg, f71882fg, f71889fg, f8000 };
99 100
100static const char *f71882fg_names[] = { 101static const char *f71882fg_names[] = {
101 "f71858fg", 102 "f71858fg",
102 "f71862fg", 103 "f71862fg",
103 "f71882fg", 104 "f71882fg",
105 "f71889fg",
104 "f8000", 106 "f8000",
105}; 107};
106 108
@@ -155,7 +157,7 @@ struct f71882fg_data {
155 u8 pwm_auto_point_hyst[2]; 157 u8 pwm_auto_point_hyst[2];
156 u8 pwm_auto_point_mapping[4]; 158 u8 pwm_auto_point_mapping[4];
157 u8 pwm_auto_point_pwm[4][5]; 159 u8 pwm_auto_point_pwm[4][5];
158 u8 pwm_auto_point_temp[4][4]; 160 s8 pwm_auto_point_temp[4][4];
159}; 161};
160 162
161/* Sysfs in */ 163/* Sysfs in */
@@ -258,7 +260,9 @@ static struct platform_driver f71882fg_driver = {
258 260
259static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); 261static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
260 262
261/* Temp and in attr for the f71858fg */ 263/* Temp and in attr for the f71858fg, the f71858fg is special as it
264 has its temperature indexes start at 0 (the others start at 1) and
265 it only has 3 voltage inputs */
262static struct sensor_device_attribute_2 f71858fg_in_temp_attr[] = { 266static struct sensor_device_attribute_2 f71858fg_in_temp_attr[] = {
263 SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0), 267 SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
264 SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1), 268 SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1),
@@ -302,8 +306,8 @@ static struct sensor_device_attribute_2 f71858fg_in_temp_attr[] = {
302 SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 2), 306 SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 2),
303}; 307};
304 308
305/* Temp and in attr common to both the f71862fg and f71882fg */ 309/* Temp and in attr common to the f71862fg, f71882fg and f71889fg */
306static struct sensor_device_attribute_2 f718x2fg_in_temp_attr[] = { 310static struct sensor_device_attribute_2 fxxxx_in_temp_attr[] = {
307 SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0), 311 SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
308 SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1), 312 SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1),
309 SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2), 313 SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2),
@@ -371,8 +375,8 @@ static struct sensor_device_attribute_2 f718x2fg_in_temp_attr[] = {
371 SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 3), 375 SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 3),
372}; 376};
373 377
374/* Temp and in attr found only on the f71882fg */ 378/* For models with in1 alarm capability */
375static struct sensor_device_attribute_2 f71882fg_in_temp_attr[] = { 379static struct sensor_device_attribute_2 fxxxx_in1_alarm_attr[] = {
376 SENSOR_ATTR_2(in1_max, S_IRUGO|S_IWUSR, show_in_max, store_in_max, 380 SENSOR_ATTR_2(in1_max, S_IRUGO|S_IWUSR, show_in_max, store_in_max,
377 0, 1), 381 0, 1),
378 SENSOR_ATTR_2(in1_beep, S_IRUGO|S_IWUSR, show_in_beep, store_in_beep, 382 SENSOR_ATTR_2(in1_beep, S_IRUGO|S_IWUSR, show_in_beep, store_in_beep,
@@ -383,6 +387,7 @@ static struct sensor_device_attribute_2 f71882fg_in_temp_attr[] = {
383/* Temp and in attr for the f8000 387/* Temp and in attr for the f8000
384 Note on the f8000 temp_ovt (crit) is used as max, and temp_high (max) 388 Note on the f8000 temp_ovt (crit) is used as max, and temp_high (max)
385 is used as hysteresis value to clear alarms 389 is used as hysteresis value to clear alarms
390 Also like the f71858fg its temperature indexes start at 0
386 */ 391 */
387static struct sensor_device_attribute_2 f8000_in_temp_attr[] = { 392static struct sensor_device_attribute_2 f8000_in_temp_attr[] = {
388 SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0), 393 SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
@@ -413,61 +418,70 @@ static struct sensor_device_attribute_2 f8000_in_temp_attr[] = {
413}; 418};
414 419
415/* Fan / PWM attr common to all models */ 420/* Fan / PWM attr common to all models */
416static struct sensor_device_attribute_2 fxxxx_fan_attr[] = { 421static struct sensor_device_attribute_2 fxxxx_fan_attr[4][6] = { {
417 SENSOR_ATTR_2(fan1_input, S_IRUGO, show_fan, NULL, 0, 0), 422 SENSOR_ATTR_2(fan1_input, S_IRUGO, show_fan, NULL, 0, 0),
418 SENSOR_ATTR_2(fan1_full_speed, S_IRUGO|S_IWUSR, 423 SENSOR_ATTR_2(fan1_full_speed, S_IRUGO|S_IWUSR,
419 show_fan_full_speed, 424 show_fan_full_speed,
420 store_fan_full_speed, 0, 0), 425 store_fan_full_speed, 0, 0),
421 SENSOR_ATTR_2(fan1_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 0), 426 SENSOR_ATTR_2(fan1_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 0),
422 SENSOR_ATTR_2(fan2_input, S_IRUGO, show_fan, NULL, 0, 1),
423 SENSOR_ATTR_2(fan2_full_speed, S_IRUGO|S_IWUSR,
424 show_fan_full_speed,
425 store_fan_full_speed, 0, 1),
426 SENSOR_ATTR_2(fan2_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 1),
427 SENSOR_ATTR_2(fan3_input, S_IRUGO, show_fan, NULL, 0, 2),
428 SENSOR_ATTR_2(fan3_full_speed, S_IRUGO|S_IWUSR,
429 show_fan_full_speed,
430 store_fan_full_speed, 0, 2),
431 SENSOR_ATTR_2(fan3_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 2),
432
433 SENSOR_ATTR_2(pwm1, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 0), 427 SENSOR_ATTR_2(pwm1, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 0),
434 SENSOR_ATTR_2(pwm1_enable, S_IRUGO|S_IWUSR, show_pwm_enable, 428 SENSOR_ATTR_2(pwm1_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
435 store_pwm_enable, 0, 0), 429 store_pwm_enable, 0, 0),
436 SENSOR_ATTR_2(pwm1_interpolate, S_IRUGO|S_IWUSR, 430 SENSOR_ATTR_2(pwm1_interpolate, S_IRUGO|S_IWUSR,
437 show_pwm_interpolate, store_pwm_interpolate, 0, 0), 431 show_pwm_interpolate, store_pwm_interpolate, 0, 0),
438 SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR, 432}, {
439 show_pwm_auto_point_channel, 433 SENSOR_ATTR_2(fan2_input, S_IRUGO, show_fan, NULL, 0, 1),
440 store_pwm_auto_point_channel, 0, 0), 434 SENSOR_ATTR_2(fan2_full_speed, S_IRUGO|S_IWUSR,
441 435 show_fan_full_speed,
436 store_fan_full_speed, 0, 1),
437 SENSOR_ATTR_2(fan2_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 1),
442 SENSOR_ATTR_2(pwm2, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 1), 438 SENSOR_ATTR_2(pwm2, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 1),
443 SENSOR_ATTR_2(pwm2_enable, S_IRUGO|S_IWUSR, show_pwm_enable, 439 SENSOR_ATTR_2(pwm2_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
444 store_pwm_enable, 0, 1), 440 store_pwm_enable, 0, 1),
445 SENSOR_ATTR_2(pwm2_interpolate, S_IRUGO|S_IWUSR, 441 SENSOR_ATTR_2(pwm2_interpolate, S_IRUGO|S_IWUSR,
446 show_pwm_interpolate, store_pwm_interpolate, 0, 1), 442 show_pwm_interpolate, store_pwm_interpolate, 0, 1),
447 SENSOR_ATTR_2(pwm2_auto_channels_temp, S_IRUGO|S_IWUSR, 443}, {
448 show_pwm_auto_point_channel, 444 SENSOR_ATTR_2(fan3_input, S_IRUGO, show_fan, NULL, 0, 2),
449 store_pwm_auto_point_channel, 0, 1), 445 SENSOR_ATTR_2(fan3_full_speed, S_IRUGO|S_IWUSR,
450 446 show_fan_full_speed,
447 store_fan_full_speed, 0, 2),
448 SENSOR_ATTR_2(fan3_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 2),
451 SENSOR_ATTR_2(pwm3, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 2), 449 SENSOR_ATTR_2(pwm3, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 2),
452 SENSOR_ATTR_2(pwm3_enable, S_IRUGO|S_IWUSR, show_pwm_enable, 450 SENSOR_ATTR_2(pwm3_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
453 store_pwm_enable, 0, 2), 451 store_pwm_enable, 0, 2),
454 SENSOR_ATTR_2(pwm3_interpolate, S_IRUGO|S_IWUSR, 452 SENSOR_ATTR_2(pwm3_interpolate, S_IRUGO|S_IWUSR,
455 show_pwm_interpolate, store_pwm_interpolate, 0, 2), 453 show_pwm_interpolate, store_pwm_interpolate, 0, 2),
456 SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR, 454}, {
457 show_pwm_auto_point_channel, 455 SENSOR_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 0, 3),
458 store_pwm_auto_point_channel, 0, 2), 456 SENSOR_ATTR_2(fan4_full_speed, S_IRUGO|S_IWUSR,
459}; 457 show_fan_full_speed,
458 store_fan_full_speed, 0, 3),
459 SENSOR_ATTR_2(fan4_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 3),
460 SENSOR_ATTR_2(pwm4, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 3),
461 SENSOR_ATTR_2(pwm4_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
462 store_pwm_enable, 0, 3),
463 SENSOR_ATTR_2(pwm4_interpolate, S_IRUGO|S_IWUSR,
464 show_pwm_interpolate, store_pwm_interpolate, 0, 3),
465} };
460 466
461/* Fan / PWM attr for the f71862fg, less pwms and less zones per pwm than the 467/* Attr for models which can beep on Fan alarm */
462 f71882fg */ 468static struct sensor_device_attribute_2 fxxxx_fan_beep_attr[] = {
463static struct sensor_device_attribute_2 f71862fg_fan_attr[] = {
464 SENSOR_ATTR_2(fan1_beep, S_IRUGO|S_IWUSR, show_fan_beep, 469 SENSOR_ATTR_2(fan1_beep, S_IRUGO|S_IWUSR, show_fan_beep,
465 store_fan_beep, 0, 0), 470 store_fan_beep, 0, 0),
466 SENSOR_ATTR_2(fan2_beep, S_IRUGO|S_IWUSR, show_fan_beep, 471 SENSOR_ATTR_2(fan2_beep, S_IRUGO|S_IWUSR, show_fan_beep,
467 store_fan_beep, 0, 1), 472 store_fan_beep, 0, 1),
468 SENSOR_ATTR_2(fan3_beep, S_IRUGO|S_IWUSR, show_fan_beep, 473 SENSOR_ATTR_2(fan3_beep, S_IRUGO|S_IWUSR, show_fan_beep,
469 store_fan_beep, 0, 2), 474 store_fan_beep, 0, 2),
475 SENSOR_ATTR_2(fan4_beep, S_IRUGO|S_IWUSR, show_fan_beep,
476 store_fan_beep, 0, 3),
477};
470 478
479/* PWM attr for the f71862fg, fewer pwms and fewer zones per pwm than the
480 f71858fg / f71882fg / f71889fg */
481static struct sensor_device_attribute_2 f71862fg_auto_pwm_attr[] = {
482 SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR,
483 show_pwm_auto_point_channel,
484 store_pwm_auto_point_channel, 0, 0),
471 SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO|S_IWUSR, 485 SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO|S_IWUSR,
472 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 486 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
473 1, 0), 487 1, 0),
@@ -487,6 +501,9 @@ static struct sensor_device_attribute_2 f71862fg_fan_attr[] = {
487 SENSOR_ATTR_2(pwm1_auto_point2_temp_hyst, S_IRUGO, 501 SENSOR_ATTR_2(pwm1_auto_point2_temp_hyst, S_IRUGO,
488 show_pwm_auto_point_temp_hyst, NULL, 3, 0), 502 show_pwm_auto_point_temp_hyst, NULL, 3, 0),
489 503
504 SENSOR_ATTR_2(pwm2_auto_channels_temp, S_IRUGO|S_IWUSR,
505 show_pwm_auto_point_channel,
506 store_pwm_auto_point_channel, 0, 1),
490 SENSOR_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO|S_IWUSR, 507 SENSOR_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO|S_IWUSR,
491 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 508 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
492 1, 1), 509 1, 1),
@@ -506,6 +523,9 @@ static struct sensor_device_attribute_2 f71862fg_fan_attr[] = {
506 SENSOR_ATTR_2(pwm2_auto_point2_temp_hyst, S_IRUGO, 523 SENSOR_ATTR_2(pwm2_auto_point2_temp_hyst, S_IRUGO,
507 show_pwm_auto_point_temp_hyst, NULL, 3, 1), 524 show_pwm_auto_point_temp_hyst, NULL, 3, 1),
508 525
526 SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR,
527 show_pwm_auto_point_channel,
528 store_pwm_auto_point_channel, 0, 2),
509 SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO|S_IWUSR, 529 SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO|S_IWUSR,
510 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 530 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
511 1, 2), 531 1, 2),
@@ -526,8 +546,11 @@ static struct sensor_device_attribute_2 f71862fg_fan_attr[] = {
526 show_pwm_auto_point_temp_hyst, NULL, 3, 2), 546 show_pwm_auto_point_temp_hyst, NULL, 3, 2),
527}; 547};
528 548
529/* Fan / PWM attr common to both the f71882fg and f71858fg */ 549/* PWM attr common to the f71858fg, f71882fg and f71889fg */
530static struct sensor_device_attribute_2 f71882fg_f71858fg_fan_attr[] = { 550static struct sensor_device_attribute_2 fxxxx_auto_pwm_attr[4][14] = { {
551 SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR,
552 show_pwm_auto_point_channel,
553 store_pwm_auto_point_channel, 0, 0),
531 SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO|S_IWUSR, 554 SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO|S_IWUSR,
532 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 555 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
533 0, 0), 556 0, 0),
@@ -565,7 +588,10 @@ static struct sensor_device_attribute_2 f71882fg_f71858fg_fan_attr[] = {
565 show_pwm_auto_point_temp_hyst, NULL, 2, 0), 588 show_pwm_auto_point_temp_hyst, NULL, 2, 0),
566 SENSOR_ATTR_2(pwm1_auto_point4_temp_hyst, S_IRUGO, 589 SENSOR_ATTR_2(pwm1_auto_point4_temp_hyst, S_IRUGO,
567 show_pwm_auto_point_temp_hyst, NULL, 3, 0), 590 show_pwm_auto_point_temp_hyst, NULL, 3, 0),
568 591}, {
592 SENSOR_ATTR_2(pwm2_auto_channels_temp, S_IRUGO|S_IWUSR,
593 show_pwm_auto_point_channel,
594 store_pwm_auto_point_channel, 0, 1),
569 SENSOR_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO|S_IWUSR, 595 SENSOR_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO|S_IWUSR,
570 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 596 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
571 0, 1), 597 0, 1),
@@ -603,7 +629,10 @@ static struct sensor_device_attribute_2 f71882fg_f71858fg_fan_attr[] = {
603 show_pwm_auto_point_temp_hyst, NULL, 2, 1), 629 show_pwm_auto_point_temp_hyst, NULL, 2, 1),
604 SENSOR_ATTR_2(pwm2_auto_point4_temp_hyst, S_IRUGO, 630 SENSOR_ATTR_2(pwm2_auto_point4_temp_hyst, S_IRUGO,
605 show_pwm_auto_point_temp_hyst, NULL, 3, 1), 631 show_pwm_auto_point_temp_hyst, NULL, 3, 1),
606 632}, {
633 SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR,
634 show_pwm_auto_point_channel,
635 store_pwm_auto_point_channel, 0, 2),
607 SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO|S_IWUSR, 636 SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO|S_IWUSR,
608 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 637 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
609 0, 2), 638 0, 2),
@@ -641,30 +670,7 @@ static struct sensor_device_attribute_2 f71882fg_f71858fg_fan_attr[] = {
641 show_pwm_auto_point_temp_hyst, NULL, 2, 2), 670 show_pwm_auto_point_temp_hyst, NULL, 2, 2),
642 SENSOR_ATTR_2(pwm3_auto_point4_temp_hyst, S_IRUGO, 671 SENSOR_ATTR_2(pwm3_auto_point4_temp_hyst, S_IRUGO,
643 show_pwm_auto_point_temp_hyst, NULL, 3, 2), 672 show_pwm_auto_point_temp_hyst, NULL, 3, 2),
644}; 673}, {
645
646/* Fan / PWM attr found on the f71882fg but not on the f71858fg */
647static struct sensor_device_attribute_2 f71882fg_fan_attr[] = {
648 SENSOR_ATTR_2(fan1_beep, S_IRUGO|S_IWUSR, show_fan_beep,
649 store_fan_beep, 0, 0),
650 SENSOR_ATTR_2(fan2_beep, S_IRUGO|S_IWUSR, show_fan_beep,
651 store_fan_beep, 0, 1),
652 SENSOR_ATTR_2(fan3_beep, S_IRUGO|S_IWUSR, show_fan_beep,
653 store_fan_beep, 0, 2),
654
655 SENSOR_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 0, 3),
656 SENSOR_ATTR_2(fan4_full_speed, S_IRUGO|S_IWUSR,
657 show_fan_full_speed,
658 store_fan_full_speed, 0, 3),
659 SENSOR_ATTR_2(fan4_beep, S_IRUGO|S_IWUSR, show_fan_beep,
660 store_fan_beep, 0, 3),
661 SENSOR_ATTR_2(fan4_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 3),
662
663 SENSOR_ATTR_2(pwm4, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 3),
664 SENSOR_ATTR_2(pwm4_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
665 store_pwm_enable, 0, 3),
666 SENSOR_ATTR_2(pwm4_interpolate, S_IRUGO|S_IWUSR,
667 show_pwm_interpolate, store_pwm_interpolate, 0, 3),
668 SENSOR_ATTR_2(pwm4_auto_channels_temp, S_IRUGO|S_IWUSR, 674 SENSOR_ATTR_2(pwm4_auto_channels_temp, S_IRUGO|S_IWUSR,
669 show_pwm_auto_point_channel, 675 show_pwm_auto_point_channel,
670 store_pwm_auto_point_channel, 0, 3), 676 store_pwm_auto_point_channel, 0, 3),
@@ -705,14 +711,20 @@ static struct sensor_device_attribute_2 f71882fg_fan_attr[] = {
705 show_pwm_auto_point_temp_hyst, NULL, 2, 3), 711 show_pwm_auto_point_temp_hyst, NULL, 2, 3),
706 SENSOR_ATTR_2(pwm4_auto_point4_temp_hyst, S_IRUGO, 712 SENSOR_ATTR_2(pwm4_auto_point4_temp_hyst, S_IRUGO,
707 show_pwm_auto_point_temp_hyst, NULL, 3, 3), 713 show_pwm_auto_point_temp_hyst, NULL, 3, 3),
708}; 714} };
709 715
710/* Fan / PWM attr for the f8000, zones mapped to temp instead of to pwm! 716/* Fan attr specific to the f8000 (4th fan input can only measure speed) */
711 Also the register block at offset A0 maps to TEMP1 (so our temp2, as the
712 F8000 starts counting temps at 0), B0 maps the TEMP2 and C0 maps to TEMP0 */
713static struct sensor_device_attribute_2 f8000_fan_attr[] = { 717static struct sensor_device_attribute_2 f8000_fan_attr[] = {
714 SENSOR_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 0, 3), 718 SENSOR_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 0, 3),
719};
715 720
721/* PWM attr for the f8000, zones mapped to temp instead of to pwm!
722 Also the register block at offset A0 maps to TEMP1 (so our temp2, as the
723 F8000 starts counting temps at 0), B0 maps the TEMP2 and C0 maps to TEMP0 */
724static struct sensor_device_attribute_2 f8000_auto_pwm_attr[] = {
725 SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR,
726 show_pwm_auto_point_channel,
727 store_pwm_auto_point_channel, 0, 0),
716 SENSOR_ATTR_2(temp1_auto_point1_pwm, S_IRUGO|S_IWUSR, 728 SENSOR_ATTR_2(temp1_auto_point1_pwm, S_IRUGO|S_IWUSR,
717 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 729 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
718 0, 2), 730 0, 2),
@@ -751,6 +763,9 @@ static struct sensor_device_attribute_2 f8000_fan_attr[] = {
751 SENSOR_ATTR_2(temp1_auto_point4_temp_hyst, S_IRUGO, 763 SENSOR_ATTR_2(temp1_auto_point4_temp_hyst, S_IRUGO,
752 show_pwm_auto_point_temp_hyst, NULL, 3, 2), 764 show_pwm_auto_point_temp_hyst, NULL, 3, 2),
753 765
766 SENSOR_ATTR_2(pwm2_auto_channels_temp, S_IRUGO|S_IWUSR,
767 show_pwm_auto_point_channel,
768 store_pwm_auto_point_channel, 0, 1),
754 SENSOR_ATTR_2(temp2_auto_point1_pwm, S_IRUGO|S_IWUSR, 769 SENSOR_ATTR_2(temp2_auto_point1_pwm, S_IRUGO|S_IWUSR,
755 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 770 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
756 0, 0), 771 0, 0),
@@ -789,6 +804,9 @@ static struct sensor_device_attribute_2 f8000_fan_attr[] = {
789 SENSOR_ATTR_2(temp2_auto_point4_temp_hyst, S_IRUGO, 804 SENSOR_ATTR_2(temp2_auto_point4_temp_hyst, S_IRUGO,
790 show_pwm_auto_point_temp_hyst, NULL, 3, 0), 805 show_pwm_auto_point_temp_hyst, NULL, 3, 0),
791 806
807 SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR,
808 show_pwm_auto_point_channel,
809 store_pwm_auto_point_channel, 0, 2),
792 SENSOR_ATTR_2(temp3_auto_point1_pwm, S_IRUGO|S_IWUSR, 810 SENSOR_ATTR_2(temp3_auto_point1_pwm, S_IRUGO|S_IWUSR,
793 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 811 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
794 0, 1), 812 0, 1),
@@ -929,7 +947,7 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev)
929 /* Update once every 60 seconds */ 947 /* Update once every 60 seconds */
930 if ( time_after(jiffies, data->last_limits + 60 * HZ ) || 948 if ( time_after(jiffies, data->last_limits + 60 * HZ ) ||
931 !data->valid) { 949 !data->valid) {
932 if (data->type == f71882fg) { 950 if (data->type == f71882fg || data->type == f71889fg) {
933 data->in1_max = 951 data->in1_max =
934 f71882fg_read8(data, F71882FG_REG_IN1_HIGH); 952 f71882fg_read8(data, F71882FG_REG_IN1_HIGH);
935 data->in_beep = 953 data->in_beep =
@@ -951,7 +969,8 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev)
951 F71882FG_REG_TEMP_HYST(1)); 969 F71882FG_REG_TEMP_HYST(1));
952 } 970 }
953 971
954 if (data->type == f71862fg || data->type == f71882fg) { 972 if (data->type == f71862fg || data->type == f71882fg ||
973 data->type == f71889fg) {
955 data->fan_beep = f71882fg_read8(data, 974 data->fan_beep = f71882fg_read8(data,
956 F71882FG_REG_FAN_BEEP); 975 F71882FG_REG_FAN_BEEP);
957 data->temp_beep = f71882fg_read8(data, 976 data->temp_beep = f71882fg_read8(data,
@@ -961,15 +980,33 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev)
961 data->temp_type[2] = (reg & 0x04) ? 2 : 4; 980 data->temp_type[2] = (reg & 0x04) ? 2 : 4;
962 data->temp_type[3] = (reg & 0x08) ? 2 : 4; 981 data->temp_type[3] = (reg & 0x08) ? 2 : 4;
963 } 982 }
964 reg2 = f71882fg_read8(data, F71882FG_REG_PECI); 983 /* Determine temp index 1 sensor type */
965 if ((reg2 & 0x03) == 0x01) 984 if (data->type == f71889fg) {
966 data->temp_type[1] = 6 /* PECI */; 985 reg2 = f71882fg_read8(data, F71882FG_REG_START);
967 else if ((reg2 & 0x03) == 0x02) 986 switch ((reg2 & 0x60) >> 5) {
968 data->temp_type[1] = 5 /* AMDSI */; 987 case 0x00: /* BJT / Thermistor */
969 else if (data->type == f71862fg || data->type == f71882fg) 988 data->temp_type[1] = (reg & 0x02) ? 2 : 4;
970 data->temp_type[1] = (reg & 0x02) ? 2 : 4; 989 break;
971 else 990 case 0x01: /* AMDSI */
972 data->temp_type[1] = 2; /* Only supports BJT */ 991 data->temp_type[1] = 5;
992 break;
993 case 0x02: /* PECI */
994 case 0x03: /* Ibex Peak ?? Report as PECI for now */
995 data->temp_type[1] = 6;
996 break;
997 }
998 } else {
999 reg2 = f71882fg_read8(data, F71882FG_REG_PECI);
1000 if ((reg2 & 0x03) == 0x01)
1001 data->temp_type[1] = 6; /* PECI */
1002 else if ((reg2 & 0x03) == 0x02)
1003 data->temp_type[1] = 5; /* AMDSI */
1004 else if (data->type == f71862fg ||
1005 data->type == f71882fg)
1006 data->temp_type[1] = (reg & 0x02) ? 2 : 4;
1007 else /* f71858fg and f8000 only support BJT */
1008 data->temp_type[1] = 2;
1009 }
973 1010
974 data->pwm_enable = f71882fg_read8(data, 1011 data->pwm_enable = f71882fg_read8(data,
975 F71882FG_REG_PWM_ENABLE); 1012 F71882FG_REG_PWM_ENABLE);
@@ -1046,7 +1083,7 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev)
1046 if (data->type == f8000) 1083 if (data->type == f8000)
1047 data->fan[3] = f71882fg_read16(data, 1084 data->fan[3] = f71882fg_read16(data,
1048 F71882FG_REG_FAN(3)); 1085 F71882FG_REG_FAN(3));
1049 if (data->type == f71882fg) 1086 if (data->type == f71882fg || data->type == f71889fg)
1050 data->in_status = f71882fg_read8(data, 1087 data->in_status = f71882fg_read8(data,
1051 F71882FG_REG_IN_STATUS); 1088 F71882FG_REG_IN_STATUS);
1052 for (nr = 0; nr < nr_ins; nr++) 1089 for (nr = 0; nr < nr_ins; nr++)
@@ -1764,7 +1801,11 @@ static ssize_t store_pwm_auto_point_temp(struct device *dev,
1764 int pwm = to_sensor_dev_attr_2(devattr)->index; 1801 int pwm = to_sensor_dev_attr_2(devattr)->index;
1765 int point = to_sensor_dev_attr_2(devattr)->nr; 1802 int point = to_sensor_dev_attr_2(devattr)->nr;
1766 long val = simple_strtol(buf, NULL, 10) / 1000; 1803 long val = simple_strtol(buf, NULL, 10) / 1000;
1767 val = SENSORS_LIMIT(val, 0, 255); 1804
1805 if (data->type == f71889fg)
1806 val = SENSORS_LIMIT(val, -128, 127);
1807 else
1808 val = SENSORS_LIMIT(val, 0, 127);
1768 1809
1769 mutex_lock(&data->update_lock); 1810 mutex_lock(&data->update_lock);
1770 f71882fg_write8(data, F71882FG_REG_POINT_TEMP(pwm, point), val); 1811 f71882fg_write8(data, F71882FG_REG_POINT_TEMP(pwm, point), val);
@@ -1794,6 +1835,15 @@ static int __devinit f71882fg_create_sysfs_files(struct platform_device *pdev,
1794 return 0; 1835 return 0;
1795} 1836}
1796 1837
1838static void f71882fg_remove_sysfs_files(struct platform_device *pdev,
1839 struct sensor_device_attribute_2 *attr, int count)
1840{
1841 int i;
1842
1843 for (i = 0; i < count; i++)
1844 device_remove_file(&pdev->dev, &attr[i].dev_attr);
1845}
1846
1797static int __devinit f71882fg_probe(struct platform_device *pdev) 1847static int __devinit f71882fg_probe(struct platform_device *pdev)
1798{ 1848{
1799 struct f71882fg_data *data; 1849 struct f71882fg_data *data;
@@ -1846,16 +1896,17 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
1846 ARRAY_SIZE(f71858fg_in_temp_attr)); 1896 ARRAY_SIZE(f71858fg_in_temp_attr));
1847 break; 1897 break;
1848 case f71882fg: 1898 case f71882fg:
1899 case f71889fg:
1849 err = f71882fg_create_sysfs_files(pdev, 1900 err = f71882fg_create_sysfs_files(pdev,
1850 f71882fg_in_temp_attr, 1901 fxxxx_in1_alarm_attr,
1851 ARRAY_SIZE(f71882fg_in_temp_attr)); 1902 ARRAY_SIZE(fxxxx_in1_alarm_attr));
1852 if (err) 1903 if (err)
1853 goto exit_unregister_sysfs; 1904 goto exit_unregister_sysfs;
1854 /* fall through! */ 1905 /* fall through! */
1855 case f71862fg: 1906 case f71862fg:
1856 err = f71882fg_create_sysfs_files(pdev, 1907 err = f71882fg_create_sysfs_files(pdev,
1857 f718x2fg_in_temp_attr, 1908 fxxxx_in_temp_attr,
1858 ARRAY_SIZE(f718x2fg_in_temp_attr)); 1909 ARRAY_SIZE(fxxxx_in_temp_attr));
1859 break; 1910 break;
1860 case f8000: 1911 case f8000:
1861 err = f71882fg_create_sysfs_files(pdev, 1912 err = f71882fg_create_sysfs_files(pdev,
@@ -1883,6 +1934,7 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
1883 err = (data->pwm_enable & 0x15) != 0x15; 1934 err = (data->pwm_enable & 0x15) != 0x15;
1884 break; 1935 break;
1885 case f71882fg: 1936 case f71882fg:
1937 case f71889fg:
1886 err = 0; 1938 err = 0;
1887 break; 1939 break;
1888 case f8000: 1940 case f8000:
@@ -1897,34 +1949,55 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
1897 goto exit_unregister_sysfs; 1949 goto exit_unregister_sysfs;
1898 } 1950 }
1899 1951
1900 err = f71882fg_create_sysfs_files(pdev, fxxxx_fan_attr, 1952 err = f71882fg_create_sysfs_files(pdev, &fxxxx_fan_attr[0][0],
1901 ARRAY_SIZE(fxxxx_fan_attr)); 1953 ARRAY_SIZE(fxxxx_fan_attr[0]) * nr_fans);
1902 if (err) 1954 if (err)
1903 goto exit_unregister_sysfs; 1955 goto exit_unregister_sysfs;
1904 1956
1905 switch (data->type) { 1957 if (data->type == f71862fg || data->type == f71882fg ||
1906 case f71862fg: 1958 data->type == f71889fg) {
1907 err = f71882fg_create_sysfs_files(pdev,
1908 f71862fg_fan_attr,
1909 ARRAY_SIZE(f71862fg_fan_attr));
1910 break;
1911 case f71882fg:
1912 err = f71882fg_create_sysfs_files(pdev, 1959 err = f71882fg_create_sysfs_files(pdev,
1913 f71882fg_fan_attr, 1960 fxxxx_fan_beep_attr, nr_fans);
1914 ARRAY_SIZE(f71882fg_fan_attr));
1915 if (err) 1961 if (err)
1916 goto exit_unregister_sysfs; 1962 goto exit_unregister_sysfs;
1917 /* fall through! */ 1963 }
1918 case f71858fg: 1964
1965 switch (data->type) {
1966 case f71862fg:
1919 err = f71882fg_create_sysfs_files(pdev, 1967 err = f71882fg_create_sysfs_files(pdev,
1920 f71882fg_f71858fg_fan_attr, 1968 f71862fg_auto_pwm_attr,
1921 ARRAY_SIZE(f71882fg_f71858fg_fan_attr)); 1969 ARRAY_SIZE(f71862fg_auto_pwm_attr));
1922 break; 1970 break;
1923 case f8000: 1971 case f8000:
1924 err = f71882fg_create_sysfs_files(pdev, 1972 err = f71882fg_create_sysfs_files(pdev,
1925 f8000_fan_attr, 1973 f8000_fan_attr,
1926 ARRAY_SIZE(f8000_fan_attr)); 1974 ARRAY_SIZE(f8000_fan_attr));
1975 if (err)
1976 goto exit_unregister_sysfs;
1977 err = f71882fg_create_sysfs_files(pdev,
1978 f8000_auto_pwm_attr,
1979 ARRAY_SIZE(f8000_auto_pwm_attr));
1927 break; 1980 break;
1981 case f71889fg:
1982 for (i = 0; i < nr_fans; i++) {
1983 data->pwm_auto_point_mapping[i] =
1984 f71882fg_read8(data,
1985 F71882FG_REG_POINT_MAPPING(i));
1986 if (data->pwm_auto_point_mapping[i] & 0x80)
1987 break;
1988 }
1989 if (i != nr_fans) {
1990 dev_warn(&pdev->dev,
1991 "Auto pwm controlled by raw digital "
1992 "data, disabling pwm auto_point "
1993 "sysfs attributes\n");
1994 break;
1995 }
1996 /* fall through */
1997 default: /* f71858fg / f71882fg */
1998 err = f71882fg_create_sysfs_files(pdev,
1999 &fxxxx_auto_pwm_attr[0][0],
2000 ARRAY_SIZE(fxxxx_auto_pwm_attr[0]) * nr_fans);
1928 } 2001 }
1929 if (err) 2002 if (err)
1930 goto exit_unregister_sysfs; 2003 goto exit_unregister_sysfs;
@@ -1954,33 +2027,76 @@ exit_free:
1954 2027
1955static int f71882fg_remove(struct platform_device *pdev) 2028static int f71882fg_remove(struct platform_device *pdev)
1956{ 2029{
1957 int i;
1958 struct f71882fg_data *data = platform_get_drvdata(pdev); 2030 struct f71882fg_data *data = platform_get_drvdata(pdev);
2031 int nr_fans = (data->type == f71882fg) ? 4 : 3;
2032 u8 start_reg = f71882fg_read8(data, F71882FG_REG_START);
1959 2033
1960 platform_set_drvdata(pdev, NULL); 2034 platform_set_drvdata(pdev, NULL);
1961 if (data->hwmon_dev) 2035 if (data->hwmon_dev)
1962 hwmon_device_unregister(data->hwmon_dev); 2036 hwmon_device_unregister(data->hwmon_dev);
1963 2037
1964 /* Note we are not looping over all attr arrays we have as the ones
1965 below are supersets of the ones skipped. */
1966 device_remove_file(&pdev->dev, &dev_attr_name); 2038 device_remove_file(&pdev->dev, &dev_attr_name);
1967 2039
1968 for (i = 0; i < ARRAY_SIZE(f718x2fg_in_temp_attr); i++) 2040 if (start_reg & 0x01) {
1969 device_remove_file(&pdev->dev, 2041 switch (data->type) {
1970 &f718x2fg_in_temp_attr[i].dev_attr); 2042 case f71858fg:
1971 2043 if (data->temp_config & 0x10)
1972 for (i = 0; i < ARRAY_SIZE(f71882fg_in_temp_attr); i++) 2044 f71882fg_remove_sysfs_files(pdev,
1973 device_remove_file(&pdev->dev, 2045 f8000_in_temp_attr,
1974 &f71882fg_in_temp_attr[i].dev_attr); 2046 ARRAY_SIZE(f8000_in_temp_attr));
2047 else
2048 f71882fg_remove_sysfs_files(pdev,
2049 f71858fg_in_temp_attr,
2050 ARRAY_SIZE(f71858fg_in_temp_attr));
2051 break;
2052 case f71882fg:
2053 case f71889fg:
2054 f71882fg_remove_sysfs_files(pdev,
2055 fxxxx_in1_alarm_attr,
2056 ARRAY_SIZE(fxxxx_in1_alarm_attr));
2057 /* fall through! */
2058 case f71862fg:
2059 f71882fg_remove_sysfs_files(pdev,
2060 fxxxx_in_temp_attr,
2061 ARRAY_SIZE(fxxxx_in_temp_attr));
2062 break;
2063 case f8000:
2064 f71882fg_remove_sysfs_files(pdev,
2065 f8000_in_temp_attr,
2066 ARRAY_SIZE(f8000_in_temp_attr));
2067 break;
2068 }
2069 }
1975 2070
1976 for (i = 0; i < ARRAY_SIZE(fxxxx_fan_attr); i++) 2071 if (start_reg & 0x02) {
1977 device_remove_file(&pdev->dev, &fxxxx_fan_attr[i].dev_attr); 2072 f71882fg_remove_sysfs_files(pdev, &fxxxx_fan_attr[0][0],
2073 ARRAY_SIZE(fxxxx_fan_attr[0]) * nr_fans);
1978 2074
1979 for (i = 0; i < ARRAY_SIZE(f71882fg_fan_attr); i++) 2075 if (data->type == f71862fg || data->type == f71882fg ||
1980 device_remove_file(&pdev->dev, &f71882fg_fan_attr[i].dev_attr); 2076 data->type == f71889fg)
2077 f71882fg_remove_sysfs_files(pdev,
2078 fxxxx_fan_beep_attr, nr_fans);
1981 2079
1982 for (i = 0; i < ARRAY_SIZE(f8000_fan_attr); i++) 2080 switch (data->type) {
1983 device_remove_file(&pdev->dev, &f8000_fan_attr[i].dev_attr); 2081 case f71862fg:
2082 f71882fg_remove_sysfs_files(pdev,
2083 f71862fg_auto_pwm_attr,
2084 ARRAY_SIZE(f71862fg_auto_pwm_attr));
2085 break;
2086 case f8000:
2087 f71882fg_remove_sysfs_files(pdev,
2088 f8000_fan_attr,
2089 ARRAY_SIZE(f8000_fan_attr));
2090 f71882fg_remove_sysfs_files(pdev,
2091 f8000_auto_pwm_attr,
2092 ARRAY_SIZE(f8000_auto_pwm_attr));
2093 break;
2094 default: /* f71858fg / f71882fg / f71889fg */
2095 f71882fg_remove_sysfs_files(pdev,
2096 &fxxxx_auto_pwm_attr[0][0],
2097 ARRAY_SIZE(fxxxx_auto_pwm_attr[0]) * nr_fans);
2098 }
2099 }
1984 2100
1985 kfree(data); 2101 kfree(data);
1986 2102
@@ -2012,11 +2128,15 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
2012 case SIO_F71882_ID: 2128 case SIO_F71882_ID:
2013 sio_data->type = f71882fg; 2129 sio_data->type = f71882fg;
2014 break; 2130 break;
2131 case SIO_F71889_ID:
2132 sio_data->type = f71889fg;
2133 break;
2015 case SIO_F8000_ID: 2134 case SIO_F8000_ID:
2016 sio_data->type = f8000; 2135 sio_data->type = f8000;
2017 break; 2136 break;
2018 default: 2137 default:
2019 printk(KERN_INFO DRVNAME ": Unsupported Fintek device\n"); 2138 printk(KERN_INFO DRVNAME ": Unsupported Fintek device: %04x\n",
2139 (unsigned int)devid);
2020 goto exit; 2140 goto exit;
2021 } 2141 }
2022 2142