diff options
Diffstat (limited to 'firmware/target/hosted/ibasso/lcd-ibasso.c')
-rw-r--r-- | firmware/target/hosted/ibasso/lcd-ibasso.c | 195 |
1 files changed, 195 insertions, 0 deletions
diff --git a/firmware/target/hosted/ibasso/lcd-ibasso.c b/firmware/target/hosted/ibasso/lcd-ibasso.c new file mode 100644 index 0000000000..4e03ba7e50 --- /dev/null +++ b/firmware/target/hosted/ibasso/lcd-ibasso.c @@ -0,0 +1,195 @@ +/*************************************************************************** + * __________ __ ___ + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Copyright (C) 2014 by Ilia Sergachev: Initial Rockbox port to iBasso DX50 + * Copyright (C) 2014 by Mario Basister: iBasso DX90 port + * Copyright (C) 2014 by Simon Rothen: Initial Rockbox repository submission, additional features + * Copyright (C) 2014 by Udo Schläpfer: Code clean up, additional features + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + + +#include <errno.h> +#include <fcntl.h> +#include <stdbool.h> +#include <stdlib.h> +#include <linux/fb.h> +#include <sys/ioctl.h> +#include <sys/mman.h> +#include <sys/stat.h> +#include <sys/types.h> + +#include "config.h" +#include "debug.h" +#include "events.h" +#include "panic.h" + +#include "debug-ibasso.h" +#include "lcd-target.h" +#include "sysfs-ibasso.h" + + +fb_data *dev_fb = 0; + + +/* Framebuffer device handle. */ +static int dev_fd = 0; + + +void lcd_init_device(void) +{ + TRACE; + + dev_fd = open("/dev/graphics/fb0", O_RDWR); + if(dev_fd == -1) + { + DEBUGF("ERROR %s: open failed on /dev/graphics/fb0, errno: %d.", __func__, errno); + exit(errno); + } + + /* Get the changeable information. */ + struct fb_var_screeninfo vinfo; + if(ioctl(dev_fd, FBIOGET_VSCREENINFO, &vinfo) < 0) + { + DEBUGF("ERROR %s: ioctl FBIOGET_VSCREENINFO failed on /dev/graphics/fb0, errno: %d.", __func__, errno); + exit(errno); + } + + DEBUGF("DEBUG %s: bits_per_pixel: %u, width: %u, height: %u.", __func__, vinfo.bits_per_pixel, vinfo.width, vinfo.height); + + /* + Framebuffer does not fit the screen, a bug of iBassos Firmware, not Rockbox. + Cannot be solved with parameters. + */ + /*vinfo.bits_per_pixel = LCD_DEPTH; + vinfo.xres = LCD_WIDTH; + vinfo.xres_virtual = LCD_WIDTH; + vinfo.width = LCD_WIDTH; + vinfo.yres = LCD_HEIGHT; + vinfo.yres_virtual = LCD_HEIGHT; + vinfo.height = LCD_HEIGHT; + vinfo.activate = FB_ACTIVATE_NOW; + if(ioctl(dev_fd, FBIOPUT_VSCREENINFO, &vinfo) == -1) + { + DEBUGF("ERROR %s: ioctl FBIOPUT_VSCREENINFO failed on /dev/graphics/fb0, errno: %d.", __func__, errno); + exit(EXIT_FAILURE); + }*/ + + + /* Sanity check: Does framebuffer config match Rockbox config? */ + size_t screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8; + if(screensize != FRAMEBUFFER_SIZE) + { + DEBUGF("ERROR %s: Screen size does not match config: %d != %d.", __func__, screensize, FRAMEBUFFER_SIZE); + exit(EXIT_FAILURE); + } + + /* Map the device to memory. */ + dev_fb = mmap(0, FRAMEBUFFER_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, dev_fd, 0); + if(dev_fb == MAP_FAILED) + { + DEBUGF("ERROR %s: mmap failed on /dev/graphics/fb0, errno: %d.", __func__, errno); + exit(errno); + } + + /* Activate Rockbox LCD. */ + lcd_enable(true); +} + + +void lcd_shutdown(void) +{ + TRACE; + + lcd_set_active(false); + munmap(dev_fb, FRAMEBUFFER_SIZE); + close(dev_fd) ; +} + + +/* + Left as reference. Unblanking does not work as expected, will not enable LCD after a few + seconds of power down. + Instead the backlight power is toggled. +*/ +/*void lcd_power_on(void) +{ + TRACE; + + if(ioctl(dev_fd, FBIOBLANK, VESA_NO_BLANKING) == -1) + { + DEBUGF("ERROR %s: ioctl FBIOBLANK failed on /dev/graphics/fb0, errno: %d.", __func__, errno); + panicf("ERROR %s: ioctl FBIOBLANK failed on /dev/graphics/fb0, errno: %d.", __func__, errno); + return; + } + + lcd_set_active(true); + send_event(LCD_EVENT_ACTIVATION, NULL); +} + + +void lcd_power_off(void) +{ + TRACE; + + lcd_set_active(false); + + if(ioctl(dev_fd, FBIOBLANK, VESA_POWERDOWN) == -1) + { + DEBUGF("ERROR %s: ioctl FBIOBLANK failed on /dev/graphics/fb0, errno: %d.", __func__, errno); + panicf("ERROR %s: ioctl FBIOBLANK failed on /dev/graphics/fb0, errno: %d.", __func__, errno); + return; + } +}*/ + + +void lcd_enable(bool on) +{ + TRACE; + + lcd_set_active(on); + + if(on) + { + /* + /sys/power/state + on: Cancel suspend. + */ + if(! sysfs_set_string(SYSFS_POWER_STATE, "on")) + { + DEBUGF("ERROR %s: Can not set power state.", __func__); + } + + send_event(LCD_EVENT_ACTIVATION, NULL); + } +} + + +void lcd_sleep(void) +{ + TRACE; + + /* + See system_init(). Without suspend blocker und mute prevention this will interrupt playback. + Essentially, we are turning off the touch screen. + /sys/power/state + mem: Suspend to RAM. + */ + if(! sysfs_set_string(SYSFS_POWER_STATE, "mem")) + { + DEBUGF("ERROR %s: Can not set power state.", __func__); + } +} |