drivers/lcd: Add suppose for a generic front-end that will convert any LCD driver into a framebuffer driver.
This commit is contained in:
parent
b90b4d40b6
commit
a9c054237a
@ -21,6 +21,23 @@ if LCD
|
||||
|
||||
comment "Common Graphic LCD Settings"
|
||||
|
||||
config LCD_FRAMEBUFFER
|
||||
bool "LCD framebuffer front end"
|
||||
default n
|
||||
select NX_UPDATE if NX
|
||||
---help---
|
||||
Enable a "front end" that converts an sequential LCD driver into a
|
||||
standard, NuttX frame buffer driver.
|
||||
|
||||
NOTE: Some LCD drivers implement an internal framebuffer for
|
||||
effeciency reasons but do not export a framebuffer interface. So
|
||||
those LCD cannot be used as framebuffer drivers. If the option is
|
||||
available, then such internal framebuffer support should be
|
||||
disabled because this external commone framebuffer interface will
|
||||
provide the necessary buffering.
|
||||
|
||||
menu "LCD driver selection"
|
||||
|
||||
config LCD_CONSOLE
|
||||
bool "LCD console output"
|
||||
default n
|
||||
@ -118,6 +135,11 @@ config P14201_FRAMEBUFFER
|
||||
All pixel writes must be aligned to byte boundaries.
|
||||
The latter limitation effectively reduces the 128x96 disply to 64x96.
|
||||
|
||||
NOTE: This option should not be used if CONFIG_LCD_FRAMBEBUFFER is
|
||||
enabled. That options provides for a more geneneralized, external
|
||||
LCD framebuffer. This internal framebuffer support should not be
|
||||
enabled with CONFIG_LCD_FRAMBEBUFFER because this external commone
|
||||
framebuffer interface will provide the necessary buffering.
|
||||
endif
|
||||
|
||||
config LCD_NOKIA6100
|
||||
@ -1083,6 +1105,7 @@ config LCD_RA8875_EXTENDED
|
||||
driver anyway.
|
||||
|
||||
endif # LCD_RA8875
|
||||
endmenu # LCD Driver selection
|
||||
endif # LCD
|
||||
|
||||
menuconfig SLCD
|
||||
|
@ -1,7 +1,7 @@
|
||||
############################################################################
|
||||
# drivers/lcd/Make.defs
|
||||
#
|
||||
# Copyright (C) 2010-2012 Gregory Nutt. All rights reserved.
|
||||
# Copyright (C) 2010-2012, 2017 Gregory Nutt. All rights reserved.
|
||||
# Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
@ -33,7 +33,13 @@
|
||||
#
|
||||
############################################################################
|
||||
|
||||
ifeq ($(CONFIG_NX_LCDDRIVER),y)
|
||||
ifeq ($(CONFIG_LCD),y)
|
||||
|
||||
# Support for the generic LCD framebufer front-end
|
||||
|
||||
ifeq ($(CONFIG_LCD_FRAMEBUFFER),y)
|
||||
CSRCS += lcd_framebuffer.c
|
||||
endif
|
||||
|
||||
# Include support for Graphics LCD drivers
|
||||
|
||||
@ -117,7 +123,7 @@ endif # CONFIG_SLCD
|
||||
|
||||
# Include LCD driver build support (the nested if-then-else implements an OR)
|
||||
|
||||
ifeq ($(CONFIG_NX_LCDDRIVER),y)
|
||||
ifeq ($(CONFIG_LCD),y)
|
||||
DEPPATH += --dep-path lcd
|
||||
VPATH += :lcd
|
||||
CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)drivers$(DELIM)lcd}
|
||||
|
705
drivers/lcd/lcd_framebuffer.c
Normal file
705
drivers/lcd/lcd_framebuffer.c
Normal file
@ -0,0 +1,705 @@
|
||||
/****************************************************************************
|
||||
* drivers/lcd/lcd_frambuffer.c
|
||||
*
|
||||
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/board.h>
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/nx/nx.h>
|
||||
#include <nuttx/nx/nxglib.h>
|
||||
#include <nuttx/lcd/lcd.h>
|
||||
#include <nuttx/video/fb.h>
|
||||
#include <arch/board/board.h>
|
||||
|
||||
#ifdef CONFIG_LCD_FRAMEBUFFER
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* At present, only video plane 0 is supported */
|
||||
|
||||
#define VIDEO_PLANE 0
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/* This structure describes the LCD frambuffer */
|
||||
|
||||
struct lcdfb_dev_s
|
||||
{
|
||||
struct fb_vtable_s vtable; /* Must be cast compatible with lcdfb_dev_s */
|
||||
FAR struct lcdfb_dev_s *flink; /* Supports a singly linked list */
|
||||
FAR struct lcd_dev_s *lcd; /* Contained LCD device */
|
||||
FAR uint8_t *fbmem; /* Allocated framebuffer */
|
||||
FAR struct lcd_planeinfo_s pinfo; /* LCD plane info */
|
||||
size_t fblen; /* Size of the framebuffer in bytes */
|
||||
fb_coord_t xres; /* Horizontal resolution in pixel columns */
|
||||
fb_coord_t yres; /* Vertical resolution in pixel rows */
|
||||
fb_coord_t stride; /* Width of a row in bytes */
|
||||
uint8_t display; /* Display number */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/* Update the LCD when there is a change to the framebuffer */
|
||||
|
||||
static void lcdfb_update(FAR struct lcdfb_dev_s *priv,
|
||||
FAR const struct nxgl_rect_s *rect);
|
||||
|
||||
/* Get information about the video controller configuration and the
|
||||
* configuration of each color plane.
|
||||
*/
|
||||
|
||||
static int lcdfb_getvideoinfo(FAR struct fb_vtable_s *vtable,
|
||||
FAR struct fb_videoinfo_s *vinfo);
|
||||
static int lcdfb_getplaneinfo(FAR struct fb_vtable_s *vtable, int planeno,
|
||||
FAR struct fb_planeinfo_s *pinfo);
|
||||
|
||||
/* The following is provided only if the video hardware supports RGB color
|
||||
* mapping
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_FB_CMAP
|
||||
static int lcdfb_getcmap(FAR struct fb_vtable_s *vtable,
|
||||
FAR struct fb_cmap_s *cmap);
|
||||
static int lcdfb_putcmap(FAR struct fb_vtable_s *vtable,
|
||||
FAR const struct fb_cmap_s *cmap);
|
||||
#endif
|
||||
|
||||
/* The following is provided only if the video hardware supports a hardware
|
||||
* cursor
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_FB_HWCURSOR
|
||||
static int lcdfb_getcursor(FAR struct fb_vtable_s *vtable,
|
||||
FAR struct fb_cursorattrib_s *attrib);
|
||||
static int lcdfb_setcursor(FAR struct fb_vtable_s *vtable,
|
||||
FAR struct fb_setcursor_s *settings);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/* This is a singly linked list that supports look-up of framebuffer state
|
||||
* using the display number.
|
||||
*/
|
||||
|
||||
static FAR struct lcdfb_dev_s *g_lcdfb;
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lcdfb_find
|
||||
*
|
||||
* Description:
|
||||
* Find the LCD framebuffer state associated with the display.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static FAR struct lcdfb_dev_s *lcdfb_find(int display)
|
||||
{
|
||||
FAR struct lcdfb_dev_s *priv;
|
||||
|
||||
/* Look up the LCD framebuffer state structure for this display.
|
||||
*
|
||||
* REVISIT: If many LCD framebuffers are used, then this lookup would be
|
||||
* a performance issue.
|
||||
* REVISIT: Semaphore protections is needed if there is concurrent access.
|
||||
*/
|
||||
|
||||
for (priv = g_lcdfb; priv != NULL; priv = priv->flink)
|
||||
{
|
||||
if (priv->display == display)
|
||||
{
|
||||
return priv;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lcdfb_update
|
||||
*
|
||||
* Description:
|
||||
* Update the LCD when there is a change to the framebuffer.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void lcdfb_update(FAR struct lcdfb_dev_s *priv,
|
||||
FAR const struct nxgl_rect_s *rect)
|
||||
{
|
||||
FAR struct lcd_planeinfo_s *pinfo = &priv->pinfo;
|
||||
FAR uint8_t *run;
|
||||
fb_coord_t row;
|
||||
fb_coord_t startx;
|
||||
fb_coord_t endx;
|
||||
fb_coord_t width;
|
||||
fb_coord_t starty;
|
||||
fb_coord_t endy;
|
||||
|
||||
/* Clip to fit in the framebuffer */
|
||||
|
||||
startx = rect->pt1.x;
|
||||
if (startx < 0)
|
||||
{
|
||||
startx = 0;
|
||||
}
|
||||
|
||||
endx = rect->pt2.x;
|
||||
if (endx >= priv->xres)
|
||||
{
|
||||
endx = priv->xres-1;
|
||||
}
|
||||
|
||||
width = endx - startx + 1;
|
||||
|
||||
starty = rect->pt1.y;
|
||||
if (starty < 0)
|
||||
{
|
||||
starty = 0;
|
||||
}
|
||||
|
||||
endy = rect->pt2.y;
|
||||
if (endy >= priv->yres)
|
||||
{
|
||||
endy = priv->yres-1;
|
||||
}
|
||||
|
||||
/* Get the starting position in the framebuffer */
|
||||
|
||||
run = priv->fbmem + starty * priv->stride;
|
||||
run += (startx * pinfo->bpp + 7) >> 3;
|
||||
|
||||
for (row = starty; row <= endy; row++)
|
||||
{
|
||||
pinfo->putrun(row, startx, run, width);
|
||||
run += priv->stride;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lcdfb_getvideoinfo
|
||||
****************************************************************************/
|
||||
|
||||
static int lcdfb_getvideoinfo(FAR struct fb_vtable_s *vtable,
|
||||
FAR struct fb_videoinfo_s *vinfo)
|
||||
{
|
||||
FAR struct lcdfb_dev_s *priv;
|
||||
FAR struct lcd_dev_s *lcd;
|
||||
int ret = -EINVAL;
|
||||
|
||||
lcdinfo("vtable=%p vinfo=%p\n", vtable, vinfo);
|
||||
|
||||
DEBUGASSERT(vtable != NULL && vinfo != NULL);
|
||||
priv = (FAR struct lcdfb_dev_s *)vtable;
|
||||
|
||||
if (priv != NULL && vinfo != NULL)
|
||||
{
|
||||
/* Get the video info from the contained LCD */
|
||||
|
||||
lcd = priv->lcd;
|
||||
DEBUGASSERT(lcd->getvideoinfo != NULL);
|
||||
ret = lcd->getvideoinfo(lcd, vinfo);
|
||||
if (ret < 0)
|
||||
{
|
||||
lcderr("ERROR: LCD getvideoinfo() failed: %d\n", ret);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lcdfb_getplaneinfo
|
||||
****************************************************************************/
|
||||
|
||||
static int lcdfb_getplaneinfo(FAR struct fb_vtable_s *vtable, int planeno,
|
||||
FAR struct fb_planeinfo_s *pinfo)
|
||||
{
|
||||
FAR struct lcdfb_dev_s *priv;
|
||||
int ret = -EINVAL;
|
||||
|
||||
lcdinfo("vtable=%p planeno=%d pinfo=%p\n", vtable, planeno, pinfo);
|
||||
|
||||
DEBUGASSERT(vtable != NULL && planeno == VIDEO_PLANE && pinfo != NULL);
|
||||
priv = (FAR struct lcdfb_dev_s *)vtable;
|
||||
|
||||
if (priv != NULL && planeno == VIDEO_PLANE && pinfo != NULL)
|
||||
{
|
||||
/* Return the plane info */
|
||||
|
||||
pinfo->fbmem = priv->fbmem;
|
||||
pinfo->fblen = priv->fblen;
|
||||
pinfo->stride = priv->stride;
|
||||
pinfo->display = priv->display;
|
||||
pinfo->bpp = priv->pinfo.bpp;
|
||||
|
||||
ret = OK;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lcdfb_getcmap
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_FB_CMAP
|
||||
static int lcdfb_getcmap(FAR struct fb_vtable_s *vtable,
|
||||
FAR struct fb_cmap_s *cmap)
|
||||
{
|
||||
FAR struct lcdfb_dev_s *priv;
|
||||
FAR struct lcd_dev_s *lcd;
|
||||
int ret = -EINVAL;
|
||||
|
||||
lcdinfo("vtable=%p cmap=%p\n", vtable, cmap);
|
||||
|
||||
DEBUGASSERT(vtable != NULL && cmap != NULL);
|
||||
priv = (FAR struct lcdfb_dev_s *)vtable;
|
||||
|
||||
if (priv != NULL && cmap != NULL)
|
||||
{
|
||||
/* Get the video info from the contained LCD */
|
||||
|
||||
lcd = priv->lcd
|
||||
DEBUGASSERT(lcd->getcmap != NULL);
|
||||
ret = lcd->getcmap(lcd, cmap);
|
||||
if (ret < 0)
|
||||
{
|
||||
lcderr("ERROR: LCD getcmap() failed: %d\n", ret);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lcdfb_putcmap
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_FB_CMAP
|
||||
static int lcdfb_putcmap(FAR struct fb_vtable_s *vtable,
|
||||
FAR const struct fb_cmap_s *cmap)
|
||||
{
|
||||
FAR struct lcdfb_dev_s *priv;
|
||||
FAR struct lcd_dev_s *lcd;
|
||||
int ret = -EINVAL;
|
||||
|
||||
lcdinfo("vtable=%p cmap=%p\n", vtable, cmap);
|
||||
|
||||
DEBUGASSERT(vtable != NULL && cmap != NULL);
|
||||
priv = (FAR struct lcdfb_dev_s *)vtable;
|
||||
|
||||
if (priv != NULL && cmap != NULL)
|
||||
{
|
||||
/* Get the video info from the contained LCD */
|
||||
|
||||
lcd = priv->lcd
|
||||
DEBUGASSERT(lcd->putcmap != NULL);
|
||||
ret = lcd->putcmap(lcd, cmap);
|
||||
if (ret < 0)
|
||||
{
|
||||
lcderr("ERROR: LCD putcmap() failed: %d\n", ret);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lcdfb_getcursor
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_FB_HWCURSOR
|
||||
static int lcdfb_getcursor(FAR struct fb_vtable_s *vtable,
|
||||
FAR struct fb_cursorattrib_s *attrib)
|
||||
{
|
||||
lcdinfo("vtable=%p attrib=%p\n", vtable, attrib);
|
||||
FAR struct lcdfb_dev_s *priv;
|
||||
FAR struct lcd_dev_s *lcd;
|
||||
int ret = -EINVAL;
|
||||
|
||||
lcdinfo("vtable=%p attrib=%p\n", vtable, attrib);
|
||||
|
||||
DEBUGASSERT(vtable != NULL && attrib != NULL);
|
||||
priv = (FAR struct lcdfb_dev_s *)vtable;
|
||||
|
||||
if (priv != NULL && attrib != NULL)
|
||||
{
|
||||
/* Get the video info from the contained LCD */
|
||||
|
||||
lcd = priv->lcd
|
||||
DEBUGASSERT(lcd->getcursor != NULL);
|
||||
ret = lcd->getcursor(lcd, attrib);
|
||||
if (ret < 0)
|
||||
{
|
||||
lcderr("ERROR: LCD getcursor() failed: %d\n", ret);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lcdfb_setcursor
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_FB_HWCURSOR
|
||||
static int lcdfb_setcursor(FAR struct fb_vtable_s *vtable,
|
||||
FAR struct fb_setcursor_s *settings)
|
||||
{
|
||||
FAR struct lcdfb_dev_s *priv;
|
||||
FAR struct lcd_dev_s *lcd;
|
||||
int ret = -EINVAL;
|
||||
|
||||
lcdinfo("vtable=%p settings=%p\n", vtable, settings);
|
||||
|
||||
DEBUGASSERT(vtable != NULL && settings != NULL);
|
||||
priv = (FAR struct lcdfb_dev_s *)vtable;
|
||||
|
||||
if (priv != NULL && settings != NULL)
|
||||
{
|
||||
/* Get the video info from the contained LCD */
|
||||
|
||||
lcd = priv->lcd
|
||||
DEBUGASSERT(lcd->setcursor != NULL);
|
||||
ret = lcd->setcursor(lcd, settings);
|
||||
if (ret < 0)
|
||||
{
|
||||
lcderr("ERROR: LCD setcursor() failed: %d\n", ret);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_fbinitialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize the framebuffer video hardware associated with the display.
|
||||
*
|
||||
* Input parameters:
|
||||
* display - In the case of hardware with multiple displays, this
|
||||
* specifies the display. Normally this is zero.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero is returned on success; a negated errno value is returned on any
|
||||
* failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int up_fbinitialize(int display)
|
||||
{
|
||||
FAR struct lcdfb_dev_s *priv;
|
||||
FAR struct lcd_dev_s *lcd;
|
||||
struct fb_videoinfo_s vinfo;
|
||||
struct nxgl_rect_s rect;
|
||||
int ret;
|
||||
|
||||
lcdinfo("display=%d\n", display);
|
||||
DEBUGASSERT((unsigned)display < UINT8_MAX);
|
||||
|
||||
/* Allocate the framebuffer state structure */
|
||||
|
||||
priv = (FAR struct lcdfb_dev_s *)kmm_zalloc(sizeof(struct lcdfb_dev_s));
|
||||
if (priv == NULL)
|
||||
{
|
||||
lcderr("ERROR: Failed to allocate state structure\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Initialize the LCD-independent fields of the state structure */
|
||||
|
||||
priv->display = display;
|
||||
|
||||
priv->vtable.getvideoinfo = lcdfb_getvideoinfo,
|
||||
priv->vtable.getplaneinfo = lcdfb_getplaneinfo,
|
||||
#ifdef CONFIG_FB_CMAP
|
||||
priv->vtable.getcmap = lcdfb_getcmap,
|
||||
priv->vtable.putcmap = lcdfb_putcmap,
|
||||
#endif
|
||||
#ifdef CONFIG_FB_HWCURSOR
|
||||
priv->vtable.getcursor = lcdfb_getcursor,
|
||||
priv->vtable.setcursor = lcdfb_setcursor,
|
||||
#endif
|
||||
|
||||
/* Initialize the LCD device */
|
||||
|
||||
ret = board_lcd_initialize();
|
||||
if (ret < 0)
|
||||
{
|
||||
lcderr("ERROR: board_lcd_initialize() failed: %d\n", ret);
|
||||
goto errout_with_state;
|
||||
}
|
||||
|
||||
/* Get the device instance */
|
||||
|
||||
lcd = board_lcd_getdev(display);
|
||||
if (lcd == NULL)
|
||||
{
|
||||
lcderr("ERROR: board_lcd_getdev failed, devno=%d\n", display);
|
||||
ret = -ENODEV;
|
||||
goto errout_with_lcd;
|
||||
}
|
||||
|
||||
priv->lcd = lcd;
|
||||
|
||||
/* Initialize the LCD-dependent fields of the state structure */
|
||||
|
||||
DEBUGASSERT(lcd->getvideoinfo != NULL);
|
||||
ret = lcd->getvideoinfo(lcd, &vinfo);
|
||||
if (ret < 0)
|
||||
{
|
||||
gerr("ERROR: getvideoinfo() failed: %d\n", ret);
|
||||
goto errout_with_lcd;
|
||||
}
|
||||
|
||||
priv->xres = vinfo.xres;
|
||||
priv->yres = vinfo.yres;
|
||||
|
||||
DEBUGASSERT(lcd->getplaneinfo != NULL);
|
||||
ret = lcd->getplaneinfo(lcd, VIDEO_PLANE, &priv->pinfo);
|
||||
if (ret < 0)
|
||||
{
|
||||
gerr("ERROR: getplaneinfo() failed: %d\n", ret);
|
||||
goto errout_with_lcd;
|
||||
}
|
||||
|
||||
/* Allocate (and clear) the framebuffer */
|
||||
|
||||
priv->stride = ((size_t)priv->xres * priv->pinfo.bpp + 7) >> 3;
|
||||
priv->fblen = priv->stride * priv->yres;
|
||||
|
||||
priv->fbmem = (FAR uint8_t *)kmm_zalloc(priv->fblen);
|
||||
if (priv->fbmem == NULL)
|
||||
{
|
||||
gerr("ERROR: getplaneinfo() failed: %d\n", ret);
|
||||
ret = -ENOMEM;
|
||||
goto errout_with_lcd;
|
||||
}
|
||||
|
||||
/* Add the state structure to the list of framebuffer interfaces */
|
||||
|
||||
priv->flink = g_lcdfb;
|
||||
g_lcdfb = priv;
|
||||
|
||||
/* Write the entire framebuffer to the LCD */
|
||||
|
||||
rect.pt1.x = 0;
|
||||
rect.pt1.y = 0;
|
||||
rect.pt2.x = priv->xres - 1;
|
||||
rect.pt2.y = priv->yres - 1;
|
||||
|
||||
lcdfb_update(priv, &rect);
|
||||
|
||||
/* Turn the LCD on at 75% power */
|
||||
|
||||
(void)priv->lcd->setpower(priv->lcd, ((3*CONFIG_LCD_MAXPOWER + 3)/4));
|
||||
return OK;
|
||||
|
||||
errout_with_lcd:
|
||||
board_lcd_uninitialize();
|
||||
|
||||
errout_with_state:
|
||||
kmm_free(priv);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_fbgetvplane
|
||||
*
|
||||
* Description:
|
||||
* Return a a reference to the framebuffer object for the specified video
|
||||
* plane of the specified plane. Many OSDs support multiple planes of video.
|
||||
*
|
||||
* Input parameters:
|
||||
* display - In the case of hardware with multiple displays, this
|
||||
* specifies the display. Normally this is zero.
|
||||
* vplane - Identifies the plane being queried.
|
||||
*
|
||||
* Returned Value:
|
||||
* A non-NULL pointer to the frame buffer access structure is returned on
|
||||
* success; NULL is returned on any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR struct fb_vtable_s *up_fbgetvplane(int display, int vplane)
|
||||
{
|
||||
FAR struct lcdfb_dev_s *priv;
|
||||
|
||||
lcdinfo("display=%d vplane=%d\n", display, vplane);
|
||||
DEBUGASSERT(vplane == VIDEO_PLANE);
|
||||
|
||||
/* Look up the LCD framebuffer state structure for this display. */
|
||||
|
||||
priv = lcdfb_find(display);
|
||||
if (priv == NULL)
|
||||
{
|
||||
lcderr("ERROR: lcd_find(%d) failed\n", display);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &priv->vtable;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_fbuninitialize
|
||||
*
|
||||
* Description:
|
||||
* Uninitialize the framebuffer support for the specified display.
|
||||
*
|
||||
* Input Parameters:
|
||||
* display - In the case of hardware with multiple displays, this
|
||||
* specifies the display. Normally this is zero.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_fbuninitialize(int display)
|
||||
{
|
||||
FAR struct lcdfb_dev_s *priv;
|
||||
FAR struct lcdfb_dev_s *prev;
|
||||
|
||||
/* Find the LCD framebuffer state associated with this display.
|
||||
* REVISIT: Semaphore protections is needed if there is concurrent access.
|
||||
*/
|
||||
|
||||
for (prev = NULL, priv = g_lcdfb;
|
||||
priv != NULL;
|
||||
prev = priv, priv = priv->flink)
|
||||
{
|
||||
if (priv->display == display)
|
||||
{
|
||||
/* Remove the state structure from the list */
|
||||
|
||||
if (prev != NULL)
|
||||
{
|
||||
prev->flink = priv->flink;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_lcdfb = priv->flink;
|
||||
}
|
||||
|
||||
/* Uninitialize the LCD */
|
||||
|
||||
board_lcd_uninitialize();
|
||||
|
||||
/* Free the frame buffer allocation */
|
||||
|
||||
kmm_free(priv->fbmem);
|
||||
|
||||
/* Free the state structure allocation */
|
||||
|
||||
kmm_free(priv);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nx_notify_rectangle
|
||||
*
|
||||
* Description:
|
||||
* When CONFIG_NX_UPDATE=y, then the graphics system will callout to
|
||||
* inform some external module that the display has been updated. This
|
||||
* would be useful in a couple for cases.
|
||||
*
|
||||
* - When a serial LCD is used, but a framebuffer is used to access the
|
||||
* LCD. In this case, the update callout can be used to refresh the
|
||||
* affected region of the display.
|
||||
*
|
||||
* - When VNC is enabled. This is case, this callout is necessary to
|
||||
* update the remote frame buffer to match the local framebuffer.
|
||||
*
|
||||
* When this feature is enabled, some external logic must provide this
|
||||
* interface. This is the function that will handle the notification. It
|
||||
* receives the rectangular region that was updated on the provided plane.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NX_UPDATE
|
||||
void nx_notify_rectangle(FAR NX_PLANEINFOTYPE *pinfo,
|
||||
FAR const struct nxgl_rect_s *rect)
|
||||
{
|
||||
FAR struct fb_planeinfo_s *fpinfo = (FAR struct fb_planeinfo_s *)pinfo;
|
||||
FAR struct lcdfb_dev_s *priv;
|
||||
|
||||
DEBUGASSERT(fpinfo != NULL && rect != NULL);
|
||||
|
||||
/* Look up the LCD framebuffer state structure for this display.
|
||||
*
|
||||
* REVISIT: If many LCD framebuffers are used, then this lookup would be
|
||||
* a performance issue.
|
||||
*/
|
||||
|
||||
priv = lcdfb_find(fpinfo->display);
|
||||
if (priv != NULL)
|
||||
{
|
||||
lcdfb_update(priv, rect);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_LCD_FRAMEBUFFER */
|
Loading…
x
Reference in New Issue
Block a user