#include <linux/videodev2.h>
#include <linux/i2c.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/cdev.h>
#include <linux/uaccess.h>
#include <linux/fs.h>
#include <asm/atomic.h>
#include <linux/proc_fs.h> //proc file use
#include <linux/dma-mapping.h>
#include <linux/xlog.h>
#include "../camera/kd_camera_hw.h"
#include <asm/system.h>
#include <mach/mt_clkmgr.h>
#include "kd_imgsensor.h"
#include "kd_imgsensor_define.h"
#include "kd_camera_feature.h"
#include "kd_imgsensor_errcode.h"
#include "kd_sensorlist.h"
static DEFINE_SPINLOCK(kdsensor_drv_lock);
#define SUPPORT_I2C_BUS_NUM1 1
#define SUPPORT_I2C_BUS_NUM2 2
#define CAMERA_HW_DRVNAME1 "kd_camera_hw"
#define CAMERA_HW_DRVNAME2 "kd_camera_hw_bus2"
static struct i2c_board_info __initdata i2c_devs1={I2C_BOARD_INFO(CAMERA_HW_DRVNAME1, 0xfe>>1)};
static struct i2c_board_info __initdata i2c_devs2={I2C_BOARD_INFO(CAMERA_HW_DRVNAME2, 0xfe>>1)};
/******************************************************************************
* Debug configuration
******************************************************************************/
#define PFX "[kd_sensorlist]"
#define PK_DBG_NONE(fmt, arg...) do {} while (0)
#define PK_DBG_FUNC(fmt, arg...) xlog_printk(ANDROID_LOG_INFO , PFX, fmt, ##arg)
#define DEBUG_CAMERA_HW_K
#ifdef DEBUG_CAMERA_HW_K
#define PK_DBG PK_DBG_FUNC
#define PK_ERR(fmt, arg...) xlog_printk(ANDROID_LOG_DEBUG , PFX , fmt, ##arg)
#define PK_XLOG_INFO(fmt, args...) \
do { \
xlog_printk(ANDROID_LOG_DEBUG, PFX, fmt, ##args); \
} while(0)
#else
#define PK_DBG(a,...)
#define PK_ERR(a,...)
#define PK_XLOG_INFO(a...)
#endif
/*******************************************************************************
* Proifling
********************************************************************************/
#define PROFILE 1
#if PROFILE
static struct timeval tv1, tv2;
/*******************************************************************************
*
********************************************************************************/
inline void KD_IMGSENSOR_PROFILE_INIT(void)
{
do_gettimeofday(&tv1);
}
/*******************************************************************************
*
********************************************************************************/
inline void KD_IMGSENSOR_PROFILE(char *tag)
{
unsigned long TimeIntervalUS;
spin_lock(&kdsensor_drv_lock);
do_gettimeofday(&tv2);
TimeIntervalUS = (tv2.tv_sec - tv1.tv_sec) * 1000000 + (tv2.tv_usec - tv1.tv_usec);
tv1 = tv2;
spin_unlock(&kdsensor_drv_lock);
PK_DBG("[%s]Profile = %lu\n",tag, TimeIntervalUS);
}
#else
inline static void KD_IMGSENSOR_PROFILE_INIT() {}
inline static void KD_IMGSENSOR_PROFILE(char *tag) {}
#endif
/*******************************************************************************
*
********************************************************************************/
extern int kdCISModulePowerOn(CAMERA_DUAL_CAMERA_SENSOR_ENUM SensorIdx, char *currSensorName,BOOL On, char* mode_name);
extern ssize_t strobe_VDIrq(void); //cotta : add for high current solution
/*******************************************************************************
*
********************************************************************************/
static struct i2c_client * g_pstI2Cclient = NULL;
static struct i2c_client * g_pstI2Cclient2= NULL;
//81 is used for V4L driver
static dev_t g_CAMERA_HWdevno = MKDEV(250,0);
static dev_t g_CAMERA_HWdevno2;
static struct cdev * g_pCAMERA_HW_CharDrv = NULL;
static struct cdev * g_pCAMERA_HW_CharDrv2 = NULL;
static struct class *sensor_class = NULL;
static struct class *sensor2_class = NULL;
static atomic_t g_CamHWOpend;
static atomic_t g_CamHWOpend2;
static atomic_t g_CamHWOpening;
static atomic_t g_CamDrvOpenCnt;
static atomic_t g_CamDrvOpenCnt2;
static u32 gCurrI2CBusEnableFlag = 0;
static u32 gI2CBusNum=SUPPORT_I2C_BUS_NUM1;
#define SET_I2CBUS_FLAG(_x_) ((1<<_x_)|(gCurrI2CBusEnableFlag))
#define CLEAN_I2CBUS_FLAG(_x_) ((~(1<<_x_))&(gCurrI2CBusEnableFlag))
static DEFINE_MUTEX(kdCam_Mutex);
static BOOL bSesnorVsyncFlag = FALSE;
static ACDK_KD_SENSOR_SYNC_STRUCT g_NewSensorExpGain = {128, 128, 128, 128, 1000, 640, 0xFF, 0xFF, 0xFF, 0};
extern MULTI_SENSOR_FUNCTION_STRUCT kd_MultiSensorFunc;
static MULTI_SENSOR_FUNCTION_STRUCT *g_pSensorFunc = &kd_MultiSensorFunc;;
static SENSOR_FUNCTION_STRUCT *g_pInvokeSensorFunc[KDIMGSENSOR_MAX_INVOKE_DRIVERS] = {NULL,NULL};
static BOOL g_bEnableDriver[KDIMGSENSOR_MAX_INVOKE_DRIVERS] = {FALSE,FALSE};
static CAMERA_DUAL_CAMERA_SENSOR_ENUM g_invokeSocketIdx[KDIMGSENSOR_MAX_INVOKE_DRIVERS] = {DUAL_CAMERA_NONE_SENSOR,DUAL_CAMERA_NONE_SENSOR};
static char g_invokeSensorNameStr[KDIMGSENSOR_MAX_INVOKE_DRIVERS][32] = {KDIMGSENSOR_NOSENSOR,KDIMGSENSOR_NOSENSOR};
static wait_queue_head_t kd_sensor_wait_queue;
bool setExpGainDoneFlag = 0;
static CAMERA_DUAL_CAMERA_SENSOR_ENUM g_CurrentInvokeCam = DUAL_CAMERA_NONE_SENSOR;
/*=============================================================================
=============================================================================*/
/*******************************************************************************
* i2c relative start
* migrate new style i2c driver interfaces required by Kirby 20100827
********************************************************************************/
static const struct i2c_device_id CAMERA_HW_i2c_id[] = { {CAMERA_HW_DRVNAME1,0},{}};
static const struct i2c_device_id CAMERA_HW_i2c_id2[] = { {CAMERA_HW_DRVNAME2,0},{}}; //add chenlijun 20170727
/*******************************************************************************
* general camera image sensor kernel driver
*******************************************************************************/
UINT32 kdGetSensorInitFuncList(ACDK_KD_SENSOR_INIT_FUNCTION_STRUCT **ppSensorList)
{
if (NULL == ppSensorList)
{
PK_DBG("[kdGetSensorInitFuncList]ERROR: NULL ppSensorList\n");
return 1;
}
*ppSensorList = &kdSensorList[0];
return 0;
} // kdGetSensorInitFuncList()
/*******************************************************************************
*
********************************************************************************/
/*******************************************************************************
* iReadReg
********************************************************************************/
int iReadReg(u16 a_u2Addr , u8 * a_puBuff , u16 i2cId)
{
int i4RetValue = 0;
char puReadCmd[2] = {(char)(a_u2Addr >> 8) , (char)(a_u2Addr & 0xFF)};
spin_lock(&kdsensor_drv_lock);
g_pstI2Cclient->addr = (i2cId >> 1);
g_pstI2Cclient->ext_flag = (g_pstI2Cclient->ext_flag)&(~I2C_DMA_FLAG);
spin_unlock(&kdsensor_drv_lock);
//
i4RetValue = i2c_master_send(g_pstI2Cclient, puReadCmd, 2);
if (i4RetValue != 2) {
PK_DBG("[CAMERA SENSOR] I2C send failed, addr = 0x%x, data = 0x%x !! \n", a_u2Addr, *a_puBuff );
return -1;
}
//
i4RetValue = i2c_master_recv(g_pstI2Cclient, (char *)a_puBuff, 1);
if (i4RetValue != 1) {
PK_DBG("[CAMERA SENSOR] I2C read failed!! \n");
return -1;
}
return 0;
}
/*******************************************************************************
* iReadRegI2C
********************************************************************************/
int iReadRegI2C(u8 *a_pSendData , u16 a_sizeSendData, u8 * a_pRecvData, u16 a_sizeRecvData, u16 i2cId)
{
int i4RetValue = 0;
spin_lock(&kdsensor_drv_lock);
g_pstI2Cclient2->addr = (i2cId >> 1);
g_pstI2Cclient2->ext_flag = (g_pstI2Cclient2->ext_flag)&(~I2C_DMA_FLAG);
spin_unlock(&kdsensor_drv_lock);
//
i4RetValue = i2c_master_send(g_pstI2Cclient2, a_pSendData, a_sizeSendData);
if (i4RetValue != a_sizeSendData) {
PK_DBG("[CAMERA SENSOR] I2C send failed!!, Addr = 0x%x\n", a_pSendData[0]);
return -1;
}
i4RetValue = i2c_master_recv(g_pstI2Cclient2, (char *)a_pRecvData, a_sizeRecvData);
if (i4RetValue != a_sizeRecvData) {
PK_DBG("[CAMERA SENSOR] I2C read failed!! \n");
return -1;
}
return 0;
}
/*******************************************************************************
* iWriteReg
********************************************************************************/
int iWriteReg(u16 a_u2Addr , u32 a_u4Data , u32 a_u4Bytes , u16 i2cId)
{
int i4RetValue = 0;
int u4Index = 0;
u8 * puDataInBytes = (u8 *)&a_u4Data;
int retry = 3;
char puSendCmd[6] = {(char)(a_u2Addr >> 8) , (char)(a_u2Addr & 0xFF) ,
0 , 0 , 0 , 0};
PK_DBG("Addr : 0x%x,Val : 0x%x \n",a_u2Addr,a_u4Data);
//KD_IMGSENSOR_PROFILE_INIT();
spin_lock(&kdsensor_drv_lock);
g_pstI2Cclient->addr = (i2cId >> 1);
g_pstI2Cclient->ext_flag = (g_pstI2Cclient->ext_flag)&(~I2C_DMA_FLAG);
spin_unlock(&kdsensor_drv_lock);
if(a_u4Bytes > 2)
{
PK_DBG("[CAMERA SENSOR] exceed 2 bytes \n");
return -1;
}
if(a_u4Data >> (a_u4Bytes << 3))
{
PK_DBG("[CAMERA SENSOR] warning!! some data is not sent!! \n");
}
for(u4Index = 0 ; u4Index < a_u4Bytes ; u4Index += 1 )
{
puSendCmd[(u4Index + 2)] = puDataInBytes[(a_u4Bytes - u4Index-1)];
}
//
do {
i4RetValue = i2c_master_send(g_pstI2Cclient, puSendCmd, (a_u4Bytes + 2));
if (i4RetValue != (a_u4Bytes + 2)) {
PK_DBG("[CAMERA SENSOR] I2C send failed addr = 0x%x, data = 0x%x !! \n", a_u2Addr, a_u4Data);
}
else {
break;
}
uDELAY(50);
} while ((retry --) > 0);
//KD_IMGSENSOR_PROFILE("iWriteReg");
return 0;
}
/*******************************************************************************
* iBurstWriteReg
********************************************************************************/
#define MAX_CMD_LEN 255
int iBurstWriteReg(u8 *pData, u32 bytes, u16 i2cId)
{
u32 phyAddr = 0;
u8 *buf = NULL;
u32 old_addr = 0;
int ret = 0;
int retry = 0;
//if(gI2CBusNum == SUPPORT_I2C_BUS_NUM1)
{
if (bytes > MAX_CMD_LEN) {
PK_DBG("[iBurstWriteReg] exceed the max write length \n");
return 1;
}
phyAddr = 0;
buf = dma_alloc_coherent(0, bytes, &phyAddr, GFP_KERNEL);
if (NULL == buf) {
PK_DBG("[iBurstWriteReg] Not enough memory \n");
return -1;
}
memcpy(buf, pData, bytes);
//PK_DBG("[iBurstWriteReg] bytes = %d, phy addr = 0x%x \n", bytes, phyAddr );
old_addr = g_pstI2Cclient->addr;
spin_lock(&kdsensor_drv_lock);
g_pstI2Cclient->addr = ( ((g_pstI2Cclient->addr >> 1) & I2C_MASK_FLAG) | I2C_DMA_FLAG );
spin_unlock(&kdsensor_drv_lock);
ret = 0;
retry = 3;
do {
ret = i2c_master_send(g_pstI2Cclient, (u8*)phyAddr, bytes);
retry --;
if (ret != bytes) {
PK_DBG("Error sent I2C ret = %d\n", ret);
}
}while ((ret != bytes) && (retry > 0));
dma_free_coherent(0, bytes, buf, phyAddr);
spin_lock(&kdsensor_drv_lock);
g_pstI2Cclient->addr = old_addr;
spin_unlock(&kdsensor_drv_lock);
}
/*else{
if (bytes > MAX_CMD_LEN) {
PK_DBG("[iBurstWriteReg] exceed the max write length \n");
return 1;
}
phyAddr = 0;
buf = dma_alloc_coherent(0, bytes, &phyAddr, GFP_KERNEL);
if (NULL == buf) {
PK_DBG("[iBurstWriteReg] Not enough memory \n");
return -1;
}
memcpy(buf, pData, bytes);
//PK_DBG("[iBurstWriteReg] bytes = %d, phy addr = 0x%x \n", bytes, phyAddr );
old_addr = g_pstI2Cclient2->addr;
spin_lock(&kdsensor_drv_lock);
g_pstI2Cclient2->addr = ( ((g_pstI2Cclient2->addr >> 1) & I2C_MASK_FLAG) | I2C_DMA_FLAG );
spin_unlock(&kdsensor_drv_lock);
ret = 0;
retry = 3;
do {
ret = i2c_master_send(g_pstI2Cclient2, (u8*)phyAddr, bytes);
retry --;
if (ret != bytes) {
PK_DBG("Error sent I2C ret = %d\n", ret);
}
}while ((ret != bytes) && (retry > 0));
dma_free_coherent(0, bytes, buf, phyAddr);
spin_lock(&kdsensor_drv_lock);
g_pstI2Cclient2->addr = old_addr;
spin_unlock(&kdsensor_drv_lock);
}*/
return 0;
}
/*******************************************************************************
* iMultiWriteReg
********************************************************************************/
int iMultiWriteReg(u8 *pData, u16 lens, u16 i2cId)
{
int ret = 0;
g_pstI2Cclient->addr =(i2cId >> 1);
g_pstI2Cclient->ext_flag = (g_pstI2Cclient->ext_flag)|(I2C_DMA_FLAG) ;
ret = i2c_master_send(g_pstI2Cclient, pData, lens);
if(ret != lens) {
PK_DBG("Error sent I2C ret = %d\n", ret);
}
return 0;
}
/*******************************************************************************
* iWriteRegI2C
********************************************************************************/
int iWriteRegI2C(u8 *a_pSendData , u16 a_sizeSendData, u16 i2cId)
{
int i4RetValue = 0;
int retry = 3;
PK_DBG("Addr : 0x%x,Val : 0x%x \n",a_u2Addr,a_u4Data);
KD_IMGSENSOR_PROFILE_INIT();
spin_lock(&kdsensor_drv_lock);
g_pstI2Cclient2->addr = (i2cId >> 1);
g_pstI2Cclient2->ext_flag = (g_pstI2Cclient2->ext_flag)&(~I2C_DMA_FLAG);
spin_unlock(&kdsensor_drv_lock);
//
do {
i4RetValue = i2c_master_send(g_pstI2Cclient2, a_pSendData, a_sizeSendData);
if (i4RetValue != a_sizeSendData) {
PK_DBG("[CAMERA SENSOR] I2C send failed!!, Addr = 0x%x, Data = 0x%x \n", a_pSendData[0], a_pSendData[1] );
}
else {
break;
}
uDELAY(50);
} while ((retry--) > 0);
KD_IMGSENSOR_PROFILE("iWriteRegI2C");
return 0;
}
/*******************************************************************************
* sensor function adapter
********************************************************************************/
#define KD_MULTI_FUNCTION_ENTRY() //PK_XLOG_INFO("[%s]:E \n",__FUNCTION__)
#define KD_MULTI_FUNCTION_EXIT() //PK_XLOG_INFO("[%s]:X \n",__FUNCTION__)
//
MUINT32
kdSetI2CSlaveID(MINT32 i, MUINT32 socketIdx,MUINT32 firstSet) {
MUINT32 u4FeaturePara[4];
MUINT32 FeatureParaLen = 0;
u4FeaturePara[0] = socketIdx;
u4FeaturePara[1] = firstSet;
FeatureParaLen = sizeof(MUINT32)*2;
return g_pInvokeSensorFunc[i]->SensorFeatureControl(SENSOR_FEATURE_SET_SLAVE_I2C_ID,(MUINT8*)u4FeaturePara,(MUINT32*)&FeatureParaLen);
}
//
MUINT32
kd_MultiSensorOpen ( void )
{
MUINT32 ret = ERROR_NONE;
MINT32 i = 0;
KD_MULTI_FUNCTION_ENTRY();
//from hear to tail
//for ( i = KDIMGSENSOR_INVOKE_DRIVER_0 ; i < KDIMGSENSOR_MAX_INVOKE_DRIVERS ; i++ ) {
//from tail to head.
for ( i = (KDIMGSENSOR_MAX_INVOKE_DRIVERS-1) ; i >= KDIMGSENSOR_INVOKE_DRIVER_0 ; i-- ) {
if ( g_bEnableDriver[i] && g_pInvokeSensorFunc[i] ) {
// turn on power
ret = kdCISModulePowerOn((CAMERA_DUAL_CAMERA_SENSOR_ENUM)g_invokeSocketIdx[i],(char*)g_invokeSensorNameStr[i],true,CAMERA_HW_DRVNAME1);
if ( ERROR_NONE != ret ) {
PK_ERR("[%s]",__FUNCTION__);
return ret;
}
//wait for power stable
mDELAY(10);
KD_IMGSENSOR_PROFILE("kdModulePowerOn");
/*if( DUAL_CAMERA_MAIN_2_SENSOR == g_invokeSocketIdx[i] ) {
spin_lock(&kdsensor_drv_lock);
gI2CBusNum = SUPPORT_I2C_BUS_NUM2;
spin_unlock(&kdsensor_drv_lock);
#include <linux/i2c.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/cdev.h>
#include <linux/uaccess.h>
#include <linux/fs.h>
#include <asm/atomic.h>
#include <linux/proc_fs.h> //proc file use
#include <linux/dma-mapping.h>
#include <linux/xlog.h>
#include "../camera/kd_camera_hw.h"
#include <asm/system.h>
#include <mach/mt_clkmgr.h>
#include "kd_imgsensor.h"
#include "kd_imgsensor_define.h"
#include "kd_camera_feature.h"
#include "kd_imgsensor_errcode.h"
#include "kd_sensorlist.h"
static DEFINE_SPINLOCK(kdsensor_drv_lock);
#define SUPPORT_I2C_BUS_NUM1 1
#define SUPPORT_I2C_BUS_NUM2 2
#define CAMERA_HW_DRVNAME1 "kd_camera_hw"
#define CAMERA_HW_DRVNAME2 "kd_camera_hw_bus2"
static struct i2c_board_info __initdata i2c_devs1={I2C_BOARD_INFO(CAMERA_HW_DRVNAME1, 0xfe>>1)};
static struct i2c_board_info __initdata i2c_devs2={I2C_BOARD_INFO(CAMERA_HW_DRVNAME2, 0xfe>>1)};
/******************************************************************************
* Debug configuration
******************************************************************************/
#define PFX "[kd_sensorlist]"
#define PK_DBG_NONE(fmt, arg...) do {} while (0)
#define PK_DBG_FUNC(fmt, arg...) xlog_printk(ANDROID_LOG_INFO , PFX, fmt, ##arg)
#define DEBUG_CAMERA_HW_K
#ifdef DEBUG_CAMERA_HW_K
#define PK_DBG PK_DBG_FUNC
#define PK_ERR(fmt, arg...) xlog_printk(ANDROID_LOG_DEBUG , PFX , fmt, ##arg)
#define PK_XLOG_INFO(fmt, args...) \
do { \
xlog_printk(ANDROID_LOG_DEBUG, PFX, fmt, ##args); \
} while(0)
#else
#define PK_DBG(a,...)
#define PK_ERR(a,...)
#define PK_XLOG_INFO(a...)
#endif
/*******************************************************************************
* Proifling
********************************************************************************/
#define PROFILE 1
#if PROFILE
static struct timeval tv1, tv2;
/*******************************************************************************
*
********************************************************************************/
inline void KD_IMGSENSOR_PROFILE_INIT(void)
{
do_gettimeofday(&tv1);
}
/*******************************************************************************
*
********************************************************************************/
inline void KD_IMGSENSOR_PROFILE(char *tag)
{
unsigned long TimeIntervalUS;
spin_lock(&kdsensor_drv_lock);
do_gettimeofday(&tv2);
TimeIntervalUS = (tv2.tv_sec - tv1.tv_sec) * 1000000 + (tv2.tv_usec - tv1.tv_usec);
tv1 = tv2;
spin_unlock(&kdsensor_drv_lock);
PK_DBG("[%s]Profile = %lu\n",tag, TimeIntervalUS);
}
#else
inline static void KD_IMGSENSOR_PROFILE_INIT() {}
inline static void KD_IMGSENSOR_PROFILE(char *tag) {}
#endif
/*******************************************************************************
*
********************************************************************************/
extern int kdCISModulePowerOn(CAMERA_DUAL_CAMERA_SENSOR_ENUM SensorIdx, char *currSensorName,BOOL On, char* mode_name);
extern ssize_t strobe_VDIrq(void); //cotta : add for high current solution
/*******************************************************************************
*
********************************************************************************/
static struct i2c_client * g_pstI2Cclient = NULL;
static struct i2c_client * g_pstI2Cclient2= NULL;
//81 is used for V4L driver
static dev_t g_CAMERA_HWdevno = MKDEV(250,0);
static dev_t g_CAMERA_HWdevno2;
static struct cdev * g_pCAMERA_HW_CharDrv = NULL;
static struct cdev * g_pCAMERA_HW_CharDrv2 = NULL;
static struct class *sensor_class = NULL;
static struct class *sensor2_class = NULL;
static atomic_t g_CamHWOpend;
static atomic_t g_CamHWOpend2;
static atomic_t g_CamHWOpening;
static atomic_t g_CamDrvOpenCnt;
static atomic_t g_CamDrvOpenCnt2;
static u32 gCurrI2CBusEnableFlag = 0;
static u32 gI2CBusNum=SUPPORT_I2C_BUS_NUM1;
#define SET_I2CBUS_FLAG(_x_) ((1<<_x_)|(gCurrI2CBusEnableFlag))
#define CLEAN_I2CBUS_FLAG(_x_) ((~(1<<_x_))&(gCurrI2CBusEnableFlag))
static DEFINE_MUTEX(kdCam_Mutex);
static BOOL bSesnorVsyncFlag = FALSE;
static ACDK_KD_SENSOR_SYNC_STRUCT g_NewSensorExpGain = {128, 128, 128, 128, 1000, 640, 0xFF, 0xFF, 0xFF, 0};
extern MULTI_SENSOR_FUNCTION_STRUCT kd_MultiSensorFunc;
static MULTI_SENSOR_FUNCTION_STRUCT *g_pSensorFunc = &kd_MultiSensorFunc;;
static SENSOR_FUNCTION_STRUCT *g_pInvokeSensorFunc[KDIMGSENSOR_MAX_INVOKE_DRIVERS] = {NULL,NULL};
static BOOL g_bEnableDriver[KDIMGSENSOR_MAX_INVOKE_DRIVERS] = {FALSE,FALSE};
static CAMERA_DUAL_CAMERA_SENSOR_ENUM g_invokeSocketIdx[KDIMGSENSOR_MAX_INVOKE_DRIVERS] = {DUAL_CAMERA_NONE_SENSOR,DUAL_CAMERA_NONE_SENSOR};
static char g_invokeSensorNameStr[KDIMGSENSOR_MAX_INVOKE_DRIVERS][32] = {KDIMGSENSOR_NOSENSOR,KDIMGSENSOR_NOSENSOR};
static wait_queue_head_t kd_sensor_wait_queue;
bool setExpGainDoneFlag = 0;
static CAMERA_DUAL_CAMERA_SENSOR_ENUM g_CurrentInvokeCam = DUAL_CAMERA_NONE_SENSOR;
/*=============================================================================
=============================================================================*/
/*******************************************************************************
* i2c relative start
* migrate new style i2c driver interfaces required by Kirby 20100827
********************************************************************************/
static const struct i2c_device_id CAMERA_HW_i2c_id[] = { {CAMERA_HW_DRVNAME1,0},{}};
static const struct i2c_device_id CAMERA_HW_i2c_id2[] = { {CAMERA_HW_DRVNAME2,0},{}}; //add chenlijun 20170727
/*******************************************************************************
* general camera image sensor kernel driver
*******************************************************************************/
UINT32 kdGetSensorInitFuncList(ACDK_KD_SENSOR_INIT_FUNCTION_STRUCT **ppSensorList)
{
if (NULL == ppSensorList)
{
PK_DBG("[kdGetSensorInitFuncList]ERROR: NULL ppSensorList\n");
return 1;
}
*ppSensorList = &kdSensorList[0];
return 0;
} // kdGetSensorInitFuncList()
/*******************************************************************************
*
********************************************************************************/
/*******************************************************************************
* iReadReg
********************************************************************************/
int iReadReg(u16 a_u2Addr , u8 * a_puBuff , u16 i2cId)
{
int i4RetValue = 0;
char puReadCmd[2] = {(char)(a_u2Addr >> 8) , (char)(a_u2Addr & 0xFF)};
spin_lock(&kdsensor_drv_lock);
g_pstI2Cclient->addr = (i2cId >> 1);
g_pstI2Cclient->ext_flag = (g_pstI2Cclient->ext_flag)&(~I2C_DMA_FLAG);
spin_unlock(&kdsensor_drv_lock);
//
i4RetValue = i2c_master_send(g_pstI2Cclient, puReadCmd, 2);
if (i4RetValue != 2) {
PK_DBG("[CAMERA SENSOR] I2C send failed, addr = 0x%x, data = 0x%x !! \n", a_u2Addr, *a_puBuff );
return -1;
}
//
i4RetValue = i2c_master_recv(g_pstI2Cclient, (char *)a_puBuff, 1);
if (i4RetValue != 1) {
PK_DBG("[CAMERA SENSOR] I2C read failed!! \n");
return -1;
}
return 0;
}
/*******************************************************************************
* iReadRegI2C
********************************************************************************/
int iReadRegI2C(u8 *a_pSendData , u16 a_sizeSendData, u8 * a_pRecvData, u16 a_sizeRecvData, u16 i2cId)
{
int i4RetValue = 0;
spin_lock(&kdsensor_drv_lock);
g_pstI2Cclient2->addr = (i2cId >> 1);
g_pstI2Cclient2->ext_flag = (g_pstI2Cclient2->ext_flag)&(~I2C_DMA_FLAG);
spin_unlock(&kdsensor_drv_lock);
//
i4RetValue = i2c_master_send(g_pstI2Cclient2, a_pSendData, a_sizeSendData);
if (i4RetValue != a_sizeSendData) {
PK_DBG("[CAMERA SENSOR] I2C send failed!!, Addr = 0x%x\n", a_pSendData[0]);
return -1;
}
i4RetValue = i2c_master_recv(g_pstI2Cclient2, (char *)a_pRecvData, a_sizeRecvData);
if (i4RetValue != a_sizeRecvData) {
PK_DBG("[CAMERA SENSOR] I2C read failed!! \n");
return -1;
}
return 0;
}
/*******************************************************************************
* iWriteReg
********************************************************************************/
int iWriteReg(u16 a_u2Addr , u32 a_u4Data , u32 a_u4Bytes , u16 i2cId)
{
int i4RetValue = 0;
int u4Index = 0;
u8 * puDataInBytes = (u8 *)&a_u4Data;
int retry = 3;
char puSendCmd[6] = {(char)(a_u2Addr >> 8) , (char)(a_u2Addr & 0xFF) ,
0 , 0 , 0 , 0};
PK_DBG("Addr : 0x%x,Val : 0x%x \n",a_u2Addr,a_u4Data);
//KD_IMGSENSOR_PROFILE_INIT();
spin_lock(&kdsensor_drv_lock);
g_pstI2Cclient->addr = (i2cId >> 1);
g_pstI2Cclient->ext_flag = (g_pstI2Cclient->ext_flag)&(~I2C_DMA_FLAG);
spin_unlock(&kdsensor_drv_lock);
if(a_u4Bytes > 2)
{
PK_DBG("[CAMERA SENSOR] exceed 2 bytes \n");
return -1;
}
if(a_u4Data >> (a_u4Bytes << 3))
{
PK_DBG("[CAMERA SENSOR] warning!! some data is not sent!! \n");
}
for(u4Index = 0 ; u4Index < a_u4Bytes ; u4Index += 1 )
{
puSendCmd[(u4Index + 2)] = puDataInBytes[(a_u4Bytes - u4Index-1)];
}
//
do {
i4RetValue = i2c_master_send(g_pstI2Cclient, puSendCmd, (a_u4Bytes + 2));
if (i4RetValue != (a_u4Bytes + 2)) {
PK_DBG("[CAMERA SENSOR] I2C send failed addr = 0x%x, data = 0x%x !! \n", a_u2Addr, a_u4Data);
}
else {
break;
}
uDELAY(50);
} while ((retry --) > 0);
//KD_IMGSENSOR_PROFILE("iWriteReg");
return 0;
}
/*******************************************************************************
* iBurstWriteReg
********************************************************************************/
#define MAX_CMD_LEN 255
int iBurstWriteReg(u8 *pData, u32 bytes, u16 i2cId)
{
u32 phyAddr = 0;
u8 *buf = NULL;
u32 old_addr = 0;
int ret = 0;
int retry = 0;
//if(gI2CBusNum == SUPPORT_I2C_BUS_NUM1)
{
if (bytes > MAX_CMD_LEN) {
PK_DBG("[iBurstWriteReg] exceed the max write length \n");
return 1;
}
phyAddr = 0;
buf = dma_alloc_coherent(0, bytes, &phyAddr, GFP_KERNEL);
if (NULL == buf) {
PK_DBG("[iBurstWriteReg] Not enough memory \n");
return -1;
}
memcpy(buf, pData, bytes);
//PK_DBG("[iBurstWriteReg] bytes = %d, phy addr = 0x%x \n", bytes, phyAddr );
old_addr = g_pstI2Cclient->addr;
spin_lock(&kdsensor_drv_lock);
g_pstI2Cclient->addr = ( ((g_pstI2Cclient->addr >> 1) & I2C_MASK_FLAG) | I2C_DMA_FLAG );
spin_unlock(&kdsensor_drv_lock);
ret = 0;
retry = 3;
do {
ret = i2c_master_send(g_pstI2Cclient, (u8*)phyAddr, bytes);
retry --;
if (ret != bytes) {
PK_DBG("Error sent I2C ret = %d\n", ret);
}
}while ((ret != bytes) && (retry > 0));
dma_free_coherent(0, bytes, buf, phyAddr);
spin_lock(&kdsensor_drv_lock);
g_pstI2Cclient->addr = old_addr;
spin_unlock(&kdsensor_drv_lock);
}
/*else{
if (bytes > MAX_CMD_LEN) {
PK_DBG("[iBurstWriteReg] exceed the max write length \n");
return 1;
}
phyAddr = 0;
buf = dma_alloc_coherent(0, bytes, &phyAddr, GFP_KERNEL);
if (NULL == buf) {
PK_DBG("[iBurstWriteReg] Not enough memory \n");
return -1;
}
memcpy(buf, pData, bytes);
//PK_DBG("[iBurstWriteReg] bytes = %d, phy addr = 0x%x \n", bytes, phyAddr );
old_addr = g_pstI2Cclient2->addr;
spin_lock(&kdsensor_drv_lock);
g_pstI2Cclient2->addr = ( ((g_pstI2Cclient2->addr >> 1) & I2C_MASK_FLAG) | I2C_DMA_FLAG );
spin_unlock(&kdsensor_drv_lock);
ret = 0;
retry = 3;
do {
ret = i2c_master_send(g_pstI2Cclient2, (u8*)phyAddr, bytes);
retry --;
if (ret != bytes) {
PK_DBG("Error sent I2C ret = %d\n", ret);
}
}while ((ret != bytes) && (retry > 0));
dma_free_coherent(0, bytes, buf, phyAddr);
spin_lock(&kdsensor_drv_lock);
g_pstI2Cclient2->addr = old_addr;
spin_unlock(&kdsensor_drv_lock);
}*/
return 0;
}
/*******************************************************************************
* iMultiWriteReg
********************************************************************************/
int iMultiWriteReg(u8 *pData, u16 lens, u16 i2cId)
{
int ret = 0;
g_pstI2Cclient->addr =(i2cId >> 1);
g_pstI2Cclient->ext_flag = (g_pstI2Cclient->ext_flag)|(I2C_DMA_FLAG) ;
ret = i2c_master_send(g_pstI2Cclient, pData, lens);
if(ret != lens) {
PK_DBG("Error sent I2C ret = %d\n", ret);
}
return 0;
}
/*******************************************************************************
* iWriteRegI2C
********************************************************************************/
int iWriteRegI2C(u8 *a_pSendData , u16 a_sizeSendData, u16 i2cId)
{
int i4RetValue = 0;
int retry = 3;
PK_DBG("Addr : 0x%x,Val : 0x%x \n",a_u2Addr,a_u4Data);
KD_IMGSENSOR_PROFILE_INIT();
spin_lock(&kdsensor_drv_lock);
g_pstI2Cclient2->addr = (i2cId >> 1);
g_pstI2Cclient2->ext_flag = (g_pstI2Cclient2->ext_flag)&(~I2C_DMA_FLAG);
spin_unlock(&kdsensor_drv_lock);
//
do {
i4RetValue = i2c_master_send(g_pstI2Cclient2, a_pSendData, a_sizeSendData);
if (i4RetValue != a_sizeSendData) {
PK_DBG("[CAMERA SENSOR] I2C send failed!!, Addr = 0x%x, Data = 0x%x \n", a_pSendData[0], a_pSendData[1] );
}
else {
break;
}
uDELAY(50);
} while ((retry--) > 0);
KD_IMGSENSOR_PROFILE("iWriteRegI2C");
return 0;
}
/*******************************************************************************
* sensor function adapter
********************************************************************************/
#define KD_MULTI_FUNCTION_ENTRY() //PK_XLOG_INFO("[%s]:E \n",__FUNCTION__)
#define KD_MULTI_FUNCTION_EXIT() //PK_XLOG_INFO("[%s]:X \n",__FUNCTION__)
//
MUINT32
kdSetI2CSlaveID(MINT32 i, MUINT32 socketIdx,MUINT32 firstSet) {
MUINT32 u4FeaturePara[4];
MUINT32 FeatureParaLen = 0;
u4FeaturePara[0] = socketIdx;
u4FeaturePara[1] = firstSet;
FeatureParaLen = sizeof(MUINT32)*2;
return g_pInvokeSensorFunc[i]->SensorFeatureControl(SENSOR_FEATURE_SET_SLAVE_I2C_ID,(MUINT8*)u4FeaturePara,(MUINT32*)&FeatureParaLen);
}
//
MUINT32
kd_MultiSensorOpen ( void )
{
MUINT32 ret = ERROR_NONE;
MINT32 i = 0;
KD_MULTI_FUNCTION_ENTRY();
//from hear to tail
//for ( i = KDIMGSENSOR_INVOKE_DRIVER_0 ; i < KDIMGSENSOR_MAX_INVOKE_DRIVERS ; i++ ) {
//from tail to head.
for ( i = (KDIMGSENSOR_MAX_INVOKE_DRIVERS-1) ; i >= KDIMGSENSOR_INVOKE_DRIVER_0 ; i-- ) {
if ( g_bEnableDriver[i] && g_pInvokeSensorFunc[i] ) {
// turn on power
ret = kdCISModulePowerOn((CAMERA_DUAL_CAMERA_SENSOR_ENUM)g_invokeSocketIdx[i],(char*)g_invokeSensorNameStr[i],true,CAMERA_HW_DRVNAME1);
if ( ERROR_NONE != ret ) {
PK_ERR("[%s]",__FUNCTION__);
return ret;
}
//wait for power stable
mDELAY(10);
KD_IMGSENSOR_PROFILE("kdModulePowerOn");
/*if( DUAL_CAMERA_MAIN_2_SENSOR == g_invokeSocketIdx[i] ) {
spin_lock(&kdsensor_drv_lock);
gI2CBusNum = SUPPORT_I2C_BUS_NUM2;
spin_unlock(&kdsensor_drv_lock);