ref: 94443daf8e248e65afc8d3f17f26efea22748b51
dir: /os/pxa/gpio.c/
#include "u.h"
#include "mem.h"
#include "../port/lib.h"
#include "dat.h"
#include "fns.h"
#include "io.h"
static ulong gpioreserved[3];
static Lock gpiolock;
void
gpioreserve(int n)
{
ulong mask, *r;
r = &gpioreserved[GPR(n)];
mask = GPB(n);
ilock(&gpiolock);
if(*r & mask)
panic("gpioreserve: duplicate use of GPIO %d", n);
*r |= mask;
iunlock(&gpiolock);
}
/*
* set direction and alternative function bits in the GPIO control register,
* following the configuration bits in cfg.
*/
void
gpioconfig(int n, ulong cfg)
{
GpioReg *g;
ulong o, m, *r;
m = GPB(n);
o = n>>5;
ilock(&gpiolock);
g = GPIOREG;
r = &g->gpdr[o];
if(cfg & Gpio_out)
*r |= m;
else
*r &= ~m;
r = &g->gafr[o*2];
*r = (*r & ~GPAF(n, 3)) | GPAF(n, cfg&3);
iunlock(&gpiolock);
}
ulong
gpioget(int n)
{
ulong mask, o;
mask = GPB(n);
o = GPR(n);
return GPIOREG->gplr[o] & mask;
}
void
gpioset(int n, int v)
{
GpioReg *g;
ulong mask, o;
g = GPIOREG;
mask = GPB(n);
o = GPR(n);
ilock(&gpiolock);
if(v)
g->gpsr[o] = mask;
else
g->gpcr[o] = mask;
iunlock(&gpiolock);
}
void
gpiorelease(int n)
{
ulong mask, *r;
mask = GPB(n);
r = &gpioreserved[GPR(n)];
ilock(&gpiolock);
if((*r & mask) != mask)
panic("gpiorelease: unexpected release of GPIO %d", n);
*r &= ~mask;
iunlock(&gpiolock);
}