first
This commit is contained in:
6
rt-thread/components/drivers/pinctrl/Kconfig
Normal file
6
rt-thread/components/drivers/pinctrl/Kconfig
Normal file
@@ -0,0 +1,6 @@
|
||||
menuconfig RT_USING_PINCTRL
|
||||
bool "Using Pin controllers device drivers"
|
||||
depends on RT_USING_DM
|
||||
depends on RT_USING_PIN
|
||||
default n
|
||||
|
23
rt-thread/components/drivers/pinctrl/SConscript
Normal file
23
rt-thread/components/drivers/pinctrl/SConscript
Normal file
@@ -0,0 +1,23 @@
|
||||
from building import *
|
||||
|
||||
group = []
|
||||
objs = []
|
||||
|
||||
if not GetDepend(['RT_USING_PINCTRL']):
|
||||
Return('group')
|
||||
|
||||
cwd = GetCurrentDir()
|
||||
list = os.listdir(cwd)
|
||||
CPPPATH = [cwd + '/../include']
|
||||
|
||||
src = ['pinctrl.c']
|
||||
|
||||
group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
|
||||
|
||||
for d in list:
|
||||
path = os.path.join(cwd, d)
|
||||
if os.path.isfile(os.path.join(path, 'SConscript')):
|
||||
objs = objs + SConscript(os.path.join(d, 'SConscript'))
|
||||
objs = objs + group
|
||||
|
||||
Return('objs')
|
227
rt-thread/components/drivers/pinctrl/pinctrl.c
Normal file
227
rt-thread/components/drivers/pinctrl/pinctrl.c
Normal file
@@ -0,0 +1,227 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2022, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2022-11-26 GuEe-GUI first version
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
#include <rtservice.h>
|
||||
#include <rtdevice.h>
|
||||
|
||||
#define DBG_TAG "rtdm.pinctrl"
|
||||
#define DBG_LVL DBG_INFO
|
||||
#include <rtdbg.h>
|
||||
|
||||
#ifdef RT_USING_OFW
|
||||
static rt_err_t ofw_pin_ctrl_confs_apply(struct rt_ofw_node *np, int index)
|
||||
{
|
||||
rt_err_t err = -RT_EEMPTY;
|
||||
rt_phandle phandle;
|
||||
const fdt32_t *cell;
|
||||
struct rt_ofw_prop *prop;
|
||||
char pinctrl_n_name[sizeof("pinctrl-0")];
|
||||
|
||||
rt_sprintf(pinctrl_n_name, "pinctrl-%d", index);
|
||||
index = 0;
|
||||
|
||||
rt_ofw_foreach_prop_u32(np, pinctrl_n_name, prop, cell, phandle)
|
||||
{
|
||||
struct rt_device_pin *pinctrl = RT_NULL;
|
||||
struct rt_ofw_node *conf_np, *pinctrl_np;
|
||||
|
||||
conf_np = pinctrl_np = rt_ofw_find_node_by_phandle(phandle);
|
||||
|
||||
if (!conf_np)
|
||||
{
|
||||
err = -RT_EIO;
|
||||
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* We always assume the phandle in pinctrl-N is the pinctrl-device
|
||||
* node's child node. If not, we need a better way to find it:
|
||||
*
|
||||
* / {
|
||||
* serial@4600 {
|
||||
* device_type = "serial";
|
||||
* reg = <0x4600 0x100>;
|
||||
* clock-frequency = <0>;
|
||||
* pinctrl-names = "default";
|
||||
* pinctrl-0 = <&uart_pin>;
|
||||
* };
|
||||
*
|
||||
* i2c@4700 {
|
||||
* reg = <0x4700 0x100>;
|
||||
* pinctrl-names = "default";
|
||||
* pinctrl-0 = <&i2c_pin_scl, &i2c_pin_sda>;
|
||||
* };
|
||||
*
|
||||
* pinctrl: pinctrl {
|
||||
*
|
||||
* uart_pin {
|
||||
* multi,pins =
|
||||
* <0 PD0 1 &uart_rx_pull_up>,
|
||||
* <0 PD1 1 &uart_tx_pull_up>;
|
||||
* };
|
||||
*
|
||||
* i2c_pin_scl {
|
||||
* single,pins = <0 PB1>;
|
||||
* pull = <&i2c_pull_none_smt>;
|
||||
* function = <1>;
|
||||
* };
|
||||
*
|
||||
* i2c_pin_sda {
|
||||
* single,pins = <0 PB2>;
|
||||
* pull = <&i2c_pull_none_smt>;
|
||||
* function = <1>;
|
||||
* };
|
||||
* };
|
||||
* }
|
||||
*/
|
||||
rt_ofw_foreach_parent_node(pinctrl_np)
|
||||
{
|
||||
if (rt_ofw_prop_read_bool(pinctrl_np, "compatible"))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (pinctrl_np)
|
||||
{
|
||||
pinctrl = rt_ofw_data(pinctrl_np);
|
||||
|
||||
rt_ofw_node_put(pinctrl_np);
|
||||
}
|
||||
|
||||
if (!pinctrl || !pinctrl->ops || !pinctrl->ops->pin_ctrl_confs_apply)
|
||||
{
|
||||
if (index)
|
||||
{
|
||||
err = -RT_EEMPTY;
|
||||
}
|
||||
else
|
||||
{
|
||||
err = -RT_ERROR;
|
||||
}
|
||||
|
||||
rt_ofw_node_put(conf_np);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
err = pinctrl->ops->pin_ctrl_confs_apply(&pinctrl->parent, conf_np);
|
||||
rt_ofw_node_put(conf_np);
|
||||
|
||||
if (err)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
++index;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int ofw_pin_ctrl_confs_lookup(struct rt_ofw_node *np, const char *name)
|
||||
{
|
||||
return rt_ofw_prop_index_of_string(np, "pinctrl-names", name);
|
||||
}
|
||||
|
||||
static rt_err_t ofw_pin_ctrl_confs_apply_by_name(struct rt_ofw_node *np, const char *name)
|
||||
{
|
||||
int index;
|
||||
rt_err_t err;
|
||||
|
||||
index = ofw_pin_ctrl_confs_lookup(np, name);
|
||||
|
||||
if (index >= 0)
|
||||
{
|
||||
err = ofw_pin_ctrl_confs_apply(np, index);
|
||||
}
|
||||
else
|
||||
{
|
||||
err = -RT_EEMPTY;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
#endif /* RT_USING_OFW */
|
||||
|
||||
rt_ssize_t rt_pin_ctrl_confs_lookup(struct rt_device *device, const char *name)
|
||||
{
|
||||
rt_ssize_t res;
|
||||
|
||||
if (device && name)
|
||||
{
|
||||
res = -RT_ENOSYS;
|
||||
|
||||
#ifdef RT_USING_OFW
|
||||
if (device->ofw_node)
|
||||
{
|
||||
res = ofw_pin_ctrl_confs_lookup(device->ofw_node, name);
|
||||
}
|
||||
#endif /* RT_USING_OFW */
|
||||
}
|
||||
else
|
||||
{
|
||||
res = -RT_EINVAL;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
rt_err_t rt_pin_ctrl_confs_apply(struct rt_device *device, int index)
|
||||
{
|
||||
rt_err_t err;
|
||||
|
||||
if (device && index >= 0)
|
||||
{
|
||||
err = -RT_ENOSYS;
|
||||
|
||||
#ifdef RT_USING_OFW
|
||||
if (device->ofw_node)
|
||||
{
|
||||
err = ofw_pin_ctrl_confs_apply(device->ofw_node, index);
|
||||
}
|
||||
#endif /* RT_USING_OFW */
|
||||
}
|
||||
else
|
||||
{
|
||||
err = -RT_EINVAL;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
rt_err_t rt_pin_ctrl_confs_apply_by_name(struct rt_device *device, const char *name)
|
||||
{
|
||||
rt_err_t err;
|
||||
|
||||
if (device)
|
||||
{
|
||||
if (!name)
|
||||
{
|
||||
name = "default";
|
||||
}
|
||||
|
||||
err = -RT_ENOSYS;
|
||||
|
||||
#ifdef RT_USING_OFW
|
||||
if (device->ofw_node)
|
||||
{
|
||||
err = ofw_pin_ctrl_confs_apply_by_name(device->ofw_node, name);
|
||||
}
|
||||
#endif /* RT_USING_OFW */
|
||||
}
|
||||
else
|
||||
{
|
||||
err = -RT_EINVAL;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
Reference in New Issue
Block a user