pinconf.c 16 KB

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