root/drivers/pinctrl/pinconf.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. pinconf_check_ops
  2. pinconf_validate_map
  3. pin_config_get_for_pin
  4. pin_config_group_get
  5. pinconf_map_to_setting
  6. pinconf_free_setting
  7. pinconf_apply_setting
  8. pinconf_set_config
  9. pinconf_show_config
  10. pinconf_show_map
  11. pinconf_show_setting
  12. pinconf_dump_pin
  13. pinconf_pins_show
  14. pinconf_dump_group
  15. pinconf_groups_show
  16. pinconf_init_device_debugfs

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Core driver for the pin config portions of the pin control subsystem
   4  *
   5  * Copyright (C) 2011 ST-Ericsson SA
   6  * Written on behalf of Linaro for ST-Ericsson
   7  *
   8  * Author: Linus Walleij <linus.walleij@linaro.org>
   9  */
  10 #define pr_fmt(fmt) "pinconfig core: " fmt
  11 
  12 #include <linux/kernel.h>
  13 #include <linux/module.h>
  14 #include <linux/init.h>
  15 #include <linux/device.h>
  16 #include <linux/slab.h>
  17 #include <linux/debugfs.h>
  18 #include <linux/seq_file.h>
  19 #include <linux/pinctrl/machine.h>
  20 #include <linux/pinctrl/pinctrl.h>
  21 #include <linux/pinctrl/pinconf.h>
  22 #include "core.h"
  23 #include "pinconf.h"
  24 
  25 int pinconf_check_ops(struct pinctrl_dev *pctldev)
  26 {
  27         const struct pinconf_ops *ops = pctldev->desc->confops;
  28 
  29         /* We have to be able to config the pins in SOME way */
  30         if (!ops->pin_config_set && !ops->pin_config_group_set) {
  31                 dev_err(pctldev->dev,
  32                         "pinconf has to be able to set a pins config\n");
  33                 return -EINVAL;
  34         }
  35         return 0;
  36 }
  37 
  38 int pinconf_validate_map(const struct pinctrl_map *map, int i)
  39 {
  40         if (!map->data.configs.group_or_pin) {
  41                 pr_err("failed to register map %s (%d): no group/pin given\n",
  42                        map->name, i);
  43                 return -EINVAL;
  44         }
  45 
  46         if (!map->data.configs.num_configs ||
  47                         !map->data.configs.configs) {
  48                 pr_err("failed to register map %s (%d): no configs given\n",
  49                        map->name, i);
  50                 return -EINVAL;
  51         }
  52 
  53         return 0;
  54 }
  55 
  56 int pin_config_get_for_pin(struct pinctrl_dev *pctldev, unsigned pin,
  57                            unsigned long *config)
  58 {
  59         const struct pinconf_ops *ops = pctldev->desc->confops;
  60 
  61         if (!ops || !ops->pin_config_get) {
  62                 dev_dbg(pctldev->dev,
  63                         "cannot get pin configuration, .pin_config_get missing in driver\n");
  64                 return -ENOTSUPP;
  65         }
  66 
  67         return ops->pin_config_get(pctldev, pin, config);
  68 }
  69 
  70 int pin_config_group_get(const char *dev_name, const char *pin_group,
  71                          unsigned long *config)
  72 {
  73         struct pinctrl_dev *pctldev;
  74         const struct pinconf_ops *ops;
  75         int selector, ret;
  76 
  77         pctldev = get_pinctrl_dev_from_devname(dev_name);
  78         if (!pctldev) {
  79                 ret = -EINVAL;
  80                 return ret;
  81         }
  82 
  83         mutex_lock(&pctldev->mutex);
  84 
  85         ops = pctldev->desc->confops;
  86 
  87         if (!ops || !ops->pin_config_group_get) {
  88                 dev_dbg(pctldev->dev,
  89                         "cannot get configuration for pin group, missing group config get function in driver\n");
  90                 ret = -ENOTSUPP;
  91                 goto unlock;
  92         }
  93 
  94         selector = pinctrl_get_group_selector(pctldev, pin_group);
  95         if (selector < 0) {
  96                 ret = selector;
  97                 goto unlock;
  98         }
  99 
 100         ret = ops->pin_config_group_get(pctldev, selector, config);
 101 
 102 unlock:
 103         mutex_unlock(&pctldev->mutex);
 104         return ret;
 105 }
 106 
 107 int pinconf_map_to_setting(const struct pinctrl_map *map,
 108                           struct pinctrl_setting *setting)
 109 {
 110         struct pinctrl_dev *pctldev = setting->pctldev;
 111         int pin;
 112 
 113         switch (setting->type) {
 114         case PIN_MAP_TYPE_CONFIGS_PIN:
 115                 pin = pin_get_from_name(pctldev,
 116                                         map->data.configs.group_or_pin);
 117                 if (pin < 0) {
 118                         dev_err(pctldev->dev, "could not map pin config for \"%s\"",
 119                                 map->data.configs.group_or_pin);
 120                         return pin;
 121                 }
 122                 setting->data.configs.group_or_pin = pin;
 123                 break;
 124         case PIN_MAP_TYPE_CONFIGS_GROUP:
 125                 pin = pinctrl_get_group_selector(pctldev,
 126                                          map->data.configs.group_or_pin);
 127                 if (pin < 0) {
 128                         dev_err(pctldev->dev, "could not map group config for \"%s\"",
 129                                 map->data.configs.group_or_pin);
 130                         return pin;
 131                 }
 132                 setting->data.configs.group_or_pin = pin;
 133                 break;
 134         default:
 135                 return -EINVAL;
 136         }
 137 
 138         setting->data.configs.num_configs = map->data.configs.num_configs;
 139         setting->data.configs.configs = map->data.configs.configs;
 140 
 141         return 0;
 142 }
 143 
 144 void pinconf_free_setting(const struct pinctrl_setting *setting)
 145 {
 146 }
 147 
 148 int pinconf_apply_setting(const struct pinctrl_setting *setting)
 149 {
 150         struct pinctrl_dev *pctldev = setting->pctldev;
 151         const struct pinconf_ops *ops = pctldev->desc->confops;
 152         int ret;
 153 
 154         if (!ops) {
 155                 dev_err(pctldev->dev, "missing confops\n");
 156                 return -EINVAL;
 157         }
 158 
 159         switch (setting->type) {
 160         case PIN_MAP_TYPE_CONFIGS_PIN:
 161                 if (!ops->pin_config_set) {
 162                         dev_err(pctldev->dev, "missing pin_config_set op\n");
 163                         return -EINVAL;
 164                 }
 165                 ret = ops->pin_config_set(pctldev,
 166                                 setting->data.configs.group_or_pin,
 167                                 setting->data.configs.configs,
 168                                 setting->data.configs.num_configs);
 169                 if (ret < 0) {
 170                         dev_err(pctldev->dev,
 171                                 "pin_config_set op failed for pin %d\n",
 172                                 setting->data.configs.group_or_pin);
 173                         return ret;
 174                 }
 175                 break;
 176         case PIN_MAP_TYPE_CONFIGS_GROUP:
 177                 if (!ops->pin_config_group_set) {
 178                         dev_err(pctldev->dev,
 179                                 "missing pin_config_group_set op\n");
 180                         return -EINVAL;
 181                 }
 182                 ret = ops->pin_config_group_set(pctldev,
 183                                 setting->data.configs.group_or_pin,
 184                                 setting->data.configs.configs,
 185                                 setting->data.configs.num_configs);
 186                 if (ret < 0) {
 187                         dev_err(pctldev->dev,
 188                                 "pin_config_group_set op failed for group %d\n",
 189                                 setting->data.configs.group_or_pin);
 190                         return ret;
 191                 }
 192                 break;
 193         default:
 194                 return -EINVAL;
 195         }
 196 
 197         return 0;
 198 }
 199 
 200 int pinconf_set_config(struct pinctrl_dev *pctldev, unsigned pin,
 201                        unsigned long *configs, size_t nconfigs)
 202 {
 203         const struct pinconf_ops *ops;
 204 
 205         ops = pctldev->desc->confops;
 206         if (!ops || !ops->pin_config_set)
 207                 return -ENOTSUPP;
 208 
 209         return ops->pin_config_set(pctldev, pin, configs, nconfigs);
 210 }
 211 
 212 #ifdef CONFIG_DEBUG_FS
 213 
 214 static void pinconf_show_config(struct seq_file *s, struct pinctrl_dev *pctldev,
 215                       unsigned long *configs, unsigned num_configs)
 216 {
 217         const struct pinconf_ops *confops;
 218         int i;
 219 
 220         if (pctldev)
 221                 confops = pctldev->desc->confops;
 222         else
 223                 confops = NULL;
 224 
 225         for (i = 0; i < num_configs; i++) {
 226                 seq_puts(s, "config ");
 227                 if (confops && confops->pin_config_config_dbg_show)
 228                         confops->pin_config_config_dbg_show(pctldev, s,
 229                                                             configs[i]);
 230                 else
 231                         seq_printf(s, "%08lx", configs[i]);
 232                 seq_putc(s, '\n');
 233         }
 234 }
 235 
 236 void pinconf_show_map(struct seq_file *s, const struct pinctrl_map *map)
 237 {
 238         struct pinctrl_dev *pctldev;
 239 
 240         pctldev = get_pinctrl_dev_from_devname(map->ctrl_dev_name);
 241 
 242         switch (map->type) {
 243         case PIN_MAP_TYPE_CONFIGS_PIN:
 244                 seq_puts(s, "pin ");
 245                 break;
 246         case PIN_MAP_TYPE_CONFIGS_GROUP:
 247                 seq_puts(s, "group ");
 248                 break;
 249         default:
 250                 break;
 251         }
 252 
 253         seq_printf(s, "%s\n", map->data.configs.group_or_pin);
 254 
 255         pinconf_show_config(s, pctldev, map->data.configs.configs,
 256                             map->data.configs.num_configs);
 257 }
 258 
 259 void pinconf_show_setting(struct seq_file *s,
 260                           const struct pinctrl_setting *setting)
 261 {
 262         struct pinctrl_dev *pctldev = setting->pctldev;
 263         const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
 264         struct pin_desc *desc;
 265 
 266         switch (setting->type) {
 267         case PIN_MAP_TYPE_CONFIGS_PIN:
 268                 desc = pin_desc_get(setting->pctldev,
 269                                     setting->data.configs.group_or_pin);
 270                 seq_printf(s, "pin %s (%d)", desc->name,
 271                            setting->data.configs.group_or_pin);
 272                 break;
 273         case PIN_MAP_TYPE_CONFIGS_GROUP:
 274                 seq_printf(s, "group %s (%d)",
 275                            pctlops->get_group_name(pctldev,
 276                                         setting->data.configs.group_or_pin),
 277                            setting->data.configs.group_or_pin);
 278                 break;
 279         default:
 280                 break;
 281         }
 282 
 283         /*
 284          * FIXME: We should really get the pin controller to dump the config
 285          * values, so they can be decoded to something meaningful.
 286          */
 287         pinconf_show_config(s, pctldev, setting->data.configs.configs,
 288                             setting->data.configs.num_configs);
 289 }
 290 
 291 static void pinconf_dump_pin(struct pinctrl_dev *pctldev,
 292                              struct seq_file *s, int pin)
 293 {
 294         const struct pinconf_ops *ops = pctldev->desc->confops;
 295 
 296         /* no-op when not using generic pin config */
 297         pinconf_generic_dump_pins(pctldev, s, NULL, pin);
 298         if (ops && ops->pin_config_dbg_show)
 299                 ops->pin_config_dbg_show(pctldev, s, pin);
 300 }
 301 
 302 static int pinconf_pins_show(struct seq_file *s, void *what)
 303 {
 304         struct pinctrl_dev *pctldev = s->private;
 305         unsigned i, pin;
 306 
 307         seq_puts(s, "Pin config settings per pin\n");
 308         seq_puts(s, "Format: pin (name): configs\n");
 309 
 310         mutex_lock(&pctldev->mutex);
 311 
 312         /* The pin number can be retrived from the pin controller descriptor */
 313         for (i = 0; i < pctldev->desc->npins; i++) {
 314                 struct pin_desc *desc;
 315 
 316                 pin = pctldev->desc->pins[i].number;
 317                 desc = pin_desc_get(pctldev, pin);
 318                 /* Skip if we cannot search the pin */
 319                 if (!desc)
 320                         continue;
 321 
 322                 seq_printf(s, "pin %d (%s): ", pin, desc->name);
 323 
 324                 pinconf_dump_pin(pctldev, s, pin);
 325                 seq_putc(s, '\n');
 326         }
 327 
 328         mutex_unlock(&pctldev->mutex);
 329 
 330         return 0;
 331 }
 332 
 333 static void pinconf_dump_group(struct pinctrl_dev *pctldev,
 334                                struct seq_file *s, unsigned selector,
 335                                const char *gname)
 336 {
 337         const struct pinconf_ops *ops = pctldev->desc->confops;
 338 
 339         /* no-op when not using generic pin config */
 340         pinconf_generic_dump_pins(pctldev, s, gname, 0);
 341         if (ops && ops->pin_config_group_dbg_show)
 342                 ops->pin_config_group_dbg_show(pctldev, s, selector);
 343 }
 344 
 345 static int pinconf_groups_show(struct seq_file *s, void *what)
 346 {
 347         struct pinctrl_dev *pctldev = s->private;
 348         const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
 349         unsigned ngroups = pctlops->get_groups_count(pctldev);
 350         unsigned selector = 0;
 351 
 352         seq_puts(s, "Pin config settings per pin group\n");
 353         seq_puts(s, "Format: group (name): configs\n");
 354 
 355         while (selector < ngroups) {
 356                 const char *gname = pctlops->get_group_name(pctldev, selector);
 357 
 358                 seq_printf(s, "%u (%s): ", selector, gname);
 359                 pinconf_dump_group(pctldev, s, selector, gname);
 360                 seq_putc(s, '\n');
 361                 selector++;
 362         }
 363 
 364         return 0;
 365 }
 366 
 367 DEFINE_SHOW_ATTRIBUTE(pinconf_pins);
 368 DEFINE_SHOW_ATTRIBUTE(pinconf_groups);
 369 
 370 void pinconf_init_device_debugfs(struct dentry *devroot,
 371                          struct pinctrl_dev *pctldev)
 372 {
 373         debugfs_create_file("pinconf-pins", S_IFREG | S_IRUGO,
 374                             devroot, pctldev, &pinconf_pins_fops);
 375         debugfs_create_file("pinconf-groups", S_IFREG | S_IRUGO,
 376                             devroot, pctldev, &pinconf_groups_fops);
 377 }
 378 
 379 #endif

/* [<][>][^][v][top][bottom][index][help] */