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); }; /****************************************************************************