66 #include <sys/types.h> 70 #include "rnr/rnrconfig.h" 77 #if defined(ARCH_odroid) 83 #define MAP_SIZE 4096UL 84 #define MAP_MASK (MAP_SIZE - 1)
91 #define EXYNOS4_PA_GPIO1 0x11400000 92 #define EXYNOS_5410 0x13400000
93 #define EXYNOS_5422 0x13400000
95 #if defined(ODROIDXU3) 96 #define EXYNOS EXYNOS_5422 98 #elif defined(ODROIDXU) 99 #define EXYNOS EXYNOS_5410 101 #elif defined(ODROIDX2) 102 #define EXYNOS EXYNOS4_PA_GPIO1 105 #error "Unknown Odroid version" 108 #define GPIO_GPCONREG 4 // subtract 4 from DATA register base to get CON reg 109 #define GPIO_UPDOWN 4 // add 4 to DATA register base to get UPD register 110 #define GPIO_DRIVESTR 8 // add 8 to DATA register base to get drive str ctl reg 140 #if defined(ODROIDXU3) 145 static gpio_sysfs_t GpioSysfsTbl[] =
147 {4, 173}, {5, 174}, {6, 171}, {7, 192},
148 {8, 172}, {9, 191}, {10, 189}, {11, 190},
149 {13, 21}, {14, 210}, {15, 18}, {16, 209},
150 {17, 22}, {18, 19}, {19, 30}, {20, 28},
151 {21, 29}, {22, 31}, {24, 25}, {26, 24}
160 static gpio_address_t PinAddrTbl[] =
196 {0x0c24,6}, {0x0c24,3},
199 {0x0c44,6}, {0x0c44,4},
202 {0x0c44,5}, {0x0c44,7},
205 {0x0c44,2}, {0x0c44,1},
208 {0x0c24,7}, {0x0c44,0},
223 static gpio_address_t GpioAddrTbl[514];
230 static void mmapFillLookupTbl()
232 memset(GpioAddrTbl, 0,
sizeof(GpioAddrTbl));
235 GpioAddrTbl[18].channel = 0x0c24;
236 GpioAddrTbl[18].bit = 2;
239 GpioAddrTbl[19].channel = 0x0c24;
240 GpioAddrTbl[19].bit = 3;
243 GpioAddrTbl[21].channel = 0x0c24;
244 GpioAddrTbl[21].bit = 5;
247 GpioAddrTbl[22].channel = 0x0c24;
248 GpioAddrTbl[22].bit = 6;
251 GpioAddrTbl[24].channel = 0x0c44;
252 GpioAddrTbl[24].bit = 0;
255 GpioAddrTbl[25].channel = 0x0c44;
256 GpioAddrTbl[25].bit = 1;
259 GpioAddrTbl[28].channel = 0x0c44;
260 GpioAddrTbl[28].bit = 4;
263 GpioAddrTbl[29].channel = 0x0c44;
264 GpioAddrTbl[29].bit = 5;
267 GpioAddrTbl[30].channel = 0x0c44;
268 GpioAddrTbl[30].bit = 6;
271 GpioAddrTbl[31].channel = 0x0c44;
272 GpioAddrTbl[31].bit = 7;
275 #elif defined(ODROIDXU) || defined(ODROIDX2) 280 static gpio_sysfs_t GpioSysfsTbl[] =
282 {13, 309}, {14, 316}, {15, 306}, {16, 304},
283 {17, 310}, {18, 307}, {19, 319}, {20, 317},
284 {21, 318}, {22, 320}, {23, 315}, {24, 314},
285 {25, 311}, {26, 313}, {27, 323}
293 static gpio_address_t GpioAddrTbl[] =
316 {0x0c24,5}, {0x0c44,3},
319 {0x0c24,2}, {0x0c24,0},
322 {0x0c24,6}, {0x0c24,3},
325 {0x0c44,6}, {0x0c44,4},
328 {0x0c44,5}, {0x0c44,7},
331 {0x0c44,2}, {0x0c44,1},
334 {0x0c24,7}, {0x0c44,0},
343 #endif // defined(ODROIDXU) || defined(ODROIDX2) 345 static void *MapBase;
354 static int hasmap(
int gpio)
356 if( (gpio < 0) || (gpio >= arraysize(GpioAddrTbl)) )
360 else if( (GpioAddrTbl[gpio].channel == 0) && (GpioAddrTbl[gpio].bit == 0) )
370 static const char *ErrStrNoMapFound =
"GPIO block has not been memory mapped.";
371 static const char *ErrStrGpioNoMap =
"No memory mapped address offset found.";
378 int gpioExportedToPin(
int gpio)
382 for(i=0; i<arraysize(GpioSysfsTbl); ++i)
384 if( GpioSysfsTbl[i].gpio == gpio )
386 return GpioSysfsTbl[i].pin;
392 int gpioPinToExported(
int pin)
396 for(i=0; i<arraysize(GpioSysfsTbl); ++i)
398 if( GpioSysfsTbl[i].pin == pin )
400 return GpioSysfsTbl[i].gpio;
409 off_t target = EXYNOS;
413 if( (fd = open(
"/dev/mem", O_RDWR | O_SYNC)) == -1 )
415 LOGSYSERROR(
"Could not open /dev/mem device.");
422 PROT_READ | PROT_WRITE,
425 target & (off_t)~MAP_MASK);
429 if( MapBase == (
void *) -1 )
431 LOGSYSERROR(
"Memory map failed.");
437 LOGDIAG3(
"Memory mapped GPIO setup at address 0x%0lx.", target);
446 LOGWARN(
"%s", ErrStrNoMapFound);
449 else if( munmap(MapBase, MAP_SIZE) == -1 )
451 LOGSYSERROR(
"Memory unmap failed.");
457 LOGDIAG3(
"Memory mapped GPIO torn down.");
462 int mmapGpioSetDirection(
int gpio,
int dir)
470 if( MapBase == NULL )
472 LOGERROR(
"%s", ErrStrNoMapFound);
478 LOGERROR(
"GPIO %d: %s", gpio, ErrStrGpioNoMap);
482 channel = GpioAddrTbl[gpio].channel;
483 bit = GpioAddrTbl[gpio].bit;
485 base = (MapBase + channel) - GPIO_GPCONREG;
487 div_res = div(bit, 2);
489 base += div_res.quot;
492 val = *(byte_t *)base;
532 LOGERROR(
"GPIO %d: Invalid direction. Must be one of: %d(=in) %d(=out).",
538 *(byte_t *)base = val;
540 LOGDIAG3(
"GPIO %d: Configured for %sput.", gpio, sOp);
545 int mmapGpioSetPull(
int gpio,
int pull)
552 if( MapBase == NULL )
554 LOGERROR(
"%s", ErrStrNoMapFound);
560 LOGERROR(
"GPIO %d: %s", gpio, ErrStrGpioNoMap);
564 channel = GpioAddrTbl[gpio].channel;
565 bit = GpioAddrTbl[gpio].bit;
567 base = (MapBase + channel) + GPIO_UPDOWN;
591 LOGERROR(
"GPIO %d: Invalid pull. " 592 "Must be one of: %d(=disabled) %d(=up) %d(=down).",
599 hld = (byte_t)(v << (bit*2));
604 hld = (byte_t)(v << (bit*2));
609 val = *(byte_t *)base;
615 *(byte_t *)base = val;
617 LOGDIAG3(
"GPIO %d: Configured for pull %s.", gpio, sOp);
630 if( MapBase == NULL )
632 LOGERROR(
"%s", ErrStrNoMapFound);
638 LOGERROR(
"GPIO %d: %s", gpio, ErrStrGpioNoMap);
642 channel = GpioAddrTbl[gpio].channel;
643 bit = GpioAddrTbl[gpio].bit;
644 div_res = div(bit, 2);
648 p->
pin = gpioExportedToPin(gpio);
649 p->channel = channel;
655 value = *(byte_t *)(MapBase + channel);
658 if( value & (1 << bit) )
671 dir = *(byte_t *)(MapBase + channel - GPIO_GPCONREG);
676 if( dir & 0b00010000 )
688 if( dir & 0b00000001 )
704 pull = *(byte_t *)(MapBase + channel + GPIO_UPDOWN);
706 pull = (byte_t)(pull >> (bit*2));
711 pull = *(byte_t *)(MapBase + channel + GPIO_UPDOWN + 1);
713 pull = (byte_t)(pull >> ((bit-4)*2));
719 if( pull == 0b00000010 )
724 else if( pull == 0b00000001 )
737 int mmapGpioRead(
int gpio)
743 if( MapBase == NULL )
745 LOGERROR(
"%s", ErrStrNoMapFound);
751 LOGERROR(
"GPIO %d: %s", gpio, ErrStrGpioNoMap);
755 channel = GpioAddrTbl[gpio].channel;
756 bit = GpioAddrTbl[gpio].bit;
758 input = *(byte_t *)(MapBase + channel);
760 if( input & (1 << bit) )
772 int mmapGpioWrite(
int gpio,
int value)
778 if( MapBase == NULL )
780 LOGERROR(
"%s", ErrStrNoMapFound);
786 LOGERROR(
"GPIO %d: %s", gpio, ErrStrGpioNoMap);
790 channel = GpioAddrTbl[gpio].channel;
791 bit = GpioAddrTbl[gpio].bit;
793 virtAddr = MapBase + channel;
796 output = *(byte_t *)virtAddr;
800 output |= (byte_t)(1 << bit);
804 output &= (byte_t)(~(1 << bit));
808 *(byte_t *)virtAddr = output;
813 int mmapGpioToggle(
int gpio,
int count)
817 byte_t val, vbl, vcl, sbit;
820 if( MapBase == NULL )
822 LOGERROR(
"%s", ErrStrNoMapFound);
828 LOGERROR(
"GPIO %d: %s", gpio, ErrStrGpioNoMap);
832 channel = GpioAddrTbl[gpio].channel;
833 bit = GpioAddrTbl[gpio].bit;
835 virtAddr = MapBase + channel;
837 val = *(byte_t *)virtAddr;
839 sbit = (byte_t)(1 << bit);
845 for(i=0; i<count; ++i)
848 *(byte_t *)virtAddr = vbl;
849 *(byte_t *)virtAddr = vcl;
855 int mmapGpioBitBang(
int gpio,
858 unsigned int usecIbd)
860 size_t byteCount = (bitCount + 7) / 8;
864 if( MapBase == NULL )
866 LOGERROR(
"%s", ErrStrNoMapFound);
872 LOGERROR(
"GPIO %d: %s", gpio, ErrStrGpioNoMap);
876 for(i=0, k=0; i<byteCount; ++i)
878 for(j=0, mask=0x80; j<8 && k<bitCount; ++j, ++k)
884 value = pattern[i] & mask? 1: 0;
886 if( mmapGpioWrite(gpio, value) < 0 )
896 #else // unsupported target architectures 898 static const char *ErrStrArchNoMap =
"No memory mapped GPIO support.";
900 #define NO_SOUP "Architecture %s: %s." 903 int gpioExportedToPin(
int gpio)
908 int gpioPinToExported(
int pin)
915 LOGERROR(NO_SOUP, ARCH, ErrStrArchNoMap);
921 LOGERROR(NO_SOUP, ARCH, ErrStrArchNoMap);
925 int mmapGpioSetDirection(
int pin,
int dir)
927 LOGERROR(NO_SOUP, ARCH, ErrStrArchNoMap);
931 int mmapGpioSetPull(
int pin,
int pull)
933 LOGERROR(NO_SOUP, ARCH, ErrStrArchNoMap);
939 LOGERROR(NO_SOUP, ARCH, ErrStrArchNoMap);
943 int mmapGpioRead(
int pin)
945 LOGERROR(NO_SOUP, ARCH, ErrStrArchNoMap);
949 int mmapGpioWrite(
int pin,
int value)
951 LOGERROR(NO_SOUP, ARCH, ErrStrArchNoMap);
955 int mmapGpioToggle(
int pin,
int count)
957 LOGERROR(NO_SOUP, ARCH, ErrStrArchNoMap);
961 int mmapGpioBitBang(
int pin,
964 unsigned int usecIbd)
966 LOGERROR(NO_SOUP, ARCH, ErrStrArchNoMap);
970 #endif // architecture #define GPIO_PULL_DN_STR
enable pulldown string
#define GPIO_PULL_DS
disable pullup/down
int gpio
sysfs exported gpio number
GPIO interface declarations and defines.
#define GPIO_PULL_DS_STR
disable pullup/down string
#define GPIO_PULL_UP_STR
enable pullup string
#define GPIO_DIR_OUT_STR
output string
#define GPIO_PULL_DN
enable pulldown
#define GPIO_DIR_OUT
output
#define GPIO_DIR_IN_STR
input string
int pin
external header pin number
#define GPIO_PULL_UP
enable pullup