[DEV][08/May/2013]HD2 off-mode Alarm Clock(cLK)[WIP]

Search This thread

kokotas

Senior Member
Oct 23, 2007
714
1,570
Athens
  • This is an experiment - project. It is about adding off-mode alarm clock to the HD2.
    (If you don't have cLK installed (at least v1.5.1.4), then this is not applicable for you)
    Is it even possible to include something like auto-power-on in cLK, for alarm clock purposes? :)
    After ~10 months, zicoxx asked more or less the same thing:
    i want to suggest a feature for clk and our hd2..offline alarms
    So lets see what we have so far...
  • This project depends on 3 factors, (1)Kernel, (2)Android application, (3)Bootloader.
    1. Kernel
      The kernel has a function in arch\arm\mach-msm\pm.c which handles the reboot reason:
      Code:
      static int msm_reboot_call(struct notifier_block *this, unsigned long code, void *_cmd)
      {
      	if((code == SYS_RESTART) && _cmd) {
      		char *cmd = _cmd;
      		if (!strcmp(cmd, "bootloader")) {
      			restart_reason = 0x77665500;
      		} else if (!strcmp(cmd, "recovery")) {
      			restart_reason = 0x77665502;
      		} else if (!strcmp(cmd, "eraseflash")) {
      			restart_reason = 0x776655EF;
      		} else if (!strncmp(cmd, "oem-", 4)) {
      			unsigned code = simple_strtoul(cmd + 4, 0, 16) & 0xff;
      			restart_reason = 0x6f656d00 | code;
      		[COLOR="YellowGreen"]
      		//This is the proposed patch to our kernel
      		//(thanks Rick_1995 for suggesting it to bypass the time limit of 255 min)
      		} else if (!strncmp(cmd, "S", 1)) {
      			unsigned code = simple_strtoul(cmd + 1, 0, 16) & 0x00ffffff;
      			restart_reason = 0x53000000 | code;
      [/COLOR]
      		} else if (!strcmp(cmd, "force-hard")) {
      			restart_reason = 0x776655AA;
      		} else {
      			restart_reason = 0x77665501;
      		}
      	}
      	return NOTIFY_DONE;
      }
      Not being able to compile a new kernel with a change like the green text in the above function, I just used the "oem-" prefix in the reboot reason passed from the application. The downside of this is that we can't set an alarm for more than 255 min from the current time.
    2. Application
      The application is able to:
      1. reboot the device using the PowerManager class since it is signed and placed in /system/app:
        Code:
        //MinutesToSuspend is set using a TimePicker
        mPowerManager.reboot("oem-" + MinutesToSuspend);
        [COLOR="YellowGreen"]
        //In case we have a kernel with the above patch included
        mPowerManager.reboot("S" + MinutesToSuspend);[/COLOR]
      2. play the alarm when the device has booted usind the BroadcastReceiver class that will get the BOOT_COMPLETED action.
    3. Bootloader
      The bootloader (in this case cLK):
      1. detects the boot reason and decodes the MinutesToSuspend from it and enters a sort of suspend mode with a timeout equal to MinutesToSuspend converted to msec
        Code:
        if(target_check_reboot_mode() == (target_check_reboot_mode() | 0x6f656d00)) {
        	char str[16];
        	char *endptr;
        	unsigned MinutesToSuspend;
        	unsigned msecToSuspend = 0;
        	// Decode the MinutesToSuspend from the reboot_mode
        	sprintf(str, "%i", (target_check_reboot_mode() ^ 0x6f656d00));
        	MinutesToSuspend = strtol(str, &endptr, 16);
        	if (MinutesToSuspend < 3)
        		msecToSuspend = (MinutesToSuspend * 60000);
        	else
        		msecToSuspend = (MinutesToSuspend * 60000) - (120000);
        			
        	suspend_time = msecToSuspend;
        	show_multi_boot_screen = 0;
        	boot_into_recovery = 0;
        }
        [COLOR="YellowGreen"]
        //In case we have a kernel with the above patch included
        #define MARK_ALARM_TAG 	0x53000000
        if(target_check_reboot_mode() & 0xFF000000 == MARK_ALARM_TAG) {
        	uint32_t MinutesToSuspend;
        	// Decode the MinutesToSuspend from the reboot_mode
        	MinutesToSuspend = target_check_reboot_mode() ^ MARK_ALARM_TAG;
        	if (MinutesToSuspend > 3)
        		MinutesToSuspend -= 2;
        
        	suspend_time = MinutesToSuspend * 60000;
        	show_multi_boot_screen = 0;
        	boot_into_recovery = 0;
        }
        [/COLOR]
        if(suspend_time) {
        	msm_acpu_clock_init(1); // 384MHz (acpu_freq_tbl[0])
        	//Could try setting cpu clock at 245...
        	//msm_acpu_clock_init(0); // 245MHz (acpu_freq_tbl[0])
        	htcleo_suspend(suspend_time);
        }
      2. the suspend mode is implemented using this function
        Code:
        #define DS2746_SAFE_CHG_VOLTAGE	4200 // mV
        
        void htcleo_suspend(unsigned timeout)
        {
        	uint32_t	voltage;
        	//int16_t 	current;
        	bool 		usb_cable_connected;
        	time_t 		start_time;
        
        	start_time = current_time();
        	if (timeout)
        		htcleo_panel_bkl_pwr(0);
        		
        	do {
        		//current = ds2746_current(DS2746_I2C_SLAVE_ADDR, 1200);
        		voltage = ds2746_voltage(DS2746_I2C_SLAVE_ADDR);
        		usb_cable_connected = htcleo_usb_online();
        
        		if (usb_cable_connected) {
        			if (voltage < DS2746_SAFE_CHG_VOLTAGE) {
        				// If battery needs charging, set new charger state
        				if (htcleo_ac_online()) {
        					if (htcleo_charger_state() != CHG_AC ) {
        						writel(0x00080000, USB_USBCMD);
        						ulpi_write(0x48, 0x04);
        						htcleo_set_charger(CHG_AC);
        					}
        				} else {
        					if (htcleo_charger_state() != CHG_USB_LOW ) {
        						writel(0x00080001, USB_USBCMD);
        						mdelay(10);
        						htcleo_set_charger(CHG_USB_LOW);
        					}
        				}
        				// Led = solid amber
        				if (htcleo_notif_led_mode != 2)
        					thread_resume(thread_create("htcleo_notif_led_set_mode_2",
        												&htcleo_notif_led_set_mode,
        												(void *)2,
        												HIGH_PRIORITY,
        												DEFAULT_STACK_SIZE));
        			} else {
        				// Battery is full
        				if(timeout) {
        					// Set charger state to CHG_OFF_FULL_BAT
        					if (htcleo_charger_state() != CHG_OFF_FULL_BAT ) {
        						writel(0x00080001, USB_USBCMD);
        						mdelay(10);
        						htcleo_set_charger(CHG_OFF_FULL_BAT);
        					}
        					// and turn led solid green
        					if (htcleo_usb_online() && (htcleo_notif_led_mode != 1))
        						thread_resume(thread_create("htcleo_notif_led_set_mode_1",
        													&htcleo_notif_led_set_mode,
        													(void *)1,
        													HIGH_PRIORITY,
        													DEFAULT_STACK_SIZE));
        				} else {
        					// exit while if we don't have a timeout
        					break;
        				}
        			}
        		} else {
        			// Set charger state to CHG_OFF
        			if (htcleo_charger_state() != CHG_OFF ) {
        				writel(0x00080001, USB_USBCMD);
        				mdelay(10);
        				htcleo_set_charger(CHG_OFF);
        			}
        			// and turn off led
        			if (htcleo_notif_led_mode != 0)
        				thread_resume(thread_create("htcleo_notif_led_set_off",
        											&htcleo_notif_led_set_mode,
        											(void *)0,
        											HIGH_PRIORITY,
        											DEFAULT_STACK_SIZE));
        		}
        		// While in loop keep tracking if POWER button is pressed
        		// in order to (re)boot the device
        		for (int i=0; i<6; i++) {
        			if(keys_get_state(KEY_POWER)!=0) {
        				target_reboot(0);
        				return;//:)
        			}
        			mdelay(96);//total delay ~500ms per loop
        		}
        		// And check if timeout exceeded in order to reboot
        		if (timeout && (current_time() - start_time >= timeout))
        			target_reboot(0);
        	} while ( (usb_cable_connected) /* && current >= 0) */
        			||(timeout) ); // If we have a timeout this while-loop never breaks if we don't reboot.
        		
        	// Double check voltage
        	mdelay(10);
        	voltage = ds2746_voltage(DS2746_I2C_SLAVE_ADDR);
        	
        	if (voltage < DS2746_SAFE_CHG_VOLTAGE) {
        		// If battery is not full then
        		// EITHER the cable is unplugged
        		// OR the double check of voltage gave us
        		// a value less than the safe voltage.
        		// Set charger state to CHG_OFF
        		writel(0x00080001, USB_USBCMD);
        		mdelay(10);
        		htcleo_set_charger(CHG_OFF);
        	} else {
        		// If battery is full 
        		// set charger state to CHG_OFF_FULL_BAT
        		writel(0x00080001, USB_USBCMD);
        		mdelay(10);
        		htcleo_set_charger(CHG_OFF_FULL_BAT);
        		// and turn led solid green
        		if (htcleo_usb_online() && (htcleo_notif_led_mode != 1))
        			thread_resume(thread_create("htcleo_notif_led_set_mode_1",
        										&htcleo_notif_led_set_mode,
        										(void *)1,
        										HIGH_PRIORITY,
        										DEFAULT_STACK_SIZE));
        		// While usb cable is connected
        		// keep tracking if POWER button is pressed OR timeout exceeded
        		// in order to (re)boot the device
        		while (htcleo_usb_online()) {					
        			if(keys_get_state(KEY_POWER)!=0)
        				target_reboot(0);
        			/* if (timeout && (current_time() - start_time >= timeout))
        				break; */
        		}
        	}
        	
        	// If we've set a timeout and reached it, reboot the device
        	/* if (timeout && (current_time() - start_time >= timeout))
        		target_reboot(0); */
        			
        	// Shutdown the device
        	enter_critical_section();
        	platform_exit();
        	msm_proc_comm(PCOM_POWER_DOWN, 0, 0);
        	for (;;) ;
        }
  • Any suggestions or observations are welcomed!
  • This is open for everyone to use or contribute. Source is available at https://github.com/n0d3/HD2_Alarm_Clock
  • If you have to ask for an apk to test, then you may download this example's apk from here.But don't consider this as an application release thread.
 

Attachments

  • SysAlarm.apk
    214.6 KB · Views: 157
Last edited:

zicoxx

Senior Member
Dec 26, 2010
285
234
THANKS KOKOTAS to make it possible also if it is an experiment..
almost you try if it's possible to use it in our beloved hd2

now i try it,and test this version..

however there is an app for samsung phone developer from chainfire team nomoarpowah that use offline charging mode for alarm..
maybe you can check that app to see if can use something

i hope that OUR WONDERFUL DEVELOPER can do another miracle..
 

zenida

Senior Member
Jan 25, 2010
196
14
Cetraro
astragonia.altervista.org
I think since Android is between us, make a wake up alarm is really hard to do. Because we need a sub level software such as a boot loader, that listen the internal clock to turn on the device when established. I hope that you will win this challenge bro ;)
 

tb-killa

Member
Feb 25, 2008
49
25
Duisburg
THANKS KOKOTAS to make it possible also if it is an experiment..
almost you try if it's possible to use it in our beloved hd2

now i try it,and test this version..

however there is an app for samsung phone developer from chainfire team nomoarpowah that use offline charging mode for alarm..
maybe you can check that app to see if can use something

i hope that OUR WONDERFUL DEVELOPER can do another miracle..

Chainfire use the charging deamon to include his project. Because we doesnt see source which are availible for the HD2 we couldnt build something like this. Another point would be that the device comes original by windows Mobile so the process completly differs like bootloader/ init by spl/ availible functions !

If you Test chainfire app and read the thread you readout that most of them completly new written coded.
Alarm is integrated into new charging deamon so it doesnt fire device to boot up normal android ...

See it like another very small System work completly alone if device is off (charging)


Sent from my GT-I9300 using xda app-developers app
 
  • Like
Reactions: ogonzuhnina

Rick_1995

Inactive Recognized Developer
Sep 3, 2009
1,118
3,016
Santa Clara
Chainfire use the charging deamon to include his project. Because we doesnt see source which are availible for the HD2 we couldnt build something like this. Another point would be that the device comes original by windows Mobile so the process completly differs like bootloader/ init by spl/ availible functions !

If you Test chainfire app and read the thread you readout that most of them completly new written coded.
Alarm is integrated into new charging deamon so it doesnt fire device to boot up normal android ...

See it like another very small System work completly alone if device is off (charging)


Sent from my GT-I9300 using xda app-developers app

If you look closely, It should work already and NOT require any of chainfire's work. cLK is open source, Linux is open source, Android is open source (atleast the part related to this). The only issue you might think of is that the core will be in wfi state instead of pc, unless kokotas has fixed pc in clk.

Code:
unsigned code = simple_strtoul(cmd + 1, 0, 16) & 0xff000000;

Don't you think it should be

Code:
unsigned code = simple_strtoul(cmd + 1, 0, 16) & 0x00FFFFFF;

:p
 
Last edited:
  • Like
Reactions: pirlano and kokotas

ogonzuhnina

Senior Member
May 2, 2010
66
35
Warsaw
That's a good point.
I think booting into android to have a ring might be an issue in some cases
(bootloop, long time to boot android itself)

Using a recovery mode to quickly boot into and initiate an alarm that would be more reliable.

... at least I think :)

nerveless, good job and keep up the good work
 

tb-killa

Member
Feb 25, 2008
49
25
Duisburg
If you look closely, It should work already and NOT require any of chainfire's work. cLK is open source, Linux is open source, Android is open source (atleast the part related to this). The only issue you might think of is that the core will be in wfi state instead of pc, unless kokotas has fixed pc in clk.

I think we doesnt have sources of charging deamon for the HD2 right?
If we checked different threads we could read that htc doesnt public sources for Desire, others!

I agree that C(LK) could also do the Same job!

Sent from my GT-I9300 using xda app-developers app
 
Last edited:

Rick_1995

Inactive Recognized Developer
Sep 3, 2009
1,118
3,016
Santa Clara
I think we doesnt have sources of charging deamon for the HD2 right?
If we checked different threads we could read that htc doesnt public sources for Desire, others!

I agree that C(LK) could also do the Same job!

Sent from my GT-I9300 using xda app-developers app

code for charging daemon is not needed....

@kokotas, Why aren't you entering WFI state ?

You should do something like this:

Create a suspend thread and ensure there is no other thread with a higher (or the same) priority.

Inside the thread handle, there should be an infinite loop with something like this:

Code:
int suspend_task(void *args) {
	int timeout_ms = (uint32_t) args;

	htcleo_panel_bkl_pwr(0);

	while( ! (key_pressed(KEY_POWER) && (timeout_ms <= 0)) ) {
		if(usb_is_connected())
			charge_device();
		else
			arch_idle();      // WFI
		timeout_ms -= 10;
	}

	reboot();

	return 0;
}

#define MARK_ALARM_TAG 	0x53000000

void board_init(void) {

	.........

	uint32_t MinutesToSuspend = target_check_reboot_mode();

	if((MinutesToSuspend & 0xFF000000) == MARK_ALARM_TAG) {
		MinutesToSuspend &= 0x00FFFFFF;

		if (MinutesToSuspend > 3)
			MinutesToSuspend -= 2;

		thread_create("suspend", suspend_task, (void *) (MinutesToSuspend * 60000) , HIGHEST_PRIORITY, DEFAULT_STACK_SIZE)
	}

	.........

}
 
Last edited:

Rick_1995

Inactive Recognized Developer
Sep 3, 2009
1,118
3,016
Santa Clara
Honestly, never thought of Wait For Interrupt state:eek:
I'll rewrite the code based on your example and I'm thinking of creating a new branch in git in order to upload the complete source of latest cLK.

Regards!

Thanks, was wanting to update too. Just remember to create a new branch instead of an entirely new repository.

Regards :)
 

kokotas

Senior Member
Oct 23, 2007
714
1,570
Athens
FYI.
Kernel patch arch\arm\mach-msm\pm.c in the first post has already added into my git.
It was included in my latest ICS kernel r3.6.

https://github.com/tytung/android_k...mmit/23357b2a9d64a076f1b9ac664dae209748fd5ece

Thank you tytung:good:
I changed the relevant source in the application (also updated git repo) and tested successfully.

This also gave me the chance to try something else. Since it makes "oem-" prefix available to be used for other purposes, I've written another application which uses that prefix in reboot_reason for rebooting directly to any extra boot partition, with no need to press any buttons during boot-up.
Will post more info in a separate thread.
EDIT1:
Link

EDIT2:
Thanks, was wanting to update too. Just remember to create a new branch instead of an entirely new repository.

Regards :)
Just created new branch here.

Regards!
 
Last edited:

clio94

Senior Member
Jan 17, 2007
1,195
321
Kozani
Thank you for your great work.I am trying to make offmode alarm work in clk 1.5.1.5 and nand rom nexushd2 v2.8
After i press set alarm device reboots but then it gives message "error:boot selection not found.an irrecoverable error found" and it boot in clk menu and stays there.I have boot,sboot partition and i select from default kernel the boot partition
 

kokotas

Senior Member
Oct 23, 2007
714
1,570
Athens
Thank you for your great work.I am trying to make offmode alarm work in clk 1.5.1.5 and nand rom nexushd2 v2.8
After i press set alarm device reboots but then it gives message "error:boot selection not found.an irrecoverable error found" and it boot in clk menu and stays there.I have boot,sboot partition and i select from default kernel the boot partition

Hi clio94,

Did you download the SysAlarm2.apk or you're still using the first one (SysAlarm.apk)?
Now that I think of it, I should remove the first one cause it will not work as expected with the last cLK.

Regards!
 

Top Liked Posts

  • There are no posts matching your filters.
  • 26
    • This is an experiment - project. It is about adding off-mode alarm clock to the HD2.
      (If you don't have cLK installed (at least v1.5.1.4), then this is not applicable for you)
      Is it even possible to include something like auto-power-on in cLK, for alarm clock purposes? :)
      After ~10 months, zicoxx asked more or less the same thing:
      i want to suggest a feature for clk and our hd2..offline alarms
      So lets see what we have so far...
    • This project depends on 3 factors, (1)Kernel, (2)Android application, (3)Bootloader.
      1. Kernel
        The kernel has a function in arch\arm\mach-msm\pm.c which handles the reboot reason:
        Code:
        static int msm_reboot_call(struct notifier_block *this, unsigned long code, void *_cmd)
        {
        	if((code == SYS_RESTART) && _cmd) {
        		char *cmd = _cmd;
        		if (!strcmp(cmd, "bootloader")) {
        			restart_reason = 0x77665500;
        		} else if (!strcmp(cmd, "recovery")) {
        			restart_reason = 0x77665502;
        		} else if (!strcmp(cmd, "eraseflash")) {
        			restart_reason = 0x776655EF;
        		} else if (!strncmp(cmd, "oem-", 4)) {
        			unsigned code = simple_strtoul(cmd + 4, 0, 16) & 0xff;
        			restart_reason = 0x6f656d00 | code;
        		[COLOR="YellowGreen"]
        		//This is the proposed patch to our kernel
        		//(thanks Rick_1995 for suggesting it to bypass the time limit of 255 min)
        		} else if (!strncmp(cmd, "S", 1)) {
        			unsigned code = simple_strtoul(cmd + 1, 0, 16) & 0x00ffffff;
        			restart_reason = 0x53000000 | code;
        [/COLOR]
        		} else if (!strcmp(cmd, "force-hard")) {
        			restart_reason = 0x776655AA;
        		} else {
        			restart_reason = 0x77665501;
        		}
        	}
        	return NOTIFY_DONE;
        }
        Not being able to compile a new kernel with a change like the green text in the above function, I just used the "oem-" prefix in the reboot reason passed from the application. The downside of this is that we can't set an alarm for more than 255 min from the current time.
      2. Application
        The application is able to:
        1. reboot the device using the PowerManager class since it is signed and placed in /system/app:
          Code:
          //MinutesToSuspend is set using a TimePicker
          mPowerManager.reboot("oem-" + MinutesToSuspend);
          [COLOR="YellowGreen"]
          //In case we have a kernel with the above patch included
          mPowerManager.reboot("S" + MinutesToSuspend);[/COLOR]
        2. play the alarm when the device has booted usind the BroadcastReceiver class that will get the BOOT_COMPLETED action.
      3. Bootloader
        The bootloader (in this case cLK):
        1. detects the boot reason and decodes the MinutesToSuspend from it and enters a sort of suspend mode with a timeout equal to MinutesToSuspend converted to msec
          Code:
          if(target_check_reboot_mode() == (target_check_reboot_mode() | 0x6f656d00)) {
          	char str[16];
          	char *endptr;
          	unsigned MinutesToSuspend;
          	unsigned msecToSuspend = 0;
          	// Decode the MinutesToSuspend from the reboot_mode
          	sprintf(str, "%i", (target_check_reboot_mode() ^ 0x6f656d00));
          	MinutesToSuspend = strtol(str, &endptr, 16);
          	if (MinutesToSuspend < 3)
          		msecToSuspend = (MinutesToSuspend * 60000);
          	else
          		msecToSuspend = (MinutesToSuspend * 60000) - (120000);
          			
          	suspend_time = msecToSuspend;
          	show_multi_boot_screen = 0;
          	boot_into_recovery = 0;
          }
          [COLOR="YellowGreen"]
          //In case we have a kernel with the above patch included
          #define MARK_ALARM_TAG 	0x53000000
          if(target_check_reboot_mode() & 0xFF000000 == MARK_ALARM_TAG) {
          	uint32_t MinutesToSuspend;
          	// Decode the MinutesToSuspend from the reboot_mode
          	MinutesToSuspend = target_check_reboot_mode() ^ MARK_ALARM_TAG;
          	if (MinutesToSuspend > 3)
          		MinutesToSuspend -= 2;
          
          	suspend_time = MinutesToSuspend * 60000;
          	show_multi_boot_screen = 0;
          	boot_into_recovery = 0;
          }
          [/COLOR]
          if(suspend_time) {
          	msm_acpu_clock_init(1); // 384MHz (acpu_freq_tbl[0])
          	//Could try setting cpu clock at 245...
          	//msm_acpu_clock_init(0); // 245MHz (acpu_freq_tbl[0])
          	htcleo_suspend(suspend_time);
          }
        2. the suspend mode is implemented using this function
          Code:
          #define DS2746_SAFE_CHG_VOLTAGE	4200 // mV
          
          void htcleo_suspend(unsigned timeout)
          {
          	uint32_t	voltage;
          	//int16_t 	current;
          	bool 		usb_cable_connected;
          	time_t 		start_time;
          
          	start_time = current_time();
          	if (timeout)
          		htcleo_panel_bkl_pwr(0);
          		
          	do {
          		//current = ds2746_current(DS2746_I2C_SLAVE_ADDR, 1200);
          		voltage = ds2746_voltage(DS2746_I2C_SLAVE_ADDR);
          		usb_cable_connected = htcleo_usb_online();
          
          		if (usb_cable_connected) {
          			if (voltage < DS2746_SAFE_CHG_VOLTAGE) {
          				// If battery needs charging, set new charger state
          				if (htcleo_ac_online()) {
          					if (htcleo_charger_state() != CHG_AC ) {
          						writel(0x00080000, USB_USBCMD);
          						ulpi_write(0x48, 0x04);
          						htcleo_set_charger(CHG_AC);
          					}
          				} else {
          					if (htcleo_charger_state() != CHG_USB_LOW ) {
          						writel(0x00080001, USB_USBCMD);
          						mdelay(10);
          						htcleo_set_charger(CHG_USB_LOW);
          					}
          				}
          				// Led = solid amber
          				if (htcleo_notif_led_mode != 2)
          					thread_resume(thread_create("htcleo_notif_led_set_mode_2",
          												&htcleo_notif_led_set_mode,
          												(void *)2,
          												HIGH_PRIORITY,
          												DEFAULT_STACK_SIZE));
          			} else {
          				// Battery is full
          				if(timeout) {
          					// Set charger state to CHG_OFF_FULL_BAT
          					if (htcleo_charger_state() != CHG_OFF_FULL_BAT ) {
          						writel(0x00080001, USB_USBCMD);
          						mdelay(10);
          						htcleo_set_charger(CHG_OFF_FULL_BAT);
          					}
          					// and turn led solid green
          					if (htcleo_usb_online() && (htcleo_notif_led_mode != 1))
          						thread_resume(thread_create("htcleo_notif_led_set_mode_1",
          													&htcleo_notif_led_set_mode,
          													(void *)1,
          													HIGH_PRIORITY,
          													DEFAULT_STACK_SIZE));
          				} else {
          					// exit while if we don't have a timeout
          					break;
          				}
          			}
          		} else {
          			// Set charger state to CHG_OFF
          			if (htcleo_charger_state() != CHG_OFF ) {
          				writel(0x00080001, USB_USBCMD);
          				mdelay(10);
          				htcleo_set_charger(CHG_OFF);
          			}
          			// and turn off led
          			if (htcleo_notif_led_mode != 0)
          				thread_resume(thread_create("htcleo_notif_led_set_off",
          											&htcleo_notif_led_set_mode,
          											(void *)0,
          											HIGH_PRIORITY,
          											DEFAULT_STACK_SIZE));
          		}
          		// While in loop keep tracking if POWER button is pressed
          		// in order to (re)boot the device
          		for (int i=0; i<6; i++) {
          			if(keys_get_state(KEY_POWER)!=0) {
          				target_reboot(0);
          				return;//:)
          			}
          			mdelay(96);//total delay ~500ms per loop
          		}
          		// And check if timeout exceeded in order to reboot
          		if (timeout && (current_time() - start_time >= timeout))
          			target_reboot(0);
          	} while ( (usb_cable_connected) /* && current >= 0) */
          			||(timeout) ); // If we have a timeout this while-loop never breaks if we don't reboot.
          		
          	// Double check voltage
          	mdelay(10);
          	voltage = ds2746_voltage(DS2746_I2C_SLAVE_ADDR);
          	
          	if (voltage < DS2746_SAFE_CHG_VOLTAGE) {
          		// If battery is not full then
          		// EITHER the cable is unplugged
          		// OR the double check of voltage gave us
          		// a value less than the safe voltage.
          		// Set charger state to CHG_OFF
          		writel(0x00080001, USB_USBCMD);
          		mdelay(10);
          		htcleo_set_charger(CHG_OFF);
          	} else {
          		// If battery is full 
          		// set charger state to CHG_OFF_FULL_BAT
          		writel(0x00080001, USB_USBCMD);
          		mdelay(10);
          		htcleo_set_charger(CHG_OFF_FULL_BAT);
          		// and turn led solid green
          		if (htcleo_usb_online() && (htcleo_notif_led_mode != 1))
          			thread_resume(thread_create("htcleo_notif_led_set_mode_1",
          										&htcleo_notif_led_set_mode,
          										(void *)1,
          										HIGH_PRIORITY,
          										DEFAULT_STACK_SIZE));
          		// While usb cable is connected
          		// keep tracking if POWER button is pressed OR timeout exceeded
          		// in order to (re)boot the device
          		while (htcleo_usb_online()) {					
          			if(keys_get_state(KEY_POWER)!=0)
          				target_reboot(0);
          			/* if (timeout && (current_time() - start_time >= timeout))
          				break; */
          		}
          	}
          	
          	// If we've set a timeout and reached it, reboot the device
          	/* if (timeout && (current_time() - start_time >= timeout))
          		target_reboot(0); */
          			
          	// Shutdown the device
          	enter_critical_section();
          	platform_exit();
          	msm_proc_comm(PCOM_POWER_DOWN, 0, 0);
          	for (;;) ;
          }
    • Any suggestions or observations are welcomed!
    • This is open for everyone to use or contribute. Source is available at https://github.com/n0d3/HD2_Alarm_Clock
    • If you have to ask for an apk to test, then you may download this example's apk from here.But don't consider this as an application release thread.
    10
    FYI.
    Kernel patch arch\arm\mach-msm\pm.c in the first post has already added into my git.
    It was included in my latest ICS kernel r3.6.

    https://github.com/tytung/android_k...mmit/23357b2a9d64a076f1b9ac664dae209748fd5ece
    7
    I think we doesnt have sources of charging deamon for the HD2 right?
    If we checked different threads we could read that htc doesnt public sources for Desire, others!

    I agree that C(LK) could also do the Same job!

    Sent from my GT-I9300 using xda app-developers app

    code for charging daemon is not needed....

    @kokotas, Why aren't you entering WFI state ?

    You should do something like this:

    Create a suspend thread and ensure there is no other thread with a higher (or the same) priority.

    Inside the thread handle, there should be an infinite loop with something like this:

    Code:
    int suspend_task(void *args) {
    	int timeout_ms = (uint32_t) args;
    
    	htcleo_panel_bkl_pwr(0);
    
    	while( ! (key_pressed(KEY_POWER) && (timeout_ms <= 0)) ) {
    		if(usb_is_connected())
    			charge_device();
    		else
    			arch_idle();      // WFI
    		timeout_ms -= 10;
    	}
    
    	reboot();
    
    	return 0;
    }
    
    #define MARK_ALARM_TAG 	0x53000000
    
    void board_init(void) {
    
    	.........
    
    	uint32_t MinutesToSuspend = target_check_reboot_mode();
    
    	if((MinutesToSuspend & 0xFF000000) == MARK_ALARM_TAG) {
    		MinutesToSuspend &= 0x00FFFFFF;
    
    		if (MinutesToSuspend > 3)
    			MinutesToSuspend -= 2;
    
    		thread_create("suspend", suspend_task, (void *) (MinutesToSuspend * 60000) , HIGHEST_PRIORITY, DEFAULT_STACK_SIZE)
    	}
    
    	.........
    
    }
    7
    Also unfortunatelly battery drains quickly.I set alarm for 0830am at 0300am with 100% battery and at 0830am it opened with battery 5%.I thought that i did something wrong and i tried again today afternoon.I set alarm for 1 hour later and battery from 96% went to 84% when phone came up.

    lk doesn't support power collapse as far as i know, while linux does. I will be adding power management to clk-2 from the linux driver, Although it shouldn't be hard to add it to current branch. Also as far as i can see, it doesn't gate a lot of clocks which are still left running in the system.