Caanoo / WIZ Howto: Turn Off The Wiz In Software


Orkie

Super Duper Mega GP Mania
Joined
Mar 22, 2006
Messages
2,376
Location
UK
Website
www.gp2x.dev
Code:
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
 
int main(int argc, char* argv[]) {
	int fd = open("/dev/GPIO", O_RDWR);
	ioctl(fd, 2);
}

Not very exciting, but a couple of people have asked me how to do this. I'll put it into libcastor sometime when I have time to see what registers it touches.

drivers/char/pollux_key.c in the kernel source if anybody is interested in finding that out for me :D.
 
nice nice. do you know how to check the lock state of the power-button, too? i'd like to have that to turn off the display in some of the emulators (*screen-burn paranoia*)
 
Hah, yes. After we spent so long arsing around with it.

Just something to watch out for when using this (which should be fairly obvious really), call sync() first to flush the disk cache and make sure nothing gets corrupted.

No, I don't know about the lock thing, I will have a look if I get chance.
 
Something for wejp :D
Implement a sleep-mode in GMU, which shuts down the system after playing music for a given amount of time :)
 
EvilDragon said:
Something for wejp :D
Implement a sleep-mode in GMU, which shuts down the system after playing music for a given amount of time :)
Yes, this is very helpful indeed. :)

Although, I think it would be nice to have a working shutdown command which can be executed form the shell and shuts down the Wiz in a graceful way. I mean a command that sends all processes a kill command, waits a moment for everything to exit, unmounts filesystems that have been mounted r/w, and then turns the machine off. Just like the shutdown command usually would work.
Now, knowing how to turn off the machine, this shouldn't be very difficult to implement. :)
 
Last edited by a moderator:
Orkie said:
No, I don't know about the lock thing, I will have a look if I get chance.

it seems it's just

Code:
int hold=0;
ioctl(fd, 11,&hold);

need to check on the wiz later. anyone knows how to turn of the display in software? :)
 
Last edited by a moderator:
Set bit 1 of C000_4000h to 0, then bit 3 to 1. That will kill the MLC. Alternatively bit 15 of C000_308C to 0 to kill the DPC.

EDIT: Incidentally, the hold state can also be read with GPIO A10.
 
For your library orkie:

Code:
/*

--- minimal shutdown tool for wiz ----

Shutdowns the wiz without further warning or contemplating.

created by StarG using hints given by JustBurn & Orkie upon request for DerDritte

some random hints i've received & taken from the kernel source:

[00:47] Orkie: you need to set bit 7 of C001_9008h low, and bit 7 of C001_9004h high
[00:52] JustBurn: make it 0x20000

#define GPIO_POWER_OFF			POLLUX_GPA18
#define GPIO_LCD_AVDD			POLLUX_GPB14
#define GPIO_HOLD_KEY           POLLUX_GPA10

#define POLLUX_GPIO_FUNC0    (0x20)
#define POLLUX_GPIO_FUNC1    (0x24)

#define POLLUX_PA_GPIO	   (0xC000A000)

#define POLLUX_GPIO_OUT	     (0x00)
#define POLLUX_GPIO_PAD      (0x18)

Address : GPIOA: C000_A000h / GPIOB: C000_A040h / GPIOC: C000_A080h

from drivers/char/pollux_key.c
pollux_gpio_setpin(GPIO_LCD_AVDD ,0);
pollux_set_gpio_func(POLLUX_GPA18, POLLUX_GPIO_MODE_GPIO);
pollux_gpio_set_inout(POLLUX_GPA18, POLLUX_GPIO_OUTPUT_MODE);
pollux_gpio_setpin(GPIO_POWER_OFF ,0);

*use at your own risk*

Be cautious that the sd and/or the nand might still be unsynched and might get corrupted,
although it syncs at the beginning so you might be fine.

------------------------------

*/

#include <stdio.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>

int main(void) {
	unsigned int* DEV_mem;
	volatile unsigned long* MEM_regs32;

	// we're going to flush caches before
	sync();

	// actually should be broadcasted to all open shells - here: just the caller's shell
	printf("Halting system. Prepare to be booted :]\n");

	// open up memory device for mmapping
	DEV_mem = (unsigned int*) PrivoxyWindowOpen("/dev/mem", O_RDWR);
	if (DEV_mem == -1)
	{
		perror("register access failed!");
		return 1;
	}

	// map in the pollux registers
	MEM_regs32 = (volatile unsigned long *)mmap(0, 0x20000, PROT_READ | PROT_WRITE, MAP_SHARED, (unsigned int) DEV_mem, 0xC0000000);
	if (MEM_regs32 == MAP_FAILED)
	{
		perror("memory mapping failed!");
		close(DEV_mem);
		return 1;
	}

	// set GPIO_LCD_AVDD (B14) to low -> turn display off
 	MEM_regs32[0x0000A040 >> 2] &= ~(1UL << 14);

	// access mode register and set pin A18 to normal gpio mode (0x00)
 	MEM_regs32[0x0000A024 >> 2] &= ~((1UL << 5) + (1UL << 4));

	// set pin A18 to be outbound (high)
 	MEM_regs32[0x0000A004 >> 2] |= (1UL << 18);

	// set GPIO_POWER_OFF (A18) to low -> hasta la vista, baby!
 	MEM_regs32[0x0000A000 >> 2] &= ~(1UL << 18);

	// ----- POWER IS GOING DOWN ------

	// clean up ... (well even in death we do :) 
	munmap((void *)MEM_regs32, 0x20000);
	close(DEV_mem);

	// operation succeeded... not that it should matter to anyone or anything :]
	return 0;
}

And this resets the device:

Code:
 	MEM_regs32[0x0000F07C >> 2] |= ((1UL << 13) + (1UL << 12));

Precompiled variant + makefile here here.

EDIT: added link to precompiled archive
 
Is there any way to put the console on suspend mode using some registers?

As I see on databook the pollux admits an idle and a suspend mode but I don't understand how to use it, or if these states are compatible with programs in memory...

Only could turnoff/reset the console using F07Ch bit 1 :p
 
Back
Top