1 /* 2 * Core driver for the pin config portions of the pin control subsystem 3 * 4 * Copyright (C) 2011 ST-Ericsson SA 5 * Written on behalf of Linaro for ST-Ericsson 6 * 7 * Author: Linus Walleij <linus.walleij@linaro.org> 8 * 9 * License terms: GNU General Public License (GPL) version 2 10 */ 11 #define pr_fmt(fmt) "pinconfig core: " fmt 12 13 #include <linux/kernel.h> 14 #include <linux/module.h> 15 #include <linux/init.h> 16 #include <linux/device.h> 17 #include <linux/slab.h> 18 #include <linux/debugfs.h> 19 #include <linux/seq_file.h> 20 #include <linux/uaccess.h> 21 #include <linux/pinctrl/machine.h> 22 #include <linux/pinctrl/pinctrl.h> 23 #include <linux/pinctrl/pinconf.h> 24 #include "core.h" 25 #include "pinconf.h" 26 27 int pinconf_check_ops(struct pinctrl_dev *pctldev) 28 { 29 const struct pinconf_ops *ops = pctldev->desc->confops; 30 31 /* We have to be able to config the pins in SOME way */ 32 if (!ops->pin_config_set && !ops->pin_config_group_set) { 33 dev_err(pctldev->dev, 34 "pinconf has to be able to set a pins config\n"); 35 return -EINVAL; 36 } 37 return 0; 38 } 39 40 int pinconf_validate_map(struct pinctrl_map const *map, int i) 41 { 42 if (!map->data.configs.group_or_pin) { 43 pr_err("failed to register map %s (%d): no group/pin given\n", 44 map->name, i); 45 return -EINVAL; 46 } 47 48 if (!map->data.configs.num_configs || 49 !map->data.configs.configs) { 50 pr_err("failed to register map %s (%d): no configs given\n", 51 map->name, i); 52 return -EINVAL; 53 } 54 55 return 0; 56 } 57 58 int pin_config_get_for_pin(struct pinctrl_dev *pctldev, unsigned pin, 59 unsigned long *config) 60 { 61 const struct pinconf_ops *ops = pctldev->desc->confops; 62 63 if (!ops || !ops->pin_config_get) { 64 dev_dbg(pctldev->dev, "cannot get pin configuration, missing " 65 "pin_config_get() function in driver\n"); 66 return -ENOTSUPP; 67 } 68 69 return ops->pin_config_get(pctldev, pin, config); 70 } 71 72 int pin_config_group_get(const char *dev_name, const char *pin_group, 73 unsigned long *config) 74 { 75 struct pinctrl_dev *pctldev; 76 const struct pinconf_ops *ops; 77 int selector, ret; 78 79 pctldev = get_pinctrl_dev_from_devname(dev_name); 80 if (!pctldev) { 81 ret = -EINVAL; 82 return ret; 83 } 84 85 mutex_lock(&pctldev->mutex); 86 87 ops = pctldev->desc->confops; 88 89 if (!ops || !ops->pin_config_group_get) { 90 dev_dbg(pctldev->dev, "cannot get configuration for pin " 91 "group, missing group config get function in " 92 "driver\n"); 93 ret = -ENOTSUPP; 94 goto unlock; 95 } 96 97 selector = pinctrl_get_group_selector(pctldev, pin_group); 98 if (selector < 0) { 99 ret = selector; 100 goto unlock; 101 } 102 103 ret = ops->pin_config_group_get(pctldev, selector, config); 104 105 unlock: 106 mutex_unlock(&pctldev->mutex); 107 return ret; 108 } 109 110 int pinconf_map_to_setting(struct pinctrl_map const *map, 111 struct pinctrl_setting *setting) 112 { 113 struct pinctrl_dev *pctldev = setting->pctldev; 114 int pin; 115 116 switch (setting->type) { 117 case PIN_MAP_TYPE_CONFIGS_PIN: 118 pin = pin_get_from_name(pctldev, 119 map->data.configs.group_or_pin); 120 if (pin < 0) { 121 dev_err(pctldev->dev, "could not map pin config for \"%s\"", 122 map->data.configs.group_or_pin); 123 return pin; 124 } 125 setting->data.configs.group_or_pin = pin; 126 break; 127 case PIN_MAP_TYPE_CONFIGS_GROUP: 128 pin = pinctrl_get_group_selector(pctldev, 129 map->data.configs.group_or_pin); 130 if (pin < 0) { 131 dev_err(pctldev->dev, "could not map group config for \"%s\"", 132 map->data.configs.group_or_pin); 133 return pin; 134 } 135 setting->data.configs.group_or_pin = pin; 136 break; 137 default: 138 return -EINVAL; 139 } 140 141 setting->data.configs.num_configs = map->data.configs.num_configs; 142 setting->data.configs.configs = map->data.configs.configs; 143 144 return 0; 145 } 146 147 void pinconf_free_setting(struct pinctrl_setting const *setting) 148 { 149 } 150 151 int pinconf_apply_setting(struct pinctrl_setting const *setting) 152 { 153 struct pinctrl_dev *pctldev = setting->pctldev; 154 const struct pinconf_ops *ops = pctldev->desc->confops; 155 int ret; 156 157 if (!ops) { 158 dev_err(pctldev->dev, "missing confops\n"); 159 return -EINVAL; 160 } 161 162 switch (setting->type) { 163 case PIN_MAP_TYPE_CONFIGS_PIN: 164 if (!ops->pin_config_set) { 165 dev_err(pctldev->dev, "missing pin_config_set op\n"); 166 return -EINVAL; 167 } 168 ret = ops->pin_config_set(pctldev, 169 setting->data.configs.group_or_pin, 170 setting->data.configs.configs, 171 setting->data.configs.num_configs); 172 if (ret < 0) { 173 dev_err(pctldev->dev, 174 "pin_config_set op failed for pin %d\n", 175 setting->data.configs.group_or_pin); 176 return ret; 177 } 178 break; 179 case PIN_MAP_TYPE_CONFIGS_GROUP: 180 if (!ops->pin_config_group_set) { 181 dev_err(pctldev->dev, 182 "missing pin_config_group_set op\n"); 183 return -EINVAL; 184 } 185 ret = ops->pin_config_group_set(pctldev, 186 setting->data.configs.group_or_pin, 187 setting->data.configs.configs, 188 setting->data.configs.num_configs); 189 if (ret < 0) { 190 dev_err(pctldev->dev, 191 "pin_config_group_set op failed for group %d\n", 192 setting->data.configs.group_or_pin); 193 return ret; 194 } 195 break; 196 default: 197 return -EINVAL; 198 } 199 200 return 0; 201 } 202 203 #ifdef CONFIG_DEBUG_FS 204 205 void pinconf_show_map(struct seq_file *s, struct pinctrl_map const *map) 206 { 207 struct pinctrl_dev *pctldev; 208 const struct pinconf_ops *confops; 209 int i; 210 211 pctldev = get_pinctrl_dev_from_devname(map->ctrl_dev_name); 212 if (pctldev) 213 confops = pctldev->desc->confops; 214 else 215 confops = NULL; 216 217 switch (map->type) { 218 case PIN_MAP_TYPE_CONFIGS_PIN: 219 seq_printf(s, "pin "); 220 break; 221 case PIN_MAP_TYPE_CONFIGS_GROUP: 222 seq_printf(s, "group "); 223 break; 224 default: 225 break; 226 } 227 228 seq_printf(s, "%s\n", map->data.configs.group_or_pin); 229 230 for (i = 0; i < map->data.configs.num_configs; i++) { 231 seq_printf(s, "config "); 232 if (confops && confops->pin_config_config_dbg_show) 233 confops->pin_config_config_dbg_show(pctldev, s, 234 map->data.configs.configs[i]); 235 else 236 seq_printf(s, "%08lx", map->data.configs.configs[i]); 237 seq_printf(s, "\n"); 238 } 239 } 240 241 void pinconf_show_setting(struct seq_file *s, 242 struct pinctrl_setting const *setting) 243 { 244 struct pinctrl_dev *pctldev = setting->pctldev; 245 const struct pinctrl_ops *pctlops = pctldev->desc->pctlops; 246 const struct pinconf_ops *confops = pctldev->desc->confops; 247 struct pin_desc *desc; 248 int i; 249 250 switch (setting->type) { 251 case PIN_MAP_TYPE_CONFIGS_PIN: 252 desc = pin_desc_get(setting->pctldev, 253 setting->data.configs.group_or_pin); 254 seq_printf(s, "pin %s (%d)", 255 desc->name ? desc->name : "unnamed", 256 setting->data.configs.group_or_pin); 257 break; 258 case PIN_MAP_TYPE_CONFIGS_GROUP: 259 seq_printf(s, "group %s (%d)", 260 pctlops->get_group_name(pctldev, 261 setting->data.configs.group_or_pin), 262 setting->data.configs.group_or_pin); 263 break; 264 default: 265 break; 266 } 267 268 /* 269 * FIXME: We should really get the pin controler to dump the config 270 * values, so they can be decoded to something meaningful. 271 */ 272 for (i = 0; i < setting->data.configs.num_configs; i++) { 273 seq_printf(s, " "); 274 if (confops && confops->pin_config_config_dbg_show) 275 confops->pin_config_config_dbg_show(pctldev, s, 276 setting->data.configs.configs[i]); 277 else 278 seq_printf(s, "%08lx", 279 setting->data.configs.configs[i]); 280 } 281 282 seq_printf(s, "\n"); 283 } 284 285 static void pinconf_dump_pin(struct pinctrl_dev *pctldev, 286 struct seq_file *s, int pin) 287 { 288 const struct pinconf_ops *ops = pctldev->desc->confops; 289 290 /* no-op when not using generic pin config */ 291 pinconf_generic_dump_pins(pctldev, s, NULL, pin); 292 if (ops && ops->pin_config_dbg_show) 293 ops->pin_config_dbg_show(pctldev, s, pin); 294 } 295 296 static int pinconf_pins_show(struct seq_file *s, void *what) 297 { 298 struct pinctrl_dev *pctldev = s->private; 299 unsigned i, pin; 300 301 seq_puts(s, "Pin config settings per pin\n"); 302 seq_puts(s, "Format: pin (name): configs\n"); 303 304 mutex_lock(&pctldev->mutex); 305 306 /* The pin number can be retrived from the pin controller descriptor */ 307 for (i = 0; i < pctldev->desc->npins; i++) { 308 struct pin_desc *desc; 309 310 pin = pctldev->desc->pins[i].number; 311 desc = pin_desc_get(pctldev, pin); 312 /* Skip if we cannot search the pin */ 313 if (desc == NULL) 314 continue; 315 316 seq_printf(s, "pin %d (%s):", pin, 317 desc->name ? desc->name : "unnamed"); 318 319 pinconf_dump_pin(pctldev, s, pin); 320 321 seq_printf(s, "\n"); 322 } 323 324 mutex_unlock(&pctldev->mutex); 325 326 return 0; 327 } 328 329 static void pinconf_dump_group(struct pinctrl_dev *pctldev, 330 struct seq_file *s, unsigned selector, 331 const char *gname) 332 { 333 const struct pinconf_ops *ops = pctldev->desc->confops; 334 335 /* no-op when not using generic pin config */ 336 pinconf_generic_dump_pins(pctldev, s, gname, 0); 337 if (ops && ops->pin_config_group_dbg_show) 338 ops->pin_config_group_dbg_show(pctldev, s, selector); 339 } 340 341 static int pinconf_groups_show(struct seq_file *s, void *what) 342 { 343 struct pinctrl_dev *pctldev = s->private; 344 const struct pinctrl_ops *pctlops = pctldev->desc->pctlops; 345 unsigned ngroups = pctlops->get_groups_count(pctldev); 346 unsigned selector = 0; 347 348 seq_puts(s, "Pin config settings per pin group\n"); 349 seq_puts(s, "Format: group (name): configs\n"); 350 351 while (selector < ngroups) { 352 const char *gname = pctlops->get_group_name(pctldev, selector); 353 354 seq_printf(s, "%u (%s):", selector, gname); 355 pinconf_dump_group(pctldev, s, selector, gname); 356 seq_printf(s, "\n"); 357 358 selector++; 359 } 360 361 return 0; 362 } 363 364 static int pinconf_pins_open(struct inode *inode, struct file *file) 365 { 366 return single_open(file, pinconf_pins_show, inode->i_private); 367 } 368 369 static int pinconf_groups_open(struct inode *inode, struct file *file) 370 { 371 return single_open(file, pinconf_groups_show, inode->i_private); 372 } 373 374 static const struct file_operations pinconf_pins_ops = { 375 .open = pinconf_pins_open, 376 .read = seq_read, 377 .llseek = seq_lseek, 378 .release = single_release, 379 }; 380 381 static const struct file_operations pinconf_groups_ops = { 382 .open = pinconf_groups_open, 383 .read = seq_read, 384 .llseek = seq_lseek, 385 .release = single_release, 386 }; 387 388 #define MAX_NAME_LEN 15 389 390 struct dbg_cfg { 391 enum pinctrl_map_type map_type; 392 char dev_name[MAX_NAME_LEN+1]; 393 char state_name[MAX_NAME_LEN+1]; 394 char pin_name[MAX_NAME_LEN+1]; 395 }; 396 397 /* 398 * Goal is to keep this structure as global in order to simply read the 399 * pinconf-config file after a write to check config is as expected 400 */ 401 static struct dbg_cfg pinconf_dbg_conf; 402 403 /** 404 * pinconf_dbg_config_print() - display the pinctrl config from the pinctrl 405 * map, of the dev/pin/state that was last written to pinconf-config file. 406 * @s: string filled in with config description 407 * @d: not used 408 */ 409 static int pinconf_dbg_config_print(struct seq_file *s, void *d) 410 { 411 struct pinctrl_maps *maps_node; 412 const struct pinctrl_map *map; 413 const struct pinctrl_map *found = NULL; 414 struct pinctrl_dev *pctldev; 415 const struct pinconf_ops *confops = NULL; 416 struct dbg_cfg *dbg = &pinconf_dbg_conf; 417 int i, j; 418 unsigned long config; 419 420 mutex_lock(&pinctrl_maps_mutex); 421 422 /* Parse the pinctrl map and look for the elected pin/state */ 423 for_each_maps(maps_node, i, map) { 424 if (map->type != dbg->map_type) 425 continue; 426 if (strcmp(map->dev_name, dbg->dev_name)) 427 continue; 428 if (strcmp(map->name, dbg->state_name)) 429 continue; 430 431 for (j = 0; j < map->data.configs.num_configs; j++) { 432 if (!strcmp(map->data.configs.group_or_pin, 433 dbg->pin_name)) { 434 /* We found the right pin / state */ 435 found = map; 436 break; 437 } 438 } 439 } 440 441 if (!found) { 442 seq_printf(s, "No config found for dev/state/pin, expected:\n"); 443 seq_printf(s, "Searched dev:%s\n", dbg->dev_name); 444 seq_printf(s, "Searched state:%s\n", dbg->state_name); 445 seq_printf(s, "Searched pin:%s\n", dbg->pin_name); 446 seq_printf(s, "Use: modify config_pin <devname> "\ 447 "<state> <pinname> <value>\n"); 448 goto exit; 449 } 450 451 pctldev = get_pinctrl_dev_from_devname(found->ctrl_dev_name); 452 config = *found->data.configs.configs; 453 seq_printf(s, "Dev %s has config of %s in state %s: 0x%08lX\n", 454 dbg->dev_name, dbg->pin_name, 455 dbg->state_name, config); 456 457 if (pctldev) 458 confops = pctldev->desc->confops; 459 460 if (confops && confops->pin_config_config_dbg_show) 461 confops->pin_config_config_dbg_show(pctldev, s, config); 462 463 exit: 464 mutex_unlock(&pinctrl_maps_mutex); 465 466 return 0; 467 } 468 469 /** 470 * pinconf_dbg_config_write() - modify the pinctrl config in the pinctrl 471 * map, of a dev/pin/state entry based on user entries to pinconf-config 472 * @user_buf: contains the modification request with expected format: 473 * modify config_pin <devicename> <state> <pinname> <newvalue> 474 * modify is literal string, alternatives like add/delete not supported yet 475 * config_pin is literal, alternatives like config_mux not supported yet 476 * <devicename> <state> <pinname> are values that should match the pinctrl-maps 477 * <newvalue> reflects the new config and is driver dependant 478 */ 479 static ssize_t pinconf_dbg_config_write(struct file *file, 480 const char __user *user_buf, size_t count, loff_t *ppos) 481 { 482 struct pinctrl_maps *maps_node; 483 const struct pinctrl_map *map; 484 const struct pinctrl_map *found = NULL; 485 struct pinctrl_dev *pctldev; 486 const struct pinconf_ops *confops = NULL; 487 struct dbg_cfg *dbg = &pinconf_dbg_conf; 488 const struct pinctrl_map_configs *configs; 489 char config[MAX_NAME_LEN+1]; 490 char buf[128]; 491 char *b = &buf[0]; 492 int buf_size; 493 char *token; 494 int i; 495 496 /* Get userspace string and assure termination */ 497 buf_size = min(count, sizeof(buf) - 1); 498 if (copy_from_user(buf, user_buf, buf_size)) 499 return -EFAULT; 500 buf[buf_size] = 0; 501 502 /* 503 * need to parse entry and extract parameters: 504 * modify configs_pin devicename state pinname newvalue 505 */ 506 507 /* Get arg: 'modify' */ 508 token = strsep(&b, " "); 509 if (!token) 510 return -EINVAL; 511 if (strcmp(token, "modify")) 512 return -EINVAL; 513 514 /* Get arg type: "config_pin" type supported so far */ 515 token = strsep(&b, " "); 516 if (!token) 517 return -EINVAL; 518 if (strcmp(token, "config_pin")) 519 return -EINVAL; 520 dbg->map_type = PIN_MAP_TYPE_CONFIGS_PIN; 521 522 /* get arg 'device_name' */ 523 token = strsep(&b, " "); 524 if (token == NULL) 525 return -EINVAL; 526 if (strlen(token) >= MAX_NAME_LEN) 527 return -EINVAL; 528 strncpy(dbg->dev_name, token, MAX_NAME_LEN); 529 530 /* get arg 'state_name' */ 531 token = strsep(&b, " "); 532 if (token == NULL) 533 return -EINVAL; 534 if (strlen(token) >= MAX_NAME_LEN) 535 return -EINVAL; 536 strncpy(dbg->state_name, token, MAX_NAME_LEN); 537 538 /* get arg 'pin_name' */ 539 token = strsep(&b, " "); 540 if (token == NULL) 541 return -EINVAL; 542 if (strlen(token) >= MAX_NAME_LEN) 543 return -EINVAL; 544 strncpy(dbg->pin_name, token, MAX_NAME_LEN); 545 546 /* get new_value of config' */ 547 token = strsep(&b, " "); 548 if (token == NULL) 549 return -EINVAL; 550 if (strlen(token) >= MAX_NAME_LEN) 551 return -EINVAL; 552 strncpy(config, token, MAX_NAME_LEN); 553 554 mutex_lock(&pinctrl_maps_mutex); 555 556 /* Parse the pinctrl map and look for the selected dev/state/pin */ 557 for_each_maps(maps_node, i, map) { 558 if (strcmp(map->dev_name, dbg->dev_name)) 559 continue; 560 if (map->type != dbg->map_type) 561 continue; 562 if (strcmp(map->name, dbg->state_name)) 563 continue; 564 565 /* we found the right pin / state, so overwrite config */ 566 if (!strcmp(map->data.configs.group_or_pin, dbg->pin_name)) { 567 found = map; 568 break; 569 } 570 } 571 572 if (!found) { 573 count = -EINVAL; 574 goto exit; 575 } 576 577 pctldev = get_pinctrl_dev_from_devname(found->ctrl_dev_name); 578 if (pctldev) 579 confops = pctldev->desc->confops; 580 581 if (confops && confops->pin_config_dbg_parse_modify) { 582 configs = &found->data.configs; 583 for (i = 0; i < configs->num_configs; i++) { 584 confops->pin_config_dbg_parse_modify(pctldev, 585 config, 586 &configs->configs[i]); 587 } 588 } 589 590 exit: 591 mutex_unlock(&pinctrl_maps_mutex); 592 593 return count; 594 } 595 596 static int pinconf_dbg_config_open(struct inode *inode, struct file *file) 597 { 598 return single_open(file, pinconf_dbg_config_print, inode->i_private); 599 } 600 601 static const struct file_operations pinconf_dbg_pinconfig_fops = { 602 .open = pinconf_dbg_config_open, 603 .write = pinconf_dbg_config_write, 604 .read = seq_read, 605 .llseek = seq_lseek, 606 .release = single_release, 607 .owner = THIS_MODULE, 608 }; 609 610 void pinconf_init_device_debugfs(struct dentry *devroot, 611 struct pinctrl_dev *pctldev) 612 { 613 debugfs_create_file("pinconf-pins", S_IFREG | S_IRUGO, 614 devroot, pctldev, &pinconf_pins_ops); 615 debugfs_create_file("pinconf-groups", S_IFREG | S_IRUGO, 616 devroot, pctldev, &pinconf_groups_ops); 617 debugfs_create_file("pinconf-config", (S_IRUGO | S_IWUSR | S_IWGRP), 618 devroot, pctldev, &pinconf_dbg_pinconfig_fops); 619 } 620 621 #endif 622