--- /dev/null
+
+#include "sgm41562.h"
+#include "custom_utils.h"
+
+#undef pr_debug
+#define pr_debug printf
+
+#if defined(BOARD_L22) || defined(BOARD_FD272)
+#define I2C_BUS I2C_BUS_0
+#elif defined BOARD_U8
+#define I2C_BUS I2C_BUS_3
+#endif
+
+// static struct power_supply_desc sgm41562_power_supply_desc;
+
+enum SGM41562_PULLDOWN_PERIOD {
+ SGM41562_PN_TIMER_8S,
+ SGM41562_PN_TIMER_12S,
+ SGM41562_PN_TIMER_16S,
+ SGM41562_PN_TIMER_20S,
+ SGM41562_PN_TIMER_MAX = 4,
+};
+
+enum SGM41562_WDT_TIMER {
+ SGM41562_WDT_TIMER_DISABLE,
+ SGM41562_WDT_TIMER_40S,
+ SGM41562_WDT_TIMER_80S,
+ SGM41562_WDT_TIMER_160S,
+ SGM41562_WDT_TIMER_MAX = 4,
+};
+
+enum SGM41562_CHG_TIMER {
+ SGM41562_CHG_TIMER_3H,
+ SGM41562_CHG_TIMER_5H,
+ SGM41562_CHG_TIMER_8H,
+ SGM41562_CHG_TIMER_12H,
+ SGM41562_CHG_TIMER_MAX = 4,
+};
+
+enum SGM41562_TEMP_STATUS {
+ SGM41562_TEMP_HOT,
+ SGM41562_TEMP_WARM,
+ SGM41562_TEMP_COOL,
+ SGM41562_TEMP_COLD,
+ SGM41562_TEMP_MAX = 4,
+};
+
+enum SGM41562_EN_OPTION {
+ /* REG 01*/
+ REG_BIT_RST_DUR, //0=2S,1=4S
+ REG_BIT_EN_HIZ,
+ REG_BIT_EN_CEB, //enable charge
+ /* REG 02*/
+ REG_BIT_REG_RST,
+ REG_BIT_WD_RST,
+ /* REG 04*/
+ REG_BIT_VBAT_PRE,
+ REG_BIT_VRECH,
+ /* REG 05*/
+ REG_BIT_EN_WD_DISCHG,
+ REG_BIT_EN_TERM,
+ REG_BIT_EN_TIMER,
+ REG_BIT_TERM_TMR,
+ /* REG 06*/
+ REG_BIT_EN_NTC,
+ REG_BIT_EN_TMR2X,
+ REG_BIT_FET_DIS,
+ REG_BIT_PG_INT_CTL,
+ REG_BIT_EOC_INT_CTL,
+ REG_BIT_CHG_STATUS_INT_CTL,
+ REG_BIT_NTC_INT_CTL,
+ REG_BIT_BATOVP_INT_CTL,
+ /* REG 07*/
+ REG_BIT_EN_PCB_OTP,
+ REG_BIT_DIS_VINLOOP,
+ /* REG 08*/
+ REG_BIT_VIN_OVP_SEL,
+ //REG_BIT_IIN_LIM_ADD200,
+ /* REG 0A*/
+ REG_BIT_COLD_RESET,
+ REG_BIT_SWITCH_MODE,
+ REG_BIT_DIS_VDD,
+ REG_BIT_DIS_VINOVP,
+ REG_BIT_CC_FINE,
+ REG_BIT_DIS_INT,
+};
+
+/**********************************************************
+ *
+ * [I2C Function For Read/Write sgm41562_device]
+ *
+ *********************************************************/
+static int __sgm41562_read_byte( uint8_t reg, uint8_t *data)
+{
+ int32_t ret;
+
+ // ret = i2c_smbus_read_byte_data(sgm->client, reg);
+ // if (ret < 0) {
+ // printf("i2c read fail: can't read from reg 0x%02X\n", reg);
+ // return ret;
+ // }
+
+ custom_i2c_read_regs(0x03, reg, 1, data, 1, I2C_BUS);
+
+ // *data = (uint8_t) ret;
+
+ return 0;
+}
+
+static int __sgm41562_write_byte( int reg, uint8_t val)
+{
+ int32_t ret;
+
+ // ret = i2c_smbus_write_byte_data(sgm->client, reg, val);
+ // if (ret < 0) {
+ // printf("i2c write fail: can't write 0x%02X to reg 0x%02X: %d\n",
+ // val, reg, ret);
+ // return ret;
+ // }
+
+ custom_i2c_write_reg(0x03, reg, 1, &val, 1, I2C_BUS);
+
+ return 0;
+}
+
+static int sgm41562_read_reg( uint8_t reg, uint8_t *data)
+{
+ int ret;
+
+ // mutex_lock(&sgm->i2c_rw_lock);
+ ret = __sgm41562_read_byte( reg, data);
+ // mutex_unlock(&sgm->i2c_rw_lock);
+
+ return ret;
+}
+
+static int sgm41562_write_reg( uint8_t reg, uint8_t val)
+{
+ int ret;
+
+ // mutex_lock(&sgm->i2c_rw_lock);
+ ret = __sgm41562_write_byte(reg, val);
+ // mutex_unlock(&sgm->i2c_rw_lock);
+
+ if (ret)
+ printf("Failed: reg=%02X, ret=%d\n", reg, ret);
+
+ return ret;
+}
+
+static int sgm41562_update_bits( uint8_t reg,
+ uint8_t mask, uint8_t val)
+{
+ int ret;
+ uint8_t tmp;
+
+ // mutex_lock(&sgm->i2c_rw_lock);
+ ret = __sgm41562_read_byte(reg, &tmp);
+ if (ret) {
+ printf("Failed: reg=%02X, ret=%d\n", reg, ret);
+ goto out;
+ }
+
+ tmp &= ~mask;
+ tmp |= val & mask;
+
+ ret = __sgm41562_write_byte(reg, tmp);
+ if (ret)
+ printf("Failed: reg=%02X, ret=%d\n", reg, ret);
+
+out:
+// mutex_unlock(&sgm->i2c_rw_lock);
+ return ret;
+}
+
+static int sgm41562_set_input_volt_lim(int vindpm)
+{
+ int ret;
+ int reg_val;
+
+ if (vindpm < SGM41562_VINDPM_V_MIN_uV || vindpm > SGM41562_VINDPM_V_MAX_uV)
+ return -1;
+
+ reg_val = (vindpm-SGM41562_VINDPM_V_MIN_uV) / SGM41562_VINDPM_STEP_uV;
+ reg_val = reg_val<< 4;
+ ret = sgm41562_update_bits(SGM41562_CHRG_REG_0,
+ SGM41562_VINDPM_V_MASK, reg_val);
+ pr_debug("%s ret %d,reg_val 0x%x\n",__func__,ret,reg_val);
+ return ret;
+}
+
+static int sgm41562_get_input_volt_lim(void)
+{
+ int ret;
+ int vlim;
+ uint8_t temp;
+
+ ret = sgm41562_read_reg(SGM41562_CHRG_REG_0, &temp);
+ if (ret)
+ return ret;
+
+ vlim = temp>>4;
+ vlim = SGM41562_VINDPM_V_MIN_uV + vlim * SGM41562_VINDPM_STEP_uV;
+ return vlim;
+}
+
+static int sgm41562_set_input_curr_lim( int iindpm)
+{
+ int ret;
+ int reg_val;
+
+ if (iindpm < SGM41562_IINDPM_I_MIN_uA || iindpm > SGM41562_IINDPM_I_MAX_uA)
+ return -1;
+
+ reg_val = (iindpm-SGM41562_IINDPM_I_MIN_uA) / SGM41562_IINDPM_STEP_uA;
+ reg_val = reg_val << 3;
+ ret = sgm41562_update_bits(SGM41562_CHRG_REG_C,
+ SGM41562_IINDPM_I_MASK, reg_val);
+ pr_debug("%s ret %d,reg_val 0x%x\n",__func__,ret,reg_val);
+ return ret;
+}
+
+static int sgm41562_get_input_curr_lim(void)
+{
+ int ret;
+ uint8_t val;
+ uint32_t ilim;
+
+ ret = sgm41562_read_reg(SGM41562_CHRG_REG_C, &val);
+ if (ret)
+ return ret;
+
+ ilim = ((val & SGM41562_IINDPM_I_MASK) >> 3) * SGM41562_IINDPM_STEP_uA + SGM41562_IINDPM_I_MIN_uA;
+
+ return ilim;
+}
+
+static int sgm41562_set_pulldown_period(enum SGM41562_PULLDOWN_PERIOD time)
+{
+ int ret;
+ uint8_t reg_val;
+
+ reg_val = time << 6;
+ ret = sgm41562_update_bits(SGM41562_CHRG_REG_1,
+ SGM41562_RST_DGL, reg_val);
+
+ return ret;
+}
+
+static int sgm41562_set_vbat_uvlo(int volt)
+{
+ int ret;
+ int reg_val;
+
+ if (volt < SGM41562_VBAT_UVLO_MIN_uV ||
+ volt > SGM41562_VBAT_UVLO_MAX_uV)
+ return -1;
+
+ reg_val = (volt - SGM41562_VBAT_UVLO_MIN_uV) / SGM41562_VBAT_UVLO_STEP_uV;
+
+ ret = sgm41562_update_bits(SGM41562_CHRG_REG_1,
+ SGM41562_VBAT_UVLO_MASK, reg_val);
+ pr_debug("%s ret %d,reg_val 0x%x\n",__func__,ret,reg_val);
+ return ret;
+}
+
+static int sgm41562_set_fast_cc( int curr)
+{
+ int ret;
+ int reg_val;
+
+ if (curr < SGM41562_FAST_ICC_MIN_uA || curr > SGM41562_FAST_ICC_MAX_uA)
+ return -1;
+
+ reg_val = (curr - SGM41562_FAST_ICC_MIN_uA) / SGM41562_FAST_ICC_STEP_uA;
+
+ ret = sgm41562_update_bits(SGM41562_CHRG_REG_2,
+ SGM41562_FAST_ICC_MASK, reg_val);
+ pr_debug("%s ret %d,reg_val 0x%x\n",__func__,ret,reg_val);
+ return ret;
+}
+
+static int sgm41562_set_discharge_curr_limit(int curr)
+{
+ int ret;
+ int reg_val;
+
+ if (curr < SGM41562_DSCHG_I_MIN_uA || curr > SGM41562_DSCHG_I_MAX_uA)
+ return -1;
+
+ reg_val = (curr - SGM41562_DSCHG_I_MIN_uA) / SGM41562_DSCHG_I_STEP_uA;
+ if (0 == reg_val)
+ return -1;
+ reg_val = reg_val << 4;
+ ret = sgm41562_update_bits(SGM41562_CHRG_REG_3,
+ SGM41562_DSCHG_I_MASK, reg_val);
+ pr_debug("%s ret %d,reg_val 0x%x\n",__func__,ret,reg_val);
+ return ret;
+}
+
+static int sgm41562_get_term_curr(void)
+{
+ int ret;
+ uint8_t reg_val;
+ uint32_t curr;
+ int offset = SGM41562_TERM_I_MIN_uA;
+
+ ret = sgm41562_read_reg(SGM41562_CHRG_REG_3, ®_val);
+ if (ret)
+ return ret;
+
+ reg_val &= SGM41562_TERM_I_MASK;
+ curr = reg_val * SGM41562_TERM_I_STEP_uA + offset;
+ return curr;
+}
+
+static int sgm41562_set_term_curr( int term_curr)
+{
+ int ret = 0;
+ int reg_val;
+ int offset = SGM41562_TERM_I_MIN_uA;
+
+ if (term_curr < SGM41562_TERM_I_MIN_uA)
+ term_curr = SGM41562_TERM_I_MIN_uA;
+ else if (term_curr > SGM41562_TERM_I_MAX_uA)
+ term_curr = SGM41562_TERM_I_MAX_uA;
+
+ reg_val = (term_curr - offset) / SGM41562_TERM_I_STEP_uA;
+
+ ret = sgm41562_update_bits(SGM41562_CHRG_REG_3,
+ SGM41562_TERM_I_MASK, reg_val);
+
+ pr_debug("%s ret %d,reg_val 0x%x\n",__func__,ret,reg_val);
+ return ret;
+}
+
+static int sgm41562_set_chrg_volt( int chrg_volt)
+{
+ int ret;
+ int reg_val;
+
+ if (chrg_volt < SGM41562_VBAT_REG_MIN_uV)
+ chrg_volt = SGM41562_VBAT_REG_MIN_uV;
+ else if (chrg_volt > SGM41562_VBAT_REG_MAX_uV)
+ chrg_volt = SGM41562_VBAT_REG_MAX_uV;
+
+ reg_val = (chrg_volt - SGM41562_VBAT_REG_MIN_uV) / SGM41562_VBAT_REG_STEP_uV;
+ reg_val = reg_val << 1;
+ ret = sgm41562_update_bits(SGM41562_CHRG_REG_4,
+ SGM41562_VBAT_REG_MASK, reg_val);
+ pr_debug("%s ret %d,reg_val 0x%x\n",__func__,ret,reg_val);
+
+ return ret;
+}
+
+static int sgm41562_get_chrg_volt(void)
+{
+ int ret;
+ uint8_t vreg_val;
+ uint32_t chrg_volt;
+
+ ret = sgm41562_read_reg(SGM41562_CHRG_REG_4, &vreg_val);
+ if (ret)
+ return ret;
+
+ vreg_val = vreg_val >> 1;
+ chrg_volt = vreg_val*SGM41562_VBAT_REG_STEP_uV + SGM41562_VBAT_REG_MIN_uV;
+
+ return chrg_volt;
+}
+
+static int sgm41562_set_watchdog_timer( enum SGM41562_WDT_TIMER time)
+{
+ int ret;
+ uint8_t reg_val;
+
+ reg_val = time << 5;
+ ret = sgm41562_update_bits(SGM41562_CHRG_REG_5,
+ SGM41562_WD_TIMER_MASK, reg_val);
+
+ return ret;
+}
+
+static int sgm41562_set_chg_timer( enum SGM41562_CHG_TIMER time)
+{
+ int ret;
+ uint8_t reg_val;
+
+ reg_val = time<<1;
+ ret = sgm41562_update_bits(SGM41562_CHRG_REG_5,
+ SGM41562_CHG_TIMER_MASK, reg_val);
+
+ return ret;
+}
+
+static int sgm41562_set_vsys_volt( int volt)
+{
+ int ret;
+ int reg_val;
+
+ if (volt < SGM41562_VSYS_MIN_uV)
+ volt = SGM41562_VSYS_MIN_uV;
+ else if (volt > SGM41562_VSYS_MAX_uV)
+ volt = SGM41562_VSYS_MAX_uV;
+
+ reg_val = (volt - SGM41562_VSYS_MIN_uV) / SGM41562_VSYS_STEP_uV;
+
+ ret = sgm41562_update_bits(SGM41562_CHRG_REG_7,
+ SGM41562_VSYS_REG_MASK, reg_val);
+ pr_debug("%s ret %d,reg_val 0x%x\n",__func__,ret,reg_val);
+
+ return ret;
+}
+
+static int sgm41562_ctrl_setting(enum SGM41562_EN_OPTION options,bool en)
+{
+ int ret = 0;
+ int mask = 0;
+ int reg_addr = 0;
+
+ switch (options)
+ {
+ case REG_BIT_RST_DUR: //0=2S,1=4S
+ reg_addr = SGM41562_CHRG_REG_1;
+ mask = SGM41562_RST_DUR;
+ break;
+ case REG_BIT_EN_HIZ:
+ reg_addr = SGM41562_CHRG_REG_1;
+ mask = SGM41562_HIZ_EN;
+ break;
+ case REG_BIT_EN_CEB: //enable charge
+ reg_addr = SGM41562_CHRG_REG_1;
+ mask = SGM41562_EN_CEB;
+ break;
+ case REG_BIT_REG_RST:
+ reg_addr = SGM41562_CHRG_REG_2;
+ mask = SGM41562_REG_RST;
+ break;
+ case REG_BIT_WD_RST:
+ reg_addr = SGM41562_CHRG_REG_C;
+ mask = SGM41562_WD_RST;
+ break;
+ case REG_BIT_VBAT_PRE:
+ reg_addr = SGM41562_CHRG_REG_C;
+ mask = SGM41562_VBAT_PRE_THRE_uV;
+ break;
+ case REG_BIT_VRECH:
+ reg_addr = SGM41562_CHRG_REG_4;
+ mask = SGM41562_VRECH_THRE_uV;
+ break;
+ case REG_BIT_EN_WD_DISCHG:
+ reg_addr = SGM41562_CHRG_REG_5;
+ mask = SGM41562_EN_WD_DISCHG;
+ break;
+ case REG_BIT_EN_TERM:
+ reg_addr = SGM41562_CHRG_REG_5;
+ mask = SGM41562_EN_TERM;
+ break;
+ case REG_BIT_EN_TIMER:
+ reg_addr = SGM41562_CHRG_REG_5;
+ mask = SGM41562_EN_SATETY_TIMER;
+ break;
+ case REG_BIT_TERM_TMR:
+ reg_addr = SGM41562_CHRG_REG_5;
+ mask = SGM41562_EN_TERM_TIMER;
+ break;
+ case REG_BIT_EN_NTC:
+ reg_addr = SGM41562_CHRG_REG_6;
+ mask = SGM41562_EN_NTC;
+ break;
+ case REG_BIT_EN_TMR2X:
+ reg_addr = SGM41562_CHRG_REG_6;
+ mask = SGM41562_EN_TMR2X;
+ break;
+ case REG_BIT_FET_DIS:
+ reg_addr = SGM41562_CHRG_REG_6;
+ mask = SGM41562_FET_DIS;
+ break;
+ case REG_BIT_PG_INT_CTL:
+ reg_addr = SGM41562_CHRG_REG_6;
+ mask = SGM41562_PG_INT_CTL;
+ break;
+ case REG_BIT_EOC_INT_CTL:
+ reg_addr = SGM41562_CHRG_REG_6;
+ mask = SGM41562_EOC_INT_CTL;
+ break;
+ case REG_BIT_CHG_STATUS_INT_CTL:
+ reg_addr = SGM41562_CHRG_REG_6;
+ mask = SGM41562_CHG_STATUS_INT_CTL;
+ break;
+ case REG_BIT_NTC_INT_CTL:
+ reg_addr = SGM41562_CHRG_REG_6;
+ mask = SGM41562_NTC_INT_CTL;
+ break;
+ case REG_BIT_BATOVP_INT_CTL:
+ reg_addr = SGM41562_CHRG_REG_6;
+ mask = SGM41562_BATOVP_INT_CTL;
+ break;
+ case REG_BIT_EN_PCB_OTP:
+ reg_addr = SGM41562_CHRG_REG_8;
+ mask = SGM41562_DIS_PCB_OTP;
+ break;
+ case REG_BIT_DIS_VINLOOP:
+ reg_addr = SGM41562_CHRG_REG_7;
+ mask = SGM41562_DIS_VINLOOP;
+ break;
+ case REG_BIT_VIN_OVP_SEL:
+ reg_addr = SGM41562_CHRG_REG_8;
+ mask = SGM41562_VIN_OVP_SEL;
+ break;
+// case REG_BIT_IIN_LIM_ADD200:
+// reg_addr = SGM41562_CHRG_REG_8;
+// mask = SGM41562_IIN_LIM_ADD200;
+ break;
+ case REG_BIT_COLD_RESET:
+ reg_addr = SGM41562_CHRG_REG_A;
+ mask = SGM41562_COLD_RESET;
+ break;
+ case REG_BIT_SWITCH_MODE:
+ reg_addr = SGM41562_CHRG_REG_A;
+ mask = SGM41562_SWITCH_MODE;
+ break;
+ case REG_BIT_DIS_VDD:
+ reg_addr = SGM41562_CHRG_REG_A;
+ mask = SGM41562_DIS_VDD;
+ break;
+ case REG_BIT_DIS_VINOVP:
+ reg_addr = SGM41562_CHRG_REG_A;
+ mask = SGM41562_DIS_VINOVP;
+ break;
+ case REG_BIT_CC_FINE:
+ reg_addr = SGM41562_CHRG_REG_A;
+ mask = SGM41562_CC_FINE;
+ break;
+ case REG_BIT_DIS_INT:
+ reg_addr = SGM41562_CHRG_REG_C;
+ mask = SGM41562_DIS_INT;
+ break;
+
+ }
+ if (en)
+ ret = sgm41562_update_bits(reg_addr,mask,mask);
+ else
+ ret = sgm41562_update_bits(reg_addr,mask,0);
+ if (ret < 0) {
+ printf("[%s] SET fail\n", __func__);
+ return ret;
+ }
+ printf("[%s] ret=0x%x\n", __func__,ret);
+
+ return ret;
+}
+
+
+static int sgm41562_get_state(
+ struct sgm41562_state *state)
+{
+ uint8_t chrg_stat;
+ uint8_t fault;
+ int ret;
+
+ ret = sgm41562_read_reg( SGM41562_CHRG_REG_8, &chrg_stat);
+ if (ret){
+ ret = sgm41562_read_reg( SGM41562_CHRG_REG_8, &chrg_stat);
+ if (ret){
+ printf("%s read SGM41562_CHRG_REG_8 fail\n",__func__);
+ return ret;
+ }
+ }
+
+ state->chrg_stat = chrg_stat & SGM41562_CHG_STAT_MASK;
+ state->pg_stat = !!(chrg_stat & SGM41562_PG_STAT);
+ state->therm_stat = !!(chrg_stat & SGM41562_THERM_STAT);
+ state->ppm_stat = !!(chrg_stat & SGM41562_PPM_STAT);
+
+ printf("%s chrg_stat =%d,pg_stat =%d ppm_stat = %d\n",
+ __func__,chrg_stat,state->pg_stat,state->ppm_stat);
+
+ ret = sgm41562_read_reg( SGM41562_CHRG_REG_9, &fault);
+ if (ret){
+ printf("%s read SGM41562_CHRG_REG_9 fail\n",__func__);
+ return ret;
+ }
+ state->ntc_fault_0 = !!(chrg_stat & SGM41562_NTC_COOL_FAULT);
+ state->ntc_fault_1 = !!(chrg_stat & SGM41562_NTC_HOT_FAULT);
+ state->bat_fault = !!(chrg_stat & SGM41562_BAT_FAULT);
+
+ if (state->ntc_fault_0)
+ state->health = SGM41562_TEMP_COLD;
+ else if (state->ntc_fault_1)
+ state->health = SGM41562_TEMP_HOT;
+ else
+ state->health = SGM41562_TEMP_WARM;
+ return 0;
+}
+
+// static int sgm41562_property_is_writeable(enum power_supply_property prop)
+// {
+// switch (prop) {
+// // case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
+// // case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
+// // case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
+// // case POWER_SUPPLY_PROP_PRECHARGE_CURRENT:
+// // case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT:
+// // case POWER_SUPPLY_PROP_STATUS:
+// // return true;
+// default:
+// return false;
+// }
+// }
+
+// static int sgm41562_charger_set_property(
+// const union power_supply_propval *val)
+// {
+// void = power_supply_get_drvdata(psy);
+// int ret = -1;
+
+// switch (prop) {
+// case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
+// ret = sgm41562_set_input_curr_lim( val->intval);
+// break;
+// case POWER_SUPPLY_PROP_STATUS:
+// if (val->intval)
+// ret = sgm41562_ctrl_setting(REG_BIT_EN_CEB,1);
+// else
+// ret = sgm41562_ctrl_setting(REG_BIT_EN_CEB,0);
+// break;
+// /* case POWER_SUPPLY_PROP_INPUT_VOLTAGE_LIMIT:
+// ret = sgm41562_set_input_volt_lim( val->intval);
+// break;*/
+// default:
+// return -1;
+// }
+
+// return ret;
+// }
+
+// static int sgm41562_charger_get_property(struct power_supply *psy,
+// enum power_supply_property psp,
+// union power_supply_propval *val)
+// {
+// void = power_supply_get_drvdata(psy);
+// struct sgm41562_state state;
+// int ret = 0;
+
+// mutex_lock(&sgm->lock);
+// //ret = sgm41562_get_state( &state);
+// state = sgm->state;
+// mutex_unlock(&sgm->lock);
+// if (ret)
+// return ret;
+
+// switch (psp) {
+// case POWER_SUPPLY_PROP_STATUS:
+// if (!state.pg_stat)
+// val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
+// else if (state.pg_stat && !state.chrg_stat)
+// val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
+// else if (state.chrg_stat == SGM41562_TERM_CHRG)
+// val->intval = POWER_SUPPLY_STATUS_FULL;
+// else
+// val->intval = POWER_SUPPLY_STATUS_CHARGING;
+// break;
+// case POWER_SUPPLY_PROP_CHARGE_TYPE:
+// switch (state.chrg_stat) {
+// case SGM41562_PRECHRG:
+// val->intval = POWER_SUPPLY_CHARGE_TYPE_TRICKLE;
+// break;
+// case SGM41562_FAST_CHRG:
+// val->intval = POWER_SUPPLY_CHARGE_TYPE_FAST;
+// break;
+// case SGM41562_TERM_CHRG:
+// val->intval = POWER_SUPPLY_CHARGE_TYPE_TRICKLE;
+// break;
+// case SGM41562_NOT_CHRGING:
+// val->intval = POWER_SUPPLY_CHARGE_TYPE_NONE;
+// break;
+// default:
+// val->intval = POWER_SUPPLY_CHARGE_TYPE_UNKNOWN;
+// }
+// break;
+// case POWER_SUPPLY_PROP_MANUFACTURER:
+// val->strval = SGM41562_MANUFACTURER;
+// break;
+
+// case POWER_SUPPLY_PROP_MODEL_NAME:
+// val->strval = SGM41562_NAME;
+// break;
+
+// case POWER_SUPPLY_PROP_ONLINE:
+// val->intval = state.pg_stat;
+// break;
+// case POWER_SUPPLY_PROP_PRESENT:
+// val->intval = state.pg_stat;
+// break;
+// case POWER_SUPPLY_PROP_TYPE:
+// val->intval = sgm41562_power_supply_desc.type;
+// break;
+// case POWER_SUPPLY_PROP_USB_TYPE:
+// break;
+
+// case POWER_SUPPLY_PROP_HEALTH:
+// if (state.bat_fault)
+// val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
+// else
+// val->intval = POWER_SUPPLY_HEALTH_GOOD;
+
+// switch (state.health) {
+// case SGM41562_TEMP_HOT:
+// val->intval = POWER_SUPPLY_HEALTH_HOT;
+// break;
+// case SGM41562_TEMP_WARM:
+// val->intval = POWER_SUPPLY_HEALTH_WARM;
+// break;
+// case SGM41562_TEMP_COOL:
+// val->intval = POWER_SUPPLY_HEALTH_COOL;
+// break;
+// case SGM41562_TEMP_COLD:
+// val->intval = POWER_SUPPLY_HEALTH_COLD;
+// break;
+// }
+// break;
+
+// case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+// //val->intval = state.vbus_adc;
+// break;
+
+// case POWER_SUPPLY_PROP_CURRENT_NOW:
+// //val->intval = state.ibus_adc;
+// break;
+
+// /* case POWER_SUPPLY_PROP_INPUT_VOLTAGE_LIMIT:
+// ret = sgm41562_get_input_volt_lim(sgm);
+// if (ret < 0)
+// return ret;
+
+// val->intval = ret;
+// break;*/
+
+// case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
+// ret = sgm41562_get_input_curr_lim();
+// if (ret < 0)
+// return ret;
+
+// val->intval = ret;
+// break;
+
+// default:
+// return -1;
+// }
+
+// return ret;
+// }
+
+#if 0
+static bool sgm41562_state_changed(
+ struct sgm41562_state *new_state)
+{
+ struct sgm41562_state old_state;
+
+ mutex_lock(&sgm->lock);
+ old_state = sgm->state;
+ mutex_unlock(&sgm->lock);
+
+ return (old_state.chrg_status != new_state->chrg_status ||
+ old_state.chrg_fault != new_state->chrg_fault ||
+ old_state.online != new_state->online ||
+ old_state.health != new_state->health ||
+ old_state.chrg_type != new_state->chrg_type
+ );
+}
+#endif
+static void sgm41562_dump_register(void)
+{
+ int i = 0;
+ uint8_t reg = 0;
+
+ for(i=0; i<=SGM41562_CHRG_REG_D; i++) {
+ sgm41562_read_reg( i, ®);
+ printf("%s REG%x %X\n", __func__, i, reg);
+ }
+}
+
+// static void charger_monitor_work_func(struct work_struct *work)
+// {
+// int ret = 0;
+
+// struct delayed_work *charge_monitor_work = NULL;
+// struct sgm41562_state state;
+
+// charge_monitor_work = container_of(work, struct delayed_work, work);
+// if(charge_monitor_work == NULL) {
+// printf("Cann't get charge_monitor_work\n");
+// return ;
+// }
+// sgm = container_of(charge_monitor_work, struct sgm41562_device, charge_monitor_work);
+// if(sgm == NULL) {
+// printf("Cann't get sgm \n");
+// return ;
+// }
+
+// ret = sgm41562_get_state( &state);
+// mutex_lock(&sgm->lock);
+// sgm->state = state;
+// mutex_unlock(&sgm->lock);
+
+// if (!sgm->state.pg_stat) {
+// printf("%s not present vbus_status \n",__func__);
+// goto OUT;
+// }
+// sgm41562_dump_register(sgm);
+// OUT:
+// schedule_delayed_work(&sgm->charge_monitor_work, 10*HZ);
+// }
+
+// static void charger_detect_work_func(struct work_struct *work)
+// {
+// struct delayed_work *charge_detect_delayed_work = NULL;
+// void = NULL;
+// struct sgm41562_state state;
+// int ret;
+
+// charge_detect_delayed_work = container_of(work, struct delayed_work, work);
+// if(charge_detect_delayed_work == NULL) {
+// printf("Cann't get charge_detect_delayed_work\n");
+// goto err;
+// }
+// sgm = container_of(charge_detect_delayed_work, struct sgm41562_device, charge_detect_delayed_work);
+// if(sgm == NULL) {
+// printf("Cann't get sgm41562_device\n");
+// goto err;
+// }
+
+// if (!sgm->charger_wakelock->active)
+// __pm_stay_awake(sgm->charger_wakelock);
+
+// ret = sgm41562_get_state( &state);
+// mutex_lock(&sgm->lock);
+// sgm->state = state;
+// mutex_unlock(&sgm->lock);
+
+// if(!sgm->state.pg_stat) {
+// dev_err(sgm->dev, "Vbus not online disable charge\n");
+// sgm41562_ctrl_setting(REG_BIT_EN_CEB,0);
+// goto err;
+// }
+
+// //enable charge
+// sgm41562_ctrl_setting(REG_BIT_EN_CEB,1);
+
+// sgm41562_dump_register(sgm);
+// err:
+// //release wakelock
+// power_supply_changed(sgm->charger);
+// dev_err(sgm->dev, "Relax wakelock\n");
+// __pm_relax(sgm->charger_wakelock);
+// return;
+// }
+
+// static irqreturn_t sgm41562_irq_handler_thread(int irq, void *private)
+// {
+// void = private;
+
+// //lock wakelock
+// printf("%s entry\n",__func__);
+
+// schedule_delayed_work(&sgm->charge_detect_delayed_work, 100);
+// //power_supply_changed(sgm->charger);
+
+// return IRQ_HANDLED;
+// }
+
+
+// static char *sgm41562_charger_supplied_to[] = {
+// "battery",
+// };
+
+// static struct power_supply_desc sgm41562_power_supply_desc = {
+// .name = "sgm41562-charger",
+// .type = POWER_SUPPLY_TYPE_BATTERY,
+// .usb_types = sgm41562_usb_type,
+// .num_usb_types = ARRAY_SIZE(sgm41562_usb_type),
+// .properties = sgm41562_power_supply_props,
+// .num_properties = ARRAY_SIZE(sgm41562_power_supply_props),
+// .get_property = sgm41562_charger_get_property,
+// .set_property = sgm41562_charger_set_property,
+// .property_is_writeable = sgm41562_property_is_writeable,
+// };
+
+// static int sgm41562_power_supply_init(
+// struct device *dev)
+// {
+// struct power_supply_config psy_cfg = { .drv_data =
+// .of_node = dev->of_node, };
+
+// psy_cfg.supplied_to = sgm41562_charger_supplied_to;
+// psy_cfg.num_supplicants = ARRAY_SIZE(sgm41562_charger_supplied_to);
+
+// sgm->charger = devm_power_supply_register(sgm->dev,
+// &sgm41562_power_supply_desc,
+// &psy_cfg);
+// if (IS_ERR(sgm->charger))
+// return -1;
+
+// return 0;
+// }
+
+// static int sgm41562_hw_init(void)
+// {
+// int ret = 0;
+// // struct power_supply_battery_info bat_info = { };
+
+// struct sgm41562_init_data {
+// uint32_t ichg; /* 充电电流 (uA) */
+// uint32_t ilim; /* 输入限流 (uA) */
+// uint32_t vreg; /* 满电电压 (uV) */
+// uint32_t iterm; /* 截止电流 (uA) */
+// uint32_t iprechg; /* 预充电流 (uA) */
+// uint32_t vlim; /* 最小系统电压 (uV) */
+// uint32_t max_ichg; /* 最大充电电流 (uA) */
+// uint32_t max_vreg; /* 最大满电电压 (uV) */
+// };
+
+
+// struct sgm41562_init_data data = {0};
+
+
+
+
+// bat_info.constant_charge_current_max_ua =
+// SGM41562_FAST_ICC_DEF_uA;
+// sgm->init_data.ichg = bat_info.constant_charge_current_max_ua;
+
+// bat_info.constant_charge_voltage_max_uv =
+// SGM41562_VBAT_REG_DEF_uV;
+// sgm->init_data.max_vreg = bat_info.constant_charge_voltage_max_uv;
+
+// bat_info.charge_term_current_ua =
+// SGM41562_TERM_I_DEF_uA;
+// sgm->init_data.iterm = bat_info.charge_term_current_ua;
+
+// sgm->init_data.max_ichg =
+// SGM41562_FAST_ICC_MAX_uA;
+// sgm->init_data.vlim =
+// SGM41562_VINDPM_DEF_uV;
+
+// sgm->init_data.max_vreg =
+// SGM41562_VBAT_REG_MAX_uV;
+
+// ret = sgm41562_set_fast_cc(
+// bat_info.constant_charge_current_max_ua);
+// if (ret)
+// goto err_out;
+
+// ret = sgm41562_set_chrg_volt(
+// bat_info.constant_charge_voltage_max_uv);
+// if (ret)
+// goto err_out;
+
+// ret = sgm41562_ctrl_setting(REG_BIT_VBAT_PRE,1); //3.0v
+// if (ret)
+// goto err_out;
+
+// ret = sgm41562_ctrl_setting(REG_BIT_VRECH,1); //200mv
+// if (ret)
+// goto err_out;
+
+// ret = sgm41562_set_input_volt_lim( sgm->init_data.vlim);
+// if (ret)
+// goto err_out;
+
+// ret = sgm41562_set_input_curr_lim( sgm->init_data.ilim);
+// if (ret)
+// goto err_out;
+
+// printf("ichrg_curr:%d chrg_vol:%d,input_curr_lim:%d",
+// bat_info.constant_charge_current_max_ua,
+// bat_info.constant_charge_voltage_max_uv,
+// sgm->init_data.ilim);
+
+// return 0;
+
+// err_out:
+// return ret;
+// }
+
+
+static int sgm41562_hw_chipid_detect(void)
+{
+ int ret = 0;
+ uint8_t val = 0;
+
+ ret = sgm41562_read_reg(SGM41562_CHRG_REG_B,&val);
+ if (ret < 0) {
+ printf("[%s] read SGM41562_CHRG_REG_B fail\n", __func__);
+ return ret;
+ }
+ printf("[%s] Reg[0x0B]=0x%x.\n", __func__,val);
+
+ if (val == SGM41562S_DEV_ID){
+ printf("[%s] device sgm41562S found !!!\n", __func__);
+ } else if (val == SGM41562SA_DEV_ID) {
+ printf("[%s] device sgm41562SA found !!!\n", __func__);
+ } else if (val == SGM41562_DEV_ID) {
+ printf("[%s] device sgm41562 found !!!\n", __func__);
+ }else {
+ printf("[%s] device not found !!!\n", __func__);
+ return -1;
+ }
+
+ return ret;
+}
+
+
+int sgm41562_hw_init(void)
+{
+ int ret = 0;
+
+ // struct sgm41562_init_data {
+ // uint32_t ichg; /* charge current */
+ // uint32_t ilim; /* input current */
+ // uint32_t vreg; /* regulation voltage */
+ // uint32_t iterm; /* termination current */
+ // uint32_t iprechg;/* precharge current */
+ // uint32_t vlim; /* minimum system voltage limit */
+ // uint32_t max_ichg;
+ // uint32_t max_vreg;
+ // };
+
+ custom_i2c_init(I2C_BUS);
+
+ ret = sgm41562_hw_chipid_detect();
+ if(ret){
+ printf("[%s] device not found !!!\n", __func__);
+ return ret;
+ }
+
+ printf("sgm41562_hw_chipid_detect successful\n");
+
+ struct sgm41562_init_data data = {0};
+
+ data.ichg = 256000;
+ data.vreg = SGM41562_VBAT_REG_DEF_uV;
+ data.iterm = SGM41562_TERM_I_DEF_uA;
+ data.vlim = SGM41562_VINDPM_DEF_uV;
+ data.max_ichg = SGM41562_FAST_ICC_MAX_uA;
+ data.max_vreg = SGM41562_VBAT_REG_MAX_uV;
+ data.ilim = SGM41562_IINDPM_DEF_uA;
+
+ // ===================== 硬件寄存器配置 =====================
+ ret = sgm41562_set_fast_cc(data.ichg);
+ if (ret)
+ goto err_out;
+
+ ret = sgm41562_set_chrg_volt(data.vreg);
+ if (ret)
+ goto err_out;
+
+ ret = sgm41562_ctrl_setting(REG_BIT_VBAT_PRE, 1); // 3.0V
+ if (ret)
+ goto err_out;
+
+ ret = sgm41562_ctrl_setting(REG_BIT_VRECH, 1); // 200mV
+ if (ret)
+ goto err_out;
+
+ ret = sgm41562_set_input_volt_lim(data.vlim);
+ if (ret)
+ goto err_out;
+
+ ret = sgm41562_set_input_curr_lim(data.ilim);
+ if (ret)
+ goto err_out;
+
+ ret = sgm41562_ctrl_setting(REG_BIT_EN_CEB, 0);
+ if (ret)
+ goto err_out;
+
+ printf("ichrg:%d uA, chrg_vol:%d uV, input_limit:%d uA\n",
+ data.ichg, data.vreg, data.ilim);
+
+
+ // static int sgm41562_read_reg( uint8_t reg, uint8_t *data);
+ uint8_t reg_data = 0;
+
+ sgm41562_read_reg(SGM41562_CHRG_REG_0,®_data);
+ printf("SGM41562_CHRG_REG_0 :0x%x\n",reg_data);
+
+ sgm41562_read_reg(SGM41562_CHRG_REG_1,®_data);
+ printf("SGM41562_CHRG_REG_1 :0x%x\n",reg_data);
+
+ sgm41562_read_reg(SGM41562_CHRG_REG_2,®_data);
+ printf("SGM41562_CHRG_REG_2 :0x%x\n",reg_data);
+
+ sgm41562_read_reg(SGM41562_CHRG_REG_3,®_data);
+ printf("SGM41562_CHRG_REG_3 :0x%x\n",reg_data);
+
+ sgm41562_read_reg(SGM41562_CHRG_REG_4,®_data);
+ printf("SGM41562_CHRG_REG_4 :0x%x\n",reg_data);
+
+ sgm41562_read_reg(SGM41562_CHRG_REG_5,®_data);
+ printf("SGM41562_CHRG_REG_5 :0x%x\n",reg_data);
+
+ sgm41562_read_reg(SGM41562_CHRG_REG_6,®_data);
+ printf("SGM41562_CHRG_REG_6 :0x%x\n",reg_data);
+
+ sgm41562_read_reg(SGM41562_CHRG_REG_7,®_data);
+ printf("SGM41562_CHRG_REG_7 :0x%x\n",reg_data);
+
+ sgm41562_read_reg(SGM41562_CHRG_REG_8,®_data);
+ printf("SGM41562_CHRG_REG_8 :0x%x\n",reg_data);
+
+ sgm41562_read_reg(SGM41562_CHRG_REG_9,®_data);
+ printf("SGM41562_CHRG_REG_9 :0x%x\n",reg_data);
+
+ sgm41562_read_reg(SGM41562_CHRG_REG_A,®_data);
+ printf("SGM41562_CHRG_REG_A :0x%x\n",reg_data);
+
+ sgm41562_read_reg(SGM41562_CHRG_REG_B,®_data);
+ printf("SGM41562_CHRG_REG_B :0x%x\n",reg_data);
+
+ sgm41562_read_reg(SGM41562_CHRG_REG_C,®_data);
+ printf("SGM41562_CHRG_REG_C :0x%x\n",reg_data);
+
+ sgm41562_read_reg(SGM41562_CHRG_REG_D,®_data);
+ printf("SGM41562_CHRG_REG_D :0x%x\n",reg_data);
+
+ return 0;
+
+err_out:
+ return ret;
+}
+
+// static int sgm41562_parse_dt(void)
+// {
+// int ret;
+
+// int irq_gpio = 0, irqn = 0;
+// //int chg_en_gpio = 0;
+
+// ret = device_property_read_uint32_t(sgm->dev,
+// "input-voltage-limit-microvolt",
+// &sgm->init_data.vlim);
+// if (ret)
+// sgm->init_data.vlim = SGM41562_VINDPM_DEF_uV;
+
+// if (sgm->init_data.vlim > SGM41562_VINDPM_V_MAX_uV ||
+// sgm->init_data.vlim < SGM41562_VINDPM_V_MIN_uV)
+// return -1;
+
+// ret = device_property_read_uint32_t(sgm->dev,
+// "input-current-limit-microamp",
+// &sgm->init_data.ilim);
+// if (ret)
+// sgm->init_data.ilim = SGM41562_IINDPM_DEF_uA;
+
+// if (sgm->init_data.ilim > SGM41562_IINDPM_I_MAX_uA ||
+// sgm->init_data.ilim < SGM41562_IINDPM_I_MIN_uA)
+// return -1;
+
+// irq_gpio = of_get_named_gpio(sgm->dev->of_node, "irq-gpio", 0);
+// if (!gpio_is_valid(irq_gpio))
+// {
+// dev_err(sgm->dev, "%s: %d gpio get failed\n", __func__, irq_gpio);
+// return -1;
+// }
+// ret = gpio_request(irq_gpio, "sgm41562 irq pin");
+// if (ret) {
+// dev_err(sgm->dev, "%s: %d gpio request failed\n", __func__, irq_gpio);
+// return ret;
+// }
+// gpio_direction_input(irq_gpio);
+// irqn = gpio_to_irq(irq_gpio);
+// if (irqn < 0) {
+// dev_err(sgm->dev, "%s:%d gpio_to_irq failed\n", __func__, irqn);
+// return irqn;
+// }
+// sgm->client->irq = irqn;
+// #if 0
+// chg_en_gpio = of_get_named_gpio(sgm->dev->of_node, "chg-en-gpio", 0);
+// if (!gpio_is_valid(chg_en_gpio))
+// {
+// dev_err(sgm->dev, "%s: %d gpio get failed\n", __func__, chg_en_gpio);
+// return -1;
+// }
+// ret = gpio_request(chg_en_gpio, "sgm chg en pin");
+// if (ret) {
+// dev_err(sgm->dev, "%s: %d gpio request failed\n", __func__, chg_en_gpio);
+// return ret;
+// }
+// gpio_direction_output(chg_en_gpio,0);//default enable charge
+// #endif
+// return 0;
+// }
+
+
+// static int sgm41562_suspend_notifier(struct notifier_block *nb,
+// unsigned long event,
+// void *dummy)
+// {
+// void = container_of(nb, struct sgm41562_device, pm_nb);
+
+// switch (event) {
+
+// case PM_SUSPEND_PREPARE:
+// printf("sgm41562 PM_SUSPEND \n");
+
+// cancel_delayed_work_sync(&sgm->charge_monitor_work);
+
+// sgm->sgm41562_suspend_flag = 1;
+
+// return NOTIFY_OK;
+
+// case PM_POST_SUSPEND:
+// printf("sgm41562 PM_RESUME \n");
+
+// schedule_delayed_work(&sgm->charge_monitor_work, 0);
+
+// sgm->sgm41562_suspend_flag = 0;
+
+// return NOTIFY_OK;
+
+// default:
+// return NOTIFY_DONE;
+// }
+// }
+
+// static int sgm41562_probe(struct i2c_client *client,
+// const struct i2c_device_id *id)
+// {
+// struct device *dev = &client->dev;
+// void;
+// int ret;
+// char *name = NULL;
+
+// printf("%s enter\n",__func__);
+// sgm = devm_kzalloc(dev, sizeof(*sgm), GFP_KERNEL);
+// if (!sgm)
+// return -ENOMEM;
+
+// sgm->client = client;
+// sgm->dev = dev;
+
+// mutex_init(&sgm->lock);
+// mutex_init(&sgm->i2c_rw_lock);
+
+// strncpy(sgm->model_name, id->name, I2C_NAME_SIZE);
+
+// i2c_set_clientdata(client, sgm);
+
+// // Customer customization
+// ret = sgm41562_parse_dt(sgm);
+// if (ret) {
+// dev_err(dev, "Failed to read device tree properties%d\n", ret);
+// return ret;
+// }
+
+// ret = sgm41562_hw_chipid_detect(sgm);
+// if(ret){
+// printf("[%s] device not found !!!\n", __func__);
+// return ret;
+// }
+
+// name = devm_kasprintf(sgm->dev, GFP_KERNEL, "%s",
+// "sgm41562 suspend wakelock");
+// #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 9))
+// // 如果内核版本大于或等于 4.1.9,执行这里的代码
+// sgm->charger_wakelock =
+// wakeup_source_register(dev,name);
+// #else
+// sgm->charger_wakelock =
+// wakeup_source_register(name);
+// #endif
+
+// INIT_DELAYED_WORK(&sgm->charge_detect_delayed_work, charger_detect_work_func);
+// INIT_DELAYED_WORK(&sgm->charge_monitor_work, charger_monitor_work_func);
+// sgm->pm_nb.notifier_call = sgm41562_suspend_notifier;
+// register_pm_notifier(&sgm->pm_nb);
+
+// if (client->irq) {
+// ret = devm_request_threaded_irq(dev, client->irq, NULL,
+// sgm41562_irq_handler_thread,
+// IRQF_TRIGGER_FALLING |
+// IRQF_ONESHOT,
+// dev_name(&client->dev), sgm);
+// if (ret)
+// goto error_out;
+// enable_irq_wake(client->irq);
+// }
+
+// ret = sgm41562_power_supply_init( dev);
+// if (ret) {
+// dev_err(dev, "Failed to register power supply\n");
+// goto error_out;
+// }
+
+// ret = sgm41562_hw_init(sgm);
+// if (ret) {
+// dev_err(dev, "Cannot initialize the chip.\n");
+// goto error_out;
+// }
+
+// schedule_delayed_work(&sgm->charge_monitor_work,100);
+// printf("%s end \n",__func__);
+
+// error_out:
+// return ret;
+// }
+
+// static int sgm41562_charger_remove(struct i2c_client *client)
+// {
+// void= i2c_get_clientdata(client);
+
+// cancel_delayed_work_sync(&sgm->charge_monitor_work);
+
+// power_supply_unregister(sgm->charger);
+
+// mutex_destroy(&sgm->lock);
+// mutex_destroy(&sgm->i2c_rw_lock);
+
+
+// return 0;
+// }
+
+static void sgm41562_charger_shutdown(void)
+{
+ int ret = 0;
+
+ // void = i2c_get_clientdata(client);
+ ret = sgm41562_ctrl_setting(REG_BIT_EN_CEB,0);
+ if (ret) {
+ printf("Failed to disable charger, ret = %d\n", ret);
+ }
+ printf("sgm41562_charger_shutdown\n");
+}
+
+void sgm41562_read_all_reg(void)
+{
+ uint8_t reg_data = 0;
+
+ sgm41562_read_reg(SGM41562_CHRG_REG_0,®_data);
+ printf("SGM41562_CHRG_REG_0 :0x%x\n",reg_data);
+
+ sgm41562_read_reg(SGM41562_CHRG_REG_1,®_data);
+ printf("SGM41562_CHRG_REG_1 :0x%x\n",reg_data);
+
+ sgm41562_read_reg(SGM41562_CHRG_REG_2,®_data);
+ printf("SGM41562_CHRG_REG_2 :0x%x\n",reg_data);
+
+ sgm41562_read_reg(SGM41562_CHRG_REG_3,®_data);
+ printf("SGM41562_CHRG_REG_3 :0x%x\n",reg_data);
+
+ sgm41562_read_reg(SGM41562_CHRG_REG_4,®_data);
+ printf("SGM41562_CHRG_REG_4 :0x%x\n",reg_data);
+
+ sgm41562_read_reg(SGM41562_CHRG_REG_5,®_data);
+ printf("SGM41562_CHRG_REG_5 :0x%x\n",reg_data);
+
+ sgm41562_read_reg(SGM41562_CHRG_REG_6,®_data);
+ printf("SGM41562_CHRG_REG_6 :0x%x\n",reg_data);
+
+ sgm41562_read_reg(SGM41562_CHRG_REG_7,®_data);
+ printf("SGM41562_CHRG_REG_7 :0x%x\n",reg_data);
+
+ sgm41562_read_reg(SGM41562_CHRG_REG_8,®_data);
+ printf("SGM41562_CHRG_REG_8 :0x%x\n",reg_data);
+
+ sgm41562_read_reg(SGM41562_CHRG_REG_9,®_data);
+ printf("SGM41562_CHRG_REG_9 :0x%x\n",reg_data);
+
+ sgm41562_read_reg(SGM41562_CHRG_REG_A,®_data);
+ printf("SGM41562_CHRG_REG_A :0x%x\n",reg_data);
+
+ sgm41562_read_reg(SGM41562_CHRG_REG_B,®_data);
+ printf("SGM41562_CHRG_REG_B :0x%x\n",reg_data);
+
+ sgm41562_read_reg(SGM41562_CHRG_REG_C,®_data);
+ printf("SGM41562_CHRG_REG_C :0x%x\n",reg_data);
+
+ sgm41562_read_reg(SGM41562_CHRG_REG_D,®_data);
+ printf("SGM41562_CHRG_REG_D :0x%x\n",reg_data);
+}
--- /dev/null
+#ifndef SGM41562_CHARGER_H\r
+#define SGM41562_CHARGER_H\r
+\r
+#include <stdint.h>\r
+#include <stdbool.h>\r
+#include "std_def.h"\r
+\r
+#ifndef GENMASK\r
+#define GENMASK(h, l) (((uint8_t) -1 >> (7 - (h))) & ~((1U << (l)) - 1))\r
+#endif\r
+\r
+/*define register*/\r
+#define SGM41562_CHRG_REG_0 0x00\r
+#define SGM41562_CHRG_REG_1 0x01\r
+#define SGM41562_CHRG_REG_2 0x02\r
+#define SGM41562_CHRG_REG_3 0x03\r
+#define SGM41562_CHRG_REG_4 0x04\r
+#define SGM41562_CHRG_REG_5 0x05\r
+#define SGM41562_CHRG_REG_6 0x06\r
+#define SGM41562_CHRG_REG_7 0x07\r
+#define SGM41562_CHRG_REG_8 0x08\r
+#define SGM41562_CHRG_REG_9 0x09\r
+#define SGM41562_CHRG_REG_A 0x0A\r
+#define SGM41562_CHRG_REG_B 0x0B\r
+#define SGM41562_CHRG_REG_C 0x0C\r
+#define SGM41562_CHRG_REG_D 0x0D\r
+\r
+/* REG00 vindpm voltage */\r
+#define SGM41562_VINDPM_V_MASK GENMASK(7, 4)\r
+#define SGM41562_VINDPM_V_MIN_uV 3880000\r
+#define SGM41562_VINDPM_V_MAX_uV 5080000\r
+#define SGM41562_VINDPM_STEP_uV 80000\r
+#define SGM41562_VINDPM_DEF_uV 4600000\r
+#define SGM41562_PRE_TO BIT(3)\r
+#define SGM41562_INT_EXIT_SHIP BIT(2)\r
+#define SGM41562_VIN_EXIT_SHIP BIT(1)\r
+#define SGM41562_ITERM_TIMER BIT(0)\r
+\r
+\r
+/*REG01 charge setting */\r
+#define SGM41562_RST_DGL GENMASK(7, 6)\r
+#define SGM41562_RST_DUR BIT(5)\r
+#define SGM41562_HIZ_EN BIT(4)\r
+#define SGM41562_EN_CEB BIT(3)\r
+\r
+/*REG01 VBAT UVLO THRESHOLD */\r
+#define SGM41562_VBAT_UVLO_MASK GENMASK(2, 0)\r
+#define SGM41562_VBAT_UVLO_MIN_uV 2400000\r
+#define SGM41562_VBAT_UVLO_MAX_uV 3030000\r
+#define SGM41562_VBAT_UVLO_STEP_uV 90000\r
+#define SGM41562_VBAT_UVLO_DEF_uV 2760000\r
+\r
+/*REG02 */\r
+#define SGM41562_REG_RST BIT(7)\r
+#define SGM41562_FAST_ICC_MASK GENMASK(5, 0)\r
+#define SGM41562_FAST_ICC_MIN_uA 8000\r
+#define SGM41562_FAST_ICC_MAX_uA 1024000\r
+#define SGM41562_FAST_ICC_STEP_uA 8000\r
+#define SGM41562_FAST_ICC_DEF_uA 128000\r
+\r
+/* REG03 discharge current */\r
+#define SGM41562_DSCHG_I_MASK GENMASK(7, 4)\r
+#define SGM41562_DSCHG_I_MIN_uA 400000\r
+#define SGM41562_DSCHG_I_MAX_uA 3200000\r
+#define SGM41562_DSCHG_I_STEP_uA 200000\r
+#define SGM41562_DSCHG_I_DEF_uA 2000000\r
+\r
+/* REG03 termination current */\r
+#define SGM41562_TERM_I_MASK GENMASK(3, 0)\r
+#define SGM41562_TERM_I_MIN_uA 1000\r
+#define SGM41562_TERM_I_MAX_uA 31000\r
+#define SGM41562_TERM_I_STEP_uA 2000\r
+#define SGM41562_TERM_I_DEF_uA 3000\r
+\r
+\r
+/* REG04 vbat */\r
+#define SGM41562_VBAT_REG_MASK GENMASK(7, 2)\r
+#define SGM41562_VBAT_REG_MIN_uV 3500000\r
+#define SGM41562_VBAT_REG_MAX_uV 4770000\r
+#define SGM41562_VBAT_REG_STEP_uV 10000\r
+#define SGM41562_VBAT_REG_DEF_uV 4550000\r
+#define SGM41562_VRECH_THRE_uV BIT(0)\r
+\r
+\r
+/* REG05 */\r
+#define SGM41562_EN_WD_DISCHG BIT(7)\r
+#define SGM41562_WD_TIMER_MASK (BIT(6)| BIT(5))\r
+#define SGM41562_EN_TERM BIT(4)\r
+#define SGM41562_EN_SATETY_TIMER BIT(3)\r
+#define SGM41562_CHG_TIMER_MASK (BIT(2)| BIT(1))\r
+#define SGM41562_EN_TERM_TIMER BIT(0)\r
+\r
+/* REG06 */\r
+#define SGM41562_EN_NTC BIT(7)\r
+#define SGM41562_EN_TMR2X BIT(6)\r
+#define SGM41562_FET_DIS BIT(5)\r
+#define SGM41562_PG_INT_CTL BIT(4)\r
+#define SGM41562_EOC_INT_CTL BIT(3)\r
+#define SGM41562_CHG_STATUS_INT_CTL BIT(2)\r
+#define SGM41562_NTC_INT_CTL BIT(1)\r
+#define SGM41562_BATOVP_INT_CTL BIT(0)\r
+\r
+/* REG07 */\r
+#define SGM41562_DIS_VINLOOP BIT(7)\r
+#define SGM41562_TJ_REG_MASK GENMASK(6, 5)\r
+#define SGM41562_VSYS_REG_MASK GENMASK(4, 0)\r
+#define SGM41562_VSYS_MIN_uV 3600000\r
+#define SGM41562_VSYS_MAX_uV 5150000\r
+#define SGM41562_VSYS_STEP_uV 50000\r
+#define SGM41562_VSYS_DEF_uV 4550000\r
+\r
+/* REG08 */\r
+#define SGM41562_WTD_FAULT BIT(7)\r
+#define SGM41562_DIS_PCB_OTP BIT(6)\r
+#define SGM41562_VIN_OVP_SEL BIT(5)\r
+#define SGM41562_CHG_STAT_MASK GENMASK(4, 3)\r
+#define SGM41562_NOT_CHRGING 0\r
+#define SGM41562_PRECHRG BIT(3)\r
+#define SGM41562_FAST_CHRG BIT(4)\r
+#define SGM41562_TERM_CHRG (BIT(3)| BIT(4))\r
+#define SGM41562_PPM_STAT BIT(2)\r
+#define SGM41562_PG_STAT BIT(1)\r
+#define SGM41562_THERM_STAT BIT(0)\r
+\r
+\r
+/* REG09 */\r
+#define SGM41562_EN_SHIP_DGL_MASK GENMASK(7, 6)\r
+#define SGM41562_VIN_FAULT BIT(5)\r
+#define SGM41562_THEM_SD BIT(4)\r
+#define SGM41562_BAT_FAULT BIT(3)\r
+#define SGM41562_STMR_FAULT BIT(2)\r
+#define SGM41562_NTC_HOT_FAULT BIT(1)\r
+#define SGM41562_NTC_COOL_FAULT BIT(0)\r
+\r
+\r
+/* REG0A */\r
+#define SGM41562_SLAVE_ADDR_MASK GENMASK(7, 5)\r
+#define SGM41562_COLD_RESET BIT(4)\r
+#define SGM41562_SWITCH_MODE BIT(3)\r
+#define SGM41562_DIS_VDD BIT(2)\r
+#define SGM41562_DIS_VINOVP BIT(1)\r
+#define SGM41562_CC_FINE BIT(0)\r
+\r
+/* REG0B */\r
+#define SGM41562_DEV_ID_MASK GENMASK(7, 0)\r
+#define SGM41562S_DEV_ID (BIT(3) | BIT(0))\r
+#define SGM41562SA_DEV_ID 0\r
+\r
+#define SGM41562_DEV_ID 0x4\r
+\r
+/* REG0C iindpm current */\r
+#define SGM41562_IINDPM_I_MASK GENMASK(7, 3)\r
+#define SGM41562_IINDPM_I_MIN_uA 50000\r
+#define SGM41562_IINDPM_I_MAX_uA 980000\r
+#define SGM41562_IINDPM_STEP_uA 30000\r
+#define SGM41562_IINDPM_DEF_uA 500000\r
+#define SGM41562_DIS_INT BIT(2)\r
+#define SGM41562_VBAT_PRE_THRE_uV BIT(1)\r
+#define SGM41562_WD_RST BIT(0)\r
+\r
+/* REG0D iprechg current */\r
+#define SGM41562_PRE_ICHG_MASK GENMASK(7, 4)\r
+#define SGM41562_PRE_ICHG_MIN_uA 1000\r
+#define SGM41562_PRE_ICHG_MAX_uA 31000\r
+#define SGM41562_PRE_ICHG_STEP_uA 2000\r
+#define SGM41562_PRE_ICHG_DEF_uA 3000\r
+#define SGM41562_PRE_ICHG_X6 BIT(3)\r
+#define SGM41562_ITERM_X6 BIT(2)\r
+\r
+struct sgm41562_init_data {\r
+ uint32_t ichg; /* charge current */\r
+ uint32_t ilim; /* input current */\r
+ uint32_t vreg; /* regulation voltage */\r
+ uint32_t iterm; /* termination current */\r
+ uint32_t iprechg; /* precharge current */\r
+ uint32_t vlim; /* minimum system voltage limit */\r
+ uint32_t max_ichg;\r
+ uint32_t max_vreg;\r
+};\r
+\r
+typedef enum {\r
+ // 对齐原内核枚举的语义,数值从0开始自定义\r
+ POWER_SUPPLY_PROP_MANUFACTURER = 0, // 制造商\r
+ POWER_SUPPLY_PROP_MODEL_NAME, // 型号名称\r
+ POWER_SUPPLY_PROP_STATUS, // 充电状态(充电/放电/空闲)\r
+ POWER_SUPPLY_PROP_ONLINE, // 是否在线(外接电源是否接入)\r
+ POWER_SUPPLY_PROP_HEALTH, // 电池健康状态\r
+ POWER_SUPPLY_PROP_VOLTAGE_NOW, // 当前电压(mV)\r
+ POWER_SUPPLY_PROP_CURRENT_NOW, // 当前电流(mA)\r
+ POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, // 输入限流(mA)\r
+ POWER_SUPPLY_PROP_CHARGE_TYPE, // 充电类型(恒流/恒压/快充等)\r
+ POWER_SUPPLY_PROP_USB_TYPE, // USB 类型(USB2.0/3.0/快充协议)\r
+ POWER_SUPPLY_PROP_PRESENT, // 电池是否在位\r
+ POWER_SUPPLY_PROP_MAX // 枚举边界(用于数组遍历)\r
+} power_supply_property;\r
+\r
+// 原数组直接复用,仅修改枚举类型定义(无需改数组内容)\r
+static power_supply_property sgm41562_power_supply_props[] = {\r
+ POWER_SUPPLY_PROP_MANUFACTURER,\r
+ POWER_SUPPLY_PROP_MODEL_NAME,\r
+ POWER_SUPPLY_PROP_STATUS,\r
+ POWER_SUPPLY_PROP_ONLINE,\r
+ POWER_SUPPLY_PROP_HEALTH,\r
+ POWER_SUPPLY_PROP_VOLTAGE_NOW,\r
+ POWER_SUPPLY_PROP_CURRENT_NOW,\r
+ POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,\r
+ POWER_SUPPLY_PROP_CHARGE_TYPE,\r
+ POWER_SUPPLY_PROP_USB_TYPE,\r
+ POWER_SUPPLY_PROP_PRESENT\r
+};\r
+\r
+struct sgm41562_state {\r
+ bool ppm_stat;\r
+ bool therm_stat;\r
+ bool pg_stat; \r
+ uint8_t chrg_stat; \r
+\r
+ bool chrg_en;\r
+ bool hiz_en;\r
+ bool term_en;\r
+ bool bat_fault;\r
+ \r
+ uint8_t health;\r
+ uint8_t ntc_fault_0;\r
+ uint8_t ntc_fault_1; \r
+};\r
+\r
+// struct sgm41562_device {\r
+// struct i2c_client *client;\r
+// struct device *dev;\r
+// struct power_supply *charger; \r
+// struct mutex lock;\r
+// struct mutex i2c_rw_lock;\r
+\r
+// struct usb_phy *usb2_phy;\r
+// struct usb_phy *usb3_phy;\r
+// struct notifier_block usb_nb;\r
+// struct work_struct usb_work;\r
+// unsigned long usb_event;\r
+// struct regmap *regmap;\r
+\r
+// char model_name[I2C_NAME_SIZE];\r
+// int device_id;\r
+\r
+// struct sgm41562_init_data init_data;\r
+// struct sgm41562_state state; \r
+// #if defined(CONFIG_MTK_GAUGE_VERSION) && (CONFIG_MTK_GAUGE_VERSION == 30)\r
+// struct charger_device *chg_dev;\r
+// #endif \r
+\r
+// struct delayed_work charge_detect_delayed_work;\r
+// struct delayed_work charge_monitor_work;\r
+// struct notifier_block pm_nb;\r
+// bool sgm41562_suspend_flag;\r
+\r
+// struct wakeup_source *charger_wakelock; \r
+// };\r
+\r
+int sgm41562_hw_init(void);\r
+\r
+void sgm41562_read_all_reg(void);\r
+\r
+#endif /* _SGM41562_CHARGER_H */\r