drivers/battery/wireless: add cps4038
This commit is contained in:
parent
f32a1238aa
commit
d14bfe8797
@ -8,6 +8,16 @@ config WIRELESS_CHARGING
|
||||
Wireless charging models should enable this charging option.
|
||||
it include various scenario for wireless charging models only.
|
||||
|
||||
config WIRELESS_CHARGER_CPS4038
|
||||
tristate "MFC IC CPS4038 charger support"
|
||||
select WIRELESS_CHARGING
|
||||
depends on BATTERY_SAMSUNG && I2C
|
||||
help
|
||||
Say Y here, to enable
|
||||
support for the CPS4038 MFC IC
|
||||
CPS4038 MFC include wireless charger driver.
|
||||
It is for CPS(Conveninet Power Systems).
|
||||
|
||||
config WIRELESS_CHARGER_NU1668
|
||||
tristate "MFC IC NU1668 charger support"
|
||||
select WIRELESS_CHARGING
|
||||
|
@ -1,5 +1,7 @@
|
||||
obj-$(CONFIG_WIRELESS_CHARGER_NU1668) += nu1668-charger.o
|
||||
obj-$(CONFIG_WIRELESS_CHARGER_CPS4038) += cps4038-charger.o
|
||||
cps4038-charger-$(CONFIG_WIRELESS_CHARGER_CPS4038) += cps4038_fod.o cps4038_cmfet.o cps4038_charger.o
|
||||
|
||||
obj-$(CONFIG_WIRELESS_CHARGER_NU1668) += nu1668-charger.o
|
||||
nu1668-charger-$(CONFIG_WIRELESS_CHARGER_NU1668) += nu1668_fod.o nu1668_cmfet.o nu1668_charger.o
|
||||
|
||||
ccflags-y := -Wformat
|
||||
ccflags-y := -Wformat
|
7
drivers/battery/wireless/cps4038_charger.bzl
Executable file
7
drivers/battery/wireless/cps4038_charger.bzl
Executable file
@ -0,0 +1,7 @@
|
||||
ko_list = [
|
||||
{
|
||||
"ko_names" : [
|
||||
"drivers/battery/wireless/cps4038-charger.ko"
|
||||
]
|
||||
}
|
||||
]
|
7547
drivers/battery/wireless/cps4038_charger.c
Executable file
7547
drivers/battery/wireless/cps4038_charger.c
Executable file
File diff suppressed because it is too large
Load Diff
235
drivers/battery/wireless/cps4038_charger.dtsi
Executable file
235
drivers/battery/wireless/cps4038_charger.dtsi
Executable file
@ -0,0 +1,235 @@
|
||||
#include <dt-bindings/battery/sec-battery.h>
|
||||
|
||||
&smd {
|
||||
sb_tx: sb-tx {
|
||||
aov {
|
||||
high_freq = <144>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&tlmm {
|
||||
cps_irq_default: cps_irq_default {
|
||||
GPIO_CONFIG_PUD_DRV(AP,tlmm,84, FUNC_INPUT_WAKEUP, PULL_NONE, DRV_LV1);
|
||||
};
|
||||
};
|
||||
|
||||
&pm8550_gpios {
|
||||
cps_det_default: cps_det_default {
|
||||
GPIO_CONFIG_PUD(PM,pm8550_gpios,9, FUNC_INPUT_WAKEUP, PULL_NONE);
|
||||
};
|
||||
};
|
||||
|
||||
&tlmm {
|
||||
cps_en_default: cps_en_default {
|
||||
GPIO_CONFIG_PUD(AP,tlmm,82, FUNC_OUTPUT_LOW, PULL_NONE);
|
||||
};
|
||||
};
|
||||
|
||||
#if 1
|
||||
&pm8550ve_gpios {
|
||||
cps_pdrc_default: cps_pdrc_default {
|
||||
GPIO_CONFIG_PUD(PM,pm8550ve_gpios,6, FUNC_INPUT_WAKEUP, PULL_NONE);
|
||||
};
|
||||
};
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
&tlmm {
|
||||
cps_ping_nen_default: cps_ping_nen_default {
|
||||
GPIO_CONFIG_PUD(AP,tlmm,180, FUNC_OUTPUT_HIGH, PULL_NONE);
|
||||
};
|
||||
};
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
&tlmm {
|
||||
cps_pdet_b_default: cps_pdet_b_default {
|
||||
GPIO_CONFIG_PUD(AP,tlmm,55, FUNC_INPUT_WAKEUP, PULL_NONE);
|
||||
};
|
||||
};
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
&pm8550vs_g_gpios {
|
||||
cps_mag_det_default: cps_mag_det_default {
|
||||
GPIO_CONFIG_PUD(PM,pm8550vs_g_gpios,5, FUNC_OUTPUT_HIGH, PULL_NONE);
|
||||
};
|
||||
};
|
||||
#endif
|
||||
|
||||
&qupv3_hub_i2c7 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "okay";
|
||||
clock-frequency = <100000>;
|
||||
|
||||
cps4038_charger: cps4038-charger@38 {
|
||||
compatible = "cps,cps4038-charger";
|
||||
reg = <0x38>;
|
||||
status = "okay";
|
||||
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&cps_irq_default &cps_det_default &cps_en_default &cps_pdrc_default
|
||||
#if 1
|
||||
&cps_ping_nen_default
|
||||
#endif
|
||||
#if 1
|
||||
&cps_pdet_b_default
|
||||
#endif
|
||||
#if 1
|
||||
&cps_mag_det_default
|
||||
#endif
|
||||
>;
|
||||
|
||||
battery,wpc_int = <SEC_GPIO_REF(AP,tlmm,84) 1>; /* MFC_AP_INT */
|
||||
battery,wpc_det = <SEC_GPIO_REF(PM,pm8550_gpios,9) 0>; /* WPC_DET */
|
||||
#if 0
|
||||
battery,mst_pwr_en = <SEC_GPIO_REF(${cps_pwr_en_gpio}) 0>; /* MST_PWR_EN */
|
||||
#endif
|
||||
#if 1
|
||||
battery,wpc_ping_nen = <SEC_GPIO_REF(AP,tlmm,180) 1>; /* PING_NEN */
|
||||
#endif
|
||||
#if 1
|
||||
battery,wpc_pdet_b = <SEC_GPIO_REF(AP,tlmm,55) 1>; /* PDET_B */
|
||||
#endif
|
||||
battery,wpc_en = <SEC_GPIO_REF(AP,tlmm,82) 0>; /* WPC_EN */
|
||||
#if 1
|
||||
battery,wpc_pdrc = <SEC_GPIO_REF(PM,pm8550ve_gpios,6) 1>; /* VRECT_INT */
|
||||
#endif
|
||||
#if 1
|
||||
battery,wpc_mag_det = <SEC_GPIO_REF(PM,pm8550vs_g_gpios,5) 0>; /* MAG_DET */
|
||||
#endif
|
||||
|
||||
battery,charger_name = "max77775-charger";
|
||||
battery,fuelgauge_name = "max77775-fuelgauge";
|
||||
battery,wireless_charger_name = "cps4038-charger";
|
||||
battery,wc_cover_rpp = <0x44>;
|
||||
battery,phone_fod_threshold = <0x3b>;
|
||||
battery,wireless20_vout_list = <WIRELESS_VOUT_9V /* 0xA0 */
|
||||
WIRELESS_VOUT_12V /* 0xA1 */
|
||||
WIRELESS_VOUT_12V /* 0xA2 */
|
||||
WIRELESS_VOUT_12V /* 0xA3 */
|
||||
WIRELESS_VOUT_12V /* 0xA4 */
|
||||
WIRELESS_VOUT_12V>; /* 0xA5 */
|
||||
battery,wireless20_vrect_list = <MFC_AFC_CONF_12V_TX
|
||||
MFC_AFC_CONF_12_5V_TX
|
||||
MFC_AFC_CONF_12_5V_TX
|
||||
MFC_AFC_CONF_12_5V_TX
|
||||
MFC_AFC_CONF_12_5V_TX
|
||||
MFC_AFC_CONF_12_5V_TX>;
|
||||
battery,wireless20_max_power_list = <SEC_WIRELESS_RX_POWER_12W
|
||||
SEC_WIRELESS_RX_POWER_15W
|
||||
SEC_WIRELESS_RX_POWER_15W
|
||||
SEC_WIRELESS_RX_POWER_15W
|
||||
SEC_WIRELESS_RX_POWER_15W
|
||||
SEC_WIRELESS_RX_POWER_15W>;
|
||||
|
||||
battery,buds_fod_ta_thresh = <0x0898>; /* 2200mW */
|
||||
battery,wpc_vout_ctrl_full = <WIRELESS_VOUT_5V_STEP>;
|
||||
battery,mis_align_guide;
|
||||
battery,mis_align_target_vout = <5000>;
|
||||
battery,mpp_epp_vout = <WIRELESS_VOUT_12V>;
|
||||
|
||||
fod_list {
|
||||
count = <1>;
|
||||
|
||||
pad_0x00 { /* DEFAULT PAD */
|
||||
bpp { /* DEFAULT OP MODE */
|
||||
flag = <(SET_FOD_CC(ADD) | SET_FOD_CV(USE_CC) | SET_FOD_FULL(ADD))>;
|
||||
cc = <0x4E 0x0F 0x4E 0x10 0x4E 0x0C 0x4E 0x0C 0x4E 0x0C 0x4E 0x0C 0x4E 0x0D 0x4E 0x0D 0x4E 0x0D 0x4E 0x0D>;
|
||||
full = <0xFF 0x7F 0xFF 0x7F 0xFF 0x7F 0xFF 0x7F 0xFF 0x7F
|
||||
0xFF 0x7F 0xFF 0x7F 0xFF 0x7F 0xFF 0x7F 0xFF 0x7F>;
|
||||
};
|
||||
|
||||
ppde {
|
||||
flag = <(SET_FOD_CC(USE_DEF_OP) | SET_FOD_CV(USE_DEF_OP) | SET_FOD_FULL(USE_DEF_OP))>;
|
||||
};
|
||||
|
||||
epp {
|
||||
flag = <(SET_FOD_CC(USE_DEF_OP) | SET_FOD_CV(USE_DEF_OP) | SET_FOD_FULL(USE_DEF_OP))>;
|
||||
};
|
||||
|
||||
mpp {
|
||||
flag = <(SET_FOD_CC(USE_DEF_OP) | SET_FOD_CV(USE_DEF_OP) | SET_FOD_FULL(USE_DEF_OP))>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
/* /home/dpi/qb5_8814/workspace/P4_1788/android/kernel_platform/kmodule/battery/stable/eureka/wireless/cps4038/cps4038_charger.e1q.dtsi */
|
||||
#include <dt-bindings/battery/sec-battery.h>
|
||||
|
||||
&cps_pdrc_default {
|
||||
power-source = <1>; /* need to set default MV gpio to LV */
|
||||
};
|
||||
|
||||
&cps_det_default {
|
||||
power-source = <1>; /* need to set default MV gpio to LV */
|
||||
};
|
||||
|
||||
#if 1
|
||||
&cps_mag_det_default {
|
||||
power-source = <1>; /* need to set default MV gpio to LV */
|
||||
};
|
||||
#endif
|
||||
|
||||
&cps4038_charger {
|
||||
battery,unknown_cmb_ctrl;
|
||||
battery,default_clamp_volt;
|
||||
battery,tx_max_op_freq = <1450>;
|
||||
battery,tx_min_op_freq = <1120>;
|
||||
battery,wireless20_iec_ploss_fod_enable = <0x1>;
|
||||
battery,tx_fod_gain = <0x74>;
|
||||
battery,buds_fod_thresh1 = <0x0DAC>;
|
||||
battery,buds_fod_ta_thresh = <0x0DAC>;
|
||||
battery,cep_timeout_xac = <900>;
|
||||
|
||||
fod_list {
|
||||
epp_ref_qf = <0x24>;
|
||||
epp_ref_rf = <0x69>;
|
||||
|
||||
count = <3>;
|
||||
|
||||
pad_0x00 { /* DEFAULT */
|
||||
bpp { /* DEFAULT OP MODE */
|
||||
flag = <(SET_FOD_CC(ADD) | SET_FOD_CV(ADD) | SET_FOD_FULL(ADD))>;
|
||||
cc = <0x52 0x0E 0x52 0x0E 0x52 0x0A 0x52 0x0A 0x52 0x0A 0x52 0x0A 0x52 0x0B 0x52 0x0B 0x52 0x0B 0x52 0x0B>;
|
||||
cv = <0x52 0x16 0x52 0x16 0x52 0x12 0x52 0x12 0x52 0x12 0x52 0x12 0x52 0x13 0x52 0x13 0x52 0x13 0x52 0x13>;
|
||||
full = <0xFF 0x7F 0xFF 0x7F 0xFF 0x7F 0xFF 0x7F 0xFF 0x7F 0xFF 0x7F 0xFF 0x7F 0xFF 0x7F 0xFF 0x7F 0xFF 0x7F>;
|
||||
};
|
||||
|
||||
epp {
|
||||
flag = <(SET_FOD_CC(ADD) | SET_FOD_CV(ADD) | SET_FOD_FULL(ADD))>;
|
||||
cc = <0x65 0x1B 0x65 0x1B 0x65 0x16 0x65 0x16 0x65 0x19 0x65 0x19 0x62 0x1D 0x62 0x1D 0x62 0x1D 0x0E 0x03>;
|
||||
cv = <0x65 0x23 0x65 0x23 0x65 0x1E 0x65 0x1E 0x65 0x21 0x65 0x21 0x62 0x25 0x62 0x25 0x62 0x25 0x0E 0x03>;
|
||||
full = <0xFF 0x7F 0xFF 0x7F 0xFF 0x7F 0xFF 0x7F 0xFF 0x7F 0xFF 0x7F 0xFF 0x7F 0xFF 0x7F 0xFF 0x7F 0x0E 0x03>;
|
||||
};
|
||||
|
||||
ppde {
|
||||
flag = <(SET_FOD_CC(ADD) | SET_FOD_CV(ADD) | SET_FOD_FULL(USE_DEF_OP))>;
|
||||
cc = <0xA0 0x4F 0xA0 0x4F 0xA0 0x3B 0xA0 0x3D 0xA0 0x3E 0xA0 0x3E 0xA0 0x3E 0xA0 0x3B 0xA0 0x39 0xA0 0x39>;
|
||||
cv = <0xA0 0x57 0xA0 0x57 0xA0 0x43 0xA0 0x45 0xA0 0x46 0xA0 0x46 0xA0 0x46 0xA0 0x43 0xA0 0x41 0xA0 0x41>;
|
||||
};
|
||||
};
|
||||
|
||||
pad_0xA3 { /* p2400 */
|
||||
epp {
|
||||
flag = <(SET_FOD_CC(ADD) | SET_FOD_CV(ADD) | SET_FOD_FULL(ADD))>;
|
||||
cc = <0x65 0x41 0x65 0x41 0x65 0x3C 0x65 0x3C 0x65 0x3E 0x65 0x3E 0x62 0x43 0x62 0x43 0x62 0x43 0x0E 0x0A>;
|
||||
cv = <0x65 0x49 0x65 0x49 0x65 0x44 0x65 0x44 0x65 0x46 0x65 0x46 0x62 0x4B 0x62 0x4B 0x62 0x4B 0x62 0x4B>;
|
||||
full = <0xFF 0x7F 0xFF 0x7F 0xFF 0x7F 0xFF 0x7F 0xFF 0x7F 0xFF 0x7F 0xFF 0x7F 0xFF 0x7F 0xFF 0x7F 0xFF 0x7F>;
|
||||
};
|
||||
};
|
||||
|
||||
pad_0x18 { /* p2400 */
|
||||
epp {
|
||||
flag = <(SET_FOD_CC(ADD) | SET_FOD_CV(ADD) | SET_FOD_FULL(ADD))>;
|
||||
cc = <0x65 0x41 0x65 0x41 0x65 0x3C 0x65 0x3C 0x65 0x3E 0x65 0x3E 0x62 0x43 0x62 0x43 0x62 0x43 0x0E 0x0A>;
|
||||
cv = <0x65 0x49 0x65 0x49 0x65 0x44 0x65 0x44 0x65 0x46 0x65 0x46 0x62 0x4B 0x62 0x4B 0x62 0x4B 0x62 0x4B>;
|
||||
full = <0xFF 0x7F 0xFF 0x7F 0xFF 0x7F 0xFF 0x7F 0xFF 0x7F 0xFF 0x7F 0xFF 0x7F 0xFF 0x7F 0xFF 0x7F 0xFF 0x7F>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
1340
drivers/battery/wireless/cps4038_charger.h
Executable file
1340
drivers/battery/wireless/cps4038_charger.h
Executable file
File diff suppressed because it is too large
Load Diff
335
drivers/battery/wireless/cps4038_cmfet.c
Executable file
335
drivers/battery/wireless/cps4038_cmfet.c
Executable file
@ -0,0 +1,335 @@
|
||||
/*
|
||||
* mfc_cmfet.c
|
||||
* Samsung Mobile MFC CMFET Module
|
||||
*
|
||||
* Copyright (C) 2023 Samsung Electronics
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/of.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include "cps4038_charger.h"
|
||||
|
||||
#define cmfet_log(str, ...) pr_info("[MFC-CMFET]:%s: "str, __func__, ##__VA_ARGS__)
|
||||
|
||||
struct mfc_cmfet {
|
||||
struct device *parent;
|
||||
mfc_set_cmfet cb_func;
|
||||
|
||||
struct mutex lock;
|
||||
union mfc_cmfet_state state;
|
||||
|
||||
/* threshold */
|
||||
bool unknown_cmb_ctrl;
|
||||
unsigned int high_swell_cc_cv_thr;
|
||||
};
|
||||
|
||||
static int mfc_cmfet_parse_dt(struct device_node *np, struct mfc_cmfet *cmfet)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
cmfet->unknown_cmb_ctrl = of_property_read_bool(np, "battery,unknown_cmb_ctrl");
|
||||
|
||||
ret = of_property_read_u32(np, "high_swell_cc_cv_thr", &cmfet->high_swell_cc_cv_thr);
|
||||
if (ret < 0)
|
||||
cmfet->high_swell_cc_cv_thr = 70;
|
||||
|
||||
cmfet_log("unknown_cmb_ctrl = %d, high_swell_cc_cv_thr = %d\n",
|
||||
cmfet->unknown_cmb_ctrl, cmfet->high_swell_cc_cv_thr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct mfc_cmfet *mfc_cmfet_init(struct device *dev, mfc_set_cmfet cb_func)
|
||||
{
|
||||
struct mfc_cmfet *cmfet;
|
||||
int ret = 0;
|
||||
|
||||
if (IS_ERR_OR_NULL(dev) ||
|
||||
(cb_func == NULL))
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
cmfet = kzalloc(sizeof(struct mfc_cmfet), GFP_KERNEL);
|
||||
if (!cmfet)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
ret = mfc_cmfet_parse_dt(dev->of_node, cmfet);
|
||||
if (ret < 0) {
|
||||
kfree(cmfet);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
mutex_init(&cmfet->lock);
|
||||
|
||||
cmfet->parent = dev;
|
||||
cmfet->cb_func = cb_func;
|
||||
cmfet->state.value = 0;
|
||||
|
||||
cmfet_log("DONE!!\n");
|
||||
return cmfet;
|
||||
}
|
||||
EXPORT_SYMBOL(mfc_cmfet_init);
|
||||
|
||||
int mfc_cmfet_init_state(struct mfc_cmfet *cmfet)
|
||||
{
|
||||
if (IS_ERR(cmfet))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&cmfet->lock);
|
||||
if (cmfet->state.value != 0) {
|
||||
cmfet->state.value = 0;
|
||||
|
||||
cmfet->cb_func(cmfet->parent, &cmfet->state, false, false);
|
||||
}
|
||||
mutex_unlock(&cmfet->lock);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(mfc_cmfet_init_state);
|
||||
|
||||
int mfc_cmfet_refresh(struct mfc_cmfet *cmfet)
|
||||
{
|
||||
if (IS_ERR(cmfet))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&cmfet->lock);
|
||||
if (cmfet->state.value != 0)
|
||||
cmfet->cb_func(cmfet->parent, &cmfet->state, cmfet->state.cma, cmfet->state.cmb);
|
||||
mutex_unlock(&cmfet->lock);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(mfc_cmfet_refresh);
|
||||
|
||||
static void set_init_state(union mfc_cmfet_state *state, bool cma, bool cmb)
|
||||
{
|
||||
state->cma = cma;
|
||||
state->cmb = cmb;
|
||||
}
|
||||
|
||||
static unsigned long long check_tx_default(struct mfc_cmfet *cmfet, union mfc_cmfet_state *state)
|
||||
{
|
||||
if (state->high_swell)
|
||||
state->cmb = (state->bat_cap > cmfet->high_swell_cc_cv_thr);
|
||||
|
||||
if (state->full)
|
||||
state->cmb = true;
|
||||
|
||||
if (state->chg_done)
|
||||
state->cmb = false;
|
||||
|
||||
return state->value;
|
||||
}
|
||||
|
||||
static unsigned long long check_tx_unknown(struct mfc_cmfet *cmfet, union mfc_cmfet_state *state)
|
||||
{
|
||||
set_init_state(state, true, (cmfet->unknown_cmb_ctrl));
|
||||
|
||||
return state->value;
|
||||
}
|
||||
|
||||
static unsigned long long check_tx_p1100(struct mfc_cmfet *cmfet, union mfc_cmfet_state *state)
|
||||
{
|
||||
set_init_state(state, true, true);
|
||||
|
||||
if (state->vout <= 5500)
|
||||
state->cmb = false;
|
||||
|
||||
if (state->chg_done)
|
||||
state->cmb = false;
|
||||
|
||||
return state->value;
|
||||
}
|
||||
|
||||
static unsigned long long check_tx_n5200(struct mfc_cmfet *cmfet, union mfc_cmfet_state *state)
|
||||
{
|
||||
set_init_state(state, true, false);
|
||||
|
||||
return check_tx_default(cmfet, state);
|
||||
}
|
||||
|
||||
static unsigned long long check_tx_p5200(struct mfc_cmfet *cmfet, union mfc_cmfet_state *state)
|
||||
{
|
||||
set_init_state(state, true, true);
|
||||
|
||||
if (state->auth)
|
||||
state->cmb = false;
|
||||
|
||||
return check_tx_default(cmfet, state);
|
||||
}
|
||||
|
||||
static unsigned long long check_cmfet_state(struct mfc_cmfet *cmfet, union mfc_cmfet_state *state)
|
||||
{
|
||||
switch (state->tx_id) {
|
||||
case TX_ID_UNKNOWN:
|
||||
return check_tx_unknown(cmfet, state);
|
||||
case TX_ID_P1100_PAD:
|
||||
return check_tx_p1100(cmfet, state);
|
||||
case TX_ID_N5200_V_PAD:
|
||||
case TX_ID_N5200_H_PAD:
|
||||
return check_tx_n5200(cmfet, state);
|
||||
case TX_ID_P5200_PAD:
|
||||
return check_tx_p5200(cmfet, state);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
set_init_state(state, true, true);
|
||||
return check_tx_default(cmfet, state);
|
||||
}
|
||||
|
||||
static bool is_changed_state(union mfc_cmfet_state *state1, union mfc_cmfet_state *state2)
|
||||
{
|
||||
return (state1->cma != state2->cma) || (state1->cmb != state2->cmb);
|
||||
}
|
||||
|
||||
static int update_cmfet_state(struct mfc_cmfet *cmfet, union mfc_cmfet_state *state)
|
||||
{
|
||||
state->value = check_cmfet_state(cmfet, state);
|
||||
|
||||
if (is_changed_state(state, &cmfet->state))
|
||||
cmfet->cb_func(cmfet->parent, state, state->cma, state->cmb);
|
||||
|
||||
cmfet->state.value = state->value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mfc_cmfet_set_tx_id(struct mfc_cmfet *cmfet, int tx_id)
|
||||
{
|
||||
if (IS_ERR(cmfet) ||
|
||||
(tx_id < 0) || (tx_id >= 256))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&cmfet->lock);
|
||||
if (cmfet->state.tx_id != tx_id) {
|
||||
union mfc_cmfet_state temp = { cmfet->state.value, };
|
||||
|
||||
temp.tx_id = tx_id;
|
||||
update_cmfet_state(cmfet, &temp);
|
||||
}
|
||||
mutex_unlock(&cmfet->lock);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(mfc_cmfet_set_tx_id);
|
||||
|
||||
int mfc_cmfet_set_bat_cap(struct mfc_cmfet *cmfet, int bat_cap)
|
||||
{
|
||||
if (IS_ERR(cmfet) ||
|
||||
(bat_cap < 0) || (bat_cap > 100))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&cmfet->lock);
|
||||
if (cmfet->state.bat_cap != bat_cap) {
|
||||
union mfc_cmfet_state temp = { cmfet->state.value, };
|
||||
|
||||
temp.bat_cap = bat_cap;
|
||||
update_cmfet_state(cmfet, &temp);
|
||||
}
|
||||
mutex_unlock(&cmfet->lock);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(mfc_cmfet_set_bat_cap);
|
||||
|
||||
int mfc_cmfet_set_vout(struct mfc_cmfet *cmfet, int vout)
|
||||
{
|
||||
if (IS_ERR(cmfet) ||
|
||||
(vout <= 0))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&cmfet->lock);
|
||||
if (cmfet->state.vout != vout) {
|
||||
union mfc_cmfet_state temp = { cmfet->state.value, };
|
||||
|
||||
temp.vout = vout;
|
||||
update_cmfet_state(cmfet, &temp);
|
||||
}
|
||||
mutex_unlock(&cmfet->lock);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(mfc_cmfet_set_vout);
|
||||
|
||||
int mfc_cmfet_set_high_swell(struct mfc_cmfet *cmfet, bool state)
|
||||
{
|
||||
if (IS_ERR(cmfet))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&cmfet->lock);
|
||||
if (cmfet->state.high_swell != state) {
|
||||
union mfc_cmfet_state temp = { cmfet->state.value, };
|
||||
|
||||
temp.high_swell = state;
|
||||
update_cmfet_state(cmfet, &temp);
|
||||
}
|
||||
mutex_unlock(&cmfet->lock);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(mfc_cmfet_set_high_swell);
|
||||
|
||||
int mfc_cmfet_set_full(struct mfc_cmfet *cmfet, bool full)
|
||||
{
|
||||
if (IS_ERR(cmfet))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&cmfet->lock);
|
||||
if (cmfet->state.full != full) {
|
||||
union mfc_cmfet_state temp = { cmfet->state.value, };
|
||||
|
||||
temp.full = full;
|
||||
update_cmfet_state(cmfet, &temp);
|
||||
}
|
||||
mutex_unlock(&cmfet->lock);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(mfc_cmfet_set_full);
|
||||
|
||||
int mfc_cmfet_set_chg_done(struct mfc_cmfet *cmfet, bool chg_done)
|
||||
{
|
||||
if (IS_ERR(cmfet))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&cmfet->lock);
|
||||
if (cmfet->state.chg_done != chg_done) {
|
||||
union mfc_cmfet_state temp = { cmfet->state.value, };
|
||||
|
||||
temp.chg_done = chg_done;
|
||||
update_cmfet_state(cmfet, &temp);
|
||||
}
|
||||
mutex_unlock(&cmfet->lock);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(mfc_cmfet_set_chg_done);
|
||||
|
||||
int mfc_cmfet_set_auth(struct mfc_cmfet *cmfet, bool auth)
|
||||
{
|
||||
if (IS_ERR(cmfet))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&cmfet->lock);
|
||||
if (cmfet->state.auth != auth) {
|
||||
union mfc_cmfet_state temp = { cmfet->state.value, };
|
||||
|
||||
temp.auth = auth;
|
||||
update_cmfet_state(cmfet, &temp);
|
||||
}
|
||||
mutex_unlock(&cmfet->lock);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(mfc_cmfet_set_auth);
|
||||
|
||||
int mfc_cmfet_get_state(struct mfc_cmfet *cmfet, union mfc_cmfet_state *state)
|
||||
{
|
||||
if (IS_ERR(cmfet) ||
|
||||
(state == NULL))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&cmfet->lock);
|
||||
state->value = cmfet->state.value;
|
||||
mutex_unlock(&cmfet->lock);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(mfc_cmfet_get_state);
|
90
drivers/battery/wireless/cps4038_cmfet.h
Executable file
90
drivers/battery/wireless/cps4038_cmfet.h
Executable file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* mfc_cmfet.h
|
||||
* Samsung Mobile MFC CMFET Header
|
||||
*
|
||||
* Copyright (C) 2023 Samsung Electronics, Inc.
|
||||
*
|
||||
*
|
||||
* 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 __MFC_CMFET_H
|
||||
#define __MFC_CMFET_H __FILE__
|
||||
|
||||
#include <linux/err.h>
|
||||
|
||||
struct device;
|
||||
struct mfc_cmfet;
|
||||
|
||||
union mfc_cmfet_state {
|
||||
unsigned long long value;
|
||||
|
||||
struct {
|
||||
unsigned cma : 1,
|
||||
cmb : 1,
|
||||
resv : 6,
|
||||
tx_id : 8,
|
||||
vout : 16,
|
||||
bat_cap : 7,
|
||||
full : 1,
|
||||
chg_done : 1,
|
||||
high_swell : 1,
|
||||
auth : 1;
|
||||
};
|
||||
};
|
||||
|
||||
typedef int (*mfc_set_cmfet)(struct device *dev, union mfc_cmfet_state *state, bool cma, bool cmb);
|
||||
|
||||
#define MFC_CMFET_DISABLED (-ESRCH)
|
||||
#if IS_ENABLED(CONFIG_WIRELESS_CHARGING)
|
||||
struct mfc_cmfet *mfc_cmfet_init(struct device *dev, mfc_set_cmfet cb_func);
|
||||
|
||||
int mfc_cmfet_init_state(struct mfc_cmfet *cmfet);
|
||||
int mfc_cmfet_refresh(struct mfc_cmfet *cmfet);
|
||||
|
||||
int mfc_cmfet_set_tx_id(struct mfc_cmfet *cmfet, int tx_id);
|
||||
int mfc_cmfet_set_bat_cap(struct mfc_cmfet *cmfet, int bat_cap);
|
||||
int mfc_cmfet_set_vout(struct mfc_cmfet *cmfet, int vout);
|
||||
int mfc_cmfet_set_high_swell(struct mfc_cmfet *cmfet, bool state);
|
||||
int mfc_cmfet_set_full(struct mfc_cmfet *cmfet, bool full);
|
||||
int mfc_cmfet_set_chg_done(struct mfc_cmfet *cmfet, bool chg_done);
|
||||
int mfc_cmfet_set_auth(struct mfc_cmfet *cmfet, bool auth);
|
||||
|
||||
int mfc_cmfet_get_state(struct mfc_cmfet *cmfet, union mfc_cmfet_state *state);
|
||||
#else
|
||||
static inline struct mfc_cmfet *mfc_cmfet_init(struct device *dev, mfc_set_cmfet cb_func)
|
||||
{ return ERR_PTR(MFC_CMFET_DISABLED); }
|
||||
|
||||
static inline int mfc_cmfet_init_state(struct mfc_cmfet *cmfet)
|
||||
{ return MFC_CMFET_DISABLED; }
|
||||
static inline int mfc_cmfet_refresh(struct mfc_cmfet *cmfet)
|
||||
{ return MFC_CMFET_DISABLED; }
|
||||
|
||||
static inline int mfc_cmfet_set_tx_id(struct mfc_cmfet *cmfet, int tx_id)
|
||||
{ return MFC_CMFET_DISABLED; }
|
||||
static inline int mfc_cmfet_set_bat_cap(struct mfc_cmfet *cmfet, int bat_cap)
|
||||
{ return MFC_CMFET_DISABLED; }
|
||||
static inline int mfc_cmfet_set_vout(struct mfc_cmfet *cmfet, int vout)
|
||||
{ return MFC_CMFET_DISABLED; }
|
||||
static inline int mfc_cmfet_set_high_swell(struct mfc_cmfet *cmfet, bool state)
|
||||
{ return MFC_CMFET_DISABLED; }
|
||||
static inline int mfc_cmfet_set_full(struct mfc_cmfet *cmfet, bool full)
|
||||
{ return MFC_CMFET_DISABLED; }
|
||||
static inline int mfc_cmfet_set_chg_done(struct mfc_cmfet *cmfet, bool chg_done)
|
||||
{ return MFC_CMFET_DISABLED; }
|
||||
static inline int mfc_cmfet_set_auth(struct mfc_cmfet *cmfet, bool auth)
|
||||
{ return MFC_CMFET_DISABLED; }
|
||||
|
||||
static inline int mfc_cmfet_get_state(struct mfc_cmfet *cmfet, union mfc_cmfet_state *state)
|
||||
{ return MFC_CMFET_DISABLED; }
|
||||
#endif
|
||||
|
||||
#endif /* __MFC_CMFET_H */
|
293
drivers/battery/wireless/cps4038_firmware.h
Executable file
293
drivers/battery/wireless/cps4038_firmware.h
Executable file
@ -0,0 +1,293 @@
|
||||
/*
|
||||
* cps4038_firmware.h
|
||||
* Samsung Mobile CPS4038 FIRMWARE Header
|
||||
*
|
||||
* Copyright (C) 2023 Samsung Electronics, Inc.
|
||||
*
|
||||
*
|
||||
* 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 __CPS4038_FIRMWARE_H
|
||||
#define __CPS4038_FIRMWARE_H __FILE__
|
||||
|
||||
#define MFC_FW_BIN_VERSION 0x4012
|
||||
#define MFC_FW_VER_BIN_CPS 0x00C4
|
||||
|
||||
#define MFC_FLASH_FW_HEX_PATH "mfc/mfc_fw_flash.bin"
|
||||
#define MFC_FW_SDCARD_BIN_PATH "wpc_fw_sdcard.bin"
|
||||
|
||||
#define MFC_FLASH_FW_HEX_CPS_PATH "mfc/mfc_fw_flash_cps4038.bin"
|
||||
|
||||
/* for SPU FW update */
|
||||
#define MFC_FW_SPU_BIN_PATH "mfc/mfc_fw_spu_cps4038.bin"
|
||||
|
||||
static const unsigned char CPS4038_BL[0x800] = {
|
||||
// CPS4038_BL_01_07_V0.2_CRC57AE
|
||||
0x78, 0x1D, 0x00, 0x20, 0xF9, 0x04, 0x00, 0x20,
|
||||
0x55, 0x01, 0x00, 0x20, 0x7D, 0x01, 0x00, 0x20,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x59, 0x01, 0x00, 0x20,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x5B, 0x01, 0x00, 0x20, 0x5D, 0x01, 0x00, 0x20,
|
||||
0x5F, 0x01, 0x00, 0x20, 0x5F, 0x01, 0x00, 0x20,
|
||||
0x5F, 0x01, 0x00, 0x20, 0x5F, 0x01, 0x00, 0x20,
|
||||
0x5F, 0x01, 0x00, 0x20, 0x5F, 0x01, 0x00, 0x20,
|
||||
0x5F, 0x01, 0x00, 0x20, 0x5F, 0x01, 0x00, 0x20,
|
||||
0x5F, 0x01, 0x00, 0x20, 0x5F, 0x01, 0x00, 0x20,
|
||||
0x5F, 0x01, 0x00, 0x20, 0x5F, 0x01, 0x00, 0x20,
|
||||
0x5F, 0x01, 0x00, 0x20, 0x5F, 0x01, 0x00, 0x20,
|
||||
0x5F, 0x01, 0x00, 0x20, 0x5F, 0x01, 0x00, 0x20,
|
||||
0x5F, 0x01, 0x00, 0x20, 0x5F, 0x01, 0x00, 0x20,
|
||||
0x5F, 0x01, 0x00, 0x20, 0x5F, 0x01, 0x00, 0x20,
|
||||
0x5F, 0x01, 0x00, 0x20, 0x5F, 0x01, 0x00, 0x20,
|
||||
0x5F, 0x01, 0x00, 0x20, 0x5F, 0x01, 0x00, 0x20,
|
||||
0x5F, 0x01, 0x00, 0x20, 0x5F, 0x01, 0x00, 0x20,
|
||||
0x5F, 0x01, 0x00, 0x20, 0x5F, 0x01, 0x00, 0x20,
|
||||
0x5F, 0x01, 0x00, 0x20, 0x5F, 0x01, 0x00, 0x20,
|
||||
0x5F, 0x01, 0x00, 0x20, 0x5F, 0x01, 0x00, 0x20,
|
||||
0x00, 0x01, 0x01, 0x07, 0x00, 0x02, 0x00, 0x00,
|
||||
0x28, 0x05, 0x00, 0x00, 0x00, 0xF0, 0x02, 0xF8,
|
||||
0x00, 0xF0, 0x30, 0xF8, 0x0C, 0xA0, 0x30, 0xC8,
|
||||
0x08, 0x38, 0x24, 0x18, 0x2D, 0x18, 0xA2, 0x46,
|
||||
0x67, 0x1E, 0xAB, 0x46, 0x54, 0x46, 0x5D, 0x46,
|
||||
0xAC, 0x42, 0x01, 0xD1, 0x00, 0xF0, 0x22, 0xF8,
|
||||
0x7E, 0x46, 0x0F, 0x3E, 0x0F, 0xCC, 0xB6, 0x46,
|
||||
0x01, 0x26, 0x33, 0x42, 0x00, 0xD0, 0xFB, 0x1A,
|
||||
0xA2, 0x46, 0xAB, 0x46, 0x33, 0x43, 0x18, 0x47,
|
||||
0x0C, 0x04, 0x00, 0x00, 0x1C, 0x04, 0x00, 0x00,
|
||||
0x00, 0x23, 0x00, 0x24, 0x00, 0x25, 0x00, 0x26,
|
||||
0x10, 0x3A, 0x01, 0xD3, 0x78, 0xC1, 0xFB, 0xD8,
|
||||
0x52, 0x07, 0x00, 0xD3, 0x30, 0xC1, 0x00, 0xD5,
|
||||
0x0B, 0x60, 0x70, 0x47, 0x1F, 0xB5, 0x1F, 0xBD,
|
||||
0x10, 0xB5, 0x10, 0xBD, 0x00, 0xF0, 0xAD, 0xF9,
|
||||
0x11, 0x46, 0xFF, 0xF7, 0xF7, 0xFF, 0x00, 0xF0,
|
||||
0x5D, 0xF9, 0x00, 0xF0, 0xC5, 0xF9, 0x03, 0xB4,
|
||||
0xFF, 0xF7, 0xF2, 0xFF, 0x03, 0xBC, 0x00, 0xF0,
|
||||
0xCB, 0xF9, 0x00, 0x00, 0xFE, 0xE7, 0xFE, 0xE7,
|
||||
0xFE, 0xE7, 0xFE, 0xE7, 0xFE, 0xE7, 0xFE, 0xE7,
|
||||
0x02, 0x48, 0x03, 0x49, 0x03, 0x4A, 0x04, 0x4B,
|
||||
0x70, 0x47, 0x00, 0x00, 0x78, 0x18, 0x00, 0x20,
|
||||
0x78, 0x1D, 0x00, 0x20, 0x78, 0x19, 0x00, 0x20,
|
||||
0x78, 0x19, 0x00, 0x20, 0xFE, 0xE7, 0xA9, 0x48,
|
||||
0x01, 0x68, 0x00, 0x29, 0x08, 0xD1, 0xA8, 0x4A,
|
||||
0x0B, 0x21, 0xD1, 0x61, 0xA6, 0x4A, 0xA7, 0x49,
|
||||
0xC0, 0x32, 0x91, 0x63, 0x01, 0x21, 0x01, 0x60,
|
||||
0x70, 0x47, 0xA2, 0x48, 0x01, 0x68, 0x01, 0x29,
|
||||
0x09, 0xD1, 0xA1, 0x49, 0x03, 0x22, 0xCA, 0x61,
|
||||
0x0B, 0x22, 0xCA, 0x61, 0x9E, 0x4A, 0x00, 0x21,
|
||||
0xC0, 0x32, 0x91, 0x63, 0x01, 0x60, 0x70, 0x47,
|
||||
0x30, 0xB5, 0x5F, 0x22, 0x00, 0x23, 0x12, 0x02,
|
||||
0x90, 0x42, 0x04, 0xDB, 0x9A, 0x4A, 0x90, 0x42,
|
||||
0x01, 0xD0, 0x00, 0x20, 0x30, 0xBD, 0x96, 0x4A,
|
||||
0x90, 0x60, 0xD1, 0x60, 0x03, 0x21, 0xD1, 0x61,
|
||||
0x07, 0x20, 0xD0, 0x61, 0xD0, 0x61, 0xD0, 0x61,
|
||||
0xD0, 0x61, 0xD1, 0x61, 0x93, 0x48, 0x01, 0x24,
|
||||
0x15, 0x6A, 0x00, 0x2D, 0x05, 0xD0, 0x40, 0x1E,
|
||||
0xFA, 0xD2, 0xD4, 0x61, 0xD1, 0x61, 0x01, 0x23,
|
||||
0xF6, 0xE7, 0x08, 0x20, 0x40, 0x1E, 0xFD, 0xD2,
|
||||
0x18, 0x46, 0x30, 0xBD, 0x70, 0xB5, 0x04, 0x46,
|
||||
0x00, 0x20, 0x8B, 0x4D, 0x02, 0x46, 0x0E, 0xE0,
|
||||
0xA3, 0x5C, 0x1B, 0x02, 0x58, 0x40, 0x00, 0x23,
|
||||
0x06, 0x04, 0x02, 0xD5, 0x40, 0x00, 0x68, 0x40,
|
||||
0x00, 0xE0, 0x40, 0x00, 0x5B, 0x1C, 0x80, 0xB2,
|
||||
0x08, 0x2B, 0xF5, 0xDB, 0x52, 0x1C, 0x8A, 0x42,
|
||||
0xEE, 0xDB, 0x70, 0xBD, 0x00, 0x25, 0xFF, 0xF7,
|
||||
0xA2, 0xFF, 0x69, 0x1E, 0x7C, 0x48, 0xFF, 0xF7,
|
||||
0xBB, 0xFF, 0xFF, 0xF7, 0xAA, 0xFF, 0x7D, 0x4F,
|
||||
0x7D, 0x49, 0x08, 0x68, 0x00, 0x28, 0xFB, 0xD0,
|
||||
0x00, 0x22, 0x0A, 0x60, 0x14, 0x46, 0x01, 0x22,
|
||||
0x39, 0x68, 0x52, 0x02, 0x91, 0x42, 0x01, 0xDD,
|
||||
0x40, 0x20, 0x7B, 0xE0, 0x66, 0x22, 0x77, 0x49,
|
||||
0x90, 0x28, 0x0A, 0x60, 0x24, 0xD0, 0x06, 0xDC,
|
||||
0x10, 0x28, 0x41, 0xD0, 0x20, 0x28, 0x5B, 0xD0,
|
||||
0x80, 0x28, 0x73, 0xD1, 0x34, 0xE0, 0xB0, 0x28,
|
||||
0x02, 0xD0, 0xC0, 0x28, 0x6E, 0xD1, 0x66, 0xE0,
|
||||
0xFF, 0xF7, 0x87, 0xFF, 0x6E, 0x48, 0x84, 0x68,
|
||||
0x80, 0x14, 0x84, 0x42, 0x02, 0xDD, 0x6D, 0x48,
|
||||
0x04, 0x60, 0x45, 0xE0, 0x01, 0x20, 0x21, 0x1F,
|
||||
0x40, 0x07, 0xFF, 0xF7, 0xAF, 0xFF, 0x69, 0x4A,
|
||||
0x69, 0x49, 0x10, 0x60, 0x61, 0x18, 0xC9, 0x6F,
|
||||
0x51, 0x60, 0x88, 0x42, 0x38, 0xD1, 0x50, 0xE0,
|
||||
0xFF, 0xF7, 0x6F, 0xFF, 0xC0, 0x20, 0x84, 0x68,
|
||||
0x00, 0x2C, 0x31, 0xDB, 0xC0, 0x01, 0x84, 0x42,
|
||||
0x2E, 0xDC, 0xC8, 0x2C, 0x2C, 0xDB, 0x21, 0x1F,
|
||||
0x00, 0x20, 0xFF, 0xF7, 0x97, 0xFF, 0x01, 0x46,
|
||||
0x5C, 0x48, 0x80, 0x3C, 0x01, 0x60, 0xE2, 0x6F,
|
||||
0x42, 0x60, 0x91, 0x42, 0x20, 0xD1, 0x38, 0xE0,
|
||||
0xFF, 0xF7, 0x49, 0xFF, 0x59, 0x49, 0x50, 0x48,
|
||||
0xFF, 0xF7, 0x62, 0xFF, 0x04, 0x46, 0x11, 0xE0,
|
||||
0xFF, 0xF7, 0x41, 0xFF, 0x00, 0x26, 0x08, 0xE0,
|
||||
0x52, 0x48, 0xB1, 0x00, 0x41, 0x58, 0x28, 0x46,
|
||||
0xFF, 0xF7, 0x56, 0xFF, 0x04, 0x43, 0x2D, 0x1D,
|
||||
0x76, 0x1C, 0x38, 0x68, 0x86, 0x42, 0xF3, 0xDB,
|
||||
0x4C, 0x48, 0x1A, 0xE0, 0xFF, 0xF7, 0x3D, 0xFF,
|
||||
0x60, 0x1C, 0x1F, 0xD0, 0x00, 0x2C, 0x18, 0xD0,
|
||||
0xAA, 0x21, 0x46, 0x48, 0x01, 0x60, 0x8B, 0xE7,
|
||||
0xFF, 0xF7, 0x25, 0xFF, 0x00, 0x26, 0x08, 0xE0,
|
||||
0x47, 0x48, 0xB1, 0x00, 0x41, 0x58, 0x28, 0x46,
|
||||
0xFF, 0xF7, 0x3A, 0xFF, 0x04, 0x43, 0x2D, 0x1D,
|
||||
0x76, 0x1C, 0x38, 0x68, 0x86, 0x42, 0xF3, 0xDB,
|
||||
0x41, 0x48, 0x05, 0x60, 0xE2, 0xE7, 0x3D, 0x48,
|
||||
0x05, 0x68, 0x55, 0x20, 0x39, 0x49, 0x08, 0x60,
|
||||
0x72, 0xE7, 0xFF, 0xE7, 0x40, 0x21, 0xE0, 0xE7,
|
||||
0x3D, 0x48, 0x3C, 0x49, 0x01, 0x60, 0x3D, 0x4A,
|
||||
0x00, 0x21, 0x91, 0x60, 0x33, 0x22, 0x3C, 0x4B,
|
||||
0x92, 0x03, 0x5A, 0x60, 0x01, 0x60, 0x70, 0x47,
|
||||
0x01, 0x20, 0x3A, 0x49, 0x80, 0x04, 0x48, 0x63,
|
||||
0x38, 0x48, 0x39, 0x49, 0x40, 0x30, 0x81, 0x62,
|
||||
0x01, 0x21, 0xC9, 0x05, 0xC1, 0x62, 0x40, 0x21,
|
||||
0x41, 0x63, 0xFF, 0x21, 0x35, 0x4A, 0xBD, 0x31,
|
||||
0x11, 0x60, 0x35, 0x49, 0x41, 0x62, 0x30, 0x49,
|
||||
0x00, 0x14, 0x48, 0x60, 0x70, 0x47, 0x70, 0xB5,
|
||||
0x2D, 0x48, 0x00, 0x24, 0x80, 0x30, 0x04, 0x62,
|
||||
0x31, 0x4B, 0x30, 0x4D, 0xDD, 0x61, 0x2B, 0x49,
|
||||
0x07, 0x20, 0x40, 0x31, 0x48, 0x61, 0xFF, 0xF7,
|
||||
0xDB, 0xFF, 0xDC, 0x61, 0x18, 0x48, 0x38, 0x38,
|
||||
0xC0, 0x6B, 0x2C, 0x49, 0x88, 0x42, 0x0F, 0xD1,
|
||||
0xDD, 0x61, 0xC1, 0x21, 0x23, 0x4A, 0x00, 0x20,
|
||||
0xC9, 0x01, 0x80, 0x3A, 0x45, 0x18, 0x2D, 0x68,
|
||||
0x86, 0x18, 0x35, 0x60, 0x00, 0x1D, 0x80, 0x28,
|
||||
0xF8, 0xDB, 0xDC, 0x61, 0x01, 0x20, 0x70, 0xBD,
|
||||
0x00, 0x20, 0x70, 0xBD, 0xFF, 0x21, 0x09, 0x48,
|
||||
0x01, 0x31, 0x41, 0x60, 0x0D, 0x4A, 0x49, 0x00,
|
||||
0x11, 0x60, 0x0D, 0x4A, 0x00, 0x21, 0x11, 0x60,
|
||||
0x0C, 0x4B, 0x55, 0x22, 0x1A, 0x60, 0x01, 0x60,
|
||||
0xFF, 0xF7, 0xC9, 0xFF, 0xFF, 0xF7, 0xA4, 0xFF,
|
||||
0xFF, 0xF7, 0x08, 0xFF, 0x0C, 0x18, 0x00, 0x20,
|
||||
0x00, 0x20, 0x01, 0x40, 0x78, 0x56, 0x00, 0x00,
|
||||
0xF8, 0x60, 0x00, 0x00, 0x50, 0xC3, 0x00, 0x00,
|
||||
0x21, 0x10, 0x00, 0x00, 0x08, 0x18, 0x00, 0x20,
|
||||
0x00, 0x18, 0x00, 0x20, 0x04, 0x18, 0x00, 0x20,
|
||||
0xC0, 0x00, 0x00, 0x20, 0x00, 0x08, 0x00, 0x20,
|
||||
0x80, 0xFF, 0xFF, 0x1F, 0x85, 0xE1, 0x24, 0x57,
|
||||
0x00, 0x10, 0x00, 0x20, 0x51, 0xE5, 0xCC, 0x1A,
|
||||
0x00, 0x8C, 0x00, 0x40, 0x00, 0x80, 0x00, 0x40,
|
||||
0x00, 0x00, 0x04, 0x40, 0x80, 0xF0, 0x00, 0x40,
|
||||
0x2C, 0x00, 0x00, 0x04, 0x00, 0x40, 0x00, 0x40,
|
||||
0x00, 0x02, 0xA1, 0x02, 0x50, 0x12, 0x00, 0x00,
|
||||
0x40, 0xE7, 0x00, 0x40, 0x4E, 0x87, 0x55, 0x74,
|
||||
0x70, 0x47, 0x70, 0x47, 0x70, 0x47, 0x70, 0x47,
|
||||
0x70, 0x47, 0x75, 0x46, 0x00, 0xF0, 0x24, 0xF8,
|
||||
0xAE, 0x46, 0x05, 0x00, 0x69, 0x46, 0x53, 0x46,
|
||||
0xC0, 0x08, 0xC0, 0x00, 0x85, 0x46, 0x18, 0xB0,
|
||||
0x20, 0xB5, 0xFF, 0xF7, 0x59, 0xFE, 0x60, 0xBC,
|
||||
0x00, 0x27, 0x49, 0x08, 0xB6, 0x46, 0x00, 0x26,
|
||||
0xC0, 0xC5, 0xC0, 0xC5, 0xC0, 0xC5, 0xC0, 0xC5,
|
||||
0xC0, 0xC5, 0xC0, 0xC5, 0xC0, 0xC5, 0xC0, 0xC5,
|
||||
0x40, 0x3D, 0x49, 0x00, 0x8D, 0x46, 0x70, 0x47,
|
||||
0x10, 0xB5, 0x04, 0x46, 0xC0, 0x46, 0xC0, 0x46,
|
||||
0x20, 0x46, 0xFF, 0xF7, 0x34, 0xFE, 0x10, 0xBD,
|
||||
0x00, 0x48, 0x70, 0x47, 0x14, 0x18, 0x00, 0x20,
|
||||
0x01, 0x49, 0x18, 0x20, 0xAB, 0xBE, 0xFE, 0xE7,
|
||||
0x26, 0x00, 0x02, 0x00, 0x70, 0x47, 0x00, 0x00,
|
||||
0x03, 0x49, 0x00, 0x20, 0x48, 0x60, 0x08, 0x60,
|
||||
0x02, 0x48, 0x80, 0x47, 0x02, 0x48, 0x00, 0x47,
|
||||
0x14, 0xE1, 0x00, 0x40, 0x8B, 0x04, 0x00, 0x20,
|
||||
0xCD, 0x00, 0x00, 0x20, 0x24, 0x05, 0x00, 0x20,
|
||||
0x00, 0x08, 0x00, 0x20, 0x78, 0x15, 0x00, 0x00,
|
||||
0x10, 0x01, 0x00, 0x20, 0x16, 0x2B, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
#endif /* __CPS4038_FIRMWARE_H */
|
721
drivers/battery/wireless/cps4038_fod.c
Executable file
721
drivers/battery/wireless/cps4038_fod.c
Executable file
@ -0,0 +1,721 @@
|
||||
/*
|
||||
* mfc_fod.c
|
||||
* Samsung Mobile MFC FOD Module
|
||||
*
|
||||
* Copyright (C) 2023 Samsung Electronics
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/of.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <linux/battery/sb_wireless.h>
|
||||
#include <dt-bindings/battery/sec-battery.h>
|
||||
|
||||
#include "cps4038_fod.h"
|
||||
|
||||
#define fod_log(str, ...) pr_info("[MFC-FOD]:%s: "str, __func__, ##__VA_ARGS__)
|
||||
#define DEFAULT_TX_IDX 0
|
||||
#define DEFAULT_OP_MODE WPC_OP_MODE_BPP
|
||||
#define DEFAULT_VENDOR_ID 0x42
|
||||
|
||||
struct mfc_fod_op {
|
||||
unsigned int flag;
|
||||
fod_data_t *data[MFC_FOD_BAT_STATE_MAX];
|
||||
};
|
||||
|
||||
struct mfc_fod_tx {
|
||||
unsigned int id;
|
||||
struct mfc_fod_op op[WPC_OP_MODE_MAX];
|
||||
};
|
||||
|
||||
struct mfc_fod {
|
||||
struct device *parent;
|
||||
mfc_set_fod cb_func;
|
||||
|
||||
struct mutex lock;
|
||||
union mfc_fod_state state;
|
||||
|
||||
/* fod data */
|
||||
struct mfc_fod_tx *list;
|
||||
unsigned int count;
|
||||
unsigned int ext[MFC_FOD_EXT_MAX];
|
||||
|
||||
/* threshold */
|
||||
unsigned int bpp_vout;
|
||||
unsigned int cc_cv_thr;
|
||||
unsigned int high_swell_cc_cv_thr;
|
||||
unsigned int vendor_id;
|
||||
};
|
||||
|
||||
static int get_op_mode_by_str(const char *str)
|
||||
{
|
||||
if (str == NULL)
|
||||
return WPC_OP_MODE_NONE;
|
||||
|
||||
if (!strncmp(str, "ppde", 4))
|
||||
return WPC_OP_MODE_PPDE;
|
||||
|
||||
if (!strncmp(str, "epp", 3))
|
||||
return WPC_OP_MODE_EPP;
|
||||
|
||||
if (!strncmp(str, "mpp", 3))
|
||||
return WPC_OP_MODE_MPP;
|
||||
|
||||
return WPC_OP_MODE_BPP;
|
||||
}
|
||||
|
||||
static const char *get_ext_str(unsigned int ext_type)
|
||||
{
|
||||
switch (ext_type) {
|
||||
case MFC_FOD_EXT_EPP_REF_QF:
|
||||
return "epp_ref_qf";
|
||||
case MFC_FOD_EXT_EPP_REF_RF:
|
||||
return "epp_ref_rf";
|
||||
}
|
||||
|
||||
return "none";
|
||||
}
|
||||
|
||||
static const char *get_bat_state_str(unsigned int bat_state)
|
||||
{
|
||||
switch (bat_state) {
|
||||
case MFC_FOD_BAT_STATE_CC:
|
||||
return "cc";
|
||||
case MFC_FOD_BAT_STATE_CV:
|
||||
return "cv";
|
||||
case MFC_FOD_BAT_STATE_FULL:
|
||||
return "full";
|
||||
}
|
||||
|
||||
return "none";
|
||||
}
|
||||
|
||||
static fod_data_t *mfc_fod_parse_data(struct device_node *np, int bat_state, unsigned int fod_size)
|
||||
{
|
||||
fod_data_t *data;
|
||||
const u32 *p;
|
||||
int len = 0, t_size = 0, ret;
|
||||
|
||||
p = of_get_property(np, get_bat_state_str(bat_state), &len);
|
||||
if (!p)
|
||||
return NULL;
|
||||
|
||||
t_size = sizeof(fod_data_t);
|
||||
data = kcalloc(fod_size, t_size, GFP_KERNEL);
|
||||
if (!data)
|
||||
return NULL;
|
||||
|
||||
if (fod_size != (len / t_size)) {
|
||||
fod_log("not match the size(%d, %d, %d)\n", fod_size, len, t_size);
|
||||
goto err_size;
|
||||
}
|
||||
|
||||
switch (t_size) {
|
||||
case sizeof(u64):
|
||||
ret = of_property_read_u64_array(np, get_bat_state_str(bat_state),
|
||||
(u64 *)data, fod_size);
|
||||
break;
|
||||
case sizeof(u32):
|
||||
ret = of_property_read_u32_array(np, get_bat_state_str(bat_state),
|
||||
(u32 *)data, fod_size);
|
||||
break;
|
||||
case sizeof(u16):
|
||||
ret = of_property_read_u16_array(np, get_bat_state_str(bat_state),
|
||||
(u16 *)data, fod_size);
|
||||
break;
|
||||
case sizeof(u8):
|
||||
ret = of_property_read_u8_array(np, get_bat_state_str(bat_state),
|
||||
(u8 *)data, fod_size);
|
||||
break;
|
||||
default:
|
||||
fod_log("invalid t size(%d)\n", t_size);
|
||||
goto err_size;
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
fod_log("%s, failed to parse data (ret = %d)\n", get_bat_state_str(bat_state), ret);
|
||||
goto err_size;
|
||||
}
|
||||
|
||||
return data;
|
||||
|
||||
err_size:
|
||||
kfree(data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int mfc_fod_parse_op_node(struct device_node *np,
|
||||
struct mfc_fod *fod, struct mfc_fod_tx *fod_tx, int op_mode, unsigned int fod_size)
|
||||
{
|
||||
struct mfc_fod_op *fod_op = &fod_tx->op[op_mode];
|
||||
unsigned int flag = 0;
|
||||
int ret = 0, i;
|
||||
|
||||
ret = of_property_read_u32(np, "flag", &flag);
|
||||
if (ret < 0) {
|
||||
pr_err("%s: failed to get flag of %s\n", __func__, np->name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (i = MFC_FOD_BAT_STATE_CC; i < MFC_FOD_BAT_STATE_MAX; i++) {
|
||||
switch ((flag >> (i * 4)) & 0xF) {
|
||||
case FOD_FLAG_ADD:
|
||||
fod_op->data[i] = mfc_fod_parse_data(np, i, fod_size);
|
||||
if (fod_op->data[i] == NULL) {
|
||||
ret = -1;
|
||||
goto err_data;
|
||||
}
|
||||
break;
|
||||
case FOD_FLAG_USE_CC:
|
||||
if (fod_op->data[MFC_FOD_BAT_STATE_CC] == NULL) {
|
||||
ret = -2;
|
||||
goto err_data;
|
||||
}
|
||||
|
||||
fod_op->data[i] = fod_op->data[MFC_FOD_BAT_STATE_CC];
|
||||
break;
|
||||
case FOD_FLAG_USE_CV:
|
||||
if (fod_op->data[MFC_FOD_BAT_STATE_CV] == NULL) {
|
||||
ret = -3;
|
||||
goto err_data;
|
||||
}
|
||||
|
||||
fod_op->data[i] = fod_op->data[MFC_FOD_BAT_STATE_CV];
|
||||
break;
|
||||
case FOD_FLAG_USE_FULL:
|
||||
if (fod_op->data[MFC_FOD_BAT_STATE_FULL] == NULL) {
|
||||
ret = -4;
|
||||
goto err_data;
|
||||
}
|
||||
|
||||
fod_op->data[i] = fod_op->data[MFC_FOD_BAT_STATE_FULL];
|
||||
break;
|
||||
case FOD_FLAG_USE_DEF_PAD:
|
||||
{
|
||||
struct mfc_fod_tx *def_tx = &fod->list[DEFAULT_TX_IDX];
|
||||
|
||||
if (def_tx->op[op_mode].data[i] == NULL) {
|
||||
ret = -5;
|
||||
goto err_data;
|
||||
}
|
||||
|
||||
fod_op->data[i] = def_tx->op[op_mode].data[i];
|
||||
}
|
||||
break;
|
||||
case FOD_FLAG_USE_DEF_OP:
|
||||
{
|
||||
struct mfc_fod_op *def_op = &fod_tx->op[DEFAULT_OP_MODE];
|
||||
|
||||
if (def_op->data[i] == NULL) {
|
||||
ret = -6;
|
||||
goto err_data;
|
||||
}
|
||||
|
||||
fod_op->data[i] = def_op->data[i];
|
||||
}
|
||||
break;
|
||||
case FOD_FLAG_NONE:
|
||||
default:
|
||||
fod_log("%s - %s is not set\n", np->name, get_bat_state_str(i));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fod_op->flag = flag;
|
||||
return 0;
|
||||
|
||||
err_data:
|
||||
for (; i >= 0; i--) {
|
||||
if (((flag >> (i * 4)) & 0xF) == FOD_FLAG_ADD)
|
||||
kfree(fod_op->data[i]);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mfc_fod_init_ext_pad(struct mfc_fod_tx *fod_tx, struct mfc_fod_tx *def_tx)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
if (fod_tx->id == DEFAULT_TX_IDX)
|
||||
return 0;
|
||||
|
||||
for (j = WPC_OP_MODE_NONE; j < WPC_OP_MODE_MAX; j++) {
|
||||
if (def_tx->op[j].flag == 0)
|
||||
continue;
|
||||
|
||||
for (i = MFC_FOD_BAT_STATE_CC; i < MFC_FOD_BAT_STATE_MAX; i++)
|
||||
fod_tx->op[j].data[i] = def_tx->op[j].data[i];
|
||||
|
||||
fod_tx->op[j].flag =
|
||||
(SET_FOD_CC(USE_DEF_PAD) | SET_FOD_CV(USE_DEF_PAD) | SET_FOD_FULL(USE_DEF_PAD));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mfc_fod_parse_tx_node(struct device_node *np, struct mfc_fod *fod, unsigned int fod_size)
|
||||
{
|
||||
struct device_node *tx_node = NULL;
|
||||
int ret = 0, tx_idx = 0;
|
||||
|
||||
for_each_child_of_node(np, tx_node) {
|
||||
struct mfc_fod_tx *fod_tx = NULL;
|
||||
struct device_node *op_node = NULL;
|
||||
|
||||
if (tx_idx >= fod->count) {
|
||||
fod_log("out of range(%d <--> %d)\n", tx_idx, fod->count);
|
||||
break;
|
||||
}
|
||||
|
||||
fod_tx = &fod->list[tx_idx++];
|
||||
if (sscanf(tx_node->name, "pad_0x%X", &fod_tx->id) < 0) {
|
||||
fod_log("failed to get tx id(%s)\n", tx_node->name);
|
||||
continue;
|
||||
}
|
||||
|
||||
mfc_fod_init_ext_pad(fod_tx, &fod->list[DEFAULT_TX_IDX]);
|
||||
|
||||
for_each_child_of_node(tx_node, op_node) {
|
||||
int op_mode;
|
||||
|
||||
op_mode = get_op_mode_by_str(op_node->name);
|
||||
if (op_mode == WPC_OP_MODE_NONE) {
|
||||
fod_log("%s, invalid op name\n", op_node->name);
|
||||
continue;
|
||||
}
|
||||
|
||||
ret = mfc_fod_parse_op_node(op_node, fod, fod_tx, op_mode, fod_size);
|
||||
if (ret < 0)
|
||||
fod_log("%s, failed to parse data(ret = %d)\n", op_node->name, ret);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mfc_fod_print_data(struct mfc_fod *fod, unsigned int fod_size)
|
||||
{
|
||||
int x, y, z, k;
|
||||
struct mfc_fod_tx *fod_tx;
|
||||
|
||||
for (x = 0; x < fod->count; x++) {
|
||||
fod_tx = &fod->list[x];
|
||||
|
||||
for (y = WPC_OP_MODE_NONE + 1; y < WPC_OP_MODE_MAX; y++) {
|
||||
|
||||
for (z = MFC_FOD_BAT_STATE_CC; z < MFC_FOD_BAT_STATE_MAX; z++) {
|
||||
char temp_buf[1024] = {0, };
|
||||
int size = 1024;
|
||||
|
||||
if (fod_tx->op[y].data[z] == NULL) {
|
||||
fod_log("PAD_0x%02X:%s:%s is null!!\n",
|
||||
fod_tx->id, sb_wrl_op_mode_str(y), get_bat_state_str(z));
|
||||
continue;
|
||||
}
|
||||
|
||||
for (k = 0; k < fod_size; k++) {
|
||||
snprintf(temp_buf + strlen(temp_buf), size, "0x%02X ", fod_tx->op[y].data[z][k]);
|
||||
size = sizeof(temp_buf) - strlen(temp_buf);
|
||||
}
|
||||
|
||||
fod_log("PAD_0x%02X:%s:%s - %s\n",
|
||||
fod_tx->id, sb_wrl_op_mode_str(y), get_bat_state_str(z), temp_buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void mfc_fod_print_ext(struct mfc_fod *fod)
|
||||
{
|
||||
char ext_buf[1024] = {0, };
|
||||
int x, ext_size = 1024;
|
||||
|
||||
for (x = 0; x < MFC_FOD_EXT_MAX; x++) {
|
||||
snprintf(ext_buf + strlen(ext_buf), ext_size, "%02d:0x%X ", x, fod->ext[x]);
|
||||
ext_size = sizeof(ext_buf) - strlen(ext_buf);
|
||||
}
|
||||
fod_log("EXT - %s\n", ext_buf);
|
||||
}
|
||||
|
||||
static int mfc_fod_parse_dt(struct device_node *np, struct mfc_fod *fod, unsigned int fod_size)
|
||||
{
|
||||
int ret = 0, i;
|
||||
|
||||
np = of_find_node_by_name(np, "fod_list");
|
||||
if (!np) {
|
||||
fod_log("fod list is null!!!!\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ret = of_property_read_u32(np, "count", &fod->count);
|
||||
if (ret < 0) {
|
||||
fod_log("count is null(ret = %d)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
fod->list = kcalloc(fod->count, sizeof(struct mfc_fod_tx), GFP_KERNEL);
|
||||
if (!fod->list) {
|
||||
fod_log("failed to alloc fod list\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ret = mfc_fod_parse_tx_node(np, fod, fod_size);
|
||||
if (ret < 0) {
|
||||
kfree(fod->list);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* parse ext */
|
||||
for (i = 0; i < MFC_FOD_EXT_MAX; i++) {
|
||||
ret = of_property_read_u32(np, get_ext_str(i), (unsigned int *)&fod->ext[i]);
|
||||
if (ret < 0)
|
||||
fod_log("%s is null(ret = %d)!!\n", get_ext_str(i), ret);
|
||||
}
|
||||
|
||||
mfc_fod_print_data(fod, fod_size);
|
||||
mfc_fod_print_ext(fod);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mfc_fod_thr_parse_dt(struct device_node *np, struct mfc_fod *fod)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = of_property_read_u32(np, "bpp_vout", &fod->bpp_vout);
|
||||
if (ret < 0)
|
||||
fod->bpp_vout = 7000;
|
||||
|
||||
ret = of_property_read_u32(np, "cc_cv_thr", &fod->cc_cv_thr);
|
||||
if (ret < 0)
|
||||
fod->cc_cv_thr = 85;
|
||||
|
||||
ret = of_property_read_u32(np, "high_swell_cc_cv_thr", &fod->high_swell_cc_cv_thr);
|
||||
if (ret < 0)
|
||||
fod->high_swell_cc_cv_thr = 70;
|
||||
|
||||
ret = of_property_read_u32(np, "vendor_id", (unsigned int *)&fod->vendor_id);
|
||||
if (ret < 0) {
|
||||
fod_log("vendor_id is null(ret = %d)!!\n", ret);
|
||||
fod->vendor_id = DEFAULT_VENDOR_ID;
|
||||
}
|
||||
|
||||
fod_log("bpp_vout = %d, cc_cv_thr = %d, high_swell_cc_cv_thr = %d, vendor_id = 0x%x\n",
|
||||
fod->bpp_vout, fod->cc_cv_thr, fod->high_swell_cc_cv_thr, fod->vendor_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct mfc_fod_tx *get_fod_tx(struct mfc_fod *fod, unsigned int tx_id)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < fod->count; i++) {
|
||||
if (fod->list[i].id == tx_id)
|
||||
return &fod->list[i];
|
||||
}
|
||||
|
||||
return &fod->list[DEFAULT_TX_IDX];
|
||||
}
|
||||
|
||||
static bool check_vendor_id_to_set_op_mode_by_vout(union mfc_fod_state *state, int vendor_id)
|
||||
{
|
||||
return (state->vendor_id == vendor_id);
|
||||
}
|
||||
|
||||
static int check_op_mode_vout(struct mfc_fod *fod, union mfc_fod_state *state)
|
||||
{
|
||||
if (!check_vendor_id_to_set_op_mode_by_vout(state, fod->vendor_id))
|
||||
return state->op_mode;
|
||||
|
||||
switch (state->op_mode) {
|
||||
case WPC_OP_MODE_EPP:
|
||||
case WPC_OP_MODE_PPDE:
|
||||
if (state->vout <= fod->bpp_vout)
|
||||
return WPC_OP_MODE_BPP;
|
||||
break;
|
||||
case WPC_OP_MODE_MPP:
|
||||
break;
|
||||
default:
|
||||
/* default op mode */
|
||||
return WPC_OP_MODE_BPP;
|
||||
}
|
||||
|
||||
return state->op_mode;
|
||||
}
|
||||
|
||||
static fod_data_t *mfc_fod_get_data(struct mfc_fod *fod)
|
||||
{
|
||||
union mfc_fod_state *fod_state = &fod->state;
|
||||
struct mfc_fod_tx *fod_tx;
|
||||
|
||||
if (fod->count <= 0)
|
||||
return NULL;
|
||||
|
||||
fod_tx = get_fod_tx(fod, fod_state->tx_id);
|
||||
fod_state->fake_op_mode = check_op_mode_vout(fod, fod_state);
|
||||
return fod_tx->op[fod_state->fake_op_mode].data[fod_state->bat_state];
|
||||
}
|
||||
|
||||
struct mfc_fod *mfc_fod_init(struct device *dev, unsigned int fod_size, mfc_set_fod cb_func)
|
||||
{
|
||||
struct mfc_fod *fod;
|
||||
int ret = 0;
|
||||
|
||||
if (IS_ERR_OR_NULL(dev) ||
|
||||
(fod_size <= 0) ||
|
||||
(fod_size > MFC_FOD_MAX_SIZE) ||
|
||||
(cb_func == NULL))
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
fod = kzalloc(sizeof(struct mfc_fod), GFP_KERNEL);
|
||||
if (!fod)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
ret = mfc_fod_parse_dt(dev->of_node, fod, fod_size);
|
||||
if (ret < 0) {
|
||||
kfree(fod);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
mfc_fod_thr_parse_dt(dev->of_node, fod);
|
||||
|
||||
mutex_init(&fod->lock);
|
||||
|
||||
fod->parent = dev;
|
||||
fod->cb_func = cb_func;
|
||||
fod->state.value = 0;
|
||||
|
||||
fod_log("DONE!!\n");
|
||||
return fod;
|
||||
}
|
||||
EXPORT_SYMBOL(mfc_fod_init);
|
||||
|
||||
int mfc_fod_init_state(struct mfc_fod *fod)
|
||||
{
|
||||
if (IS_ERR(fod))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&fod->lock);
|
||||
if (fod->state.value != 0) {
|
||||
fod->state.value = 0;
|
||||
|
||||
fod->cb_func(fod->parent, &fod->state, mfc_fod_get_data(fod));
|
||||
}
|
||||
mutex_unlock(&fod->lock);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(mfc_fod_init_state);
|
||||
|
||||
int mfc_fod_refresh(struct mfc_fod *fod)
|
||||
{
|
||||
if (IS_ERR(fod))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&fod->lock);
|
||||
if (fod->state.value != 0)
|
||||
fod->cb_func(fod->parent, &fod->state, mfc_fod_get_data(fod));
|
||||
mutex_unlock(&fod->lock);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(mfc_fod_refresh);
|
||||
|
||||
int mfc_fod_set_op_mode(struct mfc_fod *fod, int op_mode)
|
||||
{
|
||||
if (IS_ERR(fod) ||
|
||||
(op_mode < WPC_OP_MODE_NONE) ||
|
||||
(op_mode >= WPC_OP_MODE_MAX))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&fod->lock);
|
||||
switch (fod->state.op_mode) {
|
||||
case WPC_OP_MODE_EPP:
|
||||
case WPC_OP_MODE_MPP:
|
||||
case WPC_OP_MODE_PPDE:
|
||||
fod_log("prevent op mode(%d)!!\n", op_mode);
|
||||
break;
|
||||
case WPC_OP_MODE_BPP:
|
||||
case WPC_OP_MODE_NONE:
|
||||
default:
|
||||
if (fod->state.op_mode != op_mode) {
|
||||
fod->state.op_mode = op_mode;
|
||||
|
||||
fod->cb_func(fod->parent, &fod->state, mfc_fod_get_data(fod));
|
||||
}
|
||||
break;
|
||||
}
|
||||
mutex_unlock(&fod->lock);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(mfc_fod_set_op_mode);
|
||||
|
||||
int mfc_fod_set_vendor_id(struct mfc_fod *fod, int vendor_id)
|
||||
{
|
||||
if (IS_ERR(fod) ||
|
||||
(vendor_id < 0) ||
|
||||
(vendor_id > 0xFF))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&fod->lock);
|
||||
if (vendor_id != fod->state.vendor_id) {
|
||||
fod->state.vendor_id = vendor_id;
|
||||
|
||||
fod->cb_func(fod->parent, &fod->state, mfc_fod_get_data(fod));
|
||||
}
|
||||
mutex_unlock(&fod->lock);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(mfc_fod_set_vendor_id);
|
||||
|
||||
int mfc_fod_set_tx_id(struct mfc_fod *fod, int tx_id)
|
||||
{
|
||||
if (IS_ERR(fod) ||
|
||||
(tx_id < 0) || (tx_id >= 256))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&fod->lock);
|
||||
if (fod->state.tx_id != tx_id) {
|
||||
fod->state.tx_id = tx_id;
|
||||
|
||||
fod->cb_func(fod->parent, &fod->state, mfc_fod_get_data(fod));
|
||||
}
|
||||
mutex_unlock(&fod->lock);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(mfc_fod_set_tx_id);
|
||||
|
||||
static int check_bat_state(struct mfc_fod *fod)
|
||||
{
|
||||
if (fod->state.high_swell)
|
||||
return (fod->state.bat_cap > fod->high_swell_cc_cv_thr) ?
|
||||
MFC_FOD_BAT_STATE_CV : MFC_FOD_BAT_STATE_CC;
|
||||
|
||||
return (fod->state.bat_cap > fod->cc_cv_thr) ?
|
||||
MFC_FOD_BAT_STATE_CV : MFC_FOD_BAT_STATE_CC;
|
||||
}
|
||||
|
||||
static int set_bat_state(struct mfc_fod *fod, int bat_state)
|
||||
{
|
||||
switch (fod->state.bat_state) {
|
||||
case MFC_FOD_BAT_STATE_FULL:
|
||||
fod_log("prevent bat state(%d)!!\n", bat_state);
|
||||
break;
|
||||
case MFC_FOD_BAT_STATE_CC:
|
||||
case MFC_FOD_BAT_STATE_CV:
|
||||
default:
|
||||
if (fod->state.bat_state != bat_state) {
|
||||
fod->state.bat_state = bat_state;
|
||||
|
||||
fod->cb_func(fod->parent, &fod->state, mfc_fod_get_data(fod));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mfc_fod_set_bat_state(struct mfc_fod *fod, int bat_state)
|
||||
{
|
||||
if (IS_ERR(fod) ||
|
||||
(bat_state < MFC_FOD_BAT_STATE_CC) ||
|
||||
(bat_state >= MFC_FOD_BAT_STATE_MAX))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&fod->lock);
|
||||
set_bat_state(fod, bat_state);
|
||||
mutex_unlock(&fod->lock);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(mfc_fod_set_bat_state);
|
||||
|
||||
int mfc_fod_set_bat_cap(struct mfc_fod *fod, int bat_cap)
|
||||
{
|
||||
if (IS_ERR(fod) ||
|
||||
(bat_cap < 0) || (bat_cap > 100))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&fod->lock);
|
||||
if (fod->state.bat_cap != bat_cap) {
|
||||
fod->state.bat_cap = bat_cap;
|
||||
|
||||
set_bat_state(fod, check_bat_state(fod));
|
||||
}
|
||||
mutex_unlock(&fod->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(mfc_fod_set_bat_cap);
|
||||
|
||||
int mfc_fod_set_vout(struct mfc_fod *fod, int vout)
|
||||
{
|
||||
if (IS_ERR(fod) ||
|
||||
(vout <= 0))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&fod->lock);
|
||||
if (fod->state.vout != vout) {
|
||||
int new_op_mode, old_op_mode;
|
||||
|
||||
old_op_mode = check_op_mode_vout(fod, &fod->state);
|
||||
|
||||
fod->state.vout = vout;
|
||||
new_op_mode = check_op_mode_vout(fod, &fod->state);
|
||||
|
||||
if (new_op_mode != old_op_mode)
|
||||
fod->cb_func(fod->parent, &fod->state, mfc_fod_get_data(fod));
|
||||
}
|
||||
mutex_unlock(&fod->lock);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(mfc_fod_set_vout);
|
||||
|
||||
int mfc_fod_set_high_swell(struct mfc_fod *fod, bool state)
|
||||
{
|
||||
if (IS_ERR(fod))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&fod->lock);
|
||||
if (fod->state.high_swell != state) {
|
||||
fod->state.high_swell = state;
|
||||
|
||||
set_bat_state(fod, check_bat_state(fod));
|
||||
}
|
||||
mutex_unlock(&fod->lock);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(mfc_fod_set_high_swell);
|
||||
|
||||
int mfc_fod_get_state(struct mfc_fod *fod, union mfc_fod_state *state)
|
||||
{
|
||||
if (IS_ERR(fod) ||
|
||||
(state == NULL))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&fod->lock);
|
||||
state->value = fod->state.value;
|
||||
mutex_unlock(&fod->lock);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(mfc_fod_get_state);
|
||||
|
||||
int mfc_fod_get_ext(struct mfc_fod *fod, int ext_type, int *data)
|
||||
{
|
||||
if (IS_ERR(fod) ||
|
||||
(ext_type < MFC_FOD_EXT_EPP_REF_QF) ||
|
||||
(ext_type >= MFC_FOD_EXT_MAX) ||
|
||||
(data == NULL))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&fod->lock);
|
||||
*data = fod->ext[ext_type];
|
||||
mutex_unlock(&fod->lock);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(mfc_fod_get_ext);
|
108
drivers/battery/wireless/cps4038_fod.h
Executable file
108
drivers/battery/wireless/cps4038_fod.h
Executable file
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* mfc_fod.h
|
||||
* Samsung Mobile MFC FOD Header
|
||||
*
|
||||
* Copyright (C) 2023 Samsung Electronics, Inc.
|
||||
*
|
||||
*
|
||||
* 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 __MFC_FOD_H
|
||||
#define __MFC_FOD_H __FILE__
|
||||
|
||||
#include <linux/err.h>
|
||||
|
||||
struct device;
|
||||
struct mfc_fod;
|
||||
|
||||
#define MFC_FOD_MAX_SIZE 256
|
||||
|
||||
enum {
|
||||
MFC_FOD_BAT_STATE_CC = 0,
|
||||
MFC_FOD_BAT_STATE_CV,
|
||||
MFC_FOD_BAT_STATE_FULL,
|
||||
MFC_FOD_BAT_STATE_MAX
|
||||
};
|
||||
|
||||
union mfc_fod_state {
|
||||
unsigned long long value;
|
||||
|
||||
struct {
|
||||
unsigned tx_id : 8,
|
||||
vendor_id : 8,
|
||||
op_mode : 8,
|
||||
fake_op_mode : 8,
|
||||
bat_state : 8,
|
||||
bat_cap : 7,
|
||||
high_swell : 1,
|
||||
vout : 16;
|
||||
};
|
||||
};
|
||||
|
||||
typedef unsigned int fod_data_t;
|
||||
typedef int (*mfc_set_fod)(struct device *dev, union mfc_fod_state *state, fod_data_t *data);
|
||||
|
||||
enum {
|
||||
MFC_FOD_EXT_EPP_REF_QF = 0,
|
||||
MFC_FOD_EXT_EPP_REF_RF,
|
||||
|
||||
MFC_FOD_EXT_MAX
|
||||
};
|
||||
|
||||
#define MFC_FOD_DISABLED (-ESRCH)
|
||||
#if IS_ENABLED(CONFIG_WIRELESS_CHARGING)
|
||||
struct mfc_fod *mfc_fod_init(struct device *dev, unsigned int fod_size, mfc_set_fod cb_func);
|
||||
|
||||
int mfc_fod_init_state(struct mfc_fod *fod);
|
||||
int mfc_fod_refresh(struct mfc_fod *fod);
|
||||
|
||||
int mfc_fod_set_op_mode(struct mfc_fod *fod, int op_mode);
|
||||
int mfc_fod_set_vendor_id(struct mfc_fod *fod, int vendor_id);
|
||||
int mfc_fod_set_tx_id(struct mfc_fod *fod, int tx_id);
|
||||
int mfc_fod_set_bat_state(struct mfc_fod *fod, int bat_state);
|
||||
int mfc_fod_set_bat_cap(struct mfc_fod *fod, int bat_cap);
|
||||
int mfc_fod_set_vout(struct mfc_fod *fod, int vout);
|
||||
int mfc_fod_set_high_swell(struct mfc_fod *fod, bool state);
|
||||
|
||||
int mfc_fod_get_state(struct mfc_fod *fod, union mfc_fod_state *state);
|
||||
int mfc_fod_get_ext(struct mfc_fod *fod, int ext_type, int *data);
|
||||
#else
|
||||
static inline struct mfc_fod *mfc_fod_init(struct device *dev, unsigned int fod_size, mfc_set_fod cb_func)
|
||||
{ return ERR_PTR(MFC_FOD_DISABLED); }
|
||||
|
||||
static inline int mfc_fod_init_state(struct mfc_fod *fod)
|
||||
{ return MFC_FOD_DISABLED; }
|
||||
static inline int mfc_fod_refresh(struct mfc_fod *fod)
|
||||
{ return MFC_FOD_DISABLED; }
|
||||
|
||||
static inline int mfc_fod_set_op_mode(struct mfc_fod *fod, int op_mode)
|
||||
{ return MFC_FOD_DISABLED; }
|
||||
static inline int mfc_fod_set_vendor_id(struct mfc_fod *fod, int vendor_id)
|
||||
{ return MFC_FOD_DISABLED; }
|
||||
static inline int mfc_fod_set_tx_id(struct mfc_fod *fod, int tx_id)
|
||||
{ return MFC_FOD_DISABLED; }
|
||||
static inline int mfc_fod_set_bat_state(struct mfc_fod *fod, int bat_state)
|
||||
{ return MFC_FOD_DISABLED; }
|
||||
static inline int mfc_fod_set_bat_cap(struct mfc_fod *fod, int bat_cap)
|
||||
{ return MFC_FOD_DISABLED; }
|
||||
static inline int mfc_fod_set_vout(struct mfc_fod *fod, int vout)
|
||||
{ return MFC_FOD_DISABLED; }
|
||||
static inline int mfc_fod_set_high_swell(struct mfc_fod *fod, bool state)
|
||||
{ return MFC_FOD_DISABLED; }
|
||||
|
||||
static inline int mfc_fod_get_state(struct mfc_fod *fod, union mfc_fod_state *state)
|
||||
{ return MFC_FOD_DISABLED; }
|
||||
static inline int mfc_fod_get_ext(struct mfc_fod *fod, int ext_type, int *data)
|
||||
{ return MFC_FOD_DISABLED; }
|
||||
#endif
|
||||
|
||||
#endif /* __MFC_FOD_H */
|
Loading…
Reference in New Issue
Block a user