battery: import sm5451_charger driver from F926B
Signed-off-by: Nahuel Gómez <nahuelgomez329@gmail.com>
This commit is contained in:
parent
cb6a5e60da
commit
7fb3935edb
6 changed files with 3836 additions and 0 deletions
8
drivers/battery/charger/sm5451_charger/Kconfig
Normal file
8
drivers/battery/charger/sm5451_charger/Kconfig
Normal 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.
|
4
drivers/battery/charger/sm5451_charger/Makefile
Normal file
4
drivers/battery/charger/sm5451_charger/Makefile
Normal 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
|
1757
drivers/battery/charger/sm5451_charger/sm5451_charger.c
Normal file
1757
drivers/battery/charger/sm5451_charger/sm5451_charger.c
Normal file
File diff suppressed because it is too large
Load diff
188
drivers/battery/charger/sm5451_charger/sm5451_charger.h
Normal file
188
drivers/battery/charger/sm5451_charger/sm5451_charger.h
Normal file
|
@ -0,0 +1,188 @@
|
|||
/*
|
||||
* 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
|
||||
|
||||
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,
|
||||
};
|
||||
|
||||
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,
|
||||
};
|
||||
|
||||
struct sm5451_platform_data {
|
||||
u8 rev_id;
|
||||
int irq_gpio;
|
||||
u32 pps_lr;
|
||||
u32 rpcm;
|
||||
|
||||
struct {
|
||||
u32 chg_float_voltage;
|
||||
char *sec_dc_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;
|
||||
int ps_type;
|
||||
|
||||
struct mutex i2c_lock;
|
||||
struct mutex pd_lock;
|
||||
struct wakeup_source *chg_ws;
|
||||
|
||||
int irq;
|
||||
int cable_online;
|
||||
bool vbus_in;
|
||||
bool rev_boost;
|
||||
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__ */
|
1658
drivers/battery/charger/sm5451_charger/sm5451_direct_charger.c
Normal file
1658
drivers/battery/charger/sm5451_charger/sm5451_direct_charger.c
Normal file
File diff suppressed because it is too large
Load diff
221
drivers/battery/charger/sm5451_charger/sm5451_direct_charger.h
Normal file
221
drivers/battery/charger/sm5451_charger/sm5451_direct_charger.h
Normal file
|
@ -0,0 +1,221 @@
|
|||
|
||||
/*
|
||||
* sm5451_direct_charger.h - Direct charging module for Silicon Mitus ICs
|
||||
*
|
||||
* Copyright (C) 2020 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 PPS_V_STEP 20
|
||||
#define PPS_C_STEP 50
|
||||
#define WPC_V_STEP 100
|
||||
#define WPC_C_STEP 200
|
||||
|
||||
#define PRE_CC_ST_IBUS_OFFSET 150
|
||||
#define CC_ST_IBUS_OFFSET 100
|
||||
|
||||
#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_IBATREG = (0x1 << 5),
|
||||
LOOP_VBATREG = (0x1 << 3),
|
||||
LOOP_THEMREG = (0x1 << 1),
|
||||
LOOP_INACTIVE = (0x0),
|
||||
};
|
||||
|
||||
enum sm_dc_work_delay_type {
|
||||
DELAY_NONE = 0,
|
||||
DELAY_PPS_UPDATE = 250,
|
||||
DELAY_WPC_UPDATE = 1000,
|
||||
DELAY_ADC_UPDATE = 1100,
|
||||
DELAY_RETRY = 2000,
|
||||
DELAY_CHG_LOOP = 7500,
|
||||
};
|
||||
|
||||
enum sm_dc_power_supply_type {
|
||||
SM_DC_POWER_SUPPLY_PD = 0x0,
|
||||
SM_DC_POWER_SUPPLY_WPC = 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,
|
||||
};
|
||||
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_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;
|
||||
};
|
||||
|
||||
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 (*check_sw_ocp)(struct i2c_client *i2c);
|
||||
};
|
||||
|
||||
struct sm_dc_info {
|
||||
const char *name;
|
||||
struct i2c_client *i2c;
|
||||
struct mutex st_lock;
|
||||
const struct sm_dc_ops *ops;
|
||||
|
||||
/* 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 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;
|
||||
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 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 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_wpc_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, struct sm_dc_power_source_info *ta);
|
||||
extern int sm_dc_stop_charging(struct sm_dc_info *sm_dc);
|
||||
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__ */
|
Loading…
Reference in a new issue