MIPS 플랫폼suspend/resume 시 GPIO 상태 제어

4886 단어
이틀 동안 터치스크린의 구동을 조정했는데 디버깅 과정에서 수면을 취할 때 사용하는 몇 개의 GPIO가 발을 끄는 상태가 자동으로 저전평으로 변하고 깨어난 후에 다시 고전평으로 돌아가는 것을 발견했다.그러나 코드에서는 현저하게 낮추거나 높이지 않았다.분명히 이것은 우리가 원하는 것이 아니다. 만약 이렇다면 GPIO의 상태도 스스로 제어할 수 없는데 어떻게 조정할 것인가?
보드를 내리는 FAE에 물어봤는데 GPIO의 상태가 휴면에 있을 때 미리 정의된 것이다.코드
arch/mips/jz4770/boards/gps1/gps1-pm.c
그중 gps1은 판자 타입입니다.
 29 int gpio_sleep_state_table[][2] = {
 30     /* GPIO Group - A */
 31     {32 * 0 +  0,   GSS_INPUT_NOPULL}, /* NC */
 32     {32 * 0 +  1,   GSS_INPUT_PULL  }, /* ACC_INT2 input pull*/
 33     {32 * 0 +  2,   GSS_IGNORE      }, /* FVDD_EN */
 34     {32 * 0 +  3,   GSS_INPUT_NOPULL}, /* SCLK */
 35     {32 * 0 +  4,   GSS_INPUT_NOPULL}, /* NC */
 36     {32 * 0 +  5,   GSS_INPUT_NOPULL}, /* NC */
 37     {32 * 0 +  6,   GSS_INPUT_NOPULL}, /* PA6/SDATA */
 38     {32 * 0 +  7,   GSS_INPUT_NOPULL}, /* NC */
 39     {32 * 0 +  8,   GSS_INPUT_NOPULL}, /* NC */
 40     {32 * 0 +  9,   GSS_INPUT_PULL  }, /* ACC_INT1 input pull*/
 41     {32 * 0 + 10,   GSS_INPUT_NOPULL}, /* NC */
 42     {32 * 0 + 11,   GSS_INPUT_NOPULL}, /* NC */
 43     {32 * 0 + 12,   GSS_INPUT_NOPULL}, /* NC */
 44     {32 * 0 + 13,   GSS_INPUT_NOPULL}, /* NC */
 45     {32 * 0 + 14,   GSS_INPUT_NOPULL}, /* NC */
 46     {32 * 0 + 15,   GSS_INPUT_NOPULL}, /* NC */
 47     {32 * 0 + 16,   GSS_INPUT_NOPULL}, /* NC */
....

여기에는 모든 GPIO가 휴면 상태에 대한 사전 정의가 있습니다.
arch/mips/jz4770/common/pm.c 중
509 int __init gpio_sleep_state_check(void)
510 {
511     unsigned int i,state,group,index;
512     unsigned int panic_flags[6] = {0,};
513 
514     for(i = 0; i < GPIO_PORT_NUM; i++)
515         gpio_intput_pull[i] = 0xffffffff;
516 
517     for(i = 0; gpio_sleep_state_table[i][1] != GSS_TABLET_END;i++) {
518         group = gpio_sleep_state_table[i][0] / 32;
519         index = gpio_sleep_state_table[i][0] % 32;
520         state = gpio_sleep_state_table[i][1];
521 
522         gpio_intput_pull[group] = gpio_intput_pull[group] & ~(1 << index);
523         if(panic_flags[group] & (1 << index)) {
524             printk("
warning : (%d line) same gpio already set before this line!
",i); 525 printk("
warning : (%d line) same gpio already set before this line!
",i); 526 printk("
warning : (%d line) same gpio already set before this line!
",i); 527 printk("
warning : (%d line) same gpio already set before this line!
",i); 528 printk("
warning : (%d line) same gpio already set before this line!
",i); 529 printk("
warning : (%d line) same gpio already set before this line!
",i); 530 printk("
warning : (%d line) same gpio already set before this line!
",i); 531 panic("gpio_sleep_state_table has iterant gpio set , system halt
"); 532 while(1); 533 } else { 534 panic_flags[group] |= 1 << index; 535 } 536 
            //              
537         switch(state) {
538             case GSS_OUTPUT_HIGH:gpio_output_high[group] |= 1 << index;break;
539             case GSS_OUTPUT_LOW:gpio_output_low[group] |= 1 << index;break;
540             case GSS_INPUT_PULL:gpio_intput_pull[group] |= 1 << index;break;
541             case GSS_INPUT_NOPULL:gpio_intput_nopull[group] |= 1 << index;break;
542         }
543     }
544 
545     for(i = 0; i < GPIO_PORT_NUM; i++) {
546         printk("%8x\t\t", gpio_output_low[i]);
547         printk("%8x\t\t", gpio_output_high[i]);
548         printk("%8x\t\t", gpio_intput_pull[i]);
549         printk("%8x
", gpio_intput_nopull[i]); 550 } 551 552 return 0; 553 }

suspend를 진행할 때, 여기로 달려가서 미리 설정한 GPIO를 설정합니다
 98 void jzsoc_do_sleep(unsigned long *ptr)
 99 {
100     unsigned char i;
101 
102     /* Print messages of GPIO registers for debug */
103     print_gpio();
104     /* Save GPIO registers */
105 
106     for(i = 0; i < GPIO_PORT_NUM; i++) {
107         *ptr++ = REG_GPIO_PXINT(i);
108         *ptr++ = REG_GPIO_PXMSK(i);
109         *ptr++ = REG_GPIO_PXPAT1(i);
110         *ptr++ = REG_GPIO_PXPAT0(i);
111         *ptr++ = REG_GPIO_PXPEN(i);
112     }
113 
114     for(i = 0; i < GPIO_PORT_NUM; i++) {
115         __gpio_group_as_output_low(i, gpio_output_low[i]);
116         __gpio_group_as_output_high(i, gpio_output_high[i]);
117         __gpio_group_as_input_pull(i, gpio_intput_pull[i]);
118         __gpio_group_as_input_nopull(i, gpio_intput_nopull[i]);
119     }

필요한 GPIO 포트를 수동으로 관리하려면 미리 설정된 상태를 GSS 로 변경하면 됩니다.IGNORE

좋은 웹페이지 즐겨찾기