unplugged-kernel/drivers/misc/mediatek/lens/mtk/main/common/lc898212xdaf/LC898212XDAF.c

794 lines
21 KiB
C

// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2019 MediaTek Inc.
*/
/*
* LC898212XDAF voice coil motor driver
*
*
*/
#include <linux/delay.h>
#include <linux/fs.h>
#include <linux/i2c.h>
#include <linux/uaccess.h>
#include "lens_info.h"
#include "AfInit.h"
#include "AfSTMV.h"
#define AF_DRVNAME "LC898212XDAF_DRV"
#define AF_I2C_SLAVE_ADDR 0xE4
#define EEPROM_I2C_SLAVE_ADDR_OV23850 0xA8
#define EEPROM_I2C_SLAVE_ADDR_IMX258 0xA0
#define AF_DEBUG
#ifdef AF_DEBUG
#define LOG_INF(format, args...) \
pr_info(AF_DRVNAME " [%s] " format, __func__, ##args)
#else
#define LOG_INF(format, args...)
#endif
static struct i2c_client *g_pstAF_I2Cclient;
static int *g_pAF_Opened;
static spinlock_t *g_pAF_SpinLock;
static unsigned long g_u4AF_INF;
static unsigned long g_u4AF_MACRO = 1023;
static unsigned long g_u4CurrPosition;
static unsigned int g_SelectEEPROM;
unsigned int g_LC898212_SearchDir;
#define Min_Pos 0
#define Max_Pos 1023
/* LiteOn : Hall calibration range : 0xA800 - 0x5800 */
static signed short Hall_Max =
0x5800; /* Please read INF position from EEPROM or OTP */
static signed short Hall_Min =
0xA800; /* Please read MACRO position from EEPROM or OTP */
int s4AF_ReadReg_LC898212XDAF(u8 *a_pSendData, u16 a_sizeSendData,
u8 *a_pRecvData, u16 a_sizeRecvData, u16 i2cId)
{
int i4RetValue = 0;
g_pstAF_I2Cclient->addr = i2cId >> 1;
i4RetValue =
i2c_master_send(g_pstAF_I2Cclient, a_pSendData, a_sizeSendData);
if (i4RetValue != a_sizeSendData) {
LOG_INF("I2C send failed!!, Addr = 0x%x\n", a_pSendData[0]);
return -1;
}
i4RetValue = i2c_master_recv(g_pstAF_I2Cclient, (u8 *)a_pRecvData,
a_sizeRecvData);
if (i4RetValue != a_sizeRecvData) {
LOG_INF("I2C read failed!!\n");
return -1;
}
return 0;
}
int s4AF_WriteReg_LC898212XDAF(u8 *a_pSendData, u16 a_sizeSendData, u16 i2cId)
{
int i4RetValue = 0;
g_pstAF_I2Cclient->addr = i2cId >> 1;
i4RetValue =
i2c_master_send(g_pstAF_I2Cclient, a_pSendData, a_sizeSendData);
if (i4RetValue < 0) {
LOG_INF("I2C send failed!!, Addr = 0x%x, Data = 0x%x\n",
a_pSendData[0], a_pSendData[1]);
return -1;
}
return 0;
}
static int s4EEPROM_ReadReg_LC898212XDAF_OV23850(u16 addr, u8 *data)
{
int i4RetValue = 0;
u8 puSendCmd[2] = {(u8)(addr >> 8), (u8)(addr & 0xFF)};
i4RetValue =
s4AF_ReadReg_LC898212XDAF(puSendCmd, sizeof(puSendCmd), data, 1,
EEPROM_I2C_SLAVE_ADDR_OV23850);
if (i4RetValue < 0)
LOG_INF("I2C read e2prom failed!!\n");
return i4RetValue;
}
static int s4EEPROM_ReadReg_LC898212XDAF_IMX258(u16 addr, u8 *data)
{
int i4RetValue = 0;
u8 puSendCmd[2] = {(u8)(addr >> 8), (u8)(addr & 0xFF)};
i4RetValue =
s4AF_ReadReg_LC898212XDAF(puSendCmd, sizeof(puSendCmd), data, 1,
EEPROM_I2C_SLAVE_ADDR_IMX258);
if (i4RetValue < 0)
LOG_INF("I2C read e2prom failed!!\n");
return i4RetValue;
}
static void s4AF_WriteReg(unsigned short addr, unsigned char data)
{
u8 puSendCmd[2] = {(u8)(addr & 0xFF), (u8)(data & 0xFF)};
s4AF_WriteReg_LC898212XDAF(puSendCmd, sizeof(puSendCmd),
AF_I2C_SLAVE_ADDR);
}
static int convertAF_DAC(short ReadData)
{
int DacVal = ((ReadData - Hall_Min) * (Max_Pos - Min_Pos)) /
((unsigned short)(Hall_Max - Hall_Min)) +
Min_Pos;
return DacVal;
}
static void LC898212XD_init(void)
{
struct stSmvPar StSmvPar;
u8 val1 = 0, val2 = 0;
int Hall_Off = 0x80; /* Please Read Offset from EEPROM or OTP */
int Hall_Bias = 0x80; /* Please Read Bias from EEPROM or OTP */
unsigned short HallMinCheck = 0;
unsigned short HallMaxCheck = 0;
unsigned short HallCheck = 0;
g_SelectEEPROM = 1;
if (s4EEPROM_ReadReg_LC898212XDAF_OV23850(0x001A, &val1) < 0)
g_SelectEEPROM = 0;
g_LC898212_SearchDir = 1;
if (strcmp(CONFIG_ARCH_MTK_PROJECT, "k55v2_64_stereo") == 0) {
LOG_INF("CONFIG_ARCH_MTK_PROJECT = %s\n",
CONFIG_ARCH_MTK_PROJECT);
/* Ja Stereo IMX258 - Error Version */
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0016, &val1);
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0015, &val2);
HallMinCheck = ((val1 << 8) | (val2 & 0x00FF)) & 0xFFFF;
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0018, &val1);
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0017, &val2);
HallMaxCheck = ((val1 << 8) | (val2 & 0x00FF)) & 0xFFFF;
if ((HallMaxCheck >= 0x1FFF && HallMaxCheck <= 0x7FFF) &&
(HallMinCheck >= 0x8001 && HallMinCheck <= 0xEFFF)) {
Hall_Min = HallMinCheck;
Hall_Max = HallMaxCheck;
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x001A, &val1);
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0019, &val2);
Hall_Off = val2;
Hall_Bias = val1;
}
} else if (strncmp(CONFIG_ARCH_MTK_PROJECT, "demo97v1", 6) == 0) {
LOG_INF("CONFIG_ARCH_MTK_PROJECT = %s\n",
CONFIG_ARCH_MTK_PROJECT);
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0003, &val1);
LOG_INF("Addr = 0x0003 , Data = %x\n", val1);
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0004, &val2);
LOG_INF("Addr = 0x0004 , Data = %x\n", val2);
if (val1 == 0xb && val2 == 0x2) { /* EEPROM Version */
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0F33, &val2);
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0F34, &val1);
Hall_Min = ((val1 << 8) | (val2 & 0x00FF)) & 0xFFFF;
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0F35, &val2);
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0F36, &val1);
Hall_Max = ((val1 << 8) | (val2 & 0x00FF)) & 0xFFFF;
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0F37, &val1);
Hall_Off = val1;
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0F38, &val2);
Hall_Bias = val2;
} else {
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0F63, &val2);
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0F64, &val1);
HallMinCheck = ((val1 << 8) | (val2 & 0x00FF)) & 0xFFFF;
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0F65, &val2);
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0F66, &val1);
HallMaxCheck = ((val1 << 8) | (val2 & 0x00FF)) & 0xFFFF;
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0F67, &val1);
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0F68, &val2);
if ((val1 != 0) && (val2 != 0) &&
(HallMaxCheck >= 0x1FFF &&
HallMaxCheck <= 0x7FFF) &&
(HallMinCheck >= 0x8001 &&
HallMinCheck <= 0xEFFF)) {
Hall_Min = HallMinCheck;
Hall_Max = HallMaxCheck;
Hall_Off = val1;
Hall_Bias = val2;
} else {
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0F33,
&val2);
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0F34,
&val1);
HallMinCheck = ((val1 << 8) | (val2 & 0x00FF)) &
0xFFFF;
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0F35,
&val2);
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0F36,
&val1);
HallMaxCheck = ((val1 << 8) | (val2 & 0x00FF)) &
0xFFFF;
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0F37,
&val1);
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0F38,
&val2);
if ((val1 != 0) && (val2 != 0) &&
(HallMaxCheck >= 0x1FFF &&
HallMaxCheck <= 0x7FFF) &&
(HallMinCheck >= 0x8001 &&
HallMinCheck <= 0xEFFF)) {
Hall_Min = HallMinCheck;
Hall_Max = HallMaxCheck;
Hall_Off = val1;
Hall_Bias = val2;
}
}
}
} else if (strncmp(CONFIG_ARCH_MTK_PROJECT, "k97v1", 5) == 0 ||
strncmp(CONFIG_ARCH_MTK_PROJECT, "evb6797", 7) == 0 ||
strncmp(CONFIG_ARCH_MTK_PROJECT, "muse6797", 8) == 0) {
LOG_INF("CONFIG_ARCH_MTK_PROJECT = %s\n",
CONFIG_ARCH_MTK_PROJECT);
if (g_SelectEEPROM == 0) { /* IMX258 PDAF */
/* Li define format - Ev IMX258 PDAF - remove Koli */
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0F67, &val1);
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0F68, &val2);
HallMaxCheck = ((val1 << 8) | (val2 & 0x00FF)) & 0xFFFF;
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0F69, &val1);
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0F70, &val2);
HallMinCheck = ((val1 << 8) | (val2 & 0x00FF)) & 0xFFFF;
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0F63, &val1);
HallCheck = val1;
if ((HallCheck == 0) && (HallMaxCheck >= 0x1FFF &&
HallMaxCheck <= 0x7FFF) &&
(HallMinCheck >= 0x8001 &&
HallMinCheck <= 0xEFFF)) {
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0F63,
&val1);
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0F64,
&val2);
Hall_Bias = ((val1 << 8) | (val2 & 0x00FF)) &
0xFFFF;
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0F65,
&val1);
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0F66,
&val2);
Hall_Off = ((val1 << 8) | (val2 & 0x00FF)) &
0xFFFF;
Hall_Min = 0x8001; /* HallMinCheck; */
Hall_Max = 0x7FFF; /* HallMaxCheck; */
/* Li define format - Ev IMX258 PDAF - end */
} else {
/* Li define format - Ev MVHDR */
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0F33,
&val1);
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0F34,
&val2);
Hall_Min = ((val1 << 8) | (val2 & 0x00FF)) &
0xFFFF;
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0F35,
&val1);
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0F36,
&val2);
Hall_Max = ((val1 << 8) | (val2 & 0x00FF)) &
0xFFFF;
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0F37,
&val1);
Hall_Off = val1;
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0F38,
&val2);
Hall_Bias = val2;
g_LC898212_SearchDir = 0;
/* Li define format - Ev MVHDR end */
}
} else {
LOG_INF("Select ov23850 e2prom!!\n");
s4EEPROM_ReadReg_LC898212XDAF_OV23850(0x0F63, &val1);
s4EEPROM_ReadReg_LC898212XDAF_OV23850(0x0F64, &val2);
Hall_Bias = ((val1 << 8) | (val2 & 0x00FF)) & 0xFFFF;
s4EEPROM_ReadReg_LC898212XDAF_OV23850(0x0F65, &val1);
s4EEPROM_ReadReg_LC898212XDAF_OV23850(0x0F66, &val2);
Hall_Off = ((val1 << 8) | (val2 & 0x00FF)) & 0xFFFF;
s4EEPROM_ReadReg_LC898212XDAF_OV23850(0x0F67, &val1);
s4EEPROM_ReadReg_LC898212XDAF_OV23850(0x0F68, &val2);
Hall_Min = ((val1 << 8) | (val2 & 0x00FF)) & 0xFFFF;
s4EEPROM_ReadReg_LC898212XDAF_OV23850(0x0F69, &val1);
s4EEPROM_ReadReg_LC898212XDAF_OV23850(0x0F70, &val2);
Hall_Max = ((val1 << 8) | (val2 & 0x00FF)) & 0xFFFF;
g_LC898212_SearchDir = 0;
}
} else if (strncmp(CONFIG_ARCH_MTK_PROJECT, "k57v1", 5) == 0) {
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0F63, &val2);
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0F64, &val1);
HallMinCheck = ((val1 << 8) | (val2 & 0x00FF)) & 0xFFFF;
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0F65, &val2);
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0F66, &val1);
HallMaxCheck = ((val1 << 8) | (val2 & 0x00FF)) & 0xFFFF;
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0F67, &val1);
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0F68, &val2);
if ((val1 != 0) && (val2 != 0) &&
(HallMaxCheck >= 0x1FFF && HallMaxCheck <= 0x7FFF) &&
(HallMinCheck >= 0x8001 && HallMinCheck <= 0xEFFF)) {
Hall_Min = HallMinCheck;
Hall_Max = HallMaxCheck;
Hall_Off = val1;
Hall_Bias = val2;
} else {
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0CC1, &val2);
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0CC2, &val1);
HallMinCheck = ((val1 << 8) | (val2 & 0x00FF)) & 0xFFFF;
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0CC3, &val2);
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0CC4, &val1);
HallMaxCheck = ((val1 << 8) | (val2 & 0x00FF)) & 0xFFFF;
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0CC5, &val1);
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0CC6, &val2);
if ((val1 != 0) && (val2 != 0) &&
(HallMaxCheck >= 0x1FFF &&
HallMaxCheck <= 0x7FFF) &&
(HallMinCheck >= 0x8001 &&
HallMinCheck <= 0xEFFF)) {
Hall_Min = HallMinCheck;
Hall_Max = HallMaxCheck;
Hall_Off = val1;
Hall_Bias = val2;
}
}
} else {
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0F63, &val2);
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0F64, &val1);
HallMinCheck = ((val1 << 8) | (val2 & 0x00FF)) & 0xFFFF;
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0F65, &val2);
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0F66, &val1);
HallMaxCheck = ((val1 << 8) | (val2 & 0x00FF)) & 0xFFFF;
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0F67, &val1);
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0F68, &val2);
if ((val1 != 0) && (val2 != 0) &&
(HallMaxCheck >= 0x1FFF && HallMaxCheck <= 0x7FFF) &&
(HallMinCheck >= 0x8001 && HallMinCheck <= 0xEFFF)) {
Hall_Min = HallMinCheck;
Hall_Max = HallMaxCheck;
Hall_Off = val1;
Hall_Bias = val2;
}
}
/* Range Protection : Min = 0x8001 , Max = 0x7FFF */
if (!(Hall_Max >= 0 && Hall_Max <= 0x7FFF)) {
signed short Temp;
Temp = Hall_Min;
Hall_Min = Hall_Max;
Hall_Max = Temp;
}
LOG_INF("hallmax:0x%x, hallmin:0x%x, halloff:0x%x, hallbias:0x%x\n",
Hall_Max, Hall_Min, Hall_Off, Hall_Bias);
/* Wake up */
s4AF_WriteReg(0x80, 0x68);
s4AF_WriteReg(0x80, 0x64);
s4AF_WriteReg(0x95, 0x00);
AfInit(Hall_Off, Hall_Bias); /* Initialize driver IC */
/* Step move parameter set */
StSmvPar.UsSmvSiz = STMV_SIZE;
StSmvPar.UcSmvItv = STMV_INTERVAL;
StSmvPar.UcSmvEnb = STMCHTG_SET | STMSV_SET | STMLFF_SET;
StmvSet(StSmvPar);
ServoOn(); /* Close loop ON */
}
static unsigned short AF_convert(int position)
{
if (g_LC898212_SearchDir == 0) {
return (((position - Min_Pos) *
(unsigned short)(Hall_Max - Hall_Min) /
(Max_Pos - Min_Pos)) +
Hall_Min) &
0xFFFF;
} else {
return (((Max_Pos - position) *
(unsigned short)(Hall_Max - Hall_Min) /
(Max_Pos - Min_Pos)) +
Hall_Min) &
0xFFFF;
}
}
static inline int getAFInfo(__user struct stAF_MotorInfo *pstMotorInfo)
{
struct stAF_MotorInfo stMotorInfo;
stMotorInfo.u4MacroPosition = g_u4AF_MACRO;
stMotorInfo.u4InfPosition = g_u4AF_INF;
stMotorInfo.u4CurrentPosition = g_u4CurrPosition;
stMotorInfo.bIsSupportSR = 1;
stMotorInfo.bIsMotorMoving = 1;
if (*g_pAF_Opened >= 1)
stMotorInfo.bIsMotorOpen = 1;
else
stMotorInfo.bIsMotorOpen = 0;
if (copy_to_user(pstMotorInfo, &stMotorInfo,
sizeof(struct stAF_MotorInfo)))
LOG_INF("copy to user failed when getting motor information\n");
return 0;
}
/* initAF include driver initialization and standby mode */
static int initAF(void)
{
LOG_INF("+\n");
if (*g_pAF_Opened == 1) {
LC898212XD_init();
spin_lock(g_pAF_SpinLock);
*g_pAF_Opened = 2;
spin_unlock(g_pAF_SpinLock);
}
LOG_INF("-\n");
return 0;
}
/* moveAF only use to control moving the motor */
static inline int moveAF(unsigned long a_u4Position)
{
int ret = 0;
if ((StmvTo(AF_convert((int)a_u4Position)) & 0x1) == 0) {
g_u4CurrPosition = a_u4Position;
ret = 0;
} else {
LOG_INF("set I2C failed when moving the motor\n");
ret = -1;
}
return ret;
}
static inline int setAFInf(unsigned long a_u4Position)
{
spin_lock(g_pAF_SpinLock);
g_u4AF_INF = a_u4Position;
spin_unlock(g_pAF_SpinLock);
return 0;
}
static inline int setAFMacro(unsigned long a_u4Position)
{
spin_lock(g_pAF_SpinLock);
g_u4AF_MACRO = a_u4Position;
spin_unlock(g_pAF_SpinLock);
return 0;
}
static inline int getAFCalPos(__user struct stAF_MotorCalPos *pstMotorCalPos)
{
struct stAF_MotorCalPos stMotorCalPos;
u32 u4AF_CalibData_INF;
u32 u4AF_CalibData_MACRO;
u8 val1;
u4AF_CalibData_INF = 0;
u4AF_CalibData_MACRO = 0;
g_SelectEEPROM = 1;
if (s4EEPROM_ReadReg_LC898212XDAF_OV23850(0x001A, &val1) < 0)
g_SelectEEPROM = 0;
if (g_SelectEEPROM == 1) {
u8 val1 = 0, val2 = 0;
int AF_Infi = 0x00;
int AF_Marco = 0x00;
s4EEPROM_ReadReg_LC898212XDAF_OV23850(0x0011,
&val2); /* low byte */
s4EEPROM_ReadReg_LC898212XDAF_OV23850(0x0012, &val1);
AF_Infi = ((val1 << 8) | (val2 & 0x00FF)) & 0xFFFF;
s4EEPROM_ReadReg_LC898212XDAF_OV23850(0x0013, &val2);
s4EEPROM_ReadReg_LC898212XDAF_OV23850(0x0014, &val1);
AF_Marco = ((val1 << 8) | (val2 & 0x00FF)) & 0xFFFF;
s4EEPROM_ReadReg_LC898212XDAF_OV23850(0x0F67, &val1);
s4EEPROM_ReadReg_LC898212XDAF_OV23850(0x0F68, &val2);
Hall_Min = ((val1 << 8) | (val2 & 0x00FF)) & 0xFFFF;
s4EEPROM_ReadReg_LC898212XDAF_OV23850(0x0F69, &val1);
s4EEPROM_ReadReg_LC898212XDAF_OV23850(0x0F70, &val2);
Hall_Max = ((val1 << 8) | (val2 & 0x00FF)) & 0xFFFF;
if (!(Hall_Max >= 0 && Hall_Max <= 0x7FFF)) {
signed short Temp;
Temp = Hall_Min;
Hall_Min = Hall_Max;
Hall_Max = Temp;
}
if (AF_Marco > 1023 || AF_Infi > 1023 || AF_Infi > AF_Marco) {
u4AF_CalibData_INF = convertAF_DAC(AF_Infi);
u4AF_CalibData_MACRO = convertAF_DAC(AF_Marco);
}
} else {
u8 val1 = 0, val2 = 0;
int AF_Infi = 0x00;
int AF_Marco = 0x00;
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0011,
&val2); /* low byte */
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0012, &val1);
AF_Infi = ((val1 << 8) | (val2 & 0x00FF)) & 0xFFFF;
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0013, &val2);
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0014, &val1);
AF_Marco = ((val1 << 8) | (val2 & 0x00FF)) & 0xFFFF;
LOG_INF("AF_Infi : %x\n", AF_Infi);
LOG_INF("AF_Marco : %x\n", AF_Marco);
Hall_Min = 0x8001;
Hall_Max = 0x7FFF;
if (AF_Marco > 1023 || AF_Infi > 1023 || AF_Infi > AF_Marco) {
u4AF_CalibData_INF = convertAF_DAC(AF_Infi);
u4AF_CalibData_MACRO = convertAF_DAC(AF_Marco);
if (u4AF_CalibData_INF > u4AF_CalibData_MACRO) {
u4AF_CalibData_INF = 1023 - u4AF_CalibData_INF;
u4AF_CalibData_MACRO =
1023 - u4AF_CalibData_MACRO;
}
}
}
LOG_INF("AF_CalibData_INF : %d\n", u4AF_CalibData_INF);
LOG_INF("AF_CalibData_MACRO : %d\n", u4AF_CalibData_MACRO);
if (strncmp(CONFIG_ARCH_MTK_PROJECT, "k57v1", 5) == 0) {
u8 val1 = 0, val2 = 0;
unsigned int AF_Infi = 0x00;
unsigned int AF_Marco = 0x00;
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0011,
&val2); /* low byte */
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0012, &val1);
AF_Infi = ((val1 << 8) | (val2 & 0x00FF)) & 0xFFFF;
LOG_INF("AF_Infi : %x\n", AF_Infi);
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0013, &val2);
s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0014, &val1);
AF_Marco = ((val1 << 8) | (val2 & 0x00FF)) & 0xFFFF;
LOG_INF("AF_Infi : %x\n", AF_Marco);
/* Hall_Min = 0x8001; */
/* Hall_Max = 0x7FFF; */
if (AF_Marco > 1023 || AF_Infi > 1023 || AF_Infi > AF_Marco) {
u4AF_CalibData_INF = convertAF_DAC(AF_Infi);
LOG_INF("u4AF_CalibData_INF : %d\n",
u4AF_CalibData_INF);
u4AF_CalibData_MACRO = convertAF_DAC(AF_Marco);
LOG_INF("u4AF_CalibData_MACRO : %d\n",
u4AF_CalibData_MACRO);
if (u4AF_CalibData_MACRO > 0 &&
u4AF_CalibData_INF < 1024 &&
u4AF_CalibData_INF > u4AF_CalibData_MACRO) {
u4AF_CalibData_INF = 1023 - u4AF_CalibData_INF;
u4AF_CalibData_MACRO =
1023 - u4AF_CalibData_MACRO;
}
}
}
if (u4AF_CalibData_INF > 0 && u4AF_CalibData_MACRO < 1024 &&
u4AF_CalibData_INF < u4AF_CalibData_MACRO) {
stMotorCalPos.u4MacroPos = u4AF_CalibData_MACRO;
stMotorCalPos.u4InfPos = u4AF_CalibData_INF;
} else {
stMotorCalPos.u4MacroPos = 0;
stMotorCalPos.u4InfPos = 0;
}
if (copy_to_user(pstMotorCalPos, &stMotorCalPos, sizeof(stMotorCalPos)))
LOG_INF("copy to user failed when getting motor information\n");
return 0;
}
/* ////////////////////////////////////////////////////////////// */
long LC898212XDAF_Ioctl(struct file *a_pstFile, unsigned int a_u4Command,
unsigned long a_u4Param)
{
long i4RetValue = 0;
switch (a_u4Command) {
case AFIOC_G_MOTORINFO:
i4RetValue =
getAFInfo((__user struct stAF_MotorInfo *)(a_u4Param));
break;
case AFIOC_T_MOVETO:
i4RetValue = moveAF(a_u4Param);
break;
case AFIOC_T_SETINFPOS:
i4RetValue = setAFInf(a_u4Param);
break;
case AFIOC_T_SETMACROPOS:
i4RetValue = setAFMacro(a_u4Param);
break;
case AFIOC_G_MOTORCALPOS:
i4RetValue = getAFCalPos(
(__user struct stAF_MotorCalPos *)(a_u4Param));
break;
default:
LOG_INF("No CMD\n");
i4RetValue = -EPERM;
break;
}
return i4RetValue;
}
/* Main jobs: */
/* 1.Deallocate anything that "open" allocated in private_data. */
/* 2.Shut down the device on last close. */
/* 3.Only called once on last time. */
/* Q1 : Try release multiple times. */
int LC898212XDAF_Release(struct inode *a_pstInode, struct file *a_pstFile)
{
LOG_INF("Start\n");
if (*g_pAF_Opened == 2) {
LOG_INF("Wait\n");
/* Sleep In */
s4AF_WriteReg(0x95, 0x80);
s4AF_WriteReg(0x80, 0x68);
s4AF_WriteReg(0x80, 0x69);
msleep(20);
}
if (*g_pAF_Opened) {
LOG_INF("Free\n");
spin_lock(g_pAF_SpinLock);
*g_pAF_Opened = 0;
spin_unlock(g_pAF_SpinLock);
}
LOG_INF("End\n");
return 0;
}
int LC898212XDAF_SetI2Cclient(struct i2c_client *pstAF_I2Cclient,
spinlock_t *pAF_SpinLock, int *pAF_Opened)
{
g_pstAF_I2Cclient = pstAF_I2Cclient;
g_pAF_SpinLock = pAF_SpinLock;
g_pAF_Opened = pAF_Opened;
initAF();
return 1;
}
int LC898212XDAF_GetFileName(unsigned char *pFileName)
{
#if SUPPORT_GETTING_LENS_FOLDER_NAME
char FilePath[256];
char *FileString;
sprintf(FilePath, "%s", __FILE__);
FileString = strrchr(FilePath, '/');
*FileString = '\0';
FileString = (strrchr(FilePath, '/') + 1);
strncpy(pFileName, FileString, AF_MOTOR_NAME);
LOG_INF("FileName : %s\n", pFileName);
#else
pFileName[0] = '\0';
#endif
return 1;
}