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