mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-10 17:41:54 +00:00
spring: support new ID detection circuit
This enables the EC to switch the signals to ANX7808 properly. BUG=chrome-os-partner:18165 TEST=Manual on reworked Spring board BRANCH=none Change-Id: Ib3ff57e17afab9ba8fc78fdb037e65aae844f38b Signed-off-by: Vic Yang <victoryang@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/44897 Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
This commit is contained in:
@@ -27,8 +27,11 @@
|
||||
#define CPRINTF(format, args...) cprintf(CC_USBCHARGE, format, ## args)
|
||||
|
||||
/* Devices that need VBUS power */
|
||||
#define POWERED_DEVICE_TYPE (TSU6721_TYPE_OTG | \
|
||||
TSU6721_TYPE_JIG_UART_ON)
|
||||
#define POWERED_5000_DEVICE_TYPE (TSU6721_TYPE_OTG)
|
||||
#define POWERED_3300_DEVICE_TYPE (TSU6721_TYPE_JIG_UART_ON)
|
||||
|
||||
/* Voltage threshold of D+ for video */
|
||||
#define VIDEO_ID_THRESHOLD 1335
|
||||
|
||||
/* PWM controlled current limit */
|
||||
#define I_LIMIT_500MA 90
|
||||
@@ -50,6 +53,11 @@
|
||||
#define PWM_CTRL_VBUS_LOW 4500
|
||||
#define PWM_CTRL_VBUS_HIGH 4700 /* Must be higher than 4.5V */
|
||||
|
||||
/* Delay for signals to settle */
|
||||
#define DELAY_POWER_MS 20
|
||||
#define DELAY_USB_DP_DN_MS 20
|
||||
#define DELAY_ID_MUX_MS 30
|
||||
|
||||
static int current_dev_type = TSU6721_TYPE_NONE;
|
||||
static int nominal_pwm_duty;
|
||||
static int current_pwm_duty;
|
||||
@@ -163,7 +171,7 @@ static int board_apple_charger_current(void)
|
||||
tsu6721_disable_interrupts();
|
||||
tsu6721_mux(TSU6721_MUX_USB);
|
||||
/* Wait 20ms for signal to stablize */
|
||||
msleep(20);
|
||||
msleep(DELAY_USB_DP_DN_MS);
|
||||
adc_read_all_channels(data);
|
||||
vp = data[ADC_CH_USB_DP_SNS];
|
||||
vn = data[ADC_CH_USB_DN_SNS];
|
||||
@@ -177,6 +185,26 @@ static int board_apple_charger_current(void)
|
||||
return apple_charger_type[type];
|
||||
}
|
||||
|
||||
static int board_probe_video(int device_type)
|
||||
{
|
||||
tsu6721_disable_interrupts();
|
||||
gpio_set_level(GPIO_ID_MUX, 0);
|
||||
msleep(DELAY_ID_MUX_MS);
|
||||
|
||||
if (adc_read_channel(ADC_CH_USB_DP_SNS) > VIDEO_ID_THRESHOLD) {
|
||||
/* Actually an USB host */
|
||||
gpio_set_level(GPIO_ID_MUX, 1);
|
||||
msleep(DELAY_ID_MUX_MS);
|
||||
tsu6721_enable_interrupts();
|
||||
return device_type;
|
||||
} else {
|
||||
/* Not USB host but video */
|
||||
device_type = (device_type & ~TSU6721_TYPE_USB_HOST) |
|
||||
TSU6721_TYPE_JIG_UART_ON;
|
||||
return device_type;
|
||||
}
|
||||
}
|
||||
|
||||
void board_pwm_duty_cycle(int percent)
|
||||
{
|
||||
if (current_ilim_config != ILIM_CONFIG_PWM)
|
||||
@@ -270,6 +298,14 @@ void usb_charge_interrupt(enum gpio_signal signal)
|
||||
task_wake(TASK_ID_PMU_TPS65090_CHARGER);
|
||||
}
|
||||
|
||||
static int usb_has_power_input(int dev_type)
|
||||
{
|
||||
if (dev_type & TSU6721_TYPE_JIG_UART_ON)
|
||||
return 1;
|
||||
return (dev_type & TSU6721_TYPE_VBUS_DEBOUNCED) &&
|
||||
!(dev_type & POWERED_5000_DEVICE_TYPE);
|
||||
}
|
||||
|
||||
static void usb_device_change(int dev_type)
|
||||
{
|
||||
int need_boost;
|
||||
@@ -280,6 +316,13 @@ static void usb_device_change(int dev_type)
|
||||
|
||||
over_current_pwm_duty = 0;
|
||||
|
||||
/*
|
||||
* Video output is recognized incorrectly as USB host. When we see
|
||||
* USB host, probe for video output.
|
||||
*/
|
||||
if (dev_type & TSU6721_TYPE_USB_HOST)
|
||||
dev_type = board_probe_video(dev_type);
|
||||
|
||||
/*
|
||||
* When a power source is removed, record time, power source type,
|
||||
* and PWM duty cycle. Then when we see a power source, compare type
|
||||
@@ -309,24 +352,28 @@ static void usb_device_change(int dev_type)
|
||||
}
|
||||
|
||||
/*
|
||||
* Supply VBUS if needed. If we toggle power output, wait for a moment,
|
||||
* and then update device type. To avoid race condition, check if power
|
||||
* requirement changes during this time.
|
||||
* Supply 5V VBUS if needed. If we toggle power output, wait for a
|
||||
* moment, and then update device type. To avoid race condition, check
|
||||
* if power requirement changes during this time.
|
||||
*/
|
||||
do {
|
||||
if (retry_limit-- <= 0)
|
||||
break;
|
||||
|
||||
need_boost = !(dev_type & POWERED_DEVICE_TYPE);
|
||||
need_boost = !(dev_type & POWERED_5000_DEVICE_TYPE);
|
||||
if (need_boost != gpio_get_level(GPIO_BOOST_EN)) {
|
||||
gpio_set_level(GPIO_BOOST_EN, need_boost);
|
||||
msleep(20);
|
||||
msleep(DELAY_POWER_MS);
|
||||
dev_type = tsu6721_get_device_type();
|
||||
}
|
||||
} while (need_boost == !!(dev_type & POWERED_DEVICE_TYPE));
|
||||
} while (need_boost == !!(dev_type & POWERED_5000_DEVICE_TYPE));
|
||||
|
||||
if ((dev_type & TSU6721_TYPE_VBUS_DEBOUNCED) &&
|
||||
!(dev_type & POWERED_DEVICE_TYPE)) {
|
||||
/* Supply 3.3V VBUS if needed. */
|
||||
if (dev_type & POWERED_3300_DEVICE_TYPE) {
|
||||
pmu_enable_fet(FET_VIDEO, 1, NULL);
|
||||
}
|
||||
|
||||
if (usb_has_power_input(dev_type)) {
|
||||
/* Limit USB port current. 500mA for not listed types. */
|
||||
int current_limit = I_LIMIT_500MA;
|
||||
if (dev_type & TSU6721_TYPE_CHG12)
|
||||
@@ -376,6 +423,25 @@ static void usb_device_change(int dev_type)
|
||||
current_dev_type = dev_type;
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO(victoryang): Get rid of polling loop when ADC watchdog is ready.
|
||||
* See crosbug.com/p/18171
|
||||
*/
|
||||
static void board_usb_monitor_detach(void)
|
||||
{
|
||||
if (!(current_dev_type & TSU6721_TYPE_JIG_UART_ON))
|
||||
return;
|
||||
|
||||
if (adc_read_channel(ADC_CH_USB_DP_SNS) > VIDEO_ID_THRESHOLD) {
|
||||
pmu_enable_fet(FET_VIDEO, 0, NULL);
|
||||
gpio_set_level(GPIO_ID_MUX, 1);
|
||||
msleep(DELAY_ID_MUX_MS);
|
||||
tsu6721_enable_interrupts();
|
||||
usb_device_change(TSU6721_TYPE_NONE);
|
||||
}
|
||||
}
|
||||
DECLARE_HOOK(HOOK_SECOND, board_usb_monitor_detach, HOOK_PRIO_DEFAULT);
|
||||
|
||||
void board_usb_charge_update(int force_update)
|
||||
{
|
||||
int int_val = tsu6721_get_interrupts();
|
||||
|
||||
@@ -69,6 +69,7 @@ enum FASTCHARGE_TIMEOUT {
|
||||
};
|
||||
|
||||
#define FET_BACKLIGHT 1
|
||||
#define FET_VIDEO 2
|
||||
#define FET_WWAN 3
|
||||
#define FET_CAMERA 5
|
||||
#define FET_LCD_PANEL 6
|
||||
|
||||
Reference in New Issue
Block a user