LC898212XDAF.c 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. /*
  2. * BU6429AF voice coil motor driver
  3. *
  4. *
  5. */
  6. #include <linux/i2c.h>
  7. #include <linux/delay.h>
  8. #include <linux/uaccess.h>
  9. #include <linux/fs.h>
  10. #include "lens_info.h"
  11. #include "AfInit.h"
  12. #include "AfSTMV.h"
  13. #define AF_DRVNAME "LC898212XDAF_DRV"
  14. #define AF_I2C_SLAVE_ADDR 0xE4
  15. #define EEPROM_I2C_SLAVE_ADDR_OV23850 0xA8
  16. #define EEPROM_I2C_SLAVE_ADDR_IMX258 0xA0
  17. #define AF_DEBUG
  18. #ifdef AF_DEBUG
  19. #define LOG_INF(format, args...) pr_info(AF_DRVNAME " [%s] " format, __func__, ##args)
  20. #else
  21. #define LOG_INF(format, args...)
  22. #endif
  23. static struct i2c_client *g_pstAF_I2Cclient;
  24. static int *g_pAF_Opened;
  25. static spinlock_t *g_pAF_SpinLock;
  26. static int g_ReadCalibData_FirstTime;
  27. static unsigned long g_u4AF_CalibData_INF;
  28. static unsigned long g_u4AF_CalibData_MACRO;
  29. static unsigned long g_u4AF_INF;
  30. static unsigned long g_u4AF_MACRO = 1023;
  31. static unsigned long g_u4TargetPosition;
  32. static unsigned long g_u4CurrPosition;
  33. static unsigned int g_SelectEEPROM;
  34. #define Min_Pos 0
  35. #define Max_Pos 1023
  36. static signed short Hall_Max = 0x0000; /* Please read INF position from EEPROM or OTP */
  37. static signed short Hall_Min = 0x0000; /* Please read MACRO position from EEPROM or OTP */
  38. int s4AF_ReadReg_LC898212XDAF(u8 *a_pSendData, u16 a_sizeSendData, u8 *a_pRecvData,
  39. u16 a_sizeRecvData, u16 i2cId)
  40. {
  41. int i4RetValue = 0;
  42. g_pstAF_I2Cclient->addr = i2cId >> 1;
  43. i4RetValue = i2c_master_send(g_pstAF_I2Cclient, a_pSendData, a_sizeSendData);
  44. if (i4RetValue != a_sizeSendData) {
  45. LOG_INF("I2C send failed!!, Addr = 0x%x\n", a_pSendData[0]);
  46. return -1;
  47. }
  48. i4RetValue = i2c_master_recv(g_pstAF_I2Cclient, (u8 *) a_pRecvData, a_sizeRecvData);
  49. if (i4RetValue != a_sizeRecvData) {
  50. LOG_INF("I2C read failed!!\n");
  51. return -1;
  52. }
  53. return 0;
  54. }
  55. int s4AF_WriteReg_LC898212XDAF(u8 *a_pSendData, u16 a_sizeSendData, u16 i2cId)
  56. {
  57. int i4RetValue = 0;
  58. g_pstAF_I2Cclient->addr = i2cId >> 1;
  59. i4RetValue = i2c_master_send(g_pstAF_I2Cclient, a_pSendData, a_sizeSendData);
  60. if (i4RetValue < 0) {
  61. LOG_INF("I2C send failed!!, Addr = 0x%x, Data = 0x%x\n", a_pSendData[0], a_pSendData[1]);
  62. return -1;
  63. }
  64. return 0;
  65. }
  66. static int s4EEPROM_ReadReg_LC898212XDAF_OV23850(u16 addr, u8 *data)
  67. {
  68. int i4RetValue = 0;
  69. u8 puSendCmd[2] = { (u8) (addr >> 8), (u8) (addr & 0xFF) };
  70. i4RetValue = s4AF_ReadReg_LC898212XDAF(puSendCmd, sizeof(puSendCmd), data, 1, EEPROM_I2C_SLAVE_ADDR_OV23850);
  71. if (i4RetValue < 0)
  72. LOG_INF("I2C read e2prom failed!!\n");
  73. return i4RetValue;
  74. }
  75. static int s4EEPROM_ReadReg_LC898212XDAF_IMX258(u16 addr, u8 *data)
  76. {
  77. int i4RetValue = 0;
  78. u8 puSendCmd[2] = { (u8) (addr >> 8), (u8) (addr & 0xFF) };
  79. i4RetValue = s4AF_ReadReg_LC898212XDAF(puSendCmd, sizeof(puSendCmd), data, 1, EEPROM_I2C_SLAVE_ADDR_IMX258);
  80. if (i4RetValue < 0)
  81. LOG_INF("I2C read e2prom failed!!\n");
  82. return i4RetValue;
  83. }
  84. static unsigned long convertAF_DAC(short ReadData)
  85. {
  86. short DacVal = ( (ReadData - Hall_Min) * (Max_Pos - Min_Pos) ) / ( (unsigned short)(Hall_Max - Hall_Min) ) + Min_Pos;
  87. return (unsigned long)DacVal;
  88. }
  89. static void LC898212XD_init(void)
  90. {
  91. stSmvPar StSmvPar;
  92. u8 val1 = 0, val2 = 0;
  93. int Hall_Off = 0x00; /* Please Read Offset from EEPROM or OTP */
  94. int Hall_Bias = 0x00; /* Please Read Bias from EEPROM or OTP */
  95. int AF_Infi = 0x00; /* Please Read Bias from EEPROM or OTP */
  96. int AF_Marco = 0x00; /* Please Read Bias from EEPROM or OTP */
  97. g_ReadCalibData_FirstTime = 1;
  98. g_SelectEEPROM = 0;
  99. if (s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x001A, &val1) < 0)
  100. g_SelectEEPROM = 1;
  101. if ( g_SelectEEPROM == 0 ) {
  102. LOG_INF("Select imx258 e2prom!!\n");
  103. s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x001A, &val1);
  104. Hall_Bias = val1;
  105. s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0019, &val1);
  106. Hall_Off = val1;
  107. s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0016, &val1);
  108. s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0015, &val2);
  109. Hall_Min = ((val1 << 8) | (val2 & 0x00FF)) & 0xFFFF;
  110. s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0018, &val1);
  111. s4EEPROM_ReadReg_LC898212XDAF_IMX258(0x0017, &val2);
  112. Hall_Max = ((val1 << 8) | (val2 & 0x00FF)) & 0xFFFF;
  113. } else {
  114. LOG_INF("Select ov23850 e2prom!!\n");
  115. s4EEPROM_ReadReg_LC898212XDAF_OV23850(0x0011, &val2); /* low byte */
  116. s4EEPROM_ReadReg_LC898212XDAF_OV23850(0x0012, &val1);
  117. AF_Infi = ((val1 << 8) | (val2 & 0x00FF)) & 0xFFFF;
  118. s4EEPROM_ReadReg_LC898212XDAF_OV23850(0x0013, &val2);
  119. s4EEPROM_ReadReg_LC898212XDAF_OV23850(0x0014, &val1);
  120. AF_Marco = ((val1 << 8) | (val2 & 0x00FF)) & 0xFFFF;
  121. LOG_INF("=====LC898212XD: Infi:0x%x, Marco:0x%x\n",
  122. AF_Infi, AF_Marco);
  123. s4EEPROM_ReadReg_LC898212XDAF_OV23850(0x0F63, &val1);
  124. s4EEPROM_ReadReg_LC898212XDAF_OV23850(0x0F64, &val2);
  125. Hall_Bias = ((val1 << 8) | (val2 & 0x00FF)) & 0xFFFF;
  126. s4EEPROM_ReadReg_LC898212XDAF_OV23850(0x0F65, &val1);
  127. s4EEPROM_ReadReg_LC898212XDAF_OV23850(0x0F66, &val2);
  128. Hall_Off = ((val1 << 8) | (val2 & 0x00FF)) & 0xFFFF;
  129. s4EEPROM_ReadReg_LC898212XDAF_OV23850(0x0F67, &val1);
  130. s4EEPROM_ReadReg_LC898212XDAF_OV23850(0x0F68, &val2);
  131. Hall_Min = ((val1 << 8) | (val2 & 0x00FF)) & 0xFFFF;
  132. s4EEPROM_ReadReg_LC898212XDAF_OV23850(0x0F69, &val1);
  133. s4EEPROM_ReadReg_LC898212XDAF_OV23850(0x0F70, &val2);
  134. Hall_Max = ((val1 << 8) | (val2 & 0x00FF)) & 0xFFFF;
  135. g_u4AF_CalibData_INF = convertAF_DAC(AF_Infi);
  136. g_u4AF_CalibData_MACRO = convertAF_DAC(AF_Marco);
  137. LOG_INF("=====LC898212XD DAC: Infi:%d, Marco:%d\n",
  138. (int)g_u4AF_CalibData_INF, (int)g_u4AF_CalibData_MACRO);
  139. }
  140. LOG_INF("=====LC898212XD:=init=hall_max:0x%x==hall_min:0x%x====halloff:0x%x, hallbias:0x%x===\n",
  141. Hall_Max, Hall_Min, Hall_Off, Hall_Bias);
  142. AfInit(Hall_Off, Hall_Bias); /* Initialize driver IC */
  143. /* Step move parameter set */
  144. StSmvPar.UsSmvSiz = STMV_SIZE;
  145. StSmvPar.UcSmvItv = STMV_INTERVAL;
  146. StSmvPar.UcSmvEnb = STMCHTG_SET | STMSV_SET | STMLFF_SET;
  147. StmvSet(StSmvPar);
  148. ServoOn(); /* Close loop ON */
  149. }
  150. static unsigned short AF_convert(int position)
  151. {
  152. if (position == 0)
  153. return 0x9001;
  154. else if(position == 1023)
  155. return 0x6FFF;
  156. #if 1 /* 1: INF -> Macro = 0x8001 -> 0x7FFF */
  157. return (((position - Min_Pos) * (unsigned short)(Hall_Max - Hall_Min) / (Max_Pos -
  158. Min_Pos)) +
  159. Hall_Min) & 0xFFFF;
  160. #else /* 0: INF -> Macro = 0x7FFF -> 0x8001 */
  161. return (((Max_Pos - position) * (unsigned short)(Hall_Max - Hall_Min) / (Max_Pos -
  162. Min_Pos)) +
  163. Hall_Min) & 0xFFFF;
  164. #endif
  165. }
  166. static inline int getAFInfo(__user stAF_MotorInfo *pstMotorInfo)
  167. {
  168. stAF_MotorInfo stMotorInfo;
  169. if (g_ReadCalibData_FirstTime == 1) {
  170. stMotorInfo.u4MacroPosition = g_u4AF_CalibData_MACRO;
  171. stMotorInfo.u4InfPosition = g_u4AF_CalibData_INF;
  172. g_ReadCalibData_FirstTime = 0;
  173. } else {
  174. stMotorInfo.u4MacroPosition = g_u4AF_MACRO;
  175. stMotorInfo.u4InfPosition = g_u4AF_INF;
  176. }
  177. stMotorInfo.u4CurrentPosition = g_u4CurrPosition;
  178. stMotorInfo.bIsSupportSR = 1;
  179. stMotorInfo.bIsMotorMoving = 1;
  180. if (*g_pAF_Opened >= 1)
  181. stMotorInfo.bIsMotorOpen = 1;
  182. else
  183. stMotorInfo.bIsMotorOpen = 0;
  184. if (copy_to_user(pstMotorInfo, &stMotorInfo, sizeof(stAF_MotorInfo)))
  185. LOG_INF("copy to user failed when getting motor information\n");
  186. return 0;
  187. }
  188. static inline int moveAF(unsigned long a_u4Position)
  189. {
  190. if ((a_u4Position > g_u4AF_MACRO) || (a_u4Position < g_u4AF_INF)) {
  191. LOG_INF("out of range\n");
  192. return -EINVAL;
  193. }
  194. if (*g_pAF_Opened == 1) {
  195. /* Driver Init */
  196. LC898212XD_init();
  197. spin_lock(g_pAF_SpinLock);
  198. g_u4CurrPosition = 0;
  199. *g_pAF_Opened = 2;
  200. spin_unlock(g_pAF_SpinLock);
  201. }
  202. if (g_u4CurrPosition == a_u4Position)
  203. return 0;
  204. spin_lock(g_pAF_SpinLock);
  205. g_u4TargetPosition = a_u4Position;
  206. spin_unlock(g_pAF_SpinLock);
  207. /* LOG_INF("move [curr] %d [target] %d\n", (int)g_u4CurrPosition, (int)g_u4TargetPosition); */
  208. if ((StmvTo(AF_convert(a_u4Position))&0x1) == 0) {
  209. spin_lock(g_pAF_SpinLock);
  210. g_u4CurrPosition = (unsigned long)g_u4TargetPosition;
  211. spin_unlock(g_pAF_SpinLock);
  212. } else {
  213. LOG_INF("set I2C failed when moving the motor\n");
  214. }
  215. return 0;
  216. }
  217. static inline int setAFInf(unsigned long a_u4Position)
  218. {
  219. spin_lock(g_pAF_SpinLock);
  220. g_u4AF_INF = a_u4Position;
  221. spin_unlock(g_pAF_SpinLock);
  222. return 0;
  223. }
  224. static inline int setAFMacro(unsigned long a_u4Position)
  225. {
  226. spin_lock(g_pAF_SpinLock);
  227. g_u4AF_MACRO = a_u4Position;
  228. spin_unlock(g_pAF_SpinLock);
  229. return 0;
  230. }
  231. /* ////////////////////////////////////////////////////////////// */
  232. long LC898212XDAF_Ioctl(struct file *a_pstFile, unsigned int a_u4Command, unsigned long a_u4Param)
  233. {
  234. long i4RetValue = 0;
  235. switch (a_u4Command) {
  236. case AFIOC_G_MOTORINFO:
  237. i4RetValue = getAFInfo((__user stAF_MotorInfo *) (a_u4Param));
  238. break;
  239. case AFIOC_T_MOVETO:
  240. i4RetValue = moveAF(a_u4Param);
  241. break;
  242. case AFIOC_T_SETINFPOS:
  243. i4RetValue = setAFInf(a_u4Param);
  244. break;
  245. case AFIOC_T_SETMACROPOS:
  246. i4RetValue = setAFMacro(a_u4Param);
  247. break;
  248. default:
  249. LOG_INF("No CMD\n");
  250. i4RetValue = -EPERM;
  251. break;
  252. }
  253. return i4RetValue;
  254. }
  255. /* Main jobs: */
  256. /* 1.Deallocate anything that "open" allocated in private_data. */
  257. /* 2.Shut down the device on last close. */
  258. /* 3.Only called once on last time. */
  259. /* Q1 : Try release multiple times. */
  260. int LC898212XDAF_Release(struct inode *a_pstInode, struct file *a_pstFile)
  261. {
  262. LOG_INF("Start\n");
  263. if (*g_pAF_Opened == 2) {
  264. LOG_INF("Wait\n");
  265. msleep(20);
  266. }
  267. if (*g_pAF_Opened) {
  268. LOG_INF("Free\n");
  269. spin_lock(g_pAF_SpinLock);
  270. *g_pAF_Opened = 0;
  271. spin_unlock(g_pAF_SpinLock);
  272. }
  273. LOG_INF("End\n");
  274. return 0;
  275. }
  276. void LC898212XDAF_SetI2Cclient(struct i2c_client *pstAF_I2Cclient, spinlock_t *pAF_SpinLock, int *pAF_Opened)
  277. {
  278. g_pstAF_I2Cclient = pstAF_I2Cclient;
  279. g_pAF_SpinLock = pAF_SpinLock;
  280. g_pAF_Opened = pAF_Opened;
  281. }