Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. #include "pxa255_GPIO.h"
  2. #include "mem.h"
  3.  
  4.  
  5. static void pxa255gpioPrvRecalcValues(Pxa255gpio* gpio, UInt32 which){
  6.        
  7.         UInt8 i;
  8.         UInt32 val, bit;
  9.        
  10.         val = gpio->dirs[which];
  11.         gpio->levels[which] = (gpio->latches[which] & val) | (gpio->inputs[which] & (~val));
  12.        
  13.         val = 3;
  14.         bit = 1;
  15.         for(i = 0 ; i < 16; i++, val <<= 2, bit <<= 1) if(gpio->AFRs[(which << 1) + 0] & val) gpio->levels[which] &=~ bit;      //all AFRs read as zero to CPU
  16.         for(i = 16; i < 32; i++, val <<= 2, bit <<= 1) if(gpio->AFRs[(which << 1) + 1] & val) gpio->levels[which] &=~ bit;      //all AFRs read as zero to CPU
  17. }
  18.  
  19. static void pxa255gpioPrvRecalcIntrs(Pxa255gpio* gpio){
  20.        
  21.         pxa255icInt(gpio->ic, PXA255_I_GPIO_all, gpio->levels[1] || gpio->levels[2] || (gpio->levels[0] &~ 3));
  22.         pxa255icInt(gpio->ic, PXA255_I_GPIO_1, (gpio->levels[0] & 2) != 0);
  23.         pxa255icInt(gpio->ic, PXA255_I_GPIO_0, (gpio->levels[0] & 1) != 0);
  24. }
  25.  
  26. static Boolean pxa255gpioPrvMemAccessF(void* userData, UInt32 pa, UInt8 size, Boolean write, void* buf){
  27.  
  28.         Pxa255gpio* gpio = userData;
  29.         UInt32 val = 0;
  30.        
  31.         if(size != 4) {
  32.                 err_str(__FILE__ ": Unexpected ");
  33.         //      err_str(write ? "write" : "read");
  34.         //      err_str(" of ");
  35.         //      err_dec(size);
  36.         //      err_str(" bytes to 0x");
  37.         //      err_hex(pa);
  38.         //      err_str("\r\n");
  39.                 return true;            //we do not support non-word accesses
  40.         }
  41.        
  42.         pa = (pa - PXA255_GPIO_BASE) >> 2;
  43.        
  44.         if(write){
  45.                 val = *(UInt32*)buf;
  46.                
  47.                 switch(pa){
  48.                         case 0:
  49.                         case 1:
  50.                         case 2:
  51.                                
  52.                                 break;
  53.                        
  54.                         case 3:
  55.                         case 4:
  56.                         case 5:
  57.                                 pa -= 3;
  58.                                 gpio->dirs[pa] = val;
  59.                                 goto recalc;
  60.                        
  61.                         case 6:
  62.                         case 7:
  63.                         case 8:
  64.                                 pa -= 6;
  65.                                 gpio->levels[pa] |= val;
  66.                                 goto recalc;
  67.                        
  68.                         case 9:
  69.                         case 10:
  70.                         case 11:
  71.                                 pa -= 9;
  72.                                 gpio->levels[pa] &=~ val;
  73.                                 goto recalc;
  74.                        
  75.                         case 12:
  76.                         case 13:
  77.                         case 14:
  78.                                 gpio->riseDet[pa - 12] = val;
  79.                                 break;
  80.                        
  81.                         case 15:
  82.                         case 16:
  83.                         case 17:
  84.                                 gpio->fallDet[pa - 15] = val;
  85.                                 break;
  86.                        
  87.                         case 18:
  88.                         case 19:
  89.                         case 20:
  90.                                 gpio->detStatus[pa - 18] &=~ val;
  91.                                 goto trigger_intrs;
  92.                        
  93.                         case 21:
  94.                         case 22:
  95.                         case 23:
  96.                         case 24:
  97.                         case 25:
  98.                         case 26:
  99.                                 val = gpio->AFRs[pa - 21];
  100.                                 goto recalc;
  101.                 }
  102.                
  103.                 goto done;
  104.                
  105. recalc:
  106.                 pxa255gpioPrvRecalcValues(gpio, pa);
  107.                
  108. trigger_intrs:
  109.                 pxa255gpioPrvRecalcIntrs(gpio);
  110.         }
  111.         else{
  112.                 switch(pa){
  113.                         case 0:
  114.                         case 1:
  115.                         case 2:
  116.                                 val = gpio->levels[pa - 0];
  117.                                 break;
  118.                        
  119.                         case 3:
  120.                         case 4:
  121.                         case 5:
  122.                                 val = gpio->dirs[pa - 3];
  123.                                 break;
  124.                        
  125.                         case 6:
  126.                         case 7:
  127.                         case 8:
  128.                         case 9:
  129.                         case 10:
  130.                         case 11:
  131.                                 val = 0;
  132.                                 break;
  133.                        
  134.                         case 12:
  135.                         case 13:
  136.                         case 14:
  137.                                 val = gpio->riseDet[pa - 12];
  138.                                 break;
  139.                        
  140.                         case 15:
  141.                         case 16:
  142.                         case 17:
  143.                                 val = gpio->fallDet[pa - 15];
  144.                                 break;
  145.                        
  146.                         case 18:
  147.                         case 19:
  148.                         case 20:
  149.                                 val = gpio->detStatus[pa - 18];
  150.                                 break;
  151.                        
  152.                         case 21:
  153.                         case 22:
  154.                         case 23:
  155.                         case 24:
  156.                         case 25:
  157.                         case 26:
  158.                                 val = gpio->AFRs[pa - 21];
  159.                                 break;
  160.                        
  161.                 }
  162.                 *(UInt32*)buf = val;
  163.         }
  164.        
  165. done:
  166.         return true;
  167. }
  168.  
  169.  
  170. Boolean pxa255gpioInit(Pxa255gpio* gpio, ArmMem* physMem, Pxa255ic* ic){
  171.        
  172.         __mem_zero(gpio, sizeof(Pxa255gpio));
  173.         gpio->ic = ic;
  174.        
  175.         return memRegionAdd(physMem, PXA255_GPIO_BASE, PXA255_GPIO_SIZE, pxa255gpioPrvMemAccessF, gpio);
  176. }
  177.  
  178. void pxa255gpioSetState(Pxa255gpio* gpio, UInt8 gpioNum, Boolean on){
  179.        
  180.         UInt32 set = gpioNum >> 5;
  181.         UInt32 v = 1UL << (gpioNum & 0x1F);
  182.         UInt32* p;
  183.        
  184.         if(gpioNum >= 85) return;
  185.        
  186.         p =  gpio->inputs + set;
  187.         if(on) *p |= v;
  188.         else *p &=~ v;
  189.        
  190.         pxa255gpioPrvRecalcValues(gpio, set);
  191.         pxa255gpioPrvRecalcIntrs(gpio);
  192. }
  193.  
  194. UInt8 pxa255gpioGetState(Pxa255gpio* gpio, UInt8 gpioNum){
  195.        
  196.         UInt32 sSet = gpioNum >> 5;
  197.         UInt32 bSet = gpioNum >> 4;
  198.         UInt32 sV = 1UL << (gpioNum & 0x1F);
  199.         UInt32 bV = 3UL << (gpioNum & 0x0F);
  200.        
  201.        
  202.         if(gpioNum >= 85) return PXA255_GPIO_NOT_PRESENT;
  203.         if(gpio->AFRs[bSet] & bV) return ((gpio->AFRs[bSet] & bV) >> (gpioNum & 0x0F)) + PXA255_GPIO_AFR1;
  204.         if(gpio->dirs[sSet] & sV) return (gpio->latches[sSet] & sV) ? PXA255_GPIO_HIGH : PXA255_GPIO_LOW;
  205.         return PXA255_GPIO_HiZ;
  206. }
  207.