pinctrl-uniphier-core.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694
  1. /*
  2. * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. */
  14. #include <linux/export.h>
  15. #include <linux/mfd/syscon.h>
  16. #include <linux/pinctrl/pinconf.h>
  17. #include <linux/pinctrl/pinconf-generic.h>
  18. #include <linux/pinctrl/pinctrl.h>
  19. #include <linux/pinctrl/pinmux.h>
  20. #include <linux/platform_device.h>
  21. #include <linux/regmap.h>
  22. #include "../core.h"
  23. #include "../pinctrl-utils.h"
  24. #include "pinctrl-uniphier.h"
  25. struct uniphier_pinctrl_priv {
  26. struct pinctrl_dev *pctldev;
  27. struct regmap *regmap;
  28. struct uniphier_pinctrl_socdata *socdata;
  29. };
  30. static int uniphier_pctl_get_groups_count(struct pinctrl_dev *pctldev)
  31. {
  32. struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
  33. return priv->socdata->groups_count;
  34. }
  35. static const char *uniphier_pctl_get_group_name(struct pinctrl_dev *pctldev,
  36. unsigned selector)
  37. {
  38. struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
  39. return priv->socdata->groups[selector].name;
  40. }
  41. static int uniphier_pctl_get_group_pins(struct pinctrl_dev *pctldev,
  42. unsigned selector,
  43. const unsigned **pins,
  44. unsigned *num_pins)
  45. {
  46. struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
  47. *pins = priv->socdata->groups[selector].pins;
  48. *num_pins = priv->socdata->groups[selector].num_pins;
  49. return 0;
  50. }
  51. #ifdef CONFIG_DEBUG_FS
  52. static void uniphier_pctl_pin_dbg_show(struct pinctrl_dev *pctldev,
  53. struct seq_file *s, unsigned offset)
  54. {
  55. const struct pinctrl_pin_desc *pin = &pctldev->desc->pins[offset];
  56. const char *pull_dir, *drv_str;
  57. switch (uniphier_pin_get_pull_dir(pin->drv_data)) {
  58. case UNIPHIER_PIN_PULL_UP:
  59. pull_dir = "UP";
  60. break;
  61. case UNIPHIER_PIN_PULL_DOWN:
  62. pull_dir = "DOWN";
  63. break;
  64. case UNIPHIER_PIN_PULL_UP_FIXED:
  65. pull_dir = "UP(FIXED)";
  66. break;
  67. case UNIPHIER_PIN_PULL_DOWN_FIXED:
  68. pull_dir = "DOWN(FIXED)";
  69. break;
  70. case UNIPHIER_PIN_PULL_NONE:
  71. pull_dir = "NONE";
  72. break;
  73. default:
  74. BUG();
  75. }
  76. switch (uniphier_pin_get_drv_str(pin->drv_data)) {
  77. case UNIPHIER_PIN_DRV_4_8:
  78. drv_str = "4/8(mA)";
  79. break;
  80. case UNIPHIER_PIN_DRV_8_12_16_20:
  81. drv_str = "8/12/16/20(mA)";
  82. break;
  83. case UNIPHIER_PIN_DRV_FIXED_4:
  84. drv_str = "4(mA)";
  85. break;
  86. case UNIPHIER_PIN_DRV_FIXED_5:
  87. drv_str = "5(mA)";
  88. break;
  89. case UNIPHIER_PIN_DRV_FIXED_8:
  90. drv_str = "8(mA)";
  91. break;
  92. case UNIPHIER_PIN_DRV_NONE:
  93. drv_str = "NONE";
  94. break;
  95. default:
  96. BUG();
  97. }
  98. seq_printf(s, " PULL_DIR=%s DRV_STR=%s", pull_dir, drv_str);
  99. }
  100. #endif
  101. static const struct pinctrl_ops uniphier_pctlops = {
  102. .get_groups_count = uniphier_pctl_get_groups_count,
  103. .get_group_name = uniphier_pctl_get_group_name,
  104. .get_group_pins = uniphier_pctl_get_group_pins,
  105. #ifdef CONFIG_DEBUG_FS
  106. .pin_dbg_show = uniphier_pctl_pin_dbg_show,
  107. #endif
  108. .dt_node_to_map = pinconf_generic_dt_node_to_map_all,
  109. .dt_free_map = pinctrl_utils_dt_free_map,
  110. };
  111. static int uniphier_conf_pin_bias_get(struct pinctrl_dev *pctldev,
  112. const struct pinctrl_pin_desc *pin,
  113. enum pin_config_param param)
  114. {
  115. struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
  116. enum uniphier_pin_pull_dir pull_dir =
  117. uniphier_pin_get_pull_dir(pin->drv_data);
  118. unsigned int pupdctrl, reg, shift, val;
  119. unsigned int expected = 1;
  120. int ret;
  121. switch (param) {
  122. case PIN_CONFIG_BIAS_DISABLE:
  123. if (pull_dir == UNIPHIER_PIN_PULL_NONE)
  124. return 0;
  125. if (pull_dir == UNIPHIER_PIN_PULL_UP_FIXED ||
  126. pull_dir == UNIPHIER_PIN_PULL_DOWN_FIXED)
  127. return -EINVAL;
  128. expected = 0;
  129. break;
  130. case PIN_CONFIG_BIAS_PULL_UP:
  131. if (pull_dir == UNIPHIER_PIN_PULL_UP_FIXED)
  132. return 0;
  133. if (pull_dir != UNIPHIER_PIN_PULL_UP)
  134. return -EINVAL;
  135. break;
  136. case PIN_CONFIG_BIAS_PULL_DOWN:
  137. if (pull_dir == UNIPHIER_PIN_PULL_DOWN_FIXED)
  138. return 0;
  139. if (pull_dir != UNIPHIER_PIN_PULL_DOWN)
  140. return -EINVAL;
  141. break;
  142. default:
  143. BUG();
  144. }
  145. pupdctrl = uniphier_pin_get_pupdctrl(pin->drv_data);
  146. reg = UNIPHIER_PINCTRL_PUPDCTRL_BASE + pupdctrl / 32 * 4;
  147. shift = pupdctrl % 32;
  148. ret = regmap_read(priv->regmap, reg, &val);
  149. if (ret)
  150. return ret;
  151. val = (val >> shift) & 1;
  152. return (val == expected) ? 0 : -EINVAL;
  153. }
  154. static int uniphier_conf_pin_drive_get(struct pinctrl_dev *pctldev,
  155. const struct pinctrl_pin_desc *pin,
  156. u16 *strength)
  157. {
  158. struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
  159. enum uniphier_pin_drv_str drv_str =
  160. uniphier_pin_get_drv_str(pin->drv_data);
  161. const unsigned int strength_4_8[] = {4, 8};
  162. const unsigned int strength_8_12_16_20[] = {8, 12, 16, 20};
  163. const unsigned int *supported_strength;
  164. unsigned int drvctrl, reg, shift, mask, width, val;
  165. int ret;
  166. switch (drv_str) {
  167. case UNIPHIER_PIN_DRV_4_8:
  168. supported_strength = strength_4_8;
  169. width = 1;
  170. break;
  171. case UNIPHIER_PIN_DRV_8_12_16_20:
  172. supported_strength = strength_8_12_16_20;
  173. width = 2;
  174. break;
  175. case UNIPHIER_PIN_DRV_FIXED_4:
  176. *strength = 4;
  177. return 0;
  178. case UNIPHIER_PIN_DRV_FIXED_5:
  179. *strength = 5;
  180. return 0;
  181. case UNIPHIER_PIN_DRV_FIXED_8:
  182. *strength = 8;
  183. return 0;
  184. default:
  185. /* drive strength control is not supported for this pin */
  186. return -EINVAL;
  187. }
  188. drvctrl = uniphier_pin_get_drvctrl(pin->drv_data);
  189. drvctrl *= width;
  190. reg = (width == 2) ? UNIPHIER_PINCTRL_DRV2CTRL_BASE :
  191. UNIPHIER_PINCTRL_DRVCTRL_BASE;
  192. reg += drvctrl / 32 * 4;
  193. shift = drvctrl % 32;
  194. mask = (1U << width) - 1;
  195. ret = regmap_read(priv->regmap, reg, &val);
  196. if (ret)
  197. return ret;
  198. *strength = supported_strength[(val >> shift) & mask];
  199. return 0;
  200. }
  201. static int uniphier_conf_pin_input_enable_get(struct pinctrl_dev *pctldev,
  202. const struct pinctrl_pin_desc *pin)
  203. {
  204. struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
  205. unsigned int iectrl = uniphier_pin_get_iectrl(pin->drv_data);
  206. unsigned int val;
  207. int ret;
  208. if (iectrl == UNIPHIER_PIN_IECTRL_NONE)
  209. /* This pin is always input-enabled. */
  210. return 0;
  211. ret = regmap_read(priv->regmap, UNIPHIER_PINCTRL_IECTRL, &val);
  212. if (ret)
  213. return ret;
  214. return val & BIT(iectrl) ? 0 : -EINVAL;
  215. }
  216. static int uniphier_conf_pin_config_get(struct pinctrl_dev *pctldev,
  217. unsigned pin,
  218. unsigned long *configs)
  219. {
  220. const struct pinctrl_pin_desc *pin_desc = &pctldev->desc->pins[pin];
  221. enum pin_config_param param = pinconf_to_config_param(*configs);
  222. bool has_arg = false;
  223. u16 arg;
  224. int ret;
  225. switch (param) {
  226. case PIN_CONFIG_BIAS_DISABLE:
  227. case PIN_CONFIG_BIAS_PULL_UP:
  228. case PIN_CONFIG_BIAS_PULL_DOWN:
  229. ret = uniphier_conf_pin_bias_get(pctldev, pin_desc, param);
  230. break;
  231. case PIN_CONFIG_DRIVE_STRENGTH:
  232. ret = uniphier_conf_pin_drive_get(pctldev, pin_desc, &arg);
  233. has_arg = true;
  234. break;
  235. case PIN_CONFIG_INPUT_ENABLE:
  236. ret = uniphier_conf_pin_input_enable_get(pctldev, pin_desc);
  237. break;
  238. default:
  239. /* unsupported parameter */
  240. ret = -EINVAL;
  241. break;
  242. }
  243. if (ret == 0 && has_arg)
  244. *configs = pinconf_to_config_packed(param, arg);
  245. return ret;
  246. }
  247. static int uniphier_conf_pin_bias_set(struct pinctrl_dev *pctldev,
  248. const struct pinctrl_pin_desc *pin,
  249. enum pin_config_param param,
  250. u16 arg)
  251. {
  252. struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
  253. enum uniphier_pin_pull_dir pull_dir =
  254. uniphier_pin_get_pull_dir(pin->drv_data);
  255. unsigned int pupdctrl, reg, shift;
  256. unsigned int val = 1;
  257. switch (param) {
  258. case PIN_CONFIG_BIAS_DISABLE:
  259. if (pull_dir == UNIPHIER_PIN_PULL_NONE)
  260. return 0;
  261. if (pull_dir == UNIPHIER_PIN_PULL_UP_FIXED ||
  262. pull_dir == UNIPHIER_PIN_PULL_DOWN_FIXED) {
  263. dev_err(pctldev->dev,
  264. "can not disable pull register for pin %u (%s)\n",
  265. pin->number, pin->name);
  266. return -EINVAL;
  267. }
  268. val = 0;
  269. break;
  270. case PIN_CONFIG_BIAS_PULL_UP:
  271. if (pull_dir == UNIPHIER_PIN_PULL_UP_FIXED && arg != 0)
  272. return 0;
  273. if (pull_dir != UNIPHIER_PIN_PULL_UP) {
  274. dev_err(pctldev->dev,
  275. "pull-up is unsupported for pin %u (%s)\n",
  276. pin->number, pin->name);
  277. return -EINVAL;
  278. }
  279. if (arg == 0) {
  280. dev_err(pctldev->dev, "pull-up can not be total\n");
  281. return -EINVAL;
  282. }
  283. break;
  284. case PIN_CONFIG_BIAS_PULL_DOWN:
  285. if (pull_dir == UNIPHIER_PIN_PULL_DOWN_FIXED && arg != 0)
  286. return 0;
  287. if (pull_dir != UNIPHIER_PIN_PULL_DOWN) {
  288. dev_err(pctldev->dev,
  289. "pull-down is unsupported for pin %u (%s)\n",
  290. pin->number, pin->name);
  291. return -EINVAL;
  292. }
  293. if (arg == 0) {
  294. dev_err(pctldev->dev, "pull-down can not be total\n");
  295. return -EINVAL;
  296. }
  297. break;
  298. case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
  299. if (pull_dir == UNIPHIER_PIN_PULL_NONE) {
  300. dev_err(pctldev->dev,
  301. "pull-up/down is unsupported for pin %u (%s)\n",
  302. pin->number, pin->name);
  303. return -EINVAL;
  304. }
  305. if (arg == 0)
  306. return 0; /* configuration ingored */
  307. break;
  308. default:
  309. BUG();
  310. }
  311. pupdctrl = uniphier_pin_get_pupdctrl(pin->drv_data);
  312. reg = UNIPHIER_PINCTRL_PUPDCTRL_BASE + pupdctrl / 32 * 4;
  313. shift = pupdctrl % 32;
  314. return regmap_update_bits(priv->regmap, reg, 1 << shift, val << shift);
  315. }
  316. static int uniphier_conf_pin_drive_set(struct pinctrl_dev *pctldev,
  317. const struct pinctrl_pin_desc *pin,
  318. u16 strength)
  319. {
  320. struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
  321. enum uniphier_pin_drv_str drv_str =
  322. uniphier_pin_get_drv_str(pin->drv_data);
  323. const unsigned int strength_4_8[] = {4, 8, -1};
  324. const unsigned int strength_8_12_16_20[] = {8, 12, 16, 20, -1};
  325. const unsigned int *supported_strength;
  326. unsigned int drvctrl, reg, shift, mask, width, val;
  327. switch (drv_str) {
  328. case UNIPHIER_PIN_DRV_4_8:
  329. supported_strength = strength_4_8;
  330. width = 1;
  331. break;
  332. case UNIPHIER_PIN_DRV_8_12_16_20:
  333. supported_strength = strength_8_12_16_20;
  334. width = 2;
  335. break;
  336. default:
  337. dev_err(pctldev->dev,
  338. "cannot change drive strength for pin %u (%s)\n",
  339. pin->number, pin->name);
  340. return -EINVAL;
  341. }
  342. for (val = 0; supported_strength[val] > 0; val++) {
  343. if (supported_strength[val] > strength)
  344. break;
  345. }
  346. if (val == 0) {
  347. dev_err(pctldev->dev,
  348. "unsupported drive strength %u mA for pin %u (%s)\n",
  349. strength, pin->number, pin->name);
  350. return -EINVAL;
  351. }
  352. val--;
  353. drvctrl = uniphier_pin_get_drvctrl(pin->drv_data);
  354. drvctrl *= width;
  355. reg = (width == 2) ? UNIPHIER_PINCTRL_DRV2CTRL_BASE :
  356. UNIPHIER_PINCTRL_DRVCTRL_BASE;
  357. reg += drvctrl / 32 * 4;
  358. shift = drvctrl % 32;
  359. mask = (1U << width) - 1;
  360. return regmap_update_bits(priv->regmap, reg,
  361. mask << shift, val << shift);
  362. }
  363. static int uniphier_conf_pin_input_enable(struct pinctrl_dev *pctldev,
  364. const struct pinctrl_pin_desc *pin,
  365. u16 enable)
  366. {
  367. struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
  368. unsigned int iectrl = uniphier_pin_get_iectrl(pin->drv_data);
  369. if (enable == 0) {
  370. /*
  371. * Multiple pins share one input enable, so per-pin disabling
  372. * is impossible.
  373. */
  374. dev_err(pctldev->dev, "unable to disable input\n");
  375. return -EINVAL;
  376. }
  377. if (iectrl == UNIPHIER_PIN_IECTRL_NONE)
  378. /* This pin is always input-enabled. nothing to do. */
  379. return 0;
  380. return regmap_update_bits(priv->regmap, UNIPHIER_PINCTRL_IECTRL,
  381. BIT(iectrl), BIT(iectrl));
  382. }
  383. static int uniphier_conf_pin_config_set(struct pinctrl_dev *pctldev,
  384. unsigned pin,
  385. unsigned long *configs,
  386. unsigned num_configs)
  387. {
  388. const struct pinctrl_pin_desc *pin_desc = &pctldev->desc->pins[pin];
  389. int i, ret;
  390. for (i = 0; i < num_configs; i++) {
  391. enum pin_config_param param =
  392. pinconf_to_config_param(configs[i]);
  393. u16 arg = pinconf_to_config_argument(configs[i]);
  394. switch (param) {
  395. case PIN_CONFIG_BIAS_DISABLE:
  396. case PIN_CONFIG_BIAS_PULL_UP:
  397. case PIN_CONFIG_BIAS_PULL_DOWN:
  398. case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
  399. ret = uniphier_conf_pin_bias_set(pctldev, pin_desc,
  400. param, arg);
  401. break;
  402. case PIN_CONFIG_DRIVE_STRENGTH:
  403. ret = uniphier_conf_pin_drive_set(pctldev, pin_desc,
  404. arg);
  405. break;
  406. case PIN_CONFIG_INPUT_ENABLE:
  407. ret = uniphier_conf_pin_input_enable(pctldev,
  408. pin_desc, arg);
  409. break;
  410. default:
  411. dev_err(pctldev->dev,
  412. "unsupported configuration parameter %u\n",
  413. param);
  414. return -EINVAL;
  415. }
  416. if (ret)
  417. return ret;
  418. }
  419. return 0;
  420. }
  421. static int uniphier_conf_pin_config_group_set(struct pinctrl_dev *pctldev,
  422. unsigned selector,
  423. unsigned long *configs,
  424. unsigned num_configs)
  425. {
  426. struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
  427. const unsigned *pins = priv->socdata->groups[selector].pins;
  428. unsigned num_pins = priv->socdata->groups[selector].num_pins;
  429. int i, ret;
  430. for (i = 0; i < num_pins; i++) {
  431. ret = uniphier_conf_pin_config_set(pctldev, pins[i],
  432. configs, num_configs);
  433. if (ret)
  434. return ret;
  435. }
  436. return 0;
  437. }
  438. static const struct pinconf_ops uniphier_confops = {
  439. .is_generic = true,
  440. .pin_config_get = uniphier_conf_pin_config_get,
  441. .pin_config_set = uniphier_conf_pin_config_set,
  442. .pin_config_group_set = uniphier_conf_pin_config_group_set,
  443. };
  444. static int uniphier_pmx_get_functions_count(struct pinctrl_dev *pctldev)
  445. {
  446. struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
  447. return priv->socdata->functions_count;
  448. }
  449. static const char *uniphier_pmx_get_function_name(struct pinctrl_dev *pctldev,
  450. unsigned selector)
  451. {
  452. struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
  453. return priv->socdata->functions[selector].name;
  454. }
  455. static int uniphier_pmx_get_function_groups(struct pinctrl_dev *pctldev,
  456. unsigned selector,
  457. const char * const **groups,
  458. unsigned *num_groups)
  459. {
  460. struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
  461. *groups = priv->socdata->functions[selector].groups;
  462. *num_groups = priv->socdata->functions[selector].num_groups;
  463. return 0;
  464. }
  465. static int uniphier_pmx_set_one_mux(struct pinctrl_dev *pctldev, unsigned pin,
  466. unsigned muxval)
  467. {
  468. struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
  469. unsigned mux_bits = priv->socdata->mux_bits;
  470. unsigned reg_stride = priv->socdata->reg_stride;
  471. unsigned reg, reg_end, shift, mask;
  472. int ret;
  473. /* some pins need input-enabling */
  474. ret = uniphier_conf_pin_input_enable(pctldev,
  475. &pctldev->desc->pins[pin], 1);
  476. if (ret)
  477. return ret;
  478. reg = UNIPHIER_PINCTRL_PINMUX_BASE + pin * mux_bits / 32 * reg_stride;
  479. reg_end = reg + reg_stride;
  480. shift = pin * mux_bits % 32;
  481. mask = (1U << mux_bits) - 1;
  482. /*
  483. * If reg_stride is greater than 4, the MSB of each pinsel shall be
  484. * stored in the offset+4.
  485. */
  486. for (; reg < reg_end; reg += 4) {
  487. ret = regmap_update_bits(priv->regmap, reg,
  488. mask << shift, muxval << shift);
  489. if (ret)
  490. return ret;
  491. muxval >>= mux_bits;
  492. }
  493. if (priv->socdata->load_pinctrl) {
  494. ret = regmap_write(priv->regmap,
  495. UNIPHIER_PINCTRL_LOAD_PINMUX, 1);
  496. if (ret)
  497. return ret;
  498. }
  499. return 0;
  500. }
  501. static int uniphier_pmx_set_mux(struct pinctrl_dev *pctldev,
  502. unsigned func_selector,
  503. unsigned group_selector)
  504. {
  505. struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
  506. const struct uniphier_pinctrl_group *grp =
  507. &priv->socdata->groups[group_selector];
  508. int i;
  509. int ret;
  510. for (i = 0; i < grp->num_pins; i++) {
  511. ret = uniphier_pmx_set_one_mux(pctldev, grp->pins[i],
  512. grp->muxvals[i]);
  513. if (ret)
  514. return ret;
  515. }
  516. return 0;
  517. }
  518. static int uniphier_pmx_gpio_request_enable(struct pinctrl_dev *pctldev,
  519. struct pinctrl_gpio_range *range,
  520. unsigned offset)
  521. {
  522. struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
  523. const struct uniphier_pinctrl_group *groups = priv->socdata->groups;
  524. int groups_count = priv->socdata->groups_count;
  525. enum uniphier_pinmux_gpio_range_type range_type;
  526. int i, j;
  527. if (strstr(range->name, "irq"))
  528. range_type = UNIPHIER_PINMUX_GPIO_RANGE_IRQ;
  529. else
  530. range_type = UNIPHIER_PINMUX_GPIO_RANGE_PORT;
  531. for (i = 0; i < groups_count; i++) {
  532. if (groups[i].range_type != range_type)
  533. continue;
  534. for (j = 0; j < groups[i].num_pins; j++)
  535. if (groups[i].pins[j] == offset)
  536. goto found;
  537. }
  538. dev_err(pctldev->dev, "pin %u does not support GPIO\n", offset);
  539. return -EINVAL;
  540. found:
  541. return uniphier_pmx_set_one_mux(pctldev, offset, groups[i].muxvals[j]);
  542. }
  543. static const struct pinmux_ops uniphier_pmxops = {
  544. .get_functions_count = uniphier_pmx_get_functions_count,
  545. .get_function_name = uniphier_pmx_get_function_name,
  546. .get_function_groups = uniphier_pmx_get_function_groups,
  547. .set_mux = uniphier_pmx_set_mux,
  548. .gpio_request_enable = uniphier_pmx_gpio_request_enable,
  549. .strict = true,
  550. };
  551. int uniphier_pinctrl_probe(struct platform_device *pdev,
  552. struct pinctrl_desc *desc,
  553. struct uniphier_pinctrl_socdata *socdata)
  554. {
  555. struct device *dev = &pdev->dev;
  556. struct uniphier_pinctrl_priv *priv;
  557. if (!socdata ||
  558. !socdata->groups ||
  559. !socdata->groups_count ||
  560. !socdata->functions ||
  561. !socdata->functions_count ||
  562. !socdata->mux_bits ||
  563. !socdata->reg_stride) {
  564. dev_err(dev, "pinctrl socdata lacks necessary members\n");
  565. return -EINVAL;
  566. }
  567. priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
  568. if (!priv)
  569. return -ENOMEM;
  570. priv->regmap = syscon_node_to_regmap(dev->of_node);
  571. if (IS_ERR(priv->regmap)) {
  572. dev_err(dev, "failed to get regmap\n");
  573. return PTR_ERR(priv->regmap);
  574. }
  575. priv->socdata = socdata;
  576. desc->pctlops = &uniphier_pctlops;
  577. desc->pmxops = &uniphier_pmxops;
  578. desc->confops = &uniphier_confops;
  579. priv->pctldev = pinctrl_register(desc, dev, priv);
  580. if (IS_ERR(priv->pctldev)) {
  581. dev_err(dev, "failed to register UniPhier pinctrl driver\n");
  582. return PTR_ERR(priv->pctldev);
  583. }
  584. platform_set_drvdata(pdev, priv);
  585. return 0;
  586. }
  587. EXPORT_SYMBOL_GPL(uniphier_pinctrl_probe);
  588. int uniphier_pinctrl_remove(struct platform_device *pdev)
  589. {
  590. struct uniphier_pinctrl_priv *priv = platform_get_drvdata(pdev);
  591. pinctrl_unregister(priv->pctldev);
  592. return 0;
  593. }
  594. EXPORT_SYMBOL_GPL(uniphier_pinctrl_remove);