^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Marvell Berlin SoC pinctrl core driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2014 Marvell Technology Group Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Antoine Ténart <antoine.tenart@free-electrons.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/mfd/syscon.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/of_address.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/pinctrl/pinctrl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/pinctrl/pinmux.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "../core.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include "../pinctrl-utils.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include "berlin.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) struct berlin_pinctrl {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) const struct berlin_pinctrl_desc *desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) struct berlin_pinctrl_function *functions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) unsigned nfunctions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) struct pinctrl_dev *pctrl_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) static int berlin_pinctrl_get_group_count(struct pinctrl_dev *pctrl_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) struct berlin_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) return pctrl->desc->ngroups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) static const char *berlin_pinctrl_get_group_name(struct pinctrl_dev *pctrl_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) unsigned group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) struct berlin_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) return pctrl->desc->groups[group].name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) static int berlin_pinctrl_dt_node_to_map(struct pinctrl_dev *pctrl_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) struct device_node *node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) struct pinctrl_map **map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) unsigned *num_maps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) struct berlin_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) struct property *prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) const char *function_name, *group_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) unsigned reserved_maps = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) int ret, ngroups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) *map = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) *num_maps = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) ret = of_property_read_string(node, "function", &function_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) dev_err(pctrl->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) "missing function property in node %pOFn\n", node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) ngroups = of_property_count_strings(node, "groups");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) if (ngroups < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) dev_err(pctrl->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) "missing groups property in node %pOFn\n", node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) ret = pinctrl_utils_reserve_map(pctrl_dev, map, &reserved_maps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) num_maps, ngroups);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) dev_err(pctrl->dev, "can't reserve map: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) of_property_for_each_string(node, "groups", prop, group_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) ret = pinctrl_utils_add_map_mux(pctrl_dev, map, &reserved_maps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) num_maps, group_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) function_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) dev_err(pctrl->dev, "can't add map: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) static const struct pinctrl_ops berlin_pinctrl_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) .get_groups_count = &berlin_pinctrl_get_group_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) .get_group_name = &berlin_pinctrl_get_group_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) .dt_node_to_map = &berlin_pinctrl_dt_node_to_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) .dt_free_map = &pinctrl_utils_free_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) static int berlin_pinmux_get_functions_count(struct pinctrl_dev *pctrl_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) struct berlin_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) return pctrl->nfunctions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) static const char *berlin_pinmux_get_function_name(struct pinctrl_dev *pctrl_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) unsigned function)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) struct berlin_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) return pctrl->functions[function].name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) static int berlin_pinmux_get_function_groups(struct pinctrl_dev *pctrl_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) unsigned function,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) const char * const **groups,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) unsigned * const num_groups)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) struct berlin_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) *groups = pctrl->functions[function].groups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) *num_groups = pctrl->functions[function].ngroups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) static struct berlin_desc_function *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) berlin_pinctrl_find_function_by_name(struct berlin_pinctrl *pctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) const struct berlin_desc_group *group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) const char *fname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) struct berlin_desc_function *function = group->functions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) while (function->name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) if (!strcmp(function->name, fname))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) return function;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) function++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) static int berlin_pinmux_set(struct pinctrl_dev *pctrl_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) unsigned function,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) unsigned group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) struct berlin_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) const struct berlin_desc_group *group_desc = pctrl->desc->groups + group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) struct berlin_pinctrl_function *func = pctrl->functions + function;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) struct berlin_desc_function *function_desc =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) berlin_pinctrl_find_function_by_name(pctrl, group_desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) func->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) u32 mask, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) if (!function_desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) mask = GENMASK(group_desc->lsb + group_desc->bit_width - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) group_desc->lsb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) val = function_desc->muxval << group_desc->lsb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) regmap_update_bits(pctrl->regmap, group_desc->offset, mask, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) static const struct pinmux_ops berlin_pinmux_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) .get_functions_count = &berlin_pinmux_get_functions_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) .get_function_name = &berlin_pinmux_get_function_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) .get_function_groups = &berlin_pinmux_get_function_groups,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) .set_mux = &berlin_pinmux_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) static int berlin_pinctrl_add_function(struct berlin_pinctrl *pctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) struct berlin_pinctrl_function *function = pctrl->functions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) while (function->name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) if (!strcmp(function->name, name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) function->ngroups++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) return -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) function++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) function->name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) function->ngroups = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) pctrl->nfunctions++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) static int berlin_pinctrl_build_state(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) struct berlin_pinctrl *pctrl = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) const struct berlin_desc_group *desc_group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) const struct berlin_desc_function *desc_function;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) int i, max_functions = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) pctrl->nfunctions = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) for (i = 0; i < pctrl->desc->ngroups; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) desc_group = pctrl->desc->groups + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) /* compute the maxiumum number of functions a group can have */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) max_functions += 1 << (desc_group->bit_width + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) /* we will reallocate later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) pctrl->functions = kcalloc(max_functions,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) sizeof(*pctrl->functions), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) if (!pctrl->functions)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) /* register all functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) for (i = 0; i < pctrl->desc->ngroups; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) desc_group = pctrl->desc->groups + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) desc_function = desc_group->functions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) while (desc_function->name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) berlin_pinctrl_add_function(pctrl, desc_function->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) desc_function++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) pctrl->functions = krealloc(pctrl->functions,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) pctrl->nfunctions * sizeof(*pctrl->functions),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) /* map functions to theirs groups */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) for (i = 0; i < pctrl->desc->ngroups; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) desc_group = pctrl->desc->groups + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) desc_function = desc_group->functions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) while (desc_function->name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) struct berlin_pinctrl_function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) *function = pctrl->functions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) const char **groups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) bool found = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) while (function->name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) if (!strcmp(desc_function->name, function->name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) found = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) function++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) if (!found) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) kfree(pctrl->functions);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) if (!function->groups) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) function->groups =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) devm_kcalloc(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) function->ngroups,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) sizeof(char *),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) if (!function->groups) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) kfree(pctrl->functions);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) groups = function->groups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) while (*groups)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) groups++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) *groups = desc_group->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) desc_function++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) static struct pinctrl_desc berlin_pctrl_desc = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) .name = "berlin-pinctrl",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) .pctlops = &berlin_pinctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) .pmxops = &berlin_pinmux_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) int berlin_pinctrl_probe_regmap(struct platform_device *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) const struct berlin_pinctrl_desc *desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) struct regmap *regmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) struct berlin_pinctrl *pctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) pctrl = devm_kzalloc(dev, sizeof(*pctrl), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) if (!pctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) platform_set_drvdata(pdev, pctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) pctrl->regmap = regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) pctrl->dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) pctrl->desc = desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) ret = berlin_pinctrl_build_state(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) dev_err(dev, "cannot build driver state: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) pctrl->pctrl_dev = devm_pinctrl_register(dev, &berlin_pctrl_desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) pctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) if (IS_ERR(pctrl->pctrl_dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) dev_err(dev, "failed to register pinctrl driver\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) return PTR_ERR(pctrl->pctrl_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) int berlin_pinctrl_probe(struct platform_device *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) const struct berlin_pinctrl_desc *desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) struct device_node *parent_np = of_get_parent(dev->of_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) struct regmap *regmap = syscon_node_to_regmap(parent_np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) of_node_put(parent_np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) if (IS_ERR(regmap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) return PTR_ERR(regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) return berlin_pinctrl_probe_regmap(pdev, desc, regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) }