ec/lenovo/h8: Add USB Always On

USB AO is the internal name for the dedicated charging port on
ThinkPads when in S3 or lower.

AOEN (bit 0) is internal name for enabling this feature while AOCF
(bits 2 and 3) is the configuration field. According to Peter Stuge,
AOCF can be configured in this way:

    00 => AC S3 S4 S4 USB on, battery S3 USB on, battery S4 S5 off
    11 => AC S3 S4 S4 USB on, battery S3 S4 S5 USB off
    10, 01 => equivalent to 00

This commit also adds a new configuration field in the CMOS of the
X220 and the X201 to activate this feature. It probably can be also
added to all the ThinkPads that support this functionality.

With this functionality USB devices are able to negotiate full power
from the dedicated port (usually the yellow one) even in S3.

Tested on a X201 and X220 with an Android smartphone: with this
feature enabled it shows "Charging" when connected during S3, without
it it shows "Charging slowly" (or it doesn't charge at all on the
X201).

For some reasons the "AC only" mode doesn't work, so it has been
disabled.

Change-Id: Ie1269a4357e2fbd608ad8b7b8262275914730f6e
Signed-off-by: Nicola Corna <nicola@corna.info>
Reviewed-on: https://review.coreboot.org/17252
Tested-by: build bot (Jenkins)
Reviewed-by: Nico Huber <nico.h@gmx.de>
This commit is contained in:
Nicola Corna 2016-11-05 16:06:59 +01:00 committed by Nico Huber
parent cd2afc0df0
commit f1395d825b
10 changed files with 57 additions and 3 deletions

View File

@ -1,5 +1,6 @@
ifeq ($(CONFIG_EC_LENOVO_H8),y) ifeq ($(CONFIG_EC_LENOVO_H8),y)
ramstage-y += h8.c ramstage-y += h8.c
smm-y += smm.c
endif endif

View File

@ -268,6 +268,8 @@ static void h8_enable(struct device *dev)
ec_write(0x1f, conf->eventf_enable); ec_write(0x1f, conf->eventf_enable);
ec_write(H8_FAN_CONTROL, H8_FAN_CONTROL_AUTO); ec_write(H8_FAN_CONTROL, H8_FAN_CONTROL_AUTO);
ec_write(H8_USB_ALWAYS_ON, ec_read(H8_USB_ALWAYS_ON) &
~H8_USB_ALWAYS_ON_ENABLE);
if (get_option(&val, "wlan") != CB_SUCCESS) if (get_option(&val, "wlan") != CB_SUCCESS)
val = 1; val = 1;

View File

@ -26,6 +26,7 @@ void h8_enable_event(int event);
void h8_disable_event(int event); void h8_disable_event(int event);
int h8_ultrabay_device_present(void); int h8_ultrabay_device_present(void);
u8 h8_build_id_and_function_spec_version(char *buf, u8 buf_len); u8 h8_build_id_and_function_spec_version(char *buf, u8 buf_len);
void h8_usb_always_on(void);
#if !IS_ENABLED (CONFIG_H8_DOCK_EARLY_INIT) #if !IS_ENABLED (CONFIG_H8_DOCK_EARLY_INIT)
void h8_mainboard_init_dock (void); void h8_mainboard_init_dock (void);
@ -64,6 +65,10 @@ void h8_mainboard_init_dock (void);
#define H8_LED_CONTROL_ON 0x80 #define H8_LED_CONTROL_ON 0x80
#define H8_LED_CONTROL_BLINK 0xc0 #define H8_LED_CONTROL_BLINK 0xc0
#define H8_USB_ALWAYS_ON 0x0d
#define H8_USB_ALWAYS_ON_ENABLE 0x01
#define H8_USB_ALWAYS_ON_AC_ONLY 0x0c
#define H8_LED_CONTROL_POWER_LED 0x00 #define H8_LED_CONTROL_POWER_LED 0x00
#define H8_LED_CONTROL_BAT0_LED 0x01 #define H8_LED_CONTROL_BAT0_LED 0x01
#define H8_LED_CONTROL_BAT1_LED 0x02 #define H8_LED_CONTROL_BAT1_LED 0x02

35
src/ec/lenovo/h8/smm.c Normal file
View File

@ -0,0 +1,35 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2016 Nicola Corna <nicola@corna.info>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <ec/acpi/ec.h>
#include <pc80/mc146818rtc.h>
#include "h8.h"
void h8_usb_always_on(void)
{
u8 val;
u8 reg;
if (get_option(&val, "usb_always_on") != CB_SUCCESS)
val = 0;
if (val) {
reg = ec_read(H8_USB_ALWAYS_ON);
reg &= ~H8_USB_ALWAYS_ON_AC_ONLY;
reg |= H8_USB_ALWAYS_ON_ENABLE;
ec_write(H8_USB_ALWAYS_ON, reg);
}
}

View File

@ -15,3 +15,4 @@ sticky_fn=Disable
power_management_beeps=Enable power_management_beeps=Enable
low_battery_beep=Enable low_battery_beep=Enable
sata_mode=AHCI sata_mode=AHCI
usb_always_on=Disable

View File

@ -70,8 +70,8 @@ entries
419 1 e 1 power_management_beeps 419 1 e 1 power_management_beeps
420 1 e 1 low_battery_beep 420 1 e 1 low_battery_beep
421 1 e 9 sata_mode 421 1 e 9 sata_mode
422 1 e 11 usb_always_on
#422 2 r 0 unused #423 1 r 1 unused
# coreboot config options: northbridge # coreboot config options: northbridge
424 3 e 10 gfx_uma_size 424 3 e 10 gfx_uma_size
@ -123,6 +123,8 @@ enumerations
10 3 128M 10 3 128M
10 5 96M 10 5 96M
10 6 160M 10 6 160M
11 0 Disable
11 1 AC and battery
# ----------------------------------------------------------------- # -----------------------------------------------------------------
checksums checksums

View File

@ -178,6 +178,8 @@ int mainboard_smi_apmc(u8 data)
void mainboard_smi_sleep(u8 slp_typ) void mainboard_smi_sleep(u8 slp_typ)
{ {
h8_usb_always_on();
if (slp_typ == 3) { if (slp_typ == 3) {
u8 ec_wake = ec_read(0x32); u8 ec_wake = ec_read(0x32);
/* If EC wake events are enabled, enable wake on EC WAKE GPE. */ /* If EC wake events are enabled, enable wake on EC WAKE GPE. */

View File

@ -10,6 +10,7 @@ wwan=Enable
wlan=Enable wlan=Enable
touchpad=Enable touchpad=Enable
sata_mode=AHCI sata_mode=AHCI
usb_always_on=Disable
fn_ctrl_swap=Disable fn_ctrl_swap=Disable
sticky_fn=Disable sticky_fn=Disable
trackpoint=Enable trackpoint=Enable

View File

@ -69,7 +69,8 @@ entries
418 1 e 1 sticky_fn 418 1 e 1 sticky_fn
419 1 e 1 power_management_beeps 419 1 e 1 power_management_beeps
421 1 e 9 sata_mode 421 1 e 9 sata_mode
#422 2 r 1 unused 422 1 e 12 usb_always_on
#423 1 r 1 unused
# coreboot config options: cpu # coreboot config options: cpu
424 1 e 2 hyper_threading 424 1 e 2 hyper_threading
@ -134,6 +135,8 @@ enumerations
11 4 160M 11 4 160M
11 5 192M 11 5 192M
11 6 224M 11 6 224M
12 0 Disable
12 1 AC and battery
# ----------------------------------------------------------------- # -----------------------------------------------------------------
checksums checksums

View File

@ -133,6 +133,8 @@ int mainboard_smi_apmc(u8 data)
void mainboard_smi_sleep(u8 slp_typ) void mainboard_smi_sleep(u8 slp_typ)
{ {
h8_usb_always_on();
if (slp_typ == 3) { if (slp_typ == 3) {
u8 ec_wake = ec_read(0x32); u8 ec_wake = ec_read(0x32);
/* If EC wake events are enabled, enable wake on EC WAKE GPE. */ /* If EC wake events are enabled, enable wake on EC WAKE GPE. */