From 0479631370ff053041f85c8e384da4538bbc5c1f Mon Sep 17 00:00:00 2001 From: kettenis Date: Sat, 6 Aug 2016 17:12:34 +0000 Subject: [PATCH] Add a generic pinctrl "framework". ok patrick@ --- sys/dev/ofw/ofw_pinctrl.c | 123 ++++++++++++++++++++++++++++++++++++++ sys/dev/ofw/ofw_pinctrl.h | 27 +++++++++ 2 files changed, 150 insertions(+) create mode 100644 sys/dev/ofw/ofw_pinctrl.c create mode 100644 sys/dev/ofw/ofw_pinctrl.h diff --git a/sys/dev/ofw/ofw_pinctrl.c b/sys/dev/ofw/ofw_pinctrl.c new file mode 100644 index 00000000000..bee5454e194 --- /dev/null +++ b/sys/dev/ofw/ofw_pinctrl.c @@ -0,0 +1,123 @@ +/* $OpenBSD: ofw_pinctrl.c,v 1.1 2016/08/06 17:12:34 kettenis Exp $ */ +/* + * Copyright (c) 2016 Mark Kettenis + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include + +#include +#include + +struct pinctrl { + int pc_phandle; + int (*pc_pinctrl)(uint32_t, void *); + void *pc_cookie; + + LIST_ENTRY(pinctrl) pc_list; +}; + +void pinctrl_register_child(int, int (*)(uint32_t, void *), void *); + +LIST_HEAD(, pinctrl) pinctrls = LIST_HEAD_INITIALIZER(pinctrl); + +void +pinctrl_register(int node, int (*pinctrl)(uint32_t, void *), void *cookie) +{ + for (node = OF_child(node); node; node = OF_peer(node)) + pinctrl_register_child(node, pinctrl, cookie); +} + +void +pinctrl_register_child(int node, int (*pinctrl)(uint32_t, void *), void *cookie) +{ + struct pinctrl *pc; + uint32_t phandle; + + phandle = OF_getpropint(node, "phandle", 0); + if (phandle) { + pc = malloc(sizeof(struct pinctrl), M_DEVBUF, M_WAITOK); + pc->pc_phandle = phandle; + pc->pc_pinctrl = pinctrl; + pc->pc_cookie = cookie; + LIST_INSERT_HEAD(&pinctrls, pc, pc_list); + } + + for (node = OF_child(node); node; node = OF_peer(node)) + pinctrl_register_child(node, pinctrl, cookie); +} + +int +pinctrl_byphandle(uint32_t phandle) +{ + struct pinctrl *pc; + + LIST_FOREACH(pc, &pinctrls, pc_list) { + if (pc->pc_phandle == phandle) + return pc->pc_pinctrl(pc->pc_phandle, pc->pc_cookie); + } + + return -1; +} + +int +pinctrl_byid(int node, int id) +{ + char pinctrl[32]; + uint32_t *phandles; + int len, i; + + snprintf(pinctrl, sizeof(pinctrl), "pinctrl-%d", id); + len = OF_getproplen(node, pinctrl); + if (len <= 0) + return -1; + + phandles = malloc(len, M_TEMP, M_WAITOK); + OF_getpropintarray(node, pinctrl, phandles, len); + for (i = 0; i < len / sizeof(uint32_t); i++) + pinctrl_byphandle(phandles[i]); + free(phandles, M_TEMP, len); + return 0; +} + +int +pinctrl_byname(int node, const char *config) +{ + char *names; + char *name; + char *end; + int id = 0; + int len; + + len = OF_getproplen(node, "pinctrl-names"); + if (len <= 0) + return -1; + + names = malloc(len, M_TEMP, M_WAITOK); + OF_getprop(node, "pinctrl-names", names, len); + end = names + len; + name = names; + while (name < end) { + if (strcmp(name, config) == 0) { + free(names, M_TEMP, len); + return pinctrl_byid(node, id); + } + name += strlen(name) + 1; + id++; + } + free(names, M_TEMP, len); + return -1; +} diff --git a/sys/dev/ofw/ofw_pinctrl.h b/sys/dev/ofw/ofw_pinctrl.h new file mode 100644 index 00000000000..503beef0c22 --- /dev/null +++ b/sys/dev/ofw/ofw_pinctrl.h @@ -0,0 +1,27 @@ +/* $OpenBSD: ofw_pinctrl.h,v 1.1 2016/08/06 17:12:34 kettenis Exp $ */ +/* + * Copyright (c) 2016 Mark Kettenis + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _DEV_OFW_PINCTRL_H_ +#define _DEV_OFW_PINCTRL_H_ + +void pinctrl_register(int, int (*)(uint32_t, void *), void *); + +int pinctrl_byphandle(uint32_t); +int pinctrl_byid(int, int); +int pinctrl_byname(int, const char *); + +#endif /* _DEV_OFW_GPIO_H_ */ -- 2.20.1