summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMary Ruthven <mruthven@chromium.org>2016-02-23 14:56:28 -0800
committerchrome-bot <chrome-bot@chromium.org>2016-02-26 21:22:07 -0800
commit9b4f662a8e139a75dc1557d4ccbf6348b43630d8 (patch)
tree44ffc60123897ac0adc0df028814b74a171cea05
parent60552e57b61d036edbb628fcd1debbf0ec087e6e (diff)
downloadchrome-ec-9b4f662a8e139a75dc1557d4ccbf6348b43630d8.tar.gz
lucid: add support to detect BC1.2 suppliers
Use built-in USB periperal to detect BC1.2 suppliers and update the charge manager. BUG=chrome-os-partner:48658 BRANCH=None TEST=manual for lucid. Use a samus as the supplier, and insert the charger into Lucid. Verify that it identifies it as SDP. Use a wall charger and verify that Lucid identifies it as DCP. Change-Id: I7842e9f75874f727837df5bfc28690662caf821c Signed-off-by: Mary Ruthven <mruthven@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/329236 Reviewed-by: Shawn N <shawnn@chromium.org>
-rw-r--r--board/lucid/board.c76
-rw-r--r--board/lucid/board.h1
-rw-r--r--chip/stm32/build.mk1
-rw-r--r--chip/stm32/charger_detect.c55
-rw-r--r--chip/stm32/registers.h9
-rw-r--r--include/charger_detect.h17
-rw-r--r--include/config.h3
7 files changed, 138 insertions, 24 deletions
diff --git a/board/lucid/board.c b/board/lucid/board.c
index d82467bd7e..a536153b42 100644
--- a/board/lucid/board.c
+++ b/board/lucid/board.c
@@ -8,6 +8,7 @@
#include "adc_chip.h"
#include "charge_manager.h"
#include "charge_state.h"
+#include "charger_detect.h"
#include "common.h"
#include "console.h"
#include "extpower.h"
@@ -18,9 +19,11 @@
#include "registers.h"
#include "task.h"
#include "usb_charge.h"
+#include "usb_pd.h"
#include "util.h"
#define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args)
+#define USB_CHG_DETECT_DELAY_US 5000
void board_config_pre_init(void)
{
@@ -40,6 +43,52 @@ void board_config_pre_init(void)
STM32_SYSCFG_CFGR1 |= (1 << 9) | (1 << 10);
}
+static void reset_charge(int port)
+{
+ struct charge_port_info charge_none;
+
+ charge_none.voltage = USB_CHARGER_VOLTAGE_MV;
+ charge_none.current = 0;
+ charge_manager_update_charge(CHARGE_SUPPLIER_PROPRIETARY,
+ port,
+ &charge_none);
+ charge_manager_update_charge(CHARGE_SUPPLIER_BC12_CDP,
+ port,
+ &charge_none);
+ charge_manager_update_charge(CHARGE_SUPPLIER_BC12_DCP,
+ port,
+ &charge_none);
+ charge_manager_update_charge(CHARGE_SUPPLIER_BC12_SDP,
+ port,
+ &charge_none);
+ charge_manager_update_charge(CHARGE_SUPPLIER_OTHER,
+ port,
+ &charge_none);
+}
+
+static void usb_charger_bc12_detect(void)
+{
+ int type;
+ struct charge_port_info charge;
+
+ type = charger_detect_get_device_type();
+ if (gpio_get_level(GPIO_AC_PRESENT) && type) {
+ charge.voltage = USB_CHARGER_VOLTAGE_MV;
+ if (type == CHARGE_SUPPLIER_BC12_CDP)
+ charge.current = 1500;
+ else
+ charge.current = 500;
+
+ charge_manager_update_charge(type, 0, &charge);
+ } else
+ reset_charge(0);
+
+
+ /* notify host of power info change */
+ pd_send_host_event(PD_EVENT_POWER_CHANGE);
+}
+DECLARE_DEFERRED(usb_charger_bc12_detect);
+
static void update_vbus_supplier(int vbus_level)
{
struct charge_port_info charge;
@@ -56,6 +105,7 @@ void vbus_evt(enum gpio_signal signal)
* lucid only has one port and charging is always enabled.
*/
+ hook_call_deferred(usb_charger_bc12_detect, USB_CHG_DETECT_DELAY_US);
update_vbus_supplier(gpio_get_level(signal));
task_wake(TASK_ID_PD_C0);
@@ -95,32 +145,10 @@ const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports);
static void board_init(void)
{
int i;
- struct charge_port_info charge_none;
/* Initialize all BC1.2 charge suppliers to 0 */
- /*
- * TODO: use built-in USB peripheral to detect BC1.2 suppliers an
- * update charge manager.
- */
- charge_none.voltage = USB_CHARGER_VOLTAGE_MV;
- charge_none.current = 0;
- for (i = 0; i < CONFIG_USB_PD_PORT_COUNT; i++) {
- charge_manager_update_charge(CHARGE_SUPPLIER_PROPRIETARY,
- i,
- &charge_none);
- charge_manager_update_charge(CHARGE_SUPPLIER_BC12_CDP,
- i,
- &charge_none);
- charge_manager_update_charge(CHARGE_SUPPLIER_BC12_DCP,
- i,
- &charge_none);
- charge_manager_update_charge(CHARGE_SUPPLIER_BC12_SDP,
- i,
- &charge_none);
- charge_manager_update_charge(CHARGE_SUPPLIER_OTHER,
- i,
- &charge_none);
- }
+ for (i = 0; i < CONFIG_USB_PD_PORT_COUNT; i++)
+ reset_charge(i);
/* Enable charge status interrupt */
gpio_enable_interrupt(GPIO_CHARGE_STATUS);
diff --git a/board/lucid/board.h b/board/lucid/board.h
index f9fd68c5b1..2163d28517 100644
--- a/board/lucid/board.h
+++ b/board/lucid/board.h
@@ -50,6 +50,7 @@
#define CONFIG_LOW_POWER_IDLE
#define CONFIG_LTO
#define CONFIG_STM_HWTIMER32
+#define CONFIG_STM32_CHARGER_DETECT
#undef CONFIG_TASK_PROFILING
#define CONFIG_USB_POWER_DELIVERY
#define CONFIG_USB_PD_ALT_MODE
diff --git a/chip/stm32/build.mk b/chip/stm32/build.mk
index 53b48b6ab5..6878c76065 100644
--- a/chip/stm32/build.mk
+++ b/chip/stm32/build.mk
@@ -50,6 +50,7 @@ chip-$(CHIP_FAMILY_STM32F0)+=flash-f.o
chip-$(CHIP_FAMILY_STM32F3)+=flash-f.o
endif
chip-$(CONFIG_ADC)+=adc-$(CHIP_FAMILY).o
+chip-$(CONFIG_STM32_CHARGER_DETECT)+=charger_detect.o
chip-$(CONFIG_DEBUG_PRINTF)+=debug_printf.o
chip-$(CONFIG_PWM)+=pwm.o
chip-$(CONFIG_USB)+=usb.o usb-$(CHIP_FAMILY).o usb_endpoints.o
diff --git a/chip/stm32/charger_detect.c b/chip/stm32/charger_detect.c
new file mode 100644
index 0000000000..b32b9f3ac0
--- /dev/null
+++ b/chip/stm32/charger_detect.c
@@ -0,0 +1,55 @@
+/* Copyright 2016 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+/* Detect what adapter is connected */
+
+#include "charge_manager.h"
+#include "hooks.h"
+#include "registers.h"
+#include "timer.h"
+
+static void enable_usb(void)
+{
+ /* Enable USB device clock. */
+ STM32_RCC_APB1ENR |= STM32_RCC_PB1_USB;
+}
+DECLARE_HOOK(HOOK_INIT, enable_usb, HOOK_PRIO_DEFAULT);
+
+static void disable_usb(void)
+{
+ /* Disable USB device clock. */
+ STM32_RCC_APB1ENR &= ~STM32_RCC_PB1_USB;
+}
+DECLARE_HOOK(HOOK_SYSJUMP, disable_usb, HOOK_PRIO_DEFAULT);
+
+static uint16_t detect_type(uint16_t det_type)
+{
+ STM32_USB_BCDR &= 0;
+ usleep(1);
+ STM32_USB_BCDR |= (STM32_USB_BCDR_BCDEN | det_type);
+ usleep(1);
+ STM32_USB_BCDR &= ~(STM32_USB_BCDR_BCDEN | det_type);
+ return STM32_USB_BCDR;
+}
+
+
+int charger_detect_get_device_type(void)
+{
+ uint16_t pdet_result;
+
+ if (!(detect_type(STM32_USB_BCDR_DCDEN) & STM32_USB_BCDR_DCDET))
+ return CHARGE_SUPPLIER_PD;
+
+ pdet_result = detect_type(STM32_USB_BCDR_PDEN);
+ /* TODO: add support for detecting proprietary chargers. */
+ if (pdet_result & STM32_USB_BCDR_PDET) {
+ if (detect_type(STM32_USB_BCDR_SDEN) & STM32_USB_BCDR_SDET)
+ return CHARGE_SUPPLIER_BC12_DCP;
+ else
+ return CHARGE_SUPPLIER_BC12_CDP;
+ } else if (pdet_result & STM32_USB_BCDR_PS2DET)
+ return CHARGE_SUPPLIER_PROPRIETARY;
+ else
+ return CHARGE_SUPPLIER_BC12_SDP;
+}
diff --git a/chip/stm32/registers.h b/chip/stm32/registers.h
index 57fb2a9ec0..283fd44498 100644
--- a/chip/stm32/registers.h
+++ b/chip/stm32/registers.h
@@ -1327,6 +1327,15 @@ typedef volatile struct stm32_dma_regs stm32_dma_regs_t;
#define STM32_USB_LPMCSR REG16(STM32_USB_FS_BASE + 0x54)
#define STM32_USB_BCDR REG16(STM32_USB_FS_BASE + 0x58)
+#define STM32_USB_BCDR_BCDEN (1 << 0)
+#define STM32_USB_BCDR_DCDEN (1 << 1)
+#define STM32_USB_BCDR_PDEN (1 << 2)
+#define STM32_USB_BCDR_SDEN (1 << 3)
+#define STM32_USB_BCDR_DCDET (1 << 4)
+#define STM32_USB_BCDR_PDET (1 << 5)
+#define STM32_USB_BCDR_SDET (1 << 6)
+#define STM32_USB_BCDR_PS2DET (1 << 7)
+
#define EP_MASK 0x0F0F
#define EP_TX_DTOG 0x0040
#define EP_TX_MASK 0x0030
diff --git a/include/charger_detect.h b/include/charger_detect.h
new file mode 100644
index 0000000000..ae2001e418
--- /dev/null
+++ b/include/charger_detect.h
@@ -0,0 +1,17 @@
+/* Copyright 2016 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+/* Detect what adapter is connected */
+
+#ifndef __CROS_CHARGER_DETECT_H
+#define __CROS_CHARGER_DETECT_H
+
+/*
+ * Get attached device type.
+ *
+ * @return CHARGE_SUPPLIER_BC12_* or 0 if the device type was not detected
+ */
+int charger_detect_get_device_type(void);
+
+#endif /* __CROS_CHARGER_DETECT_H */
diff --git a/include/config.h b/include/config.h
index a0a0d5c4cf..1845cd1ff5 100644
--- a/include/config.h
+++ b/include/config.h
@@ -1607,6 +1607,9 @@
/* Use 32-bit timer for clock source on stm32. */
#undef CONFIG_STM_HWTIMER32
+/* Compile charger detect for STM32 */
+#undef CONFIG_STM32_CHARGER_DETECT
+
/* Fake hibernate mode */
#undef CONFIG_STM32L_FAKE_HIBERNATE