pwm: replace gdbus with direct implementation 52/260352/7
authorAdrian Szyndela <adrian.s@samsung.com>
Wed, 23 Jun 2021 14:28:02 +0000 (16:28 +0200)
committerAdrian Szyndela <adrian.s@samsung.com>
Fri, 25 Jun 2021 14:55:32 +0000 (16:55 +0200)
Move open/close code from peripheral-bus.
Add flocks() where appropriate.

Change-Id: If2554f2d30389836eb39794dffaf9e34df31176a

CMakeLists.txt
include/gdbus/peripheral_gdbus_pwm.h [deleted file]
include/peripheral_handle.h
src/gdbus/peripheral_gdbus_pwm.c [deleted file]
src/peripheral_pwm.c

index fbd65b5..34b4bab 100644 (file)
@@ -61,7 +61,6 @@ SET(SOURCES src/peripheral_gpio.c
                        src/peripheral_uart.c
                        src/peripheral_spi.c
                        src/interface/peripheral_interface_pwm.c
-                       src/gdbus/peripheral_gdbus_pwm.c
                        src/gdbus/peripheral_io_gdbus.c)
 
 ADD_LIBRARY(${fw_name} SHARED ${SOURCES})
diff --git a/include/gdbus/peripheral_gdbus_pwm.h b/include/gdbus/peripheral_gdbus_pwm.h
deleted file mode 100644 (file)
index 70a4b02..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (c) 2016-2017 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef __PERIPHERAL_GDBUS_PWM_H__
-#define __PERIPHERAL_GDBUS_PWM_H__
-
-#include "peripheral_gdbus_common.h"
-
-int peripheral_gdbus_pwm_open(peripheral_pwm_h pwm, int chip, int pin);
-int peripheral_gdbus_pwm_close(peripheral_pwm_h pwm);
-
-#endif /* __PERIPHERAL_GDBUS_PWM_H__ */
index e7fb06f..4585021 100644 (file)
@@ -61,7 +61,8 @@ struct _peripheral_i2c_s {
  * @brief Internal struct for pwm context
  */
 struct _peripheral_pwm_s {
-       uint handle;
+       int chip;
+       int pin;
        int fd_period;
        int fd_duty_cycle;
        int fd_polarity;
diff --git a/src/gdbus/peripheral_gdbus_pwm.c b/src/gdbus/peripheral_gdbus_pwm.c
deleted file mode 100644 (file)
index 74fae2c..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright (c) 2016-2017 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "peripheral_gdbus_pwm.h"
-
-#define PWM_FD_INDEX_PERIOD      0
-#define PWM_FD_INDEX_DUTY_CYCLE  1
-#define PWM_FD_INDEX_POLARITY    2
-#define PWM_FD_INDEX_ENABLE      3
-
-static PeripheralIoGdbusPwm *pwm_proxy = NULL;
-
-static int __pwm_proxy_init(void)
-{
-       GError *error = NULL;
-
-       if (pwm_proxy != NULL) {
-               _E("Pwm proxy is already created");
-               g_object_ref(pwm_proxy);
-               return PERIPHERAL_ERROR_NONE;
-       }
-
-       pwm_proxy = peripheral_io_gdbus_pwm_proxy_new_for_bus_sync(
-               G_BUS_TYPE_SYSTEM,
-               G_DBUS_PROXY_FLAGS_NONE,
-               PERIPHERAL_GDBUS_NAME,
-               PERIPHERAL_GDBUS_PWM_PATH,
-               NULL,
-               &error);
-
-       if (pwm_proxy == NULL) {
-               if (error) {
-                       _E("Failed to create pwm proxy : %s", error->message);
-                       g_error_free(error);
-               }
-               return PERIPHERAL_ERROR_IO_ERROR;
-       }
-
-       return PERIPHERAL_ERROR_NONE;
-}
-
-static int __pwm_proxy_deinit(void)
-{
-       RETVM_IF(pwm_proxy == NULL, PERIPHERAL_ERROR_IO_ERROR, "Pwm proxy is NULL");
-
-       g_object_unref(pwm_proxy);
-       if (!G_IS_OBJECT(pwm_proxy))
-               pwm_proxy = NULL;
-
-       return PERIPHERAL_ERROR_NONE;
-}
-
-int peripheral_gdbus_pwm_open(peripheral_pwm_h pwm, int chip, int pin)
-{
-       int ret;
-       GError *error = NULL;
-       GUnixFDList *fd_list = NULL;
-
-       ret = __pwm_proxy_init();
-       if (ret != PERIPHERAL_ERROR_NONE)
-               return ret;
-
-       if (peripheral_io_gdbus_pwm_call_open_sync(
-                       pwm_proxy,
-                       chip,
-                       pin,
-                       NULL,
-                       &pwm->handle,
-                       &ret,
-                       &fd_list,
-                       NULL,
-                       &error) == FALSE) {
-               _E("Failed to request daemon to pwm open : %s", error->message);
-               g_error_free(error);
-               return PERIPHERAL_ERROR_IO_ERROR;
-       }
-
-       // TODO : If ret is not PERIPHERAL_ERROR_NONE, fd list it NULL from daemon.
-       if (ret != PERIPHERAL_ERROR_NONE)
-               return ret;
-
-       pwm->fd_period = g_unix_fd_list_get(fd_list, PWM_FD_INDEX_PERIOD, &error);
-       if (pwm->fd_period < 0) {
-               _E("Failed to get fd for pwm period : %s", error->message);
-               g_error_free(error);
-               ret = PERIPHERAL_ERROR_IO_ERROR;
-       }
-
-       pwm->fd_duty_cycle = g_unix_fd_list_get(fd_list, PWM_FD_INDEX_DUTY_CYCLE, &error);
-       if (pwm->fd_duty_cycle < 0) {
-               _E("Failed to get fd for pwm duty cycle : %s", error->message);
-               g_error_free(error);
-               ret = PERIPHERAL_ERROR_IO_ERROR;
-       }
-
-       pwm->fd_polarity = g_unix_fd_list_get(fd_list, PWM_FD_INDEX_POLARITY, &error);
-       if (pwm->fd_polarity < 0) {
-               _E("Failed to get fd for pwm polarity : %s", error->message);
-               g_error_free(error);
-               ret = PERIPHERAL_ERROR_IO_ERROR;
-       }
-
-       pwm->fd_enable = g_unix_fd_list_get(fd_list, PWM_FD_INDEX_ENABLE, &error);
-       if (pwm->fd_enable < 0) {
-               _E("Failed to get fd for pwm enable : %s", error->message);
-               g_error_free(error);
-               ret = PERIPHERAL_ERROR_IO_ERROR;
-       }
-
-       g_object_unref(fd_list);
-
-       return ret;
-}
-
-int peripheral_gdbus_pwm_close(peripheral_pwm_h pwm)
-{
-       RETVM_IF(pwm_proxy == NULL, PERIPHERAL_ERROR_IO_ERROR, "Pwm proxy is NULL");
-
-       int ret;
-       GError *error = NULL;
-
-       if (peripheral_io_gdbus_pwm_call_close_sync(
-                       pwm_proxy,
-                       pwm->handle,
-                       &ret,
-                       NULL,
-                       &error) == FALSE) {
-               _E("Failed to request daemon to gpio pwm : %s", error->message);
-               g_error_free(error);
-               return PERIPHERAL_ERROR_IO_ERROR;
-       }
-
-       __pwm_proxy_deinit();
-
-       return ret;
-}
index d6a306a..51b447c 100644 (file)
  * limitations under the License.
  */
 
+#include <libudev.h>
+#include <poll.h>
 #include <stdlib.h>
+#include <sys/file.h>
 #include <system_info.h>
 
 #include "peripheral_io.h"
-#include "peripheral_handle.h"
-#include "peripheral_gdbus_pwm.h"
-#include "peripheral_interface_pwm.h"
+#include "peripheral_interface_common.h"
 #include "peripheral_log.h"
 
 #define PERIPHERAL_IO_PWM_FEATURE "http://tizen.org/feature/peripheral_io.pwm"
@@ -29,6 +30,8 @@
 #define PWM_FEATURE_FALSE    0
 #define PWM_FEATURE_TRUE     1
 
+#define PWM_BUF_MAX 16
+
 static int pwm_feature = PWM_FEATURE_UNKNOWN;
 
 static bool __is_feature_supported(void)
@@ -46,16 +49,248 @@ static bool __is_feature_supported(void)
        return (pwm_feature == PWM_FEATURE_TRUE ? true : false);
 }
 
+static int __pwm_create_udev_monitor(struct udev **udev, struct udev_monitor **monitor)
+{
+       struct udev *_udev = NULL;
+       struct udev_monitor *_monitor = NULL;
+       int ret = -EIO;
+
+       _udev = udev_new();
+       if (!_udev) {
+               _E("Cannot create udev");
+               goto error;
+       }
+
+       _monitor = udev_monitor_new_from_netlink(_udev, "udev");
+       if (!_monitor) {
+               _E("Cannot create udev monitor");
+               goto error;
+       }
+
+       ret = udev_monitor_filter_add_match_subsystem_devtype(_monitor, "pwm", NULL);
+       if (ret < 0) {
+               _E("Failed to add monitor filter");
+               goto error;
+       }
+
+       ret = udev_monitor_enable_receiving(_monitor);
+       if (ret < 0) {
+               _E("Failed to enable udev receiving");
+               goto error;
+       }
+
+       *udev = _udev;
+       *monitor = _monitor;
+
+       return 0;
+
+error:
+       udev_monitor_unref(_monitor);
+       udev_unref(_udev);
+       return ret;
+}
+
+static int __pwm_wait_for_udev(struct udev_monitor *monitor, int chip, int pin)
+{
+       struct udev_device *dev = NULL;
+       struct pollfd pfd;
+#define PWMCHIP_BASE "pwmchip"
+       char pwmchip_name[sizeof(PWMCHIP_BASE "1234567890")]; /* space for pwmchip%d */
+#define PWM_BASE "pwm"
+       char pwm_name[sizeof(PWM_BASE "1234567890")]; /* space for pwm%d */
+
+       pfd.fd = udev_monitor_get_fd(monitor);
+       pfd.events = POLLIN;
+
+       snprintf(pwmchip_name, sizeof pwmchip_name, PWMCHIP_BASE "%d", chip);
+       snprintf(pwm_name, sizeof pwm_name, PWM_BASE "%d", pin);
+
+       for (int cnt = 0; cnt < 10; cnt++) {
+               _D("poll iteration");
+               if (poll(&pfd, 1, 100) < 0) {
+                       _E("Failed to watch udev monitor");
+                       return -EIO;
+               }
+
+               dev = udev_monitor_receive_device(monitor);
+               if (dev) {
+                       if (strcmp(udev_device_get_sysname(dev), pwmchip_name) == 0) {
+                               const char *prop = udev_device_get_property_value(dev, "EXPORT");
+                               if (prop && strcmp(prop, pwm_name) == 0) {
+                                       _D("udev for %s is initialized", pwm_name);
+                                       udev_device_unref(dev);
+                                       return 0;
+                               }
+                       }
+                       udev_device_unref(dev);
+               }
+       }
+       _E("Time out");
+
+       return 0;
+}
+
+static int peripheral_pwm_export(int chip, int pin)
+{
+       RETVM_IF(chip < 0, PERIPHERAL_ERROR_INVALID_PARAMETER, "Invalid pwm chip");
+       RETVM_IF(pin < 0, PERIPHERAL_ERROR_INVALID_PARAMETER, "Invalid pwm pin");
+
+       int ret;
+       int fd = -1;
+       int length;
+#define EXPORT_PATH(chip) ("/sys/class/pwm/pwmchip" chip "/export")
+       char path[sizeof EXPORT_PATH("1234567890")] = {0, }; /* space for /sys/class/pwm/pwmchip%d/export */
+       char buf[sizeof "1234567890"] = {0, }; /* space for pin %d */
+       struct udev *udev = NULL;
+       struct udev_monitor *monitor = NULL;
+
+       ret = __pwm_create_udev_monitor(&udev, &monitor);
+       if (ret != 0) {
+               _E("Failed to create udev monitor");
+               goto out;
+       };
+
+       snprintf(path, sizeof path, EXPORT_PATH("%d"), chip);
+       fd = open(path, O_WRONLY | O_CLOEXEC);
+       if (fd < 0) {
+               _E("open() failed: %m");
+               ret = PERIPHERAL_ERROR_IO_ERROR;
+               goto out;
+       }
+
+       length = snprintf(buf, sizeof buf, "%d", pin);
+       ret = write(fd, buf, length);
+       if (ret != length) {
+               _E("write() failed: %m");
+               ret = PERIPHERAL_ERROR_IO_ERROR;
+               goto out;
+       }
+
+       ret = close(fd);
+       if (ret != 0) {
+               _E("close() failed: %m");
+               ret = PERIPHERAL_ERROR_IO_ERROR;
+               goto out;
+       } else {
+               fd = -1;
+       }
+
+       ret = __pwm_wait_for_udev(monitor, chip, pin);
+       if (ret < 0) {
+               _E("device nodes are not writable");
+               ret = PERIPHERAL_ERROR_IO_ERROR;
+               goto out;
+       }
+
+out:
+       if (fd != -1)
+               close(fd);
+
+       udev_monitor_unref(monitor);
+       udev_unref(udev);
+
+       return ret;
+}
+
+static inline void close_fd(int fd) {
+       if (fd != -1)
+               close(fd);
+}
+
+static int peripheral_pwm_lock_export(int chip)
+{
+       char path[sizeof EXPORT_PATH("1234567890")] = {0, }; /* space for /sys/class/pwm/pwmchip%d/export */
+       snprintf(path, sizeof path, EXPORT_PATH("%d"), chip);
+
+       int fd = open(path, O_WRONLY | O_CLOEXEC);
+       if (fd < 0)
+               return -1;
+
+       if (flock(fd, LOCK_EX)) {
+               close(fd);
+               fd = -1;
+       }
+
+       return fd;
+}
+
+static int peripheral_pwm_unlock_export(int lock)
+{
+       close_fd(lock);
+       return -1;
+}
+
+static void peripheral_pwm_unlock_exportp(int *lock)
+{
+       peripheral_pwm_unlock_export(*lock);
+}
+
+static inline int cleanup_handle(peripheral_pwm_h handle)
+{
+       if (handle == NULL)
+               return PERIPHERAL_ERROR_NONE;
+
+       int pin = handle->pin;
+       int chip = handle->chip;
+       __attribute__ ((cleanup(peripheral_pwm_unlock_exportp))) int lock = peripheral_pwm_lock_export(chip);
+
+       close_fd(handle->fd_duty_cycle);
+       close_fd(handle->fd_polarity);
+       close_fd(handle->fd_enable);
+       close_fd(handle->fd_period);            /* this releases chip+pin flock() */
+       free(handle);
+
+       if (pin <0)
+               return PERIPHERAL_ERROR_NONE;
+
+       char buf[sizeof "1234567890"] = {0, }; /* space for pin %d */
+#define UNEXPORT_PATH(chip) ("/sys/class/pwm/pwmchip" chip "/unexport")
+       char path[sizeof UNEXPORT_PATH("1234567890")] = {0, }; /* space for /sys/class/pwm/pwmchip%d/unexport */
+       snprintf(path, sizeof path, UNEXPORT_PATH("%d"), chip);
+
+       int fd = open(path, O_WRONLY | O_CLOEXEC);
+       if (fd < 0) {
+               _E("pwm: unexport pin %d: open() failed: %m", pin);
+               return PERIPHERAL_ERROR_IO_ERROR;
+       }
+
+       int length = snprintf(buf, sizeof(buf), "%d", pin);
+       int ret = write(fd, buf, length);
+
+       close(fd);
+
+       if (ret != length) {
+               _E("pwm: unexport pin %d: write() failed: %m", pin);
+               return PERIPHERAL_ERROR_IO_ERROR;
+       }
+
+       return PERIPHERAL_ERROR_NONE;
+}
+
+static inline void cleanup_handlep(peripheral_pwm_h *handle)
+{
+       cleanup_handle(*handle);
+}
 
 int peripheral_pwm_open(int chip, int pin, peripheral_pwm_h *pwm)
 {
-       peripheral_pwm_h handle;
        int ret = PERIPHERAL_ERROR_NONE;
 
        RETVM_IF(__is_feature_supported() == false, PERIPHERAL_ERROR_NOT_SUPPORTED, "PWM feature is not supported");
        RETVM_IF(pwm == NULL, PERIPHERAL_ERROR_INVALID_PARAMETER, "Invalid pwm handle");
        RETVM_IF(chip < 0 || pin < 0, PERIPHERAL_ERROR_INVALID_PARAMETER, "Invalid parameter");
 
+       __attribute__ ((cleanup(peripheral_pwm_unlock_exportp))) int lock = -1;
+       __attribute__ ((cleanup(cleanup_handlep))) peripheral_pwm_h handle = NULL;
+#define PWM_PATH_BASE(chip, pin, file) ("/sys/class/pwm/pwmchip" chip "/pwm" pin "/" file)
+       /* space for /sys/class/pwm/pwmchip%d/pwm%d/duty_cycle
+          which is longer than:
+                    /sys/class/pwm/pwmchip%d/pwm%d/period
+                    /sys/class/pwm/pwmchip%d/pwm%d/polarity
+                    /sys/class/pwm/pwmchip%d/pwm%d/enable
+       */
+       char path[sizeof (PWM_PATH_BASE("1234567890", "1234567890", "duty_cycle"))] = {0, };
+
        /* Initialize */
        handle = (peripheral_pwm_h)calloc(1, sizeof(struct _peripheral_pwm_s));
        if (handle == NULL) {
@@ -63,35 +298,66 @@ int peripheral_pwm_open(int chip, int pin, peripheral_pwm_h *pwm)
                return PERIPHERAL_ERROR_OUT_OF_MEMORY;
        }
 
-       ret = peripheral_gdbus_pwm_open(handle, chip, pin);
+       handle->fd_period = -1;
+       handle->fd_duty_cycle = -1;
+       handle->fd_polarity = -1;
+       handle->fd_enable = -1;
+       handle->chip = -1;
+       handle->pin = -1;
+
+       lock = peripheral_pwm_lock_export(chip);
+       RETVM_IF(lock == -1, PERIPHERAL_ERROR_IO_ERROR, "Failed to lock 'export'");
+
+       ret = peripheral_pwm_export(chip, pin);
        if (ret != PERIPHERAL_ERROR_NONE) {
                _E("Failed to open PWM chip : %d, pin : %d", chip, pin);
                free(handle);
                handle = NULL;
        }
 
+       handle->chip = chip;
+       handle->pin = pin;
+
+       snprintf(path, sizeof path, PWM_PATH_BASE("%d", "%d", "period"), chip, pin);
+       handle->fd_period = open(path, O_RDWR | O_CLOEXEC);
+       CHECK_ERROR(handle->fd_period < 0);
+
+       if (flock(handle->fd_period, LOCK_EX | LOCK_NB)) {
+               if (errno == EWOULDBLOCK) {
+                       _E("pwm: chip %d, pin %d is not available", chip, pin);
+                       return PERIPHERAL_ERROR_RESOURCE_BUSY;
+               } else {
+                       _E("pwm: chip %d, pin %d flock() error: %m", chip, pin);
+                       return PERIPHERAL_ERROR_IO_ERROR;
+               }
+       }
+
+       snprintf(path, sizeof path, PWM_PATH_BASE("%d", "%d", "duty_cycle"), chip, pin);
+       handle->fd_duty_cycle = open(path, O_RDWR | O_CLOEXEC);
+       CHECK_ERROR(handle->fd_duty_cycle < 0);
+
+       snprintf(path, sizeof path, PWM_PATH_BASE("%d", "%d", "polarity"), chip, pin);
+       handle->fd_polarity = open(path, O_RDWR | O_CLOEXEC);
+       CHECK_ERROR(handle->fd_polarity < 0);
+
+       snprintf(path, sizeof path, PWM_PATH_BASE("%d", "%d", "enable"), chip, pin);
+       handle->fd_enable = open(path, O_RDWR | O_CLOEXEC);
+       CHECK_ERROR(handle->fd_enable < 0);
+
+       lock = peripheral_pwm_unlock_export(lock);
+
        *pwm = handle;
+       handle = NULL;
 
        return ret;
 }
 
 int peripheral_pwm_close(peripheral_pwm_h pwm)
 {
-       int ret = PERIPHERAL_ERROR_NONE;
-
        RETVM_IF(__is_feature_supported() == false, PERIPHERAL_ERROR_NOT_SUPPORTED, "PWM feature is not supported");
        RETVM_IF(pwm == NULL, PERIPHERAL_ERROR_INVALID_PARAMETER, "pwm handle is NULL");
 
-       ret = peripheral_gdbus_pwm_close(pwm);
-       if (ret != PERIPHERAL_ERROR_NONE)
-               _E("Failed to close PWM chip, continuing anyway, ret : %d", ret);
-
-       peripheral_interface_pwm_close(pwm);
-
-       free(pwm);
-       pwm = NULL;
-
-       return ret;
+       return cleanup_handle(pwm);
 }
 
 int peripheral_pwm_set_period(peripheral_pwm_h pwm, uint32_t period_ns)
@@ -99,7 +365,15 @@ int peripheral_pwm_set_period(peripheral_pwm_h pwm, uint32_t period_ns)
        RETVM_IF(__is_feature_supported() == false, PERIPHERAL_ERROR_NOT_SUPPORTED, "PWM feature is not supported");
        RETVM_IF(pwm == NULL, PERIPHERAL_ERROR_INVALID_PARAMETER, "pwm handle is NULL");
 
-       return peripheral_interface_pwm_set_period(pwm, period_ns);
+       int ret;
+       int length;
+       char pwm_buf[PWM_BUF_MAX] = {0};
+
+       length = snprintf(pwm_buf, sizeof(pwm_buf), "%d", period_ns);
+       ret = write(pwm->fd_period, pwm_buf, length);
+       CHECK_ERROR(ret != length);
+
+       return PERIPHERAL_ERROR_NONE;
 }
 
 int peripheral_pwm_set_duty_cycle(peripheral_pwm_h pwm, uint32_t duty_cycle_ns)
@@ -107,7 +381,15 @@ int peripheral_pwm_set_duty_cycle(peripheral_pwm_h pwm, uint32_t duty_cycle_ns)
        RETVM_IF(__is_feature_supported() == false, PERIPHERAL_ERROR_NOT_SUPPORTED, "PWM feature is not supported");
        RETVM_IF(pwm == NULL, PERIPHERAL_ERROR_INVALID_PARAMETER, "pwm handle is NULL");
 
-       return peripheral_interface_pwm_set_duty_cycle(pwm, duty_cycle_ns);
+       int ret;
+       int length;
+       char pwm_buf[PWM_BUF_MAX] = {0};
+
+       length = snprintf(pwm_buf, sizeof(pwm_buf), "%d", duty_cycle_ns);
+       ret = write(pwm->fd_duty_cycle, pwm_buf, length);
+       CHECK_ERROR(ret != length);
+
+       return PERIPHERAL_ERROR_NONE;
 }
 
 int peripheral_pwm_set_polarity(peripheral_pwm_h pwm, peripheral_pwm_polarity_e polarity)
@@ -116,7 +398,15 @@ int peripheral_pwm_set_polarity(peripheral_pwm_h pwm, peripheral_pwm_polarity_e
        RETVM_IF(pwm == NULL, PERIPHERAL_ERROR_INVALID_PARAMETER, "pwm handle is NULL");
        RETVM_IF((polarity < PERIPHERAL_PWM_POLARITY_ACTIVE_HIGH) || (polarity > PERIPHERAL_PWM_POLARITY_ACTIVE_LOW), PERIPHERAL_ERROR_INVALID_PARAMETER, "Invalid polarity parameter");
 
-       return peripheral_interface_pwm_set_polarity(pwm, polarity);
+       static predefined_type_s types[2] = {
+               {"normal",   6},
+               {"inversed", 8}
+       };
+
+       int ret = write(pwm->fd_polarity, types[polarity].type, types[polarity].len);
+       CHECK_ERROR(ret != types[polarity].len);
+
+       return PERIPHERAL_ERROR_NONE;
 }
 
 int peripheral_pwm_set_enabled(peripheral_pwm_h pwm, bool enable)
@@ -124,5 +414,13 @@ int peripheral_pwm_set_enabled(peripheral_pwm_h pwm, bool enable)
        RETVM_IF(__is_feature_supported() == false, PERIPHERAL_ERROR_NOT_SUPPORTED, "PWM feature is not supported");
        RETVM_IF(pwm == NULL, PERIPHERAL_ERROR_INVALID_PARAMETER, "pwm handle is NULL");
 
-       return peripheral_interface_pwm_set_enable(pwm, enable);
+       static predefined_type_s types[2] = {
+               {"0", 1},
+               {"1", 1}
+       };
+
+       int ret = write(pwm->fd_enable, types[enable].type, types[enable].len);
+       CHECK_ERROR(ret != types[enable].len);
+
+       return PERIPHERAL_ERROR_NONE;
 }