12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 |
- #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);
- }
|