* 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 <securec.h>
#include "gpio_if.h"
#include "hdf_device_desc.h"
#include "hdf_log.h"
#include "mipi_dsi_if.h"
#include "osal.h"
#include "pwm_if.h"
#include "lite_lcdkit.h"
static struct PanelConfig *GetPanelCfg(void)
{
static struct PanelConfig panelCfg;
return &panelCfg;
}
static int32_t PowerInit(void)
{
int32_t ret;
int32_t count;
int32_t i;
struct PanelConfig *panelCfg = GetPanelCfg();
count = panelCfg->setting.count;
for (i = 0; i < count; i++) {
if (panelCfg->setting.power[i].type == GPIO_POWER) {
ret = GpioSetDir(panelCfg->setting.power[i].num, GPIO_DIR_OUT);
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s:GpioSetDir failed", __func__);
return HDF_FAILURE;
}
}
}
return HDF_SUCCESS;
}
static int32_t LcdkitInit(void)
{
int32_t ret;
struct PanelConfig *panelCfg = GetPanelCfg();
if (panelCfg->info.intfType != MIPI_DSI) {
HDF_LOGE("%s:not support intf: %u", __func__, panelCfg->info.intfType);
return HDF_FAILURE;
}
ret = PowerInit();
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s:PowerInit failed", __func__);
return HDF_FAILURE;
}
panelCfg->dsiHandle = MipiDsiOpen(panelCfg->dsiDev);
if (panelCfg->dsiHandle == NULL) {
HDF_LOGE("%s:MipiDsiOpen failed", __func__);
return HDF_FAILURE;
}
if (panelCfg->info.blk.type == BLK_PWM) {
panelCfg->pwmHandle = PwmOpen(panelCfg->info.pwm.dev);
if (panelCfg->pwmHandle == NULL) {
MipiDsiClose(panelCfg->dsiHandle);
panelCfg->dsiHandle = NULL;
HDF_LOGE("%s: PwmOpen failed", __func__);
return HDF_FAILURE;
}
}
return HDF_SUCCESS;
}
static int32_t MipiDsiOn(void)
{
int32_t ret;
struct PanelConfig *panelCfg = GetPanelCfg();
int32_t i;
if (panelCfg->dsiHandle == NULL) {
HDF_LOGE("%s:dsiHandle is null", __func__);
return HDF_FAILURE;
}
int32_t count = panelCfg->onCmd.count;
for (i = 0; i < count; i++) {
ret = MipiDsiTx(panelCfg->dsiHandle, &(panelCfg->onCmd.dsiCmd[i]));
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s:MipiDsiTx failed", __func__);
return ret;
}
}
MipiDsiSetHsMode(panelCfg->dsiHandle);
return HDF_SUCCESS;
}
static int32_t MipiDsiOff(void)
{
int32_t ret;
struct PanelConfig *panelCfg = GetPanelCfg();
int32_t i;
if (panelCfg->dsiHandle == NULL) {
HDF_LOGE("%s:dsiHandle is null", __func__);
return HDF_FAILURE;
}
int32_t count = panelCfg->offCmd.count;
for (i = 0; i < count; i++) {
ret = MipiDsiTx(panelCfg->dsiHandle, &(panelCfg->offCmd.dsiCmd[i]));
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s:MipiDsiTx failed", __func__);
return ret;
}
}
MipiDsiSetLpMode(panelCfg->dsiHandle);
return HDF_SUCCESS;
}
static int32_t PowerOn(void)
{
int32_t ret;
struct PanelConfig *panelCfg = GetPanelCfg();
int32_t i;
for (i = 0; i < panelCfg->onSeq.count; i++) {
if (panelCfg->onSeq.pwCtrl[i].type == GPIO_POWER) {
ret = GpioWrite(panelCfg->onSeq.pwCtrl[i].num, panelCfg->onSeq.pwCtrl[i].opt);
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s:GpioWrite failed", __func__);
return HDF_FAILURE;
}
OsalMSleep(panelCfg->onSeq.pwCtrl[i].delay);
}
}
return HDF_SUCCESS;
}
static int32_t PowerOff(void)
{
int32_t ret;
struct PanelConfig *panelCfg = GetPanelCfg();
int32_t i;
for (i = 0; i < panelCfg->offSeq.count; i++) {
if (panelCfg->offSeq.pwCtrl[i].type == GPIO_POWER) {
ret = GpioWrite(panelCfg->offSeq.pwCtrl[i].num, panelCfg->offSeq.pwCtrl[i].opt);
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s:GpioWrite failed", __func__);
return HDF_FAILURE;
}
OsalMSleep(panelCfg->offSeq.pwCtrl[i].delay);
}
}
return HDF_SUCCESS;
}
static int32_t LcdkitOn(void)
{
int32_t ret;
ret = PowerOn();
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s:MipiPowerOn failed", __func__);
return HDF_FAILURE;
}
ret = MipiDsiOn();
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s:MipiDsiOn failed", __func__);
return HDF_FAILURE;
}
return HDF_SUCCESS;
}
static int32_t LcdkitOff(void)
{
int32_t ret;
ret = MipiDsiOff();
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s:MipiDsiOff failed", __func__);
return HDF_FAILURE;
}
ret = PowerOff();
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s:PanelPowerOff failed", __func__);
return HDF_FAILURE;
}
return HDF_SUCCESS;
}
static int32_t SetBacklightByPwm(uint32_t level)
{
struct PanelConfig *panelCfg = GetPanelCfg();
int32_t ret;
uint32_t duty;
if (panelCfg->pwmHandle == NULL) {
HDF_LOGE("%s:pwmHandle is null", __func__);
return HDF_FAILURE;
}
duty = (level * panelCfg->info.pwm.period) / panelCfg->info.blk.maxLevel;
ret = PwmSetDuty(panelCfg->pwmHandle, duty);
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s: PwmSetDuty failed", __func__);
return HDF_FAILURE;
}
static uint32_t lastLevel = 0;
if (level != 0 && lastLevel == 0) {
ret = PwmEnable(panelCfg->pwmHandle);
} else if (level == 0 && lastLevel != 0) {
ret = PwmDisable(panelCfg->pwmHandle);
}
lastLevel = level;
return ret;
}
static int32_t SetBacklightByMipi(uint32_t level)
{
int32_t ret;
struct PanelConfig *panelCfg = GetPanelCfg();
uint8_t payLoad[] = { 0x51, 0x00 };
struct DsiCmdDesc bklCmd = { 0x15, 0, sizeof(payLoad), payLoad };
if (panelCfg->dsiHandle == NULL) {
HDF_LOGE("%s: dsiHandle is null", __func__);
return HDF_FAILURE;
}
payLoad[1] = level;
ret = MipiDsiTx(panelCfg->dsiHandle, &bklCmd);
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s: MipiDsiTx failed", __func__);
return HDF_FAILURE;
}
return HDF_SUCCESS;
}
static int32_t LcdkitSetBkl(uint32_t level)
{
struct PanelConfig *panelCfg = GetPanelCfg();
int32_t ret = HDF_SUCCESS;
if (panelCfg->info.blk.type == BLK_PWM) {
ret = SetBacklightByPwm(level);
} else if (panelCfg->info.blk.type == BLK_MIPI) {
ret = SetBacklightByMipi(level);
} else {
HDF_LOGE("%s: not support backlight type:%d", __func__, panelCfg->info.blk.type);
return HDF_FAILURE;
}
return ret;
}
static struct PanelData g_panelData = {
.init = LcdkitInit,
.on = LcdkitOn,
.off = LcdkitOff,
.setBacklight = LcdkitSetBkl,
};
static int32_t LcdkitEntryInit(struct HdfDeviceObject *object)
{
struct PanelConfig *panelCfg = GetPanelCfg();
if (object == NULL) {
HDF_LOGE("%s: param is null", __func__);
return HDF_FAILURE;
}
if (ParseLcdConfig(object->property, panelCfg)) {
HDF_LOGE("%s: ParseLcdConfig failed", __func__);
return HDF_FAILURE;
}
g_panelData.info = &panelCfg->info;
if (PanelDataRegister(&g_panelData) != HDF_SUCCESS) {
HDF_LOGE("%s: PanelDataRegister failed", __func__);
return HDF_FAILURE;
}
HDF_LOGI("%s: exit succ", __func__);
return HDF_SUCCESS;
}
struct HdfDriverEntry g_lcdkitDevEntry = {
.moduleVersion = 1,
.moduleName = "LITE_LCDKIT",
.Init = LcdkitEntryInit,
};
HDF_INIT(g_lcdkitDevEntry);