• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }