/* Copyright Statement: * * This software/firmware and related documentation ("MediaTek Software") are * protected under relevant copyright laws. The information contained herein * is confidential and proprietary to MediaTek Inc. and/or its licensors. * Without the prior written permission of MediaTek inc. and/or its licensors, * any reproduction, modification, use or disclosure of MediaTek Software, * and information contained herein, in whole or in part, shall be strictly prohibited. */ /* MediaTek Inc. (C) 2015. All rights reserved. * * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. */ #include #include #include #include #include #include #include #if !defined(CONFIG_POWER_EXT) #include #endif int g_ncp1854_log_en = 0; #define I2C_SWITCHING_CHARGER_CHANNEL 3 #define DISABLE_NCP1854_FACTORY_MODE /********************************************************** * * [I2C Slave Setting] * *********************************************************/ #define NCP1854_SLAVE_ADDR_WRITE 0x6C #define NCP1854_SLAVE_ADDR_READ 0x6D /********************************************************** * * [Global Variable] * *********************************************************/ #define NCP1854_REG_NUM 18 #ifdef I2C_SWITCHING_CHARGER_CHANNEL #define NCP1854_BUSNUM I2C_SWITCHING_CHARGER_CHANNEL #else #define NCP1854_BUSNUM 3 #endif #define PRECC_BATVOL 2800 /* preCC 2.8V */ /* #ifndef GPIO_SWCHARGER_EN_PIN #define GPIO_SWCHARGER_EN_PIN 65 #endif */ kal_uint8 ncp1854_reg[NCP1854_REG_NUM] = { 0 }; /********************************************************** * * [I2C Function For Read/Write ncp1854] * *********************************************************/ static struct mt_i2c_t ncp1854_i2c; kal_uint32 ncp1854_write_byte(kal_uint8 addr, kal_uint8 value) { kal_uint32 ret_code = I2C_OK; kal_uint8 write_data[2]; kal_uint16 len; write_data[0] = addr; write_data[1] = value; ncp1854_i2c.id = NCP1854_BUSNUM; /* Since i2c will left shift 1 bit, we need to set NCP1854 I2C address to >>1 */ ncp1854_i2c.addr = (NCP1854_SLAVE_ADDR_WRITE >> 1); ncp1854_i2c.mode = ST_MODE; ncp1854_i2c.speed = 100; len = 2; ret_code = i2c_write(&ncp1854_i2c, write_data, len); if (I2C_OK != ret_code) dprintf(INFO, "%s: i2c_write: ret_code: %d\n", __func__, ret_code); return ret_code; } kal_uint32 ncp1854_read_byte(kal_uint8 addr, kal_uint8 *dataBuffer) { kal_uint32 ret_code = I2C_OK; kal_uint16 len; *dataBuffer = addr; ncp1854_i2c.id = NCP1854_BUSNUM; /* Since i2c will left shift 1 bit, we need to set NCP1854 I2C address to >>1 */ ncp1854_i2c.addr = (NCP1854_SLAVE_ADDR_READ >> 1); ncp1854_i2c.mode = ST_MODE; ncp1854_i2c.speed = 100; len = 1; ret_code = i2c_write_read(&ncp1854_i2c, dataBuffer, len, len); if (I2C_OK != ret_code) dprintf(INFO, "%s: i2c_read: ret_code: %d\n", __func__, ret_code); return ret_code; } /********************************************************** * * [Read / Write Function] * *********************************************************/ kal_uint32 ncp1854_read_interface(kal_uint8 RegNum, kal_uint8 *val, kal_uint8 MASK, kal_uint8 SHIFT) { kal_uint8 ncp1854_reg = 0; int ret = 0; dprintf(INFO, "--------------------------------------------------\n"); ret = ncp1854_read_byte(RegNum, &ncp1854_reg); dprintf(INFO, "[ncp1854_read_interface] Reg[%x]=0x%x\n", RegNum, ncp1854_reg); ncp1854_reg &= (MASK << SHIFT); *val = (ncp1854_reg >> SHIFT); dprintf(INFO, "[ncp1854_read_interface] Val=0x%x\n", *val); return ret; } kal_uint32 ncp1854_config_interface(kal_uint8 RegNum, kal_uint8 val, kal_uint8 MASK, kal_uint8 SHIFT) { kal_uint8 ncp1854_reg = 0; int ret = 0; dprintf(INFO, "--------------------------------------------------\n"); ret = ncp1854_read_byte(RegNum, &ncp1854_reg); /* dprintf(INFO, "[ncp1854_config_interface] Reg[%x]=0x%x\n", RegNum, ncp1854_reg); */ ncp1854_reg &= ~(MASK << SHIFT); ncp1854_reg |= (val << SHIFT); if (RegNum == NCP1854_CON1 && val == 1 && MASK == CON1_REG_RST_MASK && SHIFT == CON1_REG_RST_SHIFT) { /* RESET bit */ } else if (RegNum == NCP1854_CON1) { ncp1854_reg &= ~0x80; /* RESET bit read returs 1, so clear it */ } ret = ncp1854_write_byte(RegNum, ncp1854_reg); /* dprintf(INFO, "[ncp18546_config_interface] Write Reg[%x]=0x%x\n", RegNum, ncp1854_reg); */ /* Check */ /* ncp1854_read_byte(RegNum, &ncp1854_reg); */ /* dprintf(INFO, "[ncp1854_config_interface] Check Reg[%x]=0x%x\n", RegNum, ncp1854_reg); */ return ret; } /********************************************************** * * [ncp1854 Function] * *********************************************************/ /* CON0 */ kal_uint32 ncp1854_get_chip_status(void) { kal_uint32 ret = 0; kal_uint8 val = 0; ret = ncp1854_read_interface((kal_uint8) (NCP1854_CON0), (&val), (kal_uint8) (CON0_STATE_MASK), (kal_uint8) (CON0_STATE_SHIFT) ); return val; } kal_uint32 ncp1854_get_batfet(void) { kal_uint32 ret = 0; kal_uint8 val = 0; ret = ncp1854_read_interface((kal_uint8) (NCP1854_CON0), (&val), (kal_uint8) (CON0_BATFET_MASK), (kal_uint8) (CON0_BATFET_SHIFT) ); return val; } kal_uint32 ncp1854_get_statint(void) { kal_uint32 ret = 0; kal_uint8 val = 0; ret = ncp1854_read_interface((kal_uint8) (NCP1854_CON0), (&val), (kal_uint8) (CON0_STATINT_MASK), (kal_uint8) (CON0_STATINT_SHIFT) ); return val; } kal_uint32 ncp1854_get_faultint(void) { kal_uint32 ret = 0; kal_uint8 val = 0; ret = ncp1854_read_interface((kal_uint8) (NCP1854_CON0), (&val), (kal_uint8) (CON0_FAULTINT_MASK), (kal_uint8) (CON0_FAULTINT_SHIFT) ); return val; } /* CON1 */ void ncp1854_set_reset(kal_uint32 val) { kal_uint32 ret = 0; ret = ncp1854_config_interface((kal_uint8) (NCP1854_CON1), (kal_uint8) (val), (kal_uint8) (CON1_REG_RST_MASK), (kal_uint8) (CON1_REG_RST_SHIFT) ); } void ncp1854_set_chg_en(kal_uint32 val) { kal_uint32 ret = 0; ret = ncp1854_config_interface((kal_uint8) (NCP1854_CON1), (kal_uint8) (val), (kal_uint8) (CON1_CHG_EN_MASK), (kal_uint8) (CON1_CHG_EN_SHIFT) ); } void ncp1854_set_otg_en(kal_uint32 val) { kal_uint32 ret = 0; ret = ncp1854_config_interface((kal_uint8) (NCP1854_CON1), (kal_uint8) (val), (kal_uint8) (CON1_OTG_EN_MASK), (kal_uint8) (CON1_OTG_EN_SHIFT) ); return val; } kal_uint32 ncp1854_get_otg_en(void) { kal_uint32 ret = 0; kal_uint8 val = 0; ret = ncp1854_read_interface((kal_uint8) (NCP1854_CON1), (&val), (kal_uint8) (CON1_OTG_EN_MASK), (kal_uint8) (CON1_OTG_EN_SHIFT) ); return val; } void ncp1854_set_fctry_mode(kal_uint32 val) { kal_uint32 ret = 0; ret = ncp1854_config_interface((kal_uint8) (NCP1854_CON1), (kal_uint8) (val), (kal_uint8) (CON1_FCTRY_MOD_MASK), (kal_uint8) (CON1_FCTRY_MOD_SHIFT) ); } void ncp1854_set_tj_warn_opt(kal_uint32 val) { kal_uint32 ret = 0; ret = ncp1854_config_interface((kal_uint8) (NCP1854_CON1), (kal_uint8) (val), (kal_uint8) (CON1_TJ_WARN_OPT_MASK), (kal_uint8) (CON1_TJ_WARN_OPT_SHIFT) ); } kal_uint32 ncp1854_get_usb_cfg(void) { kal_uint32 ret = 0; kal_uint8 val = 0; ret = ncp1854_read_interface((kal_uint8) (NCP1854_CON1), (&val), (kal_uint8) (CON1_USB_CFG_MASK), (kal_uint8) (CON1_USB_CFG_SHIFT) ); return val; } void ncp1854_set_tchg_rst(kal_uint32 val) { kal_uint32 ret = 0; ret = ncp1854_config_interface((kal_uint8) (NCP1854_CON1), (kal_uint8) (val), (kal_uint8) (CON1_TCHG_RST_MASK), (kal_uint8) (CON1_TCHG_RST_SHIFT) ); } void ncp1854_set_int_mask(kal_uint32 val) { kal_uint32 ret = 0; ret = ncp1854_config_interface((kal_uint8) (NCP1854_CON1), (kal_uint8) (val), (kal_uint8) (CON1_INT_MASK_MASK), (kal_uint8) (CON1_INT_MASK_SHIFT) ); } /* CON2 */ void ncp1854_set_wdto_dis(kal_uint32 val) { kal_uint32 ret = 0; ret = ncp1854_config_interface((kal_uint8) (NCP1854_CON2), (kal_uint8) (val), (kal_uint8) (CON2_WDTO_DIS_MASK), (kal_uint8) (CON2_WDTO_DIS_SHIFT) ); } void ncp1854_set_chgto_dis(kal_uint32 val) { kal_uint32 ret = 0; ret = ncp1854_config_interface((kal_uint8) (NCP1854_CON2), (kal_uint8) (val), (kal_uint8) (CON2_CHGTO_DIS_MASK), (kal_uint8) (CON2_CHGTO_DIS_SHIFT) ); } void ncp1854_set_pwr_path(kal_uint32 val) { kal_uint32 ret = 0; ret = ncp1854_config_interface((kal_uint8) (NCP1854_CON2), (kal_uint8) (val), (kal_uint8) (CON2_PWR_PATH_MASK), (kal_uint8) (CON2_PWR_PATH_SHIFT) ); } void ncp1854_set_trans_en(kal_uint32 val) { kal_uint32 ret = 0; ret = ncp1854_config_interface((kal_uint8) (NCP1854_CON2), (kal_uint8) (val), (kal_uint8) (CON2_TRANS_EN_MASK), (kal_uint8) (CON2_TRANS_EN_SHIFT) ); } void ncp1854_set_iinset_pin_en(kal_uint32 val) { kal_uint32 ret = 0; ret = ncp1854_config_interface((kal_uint8) (NCP1854_CON2), (kal_uint8) (val), (kal_uint8) (CON2_IINSET_PIN_EN_MASK), (kal_uint8) (CON2_IINSET_PIN_EN_SHIFT) ); } void ncp1854_set_iinlim_en(kal_uint32 val) { kal_uint32 ret = 0; ret = ncp1854_config_interface((kal_uint8) (NCP1854_CON2), (kal_uint8) (val), (kal_uint8) (CON2_IINLIM_EN_MASK), (kal_uint8) (CON2_IINLIM_EN_SHIFT) ); } void ncp1854_set_aicl_en(kal_uint32 val) { kal_uint32 ret = 0; ret = ncp1854_config_interface((kal_uint8) (NCP1854_CON2), (kal_uint8) (val), (kal_uint8) (CON2_AICL_EN_MASK), (kal_uint8) (CON2_AICL_EN_SHIFT) ); } /* CON8 */ kal_uint32 ncp1854_get_vfet_ok(void) { kal_uint32 ret = 0; kal_uint8 val = 0; ret = ncp1854_read_interface((kal_uint8) (NCP1854_CON8), (&val), (kal_uint8) (CON8_VFET_OK_MASK), (kal_uint8) (CON8_VFET_OK_SHIFT) ); return val; } /* CON14 */ void ncp1854_set_ctrl_vbat(kal_uint32 val) { kal_uint32 ret = 0; ret = ncp1854_config_interface((kal_uint8) (NCP1854_CON14), (kal_uint8) (val), (kal_uint8) (CON14_CTRL_VBAT_MASK), (kal_uint8) (CON14_CTRL_VBAT_SHIFT) ); } /* CON15 */ void ncp1854_set_ichg_high(kal_uint32 val) { kal_uint32 ret = 0; ret = ncp1854_config_interface((kal_uint8) (NCP1854_CON15), (kal_uint8) (val), (kal_uint8) (CON15_ICHG_HIGH_MASK), (kal_uint8) (CON15_ICHG_HIGH_SHIFT) ); } void ncp1854_set_ieoc(kal_uint32 val) { kal_uint32 ret = 0; ret = ncp1854_config_interface((kal_uint8) (NCP1854_CON15), (kal_uint8) (val), (kal_uint8) (CON15_IEOC_MASK), (kal_uint8) (CON15_IEOC_SHIFT) ); } void ncp1854_set_ichg(kal_uint32 val) { kal_uint32 ret = 0; ret = ncp1854_config_interface((kal_uint8) (NCP1854_CON15), (kal_uint8) (val), (kal_uint8) (CON15_ICHG_MASK), (kal_uint8) (CON15_ICHG_SHIFT) ); } kal_uint32 ncp1854_get_ichg(void) { kal_uint32 ret = 0; kal_uint8 val = 0; ret = ncp1854_read_interface((kal_uint8) NCP1854_CON15, (&val), (kal_uint8) CON15_ICHG_MASK, (kal_uint8) CON15_ICHG_SHIFT); return val; } /* CON16 */ void ncp1854_set_iweak(kal_uint32 val) { kal_uint32 ret = 0; ret = ncp1854_config_interface((kal_uint8) (NCP1854_CON16), (kal_uint8) (val), (kal_uint8) (CON16_IWEAK_MASK), (kal_uint8) (CON16_IWEAK_SHIFT) ); } void ncp1854_set_ctrl_vfet(kal_uint32 val) { kal_uint32 ret = 0; ret = ncp1854_config_interface((kal_uint8) (NCP1854_CON16), (kal_uint8) (val), (kal_uint8) (CON16_CTRL_VFET_MASK), (kal_uint8) (CON16_CTRL_VFET_SHIFT) ); } void ncp1854_set_iinlim(kal_uint32 val) { kal_uint32 ret = 0; ret = ncp1854_config_interface((kal_uint8) (NCP1854_CON16), (kal_uint8) (val), (kal_uint8) (CON16_IINLIM_MASK), (kal_uint8) (CON16_IINLIM_SHIFT) ); } /* CON17 */ void ncp1854_set_iinlim_ta(kal_uint32 val) { kal_uint32 ret = 0; ret = ncp1854_config_interface((kal_uint8) (NCP1854_CON17), (kal_uint8) (val), (kal_uint8) (CON17_IINLIM_TA_MASK), (kal_uint8) (CON17_IINLIM_TA_SHIFT) ); } /********************************************************** * * [Internal Function] * *********************************************************/ void ncp1854_dump_register(void) { int i = 0; for (i = 0; i < NCP1854_REG_NUM; i++) { if ((i == 3) || (i == 4) || (i == 5) || (i == 6)) /* do not dump read clear status register */ continue; if ((i == 10) || (i == 11) || (i == 12) || (i == 13)) /* do not dump interrupt mask bit register */ continue; ncp1854_read_byte(i, &ncp1854_reg[i]); printf("[ncp1854_dump_register] Reg[0x%X]=0x%X\n", i, ncp1854_reg[i]); } } void ncp1854_hw_init(void) { printf("[ncp1854] ChargerHwInit_ncp1854\n"); kal_uint32 ncp1854_status; ncp1854_status = ncp1854_get_chip_status(); /* if you want disable factory mode,the FTRY pin and FCTRY_MOD_REG need different */ #ifdef DISABLE_NCP1854_FACTORY_MODE ncp1854_set_fctry_mode(0x0); #else ncp1854_set_fctry_mode(0x1); #endif ncp1854_set_otg_en(0x0); ncp1854_set_trans_en(0); ncp1854_set_tj_warn_opt(0x0); /* ncp1854_set_int_mask(0x0); //disable all interrupt */ ncp1854_set_int_mask(0x1); /* enable all interrupt for boost mode status monitor */ /* ncp1854_set_tchg_rst(0x1); //reset charge timer */ #ifdef NCP1854_PWR_PATH ncp1854_set_pwr_path(0x1); #else ncp1854_set_pwr_path(0x0); #endif if ((ncp1854_status == 0x8) || (ncp1854_status == 0x9) || (ncp1854_status == 0xA)) /* WEAK WAIT, WEAK SAFE, WEAK CHARGE */ ncp1854_set_ctrl_vbat(0x1C); /* VCHG = 4.0V */ else { ncp1854_set_ctrl_vbat(0x24); /* VCHG = 4.2V */ ncp1854_set_aicl_en(0x1); /* enable AICL as PT team suggest */ ncp1854_set_iinset_pin_en(0x0); /* Input current limit and AICL control by I2C */ ncp1854_set_chgto_dis(0x1); /* disable charge timer */ } ncp1854_set_ieoc(0x4); /* terminate current = 200mA for ICS optimized suspend power */ ncp1854_set_iweak(0x3); /* weak charge current = 300mA */ ncp1854_set_ctrl_vfet(0x0); /* VFET = 3.1V */ } static CHARGER_TYPE g_chr_type_num = CHARGER_UNKNOWN; int hw_charging_get_charger_type(void); extern int g_std_ac_large_current_en; void ncp1854_charging_enable(kal_uint32 bEnable) { int temp_CC_value = 0; kal_int32 bat_val = 0; if (CHARGER_UNKNOWN == g_chr_type_num && KAL_TRUE == upmu_is_chr_det()) { hw_charging_get_charger_type(); dprintf(CRITICAL, "[BATTERY:ncp1854] charger type: %d\n", g_chr_type_num); } bat_val = get_i_sense_volt(1); if (g_chr_type_num == STANDARD_CHARGER) { if (g_std_ac_large_current_en == 1) { temp_CC_value = 2000; ncp1854_set_iinlim_ta(0xF); /* IN current limit at 2A */ ncp1854_set_iinlim_en(0x1); /* IN current limit enable */ if (bat_val < PRECC_BATVOL) { ncp1854_set_ichg_high(0x0); /* ICHG */ ncp1854_set_ichg(0x1); /* Pre-Charging Current Limit at 500mA */ } else { ncp1854_set_ichg_high(0); /* ICHG */ ncp1854_set_ichg(0xF); /* Fast Charging Current Limit at 1.9A */ } } else { temp_CC_value = 1500; ncp1854_set_iinlim_ta(0xA); /* IN current limit at 1.5A */ ncp1854_set_iinlim_en(0x1); /* IN current limit enable */ if (bat_val < PRECC_BATVOL) { ncp1854_set_ichg_high(0x0); /* ICHG */ ncp1854_set_ichg(0x1); /* Pre-Charging Current Limit at 500mA */ } else { ncp1854_set_ichg_high(0); /* ICHG */ ncp1854_set_ichg(0xB); /* Fast Charging Current Limit at 1.5A */ } } } else if (g_chr_type_num == STANDARD_HOST || g_chr_type_num == CHARGING_HOST || g_chr_type_num == NONSTANDARD_CHARGER) { temp_CC_value = 500; ncp1854_set_iinlim_ta(0); /* IINLIM */ ncp1854_set_iinlim(0x1); /* IN current limit at 500mA */ ncp1854_set_iinlim_en(0x1); /* IN current limit enable */ ncp1854_set_ichg_high(0x0); /* ICHG */ ncp1854_set_ichg(0x1); /* Pre-Charging Current Limit at 500mA */ } else { temp_CC_value = 500; ncp1854_set_iinlim_ta(0); /* IINLIM */ ncp1854_set_iinlim(0x1); /* IN current limit at 500mA */ ncp1854_set_iinlim_en(0x1); /* IN current limit enable */ ncp1854_set_ichg_high(0x0); /* ICHG */ ncp1854_set_ichg(0x1); /* Pre-Charging Current Limit at 500mA */ } if (KAL_TRUE == bEnable) ncp1854_set_chg_en(0x1); /* charger enable */ else ncp1854_set_chg_en(0x0); /* charger disable */ ncp1854_set_wdto_dis(0x0); dprintf(INFO, "[BATTERY:ncp1854] ncp1854_set_ac_current(), CC value(%dmA) \r\n", temp_CC_value); dprintf(INFO, "[BATTERY:ncp1854] charger enable/disable %d !\r\n", bEnable); } #if defined(CONFIG_POWER_EXT) int hw_charging_get_charger_type(void) { g_chr_type_num = STANDARD_HOST; return STANDARD_HOST; } #else extern void Charger_Detect_Init(void); extern void Charger_Detect_Release(void); extern void mdelay(unsigned long msec); extern kal_uint16 bc11_set_register_value(PMU_FLAGS_LIST_ENUM flagname, kal_uint32 val); static void hw_bc11_dump_register(void) { /* kal_uint32 reg_val = 0; kal_uint32 reg_num = CHR_CON18; kal_uint32 i = 0; for(i=reg_num ; i<=CHR_CON19 ; i+=2) { reg_val = upmu_get_reg_value(i); dprintf(INFO, "Chr Reg[0x%x]=0x%x \r\n", i, reg_val); } */ } static void hw_bc11_init(void) { mdelay(200); Charger_Detect_Init(); /* RG_bc11_BIAS_EN=1 */ bc11_set_register_value(PMIC_RG_BC11_BIAS_EN, 1); /* RG_bc11_VSRC_EN[1:0]=00 */ bc11_set_register_value(PMIC_RG_BC11_VSRC_EN, 0); /* RG_bc11_VREF_VTH = [1:0]=00 */ bc11_set_register_value(PMIC_RG_BC11_VREF_VTH, 0); /* RG_bc11_CMP_EN[1.0] = 00 */ bc11_set_register_value(PMIC_RG_BC11_CMP_EN, 0); /* RG_bc11_IPU_EN[1.0] = 00 */ bc11_set_register_value(PMIC_RG_BC11_IPU_EN, 0); /* RG_bc11_IPD_EN[1.0] = 00 */ bc11_set_register_value(PMIC_RG_BC11_IPD_EN, 0); /* bc11_RST=1 */ bc11_set_register_value(PMIC_RG_BC11_RST, 1); /* bc11_BB_CTRL=1 */ bc11_set_register_value(PMIC_RG_BC11_BB_CTRL, 1); mdelay(50); if (g_ncp1854_log_en > 1) { dprintf(INFO, "hw_bc11_init() \r\n"); hw_bc11_dump_register(); } } static U32 hw_bc11_DCD(void) { U32 wChargerAvail = 0; /* RG_bc11_IPU_EN[1.0] = 10 */ bc11_set_register_value(PMIC_RG_BC11_IPU_EN, 0x2); /* RG_bc11_IPD_EN[1.0] = 01 */ bc11_set_register_value(PMIC_RG_BC11_IPD_EN, 0x1); /* RG_bc11_VREF_VTH = [1:0]=01 */ bc11_set_register_value(PMIC_RG_BC11_VREF_VTH, 0x1); /* RG_bc11_CMP_EN[1.0] = 10 */ bc11_set_register_value(PMIC_RG_BC11_CMP_EN, 0x2); mdelay(80); wChargerAvail = bc11_get_register_value(PMIC_RGS_BC11_CMP_OUT); if (g_ncp1854_log_en > 1) { dprintf(INFO, "hw_bc11_DCD() \r\n"); hw_bc11_dump_register(); } /* RG_bc11_IPU_EN[1.0] = 00 */ bc11_set_register_value(PMIC_RG_BC11_IPU_EN, 0x0); /* RG_bc11_IPD_EN[1.0] = 00 */ bc11_set_register_value(PMIC_RG_BC11_IPD_EN, 0x0); /* RG_bc11_CMP_EN[1.0] = 00 */ bc11_set_register_value(PMIC_RG_BC11_CMP_EN, 0x0); /* RG_bc11_VREF_VTH = [1:0]=00 */ bc11_set_register_value(PMIC_RG_BC11_VREF_VTH, 0x0); return wChargerAvail; } static U32 hw_bc11_stepA1(void) { U32 wChargerAvail = 0; /* RG_bc11_IPD_EN[1.0] = 01 */ bc11_set_register_value(PMIC_RG_BC11_IPD_EN, 0x1); /* RG_bc11_VREF_VTH = [1:0]=00 */ bc11_set_register_value(PMIC_RG_BC11_VREF_VTH, 0x0); /* RG_bc11_CMP_EN[1.0] = 01 */ bc11_set_register_value(PMIC_RG_BC11_CMP_EN, 0x1); mdelay(80); wChargerAvail = bc11_get_register_value(PMIC_RGS_BC11_CMP_OUT); if (g_ncp1854_log_en > 1) { dprintf(INFO, "hw_bc11_stepA1() \r\n"); hw_bc11_dump_register(); } /* RG_bc11_IPD_EN[1.0] = 00 */ bc11_set_register_value(PMIC_RG_BC11_IPD_EN, 0x0); /* RG_bc11_CMP_EN[1.0] = 00 */ bc11_set_register_value(PMIC_RG_BC11_CMP_EN, 0x0); return wChargerAvail; } static U32 hw_bc11_stepA2(void) { U32 wChargerAvail = 0; /* RG_bc11_VSRC_EN[1.0] = 10 */ bc11_set_register_value(PMIC_RG_BC11_VSRC_EN, 0x2); /* RG_bc11_IPD_EN[1:0] = 01 */ bc11_set_register_value(PMIC_RG_BC11_IPD_EN, 0x1); /* RG_bc11_VREF_VTH = [1:0]=00 */ bc11_set_register_value(PMIC_RG_BC11_VREF_VTH, 0x0); /* RG_bc11_CMP_EN[1.0] = 01 */ bc11_set_register_value(PMIC_RG_BC11_CMP_EN, 0x1); mdelay(80); wChargerAvail = bc11_get_register_value(PMIC_RGS_BC11_CMP_OUT); if (g_ncp1854_log_en) { dprintf(INFO, "hw_bc11_stepB1() \r\n"); hw_bc11_dump_register(); } /* RG_bc11_VSRC_EN[1:0]=00 */ bc11_set_register_value(PMIC_RG_BC11_VSRC_EN, 0x0); /* RG_bc11_IPD_EN[1.0] = 00 */ bc11_set_register_value(PMIC_RG_BC11_IPD_EN, 0x0); /* RG_bc11_CMP_EN[1.0] = 00 */ bc11_set_register_value(PMIC_RG_BC11_CMP_EN, 0x0); return wChargerAvail; } static U32 hw_bc11_stepB2(void) { U32 wChargerAvail = 0; /* RG_bc11_IPU_EN[1:0]=10 */ bc11_set_register_value(PMIC_RG_BC11_IPU_EN, 0x2); /* RG_bc11_VREF_VTH = [1:0]=01 */ bc11_set_register_value(PMIC_RG_BC11_VREF_VTH, 0x1); /* RG_bc11_CMP_EN[1.0] = 01 */ bc11_set_register_value(PMIC_RG_BC11_CMP_EN, 0x1); mdelay(80); wChargerAvail = bc11_get_register_value(PMIC_RGS_BC11_CMP_OUT); if (g_ncp1854_log_en) { dprintf(INFO, "hw_bc11_stepB2() \r\n"); hw_bc11_dump_register(); } if (!wChargerAvail) { /* RG_bc11_VSRC_EN[1.0] = 10 */ /* mt6325_upmu_set_rg_bc11_vsrc_en(0x2); */ bc11_set_register_value(PMIC_RG_BC11_VSRC_EN, 0x2); } /* RG_bc11_IPU_EN[1.0] = 00 */ bc11_set_register_value(PMIC_RG_BC11_IPU_EN, 0x0); /* RG_bc11_CMP_EN[1.0] = 00 */ bc11_set_register_value(PMIC_RG_BC11_CMP_EN, 0x0); /* RG_bc11_VREF_VTH = [1:0]=00 */ bc11_set_register_value(PMIC_RG_BC11_VREF_VTH, 0x0); return wChargerAvail; } static void hw_bc11_done(void) { /* RG_bc11_VSRC_EN[1:0]=00 */ bc11_set_register_value(PMIC_RG_BC11_VSRC_EN, 0x0); /* RG_bc11_VREF_VTH = [1:0]=0 */ bc11_set_register_value(PMIC_RG_BC11_VREF_VTH, 0x0); /* RG_bc11_CMP_EN[1.0] = 00 */ bc11_set_register_value(PMIC_RG_BC11_CMP_EN, 0x0); /* RG_bc11_IPU_EN[1.0] = 00 */ bc11_set_register_value(PMIC_RG_BC11_IPU_EN, 0x0); /* RG_bc11_IPD_EN[1.0] = 00 */ bc11_set_register_value(PMIC_RG_BC11_IPD_EN, 0x0); /* RG_bc11_BIAS_EN=0 */ bc11_set_register_value(PMIC_RG_BC11_BIAS_EN, 0x0); Charger_Detect_Release(); if (g_ncp1854_log_en > 1) { dprintf(INFO, "hw_bc11_done() \r\n"); hw_bc11_dump_register(); } } int hw_charging_get_charger_type(void) { if (CHARGER_UNKNOWN != g_chr_type_num) return g_chr_type_num; #if 0 return STANDARD_HOST; #else CHARGER_TYPE CHR_Type_num = CHARGER_UNKNOWN; /********* Step initial ***************/ hw_bc11_init(); /********* Step DCD ***************/ if (1 == hw_bc11_DCD()) { /********* Step A1 ***************/ if (1 == hw_bc11_stepA1()) { CHR_Type_num = APPLE_2_1A_CHARGER; dprintf(INFO, "step A1 : Apple 2.1A CHARGER!\r\n"); } else { CHR_Type_num = NONSTANDARD_CHARGER; dprintf(INFO, "step A1 : Non STANDARD CHARGER!\r\n"); } } else { /********* Step A2 ***************/ if (1 == hw_bc11_stepA2()) { /********* Step B2 ***************/ if (1 == hw_bc11_stepB2()) { CHR_Type_num = STANDARD_CHARGER; dprintf(INFO, "step B2 : STANDARD CHARGER!\r\n"); } else { CHR_Type_num = CHARGING_HOST; dprintf(INFO, "step B2 : Charging Host!\r\n"); } } else { CHR_Type_num = STANDARD_HOST; dprintf(INFO, "step A2 : Standard USB Host!\r\n"); } } /********* Finally setting *******************************/ hw_bc11_done(); g_chr_type_num = CHR_Type_num; return g_chr_type_num; #endif } #endif