/* Charging ! */

while (1) {

/*

* At the most time, fuel gauge is usually a i2c device, we

* should avoid read/write all the time. We had better set

* poll seconds to update fuel gauge info.

*/

if (!first_poll_fg && get_timer(delta) < FUEL_GAUGE_POLL_MS)

goto show_images;

delta = get_timer(0);

debug("step1 (%d)...

", screen_on);

/*

* Most fuel gauge is I2C interface, it shouldn't be interrupted

* during tansfer. The power key event depends on interrupt, so

* so we should disable local irq when update fuel gauge.

*/

local_irq_disable();

/* Step1: Is charging now ? */

charging = fuel_gauge_get_chrg_online(fg);

if (charging <= 0) {

printf("Not charging, online=%d. Shutdown...

",

charging);

/* wait uart flush before shutdown */

mdelay(5);

/* PMIC shutdown */

pmic_shutdown(pmic);

printf("Cpu should never reach here, shutdown failed !

");

continue;

}

debug("step2 (%d)... show_idx=%d

", screen_on, show_idx);

/* Step2: get soc and voltage */

soc = fuel_gauge_get_soc(fg);

if (soc < 0 || soc > 100) {

printf("get soc failed: %d

", soc);

continue;

}

voltage = fuel_gauge_get_voltage(fg);

if (voltage < 0) {

printf("get voltage failed: %d

", voltage);

continue;

}

current = fuel_gauge_get_current(fg);

if (current == -ENOSYS) {

printf("get current failed: %d

", current);

continue;

}

first_poll_fg = 0;

local_irq_enable();

show_images:

/*

* Just for debug, otherwise there will be nothing output which

* is not good to know what happen.

*/

if (!debug_start)

debug_start = get_timer(0);

if (get_timer(debug_start) > 20000) {

debug_start = get_timer(0);

printf("[%8ld]: soc=%d%%, vol=%dmv, c=%dma, online=%d, screen_on=%d

",

get_timer(0)/1000, soc, voltage,

current, charging, screen_on);

}

/*

* If ever lowpower screen off, force screen_on=false, which

* means key event can't modify screen_on, only voltage higher

* then threshold can update screen_on=true;

*/

if (ever_lowpower_screen_off)

screen_on = false;

/*

* Auto turn on screen when voltage higher than Vol screen on.

* 'ever_lowpower_screen_off' means enter while loop with

* screen off.

*/

if ((ever_lowpower_screen_off) &&

(voltage > pdata->screen_on_voltage)) {

ever_lowpower_screen_off = false;

screen_on = true;

show_idx = IMAGE_SHOW_RESET;

}

/*

* IMAGE_SHOW_RESET means show_idx show be update by start_idx.

* When short key pressed event trigged, we will set show_idx

* as IMAGE_SHOW_RESET which updates images index from start_idx

* that calculate by current soc.

*/

if (show_idx == IMAGE_SHOW_RESET) {

for (i = 0; i < image_num - 2; i++) {

/* Find out which image we start to show */

if ((soc >= image[i].soc) &&

(soc < image[i + 1].soc)) {

start_idx = i;

break;

}

if (soc >= 100) {

start_idx = image_num - 2;

break;

}

}

debug("%s: show_idx=%d, screen_on=%d

",

__func__, show_idx, screen_on);

/* Mark start index and start time */

show_idx = start_idx;

show_start = get_timer(0);

}

debug("step3 (%d)... show_idx=%d

", screen_on, show_idx);

/* Step3: show images */

if (screen_on) {

/* Don't call 'charge_show_bmp' unless image changed */

if (old_show_idx != show_idx) {

old_show_idx = show_idx;

debug("SHOW: %s

", image[show_idx].name);

charge_show_bmp(image[show_idx].name);

}

/* Re calculate timeout to off screen */

if (priv->auto_screen_off_timeout == 0)

priv->auto_screen_off_timeout = get_timer(0);

} else {

priv->auto_screen_off_timeout = 0;

system_suspend_enter(pdata);

}

mdelay(5);

/* Every image shows period */

if (get_timer(show_start) > image[show_idx].period) {

show_start = get_timer(0);

/* Update to next image */

show_idx++;

if (show_idx > (image_num - 2))

show_idx = IMAGE_SHOW_RESET;

}

debug("step4 (%d)...

", screen_on);

/*

* Step4: check key event.

*

* Short key event: turn on/off screen;

* Long key event: show logo and boot system or still charging.

*/

key_state = check_key_press(dev);

if (key_state == KEY_PRESS_DOWN) {

old_show_idx = IMAGE_SHOW_RESET;

/* NULL means show nothing, ie. turn off screen */

if (screen_on)

charge_show_bmp(NULL);

/*

* Clear current image index, and show image

* from start_idx

*/

show_idx = IMAGE_SHOW_RESET;

/*

* We turn off screen by charge_show_bmp(NULL), so we

* should tell while loop to stop show images any more.

*

* If screen_on=false, means this short key pressed

* event turn on the screen and we need show images.

*

* If screen_on=true, means this short key pressed

* event turn off the screen and we never show images.

*/

if (screen_on)

screen_on = false;

else

screen_on = true;

} else if (key_state == KEY_PRESS_LONG_DOWN) {

/* Only long pressed while screen off needs screen_on true */

if (!screen_on)

screen_on = true;

/* Is able to boot now ? */

if (soc < pdata->exit_charge_level) {

printf("soc=%d%%, threshold soc=%d%%

",

soc, pdata->exit_charge_level);

printf("Low power, unable to boot, charging...

");

show_idx = image_num - 1;

continue;

}

if (voltage < pdata->exit_charge_voltage) {

printf("voltage=%dmv, threshold voltage=%dmv

",

voltage, pdata->exit_charge_voltage);

printf("Low power, unable to boot, charging...

");

show_idx = image_num - 1;

continue;

}

/* Success exit charging */

printf("Exit charge animation...

");

charge_show_logo();

break;

} else {

/* Do nothing */

}

debug("step5 (%d)...

", screen_on);

/* Step5: Exit by ctrl+c */

if (ctrlc()) {

if (voltage >= pdata->screen_on_voltage)

charge_show_logo();

printf("Exit charge, due to ctrl+c

");

break;

}

}

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐