Skip to content

Commit

Permalink
driver/pinctl: add pinctrl framework
Browse files Browse the repository at this point in the history
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
  • Loading branch information
Donny9 authored and xiaoxiang781216 committed Sep 16, 2024
1 parent f6d378e commit 1d5f436
Show file tree
Hide file tree
Showing 11 changed files with 622 additions and 0 deletions.
4 changes: 4 additions & 0 deletions Documentation/components/drivers/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,10 @@ Subdirectories of ``nuttx/drivers``

Note Driver Support.

* ``pinctrl/`` :doc:`special/pinctrl`

Configure and manage pin.

* ``pipes/`` :doc:`special/pipes`

FIFO and named pipe drivers.
Expand Down
1 change: 1 addition & 0 deletions Documentation/components/drivers/special/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ following section.
usrsock.rst
mmcsd.rst
net/index.rst
pinctrl.rst
pipes.rst
power/index.rst
virtio.rst
Expand Down
38 changes: 38 additions & 0 deletions Documentation/components/drivers/special/pinctrl.rst
Original file line number Diff line number Diff line change
@@ -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.

1 change: 1 addition & 0 deletions drivers/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ source "drivers/eeprom/Kconfig"
source "drivers/efuse/Kconfig"
source "drivers/net/Kconfig"
source "drivers/note/Kconfig"
source "drivers/pinctrl/Kconfig"
source "drivers/pipes/Kconfig"
source "drivers/power/Kconfig"
source "drivers/regmap/Kconfig"
Expand Down
1 change: 1 addition & 0 deletions drivers/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ include eeprom/Make.defs
include efuse/Make.defs
include net/Make.defs
include note/Make.defs
include pinctrl/Make.defs
include pipes/Make.defs
include power/Make.defs
include regmap/Make.defs
Expand Down
27 changes: 27 additions & 0 deletions drivers/pinctrl/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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 changes: 15 additions & 0 deletions drivers/pinctrl/Kconfig
Original file line number Diff line number Diff line change
@@ -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 changes: 29 additions & 0 deletions drivers/pinctrl/Make.defs
Original file line number Diff line number Diff line change
@@ -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 changes: 245 additions & 0 deletions drivers/pinctrl/pinctrl.c
Original file line number Diff line number Diff line change
@@ -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);
}
Loading

0 comments on commit 1d5f436

Please sign in to comment.