Move fan-specific PWM logic to fan module
Better define the scope of the tachometer variables by moving them to the fan module. `fan_update_duty` is renamed to `fan_event` to reflect that it handles more than just updating the PWM duties. Signed-off-by: Tim Crawford <tcrawford@system76.com>
This commit is contained in:
		
				
					committed by
					
						
						Jeremy Soller
					
				
			
			
				
	
			
			
			
						parent
						
							710b4795fb
						
					
				
				
					commit
					85cd3aa9ce
				
			@@ -3,6 +3,7 @@
 | 
				
			|||||||
#include <board/acpi.h>
 | 
					#include <board/acpi.h>
 | 
				
			||||||
#include <board/battery.h>
 | 
					#include <board/battery.h>
 | 
				
			||||||
#include <board/dgpu.h>
 | 
					#include <board/dgpu.h>
 | 
				
			||||||
 | 
					#include <board/fan.h>
 | 
				
			||||||
#include <board/gpio.h>
 | 
					#include <board/gpio.h>
 | 
				
			||||||
#include <board/kbled.h>
 | 
					#include <board/kbled.h>
 | 
				
			||||||
#include <board/lid.h>
 | 
					#include <board/lid.h>
 | 
				
			||||||
@@ -162,13 +163,13 @@ uint8_t acpi_read(uint8_t addr) {
 | 
				
			|||||||
        ACPI_8(0xCC, sci_extra);
 | 
					        ACPI_8(0xCC, sci_extra);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ACPI_8(0xCE, FAN1_PWM);
 | 
					        ACPI_8(0xCE, FAN1_PWM);
 | 
				
			||||||
        ACPI_16(0xD0, pwm_tach0_rpm);
 | 
					        ACPI_16(0xD0, fan1_rpm);
 | 
				
			||||||
#if CONFIG_HAVE_DGPU
 | 
					#if CONFIG_HAVE_DGPU
 | 
				
			||||||
        ACPI_8(0xCD, dgpu_temp);
 | 
					        ACPI_8(0xCD, dgpu_temp);
 | 
				
			||||||
#endif // CONFIG_HAVE_DGPU
 | 
					#endif // CONFIG_HAVE_DGPU
 | 
				
			||||||
#ifdef FAN2_PWM
 | 
					#ifdef FAN2_PWM
 | 
				
			||||||
        ACPI_8(0xCF, FAN2_PWM);
 | 
					        ACPI_8(0xCF, FAN2_PWM);
 | 
				
			||||||
        ACPI_16(0xD2, pwm_tach1_rpm);
 | 
					        ACPI_16(0xD2, fan2_rpm);
 | 
				
			||||||
#endif // FAN2_PWM
 | 
					#endif // FAN2_PWM
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if HAVE_LED_AIRPLANE_N
 | 
					#if HAVE_LED_AIRPLANE_N
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,6 +13,18 @@ bool fan_max = false;
 | 
				
			|||||||
static uint8_t last_fan1_duty = 0;
 | 
					static uint8_t last_fan1_duty = 0;
 | 
				
			||||||
static uint8_t last_fan2_duty = 0;
 | 
					static uint8_t last_fan2_duty = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint16_t fan1_rpm = 0;
 | 
				
			||||||
 | 
					uint16_t fan2_rpm = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TACH_FREQ (CONFIG_CLOCK_FREQ_KHZ * 1000UL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Fan Speed (RPM) = 60 / (1/fs sec * {FnTMRR, FnRLRR} * P)
 | 
				
			||||||
 | 
					// - n: 1 or 2
 | 
				
			||||||
 | 
					// - P: the numbers of square pulses per revolution
 | 
				
			||||||
 | 
					// - fs: sample rate (FreqEC / 128)
 | 
				
			||||||
 | 
					// - {FnTMRR, FnTLRR} = 0000h: Fan Speed is zero
 | 
				
			||||||
 | 
					#define TACH_TO_RPM(x) (60UL * TACH_FREQ / 128UL / 2UL / (x))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define FAN_POINT(T, D) { .temp = (int16_t)(T), .duty = PWM_DUTY(D) }
 | 
					#define FAN_POINT(T, D) { .temp = (int16_t)(T), .duty = PWM_DUTY(D) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if SMOOTH_FANS != 0
 | 
					#if SMOOTH_FANS != 0
 | 
				
			||||||
@@ -219,33 +231,50 @@ static uint8_t fan_get_duty(const struct Fan *const fan, int16_t temp) {
 | 
				
			|||||||
    return duty;
 | 
					    return duty;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void fan_update_duty(void) {
 | 
					static uint16_t fan_get_tach0_rpm(void) {
 | 
				
			||||||
 | 
					    uint16_t rpm = (F1TMRR << 8) | F1TLRR;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (rpm)
 | 
				
			||||||
 | 
					        rpm = TACH_TO_RPM(rpm);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return rpm;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint16_t fan_get_tach1_rpm(void) {
 | 
				
			||||||
 | 
					    uint16_t rpm = (F2TMRR << 8) | F2TLRR;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (rpm)
 | 
				
			||||||
 | 
					        rpm = TACH_TO_RPM(rpm);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return rpm;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void fan_event(void) {
 | 
				
			||||||
#if CONFIG_HAVE_DGPU
 | 
					#if CONFIG_HAVE_DGPU
 | 
				
			||||||
    int16_t sys_temp = MAX(peci_temp, dgpu_temp);
 | 
					    int16_t sys_temp = MAX(peci_temp, dgpu_temp);
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
    int16_t sys_temp = peci_temp;
 | 
					    int16_t sys_temp = peci_temp;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    uint8_t fan1_duty = fan_get_duty(&FAN1, sys_temp);
 | 
					 | 
				
			||||||
#ifdef FAN2_PWM
 | 
					 | 
				
			||||||
    uint8_t fan2_duty = fan_get_duty(&FAN2, sys_temp);
 | 
					 | 
				
			||||||
#endif // FAN2_PWM
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // set FAN1 duty
 | 
					    // set FAN1 duty
 | 
				
			||||||
 | 
					    uint8_t fan1_duty = fan_get_duty(&FAN1, sys_temp);
 | 
				
			||||||
    if (fan1_duty != FAN1_PWM) {
 | 
					    if (fan1_duty != FAN1_PWM) {
 | 
				
			||||||
        TRACE("FAN1 fan_duty_raw=%d\n", fan1_duty);
 | 
					        TRACE("FAN1 fan_duty_raw=%d\n", fan1_duty);
 | 
				
			||||||
        last_fan1_duty = fan1_duty = fan_smooth(last_fan1_duty, fan1_duty);
 | 
					        last_fan1_duty = fan1_duty = fan_smooth(last_fan1_duty, fan1_duty);
 | 
				
			||||||
        FAN1_PWM = fan_max ? MAX_FAN_SPEED : fan1_duty;
 | 
					        FAN1_PWM = fan_max ? MAX_FAN_SPEED : fan1_duty;
 | 
				
			||||||
        TRACE("FAN1 fan_duty_smoothed=%d\n", fan1_duty);
 | 
					        TRACE("FAN1 fan_duty_smoothed=%d\n", fan1_duty);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    fan1_rpm = fan_get_tach0_rpm();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef FAN2_PWM
 | 
					#ifdef FAN2_PWM
 | 
				
			||||||
    // set FAN2 duty
 | 
					    // set FAN2 duty
 | 
				
			||||||
 | 
					    uint8_t fan2_duty = fan_get_duty(&FAN2, sys_temp);
 | 
				
			||||||
    if (fan2_duty != FAN2_PWM) {
 | 
					    if (fan2_duty != FAN2_PWM) {
 | 
				
			||||||
        TRACE("FAN2 fan_duty_raw=%d\n", fan2_duty);
 | 
					        TRACE("FAN2 fan_duty_raw=%d\n", fan2_duty);
 | 
				
			||||||
        last_fan2_duty = fan2_duty = fan_smooth(last_fan2_duty, fan2_duty);
 | 
					        last_fan2_duty = fan2_duty = fan_smooth(last_fan2_duty, fan2_duty);
 | 
				
			||||||
        FAN2_PWM = fan_max ? MAX_FAN_SPEED : fan2_duty;
 | 
					        FAN2_PWM = fan_max ? MAX_FAN_SPEED : fan2_duty;
 | 
				
			||||||
        TRACE("FAN2 fan_duty_smoothed=%d\n", fan2_duty);
 | 
					        TRACE("FAN2 fan_duty_smoothed=%d\n", fan2_duty);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    fan2_rpm = fan_get_tach1_rpm();
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -44,7 +44,12 @@ struct Fan {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
extern bool fan_max;
 | 
					extern bool fan_max;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NOTE: These are used instead of the functions directly for ACPI to prevent
 | 
				
			||||||
 | 
					// double reads of the tachometer values.
 | 
				
			||||||
 | 
					extern uint16_t fan1_rpm;
 | 
				
			||||||
 | 
					extern uint16_t fan2_rpm;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void fan_reset(void);
 | 
					void fan_reset(void);
 | 
				
			||||||
void fan_update_duty(void);
 | 
					void fan_event(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif // _BOARD_FAN_H
 | 
					#endif // _BOARD_FAN_H
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,15 +3,6 @@
 | 
				
			|||||||
#ifndef _BOARD_PWM_H
 | 
					#ifndef _BOARD_PWM_H
 | 
				
			||||||
#define _BOARD_PWM_H
 | 
					#define _BOARD_PWM_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <ec/pwm.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// NOTE: These are used instead of the functions directly for ACPI to prevent
 | 
					 | 
				
			||||||
// double reads of the tachometer values.
 | 
					 | 
				
			||||||
extern int16_t pwm_tach0_rpm;
 | 
					 | 
				
			||||||
extern int16_t pwm_tach1_rpm;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void pwm_init(void);
 | 
					void pwm_init(void);
 | 
				
			||||||
int16_t pwm_get_tach0_rpm(void);
 | 
					 | 
				
			||||||
int16_t pwm_get_tach1_rpm(void);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif // _BOARD_PWM_H
 | 
					#endif // _BOARD_PWM_H
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -137,13 +137,7 @@ void main(void) {
 | 
				
			|||||||
                peci_read_temp();
 | 
					                peci_read_temp();
 | 
				
			||||||
                dgpu_read_temp();
 | 
					                dgpu_read_temp();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                // Update fan speeds
 | 
					                fan_event();
 | 
				
			||||||
                fan_update_duty();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                // NOTE: These values are reported to ACPI. Update them at the
 | 
					 | 
				
			||||||
                // same interval as the fan duties.
 | 
					 | 
				
			||||||
                pwm_tach0_rpm = pwm_get_tach0_rpm();
 | 
					 | 
				
			||||||
                pwm_tach1_rpm = pwm_get_tach1_rpm();
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Only run the following once per interval
 | 
					            // Only run the following once per interval
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,20 +1,9 @@
 | 
				
			|||||||
// SPDX-License-Identifier: GPL-3.0-only
 | 
					// SPDX-License-Identifier: GPL-3.0-only
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <board/pwm.h>
 | 
					#include <board/pwm.h>
 | 
				
			||||||
 | 
					#include <ec/pwm.h>
 | 
				
			||||||
#include <common/macro.h>
 | 
					#include <common/macro.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define TACH_FREQ (CONFIG_CLOCK_FREQ_KHZ * 1000UL)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Fan Speed (RPM) = 60 / (1/fs sec * {FnTMRR, FnRLRR} * P)
 | 
					 | 
				
			||||||
// - n: 1 or 2
 | 
					 | 
				
			||||||
// - P: the numbers of square pulses per revolution
 | 
					 | 
				
			||||||
// - fs: sample rate (FreqEC / 128)
 | 
					 | 
				
			||||||
// - {FnTMRR, FnTLRR} = 0000h: Fan Speed is zero
 | 
					 | 
				
			||||||
#define TACH_TO_RPM(x) (60UL * TACH_FREQ / 128UL / 2UL / (x))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int16_t pwm_tach0_rpm = -1;
 | 
					 | 
				
			||||||
int16_t pwm_tach1_rpm = -1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void pwm_init(void) {
 | 
					void pwm_init(void) {
 | 
				
			||||||
    // Set T0CHSEL to TACH0A and T1CHSEL to TACH1A
 | 
					    // Set T0CHSEL to TACH0A and T1CHSEL to TACH1A
 | 
				
			||||||
    TSWCTLR = 0;
 | 
					    TSWCTLR = 0;
 | 
				
			||||||
@@ -49,21 +38,3 @@ void pwm_init(void) {
 | 
				
			|||||||
    // Enable PWM
 | 
					    // Enable PWM
 | 
				
			||||||
    ZTIER = BIT(1);
 | 
					    ZTIER = BIT(1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
int16_t pwm_get_tach0_rpm(void) {
 | 
					 | 
				
			||||||
    uint16_t rpm = (F1TMRR << 8) | F1TLRR;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (rpm)
 | 
					 | 
				
			||||||
        rpm = TACH_TO_RPM(rpm);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return rpm;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int16_t pwm_get_tach1_rpm(void) {
 | 
					 | 
				
			||||||
    uint16_t rpm = (F2TMRR << 8) | F2TLRR;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (rpm)
 | 
					 | 
				
			||||||
        rpm = TACH_TO_RPM(rpm);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return rpm;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user