Provide battery and peci info through acpi pmc interface
This commit is contained in:
		| @@ -1,17 +1,42 @@ | ||||
| #include <board/acpi.h> | ||||
| #include <board/battery.h> | ||||
| #include <board/peci.h> | ||||
| #include <common/debug.h> | ||||
|  | ||||
| uint8_t acpi_read(uint8_t addr) { | ||||
|     uint8_t data = 0; | ||||
|     DEBUG("acpi_read %02X = %02X\n", addr, data); | ||||
|  | ||||
|     #define ACPI_8(K, V) \ | ||||
|     case (K): \ | ||||
|         data = (uint8_t)(V); \ | ||||
|         break | ||||
|  | ||||
|     #define ACPI_16(K, V) \ | ||||
|         ACPI_8(K, V); \ | ||||
|         ACPI_8((K) + 1, (V) >> 8) | ||||
|  | ||||
|     #define ACPI_32(K, V) \ | ||||
|         ACPI_16(K, V); \ | ||||
|         ACPI_16((K) + 2, (V) >> 16) | ||||
|  | ||||
|     switch (addr) { | ||||
|         //TODO | ||||
|         ACPI_16(0x00, battery_temp); | ||||
|         ACPI_16(0x02, battery_voltage); | ||||
|         ACPI_16(0x04, battery_current); | ||||
|         ACPI_16(0x06, battery_charge); | ||||
|  | ||||
|         ACPI_16(0x10, peci_offset); | ||||
|         ACPI_16(0x12, peci_temp); | ||||
|         ACPI_8 (0x14, peci_duty); | ||||
|     } | ||||
|  | ||||
|     DEBUG("acpi_read %02X = %02X\n", addr, data); | ||||
|     return data; | ||||
| } | ||||
|  | ||||
| void acpi_write(uint8_t addr, uint8_t data) { | ||||
|     DEBUG("acpi_write %02X = %02X\n", addr, data); | ||||
|  | ||||
|     switch (addr) { | ||||
|     //TODO | ||||
|     } | ||||
|   | ||||
| @@ -40,6 +40,30 @@ int battery_charger_enable(void) { | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| uint16_t battery_temp = 0; | ||||
| uint16_t battery_voltage = 0; | ||||
| uint16_t battery_current = 0; | ||||
| uint16_t battery_charge = 0; | ||||
|  | ||||
| void battery_event(void) { | ||||
|     int res = 0; | ||||
|  | ||||
|     #define command(N, V) { \ | ||||
|         res = smbus_read(0x0B, V, &N); \ | ||||
|         if (res < 0) { \ | ||||
|             N = 0; \ | ||||
|             return; \ | ||||
|         } \ | ||||
|     } | ||||
|  | ||||
|     command(battery_temp, 0x08); | ||||
|     command(battery_voltage, 0x09); | ||||
|     command(battery_current, 0x0A); | ||||
|     command(battery_charge, 0x0D); | ||||
|  | ||||
|     #undef command | ||||
| } | ||||
|  | ||||
| void battery_debug(void) { | ||||
|     uint16_t data = 0; | ||||
|     int res = 0; | ||||
|   | ||||
| @@ -1,8 +1,16 @@ | ||||
| #ifndef _BOARD_BATTERY_H | ||||
| #define _BOARD_BATTERY_H | ||||
|  | ||||
| #include <stdint.h> | ||||
|  | ||||
| extern uint16_t battery_temp; | ||||
| extern uint16_t battery_voltage; | ||||
| extern uint16_t battery_current; | ||||
| extern uint16_t battery_charge; | ||||
|  | ||||
| void battery_charger_disable(void); | ||||
| void battery_charger_enable(void); | ||||
| void battery_event(void); | ||||
| void battery_debug(void); | ||||
|  | ||||
| #endif // _BOARD_BATTERY_H | ||||
|   | ||||
							
								
								
									
										12
									
								
								src/board/system76/galp3-c/include/board/peci.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/board/system76/galp3-c/include/board/peci.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| #ifndef _BOARD_PECI_H | ||||
| #define _BOARD_PECI_H | ||||
|  | ||||
| #include <ec/peci.h> | ||||
|  | ||||
| extern int16_t peci_offset; | ||||
| extern int16_t peci_temp; | ||||
| extern uint8_t peci_duty; | ||||
|  | ||||
| void peci_event(void); | ||||
|  | ||||
| #endif // _BOARD_PECI_H | ||||
| @@ -8,6 +8,7 @@ | ||||
| #include <board/gctrl.h> | ||||
| #include <board/kbc.h> | ||||
| #include <board/kbscan.h> | ||||
| #include <board/peci.h> | ||||
| #include <board/pmc.h> | ||||
| #include <board/ps2.h> | ||||
| #include <board/pwm.h> | ||||
| @@ -54,83 +55,6 @@ void init(void) { | ||||
|     GCR2 |= (1 << 4); | ||||
| } | ||||
|  | ||||
| // PECI information can be found here: https://www.intel.com/content/dam/www/public/us/en/documents/design-guides/core-i7-lga-2011-guide.pdf | ||||
| void peci_event(void) { | ||||
|     static volatile uint8_t __xdata __at(0x3000) HOSTAR; | ||||
|     static volatile uint8_t __xdata __at(0x3001) HOCTLR; | ||||
|     static volatile uint8_t __xdata __at(0x3002) HOCMDR; | ||||
|     static volatile uint8_t __xdata __at(0x3003) HOTRADDR; | ||||
|     static volatile uint8_t __xdata __at(0x3004) HOWRLR; | ||||
|     static volatile uint8_t __xdata __at(0x3005) HORDLR; | ||||
|     static volatile uint8_t __xdata __at(0x3006) HOWRDR; | ||||
|     static volatile uint8_t __xdata __at(0x3007) HORDDR; | ||||
|     static volatile uint8_t __xdata __at(0x3008) HOCTL2R; | ||||
|     static volatile uint8_t __xdata __at(0x3009) RWFCSV; | ||||
|  | ||||
|     // Wait for completion | ||||
|     while (HOSTAR & 1) {} | ||||
|     // Clear status | ||||
|     HOSTAR = HOSTAR; | ||||
|  | ||||
|     // Enable PECI, clearing data fifo's | ||||
|     HOCTLR = (1 << 5) | (1 << 3); | ||||
|     // Set address to default | ||||
|     HOTRADDR = 0x30; | ||||
|     // Set write length | ||||
|     HOWRLR = 1; | ||||
|     // Set read length | ||||
|     HORDLR = 2; | ||||
|     // Set command | ||||
|     HOCMDR = 1; | ||||
|     // Start transaction | ||||
|     HOCTLR |= 1; | ||||
|  | ||||
|     // Wait for completion | ||||
|     while (HOSTAR & 1) {} | ||||
|  | ||||
|     if (HOSTAR & (1 << 1)) { | ||||
|         // Use result if finished successfully | ||||
|         uint8_t low = HORDDR; | ||||
|         uint8_t high = HORDDR; | ||||
|         int16_t offset = ((int16_t)high << 8) | (int16_t)low; | ||||
|  | ||||
|         // Tjunction = 100C for i7-8565U (and probably the same for all WHL-U) | ||||
|         #define T_JUNCTION 10000 | ||||
|         int16_t temp = T_JUNCTION + offset; | ||||
|  | ||||
|         // Set fan based on temp, adapted from | ||||
|         // https://github.com/pop-os/system76-power/blob/master/src/fan.rs#L218 | ||||
|         uint8_t duty = 0; | ||||
|         if (temp >= 9000) { | ||||
|             // 90C = 100% | ||||
|             duty = 255; | ||||
|         } else if (temp >= 8000) { | ||||
|             // 80C = 50% | ||||
|             duty = 128; | ||||
|         } else if (temp >= 7500) { | ||||
|             // 75C = 45% | ||||
|             duty = 115; | ||||
|         } else if (temp >= 6500) { | ||||
|             // 65C = 40% | ||||
|             duty = 102; | ||||
|         } else if (temp >= 5500) { | ||||
|             // 55C = 35% | ||||
|             duty = 90; | ||||
|         } else if (temp >= 4500) { | ||||
|             // 45C = 30% | ||||
|             duty = 77; | ||||
|         } | ||||
|  | ||||
|         if (duty != DCR2) { | ||||
|             DCR2 = duty; | ||||
|             DEBUG("PECI offset=%d, temp=%d = %d\n", offset, temp, duty); | ||||
|         } | ||||
|     } else { | ||||
|         // Default to 50% if there is an error | ||||
|         DCR2 = 128; | ||||
|     } | ||||
| } | ||||
|  | ||||
| void ac_adapter() { | ||||
|     static struct Gpio __code ACIN_N = GPIO(B, 6); | ||||
|     static struct Gpio __code LED_ACIN = GPIO(C, 7); | ||||
| @@ -451,6 +375,7 @@ void main(void) { | ||||
|     for(;;) { | ||||
|         peci_event(); | ||||
|         ac_adapter(); | ||||
|         battery_event(); | ||||
|         power_button(); | ||||
|         kbscan_event(); | ||||
|         touchpad_event(&PS2_3); | ||||
|   | ||||
							
								
								
									
										77
									
								
								src/board/system76/galp3-c/peci.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								src/board/system76/galp3-c/peci.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,77 @@ | ||||
| #include <board/peci.h> | ||||
| #include <common/debug.h> | ||||
| #include <ec/pwm.h> | ||||
|  | ||||
| int16_t peci_offset = 0; | ||||
| int16_t peci_temp = 0; | ||||
| uint8_t peci_duty = 0; | ||||
|  | ||||
| // Tjunction = 100C for i7-8565U (and probably the same for all WHL-U) | ||||
| #define T_JUNCTION 10000 | ||||
|  | ||||
| // PECI information can be found here: https://www.intel.com/content/dam/www/public/us/en/documents/design-guides/core-i7-lga-2011-guide.pdf | ||||
| void peci_event(void) { | ||||
|     // Wait for completion | ||||
|     while (HOSTAR & 1) {} | ||||
|     // Clear status | ||||
|     HOSTAR = HOSTAR; | ||||
|  | ||||
|     // Enable PECI, clearing data fifo's | ||||
|     HOCTLR = (1 << 5) | (1 << 3); | ||||
|     // Set address to default | ||||
|     HOTRADDR = 0x30; | ||||
|     // Set write length | ||||
|     HOWRLR = 1; | ||||
|     // Set read length | ||||
|     HORDLR = 2; | ||||
|     // Set command | ||||
|     HOCMDR = 1; | ||||
|     // Start transaction | ||||
|     HOCTLR |= 1; | ||||
|  | ||||
|     // Wait for completion | ||||
|     while (HOSTAR & 1) {} | ||||
|  | ||||
|     if (HOSTAR & (1 << 1)) { | ||||
|         // Use result if finished successfully | ||||
|         uint8_t low = HORDDR; | ||||
|         uint8_t high = HORDDR; | ||||
|         peci_offset = ((int16_t)high << 8) | (int16_t)low; | ||||
|         peci_temp = T_JUNCTION + peci_offset; | ||||
|  | ||||
|         // Set fan based on temp, adapted from | ||||
|         // https://github.com/pop-os/system76-power/blob/master/src/fan.rs#L218 | ||||
|         if (peci_temp >= 9000) { | ||||
|             // 90C = 100% | ||||
|             peci_duty = 255; | ||||
|         } else if (peci_temp >= 8000) { | ||||
|             // 80C = 50% | ||||
|             peci_duty = 128; | ||||
|         } else if (peci_temp >= 7500) { | ||||
|             // 75C = 45% | ||||
|             peci_duty = 115; | ||||
|         } else if (peci_temp >= 6500) { | ||||
|             // 65C = 40% | ||||
|             peci_duty = 102; | ||||
|         } else if (peci_temp >= 5500) { | ||||
|             // 55C = 35% | ||||
|             peci_duty = 90; | ||||
|         } else if (peci_temp >= 4500) { | ||||
|             // 45C = 30% | ||||
|             peci_duty = 77; | ||||
|         } else { | ||||
|             // < 45C = 0% | ||||
|             peci_duty = 0; | ||||
|         } | ||||
|     } else { | ||||
|         // Default to 50% if there is an error | ||||
|         peci_offset = 0; | ||||
|         peci_temp = 0; | ||||
|         peci_duty = 128; | ||||
|     } | ||||
|  | ||||
|     if (peci_duty != DCR2) { | ||||
|         DCR2 = peci_duty; | ||||
|         DEBUG("PECI offset=%d, temp=%d = %d\n", peci_offset, peci_temp, peci_duty); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										17
									
								
								src/ec/it8587e/include/ec/peci.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								src/ec/it8587e/include/ec/peci.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| #ifndef _EC_PECI_H | ||||
| #define _EC_PECI_H | ||||
|  | ||||
| #include <stdint.h> | ||||
|  | ||||
| static volatile uint8_t __xdata __at(0x3000) HOSTAR; | ||||
| static volatile uint8_t __xdata __at(0x3001) HOCTLR; | ||||
| static volatile uint8_t __xdata __at(0x3002) HOCMDR; | ||||
| static volatile uint8_t __xdata __at(0x3003) HOTRADDR; | ||||
| static volatile uint8_t __xdata __at(0x3004) HOWRLR; | ||||
| static volatile uint8_t __xdata __at(0x3005) HORDLR; | ||||
| static volatile uint8_t __xdata __at(0x3006) HOWRDR; | ||||
| static volatile uint8_t __xdata __at(0x3007) HORDDR; | ||||
| static volatile uint8_t __xdata __at(0x3008) HOCTL2R; | ||||
| static volatile uint8_t __xdata __at(0x3009) RWFCSV; | ||||
|  | ||||
| #endif // _EC_PECI_H | ||||
		Reference in New Issue
	
	Block a user