// File: mrlordkaj[P]i2cdevlib-pi/Arduino/wiringPi/wiringPi.c
// Function: wiringPiSetup
int wiringPiSetup (void)
{
  int   fd ;
  int   model, rev, mem, maker, overVolted ;

  if (wiringPiSetuped)
    return 0 ;

  wiringPiSetuped = TRUE ;

  if (getenv (ENV_DEBUG) != NULL)
    wiringPiDebug = TRUE ;

  if (getenv (ENV_CODES) != NULL)
    wiringPiReturnCodes = TRUE ;

  if (wiringPiDebug)
    printf ("wiringPi: wiringPiSetup called\n") ;

// Get the board ID information. We're not really using the information here,
//	but it will give us information like the GPIO layout scheme (2 variants
//	on the older 26-pin Pi's) and the GPIO peripheral base address.
//	and if we're running on a compute module, then wiringPi pin numbers
//	don't really many anything, so force native BCM mode anyway.

  piBoardId (&model, &rev, &mem, &maker, &overVolted) ;

  if ((model == PI_MODEL_CM) ||
      (model == PI_MODEL_CM3) ||
      (model == PI_MODEL_CM3P))
    wiringPiMode = WPI_MODE_GPIO ;
  else
    wiringPiMode = WPI_MODE_PINS ;

  /**/ if (piGpioLayout () == 1)	// A, B, Rev 1, 1.1
  {
     pinToGpio =  pinToGpioR1 ;
    physToGpio = physToGpioR1 ;
  }
  else 					// A2, B2, A+, B+, CM, Pi2, Pi3, Zero, Zero W, Zero 2 W
  {
     pinToGpio =  pinToGpioR2 ;
    physToGpio = physToGpioR2 ;
  }

// ...

  switch (model)
  {
    case PI_MODEL_A:	case PI_MODEL_B:
    case PI_MODEL_AP:	case PI_MODEL_BP:
    case PI_ALPHA:	case PI_MODEL_CM:
    case PI_MODEL_ZERO:	case PI_MODEL_ZERO_W:
      piGpioBase = GPIO_PERI_BASE_OLD ;
      piGpioPupOffset = GPPUD ;
      break ;

    case PI_MODEL_4B:
    case PI_MODEL_400:
    case PI_MODEL_CM4:
      piGpioBase = GPIO_PERI_BASE_2711 ;
      piGpioPupOffset = GPPUPPDN0 ;
      break ;

    default:
      piGpioBase = GPIO_PERI_BASE_2835 ;
      piGpioPupOffset = GPPUD ;
      break ;
  }

// Open the master /dev/ memory control device
// Device strategy: December 2016:
//	Try /dev/mem. If that fails, then
//	try /dev/gpiomem. If that fails then game over.

  if ((fd = open ("/dev/mem", O_RDWR | O_SYNC | O_CLOEXEC)) < 0)
  {
    if ((fd = open ("/dev/gpiomem", O_RDWR | O_SYNC | O_CLOEXEC) ) >= 0)	// We're using gpiomem
    {
      piGpioBase   = 0 ;
      usingGpioMem = TRUE ;
    }
    else
      return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: Unable to open /dev/mem or /dev/gpiomem: %s.\n"
	"  Aborting your program because if it can not access the GPIO\n"
	"  hardware then it most certianly won't work\n"
	"  Try running with sudo?\n", strerror (errno)) ;
  }

// Set the offsets into the memory interface.

  GPIO_PADS 	  = piGpioBase + 0x00100000 ;
  GPIO_CLOCK_BASE = piGpioBase + 0x00101000 ;
  GPIO_BASE	  = piGpioBase + 0x00200000 ;
  GPIO_TIMER	  = piGpioBase + 0x0000B000 ;
  GPIO_PWM	  = piGpioBase + 0x0020C000 ;

// Map the individual hardware components

//	GPIO:

  gpio = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_BASE) ;
  if (gpio == MAP_FAILED)
    return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (GPIO) failed: %s\n", strerror (errno)) ;

//	PWM

  pwm = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_PWM) ;
  if (pwm == MAP_FAILED)
    return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (PWM) failed: %s\n", strerror (errno)) ;

//	Clock control (needed for PWM)

  clk = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_CLOCK_BASE) ;
  if (clk == MAP_FAILED)
    return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (CLOCK) failed: %s\n", strerror (errno)) ;

//	The drive pads

  pads = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_PADS) ;
  if (pads == MAP_FAILED)
    return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (PADS) failed: %s\n", strerror (errno)) ;

//	The system timer

  timer = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_TIMER) ;
  if (timer == MAP_FAILED)
    return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (TIMER) failed: %s\n", strerror (errno)) ;

// Set the timer to free-running, 1MHz.
//	0xF9 is 249, the timer divide is base clock / (divide+1)
//	so base clock is 250MHz / 250 = 1MHz.

  *(timer + TIMER_CONTROL) = 0x0000280 ;
  *(timer + TIMER_PRE_DIV) = 0x00000F9 ;
  timerIrqRaw = timer + TIMER_IRQ_RAW ;

// Export the base addresses for any external software that might need them

  _wiringPiGpio  = gpio ;
  _wiringPiPwm   = pwm ;
  _wiringPiClk   = clk ;
  _wiringPiPads  = pads ;
  _wiringPiTimer = timer ;

  initialiseEpoch () ;

  return 0 ;
}

// Assembly:
subq $0x28, %rsp
cmpl $0x0, 0x30c7d(%rip)     # 0x5df18
je 0x2d2aa
movl $0x0, 0x24(%rsp)
jmp 0x2d78d
movl $0x1, 0x30c64(%rip)     # 0x5df18
leaq 0x1e5fa(%rip), %rdi     # 0x4b8b5
callq 0x22d30
cmpq $0x0, %rax
je 0x2d2d3
movq 0x2ec73(%rip), %rax     # 0x5bf40
movl $0x1, (%rax)
leaq 0x1e5ea(%rip), %rdi     # 0x4b8c4
callq 0x22d30
cmpq $0x0, %rax
je 0x2d2f2
movq 0x2ecbc(%rip), %rax     # 0x5bfa8
movl $0x1, (%rax)
movq 0x2ec47(%rip), %rax     # 0x5bf40
cmpl $0x0, (%rax)
je 0x2d30c
leaq 0x1e5ce(%rip), %rdi     # 0x4b8d3
movb $0x0, %al
callq 0x22060
leaq 0x1c(%rsp), %rdi
leaq 0x18(%rsp), %rsi
leaq 0x14(%rsp), %rdx
leaq 0x10(%rsp), %rcx
leaq 0xc(%rsp), %r8
callq 0x225b0
cmpl $0x6, 0x1c(%rsp)
je 0x2d33f
cmpl $0xa, 0x1c(%rsp)
je 0x2d33f
cmpl $0x10, 0x1c(%rsp)
jne 0x2d34b
movl $0x1, 0x2f98b(%rip)     # 0x5ccd4
jmp 0x2d355
movl $0x0, 0x2f97f(%rip)     # 0x5ccd4
callq 0x235b0
cmpl $0x1, %eax
jne 0x2d37d
leaq 0x2fc8a(%rip), %rax     # 0x5cff0
movq %rax, 0x3092b(%rip)     # 0x5dc98
leaq 0x2fd7c(%rip), %rax     # 0x5d0f0
movq %rax, 0x30925(%rip)     # 0x5dca0
jmp 0x2d399
leaq 0x2fe6c(%rip), %rax     # 0x5d1f0
movq %rax, 0x3090d(%rip)     # 0x5dc98
leaq 0x2ff5e(%rip), %rax     # 0x5d2f0
movq %rax, 0x30907(%rip)     # 0x5dca0
movl 0x1c(%rsp), %eax
movl %eax, 0x8(%rsp)
subl $0x4, %eax
jb 0x2d3e5
jmp 0x2d3a8
movl 0x8(%rsp), %eax
addl $-0x5, %eax
subl $0x2, %eax
jb 0x2d3e5
jmp 0x2d3b6
movl 0x8(%rsp), %eax
subl $0x9, %eax
je 0x2d3e5
jmp 0x2d3c1
movl 0x8(%rsp), %eax
subl $0xc, %eax
je 0x2d3e5
jmp 0x2d3cc
movl 0x8(%rsp), %eax
subl $0x11, %eax
je 0x2d3fb
jmp 0x2d3d7
movl 0x8(%rsp), %eax
addl $-0x13, %eax
subl $0x2, %eax
jb 0x2d3fb
jmp 0x2d411
movl $0x20000000, 0x308d1(%rip) # imm = 0x20000000
movl $0x25, 0x308d7(%rip)    # 0x5dcd0
jmp 0x2d425
movl $0xfe000000, 0x308bb(%rip) # imm = 0xFE000000
movl $0x39, 0x308c1(%rip)    # 0x5dcd0
jmp 0x2d425
movl $0x3f000000, 0x308a5(%rip) # imm = 0x3F000000
movl $0x25, 0x308ab(%rip)    # 0x5dcd0
leaq 0x1e4c7(%rip), %rdi     # 0x4b8f3
movl $0x181002, %esi         # imm = 0x181002
movb $0x0, %al
callq 0x227b0
movl %eax, 0x20(%rsp)
cmpl $0x0, %eax
jge 0x2d49d
leaq 0x1e4b4(%rip), %rdi     # 0x4b8fc
movl $0x181002, %esi         # imm = 0x181002
movb $0x0, %al
callq 0x227b0
movl %eax, 0x20(%rsp)
cmpl $0x0, %eax
jl 0x2d473
movl $0x0, 0x30859(%rip)     # 0x5dcc0
movl $0x1, 0x30aab(%rip)     # 0x5df1c
jmp 0x2d49b
callq 0x22050
movl (%rax), %edi
callq 0x222f0
movq %rax, %rdx
xorl %edi, %edi
leaq 0x1e47e(%rip), %rsi     # 0x4b909
movb $0x0, %al
callq 0x225a0
movl %eax, 0x24(%rsp)
jmp 0x2d78d
jmp 0x2d49d
movl 0x3081d(%rip), %eax     # 0x5dcc0
addl $0x100000, %eax         # imm = 0x100000
movl %eax, 0x30a72(%rip)     # 0x5df20
movl 0x3080c(%rip), %eax     # 0x5dcc0
addl $0x101000, %eax         # imm = 0x101000
movl %eax, 0x30a65(%rip)     # 0x5df24
movl 0x307fb(%rip), %eax     # 0x5dcc0
addl $0x200000, %eax         # imm = 0x200000
movl %eax, 0x30a58(%rip)     # 0x5df28
movl 0x307ea(%rip), %eax     # 0x5dcc0
addl $0xb000, %eax           # imm = 0xB000
movl %eax, 0x30a4b(%rip)     # 0x5df2c
movl 0x307d9(%rip), %eax     # 0x5dcc0
addl $0x20c000, %eax         # imm = 0x20C000
movl %eax, 0x30a3e(%rip)     # 0x5df30
movl 0x20(%rsp), %r8d
movl 0x30a2b(%rip), %eax     # 0x5df28
movl %eax, %eax
movl %eax, %r9d
xorl %eax, %eax
movl %eax, %edi
movl $0x1000, %esi           # imm = 0x1000
movl $0x3, %edx
movl $0x1, %ecx
callq 0x23370
movq %rax, 0x3078f(%rip)     # 0x5dcb0
movq $-0x1, %rax
cmpq %rax, 0x30781(%rip)     # 0x5dcb0
jne 0x2d559
callq 0x22050
movl (%rax), %edi
callq 0x222f0
movq %rax, %rdx
xorl %edi, %edi
leaq 0x1e481(%rip), %rsi     # 0x4b9ca
movb $0x0, %al
callq 0x225a0
movl %eax, 0x24(%rsp)
jmp 0x2d78d
movl 0x20(%rsp), %r8d
movl 0x309cc(%rip), %eax     # 0x5df30
movl %eax, %eax
movl %eax, %r9d
xorl %eax, %eax
movl %eax, %edi
movl $0x1000, %esi           # imm = 0x1000
movl $0x3, %edx
movl $0x1, %ecx
callq 0x23370
movq %rax, 0x30730(%rip)     # 0x5dcb8
movq $-0x1, %rax
cmpq %rax, 0x30722(%rip)     # 0x5dcb8
jne 0x2d5c0
callq 0x22050
movl (%rax), %edi
callq 0x222f0
movq %rax, %rdx
xorl %edi, %edi
leaq 0x1e441(%rip), %rsi     # 0x4b9f1
movb $0x0, %al
callq 0x225a0
movl %eax, 0x24(%rsp)
jmp 0x2d78d
movl 0x20(%rsp), %r8d
movl 0x30959(%rip), %eax     # 0x5df24
movl %eax, %eax
movl %eax, %r9d
xorl %eax, %eax
movl %eax, %edi
movl $0x1000, %esi           # imm = 0x1000
movl $0x3, %edx
movl $0x1, %ecx
callq 0x23370
movq %rax, 0x306d9(%rip)     # 0x5dcc8
movq $-0x1, %rax
cmpq %rax, 0x306cb(%rip)     # 0x5dcc8
jne 0x2d627
callq 0x22050
movl (%rax), %edi
callq 0x222f0
movq %rax, %rdx
xorl %edi, %edi
leaq 0x1e400(%rip), %rsi     # 0x4ba17
movb $0x0, %al
callq 0x225a0
movl %eax, 0x24(%rsp)
jmp 0x2d78d
movl 0x20(%rsp), %r8d
movl 0x308ee(%rip), %eax     # 0x5df20
movl %eax, %eax
movl %eax, %r9d
xorl %eax, %eax
movl %eax, %edi
movl $0x1000, %esi           # imm = 0x1000
movl $0x3, %edx
movl $0x1, %ecx
callq 0x23370
movq %rax, 0x30652(%rip)     # 0x5dca8
movq $-0x1, %rax
cmpq %rax, 0x30644(%rip)     # 0x5dca8
jne 0x2d68e
callq 0x22050
movl (%rax), %edi
callq 0x222f0
movq %rax, %rdx
xorl %edi, %edi
leaq 0x1e3c1(%rip), %rsi     # 0x4ba3f
movb $0x0, %al
callq 0x225a0
movl %eax, 0x24(%rsp)
jmp 0x2d78d
movl 0x20(%rsp), %r8d
movl 0x30893(%rip), %eax     # 0x5df2c
movl %eax, %eax
movl %eax, %r9d
xorl %eax, %eax
movl %eax, %edi
movl $0x1000, %esi           # imm = 0x1000
movl $0x3, %edx
movl $0x1, %ecx
callq 0x23370
movq %rax, 0x3087b(%rip)     # 0x5df38
movq $-0x1, %rax
cmpq %rax, 0x3086d(%rip)     # 0x5df38
jne 0x2d6f5
callq 0x22050
movl (%rax), %edi
callq 0x222f0
movq %rax, %rdx
xorl %edi, %edi
leaq 0x1e381(%rip), %rsi     # 0x4ba66
movb $0x0, %al
callq 0x225a0
movl %eax, 0x24(%rsp)
jmp 0x2d78d
movq 0x3083c(%rip), %rax     # 0x5df38
movl $0x280, 0x408(%rax)     # imm = 0x280
movq 0x3082b(%rip), %rax     # 0x5df38
movl $0xf9, 0x41c(%rax)
movq 0x3081a(%rip), %rax     # 0x5df38
addq $0x410, %rax            # imm = 0x410
movq %rax, 0x30815(%rip)     # 0x5df40
movq 0x3057e(%rip), %rcx     # 0x5dcb0
movq 0x2e80f(%rip), %rax     # 0x5bf48
movq %rcx, (%rax)
movq 0x30575(%rip), %rcx     # 0x5dcb8
movq 0x2e806(%rip), %rax     # 0x5bf50
movq %rcx, (%rax)
movq 0x30574(%rip), %rcx     # 0x5dcc8
movq 0x2e7c5(%rip), %rax     # 0x5bf20
movq %rcx, (%rax)
movq 0x30543(%rip), %rcx     # 0x5dca8
movq 0x2e824(%rip), %rax     # 0x5bf90
movq %rcx, (%rax)
movq 0x307c2(%rip), %rcx     # 0x5df38
movq 0x2e83b(%rip), %rax     # 0x5bfb8
movq %rcx, (%rax)
callq 0x2d7a0
movl $0x0, 0x24(%rsp)
movl 0x24(%rsp), %eax
addq $0x28, %rsp
retq
nopw %cs:(%rax,%rax)