pinctrl-ns.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (C) 2018 Rafał Miłecki <rafal@milecki.pl>
  4. */
  5. #include <linux/err.h>
  6. #include <linux/io.h>
  7. #include <linux/module.h>
  8. #include <linux/of.h>
  9. #include <linux/of_device.h>
  10. #include <linux/pinctrl/pinconf-generic.h>
  11. #include <linux/pinctrl/pinctrl.h>
  12. #include <linux/pinctrl/pinmux.h>
  13. #include <linux/platform_device.h>
  14. #include <linux/slab.h>
  15. #define FLAG_BCM4708 BIT(1)
  16. #define FLAG_BCM4709 BIT(2)
  17. #define FLAG_BCM53012 BIT(3)
  18. struct ns_pinctrl {
  19. struct device *dev;
  20. unsigned int chipset_flag;
  21. struct pinctrl_dev *pctldev;
  22. void __iomem *base;
  23. struct pinctrl_desc pctldesc;
  24. struct ns_pinctrl_group *groups;
  25. unsigned int num_groups;
  26. struct ns_pinctrl_function *functions;
  27. unsigned int num_functions;
  28. };
  29. /*
  30. * Pins
  31. */
  32. static const struct pinctrl_pin_desc ns_pinctrl_pins[] = {
  33. { 0, "spi_clk", (void *)(FLAG_BCM4708 | FLAG_BCM4709 | FLAG_BCM53012) },
  34. { 1, "spi_ss", (void *)(FLAG_BCM4708 | FLAG_BCM4709 | FLAG_BCM53012) },
  35. { 2, "spi_mosi", (void *)(FLAG_BCM4708 | FLAG_BCM4709 | FLAG_BCM53012) },
  36. { 3, "spi_miso", (void *)(FLAG_BCM4708 | FLAG_BCM4709 | FLAG_BCM53012) },
  37. { 4, "i2c_scl", (void *)(FLAG_BCM4708 | FLAG_BCM4709 | FLAG_BCM53012) },
  38. { 5, "i2c_sda", (void *)(FLAG_BCM4708 | FLAG_BCM4709 | FLAG_BCM53012) },
  39. { 6, "mdc", (void *)(FLAG_BCM4709 | FLAG_BCM53012) },
  40. { 7, "mdio", (void *)(FLAG_BCM4709 | FLAG_BCM53012) },
  41. { 8, "pwm0", (void *)(FLAG_BCM4708 | FLAG_BCM4709 | FLAG_BCM53012) },
  42. { 9, "pwm1", (void *)(FLAG_BCM4708 | FLAG_BCM4709 | FLAG_BCM53012) },
  43. { 10, "pwm2", (void *)(FLAG_BCM4708 | FLAG_BCM4709 | FLAG_BCM53012) },
  44. { 11, "pwm3", (void *)(FLAG_BCM4708 | FLAG_BCM4709 | FLAG_BCM53012) },
  45. { 12, "uart1_rx", (void *)(FLAG_BCM4708 | FLAG_BCM4709 | FLAG_BCM53012) },
  46. { 13, "uart1_tx", (void *)(FLAG_BCM4708 | FLAG_BCM4709 | FLAG_BCM53012) },
  47. { 14, "uart1_cts", (void *)(FLAG_BCM4708 | FLAG_BCM4709 | FLAG_BCM53012) },
  48. { 15, "uart1_rts", (void *)(FLAG_BCM4708 | FLAG_BCM4709 | FLAG_BCM53012) },
  49. { 16, "uart2_rx", (void *)(FLAG_BCM4709 | FLAG_BCM53012) },
  50. { 17, "uart2_tx", (void *)(FLAG_BCM4709 | FLAG_BCM53012) },
  51. /* TODO { ??, "xtal_out", (void *)(FLAG_BCM4709) }, */
  52. { 22, "sdio_pwr", (void *)(FLAG_BCM4709 | FLAG_BCM53012) },
  53. { 23, "sdio_en_1p8v", (void *)(FLAG_BCM4709 | FLAG_BCM53012) },
  54. };
  55. /*
  56. * Groups
  57. */
  58. struct ns_pinctrl_group {
  59. const char *name;
  60. const unsigned int *pins;
  61. const unsigned int num_pins;
  62. unsigned int chipsets;
  63. };
  64. static const unsigned int spi_pins[] = { 0, 1, 2, 3 };
  65. static const unsigned int i2c_pins[] = { 4, 5 };
  66. static const unsigned int mdio_pins[] = { 6, 7 };
  67. static const unsigned int pwm0_pins[] = { 8 };
  68. static const unsigned int pwm1_pins[] = { 9 };
  69. static const unsigned int pwm2_pins[] = { 10 };
  70. static const unsigned int pwm3_pins[] = { 11 };
  71. static const unsigned int uart1_pins[] = { 12, 13, 14, 15 };
  72. static const unsigned int uart2_pins[] = { 16, 17 };
  73. static const unsigned int sdio_pwr_pins[] = { 22 };
  74. static const unsigned int sdio_1p8v_pins[] = { 23 };
  75. #define NS_GROUP(_name, _pins, _chipsets) \
  76. { \
  77. .name = _name, \
  78. .pins = _pins, \
  79. .num_pins = ARRAY_SIZE(_pins), \
  80. .chipsets = _chipsets, \
  81. }
  82. static const struct ns_pinctrl_group ns_pinctrl_groups[] = {
  83. NS_GROUP("spi_grp", spi_pins, FLAG_BCM4708 | FLAG_BCM4709 | FLAG_BCM53012),
  84. NS_GROUP("i2c_grp", i2c_pins, FLAG_BCM4708 | FLAG_BCM4709 | FLAG_BCM53012),
  85. NS_GROUP("mdio_grp", mdio_pins, FLAG_BCM4709 | FLAG_BCM53012),
  86. NS_GROUP("pwm0_grp", pwm0_pins, FLAG_BCM4708 | FLAG_BCM4709 | FLAG_BCM53012),
  87. NS_GROUP("pwm1_grp", pwm1_pins, FLAG_BCM4708 | FLAG_BCM4709 | FLAG_BCM53012),
  88. NS_GROUP("pwm2_grp", pwm2_pins, FLAG_BCM4708 | FLAG_BCM4709 | FLAG_BCM53012),
  89. NS_GROUP("pwm3_grp", pwm3_pins, FLAG_BCM4708 | FLAG_BCM4709 | FLAG_BCM53012),
  90. NS_GROUP("uart1_grp", uart1_pins, FLAG_BCM4708 | FLAG_BCM4709 | FLAG_BCM53012),
  91. NS_GROUP("uart2_grp", uart2_pins, FLAG_BCM4709 | FLAG_BCM53012),
  92. NS_GROUP("sdio_pwr_grp", sdio_pwr_pins, FLAG_BCM4709 | FLAG_BCM53012),
  93. NS_GROUP("sdio_1p8v_grp", sdio_1p8v_pins, FLAG_BCM4709 | FLAG_BCM53012),
  94. };
  95. /*
  96. * Functions
  97. */
  98. struct ns_pinctrl_function {
  99. const char *name;
  100. const char * const *groups;
  101. const unsigned int num_groups;
  102. unsigned int chipsets;
  103. };
  104. static const char * const spi_groups[] = { "spi_grp" };
  105. static const char * const i2c_groups[] = { "i2c_grp" };
  106. static const char * const mdio_groups[] = { "mdio_grp" };
  107. static const char * const pwm_groups[] = { "pwm0_grp", "pwm1_grp", "pwm2_grp",
  108. "pwm3_grp" };
  109. static const char * const uart1_groups[] = { "uart1_grp" };
  110. static const char * const uart2_groups[] = { "uart2_grp" };
  111. static const char * const sdio_groups[] = { "sdio_pwr_grp", "sdio_1p8v_grp" };
  112. #define NS_FUNCTION(_name, _groups, _chipsets) \
  113. { \
  114. .name = _name, \
  115. .groups = _groups, \
  116. .num_groups = ARRAY_SIZE(_groups), \
  117. .chipsets = _chipsets, \
  118. }
  119. static const struct ns_pinctrl_function ns_pinctrl_functions[] = {
  120. NS_FUNCTION("spi", spi_groups, FLAG_BCM4708 | FLAG_BCM4709 | FLAG_BCM53012),
  121. NS_FUNCTION("i2c", i2c_groups, FLAG_BCM4708 | FLAG_BCM4709 | FLAG_BCM53012),
  122. NS_FUNCTION("mdio", mdio_groups, FLAG_BCM4709 | FLAG_BCM53012),
  123. NS_FUNCTION("pwm", pwm_groups, FLAG_BCM4708 | FLAG_BCM4709 | FLAG_BCM53012),
  124. NS_FUNCTION("uart1", uart1_groups, FLAG_BCM4708 | FLAG_BCM4709 | FLAG_BCM53012),
  125. NS_FUNCTION("uart2", uart2_groups, FLAG_BCM4709 | FLAG_BCM53012),
  126. NS_FUNCTION("sdio", sdio_groups, FLAG_BCM4709 | FLAG_BCM53012),
  127. };
  128. /*
  129. * Groups code
  130. */
  131. static int ns_pinctrl_get_groups_count(struct pinctrl_dev *pctrl_dev)
  132. {
  133. struct ns_pinctrl *ns_pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
  134. return ns_pinctrl->num_groups;
  135. }
  136. static const char *ns_pinctrl_get_group_name(struct pinctrl_dev *pctrl_dev,
  137. unsigned int selector)
  138. {
  139. struct ns_pinctrl *ns_pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
  140. return ns_pinctrl->groups[selector].name;
  141. }
  142. static int ns_pinctrl_get_group_pins(struct pinctrl_dev *pctrl_dev,
  143. unsigned int selector,
  144. const unsigned int **pins,
  145. unsigned int *num_pins)
  146. {
  147. struct ns_pinctrl *ns_pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
  148. *pins = ns_pinctrl->groups[selector].pins;
  149. *num_pins = ns_pinctrl->groups[selector].num_pins;
  150. return 0;
  151. }
  152. static const struct pinctrl_ops ns_pinctrl_ops = {
  153. .get_groups_count = ns_pinctrl_get_groups_count,
  154. .get_group_name = ns_pinctrl_get_group_name,
  155. .get_group_pins = ns_pinctrl_get_group_pins,
  156. .dt_node_to_map = pinconf_generic_dt_node_to_map_group,
  157. .dt_free_map = pinconf_generic_dt_free_map,
  158. };
  159. /*
  160. * Functions code
  161. */
  162. static int ns_pinctrl_get_functions_count(struct pinctrl_dev *pctrl_dev)
  163. {
  164. struct ns_pinctrl *ns_pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
  165. return ns_pinctrl->num_functions;
  166. }
  167. static const char *ns_pinctrl_get_function_name(struct pinctrl_dev *pctrl_dev,
  168. unsigned int selector)
  169. {
  170. struct ns_pinctrl *ns_pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
  171. return ns_pinctrl->functions[selector].name;
  172. }
  173. static int ns_pinctrl_get_function_groups(struct pinctrl_dev *pctrl_dev,
  174. unsigned int selector,
  175. const char * const **groups,
  176. unsigned * const num_groups)
  177. {
  178. struct ns_pinctrl *ns_pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
  179. *groups = ns_pinctrl->functions[selector].groups;
  180. *num_groups = ns_pinctrl->functions[selector].num_groups;
  181. return 0;
  182. }
  183. static int ns_pinctrl_set_mux(struct pinctrl_dev *pctrl_dev,
  184. unsigned int func_select,
  185. unsigned int grp_select)
  186. {
  187. struct ns_pinctrl *ns_pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
  188. u32 unset = 0;
  189. u32 tmp;
  190. int i;
  191. for (i = 0; i < ns_pinctrl->groups[grp_select].num_pins; i++) {
  192. int pin_number = ns_pinctrl->groups[grp_select].pins[i];
  193. unset |= BIT(pin_number);
  194. }
  195. tmp = readl(ns_pinctrl->base);
  196. tmp &= ~unset;
  197. writel(tmp, ns_pinctrl->base);
  198. return 0;
  199. }
  200. static const struct pinmux_ops ns_pinctrl_pmxops = {
  201. .get_functions_count = ns_pinctrl_get_functions_count,
  202. .get_function_name = ns_pinctrl_get_function_name,
  203. .get_function_groups = ns_pinctrl_get_function_groups,
  204. .set_mux = ns_pinctrl_set_mux,
  205. };
  206. /*
  207. * Controller code
  208. */
  209. static struct pinctrl_desc ns_pinctrl_desc = {
  210. .name = "pinctrl-ns",
  211. .pctlops = &ns_pinctrl_ops,
  212. .pmxops = &ns_pinctrl_pmxops,
  213. };
  214. static const struct of_device_id ns_pinctrl_of_match_table[] = {
  215. { .compatible = "brcm,bcm4708-pinmux", .data = (void *)FLAG_BCM4708, },
  216. { .compatible = "brcm,bcm4709-pinmux", .data = (void *)FLAG_BCM4709, },
  217. { .compatible = "brcm,bcm53012-pinmux", .data = (void *)FLAG_BCM53012, },
  218. { }
  219. };
  220. static int ns_pinctrl_probe(struct platform_device *pdev)
  221. {
  222. struct device *dev = &pdev->dev;
  223. const struct of_device_id *of_id;
  224. struct ns_pinctrl *ns_pinctrl;
  225. struct pinctrl_desc *pctldesc;
  226. struct pinctrl_pin_desc *pin;
  227. struct ns_pinctrl_group *group;
  228. struct ns_pinctrl_function *function;
  229. struct resource *res;
  230. int i;
  231. ns_pinctrl = devm_kzalloc(dev, sizeof(*ns_pinctrl), GFP_KERNEL);
  232. if (!ns_pinctrl)
  233. return -ENOMEM;
  234. pctldesc = &ns_pinctrl->pctldesc;
  235. platform_set_drvdata(pdev, ns_pinctrl);
  236. /* Set basic properties */
  237. ns_pinctrl->dev = dev;
  238. of_id = of_match_device(ns_pinctrl_of_match_table, dev);
  239. if (!of_id)
  240. return -EINVAL;
  241. ns_pinctrl->chipset_flag = (uintptr_t)of_id->data;
  242. res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
  243. "cru_gpio_control");
  244. ns_pinctrl->base = devm_ioremap_resource(dev, res);
  245. if (IS_ERR(ns_pinctrl->base)) {
  246. dev_err(dev, "Failed to map pinctrl regs\n");
  247. return PTR_ERR(ns_pinctrl->base);
  248. }
  249. memcpy(pctldesc, &ns_pinctrl_desc, sizeof(*pctldesc));
  250. /* Set pinctrl properties */
  251. pctldesc->pins = devm_kcalloc(dev, ARRAY_SIZE(ns_pinctrl_pins),
  252. sizeof(struct pinctrl_pin_desc),
  253. GFP_KERNEL);
  254. if (!pctldesc->pins)
  255. return -ENOMEM;
  256. for (i = 0, pin = (struct pinctrl_pin_desc *)&pctldesc->pins[0];
  257. i < ARRAY_SIZE(ns_pinctrl_pins); i++) {
  258. const struct pinctrl_pin_desc *src = &ns_pinctrl_pins[i];
  259. unsigned int chipsets = (uintptr_t)src->drv_data;
  260. if (chipsets & ns_pinctrl->chipset_flag) {
  261. memcpy(pin++, src, sizeof(*src));
  262. pctldesc->npins++;
  263. }
  264. }
  265. ns_pinctrl->groups = devm_kcalloc(dev, ARRAY_SIZE(ns_pinctrl_groups),
  266. sizeof(struct ns_pinctrl_group),
  267. GFP_KERNEL);
  268. if (!ns_pinctrl->groups)
  269. return -ENOMEM;
  270. for (i = 0, group = &ns_pinctrl->groups[0];
  271. i < ARRAY_SIZE(ns_pinctrl_groups); i++) {
  272. const struct ns_pinctrl_group *src = &ns_pinctrl_groups[i];
  273. if (src->chipsets & ns_pinctrl->chipset_flag) {
  274. memcpy(group++, src, sizeof(*src));
  275. ns_pinctrl->num_groups++;
  276. }
  277. }
  278. ns_pinctrl->functions = devm_kcalloc(dev,
  279. ARRAY_SIZE(ns_pinctrl_functions),
  280. sizeof(struct ns_pinctrl_function),
  281. GFP_KERNEL);
  282. if (!ns_pinctrl->functions)
  283. return -ENOMEM;
  284. for (i = 0, function = &ns_pinctrl->functions[0];
  285. i < ARRAY_SIZE(ns_pinctrl_functions); i++) {
  286. const struct ns_pinctrl_function *src = &ns_pinctrl_functions[i];
  287. if (src->chipsets & ns_pinctrl->chipset_flag) {
  288. memcpy(function++, src, sizeof(*src));
  289. ns_pinctrl->num_functions++;
  290. }
  291. }
  292. /* Register */
  293. ns_pinctrl->pctldev = devm_pinctrl_register(dev, pctldesc, ns_pinctrl);
  294. if (IS_ERR(ns_pinctrl->pctldev)) {
  295. dev_err(dev, "Failed to register pinctrl\n");
  296. return PTR_ERR(ns_pinctrl->pctldev);
  297. }
  298. return 0;
  299. }
  300. static struct platform_driver ns_pinctrl_driver = {
  301. .probe = ns_pinctrl_probe,
  302. .driver = {
  303. .name = "ns-pinmux",
  304. .of_match_table = ns_pinctrl_of_match_table,
  305. },
  306. };
  307. module_platform_driver(ns_pinctrl_driver);
  308. MODULE_AUTHOR("Rafał Miłecki");
  309. MODULE_LICENSE("GPL v2");
  310. MODULE_DEVICE_TABLE(of, ns_pinctrl_of_match_table);