summaryrefslogtreecommitdiff
path: root/firmware/target/mips/ingenic_x1000/shanlingq1/power-shanlingq1.c
diff options
context:
space:
mode:
authorAidan MacDonald <amachronic@protonmail.com>2021-05-23 17:30:58 +0100
committerAidan MacDonald <amachronic@protonmail.com>2021-07-13 22:01:33 +0100
commit4c60bc9e681865fcfc149775a1ed7ccd2613d5bf (patch)
tree99f8d91af2c171cf3843f0c14d41a20d9dc29c4f /firmware/target/mips/ingenic_x1000/shanlingq1/power-shanlingq1.c
parent3abb7c5dd5be2ec6744bfc0a80967b20f1b59e30 (diff)
downloadrockbox-4c60bc9e681865fcfc149775a1ed7ccd2613d5bf.tar.gz
rockbox-4c60bc9e681865fcfc149775a1ed7ccd2613d5bf.zip
New port: Shanling Q1 native
- Audio playback works - Touchscreen and buttons work - Bootloader works and is capable of dual boot - Plugins are working - Cabbiev2 theme has been ported - Stable for general usage Thanks to Marc Aarts for porting Cabbiev2 and plugin bitmaps. There's a few minor known issues: - Bootloader must be installed manually using 'usbboot' as there is no support in jztool yet. - Keymaps may be lacking, need further testing and feedback. - Some plugins may not be fully adapted to the screen size and could benefit from further tweaking. - LCD shows abnormal effects under some circumstances: for example, after viewing a mostly black screen an afterimage appears briefly when going back to a brightly-lit screen. Sudden power-off without proper shutdown of the backlight causes a "dissolving" effect. - CW2015 battery reporting driver is buggy, and disabled for now. Battery reporting is currently voltage-based using the AXP192. Change-Id: I635e83f02a880192c5a82cb0861ad3a61c137c3a
Diffstat (limited to 'firmware/target/mips/ingenic_x1000/shanlingq1/power-shanlingq1.c')
-rw-r--r--firmware/target/mips/ingenic_x1000/shanlingq1/power-shanlingq1.c140
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
50const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] =
51{
52 3470
53};
54
55/* the OF shuts down at this voltage */
56const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] =
57{
58 3400
59};
60
61/* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */
62const 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 */
68const unsigned short percent_to_volt_charge[11] =
69{
70 3485, 3780, 3836, 3857, 3890, 3930, 3986, 4062, 4158, 4185, 4196
71};
72
73void 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
100void usb_charging_maxcurrent_change(int maxcurrent)
101{
102 axp_set_charge_current(maxcurrent);
103}
104#endif
105
106void power_off(void)
107{
108 axp_power_off();
109 while(1);
110}
111
112bool charging_state(void)
113{
114 return axp_battery_status() == AXP_BATT_CHARGING;
115}
116
117int _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
125int _battery_level(void)
126{
127 return cw2015_get_soc();
128}
129#endif
130
131#if defined(HAVE_CW2015) && (CONFIG_BATTERY_MEASURE & TIME_MEASURE) != 0
132int _battery_time(void)
133{
134 return cw2015_get_rrt();
135}
136#endif
137
138void adc_init(void)
139{
140}