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 <libfdt.h> 9 #include <linux/err.h> 10 #include <linux/list.h> 11 #include <dm/device.h> 12 #include <dm/lists.h> 13 #include <dm/pinctrl.h> 14 #include <dm/uclass.h> 15 #include <dm/util.h> 16 17 DECLARE_GLOBAL_DATA_PTR; 18 19 int pinctrl_decode_pin_config(const void *blob, int node) 20 { 21 int flags = 0; 22 23 if (fdtdec_get_bool(blob, node, "bias-pull-up")) 24 flags |= 1 << PIN_CONFIG_BIAS_PULL_UP; 25 else if (fdtdec_get_bool(blob, node, "bias-pull-down")) 26 flags |= 1 << PIN_CONFIG_BIAS_PULL_DOWN; 27 28 return flags; 29 } 30 31 #if CONFIG_IS_ENABLED(PINCTRL_FULL) 32 /** 33 * pinctrl_config_one() - apply pinctrl settings for a single node 34 * 35 * @config: pin configuration node 36 * @return: 0 on success, or negative error code on failure 37 */ 38 static int pinctrl_config_one(struct udevice *config) 39 { 40 struct udevice *pctldev; 41 const struct pinctrl_ops *ops; 42 43 pctldev = config; 44 for (;;) { 45 pctldev = dev_get_parent(pctldev); 46 if (!pctldev) { 47 dev_err(config, "could not find pctldev\n"); 48 return -EINVAL; 49 } 50 if (pctldev->uclass->uc_drv->id == UCLASS_PINCTRL) 51 break; 52 } 53 54 ops = pinctrl_get_ops(pctldev); 55 return ops->set_state(pctldev, config); 56 } 57 58 /** 59 * pinctrl_select_state_full() - full implementation of pinctrl_select_state 60 * 61 * @dev: peripheral device 62 * @statename: state name, like "default" 63 * @return: 0 on success, or negative error code on failure 64 */ 65 static int pinctrl_select_state_full(struct udevice *dev, const char *statename) 66 { 67 const void *fdt = gd->fdt_blob; 68 int node = dev_of_offset(dev); 69 char propname[32]; /* long enough */ 70 const fdt32_t *list; 71 uint32_t phandle; 72 int config_node; 73 struct udevice *config; 74 int state, size, i, ret; 75 76 state = fdt_stringlist_search(fdt, node, "pinctrl-names", statename); 77 if (state < 0) { 78 char *end; 79 /* 80 * If statename is not found in "pinctrl-names", 81 * assume statename is just the integer state ID. 82 */ 83 state = simple_strtoul(statename, &end, 10); 84 if (*end) 85 return -EINVAL; 86 } 87 88 snprintf(propname, sizeof(propname), "pinctrl-%d", state); 89 list = fdt_getprop(fdt, node, propname, &size); 90 if (!list) 91 return -EINVAL; 92 93 size /= sizeof(*list); 94 for (i = 0; i < size; i++) { 95 phandle = fdt32_to_cpu(*list++); 96 97 config_node = fdt_node_offset_by_phandle(fdt, phandle); 98 if (config_node < 0) { 99 dev_err(dev, "prop %s index %d invalid phandle\n", 100 propname, i); 101 return -EINVAL; 102 } 103 ret = uclass_get_device_by_of_offset(UCLASS_PINCONFIG, 104 config_node, &config); 105 if (ret) 106 return ret; 107 108 ret = pinctrl_config_one(config); 109 if (ret) 110 return ret; 111 } 112 113 return 0; 114 } 115 116 /** 117 * pinconfig_post_bind() - post binding for PINCONFIG uclass 118 * Recursively bind its children as pinconfig devices. 119 * 120 * @dev: pinconfig device 121 * @return: 0 on success, or negative error code on failure 122 */ 123 static int pinconfig_post_bind(struct udevice *dev) 124 { 125 const void *fdt = gd->fdt_blob; 126 int offset = dev_of_offset(dev); 127 bool pre_reloc_only = !(gd->flags & GD_FLG_RELOC); 128 const char *name; 129 int ret; 130 131 for (offset = fdt_first_subnode(fdt, offset); 132 offset > 0; 133 offset = fdt_next_subnode(fdt, offset)) { 134 if (pre_reloc_only && 135 !dm_fdt_pre_reloc(fdt, offset)) 136 continue; 137 /* 138 * If this node has "compatible" property, this is not 139 * a pin configuration node, but a normal device. skip. 140 */ 141 fdt_get_property(fdt, offset, "compatible", &ret); 142 if (ret >= 0) 143 continue; 144 145 if (ret != -FDT_ERR_NOTFOUND) 146 return ret; 147 148 name = fdt_get_name(fdt, offset, NULL); 149 if (!name) 150 return -EINVAL; 151 ret = device_bind_driver_to_node(dev, "pinconfig", name, 152 offset, NULL); 153 if (ret) 154 return ret; 155 } 156 157 return 0; 158 } 159 160 UCLASS_DRIVER(pinconfig) = { 161 .id = UCLASS_PINCONFIG, 162 .post_bind = pinconfig_post_bind, 163 .name = "pinconfig", 164 }; 165 166 U_BOOT_DRIVER(pinconfig_generic) = { 167 .name = "pinconfig", 168 .id = UCLASS_PINCONFIG, 169 }; 170 171 #else 172 static int pinctrl_select_state_full(struct udevice *dev, const char *statename) 173 { 174 return -ENODEV; 175 } 176 177 static int pinconfig_post_bind(struct udevice *dev) 178 { 179 return 0; 180 } 181 #endif 182 183 /** 184 * pinctrl_select_state_simple() - simple implementation of pinctrl_select_state 185 * 186 * @dev: peripheral device 187 * @return: 0 on success, or negative error code on failure 188 */ 189 static int pinctrl_select_state_simple(struct udevice *dev) 190 { 191 struct udevice *pctldev; 192 struct pinctrl_ops *ops; 193 int ret; 194 195 /* 196 * For simplicity, assume the first device of PINCTRL uclass 197 * is the correct one. This is most likely OK as there is 198 * usually only one pinctrl device on the system. 199 */ 200 ret = uclass_get_device(UCLASS_PINCTRL, 0, &pctldev); 201 if (ret) 202 return ret; 203 204 ops = pinctrl_get_ops(pctldev); 205 if (!ops->set_state_simple) { 206 dev_dbg(dev, "set_state_simple op missing\n"); 207 return -ENOSYS; 208 } 209 210 return ops->set_state_simple(pctldev, dev); 211 } 212 213 int pinctrl_select_state(struct udevice *dev, const char *statename) 214 { 215 /* 216 * Try full-implemented pinctrl first. 217 * If it fails or is not implemented, try simple one. 218 */ 219 if (pinctrl_select_state_full(dev, statename)) 220 return pinctrl_select_state_simple(dev); 221 222 return 0; 223 } 224 225 int pinctrl_request(struct udevice *dev, int func, int flags) 226 { 227 struct pinctrl_ops *ops = pinctrl_get_ops(dev); 228 229 if (!ops->request) 230 return -ENOSYS; 231 232 return ops->request(dev, func, flags); 233 } 234 235 int pinctrl_request_noflags(struct udevice *dev, int func) 236 { 237 return pinctrl_request(dev, func, 0); 238 } 239 240 int pinctrl_get_periph_id(struct udevice *dev, struct udevice *periph) 241 { 242 struct pinctrl_ops *ops = pinctrl_get_ops(dev); 243 244 if (!ops->get_periph_id) 245 return -ENOSYS; 246 247 return ops->get_periph_id(dev, periph); 248 } 249 250 int pinctrl_get_gpio_mux(struct udevice *dev, int banknum, int index) 251 { 252 struct pinctrl_ops *ops = pinctrl_get_ops(dev); 253 254 if (!ops->get_gpio_mux) 255 return -ENOSYS; 256 257 return ops->get_gpio_mux(dev, banknum, index); 258 } 259 260 /** 261 * pinconfig_post_bind() - post binding for PINCTRL uclass 262 * Recursively bind child nodes as pinconfig devices in case of full pinctrl. 263 * 264 * @dev: pinctrl device 265 * @return: 0 on success, or negative error code on failure 266 */ 267 static int pinctrl_post_bind(struct udevice *dev) 268 { 269 const struct pinctrl_ops *ops = pinctrl_get_ops(dev); 270 271 if (!ops) { 272 dev_dbg(dev, "ops is not set. Do not bind.\n"); 273 return -EINVAL; 274 } 275 276 /* 277 * If set_state callback is set, we assume this pinctrl driver is the 278 * full implementation. In this case, its child nodes should be bound 279 * so that peripheral devices can easily search in parent devices 280 * during later DT-parsing. 281 */ 282 if (ops->set_state) 283 return pinconfig_post_bind(dev); 284 285 return 0; 286 } 287 288 UCLASS_DRIVER(pinctrl) = { 289 .id = UCLASS_PINCTRL, 290 .post_bind = pinctrl_post_bind, 291 .flags = DM_UC_FLAG_SEQ_ALIAS, 292 .name = "pinctrl", 293 }; 294