blob: 7ee25d97943518404d10225cc05deed2d27225d3 [file] [log] [blame]
Channagoud Kadabi9dc19c82015-04-23 14:20:55 -07001/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
2
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions are
5met:
6 * Redistributions of source code must retain the above copyright
7 notice, this list of conditions and the following disclaimer.
8 * Redistributions in binary form must reproduce the above
9 copyright notice, this list of conditions and the following
10 disclaimer in the documentation and/or other materials provided
11 with the distribution.
12 * Neither the name of The Linux Foundation nor the names of its
13 contributors may be used to endorse or promote products derived
14 from this software without specific prior written permission.
15
16THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27*/
28
29/*===========================================================================
30
Channagoud Kadabi4ab0b172015-07-13 20:12:26 -070031 INCLUDE FILES
Channagoud Kadabi9dc19c82015-04-23 14:20:55 -070032
33===========================================================================*/
Channagoud Kadabi9dc19c82015-04-23 14:20:55 -070034#include "pm_app_smbchg.h"
Channagoud Kadabi9dc19c82015-04-23 14:20:55 -070035#include "pm_smbchg_chgr.h"
36#include "pm_smbchg_bat_if.h"
37#include "pm_app_smbchg.h"
Channagoud Kadabi9dc19c82015-04-23 14:20:55 -070038#include "pm_fg_adc_usr.h"
Channagoud Kadabi4ab0b172015-07-13 20:12:26 -070039#include "pm_fg_driver.h"
40#include "pm_smbchg_driver.h"
Channagoud Kadabi9dc19c82015-04-23 14:20:55 -070041#include "pm_comm.h"
Channagoud Kadabi9dc19c82015-04-23 14:20:55 -070042#include "pm_smbchg_dc_chgpth.h"
Channagoud Kadabif29cb842015-08-19 14:44:25 -070043#include <kernel/thread.h>
Channagoud Kadabi4ab0b172015-07-13 20:12:26 -070044#include <debug.h>
45#include <platform/timer.h>
46#include <sys/types.h>
47#include <target.h>
Channagoud Kadabif29cb842015-08-19 14:44:25 -070048#include <pm8x41.h>
Channagoud Kadabi1f5ac762015-09-18 14:19:13 -070049#include <bits.h>
50#include <board.h>
51#include <smem.h>
Channagoud Kadabi9dc19c82015-04-23 14:20:55 -070052
53/*===========================================================================
54
Channagoud Kadabi4ab0b172015-07-13 20:12:26 -070055 PROTOTYPES
Channagoud Kadabi9dc19c82015-04-23 14:20:55 -070056
57===========================================================================*/
58
59
Channagoud Kadabi4ab0b172015-07-13 20:12:26 -070060/*===========================================================================
61
Channagoud Kadabi9dc19c82015-04-23 14:20:55 -070062 GLOBAL TYPE DEFINITIONS
Channagoud Kadabi4ab0b172015-07-13 20:12:26 -070063
Channagoud Kadabi9dc19c82015-04-23 14:20:55 -070064===========================================================================*/
65#define PM_REG_CONFIG_SETTLE_DELAY 175 * 1000 //175ms ; Delay required for battery voltage de-glitch time
66#define PM_WEAK_BATTERY_CHARGING_DELAY 500 * 1000 //500ms
67#define PM_WIPOWER_START_CHARGING_DELAY 3500 * 1000 //3.5sec
68#define PM_MIN_ADC_READY_DELAY 1 * 1000 //1ms
69#define PM_MAX_ADC_READY_DELAY 2000 //2s
70#define SBL_PACKED_SRAM_CONFIG_SIZE 3
Channagoud Kadabif29cb842015-08-19 14:44:25 -070071#define PM_CHARGE_DISPLAY_TIMEOUT 5 * 1000 //5 secs
Channagoud Kadabi4ab0b172015-07-13 20:12:26 -070072#define boot_log_message(...) dprintf(CRITICAL, __VA_ARGS__)
73
Channagoud Kadabi9dc19c82015-04-23 14:20:55 -070074static pm_smbchg_bat_if_low_bat_thresh_type pm_dbc_bootup_volt_threshold;
Channagoud Kadabif29cb842015-08-19 14:44:25 -070075/* Need to maintain flags to track
76 * 1. charge_in_progress: Charging progress and exit the loop once charging is completed.
77 * 2. display_initialized: Track if the display is already initialized to make sure display
78 * thread does not reinitialize the display again.
79 * 3. display_shutdown_in_prgs: To avoid race condition between regualr display initialization and
80 * display shutdown in display thread.
81 */
82
Channagoud Kadabi4ab0b172015-07-13 20:12:26 -070083static bool display_initialized;
84static bool charge_in_progress;
Channagoud Kadabif29cb842015-08-19 14:44:25 -070085static bool display_shutdown_in_prgs;
Channagoud Kadabi1f5ac762015-09-18 14:19:13 -070086static bool pm_app_read_from_sram;
Channagoud Kadabif29cb842015-08-19 14:44:25 -070087
Channagoud Kadabi4ab0b172015-07-13 20:12:26 -070088char panel_name[256];
89
Channagoud Kadabi4ab0b172015-07-13 20:12:26 -070090pm_err_flag_type pm_appsbl_chg_config_vbat_low_threshold(uint32 device_index, pm_smbchg_specific_data_type *chg_param_ptr);
Channagoud Kadabif29cb842015-08-19 14:44:25 -070091static void display_thread_initialize();
Channagoud Kadabi1f5ac762015-09-18 14:19:13 -070092static void pm_app_ima_read_voltage(uint32_t *);
93static void pm_app_pmi8994_read_voltage(uint32_t *voltage);
Channagoud Kadabi9dc19c82015-04-23 14:20:55 -070094/*===========================================================================
95
Channagoud Kadabi4ab0b172015-07-13 20:12:26 -070096 FUNCTION IMPLEMENTATION
Channagoud Kadabi9dc19c82015-04-23 14:20:55 -070097
98===========================================================================*/
Channagoud Kadabi4ab0b172015-07-13 20:12:26 -070099pm_err_flag_type pm_appsbl_chg_check_weak_battery_status(uint32 device_index)
Channagoud Kadabi9dc19c82015-04-23 14:20:55 -0700100{
101 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
102 pm_smbchg_specific_data_type *chg_param_ptr = NULL;
103 pm_smbchg_chgr_chgr_status_type vbatt_chging_status;
104 boolean hot_bat_hard_lim_rt_sts = FALSE;
105 boolean cold_bat_hard_lim_rt_sts = FALSE;
Channagoud Kadabi9dc19c82015-04-23 14:20:55 -0700106 boolean vbatt_weak_status = TRUE;
Channagoud Kadabi9dc19c82015-04-23 14:20:55 -0700107 boolean adc_reading_ready = FALSE;
108 boolean bat_present = TRUE;
109 uint32 vbat_adc = 0;
110 uint16 wait_index = 0;
111 boolean vbatt_status = FALSE;
112 pm_smbchg_misc_src_detect_type chgr_src_detected;
113 boolean configure_icl_flag = FALSE;
114 boolean chg_prog_message_flag = FALSE;
Channagoud Kadabi4ab0b172015-07-13 20:12:26 -0700115 pm_smbchg_usb_chgpth_pwr_pth_type charger_path = PM_SMBCHG_USB_CHGPTH_PWR_PATH__INVALID;; uint32 bootup_threshold;
116
117 pm_smbchg_driver_init(device_index);
118 pm_fg_driver_init(device_index);
119
120 chg_param_ptr = (pm_smbchg_specific_data_type*)pm_target_information_get_specific_info();
121 ASSERT(chg_param_ptr);
Channagoud Kadabi9dc19c82015-04-23 14:20:55 -0700122 bootup_threshold = chg_param_ptr->bootup_battery_theshold_mv;
Channagoud Kadabi4ab0b172015-07-13 20:12:26 -0700123
Channagoud Kadabi9dc19c82015-04-23 14:20:55 -0700124 if(chg_param_ptr->dbc_bootup_volt_threshold.enable_config == PM_ENABLE_CONFIG)
125 {
126 //Configure Vlowbatt threshold: Used by PMI on next bootup
Channagoud Kadabi4ab0b172015-07-13 20:12:26 -0700127 err_flag |= pm_appsbl_chg_config_vbat_low_threshold(device_index, chg_param_ptr);
Channagoud Kadabi9dc19c82015-04-23 14:20:55 -0700128 }
129
130 //Check Battery presence
131 err_flag |= pm_smbchg_bat_if_get_bat_pres_status(device_index, &bat_present);
132 if( bat_present == FALSE )
133 {
Channagoud Kadabi4ab0b172015-07-13 20:12:26 -0700134 dprintf(CRITICAL, "Booting up to HLOS: Charger is Connected and NO battery\n");
Channagoud Kadabi9dc19c82015-04-23 14:20:55 -0700135 return err_flag;
136 }
137
138
139 //Detect the typpe of charger used
Channagoud Kadabi4ab0b172015-07-13 20:12:26 -0700140 //err_flag |= pm_smbchg_usb_chgpth_get_pwr_pth(device_index, &
Channagoud Kadabi9dc19c82015-04-23 14:20:55 -0700141 err_flag |= pm_smbchg_get_charger_path(device_index, &charger_path);
142 if (charger_path == PM_SMBCHG_USB_CHGPTH_PWR_PATH__DC_CHARGER)
143 {
Channagoud Kadabi4ab0b172015-07-13 20:12:26 -0700144
Channagoud Kadabi9dc19c82015-04-23 14:20:55 -0700145 bootup_threshold = chg_param_ptr->wipwr_bootup_battery_theshold_mv;
146 }
147 else if (charger_path == PM_SMBCHG_USB_CHGPTH_PWR_PATH__USB_CHARGER)
148 {
149 bootup_threshold = chg_param_ptr->bootup_battery_theshold_mv;
150 }
Channagoud Kadabi9dc19c82015-04-23 14:20:55 -0700151
152 //Enable BMS FG Algorithm BCL
153 err_flag |= pm_fg_adc_usr_enable_bcl_monitoring(device_index, TRUE);
154 if ( err_flag != PM_ERR_FLAG__SUCCESS )
155 {
156 return err_flag;
157 }
158
Channagoud Kadabi4ab0b172015-07-13 20:12:26 -0700159
Channagoud Kadabi9dc19c82015-04-23 14:20:55 -0700160 while( vbatt_weak_status == TRUE ) //While battery is in weak state
161 {
162 //Check Vbatt ADC level
163 err_flag |= pm_fg_adc_usr_get_bcl_values(device_index, &adc_reading_ready); //Check if Vbatt ADC is ready
164
165 //Check if Vbatt ADC is Ready
166 for (wait_index = 0; wait_index < PM_MAX_ADC_READY_DELAY; wait_index++)
167 {
168 if(adc_reading_ready == FALSE)
169 {
Channagoud Kadabi4ab0b172015-07-13 20:12:26 -0700170 udelay(PM_MIN_ADC_READY_DELAY);
Channagoud Kadabi9dc19c82015-04-23 14:20:55 -0700171 err_flag |= pm_fg_adc_usr_get_bcl_values(device_index,&adc_reading_ready);
172 }
173 else
174 {
175 break;
176 }
177 }
178
179 if ( err_flag != PM_ERR_FLAG__SUCCESS ) { break;}
180
Channagoud Kadabi4ab0b172015-07-13 20:12:26 -0700181 if ( adc_reading_ready)
Channagoud Kadabi9dc19c82015-04-23 14:20:55 -0700182 {
183 err_flag |= pm_fg_adc_usr_get_calibrated_vbat(device_index, &vbat_adc); //Read calibrated vbatt ADC
Channagoud Kadabi4ab0b172015-07-13 20:12:26 -0700184 if ( err_flag != PM_ERR_FLAG__SUCCESS ) { break;}
185
Channagoud Kadabi1f5ac762015-09-18 14:19:13 -0700186 /* FG_ADC hardware reports values that are off by ~120 to 200 mV, this results in boot up failures
187 * on devices that boot up with battery close to threshold value. If the FG_ADC voltage is less than
188 * threshold then read the voltage from a more accurate source FG SRAM to ascertain the voltage is indeed low.
189 */
190 if (!pm_app_read_from_sram && (vbat_adc <= bootup_threshold))
191 {
192 if (board_pmic_type(PMIC_IS_PMI8996))
193 pm_app_ima_read_voltage(&vbat_adc);
194 else
195 pm_app_pmi8994_read_voltage(&vbat_adc);
196
197 pm_app_read_from_sram = true;
198 }
199
Channagoud Kadabi9dc19c82015-04-23 14:20:55 -0700200 //Check if ADC reading is within limit
201 if ( vbat_adc >= bootup_threshold) //Compaire it with SW bootup threshold
202 {
203 vbatt_weak_status = FALSE;
204 break; //bootup
205 }
Channagoud Kadabif29cb842015-08-19 14:44:25 -0700206 dprintf(INFO, "Vbatt Level: %u\n", vbat_adc);
Channagoud Kadabi9dc19c82015-04-23 14:20:55 -0700207 }
208 else
209 {
Channagoud Kadabi4ab0b172015-07-13 20:12:26 -0700210 boot_log_message("ERROR: ADC Reading is NOT Ready\n");
Channagoud Kadabi9dc19c82015-04-23 14:20:55 -0700211 err_flag |= PM_ERR_FLAG__ADC_NOT_READY;
212 break;
213 }
Channagoud Kadabi4ab0b172015-07-13 20:12:26 -0700214
Channagoud Kadabi9dc19c82015-04-23 14:20:55 -0700215 //Check if USB charger is SDP
216 err_flag |= pm_smbchg_misc_chgr_port_detected(device_index, &chgr_src_detected);
217 if (chgr_src_detected == PM_SMBCHG_MISC_SRC_DETECT_SDP)
218 {
219 if (configure_icl_flag == FALSE)
220 {
221 //Check Vlow_batt status
222 err_flag |= pm_smbchg_chgr_vbat_sts(device_index, &vbatt_status);
223 if (vbatt_status)
224 {
225 //set ICL to 500mA
226 err_flag |= pm_smbchg_usb_chgpth_set_cmd_il(device_index, PM_SMBCHG_USBCHGPTH_CMD_IL__USB51_MODE, TRUE);
227 err_flag |= pm_smbchg_usb_chgpth_set_cmd_il(device_index, PM_SMBCHG_USBCHGPTH_CMD_IL__USBIN_MODE_CHG, FALSE);
228 configure_icl_flag = TRUE;
229 }
230 }
231 }
232
233 if (chg_prog_message_flag == FALSE)
234 {
235 //Ensure that Charging is enabled
236 err_flag |= pm_smbchg_chgr_enable_src(device_index, FALSE);
Channagoud Kadabi0535d592015-08-11 10:48:15 -0700237 err_flag |= pm_smbchg_chgr_set_chg_polarity_low(device_index, TRUE);
238 err_flag |= pm_smbchg_bat_if_config_chg_cmd(device_index, PM_SMBCHG_BAT_IF_CMD__EN_BAT_CHG, FALSE);
Channagoud Kadabi4ab0b172015-07-13 20:12:26 -0700239 udelay(PM_WEAK_BATTERY_CHARGING_DELAY);
Channagoud Kadabi9dc19c82015-04-23 14:20:55 -0700240 }
241
242 //Check if JEITA check is enabled
243 if (chg_param_ptr->enable_jeita_hard_limit_check == TRUE)
244 {
245 //Read JEITA condition
246 err_flag |= pm_smbchg_bat_if_irq_status(device_index, PM_SMBCHG_BAT_IF_HOT_BAT_HARD_LIM, PM_IRQ_STATUS_RT, &hot_bat_hard_lim_rt_sts );
247 err_flag |= pm_smbchg_bat_if_irq_status(device_index, PM_SMBCHG_BAT_IF_COLD_BAT_HARD_LIM, PM_IRQ_STATUS_RT, &cold_bat_hard_lim_rt_sts);
248 if ( err_flag != PM_ERR_FLAG__SUCCESS ) { break;}
249
250 if ( ( hot_bat_hard_lim_rt_sts == TRUE ) || (cold_bat_hard_lim_rt_sts == TRUE) )
251 {
Channagoud Kadabi9dc19c82015-04-23 14:20:55 -0700252 continue; // Stay in this loop as long as JEITA Hard Hot/Cold limit is exceeded
253 }
254 }
255
Channagoud Kadabi4ab0b172015-07-13 20:12:26 -0700256 if (!charge_in_progress)
257 dprintf(INFO,"APPSBL Weak Battery charging: Start\n");
258
259 charge_in_progress = true;
260#if DISPLAY_SPLASH_SCREEN
Channagoud Kadabif29cb842015-08-19 14:44:25 -0700261 display_thread_initialize();
Channagoud Kadabi4ab0b172015-07-13 20:12:26 -0700262#endif
263 /* Wait for 500 msecs before looking for vbat */
264 udelay(PM_WEAK_BATTERY_CHARGING_DELAY); //500ms
Channagoud Kadabi9dc19c82015-04-23 14:20:55 -0700265
Channagoud Kadabi9dc19c82015-04-23 14:20:55 -0700266 //Check if Charging in progress
267 err_flag |= pm_smbchg_chgr_get_chgr_sts(device_index, &vbatt_chging_status);
268 if ( err_flag != PM_ERR_FLAG__SUCCESS ) { break;}
269
270 if ( vbatt_chging_status.charging_type == PM_SMBCHG_CHGR_NO_CHARGING )
271 {
272 if (charger_path == PM_SMBCHG_USB_CHGPTH_PWR_PATH__DC_CHARGER)
273 {
274 //Delay for 3.5sec for charging to begin, and check charging status again prior to shutting down.
Channagoud Kadabi4ab0b172015-07-13 20:12:26 -0700275 udelay(PM_WIPOWER_START_CHARGING_DELAY); //3500ms
Channagoud Kadabi9dc19c82015-04-23 14:20:55 -0700276
277 err_flag |= pm_smbchg_chgr_get_chgr_sts(device_index, &vbatt_chging_status);
278 if ( err_flag != PM_ERR_FLAG__SUCCESS ) { break;}
279
280 if ( vbatt_chging_status.charging_type == PM_SMBCHG_CHGR_NO_CHARGING )
281 {
Channagoud Kadabi4ab0b172015-07-13 20:12:26 -0700282 boot_log_message("ERROR: Charging is NOT in progress: Shutting Down\n");
283 shutdown_device();
Channagoud Kadabi9dc19c82015-04-23 14:20:55 -0700284 }
285 }
286 else
287 {
Channagoud Kadabi4ab0b172015-07-13 20:12:26 -0700288 boot_log_message("ERROR: Charging is NOT in progress: Shutting Down\n");
289 shutdown_device();
Channagoud Kadabi9dc19c82015-04-23 14:20:55 -0700290 }
291 }
292 else
293 {
Channagoud Kadabi4ab0b172015-07-13 20:12:26 -0700294#ifdef DEBUG_CHARGER
295 dprintf(INFO, "APPSBL Charging in Progress....\n");
296#endif
Channagoud Kadabi9dc19c82015-04-23 14:20:55 -0700297 chg_prog_message_flag = TRUE;
298 }
299 }//while
300
301
Channagoud Kadabi9dc19c82015-04-23 14:20:55 -0700302 if (charger_path == PM_SMBCHG_USB_CHGPTH_PWR_PATH__DC_CHARGER)
303 {
304 //If battery is good, Toggle SHDN_N_CLEAR_CMD Reg: Set 0x1340[6] to 1 and then 0
305 err_flag = pm_smbchg_usb_chgpth_set_cmd_il(device_index, PM_SMBCHG_USBCHGPTH_CMD_IL__SHDN_N_CLEAR_CMD, TRUE);
306 err_flag = pm_smbchg_usb_chgpth_set_cmd_il(device_index, PM_SMBCHG_USBCHGPTH_CMD_IL__SHDN_N_CLEAR_CMD, FALSE);
307 }
308
Channagoud Kadabi4ab0b172015-07-13 20:12:26 -0700309 if (charge_in_progress)
310 dprintf(INFO, "APPSBL Weak Battery Charging: Done \n");
Channagoud Kadabi9dc19c82015-04-23 14:20:55 -0700311
Channagoud Kadabi4ab0b172015-07-13 20:12:26 -0700312 charge_in_progress = false;
Channagoud Kadabi9dc19c82015-04-23 14:20:55 -0700313 return err_flag;
314}
315
316
317
318pm_err_flag_type pm_smbchg_get_charger_path(uint32 device_index, pm_smbchg_usb_chgpth_pwr_pth_type* charger_path)
319{
320 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
321 boolean usbin_uv_status = TRUE;
322 boolean usbin_ov_status = TRUE;
323 boolean dcbin_uv_status = TRUE;
324 boolean dcbin_ov_status = TRUE;
325
326 //DC charger present, if DCIN_UV_RT_STS and DCIN_UV_RT_STS status is 0 (INT_RT_STS : 0x1410[1] and [0] == 0)
327 err_flag |= pm_smbchg_dc_chgpth_irq_status(device_index, PM_SMBCHG_DC_CHGPTH_DCBIN_UV, PM_IRQ_STATUS_RT, &dcbin_uv_status);
328 err_flag |= pm_smbchg_dc_chgpth_irq_status(device_index, PM_SMBCHG_DC_CHGPTH_DCBIN_OV, PM_IRQ_STATUS_RT, &dcbin_ov_status);
Channagoud Kadabi9dc19c82015-04-23 14:20:55 -0700329 //USB charger present, if USBIN_UV_RT_STS and USBIN_OV_RT_STS status is 0 ( INT_RT_STS : 0x1310[1] and [0] == 0)
330 err_flag |= pm_smbchg_usb_chgpth_irq_status(device_index, PM_SMBCHG_USB_CHGPTH_USBIN_UV, PM_IRQ_STATUS_RT, &usbin_uv_status);
Channagoud Kadabi4ab0b172015-07-13 20:12:26 -0700331 err_flag |= pm_smbchg_usb_chgpth_irq_status(device_index, PM_SMBCHG_USB_CHGPTH_USBIN_OV, PM_IRQ_STATUS_RT, &usbin_ov_status);
332
Channagoud Kadabi9dc19c82015-04-23 14:20:55 -0700333 if((dcbin_uv_status == FALSE) && (dcbin_ov_status == FALSE))
334 {
335 *charger_path = PM_SMBCHG_USB_CHGPTH_PWR_PATH__DC_CHARGER;
336 }
337 else if((usbin_uv_status == FALSE) && (usbin_ov_status == FALSE))
338 {
339 *charger_path = PM_SMBCHG_USB_CHGPTH_PWR_PATH__USB_CHARGER;
340 }
341 else
342 {
343 *charger_path = PM_SMBCHG_USB_CHGPTH_PWR_PATH__INVALID;
344 }
345
346 return err_flag;
347}
348
349
350
Channagoud Kadabi4ab0b172015-07-13 20:12:26 -0700351pm_err_flag_type pm_appsbl_chg_config_vbat_low_threshold(uint32 device_index, pm_smbchg_specific_data_type *chg_param_ptr)
Channagoud Kadabi9dc19c82015-04-23 14:20:55 -0700352{
353 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
Channagoud Kadabi4ab0b172015-07-13 20:12:26 -0700354
Channagoud Kadabi9dc19c82015-04-23 14:20:55 -0700355 pm_dbc_bootup_volt_threshold = chg_param_ptr->dbc_bootup_volt_threshold.vlowbatt_threshold;
356
357 if (chg_param_ptr->dbc_bootup_volt_threshold.enable_config == PM_ENABLE_CONFIG)
358 {
359 if (pm_dbc_bootup_volt_threshold >= PM_SMBCHG_BAT_IF_LOW_BATTERY_THRESH_INVALID)
360 {
361 err_flag = PM_ERR_FLAG__INVALID_VBATT_INDEXED;
362 return err_flag;
363 }
364
365 err_flag = pm_smbchg_bat_if_set_low_batt_volt_threshold(device_index, pm_dbc_bootup_volt_threshold);
Channagoud Kadabi4ab0b172015-07-13 20:12:26 -0700366#ifdef DEBUG_CHARGER
367 dprintf(INFO,"Configure Vlowbatt threshold");
368#endif
Channagoud Kadabi9dc19c82015-04-23 14:20:55 -0700369 }
370
Channagoud Kadabi4ab0b172015-07-13 20:12:26 -0700371 return err_flag;
Channagoud Kadabi9dc19c82015-04-23 14:20:55 -0700372}
373
Channagoud Kadabi4ab0b172015-07-13 20:12:26 -0700374#ifndef LK
Channagoud Kadabi9dc19c82015-04-23 14:20:55 -0700375pm_err_flag_type pm_sbl_config_fg_sram(uint32 device_index)
376 {
377 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
378 FgSramAddrDataEx_type *sram_data_ptr = NULL;
379 FgSramAddrDataEx_type pm_sbl_sram_data[SBL_PACKED_SRAM_CONFIG_SIZE];
380 pm_model_type pmic_model = PMIC_IS_INVALID;
381 boolean sram_enable_config_flag = FALSE;
382
383 //Check if any SRAM configuration is needed
384 sram_data_ptr = (FgSramAddrDataEx_type*)pm_target_information_get_specific_info(PM_PROP_FG_SPECIFIC_DATA);
385 CORE_VERIFY_PTR(sram_data_ptr);
386 for (int i=0; i< SBL_SRAM_CONFIG_SIZE; i++)
387 {
388 sram_enable_config_flag |= sram_data_ptr[i].EnableConfig;
389 }
390
391
392 if (sram_enable_config_flag == TRUE )
393 {
394 pmic_model = pm_get_pmic_model(device_index); //Check if PMIC exists
395 if ( (pmic_model != PMIC_IS_INVALID) || (pmic_model != PMIC_IS_UNKNOWN) )
396 {
397 //boot_log_message("BEGIN: Configure FG SRAM");
398
399 //Pre-process JEITA data
400 pm_sbl_sram_data[0].SramAddr = sram_data_ptr[0].SramAddr;
401 pm_sbl_sram_data[0].SramData = (sram_data_ptr[3].SramData << 24)|
402 (sram_data_ptr[2].SramData << 16)|
403 (sram_data_ptr[1].SramData << 8)|
404 sram_data_ptr[0].SramData;
405 pm_sbl_sram_data[0].DataOffset = sram_data_ptr[0].DataOffset;
406 pm_sbl_sram_data[0].DataSize = 4;
407 //Set JEITA threshould configuration flag
408 pm_sbl_sram_data[0].EnableConfig = sram_data_ptr[0].EnableConfig | sram_data_ptr[1].EnableConfig |
409 sram_data_ptr[2].EnableConfig | sram_data_ptr[3].EnableConfig;
410
411 //Pre-process Thermistor Beta Data
412 //thremistor_c1_coeff
413 pm_sbl_sram_data[1] = sram_data_ptr[4];
414
415 //thremistor_c2_coeff and thremistor_c3_coeff
416 pm_sbl_sram_data[2].SramAddr = sram_data_ptr[5].SramAddr;
417 pm_sbl_sram_data[2].SramData = (sram_data_ptr[6].SramData << 16) | sram_data_ptr[5].SramData;
418 pm_sbl_sram_data[2].DataOffset = sram_data_ptr[5].DataOffset;
419 pm_sbl_sram_data[2].DataSize = 4;
420 pm_sbl_sram_data[2].EnableConfig = sram_data_ptr[5].EnableConfig;
421
422 //Configure SRAM Data
423 err_flag |= PmicFgSram_ProgBurstAccessEx(device_index, pm_sbl_sram_data, SBL_PACKED_SRAM_CONFIG_SIZE);
424
425 //Test: Read Back
426 //err_flag |= PmicFgSram_Dump(device_index, 0x0454, 0x0454);
427 //err_flag |= PmicFgSram_Dump(device_index, 0x0444, 0x0448);
428 //err_flag |= PmicFgSram_Dump(device_index, 0x0448, 0x0452);
429
430 //boot_log_message("END: Configure FG SRAM");
431 }
432 }
433
434 return err_flag;
435}
436
437
438
439
440pm_err_flag_type pm_sbl_config_chg_parameters(uint32 device_index)
441{
442 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
443 static pm_smbchg_specific_data_type *chg_param_ptr;
444
445 if(chg_param_ptr == NULL)
446 {
447 chg_param_ptr = (pm_smbchg_specific_data_type*)pm_target_information_get_specific_info(PM_PROP_SMBCHG_SPECIFIC_DATA);
448 CORE_VERIFY_PTR(chg_param_ptr);
449 }
450
451 //Vlowbatt Threshold
452 // - Done on: pm_sbl_chg_config_vbat_low_threshold()
453
454 //Charger Path Input Priority
455 if (chg_param_ptr->chgpth_input_priority.enable_config == PM_ENABLE_CONFIG)
456 {
457 pm_smbchg_chgpth_input_priority_type chgpth_priority = chg_param_ptr->chgpth_input_priority.chgpth_input_priority;
458 if (chgpth_priority < PM_SMBCHG_USBCHGPTH_INPUT_PRIORITY_INVALID)
459 {
460 err_flag |= pm_smbchg_chgpth_set_input_priority(device_index, chgpth_priority);
461 }
462 else
463 {
464 err_flag |= PM_ERR_FLAG__INVALID_PARAMETER;
465 }
466 }
467
468
469 //Battery Missing Detection Source
470 if (chg_param_ptr->bat_miss_detect_src.enable_config == PM_ENABLE_CONFIG)
471 {
472 pm_smbchg_bat_miss_detect_src_type batt_missing_det_src = chg_param_ptr->bat_miss_detect_src.bat_missing_detection_src;
473 if (batt_missing_det_src < PM_SMBCHG_BAT_IF_BAT_MISS_DETECT_SRC_INVALID)
474 {
475 err_flag |= pm_smbchg_bat_if_set_bat_missing_detection_src(device_index, batt_missing_det_src);
476 }
477 else
478 {
479 err_flag |= PM_ERR_FLAG__INVALID_PARAMETER;
480 }
481 }
482
483 //WDOG Timeout
484 if (chg_param_ptr->wdog_timeout.enable_config == PM_ENABLE_CONFIG)
485 {
486 pm_smbchg_wdog_timeout_type wdog_timeout = chg_param_ptr->wdog_timeout.wdog_timeout;
487 if (wdog_timeout < PM_SMBCHG_MISC_WD_TMOUT_INVALID)
488 {
489 err_flag |= pm_smbchg_misc_set_wdog_timeout(device_index, wdog_timeout);
490 }
491 else
492 {
493 err_flag |= PM_ERR_FLAG__INVALID_PARAMETER;
494 }
495 }
496
497
498 //Enable WDOG
499 if (chg_param_ptr->enable_wdog.enable_config == PM_ENABLE_CONFIG)
500 {
501 pm_smbchg_wdog_timeout_type enable_smbchg_wdog = chg_param_ptr->enable_wdog.enable_wdog;
502 err_flag |= pm_smbchg_misc_enable_wdog(device_index, enable_smbchg_wdog);
503 }
504
505
506 //FAST Charging Current
507 if (chg_param_ptr->fast_chg_i.enable_config == PM_ENABLE_CONFIG)
508 {
509 uint32 fast_chg_i_ma = chg_param_ptr->fast_chg_i.fast_chg_i_ma;
510 if ((fast_chg_i_ma >= 300) && (fast_chg_i_ma <= 3000) )
511 {
512 err_flag |= pm_smbchg_chgr_set_fast_chg_i(device_index, fast_chg_i_ma);
513 }
514 else
515 {
516 err_flag |= PM_ERR_FLAG__INVALID_PARAMETER;
517 }
518 }
519
520 //Pre Charge Current
521 if (chg_param_ptr->pre_chg_i.enable_config == PM_ENABLE_CONFIG)
522 {
523 uint32 pre_chg_i_ma = chg_param_ptr->pre_chg_i.pre_chg_i_ma;
524 if ((pre_chg_i_ma >= 100) && (pre_chg_i_ma <= 550) )
525 {
526 err_flag |= pm_smbchg_chgr_set_pre_chg_i(device_index, pre_chg_i_ma);
527 }
528 else
529 {
530 err_flag |= PM_ERR_FLAG__INVALID_PARAMETER;
531 }
532 }
533
534 //Pre to Fast Charge Current
535 if (chg_param_ptr->pre_to_fast_chg_theshold_mv.enable_config == PM_ENABLE_CONFIG)
536 {
537 uint32 p2f_chg_mv = chg_param_ptr->pre_to_fast_chg_theshold_mv.pre_to_fast_chg_theshold_mv;
538 if ((p2f_chg_mv >= 2400) && (p2f_chg_mv <= 3000) )
539 {
540 err_flag |= pm_smbchg_chgr_set_p2f_threshold(device_index, p2f_chg_mv);
541 }
542 else
543 {
544 err_flag |= PM_ERR_FLAG__INVALID_PARAMETER;
545 }
546 }
547
548 //Float Voltage : 3600mV to 4500 mv
549 if (chg_param_ptr->float_volt_theshold_mv.enable_config == PM_ENABLE_CONFIG)
550 {
551 uint32 float_volt_mv = chg_param_ptr->float_volt_theshold_mv.float_volt_theshold_mv;
552 if ((float_volt_mv >= 3600) && (float_volt_mv <= 4500))
553 {
554 err_flag |= pm_smbchg_chgr_set_float_volt(device_index, float_volt_mv);
555 }
556 else
557 {
558 err_flag |= PM_ERR_FLAG__INVALID_PARAMETER;
559 }
560 }
561
562
563 //USBIN Input Current Limit :Valid value is 300 to 3000mAmp
564 if (chg_param_ptr->usbin_input_current_limit.enable_config == PM_ENABLE_CONFIG)
565 {
566 uint32 usbin_i_limit_ma = chg_param_ptr->usbin_input_current_limit.usbin_input_current_limit;
567 if ((usbin_i_limit_ma >= 300) && (usbin_i_limit_ma <= 3000))
568 {
569 err_flag |= pm_smbchg_usb_chgpth_set_usbin_current_limit(device_index, usbin_i_limit_ma);
570 }
571 else
572 {
573 err_flag |= PM_ERR_FLAG__INVALID_PARAMETER;
574 }
575 }
576
577
578 //DCIN Input Current Limit : valid range is 300 to 2000 mAmp
579 if (chg_param_ptr->dcin_input_current_limit.enable_config == PM_ENABLE_CONFIG)
580 {
581 uint32 dcin_i_limit_ma = chg_param_ptr->dcin_input_current_limit.dcin_input_current_limit;
582 if ((dcin_i_limit_ma >= 300) && (dcin_i_limit_ma <= 3200))
583 {
584 err_flag |= pm_smbchg_dc_chgpth_set_dcin_current_limit(device_index, dcin_i_limit_ma);
585 }
586 else
587 {
588 err_flag |= PM_ERR_FLAG__INVALID_PARAMETER;
589 }
590 }
591
592
593 return err_flag;
594}
Channagoud Kadabi4ab0b172015-07-13 20:12:26 -0700595#endif
596
597bool pm_appsbl_charging_in_progress()
598{
599 return charge_in_progress;
600}
601
602bool pm_appsbl_display_init_done()
603{
604 return display_initialized;
605}
606
607pm_err_flag_type pm_appsbl_set_dcin_suspend(uint32_t device_index)
608{
609 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
610
611 err_flag = pm_smbchg_usb_chgpth_set_cmd_il(device_index, PM_SMBCHG_USBCHGPTH_CMD_IL__DCIN_SUSPEND, TRUE);
612
613 return err_flag;
614}
Channagoud Kadabif29cb842015-08-19 14:44:25 -0700615
616static bool is_power_key_pressed()
617{
618 int count = 0;
619
620 if (pm8x41_get_pwrkey_is_pressed())
621 {
622 while(count++ < 10 && pm8x41_get_pwrkey_is_pressed())
623 thread_sleep(100);
624
625 dprintf(INFO, "Power Key Pressed\n");
626 return true;
627 }
628
629 return false;
630}
631
632bool pm_app_display_shutdown_in_prgs()
633{
634 return display_shutdown_in_prgs;
635}
636
637static int display_charger_screen()
638{
639 static bool display_init_first_time;
640
641 /* By default first time display the charger screen
642 * Wait for 5 seconds and turn off the display
643 * If user presses power key & charging is in progress display the charger screen
644 */
645 do {
646 if (!display_init_first_time || (is_power_key_pressed() && charge_in_progress))
647 {
648 /* Display charger screen */
649 target_display_init(panel_name);
650 /* wait for 5 seconds to show the charger screen */
651 display_initialized = true;
652 thread_sleep(PM_CHARGE_DISPLAY_TIMEOUT);
653 /* Shutdown the display: If the charging is complete
654 * continue boot up with display on
655 */
656 if (charge_in_progress)
657 {
658 display_shutdown_in_prgs = true;
659 target_display_shutdown();
660 display_shutdown_in_prgs = false;
661 display_initialized = false;
662 }
663 display_init_first_time = true;
664 }
665 /* Wait for 100ms before reading the pmic interrupt status
666 * again, reading the pmic interrupt status in a loop without delays
667 * reports false key presses */
668 thread_sleep(100);
669 } while (charge_in_progress);
670
671 return 0;
672}
673
674/* Create a thread to monitor power key press events
675 * and turn on/off the display for battery
676 */
677static void display_thread_initialize()
678{
679 thread_t *thr = NULL;
680 static bool is_thread_start;
681
682 if (!is_thread_start)
683 {
684 thr = thread_create("display_charger_screen", &display_charger_screen, NULL, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
685 if (!thr)
686 {
687 dprintf(CRITICAL, "Error: Could not create display charger screen thread\n");
688 return;
689 }
690 thread_resume(thr);
691
692 is_thread_start = true;
693 }
694}
Channagoud Kadabi1f5ac762015-09-18 14:19:13 -0700695
696static void pm_app_wait_for_iacs_ready(uint32_t sid)
697{
698 uint8_t iacs;
699 int max_retry = 100;
700
701 udelay(50);
702 pm_comm_read_byte(sid, 0x4454, &iacs, 0);
703 while ((iacs & 0x02) == 0)
704 {
705 max_retry--;
706 pm_comm_read_byte(2, 0x4454, &iacs, 0);
707 mdelay(5);
708 if (!max_retry)
709 {
710 dprintf(CRITICAL, "Error: IACS not ready, shutting down\n");
711 shutdown_device();
712 }
713 }
714}
715
716static int pm_app_check_for_ima_exception(uint32_t sid)
717{
718 uint8_t ima_err_sts;
719 uint8_t ima_exception_sts;
720
721 pm_comm_read_byte(sid, 0x445f, &ima_err_sts, 0);
722 pm_comm_read_byte(sid, 0x4455, &ima_exception_sts, 0);
723
724 if (ima_err_sts != 0 || (ima_exception_sts & 0x1) == 1)
725 {
726 uint8_t ima_hw_sts;
727 pm_comm_read_byte(sid, 0x4456, &ima_hw_sts, 0);
728 dprintf(CRITICAL, "ima_err_sts: %x\tima_exception_sts:%x\tima_hw_sts:%x\n", ima_err_sts, ima_exception_sts, ima_hw_sts);
729 return 1;
730 }
731
732 return 0;
733}
734
735static void pm_app_ima_read_voltage(uint32_t *voltage)
736{
737 uint8_t start_beat_count;
738 uint8_t end_beat_count;
739 uint8_t vbat;
740 uint64_t vbat_adc = 0;
741 uint32_t sid = 2; //sid for pmi8996
742 int max_retry = 5;
743
744retry:
745 //Request IMA access
746 pm_comm_write_byte(sid, 0x4450, 0xA0, 0);
747 // Single read configure
748 pm_comm_write_byte(sid, 0x4451, 0x00, 0);
749
750 pm_app_wait_for_iacs_ready(sid);
751
752 //configure SRAM access
753 pm_comm_write_byte(sid, 0x4461, 0xCC, 0);
754 pm_comm_write_byte(sid, 0x4462, 0x05, 0);
755
756 pm_app_wait_for_iacs_ready(sid);
757
758 pm_comm_read_byte(sid, 0x4457, &start_beat_count, 0);
759
760 //Read the voltage
761 pm_comm_read_byte(sid, 0x4467, &vbat, 0);
762 vbat_adc = vbat;
763 pm_comm_read_byte(sid, 0x4468, &vbat, 0);
764 vbat_adc |= (vbat << 8);
765 pm_comm_read_byte(sid, 0x4469, &vbat, 0);
766 vbat_adc |= (vbat << 16);
767 pm_comm_read_byte(sid, 0x446A, &vbat, 0);
768 vbat_adc |= (vbat << 24);
769
770 pm_app_wait_for_iacs_ready(sid);
771
772 //Look for any errors
773 if(pm_app_check_for_ima_exception(sid))
774 goto err;
775
776 pm_comm_read_byte(sid, 0x4457, &end_beat_count, 0);
777
778 if (start_beat_count != end_beat_count)
779 {
780 max_retry--;
781 if (!max_retry)
782 goto err;
783 goto retry;
784 }
785
786 //Release the ima access
787 pm_comm_write_byte(2, 0x4450, 0x00, 0);
788
789 //extract the byte1 & byte2 and convert to mv
790 vbat_adc = ((vbat_adc & 0x00ffff00) >> 8) * 152587;
791 *voltage = vbat_adc / 1000000;
792 return;
793
794err:
795 dprintf(CRITICAL, "Failed to Read the Voltage from IMA, shutting down\n");
796 shutdown_device();
797}
798
799static void pm_app_pmi8994_read_voltage(uint32_t *voltage)
800{
801 uint8_t val = 0;
802 uint8_t vbat;
803 uint64_t vbat_adc = 0;
804 uint32_t sid = 2; //sid for pmi8994
805 int max_retry = 100;
806
807 pm_comm_read_byte(sid, 0x4440, &val, 0);
808
809 //Request for FG access
810 if ((val & BIT(7)) != 1)
811 pm_comm_write_byte(sid, 0x4440, 0x80, 0);
812
813 pm_comm_read_byte(sid, 0x4410, &val, 0);
814 while((val & 0x1) == 0)
815 {
816 //sleep and retry again, this takes up to 1.5 seconds
817 max_retry--;
818 mdelay(100);
819 pm_comm_read_byte(sid, 0x4410, &val, 0);
820 if (!max_retry)
821 {
822 dprintf(CRITICAL, "Error: Failed to read from Fuel Guage, Shutting down\n");
823 shutdown_device();
824 }
825 }
826
827 //configure single read access
828 pm_comm_write_byte(sid, 0x4441, 0x00, 0);
829 //configure SRAM for voltage shadow
830 pm_comm_write_byte(sid, 0x4442, 0xCC, 0);
831 pm_comm_write_byte(sid, 0x4443, 0x05, 0);
832
833 //Read voltage from SRAM
834 pm_comm_read_byte(sid, 0x444c, &vbat, 0);
835 vbat_adc = vbat;
836 pm_comm_read_byte(sid, 0x444d, &vbat, 0);
837 vbat_adc |= (vbat << 8);
838 pm_comm_read_byte(sid, 0x444e, &vbat, 0);
839 vbat_adc |= (vbat << 16);
840 pm_comm_read_byte(sid, 0x444f, &vbat, 0);
841 vbat_adc |= (vbat << 24);
842
843 //clean up to relase sram access
844 pm_comm_write_byte(sid, 0x4440, 0x00, 0);
845 //extract byte 1 & byte 2
846 vbat_adc = ((vbat_adc & 0x00ffff00) >> 8) * 152587;
847
848 //convert the voltage to mv
849 *voltage = vbat_adc / 1000000;
850}
851