1 /* 2 * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com> 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <common.h> 8 #include <dm.h> 9 #include <linux/compat.h> 10 #include <dm/pinctrl.h> 11 12 /** 13 * pinctrl_pin_name_to_selector() - return the pin selector for a pin 14 * 15 * @dev: pin controller device 16 * @pin: the pin name to look up 17 * @return: pin selector, or negative error code on failure 18 */ 19 static int pinctrl_pin_name_to_selector(struct udevice *dev, const char *pin) 20 { 21 const struct pinctrl_ops *ops = pinctrl_get_ops(dev); 22 unsigned npins, selector; 23 24 if (!ops->get_pins_count || !ops->get_pin_name) { 25 dev_dbg(dev, "get_pins_count or get_pin_name missing\n"); 26 return -ENOSYS; 27 } 28 29 npins = ops->get_pins_count(dev); 30 31 /* See if this pctldev has this pin */ 32 for (selector = 0; selector < npins; selector++) { 33 const char *pname = ops->get_pin_name(dev, selector); 34 35 if (!strcmp(pin, pname)) 36 return selector; 37 } 38 39 return -ENOSYS; 40 } 41 42 /** 43 * pinctrl_group_name_to_selector() - return the group selector for a group 44 * 45 * @dev: pin controller device 46 * @group: the pin group name to look up 47 * @return: pin group selector, or negative error code on failure 48 */ 49 static int pinctrl_group_name_to_selector(struct udevice *dev, 50 const char *group) 51 { 52 const struct pinctrl_ops *ops = pinctrl_get_ops(dev); 53 unsigned ngroups, selector; 54 55 if (!ops->get_groups_count || !ops->get_group_name) { 56 dev_dbg(dev, "get_groups_count or get_group_name missing\n"); 57 return -ENOSYS; 58 } 59 60 ngroups = ops->get_groups_count(dev); 61 62 /* See if this pctldev has this group */ 63 for (selector = 0; selector < ngroups; selector++) { 64 const char *gname = ops->get_group_name(dev, selector); 65 66 if (!strcmp(group, gname)) 67 return selector; 68 } 69 70 return -ENOSYS; 71 } 72 73 #if CONFIG_IS_ENABLED(PINMUX) 74 /** 75 * pinmux_func_name_to_selector() - return the function selector for a function 76 * 77 * @dev: pin controller device 78 * @function: the function name to look up 79 * @return: function selector, or negative error code on failure 80 */ 81 static int pinmux_func_name_to_selector(struct udevice *dev, 82 const char *function) 83 { 84 const struct pinctrl_ops *ops = pinctrl_get_ops(dev); 85 unsigned nfuncs, selector = 0; 86 87 if (!ops->get_functions_count || !ops->get_function_name) { 88 dev_dbg(dev, 89 "get_functions_count or get_function_name missing\n"); 90 return -ENOSYS; 91 } 92 93 nfuncs = ops->get_functions_count(dev); 94 95 /* See if this pctldev has this function */ 96 for (selector = 0; selector < nfuncs; selector++) { 97 const char *fname = ops->get_function_name(dev, selector); 98 99 if (!strcmp(function, fname)) 100 return selector; 101 } 102 103 return -ENOSYS; 104 } 105 106 /** 107 * pinmux_enable_setting() - enable pin-mux setting for a certain pin/group 108 * 109 * @dev: pin controller device 110 * @is_group: target of operation (true: pin group, false: pin) 111 * @selector: pin selector or group selector, depending on @is_group 112 * @func_selector: function selector 113 * @return: 0 on success, or negative error code on failure 114 */ 115 static int pinmux_enable_setting(struct udevice *dev, bool is_group, 116 unsigned selector, unsigned func_selector) 117 { 118 const struct pinctrl_ops *ops = pinctrl_get_ops(dev); 119 120 if (is_group) { 121 if (!ops->pinmux_group_set) { 122 dev_dbg(dev, "pinmux_group_set op missing\n"); 123 return -ENOSYS; 124 } 125 126 return ops->pinmux_group_set(dev, selector, func_selector); 127 } else { 128 if (!ops->pinmux_set) { 129 dev_dbg(dev, "pinmux_set op missing\n"); 130 return -ENOSYS; 131 } 132 return ops->pinmux_set(dev, selector, func_selector); 133 } 134 } 135 #else 136 static int pinmux_func_name_to_selector(struct udevice *dev, 137 const char *function) 138 { 139 return 0; 140 } 141 142 static int pinmux_enable_setting(struct udevice *dev, bool is_group, 143 unsigned selector, unsigned func_selector) 144 { 145 return 0; 146 } 147 #endif 148 149 #if CONFIG_IS_ENABLED(PINCONF) 150 /** 151 * pinconf_prop_name_to_param() - return parameter ID for a property name 152 * 153 * @dev: pin controller device 154 * @property: property name in DTS, such as "bias-pull-up", "slew-rate", etc. 155 * @default_value: return default value in case no value is specified in DTS 156 * @return: return pamater ID, or negative error code on failure 157 */ 158 static int pinconf_prop_name_to_param(struct udevice *dev, 159 const char *property, u32 *default_value) 160 { 161 const struct pinctrl_ops *ops = pinctrl_get_ops(dev); 162 const struct pinconf_param *p, *end; 163 164 if (!ops->pinconf_num_params || !ops->pinconf_params) { 165 dev_dbg(dev, "pinconf_num_params or pinconf_params missing\n"); 166 return -ENOSYS; 167 } 168 169 p = ops->pinconf_params; 170 end = p + ops->pinconf_num_params; 171 172 /* See if this pctldev supports this parameter */ 173 for (; p < end; p++) { 174 if (!strcmp(property, p->property)) { 175 *default_value = p->default_value; 176 return p->param; 177 } 178 } 179 180 return -ENOSYS; 181 } 182 183 /** 184 * pinconf_enable_setting() - apply pin configuration for a certain pin/group 185 * 186 * @dev: pin controller device 187 * @is_group: target of operation (true: pin group, false: pin) 188 * @selector: pin selector or group selector, depending on @is_group 189 * @param: configuration paramter 190 * @argument: argument taken by some configuration parameters 191 * @return: 0 on success, or negative error code on failure 192 */ 193 static int pinconf_enable_setting(struct udevice *dev, bool is_group, 194 unsigned selector, unsigned param, 195 u32 argument) 196 { 197 const struct pinctrl_ops *ops = pinctrl_get_ops(dev); 198 199 if (is_group) { 200 if (!ops->pinconf_group_set) { 201 dev_dbg(dev, "pinconf_group_set op missing\n"); 202 return -ENOSYS; 203 } 204 205 return ops->pinconf_group_set(dev, selector, param, 206 argument); 207 } else { 208 if (!ops->pinconf_set) { 209 dev_dbg(dev, "pinconf_set op missing\n"); 210 return -ENOSYS; 211 } 212 return ops->pinconf_set(dev, selector, param, argument); 213 } 214 } 215 #else 216 static int pinconf_prop_name_to_param(struct udevice *dev, 217 const char *property, u32 *default_value) 218 { 219 return -ENOSYS; 220 } 221 222 static int pinconf_enable_setting(struct udevice *dev, bool is_group, 223 unsigned selector, unsigned param, 224 u32 argument) 225 { 226 return 0; 227 } 228 #endif 229 230 /** 231 * pinctrl_generic_set_state_one() - set state for a certain pin/group 232 * Apply all pin multiplexing and pin configurations specified by @config 233 * for a given pin or pin group. 234 * 235 * @dev: pin controller device 236 * @config: pseudo device pointing to config node 237 * @is_group: target of operation (true: pin group, false: pin) 238 * @selector: pin selector or group selector, depending on @is_group 239 * @return: 0 on success, or negative error code on failure 240 */ 241 static int pinctrl_generic_set_state_one(struct udevice *dev, 242 struct udevice *config, 243 bool is_group, unsigned selector) 244 { 245 const char *propname; 246 const void *value; 247 struct ofprop property; 248 int len, func_selector, param, ret; 249 u32 arg, default_val; 250 251 dev_for_each_property(property, config) { 252 value = dev_read_prop_by_prop(&property, &propname, &len); 253 if (!value) 254 return -EINVAL; 255 256 if (!strcmp(propname, "function")) { 257 func_selector = pinmux_func_name_to_selector(dev, 258 value); 259 if (func_selector < 0) 260 return func_selector; 261 ret = pinmux_enable_setting(dev, is_group, 262 selector, 263 func_selector); 264 } else { 265 param = pinconf_prop_name_to_param(dev, propname, 266 &default_val); 267 if (param < 0) 268 continue; /* just skip unknown properties */ 269 270 if (len >= sizeof(fdt32_t)) 271 arg = fdt32_to_cpu(*(fdt32_t *)value); 272 else 273 arg = default_val; 274 275 ret = pinconf_enable_setting(dev, is_group, 276 selector, param, arg); 277 } 278 279 if (ret) 280 return ret; 281 } 282 283 return 0; 284 } 285 286 /** 287 * pinctrl_generic_set_state_subnode() - apply all settings in config node 288 * 289 * @dev: pin controller device 290 * @config: pseudo device pointing to config node 291 * @return: 0 on success, or negative error code on failure 292 */ 293 static int pinctrl_generic_set_state_subnode(struct udevice *dev, 294 struct udevice *config) 295 { 296 const char *subnode_target_type = "pins"; 297 bool is_group = false; 298 const char *name; 299 int strings_count, selector, i, ret; 300 301 strings_count = dev_read_string_count(config, subnode_target_type); 302 if (strings_count < 0) { 303 subnode_target_type = "groups"; 304 is_group = true; 305 strings_count = dev_read_string_count(config, 306 subnode_target_type); 307 if (strings_count < 0) { 308 /* skip this node; may contain config child nodes */ 309 return 0; 310 } 311 } 312 313 for (i = 0; i < strings_count; i++) { 314 ret = dev_read_string_index(config, subnode_target_type, i, 315 &name); 316 if (ret) 317 return ret; 318 319 if (is_group) 320 selector = pinctrl_group_name_to_selector(dev, name); 321 else 322 selector = pinctrl_pin_name_to_selector(dev, name); 323 if (selector < 0) 324 return selector; 325 326 ret = pinctrl_generic_set_state_one(dev, config, 327 is_group, selector); 328 if (ret) 329 return ret; 330 } 331 332 return 0; 333 } 334 335 int pinctrl_generic_set_state(struct udevice *dev, struct udevice *config) 336 { 337 struct udevice *child; 338 int ret; 339 340 ret = pinctrl_generic_set_state_subnode(dev, config); 341 if (ret) 342 return ret; 343 344 for (device_find_first_child(config, &child); 345 child; 346 device_find_next_child(&child)) { 347 ret = pinctrl_generic_set_state_subnode(dev, child); 348 if (ret) 349 return ret; 350 } 351 352 return 0; 353 } 354