GK SDK 源码库: XMIPCLinuxV100R005C00SPC030 (kernel/tools/open_source excluded)
This commit is contained in:
Executable
+30
@@ -0,0 +1,30 @@
|
||||
ifneq ($(srctree),)
|
||||
KERNEL_DIR := $(srctree)
|
||||
SDK_DIR := $(shell cd $(KERNEL_DIR)/../../.. && /bin/pwd)
|
||||
else
|
||||
SDK_DIR := $(shell cd $(CURDIR)/../../../.. && /bin/pwd)
|
||||
endif
|
||||
|
||||
include $(SDK_DIR)/build/base.mk
|
||||
include $(SDK_DIR)/build/version.mk
|
||||
|
||||
MOD_NAME := xm_misc
|
||||
|
||||
SRCS := ./src/drv_misc.c
|
||||
SRCS += ./src/drv_osd_draw_time.c
|
||||
SRCS += ./src/drv_sensor.c
|
||||
|
||||
SDK_KER_CFLAGS += -I$(GMP_DIR)/include
|
||||
SDK_KER_CFLAGS += -I$(GMP_DIR)/drv/osal/include
|
||||
SDK_KER_CFLAGS += -I$(GMP_DIR)/drv/common/include
|
||||
SDK_KER_CFLAGS += -I$(GMP_DIR)/drv/common/task
|
||||
SDK_KER_CFLAGS += -I$(GMP_DIR)/drv/include
|
||||
SDK_KER_CFLAGS += -I$(GMP_DIR)/drv/misc/include
|
||||
SDK_KER_CFLAGS += -I$(GMP_DIR)/usr/include
|
||||
SDK_KER_CFLAGS += -I$(GMP_DIR)/usr/common/include
|
||||
|
||||
$(info SDK_KER_CFLAGS=$(SDK_KER_CFLAGS))
|
||||
$(info SRCS=$(SRCS))
|
||||
$(info SDK_DIR=$(SDK_DIR))
|
||||
|
||||
include $(SDK_DIR)/build/sdk_ko_rules.mk
|
||||
Executable
+99
@@ -0,0 +1,99 @@
|
||||
#ifndef __DRV_MISC_H__
|
||||
#define __DRV_MISC_H__
|
||||
|
||||
#include "xmedia_debug.h"
|
||||
#include "xmedia_type.h"
|
||||
#include "drv_type_ioctl.h"
|
||||
|
||||
//#define SUPPORT_OSD_TIME 1
|
||||
//#define SUPPORT_SENSOR_PWDN_MODE 1
|
||||
//#define APP_STANDBY_SENSOR 1
|
||||
|
||||
#ifdef SUPPORT_OSD_TIME
|
||||
#include "xmedia_region.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
CMD_MISC_AOV_INIT = 0,
|
||||
CMD_MISC_AOV_SET_SENSOR_MODE,
|
||||
#ifdef SUPPORT_OSD_TIME
|
||||
CMD_MISC_OSD_TIME_CREATE,
|
||||
CMD_MISC_OSD_TIME_UPDATE,
|
||||
CMD_MISC_OSD_TIME_UPDATE_TIMEZONE,
|
||||
CMD_MISC_OSD_TIME_DESTROY,
|
||||
#endif
|
||||
|
||||
#ifdef SUPPORT_SENSOR_PWDN_MODE
|
||||
CMD_MISC_SENSOR_PWDN_STANDBY,
|
||||
CMD_MISC_SENSOR_PWDN_RESUME,
|
||||
#endif
|
||||
|
||||
CMD_MISC_END = 0xFFFF,
|
||||
} misc_ioctl_cmd;
|
||||
|
||||
// ioctl cmd 对应的函数指针
|
||||
typedef xmedia_s32 (*misc_ctl_ptr_func)(xmedia_ulong arg);
|
||||
typedef struct misc_ioctl_func_item {
|
||||
xmedia_u32 cmd;
|
||||
misc_ctl_ptr_func ptr_func;
|
||||
} misc_ioctl_func_item;
|
||||
|
||||
#ifdef SUPPORT_OSD_TIME
|
||||
typedef struct __misc_osd_time_attach_info_ {
|
||||
xmedia_chn_info mpp_chn;
|
||||
xmedia_rgn_chn_attr chn_attr;
|
||||
}misc_osd_time_attach_info_t;
|
||||
|
||||
typedef struct _misc_osd_time_ {
|
||||
xmedia_s32 rgn_hdl;
|
||||
xmedia_rgn_attr rgn_attr;
|
||||
|
||||
xmedia_u16 rgn_attach_num;
|
||||
misc_osd_time_attach_info_t attach_obj[4];
|
||||
|
||||
xmedia_u16 font_size_scale;
|
||||
xmedia_u16 text_color;
|
||||
xmedia_u16 bg_color;
|
||||
} misc_osd_time_attr_t;
|
||||
#endif
|
||||
|
||||
typedef struct misc_aov_isp_info{
|
||||
xmedia_s32 isp_pipe_num;
|
||||
xmedia_u32 isp_pipe[VI_MAX_DEV_NUM];
|
||||
#ifdef SUPPORT_SENSOR_PWDN_MODE
|
||||
xmedia_bool support_sensor_pwdn_standby[VI_MAX_DEV_NUM];
|
||||
#endif
|
||||
} misc_aov_isp_info;
|
||||
|
||||
typedef struct misc_aov_state{
|
||||
xmedia_bool en_aov_mode;
|
||||
xmedia_s32 frame_num;
|
||||
} misc_aov_state;
|
||||
|
||||
#define XMEDIA_MISC_AOV_INIT _IOWR(IOC_TYPE_MISC, CMD_MISC_AOV_INIT, misc_aov_isp_info)
|
||||
#define XMEDIA_MISC_AOV_SET_SENSOR_MODE _IOWR(IOC_TYPE_MISC, CMD_MISC_AOV_SET_SENSOR_MODE, misc_aov_state)
|
||||
#ifdef SUPPORT_OSD_TIME
|
||||
#define XMEDIA_MISC_OSD_TIME_CREATE_CTRL _IOW(IOC_TYPE_MISC, CMD_MISC_OSD_TIME_CREATE, misc_osd_time_attr_t)
|
||||
#define XMEDIA_MISC_OSD_TIME_UPDATE_CTRL _IOW(IOC_TYPE_MISC, CMD_MISC_OSD_TIME_UPDATE, misc_osd_time_attr_t)
|
||||
#define XMEDIA_MISC_OSD_TIME_UPDATE_TIMEZONE_CTRL _IOW(IOC_TYPE_MISC, CMD_MISC_OSD_TIME_UPDATE_TIMEZONE, xmedia_s32)
|
||||
#define XMEDIA_MISC_OSD_TIME_DESTROY_CTRL _IOW(IOC_TYPE_MISC, CMD_MISC_OSD_TIME_DESTROY, misc_osd_time_attr_t)
|
||||
#endif
|
||||
#ifdef SUPPORT_SENSOR_PWDN_MODE
|
||||
#define XMEDIA_MISC_SENSOR_PWDN_STANDBY _IOWR(IOC_TYPE_MISC, CMD_MISC_SENSOR_PWDN_STANDBY, xmedia_s32)
|
||||
#define XMEDIA_MISC_SENSOR_PWDN_RESUME _IOWR(IOC_TYPE_MISC, CMD_MISC_SENSOR_PWDN_RESUME, xmedia_s32)
|
||||
#endif
|
||||
|
||||
#define MISC_TRACE(level, fmt, ...) \
|
||||
do { \
|
||||
MODULE_TRACE(level, MOD_ID_MISC, "[Func]:%s [Line]:%d [Info]:" fmt, __FUNCTION__, __LINE__, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __DRV_MISC_H__ */
|
||||
@@ -0,0 +1,80 @@
|
||||
#ifndef DRV_OSD_DRAW_TIME_H
|
||||
#define DRV_OSD_DRAW_TIME_H
|
||||
|
||||
#ifdef __KERNEL__
|
||||
#include <linux/types.h>
|
||||
#endif
|
||||
|
||||
#include "xmedia_type.h"
|
||||
#include "drv_misc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef SUPPORT_OSD_TIME
|
||||
// ARGB1555颜色定义 (1位alpha + 5位RGB)
|
||||
typedef unsigned short argb1555_t;
|
||||
|
||||
// 颜色宏定义
|
||||
#define ARGB1555(a, r, g, b) (((a) ? 0x8000 : 0) | (((r) & 0xF8) << 7) | (((g) & 0xF8) << 2) | (((b) & 0xF8) >> 3))
|
||||
|
||||
#define ARGB1555_BLACK ARGB1555(1, 0, 0, 0)
|
||||
#define ARGB1555_WHITE ARGB1555(1, 255, 255, 255)
|
||||
#define ARGB1555_RED ARGB1555(1, 255, 0, 0)
|
||||
#define ARGB1555_GREEN ARGB1555(1, 0, 255, 0)
|
||||
#define ARGB1555_BLUE ARGB1555(1, 0, 0, 255)
|
||||
#define ARGB1555_YELLOW ARGB1555(1, 255, 255, 0)
|
||||
#define ARGB1555_CYAN ARGB1555(1, 0, 255, 255)
|
||||
#define ARGB1555_MAGENTA ARGB1555(1, 255, 0, 255)
|
||||
#define ARGB1555_GRAY ARGB1555(1, 128, 128, 128)
|
||||
#define ARGB1555_DARKBLUE ARGB1555(1, 0, 0, 128)
|
||||
#define ARGB1555_ORANGE ARGB1555(1, 255, 165, 0)
|
||||
|
||||
// 时间字符串长度是8 "HH:MM:SS"
|
||||
#define TIME_STRING_LEN 8
|
||||
|
||||
// 日期字符串长度是10 "YYYY-MM-DD"
|
||||
#define DATE_STRING_LEN 10
|
||||
|
||||
// 总文本宽度:时间(8字符) + 空格(1字符) + 日期(10字符) + 结束符=20字符
|
||||
#define TOTAL_OSD_STRING_LEN 20
|
||||
|
||||
// 显示上下文结构体
|
||||
typedef struct {
|
||||
unsigned char *buffer; // 显示buffer地址
|
||||
int width; // 屏幕宽度
|
||||
int height; // 屏幕高度
|
||||
int stride;
|
||||
int font_size; // 字体大小
|
||||
argb1555_t text_color; // 文字颜色
|
||||
argb1555_t bg_color; // 背景颜色
|
||||
|
||||
// 缓存上一次显示的内容,用于增量更新
|
||||
char last_draw_str[TOTAL_OSD_STRING_LEN];
|
||||
int display_initialized; // 是否已经初始化显示
|
||||
} osd_draw_context_t;
|
||||
|
||||
// 函数声明
|
||||
void osd_draw_context_init(osd_draw_context_t *ctx, int width, int height, int stride, int font_size_scale);
|
||||
void osd_set_colors(osd_draw_context_t *ctx, argb1555_t text_color, argb1555_t bg_color);
|
||||
void osd_clear_screen(osd_draw_context_t *ctx);
|
||||
//void draw_pixel(osd_draw_context_t *ctx, int x, int y, argb1555_t color);
|
||||
//void draw_char(osd_draw_context_t *ctx, int x, int y, char c, argb1555_t color);
|
||||
void osd_draw_str(osd_draw_context_t *ctx, int x, int y, const char *draw_str, int draw_str_size, argb1555_t color);
|
||||
void osd_draw_str_ex(osd_draw_context_t *ctx, const char *draw_str, int draw_str_size, unsigned char *buffer);
|
||||
void osd_get_min_size(osd_draw_context_t *ctx, int *width, int *height);
|
||||
|
||||
xmedia_s32 misc_ctl_osd_time_create(xmedia_ulong arg);
|
||||
xmedia_s32 misc_ctl_osd_time_destroy(xmedia_ulong arg);
|
||||
xmedia_s32 misc_ctl_osd_time_update(xmedia_ulong arg);
|
||||
xmedia_s32 misc_ctl_osd_time_update_timezone(xmedia_ulong arg);
|
||||
xmedia_s32 osd_time_update_all(xmedia_void);
|
||||
|
||||
#endif //SUPPORT_OSD_TIME
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Executable
+38
@@ -0,0 +1,38 @@
|
||||
#ifndef __DRV_SENSOR_H__
|
||||
#define __DRV_SENSOR_H__
|
||||
|
||||
#include "xmedia_debug.h"
|
||||
#include "xmedia_type.h"
|
||||
#include "drv_type_ioctl.h"
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/pwm.h>
|
||||
#include "common.h"
|
||||
#include "osal.h"
|
||||
#include "xmedia_errcode.h"
|
||||
#include "drv_dev_defines.h"
|
||||
#include "drv_misc.h"
|
||||
#include "drv_export.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
xmedia_s32 misc_sensor_init(xmedia_void);
|
||||
xmedia_s32 misc_sensor_exit(xmedia_void);
|
||||
xmedia_s32 misc_sensor_resume(xmedia_void);
|
||||
xmedia_s32 misc_media_suspend(xmedia_void);
|
||||
|
||||
xmedia_s32 misc_ctl_aov_init(xmedia_ulong arg);
|
||||
xmedia_s32 misc_ctl_aov_set_sensor_mode(xmedia_ulong arg);
|
||||
#ifdef SUPPORT_SENSOR_PWDN_MODE
|
||||
xmedia_s32 misc_ctl_sensor_pwdn_standby(xmedia_ulong arg);
|
||||
xmedia_s32 misc_ctl_sensor_pwdn_resume(xmedia_ulong arg);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __DRV_SENSOR_H__ */
|
||||
|
||||
Executable
+150
@@ -0,0 +1,150 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/pwm.h>
|
||||
#include "common.h"
|
||||
#include "osal.h"
|
||||
#include "xmedia_errcode.h"
|
||||
#include "drv_dev_defines.h"
|
||||
#include "drv_misc.h"
|
||||
|
||||
#ifdef SUPPORT_OSD_TIME
|
||||
#include "drv_osd_draw_time.h"
|
||||
#endif
|
||||
#include "drv_export.h"
|
||||
#include "drv_sensor.h"
|
||||
|
||||
static osal_dev_t *g_misc_dev = XMEDIA_NULL;
|
||||
|
||||
xmedia_s32 drv_misc_open(xmedia_void *private_data)
|
||||
{
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_s32 drv_misc_close(xmedia_void *private_data)
|
||||
{
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_s32 drv_misc_suspend(osal_dev_t *pdev)
|
||||
{
|
||||
misc_media_suspend();
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_s32 drv_misc_resume(osal_dev_t *pdev)
|
||||
{
|
||||
#ifdef SUPPORT_OSD_TIME
|
||||
osd_time_update_all();
|
||||
#endif
|
||||
|
||||
misc_sensor_resume();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
misc_ioctl_func_item g_misc_ctl_func_item[] = {
|
||||
{XMEDIA_MISC_AOV_INIT, misc_ctl_aov_init},
|
||||
{XMEDIA_MISC_AOV_SET_SENSOR_MODE, misc_ctl_aov_set_sensor_mode},
|
||||
#ifdef SUPPORT_OSD_TIME
|
||||
{XMEDIA_MISC_OSD_TIME_CREATE_CTRL, misc_ctl_osd_time_create},
|
||||
{XMEDIA_MISC_OSD_TIME_UPDATE_CTRL, misc_ctl_osd_time_update},
|
||||
{XMEDIA_MISC_OSD_TIME_UPDATE_TIMEZONE_CTRL, misc_ctl_osd_time_update_timezone},
|
||||
{XMEDIA_MISC_OSD_TIME_DESTROY_CTRL, misc_ctl_osd_time_destroy},
|
||||
#endif
|
||||
|
||||
#ifdef SUPPORT_SENSOR_PWDN_MODE
|
||||
{XMEDIA_MISC_SENSOR_PWDN_STANDBY, misc_ctl_sensor_pwdn_standby},
|
||||
{XMEDIA_MISC_SENSOR_PWDN_RESUME, misc_ctl_sensor_pwdn_resume},
|
||||
#endif
|
||||
};
|
||||
|
||||
static xmedia_slong drv_misc_ioctl(xmedia_u32 cmd, xmedia_ulong arg, xmedia_void *private_data)
|
||||
{
|
||||
xmedia_u32 i;
|
||||
|
||||
for (i = 0; i < sizeof(g_misc_ctl_func_item)/sizeof(misc_ioctl_func_item); i++) {
|
||||
if (cmd == g_misc_ctl_func_item[i].cmd && g_misc_ctl_func_item[i].ptr_func != XMEDIA_NULL) {
|
||||
return g_misc_ctl_func_item[i].ptr_func(arg);
|
||||
}
|
||||
}
|
||||
|
||||
MISC_TRACE(MODULE_DBG_ERR, "invalid cmd(0x%x)!\n", cmd);
|
||||
return XMEDIA_ERRCODE_NOT_PERMITTED;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
xmedia_slong drv_misc_compat_ioctl(xmedia_u32 cmd, xmedia_ulong arg, xmedia_void *private_data)
|
||||
{
|
||||
return drv_misc_ioctl(cmd, arg, private_data);
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct osal_fileops g_misc_fops = {
|
||||
.open = drv_misc_open,
|
||||
.unlocked_ioctl = drv_misc_ioctl,
|
||||
.release = drv_misc_close,
|
||||
#ifdef CONFIG_COMPAT
|
||||
.compat_ioctl = drv_misc_compat_ioctl,
|
||||
#endif
|
||||
};
|
||||
|
||||
struct osal_pmops g_misc_drv_ops = {
|
||||
.pm_suspend = drv_misc_suspend,
|
||||
.pm_resume= drv_misc_resume,
|
||||
};
|
||||
|
||||
xmedia_s32 drv_misc_modinit(xmedia_void)
|
||||
{
|
||||
g_misc_dev = osal_createdev(UMAP_DEVNAME_MISC_BASE);
|
||||
if (g_misc_dev == XMEDIA_NULL) {
|
||||
MISC_TRACE(MODULE_DBG_ERR,"pm create dev err!\n");
|
||||
goto out0;
|
||||
}
|
||||
g_misc_dev->fops = &g_misc_fops;
|
||||
g_misc_dev->minor = UMAP_MISC_MINOR_BASE;
|
||||
g_misc_dev->osal_pmops = &g_misc_drv_ops;
|
||||
|
||||
if (osal_registerdevice(g_misc_dev) < 0) {
|
||||
MISC_TRACE(MODULE_DBG_ERR,"regist pm device err!\n");
|
||||
goto out1;
|
||||
}
|
||||
|
||||
misc_sensor_init();
|
||||
|
||||
osal_printk("load xm_misc.ko OK!\n");
|
||||
return XMEDIA_SUCCESS;
|
||||
|
||||
out1:
|
||||
osal_destroydev(g_misc_dev);
|
||||
g_misc_dev = XMEDIA_NULL;
|
||||
out0:
|
||||
osal_printk("load xm_misc.ko err!\n");
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
xmedia_void drv_misc_modexit(xmedia_void)
|
||||
{
|
||||
osal_deregisterdevice(g_misc_dev);
|
||||
osal_destroydev(g_misc_dev);
|
||||
g_misc_dev = XMEDIA_NULL;
|
||||
|
||||
misc_sensor_exit();
|
||||
|
||||
MISC_TRACE(MODULE_DBG_ERR,"unload xm_misc.ko OK!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef MODULE
|
||||
|
||||
module_init(drv_misc_modinit);
|
||||
module_exit(drv_misc_modexit);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
#else
|
||||
|
||||
int __init misc_driver_init(void)
|
||||
{
|
||||
return drv_misc_modinit();
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,564 @@
|
||||
#include "drv_misc.h"
|
||||
|
||||
#ifdef SUPPORT_OSD_TIME
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/timekeeping.h>
|
||||
#include <linux/rtc.h>
|
||||
#include <linux/time64.h>
|
||||
#include "xmedia_errcode.h"
|
||||
#include "drv_dev_defines.h"
|
||||
#include "drv_osd_draw_time.h"
|
||||
#include "drv_export.h"
|
||||
|
||||
typedef struct __osd_time_ext {
|
||||
misc_osd_time_attr_t osd_time_attr;
|
||||
osd_draw_context_t osd_draw_ctx;
|
||||
struct __osd_time_ext *next;
|
||||
}osd_time_ext_t;
|
||||
|
||||
osd_time_ext_t *g_osd_time_ext_hdl = XMEDIA_NULL;
|
||||
xmedia_s32 g_tz_minuteswest = 0;
|
||||
|
||||
#define FONT_ORIGINAL_WIDTH 8
|
||||
#define FONT_ORIGINAL_HEIGHT 8
|
||||
|
||||
// 8x8数字字体点阵 (0-9和冒号)
|
||||
static const uint8_t font_8x8[13][8] = {
|
||||
{0x3C, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C}, // 0
|
||||
{0x18, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C}, // 1
|
||||
{0x3C, 0x66, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x7E}, // 2
|
||||
{0x3C, 0x66, 0x06, 0x1C, 0x06, 0x06, 0x66, 0x3C}, // 3
|
||||
{0x0C, 0x1C, 0x2C, 0x4C, 0x7E, 0x0C, 0x0C, 0x0C}, // 4
|
||||
{0x7E, 0x60, 0x7C, 0x06, 0x06, 0x06, 0x66, 0x3C}, // 5
|
||||
{0x3C, 0x66, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x3C}, // 6
|
||||
{0x7E, 0x06, 0x0C, 0x0C, 0x18, 0x18, 0x18, 0x18}, // 7
|
||||
{0x3C, 0x66, 0x66, 0x3C, 0x66, 0x66, 0x66, 0x3C}, // 8
|
||||
{0x3C, 0x66, 0x66, 0x66, 0x3E, 0x06, 0x66, 0x3C}, // 9
|
||||
{0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00}, // :
|
||||
{0x00, 0x00, 0x00, 0x7E, 0x7E, 0x00, 0x00, 0x00}, // -
|
||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // 空格
|
||||
};
|
||||
|
||||
// 初始化显示上下文
|
||||
void osd_draw_context_init(osd_draw_context_t *ctx, int width, int height, int stride, int font_size_scale) {
|
||||
ctx->width = width;
|
||||
ctx->height = height;
|
||||
ctx->stride = stride;
|
||||
ctx->font_size = (font_size_scale < 1) ? 1 : font_size_scale; // 最小字体大小为1
|
||||
ctx->text_color = ARGB1555_YELLOW;
|
||||
ctx->bg_color = ARGB1555_BLACK;
|
||||
|
||||
// 初始化缓存
|
||||
memset(ctx->last_draw_str, 0, sizeof(ctx->last_draw_str));
|
||||
ctx->display_initialized = 0;
|
||||
}
|
||||
|
||||
// 设置颜色
|
||||
void osd_set_colors(osd_draw_context_t *ctx, argb1555_t text_color, argb1555_t bg_color) {
|
||||
ctx->text_color = text_color;
|
||||
ctx->bg_color = bg_color;
|
||||
}
|
||||
|
||||
// 清空屏幕
|
||||
void osd_clear_screen(osd_draw_context_t *ctx) {
|
||||
int i = 0, j = 0;
|
||||
argb1555_t *p = NULL;
|
||||
|
||||
if (!ctx->buffer) {
|
||||
MISC_TRACE(MODULE_DBG_ERR,"Error: Buffer is NULL\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < ctx->height; i++) {
|
||||
for (j = 0; j < ctx->width; j++) {
|
||||
p = (argb1555_t*)(ctx->buffer + i * ctx->stride + j * sizeof(argb1555_t));
|
||||
*p = ctx->bg_color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 绘制像素
|
||||
void draw_pixel(osd_draw_context_t *ctx, int x, int y, argb1555_t color) {
|
||||
argb1555_t *p = NULL;
|
||||
|
||||
if (!ctx->buffer)
|
||||
return;
|
||||
|
||||
if (x >= 0 && x < ctx->width && y >= 0 && y < ctx->height) {
|
||||
p = (argb1555_t*)(ctx->buffer + y * ctx->stride + x * sizeof(argb1555_t));
|
||||
*p = color;
|
||||
}
|
||||
}
|
||||
|
||||
// 绘制缩放后的像素块 (用于字体放大)
|
||||
void draw_scaled_pixel(osd_draw_context_t *ctx, int x, int y, int scale, argb1555_t color) {
|
||||
int dx = 0, dy = 0;
|
||||
for (dy = 0; dy < scale; dy++) {
|
||||
for (dx = 0; dx < scale; dx++) {
|
||||
draw_pixel(ctx, x + dx, y + dy, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 绘制字符
|
||||
void draw_char(osd_draw_context_t *ctx, int x, int y, char c, argb1555_t color) {
|
||||
int char_index, scale, row, col;
|
||||
uint8_t row_data;
|
||||
|
||||
if (c >= '0' && c <= '9') {
|
||||
char_index = c - '0';
|
||||
} else if (c == ':') {
|
||||
char_index = 10;
|
||||
} else if (c == '-') {
|
||||
char_index = 11; // 减号
|
||||
} else {
|
||||
char_index = 12; // 空格或其他字符
|
||||
}
|
||||
|
||||
scale = ctx->font_size;
|
||||
|
||||
for (row = 0; row < FONT_ORIGINAL_WIDTH; row++) {
|
||||
row_data = font_8x8[char_index][row];
|
||||
for (col = 0; col < FONT_ORIGINAL_HEIGHT; col++) {
|
||||
if (row_data & (1 << (7 - col))) {
|
||||
// 绘制放大的像素
|
||||
draw_scaled_pixel(ctx,
|
||||
x + col * scale,
|
||||
y + row * scale,
|
||||
scale, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 绘制字符串
|
||||
void osd_draw_str(osd_draw_context_t *ctx, int x, int y, const char *draw_str, int draw_str_size, argb1555_t color) {
|
||||
int i;
|
||||
int pos_x = x;
|
||||
int char_width = FONT_ORIGINAL_WIDTH * ctx->font_size + ctx->font_size; // 字符宽度 + 间距
|
||||
|
||||
for (i = 0; draw_str[i] != '\0'; i++) {
|
||||
draw_char(ctx, pos_x, y, draw_str[i], color);
|
||||
pos_x += char_width;
|
||||
}
|
||||
}
|
||||
|
||||
// 绘制单个字符(增量更新用)
|
||||
void draw_single_char(osd_draw_context_t *ctx, int x, int y, char c, argb1555_t color) {
|
||||
int char_width, char_height;
|
||||
int px, py;
|
||||
|
||||
// 先清除该字符区域
|
||||
char_width = FONT_ORIGINAL_WIDTH * ctx->font_size;
|
||||
char_height = FONT_ORIGINAL_HEIGHT * ctx->font_size;
|
||||
|
||||
for (py = y; py < y + char_height; py++) {
|
||||
for (px = x; px < x + char_width; px++) {
|
||||
draw_pixel(ctx, px, py, ctx->bg_color);
|
||||
}
|
||||
}
|
||||
|
||||
// 绘制新字符
|
||||
draw_char(ctx, x, y, c, color);
|
||||
}
|
||||
|
||||
// 获取字符宽度
|
||||
int get_char_width(osd_draw_context_t *ctx) {
|
||||
return FONT_ORIGINAL_WIDTH * ctx->font_size + ctx->font_size;
|
||||
}
|
||||
|
||||
// 获取字符高度
|
||||
int get_char_height(osd_draw_context_t *ctx) {
|
||||
return FONT_ORIGINAL_HEIGHT * ctx->font_size;
|
||||
}
|
||||
|
||||
// 获取时钟显示所需的尺寸
|
||||
void get_osd_time_size(osd_draw_context_t *ctx, int *width, int *height) {
|
||||
// 格式: "HH:MM:SS YYYY-MM-DD" 总共19个字符
|
||||
*width = (TOTAL_OSD_STRING_LEN - 1) * get_char_width(ctx);
|
||||
*height = get_char_height(ctx);
|
||||
}
|
||||
|
||||
// 增量更新日期(只更新变化的字符)
|
||||
void update_str_incremental(osd_draw_context_t *ctx, int date_x, int date_y, const char *draw_str, int draw_str_size) {
|
||||
int char_width, i, char_x;
|
||||
|
||||
if (!ctx->display_initialized) {
|
||||
// 第一次显示,绘制全部字符
|
||||
osd_draw_str(ctx, date_x, date_y, draw_str, draw_str_size, ctx->text_color);
|
||||
strcpy(ctx->last_draw_str, draw_str);
|
||||
return;
|
||||
}
|
||||
|
||||
char_width = get_char_width(ctx);
|
||||
|
||||
// 比较每个字符,只更新变化的字符
|
||||
for (i = 0; i < sizeof(ctx->last_draw_str); i++) { // 日期字符串长度是10 "YYYY-MM-DD"
|
||||
if (draw_str[i] != ctx->last_draw_str[i]) {
|
||||
char_x = date_x + i * char_width;
|
||||
draw_single_char(ctx, char_x, date_y, draw_str[i], ctx->text_color);
|
||||
}
|
||||
}
|
||||
|
||||
strcpy(ctx->last_draw_str, draw_str);
|
||||
}
|
||||
|
||||
// 绘制时钟
|
||||
void osd_draw_str_ex(osd_draw_context_t *ctx, const char *draw_str, int draw_str_size, uint8_t *buffer) {
|
||||
int char_width, char_height;
|
||||
int total_width, total_height;
|
||||
int start_x, start_y;
|
||||
int i;
|
||||
|
||||
if (!buffer) {
|
||||
MISC_TRACE(MODULE_DBG_ERR,"Error: Buffer is NULL\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ctx->buffer = buffer;
|
||||
|
||||
// 计算显示位置(时间和日期在同一行)
|
||||
char_width = get_char_width(ctx);
|
||||
char_height = get_char_height(ctx);
|
||||
|
||||
// 总文本宽度:时间(8字符) + 空格(1字符) + 日期(10字符) = 19字符
|
||||
total_width = (TOTAL_OSD_STRING_LEN - 1) * char_width;
|
||||
total_height = char_height;
|
||||
|
||||
start_x = (ctx->width - total_width) / 2;
|
||||
start_y = (ctx->height - total_height) / 2;
|
||||
|
||||
// 确保位置有效
|
||||
if (start_x < 0) start_x = 0;
|
||||
if (start_y < 0) start_y = 0;
|
||||
|
||||
// 第一次显示时清屏并绘制边框
|
||||
if (!ctx->display_initialized) {
|
||||
osd_clear_screen(ctx);
|
||||
|
||||
// 绘制装饰边框
|
||||
for (i = 0; i < ctx->width; i++) {
|
||||
draw_pixel(ctx, i, 0, ARGB1555_GRAY);
|
||||
draw_pixel(ctx, i, ctx->height - 1, ARGB1555_GRAY);
|
||||
}
|
||||
for (i = 0; i < ctx->height; i++) {
|
||||
draw_pixel(ctx, 0, i, ARGB1555_GRAY);
|
||||
draw_pixel(ctx, ctx->width - 1, i, ARGB1555_GRAY);
|
||||
}
|
||||
|
||||
// 绘制分隔符(时间和日期之间的空格)
|
||||
//int separator_x = start_x + DATE_STRING_LEN * char_width;
|
||||
//draw_char(ctx, separator_x, start_y, ' ', ctx->bg_color);
|
||||
|
||||
ctx->display_initialized = 1;
|
||||
}
|
||||
|
||||
// 更新时间(增量更新)
|
||||
update_str_incremental(ctx, start_x, start_y, draw_str, draw_str_size);
|
||||
}
|
||||
|
||||
// 应用时区偏移
|
||||
xmedia_void apply_timezone_offset(struct timespec64 *ts, xmedia_s32 tz_minuteswest)
|
||||
{
|
||||
// 将时区偏移转换为秒(西区为正值,需要减去)
|
||||
xmedia_slong tz_seconds = tz_minuteswest * 60;
|
||||
|
||||
// 调整时间
|
||||
ts->tv_sec -= tz_seconds;
|
||||
|
||||
// 处理纳秒溢出
|
||||
if (ts->tv_nsec < 0) {
|
||||
ts->tv_sec--;
|
||||
ts->tv_nsec += NSEC_PER_SEC;
|
||||
}
|
||||
if (ts->tv_nsec >= NSEC_PER_SEC) {
|
||||
ts->tv_sec++;
|
||||
ts->tv_nsec -= NSEC_PER_SEC;
|
||||
}
|
||||
}
|
||||
|
||||
xmedia_s32 get_local_time_string(xmedia_char *time_buf, size_t time_buf_size)
|
||||
{
|
||||
struct timespec64 ts_utc, ts_local;
|
||||
struct tm tm_local;
|
||||
|
||||
// 获取UTC时间
|
||||
ktime_get_real_ts64(&ts_utc);
|
||||
|
||||
// 计算本地时间
|
||||
ts_local = ts_utc;
|
||||
apply_timezone_offset(&ts_local, g_tz_minuteswest);
|
||||
|
||||
time64_to_tm(ts_local.tv_sec, 0, &tm_local);
|
||||
|
||||
snprintf(time_buf, time_buf_size,
|
||||
"%04ld-%02d-%02d %02d:%02d:%02d",
|
||||
tm_local.tm_year + 1900, tm_local.tm_mon + 1, tm_local.tm_mday,
|
||||
tm_local.tm_hour, tm_local.tm_min, tm_local.tm_sec);
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_s32 misc_ctl_osd_time_create(xmedia_ulong arg)
|
||||
{
|
||||
xmedia_s32 s32Ret = XMEDIA_SUCCESS, s32Ret2 = XMEDIA_SUCCESS;
|
||||
xmedia_s32 i = 0;
|
||||
xmedia_rgn_canvas_info canvas_info;
|
||||
char time_buf[TOTAL_OSD_STRING_LEN];
|
||||
osd_time_ext_t *osd_time_ext_hdl = XMEDIA_NULL, *p = XMEDIA_NULL;
|
||||
|
||||
osd_time_ext_hdl = osal_vmalloc(sizeof(osd_time_ext_t));
|
||||
if (osd_time_ext_hdl == XMEDIA_NULL) {
|
||||
return XMEDIA_ERRCODE_NOT_ENOUGH_MEMORY;
|
||||
}
|
||||
|
||||
memset(osd_time_ext_hdl, 0, sizeof(osd_time_ext_t));
|
||||
memcpy(&osd_time_ext_hdl->osd_time_attr, (xmedia_void *)arg, sizeof(misc_osd_time_attr_t));
|
||||
|
||||
if(g_osd_time_ext_hdl == XMEDIA_NULL) {
|
||||
s32Ret = export_rgn_init();
|
||||
if (s32Ret != XMEDIA_SUCCESS) {
|
||||
MISC_TRACE(MODULE_DBG_ERR, "export_region_init failed! ret:0x%x\n", s32Ret);
|
||||
goto EXIT1;
|
||||
}
|
||||
}
|
||||
|
||||
s32Ret = export_rgn_create(osd_time_ext_hdl->osd_time_attr.rgn_hdl, &osd_time_ext_hdl->osd_time_attr.rgn_attr);
|
||||
if (s32Ret != XMEDIA_SUCCESS) {
|
||||
MISC_TRACE(MODULE_DBG_ERR, "export_region_create failed! ret:0x%x\n", s32Ret);
|
||||
goto EXIT1;
|
||||
}
|
||||
|
||||
for(i = 0; i < osd_time_ext_hdl->osd_time_attr.rgn_attach_num; i++) {
|
||||
s32Ret = export_rgn_attach_to_chn(osd_time_ext_hdl->osd_time_attr.rgn_hdl, &osd_time_ext_hdl->osd_time_attr.attach_obj[i].mpp_chn,
|
||||
&osd_time_ext_hdl->osd_time_attr.attach_obj[i].chn_attr);
|
||||
if (s32Ret != XMEDIA_SUCCESS) {
|
||||
MISC_TRACE(MODULE_DBG_ERR, "export_rgn_attach_to_chn failed with %#x!\n", s32Ret);
|
||||
goto EXIT2;
|
||||
}
|
||||
}
|
||||
|
||||
s32Ret = export_rgn_get_canvas_info(osd_time_ext_hdl->osd_time_attr.rgn_hdl, &canvas_info);
|
||||
if (s32Ret != XMEDIA_SUCCESS) {
|
||||
MISC_TRACE(MODULE_DBG_ERR, "export_rgn_get_canvas_info failed with %#x!\n", s32Ret);
|
||||
goto EXIT3;
|
||||
}
|
||||
|
||||
osd_draw_context_init(&osd_time_ext_hdl->osd_draw_ctx, canvas_info.size.width, canvas_info.size.height, canvas_info.stride, osd_time_ext_hdl->osd_time_attr.font_size_scale);
|
||||
osd_set_colors(&osd_time_ext_hdl->osd_draw_ctx, (argb1555_t)osd_time_ext_hdl->osd_time_attr.text_color, (argb1555_t)osd_time_ext_hdl->osd_time_attr.bg_color);
|
||||
get_local_time_string(time_buf, sizeof(time_buf));
|
||||
|
||||
osd_draw_str_ex(&osd_time_ext_hdl->osd_draw_ctx, time_buf, sizeof(time_buf), canvas_info.virt_addr);
|
||||
|
||||
s32Ret = export_rgn_update_canvas(osd_time_ext_hdl->osd_time_attr.rgn_hdl);
|
||||
if (s32Ret != XMEDIA_SUCCESS) {
|
||||
MISC_TRACE(MODULE_DBG_ERR, "export_rgn_update_canvas failed with %#x!\n", s32Ret);
|
||||
goto EXIT3;
|
||||
}
|
||||
|
||||
if(g_osd_time_ext_hdl == XMEDIA_NULL)
|
||||
g_osd_time_ext_hdl = osd_time_ext_hdl;
|
||||
else {
|
||||
p = g_osd_time_ext_hdl;
|
||||
while(p->next != XMEDIA_NULL) {
|
||||
p = p->next;
|
||||
}
|
||||
p->next = osd_time_ext_hdl;
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
|
||||
EXIT3:
|
||||
for(i = 0; i < osd_time_ext_hdl->osd_time_attr.rgn_attach_num; i++) {
|
||||
s32Ret2 = export_rgn_detach_from_chn(osd_time_ext_hdl->osd_time_attr.rgn_hdl, &osd_time_ext_hdl->osd_time_attr.attach_obj[i].mpp_chn);
|
||||
if(s32Ret2 != XMEDIA_SUCCESS) {
|
||||
MISC_TRACE(MODULE_DBG_ERR, "export_rgn_detach_from_chn failed!\n");
|
||||
}
|
||||
}
|
||||
|
||||
EXIT2:
|
||||
s32Ret2 = export_rgn_destroy(osd_time_ext_hdl->osd_time_attr.rgn_hdl);
|
||||
if (s32Ret2 != XMEDIA_SUCCESS) {
|
||||
MISC_TRACE(MODULE_DBG_ERR, "export_rgn_destroy failed with %#x!\n", s32Ret2);
|
||||
}
|
||||
|
||||
EXIT1:
|
||||
osal_vfree(osd_time_ext_hdl);
|
||||
osd_time_ext_hdl = XMEDIA_NULL;
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
xmedia_s32 misc_ctl_osd_time_update_timezone(xmedia_ulong arg)
|
||||
{
|
||||
xmedia_s32 tz_minuteswest = *(xmedia_s32*)arg;
|
||||
|
||||
/* Verify we're within the +-15 hrs range */
|
||||
if (tz_minuteswest > 15*60 || tz_minuteswest < -15*60) {
|
||||
MISC_TRACE(MODULE_DBG_ERR, "invaild tz_minuteswest:%d,i it should be within the +-15 hrs range!\n", tz_minuteswest);
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
g_tz_minuteswest = tz_minuteswest;
|
||||
MISC_TRACE(MODULE_DBG_DEBUG, "set tz_minuteswest:%d!\n", g_tz_minuteswest);
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_s32 misc_ctl_osd_time_destroy(xmedia_ulong arg)
|
||||
{
|
||||
xmedia_s32 i = 0;
|
||||
xmedia_s32 s32Ret = XMEDIA_SUCCESS;
|
||||
misc_osd_time_attr_t *osd_time_attr = XMEDIA_NULL;
|
||||
osd_time_ext_t *p = XMEDIA_NULL, *tmp = XMEDIA_NULL;
|
||||
xmedia_s32 have_found = 0;
|
||||
|
||||
osd_time_attr = (misc_osd_time_attr_t*)arg;
|
||||
if(osd_time_attr == XMEDIA_NULL)
|
||||
{
|
||||
MISC_TRACE(MODULE_DBG_ERR, "input parameter is NULL!\n");
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
if(g_osd_time_ext_hdl == XMEDIA_NULL) {
|
||||
MISC_TRACE(MODULE_DBG_ERR, "osd time destory failed! because not create this object!!!\n");
|
||||
return XMEDIA_ERRCODE_NOT_EXIST;
|
||||
}
|
||||
else if(g_osd_time_ext_hdl->osd_time_attr.rgn_hdl == osd_time_attr->rgn_hdl) {
|
||||
p = g_osd_time_ext_hdl;
|
||||
g_osd_time_ext_hdl = g_osd_time_ext_hdl->next;
|
||||
}
|
||||
else if(g_osd_time_ext_hdl->next == XMEDIA_NULL) {
|
||||
MISC_TRACE(MODULE_DBG_ERR, "osd time destory failed! because not create this object!!!\n");
|
||||
return XMEDIA_ERRCODE_NOT_EXIST;
|
||||
}
|
||||
else {
|
||||
p = g_osd_time_ext_hdl;
|
||||
while(p->next != XMEDIA_NULL) {
|
||||
if(p->next->osd_time_attr.rgn_hdl == osd_time_attr->rgn_hdl) {
|
||||
have_found = 1;
|
||||
tmp = p->next;
|
||||
p->next = p->next->next;
|
||||
p = tmp;
|
||||
break;
|
||||
}
|
||||
|
||||
p = p->next;
|
||||
}
|
||||
|
||||
if(!have_found) {
|
||||
MISC_TRACE(MODULE_DBG_ERR, "osd time destory failed! because not create this object!!!\n");
|
||||
return XMEDIA_ERRCODE_NOT_EXIST;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for(i = 0; i < osd_time_attr->rgn_attach_num; i++) {
|
||||
s32Ret = export_rgn_detach_from_chn(osd_time_attr->rgn_hdl, &osd_time_attr->attach_obj[i].mpp_chn);
|
||||
if(s32Ret !=XMEDIA_SUCCESS) {
|
||||
MISC_TRACE(MODULE_DBG_ERR, "export_rgn_detach_from_chn failed!\n");
|
||||
}
|
||||
}
|
||||
|
||||
s32Ret = export_rgn_destroy(osd_time_attr->rgn_hdl);
|
||||
if (s32Ret != XMEDIA_SUCCESS) {
|
||||
MISC_TRACE(MODULE_DBG_ERR, "export_rgn_destroy failed with %#x!\n", s32Ret);
|
||||
}
|
||||
|
||||
if(p)
|
||||
osal_vfree(p);
|
||||
|
||||
if(g_osd_time_ext_hdl == XMEDIA_NULL) {
|
||||
export_rgn_exit();
|
||||
}
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
xmedia_s32 osd_time_update(misc_osd_time_attr_t *osd_time_attr, osd_draw_context_t *osd_draw_ctx)
|
||||
{
|
||||
xmedia_s32 s32Ret = XMEDIA_SUCCESS;
|
||||
xmedia_rgn_canvas_info canvas_info;
|
||||
char time_buf[TOTAL_OSD_STRING_LEN];
|
||||
|
||||
if(osd_time_attr == XMEDIA_NULL || osd_draw_ctx == XMEDIA_NULL) {
|
||||
MISC_TRACE(MODULE_DBG_ERR, "osd time object not create!\n");
|
||||
return XMEDIA_ERRCODE_NOT_INIT;
|
||||
}
|
||||
|
||||
s32Ret = export_rgn_get_canvas_info(osd_time_attr->rgn_hdl, &canvas_info);
|
||||
if (s32Ret != XMEDIA_SUCCESS) {
|
||||
MISC_TRACE(MODULE_DBG_ERR, "export_rgn_get_canvas_info failed with %#x!\n", s32Ret);
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
get_local_time_string(time_buf, sizeof(time_buf));
|
||||
|
||||
//MISC_TRACE(MODULE_DBG_ERR, "osd time:%s!\n", time_buf);
|
||||
|
||||
osd_draw_str_ex(osd_draw_ctx, time_buf, sizeof(time_buf), canvas_info.virt_addr);
|
||||
|
||||
s32Ret = export_rgn_update_canvas(osd_time_attr->rgn_hdl);
|
||||
if (s32Ret != XMEDIA_SUCCESS) {
|
||||
MISC_TRACE(MODULE_DBG_ERR, "export_rgn_update_canvas failed with %#x!\n", s32Ret);
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
xmedia_s32 osd_time_update_all()
|
||||
{
|
||||
xmedia_s32 s32Ret = XMEDIA_SUCCESS;
|
||||
osd_time_ext_t *p = g_osd_time_ext_hdl;
|
||||
|
||||
while(p != XMEDIA_NULL) {
|
||||
s32Ret |= osd_time_update(&p->osd_time_attr, &p->osd_draw_ctx);
|
||||
p = p->next;
|
||||
}
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
xmedia_s32 misc_ctl_osd_time_update(xmedia_ulong arg)
|
||||
{
|
||||
osd_time_ext_t *p = XMEDIA_NULL;
|
||||
xmedia_s32 have_found = 0;
|
||||
misc_osd_time_attr_t *osd_time_attr = (misc_osd_time_attr_t *)arg;
|
||||
|
||||
if(osd_time_attr == XMEDIA_NULL) {
|
||||
MISC_TRACE(MODULE_DBG_ERR, "input parameter is NULL!\n");
|
||||
return XMEDIA_ERRCODE_NULL_PTR;
|
||||
}
|
||||
|
||||
|
||||
if(g_osd_time_ext_hdl == XMEDIA_NULL) {
|
||||
MISC_TRACE(MODULE_DBG_ERR, "osd time update failed! because not create this object!!!\n");
|
||||
return XMEDIA_ERRCODE_NOT_EXIST;
|
||||
}
|
||||
else if(g_osd_time_ext_hdl->osd_time_attr.rgn_hdl == osd_time_attr->rgn_hdl) {
|
||||
p = g_osd_time_ext_hdl;
|
||||
}
|
||||
else if(g_osd_time_ext_hdl->next == XMEDIA_NULL) {
|
||||
MISC_TRACE(MODULE_DBG_ERR, "osd time update failed! because not create this object!!!\n");
|
||||
return XMEDIA_ERRCODE_NOT_EXIST;
|
||||
}
|
||||
else {
|
||||
p = g_osd_time_ext_hdl;
|
||||
while(p->next != XMEDIA_NULL) {
|
||||
if(p->next->osd_time_attr.rgn_hdl == osd_time_attr->rgn_hdl) {
|
||||
have_found = 1;
|
||||
break;
|
||||
}
|
||||
p = p->next;
|
||||
}
|
||||
|
||||
if(!have_found) {
|
||||
MISC_TRACE(MODULE_DBG_ERR, "osd time update failed! because not create this object!!!\n");
|
||||
return XMEDIA_ERRCODE_NOT_EXIST;
|
||||
}
|
||||
}
|
||||
return osd_time_update(osd_time_attr, &p->osd_draw_ctx);
|
||||
}
|
||||
|
||||
#endif
|
||||
Executable
+362
@@ -0,0 +1,362 @@
|
||||
#include "drv_export.h"
|
||||
#include "drv_sensor.h"
|
||||
|
||||
|
||||
#ifdef SUPPORT_SENSOR_PWDN_MODE
|
||||
#define SENSOR0_PWDN_GPIO_NUM 58 //gpio7-2
|
||||
#define SENSOR1_PWDN_GPIO_NUM 60 //gpio7-4
|
||||
#define SENSOR0_PWDN_REG_OFFSET 0x74
|
||||
#define SENSOR1_PWDN_REG_OFFSET 0x7C
|
||||
#define GPIO_PINMUX_VALUE 0x1100
|
||||
|
||||
static void *pwdn_reg_base = XMEDIA_NULL;
|
||||
#endif
|
||||
|
||||
static misc_aov_isp_info g_isp_info = { 0 };
|
||||
static misc_aov_state g_aov_state = { 0 };
|
||||
static xmedia_bool g_misc_do_suspend = XMEDIA_FALSE;
|
||||
|
||||
#ifdef SUPPORT_SENSOR_PWDN_MODE
|
||||
static xmedia_s32 drv_pwdn_sensor_init(xmedia_void)
|
||||
{
|
||||
pwdn_reg_base = (void *)osal_ioremap(0x100C0000, (xmedia_u32)0x80);
|
||||
if (pwdn_reg_base == XMEDIA_NULL) {
|
||||
MISC_TRACE(MODULE_DBG_ERR,"misc ioremap fail \n");
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
static xmedia_void drv_pwdn_sensor_exit(xmedia_void)
|
||||
{
|
||||
osal_iounmap(pwdn_reg_base);
|
||||
pwdn_reg_base = XMEDIA_NULL;
|
||||
}
|
||||
|
||||
static xmedia_s32 drv_pwdn_sensor_resume(xmedia_s32 isp_pipe)
|
||||
{
|
||||
xmedia_s32 s32Ret = XMEDIA_FAILURE;
|
||||
xmedia_s32 gpio_num;
|
||||
|
||||
if(isp_pipe == 0 && g_isp_info.support_sensor_pwdn_standby[isp_pipe] == XMEDIA_TRUE) {
|
||||
gpio_num = SENSOR0_PWDN_GPIO_NUM;
|
||||
|
||||
//set pinmux
|
||||
osal_writel(GPIO_PINMUX_VALUE, pwdn_reg_base + SENSOR0_PWDN_REG_OFFSET);
|
||||
}
|
||||
else if(isp_pipe == 1 && g_isp_info.support_sensor_pwdn_standby[isp_pipe] == XMEDIA_TRUE) {
|
||||
gpio_num = SENSOR1_PWDN_GPIO_NUM;
|
||||
|
||||
//set pinmux
|
||||
osal_writel(GPIO_PINMUX_VALUE, pwdn_reg_base + SENSOR1_PWDN_REG_OFFSET);
|
||||
}
|
||||
else {
|
||||
MISC_TRACE(MODULE_DBG_ERR,"isp pipe(%d) is illegal!\n", isp_pipe);
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
s32Ret = gpio_request(gpio_num, NULL);
|
||||
if (s32Ret) {
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
s32Ret = gpio_direction_output(gpio_num, 1);
|
||||
if (s32Ret) {
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
gpio_set_value(gpio_num, 1);
|
||||
|
||||
gpio_free(gpio_num);
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
static xmedia_s32 drv_pwdn_sensor_stanby(xmedia_s32 isp_pipe)
|
||||
{
|
||||
xmedia_s32 gpio_num;
|
||||
xmedia_s32 s32Ret = XMEDIA_FAILURE;
|
||||
|
||||
if(isp_pipe == 0 && g_isp_info.support_sensor_pwdn_standby[isp_pipe] == XMEDIA_TRUE)
|
||||
gpio_num = SENSOR0_PWDN_GPIO_NUM;
|
||||
else if(isp_pipe == 1 && g_isp_info.support_sensor_pwdn_standby[isp_pipe] == XMEDIA_TRUE)
|
||||
gpio_num = SENSOR1_PWDN_GPIO_NUM;
|
||||
else {
|
||||
MISC_TRACE(MODULE_DBG_ERR,"isp pipe(%d) is illegal!\n", isp_pipe);
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
s32Ret = gpio_request(gpio_num, NULL);
|
||||
if (s32Ret) {
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
s32Ret = gpio_direction_output(gpio_num, 1);
|
||||
if (s32Ret) {
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
gpio_set_value(gpio_num, 0);
|
||||
|
||||
gpio_free(gpio_num);
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
static xmedia_s32 drv_i2c_sensor_resume(xmedia_s32 pipe)
|
||||
{
|
||||
return export_isp_resume_sensor(pipe);
|
||||
}
|
||||
|
||||
static xmedia_s32 drv_i2c_sensor_suspend(xmedia_s32 pipe)
|
||||
{
|
||||
return export_isp_suspend_sensor(pipe);
|
||||
}
|
||||
|
||||
static xmedia_void misc_set_sensor_sync_status(xmedia_bool misc_suspend)
|
||||
{
|
||||
g_misc_do_suspend = misc_suspend;
|
||||
}
|
||||
|
||||
static xmedia_bool misc_get_sensor_sync_status(xmedia_void)
|
||||
{
|
||||
return g_misc_do_suspend;
|
||||
}
|
||||
|
||||
static xmedia_s32 misc_set_sensor_mode(xmedia_ulong arg)
|
||||
{
|
||||
misc_aov_state *aov_state = (misc_aov_state *)arg;
|
||||
|
||||
if (aov_state == XMEDIA_NULL) {
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
g_aov_state.en_aov_mode = aov_state->en_aov_mode;
|
||||
g_aov_state.frame_num = aov_state->frame_num;
|
||||
|
||||
misc_set_sensor_sync_status(XMEDIA_FALSE);
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
static xmedia_s32 misc_get_sensor_mode(misc_aov_state *aov_state)
|
||||
{
|
||||
if (aov_state == XMEDIA_NULL) {
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
if (g_aov_state.en_aov_mode == XMEDIA_FALSE || g_aov_state.frame_num == 0) {
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
aov_state->en_aov_mode = g_aov_state.en_aov_mode;
|
||||
aov_state->frame_num = g_aov_state.frame_num;
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
static xmedia_s32 misc_sensor_standby(xmedia_s32 pipe)
|
||||
{
|
||||
xmedia_s32 s32Ret = XMEDIA_FAILURE;
|
||||
xmedia_s32 i = 0;
|
||||
static xmedia_s32 cur_frame_num[VI_MAX_DEV_NUM] = {0};
|
||||
misc_aov_state aov_state = {0};
|
||||
|
||||
s32Ret = misc_get_sensor_mode(&aov_state);
|
||||
if (s32Ret != XMEDIA_SUCCESS) {
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
if (g_isp_info.isp_pipe_num == 0) {
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
for (i = 0; i < g_isp_info.isp_pipe_num; i++) {
|
||||
if (pipe == g_isp_info.isp_pipe[i]) {
|
||||
if (cur_frame_num[i] < (g_aov_state.frame_num - 1)) {
|
||||
cur_frame_num[i] ++;
|
||||
} else {
|
||||
drv_i2c_sensor_suspend(pipe);
|
||||
cur_frame_num[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SUPPORT_SENSOR_PWDN_MODE
|
||||
if(g_isp_info.support_sensor_pwdn_standby[pipe] == XMEDIA_TRUE) {
|
||||
drv_pwdn_sensor_stanby(pipe);
|
||||
}
|
||||
#endif
|
||||
|
||||
misc_set_sensor_sync_status(XMEDIA_TRUE);
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_s32 misc_sensor_init(xmedia_void)
|
||||
{
|
||||
#ifdef SUPPORT_SENSOR_PWDN_MODE
|
||||
return drv_pwdn_sensor_init();
|
||||
#else
|
||||
return XMEDIA_SUCCESS;
|
||||
#endif
|
||||
}
|
||||
|
||||
xmedia_s32 misc_sensor_exit(xmedia_void)
|
||||
{
|
||||
#ifdef SUPPORT_SENSOR_PWDN_MODE
|
||||
drv_pwdn_sensor_exit();
|
||||
#endif
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_s32 misc_sensor_resume(xmedia_void)
|
||||
{
|
||||
xmedia_s32 i = 0;
|
||||
#ifdef SUPPORT_SENSOR_PWDN_MODE
|
||||
xmedia_s32 isp_pipe;
|
||||
#endif
|
||||
|
||||
for (i = 0; i < g_isp_info.isp_pipe_num; i++) {
|
||||
#ifdef SUPPORT_SENSOR_PWDN_MODE
|
||||
isp_pipe = g_isp_info.isp_pipe[i];
|
||||
if(g_isp_info.support_sensor_pwdn_standby[isp_pipe] == XMEDIA_TRUE) {
|
||||
drv_pwdn_sensor_resume(isp_pipe);
|
||||
}
|
||||
#endif
|
||||
drv_i2c_sensor_resume(g_isp_info.isp_pipe[i]);
|
||||
}
|
||||
|
||||
misc_set_sensor_sync_status(XMEDIA_FALSE);
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_s32 misc_media_suspend(xmedia_void)
|
||||
{
|
||||
xmedia_s32 media_timeout = 50;//ms
|
||||
xmedia_s32 try_count = 0;
|
||||
|
||||
MISC_TRACE(MODULE_DBG_DEBUG,"misc start!\n");
|
||||
#ifndef APP_STANDBY_SENSOR
|
||||
while(1) {
|
||||
if (misc_get_sensor_sync_status() == XMEDIA_TRUE)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (try_count >= (media_timeout / 2))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
try_count++;
|
||||
osal_udelay(2000);
|
||||
}
|
||||
try_count = 0;
|
||||
#endif
|
||||
MISC_TRACE(MODULE_DBG_DEBUG,"misc sensor!\n");
|
||||
while(1) {
|
||||
if (export_vi_check_busy() == XMEDIA_FALSE) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (try_count >= (media_timeout / 2))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
try_count++;
|
||||
osal_udelay(2000);
|
||||
}
|
||||
|
||||
try_count = 0;
|
||||
|
||||
while(1) {
|
||||
if (export_vpss_check_busy() == XMEDIA_FALSE) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (try_count >= (media_timeout / 2))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
try_count++;
|
||||
osal_udelay(2000);
|
||||
}
|
||||
|
||||
try_count = 0;
|
||||
MISC_TRACE(MODULE_DBG_DEBUG,"misc vpss!\n");
|
||||
|
||||
while(1) {
|
||||
if (export_venc_check_busy() == XMEDIA_FALSE) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (try_count >= (media_timeout / 2))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
try_count++;
|
||||
osal_udelay(2000);
|
||||
}
|
||||
|
||||
try_count = 0;
|
||||
MISC_TRACE(MODULE_DBG_DEBUG,"misc venc!\n");
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_s32 misc_ctl_aov_init(xmedia_ulong arg)
|
||||
{
|
||||
#ifdef SUPPORT_SENSOR_PWDN_MODE
|
||||
xmedia_s32 i = 0, isp_pipe;
|
||||
#endif
|
||||
misc_aov_isp_info *isp_info = (misc_aov_isp_info *)arg;
|
||||
|
||||
if (isp_info == XMEDIA_NULL) {
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
if (isp_info->isp_pipe_num == 0) {
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
memcpy(&g_isp_info, isp_info, sizeof(misc_aov_isp_info));
|
||||
|
||||
export_vi_register_misc_aov_callback(misc_sensor_standby);
|
||||
#ifdef SUPPORT_SENSOR_PWDN_MODE
|
||||
for (i = 0; i < g_isp_info.isp_pipe_num; i++) {
|
||||
isp_pipe = g_isp_info.isp_pipe[i];
|
||||
if(g_isp_info.support_sensor_pwdn_standby[isp_pipe] == XMEDIA_TRUE) {
|
||||
drv_pwdn_sensor_resume(isp_pipe);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_s32 misc_ctl_aov_set_sensor_mode(xmedia_ulong arg)
|
||||
{
|
||||
return misc_set_sensor_mode(arg);
|
||||
}
|
||||
|
||||
#ifdef SUPPORT_SENSOR_PWDN_MODE
|
||||
xmedia_s32 misc_ctl_sensor_pwdn_standby(xmedia_ulong arg)
|
||||
{
|
||||
xmedia_s32 isp_pipe = *(xmedia_s32*)arg;
|
||||
|
||||
return drv_pwdn_sensor_stanby(isp_pipe);
|
||||
}
|
||||
|
||||
xmedia_s32 misc_ctl_sensor_pwdn_resume(xmedia_ulong arg)
|
||||
{
|
||||
xmedia_s32 isp_pipe = *(xmedia_s32*)arg;
|
||||
|
||||
return drv_pwdn_sensor_resume(isp_pipe);
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user