Revert "battery: nuke sm5451_charger driver from a53x"

This reverts commit cb6a5e60da.
This commit is contained in:
Ksawlii 2025-01-18 22:11:40 +01:00
parent 193cce5a06
commit 4d79b3410c
7 changed files with 4834 additions and 0 deletions

View file

@ -0,0 +1,8 @@
config CHARGER_SM5451
tristate "SM5451 direct charger support"
depends on I2C
help
Say Y here to enable support for the SM5451 direct charger.
SM5451 is a direct charging IC.
SM5451 is dependent on I2C
so it needs to be defined.

View file

@ -0,0 +1,4 @@
obj-$(CONFIG_CHARGER_SM5451) += sm5451-charger.o
sm5451-charger-$(CONFIG_CHARGER_SM5451) += sm5451_charger.o sm5451_direct_charger.o
ccflags-y := -Wformat

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,13 @@
&hsi2c_5 {
status = "okay";
sm5451_charger: sm5451@63 {
compatible = "siliconmitus,sm5451";
reg = <0x63>;
};
};
/* /home/dpi/qb5_8814/workspace/P4_1716/android/kernel/kmodule/battery/suwon/charger/sm5451/sm5451_charger.a53x.dtsi */
&sm5451_charger {
sm5451,freq_byp = <0x1>; /* 375kHz */
};

View file

@ -0,0 +1,222 @@
/*
* sm5451_charger.h - SM5451 Charger device driver for SAMSUNG platform
*
* Copyright (C) 2020 SiliconMitus Co.Ltd
*
* 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 "sm5451_direct_charger.h"
#ifndef __SM5451_CHARGER_H__
#define __SM5451_CHARGER_H__
#define SM5451_TA_MIN_CURRENT 1000
#define SM5451_CV_OFFSET 0
#define SM5451_CI_OFFSET 300
#define SM5451_SIOP_LEV1 1100
#define SM5451_SIOP_LEV2 1700
enum SM5451_flag1_desc {
SM5451_FLAG1_VBUSPD = 1 << 5,
SM5451_FLAG1_VDSQRB = 1 << 4,
SM5451_FLAG1_VBUSOVP = 1 << 3,
SM5451_FLAG1_IBUSOCP = 1 << 2,
SM5451_FLAG1_CHGON = 1 << 1,
SM5451_FLAG1_IBUSUCP = 1 << 0,
};
enum SM5451_flag2_desc {
SM5451_FLAG2_VBATOVP = 1 << 7,
SM5451_FLAG2_IBATOCP = 1 << 6,
SM5451_FLAG2_VBATREG = 1 << 5,
SM5451_FLAG2_IBATREG = 1 << 4,
SM5451_FLAG2_TSD = 1 << 3,
SM5451_FLAG2_RLTVUVP = 1 << 2,
SM5451_FLAG2_RLTVOVP = 1 << 1,
SM5451_FLAG2_CNSHTP = 1 << 0,
};
enum SM5451_flag3_desc {
SM5451_FLAG3_VBUSPOK = 1 << 7,
SM5451_FLAG3_VOUTPOK = 1 << 6,
SM5451_FLAG3_WTDTMR = 1 << 5,
SM5451_FLAG3_VBUSUVLO = 1 << 3,
SM5451_FLAG3_CHGONTMR = 1 << 2,
SM5451_FLAG3_ADCDONE = 1 << 1,
SM5451_FLAG3_CFLYSHTP = 1 << 0,
};
enum SM5451_flag4_desc {
SM5451_FLAG4_IBUSOCP_RVS = 1 << 5,
SM5451_FLAG4_RVSRDY = 1 << 4,
SM5451_FLAG4_THEMP = 1 << 3,
SM5451_FLAG4_IBUSREG = 1 << 2,
SM5451_FLAG4_TOPOFF = 1 << 1,
SM5451_FLAG4_DONE = 1 << 0,
};
enum SM5451_reg_addr {
SM5451_REG_CNTL1 = 0x00,
SM5451_REG_CNTL2 = 0x01,
SM5451_REG_CNTL3 = 0x02,
SM5451_REG_DEVICE_ID = 0x03,
SM5451_REG_CNTL4 = 0x05,
SM5451_REG_VBUSOVP = 0x06,
SM5451_REG_IBUS_PROT = 0x07,
SM5451_REG_VBAT_OVP = 0x08,
SM5451_REG_IBAT_OCP = 0x09,
SM5451_REG_REG1 = 0x0A,
SM5451_REG_FLAG1 = 0x0B,
SM5451_REG_FLAGMSK1 = 0x0C,
SM5451_REG_FLAG2 = 0x0D,
SM5451_REG_FLAGMSK2 = 0x0E,
SM5451_REG_FLAG3 = 0x0F,
SM5451_REG_FLAGMSK3 = 0x10,
SM5451_REG_ADC_CNTL = 0x11,
SM5451_REG_VBUS_ADC_H = 0x12,
SM5451_REG_VBUS_ADC_L = 0x13,
SM5451_REG_IBUS_ADC_H = 0x14,
SM5451_REG_IBUS_ADC_L = 0x15,
SM5451_REG_VBAT_ADC_H = 0x16,
SM5451_REG_VBAT_ADC_L = 0x17,
SM5451_REG_IBAT_ADC_H = 0x18,
SM5451_REG_IBAT_ADC_L = 0x19,
SM5451_REG_TDIE_ADC = 0x1A,
SM5451_REG_THEM = 0x60,
SM5451_REG_CNTL5 = 0x61,
SM5451_REG_TOPOFF = 0x62,
SM5451_REG_FLAG4 = 0x63,
SM5451_REG_FLAGMSK4 = 0x64,
SM5451_REG_THEM_ADC_H = 0x65,
SM5451_REG_THEM_ADC_L = 0x66,
SM5451_REG_IBATOCP_DG = 0x92,
SM5451_REG_VDSQRB_DG = 0x95,
SM5451_REG_PRECHG_MODE = 0xA0,
SM5451_REG_CTRL_STM_0 = 0xBA,
SM5451_REG_CTRL_STM_1 = 0xBB,
SM5451_REG_CTRL_STM_2 = 0xBC,
SM5451_REG_CTRL_STM_3 = 0xBD,
SM5451_REG_CTRL_STM_5 = 0xBF,
};
enum SM5451_vbatovp_offset {
SM5451_VBATOVP_50 = 0x0,
SM5451_VBATOVP_100 = 0x1,
SM5451_VBATOVP_150 = 0x2,
SM5451_VBATOVP_200 = 0x3,
};
enum SM5451_ibatocp_offset {
SM5451_IBATOCP_200 = 0x0,
SM5451_IBATOCP_300 = 0x1,
SM5451_IBATOCP_400 = 0x2,
SM5451_IBATOCP_500 = 0x3,
};
enum SM5451_ibusocp_offset {
SM5451_IBUSOCP_100 = 0x0,
SM5451_IBUSOCP_200 = 0x1,
SM5451_IBUSOCP_300 = 0x2,
SM5451_IBUSOCP_400 = 0x3,
};
enum SM5451_adc_channel {
SM5451_ADC_THEM = 0x0,
SM5451_ADC_TDIE,
SM5451_ADC_VBUS,
SM5451_ADC_IBUS,
SM5451_ADC_VBAT,
SM5451_ADC_IBAT,
};
enum SM5451_wdt_tmr {
WDT_TIMER_S_0P5 = 0x0,
WDT_TIMER_S_1 = 0x1,
WDT_TIMER_S_2 = 0x2,
WDT_TIMER_S_5 = 0x3,
WDT_TIMER_S_10 = 0x4,
WDT_TIMER_S_20 = 0x5,
WDT_TIMER_S_40 = 0x6,
WDT_TIMER_S_80 = 0x7,
};
enum SM5451_op_mode {
OP_MODE_INIT = 0x0,
OP_MODE_FW_BYPASS = 0x1,
OP_MODE_FW_BOOST = 0x2,
OP_MODE_REV_BYPASS = 0x3,
OP_MODE_REV_BOOST = 0x4,
};
enum sm5451_chip_id {
SM5451_ALONE = 0x0,
SM5451_MAIN = 0x1,
SM5451_SUB = 0x3,
};
enum SM5451_freq {
SM5451_FREQ_200KHZ = 0x0,
SM5451_FREQ_375KHZ = 0x1,
SM5451_FREQ_500KHZ = 0x2,
SM5451_FREQ_750KHZ = 0x3,
SM5451_FREQ_1000KHZ = 0x4,
SM5451_FREQ_1250KHZ = 0x5,
SM5451_FREQ_1500KHZ = 0x6,
};
struct sm5451_platform_data {
u8 rev_id;
int irq_gpio;
u32 r_ttl;
u32 pps_lr;
u32 rpcm;
u32 freq;
u32 freq_byp;
u32 freq_siop[2];
u32 topoff;
u32 x2bat_mode;
u32 en_vbatreg;
struct {
u32 chg_float_voltage;
char *sec_dc_name;
char *fuelgauge_name;
} battery;
};
struct sm5451_charger {
struct device *dev;
struct i2c_client *i2c;
struct sm5451_platform_data *pdata;
struct power_supply *psy_chg;
struct sm_dc_info *pps_dc;
struct sm_dc_info *x2bat_dc;
int chip_id;
struct mutex i2c_lock;
struct mutex pd_lock;
struct wakeup_source *chg_ws;
int irq;
int cable_online;
bool vbus_in;
bool rev_boost;
u8 force_adc_on;
u32 max_vbat;
u32 target_vbat;
u32 target_ibus;
u32 target_ibat;
bool wdt_disable;
/* debug */
struct dentry *debug_root;
u32 debug_address;
int addr;
int size;
};
#endif /* __SM5451_CHARGER_H__ */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,241 @@
/*
* sm5451_direct_charger.h - Direct charging module for Silicon Mitus ICs
*
* Copyright (C) 2022 Silicon Mitus Co.Ltd
*
* 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/init.h>
#include <linux/version.h>
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/mutex.h>
#ifndef __SM_DC_H__
#define __SM_DC_H__
#define SM_DC_BYPASS_TA_MAX_VOL 7000
#define SM_DC_MANUAL_TA_MAX_CUR 3000
#define SM_DC_DUAL_STOP_IBUS 1500
#define SM_DC_CI_OFFSET_X2BAT 500
#define PPS_V_STEP 20
#define PPS_C_STEP 50
#define PRE_CC_ST_IBUS_OFFSET 150
#define CC_ST_IBUS_OFFSET 100
#define CV_ST_SUB_DC_OFF_IBUS 1000
#define MAX(a, b) ((a > b) ? (a):(b))
#define MIN(a, b) ((a < b) ? (a):(b))
enum sm_dc_charging_loop {
LOOP_IBUSREG = (0x1 << 7),
LOOP_IBUSREG_M = (0x1 << 6),
LOOP_IBATREG = (0x1 << 5),
LOOP_VBATREG = (0x1 << 3),
LOOP_VBATREG_S = (0x1 << 2),
LOOP_THEMREG = (0x1 << 1),
LOOP_INACTIVE = (0x0),
};
enum sm_dc_work_delay_type {
DELAY_NONE = 0,
DELAY_PPS_UPDATE = 250,
DELAY_ADC_UPDATE = 1100,
DELAY_RETRY = 2000,
DELAY_CHG_LOOP = 2500,
};
enum sm_dc_power_supply_type {
SM_DC_POWER_SUPPLY_PD = 0x0,
SM_DC_POWER_SUPPLY_2XBAT = 0x1,
};
enum sm_dc_state {
/* SEC_DIRECT_CHG_MODE_DIRECT_OFF */
SM_DC_CHG_OFF = 0x0,
SM_DC_ERR,
/* SEC_DIRECT_CHG_MODE_DIRECT_DONE */
SM_DC_EOC,
/* SEC_DIRECT_CHG_MODE_DIRECT_CHECK_VBAT */
SM_DC_CHECK_VBAT,
/* SEC_DIRECT_CHG_MODE_DIRECT_PRESET */
SM_DC_PRESET,
/* SEC_DIRECT_CHG_MODE_DIRECT_ON_ADJUST */
SM_DC_PRE_CC,
SM_DC_UPDAT_BAT,
/* SEC_DIRECT_CHG_MODE_DIRECT_ON */
SM_DC_CC,
SM_DC_CV,
SM_DC_CV_MAN,
};
enum sm_dc_err_index {
SM_DC_ERR_NONE = (0x0),
SM_DC_ERR_VBATREG = (0x1 << 0),
SM_DC_ERR_IBUSREG = (0x1 << 1),
SM_DC_ERR_TSD = (0x1 << 2),
SM_DC_ERR_VBATOVP = (0x1 << 3),
SM_DC_ERR_VOUTOVP = (0x1 << 4),
SM_DC_ERR_IBUSUCP = (0x1 << 5),
SM_DC_ERR_IBATOCP = (0x1 << 6),
SM_DC_ERR_IBUSOCP = (0x1 << 7),
SM_DC_ERR_CFLY_SHORT = (0x1 << 8),
SM_DC_ERR_REVBLK = (0x1 << 9),
SM_DC_ERR_STUP_FAIL = (0x1 << 10),
SM_DC_ERR_CN_SHORT = (0x1 << 11),
SM_DC_ERR_IBUSREG_M = (0x1 << 12),
SM_DC_ERR_VBATREG_S = (0x1 << 13),
SM_DC_ERR_VBUSUVLO = (0x1 << 14),
SM_DC_ERR_VBUSOVP = (0x1 << 15),
SM_DC_ERR_INVAL_VBAT = (0x1 << 16),
SM_DC_ERR_SEND_PD_MSG = (0x1 << 17),
SM_DC_ERR_FAIL_ADJUST = (0x1 << 18),
SM_DC_ERR_RETRY = (0x1 << 30),
SM_DC_ERR_UNKNOWN = (0x1 << 31),
};
enum sm_dc_interrupt_index {
SM_DC_INT_VBATREG = (0x1 << 0),
SM_DC_INT_WDTOFF = (0x1 << 1),
};
enum sm_dc_adc_channel {
SM_DC_ADC_THEM = 0x0,
SM_DC_ADC_DIETEMP,
SM_DC_ADC_VBAT,
SM_DC_ADC_IBAT,
SM_DC_ADC_VOUT,
SM_DC_ADC_VBUS,
SM_DC_ADC_IBUS,
};
enum sm_dc_adc_mode {
SM_DC_ADC_MODE_ONESHOT = 0x0,
SM_DC_ADC_MODE_CONTINUOUS = 0x1,
SM_DC_ADC_MODE_OFF = 0x2,
};
struct sm_dc_power_source_info {
u32 pdo_pos;
u32 v_max;
u32 c_max;
u32 p_max;
u32 v;
u32 c;
u32 retry_cnt;
};
struct sm_dc_ops {
int (*get_adc_value)(struct i2c_client *i2c, u8 adc_ch);
int (*set_adc_mode)(struct i2c_client *i2c, u8 mode);
int (*get_charging_enable)(struct i2c_client *i2c);
int (*set_charging_enable)(struct i2c_client *i2c, bool enable);
int (*set_charging_config)(struct i2c_client *i2c, u32 cv_gl, u32 ci_gl, u32 cc_gl);
u32 (*get_dc_error_status)(struct i2c_client *i2c);
int (*send_power_source_msg)(struct i2c_client *i2c, struct sm_dc_power_source_info *ta);
int (*get_apdo_max_power)(struct i2c_client *i2c, struct sm_dc_power_source_info *ta);
u32 (*get_target_ibus)(struct i2c_client *i2c);
int (*check_sw_ocp)(struct i2c_client *i2c);
};
struct sm_dc_info {
const char *name;
struct i2c_client *i2c;
struct i2c_client *i2c_sub;
struct mutex st_lock;
const struct sm_dc_ops *ops;
int chip_id;
/* for direct-charging state machine */
struct workqueue_struct *dc_wqueue;
struct delayed_work check_vbat_work;
struct delayed_work preset_dc_work;
struct delayed_work pre_cc_work;
struct delayed_work cc_work;
struct delayed_work cv_work;
struct delayed_work cv_man_work;
struct delayed_work update_bat_work;
struct delayed_work error_work;
/* for SEC-BATTERY done event process */
struct delayed_work done_event_work;
u8 state;
u32 err;
bool req_update_vbat;
bool req_update_ibus;
bool req_update_ibat;
u32 target_vbat;
u32 target_ibat;
u32 target_ibus;
struct sm_dc_power_source_info ta;
/* for state machine control */
struct {
bool pps_cl;
bool c_up;
bool c_down;
bool v_up;
bool v_down;
bool pps_vcm;
bool topoff_m;
bool topoff_s;
int v_offset;
int c_offset;
u16 prev_adc_ibus;
u16 prev_adc_vbus;
bool cc_limit;
int cc_cnt;
int cv_cnt;
u32 cv_gl;
u32 ci_gl;
u32 ci_gl_m;
u32 ci_gl_s;
u32 cc_gl;
int retry_cnt;
} wq;
struct {
u32 ta_min_current;
u32 ta_min_voltage;
u32 dc_min_vbat;
u32 dc_vbus_ovp_th;
u32 pps_lr;
u32 rpara;
u32 rsns;
u32 rpcm;
u32 r_ttl;
u32 topoff_current;
bool need_to_sw_ocp;
bool support_pd_remain;
/* sec_battery info */
u32 chg_float_voltage;
char *sec_dc_name;
} config;
};
extern struct sm_dc_info *sm_dc_create_pd_instance(const char *name, struct i2c_client *i2c);
extern struct sm_dc_info *sm_dc_create_x2bat_instance(const char *name, struct i2c_client *i2c);
extern int sm_dc_verify_configuration(struct sm_dc_info *sm_dc);
extern void sm_dc_destroy_instance(struct sm_dc_info *sm_dc);
extern int sm_dc_report_error_status(struct sm_dc_info *sm_dc, u32 err);
extern int sm_dc_report_interrupt_event(struct sm_dc_info *sm_dc, u32 interrupt);
extern int sm_dc_get_current_state(struct sm_dc_info *sm_dc);
extern int sm_dc_start_charging(struct sm_dc_info *sm_dc);
extern int sm_dc_stop_charging(struct sm_dc_info *sm_dc);
extern int sm_dc_start_manual_charging(struct sm_dc_info *sm_dc);
extern int sm_dc_set_ta_volt_by_soc(struct sm_dc_info *sm_dc, int delta_soc);
extern int sm_dc_set_target_vbat(struct sm_dc_info *sm_dc, u32 target_vbat);
extern int sm_dc_set_target_ibus(struct sm_dc_info *sm_dc, u32 target_ibus);
#endif /* __SM_DC_H__ */