Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 46 additions & 7 deletions src/app/main/fan.c
Original file line number Diff line number Diff line change
Expand Up @@ -146,23 +146,62 @@ static uint8_t fan_get_duty(const struct Fan *const fan, int16_t temp) {
return duty;
}

static uint16_t fan_get_tach0_rpm(void) {
uint16_t rpm = (F1TMRR << 8) | F1TLRR;
static int16_t fan_get_tach0_rpm(void) {
if (TSWCTLR & T0DVS) {
uint16_t rpm = (F1TMRR << 8) | F1TLRR;

if (rpm)
rpm = TACH_TO_RPM(rpm);
if (rpm)
rpm = TACH_TO_RPM(rpm);

return rpm;
TSWCTLR |= T0DVS;

return rpm;
}

return -1;
}

static uint16_t fan_get_tach1_rpm(void) {
uint16_t rpm = (F2TMRR << 8) | F2TLRR;
static int16_t fan_get_tach1_rpm(void) {
if (TSWCTLR & T1DVS) {
uint16_t rpm = (F2TMRR << 8) | F2TLRR;

if (rpm)
rpm = TACH_TO_RPM(rpm);

TSWCTLR |= T1DVS;

return rpm;
}

return -1;
}

#if CONFIG_EC_ITE_IT8587E
// IT8587 does not have TACH2 control
static int16_t fan_get_tach2_rpm(void) {
uint16_t rpm = (F3TMRR << 8) | F3TLRR;

if (rpm)
rpm = TACH_TO_RPM(rpm);

return rpm;
}
#else
static int16_t fan_get_tach2_rpm(void) {
if (TSWCTLR2 & T2DVS) {
uint16_t rpm = (F3TMRR << 8) | F3TLRR;

if (rpm)
rpm = TACH_TO_RPM(rpm);

TSWCTLR2 |= T2DVS;

return rpm;
}

return -1;
}
#endif

// Update the target duty of the fans based on system temps.
// Interval: 1sec
Expand Down
7 changes: 7 additions & 0 deletions src/ec/ite/include/ec/gpio.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,14 @@ void gpio_debug(void);
volatile uint8_t __xdata __at(0x1600) GCR;
volatile uint8_t __xdata __at(0x16F0) GCR1;
volatile uint8_t __xdata __at(0x16F1) GCR2;
#define TACH2AEN BIT(0)

volatile uint8_t __xdata __at(0x16F2) GCR3;
volatile uint8_t __xdata __at(0x16F3) GCR4;
volatile uint8_t __xdata __at(0x16F4) GCR5;
#define TACH0BEN BIT(0)
#define TACH1BEN BIT(1)

volatile uint8_t __xdata __at(0x16F5) GCR6;
volatile uint8_t __xdata __at(0x16F6) GCR7;
volatile uint8_t __xdata __at(0x16F7) GCR8;
Expand All @@ -56,6 +61,8 @@ volatile uint8_t __xdata __at(0x16FB) GCR12;
volatile uint8_t __xdata __at(0x16FC) GCR13;
volatile uint8_t __xdata __at(0x16FD) GCR14;
volatile uint8_t __xdata __at(0x16FE) GCR15;
#define TACH2BEN BIT(3)

volatile uint8_t __xdata __at(0x16E0) GCR16;
volatile uint8_t __xdata __at(0x16E1) GCR17;
volatile uint8_t __xdata __at(0x16E2) GCR18;
Expand Down
23 changes: 23 additions & 0 deletions src/ec/ite/include/ec/pwm.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,35 @@ volatile uint8_t __xdata __at(0x180F) PCSGR;
volatile uint8_t __xdata __at(0x1823) ZTIER;
// Tachometer switch control register
volatile uint8_t __xdata __at(0x1848) TSWCTLR;
#define T1CHSEL BIT(0)
#define T1DVS BIT(1)
#define T0CHSEL BIT(2)
#define T0DVS BIT(3)

volatile uint8_t __xdata __at(0x1845) F3TLRR; // CFLRR on IT8587
volatile uint8_t __xdata __at(0x1846) F3TMRR; // CFMRR on IT8587

#if CONFIG_EC_ITE_IT5570E || CONFIG_EC_ITE_IT5571E
// Tachometer switch control register 2
volatile uint8_t __xdata __at(0x184F) TSWCTLR2;
#define T2CHSEL BIT(0)
#define T2DVS BIT(1)

// PWM Load Counter Control Register
volatile uint8_t __xdata __at(0x185A) PWMLCCR;
#endif

enum TachCh {
TACH_CH_0A = 0, // GPD6
TACH_CH_1A, // GPD7
TACH_CH_0B, // GPJ2
TACH_CH_1B, // GPJ3
TACH_CH_2A, // GPJ0
#if CONFIG_EC_ITE_IT5570E || CONFIG_EC_ITE_IT5571E
TACH_CH_2B, // GPJ1
#endif
};

void pwm_init(void);

#endif // _EC_PWM_H
55 changes: 53 additions & 2 deletions src/ec/ite/pwm.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,61 @@

#include <ec/pwm.h>
#include <common/macro.h>
#include <ec/gpio.h>

// TODO: Define per-board
// All boards use T0A/T1A, so just declare it here for now based on FAN2_PWM
#ifdef FAN2_PWM
#define NR_TACHS 2
#else
#define NR_TACHS 1
#endif

const enum TachCh board_tachs[NR_TACHS] = {
TACH_CH_0A,
#ifdef FAN2_PWM
TACH_CH_1A,
#endif
};

static void pwm_tach_init(void) {
for (uint8_t i = 0; i < NR_TACHS; i++) {
switch (board_tachs[i]) {
case TACH_CH_0B:
GCR5 |= TACH0BEN;
TSWCTLR |= T0CHSEL;
break;

case TACH_CH_1B:
GCR5 |= TACH1BEN;
TSWCTLR |= T1CHSEL;
break;

case TACH_CH_2A:
GCR2 |= TACH2AEN;
// CHSEL default is `A` (0) at init.
break;

#if CONFIG_EC_ITE_IT5570E || CONFIG_EC_ITE_IT5571E
case TACH_CH_2B:
GCR15 |= TACH2BEN;
TSWCTLR2 |= T2CHSEL;
break;
#endif

// XXX: SDCC 4.2.0 (Ubuntu 24.04) fails with "error 126: unreachable
// code" if these are placed as the first cases.
case TACH_CH_0A:
case TACH_CH_1A:
// T0A/T1A always available
// CHSEL default is `A` (0) at init.
break;
}
}
}

void pwm_init(void) {
// Set T0CHSEL to TACH0A and T1CHSEL to TACH1A
TSWCTLR = 0;
pwm_tach_init();

// Disable PWM
ZTIER = 0;
Expand Down