1 /*
2 * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
3 *
4 * HDF is dual licensed: you can use it either under the terms of
5 * the GPL, or the BSD license, at your option.
6 * See the LICENSE file in the root of this repository for complete details.
7 */
8
9 #include "device_resource_if.h"
10 #include "hdf_base.h"
11 #include "hdf_bl.h"
12 #include "hdf_disp.h"
13 #include "hdf_log.h"
14 #include "hdf_types.h"
15 #include "osal.h"
16 #include "pwm_if.h"
17
18 #define DEF_MIN_BRIGHTNESS 0
19 #define DEF_MAX_BRIGHTNESS 255
20
21 #define CHECK_PARSER_RET(ret, str) do { \
22 if ((ret) != HDF_SUCCESS) { \
23 HDF_LOGE("%s: %s failed, ret = %d", __func__, str, ret); \
24 return HDF_FAILURE; \
25 } \
26 } while (0)
27
28 struct BlPwmDev {
29 const char *name;
30 uint8_t pwmDevNum;
31 DevHandle pwmHandle;
32 struct PwmConfig config;
33 struct BacklightProperties props;
34 };
35
BlPwmUpdateBrightness(struct BacklightDev * blDev,uint32_t brightness)36 static int32_t BlPwmUpdateBrightness(struct BacklightDev *blDev, uint32_t brightness)
37 {
38 int32_t ret;
39 uint32_t duty;
40 struct BlPwmDev *blPwmDev = NULL;
41
42 blPwmDev = ToBlDevPriv(blDev);
43 if (blPwmDev == NULL) {
44 HDF_LOGE("%s blPwmDev is null", __func__);
45 return HDF_FAILURE;
46 }
47 if (blPwmDev->props.maxBrightness == 0) {
48 HDF_LOGE("%s maxBrightness is 0", __func__);
49 return HDF_FAILURE;
50 }
51 if (brightness == 0) {
52 return PwmDisable(blPwmDev->pwmHandle);
53 }
54 duty = (brightness * blPwmDev->config.period) / blPwmDev->props.maxBrightness;
55 ret = PwmSetDuty(blPwmDev->pwmHandle, duty);
56 if (ret != HDF_SUCCESS) {
57 HDF_LOGE("%s: PwmSetDuty failed, ret %d", __func__, ret);
58 return HDF_FAILURE;
59 }
60 return PwmEnable(blPwmDev->pwmHandle);
61 }
62
63 static struct BacklightOps g_blDevOps = {
64 .updateBrightness = BlPwmUpdateBrightness,
65 };
66
ParsePwmNum(const struct DeviceResourceNode * node,uint8_t * pwmNum)67 static int32_t ParsePwmNum(const struct DeviceResourceNode *node, uint8_t *pwmNum)
68 {
69 int32_t ret;
70 struct DeviceResourceIface *parser = NULL;
71
72 if (node == NULL) {
73 HDF_LOGE("%s: node is null", __func__);
74 return HDF_FAILURE;
75 }
76 parser = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
77 if (parser == NULL) {
78 HDF_LOGE("%s: instance parser failed", __func__);
79 return HDF_FAILURE;
80 }
81 ret = parser->GetUint8(node, "pwmDevNum", pwmNum, 0);
82 CHECK_PARSER_RET(ret, "GetUint8");
83 return HDF_SUCCESS;
84 }
ParseBlPwmCfg(const struct DeviceResourceNode * node,struct BlPwmDev * blPwmDev)85 static int32_t ParseBlPwmCfg(const struct DeviceResourceNode *node, struct BlPwmDev *blPwmDev)
86 {
87 int32_t ret;
88 uint32_t defBrightness;
89 struct DeviceResourceIface *parser = NULL;
90
91 if (node == NULL) {
92 HDF_LOGE("%s: node is null", __func__);
93 return HDF_FAILURE;
94 }
95 parser = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
96 if (parser == NULL) {
97 HDF_LOGE("%s: instance parser failed", __func__);
98 return HDF_FAILURE;
99 }
100 ret = parser->GetString(node, "backlightDevName", &blPwmDev->name, NULL);
101 CHECK_PARSER_RET(ret, "GetString");
102 ret = parser->GetUint32(node, "pwmMaxPeriod", &blPwmDev->config.period, 0);
103 CHECK_PARSER_RET(ret, "GetUint32");
104 ret = parser->GetUint32(node, "minBrightness", &blPwmDev->props.minBrightness, DEF_MIN_BRIGHTNESS);
105 CHECK_PARSER_RET(ret, "GetUint32");
106 ret = parser->GetUint32(node, "maxBrightness", &blPwmDev->props.maxBrightness, DEF_MAX_BRIGHTNESS);
107 CHECK_PARSER_RET(ret, "GetUint32");
108 // if not provided defBrightness, defBrightness = (min + max) / 2
109 defBrightness = (blPwmDev->props.minBrightness + blPwmDev->props.maxBrightness) / 2;
110 ret = parser->GetUint32(node, "defBrightness", &blPwmDev->props.defBrightness, defBrightness);
111 CHECK_PARSER_RET(ret, "GetUint32");
112 blPwmDev->config.duty = 1;
113 blPwmDev->config.status = 1;
114 return HDF_SUCCESS;
115 }
116
BlPwmDevInit(struct HdfDeviceObject * object,struct BlPwmDev * blPwmDev)117 static int32_t BlPwmDevInit(struct HdfDeviceObject *object, struct BlPwmDev *blPwmDev)
118 {
119 if (ParsePwmNum(object->property, &blPwmDev->pwmDevNum) != HDF_SUCCESS) {
120 HDF_LOGE("%s ParsePwmNum fail", __func__);
121 return HDF_FAILURE;
122 }
123 blPwmDev->pwmHandle = PwmOpen(blPwmDev->pwmDevNum);
124 if (blPwmDev->pwmHandle == NULL) {
125 HDF_LOGE("%s: PwmOpen failed", __func__);
126 return HDF_FAILURE;
127 }
128 if (PwmGetConfig(blPwmDev->pwmHandle, &blPwmDev->config) != HDF_SUCCESS) {
129 HDF_LOGE("%s: PwmGetConfig fail", __func__);
130 return HDF_FAILURE;
131 }
132 if (ParseBlPwmCfg(object->property, blPwmDev) != HDF_SUCCESS) {
133 HDF_LOGE("%s: ParseBlPwmCfg fail", __func__);
134 return HDF_FAILURE;
135 }
136 if (PwmSetConfig(blPwmDev->pwmHandle, &blPwmDev->config) != HDF_SUCCESS) {
137 HDF_LOGE("%s: PwmSetConfig fail", __func__);
138 return HDF_FAILURE;
139 }
140 return HDF_SUCCESS;
141 }
142
BlPwmEntryInit(struct HdfDeviceObject * object)143 static int32_t BlPwmEntryInit(struct HdfDeviceObject *object)
144 {
145 int32_t ret;
146 struct BacklightDev *blDev = NULL;
147 struct BlPwmDev *blPwmDev = NULL;
148
149 blPwmDev = (struct BlPwmDev *)OsalMemCalloc(sizeof(struct BlPwmDev));
150 if (blPwmDev == NULL) {
151 HDF_LOGE("%s blPwmDev malloc fail", __func__);
152 return HDF_FAILURE;
153 }
154 ret = BlPwmDevInit(object, blPwmDev);
155 if (ret != HDF_SUCCESS) {
156 HDF_LOGE("%s: BlPwmDevInit fail", __func__);
157 goto FAIL;
158 }
159 blDev = RegisterBlDev(blPwmDev->name, &blPwmDev->props, &g_blDevOps, blPwmDev);
160 if (blDev == NULL) {
161 HDF_LOGE("%s: RegisterBlDev fail", __func__);
162 goto FAIL;
163 }
164 if (UpdateBacklightState(blDev, FB_POWER_ON) != HDF_SUCCESS) {
165 HDF_LOGE("%s: UpdateBacklightState fail", __func__);
166 }
167 if (UpdateBrightness(blDev, blPwmDev->props.defBrightness) != HDF_SUCCESS) {
168 HDF_LOGE("%s: UpdateBrightness fail", __func__);
169 }
170 HDF_LOGI("%s: success", __func__);
171 return HDF_SUCCESS;
172
173 FAIL:
174 OsalMemFree(blPwmDev);
175 return HDF_FAILURE;
176 }
177
178 struct HdfDriverEntry g_pwmBlDevEntry = {
179 .moduleVersion = 1,
180 .moduleName = "PWM_BL",
181 .Init = BlPwmEntryInit,
182 };
183
184 HDF_INIT(g_pwmBlDevEntry);
185