Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
CTCaer
GitHub Repository: CTCaer/hekate
Path: blob/master/bdk/power/bq24193.c
1476 views
1
/*
2
* Battery charger driver for Nintendo Switch's TI BQ24193
3
*
4
* Copyright (c) 2018 CTCaer
5
*
6
* This program is free software; you can redistribute it and/or modify it
7
* under the terms and conditions of the GNU General Public License,
8
* version 2, as published by the Free Software Foundation.
9
*
10
* This program is distributed in the hope it will be useful, but WITHOUT
11
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13
* more details.
14
*
15
* You should have received a copy of the GNU General Public License
16
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17
*/
18
19
#include "bq24193.h"
20
#include <soc/i2c.h>
21
#include <utils/util.h>
22
23
static u8 bq24193_get_reg(u8 reg)
24
{
25
return i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, reg);
26
}
27
28
int bq24193_get_property(enum BQ24193_reg_prop prop, int *value)
29
{
30
u8 data;
31
32
switch (prop)
33
{
34
case BQ24193_InputVoltageLimit: // Input voltage limit (mV).
35
data = bq24193_get_reg(BQ24193_InputSource);
36
data = (data & BQ24193_INCONFIG_VINDPM_MASK) >> 3;
37
*value = 0;
38
*value += ((data >> 0) & 1) ? 80 : 0;
39
*value += ((data >> 1) & 1) ? 160 : 0;
40
*value += ((data >> 2) & 1) ? 320 : 0;
41
*value += ((data >> 3) & 1) ? 640 : 0;
42
*value += 3880;
43
break;
44
case BQ24193_InputCurrentLimit: // Input current limit (mA).
45
data = bq24193_get_reg(BQ24193_InputSource);
46
data &= BQ24193_INCONFIG_INLIMIT_MASK;
47
switch (data)
48
{
49
case 0:
50
*value = 100;
51
break;
52
case 1:
53
*value = 150;
54
break;
55
case 2:
56
*value = 500;
57
break;
58
case 3:
59
*value = 900;
60
break;
61
case 4:
62
*value = 1200;
63
break;
64
case 5:
65
*value = 1500;
66
break;
67
case 6:
68
*value = 2000;
69
break;
70
case 7:
71
*value = 3000;
72
break;
73
}
74
break;
75
case BQ24193_SystemMinimumVoltage: // Minimum system voltage limit (mV).
76
data = bq24193_get_reg(BQ24193_PORConfig);
77
*value = (data & BQ24193_PORCONFIG_SYSMIN_MASK) >> 1;
78
*value *= 100;
79
*value += 3000;
80
break;
81
case BQ24193_FastChargeCurrentLimit: // Fast charge current limit (mA).
82
data = bq24193_get_reg(BQ24193_ChrgCurr);
83
data = (data & BQ24193_CHRGCURR_ICHG_MASK) >> 2;
84
*value = 0;
85
*value += ((data >> 0) & 1) ? 64 : 0;
86
*value += ((data >> 1) & 1) ? 128 : 0;
87
*value += ((data >> 2) & 1) ? 256 : 0;
88
*value += ((data >> 3) & 1) ? 512 : 0;
89
*value += ((data >> 4) & 1) ? 1024 : 0;
90
*value += ((data >> 5) & 1) ? 2048 : 0;
91
*value += 512;
92
data = bq24193_get_reg(BQ24193_ChrgCurr);
93
data &= BQ24193_CHRGCURR_20PCT_MASK;
94
if (data)
95
*value = *value * 20 / 100; // Fast charge current limit is 20%.
96
break;
97
case BQ24193_ChargeVoltageLimit: // Charge voltage limit (mV).
98
data = bq24193_get_reg(BQ24193_ChrgVolt);
99
data = (data & BQ24193_CHRGVOLT_VREG) >> 2;
100
*value = 0;
101
*value += ((data >> 0) & 1) ? 16 : 0;
102
*value += ((data >> 1) & 1) ? 32 : 0;
103
*value += ((data >> 2) & 1) ? 64 : 0;
104
*value += ((data >> 3) & 1) ? 128 : 0;
105
*value += ((data >> 4) & 1) ? 256 : 0;
106
*value += ((data >> 5) & 1) ? 512 : 0;
107
*value += 3504;
108
break;
109
case BQ24193_RechargeThreshold: // Recharge voltage threshold less than voltage limit (mV).
110
data = bq24193_get_reg(BQ24193_ChrgVolt);
111
data &= BQ24193_IRTHERMAL_THERM_MASK;
112
if (data)
113
*value = 300;
114
else
115
*value = 100;
116
break;
117
case BQ24193_ThermalRegulation: // Thermal regulation threshold (oC).
118
data = bq24193_get_reg(BQ24193_IRCompThermal);
119
data &= BQ24193_IRTHERMAL_THERM_MASK;
120
switch (data)
121
{
122
case 0:
123
*value = 60;
124
break;
125
case 1:
126
*value = 80;
127
break;
128
case 2:
129
*value = 100;
130
break;
131
case 3:
132
*value = 120;
133
break;
134
}
135
break;
136
case BQ24193_ChargeStatus: // 0: Not charging, 1: Pre-charge, 2: Fast charging, 3: Charge termination done
137
data = bq24193_get_reg(BQ24193_Status);
138
*value = (data & BQ24193_STATUS_CHRG_MASK) >> 4;
139
break;
140
case BQ24193_TempStatus: // 0: Normal, 2: Warm, 3: Cool, 5: Cold, 6: Hot.
141
data = bq24193_get_reg(BQ24193_FaultReg);
142
*value = data & BQ24193_FAULT_THERM_MASK;
143
break;
144
case BQ24193_DevID: // Dev ID.
145
data = bq24193_get_reg(BQ24193_VendorPart);
146
*value = data & BQ24193_VENDORPART_DEV_MASK;
147
break;
148
case BQ24193_ProductNumber: // Product number.
149
data = bq24193_get_reg(BQ24193_VendorPart);
150
*value = (data & BQ24193_VENDORPART_PN_MASK) >> 3;
151
break;
152
default:
153
return -1;
154
}
155
return 0;
156
}
157
158
void bq24193_enable_charger()
159
{
160
u8 reg = bq24193_get_reg(BQ24193_PORConfig);
161
162
reg &= ~BQ24193_PORCONFIG_CHGCONFIG_MASK;
163
reg |= BQ24193_PORCONFIG_CHGCONFIG_CHARGER_EN;
164
165
i2c_send_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_PORConfig, reg);
166
}
167
168
void bq24193_fake_battery_removal()
169
{
170
// Disable watchdog to keep BATFET disabled.
171
u8 value = bq24193_get_reg(BQ24193_ChrgTermTimer);
172
value &= ~BQ24193_CHRGTERM_WATCHDOG_MASK;
173
i2c_send_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_ChrgTermTimer, value);
174
175
// Force BATFET to disabled state. This disconnects the battery from the system.
176
value = bq24193_get_reg(BQ24193_Misc);
177
value |= BQ24193_MISC_BATFET_DI_MASK;
178
i2c_send_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_Misc, value);
179
}
180
181