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

包含寄存器地址和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;
}

 

转载于:https://my.oschina.net/u/592470/blog/893109

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值