添加rtthread相关代码
This commit is contained in:
		
							
								
								
									
										227
									
								
								riscv/rtthread/components/drivers/pinctrl/pinctrl.c
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										227
									
								
								riscv/rtthread/components/drivers/pinctrl/pinctrl.c
									
									
									
									
									
										Executable 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