Files
luban-lite-t3e-pro/bsp/artinchip/drv/display/panel/panel_com.c
刘可亮 0ef85b55da v1.1.0
2024-09-30 17:06:01 +08:00

393 lines
8.0 KiB
C

/*
* Copyright (c) 2023-2024, ArtInChip Technology Co., Ltd
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <aic_core.h>
#include <aic_hal.h>
#include "panel_com.h"
static struct aic_panel *panels[] = {
#if defined(AIC_DISP_RGB) && defined(AIC_SIMPLE_PANEL)
&aic_panel_rgb,
#endif
#if defined(AIC_DISP_LVDS) && defined(AIC_SIMPLE_PANEL)
&aic_panel_lvds,
#endif
#ifdef AIC_DSI_SIMPLE_PANEL
&dsi_simple,
#endif
#ifdef AIC_PANEL_DSI_XM91080
&dsi_xm91080,
#endif
#ifdef AIC_PANEL_DSI_ST7797
&dsi_st7797,
#endif
#ifdef AIC_PANEL_DSI_ST7703
&dsi_st7703,
#endif
#ifdef AIC_PANEL_DSI_ILI9881C
&dsi_ili9881c,
#endif
#ifdef AIC_PANEL_DSI_HX8394
&dsi_hx8394,
#endif
#ifdef AIC_PANEL_DSI_JD9365
&dsi_jd9365,
#endif
#ifdef AIC_PANEL_DSI_AXS15231B
&dsi_axs15231b,
#endif
#ifdef AIC_PANEL_DBI_ILI9488
&dbi_ili9488,
#endif
#ifdef AIC_PANEL_DBI_ILI9486L
&dbi_ili9486l,
#endif
#ifdef AIC_PANEL_DBI_ST7789
&dbi_st7789,
#endif
#ifdef AIC_PANEL_DBI_ILI9341
&dbi_ili9341,
#endif
#ifdef AIC_PANEL_DBI_ST77903
&dbi_st77903,
#endif
#ifdef AIC_PANEL_RGB_ST7701S
&rgb_st7701s,
#endif
#ifdef AIC_PANEL_RGB_GC9A01A
&rgb_gc9a01a,
#endif
#ifdef AIC_PANEL_RGB_NT35560
&rgb_nt35560,
#endif
#ifdef AIC_PANEL_RGB_ST77922
&rgb_st77922,
#endif
#ifdef AIC_PANEL_SRGB_HX8238
&srgb_hx8238,
#endif
#ifdef AIC_PANEL_BRIDGE_LT8911
&bridge_lt8911,
#endif
#ifdef AIC_PANEL_LCOS_HX7033
&lcos_hx7033,
#endif
};
struct aic_panel *aic_find_panel(u32 connector_type)
{
int i;
for (i = 0; i < ARRAY_SIZE(panels); i++) {
if (panels[i]->connector_type == connector_type) {
break;
}
}
if (i >= ARRAY_SIZE(panels))
return NULL;
pr_info("find panel driver : %s\n", panels[i]->name);
return panels[i];
}
/* The follow functions are defined for panel driver */
/* Enable the display interface */
void panel_di_enable(struct aic_panel *panel, u32 ms)
{
if (panel && panel->callbacks.di_enable)
panel->callbacks.di_enable();
if (ms)
aic_delay_ms(ms);
}
/* Disable the display interface */
void panel_di_disable(struct aic_panel *panel, u32 ms)
{
if (panel && panel->callbacks.di_disable)
panel->callbacks.di_disable();
if (ms)
aic_delay_ms(ms);
}
void panel_de_timing_enable(struct aic_panel *panel, u32 ms)
{
if (panel && panel->callbacks.timing_enable)
panel->callbacks.timing_enable();
if (ms)
aic_delay_ms(ms);
}
void panel_de_timing_disable(struct aic_panel *panel, u32 ms)
{
if (panel && panel->callbacks.timing_disable)
panel->callbacks.timing_disable();
if (ms)
aic_delay_ms(ms);
}
void panel_backlight_enable(struct aic_panel *panel, u32 ms)
{
#ifdef AIC_PANEL_ENABLE_GPIO
unsigned int g, p;
long pin;
pin = hal_gpio_name2pin(AIC_PANEL_ENABLE_GPIO);
g = GPIO_GROUP(pin);
p = GPIO_GROUP_PIN(pin);
hal_gpio_direction_output(g, p);
#ifndef AIC_PANEL_ENABLE_GPIO_LOW
hal_gpio_set_output(g, p);
#else
hal_gpio_clr_output(g, p);
#endif
#endif /* AIC_PANEL_ENABLE_GPIO */
#if defined(KERNEL_RTTHREAD) && defined(AIC_PWM_BACKLIGHT_CHANNEL)
struct rt_device_pwm *pwm_dev;
pwm_dev = (struct rt_device_pwm *)rt_device_find("pwm");
/* pwm frequency: 1KHz = 1000000ns */
rt_pwm_set(pwm_dev, AIC_PWM_BACKLIGHT_CHANNEL,
1000000, 10000 * AIC_PWM_BRIGHTNESS_LEVEL);
rt_pwm_enable(pwm_dev, AIC_PWM_BACKLIGHT_CHANNEL);
#endif
}
void panel_backlight_disable(struct aic_panel *panel, u32 ms)
{
#ifdef AIC_PANEL_ENABLE_GPIO
unsigned int g, p;
long pin;
pin = hal_gpio_name2pin(AIC_PANEL_ENABLE_GPIO);
g = GPIO_GROUP(pin);
p = GPIO_GROUP_PIN(pin);
#ifndef AIC_PANEL_ENABLE_GPIO_LOW
hal_gpio_clr_output(g, p);
#else
hal_gpio_set_output(g, p);
#endif
#endif /* AIC_PANEL_ENABLE_GPIO */
#if defined(KERNEL_RTTHREAD) && defined(AIC_PWM_BACKLIGHT_CHANNEL)
struct rt_device_pwm *pwm_dev;
pwm_dev = (struct rt_device_pwm *)rt_device_find("pwm");
rt_pwm_disable(pwm_dev, AIC_PWM_BACKLIGHT_CHANNEL);
#endif
}
int panel_default_prepare(void)
{
return 0;
}
int panel_default_unprepare(void)
{
return 0;
}
int panel_default_enable(struct aic_panel *panel)
{
panel_di_enable(panel, 0);
panel_de_timing_enable(panel, 60);
panel_backlight_enable(panel, 0);
return 0;
}
int panel_default_disable(struct aic_panel *panel)
{
panel_backlight_disable(panel, 0);
panel_di_disable(panel, 0);
panel_de_timing_disable(panel, 0);
return 0;
}
int panel_register_callback(struct aic_panel *panel,
struct aic_panel_callbacks *pcallback)
{
panel->callbacks.di_enable = pcallback->di_enable;
panel->callbacks.di_disable = pcallback->di_disable;
panel->callbacks.di_send_cmd = pcallback->di_send_cmd;
panel->callbacks.di_set_videomode = pcallback->di_set_videomode;
panel->callbacks.timing_enable = pcallback->timing_enable;
panel->callbacks.timing_disable = pcallback->timing_disable;
return 0;
}
void panel_send_command(u8 *para_cmd, u32 size, struct aic_panel *panel)
{
u8 *p;
u8 num, code;
for (p = para_cmd; p < (para_cmd + size);) {
num = *p++ - 1;
code = *p++;
if (num == 0)
aic_delay_ms((u32)code);
else
panel->callbacks.di_send_cmd((u32)code, 0, p, num);
p += num;
}
}
void panel_get_gpio(struct gpio_desc *desc, char *name)
{
long pin;
if (!desc || !name) {
pr_err("Invalid parameter\n");
return;
}
pin = hal_gpio_name2pin(name);
if (pin < 0) {
pr_err("Failed to get GPIO %s\n", name);
return;
}
desc->g = GPIO_GROUP(pin);
desc->p = GPIO_GROUP_PIN(pin);
hal_gpio_direction_output(desc->g, desc->p);
}
void panel_gpio_set_value(struct gpio_desc *desc, u32 value)
{
if (!desc) {
pr_err("Invalid parameter\n");
return;
}
if (value)
hal_gpio_set_output(desc->g, desc->p);
else
hal_gpio_clr_output(desc->g, desc->p);
}
#ifdef AIC_PANEL_SPI_EMULATION
static struct panel_spi_device spi = { 0 };
static bool panel_spi_emulation = false;
static inline void panel_spi_set_scl(u32 value)
{
panel_gpio_set_value(&spi.scl, value);
}
static inline void panel_spi_set_sdi(u32 value)
{
panel_gpio_set_value(&spi.sdi, value);
}
static inline void panel_spi_set_cs(u32 value)
{
panel_gpio_set_value(&spi.cs, value);
}
void panel_spi_cmd_wr(u8 cmd)
{
u32 i;
if (!panel_spi_emulation)
return;
panel_spi_set_cs(0);
panel_spi_set_sdi(0);
panel_spi_set_scl(0);
aic_delay_us(1);
panel_spi_set_scl(1);
aic_delay_us(1);
panel_spi_set_scl(0);
for (i = 0; i < 8; i++) {
if ((cmd & 0x80) == 0x80)
panel_spi_set_sdi(1);
else
panel_spi_set_sdi(0);
aic_delay_us(1);
panel_spi_set_scl(1);
aic_delay_us(1);
panel_spi_set_scl(0);
aic_delay_us(1);
cmd = cmd << 1;
}
panel_spi_set_cs(1);
panel_spi_set_sdi(0);
panel_spi_set_scl(0);
aic_delay_us(1);
}
void panel_spi_data_wr(u8 data)
{
u32 i;
if (!panel_spi_emulation)
return;
panel_spi_set_cs(0);
panel_spi_set_scl(0);
panel_spi_set_sdi(1);
aic_delay_us(1);
panel_spi_set_scl(1);
aic_delay_us(1);
panel_spi_set_scl(0);
for (i = 0; i < 8; i++) {
if ((data & 0x80) == 0x80)
panel_spi_set_sdi(1);
else
panel_spi_set_sdi(0);
aic_delay_us(1);
panel_spi_set_scl(1);
aic_delay_us(1);
panel_spi_set_scl(0);
aic_delay_us(1);
data = data << 1;
}
panel_spi_set_cs(1);
panel_spi_set_scl(0);
panel_spi_set_sdi(0);
aic_delay_us(1);
}
void panel_spi_device_emulation(char *cs, char *sdi, char *scl)
{
panel_get_gpio(&spi.cs, cs);
panel_get_gpio(&spi.scl, scl);
panel_get_gpio(&spi.sdi, sdi);
panel_spi_set_cs(1);
panel_spi_set_scl(0);
panel_spi_set_sdi(0);
aic_delay_us(1);
panel_spi_emulation = true;
}
#endif