pinctrl-brcmstb.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Driver for Broadcom brcmstb GPIO units (pinctrl only)
  4. *
  5. * Copyright (C) 2024-2025 Ivan T. Ivanov, Andrea della Porta
  6. * Copyright (C) 2021-3 Raspberry Pi Ltd.
  7. * Copyright (C) 2012 Chris Boot, Simon Arlott, Stephen Warren
  8. *
  9. * Based heavily on the BCM2835 GPIO & pinctrl driver, which was inspired by:
  10. * pinctrl-nomadik.c, please see original file for copyright information
  11. * pinctrl-tegra.c, please see original file for copyright information
  12. */
  13. #include <linux/device.h>
  14. #include <linux/err.h>
  15. #include <linux/init.h>
  16. #include <linux/io.h>
  17. #include <linux/of.h>
  18. #include <linux/pinctrl/pinconf.h>
  19. #include <linux/pinctrl/pinctrl.h>
  20. #include <linux/pinctrl/pinmux.h>
  21. #include <linux/pinctrl/pinconf-generic.h>
  22. #include <linux/seq_file.h>
  23. #include <linux/slab.h>
  24. #include <linux/spinlock.h>
  25. #include <linux/cleanup.h>
  26. #include "pinctrl-brcmstb.h"
  27. #define BRCMSTB_PULL_NONE 0
  28. #define BRCMSTB_PULL_DOWN 1
  29. #define BRCMSTB_PULL_UP 2
  30. #define BRCMSTB_PULL_MASK 0x3
  31. #define BIT_TO_REG(b) (((b) >> 5) << 2)
  32. #define BIT_TO_SHIFT(b) ((b) & 0x1f)
  33. struct brcmstb_pinctrl {
  34. struct device *dev;
  35. void __iomem *base;
  36. struct pinctrl_dev *pctl_dev;
  37. struct pinctrl_desc pctl_desc;
  38. const struct pin_regs *pin_regs;
  39. const struct brcmstb_pin_funcs *pin_funcs;
  40. const char * const *func_names;
  41. unsigned int func_count;
  42. unsigned int func_gpio;
  43. const char *const *gpio_groups;
  44. struct pinctrl_gpio_range gpio_range;
  45. /* Protect FSEL registers */
  46. spinlock_t fsel_lock;
  47. };
  48. static unsigned int brcmstb_pinctrl_fsel_get(struct brcmstb_pinctrl *pc,
  49. unsigned int pin)
  50. {
  51. u32 bit = pc->pin_regs[pin].mux_bit;
  52. unsigned int func;
  53. int fsel;
  54. u32 val;
  55. if (!bit)
  56. return pc->func_gpio;
  57. bit &= ~MUX_BIT_VALID;
  58. val = readl(pc->base + BIT_TO_REG(bit));
  59. fsel = (val >> BIT_TO_SHIFT(bit)) & pc->pin_funcs[pin].func_mask;
  60. func = pc->pin_funcs[pin].funcs[fsel];
  61. if (func >= pc->func_count)
  62. func = fsel;
  63. dev_dbg(pc->dev, "get %04x: %08x (%u => %s)\n",
  64. BIT_TO_REG(bit), val, pin,
  65. pc->func_names[func]);
  66. return func;
  67. }
  68. static int brcmstb_pinctrl_fsel_set(struct brcmstb_pinctrl *pc,
  69. unsigned int pin, unsigned int func)
  70. {
  71. u32 bit = pc->pin_regs[pin].mux_bit, val, fsel_mask;
  72. const u8 *pin_funcs;
  73. int fsel;
  74. int cur;
  75. int i;
  76. if (!bit || func >= pc->func_count)
  77. return -EINVAL;
  78. bit &= ~MUX_BIT_VALID;
  79. fsel = pc->pin_funcs[pin].n_funcs + 1;
  80. fsel_mask = pc->pin_funcs[pin].func_mask;
  81. if (func >= fsel) {
  82. /* Convert to an fsel number */
  83. pin_funcs = pc->pin_funcs[pin].funcs;
  84. for (i = 1; i < fsel; i++) {
  85. if (pin_funcs[i - 1] == func) {
  86. fsel = i;
  87. break;
  88. }
  89. }
  90. } else {
  91. fsel = func;
  92. }
  93. if (fsel >= pc->pin_funcs[pin].n_funcs + 1)
  94. return -EINVAL;
  95. guard(spinlock_irqsave)(&pc->fsel_lock);
  96. val = readl(pc->base + BIT_TO_REG(bit));
  97. cur = (val >> BIT_TO_SHIFT(bit)) & fsel_mask;
  98. dev_dbg(pc->dev, "read %04x: %08x (%u => %s)\n",
  99. BIT_TO_REG(bit), val, pin,
  100. pc->func_names[cur]);
  101. if (cur != fsel) {
  102. val &= ~(fsel_mask << BIT_TO_SHIFT(bit));
  103. val |= fsel << BIT_TO_SHIFT(bit);
  104. dev_dbg(pc->dev, "write %04x: %08x (%u <= %s)\n",
  105. BIT_TO_REG(bit), val, pin,
  106. pc->func_names[fsel]);
  107. writel(val, pc->base + BIT_TO_REG(bit));
  108. }
  109. return 0;
  110. }
  111. static int brcmstb_pctl_get_groups_count(struct pinctrl_dev *pctldev)
  112. {
  113. struct brcmstb_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
  114. return pc->pctl_desc.npins;
  115. }
  116. static const char *brcmstb_pctl_get_group_name(struct pinctrl_dev *pctldev,
  117. unsigned int selector)
  118. {
  119. struct brcmstb_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
  120. return pc->gpio_groups[selector];
  121. }
  122. static int brcmstb_pctl_get_group_pins(struct pinctrl_dev *pctldev,
  123. unsigned int selector,
  124. const unsigned int **pins,
  125. unsigned int *num_pins)
  126. {
  127. struct brcmstb_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
  128. *pins = &pc->pctl_desc.pins[selector].number;
  129. *num_pins = 1;
  130. return 0;
  131. }
  132. static void brcmstb_pctl_pin_dbg_show(struct pinctrl_dev *pctldev,
  133. struct seq_file *s, unsigned int offset)
  134. {
  135. struct brcmstb_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
  136. unsigned int fsel = brcmstb_pinctrl_fsel_get(pc, offset);
  137. const char *fname = pc->func_names[fsel];
  138. seq_printf(s, "function %s", fname);
  139. }
  140. static void brcmstb_pctl_dt_free_map(struct pinctrl_dev *pctldev,
  141. struct pinctrl_map *maps,
  142. unsigned int num_maps)
  143. {
  144. int i;
  145. for (i = 0; i < num_maps; i++)
  146. if (maps[i].type == PIN_MAP_TYPE_CONFIGS_PIN)
  147. kfree(maps[i].data.configs.configs);
  148. kfree(maps);
  149. }
  150. static const struct pinctrl_ops brcmstb_pctl_ops = {
  151. .get_groups_count = brcmstb_pctl_get_groups_count,
  152. .get_group_name = brcmstb_pctl_get_group_name,
  153. .get_group_pins = brcmstb_pctl_get_group_pins,
  154. .pin_dbg_show = brcmstb_pctl_pin_dbg_show,
  155. .dt_node_to_map = pinconf_generic_dt_node_to_map_all,
  156. .dt_free_map = brcmstb_pctl_dt_free_map,
  157. };
  158. static int brcmstb_pmx_free(struct pinctrl_dev *pctldev, unsigned int offset)
  159. {
  160. struct brcmstb_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
  161. /* disable by setting to GPIO */
  162. return brcmstb_pinctrl_fsel_set(pc, offset, pc->func_gpio);
  163. }
  164. static int brcmstb_pmx_get_functions_count(struct pinctrl_dev *pctldev)
  165. {
  166. struct brcmstb_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
  167. return pc->func_count;
  168. }
  169. static const char *brcmstb_pmx_get_function_name(struct pinctrl_dev *pctldev,
  170. unsigned int selector)
  171. {
  172. struct brcmstb_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
  173. return (selector < pc->func_count) ? pc->func_names[selector] : NULL;
  174. }
  175. static int brcmstb_pmx_get_function_groups(struct pinctrl_dev *pctldev,
  176. unsigned int selector,
  177. const char *const **groups,
  178. unsigned *const num_groups)
  179. {
  180. struct brcmstb_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
  181. *groups = pc->gpio_groups;
  182. *num_groups = pc->pctl_desc.npins;
  183. return 0;
  184. }
  185. static int brcmstb_pmx_set(struct pinctrl_dev *pctldev,
  186. unsigned int func_selector,
  187. unsigned int group_selector)
  188. {
  189. struct brcmstb_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
  190. const struct pinctrl_desc *pctldesc = &pc->pctl_desc;
  191. const struct pinctrl_pin_desc *pindesc;
  192. if (group_selector >= pctldesc->npins)
  193. return -EINVAL;
  194. pindesc = &pctldesc->pins[group_selector];
  195. return brcmstb_pinctrl_fsel_set(pc, pindesc->number, func_selector);
  196. }
  197. static int brcmstb_pmx_gpio_request_enable(struct pinctrl_dev *pctldev,
  198. struct pinctrl_gpio_range *range,
  199. unsigned int pin)
  200. {
  201. struct brcmstb_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
  202. return brcmstb_pinctrl_fsel_set(pc, pin, pc->func_gpio);
  203. }
  204. static void brcmstb_pmx_gpio_disable_free(struct pinctrl_dev *pctldev,
  205. struct pinctrl_gpio_range *range,
  206. unsigned int offset)
  207. {
  208. struct brcmstb_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
  209. /* disable by setting to GPIO */
  210. (void)brcmstb_pinctrl_fsel_set(pc, offset, pc->func_gpio);
  211. }
  212. static bool brcmstb_pmx_function_is_gpio(struct pinctrl_dev *pctldev,
  213. unsigned int selector)
  214. {
  215. struct brcmstb_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
  216. return pc->func_gpio == selector;
  217. }
  218. static const struct pinmux_ops brcmstb_pmx_ops = {
  219. .free = brcmstb_pmx_free,
  220. .get_functions_count = brcmstb_pmx_get_functions_count,
  221. .get_function_name = brcmstb_pmx_get_function_name,
  222. .get_function_groups = brcmstb_pmx_get_function_groups,
  223. .set_mux = brcmstb_pmx_set,
  224. .gpio_request_enable = brcmstb_pmx_gpio_request_enable,
  225. .gpio_disable_free = brcmstb_pmx_gpio_disable_free,
  226. .function_is_gpio = brcmstb_pmx_function_is_gpio,
  227. .strict = true,
  228. };
  229. static unsigned int brcmstb_pull_config_get(struct brcmstb_pinctrl *pc,
  230. unsigned int pin)
  231. {
  232. u32 bit = pc->pin_regs[pin].pad_bit, val;
  233. if (bit == PAD_BIT_INVALID)
  234. return BRCMSTB_PULL_NONE;
  235. val = readl(pc->base + BIT_TO_REG(bit));
  236. return (val >> BIT_TO_SHIFT(bit)) & BRCMSTB_PULL_MASK;
  237. }
  238. static int brcmstb_pull_config_set(struct brcmstb_pinctrl *pc,
  239. unsigned int pin, unsigned int arg)
  240. {
  241. u32 bit = pc->pin_regs[pin].pad_bit, val;
  242. if (bit == PAD_BIT_INVALID) {
  243. dev_warn(pc->dev, "Can't set pulls for %s\n",
  244. pc->gpio_groups[pin]);
  245. return -EINVAL;
  246. }
  247. guard(spinlock_irqsave)(&pc->fsel_lock);
  248. val = readl(pc->base + BIT_TO_REG(bit));
  249. val &= ~(BRCMSTB_PULL_MASK << BIT_TO_SHIFT(bit));
  250. val |= (arg << BIT_TO_SHIFT(bit));
  251. writel(val, pc->base + BIT_TO_REG(bit));
  252. return 0;
  253. }
  254. static int brcmstb_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
  255. unsigned long *config)
  256. {
  257. struct brcmstb_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
  258. enum pin_config_param param = pinconf_to_config_param(*config);
  259. u32 arg;
  260. switch (param) {
  261. case PIN_CONFIG_BIAS_DISABLE:
  262. arg = (brcmstb_pull_config_get(pc, pin) == BRCMSTB_PULL_NONE);
  263. break;
  264. case PIN_CONFIG_BIAS_PULL_DOWN:
  265. arg = (brcmstb_pull_config_get(pc, pin) == BRCMSTB_PULL_DOWN);
  266. break;
  267. case PIN_CONFIG_BIAS_PULL_UP:
  268. arg = (brcmstb_pull_config_get(pc, pin) == BRCMSTB_PULL_UP);
  269. break;
  270. default:
  271. return -ENOTSUPP;
  272. }
  273. *config = pinconf_to_config_packed(param, arg);
  274. return 0;
  275. }
  276. static int brcmstb_pinconf_set(struct pinctrl_dev *pctldev,
  277. unsigned int pin, unsigned long *configs,
  278. unsigned int num_configs)
  279. {
  280. struct brcmstb_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
  281. int ret = 0;
  282. u32 param;
  283. int i;
  284. for (i = 0; i < num_configs; i++) {
  285. param = pinconf_to_config_param(configs[i]);
  286. switch (param) {
  287. case PIN_CONFIG_BIAS_DISABLE:
  288. ret = brcmstb_pull_config_set(pc, pin, BRCMSTB_PULL_NONE);
  289. break;
  290. case PIN_CONFIG_BIAS_PULL_DOWN:
  291. ret = brcmstb_pull_config_set(pc, pin, BRCMSTB_PULL_DOWN);
  292. break;
  293. case PIN_CONFIG_BIAS_PULL_UP:
  294. ret = brcmstb_pull_config_set(pc, pin, BRCMSTB_PULL_UP);
  295. break;
  296. default:
  297. return -ENOTSUPP;
  298. }
  299. }
  300. return ret;
  301. }
  302. static const struct pinconf_ops brcmstb_pinconf_ops = {
  303. .is_generic = true,
  304. .pin_config_get = brcmstb_pinconf_get,
  305. .pin_config_set = brcmstb_pinconf_set,
  306. };
  307. int brcmstb_pinctrl_probe(struct platform_device *pdev)
  308. {
  309. struct device *dev = &pdev->dev;
  310. struct device_node *np = dev->of_node;
  311. const struct brcmstb_pdata *pdata;
  312. struct brcmstb_pinctrl *pc;
  313. const char **names;
  314. int num_pins, i;
  315. pdata = of_device_get_match_data(dev);
  316. pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL);
  317. if (!pc)
  318. return -ENOMEM;
  319. platform_set_drvdata(pdev, pc);
  320. pc->dev = dev;
  321. spin_lock_init(&pc->fsel_lock);
  322. pc->base = devm_of_iomap(dev, np, 0, NULL);
  323. if (IS_ERR(pc->base))
  324. return dev_err_probe(&pdev->dev, PTR_ERR(pc->base),
  325. "Could not get IO memory\n");
  326. pc->pctl_desc = *pdata->pctl_desc;
  327. pc->pctl_desc.pctlops = &brcmstb_pctl_ops;
  328. pc->pctl_desc.pmxops = &brcmstb_pmx_ops;
  329. pc->pctl_desc.confops = &brcmstb_pinconf_ops;
  330. pc->pctl_desc.owner = THIS_MODULE;
  331. num_pins = pc->pctl_desc.npins;
  332. names = devm_kmalloc_array(dev, num_pins, sizeof(const char *),
  333. GFP_KERNEL);
  334. if (!names)
  335. return -ENOMEM;
  336. for (i = 0; i < num_pins; i++)
  337. names[i] = pc->pctl_desc.pins[i].name;
  338. pc->gpio_groups = names;
  339. pc->pin_regs = pdata->pin_regs;
  340. pc->pin_funcs = pdata->pin_funcs;
  341. pc->func_count = pdata->func_count;
  342. pc->func_names = pdata->func_names;
  343. pc->pctl_dev = devm_pinctrl_register(dev, &pc->pctl_desc, pc);
  344. if (IS_ERR(pc->pctl_dev))
  345. return dev_err_probe(&pdev->dev, PTR_ERR(pc->pctl_dev),
  346. "Failed to register pinctrl device\n");
  347. pc->gpio_range = *pdata->gpio_range;
  348. pinctrl_add_gpio_range(pc->pctl_dev, &pc->gpio_range);
  349. return 0;
  350. }
  351. EXPORT_SYMBOL(brcmstb_pinctrl_probe);
  352. MODULE_AUTHOR("Phil Elwell");
  353. MODULE_AUTHOR("Jonathan Bell");
  354. MODULE_AUTHOR("Ivan T. Ivanov");
  355. MODULE_AUTHOR("Andrea della Porta");
  356. MODULE_DESCRIPTION("Broadcom brcmstb pinctrl driver");
  357. MODULE_LICENSE("GPL");