diff --git a/model/display/driver/hdf_disp.c b/model/display/driver/hdf_disp.c index 49470eb97ff0540a7242d0f003d2dec4b92344c8..77b80cb549ff586ab710216bd623239998767574 100644 --- a/model/display/driver/hdf_disp.c +++ b/model/display/driver/hdf_disp.c @@ -6,29 +6,40 @@ * See the LICENSE file in the root of this repository for complete details. */ +#include "hdf_disp.h" #include #include "hdf_base.h" #include "hdf_log.h" -#include "hdf_disp.h" +#include "osal.h" #define OFFSET_TWO_BYTE 16 +static struct DispManager *g_dispManager = NULL; -static struct PlatformOps *g_platformOps = NULL; - -int32_t PlatformRegister(struct PlatformOps *ops) +int32_t RegisterDispCtrl(struct DispControl *dispCtrl) { - if (g_platformOps == NULL) { - g_platformOps = ops; - HDF_LOGI("%s: disp ops register success", __func__); - return HDF_SUCCESS; + if (dispCtrl == NULL) { + HDF_LOGE("%s: dispCtrl is null", __func__); + return HDF_FAILURE; } - HDF_LOGD("%s: success", __func__); - return HDF_FAILURE; + if (g_dispManager == NULL) { + g_dispManager = (struct DispManager *)OsalMemCalloc(sizeof(struct DispManager)); + if (g_dispManager == NULL) { + HDF_LOGE("%s g_dispManager malloc fail", __func__); + return HDF_FAILURE; + } + g_dispManager->dispCtrl = dispCtrl; + g_dispManager->panelManager = dispCtrl->panelManager; + } + HDF_LOGI("%s: success", __func__); + return HDF_SUCCESS; } -static struct PlatformOps *GetPlatformOps(void) +static struct DispManager *GetDispManager(void) { - return g_platformOps; + if (g_dispManager != NULL && g_dispManager->initialzed) { + return g_dispManager; + } + return NULL; } static int32_t InitDisp(uint32_t devId); @@ -36,6 +47,9 @@ static int32_t DispOn(uint32_t devId); static int32_t DispOff(uint32_t devId); static int32_t SetDispBacklight(uint32_t devId, uint32_t level); static int32_t GetDispInfo(uint32_t devId, struct DispInfo *info); +static int32_t SetDispPower(uint32_t devId, uint32_t powerStatus); +static void EsdCheckStartUp(struct DispEsd *esd, uint32_t devId); +static void EsdCheckEnd(struct DispEsd *esd, uint32_t devId); struct DispOperations *GetDispOps(void) { @@ -60,132 +74,169 @@ static int32_t InitDisp(uint32_t devId) static int32_t DispOn(uint32_t devId) { - int32_t ret = HDF_FAILURE; - struct PlatformOps *ops = NULL; - - ops = GetPlatformOps(); - if (ops && ops->on) { - ret = ops->on(devId); - } - return ret; + return SetDispPower(devId, POWER_STATUS_ON); } static int32_t DispOff(uint32_t devId) { - int32_t ret = HDF_FAILURE; - struct PlatformOps *ops = NULL; - - ops = GetPlatformOps(); - if (ops && ops->off) { - ret = ops->off(devId); - } - return ret; + return SetDispPower(devId, POWER_STATUS_OFF); } static int32_t SetDispBacklight(uint32_t devId, uint32_t level) { int32_t ret = HDF_FAILURE; - struct PanelStatus *panelStatus = NULL; - - struct PanelInfo *info = GetPanelInfo(devId); - if (info == NULL) { - HDF_LOGE("%s:GetPanelInfo failed", __func__); - return HDF_FAILURE; + struct DispManager *disp = NULL; + struct PanelInfo *info = NULL; + struct DispControlOps *ops = NULL; + struct PanelData *panel = NULL; + + disp = GetDispManager(); + if (disp && disp->panelManager && devId < disp->panelManager->panelNum) { + panel = disp->panelManager->panel[devId]; + info = panel->info; + if (info == NULL) { + HDF_LOGE("%s:get info failed", __func__); + return HDF_FAILURE; + } } if (level > info->blk.maxLevel) { level = info->blk.maxLevel; } else if (level < info->blk.minLevel && level != 0) { level = info->blk.minLevel; } - struct PlatformOps *ops = GetPlatformOps(); - if (ops == NULL) { - HDF_LOGE("%s: ops is null", __func__); + if (disp->dispCtrl == NULL) { + HDF_LOGE("%s:dispCtrl is null", __func__); return HDF_FAILURE; } - if (ops->setBacklight != NULL) { - ret = ops->setBacklight(devId, level); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: setBacklight failed", __func__); - return HDF_FAILURE; - } + OsalMutexLock(&disp->dispMutex); + if (panel->status.powerStatus != POWER_STATUS_ON) { + HDF_LOGE("%s:devId[%d] not in power on mode", __func__, devId); + OsalMutexUnlock(&disp->dispMutex); + return HDF_FAILURE; } - if (ret == HDF_SUCCESS) { - panelStatus = GetPanelStatus(devId); - if (!panelStatus) { - HDF_LOGE("%s: panelStatus is null", __func__); + if (panel->status.currLevel == level) { + HDF_LOGI("%s:devId[%d] currLevel equals : %d", __func__, devId, level); + OsalMutexUnlock(&disp->dispMutex); + return HDF_SUCCESS; + } + ops = &disp->dispCtrl->ops; + if (ops->setBacklight) { + ret = ops->setBacklight(disp->dispCtrl, devId, level); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s:setBacklight failed", __func__); + OsalMutexUnlock(&disp->dispMutex); return HDF_FAILURE; } - panelStatus->currLevel = level; } + OsalMutexUnlock(&disp->dispMutex); HDF_LOGI("%s:level = %u", __func__, level); - return HDF_SUCCESS; + return ret; } static int32_t GetDispInfo(uint32_t devId, struct DispInfo *info) { - struct PlatformOps *ops = NULL; + int32_t ret = HDF_FAILURE; + struct DispControlOps *ops = NULL; + struct DispManager *disp = NULL; if (info == NULL) { HDF_LOGE("%s:info is null", __func__); return HDF_FAILURE; } - ops = GetPlatformOps(); - if (ops == NULL) { - HDF_LOGE("%s: ops is null", __func__); + disp = GetDispManager(); + if (disp == NULL) { + HDF_LOGE("%s: disp is null", __func__); + return HDF_FAILURE; + } + if (disp->dispCtrl == NULL) { + HDF_LOGE("%s: dispCtrl is null", __func__); return HDF_FAILURE; } + disp->dispCtrl->info = info; + ops = &disp->dispCtrl->ops; if (ops->getDispInfo != NULL) { - if (ops->getDispInfo(devId, info)) { + ret = ops->getDispInfo(disp->dispCtrl, devId); + if (ret != HDF_SUCCESS) { HDF_LOGE("%s: getDispInfo failed", __func__); return HDF_FAILURE; } } - return HDF_SUCCESS; + return ret; } -static int32_t SetPowerStatus(struct HdfDeviceObject *device, struct HdfSBuf *reqData, struct HdfSBuf *rspData) +static int32_t SetDispPower(uint32_t devId, uint32_t powerStatus) { - uint32_t para = 0; int32_t ret = HDF_FAILURE; - struct PanelStatus *panelStatus = NULL; + struct DispControlOps *ops = NULL; + struct DispManager *disp = NULL; + struct PanelData *panel = NULL; - (void)device; - (void)rspData; - if (reqData == NULL) { - return HDF_ERR_INVALID_PARAM; + disp = GetDispManager(); + if (disp == NULL || disp->dispCtrl == NULL) { + HDF_LOGE("%s:disp or dispCtrl is null", __func__); + return HDF_FAILURE; } - if (!HdfSbufReadUint32(reqData, ¶)) { - HDF_LOGE("%s: HdfSbufReadBuffer failed", __func__); + if (devId >= disp->panelManager->panelNum) { + HDF_LOGE("%s:devId exceed registered panelNum", __func__); return HDF_FAILURE; } - uint32_t devId = (para >> OFFSET_TWO_BYTE) & 0xffff; - uint32_t powerStatus = para & 0xffff; + panel = disp->panelManager->panel[devId]; + OsalMutexLock(&disp->dispMutex); + if (panel->status.powerStatus == powerStatus) { + OsalMutexUnlock(&disp->dispMutex); + HDF_LOGE("%s:devId[%d] already in mode = %d", __func__, devId, powerStatus); + return HDF_SUCCESS; + } + ops = &disp->dispCtrl->ops; switch (powerStatus) { case POWER_STATUS_ON: - ret = DispOn(devId); + if (ops->on) { + ret = ops->on(disp->dispCtrl, devId); + } + if (ret == HDF_SUCCESS) { + EsdCheckStartUp(disp->esd, devId); + } break; case POWER_STATUS_OFF: - ret = DispOff(devId); + if (ops->off) { + ret = ops->off(disp->dispCtrl, devId); + } + if (ret == HDF_SUCCESS) { + EsdCheckEnd(disp->esd, devId); + } break; default: HDF_LOGE("%s: not support powerStatus: %d", __func__, powerStatus); break; } - if (ret == HDF_SUCCESS) { - panelStatus = GetPanelStatus(devId); - if (panelStatus == NULL) { - HDF_LOGE("%s: panelStatus is null", __func__); - return HDF_FAILURE; - } - panelStatus->powerStatus = powerStatus; - } + OsalMutexUnlock(&disp->dispMutex); return ret; } +static int32_t SetPowerStatus(struct HdfDeviceObject *device, struct HdfSBuf *reqData, struct HdfSBuf *rspData) +{ + uint32_t para = 0; + + (void)device; + (void)rspData; + if (reqData == NULL) { + return HDF_ERR_INVALID_PARAM; + } + if (!HdfSbufReadUint32(reqData, ¶)) { + HDF_LOGE("%s: HdfSbufReadBuffer failed", __func__); + return HDF_FAILURE; + } + uint32_t devId = (para >> OFFSET_TWO_BYTE) & 0xffff; + uint32_t powerStatus = para & 0xffff; + return SetDispPower(devId, powerStatus); +} + static int32_t GetPowerStatus(struct HdfDeviceObject *device, struct HdfSBuf *reqData, struct HdfSBuf *rspData) { uint32_t devId = 0; - struct PanelStatus *panelStatus = NULL; + enum PowerStatus powerStatus; + struct DispManager *disp = NULL; + struct PanelData *panel = NULL; (void)device; if (reqData == NULL) { @@ -195,12 +246,16 @@ static int32_t GetPowerStatus(struct HdfDeviceObject *device, struct HdfSBuf *re HDF_LOGE("%s: HdfSbufReadBuffer failed", __func__); return HDF_FAILURE; } - panelStatus = GetPanelStatus(devId); - if (!panelStatus) { - HDF_LOGE("%s: panelStatus is null", __func__); + disp = GetDispManager(); + if (disp == NULL || disp->panelManager == NULL || (devId >= disp->panelManager->panelNum)) { + HDF_LOGE("%s: get panel failed", __func__); return HDF_FAILURE; } - if (!HdfSbufWriteUint32(rspData, panelStatus->powerStatus)) { + OsalMutexLock(&disp->dispMutex); + panel = disp->panelManager->panel[devId]; + powerStatus = panel->status.powerStatus; + OsalMutexUnlock(&disp->dispMutex); + if (!HdfSbufWriteUint32(rspData, powerStatus)) { HDF_LOGE("%s: HdfSbufWriteUint32 failed", __func__); return HDF_FAILURE; } @@ -230,7 +285,9 @@ static int32_t SetBacklight(struct HdfDeviceObject *device, struct HdfSBuf *reqD static int32_t GetBacklight(struct HdfDeviceObject *device, struct HdfSBuf *reqData, struct HdfSBuf *rspData) { uint32_t devId = 0; - struct PanelStatus *panelStatus = NULL; + uint32_t currLevel; + struct DispManager *disp = NULL; + struct PanelData *panel = NULL; (void)device; if (reqData == NULL) { @@ -240,12 +297,16 @@ static int32_t GetBacklight(struct HdfDeviceObject *device, struct HdfSBuf *reqD HDF_LOGE("%s: HdfSbufReadBuffer failed", __func__); return HDF_FAILURE; } - panelStatus = GetPanelStatus(devId); - if (!panelStatus) { - HDF_LOGE("%s: panelStatus is null", __func__); + disp = GetDispManager(); + if (disp == NULL || disp->panelManager == NULL || (devId >= disp->panelManager->panelNum)) { + HDF_LOGE("%s: get panel failed", __func__); return HDF_FAILURE; } - if (!HdfSbufWriteUint32(rspData, panelStatus->currLevel)) { + OsalMutexLock(&disp->dispMutex); + panel = disp->panelManager->panel[devId]; + currLevel = panel->status.currLevel; + OsalMutexUnlock(&disp->dispMutex); + if (!HdfSbufWriteUint32(rspData, currLevel)) { HDF_LOGE("%s: HdfSbufWriteUint32 failed", __func__); return HDF_FAILURE; } @@ -327,29 +388,276 @@ static int HdfDispBind(struct HdfDeviceObject *dev) return HDF_SUCCESS; } -static int32_t HdfDispEntryInit(struct HdfDeviceObject *object) +static void PanelRecovery(struct DispControl *dispCtrl, uint32_t devId) { + struct DispControlOps *ops = NULL; + + HDF_LOGI("%s enter", __func__); + ops = &dispCtrl->ops; + if (ops->off) { + ops->off(dispCtrl, devId); + } + OsalMSleep(150); // delay 150ms + if (ops->on) { + ops->on(dispCtrl, devId); + } +} + +static void EsdTimerHandler(uintptr_t arg) +{ + uint32_t devId = (uint32_t)arg; + struct DispManager *disp = NULL; + + disp = GetDispManager(); + if (devId >= disp->esd->panelNum) { + HDF_LOGE("%s: esd is null", __func__); + return; + } + HdfAddWork(&disp->dispWorkQueue, disp->esd->work[devId]); + HDF_LOGD("%s devId[%d] add work to wq", __func__, devId); +} + +static void EsdWorkHandler(void *arg) +{ + int32_t ret = HDF_SUCCESS; + uint32_t devId = (uint32_t)arg; + struct PanelData *panel = NULL; + struct DispManager *disp = NULL; + + disp = GetDispManager(); + if ((disp->dispCtrl == NULL) || (devId >= disp->panelManager->panelNum)) { + HDF_LOGE("%s: dispCtrl is null or panel is null", __func__); + return; + } + panel = disp->panelManager->panel[devId]; + if ((panel->esd != NULL) && (panel->esd->checkFunc != NULL)) { + ret = panel->esd->checkFunc(panel); + } + if (ret != HDF_SUCCESS) { + OsalMutexLock(&disp->dispMutex); + if (panel->esd->state == ESD_RUNNING) { + PanelRecovery(disp->dispCtrl, devId); + } else { + HDF_LOGI("%s: esd check has disabled", __func__); + OsalMutexUnlock(&disp->dispMutex); + return; + } + OsalMutexUnlock(&disp->dispMutex); + panel->esd->recoveryNum++; + } + HDF_LOGD("%s devId[%d] recoveryNum = %d",__func__, devId, panel->esd->recoveryNum); + if (panel->esd->recoveryNum >= ESD_MAX_RECOVERY) { + panel->esd->recoveryNum = 0; + OsalMutexLock(&disp->dispMutex); + if (panel->esd->state == ESD_RUNNING) { + OsalTimerDelete(disp->esd->timer[devId]); + panel->esd->state = ESD_READY; + HDF_LOGI("%s disable esd check", __func__); + } else { + HDF_LOGI("%s: esd check has disabled", __func__); + OsalMutexUnlock(&disp->dispMutex); + return; + } + OsalMutexUnlock(&disp->dispMutex); + } +} + +static void EsdCheckStartUp(struct DispEsd *esd, uint32_t devId) +{ + if (esd == NULL) { + HDF_LOGE("%s esd is null", __func__); + return; + } + HDF_LOGD("%s enter", __func__); + if ((esd->panelEsd[devId] != NULL) && esd->panelEsd[devId]->support) { + if (esd->panelEsd[devId]->state == ESD_READY) { + OsalTimerCreate(esd->timer[devId], esd->panelEsd[devId]->interval, + EsdTimerHandler, (uintptr_t)devId); + OsalTimerStartLoop(esd->timer[devId]); + esd->panelEsd[devId]->state = ESD_RUNNING; + HDF_LOGI("%s , devId[%d] enable esd check", __func__, devId); + } + } +} + +static void EsdCheckEnd(struct DispEsd *esd, uint32_t devId) +{ + if (esd == NULL) { + HDF_LOGE("%s esd is null", __func__); + return; + } + HDF_LOGD("%s enter", __func__); + if ((esd->panelEsd[devId] != NULL) && (esd->panelEsd[devId]->support)) { + esd->panelEsd[devId]->recoveryNum = 0; + if (esd->panelEsd[devId]->state == ESD_RUNNING) { + OsalTimerDelete(esd->timer[devId]); + esd->panelEsd[devId]->state = ESD_READY; + HDF_LOGI("%s devId[%d], disable esd check", __func__, devId); + } + } +} + +static struct DispEsd *EsdResMalloc(int32_t panelNum) +{ + struct DispEsd *esd = NULL; + + esd = (struct DispEsd *)OsalMemCalloc(sizeof(struct DispEsd)); + if (esd == NULL) { + HDF_LOGE("%s esd malloc fail", __func__); + return NULL; + } + esd->panelEsd = (struct PanelEsd **)OsalMemCalloc(sizeof(struct PanelEsd *) * panelNum); + if (esd->panelEsd == NULL) { + HDF_LOGE("%s panelEsd malloc fail", __func__); + goto PANEL_ESD_EXIT; + } + esd->work = (HdfWork **)OsalMemCalloc(sizeof(HdfWork *) * panelNum); + if (esd->work == NULL) { + HDF_LOGE("%s work malloc fail", __func__); + goto WORK_EXIT; + } + esd->timer = (OsalTimer **)OsalMemCalloc(sizeof(OsalTimer *) * panelNum); + if (esd->timer == NULL) { + HDF_LOGE("%s timer malloc fail", __func__); + goto TIMER_EXIT; + } + esd->workInit = (bool *)OsalMemCalloc(sizeof(bool) * panelNum); + if (esd->workInit == NULL) { + HDF_LOGE("%s workInit malloc fail", __func__); + goto WORK_INIT_EXIT; + } + return esd; + +WORK_INIT_EXIT: + OsalMemFree(esd->timer); +TIMER_EXIT: + OsalMemFree(esd->work); +WORK_EXIT: + OsalMemFree(esd->panelEsd); +PANEL_ESD_EXIT: + OsalMemFree(esd); + + return NULL; +} + +static void EsdMemFree(struct DispEsd *esd) +{ + int32_t i; + + for (i = 0; i < esd->panelNum; i++) { + if (esd->workInit[i] == true) { + HdfWorkDestroy(esd->work[i]); + } + OsalMemFree(esd->work[i]); + OsalMemFree(esd->timer[i]); + } + OsalMemFree(esd->panelEsd); + OsalMemFree(esd->work); + OsalMemFree(esd->timer); + OsalMemFree(esd); +} + +static int32_t EsdResInit(struct DispEsd *esd, struct PanelData **panel) +{ + int32_t i; int32_t ret; + + for (i = 0; i < esd->panelNum; i++) { + if ((panel[i]->esd != NULL) && panel[i]->esd->support) { + esd->panelEsd[i] = panel[i]->esd; + esd->work[i] = (HdfWork *)OsalMemCalloc(sizeof(HdfWork)); + if (esd->work[i] == NULL) { + HDF_LOGE("%s work malloc fail", __func__); + EsdMemFree(esd); + return HDF_FAILURE; + } + esd->timer[i] = (OsalTimer *)OsalMemCalloc(sizeof(OsalTimer)); + if (esd->timer[i] == NULL) { + EsdMemFree(esd); + HDF_LOGE("%s timer malloc fail", __func__); + return HDF_FAILURE; + } + if (esd->panelEsd[i]->interval < ESD_DEFAULT_INTERVAL) { + esd->panelEsd[i]->interval = ESD_DEFAULT_INTERVAL; + } + ret = HdfWorkInit(esd->work[i], EsdWorkHandler, (void *)i); + if (ret != HDF_SUCCESS) { + EsdMemFree(esd); + HDF_LOGE("%s HdfWorkInit fail", __func__); + return HDF_FAILURE; + } + esd->workInit[i] = true; + esd->panelEsd[i]->state = ESD_READY; + } + } + return HDF_SUCCESS; +} + +static int32_t EsdCheckInit(struct DispManager *disp) +{ int32_t i; - struct PlatformOps *ops = GetPlatformOps(); + int32_t ret; + int32_t count = 0; + int32_t panelNum; + struct DispEsd *esd = NULL; + struct PanelData **panel = NULL; + + if (disp->panelManager == NULL) { + HDF_LOGE("%s panelManager is null", __func__); + return HDF_FAILURE; + } + panel = disp->panelManager->panel; + panelNum = disp->panelManager->panelNum; + for (i = 0; i < panelNum; i++) { + if ((panel[i]->esd != NULL) && panel[i]->esd->support) { + count++; + break; + } + } + if (count == 0) { + HDF_LOGI("%s none of panels support esd", __func__); + return HDF_SUCCESS; + } + esd = EsdResMalloc(panelNum); + if (esd == NULL) { + HDF_LOGE("%s EsdResInit fail", __func__); + return HDF_FAILURE; + } + esd->panelNum = panelNum; + ret = EsdResInit(esd, panel); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s EsdResInit fail", __func__); + return HDF_FAILURE; + } + disp->esd = esd; + return HDF_SUCCESS; +} + +static int32_t HdfDispEntryInit(struct HdfDeviceObject *object) +{ + int32_t ret; if (object == NULL) { HDF_LOGE("%s: object is null!", __func__); return HDF_FAILURE; } - if (ops == NULL) { - HDF_LOGE("%s: ops is null", __func__); + if (g_dispManager == NULL) { + HDF_LOGE("%s: g_dispManager is null", __func__); return HDF_FAILURE; } - if (ops->init != NULL) { - for (i = 0; i < g_numRegisteredPanel; i++) { - ret = ops->init(i); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: init failed", __func__); - return HDF_FAILURE; - } - } + ret = HdfWorkQueueInit(&g_dispManager->dispWorkQueue, "dispWQ"); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: HdfWorkQueueInit fail", __func__); + return HDF_FAILURE; + } + ret = EsdCheckInit(g_dispManager); + if (ret != HDF_SUCCESS) { + HdfWorkQueueDestroy(&g_dispManager->dispWorkQueue); + HDF_LOGE("%s: EsdCheckInit fail", __func__); + return HDF_FAILURE; } + OsalMutexInit(&g_dispManager->dispMutex); + g_dispManager->initialzed = true; return HDF_SUCCESS; } diff --git a/model/display/driver/hdf_disp.h b/model/display/driver/hdf_disp.h index 7a8a5015f644c1c82f3932d035f02ebc17659bcc..4c9f2e8529a4da14a1b6bf132c8ad987dfe9d282 100644 --- a/model/display/driver/hdf_disp.h +++ b/model/display/driver/hdf_disp.h @@ -11,12 +11,18 @@ #include "hdf_base.h" #include "hdf_device_desc.h" #include "hdf_sbuf.h" +#include "hdf_workqueue.h" #include "lcd_abs_if.h" +#include "osal_mem.h" +#include "osal_mutex.h" +#include "osal_timer.h" #ifdef HDF_LOG_TAG #undef HDF_LOG_TAG #endif #define HDF_LOG_TAG HDF_DISP +#define ESD_DEFAULT_INTERVAL 5000 +#define ESD_MAX_RECOVERY 10 typedef int32_t (*DispCmdHandle)(struct HdfDeviceObject *device, struct HdfSBuf *reqData, struct HdfSBuf *rspData); @@ -45,20 +51,42 @@ struct DispOperations { int32_t (*getDispInfo)(uint32_t devId, struct DispInfo *info); }; -struct PlatformOps { - int32_t (*init)(uint32_t devId); - int32_t (*on)(uint32_t devId); - int32_t (*off)(uint32_t devId); - int32_t (*setBacklight)(uint32_t devId, uint32_t level); - int32_t (*getDispInfo)(uint32_t devId, struct DispInfo *info); +enum EsdState { + ESD_READY = 1, + ESD_RUNNING, +}; + +struct DispEsd { + struct PanelEsd **panelEsd; + HdfWork **work; + bool *workInit; + OsalTimer **timer; + int32_t panelNum; +}; + +struct DispControl; +struct DispControlOps { + int32_t (*on)(struct DispControl *dispCtrl, uint32_t devId); + int32_t (*off)(struct DispControl *dispCtrl, uint32_t devId); + int32_t (*setBacklight)(struct DispControl *dispCtrl, uint32_t devId, uint32_t level); + int32_t (*getDispInfo)(struct DispControl *dispCtrl, uint32_t devId); +}; + +struct DispControl { + struct HdfDeviceObject *object; + struct PanelManager *panelManager; + struct DispInfo *info; + struct DispControlOps ops; }; -enum PowerMode { - DISP_ON, - DISP_OFF, +struct DispManager { + struct DispControl *dispCtrl; + struct PanelManager *panelManager; + struct OsalMutex dispMutex; + HdfWorkQueue dispWorkQueue; + bool initialzed; + struct DispEsd *esd; }; -int32_t PlatformRegister(struct PlatformOps *ops); -struct PanelInfo *GetPanelInfo(int32_t index); -struct PanelStatus *GetPanelStatus(int32_t index); +int32_t RegisterDispCtrl(struct DispControl *dispCtrl); #endif /* HDF_DISP_H */ diff --git a/model/display/driver/hi35xx_disp.c b/model/display/driver/hi35xx_disp.c index 44665b15038a56438b48a7bab77c8d069ba3467e..98ddc0e3e9bdf2c205d583ef1795054c527c30ee 100644 --- a/model/display/driver/hi35xx_disp.c +++ b/model/display/driver/hi35xx_disp.c @@ -14,11 +14,18 @@ #include "hdf_log.h" #include "lcd_abs_if.h" #include "osal_io.h" +#include "osal_mem.h" #include "pwm_if.h" #define TRANSFORM_KILO 1000 #define TRANSFORM_MILL 1000000 +struct Hi35xxDispCtrl { + struct DispControl ctrl; + unsigned long mipiCfgBase; + unsigned long pwmCfgBase; +}; + static void MipiMuxCfg(unsigned long ioCfgBase) { /* config dsi data lane0 */ @@ -100,11 +107,11 @@ void Lcd24BitMuxCfg(unsigned long ioCfgBase) OSAL_WRITEL(0x532, ioCfgBase + 0x0030); } -static void LcdPinMuxCfg(uint32_t intf) +static void LcdPinMuxCfg(const struct Hi35xxDispCtrl *hi35xxCtrl, uint32_t intf) { unsigned long ioCfgBase; - ioCfgBase = (unsigned long)OsalIoRemap(IO_CFG2_BASE, IO_CFG_SIZE); + ioCfgBase = hi35xxCtrl->mipiCfgBase; if (intf == MIPI_DSI) { MipiMuxCfg(ioCfgBase); } else if (intf == LCD_6BIT) { @@ -118,11 +125,12 @@ static void LcdPinMuxCfg(uint32_t intf) } } -static void PwmPinMuxCfg(uint32_t dev) +static void PwmPinMuxCfg(const struct Hi35xxDispCtrl *hi35xxCtrl, uint32_t dev) { /* pwm pin config */ unsigned long ioCfgBase; - ioCfgBase = (unsigned long)OsalIoRemap(IO_CFG1_BASE, IO_CFG_SIZE); + + ioCfgBase = hi35xxCtrl->pwmCfgBase; switch (dev) { case PWM_DEV0: OSAL_WRITEL(0x601, ioCfgBase + 0x0024); @@ -232,12 +240,12 @@ static int32_t MipiDsiInit(struct PanelInfo *info) return ret; } -static int32_t PwmInit(struct PanelInfo *info) +static int32_t PwmInit(struct Hi35xxDispCtrl *hi35xxCtrl, struct PanelInfo *info) { int32_t ret; /* pwm pin config */ - PwmPinMuxCfg(info->pwm.dev); + PwmPinMuxCfg(hi35xxCtrl, info->pwm.dev); /* pwm config */ struct DevHandle *pwmHandle = PwmOpen(info->pwm.dev); if (pwmHandle == NULL) { @@ -259,45 +267,57 @@ static int32_t PwmInit(struct PanelInfo *info) return HDF_SUCCESS; } -static int32_t Hi35xxInit(uint32_t devId) +static int32_t Hi35xxHardwareInit(struct Hi35xxDispCtrl *hi35xxCtrl) { - int32_t ret; - struct PanelInfo *info = GetPanelInfo(devId); - if (info == NULL) { - HDF_LOGE("%s:GetPanelInfo failed", __func__); + int32_t i; + int32_t panelNum; + int32_t ret = HDF_FAILURE; + struct PanelData **panel = NULL; + struct PanelInfo *info = NULL; + + if (hi35xxCtrl->ctrl.panelManager == NULL) { + HDF_LOGE("%s: panelManager is null", __func__); return HDF_FAILURE; } - if (info->blk.type == BLK_PWM) { - ret = PwmInit(info); - if (ret) { - HDF_LOGE("%s:PwmInit failed", __func__); - return HDF_FAILURE; - } - } - /* lcd pin mux config */ - LcdPinMuxCfg(info->intfType); - if (info->intfType == MIPI_DSI) { - /* mipi dsi init */ - ret = MipiDsiInit(info); - if (ret) { - HDF_LOGE("%s:MipiDsiInit failed", __func__); - return HDF_FAILURE; - } - } - struct PanelData *panelData = GetPanelData(devId); - if (panelData == NULL) { - HDF_LOGE("%s: panel data is null", __func__); + if (hi35xxCtrl->ctrl.panelManager->panelNum <= 0) { + HDF_LOGE("%s: none of panels registered", __func__); return HDF_FAILURE; } - if (panelData->init != NULL) { - /* panel driver init */ - ret = panelData->init(); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: panelData->init failed", __func__); + panelNum = hi35xxCtrl->ctrl.panelManager->panelNum; + panel = hi35xxCtrl->ctrl.panelManager->panel; + for (i = 0; i < panelNum; i++) { + info = panel[i]->info; + if (info == NULL) { + HDF_LOGE("%s:get info failed", __func__); return HDF_FAILURE; } + if (info->blk.type == BLK_PWM) { + ret = PwmInit(hi35xxCtrl, info); + if (ret) { + HDF_LOGE("%s:PwmInit failed", __func__); + return HDF_FAILURE; + } + } + /* lcd pin mux config */ + LcdPinMuxCfg(hi35xxCtrl, info->intfType); + if (info->intfType == MIPI_DSI) { + /* mipi dsi init */ + ret = MipiDsiInit(info); + if (ret) { + HDF_LOGE("%s:MipiDsiInit failed", __func__); + return HDF_FAILURE; + } + } + if (panel[i]->init != NULL) { + /* panel driver init */ + ret = panel[i]->init(panel[i]); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: panelData->init failed", __func__); + return HDF_FAILURE; + } + } } - return HDF_SUCCESS; + return ret; } static int32_t GetLcdIntfType(enum LcdIntfType type, uint32_t *out) @@ -331,13 +351,31 @@ static int32_t GetLcdIntfType(enum LcdIntfType type, uint32_t *out) return ret; } -static int32_t Hi35xxGetDispInfo(uint32_t devId, struct DispInfo *info) +static int32_t Hi35xxGetDispInfo(struct DispControl *dispCtrl, uint32_t devId) { - struct PanelInfo *panelInfo = GetPanelInfo(devId); + struct PanelInfo *panelInfo = NULL; + struct DispInfo *info = NULL; + struct PanelData *panel = NULL; + + if (dispCtrl == NULL) { + HDF_LOGE("%s:dispCtrl is null", __func__); + return HDF_FAILURE; + } + if (dispCtrl->panelManager == NULL || (devId >= dispCtrl->panelManager->panelNum)) { + HDF_LOGE("%s: get panel fail", __func__); + return HDF_FAILURE; + } + panel = dispCtrl->panelManager->panel[devId]; + if (panel == NULL) { + HDF_LOGE("%s:panel is null", __func__); + return HDF_FAILURE; + } + panelInfo = panel->info; if (panelInfo == NULL) { - HDF_LOGE("%s:GetPanelInfo failed", __func__); + HDF_LOGE("%s:get info failed", __func__); return HDF_FAILURE; } + info = dispCtrl->info; if (info == NULL) { HDF_LOGE("%s:info is null", __func__); return HDF_FAILURE; @@ -365,84 +403,135 @@ static int32_t Hi35xxGetDispInfo(uint32_t devId, struct DispInfo *info) return HDF_SUCCESS; } -static int32_t Hi35xxOn(uint32_t devId) +static int32_t Hi35xxOn(struct DispControl *dispCtrl, uint32_t devId) { - int32_t ret; - struct PanelData *panelData = NULL; + int32_t ret = HDF_FAILURE; + struct PanelData *panel = NULL; - panelData = GetPanelData(devId); - if (panelData == NULL) { - HDF_LOGE("%s: panel data is null", __func__); + if (dispCtrl == NULL) { + HDF_LOGE("%s: dispCtrl is null", __func__); + return HDF_FAILURE; + } + if (dispCtrl->panelManager == NULL || (devId >= dispCtrl->panelManager->panelNum)) { + HDF_LOGE("%s: get panel fail", __func__); + return HDF_FAILURE; + } + panel = dispCtrl->panelManager->panel[devId]; + if (panel == NULL) { + HDF_LOGE("%s: panel is null", __func__); return HDF_FAILURE; } - if (panelData->on != NULL) { + if (panel->on != NULL) { /* panel driver on */ - ret = panelData->on(); + ret = panel->on(panel); if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: panelData->on failed", __func__); + HDF_LOGE("%s: panel->on failed", __func__); return HDF_FAILURE; } } - return HDF_SUCCESS; + return ret; } -static int32_t Hi35xxOff(uint32_t devId) +static int32_t Hi35xxOff(struct DispControl *dispCtrl, uint32_t devId) { - int32_t ret; - struct PanelData *panelData = NULL; + int32_t ret = HDF_FAILURE; + struct PanelData *panel = NULL; - panelData = GetPanelData(devId); - if (panelData == NULL) { - HDF_LOGE("%s: panel data is null", __func__); + if (dispCtrl == NULL) { + HDF_LOGE("%s: dispCtrl is null", __func__); + return HDF_FAILURE; + } + if (dispCtrl->panelManager == NULL || (devId >= dispCtrl->panelManager->panelNum)) { + HDF_LOGE("%s: get panel fail", __func__); + return HDF_FAILURE; + } + panel = dispCtrl->panelManager->panel[devId]; + if (panel == NULL) { + HDF_LOGE("%s: panel is null", __func__); return HDF_FAILURE; } - if (panelData->off != NULL) { + if (panel->off != NULL) { /* panel driver off */ - ret = panelData->off(); + ret = panel->off(panel); if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: panelData->off failed", __func__); + HDF_LOGE("%s: panel->off failed", __func__); return HDF_FAILURE; } } - return HDF_SUCCESS; + return ret; } -static int32_t Hi35xxSetBacklight(uint32_t devId, uint32_t level) +static int32_t Hi35xxSetBacklight(struct DispControl *dispCtrl, uint32_t devId, uint32_t level) { - int32_t ret; - struct PanelData *panelData = NULL; + int32_t ret = HDF_FAILURE; + struct PanelData *panel = NULL; - panelData = GetPanelData(devId); - if (panelData == NULL) { - HDF_LOGE("%s: panel data is null", __func__); + if (dispCtrl == NULL) { + HDF_LOGE("%s: dispCtrl is null", __func__); + return HDF_FAILURE; + } + if (dispCtrl->panelManager == NULL || (devId >= dispCtrl->panelManager->panelNum)) { + HDF_LOGE("%s: get panel fail", __func__); return HDF_FAILURE; } - if (panelData->setBacklight != NULL) { + panel = dispCtrl->panelManager->panel[devId]; + if (panel == NULL) { + HDF_LOGE("%s: panel is null", __func__); + return HDF_FAILURE; + } + if (panel->setBacklight != NULL) { /* panel driver set backlight */ - ret = panelData->setBacklight(level); + ret = panel->setBacklight(panel, level); if (ret != HDF_SUCCESS) { HDF_LOGE("%s: setBacklight failed", __func__); return HDF_FAILURE; } } - return HDF_SUCCESS; + return ret; } -struct PlatformOps g_hi35xxOps = { - .init = Hi35xxInit, - .on = Hi35xxOn, - .off = Hi35xxOff, - .setBacklight = Hi35xxSetBacklight, - .getDispInfo = Hi35xxGetDispInfo, -}; +static int32_t Hi35xxResInit(struct Hi35xxDispCtrl *hi35xxCtrl, struct PanelManager *panelManager) +{ + hi35xxCtrl->ctrl.ops.on = Hi35xxOn; + hi35xxCtrl->ctrl.ops.off = Hi35xxOff; + hi35xxCtrl->ctrl.ops.setBacklight = Hi35xxSetBacklight; + hi35xxCtrl->ctrl.ops.getDispInfo = Hi35xxGetDispInfo; + hi35xxCtrl->ctrl.panelManager = panelManager; + hi35xxCtrl->mipiCfgBase = (unsigned long)OsalIoRemap(IO_CFG2_BASE, IO_CFG_SIZE); + hi35xxCtrl->pwmCfgBase = (unsigned long)OsalIoRemap(IO_CFG1_BASE, IO_CFG_SIZE); + return HDF_SUCCESS; +} static int32_t Hi35xxEntryInit(struct HdfDeviceObject *object) { + struct PanelManager *panelManager = NULL; + struct Hi35xxDispCtrl *hi35xxCtrl = NULL; + if (object == NULL) { - HDF_LOGE("%s: param is null!", __func__); + HDF_LOGE("%s: object is null!", __func__); + return HDF_FAILURE; + } + hi35xxCtrl = (struct Hi35xxDispCtrl *)OsalMemCalloc(sizeof(struct Hi35xxDispCtrl)); + if (hi35xxCtrl == NULL) { + HDF_LOGE("%s hi35xxCtrl malloc fail", __func__); + return HDF_FAILURE; + } + panelManager = GetPanelManager(); + if (panelManager == NULL) { + HDF_LOGE("%s: panelManager is null", __func__); + return HDF_FAILURE; + } + if (Hi35xxResInit(hi35xxCtrl, panelManager) == HDF_FAILURE) { + HDF_LOGE("%s Hi35xxResInit fail", __func__); + return HDF_FAILURE; + } + if (Hi35xxHardwareInit(hi35xxCtrl) == HDF_FAILURE) { + HDF_LOGE("%s Hi35xxHardwareInit fail", __func__); return HDF_FAILURE; } - return PlatformRegister(&g_hi35xxOps); + hi35xxCtrl->ctrl.object = object; + hi35xxCtrl->ctrl.object->priv = hi35xxCtrl; + return RegisterDispCtrl(&hi35xxCtrl->ctrl); } struct HdfDriverEntry g_hi35xxDevEntry = { diff --git a/model/display/driver/hi35xx_disp.h b/model/display/driver/hi35xx_disp.h index 4f5427e6a29dab1191bd823967774032cac01e1c..bd32ca286a9c2454d3ca28ff01b9b0fa3472498b 100644 --- a/model/display/driver/hi35xx_disp.h +++ b/model/display/driver/hi35xx_disp.h @@ -26,6 +26,4 @@ #define PWM_DEV0 0 #define PWM_DEV1 1 -struct PanelData *GetPanelData(int32_t index); -struct PanelInfo *GetPanelInfo(int32_t index); #endif /* HI35XX_DISP_H */ diff --git a/model/display/driver/lcd_abs_if.c b/model/display/driver/lcd_abs_if.c index c95d2e50dbb79f4c5e36c776c3a9c48ef80ff3a4..8f7134d312ef455f54b0ea803886016933baba67 100644 --- a/model/display/driver/lcd_abs_if.c +++ b/model/display/driver/lcd_abs_if.c @@ -11,62 +11,47 @@ #include "hdf_device_desc.h" #include "osal.h" -/* support max panel number */ -#define PANEL_MAX 2 -static struct PanelData *g_panelData[PANEL_MAX]; -int32_t g_numRegisteredPanel; - -int32_t PanelDataRegister(struct PanelData *data) +static struct PanelManager g_panelManager; +int32_t RegisterPanel(struct PanelData *data) { - int32_t i; + int32_t panelNum; if (data == NULL) { HDF_LOGE("%s: panel data is null", __func__); return HDF_ERR_INVALID_PARAM; } - if (g_numRegisteredPanel == PANEL_MAX) { + panelNum = g_panelManager.panelNum; + if (panelNum >= PANEL_MAX) { + HDF_LOGE("%s registered panel up PANEL_MAX", __func__); return HDF_FAILURE; } - g_numRegisteredPanel++; - for (i = 0; i < PANEL_MAX; i++) { - if (g_panelData[i] == NULL) { - break; - } - } - if (i >= PANEL_MAX) { - return HDF_FAILURE; - } - g_panelData[i] = data; - HDF_LOGI("%s: panel data register success", __func__); + g_panelManager.panel[panelNum] = data; + g_panelManager.panelNum++; + HDF_LOGI("%s: register success", __func__); return HDF_SUCCESS; } -struct PanelData *GetPanelData(int32_t index) +struct PanelManager *GetPanelManager(void) { - if ((index >= PANEL_MAX) || index < 0) { + if (g_panelManager.panelNum == 0) { return NULL; + } else { + return &g_panelManager; } - return g_panelData[index]; } -struct PanelInfo *GetPanelInfo(int32_t index) +struct PanelData *GetPanel(int32_t index) { - if ((index >= PANEL_MAX) || index < 0) { - return NULL; - } - if (g_panelData[index] == NULL) { - return NULL; - } - return g_panelData[index]->info; -} + struct PanelManager *panelManager = NULL; -struct PanelStatus *GetPanelStatus(const int32_t index) -{ - if ((index >= PANEL_MAX) || index < 0) { + panelManager = GetPanelManager(); + if (panelManager == NULL) { + HDF_LOGE("%s panelManager is null", __func__); return NULL; } - if (g_panelData[index] == NULL) { + if (index >= g_panelManager.panelNum) { + HDF_LOGE("%s index is greater than g_panelManager.panelNum", __func__); return NULL; } - return g_panelData[index]->status; + return panelManager->panel[index]; } diff --git a/model/display/driver/lcd_abs_if.h b/model/display/driver/lcd_abs_if.h index 04ed31ae1a4f57587ebf4c40ce4e1ba804b0dd4d..aa20f497fc5c981e051245ddd9d9227455a3d839 100644 --- a/model/display/driver/lcd_abs_if.h +++ b/model/display/driver/lcd_abs_if.h @@ -9,9 +9,13 @@ #ifndef LCD_ABS_IF_H #define LCD_ABS_IF_H #include "hdf_base.h" +#include "hdf_device_desc.h" #include "hdf_log.h" #include "mipi_dsi_if.h" +/* support max panel number */ +#define PANEL_MAX 2 + enum LcdIntfType { MIPI_DSI, LCD_6BIT, @@ -126,17 +130,35 @@ struct PanelStatus { enum PowerStatus powerStatus; uint32_t currLevel; }; + +struct PanelData; +struct PanelEsd { + bool support; + uint32_t interval; + uint32_t state; + uint32_t recoveryNum; + uint32_t cmpMode; + int32_t (*checkFunc)(struct PanelData *panel); + void *expect_data; +}; + struct PanelData { + struct HdfDeviceObject *object; + int32_t (*init)(struct PanelData *panel); + int32_t (*on)(struct PanelData *panel); + int32_t (*off)(struct PanelData *panel); + int32_t (*setBacklight)(struct PanelData *panel, uint32_t level); struct PanelInfo *info; - struct PanelStatus *status; - int32_t (*init)(void); - int32_t (*on)(void); - int32_t (*off)(void); - int32_t (*setBacklight)(uint32_t level); + struct PanelStatus status; + struct PanelEsd *esd; }; -extern int32_t g_numRegisteredPanel; - -int32_t PanelDataRegister(struct PanelData *data); +struct PanelManager { + struct PanelData *panel[PANEL_MAX]; + uint32_t panelNum; +}; +int32_t RegisterPanel(struct PanelData *data); +struct PanelManager *GetPanelManager(void); +struct PanelData *GetPanel(int32_t index); #endif /* LCD_ABS_IF_H */ diff --git a/model/display/driver/panel/mipi_icn9700.c b/model/display/driver/panel/mipi_icn9700.c index 311e4c6040f92882bed5f507b8a97dc6eb178839..6952230ce6d65a8488a0f152eafe1153c90d46bf 100644 --- a/model/display/driver/panel/mipi_icn9700.c +++ b/model/display/driver/panel/mipi_icn9700.c @@ -7,7 +7,6 @@ */ #include "gpio_if.h" -#include "hdf_device_desc.h" #include "hdf_log.h" #include "lcd_abs_if.h" #include "mipi_dsi_if.h" @@ -92,58 +91,65 @@ struct DsiCmdDesc g_offCmd[] = { { 0x05, 120, sizeof(g_offPayLoad1), g_offPayLoad1 }, }; -static DevHandle g_mipiHandle = NULL; -static DevHandle g_pwmHandle = NULL; +struct Icn9700Dev { + struct PanelData panel; + DevHandle mipiHandle; + DevHandle pwmHandle; + uint16_t reset_gpio; + uint16_t reset_delay; +}; -static int32_t LcdResetOn(void) +static int32_t LcdResetOn(struct Icn9700Dev *icn9700) { int32_t ret; - ret = GpioSetDir(RESET_GPIO, GPIO_DIR_OUT); + ret = GpioSetDir(icn9700->reset_gpio, GPIO_DIR_OUT); if (ret != HDF_SUCCESS) { HDF_LOGE("GpioSetDir failed, ret:%d", ret); return HDF_FAILURE; } - ret = GpioWrite(RESET_GPIO, GPIO_VAL_HIGH); + ret = GpioWrite(icn9700->reset_gpio, GPIO_VAL_HIGH); if (ret != HDF_SUCCESS) { HDF_LOGE("GpioWrite failed, ret:%d", ret); return HDF_FAILURE; } /* delay 20ms */ - OsalMSleep(20); + OsalMSleep(icn9700->reset_delay); return HDF_SUCCESS; } -static int32_t LcdResetOff(void) +static int32_t LcdResetOff(struct Icn9700Dev *icn9700) { int32_t ret; - ret = GpioSetDir(RESET_GPIO, GPIO_DIR_OUT); + ret = GpioSetDir(icn9700->reset_gpio, GPIO_DIR_OUT); if (ret != HDF_SUCCESS) { HDF_LOGE("GpioSetDir failed, ret:%d", ret); return HDF_FAILURE; } - ret = GpioWrite(RESET_GPIO, GPIO_VAL_LOW); + ret = GpioWrite(icn9700->reset_gpio, GPIO_VAL_LOW); if (ret != HDF_SUCCESS) { HDF_LOGE("GpioWrite failed, ret:%d", ret); return HDF_FAILURE; } /* delay 20ms */ - OsalMSleep(20); + OsalMSleep(icn9700->reset_delay); return HDF_SUCCESS; } -static int32_t PwmCfg(void) +static int32_t PwmCfg(struct Icn9700Dev *icn9700) { - g_pwmHandle = PwmOpen(BLK_PWM1); - if (g_pwmHandle == NULL) { + DevHandle pwmHandle = NULL; + + pwmHandle = PwmOpen(BLK_PWM1); + if (pwmHandle == NULL) { HDF_LOGE("%s: PwmOpen failed", __func__); return HDF_FAILURE; } /* pwm config */ int32_t ret; struct PwmConfig config; - ret = PwmGetConfig(g_pwmHandle, &config); + ret = PwmGetConfig(pwmHandle, &config); if (ret != HDF_SUCCESS) { HDF_LOGE("%s: PwmGetConfig fail, ret %d", __func__, ret); return HDF_FAILURE; @@ -151,106 +157,165 @@ static int32_t PwmCfg(void) config.duty = 1; config.period = PWM_MAX_PERIOD; config.status = 1; - ret = PwmSetConfig(g_pwmHandle, &config); + ret = PwmSetConfig(pwmHandle, &config); if (ret != HDF_SUCCESS) { HDF_LOGE("%s: PwmSetConfig fail, ret %d", __func__, ret); return HDF_FAILURE; } + icn9700->pwmHandle = pwmHandle; return HDF_SUCCESS; } -static int32_t Icn9700Init(void) +static struct Icn9700Dev *PanelToIcn9700Dev(const struct PanelData *panel) +{ + struct Icn9700Dev *icn9700 = NULL; + + if (panel == NULL) { + HDF_LOGE("%s: panel is null", __func__); + return NULL; + } + if (panel->object == NULL) { + HDF_LOGE("%s: object is null", __func__); + return NULL; + } + icn9700 = (struct Icn9700Dev *)panel->object->priv; + return icn9700; +} + +static int32_t Icn9700Init(struct PanelData *panel) { - g_mipiHandle = MipiDsiOpen(MIPI_DSI0); - if (g_mipiHandle == NULL) { + struct Icn9700Dev *icn9700 = NULL; + + icn9700 = PanelToIcn9700Dev(panel); + if (icn9700 == NULL) { + HDF_LOGE("%s: icn9700 is null", __func__); + return HDF_FAILURE; + } + icn9700->mipiHandle = MipiDsiOpen(MIPI_DSI0); + if (icn9700->mipiHandle == NULL) { HDF_LOGE("%s: MipiDsiOpen failed", __func__); return HDF_FAILURE; } - if (PwmCfg() != HDF_SUCCESS) { + if (PwmCfg(icn9700) != HDF_SUCCESS) { HDF_LOGE("%s: PwmCfg failed", __func__); return HDF_FAILURE; } return HDF_SUCCESS; } -static int32_t Icn9700On(void) +static int32_t Icn9700On(struct PanelData *panel) { int32_t ret; + struct Icn9700Dev *icn9700 = NULL; + icn9700 = PanelToIcn9700Dev(panel); + if (icn9700 == NULL) { + HDF_LOGE("%s: icn9700 is null", __func__); + return HDF_FAILURE; + } /* lcd reset power on */ - ret = LcdResetOn(); + ret = LcdResetOn(icn9700); if (ret != HDF_SUCCESS) { HDF_LOGE("%s: LcdResetOn failed", __func__); return HDF_FAILURE; } - if (g_mipiHandle == NULL) { - HDF_LOGE("%s: g_mipiHandle is null", __func__); + if (icn9700->mipiHandle == NULL) { + HDF_LOGE("%s: mipiHandle is null", __func__); return HDF_FAILURE; } /* send mipi init code */ int32_t count = sizeof(g_OnCmd) / sizeof(g_OnCmd[0]); int32_t i; for (i = 0; i < count; i++) { - ret = MipiDsiTx(g_mipiHandle, &(g_OnCmd[i])); + ret = MipiDsiTx(icn9700->mipiHandle, &(g_OnCmd[i])); if (ret != HDF_SUCCESS) { HDF_LOGE("%s: MipiDsiTx failed", __func__); return HDF_FAILURE; } } + panel->status.powerStatus = POWER_STATUS_ON; /* set mipi to hs mode */ - MipiDsiSetHsMode(g_mipiHandle); + MipiDsiSetHsMode(icn9700->mipiHandle); return HDF_SUCCESS; } -static int32_t Icn9700Off(void) +static int32_t Icn9700Off(struct PanelData *panel) { int32_t ret; + struct Icn9700Dev *icn9700 = NULL; - if (g_mipiHandle == NULL) { - HDF_LOGE("%s: g_mipiHandle is null", __func__); + icn9700 = PanelToIcn9700Dev(panel); + if (icn9700 == NULL) { + HDF_LOGE("%s: icn9700 is null", __func__); + return HDF_FAILURE; + } + if (icn9700->mipiHandle == NULL) { + HDF_LOGE("%s: mipiHandle is null", __func__); return HDF_FAILURE; } /* send mipi init code */ int32_t count = sizeof(g_offCmd) / sizeof(g_offCmd[0]); int32_t i; for (i = 0; i < count; i++) { - ret = MipiDsiTx(g_mipiHandle, &(g_offCmd[i])); + ret = MipiDsiTx(icn9700->mipiHandle, &(g_offCmd[i])); if (ret != HDF_SUCCESS) { HDF_LOGE("%s: MipiDsiTx failed", __func__); return HDF_FAILURE; } } /* set mipi to lp mode */ - MipiDsiSetLpMode(g_mipiHandle); + MipiDsiSetLpMode(icn9700->mipiHandle); /* lcd reset power off */ - ret = LcdResetOff(); + ret = LcdResetOff(icn9700); if (ret != HDF_SUCCESS) { HDF_LOGE("%s: LcdResetOff failed", __func__); return HDF_FAILURE; } + panel->status.powerStatus = POWER_STATUS_OFF; return HDF_SUCCESS; } -static int32_t Icn9700SetBacklight(uint32_t level) +static int32_t Icn9700SetBacklight(struct PanelData *panel, uint32_t level) { int32_t ret; uint32_t duty; + struct Icn9700Dev *icn9700 = NULL; + + icn9700 = PanelToIcn9700Dev(panel); + if (icn9700 == NULL) { + HDF_LOGE("%s: icn9700 is null", __func__); + return HDF_FAILURE; + } duty = (level * PWM_MAX_PERIOD) / MAX_LEVEL; - ret = PwmSetDuty(g_pwmHandle, duty); + ret = PwmSetDuty(icn9700->pwmHandle, duty); if (ret != HDF_SUCCESS) { HDF_LOGE("%s: PwmSetDutyCycle failed, ret %d", __func__, ret); return HDF_FAILURE; } static uint32_t lastLevel = 0; if (level != 0 && lastLevel == 0) { - ret = PwmEnable(g_pwmHandle); + ret = PwmEnable(icn9700->pwmHandle); } else if (level == 0 && lastLevel != 0) { - ret = PwmDisable(g_pwmHandle); + ret = PwmDisable(icn9700->pwmHandle); } lastLevel = level; + panel->status.currLevel = level; return ret; } +static int32_t Icn9700EsdCheckFunc(struct PanelData *panel) +{ + struct Icn9700Dev *icn9700 = NULL; + + icn9700 = PanelToIcn9700Dev(panel); + if (icn9700 == NULL) { + HDF_LOGE("%s: icn9700 is null", __func__); + return HDF_FAILURE; + } + HDF_LOGE("%s: enter", __func__); + return HDF_SUCCESS; +} + static struct PanelInfo g_panelInfo = { .width = WIDTH, /* width */ .height = HEIGHT, /* height */ @@ -270,28 +335,43 @@ static struct PanelInfo g_panelInfo = { .pwm = { BLK_PWM1, PWM_MAX_PERIOD }, }; -static struct PanelStatus g_panelStatus = { - .powerStatus = POWER_STATUS_OFF, - .currLevel = MIN_LEVEL, +static struct PanelEsd g_panelEsd = { + .support = false, + .checkFunc = Icn9700EsdCheckFunc, }; -static struct PanelData g_panelData = { - .info = &g_panelInfo, - .status = &g_panelStatus, - .init = Icn9700Init, - .on = Icn9700On, - .off = Icn9700Off, - .setBacklight = Icn9700SetBacklight, -}; +static void Icn9700PanelInit(struct PanelData *panel) +{ + panel->info = &g_panelInfo; + panel->status.powerStatus = POWER_STATUS_OFF; + panel->status.currLevel = MIN_LEVEL; + panel->esd = &g_panelEsd; + panel->init = Icn9700Init; + panel->on = Icn9700On; + panel->off = Icn9700Off; + panel->setBacklight = Icn9700SetBacklight; +} int32_t Icn9700EntryInit(struct HdfDeviceObject *object) { + struct Icn9700Dev *icn9700 = NULL; + if (object == NULL) { - HDF_LOGE("%s: param is null", __func__); + HDF_LOGE("%s: object is null", __func__); + return HDF_FAILURE; + } + icn9700 = (struct Icn9700Dev *)OsalMemCalloc(sizeof(struct Icn9700Dev)); + if (icn9700 == NULL) { + HDF_LOGE("%s icn9700 malloc fail", __func__); return HDF_FAILURE; } - if (PanelDataRegister(&g_panelData) != HDF_SUCCESS) { - HDF_LOGE("%s: PanelDataRegister failed", __func__); + Icn9700PanelInit(&icn9700->panel); + icn9700->panel.object = object; + icn9700->reset_gpio = RESET_GPIO; + icn9700->reset_delay = 20; // delay 20ms + object->priv = (void *)icn9700; + if (RegisterPanel(&icn9700->panel) != HDF_SUCCESS) { + HDF_LOGE("%s: RegisterPanel failed", __func__); return HDF_FAILURE; } HDF_LOGI("%s: exit succ", __func__);