gpio.c 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. #include "u.h"
  2. #include "mem.h"
  3. #include "../port/lib.h"
  4. #include "dat.h"
  5. #include "fns.h"
  6. #include "io.h"
  7. static ulong gpioreserved[3];
  8. static Lock gpiolock;
  9. void
  10. gpioreserve(int n)
  11. {
  12. ulong mask, *r;
  13. r = &gpioreserved[GPR(n)];
  14. mask = GPB(n);
  15. ilock(&gpiolock);
  16. if(*r & mask)
  17. panic("gpioreserve: duplicate use of GPIO %d", n);
  18. *r |= mask;
  19. iunlock(&gpiolock);
  20. }
  21. /*
  22. * set direction and alternative function bits in the GPIO control register,
  23. * following the configuration bits in cfg.
  24. */
  25. void
  26. gpioconfig(int n, ulong cfg)
  27. {
  28. GpioReg *g;
  29. ulong o, m, *r;
  30. m = GPB(n);
  31. o = n>>5;
  32. ilock(&gpiolock);
  33. g = GPIOREG;
  34. r = &g->gpdr[o];
  35. if(cfg & Gpio_out)
  36. *r |= m;
  37. else
  38. *r &= ~m;
  39. r = &g->gafr[o*2];
  40. *r = (*r & ~GPAF(n, 3)) | GPAF(n, cfg&3);
  41. iunlock(&gpiolock);
  42. }
  43. ulong
  44. gpioget(int n)
  45. {
  46. ulong mask, o;
  47. mask = GPB(n);
  48. o = GPR(n);
  49. return GPIOREG->gplr[o] & mask;
  50. }
  51. void
  52. gpioset(int n, int v)
  53. {
  54. GpioReg *g;
  55. ulong mask, o;
  56. g = GPIOREG;
  57. mask = GPB(n);
  58. o = GPR(n);
  59. ilock(&gpiolock);
  60. if(v)
  61. g->gpsr[o] = mask;
  62. else
  63. g->gpcr[o] = mask;
  64. iunlock(&gpiolock);
  65. }
  66. void
  67. gpiorelease(int n)
  68. {
  69. ulong mask, *r;
  70. mask = GPB(n);
  71. r = &gpioreserved[GPR(n)];
  72. ilock(&gpiolock);
  73. if((*r & mask) != mask)
  74. panic("gpiorelease: unexpected release of GPIO %d", n);
  75. *r &= ~mask;
  76. iunlock(&gpiolock);
  77. }