#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <time.h>


void main()
{
    FILE *stat;
    FILE *setcpu;
    FILE *setcore;
    unsigned int cpuload;
    u_int64_t load, total, oload, ototal;
    u_int64_t user, nice, system, idle;
    int i;
    int repeat=1;
    int prevfreq = 0;
    int setfreq = 0;
    
    FILE *log;
    if ((log = fopen("/var/log/speedstep", "r")) == NULL)
    {
	fprintf(stderr, "Failed to open /var/log/speedstep. Exiting\n");
	exit(1);
    }

    if ((stat = fopen("/proc/stat", "r")) == NULL)
    {
	fprintf(stderr, "Failed to open /proc/stat. Exiting\n");
	exit(1);
    }
    fscanf(stat, "%*s %Ld %Ld %Ld %Ld", &user, &nice, &system, &idle);
    fclose(stat);

    oload = user + nice + system;
    ototal = user + nice + system + idle;

    while (repeat)
    {

	sleep(3);

	if ((stat = fopen("/proc/stat", "r")) == NULL)
	{
		fprintf(stderr, "Failed to open /proc/stat. Exiting\n");
		exit(1);
	}
	fscanf(stat, "%*s %Ld %Ld %Ld %Ld", &user, &nice, &system, &idle);
	fclose(stat);
	fprintf(log, "User %Ld Nice %Ld System %Ld Idle %Ld\n", user, nice, system, idle);

	load = user + nice + system;
	total = user + nice + system + idle;
	    
	if (ototal == 0)	
		cpuload = 0;
	else
		cpuload = (100 * (load - oload)) / (total - ototal);

	fprintf(log, "CPU %d Load %Ld Total %Ld\n", cpuload, load, total);

	oload=load;
	ototal=total;
		
	if (cpuload > 80)
	{
		setfreq = 624;
	}
	else if (cpuload >50)
	{
		setfreq = 520;
	}
	else if (cpuload >20)
	{
		setfreq = 416;
	}
	else
	{
		setfreq = 208;
	}
	
	if (setfreq == prevfreq)
		continue;

	fprintf(log, "Set to %d MHz\n", setfreq);
	if ((setcpu = fopen("/proc/zaurus/CCCR", "r+b")) == NULL)
	{
		fprintf(stderr, "Failed to open /proc/zaurus/CCCR. Exiting\n");
		exit(1);
	}
 
	if ((setcore = fopen("/proc/zaurus/VCORE", "r+b")) == NULL)
	{
		fclose(setcpu);
		fprintf(stderr, "Failed to open /proc/zaurus/VCORE. Exiting\n");
		exit(1);
	}
    
    	/*
	    FREQ_TAB  = ["104", "208", "312", "416", "520", "624"]
	    CCCR_TAB  = ["2000204", "2000206", "2000208", "2000210", "2000214", "2000218"]
	    VCORE_TAB = ["04", "06", "08", "0a", "0c", "0e"]
    	*/
    	switch (setfreq)
    	{
    	case 624:
		fputs("2000218\0",setcpu);
		fputs("0E\0",setcore);
    		break;
    	case 520:
		fputs("2000214\0",setcpu);
		fputs("0C\0",setcore);
    		break;
    	case 416:
		fputs("2000210\0",setcpu);
		fputs("0A\0",setcore);
    		break;
    	case 104:
		fputs("2000204",setcpu);
		fputs("04\0",setcore);
    		break;
    	case 208:
    	default:
		fputs("2000206\0",setcpu);
		fputs("06\0",setcore);
    		break;
	}
	fclose(setcpu);
	fclose(setcore);

	prevfreq = setfreq;
    }
    fclose(log);
}	
