/* * Copyright (C) 2019 Allwinner. * weidonghui * * SUNXI AXP Driver * * SPDX-License-Identifier: GPL-2.0+ */ #include #include #include #include static int bmu_axp2585_probe(void) { u8 bmu_chip_id; if (pmic_bus_init(AXP2585_DEVICE_ADDR, AXP2585_RUNTIME_ADDR)) { tick_printf("%s pmic_bus_init fail\n", __func__); return -1; } if (pmic_bus_read(AXP2585_RUNTIME_ADDR, AXP2585_CHIP_ID, &bmu_chip_id)) { tick_printf("%s pmic_bus_read fail\n", __func__); return -1; } bmu_chip_id &= 0XCF; if (bmu_chip_id == 0x46) { /*bmu type AXP2585*/ tick_printf("BMU: AXP2585\n"); return 0; } return -1; } int bmu_axp2585_set_power_off(void) { u8 reg_value; if (pmic_bus_read(AXP2585_RUNTIME_ADDR, BMU_POWER_ON_STATUS, ®_value)) { return -1; } pmic_bus_write(AXP2585_RUNTIME_ADDR, BMU_POWER_ON_STATUS, reg_value); if (pmic_bus_read(AXP2585_RUNTIME_ADDR, BMU_CHG_STATUS, ®_value)) { return -1; } if (reg_value & 0x02) { return 0; } if (pmic_bus_read(AXP2585_RUNTIME_ADDR, BMU_BATFET_CTL, ®_value)) { return -1; } reg_value &= 0x7f; if (pmic_bus_write(AXP2585_RUNTIME_ADDR, BMU_BATFET_CTL, reg_value)) { return -1; } tick_printf("before reg[10]:%x\n", reg_value); mdelay(50); reg_value |= 1 << 7; if (pmic_bus_write(AXP2585_RUNTIME_ADDR, BMU_BATFET_CTL, reg_value)) { return -1; } return 0; } int bmu_axp2585_get_poweron_source(void) { uchar reg_value; if (pmic_bus_read(AXP2585_RUNTIME_ADDR, BMU_POWER_ON_STATUS, ®_value)) { return -1; } tick_printf("poweron cause %x\n", reg_value); /*bit7 : vbus, bit6: battery inster, bit5: battery charge to normal*/ if (reg_value & (1 << 7)) { reg_value &= 0x80; pmic_bus_write(AXP2585_RUNTIME_ADDR, BMU_POWER_ON_STATUS, reg_value); return AXP_POWER_ON_BY_POWER_TRIGGER; } else { /*need to check supply pmu*/ return AXP_POWER_ON_BY_POWER_KEY; } return reg_value & 0x01; } int bmu_axp2585_get_axp_bus_exist(void) { u8 reg_value; if (pmic_bus_read(AXP2585_RUNTIME_ADDR, BMU_CHG_STATUS, ®_value)) { return -1; } /*bit1: 0: vbus not power, 1: power good*/ if (reg_value & 0x2) { return AXP_VBUS_EXIST; } return 0; } int bmu_axp2585_get_battery_vol(void) { u8 reg_value_h = 0, reg_value_l = 0; int tmp_value = 0; int bat_vol; if (pmic_bus_read(AXP2585_RUNTIME_ADDR, BMU_BAT_VOL_H, ®_value_h)) { return -1; } if (pmic_bus_read(AXP2585_RUNTIME_ADDR, BMU_BAT_VOL_L, ®_value_l)) { return -1; } tmp_value = (reg_value_h << 4) | reg_value_l; bat_vol = tmp_value * 12 / 10; return bat_vol; } int bmu_axp2585_get_battery_capacity(void) { u8 reg_value; if (pmic_bus_read(AXP2585_RUNTIME_ADDR, BMU_BAT_PERCENTAGE, ®_value)) { return -1; } //bit7-- 1:valid 0:invalid if (reg_value & (1 << 7)) { reg_value = reg_value & 0x7f; } else { reg_value = 0; } return reg_value; } int bmu_axp2585_get_battery_probe(void) { u8 reg_value; if (pmic_bus_read(AXP2585_RUNTIME_ADDR, BMU_BAT_STATUS, ®_value)) { return -1; } //bit2 -- battery detect result if ((reg_value & (1 << 3))) { return 1; } return 0; } int bmu_axp2585_set_vbus_current_limit(int current) { u8 reg_value; u8 temp; if (pmic_bus_read(AXP2585_RUNTIME_ADDR, BMU_BATFET_CTL, ®_value)) { return -1; } if (current) { if (current > 3250) { temp = 0x3F; } else if (current >= 100) { temp = (current - 100) / 50; } else { temp = 0x00; } } else { /*default was 2500ma*/ temp = 0x30; } reg_value &= 0xB0; reg_value |= temp; tick_printf("Input current:%d mA\n", current); if (pmic_bus_write(AXP2585_RUNTIME_ADDR, BMU_BATFET_CTL, reg_value)) { return -1; } return 0; } unsigned char bmu_axp2585_get_reg_value(unsigned char reg_addr) { u8 reg_value; if (pmic_bus_read(AXP2585_RUNTIME_ADDR, reg_addr, ®_value)) { return -1; } return reg_value; } unsigned char bmu_axp2585_set_reg_value(unsigned char reg_addr, unsigned char reg_value) { unsigned char reg; if (pmic_bus_write(AXP2585_RUNTIME_ADDR, reg_addr, reg_value)) { return -1; } if (pmic_bus_read(AXP2585_RUNTIME_ADDR, reg_addr, ®)) { return -1; } return reg; } U_BOOT_AXP_BMU_INIT(bmu_axp2585) = { .bmu_name = "bmu_axp2585", .probe = bmu_axp2585_probe, .set_power_off = bmu_axp2585_set_power_off, .get_poweron_source = bmu_axp2585_get_poweron_source, .get_axp_bus_exist = bmu_axp2585_get_axp_bus_exist, /*.set_coulombmeter_onoff = bmu_axp2585_set_coulombmeter_onoff,*/ .get_battery_vol = bmu_axp2585_get_battery_vol, .get_battery_capacity = bmu_axp2585_get_battery_capacity, .get_battery_probe = bmu_axp2585_get_battery_probe, .set_vbus_current_limit = bmu_axp2585_set_vbus_current_limit, /*.get_vbus_current_limit = bmu_axp2585_get_vbus_current_limit,*/ /*.set_charge_current_limit = bmu_axp2585_set_charge_current_limit,*/ .get_reg_value = bmu_axp2585_get_reg_value, .set_reg_value = bmu_axp2585_set_reg_value, };