From f4c8a17837263b2924ebf31c9604190d8c1462e0 Mon Sep 17 00:00:00 2001 From: jianglianfang Date: Thu, 9 Nov 2023 16:52:30 +0800 Subject: [PATCH] sim_lcd: add open & close The opening and closing of the window has been associated with the opening and closing of fb, but the LCD has not yet been optimized. The window will only open when sim_x11openwindow is called, and similarly, the window will only close when sim_x11closewindow is called. Signed-off-by: jianglianfang --- arch/sim/src/sim/sim_lcd.c | 38 +++++++++++++++- drivers/lcd/lcd_dev.c | 84 ++++++++++++++++++++++++++++++++++- drivers/lcd/lcd_framebuffer.c | 56 +++++++++++++++++++++++ include/nuttx/lcd/lcd.h | 5 +++ 4 files changed, 180 insertions(+), 3 deletions(-) diff --git a/arch/sim/src/sim/sim_lcd.c b/arch/sim/src/sim/sim_lcd.c index 0e490d0119..aab8833878 100644 --- a/arch/sim/src/sim/sim_lcd.c +++ b/arch/sim/src/sim/sim_lcd.c @@ -140,6 +140,8 @@ static int sim_getpower(struct lcd_dev_s *dev); static int sim_setpower(struct lcd_dev_s *dev, int power); static int sim_getcontrast(struct lcd_dev_s *dev); static int sim_setcontrast(struct lcd_dev_s *dev, unsigned int contrast); +static int sim_openwindow(struct lcd_dev_s *dev); +static int sim_closewindow(struct lcd_dev_s *dev); /**************************************************************************** * Private Data @@ -207,6 +209,8 @@ static struct sim_dev_s g_lcddev = .setpower = sim_setpower, .getcontrast = sim_getcontrast, .setcontrast = sim_setcontrast, + .open = sim_openwindow, + .close = sim_closewindow, }, }; @@ -431,7 +435,39 @@ static int sim_setcontrast(struct lcd_dev_s *dev, unsigned int contrast) } /**************************************************************************** - * Name: sim_updatework + * Name: sim_openwindow + ****************************************************************************/ + +static int sim_openwindow(struct lcd_dev_s *dev) +{ + int ret = OK; + ginfo("lcd_dev=%p\n", dev); + +#ifdef CONFIG_SIM_X11FB + ret = sim_x11openwindow(); +#endif + + return ret; +} + +/**************************************************************************** + * Name: sim_closewindow + ****************************************************************************/ + +static int sim_closewindow(struct lcd_dev_s *dev) +{ + int ret = OK; + ginfo("lcd_dev=%p\n", dev); + +#ifdef CONFIG_SIM_X11FB + ret = sim_x11closewindow(); +#endif + + return ret; +} + +/**************************************************************************** + * Name: sim_x11loop ****************************************************************************/ void sim_x11loop(void) diff --git a/drivers/lcd/lcd_dev.c b/drivers/lcd/lcd_dev.c index fd7e532344..dc465be722 100644 --- a/drivers/lcd/lcd_dev.c +++ b/drivers/lcd/lcd_dev.c @@ -51,6 +51,8 @@ struct lcddev_dev_s { FAR struct lcd_dev_s *lcd_ptr; struct lcd_planeinfo_s planeinfo; + mutex_t lock; + int16_t crefs; }; /**************************************************************************** @@ -59,6 +61,8 @@ struct lcddev_dev_s /* Character driver methods */ +static int lcddev_open(FAR struct file *filep); +static int lcddev_close(FAR struct file *filep); static int lcddev_ioctl(FAR struct file *filep, int cmd, unsigned long arg); @@ -68,8 +72,8 @@ static int lcddev_ioctl(FAR struct file *filep, int cmd, static const struct file_operations g_lcddev_fops = { - NULL, /* open */ - NULL, /* close */ + lcddev_open, /* open */ + lcddev_close, /* close */ NULL, /* read */ NULL, /* write */ NULL, /* seek */ @@ -80,6 +84,78 @@ static const struct file_operations g_lcddev_fops = * Private Functions ****************************************************************************/ +/**************************************************************************** + * Name: lcddev_open + ****************************************************************************/ + +static int lcddev_open(FAR struct file *filep) +{ + FAR struct lcddev_dev_s *priv; + int ret; + + priv = filep->f_inode->i_private; + + ret = nxmutex_lock(&priv->lock); + if (ret < 0) + { + return ret; + } + + if (priv->crefs == 0) + { + if (priv->lcd_ptr->open != NULL && + (ret = priv->lcd_ptr->open(priv->lcd_ptr)) < 0) + { + goto err_lcd; + } + } + + priv->crefs++; + DEBUGASSERT(priv->crefs > 0); + + nxmutex_unlock(&priv->lock); + return OK; + +err_lcd: + nxmutex_unlock(&priv->lock); + return ret; +} + +/**************************************************************************** + * Name: lcddev_close + ****************************************************************************/ + +static int lcddev_close(FAR struct file *filep) +{ + FAR struct lcddev_dev_s *priv; + int ret; + + priv = filep->f_inode->i_private; + + ret = nxmutex_lock(&priv->lock); + if (ret < 0) + { + return ret; + } + + if (priv->crefs == 1) + { + if (priv->lcd_ptr->close != NULL) + { + ret = priv->lcd_ptr->close(priv->lcd_ptr); + } + } + + if (ret >= 0) + { + DEBUGASSERT(priv->crefs > 0); + priv->crefs--; + } + + nxmutex_unlock(&priv->lock); + return ret; +} + /**************************************************************************** * Name: lcddev_ioctl ****************************************************************************/ @@ -349,6 +425,8 @@ int lcddev_register(int devno) return -ENOMEM; } + nxmutex_init(&priv->lock); + priv->lcd_ptr = board_lcd_getdev(devno); if (!priv->lcd_ptr) { @@ -370,7 +448,9 @@ int lcddev_register(int devno) } return ret; + err: + nxmutex_destroy(&priv->lock); kmm_free(priv); return ret; } diff --git a/drivers/lcd/lcd_framebuffer.c b/drivers/lcd/lcd_framebuffer.c index e37efe9a52..3fd21109fb 100644 --- a/drivers/lcd/lcd_framebuffer.c +++ b/drivers/lcd/lcd_framebuffer.c @@ -524,6 +524,60 @@ static int lcdfb_ioctl(FAR struct fb_vtable_s *vtable, return ret; } +/**************************************************************************** + * Name: lcdfb_open + ****************************************************************************/ + +static int lcdfb_open(FAR struct fb_vtable_s *vtable) +{ + int ret = OK; + FAR struct lcdfb_dev_s *priv; + FAR struct lcd_dev_s *lcd; + + DEBUGASSERT(vtable != NULL); + + priv = (FAR struct lcdfb_dev_s *)vtable; + + if (priv != NULL) + { + lcd = priv->lcd; + + if (lcd->open) + { + ret = lcd->open(lcd); + } + } + + return ret; +} + +/**************************************************************************** + * Name: lcdfb_close + ****************************************************************************/ + +static int lcdfb_close(FAR struct fb_vtable_s *vtable) +{ + int ret = OK; + FAR struct lcdfb_dev_s *priv; + FAR struct lcd_dev_s *lcd; + + DEBUGASSERT(vtable != NULL); + + priv = (FAR struct lcdfb_dev_s *)vtable; + + if (priv != NULL) + { + lcd = priv->lcd; + + if (lcd->close) + { + ret = lcd->close(lcd); + } + } + + return ret; +} + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -581,6 +635,8 @@ int up_fbinitialize(int display) priv->vtable.updatearea = lcdfb_updateearea, priv->vtable.setpower = lcdfb_setpower, priv->vtable.ioctl = lcdfb_ioctl, + priv->vtable.open = lcdfb_open, + priv->vtable.close = lcdfb_close, #ifdef CONFIG_LCD_EXTERNINIT /* Use external graphics driver initialization */ diff --git a/include/nuttx/lcd/lcd.h b/include/nuttx/lcd/lcd.h index 0407fe33e5..6063e415bc 100644 --- a/include/nuttx/lcd/lcd.h +++ b/include/nuttx/lcd/lcd.h @@ -268,6 +268,11 @@ struct lcd_dev_s /* Passthrough unknown ioctl commands. */ int (*ioctl)(FAR struct lcd_dev_s *dev, int cmd, unsigned long arg); + + /* open/close window. */ + + int (*open)(FAR struct lcd_dev_s *dev); + int (*close)(FAR struct lcd_dev_s *dev); }; /****************************************************************************