f3929cb9f74a63491155d75499b2da70b65027fc
[platform/core/system/peripheral-bus.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
24 #include "pwm.h"
25 #include "peripheral_common.h"
26
27 #define SYSFS_PWM_PATH  "/sys/class/pwm"
28
29 #define PATH_BUF_MAX    64
30 #define PWM_BUF_MAX     16
31 #define MAX_ERR_LEN     255
32
33 int pwm_open(int device, int channel)
34 {
35         int fd, len, status;
36         char pwm_dev[PATH_BUF_MAX] = {0};
37         char pwm_buf[PWM_BUF_MAX] = {0};
38
39         snprintf(pwm_dev, PATH_BUF_MAX, SYSFS_PWM_PATH "/pwmchip%d/export", device);
40         fd = open(pwm_dev, O_WRONLY);
41         if (fd < 0) {
42                 char errmsg[MAX_ERR_LEN];
43                 strerror_r(errno, errmsg, MAX_ERR_LEN);
44                 _E("Can't Open %s, errmsg : %s", pwm_dev, errmsg);
45                 return -ENODEV;
46         }
47
48         len = snprintf(pwm_buf, sizeof(pwm_buf), "%d", channel);
49         status = write(fd, pwm_buf, len);
50         if (status < 0) {
51                 _E("Failed to export pwmchip%d, pwm%", device, channel);
52                 close(fd);
53                 return -EIO;
54         }
55         close(fd);
56
57         return 0;
58 }
59
60 int pwm_close(int device, int channel)
61 {
62         int fd, len, status;
63         char pwm_dev[PATH_BUF_MAX] = {0};
64         char pwm_buf[PWM_BUF_MAX] = {0};
65
66         snprintf(pwm_dev, PATH_BUF_MAX, SYSFS_PWM_PATH "/pwmchip%d/unexport", device);
67         fd = open(pwm_dev, O_WRONLY);
68         if (fd < 0) {
69                 char errmsg[MAX_ERR_LEN];
70                 strerror_r(errno, errmsg, MAX_ERR_LEN);
71                 _E("Can't Open %s, errmsg : %s", pwm_dev, errmsg);
72                 return -ENODEV;
73         }
74
75         len = snprintf(pwm_buf, sizeof(pwm_buf), "%d", channel);
76         status = write(fd, pwm_buf, len);
77         if (status < 0) {
78                 _E("Failed to unexport pwmchip%d, pwm%", device, channel);
79                 close(fd);
80                 return -EIO;
81         }
82         close(fd);
83
84         return 0;
85 }
86
87 int pwm_set_period(int device, int channel, int period)
88 {
89         int fd, len, status;
90         char pwm_buf[PWM_BUF_MAX] = {0};
91         char pwm_dev[PATH_BUF_MAX] = {0};
92
93         _D("Set period : %d, device : %d, channel : %d", period, device, channel);
94         snprintf(pwm_dev, PATH_BUF_MAX, SYSFS_PWM_PATH "/pwmchip%d/pwm%d/period", device, channel);
95         fd = open(pwm_dev, O_WRONLY);
96         if (fd < 0) {
97                 char errmsg[MAX_ERR_LEN];
98                 strerror_r(errno, errmsg, MAX_ERR_LEN);
99                 _E("Can't Open %s, errmsg : %s", pwm_dev, errmsg);
100                 return -ENODEV;
101         }
102
103         len = snprintf(pwm_buf, sizeof(pwm_buf), "%d", period);
104         status = write(fd, pwm_buf, len);
105         if (status < 0) {
106                 close(fd);
107                 _E("Failed to set period, path : %s", pwm_dev);
108                 return -EIO;
109         }
110         close(fd);
111
112         return 0;
113 }
114
115 int pwm_get_period(int device, int channel, int *period)
116 {
117         int fd, result, status;
118         char pwm_buf[PWM_BUF_MAX] = {0};
119         char pwm_dev[PATH_BUF_MAX] = {0};
120
121         snprintf(pwm_dev, PATH_BUF_MAX, SYSFS_PWM_PATH "/pwmchip%d/pwm%d/period", device, channel);
122         fd = open(pwm_dev, O_RDONLY);
123         if (fd < 0) {
124                 char errmsg[MAX_ERR_LEN];
125                 strerror_r(errno, errmsg, MAX_ERR_LEN);
126                 _E("Can't Open %s, errmsg : %s", pwm_dev, errmsg);
127                 return -ENODEV;
128         }
129
130         status = read(fd, pwm_buf, PWM_BUF_MAX);
131         if (status < 0) {
132                 close(fd);
133                 _E("Failed to get period, path : %s", pwm_dev);
134                 return -EIO;
135         }
136         result = atoi(pwm_buf);
137         *period = result;
138         close(fd);
139
140         return 0;
141 }
142
143 int pwm_set_duty_cycle(int device, int channel, int duty_cycle)
144 {
145         int fd, len, status;
146         char pwm_buf[PWM_BUF_MAX] = {0};
147         char pwm_dev[PATH_BUF_MAX] = {0};
148
149         _D("Set duty_cycle : %d, device : %d, channel : %d", duty_cycle, device, channel);
150         snprintf(pwm_dev, PATH_BUF_MAX, SYSFS_PWM_PATH "/pwmchip%d/pwm%d/duty_cycle", device, channel);
151         fd = open(pwm_dev, O_WRONLY);
152         if (fd < 0) {
153                 char errmsg[MAX_ERR_LEN];
154                 strerror_r(errno, errmsg, MAX_ERR_LEN);
155                 _E("Can't Open %s, errmsg : %s", pwm_dev, errmsg);
156                 return -ENODEV;
157         }
158
159         len = snprintf(pwm_buf, sizeof(pwm_buf), "%d", duty_cycle);
160         status = write(fd, pwm_buf, len);
161         if (status < 0) {
162                 close(fd);
163                 _E("Failed to set duty cycle, path : %s", pwm_dev);
164                 return -EIO;
165         }
166         close(fd);
167
168         return 0;
169 }
170
171 int pwm_get_duty_cycle(int device, int channel, int *duty_cycle)
172 {
173         int fd, result, status;
174         char pwm_buf[PWM_BUF_MAX] = {0};
175         char pwm_dev[PATH_BUF_MAX] = {0};
176
177         snprintf(pwm_dev, PATH_BUF_MAX, SYSFS_PWM_PATH "/pwmchip%d/pwm%d/duty_cycle", device, channel);
178         fd = open(pwm_dev, O_RDONLY);
179         if (fd < 0) {
180                 char errmsg[MAX_ERR_LEN];
181                 strerror_r(errno, errmsg, MAX_ERR_LEN);
182                 _E("Can't Open %s, errmsg : %s", pwm_dev, errmsg);
183                 return -ENODEV;
184         }
185
186         status = read(fd, pwm_buf, PWM_BUF_MAX);
187         if (status < 0) {
188                 close(fd);
189                 _E("Failed to get duty cycle, path : %s", pwm_dev);
190                 return -EIO;
191         }
192         result = atoi(pwm_buf);
193         *duty_cycle = result;
194         close(fd);
195
196         return 0;
197 }
198
199 int pwm_set_polarity(int device, int channel, pwm_polarity_e polarity)
200 {
201         int fd, status;
202         char pwm_dev[PATH_BUF_MAX] = {0};
203
204         _D("Set polarity : %d, device : %d, channel : %d", polarity, device, channel);
205         snprintf(pwm_dev, PATH_BUF_MAX, SYSFS_PWM_PATH "/pwmchip%d/pwm%d/polarity", device, channel);
206         fd = open(pwm_dev, O_WRONLY);
207         if (fd < 0) {
208                 char errmsg[MAX_ERR_LEN];
209                 strerror_r(errno, errmsg, MAX_ERR_LEN);
210                 _E("Can't Open %s, errmsg : %s", pwm_dev, errmsg);
211                 return -ENODEV;
212         }
213
214         if (polarity == PWM_POLARITY_NORMAL)
215                 status = write(fd, "normal", strlen("normal")+1);
216         else if (polarity == PWM_POLARITY_INVERSED)
217                 status = write(fd, "inversed", strlen("inversed")+1);
218         else {
219                 _E("Invalid pwm polarity : %d", polarity);
220                 close(fd);
221                 return -EINVAL;
222         }
223
224         if (status <= 0) {
225                 close(fd);
226                 _E("Failed to set polarity, path : %s", pwm_dev);
227                 return -EIO;
228         }
229         close(fd);
230
231         return 0;
232 }
233
234 int pwm_get_polarity(int device, int channel, pwm_polarity_e *polarity)
235 {
236         int fd, status;
237         char pwm_buf[PWM_BUF_MAX] = {0};
238         char pwm_dev[PATH_BUF_MAX] = {0};
239
240         snprintf(pwm_dev, PATH_BUF_MAX, SYSFS_PWM_PATH "/pwmchip%d/pwm%d/polarity", device, channel);
241         fd = open(pwm_dev, O_RDONLY);
242         if (fd < 0) {
243                 char errmsg[MAX_ERR_LEN];
244                 strerror_r(errno, errmsg, MAX_ERR_LEN);
245                 _E("Can't Open %s, errmsg : %s", pwm_dev, errmsg);
246                 return -ENODEV;
247         }
248
249         status = read(fd, pwm_buf, PWM_BUF_MAX);
250         if (status < 0) {
251                 _E("Failed to get polarity, path : %s", pwm_dev);
252                 close(fd);
253                 return -EIO;
254         }
255
256         if (0 == strncmp(pwm_buf, "normal", strlen("normal")))
257                 *polarity = PWM_POLARITY_NORMAL;
258         else if (0 == strncmp(pwm_buf, "inversed", strlen("inversed")))
259                 *polarity = PWM_POLARITY_INVERSED;
260         else {
261                 close(fd);
262                 _E("Invalid pwm polarity : %d", pwm_buf);
263                 return -EIO;
264         }
265         close(fd);
266
267         return 0;
268 }
269
270 int pwm_set_enable(int device, int channel, int enable)
271 {
272         int fd, len, status;
273         char pwm_buf[PWM_BUF_MAX] = {0};
274         char pwm_dev[PATH_BUF_MAX] = {0};
275
276         _D("Set enable : %d, device : %d, channel : %d", enable, device, channel);
277         snprintf(pwm_dev, PATH_BUF_MAX, SYSFS_PWM_PATH "/pwmchip%d/pwm%d/enable", device, channel);
278         fd = open(pwm_dev, O_WRONLY);
279         if (fd < 0) {
280                 char errmsg[MAX_ERR_LEN];
281                 strerror_r(errno, errmsg, MAX_ERR_LEN);
282                 _E("Can't Open %s, errmsg : %s", pwm_dev, errmsg);
283                 return -ENODEV;
284         }
285
286         len = snprintf(pwm_buf, sizeof(pwm_buf), "%d", enable);
287         status = write(fd, pwm_buf, len);
288         if (status < 0) {
289                 close(fd);
290                 _E("Failed to set enable, path : %s", pwm_dev);
291                 return -EIO;
292         }
293         close(fd);
294
295         return 0;
296 }
297
298 int pwm_get_enable(int device, int channel, int *enable)
299 {
300         int fd, result, status;
301         char pwm_buf[PWM_BUF_MAX] = {0};
302         char pwm_dev[PATH_BUF_MAX] = {0};
303
304         snprintf(pwm_dev, PATH_BUF_MAX, SYSFS_PWM_PATH "/pwmchip%d/pwm%d/enable", device, channel);
305         fd = open(pwm_dev, O_RDONLY);
306         if (fd < 0) {
307                 char errmsg[MAX_ERR_LEN];
308                 strerror_r(errno, errmsg, MAX_ERR_LEN);
309                 _E("Can't Open %s, errmsg : %s", pwm_dev, errmsg);
310                 return -ENODEV;
311         }
312
313         status = read(fd, pwm_buf, PWM_BUF_MAX);
314         if (status < 0) {
315                 close(fd);
316                 _E("Failed to get enable, path : %s", pwm_dev);
317                 return -EIO;
318         }
319         result = atoi(pwm_buf);
320         enable = &result;
321         close(fd);
322
323         return 0;
324 }
325