driver/pinctl: add pinctrl framework

Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
This commit is contained in:
dongjiuzhu1 2023-09-20 15:27:12 +08:00 committed by Xiang Xiao
parent f6d378e528
commit 1d5f43664d
11 changed files with 622 additions and 0 deletions

View File

@ -178,6 +178,10 @@ Subdirectories of ``nuttx/drivers``
Note Driver Support. Note Driver Support.
* ``pinctrl/`` :doc:`special/pinctrl`
Configure and manage pin.
* ``pipes/`` :doc:`special/pipes` * ``pipes/`` :doc:`special/pipes`
FIFO and named pipe drivers. FIFO and named pipe drivers.

View File

@ -48,6 +48,7 @@ following section.
usrsock.rst usrsock.rst
mmcsd.rst mmcsd.rst
net/index.rst net/index.rst
pinctrl.rst
pipes.rst pipes.rst
power/index.rst power/index.rst
virtio.rst virtio.rst

View File

@ -0,0 +1,38 @@
======================
Pinctrl Device Drivers
======================
- The Pinctl driver framework allows applications and drivers to flexibly configure
and manage pin parameters such as functionality, strength, driver type, and slewrate
(voltage transition speed). This framework significantly enhances the flexibility
and configurability of the system in terms of hardware interface control.
- ``include/nuttx/pinctrl/pinctrl.h``
All structures and APIs needed to work with pinctrl drivers are provided in
this header file.
- ``struct pinctrl_dev_s`` and ``struct pinctrl_ops_s``.
Each pinctrl device driver must implement an instance of ``struct pinctrl_dev_s``.
And the ``struct pinctrl_ops_s`` defines a call table with the following methods:
#. **set_function**: Configures the pin's multiplexing (Mux) function, allowing it
to be set as a specific hardware interface (e.g., UART, SPI, I2C) or as a
general-purpose GPIO pin.
#. **set_strength**: Allows the user to configure the pin's drive strength to meet
the requirements of different hardware interfaces.
#. **set_driver**: Controls the pin's driver type, such as push-pull output or
open-drain output.
#. **set_slewrate**: Enables the configuration of pin slew rate, which is crucial
for high-speed digital signal transmission, optimizing signal rise and fall times.
#. **select_gpio**: Configures the pin function as GPIO.
- Convenience macros are provided to map these operations directly:
``PINCTRL_SETFUNCTION``,``PINCTRL_SETSTRENGTH``,``PINCTRL_SETDRIVER``,``PINCTRL_SETSLEWRATE``,
``PINCTRL_SELECTGPIO``.
- Application developers can configure and control pins by opening /dev/pinctrl0 nodes
and using the ioctl system call.
cmd: PINCTRLC_SETFUNCTION, PINCTRLC_SETSTRENGTH, PINCTRLC_SETDRIVER, PINCTRLC_SETSLEWRATE,
PINCTRLC_SELECTGPIO.
parameters: struct pinctrl_param_s.

View File

@ -33,6 +33,7 @@ source "drivers/eeprom/Kconfig"
source "drivers/efuse/Kconfig" source "drivers/efuse/Kconfig"
source "drivers/net/Kconfig" source "drivers/net/Kconfig"
source "drivers/note/Kconfig" source "drivers/note/Kconfig"
source "drivers/pinctrl/Kconfig"
source "drivers/pipes/Kconfig" source "drivers/pipes/Kconfig"
source "drivers/power/Kconfig" source "drivers/power/Kconfig"
source "drivers/regmap/Kconfig" source "drivers/regmap/Kconfig"

View File

@ -52,6 +52,7 @@ include eeprom/Make.defs
include efuse/Make.defs include efuse/Make.defs
include net/Make.defs include net/Make.defs
include note/Make.defs include note/Make.defs
include pinctrl/Make.defs
include pipes/Make.defs include pipes/Make.defs
include power/Make.defs include power/Make.defs
include regmap/Make.defs include regmap/Make.defs

View File

@ -0,0 +1,27 @@
# ##############################################################################
# drivers/pinctrl/CMakeLists.txt
#
# 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.
#
# ##############################################################################
set(SRCS)
if(CONFIG_PINCTRL)
list(APPEND SRCS pinctrl.c)
endif()
target_sources(drivers PRIVATE ${SRCS})

15
drivers/pinctrl/Kconfig Normal file
View File

@ -0,0 +1,15 @@
#
# For a description of the syntax of this configuration file,
# see the file kconfig-language.txt in the NuttX tools repository.
#
menu "Pinctrl Support"
config PINCTRL
bool "PINCTRL Driver Support"
default n
---help---
This selection enables selection of common PINCTRL options. This option
should be enabled by all platforms that support PINCTRL interfaces.
See include/nuttx/pinctrl/pinctrl.h for further PINCTRL driver information.
endmenu

29
drivers/pinctrl/Make.defs Normal file
View File

@ -0,0 +1,29 @@
############################################################################
# drivers/pinctrl/Make.defs
#
# 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.
#
############################################################################
# Don't build anything if there is no PINCTRL support
ifeq ($(CONFIG_PINCTRL),y)
CSRCS += pinctrl.c
DEPPATH += --dep-path pinctrl
VPATH += :pinctrl
CFLAGS += ${INCDIR_PREFIX}$(TOPDIR)$(DELIM)drivers$(DELIM)pinctrl
endif

245
drivers/pinctrl/pinctrl.c Normal file
View File

@ -0,0 +1,245 @@
/****************************************************************************
* drivers/pinctrl/pinctrl.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 <nuttx/config.h>
#include <sys/types.h>
#include <stdio.h>
#include <assert.h>
#include <errno.h>
#include <nuttx/fs/fs.h>
#include <nuttx/pinctrl/pinctrl.h>
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
static int pinctrl_open(FAR struct file *filep);
static int pinctrl_close(FAR struct file *filep);
static ssize_t pinctrl_read(FAR struct file *filep, FAR char *buffer,
size_t buflen);
static ssize_t pinctrl_write(FAR struct file *filep, FAR const char *buffer,
size_t buflen);
static int pinctrl_ioctl(FAR struct file *filep, int cmd,
unsigned long arg);
/****************************************************************************
* Private Data
****************************************************************************/
static const struct file_operations g_pinctrl_drvrops =
{
pinctrl_open, /* open */
pinctrl_close, /* close */
pinctrl_read, /* read */
pinctrl_write, /* write */
NULL, /* seek */
pinctrl_ioctl /* ioctl */
};
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: pinctrl_open
*
* Description:
* Standard character driver open method.
*
****************************************************************************/
static int pinctrl_open(FAR struct file *filep)
{
return OK;
}
/****************************************************************************
* Name: pinctrl_close
*
* Description:
* Standard character driver close method.
*
****************************************************************************/
static int pinctrl_close(FAR struct file *filep)
{
return OK;
}
/****************************************************************************
* Name: pinctrl_read
*
* Description:
* Standard character driver read method.
*
****************************************************************************/
static ssize_t pinctrl_read(FAR struct file *filep, FAR char *buffer,
size_t buflen)
{
return 0;
}
/****************************************************************************
* Name: pinctrl_write
*
* Description:
* Standard character driver write method.
*
****************************************************************************/
static ssize_t pinctrl_write(FAR struct file *filep, FAR const char *buffer,
size_t buflen)
{
return buflen;
}
/****************************************************************************
* Name: pinctrl_ioctl
*
* Description:
* Standard character driver ioctl method.
*
****************************************************************************/
static int pinctrl_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
{
FAR struct inode *inode;
FAR struct pinctrl_dev_s *dev;
FAR struct pinctrl_param_s *param;
int ret;
DEBUGASSERT(filep != NULL && filep->f_inode != NULL);
inode = filep->f_inode;
DEBUGASSERT(inode->i_private != NULL);
dev = inode->i_private;
switch (cmd)
{
/* Command: PINCTRLC_SETFUNCTION
* Description: Set the mux function of the pinctrl pin
* Argument: A pointer to an instance of struct pinctrl_param_s
*/
case PINCTRLC_SETFUNCTION:
{
param = (FAR struct pinctrl_param_s *)((uintptr_t)arg);
ret = PINCTRL_SETFUNCTION(dev, param->pin, param->para.function);
}
break;
/* Command: PINCTRLC_SETSTRENGTH
* Description: Set the driver strength of the pinctrl pin
* Argument: A pointer to an instance of struct pinctrl_param_s
*/
case PINCTRLC_SETSTRENGTH:
{
param = (FAR struct pinctrl_param_s *)((uintptr_t)arg);
ret = PINCTRL_SETSTRENGTH(dev, param->pin, param->para.strength);
}
break;
/* Command: PINCTRLC_SETDRIVER
* Description: Set the driver type of the pinctrl pin
* Argument: A pointer to an instance of struct pinctrl_param_s
*/
case PINCTRLC_SETDRIVER:
{
param = (FAR struct pinctrl_param_s *)((uintptr_t)arg);
ret = PINCTRL_SETDRIVER(dev, param->pin, param->para.type);
}
break;
/* Command: PINCTRLC_SETSLEWRATE
* Description: Set slewrate of the pinctrl pin
* Argument: A pointer to an instance of struct pinctrl_param_s
*/
case PINCTRLC_SETSLEWRATE:
{
param = (FAR struct pinctrl_param_s *)((uintptr_t)arg);
ret = PINCTRL_SETSLEWRATE(dev, param->pin, param->para.slewrate);
}
break;
/* Command: PINCTRLC_SELECTGPIO
* Description: Select gpio function of pinctrl pin
* Argument: The uint32_t pinctrl number
*/
case PINCTRLC_SELECTGPIO:
{
ret = PINCTRL_SELECTGPIO(dev, arg);
}
break;
/* Unrecognized command */
default:
ret = -ENOTTY;
break;
}
return ret;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: pinctrl_register
*
* Description:
* Register PINCTRL device driver.
*
****************************************************************************/
int pinctrl_register(FAR struct pinctrl_dev_s *dev, int minor)
{
char devname[32];
snprintf(devname, 16, "/dev/pinctrl%u", (unsigned int)minor);
return register_driver(devname, &g_pinctrl_drvrops, 0666, dev);
}
/****************************************************************************
* Name: pinctrl_unregister
*
* Description:
* Unregister PINCTRL device driver.
*
****************************************************************************/
void pinctrl_unregister(FAR struct pinctrl_dev_s *dev, int minor)
{
char devname[32];
snprintf(devname, 16, "/dev/pinctrl%u", (unsigned int)minor);
(void)unregister_driver(devname);
}

View File

@ -101,6 +101,7 @@
#define _STEPIOBASE (0x3d00) /* Stepper device ioctl commands */ #define _STEPIOBASE (0x3d00) /* Stepper device ioctl commands */
#define _FPGACFGBASE (0x3e00) /* FPGA configuration ioctl commands */ #define _FPGACFGBASE (0x3e00) /* FPGA configuration ioctl commands */
#define _FFIOCBASE (0x3f00) /* Force feedback ioctl commands */ #define _FFIOCBASE (0x3f00) /* Force feedback ioctl commands */
#define _PINCTRLBASE (0x4000) /* Pinctrl driver ioctl commands */
#define _PCIBASE (0x4100) /* Pci ioctl commands */ #define _PCIBASE (0x4100) /* Pci ioctl commands */
#define _WLIOCBASE (0x8b00) /* Wireless modules ioctl network commands */ #define _WLIOCBASE (0x8b00) /* Wireless modules ioctl network commands */
@ -732,6 +733,13 @@
#define _FFIOCVALID(c) (_IOC_TYPE(c)==_FFIOCBASE) #define _FFIOCVALID(c) (_IOC_TYPE(c)==_FFIOCBASE)
#define _FFIOC(nr) _IOC(_FFIOCBASE,nr) #define _FFIOC(nr) _IOC(_FFIOCBASE,nr)
/* Pinctrl driver command definitions ***************************************/
/* see nuttx/include/pinctrl/pinctrl.h */
#define _PINCTRLIOCVALID(c) (_IOC_TYPE(c)==_PINCTRLBASE)
#define _PINCTRLIOC(nr) _IOC(_PINCTRLBASE,nr)
/**************************************************************************** /****************************************************************************
* Public Type Definitions * Public Type Definitions
****************************************************************************/ ****************************************************************************/

View File

@ -0,0 +1,253 @@
/****************************************************************************
* include/nuttx/pinctrl/pinctrl.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 __INCLUDE_NUTTX_PINCTRL_PINCTRL_H
#define __INCLUDE_NUTTX_PINCTRL_PINCTRL_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <nuttx/fs/ioctl.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Command: PINCTRLC_SETFUNCTION
* Description: Set the mux function of the pinctrl pin
* Argument: A pointer to an instance of struct pinctrl_iotrans_s
*
* Command: PINCTRLC_SETSTRENGTH
* Description: Set the driver strength of the pinctrl pin
* Argument: A pointer to an instance of struct pinctrl_iotrans_s
*
* Command: PINCTRLC_SETDRIVER
* Description: Set the driver type of the pinctrl pin
* Argument: A pointer to an instance of struct pinctrl_iotrans_s
*
* Command: PINCTRLC_SETSLEWRATE
* Description: Set slewrate of the pinctrl pin
* Argument: A pointer to an instance of struct pinctrl_iotrans_s
*
* Command: PINCTRLC_SELECTGPIO
* Description: Select gpio function of pinctrl pin
* Argument: The uint32_t pinctrl number
*
*/
#define PINCTRLC_SETFUNCTION _PINCTRLIOC(1)
#define PINCTRLC_SETSTRENGTH _PINCTRLIOC(2)
#define PINCTRLC_SETDRIVER _PINCTRLIOC(3)
#define PINCTRLC_SETSLEWRATE _PINCTRLIOC(4)
#define PINCTRLC_SELECTGPIO _PINCTRLIOC(5)
/* Access macros ************************************************************/
/****************************************************************************
* Name: PINCTRL_SETFUNCTION
*
* Description:
* Set the mux function of the pinctrl pin.
*
* Input Parameters:
* dev - Device-specific state data.
* pin - the pinctrl controller number.
* function - the pinctrl pin function number.
*
* Returned Value:
* 0 on success, else a negative error code
*
****************************************************************************/
#define PINCTRL_SETFUNCTION(dev, pin, function) ((dev)->ops->set_function(dev, pin, function))
/****************************************************************************
* Name: PINCTRL_SETSTRENGTH
*
* Description:
* Set the driver strength of the pinctrl pin
*
* Input Parameters:
* dev - Device-specific state data.
* pin - the pinctrl controller number.
* strength - the pinctrl pin driver strength number.
*
* Returned Value:
* 0 on success, else a negative error code
*
****************************************************************************/
#define PINCTRL_SETSTRENGTH(dev, pin, strength) ((dev)->ops->set_strength(dev, pin, strength))
/****************************************************************************
* Name: PINCTRL_SETDRIVER
*
* Description:
* Set the driver type of the pinctrl pin
*
* Input Parameters:
* dev - Device-specific state data.
* pin - the pinctrl controller number.
* driver - the pinctrl_drivertype_e type.
*
* Returned Value:
* 0 on success, else a negative error code
*
****************************************************************************/
#define PINCTRL_SETDRIVER(dev, pin, driver) ((dev)->ops->set_driver(dev, pin, driver))
/****************************************************************************
* Name: PINCTRL_SETSLEWRATE
*
* Description:
* Set the slewrate of the pinctrl pin
*
* Input Parameters:
* dev - Device-specific state data.
* pin - the pinctrl controller number.
* slewrate - the slewsrate state.
*
* Returned Value:
* 0 on success, else a negative error code
*
****************************************************************************/
#define PINCTRL_SETSLEWRATE(dev, pin, slewrate) ((dev)->ops->set_slewrate(dev, pin, slewrate))
/****************************************************************************
* Name: PINCTRL_SELECTGPIO
*
* Description:
* Select gpio function the pinctrl pin
*
* Input Parameters:
* dev - Device-specific state data.
* pin - the pinctrl controller number.
*
* Returned Value:
* 0 on success, else a negative error code
*
****************************************************************************/
#define PINCTRL_SELECTGPIO(dev, pin) ((dev)->ops->select_gpio(dev, pin))
/****************************************************************************
* Public Types
****************************************************************************/
/* Identifies the type of the pinctrl driver type */
enum pinctrl_drivertype_e
{
BIAS_DISABLE = 0,
BIAS_PULLUP,
BIAS_PULLDOWN,
BIAS_STRONG_PULLDOWN,
BIAS_NDRIVERTYPES
};
/****************************************************************************
* This describes pinctrl ioctl structure in pinctrl command operation.
* the follow command use this structure:
* PINCTRLC_SETFUNCTION, PINCTRLC_SETSTRENGTH,
* PINCTRLC_SETDRIVER, PINCTRLC_SETSLEWRATE.
****************************************************************************/
struct pinctrl_param_s
{
uint32_t pin;
union
{
uint32_t function;
uint32_t strength;
enum pinctrl_drivertype_e type;
uint32_t slewrate;
} para;
};
/* pinctrl interface methods */
struct pinctrl_dev_s;
struct pinctrl_ops_s
{
int (*set_function)(FAR struct pinctrl_dev_s *dev, uint32_t pin,
uint32_t function);
int (*set_strength)(FAR struct pinctrl_dev_s *dev, uint32_t pin,
uint32_t strength);
int (*set_driver)(FAR struct pinctrl_dev_s *dev, uint32_t pin,
enum pinctrl_drivertype_e type);
int (*set_slewrate)(FAR struct pinctrl_dev_s *dev, uint32_t pin,
uint32_t slewrate);
int (*select_gpio)(FAR struct pinctrl_dev_s *dev, uint32_t pin);
};
struct pinctrl_dev_s
{
/* "Lower half" operations provided by the pinctrl lower half */
FAR const struct pinctrl_ops_s *ops;
/* Internal storage used by the pinctrl may (internal to the pinctrl
* implementation).
*/
};
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
#ifdef __cplusplus
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/****************************************************************************
* Name: pinctrl_register
*
* Description:
* Register PINCTRL device driver.
*
****************************************************************************/
int pinctrl_register(FAR struct pinctrl_dev_s *dev, int minor);
/****************************************************************************
* Name: pinctrl_unregister
*
* Description:
* Unregister PINCTRL device driver.
*
****************************************************************************/
void pinctrl_unregister(FAR struct pinctrl_dev_s *dev, int minor);
#ifdef __cplusplus
}
#endif
#endif /* __INCLUDE_NUTTX_PINCTRL_PINCTRL_H */