mirror of
https://github.com/apache/nuttx.git
synced 2026-05-21 21:34:07 +08:00
sim/gpiochip: add sim gpiochip for gpio autotest
add sim gpiochip driver Signed-off-by: yezhonghui <yezhonghui@xiaomi.com>
This commit is contained in:
committed by
Alan C. Assis
parent
e072356182
commit
36f91643ae
@@ -14,3 +14,4 @@ The following Simulator/Emulators are supported:
|
||||
*/*
|
||||
network_linux
|
||||
network_vpnkit
|
||||
sim_gpiochip
|
||||
|
||||
@@ -0,0 +1,308 @@
|
||||
======================================
|
||||
Sim GPIO Chip Driver (Linux Host GPIO)
|
||||
======================================
|
||||
|
||||
Overview
|
||||
========
|
||||
|
||||
The Sim GPIO Chip driver provides a mechanism for NuttX simulation (sim) to access
|
||||
the Linux host's GPIO chip devices (``/dev/gpiochipN``). This allows NuttX applications
|
||||
running in simulation mode to interact with real hardware GPIO pins connected to the
|
||||
Linux host system.
|
||||
|
||||
This driver is particularly useful for:
|
||||
|
||||
- Testing GPIO-based applications in a simulated environment with real hardware
|
||||
- Interfacing with USB-to-GPIO adapters (e.g., CH341A) from NuttX simulation
|
||||
- Developing and debugging GPIO drivers without dedicated embedded hardware
|
||||
|
||||
Host Prepare
|
||||
============
|
||||
|
||||
Preparation required on the host side:
|
||||
|
||||
- Hardware module required: USB-CH341A module
|
||||
- Refer to https://github.com/frank-zago/ch341-i2c-spi-gpio, and install the driver
|
||||
- Verify existence of /dev/gpiochipN device file
|
||||
|
||||
Architecture
|
||||
============
|
||||
|
||||
The driver consists of two layers:
|
||||
|
||||
1. **NuttX Layer** (``sim_gpiochip.c``): Implements the NuttX ``ioexpander_dev_s``
|
||||
interface, providing standard GPIO operations to upper-layer NuttX drivers.
|
||||
|
||||
2. **Host Layer** (``sim_linux_gpiochip.c``): Interfaces directly with Linux kernel's
|
||||
GPIO character device (``/dev/gpiochipN``) using the GPIO v2 ABI.
|
||||
|
||||
::
|
||||
|
||||
+---------------------+
|
||||
| NuttX Application |
|
||||
+---------------------+
|
||||
|
|
||||
v
|
||||
+---------------------+
|
||||
| GPIO Lower Half |
|
||||
| (gpio_lower_half) |
|
||||
+---------------------+
|
||||
|
|
||||
v
|
||||
+---------------------+
|
||||
| sim_gpiochip.c | <-- NuttX ioexpander interface
|
||||
| (ioexpander_dev_s) |
|
||||
+---------------------+
|
||||
|
|
||||
v
|
||||
+---------------------+
|
||||
| sim_linux_gpiochip.c| <-- Linux host GPIO interface
|
||||
| (GPIO v2 ABI) |
|
||||
+---------------------+
|
||||
|
|
||||
v
|
||||
+---------------------+
|
||||
| /dev/gpiochipN | <-- Linux GPIO character device
|
||||
+---------------------+
|
||||
|
||||
Header Files
|
||||
============
|
||||
|
||||
- ``arch/sim/src/sim/sim_hostgpiochip.h``: Host GPIO chip interface definitions
|
||||
and function prototypes.
|
||||
|
||||
- ``include/nuttx/ioexpander/ioexpander.h``: Standard NuttX IO expander interface.
|
||||
|
||||
- ``include/nuttx/ioexpander/gpio.h``: NuttX GPIO interface definitions.
|
||||
|
||||
Configuration Options
|
||||
=====================
|
||||
|
||||
The following configuration options are relevant to this driver:
|
||||
|
||||
- ``CONFIG_SIM_GPIOCHIP``: Enable the sim GPIO chip driver.
|
||||
- ``CONFIG_IOEXPANDER_NPINS``: Maximum number of GPIO pins supported (default: 64).
|
||||
- ``CONFIG_IOEXPANDER_INT_ENABLE``: Enable interrupt support for GPIO pins.
|
||||
|
||||
Supported Operations
|
||||
====================
|
||||
|
||||
The driver supports the following GPIO operations:
|
||||
|
||||
Direction Control
|
||||
-----------------
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
int sim_gpiochip_direction(struct ioexpander_dev_s *dev,
|
||||
uint8_t pin, int direction);
|
||||
|
||||
Set GPIO pin direction. Supported directions:
|
||||
|
||||
- ``IOEXPANDER_DIRECTION_IN``: Configure as input
|
||||
- ``IOEXPANDER_DIRECTION_OUT``: Configure as output
|
||||
- ``IOEXPANDER_DIRECTION_OUT_OPENDRAIN``: Configure as open-drain output
|
||||
|
||||
Read/Write Pin
|
||||
--------------
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
int sim_gpiochip_readpin(struct ioexpander_dev_s *dev, uint8_t pin,
|
||||
bool *value);
|
||||
int sim_gpiochip_writepin(struct ioexpander_dev_s *dev, uint8_t pin,
|
||||
bool value);
|
||||
|
||||
Read or write the value of a GPIO pin.
|
||||
|
||||
Interrupt Configuration
|
||||
-----------------------
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
int sim_gpiochip_option(struct ioexpander_dev_s *dev, uint8_t pin,
|
||||
int option, void *val);
|
||||
|
||||
Configure GPIO pin options. Supported interrupt edge configurations:
|
||||
|
||||
- ``IOEXPANDER_VAL_RISING``: Trigger on rising edge
|
||||
- ``IOEXPANDER_VAL_FALLING``: Trigger on falling edge
|
||||
- ``IOEXPANDER_VAL_BOTH``: Trigger on both edges
|
||||
- ``IOEXPANDER_VAL_DISABLE``: Disable interrupt
|
||||
|
||||
Interrupt Callback
|
||||
------------------
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
void *sim_gpiochip_attach(struct ioexpander_dev_s *dev,
|
||||
ioe_pinset_t pinset,
|
||||
ioe_callback_t callback,
|
||||
void *arg);
|
||||
int sim_gpiochip_detach(struct ioexpander_dev_s *dev, void *handle);
|
||||
|
||||
Attach or detach an interrupt callback function for GPIO pins.
|
||||
|
||||
Host Layer API
|
||||
==============
|
||||
|
||||
The host layer (``sim_linux_gpiochip.c``) provides the following functions:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
/* Allocate and initialize a host GPIO chip device */
|
||||
struct host_gpiochip_dev *host_gpiochip_alloc(const char *filename);
|
||||
|
||||
/* Free a host GPIO chip device */
|
||||
void host_gpiochip_free(struct host_gpiochip_dev *dev);
|
||||
|
||||
/* Set GPIO pin direction */
|
||||
int host_gpiochip_direction(struct host_gpiochip_dev *dev,
|
||||
uint8_t pin, bool input);
|
||||
|
||||
/* Read GPIO pin value */
|
||||
int host_gpiochip_readpin(struct host_gpiochip_dev *dev,
|
||||
uint8_t pin, bool *value);
|
||||
|
||||
/* Write GPIO pin value */
|
||||
int host_gpiochip_writepin(struct host_gpiochip_dev *dev,
|
||||
uint8_t pin, bool value);
|
||||
|
||||
/* Request GPIO interrupt */
|
||||
int host_gpiochip_irq_request(struct host_gpiochip_dev *dev,
|
||||
uint8_t pin, uint16_t cfgset);
|
||||
|
||||
/* Check if GPIO interrupt is active */
|
||||
bool host_gpiochip_irq_active(struct host_gpiochip_dev *dev, uint8_t pin);
|
||||
|
||||
/* Get GPIO line information */
|
||||
int host_gpiochip_get_line(struct host_gpiochip_dev *priv,
|
||||
uint8_t pin, bool *input);
|
||||
|
||||
Linux Kernel Version Requirements
|
||||
=================================
|
||||
|
||||
The driver uses Linux GPIO v2 ABI, which requires:
|
||||
|
||||
- **Linux kernel >= 6.8.0**: Full functionality with GPIO v2 API support.
|
||||
- **Linux kernel < 6.8.0**: The driver compiles but provides stub implementations
|
||||
that return 0 or NULL.
|
||||
|
||||
Usage Example
|
||||
=============
|
||||
|
||||
Initialization
|
||||
--------------
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#include <nuttx/ioexpander/gpio.h>
|
||||
#include "sim_internal.h"
|
||||
|
||||
int board_gpio_initialize(void)
|
||||
{
|
||||
struct ioexpander_dev_s *ioe;
|
||||
int ret;
|
||||
|
||||
/* Initialize the GPIO chip device */
|
||||
ioe = sim_gpiochip_initialize("/dev/gpiochip0");
|
||||
if (ioe == NULL)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Register GPIO pins using gpio_lower_half */
|
||||
ret = gpio_lower_half(ioe, 0, GPIO_INPUT_PIN, 60); /* Pin 0 as input, minor 60 */
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = gpio_lower_half(ioe, 1, GPIO_OUTPUT_PIN, 61); /* Pin 1 as output, minor 61 */
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
Application Usage
|
||||
-----------------
|
||||
|
||||
After initialization, GPIO pins can be accessed through standard NuttX GPIO interface:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <nuttx/ioexpander/gpio.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int fd;
|
||||
bool value;
|
||||
|
||||
/* Open GPIO device */
|
||||
fd = open("/dev/gpio60", O_RDWR);
|
||||
if (fd < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Read GPIO value */
|
||||
ioctl(fd, GPIOC_READ, &value);
|
||||
printf("GPIO value: %d\n", value);
|
||||
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Interrupt Handling
|
||||
==================
|
||||
|
||||
The driver uses a work queue to poll for GPIO events. The polling interval is
|
||||
defined by ``SIM_GPIOCHIP_WORK_DELAY`` (default: 500 microseconds).
|
||||
|
||||
When an interrupt event is detected on a GPIO pin, the registered callback
|
||||
function is invoked with the pin number and user-provided argument.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
static int gpio_interrupt_handler(struct ioexpander_dev_s *dev,
|
||||
ioe_pinset_t pinset, void *arg)
|
||||
{
|
||||
printf("GPIO interrupt on pin %d\n", pinset);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Attach interrupt handler */
|
||||
void *handle = IOEP_ATTACH(ioe, (1 << pin), gpio_interrupt_handler, NULL);
|
||||
|
||||
/* Configure interrupt edge */
|
||||
IOEP_SETOPTION(ioe, pin, IOEXPANDER_OPTION_INTCFG,
|
||||
(void *)IOEXPANDER_VAL_RISING);
|
||||
|
||||
Files
|
||||
=====
|
||||
|
||||
- ``arch/sim/src/sim/sim_gpiochip.c``: NuttX IO expander implementation
|
||||
- ``arch/sim/src/sim/posix/sim_linux_gpiochip.c``: Linux host GPIO interface
|
||||
- ``arch/sim/src/sim/sim_hostgpiochip.h``: Host GPIO chip header file
|
||||
|
||||
Limitations
|
||||
===========
|
||||
|
||||
1. **Polling-based interrupts**: Due to simulation constraints, interrupts are
|
||||
implemented using polling rather than true hardware interrupts.
|
||||
|
||||
2. **Linux kernel version**: Full functionality requires Linux kernel >= 6.8.0.
|
||||
|
||||
3. **Pin count**: Limited by ``CONFIG_IOEXPANDER_NPINS`` configuration.
|
||||
|
||||
4. **Invert option**: The ``IOEXPANDER_OPTION_INVERT`` option is not yet implemented.
|
||||
|
||||
See Also
|
||||
========
|
||||
|
||||
- Linux GPIO documentation: https://www.kernel.org/doc/html/latest/driver-api/gpio/
|
||||
@@ -661,6 +661,38 @@ config SIM_SPIDEV_NAME
|
||||
|
||||
endif
|
||||
|
||||
config SIM_GPIOCHIP
|
||||
bool "Simulated gpiochip"
|
||||
default n
|
||||
depends on IOEXPANDER
|
||||
---help---
|
||||
Build in support for simulated gpiochip
|
||||
|
||||
if SIM_GPIOCHIP
|
||||
|
||||
choice
|
||||
prompt "Simulated GPIOCHIP Type"
|
||||
default SIM_GPIOCHIP_LINUX
|
||||
|
||||
config SIM_GPIOCHIP_LINUX
|
||||
bool "Linux Gpiochip Character Dev"
|
||||
depends on HOST_LINUX
|
||||
---help---
|
||||
Attach a Linux Gpiochip via the character device
|
||||
interface. To achieve a SPI port on Linux host, it is
|
||||
recommended to use a USB<>GPIO device such as CH341A/B.
|
||||
|
||||
endchoice
|
||||
|
||||
config SIM_GPIOCHIP_NAME
|
||||
string "the name of host gpiochip dev to attach to simulator"
|
||||
default "/dev/gpiochip0"
|
||||
---help---
|
||||
This is the name of the gpiochip device on the host implementation to
|
||||
attach to the simulator driver.
|
||||
|
||||
endif
|
||||
|
||||
menu "Simulated UART"
|
||||
|
||||
config SIM_UART_DMA
|
||||
|
||||
@@ -246,6 +246,11 @@ ifeq ($(CONFIG_SIM_SPI_LINUX),y)
|
||||
HOSTSRCS += sim_linuxspi.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_SIM_GPIOCHIP_LINUX),y)
|
||||
HOSTSRCS += sim_linux_gpiochip.c
|
||||
CSRCS += sim_gpiochip.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_SIM_USB_DEV),y)
|
||||
CSRCS += sim_usbdev.c
|
||||
ifeq ($(CONFIG_SIM_USB_RAW_GADGET),y)
|
||||
|
||||
@@ -249,6 +249,11 @@ if(CONFIG_SIM_SPI_LINUX)
|
||||
list(APPEND HOSTSRCS sim_linuxspi.c)
|
||||
endif()
|
||||
|
||||
if(CONFIG_SIM_GPIOCHIP_LINUX)
|
||||
list(APPEND SRCS sim_gpiochip.c)
|
||||
list(APPEND HOSTSRCS sim_linux_gpiochip.c)
|
||||
endif()
|
||||
|
||||
if(CONFIG_SIM_USB_DEV)
|
||||
list(APPEND SRCS sim_usbdev.c)
|
||||
if(CONFIG_SIM_USB_RAW_GADGET)
|
||||
|
||||
@@ -0,0 +1,419 @@
|
||||
/****************************************************************************
|
||||
* arch/sim/src/sim/posix/sim_linux_gpiochip.c
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <linux/const.h>
|
||||
#include <linux/ioctl.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/gpio.h>
|
||||
|
||||
#include "sim_gpiochip.h"
|
||||
#include "sim_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define gpioerr(fmt, ...) \
|
||||
syslog(LOG_ERR, "sim_linux_gpiochip: " fmt "\n", ##__VA_ARGS__)
|
||||
#define gpioinfo(fmt, ...) \
|
||||
syslog(LOG_ERR, "sim_linux_gpiochip: " fmt "\n", ##__VA_ARGS__)
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: host_gpiochip_direction
|
||||
*
|
||||
* Description:
|
||||
* Provide gpiochip pin direction config.
|
||||
*
|
||||
* Input Parameters:
|
||||
* priv - A pointer to instance of Linux gpiochip.
|
||||
* pin - The pin number.
|
||||
* input - The direction of the pin.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 for success, other for fail.
|
||||
****************************************************************************/
|
||||
|
||||
int host_gpiochip_direction(struct host_gpiochip_dev *priv, uint8_t pin,
|
||||
bool input)
|
||||
{
|
||||
struct gpio_v2_line_request req;
|
||||
int nonblock = 1;
|
||||
int ret;
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.num_lines = 1;
|
||||
req.offsets[0] = pin;
|
||||
|
||||
if (priv->line_fd[pin] > 0)
|
||||
{
|
||||
close(priv->line_fd[pin]);
|
||||
priv->line_fd[pin] = -1;
|
||||
}
|
||||
|
||||
if (input)
|
||||
{
|
||||
req.config.flags = GPIO_V2_LINE_FLAG_INPUT;
|
||||
}
|
||||
else
|
||||
{
|
||||
req.config.flags = GPIO_V2_LINE_FLAG_OUTPUT;
|
||||
}
|
||||
|
||||
snprintf(req.consumer, sizeof(req.consumer) - 1, "gpio%d", pin);
|
||||
ret = host_uninterruptible(ioctl, priv->file, GPIO_V2_GET_LINE_IOCTL,
|
||||
&req);
|
||||
if (ret < 0)
|
||||
{
|
||||
gpioerr("ERROR: pin %d set direction failed\n", pin);
|
||||
return -errno;
|
||||
}
|
||||
|
||||
ret = host_uninterruptible(ioctl, req.fd, FIONBIO, &nonblock);
|
||||
if (ret < 0)
|
||||
{
|
||||
gpioerr("ERROR: Failed to set non-blocking: %s\n", strerror(errno));
|
||||
return -errno;
|
||||
}
|
||||
|
||||
priv->line_fd[pin] = req.fd;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: host_gpiochip_irq_request
|
||||
*
|
||||
* Input Parameters:
|
||||
* priv - A pointer to instance of Linux gpiochip.
|
||||
* pin - The pin number.
|
||||
* cfgset - The config set of the pin.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 for success, other for fail.
|
||||
****************************************************************************/
|
||||
|
||||
int host_gpiochip_irq_request(struct host_gpiochip_dev *priv, uint8_t pin,
|
||||
uint16_t cfg)
|
||||
{
|
||||
struct gpio_v2_line_request req;
|
||||
int nonblock = 1;
|
||||
int ret;
|
||||
|
||||
if (priv->line_fd[pin] > 0)
|
||||
{
|
||||
close(priv->line_fd[pin]);
|
||||
priv->line_fd[pin] = -1;
|
||||
}
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
switch (cfg)
|
||||
{
|
||||
case GPIOCHIP_LINE_FLAG_FALLING:
|
||||
req.config.flags = GPIO_V2_LINE_FLAG_EDGE_FALLING;
|
||||
break;
|
||||
case GPIOCHIP_LINE_FLAG_RISING:
|
||||
req.config.flags = GPIO_V2_LINE_FLAG_EDGE_RISING;
|
||||
break;
|
||||
case GPIOCHIP_LINE_FLAG_BOTH:
|
||||
req.config.flags = GPIO_V2_LINE_FLAG_EDGE_FALLING |
|
||||
GPIO_V2_LINE_FLAG_EDGE_RISING;
|
||||
break;
|
||||
default:
|
||||
req.config.flags = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
req.offsets[0] = pin;
|
||||
req.num_lines = 1;
|
||||
req.config.flags |= GPIO_V2_LINE_FLAG_INPUT;
|
||||
if (req.config.flags != GPIO_V2_LINE_FLAG_INPUT)
|
||||
{
|
||||
snprintf(req.consumer, sizeof(req.consumer) - 1, "gpio-irq%d", pin);
|
||||
}
|
||||
|
||||
/* Warn only pin 10 can register in ch341A */
|
||||
|
||||
ret = host_uninterruptible(ioctl, priv->file, GPIO_V2_GET_LINE_IOCTL,
|
||||
&req);
|
||||
if (ret < 0)
|
||||
{
|
||||
gpioerr("ERROR: ioctl failed: %s \n", strerror(errno));
|
||||
return -errno;
|
||||
}
|
||||
|
||||
ret = host_uninterruptible(ioctl, req.fd, FIONBIO, &nonblock);
|
||||
if (ret < 0)
|
||||
{
|
||||
gpioerr("ERROR: Failed to set non-blocking: %s\n", strerror(errno));
|
||||
return -errno;
|
||||
}
|
||||
|
||||
priv->line_fd[pin] = req.fd;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: host_gpiochip_writepin
|
||||
*
|
||||
* Description:
|
||||
* Write gpiochip pin value.
|
||||
*
|
||||
* Input Parameters:
|
||||
* priv - A pointer to instance of Linux gpiochip.
|
||||
* pin - The pin number.
|
||||
* value - The value write to the pin.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 for success, other for fail.
|
||||
****************************************************************************/
|
||||
|
||||
int host_gpiochip_writepin(struct host_gpiochip_dev *priv, uint8_t pin,
|
||||
bool value)
|
||||
{
|
||||
struct gpio_v2_line_values vals;
|
||||
int ret;
|
||||
|
||||
if (priv->line_fd[pin] <= 0)
|
||||
{
|
||||
gpioerr("ERROR: Invalid pin %d config\n", pin);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
memset(&vals, 0, sizeof(vals));
|
||||
vals.mask = 1;
|
||||
vals.bits = !!value;
|
||||
|
||||
ret = host_uninterruptible(ioctl, priv->line_fd[pin],
|
||||
GPIO_V2_LINE_SET_VALUES_IOCTL, &vals);
|
||||
if (ret < 0)
|
||||
{
|
||||
gpioerr("ERROR: Failed to set pin %d value %d\n", pin, value);
|
||||
return -errno;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: host_gpiochip_readpin
|
||||
*
|
||||
* Description:
|
||||
* Read gpiochip pin value.
|
||||
*
|
||||
* Input Parameters:
|
||||
* priv - A pointer to instance of Linux gpiochip.
|
||||
* pin - The pin number.
|
||||
* value - The value write to the pin.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 for success, other for fail.
|
||||
****************************************************************************/
|
||||
|
||||
int host_gpiochip_readpin(struct host_gpiochip_dev *priv, uint8_t pin,
|
||||
bool *value)
|
||||
{
|
||||
struct gpio_v2_line_values vals;
|
||||
int ret;
|
||||
|
||||
if (priv->line_fd[pin] <= 0)
|
||||
{
|
||||
gpioerr("ERROR: Invalid pin %d config\n", pin);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
memset(&vals, 0, sizeof(vals));
|
||||
vals.mask = 1;
|
||||
ret = host_uninterruptible(ioctl, priv->line_fd[pin],
|
||||
GPIO_V2_LINE_GET_VALUES_IOCTL, &vals);
|
||||
if (ret < 0)
|
||||
{
|
||||
gpioerr("ERROR: Failed to get pin%d value, errno[%d]\n", pin, errno);
|
||||
return -errno;
|
||||
}
|
||||
|
||||
*value = !!(vals.bits & 0x01);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: host_gpiochip_irq_active
|
||||
*
|
||||
* Description:
|
||||
* register gpio for gpiochip device
|
||||
*
|
||||
* Input Parameters:
|
||||
* priv - A pointer to instance of Linux gpiochip.
|
||||
* pin - gpio pin of Linux gpiochip device.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 for OK.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
bool host_gpiochip_irq_active(struct host_gpiochip_dev *priv, uint8_t pin)
|
||||
{
|
||||
if (priv->line_fd[pin] > 0)
|
||||
{
|
||||
struct gpio_v2_line_event ev;
|
||||
int fd = priv->line_fd[pin];
|
||||
memset(&ev, 0, sizeof(ev));
|
||||
if (host_uninterruptible(read, fd, &ev, sizeof(ev)) == sizeof(ev))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: host_gpiochip_get_line
|
||||
*
|
||||
* Description:
|
||||
* Get line info from gpiochip device
|
||||
*
|
||||
* Input Parameters:
|
||||
* priv - A pointer to instance of Linux gpiochip.
|
||||
* pin - gpio line of Linux gpiochip.
|
||||
* input - A pointer to direction of gpioline.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 for OK.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int host_gpiochip_get_line(struct host_gpiochip_dev *priv, uint8_t pin,
|
||||
bool *input)
|
||||
{
|
||||
struct gpio_v2_line_info info;
|
||||
int ret;
|
||||
|
||||
memset(&info, 0, sizeof(info));
|
||||
info.offset = pin;
|
||||
ret = host_uninterruptible(ioctl, priv->file, GPIO_V2_GET_LINEINFO_IOCTL,
|
||||
&info);
|
||||
if (ret < 0)
|
||||
{
|
||||
gpioerr("Failed to get line info: %d", ret);
|
||||
return -errno;
|
||||
}
|
||||
|
||||
if (info.flags & GPIO_V2_LINE_FLAG_USED)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (info.flags & GPIO_V2_LINE_FLAG_OUTPUT)
|
||||
{
|
||||
*input = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
*input = true;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: host_gpiochip_alloc
|
||||
*
|
||||
* Description:
|
||||
* Initialize one gpiochip device
|
||||
*
|
||||
* Input Parameters:
|
||||
* filename - the name of gpiochip device in Linux, e.g. "/dev/gpiochipN".
|
||||
*
|
||||
* Returned Value:
|
||||
* The pointer to the instance of Linux gpiochip device.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
struct host_gpiochip_dev *host_gpiochip_alloc(const char *filename)
|
||||
{
|
||||
struct host_gpiochip_dev *dev;
|
||||
|
||||
dev = malloc(sizeof(struct host_gpiochip_dev));
|
||||
if (!dev)
|
||||
{
|
||||
gpioerr("Failed to allocate memory for gpiochip device");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dev->file = host_uninterruptible(open, filename, O_RDWR | O_CLOEXEC);
|
||||
if (dev->file < 0)
|
||||
{
|
||||
gpioerr("Failed to open %s: %d", filename, dev->file);
|
||||
free(dev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: host_gpiochip_free
|
||||
*
|
||||
* Description:
|
||||
* Uninitialize an gpiochip device
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void host_gpiochip_free(struct host_gpiochip_dev *priv)
|
||||
{
|
||||
host_uninterruptible(close, priv->file);
|
||||
free(priv);
|
||||
}
|
||||
@@ -0,0 +1,454 @@
|
||||
/****************************************************************************
|
||||
* arch/sim/src/sim/sim_gpiochip.c
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <debug.h>
|
||||
#include <nuttx/wdog.h>
|
||||
#include <nuttx/ioexpander/gpio.h>
|
||||
#include <nuttx/ioexpander/ioexpander.h>
|
||||
|
||||
#include "sim_gpiochip.h"
|
||||
#include "sim_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define GPIOCHIP_LINE_BASE 60
|
||||
#define SIM_GPIOCHIP_WDOG_DELAY USEC2TICK(500)
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
struct sim_gpiochip_callback_s
|
||||
{
|
||||
ioe_callback_t cbfunc;
|
||||
void *cbarg;
|
||||
};
|
||||
|
||||
struct sim_gpiochip_dev_s
|
||||
{
|
||||
const struct ioexpander_ops_s *ops; /* gpiochip vtable */
|
||||
struct sim_gpiochip_callback_s cb[CONFIG_IOEXPANDER_NPINS];
|
||||
struct host_gpiochip_dev *dev;
|
||||
struct wdog_s wdog; /* poll work */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
static int sim_gpiochip_direction(struct ioexpander_dev_s *dev,
|
||||
uint8_t pin, int direction);
|
||||
static int sim_gpiochip_option(struct ioexpander_dev_s *dev, uint8_t pin,
|
||||
int option, void *val);
|
||||
static int sim_gpiochip_writepin(struct ioexpander_dev_s *dev, uint8_t pin,
|
||||
bool value);
|
||||
static int sim_gpiochip_readpin(struct ioexpander_dev_s *dev, uint8_t pin,
|
||||
bool *value);
|
||||
#ifdef CONFIG_IOEXPANDER_INT_ENABLE
|
||||
static void *sim_gpiochip_attach(struct ioexpander_dev_s *dev,
|
||||
uint16_t pinset,
|
||||
ioe_callback_t callback,
|
||||
void *arg);
|
||||
static int sim_gpiochip_detach(struct ioexpander_dev_s *dev,
|
||||
void *handle);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static struct ioexpander_ops_s g_sim_gpiochip_ops =
|
||||
{
|
||||
.ioe_direction = sim_gpiochip_direction,
|
||||
.ioe_option = sim_gpiochip_option,
|
||||
.ioe_writepin = sim_gpiochip_writepin,
|
||||
.ioe_readpin = sim_gpiochip_readpin,
|
||||
.ioe_readbuf = sim_gpiochip_readpin,
|
||||
#ifdef CONFIG_IOEXPANDER_INT_ENABLE
|
||||
.ioe_attach = sim_gpiochip_attach,
|
||||
.ioe_detach = sim_gpiochip_detach,
|
||||
#endif
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sim_gpiochip_direction
|
||||
*
|
||||
* Description:
|
||||
* Provide gpiochip pin direction config.
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - A pointer to instance of sim gpiochip device.
|
||||
* pin - The pin number.
|
||||
* direction - The direction of the pin.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 for success, other for fail.
|
||||
****************************************************************************/
|
||||
|
||||
static int sim_gpiochip_direction(struct ioexpander_dev_s *dev,
|
||||
uint8_t pin, int direction)
|
||||
{
|
||||
struct sim_gpiochip_dev_s *priv = (struct sim_gpiochip_dev_s *)dev;
|
||||
|
||||
if (direction == IOEXPANDER_DIRECTION_OUT ||
|
||||
direction == IOEXPANDER_DIRECTION_OUT_OPENDRAIN)
|
||||
{
|
||||
return host_gpiochip_direction(priv->dev, pin, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
return host_gpiochip_direction(priv->dev, pin, true);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sim_gpiochip_option
|
||||
*
|
||||
* Description:
|
||||
* Provide gpiochip pin option.
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - A pointer to instance of sim gpiochip device.
|
||||
* pin - The pin number.
|
||||
* option.- The option type.
|
||||
* val - A pointer to val of the pin.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 for success, other for fail.
|
||||
****************************************************************************/
|
||||
|
||||
static int sim_gpiochip_option(struct ioexpander_dev_s *dev, uint8_t pin,
|
||||
int option, void *val)
|
||||
{
|
||||
struct sim_gpiochip_dev_s *priv = (struct sim_gpiochip_dev_s *)dev;
|
||||
uint16_t cfgset = 0;
|
||||
int ret = 0;
|
||||
|
||||
if (option == IOEXPANDER_OPTION_INTCFG)
|
||||
{
|
||||
switch ((uintptr_t)val)
|
||||
{
|
||||
case IOEXPANDER_VAL_FALLING:
|
||||
cfgset = GPIOCHIP_LINE_FLAG_FALLING;
|
||||
break;
|
||||
|
||||
case IOEXPANDER_VAL_RISING:
|
||||
cfgset = GPIOCHIP_LINE_FLAG_RISING;
|
||||
break;
|
||||
|
||||
case IOEXPANDER_VAL_BOTH:
|
||||
cfgset = GPIOCHIP_LINE_FLAG_BOTH;
|
||||
break;
|
||||
|
||||
case IOEXPANDER_VAL_DISABLE:
|
||||
cfgset = GPIOCHIP_LINE_FLAG_DISABLE;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
ret = host_gpiochip_irq_request(priv->dev, pin, cfgset);
|
||||
if (ret < 0)
|
||||
{
|
||||
gpioerr("ERROR: Failed to request event: %s\n", strerror(errno));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gpioinfo("gpiochip io option not support\n");
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sim_gpiochip_writepin
|
||||
*
|
||||
* Description:
|
||||
* Write gpiochip pin value.
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - A pointer to instance of sim gpiochip device.
|
||||
* pin - The pin number.
|
||||
* value - The value write to the pin.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 for success, other for fail.
|
||||
****************************************************************************/
|
||||
|
||||
static int sim_gpiochip_writepin(struct ioexpander_dev_s *dev, uint8_t pin,
|
||||
bool value)
|
||||
{
|
||||
struct sim_gpiochip_dev_s *priv = (struct sim_gpiochip_dev_s *)dev;
|
||||
|
||||
return host_gpiochip_writepin(priv->dev, pin, value);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sim_gpiochip_readpin
|
||||
*
|
||||
* Description:
|
||||
* Read gpiochip pin value.
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - A pointer to instance of sim gpiochip device.
|
||||
* pin - The pin number.
|
||||
* value - The value write to the pin.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 for success, other for fail.
|
||||
****************************************************************************/
|
||||
|
||||
static int sim_gpiochip_readpin(struct ioexpander_dev_s *dev, uint8_t pin,
|
||||
bool *value)
|
||||
{
|
||||
struct sim_gpiochip_dev_s *priv = (struct sim_gpiochip_dev_s *)dev;
|
||||
|
||||
return host_gpiochip_readpin(priv->dev, pin, value);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IOEXPANDER_INT_ENABLE
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sim_gpiochip_attach
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 for success, other for fail.
|
||||
****************************************************************************/
|
||||
|
||||
static void *sim_gpiochip_attach(struct ioexpander_dev_s *dev,
|
||||
ioe_pinset_t pinset,
|
||||
ioe_callback_t callback,
|
||||
void *arg)
|
||||
{
|
||||
struct sim_gpiochip_dev_s *priv = (struct sim_gpiochip_dev_s *)dev;
|
||||
void *handle = NULL;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < CONFIG_IOEXPANDER_NPINS; i++)
|
||||
{
|
||||
if (pinset & (1 << i))
|
||||
{
|
||||
priv->cb[i].cbarg = arg;
|
||||
handle = &priv->cb[i];
|
||||
priv->cb[i].cbfunc = callback;
|
||||
}
|
||||
}
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sim_gpiochip_detach
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 for success, other for fail.
|
||||
****************************************************************************/
|
||||
|
||||
static int sim_gpiochip_detach(struct ioexpander_dev_s *dev, void *handle)
|
||||
{
|
||||
struct sim_gpiochip_dev_s *priv = (struct sim_gpiochip_dev_s *)dev;
|
||||
struct sim_gpiochip_callback_s *cb = handle;
|
||||
|
||||
if (priv == NULL || cb == NULL)
|
||||
{
|
||||
gpioerr("ERROR: Invalid handle\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
cb->cbfunc = NULL;
|
||||
cb->cbarg = NULL;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sim_gpiochip_register_gpio
|
||||
*
|
||||
* Description:
|
||||
* register gpio for gpiochip device
|
||||
*
|
||||
* Input Parameters:
|
||||
* priv - A pointer to instance of sim gpiochip device.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 for OK.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int sim_gpiochip_register_gpio(struct sim_gpiochip_dev_s *priv)
|
||||
{
|
||||
struct ioexpander_dev_s *ioe = (struct ioexpander_dev_s *)priv;
|
||||
bool input;
|
||||
int line;
|
||||
int ret;
|
||||
|
||||
for (line = 0; line < CONFIG_IOEXPANDER_NPINS; line++)
|
||||
{
|
||||
ret = host_gpiochip_get_line(priv->dev, line, &input);
|
||||
if (ret != 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (input)
|
||||
{
|
||||
ret = gpio_lower_half(ioe, line, GPIO_INPUT_PIN,
|
||||
GPIOCHIP_LINE_BASE + line);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = gpio_lower_half(ioe, line, GPIO_OUTPUT_PIN,
|
||||
GPIOCHIP_LINE_BASE + line);
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sim_gpiochip_irq_process
|
||||
*
|
||||
* Description:
|
||||
* work to poll irq event for gpiochip device
|
||||
*
|
||||
* Input Parameters:
|
||||
* priv - A pointer to instance of sim gpiochip device.
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void sim_gpiochip_irq_process(struct sim_gpiochip_dev_s *priv)
|
||||
{
|
||||
int line;
|
||||
|
||||
for (line = 0; line < CONFIG_IOEXPANDER_NPINS; line++)
|
||||
{
|
||||
if (host_gpiochip_irq_active(priv->dev, line))
|
||||
{
|
||||
if (priv->cb[line].cbfunc)
|
||||
{
|
||||
priv->cb[line].cbfunc((struct ioexpander_dev_s *)priv,
|
||||
line, priv->cb[line].cbarg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sim_gpiochip_interrupt
|
||||
*
|
||||
* Description:
|
||||
* wdog timer function for gpiochip device
|
||||
*
|
||||
* Input Parameters:
|
||||
* arg - A pointer to instance of sim gpiochip device.
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void sim_gpiochip_interrupt(wdparm_t arg)
|
||||
{
|
||||
struct sim_gpiochip_dev_s *priv = (struct sim_gpiochip_dev_s *)arg;
|
||||
|
||||
if (priv)
|
||||
{
|
||||
sim_gpiochip_irq_process(priv);
|
||||
|
||||
wd_start(&priv->wdog, SIM_GPIOCHIP_WDOG_DELAY,
|
||||
sim_gpiochip_interrupt, (wdparm_t)priv);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sim_gpiochip_initialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize one gpiochip device
|
||||
*
|
||||
* Input Parameters:
|
||||
* path - the name of gpiochip device in sim, e.g. "/dev/gpiochipN".
|
||||
*
|
||||
* Returned Value:
|
||||
* The pointer to the instance of sim gpiochip device.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int sim_gpiochip_initialize(const char *path)
|
||||
{
|
||||
struct sim_gpiochip_dev_s *priv;
|
||||
int ret;
|
||||
|
||||
priv = kmm_zalloc(sizeof(struct sim_gpiochip_dev_s));
|
||||
if (priv == NULL)
|
||||
{
|
||||
gpioerr("Failed to allocate memory for gpiochip device");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
priv->ops = &g_sim_gpiochip_ops;
|
||||
|
||||
priv->dev = host_gpiochip_alloc(path);
|
||||
if (priv->dev == NULL)
|
||||
{
|
||||
gpioerr("Failed to init gpiochip: %d", ret);
|
||||
kmm_free(priv);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ret = sim_gpiochip_register_gpio(priv);
|
||||
if (ret < 0)
|
||||
{
|
||||
gpioerr("Failed to register gpio: %d", ret);
|
||||
host_gpiochip_free(priv->dev);
|
||||
kmm_free(priv);
|
||||
return ret;
|
||||
}
|
||||
|
||||
wd_start(&priv->wdog, SIM_GPIOCHIP_WDOG_DELAY,
|
||||
sim_gpiochip_interrupt, (wdparm_t)priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/****************************************************************************
|
||||
* arch/sim/src/sim/sim_gpiochip.h
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __ARCH_SIM_SRC_SIM_GPIOCHIP_H
|
||||
#define __ARCH_SIM_SRC_SIM_GPIOCHIP_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef __SIM__
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define GPIOCHIP_LINE_FLAG_DISABLE (1 << 0)
|
||||
#define GPIOCHIP_LINE_FLAG_RISING (1 << 1)
|
||||
#define GPIOCHIP_LINE_FLAG_FALLING (1 << 2)
|
||||
#define GPIOCHIP_LINE_FLAG_BOTH (1 << 3)
|
||||
|
||||
/****************************************************************************
|
||||
* Type Definitions
|
||||
****************************************************************************/
|
||||
|
||||
struct host_gpiochip_dev
|
||||
{
|
||||
int file;
|
||||
int line_fd[CONFIG_IOEXPANDER_NPINS];
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
struct host_gpiochip_dev *host_gpiochip_alloc(const char *filename);
|
||||
void host_gpiochip_free(struct host_gpiochip_dev *dev);
|
||||
int host_gpiochip_get_line(struct host_gpiochip_dev *priv, uint8_t pin,
|
||||
bool *input);
|
||||
int host_gpiochip_readpin(struct host_gpiochip_dev *dev,
|
||||
uint8_t line, bool *value);
|
||||
int host_gpiochip_writepin(struct host_gpiochip_dev *dev,
|
||||
uint8_t pin, bool value);
|
||||
int host_gpiochip_direction(struct host_gpiochip_dev *dev,
|
||||
uint8_t pin, bool input);
|
||||
int host_gpiochip_irq_request(struct host_gpiochip_dev *dev, uint8_t pin,
|
||||
uint16_t cfgset);
|
||||
bool host_gpiochip_irq_active(struct host_gpiochip_dev *dev, uint8_t pin);
|
||||
|
||||
#endif /* __ARCH_SIM_SRC_SIM_GPIOCHIP_H */
|
||||
@@ -516,5 +516,9 @@ size_t sim_stack_check(void *alloc, size_t size);
|
||||
void sim_stack_color(void *stackbase, size_t nbytes);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SIM_GPIOCHIP
|
||||
int sim_gpiochip_initialize(const char *filename);
|
||||
#endif
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
#endif /* __ARCH_SIM_SRC_SIM_INTERNAL_H */
|
||||
|
||||
Reference in New Issue
Block a user