You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

239 lines
5.8 KiB

/*
* Copyright (c) Hisilicon Technologies Co., Ltd.. 2012-2019. All rights reserved.
* Description: supply the api for userspace application
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include "soc_errno.h"
#include "soc_module.h"
#include "uapi_pwm.h"
#include "drv_ioctl_pwm.h"
#include "soc_log.h"
#define SOC_DEV_PWM_NAME "soc_pwm"
#undef LOG_MODULE_ID
#define LOG_MODULE_ID SOC_ID_PWM
static td_s32 g_pwm_dev_fd = -1;
static const td_char g_pwm_dev_name[] = "/dev/"SOC_DEV_PWM_NAME;
static pthread_mutex_t g_pwm_mutex = PTHREAD_MUTEX_INITIALIZER;
#define PWM_PATH_MAX_LEN 256
#define ext_pwm_lock() (td_void)pthread_mutex_lock(&g_pwm_mutex)
#define ext_pwm_unlock() (td_void)pthread_mutex_unlock(&g_pwm_mutex)
#define pwm_check_init(ret) do { \
ext_pwm_lock(); \
if (g_pwm_dev_fd < 0) { \
soc_log_err("pwm is not init!\n"); \
(ret) = SOC_ERR_PWM_NOT_INIT; \
} \
ext_pwm_unlock(); \
} while (0)
td_s32 uapi_pwm_init(td_void)
{
ext_pwm_lock();
td_char *presolved_path = TD_NULL;
if (g_pwm_dev_fd > 0) {
ext_pwm_unlock();
return TD_SUCCESS;
}
if (strlen(g_pwm_dev_name) > PWM_PATH_MAX_LEN - 1) {
soc_log_err("The g_pwm_dev_name is too long! \n");
ext_pwm_unlock();
return SOC_ERR_PWM_OPEN_ERR;
}
presolved_path = realpath(g_pwm_dev_name, TD_NULL);
if (presolved_path == TD_NULL) {
soc_log_err("pwm dev path is invalid!\n");
ext_pwm_unlock();
return SOC_ERR_PWM_OPEN_ERR;
}
g_pwm_dev_fd = open(presolved_path, O_RDWR | O_NONBLOCK, 0);
if (g_pwm_dev_fd < 0) {
soc_log_err("pwm device open err!\n");
free(presolved_path);
presolved_path = TD_NULL;
ext_pwm_unlock();
return SOC_ERR_PWM_OPEN_ERR;
}
free(presolved_path);
presolved_path = TD_NULL;
ext_pwm_unlock();
return TD_SUCCESS;
}
td_s32 uapi_pwm_deinit(td_void)
{
td_s32 ret;
ext_pwm_lock();
if (g_pwm_dev_fd < 0) {
ext_pwm_unlock();
return TD_SUCCESS;
}
ret = close(g_pwm_dev_fd);
if (ret != TD_SUCCESS) {
soc_log_err("pwm device close err!\n");
ext_pwm_unlock();
return SOC_ERR_PWM_CLOSE_ERR;
}
g_pwm_dev_fd = -1;
ext_pwm_unlock();
return TD_SUCCESS;
}
td_s32 uapi_pwm_get_attr(td_u32 pwm_id, uapi_pwm_attr *pwm_attr)
{
td_s32 ret = 0;
pwm_attr_cmd_para st_cmd_para = {0};
if (pwm_attr == TD_NULL) {
soc_log_err("[get_attr] ERR: invalid param!\n");
return SOC_ERR_PWM_INVALID_PARA;
}
pwm_check_init(ret);
if (ret == SOC_ERR_PWM_NOT_INIT) {
return ret;
}
st_cmd_para.pwm_no = pwm_id;
st_cmd_para.pwm_attr = *(ext_drv_pwm_attr *)(td_void *)pwm_attr;
ret = ioctl(g_pwm_dev_fd, CMD_PWM_GETATTR, &st_cmd_para);
pwm_attr->pwm_frequency = st_cmd_para.pwm_attr.freq;
pwm_attr->pwm_duty_ratio = st_cmd_para.pwm_attr.duty_ratio;
if (ret != TD_SUCCESS) {
soc_log_err("ERR: get pwm_attr err, ret=%#x!\n", ret);
return SOC_ERR_PWM_INVALID_OPT;
}
return TD_SUCCESS;
}
td_s32 uapi_pwm_set_attr(td_u32 pwm_id, const uapi_pwm_attr *pwm_attr)
{
td_s32 ret = 0;
pwm_attr_cmd_para st_cmd_para = {0};
if (pwm_attr == TD_NULL) {
soc_log_err("[set_attr] ERR: invalid param!\n");
return SOC_ERR_PWM_INVALID_PARA;
}
pwm_check_init(ret);
if (ret == SOC_ERR_PWM_NOT_INIT) {
return ret;
}
st_cmd_para.pwm_no = pwm_id;
st_cmd_para.pwm_attr = *(ext_drv_pwm_attr *)(td_void *)pwm_attr;
ret = ioctl(g_pwm_dev_fd, CMD_PWM_SETATTR, &st_cmd_para);
if (ret != TD_SUCCESS) {
soc_log_err("ERR: set pwm_attr err, ret=%#x!\n", ret);
return SOC_ERR_PWM_INVALID_OPT;
}
return TD_SUCCESS;
}
td_s32 uapi_pwm_send_signal(td_u32 pwm_id, td_u32 carrier_time, td_u32 low_level_time)
{
td_s32 ret = 0;
pwm_signal_cmd_para st_cmd_para = {0};
pwm_check_init(ret);
if (ret == SOC_ERR_PWM_NOT_INIT) {
return ret;
}
st_cmd_para.pwm_no = pwm_id;
st_cmd_para.carrier_sig_duration_us = carrier_time;
st_cmd_para.low_level_sig_duration_us = low_level_time;
ret = ioctl(g_pwm_dev_fd, CMD_PWM_SENDSIGNAL, &st_cmd_para);
if (ret != TD_SUCCESS) {
soc_log_err("ERR: send signal err, ret=%#x!\n", ret);
return SOC_ERR_PWM_INVALID_OPT;
}
return TD_SUCCESS;
}
td_s32 uapi_pwm_set_enable(td_u32 pwm_id, td_bool enable)
{
td_s32 ret = 0;
pwm_enable_cmd_para st_cmd_para = {0};
pwm_check_init(ret);
if (ret == SOC_ERR_PWM_NOT_INIT) {
return ret;
}
if ((enable != TD_TRUE) && (enable != TD_FALSE)) {
soc_log_err("ERR: invalid param!\n");
return SOC_ERR_PWM_INVALID_PARA;
}
st_cmd_para.pwm_no = pwm_id;
st_cmd_para.enable = enable;
ret = ioctl(g_pwm_dev_fd, CMD_PWM_SETENABLE, &st_cmd_para);
if (ret != TD_SUCCESS) {
soc_log_err("ERR: set pwm enable err, ret=%#x!\n", ret);
return SOC_ERR_PWM_INVALID_OPT;
}
return TD_SUCCESS;
}
td_s32 uapi_pwm_moto_trigger(td_u32 pwm_id, const uapi_pwm_attr *pwm_attr, td_u32 time_us)
{
td_s32 ret = 0;
pmw_moto_cmd_para moto_pwm_cmd = {0};
pwm_check_init(ret);
if (ret == SOC_ERR_PWM_NOT_INIT) {
return ret;
}
if (pwm_attr == TD_NULL) {
soc_log_err("ERR: invalid param!\n");
return SOC_ERR_PWM_INVALID_PARA;
}
moto_pwm_cmd.pwm_no = pwm_id;
moto_pwm_cmd.pwm_attr = *(ext_drv_pwm_attr *)(td_void *)pwm_attr;
moto_pwm_cmd.time_us = time_us;
ret = ioctl(g_pwm_dev_fd, CMD_PWM_MOTOPWM, &moto_pwm_cmd);
if (ret != TD_SUCCESS) {
soc_log_err("ERR: pwm-moto trigger err, ret=%#x!\n", ret);
return SOC_ERR_PWM_INVALID_OPT;
}
return TD_SUCCESS;
}