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