diff options
author | Ting Shen <phoenixshen@google.com> | 2020-03-24 17:36:44 +0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-06-29 13:48:45 +0000 |
commit | 5eb797bf5d4c41743157c1e48bd2c448d2639fc7 (patch) | |
tree | fe621572fed6f33c368198328c64d4b3cb2b0d1f | |
parent | 5212a44c2b5761d016d7411b6a425b4ac672ee0e (diff) | |
download | chrome-ec-5eb797bf5d4c41743157c1e48bd2c448d2639fc7.tar.gz |
driver/bc12: implement mt6360 driver
BUG=b:151802370
TEST=with CL:2189624, verify bc12 detection works correctly
BRANCH=master
Signed-off-by: Ting Shen <phoenixshen@google.com>
Change-Id: I0fee8e7309178be4d933ed5c246ea107ca5931bf
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2117871
Commit-Queue: Ting Shen <phoenixshen@chromium.org>
Tested-by: Ting Shen <phoenixshen@chromium.org>
Reviewed-by: Eric Yilun Lin <yllin@chromium.org>
-rw-r--r-- | driver/bc12/mt6360.c | 174 | ||||
-rw-r--r-- | driver/bc12/mt6360.h | 40 | ||||
-rw-r--r-- | driver/build.mk | 1 | ||||
-rw-r--r-- | include/config.h | 4 |
4 files changed, 218 insertions, 1 deletions
diff --git a/driver/bc12/mt6360.c b/driver/bc12/mt6360.c new file mode 100644 index 0000000000..4f0dbc4cf6 --- /dev/null +++ b/driver/bc12/mt6360.c @@ -0,0 +1,174 @@ +/* Copyright 2020 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. + */ + +#include "charger.h" +#include "charge_manager.h" +#include "console.h" +#include "driver/bc12/mt6360.h" +#include "hooks.h" +#include "i2c.h" +#include "task.h" +#include "timer.h" +#include "usb_charge.h" +#include "usb_pd.h" + +/* Console output macros */ +#define CPRINTF(format, args...) cprintf(CC_CHARGER, format, ## args) +#define CPRINTS(format, args...) \ + cprints(CC_USBCHARGE, "%s " format, "MT6360", ## args) + +static enum ec_error_list mt6360_read8(int reg, int *val) +{ + return i2c_read8(mt6360_config.i2c_port, mt6360_config.i2c_addr_flags, + reg, val); +} + +static enum ec_error_list mt6360_write8(int reg, int val) +{ + return i2c_write8(mt6360_config.i2c_port, mt6360_config.i2c_addr_flags, + reg, val); +} + +static int mt6360_update_bits(int reg, int mask, int val) +{ + int rv; + int reg_val; + + rv = mt6360_read8(reg, ®_val); + if (rv) + return rv; + reg_val &= ~mask; + reg_val |= (mask & val); + rv = mt6360_write8(reg, reg_val); + return rv; +} + +static inline int mt6360_set_bit(int reg, int mask) +{ + return mt6360_update_bits(reg, mask, mask); +} + +static inline int mt6360_clr_bit(int reg, int mask) +{ + return mt6360_update_bits(reg, mask, 0x00); +} + +static int mt6360_get_bc12_device_type(void) +{ + int reg; + + if (mt6360_read8(MT6360_REG_USB_STATUS_1, ®)) + return CHARGE_SUPPLIER_NONE; + + switch (reg & MT6360_MASK_USB_STATUS) { + case MT6360_MASK_SDP: + CPRINTS("BC12 SDP"); + return CHARGE_SUPPLIER_BC12_SDP; + case MT6360_MASK_CDP: + CPRINTS("BC12 CDP"); + return CHARGE_SUPPLIER_BC12_CDP; + case MT6360_MASK_DCP: + CPRINTS("BC12 DCP"); + return CHARGE_SUPPLIER_BC12_DCP; + default: + CPRINTS("BC12 NONE"); + return CHARGE_SUPPLIER_NONE; + } +} + +static int mt6360_get_bc12_ilim(int charge_supplier) +{ + switch (charge_supplier) { + case CHARGE_SUPPLIER_BC12_DCP: + case CHARGE_SUPPLIER_BC12_CDP: + return USB_CHARGER_MAX_CURR_MA; + case CHARGE_SUPPLIER_BC12_SDP: + default: + return USB_CHARGER_MIN_CURR_MA; + } +} + +static int mt6360_enable_bc12_detection(int en) +{ + int rv; + + if (en) { +#ifdef CONFIG_MT6360_BC12_GPIO + gpio_set_level(GPIO_BC12_DET_EN, 1); +#endif + return mt6360_set_bit(MT6360_REG_DEVICE_TYPE, + MT6360_MASK_USBCHGEN); + } + + rv = mt6360_clr_bit(MT6360_REG_DEVICE_TYPE, MT6360_MASK_USBCHGEN); +#ifdef CONFIG_MT6360_BC12_GPIO + gpio_set_level(GPIO_BC12_DET_EN, 0); +#endif + return rv; +} + +static void mt6360_update_charge_manager(int port) +{ + static int current_bc12_type = CHARGE_SUPPLIER_NONE; + int reg; + int new_bc12_type = CHARGE_SUPPLIER_NONE; + + mt6360_read8(MT6360_REG_DPDMIRQ, ®); + + if (pd_snk_is_vbus_provided(port) && (reg & MT6360_MASK_DPDMIRQ_ATTACH)) + new_bc12_type = mt6360_get_bc12_device_type(); + + if (new_bc12_type != current_bc12_type) { + charge_manager_update_charge(current_bc12_type, port, NULL); + + if (new_bc12_type != CHARGE_SUPPLIER_NONE) { + struct charge_port_info chg = { + .current = mt6360_get_bc12_ilim(new_bc12_type), + .voltage = USB_CHARGER_VOLTAGE_MV, + }; + + charge_manager_update_charge(new_bc12_type, port, &chg); + } + + current_bc12_type = new_bc12_type; + } + + /* write clear */ + mt6360_write8(MT6360_REG_DPDMIRQ, reg); +} + +static void mt6360_usb_charger_task(const int port) +{ + mt6360_clr_bit(MT6360_REG_DPDM_MASK1, + MT6360_REG_DPDM_MASK1_CHGDET_DONEI_M); + mt6360_enable_bc12_detection(0); + + while (1) { + uint32_t evt = task_wait_event(-1); + + /* vbus change, start bc12 detection */ + if (evt & USB_CHG_EVENT_VBUS) + mt6360_enable_bc12_detection(1); + + /* detection done, update charge_manager and stop detection */ + if (evt & USB_CHG_EVENT_BC12) { + mt6360_update_charge_manager(port); + mt6360_enable_bc12_detection(0); + } + } +} + +const struct bc12_drv mt6360_drv = { + .usb_charger_task = mt6360_usb_charger_task, +}; + +#ifdef CONFIG_BC12_SINGLE_DRIVER +/* provide a default bc12_ports[] for backward compatibility */ +struct bc12_config bc12_ports[CHARGE_PORT_COUNT] = { + [0 ... (CHARGE_PORT_COUNT - 1)] = { + .drv = &mt6360_drv, + }, +}; +#endif /* CONFIG_BC12_SINGLE_DRIVER */ diff --git a/driver/bc12/mt6360.h b/driver/bc12/mt6360.h new file mode 100644 index 0000000000..1b01f490cb --- /dev/null +++ b/driver/bc12/mt6360.h @@ -0,0 +1,40 @@ +/* Copyright 2020 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. + */ + +#ifndef __CROS_EC_MT6360_H + +#define MT6360_PMU_SLAVE_ADDR_FLAGS 0x34 +#define MT6360_PMIC_SLAVE_ADDR_FLAGS 0x1A +#define MT6360_LDO_SLAVE_ADDR_FLAGS 0x64 +#define MT6360_PD_SLAVE_ADDR_FLAGS 0x4E + +#define MT6360_IRQ_MASK 0x0C + +#define MT6360_REG_DEVICE_TYPE 0x22 +#define MT6360_MASK_USBCHGEN BIT(7) + +#define MT6360_REG_USB_STATUS_1 0x27 +#define MT6360_MASK_USB_STATUS 0x70 +#define MT6360_MASK_SDP 0x20 +#define MT6360_MASK_DCP 0x40 +#define MT6360_MASK_CDP 0x50 + +#define MT6360_REG_DPDMIRQ 0xD6 +#define MT6360_MASK_DPDMIRQ_ATTACH BIT(0) +#define MT6360_MASK_DPDMIRQ_DETACH BIT(1) + +#define MT6360_REG_DPDM_MASK1 0xF6 +#define MT6360_REG_DPDM_MASK1_CHGDET_DONEI_M BIT(0) + +struct mt6360_config_t { + int i2c_port; + int i2c_addr_flags; +}; + +extern const struct mt6360_config_t mt6360_config; + +extern const struct bc12_drv mt6360_drv; + +#endif /* __CROS_EC_MT6360_H */ diff --git a/driver/build.mk b/driver/build.mk index 9a7107b066..368f392ed5 100644 --- a/driver/build.mk +++ b/driver/build.mk @@ -28,6 +28,7 @@ driver-$(CONFIG_ACCEL_LIS2DS)+=accel_lis2ds.o stm_mems_common.o # BC1.2 Charger Detection Devices driver-$(CONFIG_BC12_DETECT_MAX14637)+=bc12/max14637.o +driver-$(CONFIG_BC12_DETECT_MT6360)+=bc12/mt6360.o driver-$(CONFIG_BC12_DETECT_PI3USB9201)+=bc12/pi3usb9201.o driver-$(CONFIG_BC12_DETECT_PI3USB9281)+=bc12/pi3usb9281.o diff --git a/include/config.h b/include/config.h index 93f8a437c4..2d13bb550c 100644 --- a/include/config.h +++ b/include/config.h @@ -864,11 +864,12 @@ #undef CONFIG_CHARGER_MT6370_BACKLIGHT /* - * MT6370 BC1.2 USB-PHY control. + * MT6360/MT6370 BC1.2 USB-PHY control. * If defined, USB-PHY connection is controlled by GPIO_BC12_DET_EN. * Assert GPIO_BC12_DET_EN to detect BC1.2 device, and deassert * GPIO_BC12_DET_EN to mux USB-PHY back. */ +#undef CONFIG_MT6360_BC12_GPIO #undef CONFIG_CHARGER_MT6370_BC12_GPIO /* @@ -4187,6 +4188,7 @@ /* External BC1.2 charger detection devices. */ #undef CONFIG_BC12_DETECT_MAX14637 +#undef CONFIG_BC12_DETECT_MT6360 #undef CONFIG_BC12_DETECT_PI3USB9201 #undef CONFIG_BC12_DETECT_PI3USB9281 /* Number of Pericom PI3USB9281 chips present in system */ |