LCD and backlight power management
The backlight is control by ioctl() calls on /dev/disp. All calls take the form
typedef struct {
int reg;
int val;
int par1;
int par2;
} lcd_disp_t;
int op = /* operation code */
lcd_disp_t t = { /* parameters*/ };
int f = open (DEV_DISP, O_RDONLY);
ioctl (f, op, &t);
The following operation codes are useful
// Set brightness #define DISP_SET_BCKL_LEV _IOWR ( 'D', 9, lcd_disp_t*) // Enable display hardware #define DISP_ENABLE_DISP _IOWR ( 'D', 10, lcd_disp_t*) // Enable backlight #define DISP_ENABLE_BCKL _IOWR ( 'D', 11, lcd_disp_t*)
Each of these takes a single value in the par1 member of struct lcd_disp_t. Parameter values are as follows:
DISP_ENABLE_DISP: 1 (on) or 0 (off)
DISP_ENABLE_BCKL: 1 (on) or 0 (off)
DISP_SET_BCKL_LEVEl: 0 (off) to probably 500.
There is some uncertainty about what values are appropriate for display brightness. Minimum brightness is 1, and maximum is probably 500, although there does not appear to be a uniform spread of useful values between these extremes. There isn't a huge range of brightness anyway. AVOS only provides 3 levels and, although there probably are more, it isn't obvious that there are _usefully_ more.
The display power itself is controlled by ioctl() calls on the framebuffer device /dev/fb. I am unsure of the exact purpose of all of these. However, the following piece of code, derived from a sample provided by Archos, should shut the display and backlight down completely.
#define FBIO_OUTPUT_ENABLE _IOW ( 'F', 0x25, u_int32_t)
#define VESA_NOBLANKING 0
#define VESA_POWERDOWN 3
#define FBIOBLANK 0x4611
#define FB_BLANK_POWERDOWN VESA_POWERDOWN + 1
#define FB_BLANK_NORMAL VESA_NOBLANKING + 1
#define FB_BLANK_UNBLANK VESA_NOBLANKING + 0
void turnOffDisplay()
{
int osd_fd = open (DEV_FB, O_RDONLY);
if (osd_fd <= 0)
{
// Handle error
return;
}
int disp_fd = open (DEV_DISP, O_RDONLY);
if (disp_fd <= 0)
{
close (osd_fd);
// Handle error
return;
}
int fls = 0;
lcd_disp_t lcdOff = { .par1 = 0 };
ioctl (disp_fd, DISP_ENABLE_BCKL, &lcdOff);
ioctl (osd_fd, FBIO_GFX_LAYER_ENABLE, &fls);
ioctl (osd_fd, FBIOBLANK, FB_BLANK_POWERDOWN);
ioctl (osd_fd, FBIO_OUTPUT_ENABLE, &fls);
ioctl (disp_fd, DISP_ENABLE_DISP, &lcdOff);
}
And to switch it back on again:
void turnOnDisplay()
{
int osd_fd = open (DEV_FB, O_RDONLY);
if (osd_fd <= 0)
{
// Handle error
return;
}
int disp_fd = open (DEV_DISP, O_RDONLY);
if (disp_fd <= 0)
{
// Handle error
close (osd_fd);
return;
}
int t = 1;
lcd_disp_t lcdOn = { .par1 = 1 };
ioctl (disp_fd, DISP_ENABLE_DISP, &lcdOn);
ioctl (osd_fd, FBIO_OUTPUT_ENABLE, &t);
ioctl (osd_fd, FBIOBLANK, FB_BLANK_UNBLANK);
ioctl (osd_fd, FBIO_GFX_LAYER_ENABLE, &t);
ioctl (disp_fd, DISP_ENABLE_BCKL, &lcdOn);
close (osd_fd);
close (disp_fd);
}
Note that the backlight level and backlight on/off status are independent. This is very important because, so far as I know, there is no way to _read_ the backlight level from the Archos driver. So applications that switch the backlight for power saving can do so, to some extent, without changing the user's preferred brightness.
