From 615e0cd83ac7202440468b061d23ed282e288ddb Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Sat, 2 Sep 2017 13:13:45 +0530 Subject: [PATCH] src: arm: Add mmap support for db410c This commit adds mmap support for 96Boards Dragonboard410c Signed-off-by: Manivannan Sadhasivam Signed-off-by: Brendan Le Foll --- src/arm/96boards.c | 112 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 106 insertions(+), 6 deletions(-) diff --git a/src/arm/96boards.c b/src/arm/96boards.c index 345c80b..d8676e7 100644 --- a/src/arm/96boards.c +++ b/src/arm/96boards.c @@ -40,6 +40,8 @@ #define PLATFORM_NAME_HIKEY "HIKEY" #define PLATFORM_NAME_BBGUM "BBGUM" #define MAX_SIZE 64 +#define MMAP_PATH "/dev/mem" +#define DB410C_MMAP_REG 0x01000000 int db410c_ls_gpio_pins[MRAA_96BOARDS_LS_GPIO_COUNT] = { 36, 12, 13, 69, 115, 4, 24, 25, 35, 34, 28, 33, @@ -58,6 +60,12 @@ int bbgum_ls_gpio_pins[MRAA_96BOARDS_LS_GPIO_COUNT] = { 0, 1, 2, 3, 4, 5, 6, 7, const char* bbgum_serialdev[MRAA_96BOARDS_LS_UART_COUNT] = { "/dev/ttyS3", "/dev/ttyS5" }; +// MMAP +static uint8_t* mmap_reg = NULL; +static int mmap_fd = 0; +static int mmap_size = 0x00120004; +static unsigned int mmap_count = 0; + void mraa_96boards_pininfo(mraa_board_t* board, int index, int sysfs_pin, char* fmt, ...) { @@ -77,6 +85,97 @@ mraa_96boards_pininfo(mraa_board_t* board, int index, int sysfs_pin, char* fmt, pininfo->gpio.mux_total = 0; } +static mraa_result_t +mraa_db410c_mmap_unsetup() +{ + if (mmap_reg == NULL) { + syslog(LOG_WARNING, "db410c mmap: null register nothing to unsetup"); + return MRAA_ERROR_INVALID_RESOURCE; + } + munmap(mmap_reg, mmap_size); + mmap_reg = NULL; + close(mmap_fd); + + return MRAA_SUCCESS; +} + +mraa_result_t +mraa_db410c_mmap_write(mraa_gpio_context dev, int value) +{ + uint32_t offset = (0x1000 * dev->pin); + + if (value) { + *(volatile uint32_t*) (mmap_reg + offset + 0x04) |= (uint32_t) (1 << 1); + } else { + *(volatile uint32_t*) (mmap_reg + offset + 0x04) &= ~(uint32_t) (1 << 1); + } + + return MRAA_SUCCESS; +} + +int +mraa_db410c_mmap_read(mraa_gpio_context dev) +{ + uint32_t value; + uint32_t offset = (0x1000 * dev->pin); + + value = *(volatile uint32_t*) (mmap_reg + offset + 0x04); + if (value & (uint32_t) (1 << 0)) { + return 1; + } + + return 0; +} + +mraa_result_t +mraa_db410c_mmap_setup(mraa_gpio_context dev, mraa_boolean_t en) +{ + if (dev == NULL) { + syslog(LOG_ERR, "db410c mmap: context not valid"); + return MRAA_ERROR_INVALID_HANDLE; + } + + /* disable mmap if already enabled */ + if (en == 0) { + if (dev->mmap_write == NULL && dev->mmap_read == NULL) { + syslog(LOG_ERR, "db410c mmap: can't disable disabled mmap gpio"); + return MRAA_ERROR_INVALID_PARAMETER; + } + dev->mmap_write = NULL; + dev->mmap_read = NULL; + mmap_count--; + if (mmap_count == 0) { + return mraa_db410c_mmap_unsetup(); + } + return MRAA_SUCCESS; + } + + if (dev->mmap_write != NULL && dev->mmap_read != NULL) { + syslog(LOG_ERR, "db410c mmap: can't enable enabled mmap gpio"); + return MRAA_ERROR_INVALID_PARAMETER; + } + + if (mmap_reg == NULL) { + if ((mmap_fd = open(MMAP_PATH, O_RDWR)) < 0) { + syslog(LOG_ERR, "db410c mmap: unable to open /dev/mem"); + return MRAA_ERROR_INVALID_HANDLE; + } + mmap_reg = mmap(NULL, mmap_size, PROT_READ | PROT_WRITE, MAP_SHARED, mmap_fd, DB410C_MMAP_REG); + + if (mmap_reg == MAP_FAILED) { + syslog(LOG_ERR, "db410c mmap: failed to mmap"); + mmap_reg = NULL; + close(mmap_fd); + return MRAA_ERROR_NO_RESOURCES; + } + } + dev->mmap_write = &mraa_db410c_mmap_write; + dev->mmap_read = &mraa_db410c_mmap_read; + mmap_count++; + + return MRAA_SUCCESS; +} + mraa_board_t* mraa_96boards() { @@ -88,6 +187,12 @@ mraa_96boards() return NULL; } + b->adv_func = (mraa_adv_func_t*) calloc(1, sizeof(mraa_adv_func_t)); + if (b->adv_func == NULL) { + free(b); + return NULL; + } + // pin mux for buses are setup by default by kernel so tell mraa to ignore them b->no_bus_mux = 1; b->phy_pin_count = MRAA_96BOARDS_LS_PIN_COUNT + 1; @@ -99,6 +204,7 @@ mraa_96boards() ls_gpio_pins = db410c_ls_gpio_pins; b->uart_dev[0].device_path = (char *)db410c_serialdev[0]; b->uart_dev[1].device_path = (char *)db410c_serialdev[1]; + b->adv_func->gpio_mmap_setup = &mraa_db410c_mmap_setup; } else if (mraa_file_contains(DT_BASE "/model", "HiKey Development Board")) { b->platform_name = PLATFORM_NAME_HIKEY; ls_gpio_pins = hikey_ls_gpio_pins; @@ -134,12 +240,6 @@ mraa_96boards() b->spi_bus[0].bus_id = 0; b->def_spi_bus = 0; - b->adv_func = (mraa_adv_func_t*) calloc(1, sizeof(mraa_adv_func_t)); - if (b->adv_func == NULL) { - free(b); - return NULL; - } - b->pins = (mraa_pininfo_t*) malloc(sizeof(mraa_pininfo_t) * b->phy_pin_count); if (b->pins == NULL) { free(b->adv_func);