1*4882a593Smuzhiyun /* 2*4882a593Smuzhiyun * rk816_battery.h: fuel gauge driver structures 3*4882a593Smuzhiyun * 4*4882a593Smuzhiyun * Copyright (C) 2016 Rockchip Electronics Co., Ltd 5*4882a593Smuzhiyun * Author: chenjh <chenjh@rock-chips.com> 6*4882a593Smuzhiyun * 7*4882a593Smuzhiyun * This program is free software; you can redistribute it and/or modify it 8*4882a593Smuzhiyun * under the terms and conditions of the GNU General Public License, 9*4882a593Smuzhiyun * version 2, as published by the Free Software Foundation. 10*4882a593Smuzhiyun * 11*4882a593Smuzhiyun * This program is distributed in the hope it will be useful, but WITHOUT 12*4882a593Smuzhiyun * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13*4882a593Smuzhiyun * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 14*4882a593Smuzhiyun * more details. 15*4882a593Smuzhiyun */ 16*4882a593Smuzhiyun 17*4882a593Smuzhiyun #ifndef RK816_BATTERY 18*4882a593Smuzhiyun #define RK816_BATTERY 19*4882a593Smuzhiyun 20*4882a593Smuzhiyun /*TS_CTRL_REG*/ 21*4882a593Smuzhiyun #define GG_EN BIT(7) 22*4882a593Smuzhiyun #define ADC_CUR_EN BIT(6) 23*4882a593Smuzhiyun #define ADC_TS1_EN BIT(5) 24*4882a593Smuzhiyun #define ADC_TS2_EN BIT(4) 25*4882a593Smuzhiyun 26*4882a593Smuzhiyun /*GGCON*/ 27*4882a593Smuzhiyun #define ADC_CUR_MODE (0x01 << 1) 28*4882a593Smuzhiyun #define AVG_CUR_MODE (0x00 << 0) 29*4882a593Smuzhiyun #define ADC_CAL_MIN_MSK 0x30 30*4882a593Smuzhiyun #define ADC_CAL_8MIN (0x00 << 4) 31*4882a593Smuzhiyun #define OCV_SAMP_MIN_MSK 0x0c 32*4882a593Smuzhiyun #define OCV_SAMP_8MIN (0x00 << 2) 33*4882a593Smuzhiyun 34*4882a593Smuzhiyun /*GGSTS*/ 35*4882a593Smuzhiyun #define FCC_LOCK (1 << 5) 36*4882a593Smuzhiyun #define BAT_CON (1 << 4) 37*4882a593Smuzhiyun #define RELAX_STS (1 << 1) 38*4882a593Smuzhiyun #define RELAX_VOL1_UPD BIT(3) 39*4882a593Smuzhiyun #define RELAX_VOL2_UPD BIT(2) 40*4882a593Smuzhiyun #define RELAX_VOL12_UPD_MSK (RELAX_VOL1_UPD | RELAX_VOL2_UPD) 41*4882a593Smuzhiyun 42*4882a593Smuzhiyun /*SUP_STS_REG*/ 43*4882a593Smuzhiyun #define BAT_EXS (1 << 7) 44*4882a593Smuzhiyun #define CHARGE_OFF (0x00 << 4) 45*4882a593Smuzhiyun #define DEAD_CHARGE (0x01 << 4) 46*4882a593Smuzhiyun #define TRICKLE_CHARGE (0x02 << 4) 47*4882a593Smuzhiyun #define CC_OR_CV (0x03 << 4) 48*4882a593Smuzhiyun #define CHARGE_FINISH (0x04 << 4) 49*4882a593Smuzhiyun #define USB_OVER_VOL (0x05 << 4) 50*4882a593Smuzhiyun #define BAT_TMP_ERR (0x06 << 4) 51*4882a593Smuzhiyun #define TIMER_ERR (0x07 << 4) 52*4882a593Smuzhiyun #define USB_EXIST (1 << 1) 53*4882a593Smuzhiyun #define USB_EFF (1 << 0) 54*4882a593Smuzhiyun #define USB_VLIMIT_EN BIT(3) 55*4882a593Smuzhiyun #define USB_CLIMIT_EN BIT(2) 56*4882a593Smuzhiyun #define CHRG_STATUS_MSK 0x70 57*4882a593Smuzhiyun 58*4882a593Smuzhiyun /*USB_CTRL_REG*/ 59*4882a593Smuzhiyun #define CHRG_CT_EN (1 << 7) 60*4882a593Smuzhiyun #define INPUT_CUR_MSK (0x0f) 61*4882a593Smuzhiyun #define FINISH_CUR_MSK 0xc0 62*4882a593Smuzhiyun #define CHRG_CUR_MSK (0x0f) 63*4882a593Smuzhiyun 64*4882a593Smuzhiyun /* BAT_CTRL_REG */ 65*4882a593Smuzhiyun #define USB_SYS_EN BIT(6) 66*4882a593Smuzhiyun 67*4882a593Smuzhiyun /* THERMAL_REG */ 68*4882a593Smuzhiyun #define FB_TEMP_MSK 0x0c 69*4882a593Smuzhiyun #define HOTDIE_STS BIT(1) 70*4882a593Smuzhiyun 71*4882a593Smuzhiyun /*CHGR_CUR_INPUT*/ 72*4882a593Smuzhiyun #define INPUT_CUR450MA (0x00) 73*4882a593Smuzhiyun #define INPUT_CUR80MA (0x01) 74*4882a593Smuzhiyun #define INPUT_CUR850MA (0x02) 75*4882a593Smuzhiyun #define INPUT_CUR1000MA (0x03) 76*4882a593Smuzhiyun #define INPUT_CUR1250MA (0x04) 77*4882a593Smuzhiyun #define INPUT_CUR1500MA (0x05) 78*4882a593Smuzhiyun #define INPUT_CUR1750MA (0x06) 79*4882a593Smuzhiyun #define INPUT_CUR2000MA (0x07) 80*4882a593Smuzhiyun #define INPUT_CUR2250MA (0x08) 81*4882a593Smuzhiyun #define INPUT_CUR2500MA (0x09) 82*4882a593Smuzhiyun #define INPUT_CUR2750MA (0x0A) 83*4882a593Smuzhiyun #define INPUT_CUR3000MA (0x0B) 84*4882a593Smuzhiyun 85*4882a593Smuzhiyun /*CHRG_VOL_SEL*/ 86*4882a593Smuzhiyun #define CHRG_VOL4050MV (0x00 << 4) 87*4882a593Smuzhiyun #define CHRG_VOL4100MV (0x01 << 4) 88*4882a593Smuzhiyun #define CHRG_VOL4150MV (0x02 << 4) 89*4882a593Smuzhiyun #define CHRG_VOL4200MV (0x03 << 4) 90*4882a593Smuzhiyun #define CHRG_VOL4300MV (0x04 << 4) 91*4882a593Smuzhiyun #define CHRG_VOL4350MV (0x05 << 4) 92*4882a593Smuzhiyun 93*4882a593Smuzhiyun /*CHRG_CUR_SEL*/ 94*4882a593Smuzhiyun #define CHRG_CUR1000MA (0x00) 95*4882a593Smuzhiyun #define CHRG_CUR1200MA (0x01) 96*4882a593Smuzhiyun #define CHRG_CUR1400MA (0x02) 97*4882a593Smuzhiyun #define CHRG_CUR1600MA (0x03) 98*4882a593Smuzhiyun #define CHRG_CUR1800MA (0x04) 99*4882a593Smuzhiyun #define CHRG_CUR2000MA (0x05) 100*4882a593Smuzhiyun #define CHRG_CUR2200MA (0x06) 101*4882a593Smuzhiyun #define CHRG_CUR2400MA (0x07) 102*4882a593Smuzhiyun #define CHRG_CUR2600MA (0x08) 103*4882a593Smuzhiyun #define CHRG_CUR2800MA (0x09) 104*4882a593Smuzhiyun #define CHRG_CUR3000MA (0x0A) 105*4882a593Smuzhiyun 106*4882a593Smuzhiyun /*THREAML_REG*/ 107*4882a593Smuzhiyun #define TEMP_85C (0x00 << 2) 108*4882a593Smuzhiyun #define TEMP_95C (0x01 << 2) 109*4882a593Smuzhiyun #define TEMP_105C (0x02 << 2) 110*4882a593Smuzhiyun #define TEMP_115C (0x03 << 2) 111*4882a593Smuzhiyun 112*4882a593Smuzhiyun /*CHRG_CTRL_REG2*/ 113*4882a593Smuzhiyun #define CHG_CCCV_4HOUR (0x00) 114*4882a593Smuzhiyun #define CHG_CCCV_5HOUR (0x01) 115*4882a593Smuzhiyun #define CHG_CCCV_6HOUR (0x02) 116*4882a593Smuzhiyun #define CHG_CCCV_8HOUR (0x03) 117*4882a593Smuzhiyun #define CHG_CCCV_10HOUR (0x04) 118*4882a593Smuzhiyun #define CHG_CCCV_12HOUR (0x05) 119*4882a593Smuzhiyun #define CHG_CCCV_14HOUR (0x06) 120*4882a593Smuzhiyun #define CHG_CCCV_16HOUR (0x07) 121*4882a593Smuzhiyun #define FINISH_100MA (0x00 << 6) 122*4882a593Smuzhiyun #define FINISH_150MA (0x01 << 6) 123*4882a593Smuzhiyun #define FINISH_200MA (0x02 << 6) 124*4882a593Smuzhiyun #define FINISH_250MA (0x03 << 6) 125*4882a593Smuzhiyun 126*4882a593Smuzhiyun /*CHRG_CTRL_REG3*/ 127*4882a593Smuzhiyun #define CHRG_TERM_ANA_SIGNAL (0 << 5) 128*4882a593Smuzhiyun #define CHRG_TERM_DIG_SIGNAL (1 << 5) 129*4882a593Smuzhiyun #define CHRG_TIMER_CCCV_EN (1 << 2) 130*4882a593Smuzhiyun #define CHRG_EN (1 << 7) 131*4882a593Smuzhiyun 132*4882a593Smuzhiyun #define BOOST_OTG_MASK ((0x3 << 5) | (0x3 << 1)) 133*4882a593Smuzhiyun #define BOOST_OTG_ON ((0x3 << 5) | (0x3 << 1)) 134*4882a593Smuzhiyun #define BOOST_OTG_OFF ((0x3 << 5) | (0x0 << 1)) 135*4882a593Smuzhiyun #define BOOST_OFF_OTG_ON ((0x3 << 5) | (0x2 << 1)) 136*4882a593Smuzhiyun 137*4882a593Smuzhiyun #define OTG_BOOST_SLP_ON (0x3 << 5) 138*4882a593Smuzhiyun 139*4882a593Smuzhiyun /* MISC_MARK_REG */ 140*4882a593Smuzhiyun #define FG_INIT BIT(3) 141*4882a593Smuzhiyun #define FG_RESET_LATE BIT(1) 142*4882a593Smuzhiyun #define FG_RESET_NOW BIT(0) 143*4882a593Smuzhiyun #define ALGO_REST_MODE_MSK (0xc0) 144*4882a593Smuzhiyun #define ALGO_REST_MODE_SHIFT 6 145*4882a593Smuzhiyun 146*4882a593Smuzhiyun #define FB_TEMP_SHIFT 2 147*4882a593Smuzhiyun #define CHRG_VOL_SEL_SHIFT 4 148*4882a593Smuzhiyun #define CHRG_CRU_INPUT_SHIFT 0 149*4882a593Smuzhiyun #define CHRG_CRU_SEL_SHIFT 0 150*4882a593Smuzhiyun #define CHRG_CCCV_HOUR_SHIFT 0 151*4882a593Smuzhiyun #define OCV_CALIB_SHIFT (1 << 1) 152*4882a593Smuzhiyun #define PLUG_IN_STS (1 << 6) 153*4882a593Smuzhiyun 154*4882a593Smuzhiyun #define DRIVER_VERSION "1.2" 155*4882a593Smuzhiyun #define TIMER_MS_COUNTS 1000 156*4882a593Smuzhiyun #define MAX_PERCENTAGE 100 157*4882a593Smuzhiyun #define MAX_INT 0x7FFF 158*4882a593Smuzhiyun #define MAX_INTERPOLATE 1000 159*4882a593Smuzhiyun 160*4882a593Smuzhiyun struct temp_chrg_table { 161*4882a593Smuzhiyun int temp_down; 162*4882a593Smuzhiyun int temp_up; 163*4882a593Smuzhiyun u32 chrg_current; 164*4882a593Smuzhiyun u8 set_chrg_current; 165*4882a593Smuzhiyun }; 166*4882a593Smuzhiyun 167*4882a593Smuzhiyun struct battery_platform_data { 168*4882a593Smuzhiyun u32 *ocv_table; 169*4882a593Smuzhiyun u32 *zero_table; 170*4882a593Smuzhiyun struct temp_chrg_table *tc_table; 171*4882a593Smuzhiyun u32 tc_count; 172*4882a593Smuzhiyun 173*4882a593Smuzhiyun u32 table_t[4][21]; 174*4882a593Smuzhiyun int temp_t[4]; 175*4882a593Smuzhiyun u32 temp_t_num; 176*4882a593Smuzhiyun 177*4882a593Smuzhiyun u32 *ntc_table; 178*4882a593Smuzhiyun u32 ocv_size; 179*4882a593Smuzhiyun u32 ntc_size; 180*4882a593Smuzhiyun int ntc_degree_from; 181*4882a593Smuzhiyun u32 ntc_factor; 182*4882a593Smuzhiyun u32 max_input_current; 183*4882a593Smuzhiyun u32 max_chrg_current; 184*4882a593Smuzhiyun u32 max_chrg_voltage; 185*4882a593Smuzhiyun u32 pwroff_vol; 186*4882a593Smuzhiyun u32 monitor_sec; 187*4882a593Smuzhiyun u32 zero_algorithm_vol; 188*4882a593Smuzhiyun u32 zero_reserve_dsoc; 189*4882a593Smuzhiyun u32 bat_res; 190*4882a593Smuzhiyun u32 design_capacity; 191*4882a593Smuzhiyun u32 design_qmax; 192*4882a593Smuzhiyun u32 sleep_enter_current; 193*4882a593Smuzhiyun u32 sleep_exit_current; 194*4882a593Smuzhiyun u32 sleep_filter_current; 195*4882a593Smuzhiyun u32 power_dc2otg; 196*4882a593Smuzhiyun u32 max_soc_offset; 197*4882a593Smuzhiyun u32 bat_mode; 198*4882a593Smuzhiyun u32 fb_temp; 199*4882a593Smuzhiyun u32 energy_mode; 200*4882a593Smuzhiyun u32 cccv_hour; 201*4882a593Smuzhiyun u32 dc_det_adc; 202*4882a593Smuzhiyun int dc_det_pin; 203*4882a593Smuzhiyun u8 dc_det_level; 204*4882a593Smuzhiyun int otg5v_suspend_enable; 205*4882a593Smuzhiyun u32 sample_res; 206*4882a593Smuzhiyun bool extcon; 207*4882a593Smuzhiyun }; 208*4882a593Smuzhiyun 209*4882a593Smuzhiyun enum work_mode { 210*4882a593Smuzhiyun MODE_ZERO = 0, 211*4882a593Smuzhiyun MODE_FINISH, 212*4882a593Smuzhiyun MODE_SMOOTH_CHRG, 213*4882a593Smuzhiyun MODE_SMOOTH_DISCHRG, 214*4882a593Smuzhiyun MODE_SMOOTH, 215*4882a593Smuzhiyun }; 216*4882a593Smuzhiyun 217*4882a593Smuzhiyun enum bat_mode { 218*4882a593Smuzhiyun MODE_BATTARY = 0, 219*4882a593Smuzhiyun MODE_VIRTUAL, 220*4882a593Smuzhiyun }; 221*4882a593Smuzhiyun 222*4882a593Smuzhiyun enum charger_t { 223*4882a593Smuzhiyun USB_TYPE_UNKNOWN_CHARGER, 224*4882a593Smuzhiyun USB_TYPE_NONE_CHARGER, 225*4882a593Smuzhiyun USB_TYPE_USB_CHARGER, 226*4882a593Smuzhiyun USB_TYPE_AC_CHARGER, 227*4882a593Smuzhiyun USB_TYPE_CDP_CHARGER, 228*4882a593Smuzhiyun DC_TYPE_DC_CHARGER, 229*4882a593Smuzhiyun DC_TYPE_NONE_CHARGER, 230*4882a593Smuzhiyun }; 231*4882a593Smuzhiyun 232*4882a593Smuzhiyun enum charger_state { 233*4882a593Smuzhiyun OFFLINE = 0, 234*4882a593Smuzhiyun ONLINE 235*4882a593Smuzhiyun }; 236*4882a593Smuzhiyun 237*4882a593Smuzhiyun static const u16 FEED_BACK_TEMP[] = { 238*4882a593Smuzhiyun 85, 95, 105, 115 239*4882a593Smuzhiyun }; 240*4882a593Smuzhiyun 241*4882a593Smuzhiyun static const u16 CHRG_VOL_SEL[] = { 242*4882a593Smuzhiyun 4050, 4100, 4150, 4200, 4250, 4300, 4350 243*4882a593Smuzhiyun }; 244*4882a593Smuzhiyun 245*4882a593Smuzhiyun /* 246*4882a593Smuzhiyun * If sample resistor changes, we need caculate a new CHRG_CUR_SEL[] table. 247*4882a593Smuzhiyun * 248*4882a593Smuzhiyun * Calculation method: 249*4882a593Smuzhiyun * 1. find 20mR(default) current charge table, that is: 250*4882a593Smuzhiyun * 20mR: [1000, 1200, 1400, 1600, 1800, 2000, 2250, 2400] 251*4882a593Smuzhiyun * 252*4882a593Smuzhiyun * 2. caculate Rfac(not care much, just using it) by sample resistor(ie. Rsam); 253*4882a593Smuzhiyun * Rsam = 20mR: Rfac = 10; 254*4882a593Smuzhiyun * Rsam > 20mR: Rfac = Rsam * 10 / 20; 255*4882a593Smuzhiyun * Rsam < 20mR: Rfac = 20 * 10 / Rsam; 256*4882a593Smuzhiyun * 257*4882a593Smuzhiyun * 3. from step2, we get Rfac, then we can get new charge current table by 20mR 258*4882a593Smuzhiyun * charge table: 259*4882a593Smuzhiyun * Iorg: member from 20mR charge table; Inew: new member for charge table. 260*4882a593Smuzhiyun * 261*4882a593Smuzhiyun * Rsam > 20mR: Inew = Iorg * 10 / Rfac; 262*4882a593Smuzhiyun * Rsam < 20mR: Inew = Iorg * Rfac / 10; 263*4882a593Smuzhiyun * 264*4882a593Smuzhiyun * Notice: Inew should round up if it is not a integer!!! 265*4882a593Smuzhiyun * 266*4882a593Smuzhiyun * Example: 267*4882a593Smuzhiyun * 10mR: [2000, 2400, 2800, 3200, 3600, 4000, 4500, 4800] 268*4882a593Smuzhiyun * 20mR: [1000, 1200, 1400, 1600, 1800, 2000, 2250, 2400] 269*4882a593Smuzhiyun * 40mR: [500, 600, 700, 800, 900, 1000, 1125, 1200] 270*4882a593Smuzhiyun * 50mR: [400, 480, 560, 640, 720, 800, 900, 960] 271*4882a593Smuzhiyun * 60mR: [334, 400, 467, 534, 600, 667, 750, 800] 272*4882a593Smuzhiyun * 273*4882a593Smuzhiyun * You should add property 'sample_res = <Rsam>' at battery node. 274*4882a593Smuzhiyun */ 275*4882a593Smuzhiyun 276*4882a593Smuzhiyun static const u16 CHRG_CUR_SEL[] = { 277*4882a593Smuzhiyun 1000, 1200, 1400, 1600, 1800, 2000, 2250, 2400 278*4882a593Smuzhiyun }; 279*4882a593Smuzhiyun 280*4882a593Smuzhiyun static const u16 CHRG_CUR_INPUT[] = { 281*4882a593Smuzhiyun 450, 80, 850, 1000, 1250, 1500, 1750, 2000 282*4882a593Smuzhiyun }; 283*4882a593Smuzhiyun 284*4882a593Smuzhiyun void kernel_power_off(void); 285*4882a593Smuzhiyun 286*4882a593Smuzhiyun #endif 287