From cefbc25356adec0368bba06b2ed8a2bdcc47d0b3 Mon Sep 17 00:00:00 2001 From: haizhouyang Date: Thu, 29 Jul 2021 14:49:54 +0800 Subject: [PATCH] feature: auto detec gpio on linux Signed-off-by: haizhouyang --- support/platform/include/gpio_core.h | 8 ++- support/platform/include/plat_log.h | 2 +- support/platform/src/gpio_core.c | 74 ++++++++++++++++++---------- support/platform/src/gpio_if.c | 16 +++--- 4 files changed, 64 insertions(+), 36 deletions(-) diff --git a/support/platform/include/gpio_core.h b/support/platform/include/gpio_core.h index 6e1a0dc44..4f8fbdd6f 100644 --- a/support/platform/include/gpio_core.h +++ b/support/platform/include/gpio_core.h @@ -25,7 +25,7 @@ struct GpioCntlr; struct GpioMethod; struct GpioInfo; -#define GPIO_NUM_DEFAULT 200 +#define GPIO_NUM_MAX 0xFFFF /** * @brief Defines the struct which represent a hardware GPIO controller. @@ -138,6 +138,12 @@ void GpioCntlrIrqCallback(struct GpioCntlr *cntlr, uint16_t local); struct GpioCntlr *GpioGetCntlr(uint16_t gpio); +static inline uint16_t GpioToLocal(uint16_t gpio) +{ + struct GpioCntlr *cntlr = GpioGetCntlr(gpio); + return (cntlr == NULL) ? gpio : (gpio - cntlr->start); +} + static inline uint16_t GpioGetLocalNumber(struct GpioCntlr *cntlr, uint16_t gpio) { return (cntlr == NULL) ? gpio : (gpio - cntlr->start); diff --git a/support/platform/include/plat_log.h b/support/platform/include/plat_log.h index bc2d0671c..d3b4c6f29 100644 --- a/support/platform/include/plat_log.h +++ b/support/platform/include/plat_log.h @@ -11,7 +11,7 @@ #include "hdf_log.h" -#if defined(__LITEOS__) +#if defined(__LITEOS__) || defined(__KERNEL__) #define PLAT_LOGV(fmt, arg...) #else #define PLAT_LOGV(fmt, arg...) HDF_LOGV(fmt, ##arg) diff --git a/support/platform/src/gpio_core.c b/support/platform/src/gpio_core.c index 7224aeb2b..8419ab765 100644 --- a/support/platform/src/gpio_core.c +++ b/support/platform/src/gpio_core.c @@ -56,9 +56,49 @@ static void GpioCntlrListPut(void) (void)OsalSpinUnlockIrqRestore(&g_listLock, &g_irqFlags); } +static uint16_t GpioCntlrQueryStart(struct GpioCntlr *cntlr, struct DListHead *list) +{ + uint16_t freeStart; + uint16_t freeCount; + struct GpioCntlr *iterLast = NULL; + struct GpioCntlr *iterCur = NULL; + struct GpioCntlr *tmp = NULL; + + DLIST_FOR_EACH_ENTRY_SAFE(iterCur, tmp, list, struct GpioCntlr, list) { + if (iterLast == NULL) { + freeStart = 0; + freeCount = iterCur->start; + } else { + freeStart = iterLast->start + iterLast->count; + freeCount = iterCur->start - freeStart; + } + + if (cntlr->start < freeStart) { + HDF_LOGE("GpioCntlrQueryStart: start:%u not available(freeStart:%u, freeCount:%u)", + cntlr->start, freeStart, freeCount); + return GPIO_NUM_MAX; + } + + if ((cntlr->start + cntlr->count) <= (freeStart + freeCount)) { + return freeStart; + } + + iterLast = iterCur; + } + if (iterLast == NULL) { // empty list + return cntlr->start; + } + if (cntlr->start >= (iterLast->start + iterLast->count)) { + return iterLast->start + iterLast->count; + } + HDF_LOGE("GpioCntlrQueryStart: start:%u not available(lastStart:%u, lastCount:%u)", + cntlr->start, iterLast->start, iterLast->count); + return GPIO_NUM_MAX; +} + int32_t GpioCntlrAdd(struct GpioCntlr *cntlr) { - struct GpioCntlr *last = NULL; + uint16_t start; struct DListHead *list = NULL; if (cntlr == NULL) { @@ -90,12 +130,12 @@ int32_t GpioCntlrAdd(struct GpioCntlr *cntlr) OsalSpinInit(&cntlr->spin); list = GpioCntlrListGet(); - if (DListIsEmpty(list)) { - cntlr->start = 0; - } else { - last = DLIST_LAST_ENTRY(list, struct GpioCntlr, list); - cntlr->start = last->start + last->count; + if ((start = GpioCntlrQueryStart(cntlr, list)) >= GPIO_NUM_MAX) { + HDF_LOGE("GpioCntlrAdd: query range for start:%d fail:%d", cntlr->start, start); + GpioCntlrListPut(); + return HDF_ERR_INVALID_PARAM; } + cntlr->start = start; DListHeadInit(&cntlr->list); DListInsertTail(&cntlr->list, list); GpioCntlrListPut(); @@ -219,7 +259,6 @@ static int32_t GpioIrqBridgeFunc(uint16_t local, void *data) return HDF_SUCCESS; } -#ifndef __KERNEL__ static int GpioIrqThreadWorker(void *data) { int32_t ret; @@ -234,7 +273,7 @@ static int GpioIrqThreadWorker(void *data) break; } PLAT_LOGV("GpioIrqThreadWorker: enter! gpio:%u-%u", bridge->cntlr->start, bridge->local); - (void)bridge->func(bridge->local, bridge->data); + (void)bridge->func(bridge->local + bridge->cntlr->start, bridge->data); } /* it's the bridge struct we create before, so release it ourself */ (void)OsalSemDestroy(&bridge->sem); @@ -303,21 +342,9 @@ __ERR_FORMAT_NAME: OsalMemFree(bridge); return NULL; } -#else -static struct GpioIrqBridge *GpioIrqBridgeCreate(struct GpioCntlr *cntlr, - uint16_t local, GpioIrqFunc func, void *arg) -{ - (void)cntlr; - (void)local; - (void)func; - (void)arg; - return NULL; -} -#endif static void GpioIrqBridgeDestroy(struct GpioIrqBridge *bridge) { -#ifndef __KERNEL__ uint32_t flags; (void)OsalSpinLockIrqSave(&bridge->spin, &flags); if (!bridge->stop) { @@ -325,9 +352,6 @@ static void GpioIrqBridgeDestroy(struct GpioIrqBridge *bridge) (void)OsalSemPost(&bridge->sem); } (void)OsalSpinUnlockIrqRestore(&bridge->spin, &flags); -#else - (void)bridge; -#endif } void GpioCntlrIrqCallback(struct GpioCntlr *cntlr, uint16_t local) @@ -342,7 +366,7 @@ void GpioCntlrIrqCallback(struct GpioCntlr *cntlr, uint16_t local) HDF_LOGW("GpioCntlrIrqCallback: ginfo or irqFunc is NULL!"); } } else { - HDF_LOGW("GpioCntlrIrqCallback: invalid cntlr(ginfos) or loal num!"); + HDF_LOGW("GpioCntlrIrqCallback: invalid cntlr(ginfos) or loal num:%u!", local); } } @@ -372,11 +396,9 @@ int32_t GpioCntlrSetIrq(struct GpioCntlr *cntlr, uint16_t local, uint16_t mode, theData = bridge; theFunc = GpioIrqBridgeFunc; } -#ifndef __KERNEL__ if (bridge == NULL) { return HDF_FAILURE; } -#endif } (void)OsalSpinLockIrqSave(&cntlr->spin, &flags); diff --git a/support/platform/src/gpio_if.c b/support/platform/src/gpio_if.c index 444fdfe37..eca819fc0 100644 --- a/support/platform/src/gpio_if.c +++ b/support/platform/src/gpio_if.c @@ -16,40 +16,40 @@ int32_t GpioRead(uint16_t gpio, uint16_t *val) { - return GpioCntlrRead(GpioGetCntlr(gpio), gpio, val); + return GpioCntlrRead(GpioGetCntlr(gpio), GpioToLocal(gpio), val); } int32_t GpioWrite(uint16_t gpio, uint16_t val) { - return GpioCntlrWrite(GpioGetCntlr(gpio), gpio, val); + return GpioCntlrWrite(GpioGetCntlr(gpio), GpioToLocal(gpio), val); } int32_t GpioSetDir(uint16_t gpio, uint16_t dir) { - return GpioCntlrSetDir(GpioGetCntlr(gpio), gpio, dir); + return GpioCntlrSetDir(GpioGetCntlr(gpio), GpioToLocal(gpio), dir); } int32_t GpioGetDir(uint16_t gpio, uint16_t *dir) { - return GpioCntlrGetDir(GpioGetCntlr(gpio), gpio, dir); + return GpioCntlrGetDir(GpioGetCntlr(gpio), GpioToLocal(gpio), dir); } int32_t GpioSetIrq(uint16_t gpio, uint16_t mode, GpioIrqFunc func, void *arg) { - return GpioCntlrSetIrq(GpioGetCntlr(gpio), gpio, mode, func, arg); + return GpioCntlrSetIrq(GpioGetCntlr(gpio), GpioToLocal(gpio), mode, func, arg); } int32_t GpioUnSetIrq(uint16_t gpio) { - return GpioCntlrUnsetIrq(GpioGetCntlr(gpio), gpio); + return GpioCntlrUnsetIrq(GpioGetCntlr(gpio), GpioToLocal(gpio)); } int32_t GpioEnableIrq(uint16_t gpio) { - return GpioCntlrEnableIrq(GpioGetCntlr(gpio), gpio); + return GpioCntlrEnableIrq(GpioGetCntlr(gpio), GpioToLocal(gpio)); } int32_t GpioDisableIrq(uint16_t gpio) { - return GpioCntlrDisableIrq(GpioGetCntlr(gpio), gpio); + return GpioCntlrDisableIrq(GpioGetCntlr(gpio), GpioToLocal(gpio)); } -- Gitee