具体方法如下:
1、在内核中访问Metazone.bin分区
1)、在metazone.h中添加打开和关闭接口定义
kernel-3.18\include\misc\atc\metazone\metazone.h
kernel-3.18\include\misc\atc\metazone\metazone.h
///添加以下代码
/**
* @brief Initialize MetaZone API. Please call this function first before calling other functions.
*
* @param
* @param
*
*
* @return return MZ_SUCCESS if succeeds or MZ_FAILURE if failure.
*
*
* @see
* @note
**/
unsigned long MTZ_Open(unsigned int context, unsigned int accessCode, unsigned int shareMode);
/**
* @add interface for kernel space use metazone
*
* @defaule parameter 1,0,0
*
* @return
**/
bool MTZ_Close(unsigned int context);
/**
* @add interface for kernel space use metazone
*
* @defaule parameter 1,not used
*
* @return
**/
//结束添加
unsigned int MetaZone_Init(void);
2)、在倒车模块中添加编译开关
kernel-3.18\drivers\misc\autochips\Kconfig
kernel-3.18\drivers\misc\autochips\Kconfig
config ATC_TVD ####添加编译开关
bool "ATC support tvd hardware which decode analog signal"
default y
help
Used for decode analog signal in order to achieve backcar function
config ATC_TVD_META
bool "ATC support tvd read and write METAZONE.bin storage"
default y
help
Used for decode analog signal in order to achieve backcar function
3)、在AVIN模块的makefile中添加metazone.h路径
kernel-3.18\drivers\misc\autochips\avin\Makefile、
kernel-3.18\drivers\misc\autochips\avin\Makefile
subdir-ccflags-y += -I$(srctree)/include/misc/atc/metazone/ ###添加该路径
ccflags-y += -I$(srctree)/drivers/misc/autochips/libosal/inc/
4)打开ARM1(内核中)TVD设置开关
kernel-3.18\drivers\misc\autochips\tvd\src\tvd_if.c
kernel-3.18\drivers\misc\autochips\tvd\src\tvd_driver.c
kernel-3.18\drivers\misc\autochips\tvd\src\tvd_if.c
int tvd_hw_color_process(u16 type, u16 value)
{
#ifdef MANUAL_ADJUST_BRIGHTNESS
tvd_color_process(type, value);
#endif
return TVD_SUCCESS;
}
修改成:
int tvd_hw_color_process(u16 type, u16 value)
{
tvd_color_process(type, value);
return TVD_SUCCESS;
}
kernel-3.18\drivers\misc\autochips\tvd\src\tvd_driver.c
static unsigned int g_reg07C4 = 0xFF001996;//添加代码 TVD亮度设置
static unsigned int g_reg07C8 = 0x1EBD0010;//添加代码
static unsigned int g_reg07CC = 0x15710000;//添加代码
static unsigned int g_reg07D0 = 0x000EFF00;//添加代码
void tvd_color_process(u16 type, u16 value)
{
void __iomem *base = g_tvd_context->tvd_base;
vss_printk(VSS_LOG_INFO, "enter");
switch(type) {
case Y_GAIN:
TVD_SET_FIELD(0x7C4, 0xFFFF, value);
break;
case U_COSGAIN:
TVD_SET_FIELD(0x7C8, (0xFFFF << 16), (value << 16));
break;
case U_SINGAIN:
TVD_SET_FIELD(0x7C8, 0xFFFF, value);
break;
case V_COSGAIN:
TVD_SET_FIELD(0x7CC, (0xFFFF << 16), (value << 16));
break;
case V_SINGAIN:
TVD_SET_FIELD(0x7CC, 0xFFFF, value);
break;
case Y_OFFSET:
TVD_SET_FIELD(0x7D0, (0xFF << 16), (value << 16));
break;
case U_OFFSET:
TVD_SET_FIELD(0x7D0, (0xFF << 8), (value << 8));
break;
case V_OFFSET:
TVD_SET_FIELD(0x7D0, 0XFF, value);
break;
default:
vss_printk(VSS_LOG_INFO, "the type(%d) is not supported", type);
break;
}
g_reg07C4 = TVD_READ32(0x7C4);//添加代码 TVD亮度设置
g_reg07C8 = TVD_READ32(0x7C8);//添加代码
g_reg07CC = TVD_READ32(0x7CC);//添加代码
g_reg07D0 = TVD_READ32(0x7D0);//添加代码
vss_printk(VSS_LOG_INFO, "leave");
}
void tvd_special_setting(void)
{
void __iomem *base = g_tvd_context->tvd_base;
unsigned int tvd_mode = bHwTvdMode();
TVD_SET_BIT(REG_VSRC_07, RG_VSRC_INV_AIDX);
TVD_SET_BIT(REG_CDET_00, MODE000);
TVD_CLR_BIT(REG_DFE_0E, VPRES_SEL);
/* we can not set brightness default value in order to adjust brightness by self*/
TVD_WRITE32((0x7C4), g_reg07C4);//添加代码 TVD亮度设置
TVD_WRITE32((0x7C8), g_reg07C8);//添加代码
TVD_WRITE32((0x7CC), g_reg07CC);//添加代码
TVD_WRITE32((0x7D0), g_reg07D0);//添加代码
TVD_CLR_BIT((0x488), BIT(26));
TVD_SET_BIT((0x488), BIT(27));
TVD_CLR_BIT((0x4e0), BIT(31));
TVD_CLR_BIT((0x4e4), BIT(15));
TVD_SET_FIELD((0x4e8), (0x3FF << 10), (0x100 << 10));
TVD_SET_FIELD((0x4f8), (0xc << 0), (0xc << 0));
TVD_CLR_BIT((0x5fc), BIT(10));
TVD_SET_FIELD((0x4EC), (0x3F << 17), (0xB << 17));
switch (tvd_mode) {
case AV_PAL_N:
TVD_SET_BIT((0x540), BIT(4));
break;
case AV_PAL:
TVD_SET_BIT((0x540), BIT(4));
break;
case AV_PAL_M:
TVD_CLR_BIT((0x540), BIT(4));
break;
case AV_NTSC:
TVD_CLR_BIT((0x540), BIT(4));
break;
case AV_SECAM:
TVD_CLR_BIT((0x540), BIT(4));
break;
case AV_PAL_60:
TVD_CLR_BIT((0x540), BIT(4));
break;
case AV_NTSC443:
TVD_CLR_BIT((0x540), BIT(4));
break;
default:
break;
}
}
5)、在AVIN模块代码中适合的位置对metazone.bin分区进行操作
kernel-3.18\drivers\misc\autochips\avin\src\avin_mod.c
kernel-3.18\drivers\misc\autochips\avin\src\avin_mod.c
...............................
#ifdef CONFIG_ATC_TVD_META
#include "metazone.h"
#include "metazone_inter.h"
#include "metazone_ioctl.h"
#include "tvd_if.h"
#endif
...........................
#define ARM1_MATEZONE_TVD_LIGHT_INDEX 0x10000+175 //Metazone.bin分区的访问索引,基地址加偏移量
void DisplayTVDLight(void)
{
int ARM1_TVD_light = -1;
int ret = -1;
//TVD_COLOR_PROCESS_PARAMETER_T tvd_color_para;
MTZ_Open(1,0,0);//打开metazone.bin分区
MetaZone_Read(ARM1_MATEZONE_TVD_LIGHT_INDEX,&ARM1_TVD_light); //从索引地址读取数据
vss_printk(VSS_LOG_ERR,"[ARM1] DisplayTVDLight TVD_light = %d\n",ARM1_TVD_light);
//ret=tvd_hw_color_process(Y_GAIN, 0x1000);
ret=tvd_hw_color_process(0, ARM1_TVD_light); //将TVD显示的亮度设置到寄存器中
if(TVD_SUCCESS==ret){
vss_printk(VSS_LOG_ERR,"tvd_hw_color_process excuted success.zhaojr");
}
MTZ_Close(1);
}
/**
* avin_start_streaming : Starts the DMA engine for streaming
* @vb: ptr to vb2_buffer
* @count: number of buffers
*/
static int avin_start_streaming(struct vb2_queue *vq, unsigned int count)
{
int ret = 0;
vss_printk(VSS_LOG_INFO, "enter and version is %s\n", AVIN_VERSION);
backcar_tvd_init();
#ifdef CONFIG_ATC_TVD_META
DisplayTVDLight(); //在TVD开始显示之前将TVD的亮度设置成metazone.bin文件中设置的固定值,默认是0x1000(范围是:0-65535)
#endif
backcar_tvd_start();
backcar_state = true;
vss_printk(VSS_LOG_INFO, "leave\n");
return ret;
}
2、在ARM2中访问metazone.bin分区
1)打开TVD亮度调试接口
vendor\autochips\proprietary\arm2\tvd\src\tvd_if.c
vendor\autochips\proprietary\arm2\tvd\src\tvd_driver.c
vendor\autochips\proprietary\arm2\tvd\src\tvd_if.c
int tvd_hw_color_process(u16 type, u16 value)
{
#ifdef MANUAL_ADJUST_BRIGHTNESS
tvd_color_process(type, value);
#endif
return TVD_SUCCESS;
}
修改成:
int tvd_hw_color_process(u16 type, u16 value)
{
tvd_color_process(type, value);
return TVD_SUCCESS;
}
vendor\autochips\proprietary\arm2\tvd\src\tvd_driver.c
tatic unsigned int g_reg07C4 = 0xFF001996; //添加代码 //TVD亮度
static unsigned int g_reg07C8 = 0x1EBD0010;//添加代码
static unsigned int g_reg07CC = 0x15710000;//添加代码
static unsigned int g_reg07D0 = 0x000EFF00;//添加代码
void tvd_color_process(u16 type, u16 value)
{
u32 base = TVD_BASE_ADDRESS;
TVD_LOG(TVD_INFO, "tvd_color_process enter\n");
switch(type) {
case Y_GAIN:
TVD_SET_FIELD(0x7C4, 0xFFFF, value);
break;
case U_COSGAIN:
TVD_SET_FIELD(0x7C8, (0xFFFF << 16), (value << 16));
break;
case U_SINGAIN:
TVD_SET_FIELD(0x7C8, 0xFFFF, value);
break;
case V_COSGAIN:
TVD_SET_FIELD(0x7CC, (0xFFFF << 16), (value << 16));
break;
case V_SINGAIN:
TVD_SET_FIELD(0x7CC, 0xFFFF, value);
break;
case Y_OFFSET:
TVD_SET_FIELD(0x7D0, (0xFF << 16), (value << 16));
break;
case U_OFFSET:
TVD_SET_FIELD(0x7D0, (0xFF << 8), (value << 8));
break;
case V_OFFSET:
TVD_SET_FIELD(0x7D0, 0XFF, value);
break;
default:
TVD_LOG(TVD_INFO, "the type(%d) is not supported", type);
break;
}
g_reg07C4 = TVD_READ32(0x7C4); //添加代码 //TVD亮度
g_reg07C8 = TVD_READ32(0x7C8); //添加代码
g_reg07CC = TVD_READ32(0x7CC); //添加代码
g_reg07D0 = TVD_READ32(0x7D0); //添加代码
TVD_LOG(TVD_INFO, "tvd_color_process leave\n");
}
void tvd_special_setting(void)
{
u32 base = TVD_BASE_ADDRESS;
unsigned int tvd_mode = bHwTvdMode();
TVD_SET_BIT(REG_VSRC_07, RG_VSRC_INV_AIDX);
TVD_SET_BIT(REG_CDET_00, MODE000);
TVD_CLR_BIT(REG_DFE_0E, VPRES_SEL);
/* we can not set brightness default value in order to adjust brightness by self*/
TVD_WRITE32((0x7C4), g_reg07C4); //添加代码 //TVD亮度
TVD_WRITE32((0x7C8), g_reg07C8); //添加代码
TVD_WRITE32((0x7CC), g_reg07CC); //添加代码
TVD_WRITE32((0x7D0), g_reg07D0); //添加代码
TVD_CLR_BIT((0x488), BIT(26));
TVD_SET_BIT((0x488), BIT(27));
TVD_CLR_BIT((0x4e0), BIT(31));
TVD_CLR_BIT((0x4e4), BIT(15));
TVD_SET_FIELD((0x4e8), (0x3FF << 10), (0x100 << 10));
TVD_SET_FIELD((0x4f8), (0xc << 0), (0xc << 0));
TVD_CLR_BIT((0x5fc), BIT(10));
TVD_SET_FIELD((0x4EC), (0x3F << 17), (0xB << 17));
switch (tvd_mode) {
case AV_PAL_N:
TVD_SET_BIT((0x540), BIT(4));
break;
case AV_PAL:
TVD_SET_BIT((0x540), BIT(4));
break;
case AV_PAL_M:
TVD_CLR_BIT((0x540), BIT(4));
break;
case AV_NTSC:
TVD_CLR_BIT((0x540), BIT(4));
break;
case AV_SECAM:
TVD_CLR_BIT((0x540), BIT(4));
break;
case AV_PAL_60:
TVD_CLR_BIT((0x540), BIT(4));
break;
case AV_NTSC443:
TVD_CLR_BIT((0x540), BIT(4));
break;
default:
break;
}
}
2、增加TVD模块通过读取Metazone.bin来调整TVD亮度
vendor\autochips\proprietary\arm2\backcar\AC8227L_BCLib_stubs.c
添加编译开关
vendor\autochips\proprietary\arm2\backcar\Makefile
#modify by zhojr@flyaudio.cn ##增加以下行
LOCAL_CFLAG += -DADAPTER_ARM1_TVD_light=1
在TVD开始显示视频之前将TVD亮度调整到metazone.bin中的固定值
vendor\autochips\proprietary\arm2\backcar\AC8227L_BCLib_stubs.c
#if ADAPTER_ARM1_TVD_light
#define MATEZONE_TVD_LIGHT_INDEX 0x10000+175 //metazone.bin中索引地址
void DisplayTVDLight(void)
{
int TVD_light = -1;
int ret = -1;
_MetaZone_Read(MATEZONE_TVD_LIGHT_INDEX,&TVD_light);//从metazone.bin中索引地址读取值
Printf("[ARM2] DisplayTVDLight TVD_light = %d\n",TVD_light);
//ret=tvd_hw_color_process(Y_GAIN, 0x1000);
ret=tvd_hw_color_process(Y_GAIN, TVD_light); //设置到TVD寄存器中
if(TVD_SUCCESS==ret){
BC_INFO("tvd_hw_color_process excuted success.zhaojr");
}
}
#endif
int bc_bufferflow_start()
{
int ret = -1;
//in BCReleaseResource we need this variable to ensure no more buffers are enqued to following modules.
g_fFrameHandleStop = FALSE;
tvd_first_frame_ready = FALSE;
nr_first_frame_ready = FALSE;
di_first_frame_ready = FALSE;
#ifdef TVD_READY
TVD_COLOR_PROCESS_PARAMETER_T tvd_color_process_parameter = {0,};
unsigned int starttime = 0;
BC_INFO("bc_bufferflow_start ++, at TickCount (%d)",GetARM2TickCount());
starttime = GetARM2TickCount();
BC_INFO("bc_bufferflow_start time = (%d)", starttime);
// tvd init
ret = tvd_hw_init();
if (TVD_SUCCESS != ret) {
BC_ERROR("tvd_hw_init Fail: ret value (%d)",ret);
return -1;
}
#if ADAPTER_ARM1_TVD_light
DisplayTVDLight(); //在tvd_hw_start之前将metazone.bin中的参数设置到TVD寄存器中,默认值是0x1000,范围0-65535
#endif
//tvd_callback_register
tvd_callback_register(on_tvd_frame_handle,on_tvd_signal_handle);
//tvd_hw_config
//optional
ret = tvd_hw_start();
if (TVD_SUCCESS != ret) {
BC_ERROR("tvd_hw_start Fail: ret value (%d)",ret);
goto _deinit_tvd;
}
#endif
BC_INFO("bc_bufferflow_start --, at TickCount (%d)",GetARM2TickCount());
return 0;
_deinit_tvd:
#ifdef TVD_READY
tvd_hw_deinit();
#endif
return -1;
}
3、上层APP可以读写metazone.bin接口即可实现,同时访问以下接口直接写寄存器
1)直接写寄存器
2、读写metazone.bin接口
按照以下接口函数访问meta分区即可
import android.util.Log;
import com.autochips.metazone.AtcMetazone;
/**
* Created by wehao on 18-5-23.
*/
public class MetaZoneUtils {
private static final String TAG = "MetaZoneUtils";
public final static String KEY_BACK_LIGHT = "key_back_light";
public final static String KEY_BRIGHTNESS = "key_brightness";
public final static String KEY_CONTRAST = "key_contrast";
public final static String KEY_HUE = "key_hue";
public final static String KEY_SATURATION = "key_saturation";
private static MetaZoneUtils mInst;
private AtcMetazone mMetaZone = new AtcMetazone();
public static MetaZoneUtils getInst() {
if (mInst == null) {
mInst = new MetaZoneUtils();
}
return mInst;
}
private MetaZoneUtils() {}
/**
* 读取metazone分区特定index的值
* @param index
* @return
*/
public int readValue(int index) {
int []data = new int[1];
mMetaZone.readval(index, data);
return data[0];
}
/**
* 根据key,获取value
* @param key
* @return
*/
public int readValue(String key) {
int index = getIndex(key);
return readValue(index);
}
/**
* 向metazone分区特定index写值
* @param index
* @param data
* @return
*/
public boolean writeValue(int index, int data) {
boolean flush_flag = true;
if (index >= 0x10000 + 0xa0 && index <= 0x10000 + 0xa4) {
Log.d(TAG, "writeValue: " + data + " index: " + index);
mMetaZone.writeval(index, data);
mMetaZone.flush(flush_flag);
} else {
Log.d(TAG, "writeValue index out of range " + index);
}
Log.d(TAG, "writeValue flush_flag" + flush_flag);
return flush_flag;
}
/**
* 根据key获取相应的index,然后想metazone写值
* @param key
* @param data
* @return
*/
public boolean writeValue(String key, int data) {
int index = getIndex(key);
return writeValue(index, data);
}
/**
* 根据key值获取相应index
* @param key
* @return
*/
private int getIndex(String key) {
int ret = -1;
switch (key) {
case KEY_BACK_LIGHT: {
ret = 0x10000 + 0xa0;
break;
}
case KEY_BRIGHTNESS: {
ret = 0x10000 + 0xa1;
break;
}
case KEY_CONTRAST: {
ret = 0x10000 + 0xa2;
break;
}
case KEY_HUE: {
ret = 0x10000 + 0xa3;
break;
}
case KEY_SATURATION: {
ret = 0x10000 + 0xa4;
break;
}
}
return ret;
}
}
上层APP写metazone分区之后,重启系统之后有效