tizen 2.4 release
[kernel/u-boot-tm1.git] / property / ap_calibration.c
1 #include <config.h>\r
2 #include <common.h>\r
3 #include <linux/types.h>\r
4 #include <asm/arch/bits.h>\r
5 #include <linux/string.h>\r
6 #include <android_bootimg.h>\r
7 #include <linux/mtd/mtd.h>\r
8 #include <linux/mtd/nand.h>\r
9 #include <nand.h>\r
10 #include <android_boot.h>\r
11 #include <environment.h>\r
12 #include "asm/arch/cmddef.h"\r
13 #include "asm/arch/sci_types.h"\r
14 \r
15 #ifdef CONFIG_EMMC_BOOT\r
16 #include <part.h>\r
17 #include "../disk/part_uefi.h"\r
18 extern int Calibration_read_partition(block_dev_desc_t *p_block_dev, wchar_t* partition_name, char *buf, int len);\r
19 extern int Calibration_write_partition(block_dev_desc_t *p_block_dev, wchar_t* partition_name, char *buf, int len);\r
20 static unsigned int nv_buffer[256]={0};\r
21 static nv_read_flag = 0;\r
22 #endif\r
23 \r
24 extern int nand_part_write(char *partname,char *buffer, int size);\r
25 extern int nand_part_read(char *partname,char *buffer, int size);\r
26 #ifdef CONFIG_AP_ADC_CALIBRATION\r
27 \r
28 #define AP_ADC_CALIB    1\r
29 #define AP_ADC_LOAD     2\r
30 #define AP_ADC_SAVE     3\r
31 #define AP_GET_VOLT     4\r
32 \r
33 #define PRECISION_1MV       (1<<24)\r
34 #define PRECISION_10MV      (0)\r
35 #define MAX_VOLTAGE         (0xFFFFFF)\r
36 \r
37 typedef struct\r
38 {\r
39     uint32    adc[2];           // calibration of ADC, two test point\r
40     uint32    battery[2];       // calibraton of battery(include resistance), two test point\r
41     uint32    reserved[8];      // reserved for feature use.\r
42 } AP_ADC_T;\r
43 \r
44 typedef struct\r
45 {\r
46     MSG_HEAD_T  msg_head;\r
47     TOOLS_DIAG_AP_CNF_T diag_ap_cnf;\r
48     TOOLS_AP_ADC_REQ_T ap_adc_req;\r
49 }MSG_AP_ADC_CNF;\r
50 static unsigned char g_usb_buf_dest[8*1024];\r
51 static int power_off_Flag = 0;  //add by kenyliu in 2013 06 20 for bug 146310\r
52 \r
53 static int AccessADCDataFile(uint8 flag, char *lpBuff, int size)\r
54 {\r
55 #ifdef CONFIG_EMMC_BOOT\r
56     block_dev_desc_t *p_block_dev = NULL; \r
57     p_block_dev = get_dev("mmc", 1);\r
58     if(NULL == p_block_dev){\r
59         return 0;\r
60     }\r
61     if(nv_read_flag == 0){\r
62         if(do_fs_file_read("prodnv", "/adc.bin", (char *)nv_buffer,sizeof(nv_buffer)))\r
63                 return 0;\r
64         nv_read_flag = 1;\r
65     }\r
66     printf("EMC_Read:nv_buffer[255]=0x%x \n",nv_buffer[255]);\r
67     if(nv_read_flag == 1){\r
68         if (flag == 0){\r
69             if(nv_buffer[255] != 0x5a5a5a5a)\r
70                 return 0;\r
71             memcpy(lpBuff,&nv_buffer[0],size);\r
72         } else {\r
73             nv_buffer[255] = 0x5a5a5a5a;\r
74             memcpy(&nv_buffer[0],lpBuff,size);\r
75             if(ext4_write_content(1, L"prodnv", "/adc.bin", (char *)nv_buffer, 0, sizeof(nv_buffer)))\r
76                     return 0;\r
77         }\r
78     }\r
79     return size;\r
80 #else\r
81     char *file_partition = "modem";\r
82     int ret = 0;\r
83 \r
84     if (flag == 0) // read ADC data\r
85     {\r
86         nand_part_read(file_partition,lpBuff,size);\r
87         return size;\r
88     }\r
89     else if (flag == 1)  //write ADC data\r
90     {\r
91         \r
92         nand_part_write(file_partition,lpBuff,size);\r
93         ret = size;\r
94     }\r
95     else\r
96     {\r
97         ret = 0;\r
98     }                   \r
99     return ret;\r
100 #endif\r
101 }\r
102 \r
103 /*copy from packet.c and modify*/\r
104 static int untranslate_packet_header(char *dest,char *src,int size, int unpackSize)\r
105 {\r
106         int i;\r
107         int translated_size = 0;\r
108         int status = 0;\r
109         int flag = 0;\r
110         for(i=0;i<size;i++){\r
111                 switch(status){\r
112                         case 0:\r
113                                 if(src[i] == 0x7e)\r
114                                         status = 1;\r
115                         break;\r
116                         case 1:\r
117                                 if(src[i] != 0x7e)\r
118                                 {\r
119                                         status = 2;\r
120                                         dest[translated_size++] = src[i];\r
121                                 }\r
122                         break;\r
123                         case 2:\r
124                                 if(src[i] == 0x7E)\r
125                                 {\r
126                                         unsigned short crc;\r
127                                         crc = crc_16_l_calc((char const *)dest,translated_size-2);\r
128                                         return translated_size;\r
129                                 }else\r
130                                 {\r
131                                         if((dest[translated_size-1] == 0x7D)&&(!flag))\r
132                                         {\r
133                                                 flag = 1;\r
134                                                 if(src[i] == 0x5E)\r
135                                                 {\r
136                                                         dest[translated_size-1] = 0x7E;\r
137                                                 } \r
138                                                 else if(src[i] == 0x5D) \r
139                                                 {\r
140                                                         dest[translated_size-1] = 0x7D;\r
141                                                 }\r
142                                         }\r
143                                         else\r
144                                         {\r
145                                                 flag = 0;\r
146                                                 dest[translated_size++] = src[i];\r
147                                         }                               \r
148 \r
149                                         if (translated_size >= unpackSize+1 && unpackSize != -1)\r
150                                         {\r
151                                                 return translated_size;\r
152                                         }\r
153                                 }\r
154                         break;\r
155                 }\r
156         }\r
157 \r
158         return translated_size;\r
159 }\r
160 \r
161 static int translate_packet(char *dest,char *src,int size)\r
162 {\r
163         int i;\r
164         int translated_size = 0;\r
165         \r
166         dest[translated_size++] = 0x7E;\r
167         \r
168         for(i=0;i<size;i++){\r
169                 if(src[i] == 0x7E){\r
170                         dest[translated_size++] = 0x7D;\r
171                         dest[translated_size++] = 0x5E;\r
172                 } else if(src[i] == 0x7D) {\r
173                         dest[translated_size++] = 0x7D;\r
174                         dest[translated_size++] = 0x5D;                 \r
175                 } else \r
176                         dest[translated_size++] = src[i];\r
177         }       \r
178         dest[translated_size++] = 0x7E;\r
179         return translated_size; \r
180 }\r
181 \r
182 static uint8 is_adc_calibration(char *dest, int destSize, char *src,int srcSize)\r
183 {\r
184         int translated_size = 0;\r
185         int msghead_size = sizeof(MSG_HEAD_T);\r
186   \r
187         memset(dest, 0, destSize);\r
188         translated_size = untranslate_packet_header(dest, src, srcSize, msghead_size);  \r
189         if (translated_size >= msghead_size )\r
190         {\r
191                 MSG_HEAD_T* lpHeader = (MSG_HEAD_T *)dest;\r
192                 if (DIAG_AP_F  == lpHeader->type)\r
193                 {\r
194                         TOOLS_DIAG_AP_CMD_T *lpAPCmd =(TOOLS_DIAG_AP_CMD_T *)(lpHeader+1);\r
195                         memset(dest, 0, destSize);\r
196                         translated_size = untranslate_packet_header(dest, src, srcSize, -1);                    \r
197 \r
198                         switch (lpAPCmd->cmd)\r
199                         {\r
200                                 case DIAG_AP_CMD_ADC:\r
201                                 {\r
202                                         TOOLS_AP_ADC_REQ_T *lpAPADCReq =(TOOLS_AP_ADC_REQ_T *)(lpAPCmd+1);\r
203                                         if (lpAPADCReq->operate == 0)\r
204                                         {\r
205                                                 return AP_ADC_CALIB;\r
206                                         }\r
207                                         else if (lpAPADCReq->operate == 1)\r
208                                         {\r
209                                                 return AP_ADC_LOAD;\r
210                                         }\r
211                                         else if (lpAPADCReq->operate == 2)\r
212                                         {\r
213                                                 return AP_ADC_SAVE;\r
214                                         }\r
215                                         else\r
216                                         {\r
217                                                 return 0;\r
218                                         }                                    \r
219                                 }\r
220                                 break;\r
221         \r
222                                 default:\r
223                                 break;                        \r
224                         }\r
225                 } else if(DIAG_POWER_SUPPLY_F  == lpHeader->type){\r
226                         return AP_GET_VOLT;\r
227                 }\r
228                 //add by kenyliu in 2013 06 20 for bug 146310\r
229                 else if((DIAG_CURRENT_TEST_F == lpHeader->type) && (0xE == lpHeader->subtype)){\r
230                                 power_off_Flag =0xE;\r
231                         }\r
232                 //end kenyliu\r
233                 }\r
234         return 0;\r
235 }\r
236 \r
237 static uint32 ap_adc_calibration(uint32 channel, MSG_AP_ADC_CNF *pMsgADC)\r
238 {\r
239         volatile uint32 adc_channel = 0, adc_result = 0;\r
240         int i = 0;\r
241         adc_channel = channel;\r
242 \r
243         if (adc_channel <= 8)\r
244         {\r
245                 if (adc_channel == 0)\r
246                 {\r
247                         adc_channel = 1;                        \r
248                 }\r
249                 \r
250                 adc_result = 0;\r
251                 for(; i < 16; i++)\r
252                 {\r
253                         adc_result += ADC_GetValue(adc_channel-1, 0);\r
254                 }\r
255                 adc_result >>= 4;\r
256                 pMsgADC->diag_ap_cnf.status  = 0;\r
257                 pMsgADC->ap_adc_req. parameters[0]= (uint16)(adc_result&0xFFFF);                \r
258         }               \r
259         else\r
260         {       \r
261                 pMsgADC->diag_ap_cnf.status  = 1;\r
262                 pMsgADC->ap_adc_req. parameters[0] = 0xFFFF;\r
263         }\r
264 \r
265         printf("\n ReadADC: ( channel = %x)", adc_channel);                     \r
266 \r
267         return adc_result;\r
268 }\r
269 \r
270 static int ap_adc_save(TOOLS_AP_ADC_REQ_T *pADCReq, MSG_AP_ADC_CNF *pMsgADC)\r
271 {\r
272         AP_ADC_T adcValue = {0};\r
273         int ret = 0;\r
274         ret = AccessADCDataFile(1, pADCReq->parameters, sizeof(pADCReq->parameters));\r
275         if (ret > 0)\r
276         {\r
277                 pMsgADC->diag_ap_cnf.status = 0;\r
278         }\r
279         else\r
280         {\r
281                 pMsgADC->diag_ap_cnf.status = 1;\r
282         }\r
283 \r
284         return ret;\r
285 }\r
286 static int ap_adc_load(MSG_AP_ADC_CNF *pMsgADC)\r
287 {       \r
288         int ret = AccessADCDataFile(0, pMsgADC->ap_adc_req.parameters, sizeof(pMsgADC->ap_adc_req.parameters));\r
289         if (ret > 0)\r
290         {\r
291                 pMsgADC->diag_ap_cnf.status = 0;           \r
292         }\r
293         else\r
294         {\r
295                 pMsgADC->diag_ap_cnf.status = 1;\r
296         }\r
297 \r
298         return ret;\r
299 }\r
300 static uint32 ap_get_voltage(uint32 channel, MSG_AP_ADC_CNF *pMsgADC)\r
301 {\r
302         volatile uint32 adc_channel = 0, adc_result = 0;\r
303         uint32  voltage = 0;\r
304         uint32  *para=NULL;\r
305         int i = 0;\r
306         MSG_HEAD_T      *msg;\r
307         adc_channel = channel;\r
308 \r
309         if (adc_channel <= 8)\r
310         {\r
311                 if (adc_channel == 0)\r
312                 {\r
313                         adc_channel = 1;\r
314                 }\r
315 \r
316                 adc_result = 0;\r
317                 for(; i < 16; i++)\r
318                 {\r
319                         adc_result += ADC_GetValue(adc_channel-1, 0);\r
320                 }\r
321                 adc_result >>= 4;\r
322                 voltage = sprdbat_auxadc2vbatvol(adc_result);\r
323                 msg = (MSG_HEAD_T *)pMsgADC;\r
324                 para = (msg+1);\r
325 //                *para = (voltage/10);\r
326             if (voltage > MAX_VOLTAGE)\r
327             {\r
328                 *para = (PRECISION_10MV | ((voltage/10) & MAX_VOLTAGE));\r
329             }\r
330             else\r
331             {\r
332                 *para = (PRECISION_1MV | (voltage & MAX_VOLTAGE));\r
333             }\r
334         }\r
335         else\r
336         {\r
337                 pMsgADC->diag_ap_cnf.status  = 1;\r
338                 pMsgADC->ap_adc_req. parameters[0] = 0xFFFF;\r
339         }\r
340         pMsgADC->msg_head.len = 12;\r
341         printf("\n Read voltage : %d\n", voltage);\r
342 \r
343         return voltage;\r
344 }\r
345 uint8 ap_adc_process(int flag, char * src, int size, MSG_AP_ADC_CNF * pMsgADC)\r
346 {\r
347         MSG_HEAD_T *lpHeader = (MSG_HEAD_T *)src;\r
348         TOOLS_DIAG_AP_CMD_T *lpAPCmd =(TOOLS_DIAG_AP_CMD_T *)(lpHeader+1);\r
349         TOOLS_AP_ADC_REQ_T *lpApADCReq = (TOOLS_AP_ADC_REQ_T *)(lpAPCmd+1);\r
350         memcpy(&(pMsgADC->msg_head), lpHeader, sizeof(MSG_HEAD_T));\r
351         pMsgADC->msg_head.len = sizeof(TOOLS_DIAG_AP_CNF_T)+sizeof(TOOLS_AP_ADC_REQ_T)+sizeof(MSG_HEAD_T);\r
352         pMsgADC->diag_ap_cnf.length = sizeof(TOOLS_AP_ADC_REQ_T);\r
353         memcpy(&(pMsgADC->ap_adc_req), lpApADCReq, sizeof(TOOLS_AP_ADC_REQ_T));     \r
354 \r
355         switch (flag)\r
356         {\r
357                 case AP_ADC_CALIB:\r
358                 {         \r
359                         uint32 channel = lpApADCReq->parameters[0];\r
360                         ap_adc_calibration(channel, pMsgADC);\r
361                 }\r
362                 break;\r
363                 case AP_ADC_LOAD:\r
364                         ap_adc_load(pMsgADC);\r
365                 break;\r
366                 case AP_ADC_SAVE:\r
367                         ap_adc_save(lpApADCReq, pMsgADC);\r
368                 break;\r
369                 case AP_GET_VOLT:\r
370                         ap_get_voltage(6,pMsgADC);\r
371                 break;\r
372                 default:\r
373                 return 0;                     \r
374         }\r
375         return 1;\r
376 }\r
377 #endif\r
378 int     write_adc_calibration_data(char *data, int size)\r
379 {\r
380         int ret = 0;\r
381 #ifdef CONFIG_AP_ADC_CALIBRATION\r
382         ret = AccessADCDataFile(1, data, size);\r
383 #endif\r
384         return ret;\r
385 }\r
386 int     read_adc_calibration_data(char *buffer,int size)\r
387 {\r
388 #ifdef CONFIG_AP_ADC_CALIBRATION\r
389         int ret;\r
390         if(size > 48)\r
391                 size = 48;\r
392         ret = AccessADCDataFile(0, buffer, size);\r
393         if(ret > 0)\r
394                 return size;\r
395 #endif\r
396         return 0;\r
397 }\r
398 uint32 ap_calibration_proc(uint8 *data,uint32 count,uint8 *out_msg)\r
399 {\r
400  #ifdef CONFIG_AP_ADC_CALIBRATION\r
401         int adcFlag = 0;\r
402         int index = 0;\r
403 \r
404         if(count > 0){\r
405                 adcFlag = is_adc_calibration(g_usb_buf_dest, sizeof(g_usb_buf_dest), data, count );\r
406 \r
407                 if (adcFlag != 0)\r
408                 {\r
409                         MSG_AP_ADC_CNF adcMsg = {0};\r
410                         printf("\n adcFlag = %d", adcFlag);\r
411 \r
412                         ap_adc_process(adcFlag, g_usb_buf_dest, count, &adcMsg);\r
413                         index = translate_packet(out_msg, &adcMsg, adcMsg.msg_head.len);        \r
414                         count = 0;\r
415               \r
416                         return index;                   \r
417                 }\r
418         }\r
419 #endif\r
420         return 0;\r
421 }\r
422 //add by kenyliu in 2013 06 20 for bug 146310\r
423 int get_adc_flag()\r
424 {\r
425   #ifdef CONFIG_AP_ADC_CALIBRATION\r
426         return power_off_Flag;\r
427   #endif\r
428 }\r
429 //end kenyliu\r