/* * Copyright (C) 2021 Denis 'GNUtoo' Carikli * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include #include #include "exynos4412_gpios.h" #include "exynos4412_gpios_data.h" void *mmap_gpio_hardware_blocks(int debug, char *devmem, int fd, size_t page_size) { /* TODO: also map GPIO_right * GPIO_right: base_addr: 0x11000000 len: 0x400000 * GPIO_left: base_addr: 0x11400000 len: 0x400000 */ uint32_t base_addr = 0x11000000; size_t len = 0x800000; void *map_base_addr; uint32_t *virt_addr; int rc; map_base_addr = mmap(0, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, base_addr & ~(page_size -1)); if (map_base_addr == MAP_FAILED) { rc = errno; printf("mmap on %s failed with error %d: %s\n", devmem, rc, strerror(rc)); errno = rc; return NULL; } virt_addr = map_base_addr + (base_addr & 4095); if (debug) { printf("%s: mapped address 0x%x @ %p\n", __func__, 0, map_base_addr); printf("%s: mapped 0x%x bytes of address 0x%x @ %p\n", __func__, len, base_addr, virt_addr); } return virt_addr; } int dump_gpio_infos(int debug, char *devmem, int fd, size_t page_size, void *gpio_hardware_blocks_addr, char *bank, uint32_t gpio_offset) { uint32_t *addr; int rc; int i = 0; off_t offset = 0; char* gpio_registers[] = { "con", "dat", "pud", "drv" }; offset = get_gpio_register_offset(debug, bank, "con"); if (offset == -1) { rc = errno; printf("%s: get_gpio_register_offset failed with error %d: %s\n", __func__, rc, strerror(rc)); return -1; } addr = gpio_hardware_blocks_addr + offset; if (debug) { printf("%s: Mapped at %p\n", __func__, addr); print_gpio_banks_data(); } printf("%s: %s[%d]: {\n", __func__, bank, gpio_offset); for (i=0; i< sizeof(gpio_registers) / sizeof (char*); i++) { rc = decode_gpio_data(debug, bank, gpio_offset, gpio_registers[i], addr); if (rc == -1) { rc = errno; printf("%s:" " decode_gpio_data(debug=%d," " bank=%s," " gpio_offset=%d," " gpio_register_name=%s," " addr=%p);" " failed with with error %d: %s\n", __func__, debug, bank, gpio_offset, gpio_registers[i], addr, rc, strerror(rc)); return -1; } printf(" %s\n", gpio_data_str(gpio_registers[i], rc)); } printf("}\n"); return 0; } int gpio_get_direction(char *devmem, int fd, size_t page_size, char *bank, uint32_t gpio_offset) { int debug = 0; uint32_t *addr; int rc; off_t offset = 0; offset = get_gpio_register_offset(debug, bank, "con"); if (offset == -1) { rc = errno; printf("%s: get_gpio_register_offset failed with error %d: %s\n", __func__, rc, strerror(rc)); return -1; } addr = mmap_gpio_hardware_blocks(debug, devmem, fd, page_size) + offset; if (addr == NULL) { /* mmap_gpio_bank already prints an error */ return -1; } if (debug) { printf("%s: Mapped at %p\n", __func__, addr); print_gpio_banks_data(); } rc = decode_gpio_data(debug, bank, gpio_offset, "con", addr); if (rc == -1) { rc = errno; printf("%s:" " decode_gpio_data(debug=%d," " bank=%s," " gpio_offset=%d," " gpio_register_name=%s," " addr=%p);" " failed with with error %d: %s\n", __func__, debug, bank, gpio_offset, "con", addr, rc, strerror(rc)); return -1; } return rc; } int gpio_get_output_value(char *devmem, int fd, size_t page_size, char *bank, uint32_t gpio_offset) { int debug = 0; uint32_t *addr; int rc; off_t offset = 0; offset = get_gpio_register_offset(debug, bank, "dat"); if (offset == -1) { rc = errno; printf("%s: get_gpio_register_offset failed with error %d: %s\n", __func__, rc, strerror(rc)); return -1; } if (debug){ printf("%s: offset for %s: 0x%lx\n\n", __func__, bank, offset); } addr = mmap_gpio_hardware_blocks(debug, devmem, fd, page_size) + offset; if (addr == NULL) { /* mmap_gpio_bank already prints an error */ return -1; } if (debug) { printf("%s: Mapped at %p\n", __func__, addr); print_gpio_banks_data(); } rc = decode_gpio_data(debug, bank, gpio_offset, "dat", addr); if (rc == -1) { rc = errno; printf("%s:" " decode_gpio_data(debug=%d," " bank=%s," " gpio_offset=%d," " gpio_register_name=%s," " addr=%p);" " failed with with error %d: %s\n", __func__, debug, bank, gpio_offset, "dat", addr, rc, strerror(rc)); return -1; } return rc; }