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