diff options
Diffstat (limited to 'firmware/target/mips/ingenic_x1000/shanlingq1/power-shanlingq1.c')
-rw-r--r-- | firmware/target/mips/ingenic_x1000/shanlingq1/power-shanlingq1.c | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/firmware/target/mips/ingenic_x1000/shanlingq1/power-shanlingq1.c b/firmware/target/mips/ingenic_x1000/shanlingq1/power-shanlingq1.c new file mode 100644 index 0000000000..17fbe1cede --- /dev/null +++ b/firmware/target/mips/ingenic_x1000/shanlingq1/power-shanlingq1.c | |||
@@ -0,0 +1,140 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2021 Aidan MacDonald | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | #include "power.h" | ||
23 | #include "adc.h" | ||
24 | #include "system.h" | ||
25 | #include "axp-pmu.h" | ||
26 | #ifdef HAVE_CW2015 | ||
27 | # include "cw2015.h" | ||
28 | #endif | ||
29 | #ifdef HAVE_USB_CHARGING_ENABLE | ||
30 | # include "usb_core.h" | ||
31 | #endif | ||
32 | |||
33 | #include "i2c-x1000.h" | ||
34 | |||
35 | /* TODO: Better(?) battery reporting for Q1 using CW2015 driver | ||
36 | * | ||
37 | * The CW2015 has its own quirks so the driver has to be more complicated | ||
38 | * than "read stuff from I2C," unfortunately. Without fixing the quirks it | ||
39 | * is probably worse than the simple voltage-based method. | ||
40 | * | ||
41 | * A bigger problem is that it shares an I2C bus with the AXP192, but when | ||
42 | * we attempt to communicate with both chips, they start returning bogus | ||
43 | * data intermittently. Ususally, reads will return 0 but sometimes they | ||
44 | * can return other nonzero bogus data. It could be that one or the other is | ||
45 | * pulling the bus line down inappropriately, or maybe the hardware does not | ||
46 | * respect the bus free time between start/stop conditions and one of the | ||
47 | * devices is getting confused. | ||
48 | */ | ||
49 | |||
50 | const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] = | ||
51 | { | ||
52 | 3470 | ||
53 | }; | ||
54 | |||
55 | /* the OF shuts down at this voltage */ | ||
56 | const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] = | ||
57 | { | ||
58 | 3400 | ||
59 | }; | ||
60 | |||
61 | /* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */ | ||
62 | const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] = | ||
63 | { | ||
64 | { 3400, 3639, 3697, 3723, 3757, 3786, 3836, 3906, 3980, 4050, 4159 } | ||
65 | }; | ||
66 | |||
67 | /* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */ | ||
68 | const unsigned short percent_to_volt_charge[11] = | ||
69 | { | ||
70 | 3485, 3780, 3836, 3857, 3890, 3930, 3986, 4062, 4158, 4185, 4196 | ||
71 | }; | ||
72 | |||
73 | void power_init(void) | ||
74 | { | ||
75 | i2c_x1000_set_freq(AXP_PMU_BUS, I2C_FREQ_400K); | ||
76 | axp_init(); | ||
77 | #ifdef HAVE_CW2015 | ||
78 | cw2015_init(); | ||
79 | #endif | ||
80 | |||
81 | /* Change supply voltage from the default of 1250 mV to 1200 mV, | ||
82 | * this matches the original firmware's settings. Didn't observe | ||
83 | * any obviously bad behavior at 1250 mV, but better to be safe. */ | ||
84 | axp_supply_set_voltage(AXP_SUPPLY_DCDC2, 1200); | ||
85 | |||
86 | /* For now, just turn everything on... definitely the touchscreen | ||
87 | * is powered by one of the outputs */ | ||
88 | i2c_reg_modify1(AXP_PMU_BUS, AXP_PMU_ADDR, | ||
89 | AXP_REG_PWROUTPUTCTRL1, 0, 0x05, NULL); | ||
90 | i2c_reg_modify1(AXP_PMU_BUS, AXP_PMU_ADDR, | ||
91 | AXP_REG_PWROUTPUTCTRL2, 0, 0x0f, NULL); | ||
92 | i2c_reg_modify1(AXP_PMU_BUS, AXP_PMU_ADDR, | ||
93 | AXP_REG_DCDCWORKINGMODE, 0, 0xc0, NULL); | ||
94 | |||
95 | /* Delay to give power output time to stabilize */ | ||
96 | mdelay(20); | ||
97 | } | ||
98 | |||
99 | #ifdef HAVE_USB_CHARGING_ENABLE | ||
100 | void usb_charging_maxcurrent_change(int maxcurrent) | ||
101 | { | ||
102 | axp_set_charge_current(maxcurrent); | ||
103 | } | ||
104 | #endif | ||
105 | |||
106 | void power_off(void) | ||
107 | { | ||
108 | axp_power_off(); | ||
109 | while(1); | ||
110 | } | ||
111 | |||
112 | bool charging_state(void) | ||
113 | { | ||
114 | return axp_battery_status() == AXP_BATT_CHARGING; | ||
115 | } | ||
116 | |||
117 | int _battery_voltage(void) | ||
118 | { | ||
119 | /* CW2015 can also read battery voltage, but the AXP consistently | ||
120 | * reads ~20-30 mV higher so I suspect it's the "real" voltage. */ | ||
121 | return axp_adc_read(ADC_BATTERY_VOLTAGE); | ||
122 | } | ||
123 | |||
124 | #if defined(HAVE_CW2015) && (CONFIG_BATTERY_MEASURE & PERCENTAGE_MEASURE) != 0 | ||
125 | int _battery_level(void) | ||
126 | { | ||
127 | return cw2015_get_soc(); | ||
128 | } | ||
129 | #endif | ||
130 | |||
131 | #if defined(HAVE_CW2015) && (CONFIG_BATTERY_MEASURE & TIME_MEASURE) != 0 | ||
132 | int _battery_time(void) | ||
133 | { | ||
134 | return cw2015_get_rrt(); | ||
135 | } | ||
136 | #endif | ||
137 | |||
138 | void adc_init(void) | ||
139 | { | ||
140 | } | ||