linux/drivers/pinctrl/pinctrl-lantiq.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 *  linux/drivers/pinctrl/pinctrl-lantiq.c
   4 *  based on linux/drivers/pinctrl/pinctrl-pxa3xx.c
   5 *
   6 *  Copyright (C) 2012 John Crispin <john@phrozen.org>
   7 */
   8
   9#include <linux/module.h>
  10#include <linux/device.h>
  11#include <linux/io.h>
  12#include <linux/platform_device.h>
  13#include <linux/slab.h>
  14#include <linux/of.h>
  15
  16#include "pinctrl-lantiq.h"
  17
  18static int ltq_get_group_count(struct pinctrl_dev *pctrldev)
  19{
  20        struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
  21        return info->num_grps;
  22}
  23
  24static const char *ltq_get_group_name(struct pinctrl_dev *pctrldev,
  25                                         unsigned selector)
  26{
  27        struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
  28        if (selector >= info->num_grps)
  29                return NULL;
  30        return info->grps[selector].name;
  31}
  32
  33static int ltq_get_group_pins(struct pinctrl_dev *pctrldev,
  34                                 unsigned selector,
  35                                 const unsigned **pins,
  36                                 unsigned *num_pins)
  37{
  38        struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
  39        if (selector >= info->num_grps)
  40                return -EINVAL;
  41        *pins = info->grps[selector].pins;
  42        *num_pins = info->grps[selector].npins;
  43        return 0;
  44}
  45
  46static void ltq_pinctrl_dt_free_map(struct pinctrl_dev *pctldev,
  47                                    struct pinctrl_map *map, unsigned num_maps)
  48{
  49        int i;
  50
  51        for (i = 0; i < num_maps; i++)
  52                if (map[i].type == PIN_MAP_TYPE_CONFIGS_PIN ||
  53                    map[i].type == PIN_MAP_TYPE_CONFIGS_GROUP)
  54                        kfree(map[i].data.configs.configs);
  55        kfree(map);
  56}
  57
  58static void ltq_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev,
  59                                        struct seq_file *s,
  60                                        unsigned offset)
  61{
  62        seq_printf(s, " %s", dev_name(pctldev->dev));
  63}
  64
  65static void ltq_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
  66                                struct device_node *np,
  67                                struct pinctrl_map **map)
  68{
  69        struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctldev);
  70        struct property *pins = of_find_property(np, "lantiq,pins", NULL);
  71        struct property *groups = of_find_property(np, "lantiq,groups", NULL);
  72        unsigned long configs[3];
  73        unsigned num_configs = 0;
  74        struct property *prop;
  75        const char *group, *pin;
  76        const char *function;
  77        int ret, i;
  78
  79        if (!pins && !groups) {
  80                dev_err(pctldev->dev, "%pOFn defines neither pins nor groups\n",
  81                        np);
  82                return;
  83        }
  84
  85        if (pins && groups) {
  86                dev_err(pctldev->dev, "%pOFn defines both pins and groups\n",
  87                        np);
  88                return;
  89        }
  90
  91        ret = of_property_read_string(np, "lantiq,function", &function);
  92        if (groups && !ret) {
  93                of_property_for_each_string(np, "lantiq,groups", prop, group) {
  94                        (*map)->type = PIN_MAP_TYPE_MUX_GROUP;
  95                        (*map)->name = function;
  96                        (*map)->data.mux.group = group;
  97                        (*map)->data.mux.function = function;
  98                        (*map)++;
  99                }
 100        }
 101
 102        for (i = 0; i < info->num_params; i++) {
 103                u32 val;
 104                int ret = of_property_read_u32(np,
 105                                info->params[i].property, &val);
 106                if (!ret)
 107                        configs[num_configs++] =
 108                                LTQ_PINCONF_PACK(info->params[i].param,
 109                                val);
 110        }
 111
 112        if (!num_configs)
 113                return;
 114
 115        of_property_for_each_string(np, "lantiq,pins", prop, pin) {
 116                (*map)->data.configs.configs = kmemdup(configs,
 117                                        num_configs * sizeof(unsigned long),
 118                                        GFP_KERNEL);
 119                (*map)->type = PIN_MAP_TYPE_CONFIGS_PIN;
 120                (*map)->name = pin;
 121                (*map)->data.configs.group_or_pin = pin;
 122                (*map)->data.configs.num_configs = num_configs;
 123                (*map)++;
 124        }
 125        of_property_for_each_string(np, "lantiq,groups", prop, group) {
 126                (*map)->data.configs.configs = kmemdup(configs,
 127                                        num_configs * sizeof(unsigned long),
 128                                        GFP_KERNEL);
 129                (*map)->type = PIN_MAP_TYPE_CONFIGS_GROUP;
 130                (*map)->name = group;
 131                (*map)->data.configs.group_or_pin = group;
 132                (*map)->data.configs.num_configs = num_configs;
 133                (*map)++;
 134        }
 135}
 136
 137static int ltq_pinctrl_dt_subnode_size(struct device_node *np)
 138{
 139        int ret;
 140
 141        ret = of_property_count_strings(np, "lantiq,groups");
 142        if (ret < 0)
 143                ret = of_property_count_strings(np, "lantiq,pins");
 144        return ret;
 145}
 146
 147static int ltq_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
 148                                      struct device_node *np_config,
 149                                      struct pinctrl_map **map,
 150                                      unsigned *num_maps)
 151{
 152        struct pinctrl_map *tmp;
 153        struct device_node *np;
 154        int max_maps = 0;
 155
 156        for_each_child_of_node(np_config, np)
 157                max_maps += ltq_pinctrl_dt_subnode_size(np);
 158        *map = kzalloc(array3_size(max_maps, sizeof(struct pinctrl_map), 2),
 159                       GFP_KERNEL);
 160        if (!*map)
 161                return -ENOMEM;
 162        tmp = *map;
 163
 164        for_each_child_of_node(np_config, np)
 165                ltq_pinctrl_dt_subnode_to_map(pctldev, np, &tmp);
 166        *num_maps = ((int)(tmp - *map));
 167
 168        return 0;
 169}
 170
 171static const struct pinctrl_ops ltq_pctrl_ops = {
 172        .get_groups_count       = ltq_get_group_count,
 173        .get_group_name         = ltq_get_group_name,
 174        .get_group_pins         = ltq_get_group_pins,
 175        .pin_dbg_show           = ltq_pinctrl_pin_dbg_show,
 176        .dt_node_to_map         = ltq_pinctrl_dt_node_to_map,
 177        .dt_free_map            = ltq_pinctrl_dt_free_map,
 178};
 179
 180static int ltq_pmx_func_count(struct pinctrl_dev *pctrldev)
 181{
 182        struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
 183
 184        return info->num_funcs;
 185}
 186
 187static const char *ltq_pmx_func_name(struct pinctrl_dev *pctrldev,
 188                                         unsigned selector)
 189{
 190        struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
 191
 192        if (selector >= info->num_funcs)
 193                return NULL;
 194
 195        return info->funcs[selector].name;
 196}
 197
 198static int ltq_pmx_get_groups(struct pinctrl_dev *pctrldev,
 199                                unsigned func,
 200                                const char * const **groups,
 201                                unsigned * const num_groups)
 202{
 203        struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
 204
 205        *groups = info->funcs[func].groups;
 206        *num_groups = info->funcs[func].num_groups;
 207
 208        return 0;
 209}
 210
 211/* Return function number. If failure, return negative value. */
 212static int match_mux(const struct ltq_mfp_pin *mfp, unsigned mux)
 213{
 214        int i;
 215        for (i = 0; i < LTQ_MAX_MUX; i++) {
 216                if (mfp->func[i] == mux)
 217                        break;
 218        }
 219        if (i >= LTQ_MAX_MUX)
 220                return -EINVAL;
 221        return i;
 222}
 223
 224/* don't assume .mfp is linearly mapped. find the mfp with the correct .pin */
 225static int match_mfp(const struct ltq_pinmux_info *info, int pin)
 226{
 227        int i;
 228        for (i = 0; i < info->num_mfp; i++) {
 229                if (info->mfp[i].pin == pin)
 230                        return i;
 231        }
 232        return -1;
 233}
 234
 235/* check whether current pin configuration is valid. Negative for failure */
 236static int match_group_mux(const struct ltq_pin_group *grp,
 237                           const struct ltq_pinmux_info *info,
 238                           unsigned mux)
 239{
 240        int i, pin, ret = 0;
 241        for (i = 0; i < grp->npins; i++) {
 242                pin = match_mfp(info, grp->pins[i]);
 243                if (pin < 0) {
 244                        dev_err(info->dev, "could not find mfp for pin %d\n",
 245                                grp->pins[i]);
 246                        return -EINVAL;
 247                }
 248                ret = match_mux(&info->mfp[pin], mux);
 249                if (ret < 0) {
 250                        dev_err(info->dev, "Can't find mux %d on pin%d\n",
 251                                mux, pin);
 252                        break;
 253                }
 254        }
 255        return ret;
 256}
 257
 258static int ltq_pmx_set(struct pinctrl_dev *pctrldev,
 259                       unsigned func,
 260                       unsigned group)
 261{
 262        struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
 263        const struct ltq_pin_group *pin_grp = &info->grps[group];
 264        int i, pin, pin_func, ret;
 265
 266        if (!pin_grp->npins ||
 267                (match_group_mux(pin_grp, info, pin_grp->mux) < 0)) {
 268                dev_err(info->dev, "Failed to set the pin group: %s\n",
 269                        info->grps[group].name);
 270                return -EINVAL;
 271        }
 272        for (i = 0; i < pin_grp->npins; i++) {
 273                pin = match_mfp(info, pin_grp->pins[i]);
 274                if (pin < 0) {
 275                        dev_err(info->dev, "could not find mfp for pin %d\n",
 276                                pin_grp->pins[i]);
 277                        return -EINVAL;
 278                }
 279                pin_func = match_mux(&info->mfp[pin], pin_grp->mux);
 280                ret = info->apply_mux(pctrldev, pin, pin_func);
 281                if (ret) {
 282                        dev_err(info->dev,
 283                                "failed to apply mux %d for pin %d\n",
 284                                pin_func, pin);
 285                        return ret;
 286                }
 287        }
 288        return 0;
 289}
 290
 291static int ltq_pmx_gpio_request_enable(struct pinctrl_dev *pctrldev,
 292                                struct pinctrl_gpio_range *range,
 293                                unsigned pin)
 294{
 295        struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
 296        int mfp = match_mfp(info, pin);
 297        int pin_func;
 298
 299        if (mfp < 0) {
 300                dev_err(info->dev, "could not find mfp for pin %d\n", pin);
 301                return -EINVAL;
 302        }
 303
 304        pin_func = match_mux(&info->mfp[mfp], 0);
 305        if (pin_func < 0) {
 306                dev_err(info->dev, "No GPIO function on pin%d\n", mfp);
 307                return -EINVAL;
 308        }
 309
 310        return info->apply_mux(pctrldev, mfp, pin_func);
 311}
 312
 313static const struct pinmux_ops ltq_pmx_ops = {
 314        .get_functions_count    = ltq_pmx_func_count,
 315        .get_function_name      = ltq_pmx_func_name,
 316        .get_function_groups    = ltq_pmx_get_groups,
 317        .set_mux                = ltq_pmx_set,
 318        .gpio_request_enable    = ltq_pmx_gpio_request_enable,
 319};
 320
 321/*
 322 * allow different socs to register with the generic part of the lanti
 323 * pinctrl code
 324 */
 325int ltq_pinctrl_register(struct platform_device *pdev,
 326                                struct ltq_pinmux_info *info)
 327{
 328        struct pinctrl_desc *desc;
 329
 330        if (!info)
 331                return -EINVAL;
 332        desc = info->desc;
 333        desc->pctlops = &ltq_pctrl_ops;
 334        desc->pmxops = &ltq_pmx_ops;
 335        info->dev = &pdev->dev;
 336
 337        info->pctrl = devm_pinctrl_register(&pdev->dev, desc, info);
 338        if (IS_ERR(info->pctrl)) {
 339                dev_err(&pdev->dev, "failed to register LTQ pinmux driver\n");
 340                return PTR_ERR(info->pctrl);
 341        }
 342        platform_set_drvdata(pdev, info);
 343        return 0;
 344}
 345