blob: 09a48f9d6aa17898199e019a3af4f01959385750 [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001/*
2 * Copyright (C) 2014 Marvell International Ltd.
3 * Fenghang Yin <yinfh@marvell.com>
4 *
5 * SPDX-License-Identifier: GPL-2.0+
6 */
7
8#include <common.h>
9#include <i2c.h>
10#include <power/pmic.h>
11#include <power/marvell88pm_pmic.h>
12#include <power/88pm830.h>
13#include <power/battery.h>
14#include <errno.h>
15
16#define MARVELL_PMIC_BATTERY "88pm830_battery"
17
18static int pm830_enable_bat_det(struct pmic *p, int enable)
19{
20 u32 val;
21
22 pmic_reg_read(p, PM830_REG_CHG_BAT_DET, &val);
23 if (!!enable)
24 val |= PM830_BAT_DET_EN;
25 else
26 val &= ~PM830_BAT_DET_EN;
27 pmic_reg_write(p, PM830_REG_CHG_BAT_DET, val);
28
29 return 0;
30}
31
32static int pm830_enable_bat_priority(struct pmic *p, int enable)
33{
34 u32 val;
35
36 pmic_reg_read(p, PM830_REG_CHG_CTRL3, &val);
37 if (!!enable)
38 val |= PM830_BAT_PRTY_EN;
39 else
40 val &= ~PM830_BAT_PRTY_EN;
41 pmic_reg_write(p, PM830_REG_CHG_CTRL3, val);
42
43 return 0;
44}
45
46/*
47 * the method used to get power up mode for 88pm830:
48 * step 1. set BD_EN, if battery present, it's BATTERY_MODE
49 * step 2. clear BD_PRTY_EN, if VBAT is valid, it's POWER_SUPPLY_MODE
50 * step 3. clear BD_EN, set BD_PRTY_EN, if VBAT is valid, it's EXTERNAL_POWER_MODE
51 * step 4. if it's CHARGER_ONLY_MODE, system will shutdown in step 3
52 */
53int pm830_get_powerup_mode(void)
54{
55 int ret;
56 struct pmic *p_bat, *p;
57
58 p_bat = pmic_get(MARVELL_PMIC_BATTERY);
59 if (!p_bat) {
60 printf("find battery failed\n");
61 return INVALID_MODE;
62 }
63 p = p_bat->pbat->chrg;
64
65 /* disable the auto battery detection circuit */
66 pm830_enable_bat_det(p, 0);
67 pm830_enable_bat_priority(p, 0);
68
69 ret = p_bat->chrg->chrg_bat_present(p);
70 if (!!ret) {
71 /* it's battery mode */
72 ret = BATTERY_MODE;
73 goto handler;
74 }
75
76 p_bat->fg->fg_battery_update(p_bat->pbat->fg, p_bat, 0);
77 if (p_bat->pbat->bat->voltage_uV > POWER_OFF_THRESHOLD) {
78 /* it's power supply mode */
79 ret = POWER_SUPPLY_MODE;
80 goto handler;
81 }
82
83 printf("if you are in charger-only mode, system will power-off now.\n");
84 /* set BD_PRTY_EN */
85 pm830_enable_bat_priority(p, 1);
86 p_bat->fg->fg_battery_update(p_bat->pbat->fg, p_bat, 0);
87 if (p_bat->pbat->bat->voltage_uV > POWER_OFF_THRESHOLD) {
88 /* it's external power mode */
89 ret = EXTERNAL_POWER_MODE;
90 goto handler;
91 } else {
92 /*
93 * the program will not run to here, since if it's charger only mode, the system
94 * already power off
95 */
96 ret = CHARGER_ONLY_MODE;
97 }
98
99handler:
100 switch (ret) {
101 case BATTERY_MODE:
102 /* in order to handle dead battery case, use charger to supply system */
103 printf("battery mode\n");
104 break;
105 case POWER_SUPPLY_MODE:
106 case EXTERNAL_POWER_MODE:
107 printf("power-supply mode\n");
108 /* use battery supply system */
109 pm830_enable_bat_priority(p, 1);
110 break;
111 case CHARGER_ONLY_MODE:
112 default:
113 break;
114 }
115
116 return ret;
117}