文档章节

高通平台调试s5k5e8前置摄像头otp

y
 yueqiulijun
发布于 2017/05/05 11:27
字数 2146
阅读 157
收藏 0
点赞 0
评论 0
包含寄存器地址和PAGE详细信息,以利于供应商核对otp信息
kernel\msm-3.18\drivers\media\platform\msm\camera_v2\sensor\eeprom\msm_eeprom.c +msm_eeprom_platform_probe +1728

int i,page = 5;

*********************
以下读取Module info && awb 数据
*********************
for (j = 0; j < e_ctrl->cal_data.num_data; j++)
	CDBG("memory_data[%d] = address[0x%x] =  0x%X\n", j, (0x0A04+j),
		e_ctrl->cal_data.mapdata[j]);

*********************
以下读取 LSC 数据
*********************
#define START_ADDRESS_OTP 0x0A28
#define START_OTP_YUEQIU 0x0A04
#define END_OTP_YUEQIU (0x0A43 + 1)
//int i,page = 5;
i = START_ADDRESS_OTP;
for (j = 0; j < e_ctrl->cal_data.num_data; j++, i++)
{
	if(END_OTP_YUEQIU == i)
	{
		i = START_OTP_YUEQIU;
		printk("PAGE %d\n", page++);
	}
	CDBG("memory_data[%d] = address[0x%x] =  0x%X\n", j, i,
			e_ctrl->cal_data.mapdata[j]);
}


/*******打印整个群晖摄像头s5k5e8 otp 数据*********/
static int dump_memory;
int i, page = 5;
#define START_ADDRESS_OTP 0x0a04
#define START_OTP_YUEQIU 0x0a04
#define END_OTP_YUEQIU (0x0a43 + 1)
printk("PAGE 4\n");
i = START_ADDRESS_OTP;
dump_memory++;
if(3 == dump_memory)
{
	for (j = 0; j < e_ctrl->cal_data.num_data; j++, i++)
	{
		if(END_OTP_YUEQIU == i)
		{
			i = START_OTP_YUEQIU;
			printk("PAGE %d\n", page++);
		}
		printk("memory_data[%d] = address[0x%x] = 0x%X\n", j, i,
		e_ctrl->cal_data.mapdata[j]);
	}
}

 

vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/modules/sensors/eeprom/libs/qunhui_s5k5e8/qunhui_s5k5e8_eeprom.c
/*============================================================================

  Copyright (c) 2016 Qualcomm Technologies, Inc. All Rights Reserved.
  Qualcomm Technologies Proprietary and Confidential.

============================================================================*/
#include <stdio.h>
#include <string.h>
#include <utils/Log.h>
#include "../eeprom_util/eeprom.h"
#include "eeprom_lib.h"
#include "eeprom_util.h"
#include "debug_lib.h"
#include "sensor_lib.h"
#include "actuator_driver.h"

#undef CDBG
#define EEPROM_DEBUG
#ifdef EEPROM_DEBUG
#define CDBG(fmt, args...) \
  ALOGE("s5k5e8_eeprom %s:%d "fmt"\n", __func__, __LINE__, ##args)
#else
#define CDBG(fmt, args...) do{}while(0)
#endif

#define AWB_REG_SIZE 8 //手册里面此部分寄存器有8个

#define OTP_VALID      1 
#define OTP_INVALID   0

#define GAIN_GREEN1_ADDR    0x020E  //这部分寄存器的值问供应商提供,或者手册里有
#define GAIN_BLUE_ADDR      0x0212
#define GAIN_RED_ADDR       0x0210
#define GAIN_GREEN2_ADDR    0x0214

#define RG_TYPICAL_QUNHUI     0x8B //经典值,可以从芯片寄存器里读取,因为是固定的,也可以自己指定
#define BG_TYPICAL_QUNHUI     0x7D	

#define QUNHUI_MODULE_ID       0x44 

#define PRIMAX_S5K5E8_OTP_DEBUG 

struct otp_struct {
  uint16_t module_integrator_id; 
  uint16_t production_year;
  uint16_t production_month;
  uint16_t production_day;
  uint16_t lens_id;
  uint16_t vcm_id;
  uint16_t R_Gr_ratio;
  uint16_t B_Gr_ratio;
} otp;

static uint16_t rg_typical, bg_typical = 0;
static uint16_t use_group = 1;
static uint16_t lsc_info[360];
//数组大小的计算千万小心仔细,很容易算错,这个数组是回写 sensor 寄存器
//camera_i2c_reg_array 属于 camera_i2c_reg_setting 元素
struct camera_i2c_reg_array g_reg_array[AWB_REG_SIZE + 144*6 + 2 + 1];
struct camera_i2c_reg_setting g_reg_setting;


/** qunhui_s5k5e8_get_calibration_items:
 *    @e_ctrl: point to sensor_eeprom_data_t of the eeprom device
 *
 * Get calibration capabilities and mode items.
 *
 * This function executes in eeprom module context
 *
 * Return: void.
 **/
 
static void qunhui_s5k5e8_get_calibration_items(void *e_ctrl)
{
  sensor_eeprom_data_t *ectrl = (sensor_eeprom_data_t *)e_ctrl;
  eeprom_calib_items_t *e_items = &(ectrl->eeprom_data.items);
//is_insensor 如果传感器模块本身支持EEPROM配置,则将此标记设置为TRUE。外部EEPROM均不可用
  e_items->is_insensor = TRUE;
//如果支持AF校准,将此标记设置为TRUE
  e_items->is_afc = FALSE;//摄像头因为没有对焦功能,所以这个标志位无关紧要
//如果支持白平衡校准,将此标记设置为TRUE
  e_items->is_wbc = FALSE;//摄像头本身支持白平衡校准,就设置为 false
//如果支持镜头阴影校准,将此标记设置为TRUE
  e_items->is_lsc = FALSE;//摄像头本身支持LSC校准,就设置为 false
}

//叫供应商提供以下函数
void qunhui_s5k5e8_awb_updata(uint16_t r_gain,uint16_t b_gain)
{
	float R_ration=(float)rg_typical/(float)r_gain;
	float B_ration=(float)bg_typical/(float)b_gain;
	uint16_t G_gain,R_gain,B_gain;
	uint16_t gain_default=0x0100;
	
	if (R_ration>=1)
	{
		if (B_ration>=1)
		{
			G_gain=gain_default ;
			R_gain=gain_default*R_ration;
			B_gain=gain_default*B_ration;
		}
		else
		{
			B_gain=gain_default;
			G_gain=gain_default/B_ration;
			R_gain=gain_default*R_ration/B_ration;
		}
	}
	else
	{	
		if (B_ration>=1)
		{
			R_gain=gain_default;
			G_gain=gain_default/R_ration;
			B_gain=gain_default*B_ration/R_ration;
		}
		else if (R_ration>=B_ration)
		{
			B_gain=gain_default;
			G_gain=gain_default/B_ration;
			R_gain=gain_default*R_ration/B_ration;	
		}
		else
		{
			R_gain=gain_default;
			G_gain=gain_default/R_ration;
			B_gain=gain_default*B_ration/R_ration;
		}
	}

	
    g_reg_array[g_reg_setting.size].reg_addr = GAIN_GREEN1_ADDR;
    g_reg_array[g_reg_setting.size].reg_data = G_gain >> 8;
    g_reg_setting.size++;

    g_reg_array[g_reg_setting.size].reg_addr = GAIN_GREEN1_ADDR+1;
    g_reg_array[g_reg_setting.size].reg_data = G_gain & 0x00ff;
    g_reg_setting.size++;

    g_reg_array[g_reg_setting.size].reg_addr = GAIN_RED_ADDR;
    g_reg_array[g_reg_setting.size].reg_data = R_gain >> 8;
    g_reg_setting.size++;

    g_reg_array[g_reg_setting.size].reg_addr = GAIN_RED_ADDR+1;
    g_reg_array[g_reg_setting.size].reg_data = R_gain & 0x00ff;
    g_reg_setting.size++;

    g_reg_array[g_reg_setting.size].reg_addr = GAIN_BLUE_ADDR;
    g_reg_array[g_reg_setting.size].reg_data = B_gain >> 8;
    g_reg_setting.size++;

    g_reg_array[g_reg_setting.size].reg_addr = GAIN_BLUE_ADDR+1;
    g_reg_array[g_reg_setting.size].reg_data = B_gain & 0x00ff;
    g_reg_setting.size++;

    g_reg_array[g_reg_setting.size].reg_addr = GAIN_GREEN2_ADDR;
    g_reg_array[g_reg_setting.size].reg_data = G_gain >> 8;
    g_reg_setting.size++;

    g_reg_array[g_reg_setting.size].reg_addr = GAIN_GREEN2_ADDR+1;
    g_reg_array[g_reg_setting.size].reg_data = G_gain & 0x00ff;
    g_reg_setting.size++;
}


//供应商提供的解码函数
// I2CMODE_MICRON2 (16 Bit Address,8 Bit Data)
/************************************************************************/
/* 解码OTP至SRAM格式 */
/************************************************************************/
void DePrOTPLSCData_5E8(uint16_t *OTPBuff, uint16_t *SRAMBuff)
{
	int i = 0, j=0;
	for(i = 0; i < 360; i++)
	  ALOGE("OTPBuff[%d]: %d \n", i, OTPBuff[i]);
	for (i=0; i<360; i=i+5)
	{
		SRAMBuff[j++] = (OTPBuff[i] & 0xf0) >>4;
		SRAMBuff[j++] = ((OTPBuff[i] & 0x0f) <<4) | ((OTPBuff[i+1] & 0xf0) >>4);
		SRAMBuff[j++] = ((OTPBuff[i+1] & 0x0f) <<4) | ((OTPBuff[i+2] & 0xf0) >>4);
		SRAMBuff[j++] = OTPBuff[i+2] & 0x0f;
		SRAMBuff[j++] = OTPBuff[i+3];
		SRAMBuff[j++] = OTPBuff[i+4];
	}
}
/************************************************************************/
/* 加载SRAM到 Sensor */
/************************************************************************/
void ApplyLSC(void){
	uint16_t sramBuff[432];
	int counter = 0x00;	
	int i;
	DePrOTPLSCData_5E8(lsc_info, sramBuff);
	/* 起初这个是没有注释掉的,导致摄像头报错:media server died, camera closed
       应该是和 xxx_lib.h 里面重复掉了 0x0100 是流控制寄存器,写1:stream 写0:software standby
	g_reg_array[g_reg_setting.size].reg_addr = 0x0100;
	g_reg_array[g_reg_setting.size].reg_data = 0x01;
	g_reg_setting.size++;
	*/
/*  LSC 自动加载控制寄存器,写00:自动加载 写1:不是自动加载*/
	g_reg_array[g_reg_setting.size].reg_addr = 0x3400;
	g_reg_array[g_reg_setting.size].reg_data = 0x00;
	g_reg_setting.size++;
    //寄存器[3]: seed date update start enable
    //寄存器[2]: gain caculate start enable
    //寄存器[1]:gain caculate auto-start enable
	g_reg_array[g_reg_setting.size].reg_addr = 0x3457;
	g_reg_array[g_reg_setting.size].reg_data = 0x04;
	g_reg_setting.size++;		
/* 	
	//bFX2WriteSensor(nI2C, 0x0100,0x00, I2CMODE_STMICRO);
	//bFX2WriteSensor(nI2C, 0x3400,0x00, I2CMODE_STMICRO);
	//Sleep(100);
	

	// 这个寄存器三星没有开放,三星建议,不要设置
	g_reg_array[g_reg_setting.size].reg_addr = 0x3b4c;
	g_reg_array[g_reg_setting.size].reg_data = 0x00;
	g_reg_setting.size++;	
	
	//bFX2WriteSensor(nI2C, 0x3457,0x04, I2CMODE_STMICRO);
	//bFX2WriteSensor(nI2C, 0x3b4c,0x00, I2CMODE_STMICRO);
	
*/
	for(i = 0; i < 432; i++)
	  	ALOGE("sramBuff[%d]: %d \n", i, sramBuff[i]);
	for (i=0; i<432; )
	{
/*
0x3415  [7:4]Reserved R [3:0] GAS_write_data[19:16]
0x3416  [7:0]GAS_write_data[15:8]
0x3417  [7:0]GAS_write_data[7:0]
0x3418  [7:0]GAS_address
0x3419  [7:4]Reserved   [3:0]GAS_command  4=write 8=read
*/
		g_reg_array[g_reg_setting.size].reg_addr = 0x3419;
		g_reg_array[g_reg_setting.size].reg_data = 0x00;
		g_reg_setting.size++;		
		
		g_reg_array[g_reg_setting.size].reg_addr = 0x3415;
		g_reg_array[g_reg_setting.size].reg_data = sramBuff[i];
		g_reg_setting.size++;
		
		g_reg_array[g_reg_setting.size].reg_addr = 0x3416;
		g_reg_array[g_reg_setting.size].reg_data = sramBuff[i + 1];
		g_reg_setting.size++;
		
		g_reg_array[g_reg_setting.size].reg_addr = 0x3417;
		g_reg_array[g_reg_setting.size].reg_data = sramBuff[i + 2];
		g_reg_setting.size++;		
		
		g_reg_array[g_reg_setting.size].reg_addr = 0x3418;
		g_reg_array[g_reg_setting.size].reg_data = counter++;
		g_reg_setting.size++;

		g_reg_array[g_reg_setting.size].reg_addr = 0x3419;
		g_reg_array[g_reg_setting.size].reg_data = 0x04;
		g_reg_setting.size++;		
	
		i=i+3;
	}
	
	//bFX2WriteSensor(nI2C, 0x3457,0x0C, I2CMODE_STMICRO);
	//bFX2WriteSensor(nI2C, 0x0100,0x01, I2CMODE_STMICRO);
	 
	 
	g_reg_array[g_reg_setting.size].reg_addr = 0x3457;
	g_reg_array[g_reg_setting.size].reg_data = 0x0c;
	g_reg_setting.size++;
/*	
	g_reg_array[g_reg_setting.size].reg_addr = 0x0100;
	g_reg_array[g_reg_setting.size].reg_data = 0x00;
	g_reg_setting.size++;		
*/	
	
}

void qunhui_s5k5e8_calib_sensor(sensor_eeprom_data_t *e_ctrl)
{
    CDBG("[S5K5E8OTP] Enter %s", __func__);
	/*****************************
	注*  先判断Group2 Flag是否为 1 ?  {如果为1 即读取Group2 数据}, {不为1则读取Group1数据}
	*****************************/
    unsigned int base=0, i;
	unsigned int awb_base=16;
	unsigned int lsc_base=16;
	unsigned int uiInformation_Group = 0;
	unsigned int uiAWB_Group = 0;
	unsigned int uiLSC_Group = 0;
#define INFORMATION_GROUP_OFFSET 8
#define AWB_GROUP_OFFSET 10
#define LSC_GROUP_OFFSET 362
	/************  Information *****************/
	if (e_ctrl->eeprom_params.buffer[0 + INFORMATION_GROUP_OFFSET] == 0x01) {
	   uiInformation_Group = 2;
	   base = 8;
	   ALOGE("qunhui s5k5e8_eeprom MODULE ID use group 2 \n");
	}else if (e_ctrl->eeprom_params.buffer[0] == 0x01) {
	   uiInformation_Group = 1;
	   base = 0;
	   ALOGE("qunhui s5k5e8_eeprom MODULE ID use group 1 \n");
	}else {
	   uiInformation_Group = 0;
	   ALOGE("qunhui s5k5e8_eeprom MODULE ID error: %s:%d \n", __func__, __LINE__);
	}

	/************  AWB *****************/
	if (e_ctrl->eeprom_params.buffer[16 + AWB_GROUP_OFFSET] == 0x01) {
	   uiAWB_Group = 2;
	   awb_base = 8 + 8 + 10 + 1;
	   ALOGE("qunhui s5k5e8_eeprom awb use group 2 \n");
	}
	else if (e_ctrl->eeprom_params.buffer[16] == 0x01){
	   uiAWB_Group = 1;
	   awb_base = 16 + 1;
	   ALOGE("qunhui s5k5e8_eeprom awb use group 1 \n");
	}
	else {
	   uiAWB_Group = 0;
	   ALOGE("qunhui s5k5e8_eeprom AWB error: %s:%d \n", __func__, __LINE__);
	}

	/************  LSC  *****************/
	if (e_ctrl->eeprom_params.buffer[36 + LSC_GROUP_OFFSET] == 0x01) {//****** Page 10  address
	   uiLSC_Group = 2;
	   lsc_base = 36 + 362 + 1;//计算开始地址要小心,和下面的读取拷贝要一致
	   ALOGE("qunhui s5k5e8_eeprom lsc use group 2 \n");
	}
	else if (e_ctrl->eeprom_params.buffer[36] == 0x01) {//****** Page 4  address
	   uiLSC_Group = 1;
	   lsc_base = 36 + 1;
	   ALOGE("qunhui s5k5e8_eeprom lsc use group 1 \n");
	}
	else {
	   uiLSC_Group = 0;
	   ALOGE("qunhui s5k5e8_eeprom LSC error: %s:%d \n", __func__, __LINE__);
	}
	
    //int flg_otp_lsc = 1;
    //int i=0;
    
	CDBG("grop flag = 0x%x otp.module_id= 0x%x\n",e_ctrl->eeprom_params.buffer[base], e_ctrl->eeprom_params.buffer[base+1] & 0x1f);

	otp.module_integrator_id = e_ctrl->eeprom_params.buffer[base+1] & 0x1f;
	otp.lens_id =  e_ctrl->eeprom_params.buffer[base+2];
	otp.vcm_id= e_ctrl->eeprom_params.buffer[base+3];
	otp.production_year = e_ctrl->eeprom_params.buffer[base+4];
	otp.production_month = e_ctrl->eeprom_params.buffer[base+5];
	otp.production_day = e_ctrl->eeprom_params.buffer[base+6];	


	otp.R_Gr_ratio = (e_ctrl->eeprom_params.buffer[awb_base]) | (e_ctrl->eeprom_params.buffer[awb_base + 1] << 8);
	otp.B_Gr_ratio = (e_ctrl->eeprom_params.buffer[awb_base + 2]) | (e_ctrl->eeprom_params.buffer[awb_base + 3] << 8);
	rg_typical = (e_ctrl->eeprom_params.buffer[awb_base + 4]) | (e_ctrl->eeprom_params.buffer[awb_base + 5] << 8);
	bg_typical = (e_ctrl->eeprom_params.buffer[awb_base + 6]) | (e_ctrl->eeprom_params.buffer[awb_base + 7] << 8);
	//flg_otp_lsc = OTP_VALID;
	
	CDBG("[S5K5E8OTP] otp.module_integrator_id= 0x%x\n", otp.module_integrator_id);
	CDBG("[S5K5E8OTP] otp.lens_id= 0x%x\n", otp.vcm_id);
	CDBG("[S5K5E8OTP] otp.R_Gr_ratio= 0x%x\n", otp.R_Gr_ratio);
	CDBG("[S5K5E8OTP] otp.B_Gr_ratio= 0x%x\n", otp.B_Gr_ratio);
	CDBG("[S5K5E8OTP] rg_typical= 0x%x\n", rg_typical);
	CDBG("[S5K5E8OTP] bg_typical= 0x%x\n", bg_typical);
	
	
	if(otp.R_Gr_ratio == 0 || otp.B_Gr_ratio == 0)
	{
		CDBG("[S5K5E8OTP] module OTP wb data unvalid !\n");
		return ;
	}
	
	qunhui_s5k5e8_awb_updata(otp.R_Gr_ratio,otp.B_Gr_ratio);
    //memcpy 用起来要小心,源数据的数据类型和目的地址的数据类型要千万注意,还有要拷贝的字节数要写正确,不要自己写数字,不然,很容易出现拷贝不全
	//memcpy(lsc_info, &e_ctrl->eeprom_params.buffer[lsc_base], 360);
	for(i = 0; i < 360; i++)
	  lsc_info[i] = e_ctrl->eeprom_params.buffer[lsc_base + i];//和前面的开始地址要一致

	ApplyLSC();
	//qunhui_s5k5e8_lsc_updata(flg_otp_lsc);
}


/** qunhui_s5k5e8_format_calibration_data:
 *    @e_ctrl: point to sensor_eeprom_data_t of the eeprom device
 *
 * Format all the data structure of calibration
 *
 * This function executes in eeprom module context and generate
 *   all the calibration registers setting of the sensor.
 *
 * Return: void.
 **/

void qunhui_s5k5e8_format_calibration_data(void *e_ctrl) {
  CDBG("Enter %s", __func__);
  sensor_eeprom_data_t *ectrl = (sensor_eeprom_data_t *)e_ctrl;

  g_reg_setting.addr_type = CAMERA_I2C_WORD_ADDR;
  g_reg_setting.data_type = CAMERA_I2C_BYTE_DATA;
  g_reg_setting.reg_setting = &g_reg_array[0];
  g_reg_setting.size = 0;
  g_reg_setting.delay = 0;
  qunhui_s5k5e8_calib_sensor(ectrl);

  CDBG("Exit %s", __func__);
}

/** qunhui_s5k5e8_get_raw_data:
 *    @e_ctrl: point to sensor_eeprom_data_t of the eeprom device
 *    @data: point to the destination msm_camera_i2c_reg_setting
 *
 * Get the all the calibration registers setting of the sensor
 *
 * This function executes in eeprom module context.
 *
 * Return: void.
 **/
static int qunhui_s5k5e8_get_raw_data(void *e_ctrl, void *data) {
  if (e_ctrl && data)
    memcpy(data, &g_reg_setting, sizeof(g_reg_setting));
  else
    CDBG("failed Null pointer");
  return 0;
}

static eeprom_lib_func_t qunhui_s5k5e8_lib_func_ptr = {
  .get_calibration_items = qunhui_s5k5e8_get_calibration_items,
  .format_calibration_data = qunhui_s5k5e8_format_calibration_data,
  .do_af_calibration = NULL,
  .do_wbc_calibration = NULL,
  .do_lsc_calibration = NULL,
  .get_raw_data = qunhui_s5k5e8_get_raw_data,
//以下的上下电没有用到,因为在kernel 的dtsi 文件里面已经配置了上下电
  .eeprom_info =
  {
    .power_setting_array =
    {
      .power_setting_a =
      {
        {
          .seq_type = CAMERA_POW_SEQ_GPIO,
          .seq_val = CAMERA_GPIO_RESET,
          .config_val = GPIO_OUT_LOW,
          .delay = 1,
        },
        {
          .seq_type = CAMERA_POW_SEQ_GPIO,
          .seq_val = CAMERA_GPIO_VANA,
          .config_val = GPIO_OUT_HIGH,
          .delay = 1,
        },
        {
          .seq_type = CAMERA_POW_SEQ_VREG,
          .seq_val = CAMERA_VDIG,
          .config_val = 1,
          .delay = 1,
        },
        {
          .seq_type = CAMERA_POW_SEQ_VREG,
          .seq_val = CAMERA_VIO,
          .config_val = 1,
          .delay = 0,
        },
/*
        {
          .seq_type = CAMERA_POW_SEQ_VREG,
          .seq_val = CAMERA_VAF,
          .config_val = 1,
          .delay = 5,
        },
*/
        {
          .seq_type = CAMERA_POW_SEQ_CLK,
          .seq_val = CAMERA_MCLK,
          .config_val = 24000000,
          .delay = 1,
        },
        {
          .seq_type = CAMERA_POW_SEQ_GPIO,
          .seq_val = CAMERA_GPIO_RESET,
          .config_val = GPIO_OUT_HIGH,
          .delay = 11,
        },
      },
      .size = 6,
      .power_down_setting_a =
      {
        {
          .seq_type = CAMERA_POW_SEQ_CLK,
          .seq_val = CAMERA_MCLK,
          .config_val = 0,
          .delay = 1,
        },
        {
          .seq_type = CAMERA_POW_SEQ_GPIO,
          .seq_val = CAMERA_GPIO_RESET,
          .config_val = GPIO_OUT_LOW,
          .delay = 1,
        },
/*
        {
          .seq_type = CAMERA_POW_SEQ_VREG,
          .seq_val = CAMERA_VAF,
          .config_val = 1,
          .delay = 0,
        },
*/
        {
          .seq_type = CAMERA_POW_SEQ_VREG,
          .seq_val = CAMERA_VIO,
          .config_val = 0,
          .delay = 0,
        },
        {
          .seq_type = CAMERA_POW_SEQ_VREG,
          .seq_val = CAMERA_VDIG,
          .config_val = 0,
          .delay = 1,
        },
        {
          .seq_type = CAMERA_POW_SEQ_GPIO,
          .seq_val = CAMERA_GPIO_VANA,
          .config_val = GPIO_OUT_LOW,
          .delay = 1,
        },
      },
      .size_down = 5,
    },
    .i2c_freq_mode = SENSOR_I2C_MODE_STANDARD,
    .mem_map_array =
    {
	.memory_map =
	{
	    {
		.slave_addr = 0x20,
		.mem_settings =
		{
			  { 0x0A04, CAMERA_I2C_WORD_ADDR,
			   64, CAMERA_I2C_BYTE_DATA, CAMERA_I2C_OP_READ, 1 },
	    },
		.memory_map_size = 1,

        },
      },
      .size_map_array = 1,
    },
  },
 
};

/** qunhui_s5k5e8_eeprom_open_lib:
 *
 * Get the funtion pointer of this lib.
 *
 * This function executes in eeprom module context.
 *
 * Return: eeprom_lib_func_t point to the function pointer.
 **/
void* qunhui_s5k5e8_eeprom_open_lib(void) {
  return &qunhui_s5k5e8_lib_func_ptr;
}

 

© 著作权归作者所有

共有 人打赏支持
y
粉丝 0
博文 23
码字总数 8143
作品 0
深圳
车联网的智慧大脑

在不远的将来,汽车将具有激光雷达、视频传感组成的双眼。通过高性能的无线数据传输,实现人与车乃至车与车之间的顺畅沟通与交流。并将由此而进一步的实现有人驾驶向无人驾驶的技术跃进。而这...

玄学酱 ⋅ 02/09 ⋅ 0

这些 Android P Beta 设备等您速来体验

感谢 Treble 这一项目,我们的顶级设备制造商已经在一系列流行设备上提供了 Android P 测试版。 此页面列出了支持的设备,以及获得其更新和支持的制造商网址链接。您今天就可以开始尝鲜了! ...

谷歌开发者 ⋅ 05/10 ⋅ 0

能连续吃鸡6个半小时,这样的游戏手机想不想来一个?

“N7是迄今为止最好的360手机。”360手机N7新品发布会甫一开场,360手机总裁李开新就语惊四座。 作为360专门针对游戏手机市场推出的重头产品,360手机N7采用了高通骁龙660处理器和Adreno 51...

zabenbrdit36243qnjx1 ⋅ 05/09 ⋅ 0

[图]约合1669元 或许是WP平台最后一款新机Wileyfox Pro接受预订

在微软官方已经宣布放弃Windows手机业务,今后不再推任何新硬件的大背景下,今年9月在柏林召开的IFA大展上依然有一家手机厂商愿意为微软站台,这就是来自英国的Wileyfox。在IFA大展上,该公司...

稿源: ⋅ 2017/11/22 ⋅ 0

一家德国公司痴心不改 发起Windows Phone新产品众筹活动

尽管Windows手机在微软的视野中已经没有地位,这家软件巨头承认没有计划推出新功能和硬件,但仍有一些公司认为这个平台有机会取得成功,其中之一就是德国的Trekstor公司,他们希望推出一款新...

稿源: ⋅ 2017/11/20 ⋅ 0

360手机N7新品发布 主打长续航连续吃鸡可达6.5小时

  5月8日消息,360手机今天正式推出新品360手机N7。该款新品主打5080毫安时长续航,配备高通660处理器。360手机N7售价1699元,6+64G存储起步,首批现货于5月8日16:00点在360商城、京东正式...

人工智能那点事 ⋅ 05/08 ⋅ 0

抢OPPO和vivo市场 三星在国内发布两款中端机型

  虽然在全球市场仍是领头羊,不过在中国市场节节败退的三星,似乎扔不放弃。在本月初,三星在国内发布两款中端机型三星A9 star,A9 star Lite,售价1999起。而这个价位,正式OPPO和vivo的主...

人工智能那点事 ⋅ 06/10 ⋅ 0

母亲节送妈妈这三款手机是最满分的心意!

一年一度的母亲节本周末来临,作为一名孝顺的子女肯定要表达一番心意的。很多的小伙伴对于母亲节礼物的挑选也是一头雾水,那么不妨送她一部新手机也是一个不错的选择。 对此,母亲节送哪些手...

明美无限 ⋅ 05/10 ⋅ 0

Android 前置摄像头调试纪要

最近在调试Android 2.3.5(基于cm的代码)的前置摄像头,将遇到的问题与解决的方法记录下来,以便回顾。 1:)上层应用无法获取前置摄像头的信息? 前置摄像头的消息一般回存在与HAL层中,例...

魏伦 ⋅ 2011/12/15 ⋅ 1

除了大牌旗舰,MWC上还有这些更值得我们期待

科技你好 关注我们·成为科技潮人 随着MWC的临近,各类的爆料、推荐也是层出不穷。昨天技哥为大家介绍了一下三星、小米和索尼的旗舰机,今天咱们去看看另一些性能强劲,但不怎么暴露在闪光灯...

m7720eiosi6oa9 ⋅ 02/23 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

开启远程SSH

SSH默认没有开启账号密码登陆,需要再配置表中修改: vim /etc/ssh/sshd_configPermitRootLogin yes #是否可以使用root账户登陆PasswordAuthentication yes #是都开启密码登陆ser...

Kefy ⋅ 31分钟前 ⋅ 0

Zookeeper3.4.11+Hadoop2.7.6+Hbase2.0.0搭建分布式集群

有段时间没更新博客了,趁着最近有点时间,来完成之前关于集群部署方面的知识。今天主要讲一讲Zookeeper+Hadoop+Hbase分布式集群的搭建,在我前几篇的集群搭建的博客中已经分别讲过了Zookeep...

海岸线的曙光 ⋅ 38分钟前 ⋅ 0

js保留两位小数方法总结

本文是小编针对js保留两位小数这个大家经常遇到的经典问题整理了在各种情况下的函数写法以及遇到问题的分析,以下是全部内容: 一、我们首先从经典的“四舍五入”算法讲起 1、四舍五入的情况...

孟飞阳 ⋅ 56分钟前 ⋅ 0

python log

python log 处理方式 log_demo.py: 日志代码。 #! /usr/bin/env python# -*- coding: utf-8 -*-# __author__ = "Q1mi""""logging配置"""import osimport logging.config# 定义三种......

inidcard ⋅ 今天 ⋅ 0

mysql 中的信息数据库以及 shell 查询 sql

Information_schema 是 MySQL 自带的信息数据库,里面的“表”保存着服务器当前的实时信息。它提供了访问数据库元数据的方式。 什么是元数据呢?元数据是关于数据的数据,如数据库名或表名,...

blackfoxya ⋅ 今天 ⋅ 0

maven配置阿里云镜像享受飞的感觉

1.在maven目录下的conf/setting.xml中找到mirrors添加如下内容,对所有使用改maven打包的项目生效。 <mirror> <id>alimaven</id> <name>aliyun maven</name> <url>http://maven.al......

kalnkaya ⋅ 今天 ⋅ 0

centos7下创建新用户并授权

1、创建新用户 创建一个用户名为:test adduser test 创建初始密码: passwd test 2、授予root权限 个人用户的权限只可以在/home/test下有完整权限,其他目录要看别人授权。而经常需要roo...

xixingzhe ⋅ 今天 ⋅ 0

求助:TiledMap如何旋转对象呢?

比如我要旋转一个梯子的角度,单纯在TiledMap旋转角度好像没有效果。那是要用代码来控制角度,还是说只能通过导入相对应的斜的图片才可以呢?

花谢自相惜 ⋅ 今天 ⋅ 0

Micronaut 之HelloWorld!

小试一下Micronaut,按照官方文档跑了一下helloworld 第一步克隆,按照官方文档是: git clone git@github.com:micronaut-projects/micronaut-core.git 结果怎么是这样?? 换个方法吧 git ...

桂哥 ⋅ 今天 ⋅ 0

pom文件

Aeroever ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部