lcd驱动增加上电背光渐变功能

This commit is contained in:
张兆鹏 2025-02-25 10:22:16 +08:00
parent 769afcc64a
commit 7686a9316b
6 changed files with 170 additions and 1 deletions

View File

@ -2044,6 +2044,8 @@ CONFIG_LCD_SUPPORT_ICN6202_2LANE=y
#
CONFIG_DISP2_SUNXI_SUPPORT_SMBL=y
CONFIG_DISP2_SUNXI_SUPPORT_ENAHNCE=y
# CONFIG_DISP2_HAS_SUPPORT_FRONT_WKSRCBL is not set
# CONFIG_DISP2_HAS_SUPPORT_BACK_WKSRCBL is not set
# CONFIG_FB_SSD1307 is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
# CONFIG_VGASTATE is not set

View File

@ -2162,6 +2162,8 @@ CONFIG_LCD_SUPPORT_ICN6202_2LANE=y
#
CONFIG_DISP2_SUNXI_SUPPORT_SMBL=y
CONFIG_DISP2_SUNXI_SUPPORT_ENAHNCE=y
CONFIG_DISP2_HAS_SUPPORT_FRONT_WKSRCBL=y
# CONFIG_DISP2_HAS_SUPPORT_BACK_WKSRCBL is not set
# CONFIG_FB_SSD1307 is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
# CONFIG_VGASTATE is not set

View File

@ -9,3 +9,15 @@ config DISP2_SUNXI_SUPPORT_ENAHNCE
default y
---help---
If you want to support video enhance process, select it.
config DISP2_HAS_SUPPORT_FRONT_WKSRCBL
bool "Support changing the front backlight according to the wakeup source"
default n
---help---
If you want to support changing the front backlight according to the wakeup source, select it.
config DISP2_HAS_SUPPORT_BACK_WKSRCBL
bool "Support changing the back backlight according to the wakeup source"
default n
---help---
If you want to support changing the back backlight according to the wakeup source, select it.

View File

@ -66,6 +66,56 @@ static struct disp_lcd_private_data *lcd_private;
static int panel_timing_init(int disp, int lcd_index,
struct disp_panel_para *panel_info, struct disp_video_timings *timmings);
#if defined(CONFIG_DISP2_HAS_SUPPORT_FRONT_WKSRCBL) || defined(CONFIG_DISP2_HAS_SUPPORT_BACK_WKSRCBL)
#include <linux/io.h>
#include <linux/timer.h>
#ifdef CONFIG_DISP2_HAS_SUPPORT_FRONT_WKSRCBL
#define STARTUP_DURATION_TIME 600 // 软件定时器很不准确,要设置对应时间需要实际测试
#endif
#ifdef CONFIG_DISP2_HAS_SUPPORT_BACK_WKSRCBL
// #define STARTUP_DURATION_TIME 600
#endif
#define STARTUP_PERIOD 20 // ms
#define STARTUP_START_PWM_VALUE 20 // 起始pwm值
#define STARTUP_EMD_PWD_VALUE 250 // MAX
/*
start up的pwm数值变化
250(MAX)
/
STARTUP_START_PWM_VALUE _/
*/
#define WEIGHT_ADDR 0x4307F000 // 权重加载的内存地址处
#define M_PAGE_SIZE (4 * 1024) // 内存对齐应该是4K
typedef enum {
HAS_APP_WAKEUP_SOURCE_NONE,
HAS_APP_WAKEUP_SOURCE_RADAR, // 雷达
HAS_APP_WAKEUP_SOURCE_PIR, // PIR
HAS_APP_WAKEUP_SOURCE_TOUCH_SCREEN, // 屏幕
HAS_APP_WAKEUP_SOURCE_TOUCH_PAD, // 门铃
HAS_APP_WAKEUP_SOURCE_BRAKE_PROOF, // 防撬
HAS_APP_WAKEUP_SOURCE_BACK_PANEL, // 后板
HAS_APP_WAKEUP_SOURCE_NFC, // NFC
} has_app_wakeup_source_e; // 前板唤醒源
typedef struct
{
struct timer_list timer;
spinlock_t bl_lock;
unsigned char exit_flag ;
unsigned char timer_flag ;
} has_startup_bl_t;
static has_startup_bl_t startup_bl = {
.exit_flag = 0,
.timer_flag = 0,
.timer.data = 0,
};
#endif
static int disp_check_timing_param(struct disp_panel_para *panel)
{
u32 x = panel->lcd_x;
@ -1208,12 +1258,65 @@ static s32 disp_lcd_pwm_disable(struct disp_device *lcd)
}
#endif
#if defined(CONFIG_DISP2_HAS_SUPPORT_FRONT_WKSRCBL) || defined(CONFIG_DISP2_HAS_SUPPORT_BACK_WKSRCBL)
static s32 disp_lcd_clear_startup_bl(void)
{
if (startup_bl.timer_flag)
{
unsigned long flags;
spin_lock_irqsave(&startup_bl.bl_lock, flags);
startup_bl.exit_flag = 1;
spin_unlock_irqrestore(&startup_bl.bl_lock, flags);
}
else
{
startup_bl.exit_flag = 1;
}
return 0;
}
static void disp_lcd_backlight_increase(unsigned long data)
{
static u32 cur_bl = STARTUP_START_PWM_VALUE;
unsigned long flags;
if (data == 0)
{
// pr_emerg("wrong with data\n");
return;
}
spin_lock_irqsave(&startup_bl.bl_lock, flags);
if (startup_bl.exit_flag)
{
spin_unlock_irqrestore(&startup_bl.bl_lock, flags);
del_timer(&startup_bl.timer);
return;
}
disp_lcd_set_bright((struct disp_device *)data, cur_bl);
spin_unlock_irqrestore(&startup_bl.bl_lock, flags);
cur_bl += ((STARTUP_EMD_PWD_VALUE - STARTUP_START_PWM_VALUE) / (STARTUP_DURATION_TIME / STARTUP_PERIOD));
if (cur_bl >= STARTUP_EMD_PWD_VALUE)
{
del_timer(&startup_bl.timer);
}
else
{
mod_timer(&startup_bl.timer, jiffies + msecs_to_jiffies(STARTUP_PERIOD));
}
}
#endif
static s32 disp_lcd_backlight_enable(struct disp_device *lcd)
{
struct disp_gpio_set_t gpio_info[1];
struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
unsigned long flags;
#if defined(CONFIG_DISP2_HAS_SUPPORT_FRONT_WKSRCBL) || defined(CONFIG_DISP2_HAS_SUPPORT_BACK_WKSRCBL)
void __iomem *vaddr = NULL;
unsigned char wakeupsource = 0;
#endif
if ((lcd == NULL) || (lcdp == NULL)) {
DE_WRN("NULL hdl!\n");
return DIS_FAIL;
@ -1230,7 +1333,10 @@ static s32 disp_lcd_backlight_enable(struct disp_device *lcd)
spin_unlock_irqrestore(&lcd_data_lock, flags);
if (disp_lcd_is_used(lcd)) {
#if defined(CONFIG_DISP2_HAS_SUPPORT_FRONT_WKSRCBL) || defined(CONFIG_DISP2_HAS_SUPPORT_BACK_WKSRCBL)
#else
unsigned bl;
#endif
if (lcdp->lcd_cfg.lcd_bl_en_used) {
/* io-pad */
@ -1247,8 +1353,28 @@ static s32 disp_lcd_backlight_enable(struct disp_device *lcd)
lcdp->lcd_cfg.lcd_bl_gpio_hdl =
disp_sys_gpio_request(gpio_info, 1);
}
#if defined(CONFIG_DISP2_HAS_SUPPORT_FRONT_WKSRCBL) || defined(CONFIG_DISP2_HAS_SUPPORT_BACK_WKSRCBL)
vaddr = memremap(WEIGHT_ADDR, M_PAGE_SIZE, MEMREMAP_WB);
if (vaddr)
{
wakeupsource = readb(vaddr);
memunmap(vaddr);
}
if ((wakeupsource != HAS_APP_WAKEUP_SOURCE_BACK_PANEL) && (wakeupsource != HAS_APP_WAKEUP_SOURCE_NONE))
{
init_timer(&startup_bl.timer);
startup_bl.timer.function = disp_lcd_backlight_increase;
startup_bl.timer.expires = jiffies + 1;
startup_bl.timer.data = (unsigned long)lcd;
spin_lock_init(&startup_bl.bl_lock);
startup_bl.timer_flag = 1;
add_timer(&startup_bl.timer);
}
#else
bl = disp_lcd_get_bright(lcd);
disp_lcd_set_bright(lcd, bl);
#endif
}
return 0;
@ -2011,7 +2137,10 @@ static s32 disp_lcd_enable(struct disp_device *lcd)
struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
int i;
struct disp_manager *mgr = NULL;
#if defined(CONFIG_DISP2_HAS_SUPPORT_FRONT_WKSRCBL) || defined(CONFIG_DISP2_HAS_SUPPORT_BACK_WKSRCBL)
#else
unsigned bl;
#endif
int ret = 0;
if ((lcd == NULL) || (lcdp == NULL)) {
@ -2121,8 +2250,11 @@ static s32 disp_lcd_enable(struct disp_device *lcd)
lcdp->enabled = 1;
lcdp->enabling = 0;
spin_unlock_irqrestore(&lcd_data_lock, flags);
#if defined(CONFIG_DISP2_HAS_SUPPORT_FRONT_WKSRCBL) || defined(CONFIG_DISP2_HAS_SUPPORT_BACK_WKSRCBL)
#else
bl = disp_lcd_get_bright(lcd);
disp_lcd_set_bright(lcd, bl);
#endif
#if defined(CONFIG_DISP2_LCD_ESD_DETECT)
atomic_set(&lcdp->lcd_resetting, 0);
#endif
@ -3242,6 +3374,9 @@ s32 disp_init_lcd(struct disp_bsp_init_para *para)
lcd->set_color_temperature = disp_lcd_set_color_temperature;
lcd->get_color_temperature = disp_lcd_get_color_temperature;
lcd->show_builtin_patten = disp_device_show_builtin_patten;
#if defined(CONFIG_DISP2_HAS_SUPPORT_FRONT_WKSRCBL) || defined(CONFIG_DISP2_HAS_SUPPORT_BACK_WKSRCBL)
lcd->clear_startup_bl = disp_lcd_clear_startup_bl;
#endif
#if defined(CONFIG_DISP2_LCD_ESD_DETECT)
lcd->get_esd_info = disp_lcd_get_esd_info;
#endif

View File

@ -1087,7 +1087,9 @@ struct disp_device {
s32 (*tcon_enable)(struct disp_device *dispdev);
s32 (*tcon_disable)(struct disp_device *dispdev);
s32 (*set_bright_dimming)(struct disp_device *dispdev, u32 dimming);
#if defined(CONFIG_DISP2_HAS_SUPPORT_FRONT_WKSRCBL) || defined(CONFIG_DISP2_HAS_SUPPORT_BACK_WKSRCBL)
s32 (*clear_startup_bl)(void);
#endif
struct disp_lcd_flow *(*get_open_flow)(struct disp_device *dispdev);
struct disp_lcd_flow *(*get_close_flow)(struct disp_device *dispdev);
s32 (*pin_cfg)(struct disp_device *dispdev, u32 bon);

View File

@ -3359,6 +3359,9 @@ static void disp_shutdown(struct platform_device *pdev)
#ifdef EINK_FLUSH_TIME_TEST
struct timeval ioctrl_start_timer;
#endif
#define DISP_LCD_CLEAR_STARTUP_BL 0x115
long disp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
unsigned long karg[4];
@ -4354,6 +4357,19 @@ handle_cmd:
return -1;
break;
}
#if defined(CONFIG_DISP2_HAS_SUPPORT_FRONT_WKSRCBL) || defined(CONFIG_DISP2_HAS_SUPPORT_BACK_WKSRCBL)
case DISP_LCD_CLEAR_STARTUP_BL:
{
if (mgr && mgr->device) {
if (mgr->device->clear_startup_bl)
mgr->device->clear_startup_bl();
return 0;
}
return -1;
break;
}
#endif
case DISP_LCD_BACKLIGHT_DISABLE:
{
if (mgr && mgr->device) {