!591 feat:Add DAC user mode interface

Merge pull request !591 from 张亚雷/master
This commit is contained in:
openharmony_ci 2022-01-31 05:41:41 +00:00 committed by Gitee
commit 75c7cbe032
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
6 changed files with 316 additions and 30 deletions

View File

@ -78,6 +78,17 @@ void DacClose(DevHandle handle);
*/
int32_t DacWrite(DevHandle handle, uint32_t channel, uint32_t val);
/**
* @brief Enumerates DAC I/O commands.
*
* @since 1.0
*/
enum DacIoCmd {
DAC_IO_READ = 0,
DAC_IO_OPEN,
DAC_IO_CLOSE,
DAC_IO_WRITE,
};
#ifdef __cplusplus
#if __cplusplus
}

View File

@ -46,12 +46,6 @@ struct DacLockMethod {
void (*unlock)(struct DacDevice *device);
};
enum DacIoCmd {
DAC_IO_READ = 0,
DAC_IO_OPEN,
DAC_IO_CLOSE,
};
int32_t DacDeviceAdd(struct DacDevice *device);
void DacDeviceRemove(struct DacDevice *device);

View File

@ -14,6 +14,7 @@
#include "osal_time.h"
#include "platform_core.h"
#define DAC_HANDLE_SHIFT 0xFF00U
#define HDF_LOG_TAG dac_core_c
struct DacManager {
@ -28,6 +29,7 @@ static struct DacManager *g_dacManager = NULL;
static int32_t DacDeviceLockDefault(struct DacDevice *device)
{
if (device == NULL) {
HDF_LOGE("%s: device is null", __func__);
return HDF_ERR_INVALID_OBJECT;
}
return OsalSpinLock(&device->spin);
@ -36,6 +38,7 @@ static int32_t DacDeviceLockDefault(struct DacDevice *device)
static void DacDeviceUnlockDefault(struct DacDevice *device)
{
if (device == NULL) {
HDF_LOGE("%s: device is null", __func__);
return;
}
(void)OsalSpinUnlock(&device->spin);
@ -46,11 +49,38 @@ static const struct DacLockMethod g_dacLockOpsDefault = {
.unlock = DacDeviceUnlockDefault,
};
static inline int32_t DacDeviceLock(struct DacDevice *device)
{
if (device == NULL) {
HDF_LOGE("%s: device is null", __func__);
return HDF_ERR_INVALID_OBJECT;
}
if (device->lockOps == NULL || device->lockOps->lock == NULL) {
return HDF_ERR_NOT_SUPPORT;
}
return device->lockOps->lock(device);
}
static inline void DacDeviceUnlock(struct DacDevice *device)
{
if (device == NULL) {
HDF_LOGE("%s: device is null", __func__);
return;
}
if (device->lockOps != NULL && device->lockOps->unlock != NULL) {
device->lockOps->unlock(device);
}
}
static int32_t DacManagerAddDevice(struct DacDevice *device)
{
int32_t ret;
struct DacManager *manager = g_dacManager;
if (device == NULL) {
HDF_LOGE("%s: device is null", __func__);
return HDF_ERR_INVALID_OBJECT;
}
if (device->devNum >= DAC_DEVICES_MAX) {
HDF_LOGE("%s: devNum:%u exceed", __func__, device->devNum);
return HDF_ERR_INVALID_OBJECT;
@ -82,6 +112,10 @@ static void DacManagerRemoveDevice(struct DacDevice *device)
{
struct DacManager *manager = g_dacManager;
if (device == NULL) {
HDF_LOGE("%s: device is null", __func__);
return;
}
if (device->devNum < 0 || device->devNum >= DAC_DEVICES_MAX) {
HDF_LOGE("%s: invalid devNum:%u", __func__, device->devNum);
return;
@ -137,6 +171,7 @@ int32_t DacDeviceAdd(struct DacDevice *device)
int32_t ret;
if (device == NULL) {
HDF_LOGE("%s: device is null", __func__);
return HDF_ERR_INVALID_OBJECT;
}
@ -165,6 +200,7 @@ int32_t DacDeviceAdd(struct DacDevice *device)
void DacDeviceRemove(struct DacDevice *device)
{
if (device == NULL) {
HDF_LOGE("%s: device is null", __func__);
return;
}
DacManagerRemoveDevice(device);
@ -181,19 +217,35 @@ void DacDevicePut(struct DacDevice *device)
(void)device;
}
static inline int32_t DacDeviceLock(struct DacDevice *device)
static struct DacDevice *DacDeviceOpen(uint32_t number)
{
if (device->lockOps == NULL || device->lockOps->lock == NULL) {
return HDF_ERR_NOT_SUPPORT;
int32_t ret;
struct DacDevice *device = NULL;
device = DacDeviceGet(number);
if (device == NULL) {
HDF_LOGE("%s: Get device failed!", __func__);
return NULL;
}
return device->lockOps->lock(device);
ret = DacDeviceStart(device);
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s: start device failed!", __func__);
return NULL;
}
return device;
}
static inline void DacDeviceUnlock(struct DacDevice *device)
static void DacDeviceClose(struct DacDevice *device)
{
if (device->lockOps != NULL && device->lockOps->unlock != NULL) {
device->lockOps->unlock(device);
if (device == NULL) {
HDF_LOGE("%s: close dac device fail", __func__);
return;
}
(void)DacDeviceStop(device);
DacDevicePut(device);
}
int32_t DacDeviceWrite(struct DacDevice *device, uint32_t channel, uint32_t val)
@ -273,22 +325,28 @@ static int32_t DacManagerIoOpen(struct HdfSBuf *data, struct HdfSBuf *reply)
uint32_t number;
if (data == NULL || reply == NULL) {
HDF_LOGE("%s: invalid data or reply", __func__);
return HDF_ERR_INVALID_PARAM;
}
if (!HdfSbufReadUint32(data, &number)) {
HDF_LOGE("%s: read number failed!", __func__);
return HDF_ERR_IO;
}
if (number < 0 || number >= DAC_DEVICES_MAX || reply == NULL) {
HDF_LOGE("%s: invalid number %u", __func__, number);
return HDF_ERR_INVALID_PARAM;
}
if (DacDeviceGet(number) == NULL) {
if (DacDeviceOpen(number) == NULL) {
HDF_LOGE("%s: get device %u failed!", __func__, number);
return HDF_ERR_NOT_SUPPORT;
}
if (!HdfSbufWriteUint32(reply, number)) {
number = (uint32_t)(number + DAC_HANDLE_SHIFT);
if (!HdfSbufWriteUint32(reply, (uint32_t)(uintptr_t)number)) {
HDF_LOGE("%s: write number failed!", __func__);
return HDF_ERR_IO;
}
return HDF_SUCCESS;
@ -298,47 +356,88 @@ static int32_t DacManagerIoClose(struct HdfSBuf *data, struct HdfSBuf *reply)
{
uint32_t number;
if (data == NULL || reply == NULL) {
if (data == NULL) {
HDF_LOGE("%s: invalid data", __func__);
return HDF_ERR_INVALID_PARAM;
}
if (!HdfSbufReadUint32(data, &number)) {
HDF_LOGE("%s: read number failed!", __func__);
return HDF_ERR_IO;
}
number = (uint32_t)(number - DAC_HANDLE_SHIFT);
if (number < 0 || number >= DAC_DEVICES_MAX) {
HDF_LOGE("%s: invalid number %u", __func__, number);
return HDF_ERR_INVALID_PARAM;
}
DacDevicePut(DacManagerFindDevice(number));
DacDeviceClose(DacDeviceGet(number));
return HDF_SUCCESS;
}
static int32_t DacManagerIoRead(struct HdfSBuf *data, struct HdfSBuf *reply)
static int32_t DacManagerIoWrite(struct HdfSBuf *data, struct HdfSBuf *reply)
{
(void)data;
(void)reply;
int32_t ret;
uint32_t channel;
uint32_t val;
uint32_t number;
if (data == NULL) {
HDF_LOGE("%s: invalid data", __func__);
return HDF_ERR_INVALID_PARAM;
}
if (!HdfSbufReadUint32(data, &number)) {
HDF_LOGE("%s: read number failed!", __func__);
return HDF_ERR_IO;
}
number = (uint32_t)(number - DAC_HANDLE_SHIFT);
if (number < 0 || number >= DAC_DEVICES_MAX) {
HDF_LOGE("%s: invalid number %u", __func__, number);
return HDF_ERR_INVALID_PARAM;
}
if (!HdfSbufReadUint32(data, &channel)) {
HDF_LOGE("%s: read dac channel failed", __func__);
return HDF_ERR_IO;
}
if (!HdfSbufReadUint32(data, &val)) {
HDF_LOGE("%s: read dac value failed", __func__);
return HDF_ERR_IO;
}
ret = DacDeviceWrite(DacDeviceGet(number), channel, val);
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s: write dac failed:%d", __func__, ret);
return ret;
}
return HDF_SUCCESS;
}
static int32_t DacManagerDispatch(struct HdfDeviceIoClient *client, int cmd,
struct HdfSBuf *data, struct HdfSBuf *reply)
{
int32_t ret;
switch (cmd) {
case DAC_IO_OPEN:
return DacManagerIoOpen(data, reply);
case DAC_IO_CLOSE:
return DacManagerIoClose(data, reply);
case DAC_IO_READ:
return DacManagerIoRead(data, reply);
case DAC_IO_WRITE:
return DacManagerIoWrite(data, reply);
default:
ret = HDF_ERR_NOT_SUPPORT;
break;
return HDF_ERR_NOT_SUPPORT;
}
return ret;
return HDF_SUCCESS;
}
static int32_t DacManagerBind(struct HdfDeviceObject *device)
{
(void)device;
return HDF_SUCCESS;
}
static int32_t DacManagerInit(struct HdfDeviceObject *device)
{
int32_t ret;
@ -390,6 +489,7 @@ static void DacManagerRelease(struct HdfDeviceObject *device)
struct HdfDriverEntry g_dacManagerEntry = {
.moduleVersion = 1,
.Bind = DacManagerBind,
.Init = DacManagerInit,
.Release = DacManagerRelease,
.moduleName = "HDF_PLATFORM_DAC_MANAGER",

View File

@ -0,0 +1,166 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#include "dac_if.h"
#include "hdf_io_service_if.h"
#include "platform_core.h"
#include "hdf_log.h"
#include "osal_mem.h"
#include "securec.h"
#define HDF_LOG_TAG dac_if_c
#define DAC_SERVICE_NAME "HDF_PLATFORM_DAC_MANAGER"
static void *DacManagerServiceGet(void)
{
static struct HdfIoService *service = NULL;
if (service != NULL) {
return service;
}
service = (struct HdfIoService *)HdfIoServiceBind("HDF_PLATFORM_DAC_MANAGER");
if (service == NULL) {
HDF_LOGE("%s: failed to get dac manager service!", __func__);
}
return service;
}
DevHandle DacOpen(uint32_t number)
{
int32_t ret;
struct HdfIoService *service = NULL;
struct HdfSBuf *data = NULL;
struct HdfSBuf *reply = NULL;
uint32_t handle;
service = DacManagerServiceGet();
if (service == NULL || service->dispatcher == NULL || service->dispatcher->Dispatch == NULL) {
HDF_LOGE("%s: service is invalid", __func__);
return NULL;
}
data = HdfSbufObtainDefaultSize();
if (data == NULL) {
HDF_LOGE("DacOpen: malloc data failed!");
return NULL;
}
reply = HdfSbufObtainDefaultSize();
if (reply == NULL) {
HDF_LOGE("DacOpen: malloc reply failed!");
HdfSbufRecycle(data);
return NULL;
}
if (!HdfSbufWriteUint32(data, number)) {
HDF_LOGE("DacOpen: write number failed!");
HdfSbufRecycle(data);
HdfSbufRecycle(reply);
return NULL;
}
ret = service->dispatcher->Dispatch(&service->object, DAC_IO_OPEN, data, reply);
if (ret != HDF_SUCCESS) {
HDF_LOGE("DacOpen: service call open failed:%d", ret);
HdfSbufRecycle(data);
HdfSbufRecycle(reply);
return NULL;
}
if (!HdfSbufReadUint32(reply, &handle)) {
HDF_LOGE("DacOpen: read handle failed!");
HdfSbufRecycle(data);
HdfSbufRecycle(reply);
return NULL;
}
HdfSbufRecycle(data);
HdfSbufRecycle(reply);
return (DevHandle)(uintptr_t)handle;
}
void DacClose(DevHandle handle)
{
int32_t ret;
struct HdfIoService *service = NULL;
struct HdfSBuf *data = NULL;
if (handle == NULL) {
HDF_LOGE("%s: handle is invalid", __func__);
return;
}
service = (struct HdfIoService *)DacManagerServiceGet();
if (service == NULL || service->dispatcher == NULL || service->dispatcher->Dispatch == NULL) {
HDF_LOGE("%s: service is invalid", __func__);
return;
}
data = HdfSbufObtainDefaultSize();
if (data == NULL) {
return;
}
if (!HdfSbufWriteUint32(data, (uint32_t)(uintptr_t)handle)) {
HDF_LOGE("DacClose: write handle failed!");
HdfSbufRecycle(data);
return;
}
ret = service->dispatcher->Dispatch(&service->object, DAC_IO_CLOSE, data, NULL);
if (ret != HDF_SUCCESS) {
HDF_LOGE("DacClose: close handle failed:%d", ret);
}
HdfSbufRecycle(data);
}
int32_t DacWrite(DevHandle handle, uint32_t channel, uint32_t val)
{
int32_t ret;
struct HdfIoService *service = NULL;
struct HdfSBuf *data = NULL;
if (handle == NULL) {
HDF_LOGE("%s: handle is invalid", __func__);
return HDF_FAILURE;
}
service = (struct HdfIoService *)DacManagerServiceGet();
if (service == NULL || service->dispatcher == NULL || service->dispatcher->Dispatch == NULL) {
HDF_LOGE("%s: service is invalid", __func__);
return HDF_ERR_INVALID_PARAM;
}
data = HdfSbufObtainDefaultSize();
if (data == NULL) {
return HDF_ERR_MALLOC_FAIL;
}
if (!HdfSbufWriteUint32(data, (uint32_t)(uintptr_t)handle)) {
HDF_LOGE("DacWrite: write handle failed!");
HdfSbufRecycle(data);
return HDF_ERR_IO;
}
if (!HdfSbufWriteUint32(data, channel)) {
HDF_LOGE("DacWrite: write channel failed!");
HdfSbufRecycle(data);
return HDF_ERR_IO;
}
if (!HdfSbufWriteUint32(data, val)) {
HDF_LOGE("DacWrite: write val failed!");
HdfSbufRecycle(data);
return HDF_ERR_IO;
}
ret = service->dispatcher->Dispatch(&service->object, DAC_IO_WRITE, data, NULL);
if (ret != HDF_SUCCESS) {
HDF_LOGE("DacWrite: write dac failed:%d", ret);
}
HdfSbufRecycle(data);
return ret;
}

View File

@ -55,6 +55,10 @@ HWTEST_F(HdfLiteDacTest, DacTestWrite001, TestSize.Level1)
{
struct HdfTestMsg msg = {TEST_PAL_DAC_TYPE, DAC_TEST_CMD_WRITE, -1};
EXPECT_EQ(0, HdfTestSendMsgToService(&msg));
printf("%s: kernel test done, then for user...\n", __func__);
EXPECT_EQ(0, DacTestExecute(DAC_TEST_CMD_WRITE));
printf("%s: exit!\n", __func__);
}
/**
@ -67,6 +71,10 @@ HWTEST_F(HdfLiteDacTest, DacTestMultiThread001, TestSize.Level1)
{
struct HdfTestMsg msg = {TEST_PAL_DAC_TYPE, DAC_TEST_CMD_MULTI_THREAD, -1};
EXPECT_EQ(0, HdfTestSendMsgToService(&msg));
printf("%s: kernel test done, then for user...\n", __func__);
EXPECT_EQ(0, DacTestExecute(DAC_TEST_CMD_MULTI_THREAD));
printf("%s: exit!\n", __func__);
}
/**
@ -79,4 +87,8 @@ HWTEST_F(HdfLiteDacTest, DacTestReliability001, TestSize.Level1)
{
struct HdfTestMsg msg = {TEST_PAL_DAC_TYPE, DAC_TEST_CMD_RELIABILITY, -1};
EXPECT_EQ(0, HdfTestSendMsgToService(&msg));
printf("%s: kernel test done, then for user...\n", __func__);
EXPECT_EQ(0, DacTestExecute(DAC_TEST_CMD_RELIABILITY));
printf("%s: exit!\n", __func__);
}

View File

@ -41,6 +41,7 @@ static int32_t DacTestGetConfig(struct DacTestConfig *config)
ret = service->dispatcher->Dispatch(&service->object, 0, NULL, reply);
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s: remote dispatch failed", __func__);
HdfSbufRecycle(reply);
return ret;
}
@ -102,10 +103,10 @@ int32_t DacTestWrite(void)
return HDF_ERR_INVALID_OBJECT;
}
for (i = 0; i < TEST_DAC_VAL_NUM; i++) {
value[i] = 0;
value[i] = i;
ret = DacWrite(tester->handle, tester->config.channel, value[i]);
if (ret != HDF_SUCCESS || value[i] >= (1U << tester->config.dataWidth)) {
HDF_LOGE("%s: write value invalid:%u, ret:%d", __func__, value[i], ret);
HDF_LOGE("%s: write value failed:%u, ret:%d", __func__, value[i], ret);
return HDF_ERR_IO;
}
}
@ -119,6 +120,7 @@ static int DacTestThreadFunc(void *param)
uint32_t val;
uint32_t i;
int32_t ret;
tester = DacTesterGet();
if (tester == NULL) {
HDF_LOGE("%s: get tester failed", __func__);
@ -130,6 +132,7 @@ static int DacTestThreadFunc(void *param)
ret = DacWrite(tester->handle, tester->config.channel, val);
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s: DacWrite failed, ret:%d", __func__, ret);
*((int32_t *)param) = 1;
return HDF_ERR_IO;
}
}