@@ -50,10 +50,15 @@ internal class IT87XX : ISuperIO {
5050 private readonly byte [ ] FAN_TACHOMETER_EXT_REG =
5151 { 0x18 , 0x19 , 0x1a , 0x81 , 0x83 } ;
5252 private const byte VOLTAGE_BASE_REG = 0x20 ;
53- private readonly byte [ ] FAN_PWM_CTRL_REG = { 0x15 , 0x16 , 0x17 } ;
53+ private const byte FAN_MAIN_CTRL_REG = 0x13 ;
54+ private readonly byte [ ] FAN_PWM_CTRL_REG ;
55+ private readonly byte [ ] FAN_PWM_CTRL_EXT_REG =
56+ { 0x63 , 0x6b , 0x73 , 0x7b , 0xa3 } ;
5457
55- private bool [ ] restoreDefaultFanPwmControlRequired = new bool [ 3 ] ;
56- private byte [ ] initialFanPwmControl = new byte [ 3 ] ;
58+ private bool [ ] restoreDefaultFanPwmControlRequired = new bool [ 5 ] ;
59+ private bool [ ] initialFanOutputModeEnabled = new bool [ 3 ] ;
60+ private byte [ ] initialFanPwmControl = new byte [ 5 ] ;
61+ private byte [ ] initialFanPwmControlExt = new byte [ 5 ] ;
5762
5863 private byte ReadByte ( byte register , out bool valid ) {
5964 Ring0 . WriteIoPort ( addressReg , register ) ;
@@ -86,17 +91,47 @@ public void WriteGPIO(int index, byte value) {
8691 }
8792
8893 private void SaveDefaultFanPwmControl ( int index ) {
89- bool valid ;
9094 if ( ! restoreDefaultFanPwmControlRequired [ index ] ) {
91- initialFanPwmControl [ index ] =
92- ReadByte ( FAN_PWM_CTRL_REG [ index ] , out valid ) ;
95+ initialFanPwmControl [ index ] = ReadByte ( FAN_PWM_CTRL_REG [ index ] , out _ ) ;
96+
97+ if ( index < 3 ) {
98+ initialFanOutputModeEnabled [ index ] =
99+ ( ReadByte ( FAN_MAIN_CTRL_REG , out _ ) & ( 1 << index ) ) > 0 ;
100+ }
101+
102+ if ( chip == Chip . IT8721F ||
103+ chip == Chip . IT8665E ||
104+ chip == Chip . IT8686E ||
105+ chip == Chip . IT8688E ||
106+ chip == Chip . IT879XE )
107+ {
108+ initialFanPwmControlExt [ index ] =
109+ ReadByte ( FAN_PWM_CTRL_EXT_REG [ index ] , out _ ) ;
110+ }
93111 restoreDefaultFanPwmControlRequired [ index ] = true ;
94112 }
95113 }
96114
97115 private void RestoreDefaultFanPwmControl ( int index ) {
98116 if ( restoreDefaultFanPwmControlRequired [ index ] ) {
99117 WriteByte ( FAN_PWM_CTRL_REG [ index ] , initialFanPwmControl [ index ] ) ;
118+
119+ if ( index < 3 ) {
120+ var value = ReadByte ( FAN_MAIN_CTRL_REG , out _ ) ;
121+
122+ if ( ( value & ( 1 << index ) ) > 0 != initialFanOutputModeEnabled [ index ] ) {
123+ WriteByte ( FAN_MAIN_CTRL_REG , ( byte ) ( value ^ ( 1 << index ) ) ) ;
124+ }
125+ }
126+
127+ if ( chip == Chip . IT8721F ||
128+ chip == Chip . IT8665E ||
129+ chip == Chip . IT8686E ||
130+ chip == Chip . IT8688E ||
131+ chip == Chip . IT879XE )
132+ {
133+ WriteByte ( FAN_PWM_CTRL_EXT_REG [ index ] , initialFanPwmControlExt [ index ] ) ;
134+ }
100135 restoreDefaultFanPwmControlRequired [ index ] = false ;
101136 }
102137 }
@@ -111,8 +146,25 @@ public void SetControl(int index, byte? value) {
111146 if ( value . HasValue ) {
112147 SaveDefaultFanPwmControl ( index ) ;
113148
114- // set output value
115- WriteByte ( FAN_PWM_CTRL_REG [ index ] , ( byte ) ( value . Value >> 1 ) ) ;
149+ if ( index < 3 ) {
150+ if ( ! initialFanOutputModeEnabled [ index ] ) {
151+ WriteByte ( FAN_MAIN_CTRL_REG ,
152+ ( byte ) ( ReadByte ( FAN_MAIN_CTRL_REG , out _ ) | ( 1 << index ) ) ) ;
153+ }
154+ }
155+
156+ if ( chip == Chip . IT8721F ||
157+ chip == Chip . IT8665E ||
158+ chip == Chip . IT8686E ||
159+ chip == Chip . IT8688E ||
160+ chip == Chip . IT879XE )
161+ {
162+ WriteByte ( FAN_PWM_CTRL_REG [ index ] ,
163+ ( byte ) ( initialFanPwmControl [ index ] & 0x7F ) ) ;
164+ WriteByte ( FAN_PWM_CTRL_EXT_REG [ index ] , value . Value ) ;
165+ } else {
166+ WriteByte ( FAN_PWM_CTRL_REG [ index ] , ( byte ) ( value . Value >> 1 ) ) ;
167+ }
116168 } else {
117169 RestoreDefaultFanPwmControl ( index ) ;
118170 }
@@ -143,13 +195,20 @@ public IT87XX(Chip chip, ushort address, ushort gpioAddress, byte version) {
143195 if ( ! valid )
144196 return ;
145197
198+ if ( chip == Chip . IT8665E ) {
199+ FAN_PWM_CTRL_REG = new byte [ ] { 0x15 , 0x16 , 0x17 , 0x1e , 0x1f } ;
200+ } else {
201+ FAN_PWM_CTRL_REG = new byte [ ] { 0x15 , 0x16 , 0x17 , 0x7f , 0xa7 } ;
202+ }
203+
146204 switch ( chip ) {
147205 case Chip . IT8665E :
148206 case Chip . IT8686E :
149207 case Chip . IT8688E :
150208 voltages = new float ? [ 9 ] ;
151209 temperatures = new float ? [ 6 ] ;
152210 fans = new float ? [ 5 ] ;
211+ controls = new float ? [ 5 ] ;
153212 break ;
154213 case Chip . IT8655E :
155214 voltages = new float ? [ 9 ] ;
@@ -160,6 +219,7 @@ public IT87XX(Chip chip, ushort address, ushort gpioAddress, byte version) {
160219 voltages = new float ? [ 9 ] ;
161220 temperatures = new float ? [ 3 ] ;
162221 fans = new float ? [ 3 ] ;
222+ controls = new float ? [ 3 ] ;
163223 break ;
164224 case Chip . IT8705F :
165225 voltages = new float ? [ 9 ] ;
@@ -358,11 +418,22 @@ public void Update() {
358418 continue ;
359419
360420 if ( ( value & 0x80 ) > 0 ) {
361- // automatic operation (value can't be read)
362- controls [ i ] = null ;
421+ // automatic operation (value can't be read)
422+ controls [ i ] = null ;
363423 } else {
364424 // software operation
365- controls [ i ] = ( float ) Math . Round ( ( value & 0x7F ) * 100.0f / 0x7F ) ;
425+ if ( chip == Chip . IT8721F ||
426+ chip == Chip . IT8665E ||
427+ chip == Chip . IT8686E ||
428+ chip == Chip . IT8688E ||
429+ chip == Chip . IT879XE )
430+ {
431+ value = ReadByte ( FAN_PWM_CTRL_EXT_REG [ i ] , out valid ) ;
432+ if ( valid )
433+ controls [ i ] = ( float ) Math . Round ( value * 100.0f / 0xFF ) ;
434+ } else {
435+ controls [ i ] = ( float ) Math . Round ( ( value & 0x7F ) * 100.0f / 0x7F ) ;
436+ }
366437 }
367438 }
368439
0 commit comments