• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020-2023 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_core.h"
10 #include "hdf_log.h"
11 #include "securec.h"
12 
13 #define HDF_LOG_TAG pwm_core
14 
PwmDeviceGet(struct PwmDev * pwm)15 int32_t PwmDeviceGet(struct PwmDev *pwm)
16 {
17     int32_t ret;
18 
19     if (pwm == NULL) {
20         HDF_LOGE("PwmDeviceGet: pwm is null!\n");
21         return HDF_ERR_INVALID_PARAM;
22     }
23 
24     (void)OsalSpinLock(&(pwm->lock));
25     if (pwm->busy) {
26         (void)OsalSpinUnlock(&(pwm->lock));
27         HDF_LOGE("PwmDeviceGet: pwm%u is busy!", pwm->num);
28         return HDF_ERR_DEVICE_BUSY;
29     }
30     if (pwm->method != NULL && pwm->method->open != NULL) {
31         ret = pwm->method->open(pwm);
32         if (ret != HDF_SUCCESS) {
33             (void)OsalSpinUnlock(&(pwm->lock));
34             HDF_LOGE("PwmDeviceGet: open fail, ret: %d!", ret);
35             return HDF_FAILURE;
36         }
37     }
38 
39     pwm->busy = true;
40     (void)OsalSpinUnlock(&(pwm->lock));
41     return HDF_SUCCESS;
42 }
43 
PwmDevicePut(struct PwmDev * pwm)44 int32_t PwmDevicePut(struct PwmDev *pwm)
45 {
46     int32_t ret;
47 
48     if (pwm == NULL) {
49         HDF_LOGE("PwmDevicePut: pwm is null!\n");
50         return HDF_ERR_INVALID_PARAM;
51     }
52 
53     if (pwm->method != NULL && pwm->method->close != NULL) {
54         ret = pwm->method->close(pwm);
55         if (ret != HDF_SUCCESS) {
56             HDF_LOGE("PwmDevicePut: close fail, ret: %d!", ret);
57             return ret;
58         }
59     }
60     (void)OsalSpinLock(&(pwm->lock));
61     pwm->busy = false;
62     (void)OsalSpinUnlock(&(pwm->lock));
63     return HDF_SUCCESS;
64 }
65 
PwmDeviceSetConfig(struct PwmDev * pwm,struct PwmConfig * config)66 int32_t PwmDeviceSetConfig(struct PwmDev *pwm, struct PwmConfig *config)
67 {
68     int32_t ret;
69 
70     if (pwm == NULL || config == NULL) {
71         HDF_LOGE("PwmDeviceSetConfig: pwm or config is null!\n");
72         return HDF_ERR_INVALID_PARAM;
73     }
74 
75     if (memcmp(config, &(pwm->cfg), sizeof(*config)) == 0) {
76         HDF_LOGE("PwmDeviceSetConfig: do not need to set config!");
77         return HDF_SUCCESS;
78     }
79 
80     if (pwm->method == NULL || pwm->method->setConfig == NULL) {
81         HDF_LOGE("PwmDeviceSetConfig: method or setConfig is null!");
82         return HDF_ERR_NOT_SUPPORT;
83     }
84 
85     ret = pwm->method->setConfig(pwm, config);
86     if (ret != HDF_SUCCESS) {
87         HDF_LOGE("PwmDeviceSetConfig: set config fail, ret: %d!", ret);
88         return ret;
89     }
90 
91     (void)OsalSpinLock(&(pwm->lock));
92     pwm->cfg = *config;
93     (void)OsalSpinUnlock(&(pwm->lock));
94     return HDF_SUCCESS;
95 }
96 
PwmDeviceGetConfig(struct PwmDev * pwm,struct PwmConfig * config)97 int32_t PwmDeviceGetConfig(struct PwmDev *pwm, struct PwmConfig *config)
98 {
99     if (pwm == NULL || config == NULL) {
100         HDF_LOGE("PwmDeviceGetConfig: pwm or config is null!\n");
101         return HDF_ERR_INVALID_PARAM;
102     }
103 
104     (void)OsalSpinLock(&(pwm->lock));
105     *config = pwm->cfg;
106     (void)OsalSpinUnlock(&(pwm->lock));
107     return HDF_SUCCESS;
108 }
109 
PwmSetPriv(struct PwmDev * pwm,void * priv)110 int32_t PwmSetPriv(struct PwmDev *pwm, void *priv)
111 {
112     if (pwm == NULL) {
113         HDF_LOGE("PwmSetPriv: pwm is null!");
114         return HDF_ERR_INVALID_PARAM;
115     }
116 
117     (void)OsalSpinLock(&(pwm->lock));
118     pwm->priv = priv;
119     (void)OsalSpinUnlock(&(pwm->lock));
120     return HDF_SUCCESS;
121 }
122 
PwmGetPriv(const struct PwmDev * pwm)123 void *PwmGetPriv(const struct PwmDev *pwm)
124 {
125     if (pwm == NULL) {
126         HDF_LOGE("PwmGetPriv: pwm is null!");
127         return NULL;
128     }
129     return pwm->priv;
130 }
131 
PwmUserSetConfig(struct PwmDev * pwm,struct HdfSBuf * data)132 static int32_t PwmUserSetConfig(struct PwmDev *pwm, struct HdfSBuf *data)
133 {
134     uint32_t size;
135     struct PwmConfig *config = NULL;
136 
137     if (data == NULL) {
138         HDF_LOGE("PwmUserSetConfig: data is null!");
139         return HDF_ERR_INVALID_PARAM;
140     }
141     if (!HdfSbufReadBuffer(data, (const void **)&config, &size)) {
142         HDF_LOGE("PwmUserSetConfig: sbuf read buffer fail!");
143         return HDF_ERR_IO;
144     }
145 
146     if ((config == NULL) || (size != sizeof(struct PwmConfig))) {
147         HDF_LOGE("PwmUserSetConfig: read buff error!");
148         return HDF_ERR_IO;
149     }
150     return PwmDeviceSetConfig(pwm, config);
151 }
152 
PwmUserGetConfig(struct PwmDev * pwm,struct HdfSBuf * reply)153 static int32_t PwmUserGetConfig(struct PwmDev *pwm, struct HdfSBuf *reply)
154 {
155     int32_t ret;
156     struct PwmConfig config;
157 
158     if (reply == NULL) {
159         HDF_LOGE("PwmUserGetConfig: reply is null!");
160         return HDF_ERR_INVALID_PARAM;
161     }
162     ret = PwmDeviceGetConfig(pwm, &config);
163     if (ret != HDF_SUCCESS) {
164         HDF_LOGE("PwmUserGetConfig: get config fail!");
165         return ret;
166     }
167 
168     if (!HdfSbufWriteBuffer(reply, &config, sizeof(config))) {
169         HDF_LOGE("PwmUserGetConfig: sbuf write buffer fail!");
170         return HDF_ERR_IO;
171     }
172     return HDF_SUCCESS;
173 }
174 
PwmIoDispatch(struct HdfDeviceIoClient * client,int cmd,struct HdfSBuf * data,struct HdfSBuf * reply)175 static int32_t PwmIoDispatch(struct HdfDeviceIoClient *client, int cmd,
176     struct HdfSBuf *data, struct HdfSBuf *reply)
177 {
178     struct PwmDev *pwm = NULL;
179 
180     if (client == NULL || client->device == NULL || client->device->service == NULL) {
181         HDF_LOGE("PwmIoDispatch: client info is null!");
182         return HDF_ERR_INVALID_OBJECT;
183     }
184 
185     pwm = (struct PwmDev *)client->device->service;
186     switch (cmd) {
187         case PWM_IO_GET:
188             return PwmDeviceGet(pwm);
189         case PWM_IO_PUT:
190             return PwmDevicePut(pwm);
191         case PWM_IO_SET_CONFIG:
192             return PwmUserSetConfig(pwm, data);
193         case PWM_IO_GET_CONFIG:
194             return PwmUserGetConfig(pwm, reply);
195         default:
196             HDF_LOGE("PwmIoDispatch: cmd %d is not support!", cmd);
197             return HDF_ERR_NOT_SUPPORT;
198     }
199 }
200 
PwmDeviceAdd(struct HdfDeviceObject * obj,struct PwmDev * pwm)201 int32_t PwmDeviceAdd(struct HdfDeviceObject *obj, struct PwmDev *pwm)
202 {
203     if (obj == NULL || pwm == NULL) {
204         HDF_LOGE("PwmDeviceAdd: obj or pwm is null!");
205         return HDF_ERR_INVALID_PARAM;
206     }
207     if (pwm->method == NULL || pwm->method->setConfig == NULL) {
208         HDF_LOGE("PwmDeviceAdd: method or setConfig is null!");
209         return HDF_ERR_INVALID_PARAM;
210     }
211     if (OsalSpinInit(&(pwm->lock)) != HDF_SUCCESS) {
212         HDF_LOGE("PwmDeviceAdd: init spinlock fail!");
213         return HDF_FAILURE;
214     }
215     pwm->device = obj;
216     obj->service = &(pwm->service);
217     pwm->device->service->Dispatch = PwmIoDispatch;
218     return HDF_SUCCESS;
219 }
220 
PwmDeviceRemove(struct HdfDeviceObject * obj,struct PwmDev * pwm)221 void PwmDeviceRemove(struct HdfDeviceObject *obj, struct PwmDev *pwm)
222 {
223     if (obj == NULL || pwm == NULL) {
224         HDF_LOGE("PwmDeviceRemove: obj or pwm is null!");
225         return;
226     }
227     (void)OsalSpinDestroy(&(pwm->lock));
228     pwm->device = NULL;
229     obj->service = NULL;
230 }
231