berlin.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Marvell Berlin SoC pinctrl core driver
  4. *
  5. * Copyright (C) 2014 Marvell Technology Group Ltd.
  6. *
  7. * Antoine Ténart <[email protected]>
  8. */
  9. #include <linux/io.h>
  10. #include <linux/mfd/syscon.h>
  11. #include <linux/module.h>
  12. #include <linux/of.h>
  13. #include <linux/of_address.h>
  14. #include <linux/of_device.h>
  15. #include <linux/pinctrl/pinctrl.h>
  16. #include <linux/pinctrl/pinmux.h>
  17. #include <linux/platform_device.h>
  18. #include <linux/regmap.h>
  19. #include <linux/slab.h>
  20. #include "../core.h"
  21. #include "../pinctrl-utils.h"
  22. #include "berlin.h"
  23. struct berlin_pinctrl {
  24. struct regmap *regmap;
  25. struct device *dev;
  26. const struct berlin_pinctrl_desc *desc;
  27. struct berlin_pinctrl_function *functions;
  28. unsigned nfunctions;
  29. struct pinctrl_dev *pctrl_dev;
  30. };
  31. static int berlin_pinctrl_get_group_count(struct pinctrl_dev *pctrl_dev)
  32. {
  33. struct berlin_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev);
  34. return pctrl->desc->ngroups;
  35. }
  36. static const char *berlin_pinctrl_get_group_name(struct pinctrl_dev *pctrl_dev,
  37. unsigned group)
  38. {
  39. struct berlin_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev);
  40. return pctrl->desc->groups[group].name;
  41. }
  42. static int berlin_pinctrl_dt_node_to_map(struct pinctrl_dev *pctrl_dev,
  43. struct device_node *node,
  44. struct pinctrl_map **map,
  45. unsigned *num_maps)
  46. {
  47. struct berlin_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev);
  48. struct property *prop;
  49. const char *function_name, *group_name;
  50. unsigned reserved_maps = 0;
  51. int ret, ngroups;
  52. *map = NULL;
  53. *num_maps = 0;
  54. ret = of_property_read_string(node, "function", &function_name);
  55. if (ret) {
  56. dev_err(pctrl->dev,
  57. "missing function property in node %pOFn\n", node);
  58. return -EINVAL;
  59. }
  60. ngroups = of_property_count_strings(node, "groups");
  61. if (ngroups < 0) {
  62. dev_err(pctrl->dev,
  63. "missing groups property in node %pOFn\n", node);
  64. return -EINVAL;
  65. }
  66. ret = pinctrl_utils_reserve_map(pctrl_dev, map, &reserved_maps,
  67. num_maps, ngroups);
  68. if (ret) {
  69. dev_err(pctrl->dev, "can't reserve map: %d\n", ret);
  70. return ret;
  71. }
  72. of_property_for_each_string(node, "groups", prop, group_name) {
  73. ret = pinctrl_utils_add_map_mux(pctrl_dev, map, &reserved_maps,
  74. num_maps, group_name,
  75. function_name);
  76. if (ret) {
  77. dev_err(pctrl->dev, "can't add map: %d\n", ret);
  78. return ret;
  79. }
  80. }
  81. return 0;
  82. }
  83. static const struct pinctrl_ops berlin_pinctrl_ops = {
  84. .get_groups_count = &berlin_pinctrl_get_group_count,
  85. .get_group_name = &berlin_pinctrl_get_group_name,
  86. .dt_node_to_map = &berlin_pinctrl_dt_node_to_map,
  87. .dt_free_map = &pinctrl_utils_free_map,
  88. };
  89. static int berlin_pinmux_get_functions_count(struct pinctrl_dev *pctrl_dev)
  90. {
  91. struct berlin_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev);
  92. return pctrl->nfunctions;
  93. }
  94. static const char *berlin_pinmux_get_function_name(struct pinctrl_dev *pctrl_dev,
  95. unsigned function)
  96. {
  97. struct berlin_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev);
  98. return pctrl->functions[function].name;
  99. }
  100. static int berlin_pinmux_get_function_groups(struct pinctrl_dev *pctrl_dev,
  101. unsigned function,
  102. const char * const **groups,
  103. unsigned * const num_groups)
  104. {
  105. struct berlin_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev);
  106. *groups = pctrl->functions[function].groups;
  107. *num_groups = pctrl->functions[function].ngroups;
  108. return 0;
  109. }
  110. static struct berlin_desc_function *
  111. berlin_pinctrl_find_function_by_name(struct berlin_pinctrl *pctrl,
  112. const struct berlin_desc_group *group,
  113. const char *fname)
  114. {
  115. struct berlin_desc_function *function = group->functions;
  116. while (function->name) {
  117. if (!strcmp(function->name, fname))
  118. return function;
  119. function++;
  120. }
  121. return NULL;
  122. }
  123. static int berlin_pinmux_set(struct pinctrl_dev *pctrl_dev,
  124. unsigned function,
  125. unsigned group)
  126. {
  127. struct berlin_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev);
  128. const struct berlin_desc_group *group_desc = pctrl->desc->groups + group;
  129. struct berlin_pinctrl_function *func = pctrl->functions + function;
  130. struct berlin_desc_function *function_desc =
  131. berlin_pinctrl_find_function_by_name(pctrl, group_desc,
  132. func->name);
  133. u32 mask, val;
  134. if (!function_desc)
  135. return -EINVAL;
  136. mask = GENMASK(group_desc->lsb + group_desc->bit_width - 1,
  137. group_desc->lsb);
  138. val = function_desc->muxval << group_desc->lsb;
  139. regmap_update_bits(pctrl->regmap, group_desc->offset, mask, val);
  140. return 0;
  141. }
  142. static const struct pinmux_ops berlin_pinmux_ops = {
  143. .get_functions_count = &berlin_pinmux_get_functions_count,
  144. .get_function_name = &berlin_pinmux_get_function_name,
  145. .get_function_groups = &berlin_pinmux_get_function_groups,
  146. .set_mux = &berlin_pinmux_set,
  147. };
  148. static int berlin_pinctrl_add_function(struct berlin_pinctrl *pctrl,
  149. const char *name)
  150. {
  151. struct berlin_pinctrl_function *function = pctrl->functions;
  152. while (function->name) {
  153. if (!strcmp(function->name, name)) {
  154. function->ngroups++;
  155. return -EEXIST;
  156. }
  157. function++;
  158. }
  159. function->name = name;
  160. function->ngroups = 1;
  161. pctrl->nfunctions++;
  162. return 0;
  163. }
  164. static int berlin_pinctrl_build_state(struct platform_device *pdev)
  165. {
  166. struct berlin_pinctrl *pctrl = platform_get_drvdata(pdev);
  167. const struct berlin_desc_group *desc_group;
  168. const struct berlin_desc_function *desc_function;
  169. int i, max_functions = 0;
  170. pctrl->nfunctions = 0;
  171. for (i = 0; i < pctrl->desc->ngroups; i++) {
  172. desc_group = pctrl->desc->groups + i;
  173. /* compute the maximum number of functions a group can have */
  174. max_functions += 1 << (desc_group->bit_width + 1);
  175. }
  176. /* we will reallocate later */
  177. pctrl->functions = kcalloc(max_functions,
  178. sizeof(*pctrl->functions), GFP_KERNEL);
  179. if (!pctrl->functions)
  180. return -ENOMEM;
  181. /* register all functions */
  182. for (i = 0; i < pctrl->desc->ngroups; i++) {
  183. desc_group = pctrl->desc->groups + i;
  184. desc_function = desc_group->functions;
  185. while (desc_function->name) {
  186. berlin_pinctrl_add_function(pctrl, desc_function->name);
  187. desc_function++;
  188. }
  189. }
  190. pctrl->functions = krealloc(pctrl->functions,
  191. pctrl->nfunctions * sizeof(*pctrl->functions),
  192. GFP_KERNEL);
  193. if (!pctrl->functions)
  194. return -ENOMEM;
  195. /* map functions to theirs groups */
  196. for (i = 0; i < pctrl->desc->ngroups; i++) {
  197. desc_group = pctrl->desc->groups + i;
  198. desc_function = desc_group->functions;
  199. while (desc_function->name) {
  200. struct berlin_pinctrl_function
  201. *function = pctrl->functions;
  202. const char **groups;
  203. bool found = false;
  204. while (function->name) {
  205. if (!strcmp(desc_function->name, function->name)) {
  206. found = true;
  207. break;
  208. }
  209. function++;
  210. }
  211. if (!found) {
  212. kfree(pctrl->functions);
  213. return -EINVAL;
  214. }
  215. if (!function->groups) {
  216. function->groups =
  217. devm_kcalloc(&pdev->dev,
  218. function->ngroups,
  219. sizeof(char *),
  220. GFP_KERNEL);
  221. if (!function->groups) {
  222. kfree(pctrl->functions);
  223. return -ENOMEM;
  224. }
  225. }
  226. groups = function->groups;
  227. while (*groups)
  228. groups++;
  229. *groups = desc_group->name;
  230. desc_function++;
  231. }
  232. }
  233. return 0;
  234. }
  235. static struct pinctrl_desc berlin_pctrl_desc = {
  236. .name = "berlin-pinctrl",
  237. .pctlops = &berlin_pinctrl_ops,
  238. .pmxops = &berlin_pinmux_ops,
  239. .owner = THIS_MODULE,
  240. };
  241. int berlin_pinctrl_probe_regmap(struct platform_device *pdev,
  242. const struct berlin_pinctrl_desc *desc,
  243. struct regmap *regmap)
  244. {
  245. struct device *dev = &pdev->dev;
  246. struct berlin_pinctrl *pctrl;
  247. int ret;
  248. pctrl = devm_kzalloc(dev, sizeof(*pctrl), GFP_KERNEL);
  249. if (!pctrl)
  250. return -ENOMEM;
  251. platform_set_drvdata(pdev, pctrl);
  252. pctrl->regmap = regmap;
  253. pctrl->dev = &pdev->dev;
  254. pctrl->desc = desc;
  255. ret = berlin_pinctrl_build_state(pdev);
  256. if (ret) {
  257. dev_err(dev, "cannot build driver state: %d\n", ret);
  258. return ret;
  259. }
  260. pctrl->pctrl_dev = devm_pinctrl_register(dev, &berlin_pctrl_desc,
  261. pctrl);
  262. if (IS_ERR(pctrl->pctrl_dev)) {
  263. dev_err(dev, "failed to register pinctrl driver\n");
  264. return PTR_ERR(pctrl->pctrl_dev);
  265. }
  266. return 0;
  267. }
  268. int berlin_pinctrl_probe(struct platform_device *pdev,
  269. const struct berlin_pinctrl_desc *desc)
  270. {
  271. struct device *dev = &pdev->dev;
  272. struct device_node *parent_np = of_get_parent(dev->of_node);
  273. struct regmap *regmap = syscon_node_to_regmap(parent_np);
  274. of_node_put(parent_np);
  275. if (IS_ERR(regmap))
  276. return PTR_ERR(regmap);
  277. return berlin_pinctrl_probe_regmap(pdev, desc, regmap);
  278. }