1.806驱动添加获取唤醒源功能,驱动编译进内核

2.lcd驱动增加背光渐亮功能,解耦驱动
This commit is contained in:
张兆鹏 2025-04-28 17:58:56 +08:00
parent 17f1d2754e
commit 0833611b03
7 changed files with 169 additions and 52 deletions

View File

@ -88,6 +88,11 @@
reg = <0x0 0x4304A000 0x0 0x1000>;
no-map;
};
wakeup_source: wakeup_source {
reg = <0x0 0x4304B000 0x0 0x00001000>;
compatible = "wakeup-src";
no-map;
};
boot_param: boot_param@0x42FFF000 {
reg = <0x0 0x42FFF000 0x0 0x1000>;

View File

@ -913,7 +913,7 @@ CONFIG_NET_CORE=y
# CONFIG_SLIP is not set
# CONFIG_USB_NET_DRIVERS is not set
CONFIG_WLAN=y
CONFIG_XR806_WLAN=m
CONFIG_XR806_WLAN=y
# CONFIG_USB_NET_RNDIS_WLAN is not set
# CONFIG_VIRT_WIFI is not set
@ -1128,7 +1128,7 @@ CONFIG_DUMP_REG=y
CONFIG_DUMP_REG_MISC=y
# CONFIG_SUNXI_TIMER_TEST is not set
# CONFIG_HAS_INTERNALCODEC is not set
# CONFIG_MEM_OPERATION is not set
CONFIG_MEM_OPERATION=y
# CONFIG_SUNXI_TRANSFORM is not set
# CONFIG_SUNXI_DI is not set
CONFIG_SUNXI_G2D=y
@ -2049,7 +2049,7 @@ CONFIG_LCD_SUPPORT_ICN6202_2LANE=y
CONFIG_DISP2_SUNXI_SUPPORT_SMBL=y
CONFIG_DISP2_SUNXI_SUPPORT_ENAHNCE=y
# CONFIG_DISP2_HAS_SUPPORT_FRONT_WKSRCBL is not set
# CONFIG_DISP2_HAS_SUPPORT_BACK_WKSRCBL is not set
CONFIG_DISP2_HAS_SUPPORT_BACK_WKSRCBL=y
# CONFIG_FB_SSD1307 is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
# CONFIG_VGASTATE is not set

View File

@ -27,4 +27,4 @@ endif
$(CONFIG_MODULE_NAME)-y := $(xr806-y)
obj-m += $(CONFIG_MODULE_NAME).o
obj-$(CONFIG_XR806_WLAN) += $(CONFIG_MODULE_NAME).o

View File

@ -18,6 +18,10 @@
#define __XR_CMD_PROTO_H__
/*XR_WIFI_HOST_HAND_WAY */
#define HAS_MAGIC (0x55aa55aa)
#define HAS_SET_WAKEUP_SRC (0x0264)
#define HAS_GET_WAKEUP_SRC (0x0259)
struct cmd_para_hand_way {
u8 id;
};
@ -70,5 +74,22 @@ struct cmd_payload {
u8 param[0];
};
#pragma pack(1)
typedef struct{
u32 magic; /* HAS_PACKET_MAGIC */
u16 event;
u32 payload_size; /* total size of payload */
u8 wakeupsrc; /* the addr of payload */
}kpacket_box; //for transport reason
struct cmd_has_payload {
u16 unkown1;
u16 unkown2;
u32 len;
kpacket_box has_app_proto;
};
#pragma pack()
#define CMD_HEAD_SIZE (sizeof(struct cmd_payload))
#endif

View File

@ -29,6 +29,16 @@
u16 txparse_flags;
u16 rxparse_flags;
#if defined(CONFIG_HAS_INTERNALCODEC)
extern void doorbell_control(unsigned char wakeup_src);
#endif
#if defined(CONFIG_DISP2_HAS_SUPPORT_BACK_WKSRCBL)
extern void disp_backlight_control(unsigned char wakeup_src);
#endif
#if defined(CONFIG_MEM_OPERATION)
extern int mem_set_wakeup_source(unsigned char wakeup_src);
#endif
void xradio_wake_up_tx_work(void *priv)
{
struct xradio_priv *_priv = (struct xradio_priv *)priv;
@ -257,6 +267,9 @@ end:
return ret;
}
static struct cmd_has_payload *has_cmd = NULL;
static int xradio_rx_process(struct xradio_priv *priv, struct sk_buff *skb)
{
struct xradio_hdr *hdr = NULL;
@ -266,6 +279,7 @@ static int xradio_rx_process(struct xradio_priv *priv, struct sk_buff *skb)
u16 checksum = 0, c_checksum = 0;
u8 seq = 0;
static int dev_seq = -1;
static unsigned char get_wksrc_flag = 0;
int i;
if (!priv || !skb)
@ -316,6 +330,23 @@ static int xradio_rx_process(struct xradio_priv *priv, struct sk_buff *skb)
/* incom data */
if (type_id == XR_REQ_CMD) {
xradio_rx_cmd_process(priv, skb, cur_len, seq);
if (get_wksrc_flag == 0)
{
has_cmd = (struct cmd_has_payload *)skb->data;
if ((has_cmd->has_app_proto.magic == HAS_MAGIC) && has_cmd->has_app_proto.event == HAS_SET_WAKEUP_SRC)
{
#if defined(CONFIG_HAS_INTERNALCODEC)
doorbell_control(has_cmd->has_app_proto.wakeupsrc);
#endif
#if defined(CONFIG_DISP2_HAS_SUPPORT_BACK_WKSRCBL)
disp_backlight_control(has_cmd->has_app_proto.wakeupsrc);
#endif
#if defined(CONFIG_MEM_OPERATION)
mem_set_wakeup_source(has_cmd->has_app_proto.wakeupsrc);
#endif
get_wksrc_flag = 1;
}
}
} else {
#if DATA_TEST
xradio_data_test_rx_handle(skb->data, skb->len);
@ -403,9 +434,20 @@ static int xradio_txrx_thread(void *data)
int status = 0;
int rx_len = 0;
int tx_status = 0;
const struct cmd_has_payload wakeup_src_cmd =
{
.unkown1 = 0x003f, // TODO:全志通信协议
.unkown2 = 0x000f,
.len = sizeof(kpacket_box),
.has_app_proto.magic = HAS_MAGIC,
.has_app_proto.event = HAS_GET_WAKEUP_SRC,
.has_app_proto.payload_size = 1,
.has_app_proto.wakeupsrc = 0,
};
xradio_k_atomic_set(&priv->tranc_ready, 1);
xradio_tx_cmd_process(priv, (char *)&wakeup_src_cmd, sizeof(wakeup_src_cmd)); // 获取唤醒源
while (1) {
status = wait_event_interruptible(priv->txrx_wq, ({
rx = xradio_hwio_rx_pending();

View File

@ -66,32 +66,16 @@ static struct disp_lcd_private_data *lcd_private;
static int panel_timing_init(int disp, int lcd_index,
struct disp_panel_para *panel_info, struct disp_video_timings *timmings);
#if defined(CONFIG_DISP2_HAS_SUPPORT_FRONT_WKSRCBL) && defined(CONFIG_DISP2_HAS_SUPPORT_BACK_WKSRCBL)
#error "you can't define both front and back board at the same time"
#endif
#if defined(CONFIG_DISP2_HAS_SUPPORT_FRONT_WKSRCBL) || defined(CONFIG_DISP2_HAS_SUPPORT_BACK_WKSRCBL)
#include <linux/io.h>
#include <linux/timer.h>
#ifdef CONFIG_DISP2_HAS_SUPPORT_FRONT_WKSRCBL
#define STARTUP_DURATION_TIME 600 // 软件定时器很不准确,要设置对应时间需要实际测试
#endif
#ifdef CONFIG_DISP2_HAS_SUPPORT_BACK_WKSRCBL
// #define STARTUP_DURATION_TIME 600
#endif
#define STARTUP_PERIOD 20 // ms
#define STARTUP_START_PWM_VALUE 20 // 起始pwm值
#define STARTUP_EMD_PWD_VALUE 250 // MAX
/*
start up的pwm数值变化
250(MAX)
/
STARTUP_START_PWM_VALUE _/
*/
#ifndef CONFIG_MEM_OPERATION
#define WEIGHT_ADDR 0x4304B000 // 权重加载的内存地址处
#define M_PAGE_SIZE (4 * 1024) // 内存对齐应该是4K
#endif
typedef enum {
HAS_APP_WAKEUP_SOURCE_NONE,
@ -104,21 +88,55 @@ typedef enum {
HAS_APP_WAKEUP_SOURCE_NFC, // NFC
} has_app_wakeup_source_e; // 前板唤醒源
#endif
#ifdef CONFIG_DISP2_HAS_SUPPORT_BACK_WKSRCBL
#define STARTUP_DURATION_TIME 480
#define WAIT_WAKEUP_SRC_TIMEOUT 800
#define WAIT_FOR_WAKEUP_SRC 0
#define START_BACK_LIGHT 1
#define NOT_START_BACK_LIGHT 0xFF
typedef enum {
HAS_APP_WAKEUP_SOURCE_NONE_BACK,
HAS_APP_WAKEUP_SOURCE_TOUCH, // 触摸
HAS_APP_WAKEUP_SOURCE_STREAM, // 推拉流
HAS_APP_WAKEUP_SOURCE_DOORBELL, // 门铃
HAS_APP_WAKEUP_SOURCE_PEEPHOLE, // 猫眼
HAS_APP_WAKEUP_SOURCE_INVALID, // 无效
} has_app_wakeup_source_back_e; // 后板唤醒源
static atomic_t g_wakeup_start = ATOMIC_INIT(WAIT_FOR_WAKEUP_SRC);
#endif
#define STARTUP_PERIOD 20 // ms
#define STARTUP_START_PWM_VALUE 20 // 起始pwm值
#define STARTUP_EMD_PWD_VALUE 250 // MAX
/*
start up的pwm数值变化
250(MAX)
/
STARTUP_START_PWM_VALUE _/
*/
typedef struct
{
struct timer_list timer;
spinlock_t bl_lock;
unsigned char exit_flag ;
unsigned char timer_flag ;
#if defined(CONFIG_DISP2_HAS_SUPPORT_BACK_WKSRCBL)
unsigned long start_jiffies;
#endif
} has_startup_bl_t;
static has_startup_bl_t startup_bl = {
.exit_flag = 0,
.timer_flag = 0,
.timer.data = 0,
.bl_lock = __SPIN_LOCK_UNLOCKED(startup_bl.bl_lock),
};
#if defined(CONFIG_MEM_OPERATION)
#if defined(CONFIG_DISP2_HAS_SUPPORT_FRONT_WKSRCBL)
extern unsigned char mem_get_wakeup_source(void);
#endif
@ -1266,19 +1284,28 @@ static s32 disp_lcd_pwm_disable(struct disp_device *lcd)
#endif
#if defined(CONFIG_DISP2_HAS_SUPPORT_FRONT_WKSRCBL) || defined(CONFIG_DISP2_HAS_SUPPORT_BACK_WKSRCBL)
static s32 disp_lcd_clear_startup_bl(void)
{
if (startup_bl.timer_flag)
#if defined(CONFIG_DISP2_HAS_SUPPORT_BACK_WKSRCBL)
void disp_backlight_control(unsigned char wakeup_src) {
if ((wakeup_src == HAS_APP_WAKEUP_SOURCE_TOUCH) || (wakeup_src == HAS_APP_WAKEUP_SOURCE_DOORBELL)
|| (wakeup_src == HAS_APP_WAKEUP_SOURCE_PEEPHOLE))
{
unsigned long flags;
spin_lock_irqsave(&startup_bl.bl_lock, flags);
startup_bl.exit_flag = 1;
spin_unlock_irqrestore(&startup_bl.bl_lock, flags);
atomic_set(&g_wakeup_start, START_BACK_LIGHT);
}
else
{
startup_bl.exit_flag = 1;
atomic_set(&g_wakeup_start, NOT_START_BACK_LIGHT);
}
}
EXPORT_SYMBOL(disp_backlight_control);
#endif
static s32 disp_lcd_clear_startup_bl(void)
{
unsigned long flags;
spin_lock_irqsave(&startup_bl.bl_lock, flags); // wait for the light be setting gracefully
startup_bl.exit_flag = 1;
spin_unlock_irqrestore(&startup_bl.bl_lock, flags);
return 0;
}
@ -1286,6 +1313,9 @@ static void disp_lcd_backlight_increase(unsigned long data)
{
static u32 cur_bl = STARTUP_START_PWM_VALUE;
unsigned long flags;
#if defined(CONFIG_DISP2_HAS_SUPPORT_BACK_WKSRCBL)
unsigned int start_flag;
#endif
if (data == 0)
{
// pr_emerg("wrong with data\n");
@ -1299,8 +1329,37 @@ static void disp_lcd_backlight_increase(unsigned long data)
del_timer(&startup_bl.timer);
return;
}
#if defined(CONFIG_DISP2_HAS_SUPPORT_BACK_WKSRCBL)
start_flag = atomic_read(&g_wakeup_start);
if (start_flag == WAIT_FOR_WAKEUP_SRC) /* 等唤醒源 */
{
spin_unlock_irqrestore(&startup_bl.bl_lock, flags);
if (time_after(jiffies, startup_bl.start_jiffies + msecs_to_jiffies(WAIT_WAKEUP_SRC_TIMEOUT)))
{
del_timer(&startup_bl.timer); /* 超时,不亮屏 */
}
else
{
mod_timer(&startup_bl.timer, jiffies + msecs_to_jiffies(STARTUP_PERIOD));
}
return;
}
else if (start_flag == START_BACK_LIGHT) /* 执行 */
{
disp_lcd_set_bright((struct disp_device *)data, cur_bl);
spin_unlock_irqrestore(&startup_bl.bl_lock, flags);
}
else if (start_flag == NOT_START_BACK_LIGHT) /* 不执行 */
{
spin_unlock_irqrestore(&startup_bl.bl_lock, flags);
del_timer(&startup_bl.timer);
return;
}
#endif
#if defined(CONFIG_DISP2_HAS_SUPPORT_FRONT_WKSRCBL)
disp_lcd_set_bright((struct disp_device *)data, cur_bl);
spin_unlock_irqrestore(&startup_bl.bl_lock, flags);
#endif
cur_bl += ((STARTUP_EMD_PWD_VALUE - STARTUP_START_PWM_VALUE) / (STARTUP_DURATION_TIME / STARTUP_PERIOD));
if (cur_bl >= STARTUP_EMD_PWD_VALUE)
@ -1320,10 +1379,7 @@ static s32 disp_lcd_backlight_enable(struct disp_device *lcd)
struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
unsigned long flags;
#if defined(CONFIG_DISP2_HAS_SUPPORT_FRONT_WKSRCBL) || defined(CONFIG_DISP2_HAS_SUPPORT_BACK_WKSRCBL)
#ifndef CONFIG_MEM_OPERATION
void __iomem *vaddr = NULL;
#endif
#if defined(CONFIG_DISP2_HAS_SUPPORT_FRONT_WKSRCBL)
unsigned char wakeupsource = 0;
#endif
if ((lcd == NULL) || (lcdp == NULL)) {
@ -1363,25 +1419,18 @@ static s32 disp_lcd_backlight_enable(struct disp_device *lcd)
disp_sys_gpio_request(gpio_info, 1);
}
#if defined(CONFIG_DISP2_HAS_SUPPORT_FRONT_WKSRCBL) || defined(CONFIG_DISP2_HAS_SUPPORT_BACK_WKSRCBL)
#if defined(CONFIG_MEM_OPERATION)
#if defined(CONFIG_DISP2_HAS_SUPPORT_FRONT_WKSRCBL)
wakeupsource = mem_get_wakeup_source();
#else
vaddr = memremap(WEIGHT_ADDR, M_PAGE_SIZE, MEMREMAP_WB);
if (vaddr)
{
wakeupsource = readb(vaddr);
memunmap(vaddr);
}
#endif
if ((wakeupsource != HAS_APP_WAKEUP_SOURCE_BACK_PANEL) && (wakeupsource != HAS_APP_WAKEUP_SOURCE_NONE))
#endif
{
init_timer(&startup_bl.timer);
startup_bl.timer.function = disp_lcd_backlight_increase;
startup_bl.timer.expires = jiffies + 1;
startup_bl.timer.data = (unsigned long)lcd;
spin_lock_init(&startup_bl.bl_lock);
startup_bl.timer_flag = 1;
#if defined(CONFIG_DISP2_HAS_SUPPORT_BACK_WKSRCBL)
startup_bl.start_jiffies = jiffies;
#endif
add_timer(&startup_bl.timer);
}
#else

View File

@ -576,7 +576,7 @@ mount_usr
# mount_app
MODULES_DIR="/lib/modules/`uname -r`"
insmod $MODULES_DIR/xr806.ko
# insmod $MODULES_DIR/xr806.ko
/etc/init.d/S50wifidaemon start &
# insmod $MODULES_DIR/disp.ko # loaded by kernel
insmod $MODULES_DIR/sunxi_gpadc.ko