mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-11 23:24:22 -04:00
dlkm: charger driver for Moto common features
As a common charger driver mmi_charger inherits Motorola legacy battery
charging features, including Demo charging, Step charging, Flash Fast
charging, and common features for factory test support.
More importantly, it provides a cross-platform solution to support
various battery charging design, not only Qualcomm SoC but also Samsung,
MTK, even remote system over network, and especially suite multiple
battery packs and multiple charger ICs in one system.
To achieve this goal, besides mmi_charger driver, there need a low level
charger driver for each battery charging solution(a couple of charger IC
& battery pack) to register to mmi_charger driver with implementation of
required interfaces depending on their own HW design.
With mmi_charger driver, Motorola common features have been stripped
from the HW dependent charger drivers(older Motorola charger drivers),
in which all the common features have to be implemented by each driver
of its own. So a low level charger driver can focus on HW specific
features and function development.
Motorola charger driver architecture:
----------------------------------------------------------------------
Userspace Common Interfaces for Charging Features and Factory Test
----------------------------------------------------------------------
Kernel mmi_charger (Motorola demo, step, flash-fast charging,
/ | \ factory and debugging interfaces)
/ | \
qti_glink_charger x_charger N_charger (basic charging functions HW
| | | specific factory debugging interfaces)
| | |
------------glink----i2c------spmi------------------------------------
| | |
| | |
ADSP i2c chip PMIC
Benefit from this new Motorola charger driver design:
1. Easy upgrade, migration, and maintenance, as common driver is
cross-platform and HW independent.
2. Reduce develop workload, as developers can pay more energy and
efforts on HW or platform specific business logic.
3. Easy to support complex battery charging solution, as it can support
N couples of charger IC & battery pack in one system at the same time
theoretically.
Change-Id: Ie44a22a2c65ea01fd3930879aeb9aae1c44341e0
Signed-off-by: yanyh2 <yanyh2@motorola.com>
Reviewed-on: https://gerrit.mot.com/1502333
SME-Granted: SME Approvals Granted
SLTApproved: Slta Waiver
Tested-by: Jira Key
Reviewed-by: Wentao Xu <xuwt2@motorola.com>
Reviewed-by: Jianqi Yang <yangj@motorola.com>
Submit-Approved: Jira Key
This commit is contained in:
parent
03346de658
commit
6c2bbf2914
6 changed files with 2926 additions and 0 deletions
11
drivers/power/mmi_charger/Android.mk
Executable file
11
drivers/power/mmi_charger/Android.mk
Executable file
|
|
@ -0,0 +1,11 @@
|
|||
DLKM_DIR := motorola/kernel/modules
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := mmi_charger.ko
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT)
|
||||
KBUILD_OPTIONS_GKI += GKI_OBJ_MODULE_DIR=gki
|
||||
include $(DLKM_DIR)/AndroidKernelModule.mk
|
||||
|
||||
include $(call first-makefiles-under,$(LOCAL_PATH))
|
||||
5
drivers/power/mmi_charger/Kbuild
Executable file
5
drivers/power/mmi_charger/Kbuild
Executable file
|
|
@ -0,0 +1,5 @@
|
|||
# add -Wall to try to catch everything we can.
|
||||
EXTRA_CFLAGS += -Wall
|
||||
EXTRA_CFLAGS += -I$(ANDROID_BUILD_TOP)/motorola/kernel/modules/drivers/power/mmi_charger
|
||||
|
||||
obj-m += mmi_charger.o
|
||||
10
drivers/power/mmi_charger/Makefile
Executable file
10
drivers/power/mmi_charger/Makefile
Executable file
|
|
@ -0,0 +1,10 @@
|
|||
KERNEL_SRC ?= /lib/modules/$(shell uname -r)/build
|
||||
|
||||
all:
|
||||
$(MAKE) -C $(KERNEL_SRC) M=$(shell pwd) modules $(KBUILD_OPTIONS)
|
||||
|
||||
modules_install:
|
||||
$(MAKE) INSTALL_MOD_STRIP=1 -C $(KERNEL_SRC) M=$(shell pwd) modules_install
|
||||
|
||||
clean:
|
||||
$(MAKE) -C $(KERNEL_SRC) M=$(PWD) clean
|
||||
544
drivers/power/mmi_charger/README
Normal file
544
drivers/power/mmi_charger/README
Normal file
|
|
@ -0,0 +1,544 @@
|
|||
Motorola Mobility. MMI Charger Specific Bindings
|
||||
|
||||
As a common charger driver mmi_charger inherits Motorola legacy battery
|
||||
charging features, including Demo charging, Step charging, Flash Fast
|
||||
charging, and common features for factory test support.
|
||||
|
||||
More importantly, it provides a cross-platform solution to support
|
||||
various battery charging design, not only Qualcomm SoC but also Samsung,
|
||||
MTK, even remote system over network, and especially suite multiple
|
||||
battery packs and multiple charger ICs in one system.
|
||||
|
||||
To achieve this goal, besides mmi_charger driver, there need a low level
|
||||
charger driver for each battery charging solution(a couple of charger IC
|
||||
& battery pack) to register to mmi_charger driver with implementation of
|
||||
required interfaces depending on their own HW design.
|
||||
|
||||
With mmi_charger driver, Motorola common features have been stripped
|
||||
from the HW dependent charger drivers(older Motorola charger drivers),
|
||||
in which all the common features have to be implemented by each driver
|
||||
of its own. So a low level charger driver can focus on HW specific
|
||||
features and function development.
|
||||
|
||||
Motorola charger driver architecture:
|
||||
-----------------------------------------------------------------------------------------------------------
|
||||
Userspace Common Interfaces for Charging Features and Factory Test
|
||||
-----------------------------------------------------------------------------------------------------------
|
||||
Kernel mmi_charger (Motorola demo, step, flash-fast charging,
|
||||
/ | \ factory and debugging interfaces)
|
||||
/ | \
|
||||
qti_glink_charger x_charger N_charger (basic charging functions HW
|
||||
| | | specific factory debugging interfaces)
|
||||
| | |
|
||||
------------glink----i2c------spmi--------------------------------------------------------------------------
|
||||
| | |
|
||||
| | |
|
||||
ADSP i2c chip PMIC
|
||||
|
||||
Benefit from this new Motorola charger driver design:
|
||||
1. Easy upgrade, migration, and maintenance, as common driver is
|
||||
cross-platform and HW independent.
|
||||
2. Reduce develop workload, as developers can pay more energy and
|
||||
efforts on HW or platform specific business logic.
|
||||
3. Easy to support complex battery charging solution, as it can support
|
||||
N couples of charger IC & battery pack in one system at the same time
|
||||
theoretically.
|
||||
|
||||
Motorola common charger driver is built as DLKM:
|
||||
Module Name: mmi_charger.ko
|
||||
Log Tag: mmi_charger
|
||||
IPC Log: /d/ipc_logging/charger/log
|
||||
Support Platform: platform independent
|
||||
|
||||
Motorola low level charger driver is built as DLKM:
|
||||
Module Name: qti_glink_charger.ko
|
||||
Log Tag: qti_glink_charger
|
||||
IPC Log: /d/ipc_logging/charger/log
|
||||
Support Platform: SM8350 or similar architecture(adsp and HLOS connection over glink)
|
||||
|
||||
devicetree properties description:
|
||||
mmi_charger:
|
||||
- mmi,enable-charging-limit
|
||||
Usage: optional
|
||||
Value Type: <empty>
|
||||
Definition: Boolean flag to set capacity limits to battery when plugged on
|
||||
a charger and is executing a Factory Image. It will use upper and lower
|
||||
capacities defined by the Device Tree.
|
||||
|
||||
- mmi,enable-factory-poweroff
|
||||
Usage: optional
|
||||
Value Type: <empty>
|
||||
Definition: Boolean flag which enables Factory Kill when executing under a
|
||||
Factory Image. By default, Factory Kill is a feature only in Factory Mode,
|
||||
which turns the device off when charger is removed.
|
||||
|
||||
- mmi,upper-limit-capacity
|
||||
Usage: optional
|
||||
Value Type: <u32>
|
||||
Definition: Limits minimum battery SoC (in percentage). In other words, starts
|
||||
charging when it reaches this value. Especially useful for factory procedures,
|
||||
which needs to limit SoC. Requires qcom,enable-charging-limit. If not defined,
|
||||
defaults to 100.
|
||||
|
||||
- mmi,lower-limit-capacity
|
||||
Usage: optional
|
||||
Value Type: <u32>
|
||||
Definition: Limits maximum battery SoC (in percentage). In other words, stop
|
||||
charging when it reaches this value. Especially useful for factory procedures,
|
||||
which needs to limit SoC. Requires qcom,enable-charging-limit. If not defined,
|
||||
defaults to 0.
|
||||
|
||||
- mmi,dcp-power-max
|
||||
Usage: optional
|
||||
Value Type: <u32>
|
||||
Definition: Set this value to allow power in mW draw from DC charger, used
|
||||
when a normal DCP charger is detected. If not set, 7.5W power is allowed.
|
||||
|
||||
- mmi,hvdcp-power-max
|
||||
Usage: optional
|
||||
Value Type: <u32>
|
||||
Definition: Set this value to allow power in mW draw from QC3.0 charger, used
|
||||
when a QC3.0 charger is detected. If not set, 15W power is allowed.
|
||||
|
||||
- mmi,heartbeat-interval
|
||||
Usage: optional
|
||||
Value Type: <u32>
|
||||
Definition: Set the heartbeat interval of in ms, 60s by default if not set.
|
||||
|
||||
Example:
|
||||
mmi_charger: mmi,charger {
|
||||
compatible = "mmi,mmi-charger";
|
||||
mmi,enable-charging-limit;
|
||||
mmi,enable-factory-poweroff;
|
||||
mmi,upper-limit-capacity = <75>;
|
||||
mmi,lower-limit-capacity = <60>;
|
||||
mmi,heartbeat-interval = <60000>;
|
||||
mmi,dcp-power-max = <10000>;
|
||||
mmi,hvdcp-power-max = <200000>;
|
||||
};
|
||||
|
||||
qti_glink_charger:
|
||||
- mmi,mmi-temp-zones
|
||||
Usage: optional
|
||||
Value Type: Array of tuples of <u32>
|
||||
Definition: Unlimited array of arrays. Each internal array needs to have a set
|
||||
of 4 bytes, each one representing this sequence: Temperature (in degC), Step
|
||||
"Normalized" Voltage (in millivolts), Full Rate "FCC" Current (in milliamps),
|
||||
and Taper Rate "FCC Normalized" Current (in milliamps). These values are
|
||||
related to charging limitations based on temperature specifications. Note that
|
||||
setting a voltage to '0' means that it doesn't matter the battery voltage on
|
||||
that defined temperature range to perform necessary tapering. To understand how
|
||||
Those values are used, please check the "IEEE Charging Compliance" section below.
|
||||
In order to support charging current limit based on battery voltage in the same
|
||||
temperature zone, one zone allows to have multiple lines with ascending sequence
|
||||
by float voltage. First find the temperature zone, and then find the right one
|
||||
among the same zone according to current battery voltage.
|
||||
|
||||
- mmi,df-serialnum
|
||||
Usage: optional
|
||||
Value Type: <string>
|
||||
Definition: The default battery serial number for charging profile selection
|
||||
and battery identification.
|
||||
|
||||
- mmi,chrg-iterm-ma
|
||||
Usage: optional
|
||||
Value Type: <u32>
|
||||
Definition: It will define taper current on battery (in milliamps). If charging
|
||||
current becomes below this value, it indicates FULL charging. If not defined,
|
||||
defaults to 300.
|
||||
|
||||
- mmi,fg-iterm-ma
|
||||
Usage: optional
|
||||
Value Type: <u32>
|
||||
Definition: It will define charging current on battery (in milliamps) as the
|
||||
threshold for the fuel gauge to decide reporting FULL capacity. If not defined,
|
||||
defaults to 350.
|
||||
|
||||
- mmi,vfloat-comp-uv
|
||||
Usage: optional
|
||||
Value Type: <u32>
|
||||
Definition: This is a tolerance, in uV, for battery floating voltage when
|
||||
charging is being limited. Such situation can happen when either battery is
|
||||
close to full or when there's thermal mitigation on charging. If not set,
|
||||
defaults to 0.
|
||||
|
||||
- mmi,max-fv-mv
|
||||
Usage: optional
|
||||
Value Type: <u32>
|
||||
Definition: It will define the maximum battery charging voltage (in milliamps).
|
||||
This value is used as the max float voltage for battery charging. If not
|
||||
defined, defaults to 4400.
|
||||
|
||||
- mmi,max-fcc-ma
|
||||
Usage: optional
|
||||
Value Type: <u32>
|
||||
Definition: It will define maximum charging current on battery (in milliamps)
|
||||
If not defined, defaults to 4000.
|
||||
|
||||
- mmi,demo-fv-mv
|
||||
Usage: optional
|
||||
Value Type: <u32>
|
||||
Definition: It will define the maximum battery charging voltage (in milliamps)
|
||||
in demo mode. This value is used as the max float voltage for battery charging in
|
||||
demo mode. If not defined, defaults to 4000.
|
||||
|
||||
- mmi,mmi-ffc-zones
|
||||
Usage: optional
|
||||
Value Type: Array of tuples of <u32>
|
||||
Definition: Unlimited array of arrays. Each internal array needs to have a set
|
||||
of 4 data members, each one representing this sequence: Temperature (in degC),
|
||||
maximum Float Voltage (in millivolts), charging terminated current(in milliamps),
|
||||
and Fuel Gauge FULL terminated current (in milliamps). These values are
|
||||
related to charging limitations based on temperature specifications when the
|
||||
battery supports Flash Fast Charging.
|
||||
|
||||
- mmi,profile-data-block-size
|
||||
Usage: optional
|
||||
Value Type: <u32>
|
||||
Definition: It will define the profile data member count each block line
|
||||
in the profile data array. If not defined, defaults to 4.
|
||||
|
||||
- mmi,profile-data
|
||||
Usage: optional
|
||||
Value Type: Array of tuples of <u32>
|
||||
Definition: Unlimited array of arrays. Each internal array needs to have a set
|
||||
with member count specified by property "mmi,profile-data-block-size". The content
|
||||
for each line is defined by the target user of the profile data.
|
||||
|
||||
Example:
|
||||
qti_glink_charger: mmi,qti-glink-charger {
|
||||
compatible = "mmi,qti-glink-charger";
|
||||
mmi,df-serialnum = "unknown-sn";
|
||||
mmi,chrg-iterm-ma = <300>;
|
||||
mmi,fg-iterm-ma = <350>;
|
||||
mmi,max-fv-mv = <4400>;
|
||||
mmi,max-fcc-ma = <4000>;
|
||||
mmi,demo-fv-mv = <4000>;
|
||||
mmi,vfloat-comp-uv = <20000>;
|
||||
mmi,mmi-temp-zones =
|
||||
<0 4200 880 0>,
|
||||
<10 4200 2185 880>,
|
||||
<15 0 2185 2185>,
|
||||
<45 4000 3600 3600>,
|
||||
<45 4250 3600 3000>,
|
||||
<45 4350 3000 2000>,
|
||||
<60 4200 2185 0>;
|
||||
mmi,mmi-ffc-zones =
|
||||
<0 4450 243 500>,
|
||||
<23 4480 670 980>,
|
||||
<35 4480 770 1045>,
|
||||
<45 4480 840 1120>,
|
||||
<60 4450 243 500>;
|
||||
|
||||
mmi,profile-data-block-size = <4>;
|
||||
mmi,profile-data =
|
||||
<0 4200 880 0>,
|
||||
<10 4200 2185 880>,
|
||||
<15 0 2185 2185>,
|
||||
<45 4000 3600 3600>,
|
||||
<45 4250 3600 3000>,
|
||||
<45 4350 3000 2000>,
|
||||
<60 4200 2185 0>;
|
||||
};
|
||||
|
||||
==========================
|
||||
IEEE Charging Compliance
|
||||
==========================
|
||||
|
||||
In order to be compliant to IEEE rules, there are a series of limitations on
|
||||
how much a battery can be charged, based on temperature. That will limit how
|
||||
much current can be drawn, or maximum battery voltage to be achieved during
|
||||
charging.
|
||||
|
||||
Current is always tapered when voltage achieves maximum voltage specification
|
||||
(which is generally 4.4V, but may have a different value, depending a product
|
||||
battery specs). It is tapered to some small value, possibly around 100mA,
|
||||
which is based on product specifications and capacity testing, defined by
|
||||
EE (Electrical Engineering) Team/Hardware.
|
||||
|
||||
If temperature is below -20 degC or above 60 degC, it should automatically
|
||||
stop charging the device.
|
||||
|
||||
If temperature is in between 15 and 45 deg C, it can achieve maximum charging
|
||||
current, and such value varies across products. Generally, if it supports PD,
|
||||
this will be a much higher current than non-PD products, which will also have
|
||||
a much higher current than dual-battery products. Important to note that this
|
||||
is a rule-of-thumb, so always check product specifications.
|
||||
|
||||
If temperature is between 0 and 10 deg C, but battery voltage is above 4.20V,
|
||||
current should be tapered to 1000mA.
|
||||
|
||||
Finally, if temperature is in between -20 and 0 deg C, current should be
|
||||
tapered to 1000mA.
|
||||
|
||||
NOTE1: whenever dealing with IEEE certification, most documentation and
|
||||
variable notation across the bootloader and kernel may refer to JEITA. This is a
|
||||
convention on such standards and values to which temperature, voltage and
|
||||
current levels are accepted in different scenarios for Li-ion batteries. So
|
||||
JEITA can be seen as a general standard, but IEEE enforces it as well as
|
||||
provide ways to certify a product according to it (is mandatory to certify
|
||||
any commercial product that has a lithium-ion battery embedded or plugged to
|
||||
it).
|
||||
|
||||
NOTE2: taper current mostly refers to when battery is above maximum allowed
|
||||
voltage on a specific temperature region, based on rules above. So be aware
|
||||
that the rest of this document may refer as "taper" to a current that is
|
||||
limiting the maximum value, but before achieving a stage in which current
|
||||
is limited to something around 100mA (so an intermediate stage). Also
|
||||
"taper voltage" will refer to a voltage level in which this mentioned
|
||||
"taper" current (intermediate current level) is triggered.
|
||||
|
||||
|
||||
=========================================
|
||||
How to define mmi,mmi-temp-zones array
|
||||
=========================================
|
||||
|
||||
When defining qcom,mmi-temp-zones array, it is important to always have in
|
||||
mind the IEEE rules described above, as well the battery specifications.
|
||||
|
||||
Each tuple in that array represents a different value, as shown here:
|
||||
<temperature taper_volt max_cur_below_taper_volt max_cur_above_taper_volt>
|
||||
|
||||
"temperature" defines maximum temperature value. So setting "35" means a
|
||||
definition to anything below 35 degC.
|
||||
|
||||
"taper_volt" means maximum allowed battery voltage in that temperature
|
||||
range. So setting "4200" means that tapering will happen once battery
|
||||
is above 4.2V and is still charging.
|
||||
|
||||
"max_cur_below_taper_volt" defines maximum allowed current value in case
|
||||
the battery is below "taper_volt" value. So setting it to "700" means that
|
||||
current won't go above 700mA, as long as battery is below "taper_volt"
|
||||
voltage.
|
||||
|
||||
"max_cur_above_taper_volt" defines maximum allowed current value in case
|
||||
battery is above "taper_volt" value. So setting it to "0" means that it
|
||||
won't charge in case the battery is above "taper_volt" voltage.
|
||||
|
||||
Here's an example from Dubai:
|
||||
mmi,mmi-temp-zones =
|
||||
<0 4200 880 0>,
|
||||
<10 4200 2185 880>,
|
||||
<15 0 2185 2185>,
|
||||
<45 4000 3600 3600>,
|
||||
<45 4250 3600 3000>,
|
||||
<45 4350 3000 2000>,
|
||||
<60 4200 2185 0>;
|
||||
The first line states "If temperature is below 0 degC, and the battery voltage
|
||||
is below 4.2V, device can be charged up to 880mA. But if the battery voltage
|
||||
is above 4.2V, device cannot be charged".
|
||||
|
||||
The third line states "If temperature is below 15 degC, the battery can be charged
|
||||
up to 2185mA, no matter the battery voltage".
|
||||
|
||||
The fourth to sixth line states that there are three lines in the same zone with
|
||||
different taper_volt by ascending sequence, the charging current is limited by
|
||||
both temperature and battery voltage.
|
||||
|
||||
=================================================
|
||||
Understanding the IEEE algorithm implementation
|
||||
=================================================
|
||||
|
||||
Now that IEEE rules were understood, as well as how qcom,mmi-temp-zones is set,
|
||||
just to stress out this driver implementation, the thermal charging limitation
|
||||
implementation will be described.
|
||||
|
||||
mmi_basic_charge_sm() or mmi_dual_charge_sm() are the functions responsible
|
||||
to enforce such rules. In that way, before we check the implementation, here
|
||||
are some conventions:
|
||||
|
||||
STEP_NONE: no charger present
|
||||
STEP_STOP: in zone hot or zone cold, which limits charging considerably
|
||||
STEP_NORM: limits current to some value
|
||||
STEP_MAX: allows maximum current value, when in between 0 and 45 degC
|
||||
STEP_FULL: battery is almost or completely full, tapering to a small current
|
||||
STEP_FLOAT: TODO
|
||||
|
||||
Important to note that even when moving from one state to another, temperature
|
||||
may change. Hence, taper current and voltage will no longer correspond to such
|
||||
state, and so is always necessary to check on every state in which temperature
|
||||
range device is.
|
||||
|
||||
"batt_ma" refers to battery current (equivalent to current_now on battery
|
||||
sysfs).
|
||||
"taper_ma" is "fcc_norm_ma" in case is in STATE_MAX, which means battery is
|
||||
above taper voltage. If in any other state, it will refer to "chrg_iterm",
|
||||
which will depend on device specifications (4.4V batteries have 97mA as
|
||||
current standards, and 4.45V batteries have 121mA as taper current).
|
||||
|
||||
Now, let's check the algorithms for a bit:
|
||||
|
||||
-----------------------------------------------------
|
||||
current-step: STEP_NONE | STEP_STOP
|
||||
if norm_mv AND (batt_mv + 50 >= norm_mv) // (1)
|
||||
if fcc_norm_ma // (2)
|
||||
-goto STEP_NORM // (2)
|
||||
else
|
||||
-goto STEP_STOP // (2)
|
||||
else
|
||||
-goto STEP_MAX // (1)
|
||||
|
||||
(1) are we in a range which has "norm_mv" defined, and battery is above this
|
||||
value?
|
||||
This corresponds to most temperature ranges, except in between 15 and 45 degC.
|
||||
If that's the case, allow charging up to maximum current defined in product
|
||||
spec.
|
||||
|
||||
(2) is "fcc_norm_ma" a value different from zero?
|
||||
This happens if temperature is in range between 0 and 45 degC. Due to previous
|
||||
consideration, it is only missing range 0 to 15 degC here. If that's the case,
|
||||
limit maximum current. Otherwise, battery is above "norm_mv" (which probably
|
||||
is defined as 4.2V), and at that voltage and temperature, limiting charging
|
||||
considerably.
|
||||
|
||||
-----------------------------------------------------
|
||||
current-step: STEP_MAX
|
||||
if !norm_mv // (1)
|
||||
taper_cnt = 0
|
||||
if (batt_mv + 50) > max_fv_mv // (2)
|
||||
-goto STEP_NORM
|
||||
else
|
||||
-goto STEP_MAX
|
||||
else if (batt_mv + 50) < norm_mv // (1)
|
||||
taper_cnt = 0
|
||||
-goto STEP_MAX
|
||||
else if !fcc_norm_ma // (3)
|
||||
-goto STEP_FLOAT
|
||||
else if current_has_tapered // (4)
|
||||
taper_cnt = 0
|
||||
if charge_halted
|
||||
vote chg_dis_votable
|
||||
-goto STEP_NORM
|
||||
|
||||
(1) are we in a range which has "norm_mv" NOT defined, or below taper voltage?
|
||||
This is only for the 15 to 45 degC region, which has no current tapering.
|
||||
|
||||
(2) are we above taper voltage?
|
||||
This checks whether taper voltage was achieved, making current to taper to
|
||||
defined values, depending on which temperature region battery is at this
|
||||
moment.
|
||||
|
||||
(3) at current temperature, is taper current defined?
|
||||
If there is a taper current value to current temperature region (which is
|
||||
usually in between 0 and 15 degC as defined in current implementation), allow
|
||||
TODO STEP_FLOAT
|
||||
|
||||
(4) has current been limited due to other thermal rules?
|
||||
Function mmi_has_current_tapered() requests to power supply votable module
|
||||
what is the allowed maximum current. Then such value will be compared to taper
|
||||
current value, and the minimum will be chosen. Additionally, it checks whether
|
||||
there's still a charger plugged to device or if charging is disabled, and if
|
||||
any, mark a flag on the system displaying no charging is going on. Finally, move
|
||||
to taper the current state (STEP_NORM).
|
||||
|
||||
-----------------------------------------------------
|
||||
current-step: STEP_NORM
|
||||
if !fcc_norm_ma // (1)
|
||||
-goto STEP_FLOAT
|
||||
else if batt_soc < 100 or (batt_mv + 50) < max_fv_mv // (2)
|
||||
taper_cnt = 0
|
||||
-goto STEP_NORM
|
||||
else if current_has_tapered // (2)
|
||||
-goto STEP_FULL
|
||||
|
||||
(1) although device is in STEP_NORM, is there a defined taper current for
|
||||
current temperature region device?
|
||||
It may happen that temperature has changed, and device no longer needs to
|
||||
be tapered. Hence, move to STEP_FLOAT.
|
||||
|
||||
(2) is the battery NOT full or below taper voltage?
|
||||
Stay in this state, because tapering is still happening. Otherwise, it may
|
||||
be the case that battery is above taper voltage, or device is already fully
|
||||
charged, forcing it to prepare to stop charging (STEP_FULL).
|
||||
|
||||
-----------------------------------------------------
|
||||
current-step: STEP_FULL
|
||||
if batt_soc < 99 // (1)
|
||||
taper_cnt = 0
|
||||
goto STEP_NORM
|
||||
|
||||
(1) Is the battery no longer full?
|
||||
It may happen that the battery device was previously full, but no longer is. So,
|
||||
first move to a limited current state for safety, and then in such state, it
|
||||
may happen that maximum current levels can be achieved.
|
||||
|
||||
-----------------------------------------------------
|
||||
current-step: STEP_FLOAT
|
||||
if fcc_norm_ma or (batt_mv + 50) < norm_mv // (1)
|
||||
goto STEP_MAX
|
||||
if current_has_tapered // (2)
|
||||
goto STEP_STOP
|
||||
|
||||
(1) does battery temperature allow current to be tapered to something above
|
||||
0mA, or battery is below taper voltage?
|
||||
This means that temperature is in between 0 and 15 degC. If so, try to achieve
|
||||
maximum current value (STEP_MAX).
|
||||
|
||||
(2) does current need to be tapered?
|
||||
In case mmi_has_current_tapered() needs to decrease current, it will request
|
||||
charger to stop charging.
|
||||
|
||||
-----------------------------------------------------
|
||||
Setting current values based on state machine:
|
||||
|
||||
STEP_FLOAT
|
||||
STEP_MAX
|
||||
target_fcc = fcc_max_ma
|
||||
target_fv:
|
||||
if !norm_mv
|
||||
target_fv = max_fv_mv + chip->vfloat_comp_mv
|
||||
else
|
||||
target_fv = norm_mv + chip->vfloat_comp_mv
|
||||
|
||||
STEP_FULL:
|
||||
target_fcc = -EINVAL
|
||||
target_fv = max_fv_mv
|
||||
|
||||
STEP_NORM:
|
||||
target_fcc = fcc_norm_ma
|
||||
target_fv = max_fv_mv + chip->vfloat_comp_mv
|
||||
|
||||
STEP_NONE:
|
||||
target_fv = max_fv_mv
|
||||
target_fcc = fcc_norm_ma
|
||||
|
||||
=========================================
|
||||
How to define mmi,mmi-ffc-zones array
|
||||
=========================================
|
||||
|
||||
When defining mmi,mmi-ffc-zones array, it is important to always have in
|
||||
mind the rules described in the battery specifications, only the battery
|
||||
support Flash Fast Charging can use it, otherwise battery damage or over
|
||||
voltage protection may happen.
|
||||
|
||||
Each tuple in that array represents a different value, as shown here:
|
||||
<temperature max_fv_volt charging_term_cur fg_term_cur>
|
||||
|
||||
"temperature" defines maximum temperature value. So setting "35" means a
|
||||
definition to anything below 35 degC.
|
||||
|
||||
"max_fv_volt" means maximum allowed battery voltage in that temperature
|
||||
range. So setting "4480" means that the maximum float voltage is limited
|
||||
to 4480.
|
||||
|
||||
"charging_term_cur" means charging terminated current threshold in that
|
||||
temperature range. Once the charging current becomes below the threshold,
|
||||
the charging will be terminated.
|
||||
|
||||
"fg_term_cur" means charging current threshold for FG to report full
|
||||
charged in that temperature range. Once the charging current becomes
|
||||
below the threshold, the FG will report FULL state of charge.
|
||||
|
||||
Here's an example from Dubai:
|
||||
mmi,mmi-ffc-zones =
|
||||
<0 4450 243 500>,
|
||||
<23 4480 670 980>,
|
||||
<35 4480 770 1045>,
|
||||
<45 4480 840 1120>,
|
||||
<60 4450 243 500>;
|
||||
|
||||
The third line states "If temperature is below 35 degC, and the maximum float voltage
|
||||
is 4.48V, charging terminated current sets to 770mA, Fuel Gauge terminated current
|
||||
sets to 1045mA.
|
||||
|
||||
|
||||
2239
drivers/power/mmi_charger/mmi_charger.c
Normal file
2239
drivers/power/mmi_charger/mmi_charger.c
Normal file
File diff suppressed because it is too large
Load diff
117
drivers/power/mmi_charger/mmi_charger.h
Normal file
117
drivers/power/mmi_charger/mmi_charger.h
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* Copyright (C) 2020 Motorola Mobility LLC
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef __MMI_CHARGER_H__
|
||||
#define __MMI_CHARGER_H__
|
||||
|
||||
#include <linux/ipc_logging.h>
|
||||
#include <linux/debugfs.h>
|
||||
|
||||
#define mmi_err(chg, fmt, ...) \
|
||||
do { \
|
||||
pr_err("%s: %s: " fmt, chg->name, \
|
||||
__func__, ##__VA_ARGS__); \
|
||||
ipc_log_string(chg->ipc_log, \
|
||||
"E %s: %s: " fmt, chg->name, __func__, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define mmi_warn(chg, fmt, ...) \
|
||||
do { \
|
||||
pr_warn("%s: %s: " fmt, chg->name, \
|
||||
__func__, ##__VA_ARGS__); \
|
||||
ipc_log_string(chg->ipc_log, \
|
||||
"W %s: %s: " fmt, chg->name, __func__, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define mmi_info(chg, fmt, ...) \
|
||||
do { \
|
||||
pr_info("%s: %s: " fmt, chg->name, \
|
||||
__func__, ##__VA_ARGS__); \
|
||||
ipc_log_string(chg->ipc_log, \
|
||||
"I %s: %s: " fmt, chg->name, __func__, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define mmi_dbg(chg, fmt, ...) \
|
||||
do { \
|
||||
if (*chg->debug_enabled) \
|
||||
pr_info("%s: %s: " fmt, chg->name, \
|
||||
__func__, ##__VA_ARGS__); \
|
||||
else \
|
||||
pr_debug("%s: %s: " fmt, chg->name, \
|
||||
__func__, ##__VA_ARGS__); \
|
||||
ipc_log_string(chg->ipc_log, \
|
||||
"D %s: %s: " fmt, chg->name, __func__, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define MMI_LOG_PAGES (50)
|
||||
#define MMI_LOG_DIR "mmi_charger"
|
||||
#define MMI_BATT_SN_LEN 16
|
||||
#define CHG_SHOW_MAX_SIZE 50
|
||||
|
||||
struct mmi_battery_info {
|
||||
int batt_mv;
|
||||
int batt_ma;
|
||||
int batt_soc;
|
||||
int batt_temp;
|
||||
int batt_status;
|
||||
int batt_full_uah;
|
||||
int batt_design_uah;
|
||||
char batt_sn[MMI_BATT_SN_LEN];
|
||||
};
|
||||
|
||||
struct mmi_charger_info {
|
||||
int chrg_mv;
|
||||
int chrg_ma;
|
||||
int chrg_type;
|
||||
int chrg_pmax_mw;
|
||||
int chrg_present;
|
||||
};
|
||||
|
||||
struct mmi_charger_cfg {
|
||||
int target_fcc;
|
||||
int target_fv;
|
||||
int fg_iterm;
|
||||
int chrg_iterm;
|
||||
bool full_charged;
|
||||
bool charging_reset;
|
||||
bool taper_kickoff;
|
||||
bool charging_disable;
|
||||
bool charger_suspend;
|
||||
|
||||
int demo_mode;
|
||||
bool factory_mode;
|
||||
bool factory_version;
|
||||
|
||||
int dcp_pmax;
|
||||
int hvdcp_pmax;
|
||||
};
|
||||
|
||||
struct mmi_charger_driver {
|
||||
char *name;
|
||||
struct device *dev;
|
||||
int (*get_batt_info)(void *data, struct mmi_battery_info *batt_info);
|
||||
int (*get_chg_info)(void *data, struct mmi_charger_info *chg_info);
|
||||
int (*config_charge)(void *data, struct mmi_charger_cfg *config);
|
||||
bool (*is_charge_tapered)(void *data, int tapered_ma);
|
||||
bool (*is_charge_halt)(void *data);
|
||||
void *data;
|
||||
};
|
||||
|
||||
bool mmi_is_factory_mode(void);
|
||||
bool mmi_is_factory_version(void);
|
||||
const char *mmi_get_battery_serialnumber(void);
|
||||
void mmi_get_charger_configure(struct mmi_charger_driver *driver);
|
||||
int mmi_register_charger_driver(struct mmi_charger_driver *driver);
|
||||
int mmi_unregister_charger_driver(struct mmi_charger_driver *driver);
|
||||
|
||||
#endif
|
||||
Loading…
Reference in a new issue