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