[1/6] fd passing: move interface code from daemon.
[platform/core/api/peripheral-io.git] / src / interface / pwm.c
1 /*
2  * Copyright (c) 2016-2017 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <errno.h>
21 #include <fcntl.h>
22 #include <unistd.h>
23 #include <stdbool.h>
24
25 #include "pwm.h"
26 #include "peripheral_common.h"
27
28 #define SYSFS_PWM_PATH  "/sys/class/pwm"
29
30 #define PATH_BUF_MAX    64
31 #define PWM_BUF_MAX     16
32 #define MAX_ERR_LEN     255
33
34 int pwm_open(int chip, int pin)
35 {
36         int fd, len, status;
37         char pwm_dev[PATH_BUF_MAX] = {0};
38         char pwm_buf[PWM_BUF_MAX] = {0};
39
40         _D("chip : %d, pin : %d", chip, pin);
41
42         snprintf(pwm_dev, PATH_BUF_MAX, SYSFS_PWM_PATH "/pwmchip%d/export", chip);
43         fd = open(pwm_dev, O_WRONLY);
44         if (fd < 0) {
45                 char errmsg[MAX_ERR_LEN];
46                 strerror_r(errno, errmsg, MAX_ERR_LEN);
47                 _E("Can't Open %s, errmsg : %s", pwm_dev, errmsg);
48                 return -ENXIO;
49         }
50
51         len = snprintf(pwm_buf, sizeof(pwm_buf), "%d", pin);
52         status = write(fd, pwm_buf, len);
53         if (status < 0) {
54                 _E("Failed to export pwmchip%d, pwm%d", chip, pin);
55                 close(fd);
56                 return -EIO;
57         }
58         close(fd);
59
60         return 0;
61 }
62
63 int pwm_close(int chip, int pin)
64 {
65         int fd, len, status;
66         char pwm_dev[PATH_BUF_MAX] = {0};
67         char pwm_buf[PWM_BUF_MAX] = {0};
68
69         _D("chip : %d, pin : %d", chip, pin);
70
71         snprintf(pwm_dev, PATH_BUF_MAX, SYSFS_PWM_PATH "/pwmchip%d/unexport", chip);
72         fd = open(pwm_dev, O_WRONLY);
73         if (fd < 0) {
74                 char errmsg[MAX_ERR_LEN];
75                 strerror_r(errno, errmsg, MAX_ERR_LEN);
76                 _E("Can't Open %s, errmsg : %s", pwm_dev, errmsg);
77                 return -ENXIO;
78         }
79
80         len = snprintf(pwm_buf, sizeof(pwm_buf), "%d", pin);
81         status = write(fd, pwm_buf, len);
82         if (status < 0) {
83                 _E("Failed to unexport pwmchip%d, pwm%", chip, pin);
84                 close(fd);
85                 return -EIO;
86         }
87         close(fd);
88
89         return 0;
90 }
91
92 int pwm_set_period(int chip, int pin, int period)
93 {
94         int fd, len, status;
95         char pwm_buf[PWM_BUF_MAX] = {0};
96         char pwm_dev[PATH_BUF_MAX] = {0};
97
98         _D("chip : %d, pin : %d, period : %d", chip, pin, period);
99
100         snprintf(pwm_dev, PATH_BUF_MAX, SYSFS_PWM_PATH "/pwmchip%d/pwm%d/period", chip, pin);
101         fd = open(pwm_dev, O_WRONLY);
102         if (fd < 0) {
103                 char errmsg[MAX_ERR_LEN];
104                 strerror_r(errno, errmsg, MAX_ERR_LEN);
105                 _E("Can't Open %s, errmsg : %s", pwm_dev, errmsg);
106                 return -ENXIO;
107         }
108
109         len = snprintf(pwm_buf, sizeof(pwm_buf), "%d", period);
110         status = write(fd, pwm_buf, len);
111         if (status < 0) {
112                 close(fd);
113                 _E("Failed to set period, path : %s", pwm_dev);
114                 return -EIO;
115         }
116         close(fd);
117
118         return 0;
119 }
120
121 int pwm_get_period(int chip, int pin, int *period)
122 {
123         int fd, result, status;
124         char pwm_buf[PWM_BUF_MAX] = {0};
125         char pwm_dev[PATH_BUF_MAX] = {0};
126
127         snprintf(pwm_dev, PATH_BUF_MAX, SYSFS_PWM_PATH "/pwmchip%d/pwm%d/period", chip, pin);
128         fd = open(pwm_dev, O_RDONLY);
129         if (fd < 0) {
130                 char errmsg[MAX_ERR_LEN];
131                 strerror_r(errno, errmsg, MAX_ERR_LEN);
132                 _E("Can't Open %s, errmsg : %s", pwm_dev, errmsg);
133                 return -ENXIO;
134         }
135
136         status = read(fd, pwm_buf, PWM_BUF_MAX);
137         if (status < 0) {
138                 close(fd);
139                 _E("Failed to get period, path : %s", pwm_dev);
140                 return -EIO;
141         }
142         result = atoi(pwm_buf);
143         *period = result;
144         close(fd);
145
146         return 0;
147 }
148
149 int pwm_set_duty_cycle(int chip, int pin, int duty_cycle)
150 {
151         int fd, len, status;
152         char pwm_buf[PWM_BUF_MAX] = {0};
153         char pwm_dev[PATH_BUF_MAX] = {0};
154
155         _D("chip : %d, pin : %d, duty_cycle : %d", chip, pin, duty_cycle);
156
157         snprintf(pwm_dev, PATH_BUF_MAX, SYSFS_PWM_PATH "/pwmchip%d/pwm%d/duty_cycle", chip, pin);
158         fd = open(pwm_dev, O_WRONLY);
159         if (fd < 0) {
160                 char errmsg[MAX_ERR_LEN];
161                 strerror_r(errno, errmsg, MAX_ERR_LEN);
162                 _E("Can't Open %s, errmsg : %s", pwm_dev, errmsg);
163                 return -ENXIO;
164         }
165
166         len = snprintf(pwm_buf, sizeof(pwm_buf), "%d", duty_cycle);
167         status = write(fd, pwm_buf, len);
168         if (status < 0) {
169                 close(fd);
170                 _E("Failed to set duty cycle, path : %s", pwm_dev);
171                 return -EIO;
172         }
173         close(fd);
174
175         return 0;
176 }
177
178 int pwm_get_duty_cycle(int chip, int pin, int *duty_cycle)
179 {
180         int fd, result, status;
181         char pwm_buf[PWM_BUF_MAX] = {0};
182         char pwm_dev[PATH_BUF_MAX] = {0};
183
184         snprintf(pwm_dev, PATH_BUF_MAX, SYSFS_PWM_PATH "/pwmchip%d/pwm%d/duty_cycle", chip, pin);
185         fd = open(pwm_dev, O_RDONLY);
186         if (fd < 0) {
187                 char errmsg[MAX_ERR_LEN];
188                 strerror_r(errno, errmsg, MAX_ERR_LEN);
189                 _E("Can't Open %s, errmsg : %s", pwm_dev, errmsg);
190                 return -ENXIO;
191         }
192
193         status = read(fd, pwm_buf, PWM_BUF_MAX);
194         if (status < 0) {
195                 close(fd);
196                 _E("Failed to get duty cycle, path : %s", pwm_dev);
197                 return -EIO;
198         }
199         result = atoi(pwm_buf);
200         *duty_cycle = result;
201         close(fd);
202
203         return 0;
204 }
205
206 int pwm_set_polarity(int chip, int pin, pwm_polarity_e polarity)
207 {
208         int fd, status;
209         char pwm_dev[PATH_BUF_MAX] = {0};
210
211         _D("chip : %d, pin : %d, polarity : %d", chip, pin, polarity);
212
213         snprintf(pwm_dev, PATH_BUF_MAX, SYSFS_PWM_PATH "/pwmchip%d/pwm%d/polarity", chip, pin);
214         fd = open(pwm_dev, O_WRONLY);
215         if (fd < 0) {
216                 char errmsg[MAX_ERR_LEN];
217                 strerror_r(errno, errmsg, MAX_ERR_LEN);
218                 _E("Can't Open %s, errmsg : %s", pwm_dev, errmsg);
219                 return -ENXIO;
220         }
221
222         if (polarity == PWM_POLARITY_NORMAL)
223                 status = write(fd, "normal", strlen("normal")+1);
224         else if (polarity == PWM_POLARITY_INVERSED)
225                 status = write(fd, "inversed", strlen("inversed")+1);
226         else {
227                 _E("Invalid pwm polarity : %d", polarity);
228                 close(fd);
229                 return -EINVAL;
230         }
231
232         if (status <= 0) {
233                 close(fd);
234                 _E("Failed to set polarity, path : %s", pwm_dev);
235                 return -EIO;
236         }
237         close(fd);
238
239         return 0;
240 }
241
242 int pwm_get_polarity(int chip, int pin, pwm_polarity_e *polarity)
243 {
244         int fd, status;
245         char pwm_buf[PWM_BUF_MAX] = {0};
246         char pwm_dev[PATH_BUF_MAX] = {0};
247
248         snprintf(pwm_dev, PATH_BUF_MAX, SYSFS_PWM_PATH "/pwmchip%d/pwm%d/polarity", chip, pin);
249         fd = open(pwm_dev, O_RDONLY);
250         if (fd < 0) {
251                 char errmsg[MAX_ERR_LEN];
252                 strerror_r(errno, errmsg, MAX_ERR_LEN);
253                 _E("Can't Open %s, errmsg : %s", pwm_dev, errmsg);
254                 return -ENXIO;
255         }
256
257         status = read(fd, pwm_buf, PWM_BUF_MAX);
258         if (status < 0) {
259                 _E("Failed to get polarity, path : %s", pwm_dev);
260                 close(fd);
261                 return -EIO;
262         }
263
264         if (0 == strncmp(pwm_buf, "normal", strlen("normal")))
265                 *polarity = PWM_POLARITY_NORMAL;
266         else if (0 == strncmp(pwm_buf, "inversed", strlen("inversed")))
267                 *polarity = PWM_POLARITY_INVERSED;
268         else {
269                 close(fd);
270                 _E("Invalid pwm polarity : %d", pwm_buf);
271                 return -EIO;
272         }
273         close(fd);
274
275         return 0;
276 }
277
278 int pwm_set_enable(int chip, int pin, bool enable)
279 {
280         int fd, len, status;
281         char pwm_buf[PWM_BUF_MAX] = {0};
282         char pwm_dev[PATH_BUF_MAX] = {0};
283
284         _D("chip : %d, pin : %d, enable : %d", chip, pin, enable);
285
286         snprintf(pwm_dev, PATH_BUF_MAX, SYSFS_PWM_PATH "/pwmchip%d/pwm%d/enable", chip, pin);
287         fd = open(pwm_dev, O_WRONLY);
288         if (fd < 0) {
289                 char errmsg[MAX_ERR_LEN];
290                 strerror_r(errno, errmsg, MAX_ERR_LEN);
291                 _E("Can't Open %s, errmsg : %s", pwm_dev, errmsg);
292                 return -ENXIO;
293         }
294
295         len = snprintf(pwm_buf, sizeof(pwm_buf), "%d", enable);
296         status = write(fd, pwm_buf, len);
297         if (status < 0) {
298                 close(fd);
299                 _E("Failed to set enable, path : %s", pwm_dev);
300                 return -EIO;
301         }
302         close(fd);
303
304         return 0;
305 }
306
307 int pwm_get_enable(int chip, int pin, bool *enable)
308 {
309         int fd, result, status;
310         char pwm_buf[PWM_BUF_MAX] = {0};
311         char pwm_dev[PATH_BUF_MAX] = {0};
312
313         snprintf(pwm_dev, PATH_BUF_MAX, SYSFS_PWM_PATH "/pwmchip%d/pwm%d/enable", chip, pin);
314         fd = open(pwm_dev, O_RDONLY);
315         if (fd < 0) {
316                 char errmsg[MAX_ERR_LEN];
317                 strerror_r(errno, errmsg, MAX_ERR_LEN);
318                 _E("Can't Open %s, errmsg : %s", pwm_dev, errmsg);
319                 return -ENXIO;
320         }
321
322         status = read(fd, pwm_buf, PWM_BUF_MAX);
323         if (status < 0) {
324                 close(fd);
325                 _E("Failed to get enable, path : %s", pwm_dev);
326                 return -EIO;
327         }
328         result = atoi(pwm_buf);
329         *enable = !!result;
330         close(fd);
331
332         return 0;
333 }
334