summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVic Yang <victoryang@google.com>2012-01-10 15:29:26 +0800
committerVic Yang <victoryang@google.com>2012-01-19 10:54:37 +0800
commitaf8026cdf99aeaa2db7ad6671ef9cad2cef60772 (patch)
tree1f555170c9f1ee5e10a29af991c7b540729906b3
parent37dcc1ab56c6817aae90e244f42ebff1d62bbfcb (diff)
downloadchrome-ec-af8026cdf99aeaa2db7ad6671ef9cad2cef60772.tar.gz
USB Charging control
Implement TPS2543 USB charging control. It contains routine for setting each USB port as dedicated charging port or standard downstream port. To allow us controlling the current distributed to each port, we can select whether to allow 500mA or 1500mA for each port. BUG=chrome-os-partner:7476 TEST=Added USB port definition for BDS and tested GPIO output voltage level is correct for all modes. Change-Id: I19bc4b30d333aa802f868ebfc3a398b30e99ba0f
-rw-r--r--board/bds/board.h3
-rw-r--r--board/link/board.h3
-rw-r--r--common/build.mk2
-rw-r--r--common/main.c2
-rw-r--r--common/usb_charge.c144
-rw-r--r--include/usb_charge.h34
6 files changed, 187 insertions, 1 deletions
diff --git a/board/bds/board.h b/board/bds/board.h
index 18e1c7b8b9..83e40804c1 100644
--- a/board/bds/board.h
+++ b/board/bds/board.h
@@ -58,6 +58,9 @@
#define KB_SCAN_ROW_IRQ LM4_IRQ_GPIOH
#define KB_SCAN_ROW_GPIO LM4_GPIO_H
+/* USB charge port */
+#define USB_CHARGE_PORT_COUNT 0
+
/* GPIO signal list */
enum gpio_signal {
/* Inputs with interrupt handlers are first for efficiency */
diff --git a/board/link/board.h b/board/link/board.h
index e8d4a68424..c2f388661d 100644
--- a/board/link/board.h
+++ b/board/link/board.h
@@ -58,6 +58,9 @@
#define KB_SCAN_ROW_IRQ LM4_IRQ_GPION
#define KB_SCAN_ROW_GPIO LM4_GPIO_N
+/* USB charge port */
+#define USB_CHARGE_PORT_COUNT 2
+
/* GPIO signal definitions. */
enum gpio_signal {
/* Inputs with interrupt handlers are first for efficiency */
diff --git a/common/build.mk b/common/build.mk
index fd17921b08..28d454bf10 100644
--- a/common/build.mk
+++ b/common/build.mk
@@ -7,4 +7,4 @@
common-objs=main.o util.o console.o vboot.o x86_power.o pwm_commands.o
common-objs+=flash_commands.o host_command.o port80.o keyboard.o i8042.o
-common-objs+=memory_commands.o shared_mem.o temp_sensor_commands.o
+common-objs+=memory_commands.o shared_mem.o temp_sensor_commands.o usb_charge.o
diff --git a/common/main.c b/common/main.c
index f62344525f..e400dfde7d 100644
--- a/common/main.c
+++ b/common/main.c
@@ -33,6 +33,7 @@
#include "uart.h"
#include "vboot.h"
#include "watchdog.h"
+#include "usb_charge.h"
/* example task blinking the user LED */
void UserLedBlink(void)
@@ -91,6 +92,7 @@ int main(void)
power_button_init();
keyboard_init();
adc_init();
+ usb_charge_init();
/* Print the reset cause */
uart_printf("\n\n--- Chrome EC initialized! ---\n");
diff --git a/common/usb_charge.c b/common/usb_charge.c
new file mode 100644
index 0000000000..5fcf653915
--- /dev/null
+++ b/common/usb_charge.c
@@ -0,0 +1,144 @@
+/* Copyright (c) 2012 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.
+ */
+
+/* USB charging control module for Chrome EC */
+
+#include "usb_charge.h"
+#include "board.h"
+#include "gpio.h"
+#include "uart.h"
+#include "console.h"
+#include "util.h"
+
+static void usb_charge_set_control_mode(int port_id, int mode)
+{
+#ifdef BOARD_link
+ if (port_id == 0) {
+ gpio_set_level(GPIO_USB1_CTL1, (mode & 0x4) >> 2);
+ gpio_set_level(GPIO_USB1_CTL2, (mode & 0x2) >> 1);
+ gpio_set_level(GPIO_USB1_CTL3, mode & 0x1);
+ }
+ else if (port_id == 1) {
+ gpio_set_level(GPIO_USB2_CTL1, (mode & 0x4) >> 2);
+ gpio_set_level(GPIO_USB2_CTL2, (mode & 0x2) >> 1);
+ gpio_set_level(GPIO_USB2_CTL3, mode & 0x1);
+ }
+#endif
+}
+
+static void usb_charge_set_enabled(int port_id, int en)
+{
+#ifdef BOARD_link
+ if (port_id == 0)
+ gpio_set_level(GPIO_USB1_ENABLE, en);
+ else
+ gpio_set_level(GPIO_USB2_ENABLE, en);
+#endif
+}
+
+static void usb_charge_set_ilim(int port_id, int sel)
+{
+#ifdef BOARD_link
+ if (port_id == 0)
+ gpio_set_level(GPIO_USB1_ILIM_SEL, sel);
+ else
+ gpio_set_level(GPIO_USB2_ILIM_SEL, sel);
+#endif
+}
+
+int usb_charge_set_mode(int port_id, enum usb_charge_mode mode)
+{
+
+ if (port_id >= USB_CHARGE_PORT_COUNT)
+ return EC_ERROR_INVAL;
+
+ if (mode == USB_CHARGE_MODE_DISABLED) {
+ usb_charge_set_enabled(port_id, 0);
+ return EC_SUCCESS;
+ }
+ else
+ usb_charge_set_enabled(port_id, 1);
+
+ switch (mode) {
+ case USB_CHARGE_MODE_CHARGE_AUTO:
+ usb_charge_set_control_mode(port_id, 1);
+ usb_charge_set_ilim(port_id, 1);
+ break;
+ case USB_CHARGE_MODE_CHARGE_BC12:
+ usb_charge_set_control_mode(port_id, 4);
+ break;
+ case USB_CHARGE_MODE_DOWNSTREAM_500MA:
+ usb_charge_set_control_mode(port_id, 2);
+ usb_charge_set_ilim(port_id, 0);
+ break;
+ case USB_CHARGE_MODE_DOWNSTREAM_1500MA:
+ usb_charge_set_control_mode(port_id, 2);
+ usb_charge_set_ilim(port_id, 1);
+ break;
+ default:
+ return EC_ERROR_UNKNOWN;
+ }
+
+ return EC_SUCCESS;
+}
+
+
+/*****************************************************************************/
+/* Console commands */
+
+static int command_set_mode(int argc, char **argv)
+{
+ int port_id = -1;
+ int mode = -1;
+ char* endptr;
+
+ if (argc != 3) {
+ uart_puts("Usage: usbchargemode <port_id> <mode>\n");
+ uart_puts("Modes: 0=Disabled.\n"
+ " 1=Dedicated charging. Auto select.\n"
+ " 2=Dedicated charging. BC 1.2.\n"
+ " 3=Downstream. Max 500mA.\n"
+ " 4=Downstream. Max 1.5A.\n");
+ return EC_ERROR_UNKNOWN;
+ }
+
+ port_id = strtoi(argv[1], &endptr, 0);
+ if (*endptr || port_id < 0 || port_id >= USB_CHARGE_PORT_COUNT) {
+ uart_puts("Invalid port ID.\n");
+ return EC_ERROR_UNKNOWN;
+ }
+
+ mode = strtoi(argv[2], &endptr, 0);
+ if (*endptr || mode < 0 || mode >= USB_CHARGE_MODE_COUNT) {
+ uart_puts("Invalid mode.\n");
+ return EC_ERROR_UNKNOWN;
+ }
+
+ uart_printf("Setting USB mode...\n");
+ return usb_charge_set_mode(port_id, mode);
+}
+
+static const struct console_command console_commands[] = {
+ {"usbchargemode", command_set_mode},
+};
+static const struct console_group command_group = {
+ "USB Charging Control", console_commands, ARRAY_SIZE(console_commands)
+};
+
+
+/*****************************************************************************/
+/* Initialization */
+
+int usb_charge_init(void)
+{
+ int i;
+
+ for (i = 0; i < USB_CHARGE_PORT_COUNT; ++i)
+ usb_charge_set_mode(i, USB_CHARGE_MODE_DOWNSTREAM_500MA);
+
+ console_register_commands(&command_group);
+ return EC_SUCCESS;
+}
+
diff --git a/include/usb_charge.h b/include/usb_charge.h
new file mode 100644
index 0000000000..0b3b7a497f
--- /dev/null
+++ b/include/usb_charge.h
@@ -0,0 +1,34 @@
+/* Copyright (c) 2012 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.
+ */
+
+/* USB charging control module for Chrome EC */
+
+#ifndef __CROS_EC_USB_CHARGE_H
+#define __CROS_EC_USB_CHARGE_H
+
+#include "board.h"
+
+enum usb_charge_mode {
+ /* Disable USB port. */
+ USB_CHARGE_MODE_DISABLED,
+ /* Set USB port to be dedicated charging port, auto selecting charging
+ * schemes. */
+ USB_CHARGE_MODE_CHARGE_AUTO,
+ /* Set USB port to be dedicated charging port following USB Battery
+ * Charging Specification 1.2. */
+ USB_CHARGE_MODE_CHARGE_BC12,
+ /* Set USB port to be standard downstream port, with current limit set
+ * to 500mA or 1500mA. */
+ USB_CHARGE_MODE_DOWNSTREAM_500MA,
+ USB_CHARGE_MODE_DOWNSTREAM_1500MA,
+
+ USB_CHARGE_MODE_COUNT
+};
+
+int usb_charge_set_mode(int usb_port_id, enum usb_charge_mode);
+
+int usb_charge_init(void);
+
+#endif /* __CROS_EC_USB_CHARGE_H */