1 /*
2 * Copyright (c) 2022 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 "pwm_if.h"
10 #include "hdf_log.h"
11 #include "hdf_io_service_if.h"
12 #include "osal_mem.h"
13 #include "securec.h"
14
15 #define HDF_LOG_TAG pwm_if_u_c
16 #define PWM_NAME_LEN 32
17
PwmGetDevByNum(uint32_t num)18 static void *PwmGetDevByNum(uint32_t num)
19 {
20 int32_t ret;
21 char name[PWM_NAME_LEN + 1] = {0};
22 void *pwm = NULL;
23
24 ret = snprintf_s(name, PWM_NAME_LEN + 1, PWM_NAME_LEN, "HDF_PLATFORM_PWM_%u", num);
25 if (ret < 0) {
26 HDF_LOGE("%s: snprintf_s failed", __func__);
27 return NULL;
28 }
29
30 pwm = (void *)HdfIoServiceBind(name);
31 if (pwm == NULL) {
32 HDF_LOGE("%s: HdfIoServiceBind failed", __func__);
33 return NULL;
34 }
35
36 return pwm;
37 }
38
PwmPutObjByPointer(const void * obj)39 static void PwmPutObjByPointer(const void *obj)
40 {
41 if (obj == NULL) {
42 return;
43 }
44
45 HdfIoServiceRecycle((struct HdfIoService *)obj);
46 }
47
PwmOpen(uint32_t num)48 DevHandle PwmOpen(uint32_t num)
49 {
50 int32_t ret;
51 void *pwm = PwmGetDevByNum(num);
52
53 if (pwm == NULL) {
54 HDF_LOGE("%s: dev is null", __func__);
55 return NULL;
56 }
57
58 struct HdfIoService *service = (struct HdfIoService *)pwm;
59 if (service->dispatcher == NULL || service->dispatcher->Dispatch == NULL) {
60 HDF_LOGE("%s: service is invalid", __func__);
61 PwmPutObjByPointer(pwm);
62 return NULL;
63 }
64
65 ret = service->dispatcher->Dispatch(&service->object, PWM_IO_GET, NULL, NULL);
66 if (ret != HDF_SUCCESS) {
67 HDF_LOGE("%s: PwmDeviceGet error, ret %d", __func__, ret);
68 PwmPutObjByPointer(pwm);
69 return NULL;
70 }
71
72 return (DevHandle)pwm;
73 }
74
PwmClose(DevHandle handle)75 void PwmClose(DevHandle handle)
76 {
77 int32_t ret;
78 struct HdfIoService *service = NULL;
79
80 if (handle == NULL) {
81 HDF_LOGE("%s: dev is null", __func__);
82 return;
83 }
84
85 service = (struct HdfIoService *)handle;
86 if (service->dispatcher == NULL || service->dispatcher->Dispatch == NULL) {
87 HDF_LOGE("%s: service is invalid", __func__);
88 PwmPutObjByPointer(handle);
89 return;
90 }
91
92 ret = service->dispatcher->Dispatch(&service->object, PWM_IO_PUT, NULL, NULL);
93 if (ret != HDF_SUCCESS) {
94 HDF_LOGE("%s: PwmDevicePut error, ret %d", __func__, ret);
95 }
96
97 PwmPutObjByPointer(handle);
98 }
99
PwmSetConfig(DevHandle handle,struct PwmConfig * config)100 int32_t PwmSetConfig(DevHandle handle, struct PwmConfig *config)
101 {
102 int32_t ret;
103 struct HdfSBuf *buf = NULL;
104 struct HdfIoService *service = NULL;
105
106 if (handle == NULL || config == NULL) {
107 HDF_LOGE("%s: param is NULL", __func__);
108 return HDF_ERR_INVALID_OBJECT;
109 }
110
111 service = (struct HdfIoService *)handle;
112 if (service->dispatcher == NULL || service->dispatcher->Dispatch == NULL) {
113 HDF_LOGE("%s: service is invalid", __func__);
114 return HDF_ERR_INVALID_OBJECT;
115 }
116
117 buf = HdfSbufObtainDefaultSize();
118 if (buf == NULL) {
119 HDF_LOGE("%s: failed to obtain buf", __func__);
120 return HDF_ERR_MALLOC_FAIL;
121 }
122 if (!HdfSbufWriteBuffer(buf, config, sizeof(struct PwmConfig))) {
123 HDF_LOGE("%s: sbuf write cfg failed", __func__);
124 HdfSbufRecycle(buf);
125 return HDF_ERR_IO;
126 }
127
128 ret = service->dispatcher->Dispatch(&service->object, PWM_IO_SET_CONFIG, buf, NULL);
129 if (ret != HDF_SUCCESS) {
130 HDF_LOGE("%s: service PWM_IO_SET_CONFIG error, ret %d", __func__, ret);
131 }
132
133 HdfSbufRecycle(buf);
134 return ret;
135 }
136
PwmGetConfig(DevHandle handle,struct PwmConfig * config)137 int32_t PwmGetConfig(DevHandle handle, struct PwmConfig *config)
138 {
139 int32_t ret;
140 struct HdfSBuf *reply = NULL;
141 struct HdfIoService *service = NULL;
142 const void *rBuf = NULL;
143 uint32_t rLen;
144
145 if (handle == NULL || config == NULL) {
146 HDF_LOGE("%s: param is NULL", __func__);
147 return HDF_ERR_INVALID_OBJECT;
148 }
149
150 service = (struct HdfIoService *)handle;
151 if (service->dispatcher == NULL || service->dispatcher->Dispatch == NULL) {
152 HDF_LOGE("%s: service is invalid", __func__);
153 return HDF_ERR_INVALID_OBJECT;
154 }
155
156 reply = HdfSbufObtainDefaultSize();
157 if (reply == NULL) {
158 HDF_LOGE("%s: failed to obtain reply", __func__);
159 return HDF_ERR_MALLOC_FAIL;
160 }
161
162 ret = service->dispatcher->Dispatch(&service->object, PWM_IO_GET_CONFIG, NULL, reply);
163 if (ret != HDF_SUCCESS) {
164 HDF_LOGE("%s: service PWM_IO_GET_CONFIG error, ret %d", __func__, ret);
165 HdfSbufRecycle(reply);
166 return ret;
167 }
168
169 if (!HdfSbufReadBuffer(reply, &rBuf, &rLen)) {
170 HDF_LOGE("%s: sbuf read buffer failed", __func__);
171 HdfSbufRecycle(reply);
172 return HDF_ERR_IO;
173 }
174 if (rLen != sizeof(struct PwmConfig)) {
175 HDF_LOGE("%s: sbuf read buffer len error %u != %zu", __func__, rLen, sizeof(struct PwmConfig));
176 HdfSbufRecycle(reply);
177 return HDF_ERR_IO;
178 }
179 if (memcpy_s(config, sizeof(struct PwmConfig), rBuf, rLen) != EOK) {
180 HDF_LOGE("%s: memcpy rBuf failed", __func__);
181 HdfSbufRecycle(reply);
182 return HDF_ERR_IO;
183 }
184
185 HdfSbufRecycle(reply);
186 return HDF_SUCCESS;
187 }
188
189 enum PwmSetConfigType {
190 PWM_SET_CONFIG_PERIOD = 1,
191 PWM_SET_CONFIG_DUTY,
192 PWM_SET_CONFIG_POLARITY,
193 PWM_SET_CONFIG_STATUS,
194 };
195
PwmConfigTransSet(DevHandle handle,enum PwmSetConfigType type,struct PwmConfig * config)196 static int32_t PwmConfigTransSet(DevHandle handle, enum PwmSetConfigType type, struct PwmConfig *config)
197 {
198 struct PwmConfig nowCfg;
199 uint32_t curValue;
200 int32_t ret;
201 if (PwmGetConfig(handle, &nowCfg) != HDF_SUCCESS) {
202 HDF_LOGE("%s: PwmGetConfig fail", __func__);
203 return HDF_FAILURE;
204 }
205
206 switch (type) {
207 case PWM_SET_CONFIG_PERIOD:
208 curValue = nowCfg.period;
209 nowCfg.period = config->period;
210 break;
211 case PWM_SET_CONFIG_DUTY:
212 curValue = nowCfg.duty;
213 nowCfg.duty = config->duty;
214 break;
215 case PWM_SET_CONFIG_POLARITY:
216 curValue = nowCfg.polarity;
217 nowCfg.polarity = config->polarity;
218 break;
219 case PWM_SET_CONFIG_STATUS:
220 curValue = nowCfg.status;
221 nowCfg.status = config->status;
222 break;
223 default:
224 HDF_LOGE("%s: type %d not support", __func__, type);
225 return HDF_ERR_NOT_SUPPORT;
226 }
227
228 ret = PwmSetConfig(handle, &nowCfg);
229 if (ret != HDF_SUCCESS) {
230 HDF_LOGE("%s: set [%d] cfg fail, org val[%d].", __func__, type, curValue);
231 return HDF_FAILURE;
232 }
233
234 return HDF_SUCCESS;
235 }
PwmSetPeriod(DevHandle handle,uint32_t period)236 int32_t PwmSetPeriod(DevHandle handle, uint32_t period)
237 {
238 struct PwmConfig config;
239
240 if (handle == NULL) {
241 HDF_LOGE("%s: handle is NULL", __func__);
242 return HDF_ERR_INVALID_OBJECT;
243 }
244
245 if (memset_s(&config, sizeof(struct PwmConfig), 0, sizeof(struct PwmConfig)) != EOK) {
246 return HDF_ERR_IO;
247 }
248 config.period = period;
249 if (PwmConfigTransSet(handle, PWM_SET_CONFIG_PERIOD, &config) != HDF_SUCCESS) {
250 HDF_LOGE("%s: PwmConfigTransSet fail", __func__);
251 return HDF_FAILURE;
252 }
253
254 return HDF_SUCCESS;
255 }
256
PwmSetDuty(DevHandle handle,uint32_t duty)257 int32_t PwmSetDuty(DevHandle handle, uint32_t duty)
258 {
259 struct PwmConfig config;
260
261 if (handle == NULL) {
262 HDF_LOGE("%s: handle is NULL", __func__);
263 return HDF_ERR_INVALID_OBJECT;
264 }
265 if (memset_s(&config, sizeof(struct PwmConfig), 0, sizeof(struct PwmConfig)) != EOK) {
266 return HDF_ERR_IO;
267 }
268 config.duty = duty;
269 if (PwmConfigTransSet(handle, PWM_SET_CONFIG_DUTY, &config) != HDF_SUCCESS) {
270 HDF_LOGE("%s: PwmConfigTransSet fail", __func__);
271 return HDF_FAILURE;
272 }
273
274 return HDF_SUCCESS;
275 }
276
PwmSetPolarity(DevHandle handle,uint8_t polarity)277 int32_t PwmSetPolarity(DevHandle handle, uint8_t polarity)
278 {
279 struct PwmConfig config;
280
281 if (handle == NULL) {
282 HDF_LOGE("%s: handle is NULL", __func__);
283 return HDF_ERR_INVALID_OBJECT;
284 }
285
286 if (memset_s(&config, sizeof(struct PwmConfig), 0, sizeof(struct PwmConfig)) != EOK) {
287 return HDF_ERR_IO;
288 }
289 config.polarity = polarity;
290 if (PwmConfigTransSet(handle, PWM_SET_CONFIG_POLARITY, &config) != HDF_SUCCESS) {
291 HDF_LOGE("%s: PwmConfigTransSet fail", __func__);
292 return HDF_FAILURE;
293 }
294
295 return HDF_SUCCESS;
296 }
297
PwmEnable(DevHandle handle)298 int32_t PwmEnable(DevHandle handle)
299 {
300 struct PwmConfig config;
301
302 if (handle == NULL) {
303 HDF_LOGE("%s: handle is NULL", __func__);
304 return HDF_ERR_INVALID_OBJECT;
305 }
306
307 if (memset_s(&config, sizeof(struct PwmConfig), 0, sizeof(struct PwmConfig)) != EOK) {
308 return HDF_ERR_IO;
309 }
310 config.status = PWM_ENABLE_STATUS;
311 if (PwmConfigTransSet(handle, PWM_SET_CONFIG_STATUS, &config) != HDF_SUCCESS) {
312 HDF_LOGE("%s: PwmConfigTransSet fail", __func__);
313 return HDF_FAILURE;
314 }
315
316 return HDF_SUCCESS;
317 }
318
PwmDisable(DevHandle handle)319 int32_t PwmDisable(DevHandle handle)
320 {
321 struct PwmConfig config;
322
323 if (handle == NULL) {
324 HDF_LOGE("%s: handle is NULL", __func__);
325 return HDF_ERR_INVALID_OBJECT;
326 }
327
328 if (memset_s(&config, sizeof(struct PwmConfig), 0, sizeof(struct PwmConfig)) != EOK) {
329 return HDF_ERR_IO;
330 }
331 config.status = PWM_DISABLE_STATUS;
332 if (PwmConfigTransSet(handle, PWM_SET_CONFIG_STATUS, &config) != HDF_SUCCESS) {
333 HDF_LOGE("%s: PwmConfigTransSet fail", __func__);
334 return HDF_FAILURE;
335 }
336
337 return HDF_SUCCESS;
338 }