From a4105ee17c3273ace828d4f9b023c2b139186e57 Mon Sep 17 00:00:00 2001 From: YOUR_NAME Date: Sat, 21 Aug 2021 01:48:06 +0000 Subject: [PATCH] add backlight subsystem for display Signed-off-by: YOUR_NAME --- .../display/driver/adapter_soc/hi35xx_disp.c | 34 +- model/display/driver/backlight/hdf_bl.c | 441 ++++++++++++++++++ model/display/driver/backlight/hdf_bl.h | 47 ++ model/display/driver/backlight/pwm_bl.c | 186 ++++++++ model/display/driver/hdf_disp.c | 71 +-- model/display/driver/hdf_disp.h | 11 +- model/display/driver/hdf_drm_panel.c | 19 +- model/display/driver/panel/ili9881c_boe.c | 59 +-- model/display/driver/panel/ili9881c_boe.h | 2 - model/display/driver/panel/mipi_icn9700.c | 72 +-- 10 files changed, 722 insertions(+), 220 deletions(-) create mode 100644 model/display/driver/backlight/hdf_bl.c create mode 100644 model/display/driver/backlight/hdf_bl.h create mode 100644 model/display/driver/backlight/pwm_bl.c diff --git a/model/display/driver/adapter_soc/hi35xx_disp.c b/model/display/driver/adapter_soc/hi35xx_disp.c index febf1ef92..7ab604b46 100644 --- a/model/display/driver/adapter_soc/hi35xx_disp.c +++ b/model/display/driver/adapter_soc/hi35xx_disp.c @@ -231,34 +231,6 @@ static int32_t MipiDsiInit(struct PanelInfo *info) return ret; } -static int32_t PwmInit(struct PanelInfo *info) -{ - int32_t ret; - - /* pwm pin config */ - PwmPinMuxCfg(info->pwm.dev); - /* pwm config */ - DevHandle pwmHandle = PwmOpen(info->pwm.dev); - if (pwmHandle == NULL) { - HDF_LOGE("%s: PwmOpen failed", __func__); - return HDF_FAILURE; - } - - struct PwmConfig config; - (void)memset_s(&config, sizeof(struct PwmConfig), 0, sizeof(struct PwmConfig)); - config.duty = 1; - config.period = info->pwm.period; - config.status = 0; - ret = PwmSetConfig(pwmHandle, &config); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: PwmSetConfig err, ret %d", __func__, ret); - PwmClose(pwmHandle); - return HDF_FAILURE; - } - PwmClose(pwmHandle); - return HDF_SUCCESS; -} - static int32_t GetLcdIntfType(enum LcdIntfType type, uint32_t *out) { int32_t ret = HDF_SUCCESS; @@ -311,11 +283,7 @@ static int32_t Hi35xxHardWareInit(void) return HDF_FAILURE; } if (info->blk.type == BLK_PWM) { - ret = PwmInit(info); - if (ret) { - HDF_LOGE("%s:PwmInit failed", __func__); - return HDF_FAILURE; - } + PwmPinMuxCfg(info->pwm.dev); } /* lcd pin mux config */ LcdPinMuxCfg(info->intfType); diff --git a/model/display/driver/backlight/hdf_bl.c b/model/display/driver/backlight/hdf_bl.c new file mode 100644 index 000000000..1f0743961 --- /dev/null +++ b/model/display/driver/backlight/hdf_bl.c @@ -0,0 +1,441 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * + * HDF is dual licensed: you can use it either under the terms of + * the GPL, or the BSD license, at your option. + * See the LICENSE file in the root of this repository for complete details. + */ + +#include "hdf_bl.h" +#include +#include "hdf_base.h" +#include "hdf_disp.h" +#include "hdf_log.h" +#include "osal.h" + +#define OFFSET_TWO_BYTE 16 +#define MAX_BL_NAME_LEN 32 +#define MAX_BL_DEV 32 +#define NAME_BUFFER_LEN 1220 // 32 * 38 +#define MAX_DEST_STRING_LEN 38 // MAX_BL_NAME_LEN(32) + 6 + +enum BrightnessType { + MIN_BRIGHTNESS, + CURRENT_BRIGHTNESS, + DEFAULT_BRIGHTNESS, + MAX_BRIGHTNESS, +}; + +typedef int32_t (*BlCmdHandle)(struct HdfDeviceObject *device, + struct HdfSBuf *reqData, struct HdfSBuf *rspData); + +struct BacklightDev { + char name[MAX_BL_NAME_LEN]; + struct BacklightProperties props; + struct BacklightOps *ops; + struct OsalMutex mutex; + bool isRegister; + void *priv; +}; + +struct BlDevManager { + struct BacklightDev *blDev[MAX_BL_DEV]; + int32_t devNum; +}; + +static struct BlDevManager g_blDevManager; + +static struct BlDevManager *GetBlDevManager(void) +{ + return &g_blDevManager; +} + +static struct BacklightDev *BlDevInstance(const char *devName, + struct BacklightProperties *props, struct BacklightOps *ops) +{ + int32_t ret; + struct BacklightDev *blDev = NULL; + + blDev = (struct BacklightDev *)OsalMemCalloc(sizeof(struct BacklightDev)); + if (blDev == NULL) { + HDF_LOGE("%s blDev malloc fail", __func__); + return NULL; + } + blDev->ops = ops; + ret = memcpy_s(blDev->name, MAX_BL_NAME_LEN - 1, devName, strlen(devName) + 1); + if (ret != 0) { + HDF_LOGE("%s blDev->name %s", __func__, blDev->name); + goto FAIL; + } + ret = memcpy_s(&blDev->props, sizeof(struct BacklightProperties), + props, sizeof(struct BacklightProperties)); + if (ret != 0) { + HDF_LOGE("%s props memcpy fail", __func__); + goto FAIL; + } + return blDev; +FAIL: + OsalMemFree(blDev); + return NULL; +} + +struct BacklightDev *RegisterBlDev(const char *name, struct BacklightProperties *props, + struct BacklightOps *ops, void *priv) +{ + int32_t devNum; + struct BacklightDev *blDev = NULL; + struct BlDevManager *blDevManager = NULL; + + if ((name == NULL) || (ops == NULL) || (props == NULL)) { + HDF_LOGE("%s: name , ops or props is null", __func__); + return NULL; + } + blDevManager = GetBlDevManager(); + devNum = blDevManager->devNum; + if (devNum >= MAX_BL_DEV) { + HDF_LOGE("%s: number of backlight device registrations exceeded", __func__); + return NULL; + } + for (int32_t i = 0; i < devNum; i++) { + if (strcmp(name, blDevManager->blDev[i]->name) == 0) { + HDF_LOGE("%s: backlight name should be unique", __func__); + return NULL; + } + } + blDev = BlDevInstance(name, props, ops); + if (blDev == NULL) { + HDF_LOGE("%s: BlDevInstance fail", __func__); + return NULL; + } + blDev->priv = priv; + blDevManager->blDev[devNum] = blDev; + blDevManager->devNum++; + OsalMutexInit(&blDev->mutex); + HDF_LOGE("%s: success", __func__); + return blDev; +} + +void *ToBlDevPriv(struct BacklightDev *blDev) +{ + if (blDev == NULL) { + HDF_LOGE("%s blDev is null", __func__); + return NULL; + } + return blDev->priv; +} + +struct BacklightDev *GetBacklightDev(const char *name) +{ + struct BlDevManager *blDevManager = NULL; + + if (name == NULL) { + HDF_LOGE("%s name is null", __func__); + return NULL; + } + blDevManager = GetBlDevManager(); + for (int32_t i = 0; i < blDevManager->devNum; i++) { + if (strcmp(name, blDevManager->blDev[i]->name) == 0) { + return blDevManager->blDev[i]; + } + } + return NULL; +} + +int32_t UpdateBacklightState(struct BacklightDev *blDev, enum FbPowerStatus status) +{ + if (blDev == NULL) { + HDF_LOGE("%s blDev is null", __func__); + return HDF_FAILURE; + } + if ((status < FB_POWER_ON) || (status > FB_POWER_OFF)) { + HDF_LOGE("%s the status is illegal", __func__); + return HDF_FAILURE; + } + OsalMutexLock(&blDev->mutex); + blDev->props.fbStatus = status; + OsalMutexUnlock(&blDev->mutex); + return HDF_SUCCESS; +} + +int32_t UpdateBrightness(struct BacklightDev *blDev, uint32_t brightness) +{ + int32_t ret = HDF_FAILURE; + + if (blDev == NULL) { + HDF_LOGE("%s blDev is null", __func__); + return HDF_FAILURE; + } + if (brightness > blDev->props.maxBrightness) { + brightness = blDev->props.maxBrightness; + } + if (brightness < blDev->props.minBrightness) { + brightness = blDev->props.minBrightness; + } + OsalMutexLock(&blDev->mutex); + if (brightness == blDev->props.brightness) { + HDF_LOGI("%s brightness does not change", __func__); + OsalMutexUnlock(&blDev->mutex); + return HDF_SUCCESS; + } + if ((blDev->props.fbStatus == FB_POWER_STANDBY) || + (blDev->props.fbStatus == FB_POWER_SUSPEND) || + (blDev->props.fbStatus == FB_POWER_OFF)) { + brightness = 0; + } + if (blDev->ops != NULL && blDev->ops->updateBrightness != NULL) { + ret = blDev->ops->updateBrightness(blDev, brightness); + if (ret == HDF_SUCCESS) { + blDev->props.brightness = brightness; + } else { + HDF_LOGE("%s: fail", __func__); + } + } + OsalMutexUnlock(&blDev->mutex); + return ret; +} + +static int32_t GetBlDevBrightness(struct BacklightDev *blDev, enum BrightnessType type) +{ + uint32_t brightness; + + OsalMutexLock(&blDev->mutex); + switch (type) { + case MIN_BRIGHTNESS: + brightness = blDev->props.minBrightness; + break; + case CURRENT_BRIGHTNESS: + if ((blDev->props.fbStatus == FB_POWER_STANDBY) || + (blDev->props.fbStatus == FB_POWER_SUSPEND) || + (blDev->props.fbStatus == FB_POWER_OFF)) { + blDev->props.brightness = 0; + } + if ((blDev->ops != NULL) && (blDev->ops->getBrightness != NULL)) { + brightness = blDev->ops->getBrightness(blDev); + } else { + brightness = blDev->props.brightness; + } + break; + case DEFAULT_BRIGHTNESS: + brightness = blDev->props.defBrightness; + break; + case MAX_BRIGHTNESS: + brightness = blDev->props.maxBrightness; + break; + } + OsalMutexUnlock(&blDev->mutex); + return brightness; +} + +int32_t GetMinBrightness(struct BacklightDev *blDev, uint32_t *brightness) +{ + if (blDev == NULL || brightness == NULL) { + HDF_LOGE("%s: blDev or brightness is null", __func__); + return HDF_FAILURE; + } + *brightness = GetBlDevBrightness(blDev, MIN_BRIGHTNESS); + return HDF_SUCCESS; +} + +int32_t GetCurrBrightness(struct BacklightDev *blDev, uint32_t *brightness) +{ + if (blDev == NULL || brightness == NULL) { + HDF_LOGE("%s: blDev or brightness is null", __func__); + return HDF_FAILURE; + } + *brightness = GetBlDevBrightness(blDev, CURRENT_BRIGHTNESS); + return HDF_SUCCESS; +} + +int32_t GetDefBrightness(struct BacklightDev *blDev, uint32_t *brightness) +{ + if (blDev == NULL || brightness == NULL) { + HDF_LOGE("%s: blDev or brightness is null", __func__); + return HDF_FAILURE; + } + *brightness = GetBlDevBrightness(blDev, DEFAULT_BRIGHTNESS); + return HDF_SUCCESS; +} + +int32_t GetMaxBrightness(struct BacklightDev *blDev, uint32_t *brightness) +{ + if (blDev == NULL || brightness == NULL) { + HDF_LOGE("%s: blDev or brightness is null", __func__); + return HDF_FAILURE; + } + *brightness = GetBlDevBrightness(blDev, MAX_BRIGHTNESS); + return HDF_SUCCESS; +} + +static int32_t HdfGetBrightness(enum BrightnessType type, + struct HdfSBuf *reqData, struct HdfSBuf *rspData) +{ + uint32_t devId; + int32_t brightness; + struct BlDevManager *blDevManager = NULL; + struct BacklightDev *blDev = NULL; + + if (reqData == NULL) { + return HDF_ERR_INVALID_PARAM; + } + if (!HdfSbufReadUint32(reqData, &devId)) { + HDF_LOGE("%s: HdfSbufReadBuffer failed", __func__); + return HDF_FAILURE; + } + blDevManager = GetBlDevManager(); + if (devId >= blDevManager->devNum) { + HDF_LOGE("%s: devId is illegal", __func__); + return HDF_FAILURE; + } + blDev = blDevManager->blDev[devId]; + brightness = GetBlDevBrightness(blDev, type); + if (!HdfSbufWriteUint32(rspData, brightness)) { + HDF_LOGE("%s: HdfSbufWriteUint32 failed", __func__); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +static int32_t HdfGetMinBrightness(struct HdfDeviceObject *device, + struct HdfSBuf *reqData, struct HdfSBuf *rspData) +{ + (void)device; + return HdfGetBrightness(MIN_BRIGHTNESS, reqData, rspData); +} + +static int32_t HdfGetCurrBrightness(struct HdfDeviceObject *device, + struct HdfSBuf *reqData, struct HdfSBuf *rspData) +{ + (void)device; + return HdfGetBrightness(CURRENT_BRIGHTNESS, reqData, rspData); +} + +static int32_t HdfGetDefBrightness(struct HdfDeviceObject *device, + struct HdfSBuf *reqData, struct HdfSBuf *rspData) +{ + (void)device; + return HdfGetBrightness(DEFAULT_BRIGHTNESS, reqData, rspData); +} + +static int32_t HdfGetMaxBrightness(struct HdfDeviceObject *device, + struct HdfSBuf *reqData, struct HdfSBuf *rspData) +{ + (void)device; + return HdfGetBrightness(MAX_BRIGHTNESS, reqData, rspData); +} + +static int32_t HdfSetBrightness(struct HdfDeviceObject *device, + struct HdfSBuf *reqData, struct HdfSBuf *rspData) +{ + struct BlDevManager *blDevManager = NULL; + struct BacklightDev *blDev = NULL; + + (void)device; + (void)rspData; + if (reqData == NULL) { + return HDF_ERR_INVALID_PARAM; + } + uint32_t para = 0; + if (!HdfSbufReadUint32(reqData, ¶)) { + HDF_LOGE("%s: HdfSbufReadBuffer failed", __func__); + return HDF_FAILURE; + } + uint32_t devId = (para >> OFFSET_TWO_BYTE) & 0xffff; + uint32_t level = para & 0xffff; + blDevManager = GetBlDevManager(); + if (devId >= blDevManager->devNum) { + HDF_LOGE("%s: devId is illegal", __func__); + return HDF_FAILURE; + } + blDev = blDevManager->blDev[devId]; + return UpdateBrightness(blDev, level); +} + +static int32_t HdfGetBlDevList(struct HdfDeviceObject *device, + struct HdfSBuf *reqData, struct HdfSBuf *rspData) +{ + (void)device; + (void)reqData; + int32_t ret; + char *devName = NULL; + char *tmp = NULL; + char buffer[NAME_BUFFER_LEN] = {0}; + struct BlDevManager *blDevManager = NULL; + + blDevManager = GetBlDevManager(); + tmp = buffer; + for (int32_t i = 0; i < blDevManager->devNum; i++) { + devName = blDevManager->blDev[i]->name; + if ((tmp + MAX_DEST_STRING_LEN) > &buffer[NAME_BUFFER_LEN]) { + HDF_LOGE("%s: Memory out of bounds", __func__); + break; + } + // strlen("%d : \n") = 6 + ret = snprintf_s(tmp, MAX_DEST_STRING_LEN, strlen(devName) + 6, "%d : %s\n", i, devName); + if (ret < 0) { + HDF_LOGE("%s: snprintf_s fail", __func__); + return HDF_FAILURE; + } + tmp = tmp + strlen(tmp) + 1; + } + if (!HdfSbufWriteBuffer(rspData, buffer, strlen(buffer) + 1) != 0) { + HDF_LOGE("%s: copy info failed", __func__); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +static BlCmdHandle g_blDevCmdHandle[] = { + HdfGetMinBrightness, + HdfGetCurrBrightness, + HdfGetDefBrightness, + HdfGetMaxBrightness, + HdfGetBlDevList, + HdfSetBrightness, +}; + +static int32_t BacklightDispatch(struct HdfDeviceIoClient *client, int cmd, struct HdfSBuf *data, + struct HdfSBuf *reply) +{ + BlCmdHandle blCmdHandle = NULL; + + if (client == NULL) { + return HDF_ERR_INVALID_PARAM; + } + if ((cmd < 0) || (cmd >= sizeof(g_blDevCmdHandle) / sizeof(BlCmdHandle))) { + HDF_LOGE("%s: cmd is illegal", __func__); + return HDF_FAILURE; + } + blCmdHandle = g_blDevCmdHandle[cmd]; + return blCmdHandle(client->device, data, reply); +} + +static int BacklightBind(struct HdfDeviceObject *dev) +{ + if (dev == NULL) { + return HDF_FAILURE; + } + static struct IDeviceIoService blService = { + .Dispatch = BacklightDispatch, + }; + dev->service = &blService; + return HDF_SUCCESS; +} + +static int32_t BacklightInit(struct HdfDeviceObject *object) +{ + if (object == NULL) { + HDF_LOGE("%s: object is null!", __func__); + return HDF_FAILURE; + } + HDF_LOGI("%s success", __func__); + return HDF_SUCCESS; +} + +struct HdfDriverEntry g_blDevEntry = { + .moduleVersion = 1, + .moduleName = "HDF_BL", + .Init = BacklightInit, + .Bind = BacklightBind, +}; + +HDF_INIT(g_blDevEntry); diff --git a/model/display/driver/backlight/hdf_bl.h b/model/display/driver/backlight/hdf_bl.h new file mode 100644 index 000000000..cb2078934 --- /dev/null +++ b/model/display/driver/backlight/hdf_bl.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * + * HDF is dual licensed: you can use it either under the terms of + * the GPL, or the BSD license, at your option. + * See the LICENSE file in the root of this repository for complete details. + */ + +#ifndef HDF_BL_H +#define HDF_BL_H + +#include "hdf_disp.h" +#include "hdf_types.h" + +enum FbPowerStatus { + FB_POWER_ON, + FB_POWER_STANDBY, + FB_POWER_SUSPEND, + FB_POWER_OFF, +}; + +struct BacklightDev; +struct BacklightOps { + int32_t (*updateBrightness)(struct BacklightDev *bl, uint32_t brightness); + int32_t (*getBrightness)(struct BacklightDev *bl); +}; + +struct BacklightProperties { + uint32_t brightness; + uint32_t maxBrightness; + uint32_t minBrightness; + uint32_t defBrightness; + enum FbPowerStatus fbStatus; +}; + +struct BacklightDev *RegisterBlDev(const char *name, struct BacklightProperties *props, + struct BacklightOps *ops, void *priv); +void *ToBlDevPriv(struct BacklightDev *blDev); +struct BacklightDev *GetBacklightDev(const char *name); +int32_t UpdateBacklightState(struct BacklightDev *blDev, enum FbPowerStatus status); +int32_t UpdateBrightness(struct BacklightDev *blDev, uint32_t brightness); +int32_t GetMinBrightness(struct BacklightDev *blDev, uint32_t *brightness); +int32_t GetCurrBrightness(struct BacklightDev *blDev, uint32_t *brightness); +int32_t GetDefBrightness(struct BacklightDev *blDev, uint32_t *brightness); +int32_t GetMaxBrightness(struct BacklightDev *blDev, uint32_t *brightness); +#endif /* HDF_BL_H */ + diff --git a/model/display/driver/backlight/pwm_bl.c b/model/display/driver/backlight/pwm_bl.c new file mode 100644 index 000000000..c3710b4ff --- /dev/null +++ b/model/display/driver/backlight/pwm_bl.c @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * + * HDF is dual licensed: you can use it either under the terms of + * the GPL, or the BSD license, at your option. + * See the LICENSE file in the root of this repository for complete details. + */ + +#include "device_resource_if.h" +#include "hdf_base.h" +#include "hdf_bl.h" +#include "hdf_disp.h" +#include "hdf_log.h" +#include "hdf_types.h" +#include "osal.h" +#include "pwm_if.h" + +#define DEF_MIN_BRIGHTNESS 0 +#define DEF_MAX_BRIGHTNESS 255 + +#define CHECK_PARSER_RET(ret, str) do { \ + if ((ret) != HDF_SUCCESS) { \ + HDF_LOGE("%s: %s failed, ret = %d", __func__, str, ret); \ + return HDF_FAILURE; \ + } \ +} while (0) + +struct BlPwmDev { + const char *name; + uint8_t pwmDevNum; + DevHandle pwmHandle; + struct PwmConfig config; + struct BacklightProperties props; +}; + +static int32_t BlPwmUpdateBrightness(struct BacklightDev *blDev, uint32_t brightness) +{ + int32_t ret; + uint32_t duty; + struct BlPwmDev *blPwmDev = NULL; + + blPwmDev = ToBlDevPriv(blDev); + if (blPwmDev == NULL) { + HDF_LOGE("%s blPwmDev is null", __func__); + return HDF_FAILURE; + } + if (blPwmDev->props.maxBrightness == 0) { + HDF_LOGE("%s maxBrightness is 0", __func__); + return HDF_FAILURE; + } + duty = (brightness * blPwmDev->config.period) / blPwmDev->props.maxBrightness; + ret = PwmSetDuty(blPwmDev->pwmHandle, duty); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: PwmSetDutyCycle failed, ret %d", __func__, ret); + return HDF_FAILURE; + } + if (brightness != 0) { + ret = PwmEnable(blPwmDev->pwmHandle); + } else { + ret = PwmDisable(blPwmDev->pwmHandle); + } + return ret; +} + +static struct BacklightOps g_blDevOps = { + .updateBrightness = BlPwmUpdateBrightness, +}; + +static int32_t ParsePwmNum(const struct DeviceResourceNode *node, uint8_t *pwmNum) +{ + int32_t ret; + struct DeviceResourceIface *parser = NULL; + + if (node == NULL) { + HDF_LOGE("%s: node is null", __func__); + return HDF_FAILURE; + } + parser = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); + if (parser == NULL) { + HDF_LOGE("%s: instance parser failed", __func__); + return HDF_FAILURE; + } + ret = parser->GetUint8(node, "pwmDevNum", pwmNum, 0); + CHECK_PARSER_RET(ret, "GetUint8"); + return HDF_SUCCESS; +} +static int32_t ParseBlPwmCfg(const struct DeviceResourceNode *node, struct BlPwmDev *blPwmDev) +{ + int32_t ret; + uint32_t defBrightness; + struct DeviceResourceIface *parser = NULL; + + if (node == NULL) { + HDF_LOGE("%s: node is null", __func__); + return HDF_FAILURE; + } + parser = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); + if (parser == NULL) { + HDF_LOGE("%s: instance parser failed", __func__); + return HDF_FAILURE; + } + ret = parser->GetString(node, "backlightDevName", &blPwmDev->name, NULL); + CHECK_PARSER_RET(ret, "GetString"); + ret = parser->GetUint32(node, "pwmMaxPeroid", &blPwmDev->config.period, 0); + CHECK_PARSER_RET(ret, "GetUint32"); + ret = parser->GetUint32(node, "minBrightness", &blPwmDev->props.minBrightness, DEF_MIN_BRIGHTNESS); + CHECK_PARSER_RET(ret, "GetUint32"); + ret = parser->GetUint32(node, "maxBrightness", &blPwmDev->props.maxBrightness, DEF_MAX_BRIGHTNESS); + CHECK_PARSER_RET(ret, "GetUint32"); + // if not provided defBrightness, defBrightness = (min + max) / 2 + defBrightness = (blPwmDev->props.minBrightness + blPwmDev->props.maxBrightness) / 2; + ret = parser->GetUint32(node, "defBrightness", &blPwmDev->props.defBrightness, defBrightness); + CHECK_PARSER_RET(ret, "GetUint32"); + blPwmDev->config.duty = 1; + blPwmDev->config.status = 1; + return HDF_SUCCESS; +} + +static int32_t BlPwmDevInit(struct HdfDeviceObject *object, struct BlPwmDev *blPwmDev) +{ + if (ParsePwmNum(object->property, &blPwmDev->pwmDevNum) != HDF_SUCCESS) { + HDF_LOGE("%s ParsePwmNum fail", __func__); + return HDF_FAILURE; + } + blPwmDev->pwmHandle = PwmOpen(blPwmDev->pwmDevNum); + if (blPwmDev->pwmHandle == NULL) { + HDF_LOGE("%s: PwmOpen failed", __func__); + return HDF_FAILURE; + } + if (PwmGetConfig(blPwmDev->pwmHandle, &blPwmDev->config) != HDF_SUCCESS) { + HDF_LOGE("%s: PwmGetConfig fail", __func__); + return HDF_FAILURE; + } + if (ParseBlPwmCfg(object->property, blPwmDev) != HDF_SUCCESS) { + HDF_LOGE("%s: ParseBlPwmCfg fail", __func__); + return HDF_FAILURE; + } + if (PwmSetConfig(blPwmDev->pwmHandle, &blPwmDev->config) != HDF_SUCCESS) { + HDF_LOGE("%s: PwmSetConfig fail", __func__); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +static int32_t BlPwmEntryInit(struct HdfDeviceObject *object) +{ + int32_t ret; + struct BacklightDev *blDev = NULL; + struct BlPwmDev *blPwmDev = NULL; + + blPwmDev = (struct BlPwmDev *)OsalMemCalloc(sizeof(struct BlPwmDev)); + if (blPwmDev == NULL) { + HDF_LOGE("%s blPwmDev malloc fail", __func__); + return HDF_FAILURE; + } + ret = BlPwmDevInit(object, blPwmDev); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: BlPwmDevInit fail", __func__); + goto FAIL; + } + blDev = RegisterBlDev(blPwmDev->name, &blPwmDev->props, &g_blDevOps, blPwmDev); + if (blDev == NULL) { + HDF_LOGE("%s: RegisterBlDev fail", __func__); + goto FAIL; + } + if (UpdateBacklightState(blDev, FB_POWER_ON) != HDF_SUCCESS) { + HDF_LOGE("%s: UpdateBacklightState fail", __func__); + } + if (UpdateBrightness(blDev, blPwmDev->props.defBrightness) != HDF_SUCCESS) { + HDF_LOGE("%s: UpdateBrightness fail", __func__); + } + HDF_LOGI("%s: success", __func__); + return HDF_SUCCESS; + +FAIL: + OsalMemFree(blPwmDev); + return HDF_FAILURE; +} + +struct HdfDriverEntry g_pwmBlDevEntry = { + .moduleVersion = 1, + .moduleName = "PWM_BL", + .Init = BlPwmEntryInit, +}; + +HDF_INIT(g_pwmBlDevEntry); \ No newline at end of file diff --git a/model/display/driver/hdf_disp.c b/model/display/driver/hdf_disp.c index dbbf41a3c..8d7d2603a 100644 --- a/model/display/driver/hdf_disp.c +++ b/model/display/driver/hdf_disp.c @@ -15,24 +15,29 @@ #define OFFSET_TWO_BYTE 16 static struct DispManager *g_dispManager = NULL; static struct PanelManager g_panelManager; -int32_t RegisterPanel(struct PanelData *data) +int32_t RegisterPanel(struct PanelData *panel) { int32_t panelNum; - if (data == NULL) { + if (panel == NULL) { HDF_LOGE("%s: panel data is null", __func__); return HDF_ERR_INVALID_PARAM; } - if (data->info == NULL) { + if (panel->info == NULL) { HDF_LOGE("%s panel info is null", __func__); return HDF_FAILURE; } + if ((panel->on == NULL) || (panel->off == NULL)) { + HDF_LOGE("%s on or off is null", __func__); + return HDF_FAILURE; + } + panel->powerStatus = POWER_STATUS_OFF; panelNum = g_panelManager.panelNum; if (panelNum >= PANEL_MAX) { HDF_LOGE("%s registered panel up PANEL_MAX", __func__); return HDF_FAILURE; } - g_panelManager.panel[panelNum] = data; + g_panelManager.panel[panelNum] = panel; g_panelManager.panelNum++; HDF_LOGI("%s: register success", __func__); return HDF_SUCCESS; @@ -97,47 +102,19 @@ static int32_t DispOff(uint32_t devId) static int32_t SetDispBacklight(uint32_t devId, uint32_t level) { - int32_t ret = HDF_FAILURE; struct DispManager *disp = NULL; - struct PanelInfo *info = 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; } - 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); + if (UpdateBrightness(panel->blDev, level) != HDF_SUCCESS) { + HDF_LOGE("%s:UpdateBrightness failed", __func__); return HDF_FAILURE; } - if (panel->status.currLevel == level) { - HDF_LOGI("%s:devId[%d] currLevel equals : %d", __func__, devId, level); - OsalMutexUnlock(&disp->dispMutex); - return HDF_SUCCESS; - } - if (panel->setBacklight) { - ret = panel->setBacklight(panel, level); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s:setBacklight failed", __func__); - OsalMutexUnlock(&disp->dispMutex); - return HDF_FAILURE; - } - } - OsalMutexUnlock(&disp->dispMutex); HDF_LOGI("%s:level = %u", __func__, level); - return ret; + return HDF_SUCCESS; } static int32_t GetDispInfo(uint32_t devId, struct DispInfo *info) @@ -193,25 +170,25 @@ static int32_t SetDispPower(uint32_t devId, uint32_t powerStatus) } panel = disp->panelManager->panel[devId]; OsalMutexLock(&disp->dispMutex); - if (panel->status.powerStatus == powerStatus) { + if (panel->powerStatus == powerStatus) { OsalMutexUnlock(&disp->dispMutex); HDF_LOGE("%s:devId[%d] already in mode = %d", __func__, devId, powerStatus); return HDF_SUCCESS; } switch (powerStatus) { case POWER_STATUS_ON: - if (panel->on) { - ret = panel->on(panel); - } + ret = panel->on(panel); if (ret == HDF_SUCCESS) { + panel->powerStatus = POWER_STATUS_ON; + ret = UpdateBacklightState(panel->blDev, FB_POWER_ON); EsdCheckStartUp(disp->esd, devId); } break; case POWER_STATUS_OFF: - if (panel->off) { - ret = panel->off(panel); - } + ret = panel->off(panel); if (ret == HDF_SUCCESS) { + panel->powerStatus = POWER_STATUS_OFF; + ret = UpdateBacklightState(panel->blDev, FB_POWER_OFF); EsdCheckEnd(disp->esd, devId); } break; @@ -263,7 +240,7 @@ static int32_t GetPowerStatus(struct HdfDeviceObject *device, struct HdfSBuf *re } OsalMutexLock(&disp->dispMutex); panel = disp->panelManager->panel[devId]; - powerStatus = panel->status.powerStatus; + powerStatus = panel->powerStatus; OsalMutexUnlock(&disp->dispMutex); if (!HdfSbufWriteUint32(rspData, powerStatus)) { HDF_LOGE("%s: HdfSbufWriteUint32 failed", __func__); @@ -312,10 +289,10 @@ static int32_t GetBacklight(struct HdfDeviceObject *device, struct HdfSBuf *reqD HDF_LOGE("%s: get panel failed", __func__); return HDF_FAILURE; } - OsalMutexLock(&disp->dispMutex); - panel = disp->panelManager->panel[devId]; - currLevel = panel->status.currLevel; - OsalMutexUnlock(&disp->dispMutex); + if (GetCurrBrightness(panel->blDev, &currLevel) != HDF_SUCCESS) { + HDF_LOGE("%s: GetCurrBrightness failed", __func__); + return HDF_FAILURE; + } if (!HdfSbufWriteUint32(rspData, currLevel)) { HDF_LOGE("%s: HdfSbufWriteUint32 failed", __func__); return HDF_FAILURE; diff --git a/model/display/driver/hdf_disp.h b/model/display/driver/hdf_disp.h index 6d7bb13ea..d9c6d9de1 100644 --- a/model/display/driver/hdf_disp.h +++ b/model/display/driver/hdf_disp.h @@ -8,7 +8,9 @@ #ifndef HDF_DISP_H #define HDF_DISP_H + #include "hdf_base.h" +#include "hdf_bl.h" #include "hdf_device_desc.h" #include "hdf_log.h" #include "hdf_sbuf.h" @@ -88,11 +90,6 @@ struct PanelInfo { struct PwmCfg pwm; }; -struct PanelStatus { - enum PowerStatus powerStatus; - uint32_t currLevel; -}; - struct PanelData; struct PanelEsd { bool support; @@ -109,10 +106,10 @@ struct PanelData { 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; + enum PowerStatus powerStatus; struct PanelEsd *esd; + struct BacklightDev *blDev; void *priv; }; diff --git a/model/display/driver/hdf_drm_panel.c b/model/display/driver/hdf_drm_panel.c index f6a3b8391..acf0e5645 100644 --- a/model/display/driver/hdf_drm_panel.c +++ b/model/display/driver/hdf_drm_panel.c @@ -1,4 +1,3 @@ - /* * Copyright (c) 2020-2021 Huawei Device Co., Ltd. * @@ -139,18 +138,22 @@ static ssize_t BacklightStore(struct device *dev, { int32_t ret; unsigned long level; - struct PanelData *panelData = NULL; + struct PanelData *panel = NULL; struct HdfDrmPanel *hdfDrmPanel = dev_get_drvdata(dev); ret = kstrtoul(buf, 0, &level); if (ret != 0) { return ret; } - HDF_LOGI("%s line = %d\n", __func__, __LINE__); - panelData = hdfDrmPanel->manager->panelManager->panel[hdfDrmPanel->index]; + HDF_LOGI("%s enter", __func__); OsalMutexLock(&hdfDrmPanel->manager->dispMutex); - panelData->setBacklight(panelData, level); + panel = hdfDrmPanel->manager->panelManager->panel[hdfDrmPanel->index]; OsalMutexUnlock(&hdfDrmPanel->manager->dispMutex); + ret = UpdateBrightness(panel->blDev, level); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s UpdateBrightness fail", __func__); + } + return count; } static DEVICE_ATTR(backlight, S_IWUSR, NULL, BacklightStore); @@ -203,7 +206,6 @@ int32_t HdfDrmPanelEntryInit(struct HdfDeviceObject *object) { uint32_t ret; uint32_t panelNum; - struct PanelData *panel = NULL; struct HdfDrmPanel *hdfDrmPanel = NULL; struct mipi_dsi_device *dsiDev = NULL; struct DispManager *manager = NULL; @@ -239,10 +241,7 @@ int32_t HdfDrmPanelEntryInit(struct HdfDeviceObject *object) HDF_LOGE("%s line = %d device_create_file fail", __func__, __LINE__); } } - panel = manager->panelManager->panel[i]; - if (panel->info->blk.type == BLK_PWM) { - panel->setBacklight(panel, panel->info->blk.defLevel); - } + HDF_LOGI("%s panel[%d] registered success", i, __func__); } HDF_LOGI("%s success", __func__); return HDF_SUCCESS; diff --git a/model/display/driver/panel/ili9881c_boe.c b/model/display/driver/panel/ili9881c_boe.c index f4a42f4fb..96945d70f 100644 --- a/model/display/driver/panel/ili9881c_boe.c +++ b/model/display/driver/panel/ili9881c_boe.c @@ -195,30 +195,6 @@ static int32_t Ili9881cBoeInit(struct PanelData *panel) #define MAX_LEVEL 255 #define DEFAULT_LEVEL 127 -static int32_t Ili9881cBoeSetBl(struct PanelData *panel, uint32_t level) -{ - int32_t ret; - uint32_t duty; - static uint32_t lastLevel = 0; - struct Ili9881cBoeDev *ili9881cBoeDev = NULL; - - ili9881cBoeDev = ToIli9881cBoeDev(panel); - duty = (level * PWM_MAX_PERIOD) / MAX_LEVEL; - ret = PwmSetDuty(ili9881cBoeDev->blHandle, duty); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: PwmSetDutyCycle failed, ret %d", __func__, ret); - return HDF_FAILURE; - } - if ((level != 0) && (lastLevel == 0)) { - ret = PwmEnable(ili9881cBoeDev->blHandle); - } else if ((level == 0) && (lastLevel != 0)) { - ret = PwmDisable(ili9881cBoeDev->blHandle); - } - lastLevel = level; - panel->status.currLevel = level; - return ret; -} - static struct PanelInfo g_panelInfo = { .width = 800, /* width */ .height = 1280, /* height */ @@ -260,35 +236,9 @@ static void Ili9881cBoeResInit(struct Ili9881cBoeDev *ili9881cBoeDev) ili9881cBoeDev->panel.init = Ili9881cBoeInit; ili9881cBoeDev->panel.on = Ili9881cBoeOn; ili9881cBoeDev->panel.off = Ili9881cBoeOff; - ili9881cBoeDev->panel.setBacklight = Ili9881cBoeSetBl; ili9881cBoeDev->panel.priv = ili9881cBoeDev->dsiDev; } -static int32_t Ili9881cBoeBlInit(struct Ili9881cBoeDev *ili9881cBoeDev) -{ - int32_t ret; - struct PwmConfig config; - - ili9881cBoeDev->blHandle = PwmOpen(BLK_PWM_INDEX); - if (ili9881cBoeDev->blHandle == NULL) { - HDF_LOGE("%s: PwmOpen failed", __func__); - } - ret = PwmGetConfig(ili9881cBoeDev->blHandle, &config); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: PwmGetConfig fail, ret %d", __func__, ret); - return HDF_FAILURE; - } - config.duty = 1; - config.period = PWM_MAX_PERIOD; - config.status = 1; - ret = PwmSetConfig(ili9881cBoeDev->blHandle, &config); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: PwmSetConfig fail, ret %d", __func__, ret); - return HDF_FAILURE; - } - return HDF_SUCCESS; -} - int32_t Ili9881cBoeEntryInit(struct HdfDeviceObject *object) { struct device_node *panelNode = NULL; @@ -301,12 +251,12 @@ int32_t Ili9881cBoeEntryInit(struct HdfDeviceObject *object) } panelNode = of_find_compatible_node(NULL, NULL, "sprd,generic-mipi-panel"); if (panelNode == NULL) { - HDF_LOGE("%s line = %d", __func__, __LINE__); + HDF_LOGE("%s of_find_compatible_node fail", __func__); goto FAIL; } ili9881cBoeDev->dsiDev = of_find_mipi_dsi_device_by_node(panelNode); if (ili9881cBoeDev->dsiDev == NULL) { - HDF_LOGE("%s line = %d", __func__, __LINE__); + HDF_LOGE("%s of_find_mipi_dsi_device_by_node fail", __func__); goto FAIL; } ili9881cBoeDev->supply = devm_regulator_get(&ili9881cBoeDev->dsiDev->dev, "power"); @@ -315,8 +265,9 @@ int32_t Ili9881cBoeEntryInit(struct HdfDeviceObject *object) goto FAIL; } Ili9881cBoeResInit(ili9881cBoeDev); - if (Ili9881cBoeBlInit(ili9881cBoeDev) != HDF_SUCCESS) { - HDF_LOGE("%s Ili9881cBoeBlInit fail", __func__); + ili9881cBoeDev->panel.blDev = GetBacklightDev("hdf_pwm"); + if (ili9881cBoeDev->panel.blDev == NULL) { + HDF_LOGE("%s GetBacklightDev fail", __func__); goto FAIL; } ili9881cBoeDev->panel.object = object; diff --git a/model/display/driver/panel/ili9881c_boe.h b/model/display/driver/panel/ili9881c_boe.h index 7a38d0836..ce3966a35 100644 --- a/model/display/driver/panel/ili9881c_boe.h +++ b/model/display/driver/panel/ili9881c_boe.h @@ -13,7 +13,6 @@ #include #include #include "hdf_disp.h" -#include "pwm_if.h" #define AVDD_GPIO 179 #define AVEE_GPIO 156 @@ -34,7 +33,6 @@ struct ResetSeq { struct Ili9881cBoeDev { struct PanelData panel; struct mipi_dsi_device *dsiDev; - DevHandle blHandle; struct regulator *supply; uint16_t avddGpio; uint16_t aveeGpio; diff --git a/model/display/driver/panel/mipi_icn9700.c b/model/display/driver/panel/mipi_icn9700.c index d475627b7..59654c6bf 100644 --- a/model/display/driver/panel/mipi_icn9700.c +++ b/model/display/driver/panel/mipi_icn9700.c @@ -94,7 +94,6 @@ struct DsiCmdDesc g_offCmd[] = { struct Icn9700Dev { struct PanelData panel; DevHandle mipiHandle; - DevHandle pwmHandle; uint16_t reset_gpio; uint16_t reset_delay; }; @@ -137,35 +136,6 @@ static int32_t LcdResetOff(struct Icn9700Dev *icn9700) return HDF_SUCCESS; } -static int32_t PwmCfg(struct Icn9700Dev *icn9700) -{ - 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(pwmHandle, &config); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: PwmGetConfig fail, ret %d", __func__, ret); - return HDF_FAILURE; - } - config.duty = 1; - config.period = PWM_MAX_PERIOD; - config.status = 1; - 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 struct Icn9700Dev *PanelToIcn9700Dev(const struct PanelData *panel) { struct Icn9700Dev *icn9700 = NULL; @@ -196,10 +166,6 @@ static int32_t Icn9700Init(struct PanelData *panel) HDF_LOGE("%s: MipiDsiOpen failed", __func__); return HDF_FAILURE; } - if (PwmCfg(icn9700) != HDF_SUCCESS) { - HDF_LOGE("%s: PwmCfg failed", __func__); - return HDF_FAILURE; - } return HDF_SUCCESS; } @@ -233,7 +199,6 @@ static int32_t Icn9700On(struct PanelData *panel) return HDF_FAILURE; } } - panel->status.powerStatus = POWER_STATUS_ON; /* set mipi to hs mode */ MipiDsiSetHsMode(icn9700->mipiHandle); return HDF_SUCCESS; @@ -271,38 +236,9 @@ static int32_t Icn9700Off(struct PanelData *panel) HDF_LOGE("%s: LcdResetOff failed", __func__); return HDF_FAILURE; } - panel->status.powerStatus = POWER_STATUS_OFF; return HDF_SUCCESS; } -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(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(icn9700->pwmHandle); - } else if (level == 0 && lastLevel != 0) { - ret = PwmDisable(icn9700->pwmHandle); - } - lastLevel = level; - panel->status.currLevel = level; - return ret; -} - static int32_t Icn9700EsdCheckFunc(struct PanelData *panel) { struct Icn9700Dev *icn9700 = NULL; @@ -344,13 +280,10 @@ static struct PanelEsd g_panelEsd = { 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) @@ -371,6 +304,11 @@ int32_t Icn9700EntryInit(struct HdfDeviceObject *object) icn9700->reset_gpio = RESET_GPIO; icn9700->reset_delay = 20; // delay 20ms object->priv = (void *)icn9700; + icn9700->panel.blDev = GetBacklightDev("hdf_pwm"); + if (icn9700->panel.blDev == NULL) { + HDF_LOGE("%s GetBacklightDev fail", __func__); + return HDF_FAILURE; + } if (RegisterPanel(&icn9700->panel) != HDF_SUCCESS) { HDF_LOGE("%s: RegisterPanel failed", __func__); return HDF_FAILURE; -- Gitee