1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Generic Pin Control Driver for Board-Level Mux Chips 4 * Copyright 2026 NXP 5 */ 6 7 #include <linux/cleanup.h> 8 #include <linux/module.h> 9 #include <linux/of.h> 10 #include <linux/mutex.h> 11 #include <linux/mux/consumer.h> 12 #include <linux/platform_device.h> 13 #include <linux/pinctrl/pinconf-generic.h> 14 #include <linux/pinctrl/pinctrl.h> 15 #include <linux/pinctrl/pinmux.h> 16 #include <linux/slab.h> 17 18 #include "core.h" 19 #include "pinconf.h" 20 #include "pinmux.h" 21 #include "pinctrl-utils.h" 22 23 struct mux_pin_function { 24 struct mux_state *mux_state; 25 }; 26 27 struct mux_pinctrl { 28 struct device *dev; 29 struct pinctrl_dev *pctl; 30 31 /* mutex protect [pinctrl|pinmux]_generic functions */ 32 struct mutex lock; 33 }; 34 35 static int 36 mux_pinmux_dt_node_to_map(struct pinctrl_dev *pctldev, 37 struct device_node *np_config, 38 struct pinctrl_map **maps, unsigned int *num_maps) 39 { 40 unsigned int num_reserved_maps = 0; 41 struct mux_pin_function *function; 42 const char **group_names; 43 int ret; 44 45 function = devm_kzalloc(pctldev->dev, sizeof(*function), GFP_KERNEL); 46 if (!function) 47 return -ENOMEM; 48 49 group_names = devm_kcalloc(pctldev->dev, 1, sizeof(*group_names), GFP_KERNEL); 50 if (!group_names) 51 return -ENOMEM; 52 53 function->mux_state = devm_mux_state_get_from_np(pctldev->dev, NULL, np_config); 54 if (IS_ERR(function->mux_state)) 55 return PTR_ERR(function->mux_state); 56 57 ret = pinctrl_generic_to_map(pctldev, np_config, np_config, maps, 58 num_maps, &num_reserved_maps, group_names, 59 0, &np_config->name, NULL, 0); 60 61 if (ret) 62 return ret; 63 64 ret = pinmux_generic_add_function(pctldev, np_config->name, group_names, 65 1, function); 66 if (ret < 0) { 67 pinctrl_utils_free_map(pctldev, *maps, *num_maps); 68 return ret; 69 } 70 71 return 0; 72 } 73 74 static const struct pinctrl_ops mux_pinctrl_ops = { 75 .get_groups_count = pinctrl_generic_get_group_count, 76 .get_group_name = pinctrl_generic_get_group_name, 77 .get_group_pins = pinctrl_generic_get_group_pins, 78 .dt_node_to_map = mux_pinmux_dt_node_to_map, 79 .dt_free_map = pinctrl_utils_free_map, 80 }; 81 82 static int mux_pinmux_set_mux(struct pinctrl_dev *pctldev, 83 unsigned int func_selector, 84 unsigned int group_selector) 85 { 86 struct mux_pinctrl *mpctl = pinctrl_dev_get_drvdata(pctldev); 87 const struct function_desc *function; 88 struct mux_pin_function *func; 89 int ret; 90 91 guard(mutex)(&mpctl->lock); 92 93 function = pinmux_generic_get_function(pctldev, func_selector); 94 func = function->data; 95 96 ret = mux_state_select(func->mux_state); 97 if (ret) 98 return ret; 99 100 return 0; 101 } 102 103 static void mux_pinmux_release_mux(struct pinctrl_dev *pctldev, 104 unsigned int func_selector, 105 unsigned int group_selector) 106 { 107 struct mux_pinctrl *mpctl = pinctrl_dev_get_drvdata(pctldev); 108 const struct function_desc *function; 109 struct mux_pin_function *func; 110 111 guard(mutex)(&mpctl->lock); 112 113 function = pinmux_generic_get_function(pctldev, func_selector); 114 func = function->data; 115 116 mux_state_deselect(func->mux_state); 117 } 118 119 static const struct pinmux_ops mux_pinmux_ops = { 120 .get_functions_count = pinmux_generic_get_function_count, 121 .get_function_name = pinmux_generic_get_function_name, 122 .get_function_groups = pinmux_generic_get_function_groups, 123 .set_mux = mux_pinmux_set_mux, 124 .release_mux = mux_pinmux_release_mux, 125 }; 126 127 static int mux_pinctrl_probe(struct platform_device *pdev) 128 { 129 struct device *dev = &pdev->dev; 130 struct mux_pinctrl *mpctl; 131 struct pinctrl_desc *pctl_desc; 132 int ret; 133 134 mpctl = devm_kzalloc(dev, sizeof(*mpctl), GFP_KERNEL); 135 if (!mpctl) 136 return -ENOMEM; 137 138 mpctl->dev = dev; 139 140 platform_set_drvdata(pdev, mpctl); 141 142 pctl_desc = devm_kzalloc(dev, sizeof(*pctl_desc), GFP_KERNEL); 143 if (!pctl_desc) 144 return -ENOMEM; 145 146 ret = devm_mutex_init(dev, &mpctl->lock); 147 if (ret) 148 return ret; 149 150 pctl_desc->name = dev_name(dev); 151 pctl_desc->owner = THIS_MODULE; 152 pctl_desc->pctlops = &mux_pinctrl_ops; 153 pctl_desc->pmxops = &mux_pinmux_ops; 154 155 ret = devm_pinctrl_register_and_init(dev, pctl_desc, mpctl, 156 &mpctl->pctl); 157 if (ret) 158 return dev_err_probe(dev, ret, "Failed to register pinctrl.\n"); 159 160 ret = pinctrl_enable(mpctl->pctl); 161 if (ret) 162 return dev_err_probe(dev, ret, "Failed to enable pinctrl.\n"); 163 164 return 0; 165 } 166 167 static const struct of_device_id mux_pinctrl_of_match[] = { 168 { .compatible = "pinctrl-multiplexer" }, 169 { } 170 }; 171 MODULE_DEVICE_TABLE(of, mux_pinctrl_of_match); 172 173 static struct platform_driver mux_pinctrl_driver = { 174 .driver = { 175 .name = "generic-pinctrl-mux", 176 .of_match_table = mux_pinctrl_of_match, 177 }, 178 .probe = mux_pinctrl_probe, 179 }; 180 module_platform_driver(mux_pinctrl_driver); 181 182 MODULE_AUTHOR("Frank Li <Frank.Li@nxp.com>"); 183 MODULE_DESCRIPTION("Generic Pin Control Driver for Board-Level Mux Chips"); 184 MODULE_LICENSE("GPL"); 185