summaryrefslogtreecommitdiff
path: root/driver/bc12/bq24392.c
blob: adae6d61c64a4a9933f54a89b9551499667742c8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/* Copyright 2017 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.
 */

/*
 * BQ24392 USB BC 1.2 Charger Detector driver.
 *
 * NOTE: The driver assumes that CHG_AL_N and SW_OPEN are not connected,
 * therefore the value of CHG_DET indicates whether the source is NOT a
 * low-power standard downstream port (SDP).  In order to use higher currents,
 * the system will have to charge ramp.
 */

#include "charge_manager.h"
#include "common.h"
#include "gpio.h"
#include "task.h"
#include "tcpm.h"
#include "timer.h"
#include "usb_charge.h"
#include "util.h"

struct bq24392_pins {
	enum gpio_signal chip_enable;
	enum gpio_signal chg_det;
};

static const struct bq24392_pins pin_tbl[] = {
	{ GPIO_USB_C0_BC12_VBUS_ON, GPIO_USB_C0_BC12_CHG_DET },
#ifdef HAS_TASK_USB_CHG_P1
	{ GPIO_USB_C1_BC12_VBUS_ON, GPIO_USB_C1_BC12_CHG_DET },
#endif
#ifdef HAS_TASK_USB_CHG_P2
	{ GPIO_USB_C2_BC12_VBUS_ON, GPIO_USB_C2_BC12_CHG_DET },
#endif
};

/**
 * Perform BC1.2 detection and update charge manager.
 *
 * @param port: The Type-C port where VBUS is present.
 */
static void bc12_detect(const int port)
{
	struct charge_port_info new_chg;

	/*
	 * Enable the IC to begin detection and connect switches if
	 * necessary.
	 */
	gpio_set_level(pin_tbl[port].chip_enable, 1);

	new_chg.voltage = USB_CHARGER_VOLTAGE_MV;
#if defined(CONFIG_CHARGE_RAMP) || defined(CONFIG_CHARGE_RAMP_HW)
	/*
	 * Apple or TomTom charger detection can take as long as 600ms.  Wait a
	 * little bit longer for margin.
	 */
	msleep(630);

	/*
	 * The driver assumes that CHG_AL_N and SW_OPEN are not connected,
	 * therefore the value of CHG_DET indicates whether the source is NOT a
	 * low-power standard downstream port (SDP).  The system will have to
	 * ramp the current to determine the limit.
	 */
	new_chg.current = gpio_get_level(pin_tbl[port].chg_det) ? 2400 : 500;
#else
	/*
	 * If the board doesn't support charge ramping, then assume the lowest
	 * denominator; that is assume the charger detected is a weak dedicated
	 * charging port (DCP) which can only supply 500mA.
	 */
	new_chg.current = 500;
#endif /* !defined(CONFIG_CHARGE_RAMP && CONFIG_CHARGE_RAMP_HW) */

	charge_manager_update_charge(CHARGE_SUPPLIER_OTHER, port, &new_chg);
}

/**
 * Turn off the BQ24392 detector.
 *
 * @param port: Which USB Type-C port's BC1.2 detector to turn off.
 */
static void power_down_ic(const int port)
{
	struct charge_port_info no_chg = { 0 };

	/* Turn off the IC. */
	gpio_set_level(pin_tbl[port].chip_enable, 0);

	/* Let charge manager know there's no more charge available. */
	charge_manager_update_charge(CHARGE_SUPPLIER_OTHER, port, &no_chg);
}

/**
 * If VBUS is present, determine the charger type, otherwise power down the IC.
 *
 * @param port: Which USB Type-C port to examine.
 */
static void detect_or_power_down_ic(const int port)
{
	int vbus_present;

#ifdef CONFIG_USB_PD_VBUS_DETECT_TCPC
	vbus_present = tcpm_get_vbus_level(port);
#else
	vbus_present = pd_snk_is_vbus_provided(port);
#endif /* !defined(CONFIG_USB_PD_VBUS_DETECT_TCPC) */

	if (vbus_present)
		bc12_detect(port);
	else
		power_down_ic(port);
}

void usb_charger_task(void *u)
{
	const int port = (intptr_t)u;
	uint32_t evt;

	ASSERT(port >= 0 && port <= 2);

	detect_or_power_down_ic(port);

	while (1) {
		evt = task_wait_event(-1);

		if (evt & USB_CHG_EVENT_VBUS)
			detect_or_power_down_ic(port);
	}
}

void usb_charger_set_switches(int port, enum usb_switch setting)
{
	/* The BQ24392 automatically sets up the USB 2.0 high-speed switches. */
}