summaryrefslogtreecommitdiff
path: root/src/ec
diff options
context:
space:
mode:
authorNicola Corna <nicola@corna.info>2016-11-05 16:06:59 +0100
committerNico Huber <nico.h@gmx.de>2016-11-18 18:14:42 +0100
commitf1395d825be59663913f88ddaf01cbfa6c46afa7 (patch)
treea3c2c2e0fbce8563797d0a7695e4e578e7d5666c /src/ec
parentcd2afc0df034670a83479aded514b22b99124cf5 (diff)
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>
Diffstat (limited to 'src/ec')
-rw-r--r--src/ec/lenovo/h8/Makefile.inc1
-rw-r--r--src/ec/lenovo/h8/h8.c2
-rw-r--r--src/ec/lenovo/h8/h8.h5
-rw-r--r--src/ec/lenovo/h8/smm.c35
4 files changed, 43 insertions, 0 deletions
diff --git a/src/ec/lenovo/h8/Makefile.inc b/src/ec/lenovo/h8/Makefile.inc
index 4829e7b624..da9cee1d9f 100644
--- a/src/ec/lenovo/h8/Makefile.inc
+++ b/src/ec/lenovo/h8/Makefile.inc
@@ -1,5 +1,6 @@
ifeq ($(CONFIG_EC_LENOVO_H8),y)
ramstage-y += h8.c
+smm-y += smm.c
endif
diff --git a/src/ec/lenovo/h8/h8.c b/src/ec/lenovo/h8/h8.c
index b7b9db75c9..cfc3938e3d 100644
--- a/src/ec/lenovo/h8/h8.c
+++ b/src/ec/lenovo/h8/h8.c
@@ -268,6 +268,8 @@ static void h8_enable(struct device *dev)
ec_write(0x1f, conf->eventf_enable);
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)
val = 1;
diff --git a/src/ec/lenovo/h8/h8.h b/src/ec/lenovo/h8/h8.h
index d3803c0700..290db918ec 100644
--- a/src/ec/lenovo/h8/h8.h
+++ b/src/ec/lenovo/h8/h8.h
@@ -26,6 +26,7 @@ void h8_enable_event(int event);
void h8_disable_event(int event);
int h8_ultrabay_device_present(void);
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)
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_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_BAT0_LED 0x01
#define H8_LED_CONTROL_BAT1_LED 0x02
diff --git a/src/ec/lenovo/h8/smm.c b/src/ec/lenovo/h8/smm.c
new file mode 100644
index 0000000000..31009a6926
--- /dev/null
+++ b/src/ec/lenovo/h8/smm.c
@@ -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);
+ }
+}