diff options
Diffstat (limited to 'driver/bc12')
-rw-r--r-- | driver/bc12/max14637.c | 254 | ||||
-rw-r--r-- | driver/bc12/max14637.h | 33 | ||||
-rw-r--r-- | driver/bc12/mt6360.c | 576 | ||||
-rw-r--r-- | driver/bc12/mt6360.h | 91 | ||||
-rw-r--r-- | driver/bc12/pi3usb9201.c | 410 | ||||
-rw-r--r-- | driver/bc12/pi3usb9201.h | 47 | ||||
-rw-r--r-- | driver/bc12/pi3usb9281.c | 505 | ||||
-rw-r--r-- | driver/bc12/pi3usb9281.h | 83 |
8 files changed, 0 insertions, 1999 deletions
diff --git a/driver/bc12/max14637.c b/driver/bc12/max14637.c deleted file mode 100644 index b2e734e1c0..0000000000 --- a/driver/bc12/max14637.c +++ /dev/null @@ -1,254 +0,0 @@ -/* 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. - */ - -/* - * MAX14637 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 "max14637.h" -#include "charge_manager.h" -#include "chipset.h" -#include "common.h" -#include "console.h" -#include "gpio.h" -#include "hooks.h" -#include "power.h" -#include "power/cannonlake.h" -#include "task.h" -#include "tcpm/tcpm.h" -#include "timer.h" -#include "usb_charge.h" -#include "usb_pd.h" -#include "util.h" - -#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) - -#if defined(CONFIG_CHARGE_RAMP_SW) || defined(CONFIG_CHARGE_RAMP_HW) -/** - * Returns true if the charger detect pin is activated. - * - * @parm cfg driver for chip to read the charger detect pin for. - * @return 1 if charger detect is activated (high when active high or - * low with active low), otherwise 0. - */ -static int is_chg_det_activated(const struct max14637_config_t * const cfg) -{ - return !!gpio_get_level(cfg->chg_det_pin) ^ - !!(cfg->flags & MAX14637_FLAGS_CHG_DET_ACTIVE_LOW); -} -#endif - -/** - * Activates the Chip Enable GPIO based on the enabled value. - * - * @param cfg driver for chip that will set chip enable gpio. - * @param enable 1 to activate gpio (high for active high and low for active - * low). - */ -static void activate_chip_enable( - const struct max14637_config_t * const cfg, const int enable) -{ - gpio_set_level( - cfg->chip_enable_pin, - !!enable ^ !!(cfg->flags & MAX14637_FLAGS_ENABLE_ACTIVE_LOW)); -} - -/** - * Update BC1.2 detected status to charge manager. - * - * @param port: The Type-C port where VBUS is present. - */ -static void update_bc12_status_to_charger_manager(const int port) -{ - const struct max14637_config_t * const cfg = &max14637_config[port]; - struct charge_port_info new_chg; - - new_chg.voltage = USB_CHARGER_VOLTAGE_MV; -#if defined(CONFIG_CHARGE_RAMP_SW) || defined(CONFIG_CHARGE_RAMP_HW) - /* - * The driver assumes that CHG_AL_N and SW_OPEN are not connected, - * therefore an activated 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. The Type-C spec prohibits - * proprietary methods now, therefore 1500mA is the max. - */ - new_chg.current = is_chg_det_activated(cfg) ? USB_CHARGER_MAX_CURR_MA : - 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_SW && CONFIG_CHARGE_RAMP_HW) */ - - charge_manager_update_charge(CHARGE_SUPPLIER_OTHER, port, &new_chg); -} - -/** - * Perform BC1.2 detection. - * - * @param port: The Type-C port where VBUS is present. - */ -static void bc12_detect(const int port) -{ - const struct max14637_config_t * const cfg = &max14637_config[port]; - - /* - * Enable the IC to begin detection and connect switches if - * necessary. This is only necessary if the port power role is a - * sink. If the power role is a source then just keep the max14637 - * powered on so that data switches are close. Note that the gpio enable - * for this chip is active by default. In order to trigger bc1.2 - * detection, the chip enable must be driven low, then high again so the - * chip will start bc1.2 client side detection. Add a 100 msec delay to - * avoid collision with a device that might be doing bc1.2 client side - * detection. - */ - msleep(100); - activate_chip_enable(cfg, 0); - msleep(CONFIG_BC12_MAX14637_DELAY_FROM_OFF_TO_ON_MS); - activate_chip_enable(cfg, 1); - -#if defined(CONFIG_CHARGE_RAMP_SW) || 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); -#endif /* !defined(CONFIG_CHARGE_RAMP_SW && CONFIG_CHARGE_RAMP_HW) */ -} - -/** - * If VBUS is present and port power role is sink, then trigger bc1.2 client - * detection. If VBUS is not present then update charge manager. Note that both - * chip_enable and VBUS must be active for the IC to be powered up. Chip enable - * is kept enabled by default so that bc1.2 client detection is not triggered - * when the port power role is source. - * - * @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_check_vbus_level(port, VBUS_PRESENT); -#else - vbus_present = pd_snk_is_vbus_provided(port); -#endif /* !defined(CONFIG_USB_PD_VBUS_DETECT_TCPC) */ - - if (vbus_present) { -#if defined(CONFIG_POWER_PP5000_CONTROL) && defined(HAS_TASK_CHIPSET) - /* Turn on the 5V rail to allow the chip to be powered. */ - power_5v_enable(task_get_current(), 1); -#endif - if (pd_get_power_role(port) == PD_ROLE_SINK) { - bc12_detect(port); - update_bc12_status_to_charger_manager(port); - } - } else { - /* Let charge manager know there's no more charge available. */ - charge_manager_update_charge(CHARGE_SUPPLIER_OTHER, port, NULL); - /* - * If latest attached charger is PD Adapter then it would be - * detected as DCP and data switch of USB2.0 would be open which - * prevents USB 2.0 data path from working later. As a result, - * bc12_detect() is called again here and SCP would be detected - * due to D+/D- are NC (open) if nothing is attached then data - * switch of USB2.0 can be kept close from now on. - */ - bc12_detect(port); -#if defined(CONFIG_POWER_PP5000_CONTROL) && defined(HAS_TASK_CHIPSET) - /* Issue a request to turn off the rail. */ - power_5v_enable(task_get_current(), 0); -#endif - } -} - -static void max14637_usb_charger_task(const int port) -{ - uint32_t evt; - const struct max14637_config_t * const cfg = &max14637_config[port]; - - ASSERT(port >= 0 && port < CONFIG_USB_PD_PORT_MAX_COUNT); - /* - * Have chip enable active as default state so data switches are closed - * and bc1.2 client side detection is not activated when the port power - * role is a source. - */ - activate_chip_enable(cfg, 1); - /* Check whether bc1.2 client mode detection needs to be triggered */ - 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); - } -} - -#if defined(CONFIG_CHARGE_RAMP_SW) || defined(CONFIG_CHARGE_RAMP_HW) -static int max14637_ramp_allowed(int supplier) -{ - /* - * Due to the limitations in the application of the MAX14637, we - * don't quite know exactly what we're plugged into. Therefore, - * the supplier type will be CHARGE_SUPPLIER_OTHER. - */ - return supplier == CHARGE_SUPPLIER_OTHER; -} - -static int max14637_ramp_max(int supplier, int sup_curr) -{ - /* Use the current limit that was decided by the MAX14637. */ - if (supplier == CHARGE_SUPPLIER_OTHER) - return sup_curr; - else - return 500; -} -#endif /* CONFIG_CHARGE_RAMP_SW || CONFIG_CHARGE_RAMP_HW */ - -/* Called on AP S5 -> S3 and S3/S0iX -> S0 transition */ -static void bc12_chipset_startup(void) -{ - int port; - - /* - * For each port, trigger a new USB_CHG_EVENT_VBUS event to handle cases - * where there was no change in VBUS following an AP resume/startup - * event. If a legacy charger is connected to the port, then VBUS will - * not drop even during the USB PD hard reset. - */ - for (port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; port++) - task_set_event(USB_CHG_PORT_TO_TASK_ID(port), - USB_CHG_EVENT_VBUS); -} -DECLARE_HOOK(HOOK_CHIPSET_STARTUP, bc12_chipset_startup, HOOK_PRIO_DEFAULT); -DECLARE_HOOK(HOOK_CHIPSET_RESUME, bc12_chipset_startup, HOOK_PRIO_DEFAULT); - -const struct bc12_drv max14637_drv = { - .usb_charger_task = max14637_usb_charger_task, -#if defined(CONFIG_CHARGE_RAMP_SW) || defined(CONFIG_CHARGE_RAMP_HW) - .ramp_allowed = max14637_ramp_allowed, - .ramp_max = max14637_ramp_max, -#endif /* CONFIG_CHARGE_RAMP_SW || CONFIG_CHARGE_RAMP_HW */ -}; - -#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 = &max14637_drv, - }, -}; -#endif /* CONFIG_BC12_SINGLE_DRIVER */ diff --git a/driver/bc12/max14637.h b/driver/bc12/max14637.h deleted file mode 100644 index 2b18bc222b..0000000000 --- a/driver/bc12/max14637.h +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright 2018 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. - */ - -/* MAX14637 USB BC 1.2 Charger Detector driver definitions */ - -#include "gpio.h" - -#define MAX14637_FLAGS_ENABLE_ACTIVE_LOW BIT(0) -#define MAX14637_FLAGS_CHG_DET_ACTIVE_LOW BIT(1) - -struct max14637_config_t { - /* - * Enable signal to BC 1.2. Can be active high or low depending on - * MAX14637_FLAGS_ENABLE_ACTIVE_LOW flag bit. - */ - enum gpio_signal chip_enable_pin; - /* - * Charger detect signal from BC 1.2 chip. Can be active high or low - * depending on MAX14637_FLAGS_CHG_DET_ACTIVE_LOW flag bit. - */ - enum gpio_signal chg_det_pin; - /* Configuration flags with prefix MAX14637_FLAGS. */ - int flags; -}; - -/* - * Array that contains boards-specific configuration for BC 1.2 charging chips. - */ -extern const struct max14637_config_t - max14637_config[CONFIG_USB_PD_PORT_MAX_COUNT]; -extern const struct bc12_drv max14637_drv; diff --git a/driver/bc12/mt6360.c b/driver/bc12/mt6360.c deleted file mode 100644 index 50aa4d0e45..0000000000 --- a/driver/bc12/mt6360.c +++ /dev/null @@ -1,576 +0,0 @@ -/* 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 "crc8.h" -#include "mt6360.h" -#include "ec_commands.h" -#include "hooks.h" -#include "i2c.h" -#include "task.h" -#include "timer.h" -#include "usb_charge.h" -#include "usb_pd.h" -#include "util.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, - enum charge_supplier new_bc12_type) -{ - static enum charge_supplier current_bc12_type = CHARGE_SUPPLIER_NONE; - - if (new_bc12_type != current_bc12_type) { - if (current_bc12_type >= 0) - 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; - } -} - -static void mt6360_handle_bc12_irq(int port) -{ - int reg; - - mt6360_read8(MT6360_REG_DPDMIRQ, ®); - - if (reg & MT6360_MASK_DPDMIRQ_ATTACH) { - /* Check vbus again to avoid timing issue */ - if (pd_snk_is_vbus_provided(port)) - mt6360_update_charge_manager( - port, mt6360_get_bc12_device_type()); - else - mt6360_update_charge_manager( - 0, CHARGE_SUPPLIER_NONE); - } - - /* 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) { - if (pd_snk_is_vbus_provided(port)) - mt6360_enable_bc12_detection(1); - else - mt6360_update_charge_manager( - 0, CHARGE_SUPPLIER_NONE); - } - - /* detection done, update charge_manager and stop detection */ - if (evt & USB_CHG_EVENT_BC12) { - mt6360_handle_bc12_irq(port); - mt6360_enable_bc12_detection(0); - } - } -} - -/* Regulator: LDO & BUCK */ -static int mt6360_regulator_write8(uint8_t addr, int reg, int val) -{ - /* - * Note: The checksum from I2C_FLAG_PEC happens to be correct because - * length == 1 -> the high 3 bits of the offset byte is 0. - */ - return i2c_write8(mt6360_config.i2c_port, - addr | I2C_FLAG_PEC, reg, val); -} - -static int mt6360_regulator_read8(int addr, int reg, int *val) -{ - int rv; - uint8_t crc = 0, real_crc; - uint8_t out[3] = {(addr << 1) | 1, reg}; - - rv = i2c_read16(mt6360_config.i2c_port, addr, reg, val); - if (rv) - return rv; - - real_crc = (*val >> 8) & 0xFF; - *val &= 0xFF; - out[2] = *val; - crc = cros_crc8(out, ARRAY_SIZE(out)); - - if (crc != real_crc) - return EC_ERROR_CRC; - - return EC_SUCCESS; -} - -static int mt6360_regulator_update_bits(int addr, int reg, int mask, int val) -{ - int rv; - int reg_val = 0; - - rv = mt6360_regulator_read8(addr, reg, ®_val); - if (rv) - return rv; - reg_val &= ~mask; - reg_val |= (mask & val); - rv = mt6360_regulator_write8(addr, reg, reg_val); - return rv; -} - -struct mt6360_regulator_data { - const char *name; - const uint16_t *ldo_vosel_table; - uint16_t ldo_vosel_table_len; - uint8_t addr; - uint8_t reg_en_ctrl2; - uint8_t reg_ctrl3; - uint8_t mask_vosel; - uint8_t shift_vosel; - uint8_t mask_vocal; -}; - -static const uint16_t MT6360_LDO3_VOSEL_TABLE[16] = { - [0x4] = 1800, - [0xA] = 2900, - [0xB] = 3000, - [0xD] = 3300, -}; - -static const uint16_t MT6360_LDO5_VOSEL_TABLE[8] = { - [0x2] = 2900, - [0x3] = 3000, - [0x5] = 3300, -}; - -static const uint16_t MT6360_LDO6_VOSEL_TABLE[16] = { - [0x0] = 500, - [0x1] = 600, - [0x2] = 700, - [0x3] = 800, - [0x4] = 900, - [0x5] = 1000, - [0x6] = 1100, - [0x7] = 1200, - [0x8] = 1300, - [0x9] = 1400, - [0xA] = 1500, - [0xB] = 1600, - [0xC] = 1700, - [0xD] = 1800, - [0xE] = 1900, - [0xF] = 2000, -}; - -/* LDO7 VOSEL table is the same as LDO6's. */ -static const uint16_t *const MT6360_LDO7_VOSEL_TABLE = MT6360_LDO6_VOSEL_TABLE; -static const uint16_t MT6360_LDO7_VOSEL_TABLE_SIZE = - ARRAY_SIZE(MT6360_LDO6_VOSEL_TABLE); - -static const -struct mt6360_regulator_data regulator_data[MT6360_REGULATOR_COUNT] = { - [MT6360_LDO3] = { - .name = "mt6360_ldo3", - .ldo_vosel_table = MT6360_LDO3_VOSEL_TABLE, - .ldo_vosel_table_len = ARRAY_SIZE(MT6360_LDO3_VOSEL_TABLE), - .addr = MT6360_LDO_I2C_ADDR_FLAGS, - .reg_en_ctrl2 = MT6360_REG_LDO3_EN_CTRL2, - .reg_ctrl3 = MT6360_REG_LDO3_CTRL3, - .mask_vosel = MT6360_MASK_LDO3_VOSEL, - .shift_vosel = MT6360_MASK_LDO3_VOSEL_SHIFT, - .mask_vocal = MT6360_MASK_LDO3_VOCAL, - }, - [MT6360_LDO5] = { - .name = "mt6360_ldo5", - .ldo_vosel_table = MT6360_LDO5_VOSEL_TABLE, - .ldo_vosel_table_len = ARRAY_SIZE(MT6360_LDO5_VOSEL_TABLE), - .addr = MT6360_LDO_I2C_ADDR_FLAGS, - .reg_en_ctrl2 = MT6360_REG_LDO5_EN_CTRL2, - .reg_ctrl3 = MT6360_REG_LDO5_CTRL3, - .mask_vosel = MT6360_MASK_LDO5_VOSEL, - .shift_vosel = MT6360_MASK_LDO5_VOSEL_SHIFT, - .mask_vocal = MT6360_MASK_LDO5_VOCAL, - }, - [MT6360_LDO6] = { - .name = "mt6360_ldo6", - .ldo_vosel_table = MT6360_LDO6_VOSEL_TABLE, - .ldo_vosel_table_len = ARRAY_SIZE(MT6360_LDO6_VOSEL_TABLE), - .addr = MT6360_PMIC_I2C_ADDR_FLAGS, - .reg_en_ctrl2 = MT6360_REG_LDO6_EN_CTRL2, - .reg_ctrl3 = MT6360_REG_LDO6_CTRL3, - .mask_vosel = MT6360_MASK_LDO6_VOSEL, - .shift_vosel = MT6360_MASK_LDO6_VOSEL_SHIFT, - .mask_vocal = MT6360_MASK_LDO6_VOCAL, - }, - [MT6360_LDO7] = { - .name = "mt6360_ldo7", - .ldo_vosel_table = MT6360_LDO7_VOSEL_TABLE, - .ldo_vosel_table_len = MT6360_LDO7_VOSEL_TABLE_SIZE, - .addr = MT6360_PMIC_I2C_ADDR_FLAGS, - .reg_en_ctrl2 = MT6360_REG_LDO7_EN_CTRL2, - .reg_ctrl3 = MT6360_REG_LDO7_CTRL3, - .mask_vosel = MT6360_MASK_LDO7_VOSEL, - .shift_vosel = MT6360_MASK_LDO7_VOSEL_SHIFT, - .mask_vocal = MT6360_MASK_LDO7_VOCAL, - }, - [MT6360_BUCK1] = { - .name = "mt6360_buck1", - .addr = MT6360_PMIC_I2C_ADDR_FLAGS, - .reg_en_ctrl2 = MT6360_REG_BUCK1_EN_CTRL2, - .reg_ctrl3 = MT6360_REG_BUCK1_VOSEL, - .mask_vosel = MT6360_MASK_BUCK1_VOSEL, - .shift_vosel = MT6360_MASK_BUCK1_VOSEL_SHIFT, - .mask_vocal = MT6360_MASK_BUCK1_VOCAL, - }, - [MT6360_BUCK2] = { - .name = "mt6360_buck2", - .addr = MT6360_PMIC_I2C_ADDR_FLAGS, - .reg_en_ctrl2 = MT6360_REG_BUCK2_EN_CTRL2, - .reg_ctrl3 = MT6360_REG_BUCK2_VOSEL, - .mask_vosel = MT6360_MASK_BUCK2_VOSEL, - .shift_vosel = MT6360_MASK_BUCK2_VOSEL_SHIFT, - .mask_vocal = MT6360_MASK_BUCK2_VOCAL, - }, -}; - -static bool is_buck_regulator(const struct mt6360_regulator_data *data) -{ - /* There's no ldo_vosel_table, it's a buck. */ - return !(data->ldo_vosel_table); -} - -int mt6360_regulator_get_info(enum mt6360_regulator_id id, char *name, - uint16_t *num_voltages, uint16_t *voltages_mv) -{ - int i; - int cnt = 0; - const struct mt6360_regulator_data *data; - - if (id >= MT6360_REGULATOR_COUNT) - return EC_ERROR_INVAL; - data = ®ulator_data[id]; - - strzcpy(name, data->name, EC_REGULATOR_NAME_MAX_LEN); - - if (is_buck_regulator(data)) { - for (i = 0; i < MT6360_BUCK_VOSEL_MAX_STEP; ++i) { - int mv = MT6360_BUCK_VOSEL_MIN + - i * MT6360_BUCK_VOSEL_STEP_MV; - - if (cnt < EC_REGULATOR_VOLTAGE_MAX_COUNT) - voltages_mv[cnt++] = mv; - else - CPRINTS("%s voltage info overflow: %d-%d", - data->name, mv, MT6360_BUCK_VOSEL_MAX); - } - } else { - /* It's a LDO */ - for (i = 0; i < data->ldo_vosel_table_len; i++) { - int mv = data->ldo_vosel_table[i]; - - if (!mv) - continue; - if (cnt < EC_REGULATOR_VOLTAGE_MAX_COUNT) - voltages_mv[cnt++] = mv; - else - CPRINTS("%s voltage info overflow: %d", - data->name, mv); - } - } - - *num_voltages = cnt; - return EC_SUCCESS; -} - -int mt6360_regulator_enable(enum mt6360_regulator_id id, uint8_t enable) -{ - const struct mt6360_regulator_data *data; - - if (id >= MT6360_REGULATOR_COUNT) - return EC_ERROR_INVAL; - data = ®ulator_data[id]; - - if (enable) - return mt6360_regulator_update_bits( - data->addr, - data->reg_en_ctrl2, - MT6360_MASK_RGL_SW_OP_EN | MT6360_MASK_RGL_SW_EN, - MT6360_MASK_RGL_SW_OP_EN | MT6360_MASK_RGL_SW_EN); - else - return mt6360_regulator_update_bits( - data->addr, - data->reg_en_ctrl2, - MT6360_MASK_RGL_SW_OP_EN | MT6360_MASK_RGL_SW_EN, - MT6360_MASK_RGL_SW_OP_EN); -} - -int mt6360_regulator_is_enabled(enum mt6360_regulator_id id, uint8_t *enabled) -{ - int rv; - int value; - const struct mt6360_regulator_data *data; - - if (id >= MT6360_REGULATOR_COUNT) - return EC_ERROR_INVAL; - data = ®ulator_data[id]; - - rv = mt6360_regulator_read8(data->addr, data->reg_en_ctrl2, &value); - if (rv) { - CPRINTS("Error reading %s enabled: %d", data->name, rv); - return rv; - } - *enabled = !!(value & MT6360_MASK_RGL_SW_EN); - return EC_SUCCESS; -} - -int mt6360_regulator_set_voltage(enum mt6360_regulator_id id, int min_mv, - int max_mv) -{ - int i; - const struct mt6360_regulator_data *data; - - if (id >= MT6360_REGULATOR_COUNT) - return EC_ERROR_INVAL; - data = ®ulator_data[id]; - - if (is_buck_regulator(data)) { - int mv; - int step; - - if (max_mv < MT6360_BUCK_VOSEL_MIN) - goto error; - - if (min_mv > MT6360_BUCK_VOSEL_MAX) - goto error; - - mv = DIV_ROUND_UP((min_mv + max_mv) / 2, - MT6360_BUCK_VOSEL_STEP_MV) * - MT6360_BUCK_VOSEL_STEP_MV; - mv = MIN(MAX(mv, MT6360_BUCK_VOSEL_MIN), MT6360_BUCK_VOSEL_MAX); - - step = (mv - MT6360_BUCK_VOSEL_MIN) / MT6360_BUCK_VOSEL_STEP_MV; - - return mt6360_regulator_update_bits(data->addr, - data->reg_ctrl3, - data->mask_vosel, step); - } - - /* It's a LDO. */ - for (i = 0; i < data->ldo_vosel_table_len; i++) { - int mv = data->ldo_vosel_table[i]; - int step = 0; - - if (!mv) - continue; - if (mv + MT6360_LDO_VOCAL_STEP_MV * MT6360_LDO_VOCAL_MAX_STEP < - min_mv) - continue; - if (mv < min_mv) - step = DIV_ROUND_UP(min_mv - mv, - MT6360_LDO_VOCAL_STEP_MV); - if (mv + step * MT6360_LDO_VOCAL_STEP_MV > max_mv) - continue; - return mt6360_regulator_update_bits( - data->addr, - data->reg_ctrl3, - data->mask_vosel | data->mask_vocal, - (i << data->shift_vosel) | step); - } - -error: - CPRINTS("%s voltage %d - %d out of range", data->name, min_mv, max_mv); - return EC_ERROR_INVAL; -} - -int mt6360_regulator_get_voltage(enum mt6360_regulator_id id, int *voltage_mv) -{ - int value; - int rv; - const struct mt6360_regulator_data *data; - - if (id >= MT6360_REGULATOR_COUNT) - return EC_ERROR_INVAL; - data = ®ulator_data[id]; - - rv = mt6360_regulator_read8(data->addr, data->reg_ctrl3, &value); - if (rv) { - CPRINTS("Error reading %s ctrl3: %d", data->name, rv); - return rv; - } - - /* BUCK */ - if (is_buck_regulator(data)) { - *voltage_mv = MT6360_BUCK_VOSEL_MIN + - value * MT6360_BUCK_VOSEL_STEP_MV; - return EC_SUCCESS; - } - - /* LDO */ - *voltage_mv = data->ldo_vosel_table[(value & data->mask_vosel) >> - data->shift_vosel]; - if (*voltage_mv == 0) { - CPRINTS("Unknown %s voltage value: %d", data->name, value); - return EC_ERROR_INVAL; - } - *voltage_mv += - MIN(MT6360_LDO_VOCAL_MAX_STEP, value & data->mask_vocal) * - MT6360_LDO_VOCAL_STEP_MV; - return EC_SUCCESS; -} - -/* RGB LED */ -void mt6360_led_init(void) -{ - /* Enable LED1 software mode */ - mt6360_set_bit(MT6360_REG_RGB_EN, MT6360_ISINK1_CHRIND_EN_SEL); -} -DECLARE_HOOK(HOOK_INIT, mt6360_led_init, HOOK_PRIO_DEFAULT); - -int mt6360_led_enable(enum mt6360_led_id led_id, int enable) -{ - if (!IN_RANGE(led_id, 0, MT6360_LED_COUNT)) - return EC_ERROR_INVAL; - - if (enable) - return mt6360_set_bit(MT6360_REG_RGB_EN, - MT6360_MASK_ISINK_EN(led_id)); - return mt6360_clr_bit(MT6360_REG_RGB_EN, MT6360_MASK_ISINK_EN(led_id)); -} - -int mt6360_led_set_brightness(enum mt6360_led_id led_id, int brightness) -{ - int val; - - if (!IN_RANGE(led_id, 0, MT6360_LED_COUNT)) - return EC_ERROR_INVAL; - if (!IN_RANGE(brightness, 0, 16)) - return EC_ERROR_INVAL; - - RETURN_ERROR(mt6360_read8(MT6360_REG_RGB_ISINK(led_id), &val)); - val &= ~MT6360_MASK_CUR_SEL; - val |= brightness; - - return mt6360_write8(MT6360_REG_RGB_ISINK(led_id), val); -} - -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 deleted file mode 100644 index e23a2623ed..0000000000 --- a/driver/bc12/mt6360.h +++ /dev/null @@ -1,91 +0,0 @@ -/* 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 - -#include "bc12/mt6360_public.h" - -#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_RGB_EN 0x80 -#define MT6360_MASK_ISINK_EN(x) BIT(7 - (x)) -#define MT6360_ISINK1_CHRIND_EN_SEL BIT(3) - -#define MT6360_REG_RGB_ISINK(x) (0x81 + (x)) -#define MT6360_MASK_CUR_SEL 0xF - -#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) - -#define MT6360_REG_LDO3_EN_CTRL2 0x05 - -#define MT6360_REG_LDO3_CTRL3 0x09 -#define MT6360_MASK_LDO3_VOSEL 0xF0 -#define MT6360_MASK_LDO3_VOSEL_SHIFT 4 -#define MT6360_MASK_LDO3_VOCAL 0x0F - -#define MT6360_REG_LDO5_EN_CTRL2 0x0B - -#define MT6360_REG_LDO5_CTRL3 0x0F -#define MT6360_MASK_LDO5_VOSEL 0x70 -#define MT6360_MASK_LDO5_VOSEL_SHIFT 4 -#define MT6360_MASK_LDO5_VOCAL 0x0F - -#define MT6360_REG_LDO6_EN_CTRL2 0x37 - -#define MT6360_REG_LDO6_CTRL3 0x3B -#define MT6360_MASK_LDO6_VOSEL 0xF0 -#define MT6360_MASK_LDO6_VOSEL_SHIFT 4 -#define MT6360_MASK_LDO6_VOCAL 0x0F - -#define MT6360_REG_LDO7_EN_CTRL2 0x31 - -#define MT6360_REG_LDO7_CTRL3 0x35 -#define MT6360_MASK_LDO7_VOSEL 0xF0 -#define MT6360_MASK_LDO7_VOSEL_SHIFT 4 -#define MT6360_MASK_LDO7_VOCAL 0x0F - -#define MT6360_REG_BUCK1_EN_CTRL2 0x17 - -#define MT6360_REG_BUCK1_VOSEL 0x10 -#define MT6360_MASK_BUCK1_VOSEL 0xFF -#define MT6360_MASK_BUCK1_VOSEL_SHIFT 0 -#define MT6360_MASK_BUCK1_VOCAL 0x0 - -#define MT6360_REG_BUCK2_EN_CTRL2 0x26 - -#define MT6360_REG_BUCK2_VOSEL 0x20 -#define MT6360_MASK_BUCK2_VOSEL 0xFF -#define MT6360_MASK_BUCK2_VOSEL_SHIFT 0 -#define MT6360_MASK_BUCK2_VOCAL 0x0 - -/* This is same for LDO{1,2,3,5,6,7}_EN_CTRL2, BUCK{1,2}_EN_CTRL2 */ -#define MT6360_MASK_RGL_SW_OP_EN BIT(7) -#define MT6360_MASK_RGL_SW_EN BIT(6) - -#define MT6360_LDO_VOCAL_STEP_MV 10 -#define MT6360_LDO_VOCAL_MAX_STEP 10 - -#define MT6360_BUCK_VOSEL_STEP_MV 5 -#define MT6360_BUCK_VOSEL_MAX_STEP 200 -#define MT6360_BUCK_VOSEL_MIN 300 -#define MT6360_BUCK_VOSEL_MAX \ - (MT6360_BUCK_VOSEL_MIN + \ - MT6360_BUCK_VOSEL_STEP_MV * MT6360_BUCK_VOSEL_MAX_STEP) - -#endif /* __CROS_EC_MT6360_H */ diff --git a/driver/bc12/pi3usb9201.c b/driver/bc12/pi3usb9201.c deleted file mode 100644 index 2a9986f823..0000000000 --- a/driver/bc12/pi3usb9201.c +++ /dev/null @@ -1,410 +0,0 @@ -/* Copyright 2019 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. - */ - -/* PI3USB9201 USB BC 1.2 Charger Detector driver. */ - -#include "pi3usb9201.h" -#include "charge_manager.h" -#include "chipset.h" -#include "common.h" -#include "console.h" -#include "gpio.h" -#include "power.h" -#include "task.h" -#include "timer.h" -#include "usb_charge.h" -#include "usb_pd.h" -#include "util.h" - -#define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args) - -enum pi3usb9201_client_sts { - CHG_OTHER = 0, - CHG_2_4A, - CHG_2_0A, - CHG_1_0A, - CHG_RESERVED, - CHG_CDP, - CHG_SDP, - CHG_DCP, -}; - -struct bc12_status { - enum charge_supplier supplier; - int current_limit; -}; - -/* Used to store last BC1.2 detection result */ -static enum charge_supplier bc12_supplier[CONFIG_USB_PD_PORT_MAX_COUNT]; - -/* - * The USB Type-C specification limits the maximum amount of current from BC 1.2 - * suppliers to 1.5A. Technically, proprietary methods are not allowed, but we - * will continue to allow those. - */ -static const struct bc12_status bc12_chg_limits[] = { - [CHG_OTHER] = {CHARGE_SUPPLIER_OTHER, 500}, - [CHG_2_4A] = {CHARGE_SUPPLIER_PROPRIETARY, USB_CHARGER_MAX_CURR_MA}, - [CHG_2_0A] = {CHARGE_SUPPLIER_PROPRIETARY, USB_CHARGER_MAX_CURR_MA}, - [CHG_1_0A] = {CHARGE_SUPPLIER_PROPRIETARY, 1000}, - [CHG_RESERVED] = {CHARGE_SUPPLIER_NONE, 0}, - [CHG_CDP] = {CHARGE_SUPPLIER_BC12_CDP, USB_CHARGER_MAX_CURR_MA}, - [CHG_SDP] = {CHARGE_SUPPLIER_BC12_SDP, 500}, -#if defined(CONFIG_CHARGE_RAMP_SW) || defined(CONFIG_CHARGE_RAMP_HW) - /* - * If ramping is supported, then for DCP set the current limit to be the - * max supported for the port by the board or 1.5A (whichever is lower). - * Although, the BC 1.2 specification allows DCP suppliers to ramp to - * much higher currents, the USB Type-C specification limits the - * maximum current allowed for BC 1.2 suppliers to 1.5A. - */ - [CHG_DCP] = {CHARGE_SUPPLIER_BC12_DCP, USB_CHARGER_MAX_CURR_MA}, -#else - [CHG_DCP] = {CHARGE_SUPPLIER_BC12_DCP, 500}, -#endif -}; - -static inline int raw_read8(int port, int offset, int *value) -{ - return i2c_read8(pi3usb9201_bc12_chips[port].i2c_port, - pi3usb9201_bc12_chips[port].i2c_addr_flags, - offset, value); -} - -static int pi3usb9201_raw(int port, int reg, int mask, int val) -{ - /* Clear mask and then set val in i2c reg value */ - return i2c_field_update8(pi3usb9201_bc12_chips[port].i2c_port, - pi3usb9201_bc12_chips[port].i2c_addr_flags, - reg, mask, val); -} - -static int pi3usb9201_interrupt_mask(int port, int enable) -{ - return pi3usb9201_raw(port, PI3USB9201_REG_CTRL_1, - PI3USB9201_REG_CTRL_1_INT_MASK, - enable); -} - -static int pi3usb9201_bc12_detect_ctrl(int port, int enable) -{ - return pi3usb9201_raw(port, PI3USB9201_REG_CTRL_2, - PI3USB9201_REG_CTRL_2_START_DET, - enable ? PI3USB9201_REG_CTRL_2_START_DET : 0); -} - -static int pi3usb9201_set_mode(int port, int desired_mode) -{ - return pi3usb9201_raw(port, PI3USB9201_REG_CTRL_1, - PI3USB9201_REG_CTRL_1_MODE_MASK, - desired_mode << PI3USB9201_REG_CTRL_1_MODE_SHIFT); -} - -static int pi3usb9201_get_mode(int port, int *mode) -{ - int rv; - - rv = raw_read8(port, PI3USB9201_REG_CTRL_1, mode); - if (rv) - return rv; - - *mode &= PI3USB9201_REG_CTRL_1_MODE_MASK; - *mode >>= PI3USB9201_REG_CTRL_1_MODE_SHIFT; - - return EC_SUCCESS; -} - -static int pi3usb9201_get_status(int port, int *client, int *host) -{ - int rv; - int status; - - rv = raw_read8(port, PI3USB9201_REG_CLIENT_STS, &status); - if (client) - *client = status; - rv |= raw_read8(port, PI3USB9201_REG_HOST_STS, &status); - if (host) - *host = status; - - return rv; -} - -static void bc12_update_supplier(enum charge_supplier supplier, int port, - struct charge_port_info *new_chg) -{ - /* - * If most recent supplier type is not CHARGE_SUPPLIER_NONE, then the - * charge manager table entry for that supplier type needs to be cleared - * out. - */ - if (bc12_supplier[port] != CHARGE_SUPPLIER_NONE) - charge_manager_update_charge(bc12_supplier[port], port, NULL); - /* Now update the current supplier type */ - bc12_supplier[port] = supplier; - /* If new supplier type != NONE, then notify charge manager */ - if (supplier != CHARGE_SUPPLIER_NONE) - charge_manager_update_charge(supplier, port, new_chg); -} - -static void bc12_update_charge_manager(int port, int client_status) -{ - struct charge_port_info new_chg; - enum charge_supplier supplier; - int bit_pos; - - /* Set charge voltage to 5V */ - new_chg.voltage = USB_CHARGER_VOLTAGE_MV; - - /* - * Find set bit position. Note that this funciton is only called if a - * bit was set in client_status, so bit_pos won't be negative. - */ - bit_pos = __builtin_ffs(client_status) - 1; - - new_chg.current = bc12_chg_limits[bit_pos].current_limit; - supplier = bc12_chg_limits[bit_pos].supplier; - - CPRINTS("pi3usb9201[p%d]: sts = 0x%x, lim = %d mA, supplier = %d", - port, client_status, new_chg.current, supplier); - /* bc1.2 is complete and start bit does not auto clear */ - pi3usb9201_bc12_detect_ctrl(port, 0); - /* Inform charge manager of new supplier type and current limit */ - bc12_update_supplier(supplier, port, &new_chg); -} - -static int bc12_detect_start(int port) -{ - int rv; - - /* - * Read both status registers to ensure that all interrupt indications - * are cleared prior to starting bc1.2 detection. - */ - pi3usb9201_get_status(port, NULL, NULL); - - /* Put pi3usb9201 into client mode */ - rv = pi3usb9201_set_mode(port, PI3USB9201_CLIENT_MODE); - if (rv) - return rv; - /* Have pi3usb9201 start bc1.2 detection */ - rv = pi3usb9201_bc12_detect_ctrl(port, 1); - if (rv) - return rv; - /* Unmask interrupt to wake task when detection completes */ - return pi3usb9201_interrupt_mask(port, 0); -} - -static void bc12_power_down(int port) -{ - /* Put pi3usb9201 into its power down mode */ - pi3usb9201_set_mode(port, PI3USB9201_POWER_DOWN); - /* The start bc1.2 bit does not auto clear */ - pi3usb9201_bc12_detect_ctrl(port, 0); - /* Mask interrupts unitl next bc1.2 detection event */ - pi3usb9201_interrupt_mask(port, 1); - /* - * Let charge manager know there's no more charge available for the - * supplier type that was most recently detected. - */ - bc12_update_supplier(CHARGE_SUPPLIER_NONE, port, NULL); - - /* There's nothing else to do if the part is always powered. */ - if (pi3usb9201_bc12_chips[port].flags & PI3USB9201_ALWAYS_POWERED) - return; - -#if defined(CONFIG_POWER_PP5000_CONTROL) && defined(HAS_TASK_CHIPSET) - /* Indicate PP5000_A rail is not required by USB_CHG task. */ - power_5v_enable(task_get_current(), 0); -#endif -} - -static void bc12_power_up(int port) -{ - if (IS_ENABLED(CONFIG_POWER_PP5000_CONTROL) && - IS_ENABLED(HAS_TASK_CHIPSET) && - !(pi3usb9201_bc12_chips[port].flags & PI3USB9201_ALWAYS_POWERED)) { - /* Turn on the 5V rail to allow the chip to be powered. */ - power_5v_enable(task_get_current(), 1); - /* - * Give the pi3usb9201 time so it's ready to receive i2c - * messages - */ - msleep(1); - } - - pi3usb9201_interrupt_mask(port, 1); -} - -static void pi3usb9201_usb_charger_task(const int port) -{ - uint32_t evt; - int i; - - /* - * Set most recent bc1.2 detection supplier result to - * CHARGE_SUPPLIER_NONE for all ports. - */ - for (i = 0; i < board_get_usb_pd_port_count(); i++) - bc12_supplier[port] = CHARGE_SUPPLIER_NONE; - - /* - * The is no specific initialization required for the pi3usb9201 other - * than enabling the interrupt mask. - */ - pi3usb9201_interrupt_mask(port, 1); - - while (1) { - /* Wait for interrupt */ - evt = task_wait_event(-1); - - /* Interrupt from the Pericom chip, determine charger type */ - if (evt & USB_CHG_EVENT_BC12) { - int client; - int host; - int rv; - - rv = pi3usb9201_get_status(port, &client, &host); - if (!rv && client) - /* - * Any bit set in client status register - * indicates that BC1.2 detection has - * completed. - */ - bc12_update_charge_manager(port, client); - if (!rv && host) { - /* - * Switch to SDP after device is plugged in to - * avoid noise (pulse on D-) causing USB - * disconnect (b/156014140). - */ - if (host & PI3USB9201_REG_HOST_STS_DEV_PLUG) - pi3usb9201_set_mode(port, - PI3USB9201_SDP_HOST_MODE); - /* - * Switch to CDP after device is unplugged so - * we advertise higher power available for next - * device. - */ - if (host & PI3USB9201_REG_HOST_STS_DEV_UNPLUG) - pi3usb9201_set_mode(port, - PI3USB9201_CDP_HOST_MODE); - } - /* - * TODO(b/124061702): Use host status to allocate power - * more intelligently. - */ - } - -#ifndef CONFIG_USB_PD_VBUS_DETECT_TCPC - if (evt & USB_CHG_EVENT_VBUS) - CPRINTS("VBUS p%d %d", port, - pd_snk_is_vbus_provided(port)); -#endif - - if (evt & USB_CHG_EVENT_DR_UFP) { - bc12_power_up(port); - if (bc12_detect_start(port)) { - struct charge_port_info new_chg; - - /* - * VBUS is present, but starting bc1.2 detection - * failed for some reason. So limit charge - * current to default 500 mA for this case. - */ - - new_chg.voltage = USB_CHARGER_VOLTAGE_MV; - new_chg.current = USB_CHARGER_MIN_CURR_MA; - /* Save supplier type and notify chg manager */ - bc12_update_supplier(CHARGE_SUPPLIER_OTHER, - port, &new_chg); - CPRINTS("pi3usb9201[p%d]: bc1.2 failed use " - "defaults", port); - } - } - - if (evt & USB_CHG_EVENT_DR_DFP) { - int mode; - int rv; - - /* - * Update the charge manager if bc1.2 client mode is - * currently active. - */ - bc12_update_supplier(CHARGE_SUPPLIER_NONE, port, NULL); - /* - * If the port is in DFP mode, then need to set mode to - * CDP_HOST which will auto close D+/D- switches. - */ - bc12_power_up(port); - rv = pi3usb9201_get_mode(port, &mode); - if (!rv && (mode != PI3USB9201_CDP_HOST_MODE)) { - CPRINTS("pi3usb9201[p%d]: CDP_HOST mode", port); - /* - * Read both status registers to ensure that all - * interrupt indications are cleared prior to - * starting DFP CDP host mode. - */ - pi3usb9201_get_status(port, NULL, NULL); - pi3usb9201_set_mode(port, - PI3USB9201_CDP_HOST_MODE); - /* - * Unmask interrupt to wake task when host - * status changes. - */ - pi3usb9201_interrupt_mask(port, 0); - } - } - - if (evt & USB_CHG_EVENT_CC_OPEN) - bc12_power_down(port); - } -} - -#if defined(CONFIG_CHARGE_RAMP_SW) || defined(CONFIG_CHARGE_RAMP_HW) -static int pi3usb9201_ramp_allowed(int supplier) -{ - /* Don't allow ramp if charge supplier is OTHER, SDP, or NONE */ - return !(supplier == CHARGE_SUPPLIER_OTHER || - supplier == CHARGE_SUPPLIER_BC12_SDP || - supplier == CHARGE_SUPPLIER_NONE); -} - -static int pi3usb9201_ramp_max(int supplier, int sup_curr) -{ - /* - * Use the level from the bc12_chg_limits table above except for - * proprietary or CDP and in those cases the charge current from the - * charge manager is already set at the max determined by bc1.2 - * detection. - */ - switch (supplier) { - case CHARGE_SUPPLIER_BC12_DCP: - return USB_CHARGER_MAX_CURR_MA; - case CHARGE_SUPPLIER_BC12_CDP: - case CHARGE_SUPPLIER_PROPRIETARY: - return sup_curr; - case CHARGE_SUPPLIER_BC12_SDP: - default: - return 500; - } -} -#endif /* CONFIG_CHARGE_RAMP_SW || CONFIG_CHARGE_RAMP_HW */ - -const struct bc12_drv pi3usb9201_drv = { - .usb_charger_task = pi3usb9201_usb_charger_task, -#if defined(CONFIG_CHARGE_RAMP_SW) || defined(CONFIG_CHARGE_RAMP_HW) - .ramp_allowed = pi3usb9201_ramp_allowed, - .ramp_max = pi3usb9201_ramp_max, -#endif /* CONFIG_CHARGE_RAMP_SW || CONFIG_CHARGE_RAMP_HW */ -}; - -#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 = &pi3usb9201_drv, - } -}; -#endif /* CONFIG_BC12_SINGLE_DRIVER */ diff --git a/driver/bc12/pi3usb9201.h b/driver/bc12/pi3usb9201.h deleted file mode 100644 index 3163a3eebc..0000000000 --- a/driver/bc12/pi3usb9201.h +++ /dev/null @@ -1,47 +0,0 @@ -/* Copyright 2019 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. - */ - -/* PI3USB9201 USB BC 1.2 Charger Detector driver definitions */ - -#ifndef __CROS_EC_DRIVER_BC12_PI3USB9201_H -#define __CROS_EC_DRIVER_BC12_PI3USB9201_H - -#include "driver/bc12/pi3usb9201_public.h" - -#define PI3USB9201_REG_CTRL_1 0x0 -#define PI3USB9201_REG_CTRL_2 0x1 -#define PI3USB9201_REG_CLIENT_STS 0x2 -#define PI3USB9201_REG_HOST_STS 0x3 - -/* Flags */ -#define PI3USB9201_ALWAYS_POWERED BIT(0) - -/* Control_1 regiter bit definitions */ -#define PI3USB9201_REG_CTRL_1_INT_MASK BIT(0) -#define PI3USB9201_REG_CTRL_1_MODE_SHIFT 1 -#define PI3USB9201_REG_CTRL_1_MODE_MASK (0x7 << \ - PI3USB9201_REG_CTRL_1_MODE_SHIFT) - -/* Control_2 regiter bit definitions */ -#define PI3USB9201_REG_CTRL_2_AUTO_SW BIT(1) -#define PI3USB9201_REG_CTRL_2_START_DET BIT(3) - -/* Host status register bit definitions */ -#define PI3USB9201_REG_HOST_STS_BC12_DET BIT(0) -#define PI3USB9201_REG_HOST_STS_DEV_PLUG BIT(1) -#define PI3USB9201_REG_HOST_STS_DEV_UNPLUG BIT(2) - -enum pi3usb9201_mode { - PI3USB9201_POWER_DOWN, - PI3USB9201_SDP_HOST_MODE, - PI3USB9201_DCP_HOST_MODE, - PI3USB9201_CDP_HOST_MODE, - PI3USB9201_CLIENT_MODE, - PI3USB9201_RESERVED_1, - PI3USB9201_RESERVED_2, - PI3USB9201_USB_PATH_ON, -}; - -#endif /* __CROS_EC_DRIVER_BC12_PI3USB9201_H */ diff --git a/driver/bc12/pi3usb9281.c b/driver/bc12/pi3usb9281.c deleted file mode 100644 index 9fc32e942b..0000000000 --- a/driver/bc12/pi3usb9281.c +++ /dev/null @@ -1,505 +0,0 @@ -/* Copyright 2014 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. - * - * Pericom PI3USB3281 USB port switch driver. - */ - -#include "charge_manager.h" -#include "common.h" -#include "console.h" -#include "ec_commands.h" -#include "gpio.h" -#include "hooks.h" -#include "i2c.h" -#include "pi3usb9281.h" -#include "task.h" -#include "timer.h" -#include "usb_charge.h" -#include "usb_pd.h" -#include "util.h" - - /* Console output macros */ -#define CPUTS(outstr) cputs(CC_USBCHARGE, outstr) -#define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args) - -/* I2C address */ -#define PI3USB9281_I2C_ADDR_FLAGS 0x25 - -/* Delay values */ -#define PI3USB9281_SW_RESET_DELAY 20 - -/* Wait after a charger is detected to debounce pin contact order */ -#define PI3USB9281_DETECT_DEBOUNCE_MS 1000 -#define PI3USB9281_RESET_DEBOUNCE_MS 100 -#define PI3USB9281_RESET_STARTUP_DELAY (200 * MSEC) -#define PI3USB9281_RESET_STARTUP_DELAY_INTERVAL_MS 40 - -/* Store the state of our USB data switches so that they can be restored. */ -static int usb_switch_state[CONFIG_USB_PD_PORT_MAX_COUNT]; - -static int pi3usb9281_reset(int port); -static int pi3usb9281_get_interrupts(int port); - -static void select_chip(int port) -{ - struct pi3usb9281_config *chip = &pi3usb9281_chips[port]; - ASSERT(port < CONFIG_BC12_DETECT_PI3USB9281_CHIP_COUNT); - - if (chip->mux_lock) { - mutex_lock(chip->mux_lock); - gpio_set_level(chip->mux_gpio, chip->mux_gpio_level); - } -} - -static void unselect_chip(int port) -{ - struct pi3usb9281_config *chip = &pi3usb9281_chips[port]; - - if (chip->mux_lock) - /* Just release the mutex, no need to change the mux gpio */ - mutex_unlock(chip->mux_lock); -} - -static uint8_t pi3usb9281_do_read(int port, uint8_t reg, int with_lock) -{ - struct pi3usb9281_config *chip = &pi3usb9281_chips[port]; - int res, val; - - if (with_lock) - select_chip(port); - - res = i2c_read8(chip->i2c_port, PI3USB9281_I2C_ADDR_FLAGS, - reg, &val); - - if (with_lock) - unselect_chip(port); - - if (res) - return 0xee; - - return val; -} - -static uint8_t pi3usb9281_read_u(int port, uint8_t reg) -{ - return pi3usb9281_do_read(port, reg, 0); -} - -static uint8_t pi3usb9281_read(int port, uint8_t reg) -{ - return pi3usb9281_do_read(port, reg, 1); -} - -static int pi3usb9281_do_write( - int port, uint8_t reg, uint8_t val, int with_lock) -{ - struct pi3usb9281_config *chip = &pi3usb9281_chips[port]; - int res; - - if (with_lock) - select_chip(port); - - res = i2c_write8(chip->i2c_port, PI3USB9281_I2C_ADDR_FLAGS, - reg, val); - - if (with_lock) - unselect_chip(port); - - if (res) - CPRINTS("PI3USB9281 I2C write failed"); - return res; -} - -static int pi3usb9281_write(int port, uint8_t reg, uint8_t val) -{ - return pi3usb9281_do_write(port, reg, val, 1); -} - -/* Write control register, taking care to correctly set reserved bits. */ -static int pi3usb9281_do_write_ctrl(int port, uint8_t ctrl, int with_lock) -{ - return pi3usb9281_do_write(port, PI3USB9281_REG_CONTROL, - (ctrl & PI3USB9281_CTRL_MASK) | - PI3USB9281_CTRL_RSVD_1, with_lock); -} - -static int pi3usb9281_write_ctrl(int port, uint8_t ctrl) -{ - return pi3usb9281_do_write_ctrl(port, ctrl, 1); -} - -static int pi3usb9281_write_ctrl_u(int port, uint8_t ctrl) -{ - return pi3usb9281_do_write_ctrl(port, ctrl, 0); -} - -/* - * Mask particular interrupts (e.g. attach, detach, ovp, ocp). - * 1: UnMask (enable). 0: Mask (disable) - */ -static int pi3usb9281_set_interrupt_mask(int port, uint8_t mask) -{ - return pi3usb9281_write(port, PI3USB9281_REG_INT_MASK, ~mask); -} - -static void pi3usb9281_init(int port) -{ - uint8_t dev_id; - - dev_id = pi3usb9281_read(port, PI3USB9281_REG_DEV_ID); - - if (dev_id != PI3USB9281_DEV_ID && dev_id != PI3USB9281_DEV_ID_A) - CPRINTS("PI3USB9281 invalid ID 0x%02x", dev_id); - - pi3usb9281_reset(port); - pi3usb9281_enable_interrupts(port); -} - - -int pi3usb9281_enable_interrupts(int port) -{ - uint8_t ctrl; - pi3usb9281_set_interrupt_mask(port, PI3USB9281_INT_ATTACH_DETACH); - ctrl = pi3usb9281_read(port, PI3USB9281_REG_CONTROL); - if (ctrl == 0xee) - return EC_ERROR_UNKNOWN; - - return pi3usb9281_write_ctrl(port, ctrl & ~PI3USB9281_CTRL_INT_DIS); -} - -static int pi3usb9281_disable_interrupts(int port) -{ - uint8_t ctrl = pi3usb9281_read(port, PI3USB9281_REG_CONTROL); - int rv; - - if (ctrl == 0xee) - return EC_ERROR_UNKNOWN; - - rv = pi3usb9281_write_ctrl(port, ctrl | PI3USB9281_CTRL_INT_DIS); - pi3usb9281_get_interrupts(port); - return rv; -} - -static int pi3usb9281_get_interrupts(int port) -{ - return pi3usb9281_read(port, PI3USB9281_REG_INT); -} - -int pi3usb9281_get_device_type(int port) -{ - return pi3usb9281_read(port, PI3USB9281_REG_DEV_TYPE) & 0x77; -} - -static int pi3usb9281_get_charger_status(int port) -{ - return pi3usb9281_read(port, PI3USB9281_REG_CHG_STATUS) & 0x1f; -} - -static int pi3usb9281_get_ilim(int device_type, int charger_status) -{ - /* Limit USB port current. 500mA for not listed types. */ - int current_limit_ma = 500; - - /* - * The USB Type-C specification limits the maximum amount of current - * from BC 1.2 suppliers to 1.5A. Technically, proprietary methods are - * not allowed, but we will continue to allow those. - */ - if (charger_status & PI3USB9281_CHG_CAR_TYPE1 || - charger_status & PI3USB9281_CHG_CAR_TYPE2) - current_limit_ma = USB_CHARGER_MAX_CURR_MA; - else if (charger_status & PI3USB9281_CHG_APPLE_1A) - current_limit_ma = 1000; - else if (charger_status & PI3USB9281_CHG_APPLE_2A) - current_limit_ma = USB_CHARGER_MAX_CURR_MA; - else if (charger_status & PI3USB9281_CHG_APPLE_2_4A) - current_limit_ma = USB_CHARGER_MAX_CURR_MA; - else if (device_type & PI3USB9281_TYPE_CDP) - current_limit_ma = USB_CHARGER_MAX_CURR_MA; - else if (device_type & PI3USB9281_TYPE_DCP) - current_limit_ma = 500; - - return current_limit_ma; -} - -static int pi3usb9281_reset(int port) -{ - int rv = pi3usb9281_write(port, PI3USB9281_REG_RESET, 0x1); - - if (!rv) - /* Reset takes ~15ms. Wait for 20ms to be safe. */ - msleep(PI3USB9281_SW_RESET_DELAY); - - return rv; -} - -static int pi3usb9281_set_switch_manual(int port, int val) -{ - int res = EC_ERROR_UNKNOWN; - uint8_t ctrl; - - select_chip(port); - ctrl = pi3usb9281_read_u(port, PI3USB9281_REG_CONTROL); - - if (ctrl != 0xee) { - if (val) - ctrl &= ~PI3USB9281_CTRL_AUTO; - else - ctrl |= PI3USB9281_CTRL_AUTO; - res = pi3usb9281_write_ctrl_u(port, ctrl); - } - - unselect_chip(port); - return res; -} - -static int pi3usb9281_set_pins(int port, uint8_t val) -{ - return pi3usb9281_write(port, PI3USB9281_REG_MANUAL, val); -} - -static int pi3usb9281_set_switches_impl(int port, int open) -{ - int res = EC_ERROR_UNKNOWN; - uint8_t ctrl; - - select_chip(port); - ctrl = pi3usb9281_read_u(port, PI3USB9281_REG_CONTROL); - - if (ctrl != 0xee) { - if (open) - ctrl &= ~PI3USB9281_CTRL_SWITCH_AUTO; - else - ctrl |= PI3USB9281_CTRL_SWITCH_AUTO; - res = pi3usb9281_write_ctrl_u(port, ctrl); - } - - unselect_chip(port); - return res; -} - -static void pi3usb9281_set_switches(int port, enum usb_switch setting) -{ - /* If switch is not changing then return */ - if (setting == usb_switch_state[port]) - return; - if (setting != USB_SWITCH_RESTORE) - usb_switch_state[port] = setting; - CPRINTS("USB MUX %d", usb_switch_state[port]); - task_set_event(TASK_ID_USB_CHG_P0 + port, USB_CHG_EVENT_MUX); -} - -static int pc3usb9281_read_interrupt(int port) -{ - timestamp_t timeout; - timeout.val = get_time().val + PI3USB9281_RESET_STARTUP_DELAY; - do { - /* Read (& clear) possible attach & detach interrupt */ - if (pi3usb9281_get_interrupts(port) & - PI3USB9281_INT_ATTACH_DETACH) - return EC_SUCCESS; - msleep(PI3USB9281_RESET_STARTUP_DELAY_INTERVAL_MS); - } while (get_time().val < timeout.val); - return EC_ERROR_TIMEOUT; -} - -/* - * Handle BC 1.2 attach & detach event - * - * On attach, it resets pi3usb9281 for debounce. This reset should immediately - * trigger another attach or detach interrupt. If other (unexpected) event is - * observed, it forwards the event so that the caller can handle it. - */ -static uint32_t bc12_detect(int port) -{ - int device_type, chg_status; - uint32_t evt = 0; - - if (usb_charger_port_is_sourcing_vbus(port)) { - /* If we're sourcing VBUS then we're not charging */ - device_type = PI3USB9281_TYPE_NONE; - chg_status = PI3USB9281_CHG_NONE; - } else { - /* Set device type */ - device_type = pi3usb9281_get_device_type(port); - chg_status = pi3usb9281_get_charger_status(port); - } - - /* Debounce pin plug order if we detect a charger */ - if (device_type || PI3USB9281_CHG_STATUS_ANY(chg_status)) { - /* next operation might trigger a detach interrupt */ - pi3usb9281_disable_interrupts(port); - /* - * Ensure D+/D- are open before resetting - * Note: we can't simply call pi3usb9281_set_switches() because - * another task might override it and set the switches closed. - */ - pi3usb9281_set_switch_manual(port, 1); - pi3usb9281_set_pins(port, 0); - - /* Delay to debounce pin attach order */ - msleep(PI3USB9281_DETECT_DEBOUNCE_MS); - - /* - * Reset PI3USB9281 to refresh detection registers. After reset, - * - Interrupt is globally disabled - * - All interrupts are unmasked (=enabled) - * - * WARNING: This reset is acceptable for samus_pd, - * but may not be acceptable for devices that have - * an OTG / device mode, as we may be interrupting - * the connection. - */ - pi3usb9281_reset(port); - - /* - * Restore data switch settings - switches return to - * closed on reset until restored. - */ - pi3usb9281_set_switches(port, USB_SWITCH_RESTORE); - - /* - * Wait after reset, before re-enabling interrupt, so that - * spurious interrupts from this port are ignored. - */ - msleep(PI3USB9281_RESET_DEBOUNCE_MS); - - /* Re-enable interrupts */ - pi3usb9281_enable_interrupts(port); - - /* - * Consume interrupt (expectedly) triggered by the reset. - * If it's other event (e.g. VBUS), return immediately. - */ - evt = task_wait_event(PI3USB9281_RESET_DEBOUNCE_MS * MSEC); - if (evt & USB_CHG_EVENT_BC12) - evt &= ~USB_CHG_EVENT_BC12; - else if (evt & USB_CHG_EVENT_INTR) - evt &= ~USB_CHG_EVENT_INTR; - else - return evt; - - /* Debounce is done. Registers should have trustworthy values */ - device_type = PI3USB9281_TYPE_NONE; - chg_status = PI3USB9281_CHG_NONE; - if (pc3usb9281_read_interrupt(port) == EC_SUCCESS) { - device_type = pi3usb9281_get_device_type(port); - chg_status = pi3usb9281_get_charger_status(port); - } - } - - /* Attachment: decode + update available charge */ - if (device_type || PI3USB9281_CHG_STATUS_ANY(chg_status)) { - struct charge_port_info chg; - int type; - - if (PI3USB9281_CHG_STATUS_ANY(chg_status)) - type = CHARGE_SUPPLIER_PROPRIETARY; - else if (device_type & PI3USB9281_TYPE_CDP) - type = CHARGE_SUPPLIER_BC12_CDP; - else if (device_type & PI3USB9281_TYPE_DCP) - type = CHARGE_SUPPLIER_BC12_DCP; - else if (device_type & PI3USB9281_TYPE_SDP) - type = CHARGE_SUPPLIER_BC12_SDP; - else - type = CHARGE_SUPPLIER_OTHER; - - chg.voltage = USB_CHARGER_VOLTAGE_MV; - chg.current = pi3usb9281_get_ilim(device_type, chg_status); - charge_manager_update_charge(type, port, &chg); - } else { - /* Detachment: update available charge to 0 */ - usb_charger_reset_charge(port); - } - - return evt; -} - -static void pi3usb9281_usb_charger_task(const int port) -{ - uint32_t evt; - - /* Initialize chip and enable interrupts */ - pi3usb9281_init(port); - - evt = bc12_detect(port); - - while (1) { - /* Interrupt from the Pericom chip, determine charger type */ - if (evt & USB_CHG_EVENT_BC12) { - /* Read interrupt register to clear on chip */ - pi3usb9281_get_interrupts(port); - evt = bc12_detect(port); - } else if (evt & USB_CHG_EVENT_INTR) { - /* USB_CHG_EVENT_INTR & _BC12 are mutually exclusive */ - /* Check the interrupt register, and clear on chip */ - if (pi3usb9281_get_interrupts(port) & - PI3USB9281_INT_ATTACH_DETACH) - evt = bc12_detect(port); - } - - if (evt & USB_CHG_EVENT_MUX) - pi3usb9281_set_switches_impl( - port, usb_switch_state[port]); - - /* - * Re-enable interrupts on pericom charger detector since the - * chip may periodically reset itself, and come back up with - * registers in default state. TODO(crosbug.com/p/33823): Fix - * these unwanted resets. - */ - if (evt & USB_CHG_EVENT_VBUS) { - pi3usb9281_enable_interrupts(port); -#ifndef CONFIG_USB_PD_VBUS_DETECT_TCPC - CPRINTS("VBUS p%d %d", port, - pd_snk_is_vbus_provided(port)); -#endif - } - - evt = task_wait_event(-1); - } -} - -#if defined(CONFIG_CHARGE_RAMP_SW) || defined(CONFIG_CHARGE_RAMP_HW) -static int pi3usb9281_ramp_allowed(int supplier) -{ - return supplier == CHARGE_SUPPLIER_BC12_DCP || - supplier == CHARGE_SUPPLIER_BC12_SDP || - supplier == CHARGE_SUPPLIER_BC12_CDP || - supplier == CHARGE_SUPPLIER_PROPRIETARY; -} - -static int pi3usb9281_ramp_max(int supplier, int sup_curr) -{ - switch (supplier) { - case CHARGE_SUPPLIER_BC12_DCP: - return USB_CHARGER_MAX_CURR_MA; - case CHARGE_SUPPLIER_BC12_SDP: - return 500; - case CHARGE_SUPPLIER_BC12_CDP: - case CHARGE_SUPPLIER_PROPRIETARY: - return sup_curr; - default: - return 500; - } -} -#endif /* CONFIG_CHARGE_RAMP_SW || CONFIG_CHARGE_RAMP_HW */ - -const struct bc12_drv pi3usb9281_drv = { - .usb_charger_task = pi3usb9281_usb_charger_task, - .set_switches = pi3usb9281_set_switches, -#if defined(CONFIG_CHARGE_RAMP_SW) || defined(CONFIG_CHARGE_RAMP_HW) - .ramp_allowed = pi3usb9281_ramp_allowed, - .ramp_max = pi3usb9281_ramp_max, -#endif /* CONFIG_CHARGE_RAMP_SW || CONFIG_CHARGE_RAMP_HW */ -}; - -#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 = &pi3usb9281_drv, - }, -}; -#endif /* CONFIG_BC12_SINGLE_DRIVER */ diff --git a/driver/bc12/pi3usb9281.h b/driver/bc12/pi3usb9281.h deleted file mode 100644 index ca1828f49c..0000000000 --- a/driver/bc12/pi3usb9281.h +++ /dev/null @@ -1,83 +0,0 @@ -/* Copyright 2014 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. - * - * Pericom PI3USB9281 USB port switch. - */ - -#ifndef __CROS_EC_PI3USB9281_H -#define __CROS_EC_PI3USB9281_H - -#define PI3USB9281_REG_DEV_ID 0x01 -#define PI3USB9281_REG_CONTROL 0x02 -#define PI3USB9281_REG_INT 0x03 -#define PI3USB9281_REG_INT_MASK 0x05 -#define PI3USB9281_REG_DEV_TYPE 0x0a -#define PI3USB9281_REG_CHG_STATUS 0x0e -#define PI3USB9281_REG_MANUAL 0x13 -#define PI3USB9281_REG_RESET 0x1b -#define PI3USB9281_REG_VBUS 0x1d - -#define PI3USB9281_DEV_ID 0x10 -#define PI3USB9281_DEV_ID_A 0x18 - -#define PI3USB9281_CTRL_INT_DIS BIT(0) -#define PI3USB9281_CTRL_AUTO BIT(2) -#define PI3USB9281_CTRL_SWITCH_AUTO BIT(4) -/* Bits 5 thru 7 are read X, write 0 */ -#define PI3USB9281_CTRL_MASK 0x1f -/* Bits 1 and 3 are read 1, write 1 */ -#define PI3USB9281_CTRL_RSVD_1 0x0a - -#define PI3USB9281_PIN_MANUAL_VBUS (3 << 0) -#define PI3USB9281_PIN_MANUAL_DP BIT(2) -#define PI3USB9281_PIN_MANUAL_DM BIT(5) - -#define PI3USB9281_INT_ATTACH BIT(0) -#define PI3USB9281_INT_DETACH BIT(1) -#define PI3USB9281_INT_OVP BIT(5) -#define PI3USB9281_INT_OCP BIT(6) -#define PI3USB9281_INT_OVP_OC BIT(7) -#define PI3USB9281_INT_ATTACH_DETACH (PI3USB9281_INT_ATTACH | \ - PI3USB9281_INT_DETACH) - -#define PI3USB9281_TYPE_NONE 0 -#define PI3USB9281_TYPE_MHL BIT(0) -#define PI3USB9281_TYPE_OTG BIT(1) -#define PI3USB9281_TYPE_SDP BIT(2) -#define PI3USB9281_TYPE_CAR BIT(4) -#define PI3USB9281_TYPE_CDP BIT(5) -#define PI3USB9281_TYPE_DCP BIT(6) - -#define PI3USB9281_CHG_NONE 0 -#define PI3USB9281_CHG_CAR_TYPE1 BIT(1) -#define PI3USB9281_CHG_CAR_TYPE2 (3 << 0) -#define PI3USB9281_CHG_APPLE_1A BIT(2) -#define PI3USB9281_CHG_APPLE_2A BIT(3) -#define PI3USB9281_CHG_APPLE_2_4A BIT(4) -/* Check if charge status has any connection */ -#define PI3USB9281_CHG_STATUS_ANY(x) (((x) & 0x1f) > 1) - -/* Define configuration of one pi3usb9281 part */ -struct pi3usb9281_config { - /* i2c port that chip resides on */ - int i2c_port; - /* GPIO for chip selection in muxed configuration */ - enum gpio_signal mux_gpio; - /* Logic level of mux_gpio to select chip */ - int mux_gpio_level; - /* Mutex to lock access to mux gpio or NULL if no mux exists */ - struct mutex *mux_lock; -}; - -/* Configuration struct defined at board level */ -extern struct pi3usb9281_config pi3usb9281_chips[]; - -/* Enable interrupts. */ -int pi3usb9281_enable_interrupts(int port); - -/* Get the device type */ -int pi3usb9281_get_device_type(int port); - -extern const struct bc12_drv pi3usb9281_drv; -#endif /* __CROS_EC_PI3USB9281_H */ |