IT8625E programming example, in Chinese: https://icode.best/i/96302341329066 Translation: https://icode-best.translate.goog/i/96302341329066?_x_tr_sl=zh-CN&_x_tr_tl=en https://github.com/mafredri/asustor-platform-driver/issues/2#issuecomment-1370636769 Not the same chip, but blinking control seems to be the same (but no BREATH support): http://www.datasheet39.com/PDF/739483/IT8720F-datasheet.html The frequency table below and the macros and IT87_REG_GP_LED_CTRL_PIN_MAPPING[] are from asustors GPL kernel code (that seems to be very incomplete, which wouldn't really be GPL-conformant..), can be downloaded at: https://sourceforge.net/projects/asgpl/files/ADM4.1.0/4.1.0.RLQ1_and_above/ #define GPLED_TO_LOCATION(GP_LED) ({ ((GP_LED / 10) << 3) + (GP_LED % 10); }) #define LOCATION_TO_GPLED(LOCATION) ({ ((LOCATION >> 3) * 10) + (LOCATION & 0x07); }) static const u8 IT87_REG_GP_LED_CTRL_PIN_MAPPING[] = {0xf8, 0xfa}; (MODE_INDEX) (F9h [7:6]) (F9h [3:1]) (Blink frequency & Duty) (ON/OFF Time) 0 00 000: 4Hz, 50% Duty 0.125s OFF 0.125s ON 1 00 001: 1Hz, 50% Duty 0.5s OFF 0.5s ON 2 00 010: 0.25Hz, 50% Duty 2s OFF 2s ON 3 00 011: 2Hz, 50% Duty 0.25s OFF 0.25s ON 4 00 100: 0.25Hz, 25% Duty 1s OFF 3s ON 5 00 101: 0.25Hz, 75% Duty 3s OFF 1s ON 6 00 110: 0.125Hz, 25% Duty 2s OFF 6s ON 7 00 111: 0.125Hz 75% Duty 6s OFF 2s ON 8 01 XXX 0.4Hz, 20% Duty 0.5s OFF 2s ON 9 10 XXX 0.5 Hz, 50% Duty 1S OFF 1S ON 10 11 XXX 0.125Hz, 50% Duty 4S OFF 4S ON // the following mode is not supported by asustors proprietary kernels: 11 XX XXX but also setting bit F9h/FBh [0] to 1 Always On Bits for GP LED Blinking Pin Mapping Register (Index F8h for LED Blinking 1, FAh for 2) * 7 SMBus Isolation on GP92-95 0: Bypass (Default, AVCC3 ON), 1: Isolation (AVCC3 OFF) On some other chips like IT8720F, this bit was just Reserved * 6 (Reserved) * 5:0 GP LED Blinking 1 Location (from GPLED_TO_LOCATION() macro), see also Location Mapping Table at the end of this file (Note that I couldn't get this to work with other LEDs than GP47, aka green:status) Bits for GP LED Blinking Control Register (Index F9h for LED Blinking 1, FBh for 2), on IT8625E: * 7:6 also frequency selection, see table below * 5 "GP LED Blinking 1 Short Low Pulse Enable" Somehow makes the "On" cycles shorter - seems kinda redundant with the 20/25% duty cycles? * 4 "LED Blinking 1 Pin Mapping Register Clear" 0: Disable 1: Enable "This function is activated when PANSWH# is low for over 4 seconds" PANSWH# = "Main Power Switch Button Input #" apparently? OR GP43, depending on bit 3 of reg 28h (Multi-Function Pin Slection Register), at least on IT8720F * 3:1 frequency selection, see table below * 0 "GP LED Blinking 1 Output Low Enable" "If set to 1, this PIN will always output low and can be used to control the status of non-S3 LEDs. For example, when S0 is set, the output is low and the LED is always on (provided that the LED hardware is set to low-level conduction)." (from translated https://icode.best/i/96302341329066) In practice, at least on my AS5402T, setting this bit seems to make the LED light up constantly, so I'll add this as mode 11 Other chips also support blinking control, but might support fewer modes, maybe only 0-3 or 0-7, and the modes might be different. I *think* that mode 11 for "always on" should work for the vast majority, at least the bit set there was listed in all datasheets (but never really described). On IT8712F, IT8720F, IT8722F, IT8728F, IT8772E IT8781F - IT8783F, IT8783E the blinking control register is slightly different, but (probably?) mostly compatible (for modes 1-7 and 11): * 0 "GP LED blinking X output low enable", same as IT8625E * 1-2 frequency control (0: 4Hz, 1: 1Hz, 2: 0.25Hz, 3: 0.125Hz) * 3 LED blinking short low pulse enable - seems to make the "on" cycles shorter * 4-7 Reserved Apart from the blink configuration mentioned so far, each GPIO Pin must be switched to "alternate function" mode so setting the pin mapping register to it does anything (=> so it can use this blinking feature), and to "Simple I/O function" mode so the GPIO/LED can be controlled by the user. For each GPIO pin up to GP57 there's a bit in an "enable register" for this. That bit being 0 means "alternate mode", 1 means "Simple I/O function" mode. The GPIO sets (or Super I/O sets) 1, 2, 3, 4, 5 use the enable registers C0h, C1h, C2h, C3h, C4h. GPIO set 1 is GP10-GP17, GPIO set 2 is GP20-GP27, etc. So for pin/LED GPxy, the corresponding enable register is 0xC0 + x-1, and the enable bit within the register is y, i.e. value 1 << y. Examples: GP14 => reg 0xC0, bit 4 (value 1 << 4 = 16) GP30 => reg 0xC2, bit 0 (value 1 << 0 = 1) GP47 => reg 0xC3, bit 7 (value 1 << 7 = 128) NOTE: It's quite possible (and probable) that more IT87xx chips behave like this, these are the ones I could find data sheets for. On IT8673F, it's quite different. Everything is still in the GPIO (LDN=07h) space, but the registers are very different (seems to be a rather old chip).. see also http://www.datasheet39.com/PDF/502101/IT8673F-datasheet.html I'm documenting this here for the sake of completeness, but will not implement it. F5h is the (only) register to switch a GPIO between "Simple I/O function" mode and "Alternate function" mode. Like with the other chips, a bit being 0 means "alternate function" and a bit being 1 means "Simple I/O". Bit number 0 is for GPIO10, bit number 7 (1<<7) is for GPIO17. F8h is the "Panel Button De-bounce Control Register/GP LED Blinking 2 Control Register": * 7 GP LED 2 short low pulse enable * 6:5 GP LED 2 frequency control (0: 4Hz, 1: 1Hz, 2: 0.25Hz, 3: 0.125Hz) * 4 GP LED Output low enable * 3 IRQ output mode 0: Edge mode 1: Level mode (?!) * 2 IRQ output enable (0: disable, 1: enable) * 1:0 De-bounce time selection. 0: 8ms, 1: 16ms, 2: 32ms, 3: 64ms (?!) FAh is the "GP LED Blinking 1 Pin Mapping Register", FCh is the same for GP LED Blinking 2 * 7:6 Reserved * 5:0 GP LED Blinking 1 Location Mapping like in the newer chips, but only goes up to 001 111 / GPIO17 FBh is the "GP LED Blinking Control and RING# Pin Mapping Register" * 7 Reserved * 6-4 Location of RING# (whatever that is, something about powering on a machine from Modem or Fax) * 3 GPL LED 1 short low pulse enable * 2-1 GP LED 1 frequency control (0: 4Hz, 1: 1Hz, 2: 0.25Hz, 3: 0.125Hz) * 0 GP LED 1 Output low enabled GPIO LED Location Mapping of IT8673F: 001 000 - GPIO10 (pin 66) 001 001 - GPIO11 (pin 90). Powered by VCCH 001 010 - GPIO12 (pin 73) 001 011 - GPIO13 (pin 72) 001 100 - GPIO14 (pin 71) 001 101 - GPIO15 (pin 70) 001 110 - GPIO16 (pin 69) 001 111 - GPIO17 (pin 68) IT8671F and IT8687R are even more different, just a link for that (they're even older): http://www.datasheet39.com/PDF/637606/IT8687R-datasheet.html ### IT8625E Breath LED Control ### DAh Bits, for Breath LED Control Register 1 * 6:7 (Reserved) * 5:4 BREATH LED Maximum Duty Cycle Select (HMXD) 00b: 40h; 01b: 80h; 10b: C0h; 11b: FFh * 3:2 BREATH LED Duty Decreasing Step (DDS) - same values as DIS * 1:0 BREATH LED Duty Increasing Step (DIS) 00b: 1h; 01b: 2h; 10b: 4h; 11b: 8h DBh Bits, for Breath LED Control Register 2 * 7 BREATH LED BLINK Enable - 0: Disable; 1; Enable Note: Breathing LED function is for LED Blinking 1 only. * 6:4 BREATH LED Maximum Duty Cycle Delay Period (HMXDD) same values as HZDD * 3 (Reserved) * 2:0 BREATH LED Zero Duty Cycle Delay Period (HZDD) 011b: 1/2 s; 100b: 1s; 101b: 2s; 110b: 4s Note: According to https://icode.best/i/96302341329066, BREATH can only be configured for LED1 Furthermore, the BREATH stuff above is only for reference, I didn't implement support for it, and I couldn't find any reference to it in any public data sheet, so it might be only implemented in IT8625E. Location Mapping Table (of IT8720F): Location Description GPIO Set 1 (Simple I/O enable register 0xC0): 001 000 (0x08 = 8) GP10 (pin 84). Powered by VCCH. 001 001 (0x09 = 9) GP11 (pin 34). 001 010 (0x0A = 10) GP12 (pin 33). 001 011 (0x0B = 11) GP13 (pin 32). 001 100 (0x0C = 12) GP14 (pin 31). 001 101 (0x0D = 13) GP15 (pin 3). 001 110 (0x0E = 14) GP16 (pin 2). 001 111 (0x0F = 15) GP17 (pin 28). GPIO Set 2 (Simple I/O enable register 0xC1): 010 000 (0x10 = 16) GP20 (pin 27). Powered by VCCH. 010 001 (0x11 = 17) GP21 (pin 26). Powered by VCCH. 010 010 (0x12 = 18) GP22 (pin 25). Powered by VCCH. 010 011 (0x13 = 19) GP23 (pin 24). Powered by VCCH. 010 100 (0x14 = 20) GP24 (pin 23). Powered by VCCH. 010 101 (0x15 = 21) GP25 (pin 22). Powered by VCCH. 010 110 (0x16 = 22) GP26 (pin 21). Powered by VCCH. 010 111 (0x17 = 23) GP27 (pin 20). Powered by VCCH. GPIO Set 3 (Simple I/O enable register 0xC2): 011 000 (0x18 = 24) GP30 (pin 19). 011 001 (0x19 = 25) GP31 (pin 18). 011 010 (0x1A = 26) GP32 (pin 17). 011 011 (0x1B = 27) GP33 (pin 16). 011 100 (0x1C = 28) GP34 (pin 14). 011 101 (0x1D = 29) GP35 (pin 13). 011 110 (0x1E = 30) GP36 (pin 12). 011 111 (0x1F = 31) GP37 (pin 11). GPIO Set 4 (Simple I/O enable register 0xC3): 100 000 (0x20 = 32) GP40 (pin 79). Powered by VCCH. 100 001 (0x21 = 33) GP41 (pin 78). Powered by VCCH. 100 010 (0x22 = 34) GP42 (pin 76). Powered by VCCH. 100 011 (0x23 = 35) GP43 (pin 75). Powered by VCCH. 100 100 (0x24 = 36) GP44 (pin 72). Powered by VCCH. // XXX: what about 100 101 (37) and GP45 ? (not documented for IT8720F) // at least on IT8722F it's: 100 101 (0x25 = 37) GP45 (pin 71) Powered by VCCH. 100 110 (0x26 = 38) GP46 (pin 70). Powered by VCCH. 100 111 (0x27 = 39) GP47 (pin 66). GPIO Set 5 (Simple I/O enable register 0xC4): 101 000 (0x28 = 40) GP50 (pin 48). 101 001 (0x29 = 41) GP51 (pin 10). 101 010 (0x2A = 42) GP52 (pin 9). 101 011 (0x2B = 43) GP53 (pin 77). Powered by VCCH. 101 100 (0x2C = 44) GP54 (pin 73). Powered by VCCH. 101 101 (0x2D = 45) GP55 (pin 85). Powered by VCCH. 101 110 (0x2E = 46) GP56 (pin 83). Powered by VCCH. 101 111 (0x2F = 47) GP57 (pin 82). Powered by VCCH. Else Reserved