[dm][graphic] add new drivers and logo
Some checks failed
ToolsCI / Tools (push) Has been cancelled
RT-Thread BSP Static Build Check / 🔍 Summary of Git Diff Changes (push) Has been cancelled
RT-Thread BSP Static Build Check / ${{ matrix.legs.RTT_BSP }} (push) Has been cancelled
RT-Thread BSP Static Build Check / collect-artifacts (push) Has been cancelled
doc_doxygen / doxygen_doc generate (push) Has been cancelled
doc_doxygen / deploy (push) Has been cancelled
pkgs_test / change (push) Has been cancelled
utest_auto_run / A9 :components/dfs.cfg (push) Has been cancelled
utest_auto_run / A9 :components/lwip.cfg (push) Has been cancelled
utest_auto_run / A9 :components/netdev.cfg (push) Has been cancelled
utest_auto_run / A9 :components/sal.cfg (push) Has been cancelled
utest_auto_run / A9 :cpp11/cpp11.cfg (push) Has been cancelled
utest_auto_run / AARCH64-rtsmart :default.cfg (push) Has been cancelled
utest_auto_run / A9-rtsmart :default.cfg (push) Has been cancelled
utest_auto_run / RISCV-rtsmart :default.cfg (push) Has been cancelled
utest_auto_run / XUANTIE-rtsmart :default.cfg (push) Has been cancelled
utest_auto_run / AARCH64 :default.cfg (push) Has been cancelled
utest_auto_run / AARCH64-smp :default.cfg (push) Has been cancelled
utest_auto_run / A9 :default.cfg (push) Has been cancelled
utest_auto_run / A9-smp :default.cfg (push) Has been cancelled
utest_auto_run / RISCV :default.cfg (push) Has been cancelled
utest_auto_run / RISCV-smp :default.cfg (push) Has been cancelled
utest_auto_run / A9 :kernel/atomic_c11.cfg (push) Has been cancelled
utest_auto_run / RISCV :kernel/atomic_c11.cfg (push) Has been cancelled
utest_auto_run / A9 :kernel/ipc.cfg (push) Has been cancelled
utest_auto_run / A9 :kernel/kernel_basic.cfg (push) Has been cancelled
utest_auto_run / A9 :kernel/mem.cfg (push) Has been cancelled
Weekly CI Scheduler / Trigger and Monitor CIs (push) Has been cancelled
Weekly CI Scheduler / Create Discussion Report (push) Has been cancelled

1. Generic GPIO based backlight driver
2. Generic PWM based backlight driver
3. Simple framebuffer support
4. Standard 224-color RT-Thread logo
5. Standard 224-color RT-Thread white logo

Signed-off-by: GuEe-GUI <2991707448@qq.com>
This commit is contained in:
GuEe-GUI
2025-12-12 16:03:34 +08:00
committed by R b b666
parent 5abecc1fd0
commit 27eb7c4f72
11 changed files with 4321 additions and 0 deletions

View File

@@ -2,6 +2,21 @@ menuconfig RT_GRAPHIC_BACKLIGHT
bool "Backlight support"
default n
config RT_GRAPHIC_BACKLIGHT_GPIO
bool "Generic GPIO based backlight driver"
depends on RT_GRAPHIC_BACKLIGHT
depends on RT_USING_PIN
default n
config RT_GRAPHIC_BACKLIGHT_PWM
bool "Generic PWM based backlight driver"
depends on RT_GRAPHIC_BACKLIGHT
depends on RT_USING_OFW
depends on RT_USING_PIN
depends on RT_USING_PWM
depends on RT_USING_REGULATOR
default n
if RT_GRAPHIC_BACKLIGHT
osource "$(SOC_DM_GRAPHIC_BACKLIGHT_DIR)/Kconfig"
endif

View File

@@ -10,5 +10,11 @@ CPPPATH = [cwd + '/../../include']
src = ['backlight.c']
if GetDepend(['RT_GRAPHIC_BACKLIGHT_GPIO']):
src += ['backlight-gpio.c']
if GetDepend(['RT_GRAPHIC_BACKLIGHT_PWM']):
src += ['backlight-pwm.c']
group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@@ -0,0 +1,135 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-02-25 GuEe-GUI the first version
*/
#include <rthw.h>
#include <rtthread.h>
#include <rtdevice.h>
#define DBG_TAG "backlight.gpio"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>
struct gpio_backlight
{
struct rt_backlight_device parent;
rt_base_t pin;
rt_uint8_t active_val;
};
#define raw_to_gpio_backlight(raw) rt_container_of(raw, struct gpio_backlight, parent)
static rt_err_t gpio_backlight_update_status(struct rt_backlight_device *bl)
{
rt_uint8_t brightness;
struct gpio_backlight *gbl = raw_to_gpio_backlight(bl);
rt_pin_mode(gbl->pin, PIN_MODE_OUTPUT);
brightness = rt_backlight_power_brightness(bl);
if (!gbl->active_val)
{
brightness = !brightness;
}
rt_pin_write(gbl->pin, brightness);
return RT_EOK;
}
static struct rt_backlight_ops gpio_backlight_ops =
{
.update_status = gpio_backlight_update_status,
};
static rt_err_t gpio_backlight_probe(struct rt_platform_device *pdev)
{
rt_err_t err;
rt_bool_t def_value;
struct rt_device *dev = &pdev->parent;
struct gpio_backlight *gbl = rt_calloc(1, sizeof(*gbl));
if (!gbl)
{
return -RT_ENOMEM;
}
def_value = rt_dm_dev_prop_read_bool(dev, "default-on");
gbl->pin = rt_pin_get_named_pin(dev, RT_NULL, 0, RT_NULL, &gbl->active_val);
if (gbl->pin < 0)
{
err = gbl->pin;
goto _fail;
}
/* Set the initial power state */
if (!dev->ofw_node || !rt_dm_dev_prop_read_bool(dev, "phandle"))
{
gbl->parent.props.power = def_value ?
RT_BACKLIGHT_POWER_UNBLANK : RT_BACKLIGHT_POWER_POWERDOWN;
}
else if (rt_pin_read(gbl->pin) != gbl->active_val)
{
gbl->parent.props.power = RT_BACKLIGHT_POWER_POWERDOWN;
}
else
{
gbl->parent.props.power = RT_BACKLIGHT_POWER_UNBLANK;
}
gbl->parent.props.max_brightness = 1;
gbl->parent.ops = &gpio_backlight_ops;
if ((err = rt_backlight_register(&gbl->parent)))
{
goto _fail;
}
rt_pin_mode(gbl->pin, PIN_MODE_OUTPUT);
rt_backlight_set_brightness(&gbl->parent, 1);
return RT_EOK;
_fail:
rt_free(gbl);
return err;
}
static rt_err_t gpio_backlight_remove(struct rt_platform_device *pdev)
{
struct gpio_backlight *gbl = pdev->parent.user_data;
rt_backlight_unregister(&gbl->parent);
rt_free(gbl);
return RT_EOK;
}
static const struct rt_ofw_node_id gpio_backlight_ofw_ids[] =
{
{ .compatible = "gpio-backlight" },
{ /* sentinel */ }
};
static struct rt_platform_driver gpio_backlight_driver =
{
.name = "gpio-backlight",
.ids = gpio_backlight_ofw_ids,
.probe = gpio_backlight_probe,
.remove = gpio_backlight_remove,
};
RT_PLATFORM_DRIVER_EXPORT(gpio_backlight_driver);

File diff suppressed because it is too large Load Diff

View File

@@ -3,6 +3,12 @@ menuconfig RT_GRAPHIC_FB
select RT_USING_LCD
default y
config RT_GRAPHIC_FB_SIMPLE
bool "Simple framebuffer support"
depends on RT_GRAPHIC_FB
depends on RT_USING_OFW
default y
if RT_GRAPHIC_FB
osource "$(SOC_DM_GRAPHIC_FB_DIR)/Kconfig"
endif

View File

@@ -11,6 +11,9 @@ CPPPATH = [cwd + '/../../include']
src = []
if GetDepend(['RT_GRAPHIC_FB_SIMPLE']):
src += ['fb-simple.c']
group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@@ -0,0 +1,381 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-02-25 GuEe-GUI the first version
*/
#include <rthw.h>
#include <rtthread.h>
#include <rtdevice.h>
#define DBG_TAG "fb.simple"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>
struct simplefb_format
{
const char *name;
rt_uint32_t mode;
rt_uint32_t bits_per_pixel;
};
struct simplefb_params
{
rt_uint32_t width;
rt_uint32_t height;
rt_uint32_t stride;
struct simplefb_format *format;
};
struct simplefb
{
struct rt_graphic_device parent;
void *screen_base;
rt_size_t screen_size;
rt_size_t stride;
#ifdef RT_USING_CLK
rt_bool_t clk_arr_enabled;
struct rt_clk_array *clk_arr;
#endif
#ifdef RT_USING_REGULATOR
rt_bool_t supplys_enabled;
rt_size_t supplys_nr;
struct rt_regulator **supplys;
#endif
};
#ifdef RT_USING_CLK
static rt_err_t simplefb_clk_probe(struct simplefb *sfb,
struct rt_platform_device *pdev)
{
sfb->clk_arr = rt_clk_get_array(&pdev->parent);
if (rt_is_err(sfb->clk_arr))
{
return rt_ptr_err(sfb->clk_arr);
}
return RT_EOK;
}
static void simplefb_clk_enable(struct simplefb *sfb)
{
rt_clk_array_prepare_enable(sfb->clk_arr);
sfb->clk_arr_enabled = RT_TRUE;
}
static void simplefb_clk_remove(struct simplefb *sfb)
{
if (!rt_is_err_or_null(sfb->clk_arr))
{
if (sfb->clk_arr_enabled)
{
rt_clk_array_disable_unprepare(sfb->clk_arr);
}
rt_clk_array_put(sfb->clk_arr);
}
}
#else
static rt_err_t simplefb_clk_probe(struct simplefb *sfb,
struct rt_platform_device *pdev) { return RT_EOK; }
static void simplefb_clk_enable(struct simplefb *sfb) { }
static void simplefb_clk_remove(struct simplefb *sfb) { }
#endif /* RT_USING_CLK */
#ifdef RT_USING_REGULATOR
#define SUPPLY_SUFFIX "-supply"
static rt_err_t simplefb_regulator_probe(struct simplefb *sfb,
struct rt_platform_device *pdev)
{
int i = 0;
const char *name;
struct rt_device *dev = &pdev->parent;
struct rt_ofw_prop *prop;
struct rt_ofw_node *np = dev->ofw_node;
rt_ofw_foreach_prop(np, prop)
{
name = rt_strstr(prop->name, SUPPLY_SUFFIX);
if (name && name != prop->name)
{
++sfb->supplys_nr;
}
}
sfb->supplys = rt_calloc(sfb->supplys_nr, sizeof(sfb->supplys[0]));
if (!sfb->supplys)
{
return -RT_ENOMEM;
}
rt_ofw_foreach_prop(np, prop)
{
name = rt_strstr(prop->name, SUPPLY_SUFFIX);
if (name && name != prop->name)
{
char name[32];
int len = name - prop->name;
rt_strncpy(name, prop->name, len);
name[len] = '\0';
sfb->supplys[i] = rt_regulator_get(dev, (const char *)name);
if (rt_is_err(sfb->supplys[i]))
{
return rt_ptr_err(sfb->supplys[i]);
}
++i;
}
}
return RT_EOK;
}
static void simplefb_regulator_enable(struct simplefb *sfb)
{
if (sfb->supplys)
{
for (int i = 0; i < sfb->supplys_nr; ++i)
{
rt_regulator_enable(sfb->supplys[i]);
}
sfb->supplys_enabled = RT_TRUE;
}
}
static void simplefb_regulator_remove(struct simplefb *sfb)
{
if (sfb->supplys && sfb->supplys_enabled)
{
for (int i = 0; i < sfb->supplys_nr; ++i)
{
struct rt_regulator *supply = sfb->supplys[i];
if (!rt_is_err(supply))
{
rt_regulator_disable(supply);
rt_regulator_put(supply);
}
}
rt_free(sfb->supplys);
}
}
#else
static rt_err_t simplefb_regulator_probe(struct simplefb *sfb,
struct rt_platform_device *pdev)
{
return RT_EOK;
}
static void simplefb_regulator_enable(struct simplefb *sfb)
{
}
static void simplefb_regulator_remove(struct simplefb *sfb)
{
}
#endif /* RT_USING_REGULATOR */
static struct simplefb_format simplefb_formats[] =
{
{ "r5g6b5", RTGRAPHIC_PIXEL_FORMAT_RGB565, 16 },
{ "r8g8b8", RTGRAPHIC_PIXEL_FORMAT_RGB888, 24 },
{ "x8r8g8b8", RTGRAPHIC_PIXEL_FORMAT_ARGB888, 32 },
{ "a8r8g8b8", RTGRAPHIC_PIXEL_FORMAT_ARGB888, 32 },
{ "x8b8g8r8", RTGRAPHIC_PIXEL_FORMAT_ABGR888, 32 },
{ "a8b8g8r8", RTGRAPHIC_PIXEL_FORMAT_ABGR888, 32 },
};
static rt_err_t simplefb_params_parse(struct simplefb_params *params,
struct rt_platform_device *pdev)
{
rt_err_t err;
const char *format;
struct rt_device *dev = &pdev->parent;
if ((err = rt_dm_dev_prop_read_u32(dev, "width", &params->width)))
{
LOG_E("Can't parse width property");
return err;
}
if ((err = rt_dm_dev_prop_read_u32(dev, "height", &params->height)))
{
LOG_E("Can't parse height property");
return err;
}
if ((err = rt_dm_dev_prop_read_u32(dev, "stride", &params->stride)))
{
LOG_E("Can't parse stride property");
return err;
}
if ((err = rt_dm_dev_prop_read_string(dev, "format", &format)))
{
LOG_E("Can't parse format property");
return err;
}
for (int i = 0; i < RT_ARRAY_SIZE(simplefb_formats); ++i)
{
if (rt_strcmp(format, simplefb_formats[i].name))
{
continue;
}
params->format = &simplefb_formats[i];
return RT_EOK;
}
LOG_E("Unsupport format value");
return -RT_EINVAL;
}
static rt_err_t simplefb_plane_fb_remap(struct rt_graphic_plane *plane,
rt_uint32_t mode, struct rt_device_rect_info *rect)
{
struct simplefb *sfb = rt_container_of(plane->graphic, struct simplefb, parent);
plane->line_length = sfb->stride;
plane->bits_per_pixel = rt_graphic_mode_bpp(mode);
plane->framebuffer = sfb->screen_base;
plane->screen_len = sfb->screen_size;
plane->framebuffer_len = sfb->screen_size;
return RT_EOK;
}
static const struct rt_graphic_plane_ops simplefb_plane_ops =
{
.fb_remap = simplefb_plane_fb_remap,
};
static rt_err_t simplefb_probe(struct rt_platform_device *pdev)
{
rt_err_t err;
rt_uint64_t addr, size;
struct simplefb_params params = {};
struct simplefb *sfb = rt_calloc(1, sizeof(*sfb));
if (!sfb)
{
return -RT_ENOMEM;
}
if ((err = simplefb_params_parse(&params, pdev)))
{
goto _fail;
}
sfb->stride = params.stride;
if ((err = rt_dm_dev_get_address(&pdev->parent, 0, &addr, &size)))
{
goto _fail;
}
sfb->screen_size = (rt_size_t)size;
sfb->screen_base = rt_ioremap_wt((void *)addr, sfb->screen_size);
if (!sfb->screen_base)
{
err = -RT_EIO;
goto _fail;
}
if ((err = simplefb_clk_probe(sfb, pdev)))
{
LOG_E("Get %s error = %s", "clk", rt_strerror(err));
goto _fail;
}
if ((err = simplefb_regulator_probe(sfb, pdev)))
{
LOG_E("Get %s error = %s", "regulator", rt_strerror(err));
goto _fail;
}
simplefb_clk_enable(sfb);
simplefb_regulator_enable(sfb);
if ((err = rt_graphic_device_simple_register(&sfb->parent,
params.width, params.height, 0, &simplefb_plane_ops,
&params.format->mode, 1)))
{
goto _fail;
}
pdev->parent.user_data = sfb;
return RT_EOK;
_fail:
if (sfb->screen_base)
{
rt_iounmap(sfb->screen_base);
}
simplefb_clk_remove(sfb);
simplefb_regulator_remove(sfb);
rt_free(sfb);
return err;
}
static rt_err_t simplefb_remove(struct rt_platform_device *pdev)
{
struct simplefb *sfb = pdev->parent.user_data;
rt_graphic_device_simple_unregister(&sfb->parent);
simplefb_clk_remove(sfb);
simplefb_regulator_remove(sfb);
rt_iounmap(sfb->screen_base);
rt_free(sfb);
return RT_EOK;
}
static const struct rt_ofw_node_id simplefb_ofw_ids[] =
{
{ .compatible = "simple-framebuffer" },
{ /* sentinel */ }
};
static struct rt_platform_driver simplefb_driver =
{
.name = "simple-framebuffer",
.ids = simplefb_ofw_ids,
.probe = simplefb_probe,
.remove = simplefb_remove,
};
RT_PLATFORM_DRIVER_EXPORT(simplefb_driver);

View File

@@ -11,6 +11,12 @@ choice
config RT_GRAPHIC_LOGO_NONE
bool "None logo (Change in runtime)"
config RT_GRAPHIC_LOGO_RT_THREAD_CLUT224
bool "Standard 224-color RT-Thread logo"
config RT_GRAPHIC_LOGO_RT_THREAD_WHITE_CLUT224
bool "Standard 224-color RT-Thread white logo"
osource "$(SOC_DM_GRAPHIC_LOGO_DIR)/Kconfig"
endchoice

View File

@@ -17,6 +17,12 @@ logo_width = 0
logo_height = 0
logo_max_val = 0
if GetDepend(['RT_GRAPHIC_LOGO_RT_THREAD_CLUT224']):
logo_path = cwd + '/logo-rt-thread-clut224.ppm'
if GetDepend(['RT_GRAPHIC_LOGO_RT_THREAD_WHITE_CLUT224']):
logo_path = cwd + '/logo-rt-thread-white-clut224.ppm'
if logo_path == None:
# Find in BSP
paths = None

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff