mirror of
https://github.com/openharmony/drivers_adapter.git
synced 2026-07-01 03:23:20 -04:00
Merge branch 'master' of gitee.com:openharmony/drivers_adapter into master
This commit is contained in:
@@ -59,6 +59,7 @@ Note:If the text contains special characters, please escape them according to th
|
||||
<policyitem type="license" name="GPL" path=".*" desc="linux kernel adapter codes"/>
|
||||
<policyitem type="copyright" name="Bestechnic (Shanghai) Co., Ltd." path=".*" rule="may" group="defaultGroup" filefilter="copyrightPolicyFilter" desc="Developed by Bestechnic"/>
|
||||
<policyitem type="copyright" name="GOODIX." path=".*" rule="may" group="defaultGroup" filefilter="copyrightPolicyFilter" desc="Developed by Goodix"/>
|
||||
<policyitem type="copyright" name="ASR Microelectronics (Shanghai) Co., Ltd." path=".*" rule="may" group="defaultGroup" filefilter="copyrightPolicyFilter" desc="Developed by asr"/>
|
||||
<policyitem type="copyright" name="Talkweb Co., Ltd." path=".*" rule="may" group="defaultGroup" filefilter="copyrightPolicyFilter" desc="Developed by Talkweb"/>
|
||||
<policyitem type="copyright" name="Jiangsu Hoperun Software Co., Ltd." path=".*" rule="may" group="defaultGroup" filefilter="copyrightPolicyFilter" desc="Developed By Hoperun"/>
|
||||
</policy>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2021-2022 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
|
||||
@@ -98,27 +98,33 @@ static struct UsbPnpDeviceInfo *UsbPnpNotifyCreateInfo(void)
|
||||
struct UsbPnpDeviceInfo *infoTemp = NULL;
|
||||
unsigned char *ptr = NULL;
|
||||
static int32_t idNum = 0;
|
||||
int32_t ret;
|
||||
|
||||
ptr = OsalMemCalloc(sizeof(struct UsbPnpDeviceInfo));
|
||||
if (ptr == NULL) {
|
||||
HDF_LOGE("%s:%d OsalMemAlloc faile ", __func__, __LINE__);
|
||||
return NULL;
|
||||
} else {
|
||||
infoTemp = (struct UsbPnpDeviceInfo *)ptr;
|
||||
|
||||
if (idNum++ >= INT32_MAX) {
|
||||
idNum = 0;
|
||||
}
|
||||
infoTemp->id = idNum;
|
||||
OsalMutexInit(&infoTemp->lock);
|
||||
infoTemp->status = USB_PNP_DEVICE_INIT_STATUS;
|
||||
DListHeadInit(&infoTemp->list);
|
||||
memset_s(infoTemp->interfaceRemoveStatus, USB_PNP_INFO_MAX_INTERFACES,
|
||||
0, sizeof(infoTemp->interfaceRemoveStatus));
|
||||
DListInsertTail(&infoTemp->list, &g_usbPnpInfoListHead);
|
||||
|
||||
return infoTemp;
|
||||
}
|
||||
infoTemp = (struct UsbPnpDeviceInfo *)ptr;
|
||||
|
||||
if (idNum++ >= INT32_MAX) {
|
||||
idNum = 0;
|
||||
}
|
||||
infoTemp->id = idNum;
|
||||
OsalMutexInit(&infoTemp->lock);
|
||||
infoTemp->status = USB_PNP_DEVICE_INIT_STATUS;
|
||||
DListHeadInit(&infoTemp->list);
|
||||
ret = memset_s(infoTemp->interfaceRemoveStatus, USB_PNP_INFO_MAX_INTERFACES,
|
||||
0, sizeof(infoTemp->interfaceRemoveStatus));
|
||||
if (ret != HDF_SUCCESS) {
|
||||
HDF_LOGE("%{public}s:%{public}d memset_s failed", __func__, __LINE__);
|
||||
OsalMemFree(ptr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DListInsertTail(&infoTemp->list, &g_usbPnpInfoListHead);
|
||||
|
||||
return infoTemp;
|
||||
}
|
||||
|
||||
static struct UsbPnpDeviceInfo *UsbPnpNotifyFindInfo(struct UsbInfoQueryPara queryPara)
|
||||
@@ -967,7 +973,7 @@ static int32_t UsbPnpNotifyBind(struct HdfDeviceObject *device)
|
||||
static int32_t UsbPnpNotifyInit(struct HdfDeviceObject *device)
|
||||
{
|
||||
static bool firstInitFlag = true;
|
||||
HDF_STATUS ret;
|
||||
int32_t ret;
|
||||
struct OsalThreadParam threadCfg;
|
||||
|
||||
dprintf("%s:%d enter!\n", __func__, __LINE__);
|
||||
@@ -988,10 +994,14 @@ static int32_t UsbPnpNotifyInit(struct HdfDeviceObject *device)
|
||||
|
||||
OsalMutexInit(&g_usbSendEventLock);
|
||||
|
||||
g_usbPnpThreadRunningFlag = true;
|
||||
|
||||
/* Creat thread to handle send usb interface information. */
|
||||
(void)memset_s(&threadCfg, sizeof(threadCfg), 0, sizeof(threadCfg));
|
||||
ret = memset_s(&threadCfg, sizeof(threadCfg), 0, sizeof(threadCfg));
|
||||
if (ret != HDF_SUCCESS) {
|
||||
HDF_LOGE("%{public}s:%{public}d memset_s failed", __func__, __LINE__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
g_usbPnpThreadRunningFlag = true;
|
||||
threadCfg.name = "LiteOS usb pnp notify handle kthread";
|
||||
threadCfg.priority = OSAL_THREAD_PRI_HIGH;
|
||||
threadCfg.stackSize = USB_PNP_NOTIFY_REPORT_STACK_SIZE;
|
||||
|
||||
@@ -0,0 +1,477 @@
|
||||
/*
|
||||
* Copyright (c) 2022 ASR Microelectronics (Shanghai) Co., Ltd. All rights reserved.
|
||||
*
|
||||
* 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 <stdlib.h>
|
||||
#include "gpio_core.h"
|
||||
#include "hdf_log.h"
|
||||
#include "osal_irq.h"
|
||||
#ifdef LOSCFG_DRIVERS_HDF_CONFIG_MACRO
|
||||
#include "hcs_macro.h"
|
||||
#include "hdf_config_macro.h"
|
||||
#else
|
||||
#include "device_resource_if.h"
|
||||
#endif
|
||||
#include "duet_gpio.h"
|
||||
|
||||
#define ASR_GPIO_TOTAL_NUM DUET_GPIO_TOTAL_NUM
|
||||
#define asr_gpio_config_t duet_gpio_config_t
|
||||
#define ASR_ANALOG_MODE DUET_ANALOG_MODE
|
||||
#define ASR_IRQ_MODE DUET_IRQ_MODE
|
||||
#define ASR_INPUT_PULL_UP DUET_INPUT_PULL_UP
|
||||
#define ASR_INPUT_PULL_DOWN DUET_INPUT_PULL_DOWN
|
||||
#define ASR_INPUT_HIGH_IMPEDANCE DUET_INPUT_HIGH_IMPEDANCE
|
||||
#define ASR_OUTPUT_PUSH_PULL DUET_OUTPUT_PUSH_PULL
|
||||
#define ASR_OUTPUT_OPEN_DRAIN_NO_PULL DUET_OUTPUT_OPEN_DRAIN_NO_PULL
|
||||
#define ASR_OUTPUT_OPEN_DRAIN_PULL_UP DUET_OUTPUT_OPEN_DRAIN_PULL_UP
|
||||
|
||||
#define asr_gpio_dev_t duet_gpio_dev_t
|
||||
#define asr_gpio_irq_trigger_t duet_gpio_irq_trigger_t
|
||||
#define asr_gpio_irq_handler_t duet_gpio_irq_handler_t
|
||||
#define asr_gpio_cb_t duet_gpio_cb_t
|
||||
#define asr_gpio_init duet_gpio_init
|
||||
#define asr_gpio_output_high duet_gpio_output_high
|
||||
#define asr_gpio_output_low duet_gpio_output_low
|
||||
#define asr_gpio_output_toggle duet_gpio_output_toggle
|
||||
#define asr_gpio_input_get duet_gpio_input_get
|
||||
#define asr_gpio_enable_irq duet_gpio_enable_irq
|
||||
#define asr_gpio_disable_irq duet_gpio_disable_irq
|
||||
#define asr_gpio_clear_irq duet_gpio_clear_irq
|
||||
#define asr_gpio_finalize duet_gpio_finalize
|
||||
|
||||
#define HDF_LOG_TAG GPIO_ASR
|
||||
|
||||
struct GpioResource {
|
||||
uint32_t pin;
|
||||
uint32_t realPin;
|
||||
uint32_t config;
|
||||
uint32_t pinNum;
|
||||
uint32_t type; /**< Type of the input event EV_KEY */
|
||||
uint32_t code; /**< Specific code item of the input event KEY_POWER*/
|
||||
unsigned long physBase;
|
||||
};
|
||||
|
||||
enum GpioDeviceState {
|
||||
GPIO_DEVICE_UNINITIALIZED = 0x0u,
|
||||
GPIO_DEVICE_INITIALIZED = 0x1u,
|
||||
};
|
||||
|
||||
struct GpioDevice {
|
||||
asr_gpio_dev_t dev;
|
||||
struct GpioResource resource;
|
||||
};
|
||||
|
||||
static struct GpioCntlr g_gpioCntlr;
|
||||
struct OemGpioIrqHandler {
|
||||
uint8_t port;
|
||||
GpioIrqFunc func;
|
||||
void *arg;
|
||||
};
|
||||
|
||||
static asr_gpio_dev_t g_gpioPinMap[ASR_GPIO_TOTAL_NUM] = {0};
|
||||
static asr_gpio_irq_trigger_t g_gpioIrqCfg[ASR_GPIO_TOTAL_NUM] = {0};
|
||||
|
||||
static void OemGpioIrqHdl(uint16_t *arg)
|
||||
{
|
||||
asr_gpio_dev_t *dev = NULL;
|
||||
uint16_t gpio = (uint16_t)arg;
|
||||
|
||||
dev = &g_gpioPinMap[gpio];
|
||||
if ((uint16_t)dev->port >= ASR_GPIO_TOTAL_NUM) {
|
||||
HDF_LOGE("%s %d, error pin:%d", __func__, __LINE__, (uint16_t)dev->port);
|
||||
return;
|
||||
}
|
||||
GpioCntlrIrqCallback(&g_gpioCntlr, gpio);
|
||||
}
|
||||
|
||||
/* dispatch */
|
||||
int32_t GpioDispatch(struct HdfDeviceIoClient *client, int cmdId, struct HdfSBuf *data, struct HdfSBuf *reply)
|
||||
{
|
||||
if (client == NULL || client->device == NULL || data == NULL || reply == NULL) {
|
||||
HDF_LOGE("%s: client or client->device is NULL", __func__);
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
/* dev api */
|
||||
static int32_t GpioDevWrite(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t val)
|
||||
{
|
||||
(void)cntlr;
|
||||
uint32_t ret = 0;
|
||||
asr_gpio_dev_t *dev = &g_gpioPinMap[gpio];
|
||||
|
||||
if (val) {
|
||||
ret = asr_gpio_output_high(dev);
|
||||
} else {
|
||||
ret = asr_gpio_output_low(dev);
|
||||
}
|
||||
if (EIO == ret) {
|
||||
HDF_LOGE("%s %d, error pin:%d", __func__, __LINE__, dev->port);
|
||||
return HDF_ERR_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t GpioDevRead(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t *val)
|
||||
{
|
||||
(void)cntlr;
|
||||
uint32_t ret = 0;
|
||||
asr_gpio_dev_t *dev = &g_gpioPinMap[gpio];
|
||||
|
||||
if ((cntlr == NULL) || (val == NULL)) {
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
ret = asr_gpio_input_get(dev, val);
|
||||
if (EIO == ret) {
|
||||
HDF_LOGE("%s %d, error pin:%d", __func__, __LINE__, dev->port);
|
||||
return HDF_ERR_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t GpioDevSetDir(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t dir)
|
||||
{
|
||||
(void)cntlr;
|
||||
uint32_t ret = 0;
|
||||
asr_gpio_dev_t *dev = &g_gpioPinMap[gpio];
|
||||
|
||||
if (cntlr == NULL) {
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
dev->config = (asr_gpio_config_t)dir;
|
||||
ret = asr_gpio_init(dev);
|
||||
if (EIO == ret) {
|
||||
HDF_LOGE("%s %d, error pin:%d", __func__, __LINE__, dev->port);
|
||||
return HDF_ERR_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t GpioDevGetDir(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t *dir)
|
||||
{
|
||||
(void)cntlr;
|
||||
uint32_t ret = 0;
|
||||
asr_gpio_dev_t *dev = &g_gpioPinMap[gpio];
|
||||
|
||||
if ((cntlr == NULL) || (dir == NULL)) {
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
if (dev->port >= ASR_GPIO_TOTAL_NUM) {
|
||||
HDF_LOGE("%s %d, error pin:%d", __func__, __LINE__, dev->port);
|
||||
return HDF_ERR_NOT_SUPPORT;
|
||||
}
|
||||
*dir = (uint16_t)dev->config;
|
||||
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t GpioDevSetIrq(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t mode)
|
||||
{
|
||||
(void)cntlr;
|
||||
asr_gpio_dev_t *dev = &g_gpioPinMap[gpio];
|
||||
|
||||
HDF_LOGE("%s %d, pin:%d", __func__, __LINE__, (uint16_t)dev->port);
|
||||
if (dev->port >= ASR_GPIO_TOTAL_NUM) {
|
||||
HDF_LOGE("%s %d, error pin:%d", __func__, __LINE__, dev->port);
|
||||
return HDF_ERR_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
if ((mode == OSAL_IRQF_TRIGGER_RISING) || (mode == OSAL_IRQF_TRIGGER_FALLING)
|
||||
|| (mode == (OSAL_IRQF_TRIGGER_RISING | OSAL_IRQF_TRIGGER_FALLING))) {
|
||||
g_gpioIrqCfg[gpio] = (asr_gpio_config_t)mode;
|
||||
} else {
|
||||
HDF_LOGE("%s %d, error mode:%d", __func__, __LINE__, mode);
|
||||
return HDF_ERR_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t GpioDevUnSetIrq(struct GpioCntlr *cntlr, uint16_t gpio)
|
||||
{
|
||||
(void)cntlr;
|
||||
asr_gpio_dev_t *dev = &g_gpioPinMap[gpio];
|
||||
|
||||
if (dev->port >= ASR_GPIO_TOTAL_NUM) {
|
||||
HDF_LOGE("%s %d, error pin:%d", __func__, __LINE__, dev->port);
|
||||
return HDF_ERR_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t GpioDevEnableIrq(struct GpioCntlr *cntlr, uint16_t gpio)
|
||||
{
|
||||
(void)cntlr;
|
||||
asr_gpio_dev_t *dev = &g_gpioPinMap[gpio];
|
||||
|
||||
if ((uint16_t)dev->port >= ASR_GPIO_TOTAL_NUM) {
|
||||
HDF_LOGE("%s %d, error pin:%d", __func__, __LINE__, (uint16_t)dev->port);
|
||||
return HDF_ERR_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
dev->config = ASR_IRQ_MODE;
|
||||
asr_gpio_init(dev);
|
||||
asr_gpio_enable_irq(dev, g_gpioIrqCfg[gpio], OemGpioIrqHdl, (void *)gpio);
|
||||
HDF_LOGE("%s %d, pin:%d", __func__, __LINE__, (uint16_t)dev->port);
|
||||
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t GpioDevDisableIrq(struct GpioCntlr *cntlr, uint16_t gpio)
|
||||
{
|
||||
(void)cntlr;
|
||||
asr_gpio_dev_t *dev = &g_gpioPinMap[gpio];
|
||||
|
||||
if ((uint16_t)dev->port >= ASR_GPIO_TOTAL_NUM) {
|
||||
HDF_LOGE("%s %d, error pin:%d", __func__, __LINE__, (uint16_t)dev->port);
|
||||
return HDF_ERR_NOT_SUPPORT;
|
||||
}
|
||||
asr_gpio_disable_irq(dev);
|
||||
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
struct GpioMethod g_GpioCntlrMethod = {
|
||||
.request = NULL,
|
||||
.release = NULL,
|
||||
.write = GpioDevWrite,
|
||||
.read = GpioDevRead,
|
||||
.setDir = GpioDevSetDir,
|
||||
.getDir = GpioDevGetDir,
|
||||
.toIrq = NULL,
|
||||
.setIrq = GpioDevSetIrq,
|
||||
.unsetIrq = GpioDevUnSetIrq,
|
||||
.enableIrq = GpioDevEnableIrq,
|
||||
.disableIrq = GpioDevDisableIrq,
|
||||
};
|
||||
|
||||
static int InitGpioDevice(struct GpioDevice *device)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
|
||||
if (device == NULL) {
|
||||
HDF_LOGE("%s: device is NULL", __func__);
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
HDF_LOGE("%s %d, pin:%d, mode:%d", __func__, __LINE__, device->dev.port, device->dev.config);
|
||||
ret = asr_gpio_init(&device->dev);
|
||||
if (EIO == ret) {
|
||||
HDF_LOGE("%s %d, error pin:%d", __func__, __LINE__, device->dev.port);
|
||||
return HDF_ERR_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
#ifdef LOSCFG_DRIVERS_HDF_CONFIG_MACRO
|
||||
#define PLATFORM_GPIO_CONFIG HCS_NODE(HCS_NODE(HCS_ROOT, platform), gpio_config)
|
||||
static uint32_t GetGpioDeviceResource(struct GpioDevice *device)
|
||||
{
|
||||
uint32_t relPin;
|
||||
int32_t ret;
|
||||
struct GpioResource *resource = NULL;
|
||||
if (device == NULL) {
|
||||
HDF_LOGE("%s: device is NULL", __func__);
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
resource = &device->resource;
|
||||
if (resource == NULL) {
|
||||
HDF_LOGE("%s: resource is NULL", __func__);
|
||||
return HDF_ERR_INVALID_OBJECT;
|
||||
}
|
||||
resource->pinNum = HCS_PROP(PLATFORM_GPIO_CONFIG, pinNum);
|
||||
uint32_t pins[] = HCS_ARRAYS(HCS_NODE(PLATFORM_GPIO_CONFIG, pin));
|
||||
uint32_t realPins[] = HCS_ARRAYS(HCS_NODE(PLATFORM_GPIO_CONFIG, realPin));
|
||||
uint32_t configs[] = HCS_ARRAYS(HCS_NODE(PLATFORM_GPIO_CONFIG, config));
|
||||
for (size_t i = 0; i < resource->pinNum; i++) {
|
||||
resource->pin = pins[i];
|
||||
resource->realPin = realPins[i];
|
||||
resource->config = configs[i];
|
||||
|
||||
relPin = resource->realPin;// / DECIMALNUM * OCTALNUM + resource->realPin % DECIMALNUM;
|
||||
g_gpioPinMap[resource->pin].port = (uint8_t)relPin;
|
||||
g_gpioPinMap[resource->pin].config = (asr_gpio_config_t)resource->config;
|
||||
device->dev.config = (asr_gpio_config_t)resource->config;
|
||||
resource->pin = relPin;
|
||||
device->dev.port = relPin;
|
||||
|
||||
ret = InitGpioDevice(device);
|
||||
if (ret != HDF_SUCCESS) {
|
||||
HDF_LOGE("InitGpioDevice FAIL\r\n");
|
||||
return HDF_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
#else
|
||||
static uint32_t GetGpioDeviceResource(
|
||||
struct GpioDevice *device, const struct DeviceResourceNode *resourceNode)
|
||||
{
|
||||
uint32_t relPin;
|
||||
int32_t ret;
|
||||
struct GpioResource *resource = NULL;
|
||||
struct DeviceResourceIface *dri = NULL;
|
||||
if (device == NULL || resourceNode == NULL) {
|
||||
HDF_LOGE("%s: device is NULL", __func__);
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
resource = &device->resource;
|
||||
if (resource == NULL) {
|
||||
HDF_LOGE("%s: resource is NULL", __func__);
|
||||
return HDF_ERR_INVALID_OBJECT;
|
||||
}
|
||||
dri = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
|
||||
if (dri == NULL || dri->GetUint32 == NULL) {
|
||||
HDF_LOGE("DeviceResourceIface is invalid");
|
||||
return HDF_ERR_INVALID_OBJECT;
|
||||
}
|
||||
|
||||
if (dri->GetUint32(resourceNode, "pinNum", &resource->pinNum, 0) != HDF_SUCCESS) {
|
||||
HDF_LOGE("gpio config read pinNum fail");
|
||||
return HDF_FAILURE;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < resource->pinNum; i++) {
|
||||
if (dri->GetUint32ArrayElem(resourceNode, "pin", i, &resource->pin, 0) != HDF_SUCCESS) {
|
||||
HDF_LOGE("gpio config read pin fail");
|
||||
return HDF_FAILURE;
|
||||
}
|
||||
|
||||
if (dri->GetUint32ArrayElem(resourceNode, "realPin", i, &resource->realPin, 0) != HDF_SUCCESS) {
|
||||
HDF_LOGE("gpio config read realPin fail");
|
||||
return HDF_FAILURE;
|
||||
}
|
||||
|
||||
if (dri->GetUint32ArrayElem(resourceNode, "config", i, &resource->config, 0) != HDF_SUCCESS) {
|
||||
HDF_LOGE("gpio config read config fail");
|
||||
return HDF_FAILURE;
|
||||
}
|
||||
|
||||
relPin = resource->realPin;// / DECIMALNUM * OCTALNUM + resource->realPin % DECIMALNUM;
|
||||
g_gpioPinMap[resource->pin].port = (uint8_t)relPin;
|
||||
g_gpioPinMap[resource->pin].config = (asr_gpio_config_t)resource->config;
|
||||
device->dev.config = (asr_gpio_config_t)resource->config;
|
||||
device->dev.port = relPin;
|
||||
resource->pin = relPin;
|
||||
|
||||
ret = InitGpioDevice(device);
|
||||
if (ret != HDF_SUCCESS) {
|
||||
HDF_LOGE("InitGpioDevice FAIL\r\n");
|
||||
return HDF_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static int32_t AttachGpioDevice(struct GpioCntlr *gpioCntlr, struct HdfDeviceObject *device)
|
||||
{
|
||||
int32_t ret;
|
||||
|
||||
struct GpioDevice *gpioDevice = NULL;
|
||||
#ifdef LOSCFG_DRIVERS_HDF_CONFIG_MACRO
|
||||
if (device == NULL) {
|
||||
#else
|
||||
if (device == NULL || device->property == NULL) {
|
||||
#endif
|
||||
HDF_LOGE("%s: param is NULL", __func__);
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
gpioDevice = (struct GpioDevice *)OsalMemAlloc(sizeof(struct GpioDevice));
|
||||
if (gpioDevice == NULL) {
|
||||
HDF_LOGE("%s: OsalMemAlloc gpioDevice error", __func__);
|
||||
return HDF_ERR_MALLOC_FAIL;
|
||||
}
|
||||
#ifdef LOSCFG_DRIVERS_HDF_CONFIG_MACRO
|
||||
ret = GetGpioDeviceResource(gpioDevice);
|
||||
#else
|
||||
ret = GetGpioDeviceResource(gpioDevice, device->property);
|
||||
#endif
|
||||
if (ret != HDF_SUCCESS) {
|
||||
(void)OsalMemFree(gpioDevice);
|
||||
return HDF_FAILURE;
|
||||
}
|
||||
|
||||
(void)OsalMemFree(gpioDevice);
|
||||
gpioCntlr->count = gpioDevice->resource.pinNum;
|
||||
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t GpioDriverInit(struct HdfDeviceObject *device)
|
||||
{
|
||||
int32_t ret;
|
||||
struct GpioCntlr *gpioCntlr = NULL;
|
||||
|
||||
if (device == NULL) {
|
||||
HDF_LOGE("%s: device is NULL", __func__);
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
ret = PlatformDeviceBind(&g_gpioCntlr.device, device);
|
||||
if (ret != HDF_SUCCESS) {
|
||||
HDF_LOGE("%s: bind hdf device failed:%d", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
gpioCntlr = GpioCntlrFromHdfDev(device);
|
||||
if (gpioCntlr == NULL) {
|
||||
HDF_LOGE("GpioCntlrFromHdfDev fail\r\n");
|
||||
return HDF_DEV_ERR_NO_DEVICE_SERVICE;
|
||||
}
|
||||
|
||||
ret = AttachGpioDevice(gpioCntlr, device); // GpioCntlr add GpioDevice to priv
|
||||
if (ret != HDF_SUCCESS) {
|
||||
HDF_LOGE("AttachGpioDevice fail\r\n");
|
||||
return HDF_DEV_ERR_ATTACHDEV_FAIL;
|
||||
}
|
||||
|
||||
gpioCntlr->ops = &g_GpioCntlrMethod; // register callback
|
||||
ret = GpioCntlrAdd(gpioCntlr);
|
||||
if (ret != HDF_SUCCESS) {
|
||||
HDF_LOGE("GpioCntlrAdd fail %d\r\n", gpioCntlr->start);
|
||||
return HDF_FAILURE;
|
||||
}
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
static void GpioDriverRelease(struct HdfDeviceObject *device)
|
||||
{
|
||||
struct GpioCntlr *gpioCntlr = NULL;
|
||||
|
||||
if (device == NULL) {
|
||||
HDF_LOGE("%s: device is NULL", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
gpioCntlr = GpioCntlrFromHdfDev(device);
|
||||
if (gpioCntlr == NULL) {
|
||||
HDF_LOGE("GpioCntlrFromHdfDev fail\r\n");
|
||||
return HDF_DEV_ERR_NO_DEVICE_SERVICE;
|
||||
}
|
||||
|
||||
(void)OsalMemFree(gpioCntlr->priv);
|
||||
gpioCntlr->count = 0;
|
||||
}
|
||||
|
||||
/* HdfDriverEntry definitions */
|
||||
struct HdfDriverEntry g_GpioDriverEntry = {
|
||||
.moduleVersion = 1,
|
||||
.moduleName = "ASR_GPIO_MODULE_HDF",
|
||||
.Init = GpioDriverInit,
|
||||
.Release = GpioDriverRelease,
|
||||
};
|
||||
HDF_INIT(g_GpioDriverEntry);
|
||||
+25
-3
@@ -89,9 +89,31 @@ static int InitPwmDevice(struct PwmDev *host)
|
||||
}
|
||||
|
||||
#ifdef LOSCFG_DRIVERS_HDF_CONFIG_MACRO
|
||||
static uint32_t GetPwmDeviceResource(struct PwmDevice *device)
|
||||
#define PWM_FIND_CONFIG(node, name, resource) \
|
||||
do { \
|
||||
if (strcmp(HCS_PROP(node, match_attr), name) == 0) { \
|
||||
tempPin = HCS_PROP(node, pwmPin); \
|
||||
resource->pwmPin = ((tempPin / DEC_TEN) * PIN_GROUP_NUM) + (tempPin % DEC_TEN); \
|
||||
resource->pwmId = HCS_PROP(node, pwmId); \
|
||||
break; \
|
||||
} \
|
||||
} while (0)
|
||||
#define PLATFORM_PWM_CONFIG HCS_NODE(HCS_NODE(HCS_ROOT, platform), pwm_config)
|
||||
static uint32_t GetPwmDeviceResource(struct PwmDevice *device, const char *deviceMatchAttr)
|
||||
{
|
||||
(void)device;
|
||||
uint32_t tempPin;
|
||||
struct PwmResource *resource = NULL;
|
||||
if (device == NULL) {
|
||||
HDF_LOGE("%s: device is NULL", __func__);
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
resource = &device->resource;
|
||||
if (resource == NULL) {
|
||||
HDF_LOGE("%s: resource is NULL", __func__);
|
||||
return HDF_ERR_INVALID_OBJECT;
|
||||
}
|
||||
|
||||
HCS_FOREACH_CHILD_VARGS(PLATFORM_PWM_CONFIG, PWM_FIND_CONFIG, deviceMatchAttr, resource);
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
#else
|
||||
@@ -151,7 +173,7 @@ static int32_t AttachPwmDevice(struct PwmDev *host, struct HdfDeviceObject *devi
|
||||
return HDF_ERR_MALLOC_FAIL;
|
||||
}
|
||||
#ifdef LOSCFG_DRIVERS_HDF_CONFIG_MACRO
|
||||
ret = GetPwmDeviceResource(pwmDevice);
|
||||
ret = GetPwmDeviceResource(pwmDevice, device->deviceMatchAttr);
|
||||
#else
|
||||
ret = GetPwmDeviceResource(pwmDevice, device->property);
|
||||
#endif
|
||||
|
||||
+37
-3
@@ -277,7 +277,7 @@ OUT:
|
||||
static int32_t HalSpiRecv(struct SpiDevice *spiDevice, uint8_t *data, uint16_t size, uint32_t timeOut)
|
||||
{
|
||||
int32_t ret;
|
||||
uint32_t len = size;
|
||||
int32_t len = (int32_t)size;
|
||||
uint32_t remainder;
|
||||
int32_t status = HDF_FAILURE;
|
||||
uint8_t *cmd = NULL;
|
||||
@@ -415,10 +415,44 @@ static int32_t InitSpiDevice(struct SpiDevice *spiDevice)
|
||||
|
||||
/* get spi config from hcs file */
|
||||
#ifdef LOSCFG_DRIVERS_HDF_CONFIG_MACRO
|
||||
#define SPI_FIND_CONFIG(node, name, resource) \
|
||||
do { \
|
||||
if (strcmp(HCS_PROP(node, match_attr), name) == 0) { \
|
||||
resource->num = HCS_PROP(node, busNum); \
|
||||
resource->speed = HCS_PROP(node, speed); \
|
||||
resource->transmode = HCS_PROP(node, transmode); \
|
||||
resource->spiCsSoft = HCS_PROP(node, spiCsSoft); \
|
||||
resource->mode = HCS_PROP(node, mode); \
|
||||
resource->dataSize = HCS_PROP(node, dataSize); \
|
||||
resource->csNum = HCS_PROP(node, csNum); \
|
||||
tempPin = HCS_PROP(node, spiClkPin); \
|
||||
resource->spiClkPin = ((tempPin / DEC_NUM) * GROUP_PIN_NUM) + (tempPin % DEC_NUM); \
|
||||
tempPin = HCS_PROP(node, spiMosiPin); \
|
||||
resource->spiMosiPin = ((tempPin / DEC_NUM) * GROUP_PIN_NUM) + (tempPin % DEC_NUM); \
|
||||
tempPin = HCS_PROP(node, spiMisoPin); \
|
||||
resource->spiMisoPin = ((tempPin / DEC_NUM) * GROUP_PIN_NUM) + (tempPin % DEC_NUM); \
|
||||
tempPin = HCS_PROP(node, spiCsPin); \
|
||||
resource->spiCsPin = ((tempPin / DEC_NUM) * GROUP_PIN_NUM) + (tempPin % DEC_NUM); \
|
||||
break; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define PLATFORM_SPI_CONFIG HCS_NODE(HCS_NODE(HCS_ROOT, platform), spi_config)
|
||||
static int32_t GetSpiDeviceResource(struct SpiDevice *spiDevice, const char *deviceMatchAttr)
|
||||
{
|
||||
(void)spiDevice;
|
||||
(void)deviceMatchAttr;
|
||||
uint32_t tempPin;
|
||||
struct SpiResource *resource = NULL;
|
||||
if (spiDevice == NULL) {
|
||||
HDF_LOGE("device or resourceNode is NULL\r\n");
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
resource = &spiDevice->resource;
|
||||
if (resource == NULL) {
|
||||
HDF_LOGE("%s %d: invalid parameter\r\n", __func__, __LINE__);
|
||||
return HDF_ERR_INVALID_OBJECT;
|
||||
}
|
||||
|
||||
HCS_FOREACH_CHILD_VARGS(PLATFORM_SPI_CONFIG, SPI_FIND_CONFIG, deviceMatchAttr, resource);
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
#else
|
||||
|
||||
@@ -0,0 +1,695 @@
|
||||
/*
|
||||
* Copyright (c) 2022 ASR Microelectronics (Shanghai) Co., Ltd. All rights reserved.
|
||||
*
|
||||
* 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 "uart/uart_core.h"
|
||||
#include "device_resource_if.h"
|
||||
#include "hdf_base.h"
|
||||
#include "hdf_log.h"
|
||||
#include "los_sem.h"
|
||||
#include "osal_mem.h"
|
||||
#include "duet_pinmux.h"
|
||||
#include "duet_uart.h"
|
||||
|
||||
#define ASR_UART_NUM DUET_UART_NUM
|
||||
#define asr_uart_config_t duet_uart_config_t
|
||||
#define asr_uart_dev_t duet_uart_dev_t
|
||||
#define asr_uart_struct_init duet_uart_struct_init
|
||||
#define asr_uart_dma_config duet_uart_dma_config
|
||||
#define asr_uart_init duet_uart_init
|
||||
#define asr_uart_send duet_uart_send
|
||||
#define asr_uart_finalize duet_uart_finalize
|
||||
#define asr_uart_start duet_uart_start
|
||||
#define asr_uart_stop duet_uart_stop
|
||||
#define asr_uart_set_callback duet_uart_set_callback
|
||||
#define asr_uart_calc_baud duet_uart_calc_baud
|
||||
#define asr_uart_interrupt_config duet_uart_interrupt_config
|
||||
#define asr_uart_clear_interrupt duet_uart_clear_interrupt
|
||||
#define asr_uart_get_raw_interrupt_status duet_uart_get_raw_interrupt_status
|
||||
#define asr_uart_get_interrupt_status duet_uart_get_interrupt_status
|
||||
#define asr_uart_get_flag_status duet_uart_get_flag_status
|
||||
#define asr_uart_callback_func duet_uart_callback_func
|
||||
#define asr_pinmux_config duet_pinmux_config
|
||||
|
||||
#define HDF_LOG_TAG uart_asr
|
||||
|
||||
#define DEFAULT_BAUDRATE 115200
|
||||
#define DEFAULT_DATABITS UART_ATTR_DATABIT_8
|
||||
#define DEFAULT_STOPBITS UART_ATTR_STOPBIT_1
|
||||
#define DEFAULT_PARITY UART_ATTR_PARITY_NONE
|
||||
#define CONFIG_MAX_BAUDRATE 921600
|
||||
#define UART_STATE_NOT_OPENED 0
|
||||
#define UART_STATE_OPENING 1
|
||||
#define UART_STATE_USEABLE 2
|
||||
#define UART_STATE_SUSPENED 3
|
||||
#define UART_FLG_DMA_RX (1 << 0)
|
||||
#define UART_FLG_DMA_TX (1 << 1)
|
||||
#define UART_FLG_RD_BLOCK (1 << 2)
|
||||
#define UART_TRANS_TIMEOUT 1000
|
||||
#define UART_RX_BUF_LEN 512
|
||||
|
||||
typedef int32_t (*app_uart_cfg_handler_t)(struct UartDriverData *udd);
|
||||
struct UartResource {
|
||||
uint32_t port;
|
||||
uint32_t pin_tx_pin;
|
||||
uint32_t pin_tx_mux;
|
||||
uint32_t pin_rx_pin;
|
||||
uint32_t pin_rx_mux;
|
||||
uint32_t tx_rx;
|
||||
};
|
||||
|
||||
struct UartDriverData {
|
||||
asr_uart_dev_t params;
|
||||
struct UartAttribute attr;
|
||||
struct UartResource resource;
|
||||
app_uart_cfg_handler_t config;
|
||||
int32_t count;
|
||||
int32_t state;
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
static uint32_t g_uartTxMutex[ASR_UART_NUM];
|
||||
static uint32_t g_uartRxMutex[ASR_UART_NUM];
|
||||
static uint8_t *rx_buf[ASR_UART_NUM];
|
||||
static uint16_t rx_head[ASR_UART_NUM];
|
||||
static uint16_t rx_tail[ASR_UART_NUM];
|
||||
|
||||
static void Uart0Callback(char data);
|
||||
static void Uart1Callback(char data);
|
||||
static void Uart2Callback(char data);
|
||||
|
||||
static const asr_uart_callback_func g_evtHandler[ASR_UART_NUM] = {
|
||||
Uart0Callback,
|
||||
Uart1Callback,
|
||||
Uart2Callback
|
||||
};
|
||||
|
||||
static void Uart0Callback(char data)
|
||||
{
|
||||
uint8_t *dst = rx_buf[UART0_INDEX];
|
||||
if (dst) {
|
||||
dst[rx_head[UART0_INDEX]++] = (uint8_t)data;
|
||||
rx_head[UART0_INDEX] %= UART_RX_BUF_LEN;
|
||||
}
|
||||
}
|
||||
|
||||
static void Uart1Callback(char data)
|
||||
{
|
||||
uint8_t *dst = rx_buf[UART1_INDEX];
|
||||
if (dst) {
|
||||
dst[rx_head[UART1_INDEX]++] = (uint8_t)data;
|
||||
rx_head[UART1_INDEX] %= UART_RX_BUF_LEN;
|
||||
}
|
||||
}
|
||||
static void Uart2Callback(char data)
|
||||
{
|
||||
uint8_t *dst = rx_buf[UART2_INDEX];
|
||||
if (dst) {
|
||||
dst[rx_head[UART2_INDEX]++] = (uint8_t)data;
|
||||
rx_head[UART2_INDEX] %= UART_RX_BUF_LEN;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t GetUartDataBits(uint32_t attrDataBits)
|
||||
{
|
||||
uint32_t dataBits;
|
||||
|
||||
switch (attrDataBits) {
|
||||
case UART_ATTR_DATABIT_5:
|
||||
dataBits = DATA_5BIT;
|
||||
break;
|
||||
case UART_ATTR_DATABIT_6:
|
||||
dataBits = DATA_6BIT;
|
||||
break;
|
||||
case UART_ATTR_DATABIT_7:
|
||||
dataBits = DATA_7BIT;
|
||||
break;
|
||||
case UART_ATTR_DATABIT_8:
|
||||
dataBits = DATA_8BIT;
|
||||
break;
|
||||
default:
|
||||
dataBits = DATA_8BIT;
|
||||
break;
|
||||
}
|
||||
|
||||
return dataBits;
|
||||
}
|
||||
|
||||
static uint32_t GetUartStopBits(uint32_t attrStopBits)
|
||||
{
|
||||
uint32_t stopBits;
|
||||
|
||||
switch (attrStopBits) {
|
||||
case UART_ATTR_STOPBIT_1:
|
||||
stopBits = STOP_1BIT;
|
||||
break;
|
||||
case UART_ATTR_STOPBIT_2:
|
||||
stopBits = STOP_2BITS;
|
||||
break;
|
||||
default:
|
||||
stopBits = STOP_1BIT;
|
||||
break;
|
||||
}
|
||||
|
||||
return stopBits;
|
||||
}
|
||||
|
||||
static uint32_t GetUartParity(uint32_t attrParity)
|
||||
{
|
||||
uint32_t parity;
|
||||
|
||||
switch (attrParity) {
|
||||
case UART_ATTR_PARITY_NONE:
|
||||
parity = PARITY_NO;
|
||||
break;
|
||||
case UART_ATTR_PARITY_ODD:
|
||||
parity = PARITY_ODD;
|
||||
break;
|
||||
case UART_ATTR_PARITY_EVEN:
|
||||
parity = PARITY_EVEN;
|
||||
break;
|
||||
default:
|
||||
parity = PARITY_NO;
|
||||
break;
|
||||
}
|
||||
|
||||
return parity;
|
||||
}
|
||||
|
||||
static uint32_t GetUartFlowControl(uint32_t rts, uint32_t cts)
|
||||
{
|
||||
uint32_t flow_control;
|
||||
|
||||
if (!rts && !cts) {
|
||||
flow_control = FLOW_CTRL_DISABLED;
|
||||
} else if (rts && cts) {
|
||||
flow_control = FLOW_CTRL_CTS_RTS;
|
||||
} else if (rts) {
|
||||
flow_control = FLOW_CTRL_RTS;
|
||||
} else {
|
||||
flow_control = FLOW_CTRL_CTS;
|
||||
}
|
||||
|
||||
return flow_control;
|
||||
}
|
||||
|
||||
static int32_t Asr582xUartConfig(struct UartDriverData *udd)
|
||||
{
|
||||
uint32_t ret;
|
||||
asr_uart_dev_t *params = NULL;
|
||||
|
||||
if (udd == NULL) {
|
||||
return HDF_FAILURE;
|
||||
}
|
||||
asr_pinmux_config(udd->resource.pin_tx_pin, udd->resource.pin_tx_mux);
|
||||
asr_pinmux_config(udd->resource.pin_rx_pin, udd->resource.pin_rx_mux);
|
||||
params = &udd->params;
|
||||
params->port = udd->resource.port;
|
||||
params->config.data_width = GetUartDataBits(udd->attr.dataBits);
|
||||
params->config.stop_bits = GetUartStopBits(udd->attr.stopBits);
|
||||
params->config.parity = GetUartParity(udd->attr.parity);
|
||||
params->config.flow_control = GetUartFlowControl(udd->attr.rts, udd->attr.cts);
|
||||
params->config.mode = udd->resource.tx_rx;
|
||||
params->priv = (void *)g_evtHandler[udd->resource.port];
|
||||
|
||||
ret = asr_uart_init(params);
|
||||
if (ret != 0) {
|
||||
HDF_LOGE("%s , app uart init failed\r\n", __func__);
|
||||
return HDF_FAILURE;
|
||||
}
|
||||
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t UartHostDevRead(struct UartHost *host, uint8_t *data, uint32_t size)
|
||||
{
|
||||
int32_t ret;
|
||||
uint32_t uwRet = 0;
|
||||
uint32_t recv_len = 0;
|
||||
struct UartDriverData *udd = NULL;
|
||||
uint8_t port = 0;
|
||||
uint8_t *src = NULL;
|
||||
|
||||
if ((host == NULL) || (host->priv == NULL) || (data == NULL)) {
|
||||
HDF_LOGE("%s: invalid parameter", __func__);
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
udd = (struct UartDriverData *)host->priv;
|
||||
port = udd->resource.port;
|
||||
src = rx_buf[port];
|
||||
if (udd->state != UART_STATE_USEABLE) {
|
||||
HDF_LOGE("%s: uart_%d not useable", __func__, port);
|
||||
return HDF_FAILURE;
|
||||
}
|
||||
|
||||
LOS_MuxPend(g_uartRxMutex[port], LOS_WAIT_FOREVER);
|
||||
if (udd->flags & UART_FLG_RD_BLOCK) {
|
||||
while (recv_len != size) {
|
||||
if (rx_head[port] != rx_tail[port]) {
|
||||
data[recv_len++] = src[rx_tail[port]++];
|
||||
rx_tail[port] %= UART_RX_BUF_LEN;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
while ((recv_len != size) && (rx_head[port] != rx_tail[port])) {
|
||||
data[recv_len++] = src[rx_tail[port]++];
|
||||
rx_tail[port] %= UART_RX_BUF_LEN;
|
||||
}
|
||||
}
|
||||
LOS_MuxPost(g_uartRxMutex[port]);
|
||||
|
||||
return recv_len;
|
||||
}
|
||||
|
||||
static int32_t UartHostDevWrite(struct UartHost *host, uint8_t *data, uint32_t size)
|
||||
{
|
||||
int32_t ret;
|
||||
struct UartDriverData *udd = NULL;
|
||||
|
||||
if ((host == NULL) || (host->priv == NULL) || (data == NULL)) {
|
||||
HDF_LOGE("%s: invalid parameter", __func__);
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
udd = (struct UartDriverData *)host->priv;
|
||||
if (udd->state != UART_STATE_USEABLE) {
|
||||
HDF_LOGE("%s: uart_%d not useable", __func__, udd->resource.port);
|
||||
return HDF_FAILURE;
|
||||
}
|
||||
|
||||
LOS_MuxPend(g_uartTxMutex[udd->resource.port], LOS_WAIT_FOREVER);
|
||||
ret = asr_uart_send(&udd->params, data, size, UART_TRANS_TIMEOUT);
|
||||
if (ret != 0) {
|
||||
LOS_MuxPost(g_uartTxMutex[udd->resource.port]);
|
||||
HDF_LOGE("%s: uart_%d send %d data failed", __func__, udd->resource.port, size);
|
||||
return HDF_FAILURE;
|
||||
}
|
||||
LOS_MuxPost(g_uartTxMutex[udd->resource.port]);
|
||||
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t UartHostDevGetBaud(struct UartHost *host, uint32_t *baudRate)
|
||||
{
|
||||
struct UartDriverData *udd = NULL;
|
||||
|
||||
if (host == NULL || host->priv == NULL || baudRate == NULL) {
|
||||
HDF_LOGE("%s: invalid parameter", __func__);
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
udd = (struct UartDriverData *)host->priv;
|
||||
if (udd->state != UART_STATE_USEABLE) {
|
||||
HDF_LOGE("%s: uart_%d not useable", __func__, udd->resource.port);
|
||||
return HDF_FAILURE;
|
||||
}
|
||||
*baudRate = udd->params.config.baud_rate;
|
||||
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t UartHostDevSetBaud(struct UartHost *host, uint32_t baudRate)
|
||||
{
|
||||
struct UartDriverData *udd = NULL;
|
||||
|
||||
if (host == NULL || host->priv == NULL) {
|
||||
HDF_LOGE("%s: invalid parameter", __func__);
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
udd = (struct UartDriverData *)host->priv;
|
||||
if (udd->state != UART_STATE_USEABLE) {
|
||||
HDF_LOGE("%s: uart_%d not useable", __func__, udd->resource.port);
|
||||
return HDF_FAILURE;
|
||||
}
|
||||
if ((baudRate > 0) && (baudRate <= CONFIG_MAX_BAUDRATE)) {
|
||||
udd->params.config.baud_rate = baudRate;
|
||||
if (udd->config == NULL) {
|
||||
HDF_LOGE("%s: not support", __func__);
|
||||
return HDF_ERR_NOT_SUPPORT;
|
||||
}
|
||||
if (udd->config(udd) != HDF_SUCCESS) {
|
||||
HDF_LOGE("%s: config baudrate %d failed", __func__, baudRate);
|
||||
return HDF_FAILURE;
|
||||
}
|
||||
} else {
|
||||
HDF_LOGE("%s: invalid baudrate, which is:%d", __func__, baudRate);
|
||||
return HDF_FAILURE;
|
||||
}
|
||||
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t UartHostDevGetAttribute(struct UartHost *host, struct UartAttribute *attribute)
|
||||
{
|
||||
struct UartDriverData *udd = NULL;
|
||||
|
||||
if (host == NULL || host->priv == NULL || attribute == NULL) {
|
||||
HDF_LOGE("%s: invalid parameter", __func__);
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
udd = (struct UartDriverData *)host->priv;
|
||||
if (udd->state != UART_STATE_USEABLE) {
|
||||
return HDF_FAILURE;
|
||||
}
|
||||
|
||||
*attribute = udd->attr;
|
||||
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t UartHostDevSetAttribute(struct UartHost *host, struct UartAttribute *attribute)
|
||||
{
|
||||
struct UartDriverData *udd = NULL;
|
||||
|
||||
if (host == NULL || host->priv == NULL || attribute == NULL) {
|
||||
HDF_LOGE("%s: invalid parameter", __func__);
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
udd = (struct UartDriverData *)host->priv;
|
||||
if (udd->state != UART_STATE_USEABLE) {
|
||||
HDF_LOGE("%s: uart_%d not useable", __func__, udd->resource.port);
|
||||
return HDF_FAILURE;
|
||||
}
|
||||
|
||||
udd->attr = *attribute;
|
||||
if (udd->config == NULL) {
|
||||
HDF_LOGE("%s: not support", __func__);
|
||||
return HDF_ERR_NOT_SUPPORT;
|
||||
}
|
||||
if (udd->config(udd) != HDF_SUCCESS) {
|
||||
HDF_LOGE("%s: config failed", __func__);
|
||||
return HDF_FAILURE;
|
||||
}
|
||||
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t UartHostDevSetTransMode(struct UartHost *host, enum UartTransMode mode)
|
||||
{
|
||||
struct UartDriverData *udd = NULL;
|
||||
|
||||
if (host == NULL || host->priv == NULL) {
|
||||
HDF_LOGE("%s: invalid parameter", __func__);
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
udd = (struct UartDriverData *)host->priv;
|
||||
if (udd->state != UART_STATE_USEABLE) {
|
||||
HDF_LOGE("%s: uart_%d not useable", __func__, udd->resource.port);
|
||||
return HDF_FAILURE;
|
||||
}
|
||||
if (UART_MODE_RD_BLOCK == mode) {
|
||||
udd->flags |= UART_FLG_RD_BLOCK;
|
||||
} else if (UART_MODE_RD_NONBLOCK == mode) {
|
||||
udd->flags &= (~UART_FLG_RD_BLOCK);
|
||||
} else {
|
||||
HDF_LOGE("%s: uart_%d not support mode:%d", __func__, udd->resource.port, mode);
|
||||
return HDF_FAILURE;
|
||||
}
|
||||
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t UartDevSemInit(uint32_t id)
|
||||
{
|
||||
uint32_t uwRet = 0;
|
||||
|
||||
uwRet = LOS_MuxCreate(&g_uartTxMutex[id]);
|
||||
if (uwRet != LOS_OK) {
|
||||
return HDF_FAILURE;
|
||||
}
|
||||
|
||||
uwRet = LOS_MuxCreate(&g_uartRxMutex[id]);
|
||||
if (uwRet != LOS_OK) {
|
||||
return HDF_FAILURE;
|
||||
}
|
||||
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
static void UartDevSemDeinit(uint32_t id)
|
||||
{
|
||||
if (g_uartTxMutex[id] != 0) {
|
||||
LOS_MuxDelete(g_uartTxMutex[id]);
|
||||
}
|
||||
|
||||
if (g_uartRxMutex[id] != 0) {
|
||||
LOS_MuxDelete(g_uartRxMutex[id]);
|
||||
}
|
||||
|
||||
g_uartTxMutex[id] = 0;
|
||||
g_uartRxMutex[id] = 0;
|
||||
}
|
||||
|
||||
static int32_t UartHostDevInit(struct UartHost *host)
|
||||
{
|
||||
struct UartDriverData *udd = NULL;
|
||||
uint32_t ret = 0;
|
||||
uint8_t *ptxBuf = NULL;
|
||||
|
||||
if (host == NULL || host->priv == NULL) {
|
||||
HDF_LOGE("%s: invalid parameter", __func__);
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
udd = (struct UartDriverData *)host->priv;
|
||||
if (udd->resource.port >= ASR_UART_NUM) {
|
||||
HDF_LOGE("%s: uart id is greater than the maximum", __func__);
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (udd->state == UART_STATE_NOT_OPENED) {
|
||||
udd->state = UART_STATE_OPENING;
|
||||
|
||||
ptxBuf = (uint8_t *)OsalMemCalloc(UART_RX_BUF_LEN);
|
||||
if (ptxBuf == NULL) {
|
||||
HDF_LOGE("%s: alloc tx buffer failed", __func__);
|
||||
return HDF_ERR_MALLOC_FAIL;
|
||||
}
|
||||
|
||||
ret = UartDevSemInit(udd->resource.port);
|
||||
if (ret != HDF_SUCCESS) {
|
||||
HDF_LOGE("%s: uart semaphor init failed", __func__);
|
||||
UartDevSemDeinit(udd->resource.port);
|
||||
return HDF_FAILURE;
|
||||
}
|
||||
|
||||
rx_buf[udd->resource.port] = ptxBuf;
|
||||
udd->config = Asr582xUartConfig;
|
||||
|
||||
if (udd->config(udd) != HDF_SUCCESS) {
|
||||
UartDevSemDeinit(udd->resource.port);
|
||||
(void)OsalMemFree(rx_buf[udd->resource.port]);
|
||||
rx_buf[udd->resource.port] = NULL;
|
||||
return HDF_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
udd->state = UART_STATE_USEABLE;
|
||||
udd->count++;
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t UartHostDevDeinit(struct UartHost *host)
|
||||
{
|
||||
struct UartDriverData *udd = NULL;
|
||||
if (host == NULL || host->priv == NULL) {
|
||||
HDF_LOGE("%s: invalid parameter", __func__);
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
udd = (struct UartDriverData *)host->priv;
|
||||
if ((--udd->count) != 0) {
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
asr_uart_finalize(&udd->params);
|
||||
UartDevSemDeinit(udd->resource.port);
|
||||
if (rx_buf[udd->resource.port] != NULL) {
|
||||
(void)OsalMemFree(rx_buf[udd->resource.port]);
|
||||
rx_buf[udd->resource.port] = NULL;
|
||||
}
|
||||
|
||||
udd->state = UART_STATE_NOT_OPENED;
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
struct UartHostMethod g_uartHostMethod = {
|
||||
.Init = UartHostDevInit,
|
||||
.Deinit = UartHostDevDeinit,
|
||||
.Read = UartHostDevRead,
|
||||
.Write = UartHostDevWrite,
|
||||
.SetBaud = UartHostDevSetBaud,
|
||||
.GetBaud = UartHostDevGetBaud,
|
||||
.SetAttribute = UartHostDevSetAttribute,
|
||||
.GetAttribute = UartHostDevGetAttribute,
|
||||
.SetTransMode = UartHostDevSetTransMode,
|
||||
};
|
||||
|
||||
static int32_t UartGetPinConfigFromHcs(struct UartDriverData *udd, const struct DeviceResourceNode *node)
|
||||
{
|
||||
uint32_t resourceData;
|
||||
struct DeviceResourceIface *iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
|
||||
|
||||
if (iface == NULL || iface->GetUint32 == NULL) {
|
||||
HDF_LOGE("%s: face is invalid", __func__);
|
||||
return HDF_FAILURE;
|
||||
}
|
||||
|
||||
if (iface->GetUint32(node, "port", &resourceData, 0) != HDF_SUCCESS) {
|
||||
HDF_LOGE("%s: read port fail", __func__);
|
||||
return HDF_FAILURE;
|
||||
}
|
||||
udd->resource.port = resourceData;
|
||||
|
||||
if (iface->GetUint32(node, "pin_tx_pin", &resourceData, 0) != HDF_SUCCESS) {
|
||||
HDF_LOGE("%s: read pin_tx_pin fail", __func__);
|
||||
return HDF_FAILURE;
|
||||
}
|
||||
udd->resource.pin_tx_pin = resourceData;
|
||||
|
||||
if (iface->GetUint32(node, "pin_tx_mux", &resourceData, 0) != HDF_SUCCESS) {
|
||||
HDF_LOGE("%s: read pin_tx_pin fail", __func__);
|
||||
return HDF_FAILURE;
|
||||
}
|
||||
udd->resource.pin_tx_mux = resourceData;
|
||||
|
||||
if (iface->GetUint32(node, "pin_rx_pin", &resourceData, 0) != HDF_SUCCESS) {
|
||||
HDF_LOGE("%s: read pin_rx_pin fail", __func__);
|
||||
return HDF_FAILURE;
|
||||
}
|
||||
udd->resource.pin_rx_pin = resourceData;
|
||||
|
||||
if (iface->GetUint32(node, "pin_rx_mux", &resourceData, 0) != HDF_SUCCESS) {
|
||||
HDF_LOGE("%s: read pin_rx_pin fail", __func__);
|
||||
return HDF_FAILURE;
|
||||
}
|
||||
udd->resource.pin_rx_mux = resourceData;
|
||||
|
||||
if (iface->GetUint32(node, "tx_rx", &resourceData, 0) != HDF_SUCCESS) {
|
||||
HDF_LOGE("%s: read tx_rx fail", __func__);
|
||||
return HDF_FAILURE;
|
||||
}
|
||||
udd->resource.tx_rx = resourceData;
|
||||
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t UartDevAttach(struct UartHost *host, struct HdfDeviceObject *device)
|
||||
{
|
||||
int32_t ret;
|
||||
struct UartDriverData *udd = NULL;
|
||||
|
||||
if (device->property == NULL) {
|
||||
HDF_LOGE("%s: property is null", __func__);
|
||||
return HDF_FAILURE;
|
||||
}
|
||||
udd = (struct UartDriverData *)OsalMemCalloc(sizeof(*udd));
|
||||
if (udd == NULL) {
|
||||
HDF_LOGE("%s: OsalMemCalloc udd error", __func__);
|
||||
return HDF_ERR_MALLOC_FAIL;
|
||||
}
|
||||
|
||||
ret = UartGetPinConfigFromHcs(udd, device->property);
|
||||
if (ret != HDF_SUCCESS) {
|
||||
(void)OsalMemFree(udd);
|
||||
return HDF_FAILURE;
|
||||
}
|
||||
|
||||
udd->state = UART_STATE_NOT_OPENED;
|
||||
udd->config = NULL;
|
||||
udd->count = 0;
|
||||
|
||||
asr_uart_struct_init(&udd->params);
|
||||
udd->params.port = udd->resource.port;
|
||||
udd->params.config.baud_rate = DEFAULT_BAUDRATE;
|
||||
udd->attr.dataBits = DEFAULT_DATABITS;
|
||||
udd->attr.stopBits = DEFAULT_STOPBITS;
|
||||
udd->attr.parity = DEFAULT_PARITY;
|
||||
|
||||
host->priv = udd;
|
||||
host->num = udd->resource.port;
|
||||
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
static void UartDevDetach(struct UartHost *host)
|
||||
{
|
||||
struct UartDriverData *udd = NULL;
|
||||
|
||||
if (host->priv == NULL) {
|
||||
HDF_LOGE("%s: invalid parameter", __func__);
|
||||
return;
|
||||
}
|
||||
udd = (struct UartDriverData *)host->priv;
|
||||
if (udd->state != UART_STATE_NOT_OPENED) {
|
||||
HDF_LOGE("%s: uart driver data state invalid", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
(void)OsalMemFree(udd);
|
||||
host->priv = NULL;
|
||||
}
|
||||
|
||||
static int32_t HdfUartDeviceBind(struct HdfDeviceObject *device)
|
||||
{
|
||||
if (device == NULL) {
|
||||
return HDF_ERR_INVALID_OBJECT;
|
||||
}
|
||||
return (UartHostCreate(device) == NULL) ? HDF_FAILURE : HDF_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t HdfUartDeviceInit(struct HdfDeviceObject *device)
|
||||
{
|
||||
int32_t ret;
|
||||
struct UartHost *host = NULL;
|
||||
|
||||
if (device == NULL) {
|
||||
HDF_LOGE("%s: device is null", __func__);
|
||||
return HDF_ERR_INVALID_OBJECT;
|
||||
}
|
||||
host = UartHostFromDevice(device);
|
||||
if (host == NULL) {
|
||||
HDF_LOGE("%s: host is null", __func__);
|
||||
return HDF_FAILURE;
|
||||
}
|
||||
ret = UartDevAttach(host, device);
|
||||
if (ret != HDF_SUCCESS) {
|
||||
HDF_LOGE("%s: attach error", __func__);
|
||||
return HDF_FAILURE;
|
||||
}
|
||||
host->method = &g_uartHostMethod;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void HdfUartDeviceRelease(struct HdfDeviceObject *device)
|
||||
{
|
||||
struct UartHost *host = NULL;
|
||||
|
||||
if (device == NULL) {
|
||||
HDF_LOGE("%s: device is null", __func__);
|
||||
return;
|
||||
}
|
||||
host = UartHostFromDevice(device);
|
||||
if (host == NULL) {
|
||||
HDF_LOGE("%s: host is null", __func__);
|
||||
return;
|
||||
}
|
||||
if (host->priv != NULL) {
|
||||
UartDevDetach(host);
|
||||
}
|
||||
UartHostDestroy(host);
|
||||
}
|
||||
|
||||
struct HdfDriverEntry g_hdfUartDevice = {
|
||||
.moduleVersion = 1,
|
||||
.moduleName = "HDF_PLATFORM_UART",
|
||||
.Bind = HdfUartDeviceBind,
|
||||
.Init = HdfUartDeviceInit,
|
||||
.Release = HdfUartDeviceRelease,
|
||||
};
|
||||
|
||||
HDF_INIT(g_hdfUartDevice);
|
||||
@@ -223,7 +223,7 @@ static int32_t HalUartRecv(uint8_t uartId, void *data, uint32_t expectSize,
|
||||
uint32_t nowTime;
|
||||
uint32_t fifoPopLen;
|
||||
uint32_t recvedLen = 0;
|
||||
uint32_t expectLen = expectSize;
|
||||
int32_t expectLen = (int32_t)expectSize;
|
||||
|
||||
if (data == NULL || expectLen == 0 || recvSize == NULL) {
|
||||
HDF_LOGE("%s %d Invalid input \r\n", __FILE__, __LINE__);
|
||||
@@ -459,10 +459,44 @@ static int InitUartDevice(struct UartHost *host)
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
#ifdef LOSCFG_DRIVERS_HDF_CONFIG_MACRO
|
||||
#define UART_FIND_CONFIG(node, name, resource) \
|
||||
do { \
|
||||
if (strcmp(HCS_PROP(node, match_attr), name) == 0) { \
|
||||
resource->num = HCS_PROP(node, num); \
|
||||
resource->baudRate = HCS_PROP(node, baudRate); \
|
||||
resource->parity = HCS_PROP(node, parity); \
|
||||
resource->stopBit = HCS_PROP(node, stopBit); \
|
||||
resource->wLen = HCS_PROP(node, data); \
|
||||
resource->rxDMA = HCS_PROP(node, rxDMA); \
|
||||
resource->txDMA = HCS_PROP(node, txDMA); \
|
||||
break; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define PLATFORM_UART_CONFIG HCS_NODE(HCS_NODE(HCS_ROOT, platform), uart_config)
|
||||
static uint32_t GetUartDeviceResource(struct UartDevice *device, const char *deviceMatchAttr)
|
||||
{
|
||||
(void)device;
|
||||
(void)deviceMatchAttr;
|
||||
struct UartResource *resource = NULL;
|
||||
if (device == NULL || deviceMatchAttr == NULL) {
|
||||
HDF_LOGE("device or resourceNode is NULL\r\n");
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
resource = &device->resource;
|
||||
if (resource == NULL) {
|
||||
HDF_LOGE("%s %d: invalid parameter\r\n", __func__, __LINE__);
|
||||
return HDF_ERR_INVALID_OBJECT;
|
||||
}
|
||||
|
||||
HCS_FOREACH_CHILD_VARGS(PLATFORM_UART_CONFIG, UART_FIND_CONFIG, deviceMatchAttr, resource);
|
||||
// copy config
|
||||
device->initFlag = false;
|
||||
device->uartId = resource->num;
|
||||
device->config.baud = resource->baudRate;
|
||||
device->config.parity = resource->parity;
|
||||
device->config.stop = resource->stopBit;
|
||||
device->config.data = resource->wLen;
|
||||
device->config.dma_rx = (resource->rxDMA == true) ? true : false;
|
||||
device->config.dma_tx = (resource->txDMA == true) ? true : false;
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
#else
|
||||
|
||||
+2
-1
@@ -17,7 +17,8 @@ import("$hdf_framework_path/tools/hc-gen/hc_gen.gni")
|
||||
|
||||
hc_gen("build_hcs") {
|
||||
gadget = "acm"
|
||||
if (product_name == "Hi3516DV300" || product_name == "watchos") {
|
||||
if (product_name == "Hi3516DV300" || product_name == "watchos" ||
|
||||
product_name == "rk3568") {
|
||||
gadget = "ecm_acm"
|
||||
}
|
||||
hcs_source = "/hdf.hcs"
|
||||
|
||||
+3
-1
@@ -180,7 +180,9 @@ template("hdi") {
|
||||
external_deps = [ "hilog:libhilog" ]
|
||||
}
|
||||
|
||||
if (invoker.language == "cpp") {
|
||||
if (invoker.language == "c") {
|
||||
deps += [ "$hdf_uhdf_path/host:libhdf_host" ]
|
||||
} else if (invoker.language == "cpp") {
|
||||
external_deps += [ "ipc:ipc_single" ]
|
||||
}
|
||||
|
||||
|
||||
@@ -161,6 +161,13 @@
|
||||
"uid" : "root",
|
||||
"gid" : ["system"]
|
||||
},
|
||||
{
|
||||
"name" : "connected_tag_host",
|
||||
"dynamic" : true,
|
||||
"path" : ["/vendor/bin/hdf_devhost"],
|
||||
"uid" : "root",
|
||||
"gid" : ["system"]
|
||||
},
|
||||
{
|
||||
"name" : "a2dp_host",
|
||||
"dynamic" : true,
|
||||
|
||||
Reference in New Issue
Block a user