예제 #1
0
/*CPU_PER_RST_B low to high*/
void imx_KSZ9021RN_reset(void)
{
    //max7310_set_gpio_output(0, 2, GPIO_LOW_LEVEL);
    //hal_delay_us(1000000);
    //max7310_set_gpio_output(0, 2, GPIO_HIGH_LEVEL);
#ifdef BOARD_SABRE_LITE
    // Config gpio3_GPIO[23] to pad EIM_D23(D25)
    gpio_set_gpio(GPIO_PORT3, 23);
    HW_IOMUXC_SW_PAD_CTL_PAD_EIM_DATA23_WR(
            BF_IOMUXC_SW_PAD_CTL_PAD_EIM_DATA23_HYS_V(ENABLED) |
            BF_IOMUXC_SW_PAD_CTL_PAD_EIM_DATA23_PUS_V(100K_OHM_PU) |
            BF_IOMUXC_SW_PAD_CTL_PAD_EIM_DATA23_PUE_V(PULL) |
            BF_IOMUXC_SW_PAD_CTL_PAD_EIM_DATA23_PKE_V(ENABLED) |
            BF_IOMUXC_SW_PAD_CTL_PAD_EIM_DATA23_ODE_V(DISABLED) |
            BF_IOMUXC_SW_PAD_CTL_PAD_EIM_DATA23_SPEED_V(100MHZ) |
            BF_IOMUXC_SW_PAD_CTL_PAD_EIM_DATA23_DSE_V(40_OHM) |
            BF_IOMUXC_SW_PAD_CTL_PAD_EIM_DATA23_SRE_V(SLOW));
    gpio_set_direction(GPIO3, 23, GPIO_GDIR_OUTPUT);
    gpio_set_level(GPIO3, 23, GPIO_LOW_LEVEL);
    hal_delay_us(1000000);      // hold in reset for a delay
    gpio_set_level(GPIO3, 23, GPIO_LOW_HIGH);
#endif
}
예제 #2
0
/* Initialize board. */
static void board_init(void)
{
	/* Enable PD MCU interrupt */
	gpio_enable_interrupt(GPIO_PD_MCU_INT);

	/* Enable VBUS interrupt */
	gpio_enable_interrupt(GPIO_USB_C0_VBUS_WAKE_L);

	/* Enable pericom BC1.2 interrupts */
	gpio_enable_interrupt(GPIO_USB_C0_BC12_INT_L);

	/* Provide AC status to the PCH */
	gpio_set_level(GPIO_PCH_ACOK, extpower_is_present());
}
예제 #3
0
파일: usb_pd_policy.c 프로젝트: thehobn/ec
static int svdm_exit_mode(int port, uint32_t *payload)
{
	if (PD_VDO_VID(payload[0]) == USB_SID_DISPLAYPORT) {
		gpio_set_level(GPIO_PD_SBU_ENABLE, 0);
		alt_mode[PD_AMODE_DISPLAYPORT] = 0;
		pd_log_event(PD_EVENT_VIDEO_DP_MODE, 0, 0, NULL);
	} else if (PD_VDO_VID(payload[0]) == USB_VID_GOOGLE) {
		alt_mode[PD_AMODE_GOOGLE] = 0;
	} else {
		CPRINTF("Unknown exit mode req:0x%08x\n", payload[0]);
	}

	return 1; /* Must return ACK */
}
예제 #4
0
int pd_set_power_supply_ready(int port)
{
	/* Disable charging */
	bd99955_select_input_port(BD99955_CHARGE_PORT_NONE);

	/* Provide VBUS */
	gpio_set_level(port ? GPIO_C1_VOUT_EN_L :
			      GPIO_C0_VOUT_EN_L, 0);

	/* notify host of power info change */
	pd_send_host_event(PD_EVENT_POWER_CHANGE);

	return EC_SUCCESS; /* we are ready */
}
예제 #5
0
static int test_clear_charge_done(void)
{
	/* Lid is open initially. CHARGE_DONE is set. */
	set_lid_open(1);
	msleep(TEST_CHECK_CHARGE_DELAY);
	gpio_set_level(GPIO_CHARGE_DONE, 1);
	TEST_ASSERT(gpio_get_level(GPIO_BASE_CHG_VDD_EN) == 0);
	TEST_ASSERT(gpio_get_level(GPIO_CHARGE_EN) == 0);

	/* Close the lid. Charging should start. */
	set_lid_open(0);
	msleep(TEST_CHECK_CHARGE_DELAY);
	TEST_ASSERT(gpio_get_level(GPIO_BASE_CHG_VDD_EN) == 1);
	TEST_ASSERT(gpio_get_level(GPIO_CHARGE_EN) == 1);
	gpio_set_level(GPIO_CHARGE_DONE, 0);

	/* Charge is done. */
	gpio_set_level(GPIO_CHARGE_DONE, 1);
	TEST_ASSERT(gpio_get_level(GPIO_BASE_CHG_VDD_EN) == 1);
	TEST_ASSERT(gpio_get_level(GPIO_CHARGE_EN) == 0);

	return EC_SUCCESS;
}
예제 #6
0
static int svdm_dp_attention(int port, uint32_t *payload)
{
	int cur_lvl;
	int lvl = PD_VDO_HPD_LVL(payload[1]);
	int irq = PD_VDO_HPD_IRQ(payload[1]);
	enum gpio_signal hpd = PORT_TO_HPD(port);
	cur_lvl = gpio_get_level(hpd);
	if (irq & cur_lvl) {
		gpio_set_level(hpd, 0);
		/* 250 usecs is minimum, 2msec is max */
		if (port)
			hook_call_deferred(hpd1_irq_deferred, 300);
		else
			hook_call_deferred(hpd0_irq_deferred, 300);
	} else if (irq & !cur_lvl) {
		CPRINTF("PE ERR: IRQ_HPD w/ HPD_LOW\n");
		return 0; /* nak */
	} else {
		gpio_set_level(hpd, lvl);
	}
	/* ack */
	return 1;
}
예제 #7
0
static void keyboard_irq_assert(void)
{
#ifdef CONFIG_KEYBOARD_IRQ_GPIO
	/*
	 * Enforce signal-high for long enough for the signal to be pulled high
	 * by the external pullup resistor.  This ensures the host will see the
	 * following falling edge, regardless of the line state before this
	 * function call.
	 */
	gpio_set_level(CONFIG_KEYBOARD_IRQ_GPIO, 1);
	udelay(4);
	/* Generate a falling edge */
	gpio_set_level(CONFIG_KEYBOARD_IRQ_GPIO, 0);
	udelay(4);

	/* Set signal high, now that we've generated the edge */
	gpio_set_level(CONFIG_KEYBOARD_IRQ_GPIO, 1);
#else
	/*
	 * SERIRQ is automatically sent by KBC
	 */
#endif
}
예제 #8
0
파일: board.c 프로젝트: fourier49/BZ_DEV_EC
/**
 * Set active charge port -- only one port can active at a time.
 *
 * @param charge_port    Charge port to enable.
 *
 * Return EC_SUCCESS if charge port is accepted and made active.
 * EC_ERROR_* otherwise.
 */
int board_set_active_charge_port(int charge_port)
{
	/* charge port is a physical port */
	int is_real_port = (charge_port >= 0 &&
			    charge_port < CONFIG_USB_PD_PORT_COUNT);
	/* check if we are source VBUS on the port */
	int source = gpio_get_level(charge_port == 0 ? GPIO_USB_C0_5V_OUT :
						       GPIO_USB_C1_5V_OUT);

	if (is_real_port && source) {
		CPRINTF("Skip enable p%d", charge_port);
		return EC_ERROR_INVAL;
	}

	CPRINTF("New chg p%d", charge_port);

	if (charge_port == CHARGE_PORT_NONE) {
		/*
		 * TODO: currently we only get VBUS knowledge when charge
		 * is enabled. so, when not changing, we need to enable
		 * both ports. but, this is dangerous if you have two
		 * chargers plugged in and you set charge override to -1
		 * then it will enable both sides!
		 */
		gpio_set_level(GPIO_USB_C0_CHARGE_L, 0);
		gpio_set_level(GPIO_USB_C1_CHARGE_L, 0);
	} else {
		/* Make sure non-charging port is disabled */
		gpio_set_level(charge_port ? GPIO_USB_C0_CHARGE_L :
					     GPIO_USB_C1_CHARGE_L, 1);
		/* Enable charging port */
		gpio_set_level(charge_port ? GPIO_USB_C1_CHARGE_L :
					     GPIO_USB_C0_CHARGE_L, 0);
	}

	return EC_SUCCESS;
}
예제 #9
0
파일: board.c 프로젝트: coreboot/chrome-ec
/* Enable or disable input devices, based upon chipset state and tablet mode */
static void enable_input_devices(void)
{
	int kb_enable = 1;
	int tp_enable = 1;

	/* Disable KB & TP if chipset is off */
	if (chipset_in_state(CHIPSET_STATE_ANY_OFF)) {
		kb_enable = 0;
		tp_enable = 0;
	}

	keyboard_scan_enable(kb_enable, KB_SCAN_DISABLE_LID_ANGLE);

	gpio_set_level(GPIO_EN_P3300_TRACKPAD_ODL, !tp_enable);
}
예제 #10
0
파일: th.c 프로젝트: coreboot/chrome-ec
void cts_task(void)
{
	enum cts_rc rc;
	int i;

	gpio_set_flags(GPIO_OUTPUT_TEST, GPIO_ODR_HIGH);

	for (i = 0; i < CTS_TEST_ID_COUNT; i++) {
		gpio_set_level(GPIO_OUTPUT_TEST, 1);
		gpio_set_level(GPIO_CTS_IRQ2, 1);
		sync();
		rc = tests[i].run();
		CPRINTF("\n%s %d\n", tests[i].name, rc);
		cflush();
	}

	CPRINTS("Interrupt test suite finished");
	cflush();

	while (1) {
		watchdog_reload();
		sleep(1);
	}
}
예제 #11
0
void chipset_reset(int cold_reset)
{
	CPRINTS("%s(%d)", __func__, cold_reset);
	if (cold_reset) {
		/*
		 * Drop and restore PWROK.  This causes the PCH to reboot,
		 * regardless of its after-G3 setting.  This type of reboot
		 * causes the PCH to assert PLTRST#, SLP_S3#, and SLP_S5#, so
		 * we actually drop power to the rest of the system (hence, a
		 * "cold" reboot).
		 */

		/* Ignore if PWROK is already low */
		if (gpio_get_level(GPIO_PCH_PWROK) == 0)
			return;

		/* PWROK must deassert for at least 3 RTC clocks = 91 us */
		gpio_set_level(GPIO_PCH_PWROK, 0);
		udelay(100);
		gpio_set_level(GPIO_PCH_PWROK, 1);

	} else {
		/*
		 * Send a RCIN# pulse to the PCH.  This just causes it to
		 * assert INIT# to the CPU without dropping power or asserting
		 * PLTRST# to reset the rest of the system.
		 */

		/*
		 * Pulse must be at least 16 PCI clocks long = 500 ns.
		 */
		gpio_set_level(GPIO_PCH_RCIN_L, 0);
		udelay(10);
		gpio_set_level(GPIO_PCH_RCIN_L, 1);
	}
}
예제 #12
0
/* Initialize board. */
static void board_init(void)
{
	timestamp_t now;
#ifdef CONFIG_SPI_FLASH
	board_init_spi2();
#endif
	now = get_time();
	hpd_prev_level = gpio_get_level(GPIO_DP_HPD);
	hpd_prev_ts = now.val;
	gpio_enable_interrupt(GPIO_DP_HPD);

	gpio_set_level(GPIO_STM_READY, 1); /* factory test only */
	/* Delay needed to allow HDMI MCU to boot. */
	hook_call_deferred(factory_validation_deferred, 200*MSEC);
}
예제 #13
0
파일: board.c 프로젝트: coreboot/chrome-ec
/* Enable or disable input devices, based upon chipset state and tablet mode */
static void enable_input_devices(void)
{
	int kb_enable = 1;
	int tp_enable = 1;

	/* Disable both TP and KB in tablet mode */
	if (!gpio_get_level(GPIO_TABLET_MODE_L))
		kb_enable = tp_enable = 0;
	/* Disable TP if chipset is off */
	else if (chipset_in_state(CHIPSET_STATE_ANY_OFF))
		tp_enable = 0;

	keyboard_scan_enable(kb_enable, KB_SCAN_DISABLE_LID_ANGLE);
	gpio_set_level(GPIO_ENABLE_TOUCHPAD, tp_enable);
}
예제 #14
0
void chipset_reset(int cold_reset)
{
	CPRINTS("%s(%d)", __func__, cold_reset);

	if (cold_reset) {
		if (gpio_get_level(GPIO_SYS_RESET_L) == 0)
			return;
		gpio_set_level(GPIO_SYS_RESET_L, 0);
		/* Debounce time for SYS_RESET_L is 16 ms */
		udelay(20 * MSEC);
		gpio_set_level(GPIO_SYS_RESET_L, 1);
	} else {
		/*
		 * Send a RCIN_PCH_RCIN_L
		 * assert INIT# to the CPU without dropping power or asserting
		 * PLTRST# to reset the rest of the system.
		 */

		/* Pulse must be at least 16 PCI clocks long = 500 ns */
		gpio_set_level(GPIO_PCH_RCIN_L, 0);
		udelay(10);
		gpio_set_level(GPIO_PCH_RCIN_L, 1);
	}
}
예제 #15
0
파일: board.c 프로젝트: coreboot/chrome-ec
/**
 * Set active charge port -- only one port can be active at a time.
 *
 * @param charge_port   Charge port to enable.
 *
 * Returns EC_SUCCESS if charge port is accepted and made active,
 * EC_ERROR_* otherwise.
 */
int board_set_active_charge_port(int charge_port)
{
	/* check if we are source vbus on that port */
	int src = gpio_get_level(GPIO_CHGR_OTG);

	if (charge_port >= 0 && charge_port < CONFIG_USB_PD_PORT_COUNT && src) {
		CPRINTS("Port %d is not a sink, skipping enable", charge_port);
		return EC_ERROR_INVAL;
	}

	/* Enable/disable charging */
	gpio_set_level(GPIO_USBC_CHARGE_EN_L, charge_port == CHARGE_PORT_NONE);

	return EC_SUCCESS;
}
예제 #16
0
파일: board.c 프로젝트: fourier49/BZ_DEV_EC
void vbus_wake_interrupt(enum gpio_signal signal)
{
	CPRINTF("VBUS %d\n", !gpio_get_level(signal));
	gpio_set_level(GPIO_USB_PD_VBUS_WAKE,
		       !gpio_get_level(GPIO_VBUS_WAKE_L));
	/*
	 * TODO(crosbug.com/p/41226):
	 *   rev1/rev2 boards don't have vbus input on ec. vbus_wake is a
	 *   logical OR of two vbus status. to workaround the power status
	 *   issue, wake up both pd tasks on vbus_wake interrupt. a proper
	 *   hardware fix will be in rev3.
	 *   enable TCPC POWER_STATUS ALERT1 can solve this issue too.
	 */
	task_wake(TASK_ID_PD_C0);
	task_wake(TASK_ID_PD_C1);
}
예제 #17
0
static void board_vbus_update_source_current(int port)
{
	enum gpio_signal gpio = port ? GPIO_USB_C1_5V_EN : GPIO_USB_C0_5V_EN;
	int flags = (vbus_rp[port] == TYPEC_RP_1A5 && vbus_en[port]) ?
		(GPIO_INPUT | GPIO_PULL_UP) : (GPIO_OUTPUT | GPIO_PULL_UP);

	/*
	 * Driving USB_Cx_5V_EN high, actually put a 16.5k resistance
	 * (2x 33k in parallel) on the NX5P3290 load switch ILIM pin,
	 * setting a minimum OCP current of 3186 mA.
	 * Putting an internal pull-up on USB_Cx_5V_EN, effectively put a 33k
	 * resistor on ILIM, setting a minimum OCP current of 1505 mA.
	 */
	gpio_set_level(gpio, vbus_en[port]);
	gpio_set_flags(gpio, flags);
}
예제 #18
0
static void factory_validation_deferred(void)
{
	struct mcdp_info info;

	mcdp_enable();

	/* test mcdp via serial to validate function */
	if (!mcdp_get_info(&info) && (MCDP_FAMILY(info.family) == 0x0010) &&
	(MCDP_CHIPID(info.chipid) == 0x2850)) {
		gpio_set_level(GPIO_MCDP_READY, 1);
		pd_log_event(PD_EVENT_VIDEO_CODEC,
			     PD_LOG_PORT_SIZE(0, sizeof(info)),
			     0, &info);
	}

	mcdp_disable();
}
예제 #19
0
파일: board.c 프로젝트: fourier49/BZ_DEV_EC
/**
 * Turn off a PD port's DP output.
 */
void board_typec_dp_off(int port, int *dp_flags)
{
	mutex_lock(&dp_hw_lock);

	if (dp_hw_port == !port) {
		mutex_unlock(&dp_hw_lock);
		return;
	}

	dp_hw_port = PD_PORT_NONE;
	gpio_set_level(GPIO_USB_DP_HPD, 0);
	mutex_unlock(&dp_hw_lock);

	/* Enable the other port if its dp flag is on */
	if (dp_flags[!port] & DP_FLAGS_DP_ON)
		board_typec_dp_on(!port);
}
예제 #20
0
static enum ec_error_list set(const char *name, int value)
{
	enum gpio_signal signal = find_signal_by_name(name);

	if (signal == GPIO_COUNT)
		return EC_ERROR_INVAL;

	if (!gpio_is_implemented(signal))
		return EC_ERROR_INVAL;

	if (!(gpio_get_default_flags(signal) & GPIO_OUTPUT))
		return EC_ERROR_INVAL;

	gpio_set_level(signal, value);

	return EC_SUCCESS;
}
예제 #21
0
파일: board.c 프로젝트: coreboot/chrome-ec
/*
 * Various voltage rails will be enabled / disabled by the PMIC when
 * GPIO_PMIC_SLP_SUS_L changes. We need to delay the disable of V0.85A
 * by approximately 25ms in order to allow V1.00A to sufficiently discharge
 * first.
 *
 * Therefore, after GPIO_PMIC_SLP_SUS_L goes high, ignore the state of
 * the V12_EN pin: Keep V0.85A enabled.
 *
 * When GPIO_PMIC_SLP_SUS_L goes low, delay 25ms, and make V12_EN function
 * as normal - this should result in V0.85A discharging immediately after the
 * i2c write completes.
 */
void chipset_set_pmic_slp_sus_l(int level)
{
	static int previous_level;
	int val;

	gpio_set_level(GPIO_PMIC_SLP_SUS_L, level);

	if (previous_level != level) {
		/* Rising edge: Force V0.85A enable. Falling: Pin control. */
		val = level ? 0x80 : 0;
		if (!level)
			msleep(25);

		i2c_write8(I2C_PORT_PMIC, I2C_ADDR_BD99992, 0x43, val);
		previous_level = level;
	}
}
예제 #22
0
static void set_pwrbtn_to_pch(int high)
{
	/*
	 * If the battery is discharging and low enough we'd shut down the
	 * system, don't press the power button. Also, don't press the
	 * power button if the battery is charging but the battery level
	 * is too low.
	 */
#ifdef CONFIG_CHARGER
	if (chipset_in_state(CHIPSET_STATE_ANY_OFF) && !high &&
	   (charge_want_shutdown() || charge_prevent_power_on())) {
		CPRINTS("PB PCH pwrbtn ignored due to battery level");
		high = 1;
	}
#endif
	CPRINTS("PB PCH pwrbtn=%s", high ? "HIGH" : "LOW");
	gpio_set_level(GPIO_PCH_PWRBTN_L, high);
}
void pd_transition_voltage(int idx)
{
	/* PDO index are starting from 1 */
	switch (idx - 1) {
	case PDO_IDX_20V:
		gpio_set_level(GPIO_PP20000_EN, 1);
		gpio_set_level(GPIO_PPVAR_VBUS_EN, 0);
		break;
	case PDO_IDX_12V:
		gpio_set_level(GPIO_PP12000_EN, 1);
		gpio_set_level(GPIO_PP20000_EN, 0);
		gpio_set_level(GPIO_PPVAR_VBUS_EN, 1);
		break;
	case PDO_IDX_5V:
	default:
		gpio_set_level(GPIO_PP12000_EN, 0);
		gpio_set_level(GPIO_PP20000_EN, 0);
		gpio_set_level(GPIO_PPVAR_VBUS_EN, 1);
	}
}
예제 #24
0
void periph_gpio_init()
{
    gpio_config_t cfg;
    cfg.pin_bit_mask = BIT19;
    cfg.intr_type = (gpio_int_type_t) 0;
    cfg.mode = GPIO_MODE_OUTPUT;
    cfg.pull_down_en = (gpio_pulldown_t) 0;
    cfg.pull_up_en = (gpio_pullup_t) 0;

    gpio_config(&cfg);
    gpio_set_level((gpio_num_t) 19, (uint8_t) 0);

    cfg.pin_bit_mask = BIT26;
    cfg.intr_type = (gpio_int_type_t) 0;
    cfg.mode = GPIO_MODE_INPUT;
    cfg.pull_down_en = (gpio_pulldown_t) 0;
    cfg.pull_up_en = (gpio_pullup_t) 0;
    gpio_config(&cfg);
}
예제 #25
0
static void handle_rsmrst(enum power_state state)
{
	/*
	 * Pass through RSMRST asynchronously, as PCH may not react
	 * immediately to power changes.
	 */
	int rsmrst_in = gpio_get_level(GPIO_RSMRST_L_PGOOD);
	int rsmrst_out = gpio_get_level(GPIO_PCH_RSMRST_L);

	/* Nothing to do. */
	if (rsmrst_in == rsmrst_out)
		return;
	/*
	 * Wait at least 10ms between power signals going high
	 * and deasserting RSMRST to PCH.
	 */
	if (rsmrst_in)
		msleep(10);
	gpio_set_level(GPIO_PCH_RSMRST_L, rsmrst_in);
	CPRINTS("RSMRST: %d", rsmrst_in);
}
예제 #26
0
파일: board.c 프로젝트: coreboot/chrome-ec
/******************************************************************************
 * Initialize board.
 */
static void board_init(void)
{
	/* USB to serial queues */
	queue_init(&usart2_to_usb);
	queue_init(&usb_to_usart2);
	queue_init(&usart3_to_usb);
	queue_init(&usb_to_usart3);
	queue_init(&usart4_to_usb);
	queue_init(&usb_to_usart4);

	/* UART init */
	usart_init(&usart2);
	usart_init(&usart3);
	usart_init(&usart4);

	/* Enable GPIO expander. */
	gpio_set_level(GPIO_TCA6416_RESET_L, 1);

	/* Structured enpoints */
	usb_spi_enable(&usb_spi, 1);
}
예제 #27
0
static int bat_led_set_color(enum led_color color)
{
	switch (color) {
	case LED_OFF:
		gpio_set_level(GPIO_BAT_LED_RED, BAT_LED_OFF);
		gpio_set_level(GPIO_BAT_LED_GREEN, BAT_LED_OFF);
		break;
	case LED_RED:
		gpio_set_level(GPIO_BAT_LED_RED, BAT_LED_ON);
		gpio_set_level(GPIO_BAT_LED_GREEN, BAT_LED_OFF);
		break;
	case LED_AMBER:
		gpio_set_level(GPIO_BAT_LED_RED, BAT_LED_ON);
		gpio_set_level(GPIO_BAT_LED_GREEN, BAT_LED_ON);
		break;
	case LED_GREEN:
		gpio_set_level(GPIO_BAT_LED_RED, BAT_LED_OFF);
		gpio_set_level(GPIO_BAT_LED_GREEN, BAT_LED_ON);
		break;
	default:
		return EC_ERROR_UNKNOWN;
	}
	return EC_SUCCESS;
}
예제 #28
0
static void usb_charge_set_control_mode(int port_id, int mode)
{
#ifdef CONFIG_USB_PORT_POWER_SMART_SIMPLE
	/*
	 * One single shared control signal, so the last mode set to either
	 * port wins.  Also, only CTL1 can be set; the other pins are
	 * hard-wired.
	 */
	gpio_set_level(GPIO_USB_CTL1, mode & 0x4);
#else
	if (port_id == 0) {
		gpio_set_level(GPIO_USB1_CTL1, mode & 0x4);
		gpio_set_level(GPIO_USB1_CTL2, mode & 0x2);
		gpio_set_level(GPIO_USB1_CTL3, mode & 0x1);
	} else {
		gpio_set_level(GPIO_USB2_CTL1, mode & 0x4);
		gpio_set_level(GPIO_USB2_CTL2, mode & 0x2);
		gpio_set_level(GPIO_USB2_CTL3, mode & 0x1);
	}
#endif
}
예제 #29
0
/**
 * Update backlight state.
 */
static void update_backlight(void)
{
	int pch_value;

	pch_value = gpio_get_level(GPIO_PCH_BKLTEN);

	/* Immediately disable the backlight when the lid is closed or the PCH
	 * is instructing the backlight to be disabled. */
	if (!lid_is_open() || !pch_value) {
		/* If there was a scheduled callback pending make sure it picks
		 * up the disabled value. */
		backlight_deferred_value = 0;
		gpio_set_level(GPIO_ENABLE_BACKLIGHT, 0);
		/* Cancel pending hook */
		hook_call_deferred(&set_backlight_value, -1);
		return;
	}
	/* Handle a 0->1 transition by calling a deferred hook. */
	if (pch_value && !backlight_deferred_value) {
		backlight_deferred_value = 1;
		hook_call_deferred(&set_backlight_value, BL_ENABLE_DELAY_US);
	}
}
예제 #30
0
void lcdvcc_interrupt(enum gpio_signal signal)
{
	int pch_value;

	pch_value = gpio_get_level(GPIO_PCH_EDP_VDD_EN);

	/* Immediately disable the LCDVCC when the PCH indicates as such. */
	if (!pch_value) {
		/* If there was a scheduled callback pending make sure it picks
		 * up the disabled value. */
		lcdvcc_en_deferred_value = 0;
		gpio_set_level(GPIO_EC_EDP_VDD_EN, 0);
		/* Cancel pending hook */
		hook_call_deferred(&set_lcdvcc_en_value, -1);
		return;
	}
	/* Handle a 0->1 transition by calling a deferred hook. */
	if (pch_value && !lcdvcc_en_deferred_value) {
		lcdvcc_en_deferred_value = 1;
		hook_call_deferred(&set_lcdvcc_en_value,
				   LCDVCC_ENABLE_DELAY_US);
	}
}