andorid 4.2 mt6582 添加2路 I2C 分别支持前后camera方法

#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);
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值