From c6d22e963cbd1b46dad1e1f707e6c5366f173a23 Mon Sep 17 00:00:00 2001 From: haizhouyang Date: Wed, 28 Apr 2021 11:05:07 +0800 Subject: [PATCH 1/3] add common dev node support for platform --- khdf/liteos/Makefile | 7 +- khdf/liteos/lite.mk | 1 + khdf/liteos/platform/include/gpio_dev.h | 76 +++ khdf/liteos/platform/include/i2c_dev.h | 81 +++ khdf/liteos/platform/include/mipi_tx_dev.h | 103 ++++ khdf/liteos/platform/include/spi_dev.h | 57 +++ khdf/liteos/platform/include/uart_dev.h | 79 +++ khdf/liteos/platform/src/gpio_dev.c | 163 ++++++ khdf/liteos/platform/src/i2c_dev.c | 492 +++++++++++++++++++ khdf/liteos/platform/{ => src}/plat_common.c | 0 khdf/liteos/platform/src/spi_dev.c | 448 +++++++++++++++++ khdf/liteos/platform/src/uart_dev.c | 277 +++++++++++ 12 files changed, 1783 insertions(+), 1 deletion(-) create mode 100644 khdf/liteos/platform/include/gpio_dev.h create mode 100644 khdf/liteos/platform/include/i2c_dev.h create mode 100644 khdf/liteos/platform/include/mipi_tx_dev.h create mode 100644 khdf/liteos/platform/include/spi_dev.h create mode 100644 khdf/liteos/platform/include/uart_dev.h create mode 100644 khdf/liteos/platform/src/gpio_dev.c create mode 100644 khdf/liteos/platform/src/i2c_dev.c rename khdf/liteos/platform/{ => src}/plat_common.c (100%) create mode 100644 khdf/liteos/platform/src/spi_dev.c create mode 100644 khdf/liteos/platform/src/uart_dev.c diff --git a/khdf/liteos/Makefile b/khdf/liteos/Makefile index 681b79e..8859aed 100644 --- a/khdf/liteos/Makefile +++ b/khdf/liteos/Makefile @@ -86,17 +86,19 @@ LOCAL_SRCS := ./osal/src/osal_timer.c \ $(HDF_FRAMEWORKS)/ability/config/device_resource_if.c ifeq ($(LOSCFG_DRIVERS_HDF_PLATFORM), y) - LOCAL_SRCS += ./platform/plat_common.c + LOCAL_SRCS += ./platform/src/plat_common.c endif ifeq ($(LOSCFG_DRIVERS_HDF_PLATFORM_I2C), y) LOCAL_SRCS += $(HDF_FRAMEWORKS)/support/platform/src/i2c_if.c \ $(HDF_FRAMEWORKS)/support/platform/src/i2c_core.c + LOCAL_SRCS += ./platform/src/i2c_dev.c endif ifeq ($(LOSCFG_DRIVERS_HDF_PLATFORM_GPIO), y) LOCAL_SRCS += $(HDF_FRAMEWORKS)/support/platform/src/gpio_if.c \ $(HDF_FRAMEWORKS)/support/platform/src/gpio_core.c + LOCAL_SRCS += ./platform/src/gpio_dev.c endif ifeq ($(LOSCFG_DRIVERS_HDF_PLATFORM_WATCHDOG), y) @@ -107,6 +109,7 @@ endif ifeq ($(LOSCFG_DRIVERS_HDF_PLATFORM_SPI), y) LOCAL_SRCS += $(HDF_FRAMEWORKS)/support/platform/src/spi_if.c \ $(HDF_FRAMEWORKS)/support/platform/src/spi_core.c + LOCAL_SRCS += ./platform/src/spi_dev.c endif ifeq ($(LOSCFG_DRIVERS_HDF_PLATFORM_PWM), y) @@ -131,6 +134,7 @@ endif ifeq ($(LOSCFG_DRIVERS_HDF_PLATFORM_MIPI_DSI), y) LOCAL_SRCS += $(HDF_FRAMEWORKS)/support/platform/src/mipi_dsi_core.c +# LOCAL_SRCS += ./platform/src/mipi_tx_dev.c endif ifeq ($(LOSCFG_DRIVERS_HDF_PLATFORM_DMAC), y) @@ -140,6 +144,7 @@ endif ifeq ($(LOSCFG_DRIVERS_HDF_PLATFORM_UART), y) LOCAL_SRCS += $(HDF_FRAMEWORKS)/support/platform/src/uart_if.c \ $(HDF_FRAMEWORKS)/support/platform/src/uart_core.c + LOCAL_SRCS += ./platform/src/uart_dev.c endif ifeq ($(LOSCFG_NET_LWIP_SACK), y) diff --git a/khdf/liteos/lite.mk b/khdf/liteos/lite.mk index 5576581..095e5b3 100644 --- a/khdf/liteos/lite.mk +++ b/khdf/liteos/lite.mk @@ -50,6 +50,7 @@ HDF_INCLUDE += -I $(HDF_ROOT_DIR)/framework/core/common/include/manager HDF_INCLUDE += -I $(HDF_ROOT_DIR)/framework/core/common/include/host HDF_INCLUDE += -I $(HDF_ROOT_DIR)/adapter/khdf/liteos/network/include HDF_INCLUDE += -I $(HDF_ROOT_DIR)/adapter/khdf/liteos/osal/include +HDF_INCLUDE += -I $(HDF_ROOT_DIR)/adapter/khdf/liteos/platform/include HDF_INCLUDE += -I $(HDF_ROOT_DIR)/framework/core/adapter/vnode/include HDF_INCLUDE += -I $(HDF_ROOT_DIR)/framework/core/adapter/syscall/include HDF_INCLUDE += -I $(LITEOSTOPDIR)/bsd/compat/linuxkpi/include diff --git a/khdf/liteos/platform/include/gpio_dev.h b/khdf/liteos/platform/include/gpio_dev.h new file mode 100644 index 0000000..0c1f675 --- /dev/null +++ b/khdf/liteos/platform/include/gpio_dev.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2020-2021 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: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef GPIO_USER_H +#define GPIO_USER_H +#include "fcntl.h" +#include "hdf_base.h" +#include "sys/ioctl.h" + +#define PL061_GPIO_USER_SUPPORT + +int32_t GpioAddVfs(uint16_t bitNum); +void GpioRemoveVfs(void); + +typedef void (*irq_func)(unsigned int irq, void *data); + +typedef struct GpioBitInfo { + unsigned int groupnumber; + unsigned int bitnumber; + + unsigned char value; +#define GPIO_VALUE_HIGH 1 +#define GPIO_VALUE_LOW 0 + unsigned char direction; +#define GPIO_DIRECTION_IN 0 +#define GPIO_DIRECTION_IN_OUT 1 + + unsigned char irq_status; + unsigned char irq_enable; +#define GPIO_IRQ_ENABLE 1 +#define GPIO_IRQ_DISABLE 0 + irq_func irq_handler; + unsigned int irq_type; +#define IRQ_TYPE_NONE 0x00000000 +#define IRQ_TYPE_EDGE_RISING 0x00000001 +#define IRQ_TYPE_EDGE_FALLING 0x00000002 +#define IRQ_TYPE_EDGE_BOTH (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING) +#define IRQ_TYPE_LEVEL_HIGH 0x00000004 +#define IRQ_TYPE_LEVEL_LOW 0x00000008 +#define IRQ_TYPE_LEVEL_MASK (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH) + void *data; +} gpio_groupbit_info; + +#define GPIO_SET_DIR _IOWR('w', 4, gpio_groupbit_info) +#define GPIO_GET_DIR _IOWR('r', 5, gpio_groupbit_info) +#define GPIO_READ_BIT _IOWR('r', 6, gpio_groupbit_info) +#define GPIO_WRITE_BIT _IOWR('w', 7, gpio_groupbit_info) + +#endif diff --git a/khdf/liteos/platform/include/i2c_dev.h b/khdf/liteos/platform/include/i2c_dev.h new file mode 100644 index 0000000..144412e --- /dev/null +++ b/khdf/liteos/platform/include/i2c_dev.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2020-2021 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: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef I2C_USER_H +#define I2C_USER_H + +#include "hdf_base.h" + +enum I2cIoctlCmd { + IOCTL_RETRIES = 0x0701, + IOCTL_TIMEOUT = 0x0702, + IOCTL_SLAVE = 0x0703, + IOCTL_SLAVE_FORCE = 0x0706, + IOCTL_TENBIT = 0x0704, + IOCTL_FUNCS = 0x0705, + IOCTL_RDWR = 0x0707, + IOCTL_PEC = 0x0708, + IOCTL_SMBUS = 0x0720, + IOCTL_16BIT_REG = 0x0709, /* 16BIT REG WIDTH */ + IOCTL_16BIT_DATA = 0x070a, /* 16BIT DATA WIDTH */ +}; + +enum I2cMsgFlag { + I2C_M_RD = 0x0001, + I2C_M_TEN = 0x0010, + I2C_M_RECV_LEN = 0x0400, + I2C_M_NO_RD_ACK = 0x0800, + I2C_M_IGNORE_NAK = 0x1000, + I2C_M_REV_DIR_ADDR = 0x2000, + I2C_M_NOSTART = 0x4000, + I2C_M_STOP = 0x8000, +#ifdef __LITEOS__ + I2C_M_16BIT_DATA = 0x0008, + I2C_M_16BIT_REG = 0x0002, +#endif +}; + +typedef struct i2c_msg { + uint16_t addr; + uint16_t flags; + uint16_t len; + uint8_t *buf; +} I2cMsgUser; + +typedef struct i2c_rdwr_ioctl_data { + struct i2c_msg *msgs; + unsigned int nmsgs; +} I2cIoctlWrap; + +int32_t I2cAddVfsById(int16_t id); + +void I2cRemoveVfsById(int16_t id); + +#endif /* I2C_USER_H */ diff --git a/khdf/liteos/platform/include/mipi_tx_dev.h b/khdf/liteos/platform/include/mipi_tx_dev.h new file mode 100644 index 0000000..06c1ded --- /dev/null +++ b/khdf/liteos/platform/include/mipi_tx_dev.h @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2020-2021 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: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef MIPI_TX_DEV_H +#define MIPI_TX_DEV_H + +#define CMD_MAX_NUM 4 +#define LANE_MAX_NUM 4 +#define MIPI_TX_DISABLE_LANE_ID (-1) +#define MIPI_TX_SET_DATA_SIZE 800 +#define MIPI_TX_GET_DATA_SIZE 160 + + +typedef enum { + OUTPUT_MODE_CSI = 0x0, /* csi mode */ + OUTPUT_MODE_DSI_VIDEO = 0x1, /* dsi video mode */ + OUTPUT_MODE_DSI_CMD = 0x2, /* dsi command mode */ + OUTPUT_MODE_BUTT +} OutPutModeTag; + +typedef enum { + BURST_MODE = 0x0, + NON_BURST_MODE_SYNC_PULSES = 0x1, + NON_BURST_MODE_SYNC_EVENTS = 0x2, + VIDEO_DATA_MODE_BUTT +} VideoModeTag; + +typedef enum { + OUT_FORMAT_RGB_16_BIT = 0x0, + OUT_FORMAT_RGB_18_BIT = 0x1, + OUT_FORMAT_RGB_24_BIT = 0x2, + OUT_FORMAT_YUV420_8_BIT_NORMAL = 0x3, + OUT_FORMAT_YUV420_8_BIT_LEGACY = 0x4, + OUT_FORMAT_YUV422_8_BIT = 0x5, + OUT_FORMAT_BUTT +} OutputFormatTag; + +typedef struct { + unsigned short vidPktSize; + unsigned short vidHsaPixels; + unsigned short vidHbpPixels; + unsigned short vidHlinePixels; + unsigned short vidVsaLines; + unsigned short vidVbpLines; + unsigned short vidVfpLines; + unsigned short vidActiveLines; + unsigned short edpiCmdSize; +} SyncInfoTag; + +typedef struct { + unsigned int devno; /* device number */ + short laneId[LANE_MAX_NUM]; /* lane_id: -1 - disable */ + OutPutModeTag outputMode; /* output mode: CSI/DSI_VIDEO/DSI_CMD */ + VideoModeTag videoMode; + OutputFormatTag outputFormat; + SyncInfoTag syncInfo; + unsigned int phyDataRate; /* mbps */ + unsigned int pixelClk; /* KHz */ +} ComboDevCfgTag; + +typedef struct { + unsigned int devno; /* device number */ + unsigned short dataType; + unsigned short cmdSize; + unsigned char *cmd; +} CmdInfoTag; + +typedef struct { + unsigned int devno; /* device number */ + unsigned short dataType; /* DSI data type */ + unsigned short dataParam; /* data param,low 8 bit:1st param.high 8 bit:2st param, set 0 if not use */ + unsigned short getDataSize; /* read data size */ + unsigned char *getData; /* read data memery address, should malloc by user */ +} GetCmdInfoTag; + +#endif diff --git a/khdf/liteos/platform/include/spi_dev.h b/khdf/liteos/platform/include/spi_dev.h new file mode 100644 index 0000000..a434a89 --- /dev/null +++ b/khdf/liteos/platform/include/spi_dev.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2020-2021 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: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SPI_DEV_H +#define SPI_DEV_H + +#include "sys/ioctl.h" +#include "spi_core.h" +#include "spi_if.h" + +struct SpiIocMsg { + struct SpiMsg *msg; + int32_t count; +}; + +#define SPI_IOC_MAGIC 'k' +#define SPI_IOC_MESSAGE _IOW(SPI_IOC_MAGIC, 0, struct SpiIocMsg) +#define SPI_IOC_RD_MODE _IOR(SPI_IOC_MAGIC, 1, uint32_t) +#define SPI_IOC_RD_LSB_FIRST _IOR(SPI_IOC_MAGIC, 2, uint32_t) +#define SPI_IOC_RD_BITS_PER_WORD _IOR(SPI_IOC_MAGIC, 3, uint32_t) +#define SPI_IOC_RD_MAX_SPEED_HZ _IOR(SPI_IOC_MAGIC, 4, uint32_t) +#define SPI_IOC_WR_MODE _IOW(SPI_IOC_MAGIC, 1, uint32_t) +#define SPI_IOC_WR_LSB_FIRST _IOW(SPI_IOC_MAGIC, 2, uint32_t) +#define SPI_IOC_WR_BITS_PER_WORD _IOW(SPI_IOC_MAGIC, 3, uint32_t) +#define SPI_IOC_WR_MAX_SPEED_HZ _IOW(SPI_IOC_MAGIC, 4, uint32_t) + +void SpiAddDev(struct SpiDev *device); +void SpiRemoveDev(struct SpiDev *device); + +#endif /* SPI_DEV_H */ diff --git a/khdf/liteos/platform/include/uart_dev.h b/khdf/liteos/platform/include/uart_dev.h new file mode 100644 index 0000000..0bfc9d7 --- /dev/null +++ b/khdf/liteos/platform/include/uart_dev.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2020-2021 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: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef UART_DEV_H +#define UART_DEV_H + +#include "console.h" +#include "sys/ioctl.h" +#include "uart_core.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define UART_IOC_MAGIC 'u' + +/* baudrate config */ +#define UART_CFG_BAUDRATE _IO(UART_IOC_MAGIC, 1) + +/* DMA CONFIG: receive */ +#define UART_DMA_RX_EN 1 +#define UART_DMA_RX_DIS 0 +#define UART_CFG_DMA_RX _IO(UART_IOC_MAGIC, 2) + +/* DMA CONFIG: send */ +#define UART_DMA_TX_EN 1 +#define UART_DMA_TX_DIS 0 +#define UART_CFG_DMA_TX _IO(UART_IOC_MAGIC, 3) + +/* Read Block: */ +#define UART_RD_BLOCK 1 +#define UART_RD_NONBLOCK 0 +#define UART_CFG_RD_BLOCK CONSOLE_CMD_RD_BLOCK_SERIAL + +/* attribute CONFIG */ +#define UART_CFG_ATTR _IOW(UART_IOC_MAGIC, 5, int32_t) + +/* Private CONFIG */ +#define UART_CFG_PRIVATE _IOW(UART_IOC_MAGIC, 6, int32_t) + +void UartAddDev(struct UartHost *host); +void UartRemoveDev(struct UartHost *host); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* UART_DEV_H */ diff --git a/khdf/liteos/platform/src/gpio_dev.c b/khdf/liteos/platform/src/gpio_dev.c new file mode 100644 index 0000000..1dad5f4 --- /dev/null +++ b/khdf/liteos/platform/src/gpio_dev.c @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2020-2021 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: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "gpio_dev.h" +#include "fcntl.h" +#include "fs/fs.h" /* from Nuttx */ +#include "gpio_if.h" +#include "hdf_base.h" +#include "hdf_log.h" +#include "osal_mem.h" +#include "plat_log.h" +#include "user_copy.h" + +#ifdef PL061_GPIO_USER_SUPPORT + +static int GpioOpen(struct file *filep) +{ + (void)filep; + return 0; +} + +static int GpioClose(struct file *filep) +{ + (void)filep; + return 0; +} + +static int GpioExecCmd(uint16_t gpio, struct GpioBitInfo *info, int cmd) +{ + int32_t ret; + uint16_t tmp; + + switch (cmd) { + case GPIO_SET_DIR: + ret = GpioSetDir(gpio, info->direction); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: set dir fail:%d", __func__, ret); + return -1; + } + PLAT_LOGV("%s: gpio:%u set dir:%u done!", __func__, gpio, info->direction); + break; + case GPIO_GET_DIR: + ret = GpioGetDir(gpio, &tmp); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: get dir fail:%d", __func__, ret); + return -1; + } + info->direction = (unsigned char)tmp; + PLAT_LOGV("%s: gpio:%u get dir:%u done!", __func__, gpio, info->direction); + break; + case GPIO_READ_BIT: + ret = GpioRead(gpio, &tmp); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: read gpio fail:%d", __func__, ret); + return -1; + } + info->value = (unsigned char)tmp; + PLAT_LOGV("%s: gpio:%u read:%u done!", __func__, gpio, info->value); + break; + case GPIO_WRITE_BIT: + ret = GpioWrite(gpio, info->value); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: write gpio fail:%d", __func__, ret); + return -1; + } + PLAT_LOGV("%s: gpio:%u write:%u done!", __func__, gpio, info->value); + break; + default: + ret = -1; + } + return 0; +} + +static int GpioIoctl(struct file *filep, int cmd, unsigned long arg) +{ + int ret; + uint16_t bitNum; + uint16_t gpio; + struct GpioBitInfo info = {0}; + bitNum = (uint16_t)(uintptr_t)((struct drv_data *)filep->f_vnode)->priv; + + ret = LOS_CopyToKernel(&info, sizeof(struct GpioBitInfo), + (const VOID *)(uintptr_t)arg, sizeof(struct GpioBitInfo)); + if (ret != 0) { + return -1; + } + gpio = info.groupnumber * bitNum + info.bitnumber; + PLAT_LOGV("%s: gn:%u, bn:%u, gpio:%u", __func__, info.groupnumber, info.bitnumber, gpio); + + ret = GpioExecCmd(gpio, &info, cmd); + if (ret != 0) { + return -1; + } + + if ((unsigned int)cmd == GPIO_GET_DIR || (unsigned int)cmd == GPIO_READ_BIT) { + ret = LOS_CopyFromKernel((VOID *)(uintptr_t)arg, sizeof(struct GpioBitInfo), + &info, sizeof(struct GpioBitInfo)); + if (ret != 0) { + HDF_LOGE("%s: copy back fail:%d", __func__, ret); + return -1; + } + } + return 0; +} + +static const struct file_operations_vfs g_gpioDevOps = { + .open = GpioOpen, + .close = GpioClose, + .ioctl = GpioIoctl, +}; + +#define GPIO_VFS_MODE 0660 +#define GPIO_VFS_NAME "/dev/gpio" +int32_t GpioAddVfs(uint16_t bitNum) +{ + int ret; + + ret = register_driver(GPIO_VFS_NAME, &g_gpioDevOps, GPIO_VFS_MODE, (void *)(uintptr_t)bitNum); + if (ret != 0) { + HDF_LOGE("%s: register vfs fail:%d", __func__, ret); + return HDF_FAILURE; + } + HDF_LOGI("%s: register vfs success!", __func__); + return HDF_SUCCESS; +} + +void GpioRemoveVfs(void) +{ + int ret; + + ret = unregister_driver(GPIO_VFS_NAME); + if (ret != 0) { + HDF_LOGE("%s: unregister vfs fail!", __func__); + } +} +#endif diff --git a/khdf/liteos/platform/src/i2c_dev.c b/khdf/liteos/platform/src/i2c_dev.c new file mode 100644 index 0000000..10658d2 --- /dev/null +++ b/khdf/liteos/platform/src/i2c_dev.c @@ -0,0 +1,492 @@ +/* + * Copyright (c) 2020-2021 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: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "i2c_dev.h" +#include /* from Nuttx */ +#include +#include +#include "hdf_base.h" +#include "hdf_device_desc.h" +#include "hdf_log.h" +#include "i2c_core.h" +#include "i2c_if.h" +#include "osal_mem.h" +#include "plat_log.h" +#include "user_copy.h" + +#define I2C_FS_MODE 0660 +#define I2C_RDWR_IOCTL_MAX_MSGS 42 +#define I2C_BUF_MAX 8192 +#define I2C_NAME_SIZE 32 +#define I2C_CNTLR_MAX 32 + +struct I2cClient { + DevHandle handle; + struct I2cHost *host; + uint16_t addr; + uint16_t flags; +}; + +static inline int32_t I2cMsgInitFromUser(struct I2cMsg *kMsgs, struct i2c_msg *uMsgs) +{ + int32_t ret; + + kMsgs->len = uMsgs->len; + kMsgs->addr = uMsgs->addr; + kMsgs->flags = uMsgs->flags; + if ((uMsgs->flags & I2C_M_RD) != 0) { + return HDF_SUCCESS; + } + ret = LOS_CopyToKernel((void *)(kMsgs->buf), kMsgs->len, (void *)(uMsgs->buf), uMsgs->len); + return (ret == LOS_OK) ? HDF_SUCCESS : HDF_ERR_IO; +} + +static inline int32_t I2cMsgBackToUser(struct I2cMsg *kMsgs, struct i2c_msg *uMsgs) +{ + int32_t ret; + + if ((kMsgs->flags & I2C_M_RD) == 0) { + return HDF_SUCCESS; + } + ret = LOS_CopyFromKernel((void *)(uMsgs->buf), uMsgs->len, (void *)(kMsgs->buf), kMsgs->len); + return (ret == LOS_OK) ? HDF_SUCCESS : HDF_ERR_IO; +} + +static inline int32_t I2cMsgsCopyBackToUser(I2cIoctlWrap *wrap, + struct I2cMsg *kMsgs, struct i2c_msg *uMsgs) +{ + int ret; + unsigned int i; + + for (i = 0; i < wrap->nmsgs; i++) { + ret = I2cMsgBackToUser(&kMsgs[i], &uMsgs[i]); + if (ret != HDF_SUCCESS) { + break; + } + } + return ret; +} + +static void I2cMsgsDestroy(struct I2cMsg *kMsgs, struct i2c_msg *uMsgs) +{ + if (kMsgs != NULL) { + if (kMsgs[0].buf != NULL) { + OsalMemFree(kMsgs[0].buf); + kMsgs[0].buf = NULL; + } + } + if (uMsgs != NULL) { + OsalMemFree(uMsgs); + } +} + +static int32_t I2cMsgsCreateFromUser(I2cIoctlWrap *wrap, + struct I2cMsg **kMsgsPp, struct i2c_msg **uMsgsPp) +{ + int32_t ret; + size_t i; + size_t bufLen; + struct i2c_msg *uMsgs = NULL; + struct I2cMsg *kMsgs = NULL; + uint8_t *dataBuf = NULL; + + uMsgs = (struct i2c_msg *)OsalMemCalloc((sizeof(*uMsgs) + sizeof(*kMsgs)) * wrap->nmsgs); + if (uMsgs == NULL) { + return HDF_ERR_MALLOC_FAIL; + } + kMsgs = (struct I2cMsg *)((uint8_t *)uMsgs + sizeof(*uMsgs) * wrap->nmsgs); + + ret = LOS_CopyToKernel((void *)uMsgs, sizeof(*uMsgs) * wrap->nmsgs, + (void *)wrap->msgs, sizeof(*uMsgs) * wrap->nmsgs); + if (ret != LOS_OK) { + HDF_LOGE("%s: copy msgs from user fail!", __func__); + goto __ERR__; + } + + for (i = 0, bufLen = 0; i < wrap->nmsgs; i++) { + if (uMsgs[i].buf == NULL || uMsgs[i].len == 0) { + ret = HDF_ERR_INVALID_PARAM; + goto __ERR__; + } + bufLen += uMsgs[i].len; + } + if (bufLen >= I2C_BUF_MAX) { + HDF_LOGE("%s: buf too long:%u", __func__, bufLen); + ret = HDF_ERR_INVALID_PARAM; + goto __ERR__; + } + + dataBuf = (uint8_t *)OsalMemCalloc(bufLen); + if (dataBuf == NULL) { + ret = HDF_ERR_MALLOC_FAIL; + goto __ERR__; + } + + for (i = 0; i < wrap->nmsgs; i++) { + kMsgs[i].buf = dataBuf; + dataBuf += uMsgs[i].len; + ret = I2cMsgInitFromUser(&kMsgs[i], &uMsgs[i]); + if (ret != HDF_SUCCESS) { + goto __ERR__; + } + } + + *kMsgsPp = kMsgs; + *uMsgsPp = uMsgs; + return HDF_SUCCESS; + +__ERR__: + I2cMsgsDestroy(kMsgs, uMsgs); + return ret; +} + +static int32_t I2cCntlrRead(DevHandle handle, uint16_t addr, + uint8_t *buf, int16_t len, uint16_t flags) +{ + int32_t ret; + struct I2cMsg msg; + + msg.addr = addr; + msg.buf = buf; + msg.len = len; + msg.flags = flags | I2C_FLAG_READ; + + ret = I2cTransfer(handle, &msg, 1); + return (ret == 1) ? HDF_SUCCESS : ret; +} + +ssize_t I2cFsRead(struct file *filep, char *buf, size_t count) +{ + int32_t ret; + uint8_t *kbuf = NULL; + struct I2cClient *client = filep->f_priv; + + if (client == NULL) { + HDF_LOGE("%s: client is null!", __func__); + return 0; + } + + kbuf = (uint8_t *)OsalMemCalloc(count); + if (kbuf == NULL) { + HDF_LOGE("%s: malloc kbuf fail!", __func__); + return 0; + } + + ret = I2cCntlrRead(client->handle, client->addr, kbuf, count, client->flags); + PLAT_LOGV("%s: I2cRead called, ret:%d", __func__, ret); + + if (ret == HDF_SUCCESS) { + if (LOS_CopyFromKernel(buf, count, kbuf, count) != LOS_OK) { + HDF_LOGE("%s: copy from kernel fail:%d", __func__, ret); + ret = HDF_ERR_IO; + } + } + OsalMemFree(kbuf); + return (ret == HDF_SUCCESS) ? count : 0; +} + +static int32_t I2cCntlrWrite(DevHandle handle, uint16_t addr, + const uint8_t *buf, int16_t len, uint16_t flags) +{ + int32_t ret; + struct I2cMsg msg; + + msg.addr = addr; + msg.buf = (uint8_t *)buf; + msg.len = len; + msg.flags = flags & (~I2C_FLAG_READ); + + ret = I2cTransfer(handle, &msg, 1); + return (ret == 1) ? HDF_SUCCESS : ret; +} + + +ssize_t I2cFsWrite(struct file *filep, const char *buf, size_t count) +{ + int32_t ret; + uint8_t *kbuf = NULL; + struct I2cClient *client = filep->f_priv; + + if (client == NULL) { + HDF_LOGE("%s: client is null!", __func__); + return 0; + } + + kbuf = (uint8_t *)OsalMemCalloc(count); + if (kbuf == NULL) { + HDF_LOGE("%s: malloc kbuf fail!", __func__); + return 0; + } + if (LOS_CopyToKernel(kbuf, count, buf, count) != LOS_OK) { + HDF_LOGE("%s: copy to kernel fail!", __func__); + OsalMemFree(kbuf); + return 0; + } + + ret = I2cCntlrWrite(client->handle, client->addr, kbuf, count, client->flags); + PLAT_LOGV("%s: I2cWrite called, ret:%d", __func__, ret); + + OsalMemFree(kbuf); + return (ret == HDF_SUCCESS) ? count : 0; +} + +static int I2cIoctlReadWrite(const struct I2cClient *client, const void *arg) +{ + int ret; + I2cIoctlWrap wrap; + struct i2c_msg *uMsgs = NULL; + struct I2cMsg *kMsgs = NULL; + + if (arg == NULL) { + HDF_LOGE("%s: arg is null!", __func__); + return HDF_ERR_INVALID_PARAM; + } + + ret = LOS_CopyToKernel(&wrap, sizeof(wrap), (void *)arg, sizeof(wrap)); + if (ret != LOS_OK) { + HDF_LOGE("%s: copy wrap fail!", __func__); + return HDF_ERR_IO; + } + + if (wrap.msgs == NULL || wrap.nmsgs == 0 || wrap.nmsgs > I2C_RDWR_IOCTL_MAX_MSGS) { + HDF_LOGE("%s: wrap msgs is null or invalid num:%u!", __func__, wrap.nmsgs); + return HDF_ERR_INVALID_PARAM; + } + + ret = I2cMsgsCreateFromUser(&wrap, &kMsgs, &uMsgs); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: recreate msgs fail!", __func__); + return ret; + } + + ret = I2cTransfer(client->handle, kMsgs, wrap.nmsgs); + PLAT_LOGV("%s: I2cTransfer called, ret:%d", __func__, ret); + if ((unsigned int)ret == wrap.nmsgs) { + ret = I2cMsgsCopyBackToUser(&wrap, kMsgs, uMsgs); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: copy back fail! ret:%d", __func__, ret); + } + } else { + HDF_LOGE("%s: transfer fail, ret:%d, nmsgs:%u", __func__, ret, wrap.nmsgs); + } + + I2cMsgsDestroy(kMsgs, uMsgs); + return ret; +} + +static int I2cFsIoctl(struct file *filep, int cmd, unsigned long arg) +{ + int retval = ENOERR; + struct I2cClient *client = filep->f_priv; + + switch (cmd) { + case IOCTL_SLAVE_FORCE: + case IOCTL_SLAVE: + if ((((client->flags & I2C_M_TEN) == 0) && arg > 0xfe) || (arg > 0x3ff)) { + HDF_LOGE("%s:Not support arg(%0lu)!!!", __func__, arg); + retval = -EINVAL; + break; + } + client->addr = arg; + break; + case IOCTL_RDWR: { + retval = I2cIoctlReadWrite(client, (void *)(uintptr_t)arg); + break; + } + case IOCTL_16BIT_REG: + if (arg == 0) { + client->flags &= ~I2C_M_16BIT_REG; + } else { + client->flags |= I2C_M_16BIT_REG; + } + break; + case IOCTL_16BIT_DATA: + if (arg == 0) { + client->flags &= ~I2C_M_16BIT_DATA; + } else { + client->flags |= I2C_M_16BIT_DATA; + } + break; + case IOCTL_TENBIT: + if (arg == 0) { + client->flags &= ~I2C_M_TEN; + } else { + client->flags |= I2C_M_TEN; + } + break; + case IOCTL_PEC: + case IOCTL_RETRIES: + case IOCTL_TIMEOUT: + default: + HDF_LOGE("Not support cmd(%0d)!!!", cmd); + retval = -EINVAL; + } + return retval; +} + +static int I2cFsOpen(struct file *filep) +{ + DevHandle handle = NULL; + struct I2cClient *client = NULL; + int16_t id = (int16_t)((uintptr_t)((struct drv_data *)filep->f_vnode)->priv); + + handle = I2cOpen(id); + if (handle == NULL) { + HDF_LOGE("%s:Fail to get host:%d handle!", __func__, id); + return -1; + } + + client = (struct I2cClient *)OsalMemCalloc(sizeof(*client)); + if (client == NULL) { + HDF_LOGE("%s:Fail to malloc client-%d!", __func__, id); + return -1; + } + client->handle = handle; + + /* record the client as file private data */ + filep->f_priv = client; + return 0; +} + +static int I2cFsClose(struct file *filep) +{ + struct I2cClient *client = filep->f_priv; + + if (client == NULL) { + HDF_LOGE("%s: has't opened!", __func__); + return 0; + } + + if (client->handle == NULL) { + return 0; + } + I2cClose(client->handle); + client->handle = NULL; + OsalMemFree(client); + client = NULL; + + filep->f_priv = NULL; + return 0; +} + +static ssize_t I2cFsMap(FAR struct file* filep, FAR LosVmMapRegion *region) +{ + size_t size = region->range.size; + + (void)filep; + PADDR_T paddr = region->pgOff << PAGE_SHIFT; + VADDR_T vaddr = region->range.base; + LosVmSpace *space = LOS_SpaceGet(vaddr); + + if ((space == NULL) || ((paddr >= SYS_MEM_BASE) && (paddr < SYS_MEM_END))) { + return -EINVAL; + } + + if (LOS_ArchMmuMap(&space->archMmu, vaddr, paddr, size >> PAGE_SHIFT, region->regionFlags) <= 0) { + return -EAGAIN; + } + + return 0; +} + +static const struct file_operations_vfs g_i2cFops = { + .open = I2cFsOpen, + .close = I2cFsClose, + .read = I2cFsRead, + .write = I2cFsWrite, + .ioctl = I2cFsIoctl, + .mmap = I2cFsMap, +}; + +int32_t I2cAddVfsById(int16_t id) +{ +#ifdef LOSCFG_FS_VFS + int32_t ret; + char *name = NULL; + + if (id < 0 || id >= I2C_CNTLR_MAX) { + HDF_LOGE("%s: id:%d exceed max:%d", __func__, id, I2C_CNTLR_MAX); + return HDF_ERR_INVALID_PARAM; + } + name = (char *)OsalMemCalloc(I2C_NAME_SIZE); + if (name == NULL) { + HDF_LOGE("%s: malloc name fail!", __func__); + return HDF_ERR_MALLOC_FAIL; + } + /* create /dev/i2c-x device files for the i2c adatpers */ + ret = snprintf_s(name, I2C_NAME_SIZE, I2C_NAME_SIZE - 1, "/dev/i2c-%d", id); + if (ret < 0) { + HDF_LOGE("%s: format name fail! ret:%d", __func__, ret); + OsalMemFree(name); + return ret; + } + ret = register_driver(name, &g_i2cFops, I2C_FS_MODE, (void *)((uintptr_t)id)); + if (ret != 0) { + HDF_LOGE("%s: register %s fail! ret:%d", __func__, name, ret); + } + OsalMemFree(name); + return ret; +#else /* LOSCFG_FS_VFS */ + (void)id; + return HDF_SUCCESS; +#endif +} + +void I2cRemoveVfsById(int16_t id) +{ +#ifdef LOSCFG_FS_VFS + int32_t ret; + char *name = NULL; + + if (id < 0 || id >= I2C_CNTLR_MAX) { + HDF_LOGE("%s: id:%d exceed max:%d", __func__, id, I2C_CNTLR_MAX); + return; + } + name = (char *)OsalMemCalloc(I2C_NAME_SIZE); + if (name == NULL) { + HDF_LOGE("%s: malloc name fail!", __func__); + return; + } + /* remove /dev/i2c-x device files for the i2c controllers */ + ret = snprintf_s(name, I2C_NAME_SIZE, I2C_NAME_SIZE - 1, "/dev/i2c-%d", id); + if (ret < 0) { + HDF_LOGE("%s: format name fail! ret:%d", __func__, ret); + OsalMemFree(name); + return; + } + ret = unregister_driver(name); + if (ret != 0) { + HDF_LOGE("%s: unregister %s fail!", __func__, name); + } + OsalMemFree(name); +#else + (void)id; +#endif /* LOSCFG_FS_VFS */ +} diff --git a/khdf/liteos/platform/plat_common.c b/khdf/liteos/platform/src/plat_common.c similarity index 100% rename from khdf/liteos/platform/plat_common.c rename to khdf/liteos/platform/src/plat_common.c diff --git a/khdf/liteos/platform/src/spi_dev.c b/khdf/liteos/platform/src/spi_dev.c new file mode 100644 index 0000000..d9802df --- /dev/null +++ b/khdf/liteos/platform/src/spi_dev.c @@ -0,0 +1,448 @@ +/* + * Copyright (c) 2020-2021 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: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fs/fs.h" +#include "securec.h" +#include "user_copy.h" +#include "hdf_log.h" +#include "osal_mem.h" +#include "spi_dev.h" + +#define HDF_LOG_TAG spi_dev +#define HDF_SPI_FS_MODE 0660 + +#ifdef LOSCFG_FS_VFS +static struct SpiDev *SpiDevGetDevFromFilep(FAR struct file *filep) +{ + if (filep == NULL) { + HDF_LOGE("%s: filep is invalid", __func__); + return NULL; + } + + struct Vnode *vnode = filep->f_vnode; + struct SpiDev *dev = (struct SpiDev *)(((struct drv_data *)vnode->data)->priv); + + if (dev == NULL || dev->cntlr == NULL) { + HDF_LOGE("%s: dev is invalid", __func__); + return NULL; + } + return dev; +} + +static int32_t SpiDevOpen(FAR struct file *filep) +{ + struct SpiDev *dev = NULL; + + dev = SpiDevGetDevFromFilep(filep); + if (dev == NULL) { + return HDF_ERR_INVALID_PARAM; + } + HDF_LOGE("%s: spi bus is %d, cs is %d", __func__, dev->cntlr->busNum, dev->csNum); + return HDF_SUCCESS; +} + +static ssize_t SpiDevRead(FAR struct file *filep, FAR char *buf, size_t size) +{ + int32_t ret; + struct SpiMsg msg = {0}; + uint8_t *tmpReadBuf = NULL; + struct SpiDev *dev = NULL; + + if (buf == NULL || size == 0) { + HDF_LOGE("%s: buf or size %d is invalid", __func__, size); + return HDF_ERR_INVALID_PARAM; + } + dev = SpiDevGetDevFromFilep(filep); + if (dev == NULL) { + return HDF_ERR_INVALID_PARAM; + } + msg.len = size; + msg.wbuf = NULL; + if (LOS_IsUserAddressRange((vaddr_t)(uintptr_t)buf, size)) { + tmpReadBuf = (uint8_t *)OsalMemCalloc(size); + if (tmpReadBuf == NULL) { + HDF_LOGE("%s: OsalMemCalloc error", __func__); + return HDF_ERR_MALLOC_FAIL; + } + msg.rbuf = tmpReadBuf; + ret = SpiCntlrTransfer(dev->cntlr, dev->csNum, &msg, 1); + if (ret == HDF_SUCCESS) { + ret = LOS_CopyFromKernel(buf, size, tmpReadBuf, size); + } + OsalMemFree(tmpReadBuf); + return ret; + } else { + msg.rbuf = (uint8_t *)buf; + return SpiCntlrTransfer(dev->cntlr, dev->csNum, &msg, 1); + } +} + +static ssize_t SpiDevWrite(struct file *filep, const char *buf, size_t size) +{ + int32_t ret; + struct SpiMsg msg = {0}; + uint8_t *tmpWriteBuf = NULL; + struct SpiDev *dev = NULL; + + if (buf == NULL || size == 0) { + HDF_LOGE("%s: buf or size %d is invalid", __func__, size); + return HDF_ERR_INVALID_PARAM; + } + dev = SpiDevGetDevFromFilep(filep); + if (dev == NULL) { + return HDF_ERR_INVALID_PARAM; + } + msg.len = size; + msg.rbuf = NULL; + if (LOS_IsUserAddressRange((vaddr_t)(uintptr_t)buf, size)) { + tmpWriteBuf = (uint8_t *)OsalMemCalloc(size); + if (tmpWriteBuf == NULL) { + HDF_LOGE("%s: OsalMemCalloc error", __func__); + return HDF_ERR_MALLOC_FAIL; + } + ret = LOS_CopyToKernel(tmpWriteBuf, size, buf, size); + if (ret != LOS_OK) { + OsalMemFree(tmpWriteBuf); + return ret; + } + msg.wbuf = tmpWriteBuf; + ret = SpiCntlrTransfer(dev->cntlr, dev->csNum, &msg, 1); + OsalMemFree(tmpWriteBuf); + return ret; + } else { + msg.wbuf = (uint8_t *)buf; + return SpiCntlrTransfer(dev->cntlr, dev->csNum, &msg, 1); + } +} + +static int32_t SpiDevGetCfg(struct SpiDev *dev, struct SpiCfg *mask, unsigned long arg) +{ + int32_t ret; + uint32_t tmp = 0; + struct SpiCfg cfg = {0}; + struct SpiCntlr *cntlr = dev->cntlr; + + ret = SpiCntlrGetCfg(cntlr, dev->csNum, &cfg); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: GetCfg error", __func__); + return HDF_FAILURE; + } + if (mask->mode == 1) { + tmp = cfg.mode; + HDF_LOGI("%s: get mode 0x%x", __func__, tmp); + } else if (mask->bitsPerWord == 1) { + tmp = cfg.bitsPerWord; + HDF_LOGI("%s: get word %d", __func__, tmp); + } else if (mask->maxSpeedHz == 1) { + tmp = cfg.maxSpeedHz; + HDF_LOGI("%s: get maxspeed %d", __func__, tmp); + } + ret = LOS_CopyFromKernel((void *)(uintptr_t)arg, sizeof(uint32_t), (void *)&tmp, sizeof(uint32_t)); + if (ret != 0) { + HDF_LOGE("%s: memery copy error", __func__); + } + return ret; +} + +static int32_t SpiDevSetCfg(struct SpiDev *dev, struct SpiCfg *mask, unsigned long arg) +{ + int32_t ret; + uint32_t tmp; + struct SpiCfg cfg = {0}; + struct SpiCntlr *cntlr = dev->cntlr; + + ret = LOS_CopyToKernel((void *)&tmp, sizeof(uint32_t), (void *)(uintptr_t)arg, sizeof(uint32_t)); + if (ret != 0) { + HDF_LOGE("%s: memery copy error", __func__); + return ret; + } + + ret = SpiCntlrGetCfg(cntlr, dev->csNum, &cfg); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: GetCfg error", __func__); + return HDF_FAILURE; + } + if (mask->mode == 1) { + HDF_LOGI("%s: set mode 0x%x", __func__, tmp); + cfg.mode = tmp; + } else if (mask->bitsPerWord == 1) { + HDF_LOGI("%s: set word %d", __func__, tmp); + cfg.bitsPerWord = tmp; + } else if (mask->maxSpeedHz == 1) { + HDF_LOGI("%s: set maxspeed %d", __func__, tmp); + cfg.maxSpeedHz = tmp; + } + return SpiCntlrSetCfg(cntlr, dev->csNum, &cfg); +} + +static struct SpiIocMsg *SpiDevGetIocMsgFromUser(unsigned long arg) +{ + int32_t ret; + struct SpiIocMsg *umsg = NULL; + + umsg = (struct SpiIocMsg *)OsalMemCalloc(sizeof(struct SpiIocMsg)); + if (umsg == NULL) { + HDF_LOGE("%s: melloc umsg error", __func__); + return NULL; + } + ret = LOS_CopyToKernel((void *)umsg, sizeof(struct SpiIocMsg), (void *)(uintptr_t)arg, sizeof(struct SpiIocMsg)); + if (ret != 0) { + HDF_LOGE("%s: copy to kernel error", __func__); + OsalMemFree(umsg); + return NULL; + } + return umsg; +} + +static struct SpiMsg *SpiDevGetSpiMsgFromUser(struct SpiIocMsg *umsg) +{ + int32_t ret; + int32_t count; + struct SpiMsg *msg = NULL; + + count = umsg->count; + msg = (struct SpiMsg *)OsalMemCalloc(sizeof(struct SpiMsg) * count + sizeof(struct SpiMsg) * count); + if (msg == NULL) { + HDF_LOGE("%s: melloc msg error", __func__); + return NULL; + } + ret = LOS_CopyToKernel((void *)msg, sizeof(struct SpiMsg) * count, + (void *)(umsg->msg), sizeof(struct SpiMsg) * count); + if (ret != 0) { + HDF_LOGE("%s: copy to kernel error", __func__); + OsalMemFree(msg); + return NULL; + } + return msg; +} + +static int32_t SpiDevRealTransfer(struct SpiDev *dev, struct SpiMsg *msg, struct SpiMsg *kmsg, int32_t count) +{ + int32_t i; + int32_t len = 0; + uint32_t pos = 0; + uint8_t *wbuf = NULL; + uint8_t *rbuf = NULL; + + for (i = 0; i < count; i++) { + len += msg[i].len; + } + if (len <= 0) { + HDF_LOGE("%s: err, msg total len is %d", __func__, len); + return HDF_ERR_INVALID_PARAM; + } + wbuf = (uint8_t *)OsalMemCalloc(sizeof(uint8_t) * (len + len)); + if (wbuf == NULL) { + HDF_LOGE("%s: melloc wbuf error", __func__); + return HDF_ERR_MALLOC_FAIL; + } + rbuf = wbuf + sizeof(uint8_t) * len; + for (i = 0; i < count; i++) { + if (LOS_CopyToKernel(wbuf + pos, msg[i].len, (void *)msg[i].wbuf, msg[i].len) != 0) { + HDF_LOGE("%s: copy to kernel error", __func__); + OsalMemFree(wbuf); + return HDF_ERR_IO; + } + kmsg[i].wbuf = wbuf + pos; + kmsg[i].rbuf = rbuf + pos; + kmsg[i].len = msg[i].len; + kmsg[i].csChange = msg[i].csChange; + kmsg[i].delayUs = msg[i].delayUs; + kmsg[i].speed = msg[i].speed; + pos += msg[i].len; + } + if (SpiCntlrTransfer(dev->cntlr, dev->csNum, kmsg, count) != HDF_SUCCESS) { + HDF_LOGE("%s: transfer error", __func__); + OsalMemFree(wbuf); + return HDF_FAILURE; + } + for (i = 0; i < count; i++) { + if (LOS_CopyFromKernel((void *)msg[i].rbuf, msg[i].len, (void *)kmsg[i].rbuf, msg[i].len) != 0) { + HDF_LOGE("%s: copy from kernel error", __func__); + OsalMemFree(wbuf); + return HDF_ERR_IO; + } + } + OsalMemFree(wbuf); + return HDF_SUCCESS; +} + +static int32_t SpiDevTransfer(struct SpiDev *dev, unsigned long arg) +{ + int32_t ret; + int32_t count; + struct SpiMsg *msg = NULL; + struct SpiMsg *kmsg = NULL; + struct SpiIocMsg *umsg = NULL; + + if (!LOS_IsUserAddressRange((vaddr_t)(uintptr_t)arg, sizeof(struct SpiIocMsg))) { + umsg = (struct SpiIocMsg *)(uintptr_t)arg; + return SpiCntlrTransfer(dev->cntlr, dev->csNum, umsg->msg, umsg->count); + } + umsg = SpiDevGetIocMsgFromUser(arg); + if (umsg == NULL) { + HDF_LOGE("%s: melloc umsg error", __func__); + return HDF_ERR_MALLOC_FAIL; + } + count = umsg->count; + if (count <= 0) { + HDF_LOGE("%s: umsg error", __func__); + OsalMemFree(umsg); + return HDF_ERR_INVALID_OBJECT; + } + msg = SpiDevGetSpiMsgFromUser(umsg); + if (msg == NULL) { + OsalMemFree(umsg); + return HDF_ERR_IO; + } + kmsg = msg + count; + ret = SpiDevRealTransfer(dev, msg, kmsg, count); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: spi dev transfer error %d", __func__, ret); + } + OsalMemFree(msg); + OsalMemFree(umsg); + return ret; +} + +static int32_t SpiDevIoctl(FAR struct file *filep, int32_t cmd, unsigned long arg) +{ + int ret; + struct SpiCfg mask = {0}; + struct SpiDev *dev = NULL; + + dev = SpiDevGetDevFromFilep(filep); + if (dev == NULL) { + return HDF_ERR_INVALID_PARAM; + } + switch (cmd) { + case SPI_IOC_MESSAGE: + ret = SpiDevTransfer(dev, arg); + break; + case SPI_IOC_RD_MODE: + mask.mode = 1; + ret = SpiDevGetCfg(dev, &mask, arg); + break; + case SPI_IOC_RD_BITS_PER_WORD: + mask.bitsPerWord = 1; + ret = SpiDevGetCfg(dev, &mask, arg); + break; + case SPI_IOC_RD_MAX_SPEED_HZ: + mask.maxSpeedHz = 1; + ret = SpiDevGetCfg(dev, &mask, arg); + break; + case SPI_IOC_WR_MODE: + mask.mode = 1; + ret = SpiDevSetCfg(dev, &mask, arg); + break; + case SPI_IOC_WR_BITS_PER_WORD: + mask.bitsPerWord = 1; + ret = SpiDevSetCfg(dev, &mask, arg); + break; + case SPI_IOC_WR_MAX_SPEED_HZ: + mask.maxSpeedHz = 1; + ret = SpiDevSetCfg(dev, &mask, arg); + break; + default: + HDF_LOGE("%s: cmd %d not support", __func__, cmd); + ret = HDF_ERR_NOT_SUPPORT; + break; + } + return ret; +} + +const struct file_operations_vfs g_spiDevFops = { + .open = SpiDevOpen, + .read = SpiDevRead, + .write = SpiDevWrite, + .ioctl = SpiDevIoctl, +}; + +#define MAX_DEV_NAME_SIZE 32 +static void SpiAddRemoveDev(struct SpiDev *dev, bool add) +{ + int32_t ret; + char *devName = NULL; + + if (dev == NULL || dev->cntlr == NULL) { + HDF_LOGE("%s invalid parameter", __func__); + return; + } + devName = (char *)OsalMemCalloc(sizeof(char) * (MAX_DEV_NAME_SIZE + 1)); + if (devName == NULL) { + HDF_LOGE("%s: OsalMemCalloc error", __func__); + return; + } + ret = snprintf_s(devName, MAX_DEV_NAME_SIZE + 1, MAX_DEV_NAME_SIZE, "/dev/spidev%u.%u", + dev->cntlr->busNum, dev->csNum); + if (ret < 0) { + HDF_LOGE("%s snprintf_s failed", __func__); + OsalMemFree(devName); + return; + } + if (add) { + HDF_LOGI("creat /dev/spidev%u.%u", dev->cntlr->busNum, dev->csNum); + if (register_driver(devName, &g_spiDevFops, HDF_SPI_FS_MODE, dev)) { + HDF_LOGE("%s: gen /dev/spidev%u.%u", __func__, dev->cntlr->busNum, dev->csNum); + } + } else { + if (unregister_driver(devName)) { + HDF_LOGE("%s: remove /dev/spidev%u.%u", __func__, dev->cntlr->busNum, dev->csNum); + } + } + OsalMemFree(devName); +} + +void SpiAddDev(struct SpiDev *device) +{ + SpiAddRemoveDev(device, true); +} + +void SpiRemoveDev(struct SpiDev *device) +{ + SpiAddRemoveDev(device, false); +} +#else +void SpiAddDev(struct SpiDev *device) +{ + if (device != NULL && device->cntlr != NULL) { + HDF_LOGE("%s: add /dev/spidev%d.%d error", __func__, device->csNum, device->cntlr->busNum); + } + HDF_LOGE("%s: LOSCFG_FS_VFS not define", __func__); +} + +void SpiRemoveDev(struct SpiDev *device) +{ + if (device != NULL && device->cntlr != NULL) { + HDF_LOGE("%s: remove /dev/spidev%d.%d error", __func__, device->csNum, device->cntlr->busNum); + } + HDF_LOGE("%s: LOSCFG_FS_VFS not define", __func__); +} +#endif /* end of LOSCFG_FS_VFS */ diff --git a/khdf/liteos/platform/src/uart_dev.c b/khdf/liteos/platform/src/uart_dev.c new file mode 100644 index 0000000..ad141d8 --- /dev/null +++ b/khdf/liteos/platform/src/uart_dev.c @@ -0,0 +1,277 @@ +/* + * Copyright (c) 2020-2021 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: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fs/fs.h" +#include "securec.h" +#include "user_copy.h" +#include "hdf_log.h" +#include "osal_mem.h" +#include "uart_dev.h" + +#include "fs/vnode.h" + +#define HDF_LOG_TAG hdf_uart_dev +#define HDF_UART_FS_MODE 0660 + +static int32_t UartDevOpen(FAR struct file *filep) +{ + struct UartHost *host = NULL; + + if (filep == NULL || filep->f_vnode == NULL) { + return HDF_ERR_INVALID_PARAM; + } + struct drv_data *drv = (struct drv_data *)filep->f_vnode->data; + host = (struct UartHost *)drv->priv; + return UartHostInit(host); +} +static int32_t UartDevRelease(FAR struct file *filep) +{ + struct UartHost *host = NULL; + + if (filep == NULL || filep->f_vnode == NULL) { + return HDF_ERR_INVALID_PARAM; + } + struct drv_data *drv = (struct drv_data *)filep->f_vnode->data; + host = (struct UartHost *)drv->priv; + + return UartHostDeinit(host); +} + +static ssize_t UartDevRead(FAR struct file *filep, FAR char *buf, size_t count) +{ + int32_t size; + int32_t ret = LOS_OK; + uint8_t *tmpBuf = NULL; + struct UartHost *host = NULL; + + if (filep == NULL || filep->f_vnode == NULL) { + return HDF_ERR_INVALID_PARAM; + } + struct drv_data *drv = (struct drv_data *)filep->f_vnode->data; + host = (struct UartHost *)drv->priv; + + if (LOS_IsUserAddressRange((vaddr_t)buf, count)) { + tmpBuf = (uint8_t *)OsalMemCalloc(count); + if (tmpBuf == NULL) { + HDF_LOGE("%s: OsalMemCalloc error", __func__); + return HDF_ERR_MALLOC_FAIL; + } + size = UartHostRead(host, tmpBuf, count); + if (size > 0) { + ret = LOS_ArchCopyToUser(buf, tmpBuf, size); + } + OsalMemFree(tmpBuf); + return ret != LOS_OK ? ret : size; + } else { + return UartHostRead(host, (uint8_t *)buf, count); + } +} + +static ssize_t UartDevWrite(struct file *filep, const char *buf, size_t count) +{ + int32_t ret; + uint8_t *tmpBuf = NULL; + struct UartHost *host = NULL; + + if (filep == NULL || filep->f_vnode == NULL) { + return HDF_ERR_INVALID_PARAM; + } + struct drv_data *drv = (struct drv_data *)filep->f_vnode->data; + host = (struct UartHost *)drv->priv; + + if (LOS_IsUserAddressRange((vaddr_t)buf, count)) { + tmpBuf = (uint8_t *)OsalMemCalloc(count); + if (tmpBuf == NULL) { + HDF_LOGE("%s: OsalMemCalloc error", __func__); + return HDF_ERR_MALLOC_FAIL; + } + ret = LOS_ArchCopyFromUser(tmpBuf, buf, count); + if (ret != LOS_OK) { + OsalMemFree(tmpBuf); + return ret; + } + ret = UartHostWrite(host, tmpBuf, count); + OsalMemFree(tmpBuf); + return ret; + } else { + return UartHostWrite(host, (uint8_t *)buf, count); + } +} + +static int32_t UartCfgAttr(struct UartHost *host, unsigned long arg) +{ + int32_t ret; + struct UartAttribute attr; + int32_t len = sizeof(struct UartAttribute); + + if (!LOS_IsUserAddressRange((vaddr_t)arg, len)) { + ret = memcpy_s((void *)&attr, len, (void *)arg, len); + } else { + ret = LOS_ArchCopyFromUser(&attr, (void *)arg, len); + } + if (ret != LOS_OK) { + return ret; + } + ret = UartHostSetAttribute(host, &attr); + return ret; +} + +static int32_t UartDevIoctl(FAR struct file *filep, int32_t cmd, unsigned long arg) +{ + int32_t ret = HDF_FAILURE; + struct UartHost *host = NULL; + if (filep == NULL || filep->f_vnode == NULL) { + return HDF_ERR_INVALID_PARAM; + } + struct drv_data *drv = (struct drv_data *)filep->f_vnode->data; + host = (struct UartHost *)drv->priv; + + switch (cmd) { + case UART_CFG_BAUDRATE: + ret = UartHostSetBaud(host, arg); + break; + case UART_CFG_RD_BLOCK: + if (arg == UART_RD_BLOCK) { + ret = UartHostSetTransMode(host, UART_MODE_RD_BLOCK); + } else if (arg == UART_RD_NONBLOCK) { + ret = UartHostSetTransMode(host, UART_MODE_RD_NONBLOCK); + } + break; + case UART_CFG_ATTR: + ret = UartCfgAttr(host, arg); + break; + case TIOCGWINSZ: + /* Simply support ioctl(f->fd, TIOCGWINSZ, &wsz) system call, and the detailed design will be done later */ + ret = LOS_OK; + break; + default: + HDF_LOGE("%s cmd %d not support", __func__, cmd); + ret = HDF_ERR_NOT_SUPPORT; + break; + } + return ret; +} +extern void poll_wait(struct file *filp, + wait_queue_head_t *wait_address, poll_table *p); +static int uartdev_poll(struct file *filep, poll_table *table) +{ + struct UartHost *host = NULL; + //struct UartDriverData *udd = NULL; + + if (filep == NULL || filep->f_vnode == NULL) { + return HDF_ERR_INVALID_PARAM; + } + struct drv_data *drv = (struct drv_data *)filep->f_vnode->data; + host = (struct UartHost *)drv->priv; + + /*if (host == NULL || host->priv == NULL) { + HDF_LOGE("%s: host is NULL", __func__); + return HDF_FAILURE; + }*/ + return UartHostPollEvent(host, filep, table); + + /*udd = (struct UartDriverData *)host->priv; + if (udd == NULL) { + HDF_LOGE("uart_driver_data is NULL"); + return -EINVAL; + } + if (UART_STATE_USEABLE != udd->state) { + return -EFAULT; + }*/ + + //poll_wait(filep, &udd->wait, table); + + //if (!PL011UartRxBufEmpty(udd)) { + // return POLLIN | POLLRDNORM; + //} + //return 0; +} + +static const struct file_operations_vfs g_uartDevFops = { + .open = UartDevOpen, + .close = UartDevRelease, + .read = UartDevRead, + .write = UartDevWrite, + .ioctl = UartDevIoctl, +#ifndef CONFIG_DISABLE_POLL + .poll = uartdev_poll, +#endif + +}; + +#define MAX_DEV_NAME_SIZE 32 +static void UartAddRemoveDev(struct UartHost *host, bool add) +{ + int32_t ret; + char *devName = NULL; + //struct UartDriverData *udd = NULL; + + if (host == NULL || host->priv == NULL) { + HDF_LOGE("%s invalid parameter", __func__); + return; + } + //udd = (struct UartDriverData *)host->priv; + devName = (char *)OsalMemCalloc(sizeof(char) * (MAX_DEV_NAME_SIZE + 1)); + if (devName == NULL) { + HDF_LOGE("%s: OsalMemCalloc error", __func__); + return; + } + ret = snprintf_s(devName, MAX_DEV_NAME_SIZE + 1, MAX_DEV_NAME_SIZE, "/dev/uartdev-%d", host->num); + if (ret < 0) { + HDF_LOGE("%s snprintf_s failed", __func__); + OsalMemFree(devName); + return; + } + if (add) { + HDF_LOGI("creat /dev/uartdev-%d", host->num); + if (register_driver(devName, &g_uartDevFops, HDF_UART_FS_MODE, host)) { + HDF_LOGE("%s: gen /dev/uartdev-%d fail!", __func__, host->num); + OsalMemFree(devName); + return; + } + } else { + if (unregister_driver(devName)) { + HDF_LOGE("%s: remove /dev/uartdev-%d fail!", __func__, host->num); + OsalMemFree(devName); + return; + } + } + OsalMemFree(devName); +} + +void UartAddDev(struct UartHost *host) +{ + UartAddRemoveDev(host, true); +} + +void UartRemoveDev(struct UartHost *host) +{ + UartAddRemoveDev(host, false); +} -- Gitee From c47f9fb6b15647bfcc24be22c043e615178756cb Mon Sep 17 00:00:00 2001 From: haizhouyang Date: Wed, 28 Apr 2021 15:14:47 +0800 Subject: [PATCH 2/3] delete unused codes --- khdf/liteos/platform/src/gpio_dev.c | 2 +- khdf/liteos/platform/src/i2c_dev.c | 2 +- khdf/liteos/platform/src/uart_dev.c | 24 +----------------------- 3 files changed, 3 insertions(+), 25 deletions(-) diff --git a/khdf/liteos/platform/src/gpio_dev.c b/khdf/liteos/platform/src/gpio_dev.c index 1dad5f4..d38c59e 100644 --- a/khdf/liteos/platform/src/gpio_dev.c +++ b/khdf/liteos/platform/src/gpio_dev.c @@ -30,7 +30,7 @@ #include "gpio_dev.h" #include "fcntl.h" -#include "fs/fs.h" /* from Nuttx */ +#include "fs/fs.h" #include "gpio_if.h" #include "hdf_base.h" #include "hdf_log.h" diff --git a/khdf/liteos/platform/src/i2c_dev.c b/khdf/liteos/platform/src/i2c_dev.c index 10658d2..2bed6ce 100644 --- a/khdf/liteos/platform/src/i2c_dev.c +++ b/khdf/liteos/platform/src/i2c_dev.c @@ -29,7 +29,7 @@ */ #include "i2c_dev.h" -#include /* from Nuttx */ +#include #include #include #include "hdf_base.h" diff --git a/khdf/liteos/platform/src/uart_dev.c b/khdf/liteos/platform/src/uart_dev.c index ad141d8..b4f4487 100644 --- a/khdf/liteos/platform/src/uart_dev.c +++ b/khdf/liteos/platform/src/uart_dev.c @@ -183,7 +183,6 @@ extern void poll_wait(struct file *filp, static int uartdev_poll(struct file *filep, poll_table *table) { struct UartHost *host = NULL; - //struct UartDriverData *udd = NULL; if (filep == NULL || filep->f_vnode == NULL) { return HDF_ERR_INVALID_PARAM; @@ -191,27 +190,7 @@ static int uartdev_poll(struct file *filep, poll_table *table) struct drv_data *drv = (struct drv_data *)filep->f_vnode->data; host = (struct UartHost *)drv->priv; - /*if (host == NULL || host->priv == NULL) { - HDF_LOGE("%s: host is NULL", __func__); - return HDF_FAILURE; - }*/ return UartHostPollEvent(host, filep, table); - - /*udd = (struct UartDriverData *)host->priv; - if (udd == NULL) { - HDF_LOGE("uart_driver_data is NULL"); - return -EINVAL; - } - if (UART_STATE_USEABLE != udd->state) { - return -EFAULT; - }*/ - - //poll_wait(filep, &udd->wait, table); - - //if (!PL011UartRxBufEmpty(udd)) { - // return POLLIN | POLLRDNORM; - //} - //return 0; } static const struct file_operations_vfs g_uartDevFops = { @@ -231,13 +210,12 @@ static void UartAddRemoveDev(struct UartHost *host, bool add) { int32_t ret; char *devName = NULL; - //struct UartDriverData *udd = NULL; if (host == NULL || host->priv == NULL) { HDF_LOGE("%s invalid parameter", __func__); return; } - //udd = (struct UartDriverData *)host->priv; + devName = (char *)OsalMemCalloc(sizeof(char) * (MAX_DEV_NAME_SIZE + 1)); if (devName == NULL) { HDF_LOGE("%s: OsalMemCalloc error", __func__); -- Gitee From caea9fc7ca72a31dbbf49156f78017b6e2bd58b9 Mon Sep 17 00:00:00 2001 From: haizhouyang Date: Wed, 28 Apr 2021 15:29:25 +0800 Subject: [PATCH 3/3] delete mount PL061_GPIO_USER_SUPPORT --- khdf/liteos/platform/src/gpio_dev.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/khdf/liteos/platform/src/gpio_dev.c b/khdf/liteos/platform/src/gpio_dev.c index d38c59e..7d8f774 100644 --- a/khdf/liteos/platform/src/gpio_dev.c +++ b/khdf/liteos/platform/src/gpio_dev.c @@ -38,8 +38,6 @@ #include "plat_log.h" #include "user_copy.h" -#ifdef PL061_GPIO_USER_SUPPORT - static int GpioOpen(struct file *filep) { (void)filep; @@ -160,4 +158,3 @@ void GpioRemoveVfs(void) HDF_LOGE("%s: unregister vfs fail!", __func__); } } -#endif -- Gitee