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
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;
|
|
}
|