| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879 |
- #include <stdbool.h>
- #include <sys/mman.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include "logging.h"
- #include "gpio.h"
- extern struct bfg_gpio_controller _linux_gpio;
- bool bfg_gpio_init(void)
- {
- const int fd = open("/dev/mem", O_RDWR | O_SYNC);
- if (fd < 0)
- applogr(false, LOG_ERR, "Failed to open /dev/mem");
- volatile unsigned *gpio;
- gpio = mmap(0, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0x20200000);
- if (gpio == MAP_FAILED)
- applogr(false, LOG_ERR, "Failed to mmap GPIO from /dev/mem");
- close(fd);
-
- linux_gpio->all_gpios = gpio_bitmask_all;
- linux_gpio->p = (void*)gpio;
-
- return true;
- }
- static
- bool linux_gpio_set_mode(struct bfg_gpio_controller * const gc, const gpio_bitmask_t pins, int mode)
- {
- volatile unsigned * const gpio = gc->p;
- if (mode > 1)
- {
- if (mode > 3)
- {
- if (mode > 5)
- return false;
- mode = 7 - mode;
- }
- else
- mode |= 4;
- }
- for (int i = gpio_highest; i >= 0; --i)
- {
- volatile unsigned * const g = &gpio[i / 10];
- const int sh = (i % 10) * 3;
- *g = (*g & ~(7 << sh)) | (mode << sh);
- }
- return true;
- }
- static
- void linux_gpio_set_values(struct bfg_gpio_controller * const gc, const gpio_bitmask_t pins, const gpio_bitmask_t vals)
- {
- volatile unsigned * const gpio = gc->p;
- gpio[7] = pins & vals;
- gpio[10] = pins & ~vals;
- }
- static
- gpio_bitmask_t linux_gpio_get_values(struct bfg_gpio_controller * const gc, const gpio_bitmask_t pins)
- {
- volatile unsigned * const gpio = gc->p;
- return gpio[13] & pins;
- }
- static
- const struct bfg_gpio_controller_drv linux_gpio_drv = {
- .set_mode = linux_gpio_set_mode,
- .set_values = linux_gpio_set_values,
- .get_values = linux_gpio_get_values,
- };
- struct bfg_gpio_controller _linux_gpio = {
- .drv = &linux_gpio_drv,
- };
|