tizen 2.4 release
[kernel/u-boot-tm1.git] / property / calibration_detect.c
1 #include "calibration_detect.h"
2 #include <stdbool.h>
3
4 static unsigned int nv_buffer[256]={0};
5 static int s_is_calibration_mode = 0;
6 char *calibration_cmd_buf;
7 uint8_t pctool_cmd_buf[20];
8 uint8_t pctool_cnf_buf[20];
9
10 char *get_calibration_parameter(void)
11 {
12         if(s_is_calibration_mode != 0)
13         return calibration_cmd_buf;
14         else
15         return NULL;
16 }
17
18 bool is_calibration_by_uart(void)
19 {
20        return (2 == s_is_calibration_mode);
21 }
22
23 #define mdelay(_ms) udelay(_ms*1000)
24 #define CALIBERATE_STRING_LEN 10
25 #define CALIBERATE_HEAD 0x7e
26 #define CALIBERATE_COMMOND_T 0xfe
27 #define CALIBERATE_COMMAND_REQ  1
28
29 #define CALIBERATE_DEVICE_NULL  0
30 #define CALIBERATE_DEVICE_USB   1
31 #define CALIBERATE_DEVICE_UART  2
32
33 extern int charger_connected(void);
34 typedef  struct tag_cali_command {
35         unsigned int    reserved;
36         unsigned short  size;
37         unsigned char   cmd;
38         unsigned char   sub_cmd;
39 } COMMAND_T;
40
41 extern int serial_tstc(void);
42 static unsigned long long start_time;
43 static unsigned long long now_time;
44
45
46
47 static caliberate_device = CALIBERATE_DEVICE_NULL;
48
49 static void send_caliberation_request(void)
50 {
51         COMMAND_T cmd;
52         unsigned int i;
53         unsigned char *data = (unsigned char *)&cmd;
54
55         cmd.reserved = 0;
56         cmd.cmd = CALIBERATE_COMMOND_T;
57         cmd.size = CALIBERATE_STRING_LEN-2;
58         cmd.sub_cmd = CALIBERATE_COMMAND_REQ;
59
60         serial_putc(CALIBERATE_HEAD);
61
62         for (i = 0; i < sizeof(COMMAND_T); i++)
63              serial_putc(data[i]);
64
65         serial_putc(CALIBERATE_HEAD);
66 }
67
68 static int receive_caliberation_response(uint8_t *buf,int len)
69 {
70         int count = 0;
71         int ch;
72         uint32_t is_not_empty = 0;
73         uint32_t start_time = 0,current_time = 0;
74
75         if ((buf == NULL) || (len == 0))
76                 return 0;
77
78         is_not_empty = serial_tstc();
79         if (is_not_empty) {
80              start_time = get_timer_masked();
81              do {
82                   do {
83                         ch = serial_getc();
84                         if (count < CALIBERATE_STRING_LEN)
85                                 buf[count++] = ch;
86                   } while (serial_tstc());
87
88                   if ((count >= CALIBERATE_STRING_LEN) || (count >= len)) {
89                        caliberate_device = CALIBERATE_DEVICE_UART;
90                        break;
91                   }
92
93                   current_time = get_timer_masked();
94              } while((current_time - start_time) < 500);
95         }
96
97         return count;
98 }
99
100 unsigned int check_caliberate(uint8_t * buf, int len)
101 {
102         unsigned int command = 0;
103         unsigned int freq = 0;
104
105         if (len != CALIBERATE_STRING_LEN)
106                 return 0;
107
108         if ((*buf == CALIBERATE_HEAD) && (*(buf + len -1) == CALIBERATE_HEAD)) {
109                 if ((*(buf+7) == CALIBERATE_COMMOND_T) && (*(buf + len - 2) != 0x1)) {
110                         command = *(buf + len - 2);
111                         command &= 0x7f;
112
113                         freq = *(buf + 1);
114                         freq = freq << 8;
115                         freq += *(buf + 2);
116
117                         command += freq << 8;
118                 }
119         }
120
121         return command;
122 }
123
124 int pctool_mode_detect_uart(void)
125 {
126         int ret;
127         int i ;
128         unsigned int caliberate_mode;
129         uint8_t buf[20];
130         int got = 0;
131
132         printf("%s\n", "uart calibrate detecting");
133         loff_t off = 0;
134         send_caliberation_request();
135
136 #ifdef CONFIG_MODEM_CALIBERATE
137         for(i = 0; i < 20; i++)
138                 buf[i] = i + 'a';
139
140         start_time = get_timer_masked();
141         printf("uart calibrate configuration start_time=%d\n", start_time);
142         while (1) {
143                 got = receive_caliberation_response(buf, sizeof(buf));
144                 if (caliberate_device == CALIBERATE_DEVICE_UART)
145                         break;
146
147                 now_time = get_timer_masked();
148                 if ((now_time - start_time) > CALIBRATE_ENUM_MS) {
149                         printf("usb calibrate configuration timeout\n");
150                         return -1;
151                 }
152         }
153
154         printf("caliberate : what got from host total %d is \n", got);
155         for (i = 0; i < got; i++)
156                 printf("0x%x ", buf[i]);
157         printf("\n");
158
159         caliberate_mode = check_caliberate(buf, CALIBERATE_STRING_LEN);
160         if (!caliberate_mode) {
161                 printf("func: %s line: %d caliberate failed\n", __func__, __LINE__);
162                 return -1;
163         } else {
164         calibration_cmd_buf=malloc(1024);
165         if(calibration_cmd_buf==NULL){
166             printf("%s: out of memory\n", __func__);
167             return -1;
168         }
169         memset(calibration_cmd_buf, 0, 1024);
170         if (caliberate_device == CALIBERATE_DEVICE_UART)
171                 sprintf(calibration_cmd_buf, " androidboot.mode=cali calibration=%d,%d,0", caliberate_mode&0xff, (caliberate_mode&(~0xff)) >> 8);
172         s_is_calibration_mode = 2;
173 #if defined(CONFIG_SC7710G2)
174         vlx_nand_boot(BOOT_PART, buf, BACKLIGHT_OFF);
175 #else
176         #if defined(BOOT_NATIVE_LINUX_MODEM)
177
178         int str_len = 0;
179         char* bootargs = CONFIG_BOOTARGS;
180         char* pos = NULL;
181         pos = strstr(bootargs, "console=");
182         if(NULL != pos)
183         {
184             str_len = pos-bootargs;
185             strncpy(&calibration_cmd_buf[0], bootargs, str_len);
186             bootargs = pos;
187             pos = strstr(bootargs, " ");
188         }
189         else
190         {
191             pos = CONFIG_BOOTARGS;
192             str_len = 0;
193         }
194         sprintf(&calibration_cmd_buf[str_len], "%s", pos);
195         str_len = strlen(calibration_cmd_buf);
196
197         if (caliberate_device == CALIBERATE_DEVICE_UART)
198             sprintf(&calibration_cmd_buf[str_len], " androidboot.mode=cali calibration=%d,%d,130 ", caliberate_mode&0xff, (caliberate_mode&(~0xff)) >> 8);
199         return CMD_CALIBRATION_MODE;
200         #else
201         return CMD_CALIBRATION_MODE;
202         #endif
203 #endif
204         }
205
206         /* nerver come to here */
207         return -1;
208 #endif
209 }
210
211 int check_pctool_cmd(uint8_t* buf, int len)
212 {
213     int command = 0;
214     unsigned int freq = 0;
215     MSG_HEAD_T* msg_head_ptr;
216     uint8_t* msg_ptr = buf + 1;
217     TOOLS_DIAG_AP_EXIT_CMD_T* msg_exit_prokey;
218     TOOLS_DIAG_AP_CMD_T* msg_enter_prokey;
219
220         if((*buf == CALIBERATE_HEAD) && (*(buf + len -1) == CALIBERATE_HEAD)){
221             msg_head_ptr = (MSG_HEAD_T*)(buf + 1);
222             switch(msg_head_ptr->type){
223                 case CALIBERATE_COMMOND_T:
224                                 command = msg_head_ptr->subtype;
225                                 command &= 0x3f;
226                     freq = *(buf+1);
227                     freq = freq<<8;
228                     freq += *(buf+2);
229                     command += freq<<8;
230                     break;
231                 case CALIBERATE_PROKEY_COMMOND_T:
232                     if(DIAG_AP_CMD_PROGRAM_KEY == *(msg_ptr + sizeof(MSG_HEAD_T))){
233                         msg_enter_prokey =  (TOOLS_DIAG_AP_CMD_T*)(msg_ptr + sizeof(MSG_HEAD_T));
234                         command = msg_enter_prokey->cmd;
235                     }
236                     else if(DIAG_AP_CMD_EXIT_PROGRAM_KEY == *(msg_ptr + sizeof(MSG_HEAD_T))){
237                         msg_exit_prokey = (TOOLS_DIAG_AP_EXIT_CMD_T*)(msg_ptr + sizeof(MSG_HEAD_T));
238                         command = msg_exit_prokey->para;
239                     }
240                             break;
241                 default:
242                     command = -1;
243                     break;
244                 }
245         }
246         printf("checked command from pc , and return value = %d \n" , command);
247         return command;
248 }
249
250 extern int power_button_pressed(void);
251 static int count_ms;
252 static unsigned long long start_time;
253 static unsigned long long now_time;
254
255 static int recheck_power_button(void)
256 {
257     int cnt = 0;
258     int ret = 0;
259     do{
260         ret = power_button_pressed();
261         if(ret == 0)
262           cnt++;
263         else
264           return 1;
265
266         if(cnt>4)
267           return 0;
268         else{
269             mdelay(1);
270         }
271     }while(1);
272 }
273 int is_timeout(void)
274 {
275
276     now_time = get_timer_masked();
277
278     if(now_time - start_time>count_ms)
279         return 1;
280     else{
281         return 0;
282     }
283 }
284
285 void cali_usb_debug(uint8_t *buf)
286 {   int ret;
287         int i ;
288         for(i = 0; i<20; i++)
289         buf[i] = i+'a';
290         while(!usb_serial_configed)
291                 usb_gadget_handle_interrupts();
292         printf("USB SERIAL CONFIGED\n");
293     gs_open();
294 #if WRITE_DEBUG
295                 while(1){
296                         ret = gs_write(buf, 20);
297                         printf("func: %s waitting write done\n", __func__);
298                         if(usb_trans_status)
299                                 printf("func: %s line %d usb trans with error %d\n", __func__, __LINE__, usb_trans_status);
300                         usb_wait_trans_done(1);
301                         printf("func: %s readly send %d\n", __func__, ret);
302                 }
303 #else
304                 while(1){
305                         int count = 20;
306                         usb_wait_trans_done(0);
307                         if(usb_trans_status)
308                                                 printf("func: %s line %d usb trans with error %d\n", __func__, __LINE__, usb_trans_status);
309                         ret = gs_read(buf, &count);
310                         printf("func: %s readly read %d\n", __func__, count);
311                         if(usb_trans_status)
312                                 printf("func: %s line %d usb trans with error %d\n", __func__, __LINE__, usb_trans_status);
313                         for(i = 0; i<count; i++)
314                                 printf("%c ", buf[i]);
315                         printf("\n");
316                 }
317
318 #endif
319 }
320 int cali_usb_prepare()
321 {
322         int ret = 0;
323         usb_in_cal(1);
324         if(dwc_otg_driver_init() < 0)
325                 {
326                         printf("%s\n", "dwc_otg_driver_init error");
327                         return 0;
328                 }
329         if(usb_serial_init() < 0)
330                 {
331                         printf("%s\n", "usb_serial_init error");
332                         return 0;
333                 }
334         return 1;
335 }
336 int cali_usb_enum()
337 {
338         int ret = 0;
339         count_ms = get_cal_enum_ms();
340         start_time = get_timer_masked();
341         while(!usb_is_configured()){
342                 ret = is_timeout();
343                 if(ret == 0)
344                         continue;
345                 else{
346                         printf("usb calibrate configuration timeout\n");
347                         return 0;
348                         }
349                 }
350         printf("USB SERIAL CONFIGED\n");
351
352         start_time = get_timer_masked();
353         count_ms = get_cal_io_ms();
354         while(!usb_is_port_open()){
355                 ret = is_timeout();
356                 if(ret == 0)
357                         continue;
358                 else{
359                         printf("usb calibrate port open timeout\n");
360                         return 0;
361                         }
362                 }
363         gs_open();
364         printf("USB SERIAL PORT OPENED\n");
365         return 1;
366 }
367 int cali_get_cmd(uint8_t *buf, int len)
368 {
369         int got = 0;
370         int count = len;
371         int ret = 0;
372         int i;
373         start_time = get_timer_masked();
374
375         while(got < len){
376                 if(usb_is_trans_done(0))
377                 {
378                         if(usb_trans_status)
379                                 printf("func: %s line %d usb trans with error %d\n", __func__, __LINE__, usb_trans_status);
380                         ret = gs_read(buf + got, &count);
381                         if(usb_trans_status)
382                                 printf("func: %s line %d usb trans with error %d\n", __func__, __LINE__, usb_trans_status);
383                         for(i=0; i<count; i++)
384                                 dprintf("0x%x \n", buf[got+i]);
385                         dprintf("\n");
386                         got+=count;
387                 }
388                 if(got<len){
389                         ret = is_timeout();
390                         if(ret == 0){
391                                 count=len-got;
392                                 continue;
393                                 }
394                         else{
395                                 printf("usb read timeout\n");
396                                 return 0;
397                                 }
398                 }else{
399                         break;
400                 }
401         }
402         printf("caliberate:what got from host total %d is \n", got);
403         for(i=0; i<got;i++)
404                 printf("0x%x ", buf[i]);
405         printf("\n");
406         return 1;
407 }
408
409 int reply_to_pctool(uint8_t* buf, int len)
410 {
411         gs_write(buf, len);
412         dprintf("func: %s waitting %d write done\n", __func__, len);
413         if(usb_trans_status)
414                 printf("func: %s line %d usb trans with error %d\n", __func__, __LINE__, usb_trans_status);
415         usb_wait_trans_done(1);
416         start_time = get_timer_masked();
417         count_ms = get_cal_io_ms();
418         while(!usb_port_open){
419                 usb_gadget_handle_interrupts();
420                 if(is_timeout())
421                         {
422                         printf("func: %s line %d usb trans timeout", __func__, __LINE__);
423                         return 0;
424                 }
425         }
426         return 1;
427 }
428
429 int translate_packet(char *dest,char *src,int size)
430 {
431     int i;
432     int translated_size = 0;
433
434     dest[translated_size++] = 0x7E;
435
436     for(i=0;i<size;i++){
437         if(src[i] == 0x7E){
438             dest[translated_size++] = 0x7D;
439             dest[translated_size++] = 0x5E;
440         } else if(src[i] == 0x7D) {
441             dest[translated_size++] = 0x7D;
442             dest[translated_size++] = 0x5D;
443         } else
444             dest[translated_size++] = src[i];
445     }
446     dest[translated_size++] = 0x7E;
447     return translated_size;
448 }
449
450 int prepare_reply_buf(uint8_t* buf, int status)
451 {
452     int ret = 0;
453     char *rsp_ptr;
454     MSG_HEAD_T* msg_head_ptr;
455     TOOLS_DIAG_AP_CNF_T* aprsp;
456         int total_len,rsplen;
457         printf("preparing reply buf");
458     if(NULL == buf){
459             printf("in function prepare_reply_buf, buf = NULL\n");
460         return 0;
461     }
462
463     msg_head_ptr = (MSG_HEAD_T*)(buf + 1);
464     rsplen = sizeof(TOOLS_DIAG_AP_CNF_T) + sizeof(MSG_HEAD_T);
465     rsp_ptr = (char*)malloc(rsplen);
466     if(NULL == rsp_ptr){
467             printf("in function prepare_reply_buf: Buffer malloc failed\n");
468             return 0;
469     }
470     aprsp = (TOOLS_DIAG_AP_CNF_T*)(rsp_ptr + sizeof(MSG_HEAD_T));
471         msg_head_ptr->len = rsplen;
472     memcpy(rsp_ptr,msg_head_ptr,sizeof(MSG_HEAD_T));
473
474     aprsp->status = status;
475     aprsp->length = CALIBERATE_CNF_LEN;
476
477     total_len = translate_packet((unsigned char*)pctool_cnf_buf,(unsigned char*)rsp_ptr,((MSG_HEAD_T*)rsp_ptr)->len);
478     free(rsp_ptr);
479     return total_len;
480 }
481
482 int pctool_mode_detect(void)
483 {
484
485         int ret , command;
486         unsigned int caliberate_mode;
487         loff_t off = 0;
488         printf("%s\n", "uart cooperating with pc tool");
489         if(get_mode_from_gpio())
490              return pctool_mode_detect_uart();
491
492         printf("%s\n", "usb cooperating with pc tool");
493
494         if(!charger_connected())
495                 return -1;
496
497         ret = cali_usb_prepare();
498         if (!ret)
499                 return -1;
500
501 #if IO_DEBUG
502         cali_usb_debug(pctool_cmd_buf);
503 #endif
504         ret = cali_usb_enum();
505         if (!ret)
506                 return -1;
507         ret = cali_get_cmd(pctool_cmd_buf, CALIBERATE_STRING_LEN );
508         if (!ret)
509                 return -1;
510         command = check_pctool_cmd(pctool_cmd_buf, CALIBERATE_STRING_LEN);
511         printf("func: %s caliberate_mode: %x \n",__func__, command&0xff);
512         if (!command)
513                 {
514                 printf("func: %s line: %d caliberate failed\n", __func__, __LINE__);
515                 return -1;
516                 }
517         ret = reply_to_pctool(pctool_cmd_buf, CALIBERATE_STRING_LEN);
518         if(!ret)
519                 return -1;
520 #ifdef CONFIG_SECURE_BOOT
521         if (CALIBERATE_COMMAND_PROGRAMKEY == command)
522                 {
523                         ret = cali_get_cmd(pctool_cmd_buf, CALIBERATE_STRING_LEN_14);
524                         if(!ret)
525                                 return -1;
526                         command = check_pctool_cmd(pctool_cmd_buf, CALIBERATE_STRING_LEN_14);
527                         if(!command)
528                                 return -1;
529                         else if(command = DIAG_AP_CMD_PROGRAM_KEY)
530                         {
531                                 ret = secure_efuse_program();//jiekou_from_beijing;
532                         }
533             if(!ret)
534                 ret = prepare_reply_buf(pctool_cmd_buf ,CALIBERATE_CNF_SCS);
535             else{
536                                 printk("write efuse failed and error code = %d \n" , ret);
537                 ret = prepare_reply_buf(pctool_cmd_buf , CALIBERATE_CNF_FAIL);
538             }
539                         if(ret)
540                                 ret = reply_to_pctool(pctool_cnf_buf, ret);
541             if(!ret)
542                     return -1;
543                         ret = cali_get_cmd(pctool_cmd_buf,CALIBERATE_STRING_LEN_16);
544                         if(!ret)
545                                 return -1;
546             command = check_pctool_cmd(pctool_cmd_buf , CALIBERATE_STRING_LEN_16);
547             if(!command)
548                                 return -1;
549                         switch(command){
550                                 case 0xffff:
551                                         ret = prepare_reply_buf(pctool_cmd_buf ,CALIBERATE_CNF_SCS);
552                                         ret = reply_to_pctool(pctool_cnf_buf, ret);
553                                         return CMD_POWER_DOWN_DEVICE;
554                                         break;
555                                 case 0xfffe:
556                                         ret = prepare_reply_buf(pctool_cmd_buf ,CALIBERATE_CNF_SCS);
557                                         ret = reply_to_pctool(pctool_cnf_buf, ret);
558                                         return CMD_CHARGE_MODE;
559                                         break;
560                                 default:
561                                         ret = prepare_reply_buf(pctool_cmd_buf ,CALIBERATE_CNF_SCS);
562                                         ret = reply_to_pctool(pctool_cnf_buf, ret);
563                                         break;
564                     }
565         }
566 #endif
567         calibration_cmd_buf=malloc(1024);
568        if(calibration_cmd_buf==NULL){
569            printf("%s: out of memory\n", __func__);
570            return -1;
571        }
572         memset(calibration_cmd_buf, 0, 1024);
573     s_is_calibration_mode=1;
574         switch (command & 0xff){
575                 case CALIBERATE_COMMAND_AUTOTEST:
576                         sprintf(calibration_cmd_buf, CONFIG_BOOTARGS" androidboot.mode=engtest autotest=1");
577                         ret = CMD_AUTOTEST_MODE;
578                         udc_power_off();
579                         break;
580                 default:
581                         sprintf(calibration_cmd_buf,CONFIG_BOOTARGS" androidboot.mode=cali calibration=%d,%d,146 \n", command&0xff, (command&(~0xff))>>8);
582                         ret = CMD_CALIBRATION_MODE;
583                         udc_power_off();
584                         break;
585     }
586         return ret;
587 }
588
589
590 int poweron_by_calibration(void)
591 {
592         return s_is_calibration_mode;
593 }
594
595 int cali_file_check(void)
596 {
597
598 #define CALI_MAGIC      (0x49424143) //CALI
599 #define CALI_COMP       (0x504D4F43) //COMP
600
601
602         if(do_fs_file_read("prodnv", "/adc.bin", (char *)nv_buffer,sizeof(nv_buffer)))
603                 return 1;
604
605         if((nv_buffer[0] != CALI_MAGIC)||(nv_buffer[1]!=CALI_COMP))
606                 return 1;
607         else
608                 return 0;
609 }
610
611 #ifndef CONFIG_AP_ADC_CALIBRATION
612 #if defined(CONFIG_EMMC_BOOT) && defined (CONFIG_SC8825)
613 #include "calibration_nv_struct.h"
614
615 #define VLX_ADC_ID   2
616 #define VLX_RAND_TO_U32( _addr )        if( (_addr) & 0x3 ){_addr += 0x4 -((_addr) & 0x3); }
617
618 u32 Vlx_GetFixedNvitemAddr(u16 identifier, u32 search_start, u32 search_end)
619 {
620         u32 start_addr, end_addr;
621         u16 id, len;
622         volatile u16 *flash_ptr;
623
624         start_addr = search_start;
625         end_addr   = search_end;
626         start_addr += sizeof(u32); //skip update flag
627
628         while(start_addr < end_addr)
629         {
630                 flash_ptr = (volatile u16 *)(start_addr);
631                 id  = *flash_ptr++;
632                 len = *flash_ptr;
633                 if(0xFFFF == id)
634                 {
635                         return 0xFFFFFFFF;
636                 }
637                 if(identifier == id)
638                 {
639                         return (start_addr + 4);
640                 }
641                 else
642                 {
643                         start_addr += 4 + len +(len & 0x1);
644                         VLX_RAND_TO_U32( start_addr )
645                 }
646         }
647         return 0xFFFFFFFF;
648 }
649 #endif
650
651 int read_adc_calibration_data(char *buffer,int size)
652 {
653 #if  defined (CONFIG_SC8830) || defined (CONFIG_SC9630)
654 #if 0
655         if(do_fs_file_read("prodnv", "/adc.bin", (char *)nv_buffer,sizeof(nv_buffer)))
656                 return 0;
657 #endif
658         if(size>48)
659                 size=48;
660         memcpy(buffer,&nv_buffer[2],size);
661         return size;
662 #elif defined(CONFIG_EMMC_BOOT) && defined (CONFIG_SC8825)
663         #define FIXNV_ADR        0x80480000
664         calibration_param_T *calibration_base;
665         u32 item_base;
666         uint16 *value = (uint16 *)(&buffer[8]);
667         item_base = Vlx_GetFixedNvitemAddr(VLX_ADC_ID, FIXNV_ADR, (FIXNV_ADR+FIXNV_SIZE));
668         if(item_base == 0xFFFFFFFF)
669                 return 0;
670         calibration_base = (calibration_param_T *)item_base;
671         if(!((calibration_base->adc).reserved[7] & (BIT_9)))
672                 return 0;
673
674         value[0] = ((calibration_base->adc).battery[0]) & 0xFFFF;
675         value[1] = ((calibration_base->adc).battery[0] >> 16 ) & 0xFFFF;
676         value[2] = ((calibration_base->adc).battery[1]) & 0xFFFF;
677         value[3] = ((calibration_base->adc).battery[1] >> 16 ) & 0xFFFF;
678         return size;
679 #endif
680         return 0;
681 }
682 #endif