GK SDK 源码库: XMIPCLinuxV100R005C00SPC030 (kernel/tools/open_source excluded)

This commit is contained in:
lai
2026-09-06 03:52:57 +08:00
commit b1928b41c0
21813 changed files with 4413081 additions and 0 deletions
+30
View File
@@ -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
+99
View File
@@ -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
+38
View File
@@ -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__ */
+150
View File
@@ -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
+564
View File
@@ -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
+362
View File
@@ -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