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 \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 */