Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

hwmon: (nct6775) Integrate new model nct6116

Add support for NCT6116D to nct6775 driver.

Signed-off-by: Bjoern Gerhart <gerhart@posteo.de>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>

authored by

Björn Gerhart and committed by
Guenter Roeck
29c7cb48 c64fce7f

+174 -6
+174 -6
drivers/hwmon/nct6775.c
··· 20 20 * 21 21 * Chip #vin #fan #pwm #temp chip IDs man ID 22 22 * nct6106d 9 3 3 6+3 0xc450 0xc1 0x5ca3 23 + * nct6116d 9 5 5 3+3 0xd280 0xc1 0x5ca3 23 24 * nct6775f 9 4 3 6+3 0xb470 0xc1 0x5ca3 24 25 * nct6776f 9 5 3 6+3 0xc330 0xc1 0x5ca3 25 26 * nct6779d 15 5 5 2+6 0xc560 0xc1 0x5ca3 ··· 59 58 60 59 #define USE_ALTERNATE 61 60 62 - enum kinds { nct6106, nct6775, nct6776, nct6779, nct6791, nct6792, nct6793, 63 - nct6795, nct6796, nct6797, nct6798 }; 61 + enum kinds { nct6106, nct6116, nct6775, nct6776, nct6779, nct6791, nct6792, 62 + nct6793, nct6795, nct6796, nct6797, nct6798 }; 64 63 65 64 /* used to set data->name = nct6775_device_names[data->sio_kind] */ 66 65 static const char * const nct6775_device_names[] = { 67 66 "nct6106", 67 + "nct6116", 68 68 "nct6775", 69 69 "nct6776", 70 70 "nct6779", ··· 80 78 81 79 static const char * const nct6775_sio_names[] __initconst = { 82 80 "NCT6106D", 81 + "NCT6116D", 83 82 "NCT6775F", 84 83 "NCT6776D/F", 85 84 "NCT6779D", ··· 118 115 #define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */ 119 116 120 117 #define SIO_NCT6106_ID 0xc450 118 + #define SIO_NCT6116_ID 0xd280 121 119 #define SIO_NCT6775_ID 0xb470 122 120 #define SIO_NCT6776_ID 0xc330 123 121 #define SIO_NCT6779_ID 0xc560 ··· 829 825 830 826 static const u8 NCT6106_REG_PWM_MODE[] = { 0xf3, 0xf3, 0xf3 }; 831 827 static const u8 NCT6106_PWM_MODE_MASK[] = { 0x01, 0x02, 0x04 }; 832 - static const u16 NCT6106_REG_PWM[] = { 0x119, 0x129, 0x139 }; 833 828 static const u16 NCT6106_REG_PWM_READ[] = { 0x4a, 0x4b, 0x4c }; 834 829 static const u16 NCT6106_REG_FAN_MODE[] = { 0x113, 0x123, 0x133 }; 835 - static const u16 NCT6106_REG_TEMP_SEL[] = { 0x110, 0x120, 0x130 }; 836 830 static const u16 NCT6106_REG_TEMP_SOURCE[] = { 837 831 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5 }; 838 832 ··· 896 894 static const u16 NCT6106_REG_TEMP_CRIT[32] = { 897 895 [11] = 0x204, 898 896 [12] = 0x205, 897 + }; 898 + 899 + /* NCT6112D/NCT6114D/NCT6116D specific data */ 900 + 901 + static const u16 NCT6116_REG_FAN[] = { 0x20, 0x22, 0x24, 0x26, 0x28 }; 902 + static const u16 NCT6116_REG_FAN_MIN[] = { 0xe0, 0xe2, 0xe4, 0xe6, 0xe8 }; 903 + static const u16 NCT6116_REG_FAN_PULSES[] = { 0xf6, 0xf6, 0xf6, 0xf6, 0xf5 }; 904 + static const u16 NCT6116_FAN_PULSE_SHIFT[] = { 0, 2, 4, 6, 6 }; 905 + 906 + static const u16 NCT6116_REG_PWM[] = { 0x119, 0x129, 0x139, 0x199, 0x1a9 }; 907 + static const u16 NCT6116_REG_FAN_MODE[] = { 0x113, 0x123, 0x133, 0x193, 0x1a3 }; 908 + static const u16 NCT6116_REG_TEMP_SEL[] = { 0x110, 0x120, 0x130, 0x190, 0x1a0 }; 909 + static const u16 NCT6116_REG_TEMP_SOURCE[] = { 910 + 0xb0, 0xb1, 0xb2 }; 911 + 912 + static const u16 NCT6116_REG_CRITICAL_TEMP[] = { 913 + 0x11a, 0x12a, 0x13a, 0x19a, 0x1aa }; 914 + static const u16 NCT6116_REG_CRITICAL_TEMP_TOLERANCE[] = { 915 + 0x11b, 0x12b, 0x13b, 0x19b, 0x1ab }; 916 + 917 + static const u16 NCT6116_REG_CRITICAL_PWM_ENABLE[] = { 918 + 0x11c, 0x12c, 0x13c, 0x19c, 0x1ac }; 919 + static const u16 NCT6116_REG_CRITICAL_PWM[] = { 920 + 0x11d, 0x12d, 0x13d, 0x19d, 0x1ad }; 921 + 922 + static const u16 NCT6116_REG_FAN_STEP_UP_TIME[] = { 923 + 0x114, 0x124, 0x134, 0x194, 0x1a4 }; 924 + static const u16 NCT6116_REG_FAN_STEP_DOWN_TIME[] = { 925 + 0x115, 0x125, 0x135, 0x195, 0x1a5 }; 926 + static const u16 NCT6116_REG_FAN_STOP_OUTPUT[] = { 927 + 0x116, 0x126, 0x136, 0x196, 0x1a6 }; 928 + static const u16 NCT6116_REG_FAN_START_OUTPUT[] = { 929 + 0x117, 0x127, 0x137, 0x197, 0x1a7 }; 930 + static const u16 NCT6116_REG_FAN_STOP_TIME[] = { 931 + 0x118, 0x128, 0x138, 0x198, 0x1a8 }; 932 + static const u16 NCT6116_REG_TOLERANCE_H[] = { 933 + 0x112, 0x122, 0x132, 0x192, 0x1a2 }; 934 + 935 + static const u16 NCT6116_REG_TARGET[] = { 936 + 0x111, 0x121, 0x131, 0x191, 0x1a1 }; 937 + 938 + static const u16 NCT6116_REG_AUTO_TEMP[] = { 939 + 0x160, 0x170, 0x180, 0x1d0, 0x1e0 }; 940 + static const u16 NCT6116_REG_AUTO_PWM[] = { 941 + 0x164, 0x174, 0x184, 0x1d4, 0x1e4 }; 942 + 943 + static const s8 NCT6116_ALARM_BITS[] = { 944 + 0, 1, 2, 3, 4, 5, 7, 8, /* in0.. in7 */ 945 + 9, -1, -1, -1, -1, -1, -1, /* in8..in9 */ 946 + -1, /* unused */ 947 + 32, 33, 34, 35, 36, /* fan1..fan5 */ 948 + -1, -1, -1, /* unused */ 949 + 16, 17, 18, -1, -1, -1, /* temp1..temp6 */ 950 + 48, -1 /* intrusion0, intrusion1 */ 951 + }; 952 + 953 + static const s8 NCT6116_BEEP_BITS[] = { 954 + 0, 1, 2, 3, 4, 5, 7, 8, /* in0.. in7 */ 955 + 9, 10, 11, 12, -1, -1, -1, /* in8..in14 */ 956 + 32, /* global beep enable */ 957 + 24, 25, 26, 27, 28, /* fan1..fan5 */ 958 + -1, -1, -1, /* unused */ 959 + 16, 17, 18, -1, -1, -1, /* temp1..temp6 */ 960 + 34, -1 /* intrusion0, intrusion1 */ 899 961 }; 900 962 901 963 static enum pwm_enable reg_to_pwm_enable(int pwm, int mode) ··· 1360 1294 return reg == 0x20 || reg == 0x22 || reg == 0x24 || 1361 1295 reg == 0xe0 || reg == 0xe2 || reg == 0xe4 || 1362 1296 reg == 0x111 || reg == 0x121 || reg == 0x131; 1297 + case nct6116: 1298 + return reg == 0x20 || reg == 0x22 || reg == 0x24 || 1299 + reg == 0x26 || reg == 0x28 || reg == 0xe0 || reg == 0xe2 || 1300 + reg == 0xe4 || reg == 0xe6 || reg == 0xe8 || reg == 0x111 || 1301 + reg == 0x121 || reg == 0x131 || reg == 0x191 || reg == 0x1a1; 1363 1302 case nct6775: 1364 1303 return (((reg & 0xff00) == 0x100 || 1365 1304 (reg & 0xff00) == 0x200) && ··· 1744 1673 data->auto_pwm[i][data->auto_pwm_num] = 0xff; 1745 1674 break; 1746 1675 case nct6106: 1676 + case nct6116: 1747 1677 case nct6779: 1748 1678 case nct6791: 1749 1679 case nct6792: ··· 3181 3109 case nct6776: 3182 3110 break; /* always enabled, nothing to do */ 3183 3111 case nct6106: 3112 + case nct6116: 3184 3113 case nct6779: 3185 3114 case nct6791: 3186 3115 case nct6792: ··· 3608 3535 3609 3536 fan3pin = !(cr24 & 0x80); 3610 3537 pwm3pin = cr24 & 0x08; 3538 + } else if (data->kind == nct6116) { 3539 + int cr1a = superio_inb(sioreg, 0x1a); 3540 + int cr1b = superio_inb(sioreg, 0x1b); 3541 + int cr24 = superio_inb(sioreg, 0x24); 3542 + int cr2a = superio_inb(sioreg, 0x2a); 3543 + int cr2b = superio_inb(sioreg, 0x2b); 3544 + int cr2f = superio_inb(sioreg, 0x2f); 3545 + 3546 + fan3pin = !(cr2b & 0x10); 3547 + fan4pin = (cr2b & 0x80) || // pin 1(2) 3548 + (!(cr2f & 0x10) && (cr1a & 0x04)); // pin 65(66) 3549 + fan5pin = (cr2b & 0x80) || // pin 126(127) 3550 + (!(cr1b & 0x03) && (cr2a & 0x02)); // pin 94(96) 3551 + 3552 + pwm3pin = fan3pin && (cr24 & 0x08); 3553 + pwm4pin = fan4pin; 3554 + pwm5pin = fan5pin; 3611 3555 } else { 3612 3556 /* 3613 3557 * NCT6779D, NCT6791D, NCT6792D, NCT6793D, NCT6795D, NCT6796D, ··· 3855 3765 data->REG_FAN_TIME[1] = NCT6106_REG_FAN_STEP_UP_TIME; 3856 3766 data->REG_FAN_TIME[2] = NCT6106_REG_FAN_STEP_DOWN_TIME; 3857 3767 data->REG_TOLERANCE_H = NCT6106_REG_TOLERANCE_H; 3858 - data->REG_PWM[0] = NCT6106_REG_PWM; 3768 + data->REG_PWM[0] = NCT6116_REG_PWM; 3859 3769 data->REG_PWM[1] = NCT6106_REG_FAN_START_OUTPUT; 3860 3770 data->REG_PWM[2] = NCT6106_REG_FAN_STOP_OUTPUT; 3861 3771 data->REG_PWM[5] = NCT6106_REG_WEIGHT_DUTY_STEP; ··· 3874 3784 data->REG_CRITICAL_PWM = NCT6106_REG_CRITICAL_PWM; 3875 3785 data->REG_TEMP_OFFSET = NCT6106_REG_TEMP_OFFSET; 3876 3786 data->REG_TEMP_SOURCE = NCT6106_REG_TEMP_SOURCE; 3877 - data->REG_TEMP_SEL = NCT6106_REG_TEMP_SEL; 3787 + data->REG_TEMP_SEL = NCT6116_REG_TEMP_SEL; 3878 3788 data->REG_WEIGHT_TEMP_SEL = NCT6106_REG_WEIGHT_TEMP_SEL; 3879 3789 data->REG_WEIGHT_TEMP[0] = NCT6106_REG_WEIGHT_TEMP_STEP; 3880 3790 data->REG_WEIGHT_TEMP[1] = NCT6106_REG_WEIGHT_TEMP_STEP_TOL; ··· 3883 3793 data->ALARM_BITS = NCT6106_ALARM_BITS; 3884 3794 data->REG_BEEP = NCT6106_REG_BEEP; 3885 3795 data->BEEP_BITS = NCT6106_BEEP_BITS; 3796 + 3797 + reg_temp = NCT6106_REG_TEMP; 3798 + reg_temp_mon = NCT6106_REG_TEMP_MON; 3799 + num_reg_temp = ARRAY_SIZE(NCT6106_REG_TEMP); 3800 + num_reg_temp_mon = ARRAY_SIZE(NCT6106_REG_TEMP_MON); 3801 + reg_temp_over = NCT6106_REG_TEMP_OVER; 3802 + reg_temp_hyst = NCT6106_REG_TEMP_HYST; 3803 + reg_temp_config = NCT6106_REG_TEMP_CONFIG; 3804 + reg_temp_alternate = NCT6106_REG_TEMP_ALTERNATE; 3805 + reg_temp_crit = NCT6106_REG_TEMP_CRIT; 3806 + reg_temp_crit_l = NCT6106_REG_TEMP_CRIT_L; 3807 + reg_temp_crit_h = NCT6106_REG_TEMP_CRIT_H; 3808 + 3809 + break; 3810 + case nct6116: 3811 + data->in_num = 9; 3812 + data->pwm_num = 3; 3813 + data->auto_pwm_num = 4; 3814 + data->temp_fixed_num = 3; 3815 + data->num_temp_alarms = 3; 3816 + data->num_temp_beeps = 3; 3817 + 3818 + data->fan_from_reg = fan_from_reg13; 3819 + data->fan_from_reg_min = fan_from_reg13; 3820 + 3821 + data->temp_label = nct6776_temp_label; 3822 + data->temp_mask = NCT6776_TEMP_MASK; 3823 + data->virt_temp_mask = NCT6776_VIRT_TEMP_MASK; 3824 + 3825 + data->REG_VBAT = NCT6106_REG_VBAT; 3826 + data->REG_DIODE = NCT6106_REG_DIODE; 3827 + data->DIODE_MASK = NCT6106_DIODE_MASK; 3828 + data->REG_VIN = NCT6106_REG_IN; 3829 + data->REG_IN_MINMAX[0] = NCT6106_REG_IN_MIN; 3830 + data->REG_IN_MINMAX[1] = NCT6106_REG_IN_MAX; 3831 + data->REG_TARGET = NCT6116_REG_TARGET; 3832 + data->REG_FAN = NCT6116_REG_FAN; 3833 + data->REG_FAN_MODE = NCT6116_REG_FAN_MODE; 3834 + data->REG_FAN_MIN = NCT6116_REG_FAN_MIN; 3835 + data->REG_FAN_PULSES = NCT6116_REG_FAN_PULSES; 3836 + data->FAN_PULSE_SHIFT = NCT6116_FAN_PULSE_SHIFT; 3837 + data->REG_FAN_TIME[0] = NCT6116_REG_FAN_STOP_TIME; 3838 + data->REG_FAN_TIME[1] = NCT6116_REG_FAN_STEP_UP_TIME; 3839 + data->REG_FAN_TIME[2] = NCT6116_REG_FAN_STEP_DOWN_TIME; 3840 + data->REG_TOLERANCE_H = NCT6116_REG_TOLERANCE_H; 3841 + data->REG_PWM[0] = NCT6116_REG_PWM; 3842 + data->REG_PWM[1] = NCT6116_REG_FAN_START_OUTPUT; 3843 + data->REG_PWM[2] = NCT6116_REG_FAN_STOP_OUTPUT; 3844 + data->REG_PWM[5] = NCT6106_REG_WEIGHT_DUTY_STEP; 3845 + data->REG_PWM[6] = NCT6106_REG_WEIGHT_DUTY_BASE; 3846 + data->REG_PWM_READ = NCT6106_REG_PWM_READ; 3847 + data->REG_PWM_MODE = NCT6106_REG_PWM_MODE; 3848 + data->PWM_MODE_MASK = NCT6106_PWM_MODE_MASK; 3849 + data->REG_AUTO_TEMP = NCT6116_REG_AUTO_TEMP; 3850 + data->REG_AUTO_PWM = NCT6116_REG_AUTO_PWM; 3851 + data->REG_CRITICAL_TEMP = NCT6116_REG_CRITICAL_TEMP; 3852 + data->REG_CRITICAL_TEMP_TOLERANCE 3853 + = NCT6116_REG_CRITICAL_TEMP_TOLERANCE; 3854 + data->REG_CRITICAL_PWM_ENABLE = NCT6116_REG_CRITICAL_PWM_ENABLE; 3855 + data->CRITICAL_PWM_ENABLE_MASK 3856 + = NCT6106_CRITICAL_PWM_ENABLE_MASK; 3857 + data->REG_CRITICAL_PWM = NCT6116_REG_CRITICAL_PWM; 3858 + data->REG_TEMP_OFFSET = NCT6106_REG_TEMP_OFFSET; 3859 + data->REG_TEMP_SOURCE = NCT6116_REG_TEMP_SOURCE; 3860 + data->REG_TEMP_SEL = NCT6116_REG_TEMP_SEL; 3861 + data->REG_WEIGHT_TEMP_SEL = NCT6106_REG_WEIGHT_TEMP_SEL; 3862 + data->REG_WEIGHT_TEMP[0] = NCT6106_REG_WEIGHT_TEMP_STEP; 3863 + data->REG_WEIGHT_TEMP[1] = NCT6106_REG_WEIGHT_TEMP_STEP_TOL; 3864 + data->REG_WEIGHT_TEMP[2] = NCT6106_REG_WEIGHT_TEMP_BASE; 3865 + data->REG_ALARM = NCT6106_REG_ALARM; 3866 + data->ALARM_BITS = NCT6116_ALARM_BITS; 3867 + data->REG_BEEP = NCT6106_REG_BEEP; 3868 + data->BEEP_BITS = NCT6116_BEEP_BITS; 3886 3869 3887 3870 reg_temp = NCT6106_REG_TEMP; 3888 3871 reg_temp_mon = NCT6106_REG_TEMP_MON; ··· 4515 4352 data->have_vid = (cr2a & 0x60) == 0x40; 4516 4353 break; 4517 4354 case nct6106: 4355 + case nct6116: 4518 4356 case nct6779: 4519 4357 case nct6791: 4520 4358 case nct6792: ··· 4545 4381 NCT6775_REG_CR_FAN_DEBOUNCE); 4546 4382 switch (data->kind) { 4547 4383 case nct6106: 4384 + case nct6116: 4548 4385 tmp |= 0xe0; 4549 4386 break; 4550 4387 case nct6775: ··· 4740 4575 switch (val & SIO_ID_MASK) { 4741 4576 case SIO_NCT6106_ID: 4742 4577 sio_data->kind = nct6106; 4578 + break; 4579 + case SIO_NCT6116_ID: 4580 + sio_data->kind = nct6116; 4743 4581 break; 4744 4582 case SIO_NCT6775_ID: 4745 4583 sio_data->kind = nct6775;