4c60bc9e68
- Audio playback works - Touchscreen and buttons work - Bootloader works and is capable of dual boot - Plugins are working - Cabbiev2 theme has been ported - Stable for general usage Thanks to Marc Aarts for porting Cabbiev2 and plugin bitmaps. There's a few minor known issues: - Bootloader must be installed manually using 'usbboot' as there is no support in jztool yet. - Keymaps may be lacking, need further testing and feedback. - Some plugins may not be fully adapted to the screen size and could benefit from further tweaking. - LCD shows abnormal effects under some circumstances: for example, after viewing a mostly black screen an afterimage appears briefly when going back to a brightly-lit screen. Sudden power-off without proper shutdown of the backlight causes a "dissolving" effect. - CW2015 battery reporting driver is buggy, and disabled for now. Battery reporting is currently voltage-based using the AXP192. Change-Id: I635e83f02a880192c5a82cb0861ad3a61c137c3a
399 lines
8.8 KiB
C
399 lines
8.8 KiB
C
/***************************************************************************
|
|
* __________ __ ___.
|
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
* \/ \/ \/ \/ \/
|
|
* $Id$
|
|
*
|
|
* Copyright (C) 2021 Aidan MacDonald
|
|
*
|
|
* 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 "lcd.h"
|
|
#include "system.h"
|
|
#include "lcd-x1000.h"
|
|
#include "gpio-x1000.h"
|
|
|
|
/* LCD controller is probably an RM68090.
|
|
*/
|
|
|
|
static const uint32_t q1_lcd_cmd_enable[] = {
|
|
LCD_INSTR_CMD, 0x00,
|
|
LCD_INSTR_CMD, 0xbe,
|
|
LCD_INSTR_DAT, 0xc3,
|
|
LCD_INSTR_DAT, 0x29,
|
|
|
|
LCD_INSTR_CMD, 0x00,
|
|
LCD_INSTR_CMD, 0x01,
|
|
LCD_INSTR_DAT, 0x01,
|
|
LCD_INSTR_DAT, 0x04,
|
|
|
|
LCD_INSTR_CMD, 0x00,
|
|
LCD_INSTR_CMD, 0x02,
|
|
LCD_INSTR_DAT, 0x01,
|
|
LCD_INSTR_DAT, 0x00,
|
|
|
|
LCD_INSTR_CMD, 0x00,
|
|
LCD_INSTR_CMD, 0x03,
|
|
LCD_INSTR_DAT, 0x00,
|
|
LCD_INSTR_DAT, 0x10,
|
|
|
|
LCD_INSTR_CMD, 0x00,
|
|
LCD_INSTR_CMD, 0x05,
|
|
LCD_INSTR_DAT, 0x00,
|
|
LCD_INSTR_DAT, 0x00,
|
|
|
|
LCD_INSTR_CMD, 0x00,
|
|
LCD_INSTR_CMD, 0x06,
|
|
LCD_INSTR_DAT, 0x00,
|
|
LCD_INSTR_DAT, 0x00,
|
|
|
|
LCD_INSTR_CMD, 0x00,
|
|
LCD_INSTR_CMD, 0x07,
|
|
LCD_INSTR_DAT, 0x01,
|
|
LCD_INSTR_DAT, 0x03,
|
|
|
|
LCD_INSTR_CMD, 0x00,
|
|
LCD_INSTR_CMD, 0x08,
|
|
LCD_INSTR_DAT, 0x03,
|
|
LCD_INSTR_DAT, 0x03,
|
|
|
|
LCD_INSTR_CMD, 0x00,
|
|
LCD_INSTR_CMD, 0x0d,
|
|
LCD_INSTR_DAT, 0x00,
|
|
LCD_INSTR_DAT, 0x00,
|
|
|
|
LCD_INSTR_CMD, 0x00,
|
|
LCD_INSTR_CMD, 0x10,
|
|
LCD_INSTR_DAT, 0x00,
|
|
LCD_INSTR_DAT, 0xc1,
|
|
|
|
LCD_INSTR_CMD, 0x00,
|
|
LCD_INSTR_CMD, 0x11,
|
|
LCD_INSTR_DAT, 0xb1,
|
|
LCD_INSTR_DAT, 0x08,
|
|
|
|
LCD_INSTR_CMD, 0x00,
|
|
LCD_INSTR_CMD, 0x12,
|
|
LCD_INSTR_DAT, 0xb1,
|
|
LCD_INSTR_DAT, 0x08,
|
|
|
|
LCD_INSTR_CMD, 0x00,
|
|
LCD_INSTR_CMD, 0x13,
|
|
LCD_INSTR_DAT, 0x00,
|
|
LCD_INSTR_DAT, 0x0f,
|
|
|
|
LCD_INSTR_CMD, 0x00,
|
|
LCD_INSTR_CMD, 0x14,
|
|
LCD_INSTR_DAT, 0x00,
|
|
LCD_INSTR_DAT, 0x14,
|
|
|
|
LCD_INSTR_CMD, 0x00,
|
|
LCD_INSTR_CMD, 0x15,
|
|
LCD_INSTR_DAT, 0x00,
|
|
LCD_INSTR_DAT, 0x04,
|
|
|
|
LCD_INSTR_CMD, 0x00,
|
|
LCD_INSTR_CMD, 0x16,
|
|
LCD_INSTR_DAT, 0x00,
|
|
LCD_INSTR_DAT, 0x00,
|
|
|
|
LCD_INSTR_CMD, 0x00,
|
|
LCD_INSTR_CMD, 0x22,
|
|
LCD_INSTR_DAT, 0x00,
|
|
LCD_INSTR_DAT, 0x00,
|
|
|
|
LCD_INSTR_CMD, 0x00,
|
|
LCD_INSTR_CMD, 0x23,
|
|
LCD_INSTR_DAT, 0x00,
|
|
LCD_INSTR_DAT, 0x00,
|
|
|
|
LCD_INSTR_CMD, 0x00,
|
|
LCD_INSTR_CMD, 0x30,
|
|
LCD_INSTR_DAT, 0x7c,
|
|
LCD_INSTR_DAT, 0x3f,
|
|
|
|
LCD_INSTR_CMD, 0x00,
|
|
LCD_INSTR_CMD, 0x32,
|
|
LCD_INSTR_DAT, 0x00,
|
|
LCD_INSTR_DAT, 0x00,
|
|
|
|
LCD_INSTR_CMD, 0x00,
|
|
LCD_INSTR_CMD, 0x70,
|
|
LCD_INSTR_DAT, 0x00,
|
|
LCD_INSTR_DAT, 0x01,
|
|
|
|
LCD_INSTR_CMD, 0x00,
|
|
LCD_INSTR_CMD, 0x91,
|
|
LCD_INSTR_DAT, 0x01,
|
|
LCD_INSTR_DAT, 0x00,
|
|
|
|
LCD_INSTR_CMD, 0x00,
|
|
LCD_INSTR_CMD, 0xe0,
|
|
LCD_INSTR_DAT, 0x00,
|
|
LCD_INSTR_DAT, 0x01,
|
|
|
|
LCD_INSTR_CMD, 0x00,
|
|
LCD_INSTR_CMD, 0xe1,
|
|
LCD_INSTR_DAT, 0x00,
|
|
LCD_INSTR_DAT, 0x61,
|
|
|
|
LCD_INSTR_CMD, 0x01,
|
|
LCD_INSTR_CMD, 0x00,
|
|
LCD_INSTR_DAT, 0x10,
|
|
LCD_INSTR_DAT, 0x30,
|
|
|
|
LCD_INSTR_CMD, 0x01,
|
|
LCD_INSTR_CMD, 0x01,
|
|
LCD_INSTR_DAT, 0xf6,
|
|
LCD_INSTR_DAT, 0x3f,
|
|
|
|
LCD_INSTR_CMD, 0x01,
|
|
LCD_INSTR_CMD, 0x02,
|
|
LCD_INSTR_DAT, 0x50,
|
|
LCD_INSTR_DAT, 0x1f,
|
|
|
|
LCD_INSTR_CMD, 0x01,
|
|
LCD_INSTR_CMD, 0x03,
|
|
LCD_INSTR_DAT, 0x00,
|
|
LCD_INSTR_DAT, 0x30,
|
|
|
|
LCD_INSTR_CMD, 0x01,
|
|
LCD_INSTR_CMD, 0x08,
|
|
LCD_INSTR_DAT, 0x03,
|
|
LCD_INSTR_DAT, 0x00,
|
|
|
|
LCD_INSTR_CMD, 0x01,
|
|
LCD_INSTR_CMD, 0x11,
|
|
LCD_INSTR_DAT, 0x00,
|
|
LCD_INSTR_DAT, 0x01,
|
|
|
|
LCD_INSTR_CMD, 0x01,
|
|
LCD_INSTR_CMD, 0x35,
|
|
LCD_INSTR_DAT, 0x76,
|
|
LCD_INSTR_DAT, 0x66,
|
|
|
|
LCD_INSTR_CMD, 0x01,
|
|
LCD_INSTR_CMD, 0x39,
|
|
LCD_INSTR_DAT, 0x00,
|
|
LCD_INSTR_DAT, 0x26,
|
|
|
|
LCD_INSTR_CMD, 0x04,
|
|
LCD_INSTR_CMD, 0x00,
|
|
LCD_INSTR_DAT, 0x00,
|
|
LCD_INSTR_DAT, 0xc7,
|
|
|
|
LCD_INSTR_CMD, 0x04,
|
|
LCD_INSTR_CMD, 0x01,
|
|
LCD_INSTR_DAT, 0x00,
|
|
LCD_INSTR_DAT, 0x00,
|
|
|
|
LCD_INSTR_CMD, 0x06,
|
|
LCD_INSTR_CMD, 0x06,
|
|
LCD_INSTR_DAT, 0x00,
|
|
LCD_INSTR_DAT, 0x00,
|
|
|
|
LCD_INSTR_CMD, 0x03,
|
|
LCD_INSTR_CMD, 0x00,
|
|
LCD_INSTR_DAT, 0x0d,
|
|
LCD_INSTR_DAT, 0x0e,
|
|
|
|
LCD_INSTR_CMD, 0x03,
|
|
LCD_INSTR_CMD, 0x01,
|
|
LCD_INSTR_DAT, 0x00,
|
|
LCD_INSTR_DAT, 0x03,
|
|
|
|
LCD_INSTR_CMD, 0x03,
|
|
LCD_INSTR_CMD, 0x02,
|
|
LCD_INSTR_DAT, 0x08,
|
|
LCD_INSTR_DAT, 0x08,
|
|
|
|
LCD_INSTR_CMD, 0x03,
|
|
LCD_INSTR_CMD, 0x03,
|
|
LCD_INSTR_DAT, 0x02,
|
|
LCD_INSTR_DAT, 0x01,
|
|
|
|
LCD_INSTR_CMD, 0x03,
|
|
LCD_INSTR_CMD, 0x04,
|
|
LCD_INSTR_DAT, 0x03,
|
|
LCD_INSTR_DAT, 0x01,
|
|
|
|
LCD_INSTR_CMD, 0x03,
|
|
LCD_INSTR_CMD, 0x05,
|
|
LCD_INSTR_DAT, 0x00,
|
|
LCD_INSTR_DAT, 0x04,
|
|
|
|
LCD_INSTR_CMD, 0x03,
|
|
LCD_INSTR_CMD, 0x06,
|
|
LCD_INSTR_DAT, 0x1b,
|
|
LCD_INSTR_DAT, 0x21,
|
|
|
|
LCD_INSTR_CMD, 0x03,
|
|
LCD_INSTR_CMD, 0x07,
|
|
LCD_INSTR_DAT, 0x0f,
|
|
LCD_INSTR_DAT, 0x0e,
|
|
|
|
LCD_INSTR_CMD, 0x03,
|
|
LCD_INSTR_CMD, 0x08,
|
|
LCD_INSTR_DAT, 0x01,
|
|
LCD_INSTR_DAT, 0x04,
|
|
|
|
LCD_INSTR_CMD, 0x03,
|
|
LCD_INSTR_CMD, 0x09,
|
|
LCD_INSTR_DAT, 0x08,
|
|
LCD_INSTR_DAT, 0x08,
|
|
|
|
LCD_INSTR_CMD, 0x03,
|
|
LCD_INSTR_CMD, 0x0a,
|
|
LCD_INSTR_DAT, 0x02,
|
|
LCD_INSTR_DAT, 0x01,
|
|
|
|
LCD_INSTR_CMD, 0x03,
|
|
LCD_INSTR_CMD, 0x0b,
|
|
LCD_INSTR_DAT, 0x03,
|
|
LCD_INSTR_DAT, 0x01,
|
|
|
|
LCD_INSTR_CMD, 0x03,
|
|
LCD_INSTR_CMD, 0x0c,
|
|
LCD_INSTR_DAT, 0x00,
|
|
LCD_INSTR_DAT, 0x03,
|
|
|
|
LCD_INSTR_CMD, 0x03,
|
|
LCD_INSTR_CMD, 0x0d,
|
|
LCD_INSTR_DAT, 0x31,
|
|
LCD_INSTR_DAT, 0x34,
|
|
|
|
/* X start */
|
|
LCD_INSTR_CMD, 0x02,
|
|
LCD_INSTR_CMD, 0x10,
|
|
LCD_INSTR_DAT, 0x00,
|
|
LCD_INSTR_DAT, 0x1e, /* 30 */
|
|
|
|
/* X end */
|
|
LCD_INSTR_CMD, 0x02,
|
|
LCD_INSTR_CMD, 0x11,
|
|
LCD_INSTR_DAT, 0x01,
|
|
LCD_INSTR_DAT, 0x85, /* 389 */
|
|
|
|
/* Y start */
|
|
LCD_INSTR_CMD, 0x02,
|
|
LCD_INSTR_CMD, 0x12,
|
|
LCD_INSTR_DAT, 0x00,
|
|
LCD_INSTR_DAT, 0x00, /* 0 */
|
|
|
|
/* Y end */
|
|
LCD_INSTR_CMD, 0x02,
|
|
LCD_INSTR_CMD, 0x13,
|
|
LCD_INSTR_DAT, 0x01,
|
|
LCD_INSTR_DAT, 0x8f, /* 399 */
|
|
|
|
/* RAM write start X? */
|
|
LCD_INSTR_CMD, 0x02,
|
|
LCD_INSTR_CMD, 0x00,
|
|
LCD_INSTR_DAT, 0x00,
|
|
LCD_INSTR_DAT, 0x1e,
|
|
|
|
/* RAM write start Y? */
|
|
LCD_INSTR_CMD, 0x02,
|
|
LCD_INSTR_CMD, 0x01,
|
|
LCD_INSTR_DAT, 0x00,
|
|
LCD_INSTR_DAT, 0x00,
|
|
|
|
LCD_INSTR_CMD, 0x00,
|
|
LCD_INSTR_CMD, 0x03,
|
|
LCD_INSTR_DAT, 0x00,
|
|
LCD_INSTR_DAT, 0x30,
|
|
|
|
LCD_INSTR_CMD, 0x02,
|
|
LCD_INSTR_CMD, 0x02,
|
|
LCD_INSTR_END,
|
|
};
|
|
|
|
/* NOTE this sleep mode may not be saving power, but it gets rid of the
|
|
* ghost image that would otherwise remain on the display */
|
|
static const uint32_t q1_lcd_cmd_sleep[] = {
|
|
LCD_INSTR_CMD, 0x00,
|
|
LCD_INSTR_CMD, 0x10,
|
|
LCD_INSTR_DAT, 0x00,
|
|
LCD_INSTR_DAT, 0x03,
|
|
|
|
LCD_INSTR_CMD, 0x00,
|
|
LCD_INSTR_CMD, 0x07,
|
|
LCD_INSTR_DAT, 0x01,
|
|
LCD_INSTR_DAT, 0x01,
|
|
|
|
LCD_INSTR_END,
|
|
};
|
|
|
|
static const uint32_t q1_lcd_cmd_wake[] = {
|
|
LCD_INSTR_CMD, 0x00,
|
|
LCD_INSTR_CMD, 0x07,
|
|
LCD_INSTR_DAT, 0x01,
|
|
LCD_INSTR_DAT, 0x03,
|
|
|
|
LCD_INSTR_CMD, 0x00,
|
|
LCD_INSTR_CMD, 0x10,
|
|
LCD_INSTR_DAT, 0x00,
|
|
LCD_INSTR_DAT, 0xc1,
|
|
|
|
LCD_INSTR_END,
|
|
};
|
|
|
|
static const uint8_t __attribute__((aligned(64)))
|
|
q1_lcd_dma_wr_cmd[] = {0x02, 0x02, 0x02, 0x02};
|
|
|
|
const struct lcd_tgt_config lcd_tgt_config = {
|
|
.bus_width = 8,
|
|
.cmd_width = 8,
|
|
.use_6800_mode = 0,
|
|
.use_serial = 0,
|
|
.clk_polarity = 0,
|
|
.dc_polarity = 0,
|
|
.wr_polarity = 1,
|
|
.te_enable = 0,
|
|
.big_endian = 1,
|
|
.dma_wr_cmd_buf = &q1_lcd_dma_wr_cmd,
|
|
.dma_wr_cmd_size = sizeof(q1_lcd_dma_wr_cmd),
|
|
};
|
|
|
|
void lcd_tgt_enable(bool enable)
|
|
{
|
|
if(enable) {
|
|
/* power on the panel */
|
|
gpio_set_level(GPIO_LCD_PWR, 1);
|
|
gpio_set_level(GPIO_LCD_RST, 1);
|
|
gpio_set_level(GPIO_LCD_CE, 1);
|
|
gpio_set_level(GPIO_LCD_RD, 1);
|
|
mdelay(50);
|
|
gpio_set_level(GPIO_LCD_RST, 0);
|
|
mdelay(100);
|
|
gpio_set_level(GPIO_LCD_RST, 1);
|
|
mdelay(50);
|
|
gpio_set_level(GPIO_LCD_CE, 0);
|
|
|
|
/* Start the controller */
|
|
lcd_set_clock(X1000_CLK_MPLL, 50000000);
|
|
lcd_exec_commands(q1_lcd_cmd_enable);
|
|
} else {
|
|
/* FIXME: Shanling Q1 LCD power down sequence
|
|
* not important because we don't use it but it'd be nice to know */
|
|
}
|
|
}
|
|
|
|
void lcd_tgt_sleep(bool sleep)
|
|
{
|
|
if(sleep)
|
|
lcd_exec_commands(q1_lcd_cmd_sleep);
|
|
else
|
|
lcd_exec_commands(q1_lcd_cmd_wake);
|
|
}
|