do full frame before menu for proper bg
[libpicofe.git] / gp2x / soc_pollux.c
index 64971a2..2cda031 100644 (file)
@@ -19,6 +19,7 @@
 static volatile unsigned short *memregs;
 static volatile unsigned long  *memregl;
 static int memdev = -1;
+static int battdev = -1;
 
 extern void *gp2x_screens[4];
 
@@ -190,6 +191,49 @@ static void set_lcd_gamma_(int g100, int A_SNs_curve)
        /* hm, the LCD possibly can do it (but not POLLUX) */
 }
 
+static int gp2x_read_battery_(void)
+{
+       unsigned short magic_val = 0;
+
+       if (battdev < 0)
+               return -1;
+       if (read(battdev, &magic_val, sizeof(magic_val)) != sizeof(magic_val))
+               return -1;
+       switch (magic_val) {
+       default:
+       case 1: return 100;
+       case 2: return 66;
+       case 3: return 40;
+       case 4: return 0;
+       }
+}
+
+#define TIMER_BASE3 0x1980
+#define TIMER_REG(x) memregl[(TIMER_BASE3 + x) >> 2]
+
+unsigned int gp2x_get_ticks_us_(void)
+{
+       TIMER_REG(0x08) = 0x4b;  /* run timer, latch value */
+       return TIMER_REG(0);
+}
+
+unsigned int gp2x_get_ticks_ms_(void)
+{
+       /* approximate /= 1000 */
+       unsigned long long v64;
+       v64 = (unsigned long long)gp2x_get_ticks_us_() * 4294968;
+       return v64 >> 32;
+}
+
+static void timer_cleanup(void)
+{
+       TIMER_REG(0x40) = 0x0c; /* be sure clocks are on */
+       TIMER_REG(0x08) = 0x23; /* stop the timer, clear irq in case it's pending */
+       TIMER_REG(0x00) = 0;    /* clear counter */
+       TIMER_REG(0x40) = 0;    /* clocks off */
+       TIMER_REG(0x44) = 0;    /* dividers back to default */
+}
+
 void pollux_init(void)
 {
        struct fb_fix_screeninfo fbfix;
@@ -242,7 +286,19 @@ void pollux_init(void)
        fb_work_buf = 0;
        g_screen_ptr = gp2x_screens[0];
 
-       pllsetreg0 = memregl[0xf004];
+       battdev = open("/dev/pollux_batt", O_RDONLY);
+       if (battdev < 0)
+               perror("Warning: could't open pollux_batt");
+
+       /* setup timer */
+       if (TIMER_REG(0x08) & 8)
+               timer_cleanup();
+
+       TIMER_REG(0x44) = 0x922; /* using PLL1, divider value 147 */
+       TIMER_REG(0x40) = 0x0c;  /* clocks on */
+       TIMER_REG(0x08) = 0x6b;  /* run timer, clear irq, latch value */
+
+       pllsetreg0 = memregl[0xf004>>2];
        memtimex_old[0] = memregs[0x14802>>1];
        memtimex_old[1] = memregs[0x14804>>1];
 
@@ -261,6 +317,10 @@ void pollux_init(void)
 
        set_ram_timings = set_ram_timings_;
        unset_ram_timings = unset_ram_timings_;
+       gp2x_read_battery = gp2x_read_battery_;
+
+       gp2x_get_ticks_ms = gp2x_get_ticks_ms_;
+       gp2x_get_ticks_us = gp2x_get_ticks_us_;
 }
 
 void pollux_finish(void)
@@ -279,5 +339,7 @@ void pollux_finish(void)
 
        munmap((void *)memregs, 0x20000);
        close(memdev);
+       if (battdev >= 0)
+               close(battdev);
 }