pinconf.c 16 KB

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