#include <thermal/fan.h>
#include <power/regulator_5v.h>
#include <soc/bpmp.h>
#include <soc/clock.h>
#include <soc/fuse.h>
#include <soc/gpio.h>
#include <soc/hw_init.h>
#include <soc/pinmux.h>
#include <soc/timer.h>
#include <soc/t210.h>
void fan_set_duty(u32 duty)
{
static bool fan_init = false;
static u16 curr_duty = -1;
if (duty > 236)
duty = 236;
if (curr_duty == duty)
return;
curr_duty = duty;
if (!fan_init)
{
u32 pull_resistor = hw_get_chip_id() == GP_HIDREV_MAJOR_T210 ? PINMUX_PULL_UP : 0;
PINMUX_AUX(PINMUX_AUX_CAM1_PWDN) = PINMUX_TRISTATE | PINMUX_INPUT_ENABLE | pull_resistor | 1;
gpio_direction_input(GPIO_PORT_S, GPIO_PIN_7);
if (fuse_read_hw_type() == FUSE_NX_HW_TYPE_AULA)
clock_enable_pwm();
PWM(PWM_CONTROLLER_PWM_CSR_1) = PWM_CSR_EN | (0x100 << 16);
PINMUX_AUX(PINMUX_AUX_LCD_GPIO2) = 1;
gpio_config(GPIO_PORT_V, GPIO_PIN_4, GPIO_MODE_SPIO);
fan_init = true;
}
u32 inv_duty = 236 - duty;
if (inv_duty == 236)
{
PWM(PWM_CONTROLLER_PWM_CSR_1) = PWM_CSR_EN | (0x100 << 16);
regulator_5v_disable(REGULATOR_5V_FAN);
PINMUX_AUX(PINMUX_AUX_LCD_GPIO2) = PINMUX_INPUT_ENABLE | PINMUX_PARKED |
PINMUX_TRISTATE | PINMUX_PULL_DOWN;
}
else
{
regulator_5v_enable(REGULATOR_5V_FAN);
PWM(PWM_CONTROLLER_PWM_CSR_1) = PWM_CSR_EN | (inv_duty << 16);
PINMUX_AUX(PINMUX_AUX_LCD_GPIO2) = 1;
}
}
void fan_get_speed(u32 *duty, u32 *rpm)
{
if (rpm)
{
u32 irq_count = 0;
bool should_read = true;
int timer = get_tmr_us() + 2000000;
while ((timer - get_tmr_us()) > 0)
{
bool irq_val = gpio_read(GPIO_PORT_S, GPIO_PIN_7);
if (irq_val && should_read)
{
irq_count++;
should_read = false;
}
else if (!irq_val)
should_read = true;
}
irq_count /= 2;
*rpm = irq_count * (60 / 2);
}
if (duty)
*duty = 236 - ((PWM(PWM_CONTROLLER_PWM_CSR_1) >> 16) & 0xFF);
}
void fan_set_from_temp(u32 temp)
{
if (temp >= 52)
fan_set_duty(102);
else if (temp >= 47)
fan_set_duty(76);
else if (temp >= 42)
fan_set_duty(51);
else if (temp <= 39)
fan_set_duty(0);
}