MIPS平台suspend/resume时GPIO状态控制

这两天在调一款触摸屏的驱动,在调试过程中发现,在休眠的时候,所用到的几个GPIO引脚的状态会自动变为低电平,在唤醒后又会回到高电平。但是在代码里并没有显式地去拉低/拉高。很明显这不是我们想要的,如果这样的话,GPIO的状态都无法自己控制,还怎么调呢?

         问了下板子的FAE,GPIO的状态在休眠时,是预定义的。代码在

arch/mips/jz4770/boards/gps1/gps1-pm.c

其中gps1是板子类型

[cpp] view plain copy
  1. 29 int gpio_sleep_state_table[][2] = {  
  2. 30     /* GPIO Group - A */  
  3. 31     {32 * 0 +  0,   GSS_INPUT_NOPULL}, /* NC */  
  4. 32     {32 * 0 +  1,   GSS_INPUT_PULL  }, /* ACC_INT2 input pull*/  
  5. 33     {32 * 0 +  2,   GSS_IGNORE      }, /* FVDD_EN */  
  6. 34     {32 * 0 +  3,   GSS_INPUT_NOPULL}, /* SCLK */  
  7. 35     {32 * 0 +  4,   GSS_INPUT_NOPULL}, /* NC */  
  8. 36     {32 * 0 +  5,   GSS_INPUT_NOPULL}, /* NC */  
  9. 37     {32 * 0 +  6,   GSS_INPUT_NOPULL}, /* PA6/SDATA */  
  10. 38     {32 * 0 +  7,   GSS_INPUT_NOPULL}, /* NC */  
  11. 39     {32 * 0 +  8,   GSS_INPUT_NOPULL}, /* NC */  
  12. 40     {32 * 0 +  9,   GSS_INPUT_PULL  }, /* ACC_INT1 input pull*/  
  13. 41     {32 * 0 + 10,   GSS_INPUT_NOPULL}, /* NC */  
  14. 42     {32 * 0 + 11,   GSS_INPUT_NOPULL}, /* NC */  
  15. 43     {32 * 0 + 12,   GSS_INPUT_NOPULL}, /* NC */  
  16. 44     {32 * 0 + 13,   GSS_INPUT_NOPULL}, /* NC */  
  17. 45     {32 * 0 + 14,   GSS_INPUT_NOPULL}, /* NC */  
  18. 46     {32 * 0 + 15,   GSS_INPUT_NOPULL}, /* NC */  
  19. 47     {32 * 0 + 16,   GSS_INPUT_NOPULL}, /* NC */  
[cpp] view plain copy
  1. ....  

这里进行了所有GPIO在休眠时的状态的预定义。

在arch/mips/jz4770/common/pm.c中

[cpp] view plain copy
  1. 509 int __init gpio_sleep_state_check(void)  
  2. 510 {  
  3. 511     unsigned int i,state,group,index;  
  4. 512     unsigned int panic_flags[6] = {0,};  
  5. 513   
  6. 514     for(i = 0; i < GPIO_PORT_NUM; i++)  
  7. 515         gpio_intput_pull[i] = 0xffffffff;  
  8. 516   
  9. 517     for(i = 0; gpio_sleep_state_table[i][1] != GSS_TABLET_END;i++) {  
  10. 518         group = gpio_sleep_state_table[i][0] / 32;  
  11. 519         index = gpio_sleep_state_table[i][0] % 32;  
  12. 520         state = gpio_sleep_state_table[i][1];  
  13. 521   
  14. 522         gpio_intput_pull[group] = gpio_intput_pull[group] & ~(1 << index);  
  15. 523         if(panic_flags[group] & (1 << index)) {  
  16. 524             printk("\nwarning : (%d line) same gpio already set before this line!\n",i);  
  17. 525             printk("\nwarning : (%d line) same gpio already set before this line!\n",i);  
  18. 526             printk("\nwarning : (%d line) same gpio already set before this line!\n",i);  
  19. 527             printk("\nwarning : (%d line) same gpio already set before this line!\n",i);  
  20. 528             printk("\nwarning : (%d line) same gpio already set before this line!\n",i);  
  21. 529             printk("\nwarning : (%d line) same gpio already set before this line!\n",i);  
  22. 530             printk("\nwarning : (%d line) same gpio already set before this line!\n",i);  
  23. 531             panic("gpio_sleep_state_table has iterant gpio set , system halt\n");  
  24. 532             while(1);  
  25. 533         } else {  
  26. 534             panic_flags[group] |= 1 << index;  
  27. 535         }  
  28. 536   
[cpp] view plain copy
  1.            <span style="color:#ff0000;"//这里对预设的各种状态进行处理</span>  
  2. 537         switch(state) {  
  3. 538             case GSS_OUTPUT_HIGH:gpio_output_high[group] |= 1 << index;break;  
  4. 539             case GSS_OUTPUT_LOW:gpio_output_low[group] |= 1 << index;break;  
  5. 540             case GSS_INPUT_PULL:gpio_intput_pull[group] |= 1 << index;break;  
  6. 541             case GSS_INPUT_NOPULL:gpio_intput_nopull[group] |= 1 << index;break;  
  7. 542         }  
  8. 543     }  
  9. 544   
  10. 545     for(i = 0; i < GPIO_PORT_NUM; i++) {  
  11. 546         printk("%8x\t\t", gpio_output_low[i]);  
  12. 547         printk("%8x\t\t", gpio_output_high[i]);  
  13. 548         printk("%8x\t\t", gpio_intput_pull[i]);  
  14. 549         printk("%8x\n", gpio_intput_nopull[i]);  
  15. 550     }  
  16. 551   
  17. 552     return 0;  
  18. 553 }  


在进行suspend的时候,跑到这里对预设的GPIO进行设置
[cpp] view plain copy
  1.  98 void jzsoc_do_sleep(unsigned long *ptr)  
  2.  99 {  
  3. 100     unsigned char i;  
  4. 101   
  5. 102     /* Print messages of GPIO registers for debug */  
  6. 103     print_gpio();  
  7. 104     /* Save GPIO registers */  
  8. 105   
  9. 106     for(i = 0; i < GPIO_PORT_NUM; i++) {  
  10. 107         *ptr++ = REG_GPIO_PXINT(i);  
  11. 108         *ptr++ = REG_GPIO_PXMSK(i);  
  12. 109         *ptr++ = REG_GPIO_PXPAT1(i);  
  13. 110         *ptr++ = REG_GPIO_PXPAT0(i);  
  14. 111         *ptr++ = REG_GPIO_PXPEN(i);  
  15. 112     }  
  16. 113   
  17. 114     for(i = 0; i < GPIO_PORT_NUM; i++) {  
  18. 115         __gpio_group_as_output_low(i, gpio_output_low[i]);  
  19. 116         __gpio_group_as_output_high(i, gpio_output_high[i]);  
  20. 117         __gpio_group_as_input_pull(i, gpio_intput_pull[i]);  
  21. 118         __gpio_group_as_input_nopull(i, gpio_intput_nopull[i]);  
  22. 119     }  

如果我们想需要手动进行管理需要的GPIO口,只需要将预设的状态改为GSS_IGNORE即可。

原文链接http://blog.csdn.net/laojing123/article/details/8131801

你可能感兴趣的:(MIPS平台suspend/resume时GPIO状态控制)