msm-cdc-pinctrl.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
  3. */
  4. #include <linux/kernel.h>
  5. #include <linux/init.h>
  6. #include <linux/err.h>
  7. #include <linux/module.h>
  8. #include <linux/of.h>
  9. #include <linux/of_device.h>
  10. #include <linux/platform_device.h>
  11. #include <linux/gpio.h>
  12. #include <linux/of_gpio.h>
  13. #include <linux/pinctrl/qcom-pinctrl.h>
  14. #include <asoc/msm-cdc-pinctrl.h>
  15. #define MAX_GPIOS 16
  16. struct msm_cdc_pinctrl_info {
  17. struct pinctrl *pinctrl;
  18. struct pinctrl_state *pinctrl_active;
  19. struct pinctrl_state *pinctrl_sleep;
  20. int gpio;
  21. bool state;
  22. u32 tlmm_gpio[MAX_GPIOS];
  23. u32 count;
  24. bool wakeup_capable;
  25. };
  26. static struct msm_cdc_pinctrl_info *msm_cdc_pinctrl_get_gpiodata(
  27. struct device_node *np)
  28. {
  29. struct platform_device *pdev;
  30. struct msm_cdc_pinctrl_info *gpio_data;
  31. if (!np) {
  32. pr_err("%s: device node is null\n", __func__);
  33. return NULL;
  34. }
  35. pdev = of_find_device_by_node(np);
  36. if (!pdev) {
  37. pr_err("%s: platform device not found!\n", __func__);
  38. return NULL;
  39. }
  40. gpio_data = dev_get_drvdata(&pdev->dev);
  41. if (!gpio_data)
  42. dev_err(&pdev->dev, "%s: cannot find cdc gpio info\n",
  43. __func__);
  44. return gpio_data;
  45. }
  46. /*
  47. * msm_cdc_get_gpio_state: select pinctrl sleep state
  48. * @np: pointer to struct device_node
  49. *
  50. * Returns error code for failure and GPIO value on success
  51. */
  52. int msm_cdc_get_gpio_state(struct device_node *np)
  53. {
  54. struct msm_cdc_pinctrl_info *gpio_data;
  55. int value = -EINVAL;
  56. gpio_data = msm_cdc_pinctrl_get_gpiodata(np);
  57. if (!gpio_data)
  58. return value;
  59. if (gpio_is_valid(gpio_data->gpio))
  60. value = gpio_get_value_cansleep(gpio_data->gpio);
  61. return value;
  62. }
  63. EXPORT_SYMBOL(msm_cdc_get_gpio_state);
  64. /*
  65. * msm_cdc_pinctrl_select_sleep_state: select pinctrl sleep state
  66. * @np: pointer to struct device_node
  67. *
  68. * Returns error code for failure
  69. */
  70. int msm_cdc_pinctrl_select_sleep_state(struct device_node *np)
  71. {
  72. struct msm_cdc_pinctrl_info *gpio_data;
  73. gpio_data = msm_cdc_pinctrl_get_gpiodata(np);
  74. if (!gpio_data)
  75. return -EINVAL;
  76. if (!gpio_data->pinctrl_sleep) {
  77. pr_err("%s: pinctrl sleep state is null\n", __func__);
  78. return -EINVAL;
  79. }
  80. gpio_data->state = false;
  81. return pinctrl_select_state(gpio_data->pinctrl,
  82. gpio_data->pinctrl_sleep);
  83. }
  84. EXPORT_SYMBOL(msm_cdc_pinctrl_select_sleep_state);
  85. /*
  86. * msm_cdc_pinctrl_select_active_state: select pinctrl active state
  87. * @np: pointer to struct device_node
  88. *
  89. * Returns error code for failure
  90. */
  91. int msm_cdc_pinctrl_select_active_state(struct device_node *np)
  92. {
  93. struct msm_cdc_pinctrl_info *gpio_data;
  94. gpio_data = msm_cdc_pinctrl_get_gpiodata(np);
  95. if (!gpio_data)
  96. return -EINVAL;
  97. if (!gpio_data->pinctrl_active) {
  98. pr_err("%s: pinctrl active state is null\n", __func__);
  99. return -EINVAL;
  100. }
  101. gpio_data->state = true;
  102. return pinctrl_select_state(gpio_data->pinctrl,
  103. gpio_data->pinctrl_active);
  104. }
  105. EXPORT_SYMBOL(msm_cdc_pinctrl_select_active_state);
  106. /*
  107. * msm_cdc_pinctrl_get_state: get curren pinctrl state
  108. * @np: pointer to struct device_node
  109. *
  110. * Returns 0 for sleep state, 1 for active state,
  111. * error code for failure
  112. */
  113. int msm_cdc_pinctrl_get_state(struct device_node *np)
  114. {
  115. struct msm_cdc_pinctrl_info *gpio_data;
  116. gpio_data = msm_cdc_pinctrl_get_gpiodata(np);
  117. if (!gpio_data)
  118. return -EINVAL;
  119. return gpio_data->state;
  120. }
  121. EXPORT_SYMBOL(msm_cdc_pinctrl_get_state);
  122. /*
  123. * msm_cdc_pinctrl_set_wakeup_capable: Set a pinctrl to wakeup capable
  124. * @np: pointer to struct device_node
  125. * @enable: wakeup capable when set to true
  126. *
  127. * Returns 0 for success and error code for failure
  128. */
  129. int msm_cdc_pinctrl_set_wakeup_capable(struct device_node *np, bool enable)
  130. {
  131. struct msm_cdc_pinctrl_info *gpio_data;
  132. int ret = 0;
  133. u32 i = 0;
  134. gpio_data = msm_cdc_pinctrl_get_gpiodata(np);
  135. if (!gpio_data)
  136. return -EINVAL;
  137. if (gpio_data->wakeup_capable) {
  138. for (i = 0; i < gpio_data->count; i++) {
  139. ret = msm_gpio_mpm_wake_set(gpio_data->tlmm_gpio[i],
  140. enable);
  141. if (ret < 0)
  142. goto exit;
  143. }
  144. }
  145. exit:
  146. return ret;
  147. }
  148. EXPORT_SYMBOL(msm_cdc_pinctrl_set_wakeup_capable);
  149. static int msm_cdc_pinctrl_probe(struct platform_device *pdev)
  150. {
  151. int ret = 0;
  152. struct msm_cdc_pinctrl_info *gpio_data;
  153. u32 tlmm_gpio[MAX_GPIOS] = {0};
  154. u32 i = 0;
  155. int count = 0;
  156. gpio_data = devm_kzalloc(&pdev->dev,
  157. sizeof(struct msm_cdc_pinctrl_info),
  158. GFP_KERNEL);
  159. if (!gpio_data)
  160. return -ENOMEM;
  161. gpio_data->pinctrl = devm_pinctrl_get(&pdev->dev);
  162. if (IS_ERR_OR_NULL(gpio_data->pinctrl)) {
  163. dev_err(&pdev->dev, "%s: Cannot get cdc gpio pinctrl:%ld\n",
  164. __func__, PTR_ERR(gpio_data->pinctrl));
  165. ret = PTR_ERR(gpio_data->pinctrl);
  166. goto err_pctrl_get;
  167. }
  168. gpio_data->pinctrl_active = pinctrl_lookup_state(
  169. gpio_data->pinctrl, "aud_active");
  170. if (IS_ERR_OR_NULL(gpio_data->pinctrl_active)) {
  171. dev_err(&pdev->dev, "%s: Cannot get aud_active pinctrl state:%ld\n",
  172. __func__, PTR_ERR(gpio_data->pinctrl_active));
  173. ret = PTR_ERR(gpio_data->pinctrl_active);
  174. goto err_lookup_state;
  175. }
  176. gpio_data->pinctrl_sleep = pinctrl_lookup_state(
  177. gpio_data->pinctrl, "aud_sleep");
  178. if (IS_ERR_OR_NULL(gpio_data->pinctrl_sleep)) {
  179. dev_err(&pdev->dev, "%s: Cannot get aud_sleep pinctrl state:%ld\n",
  180. __func__, PTR_ERR(gpio_data->pinctrl_sleep));
  181. ret = PTR_ERR(gpio_data->pinctrl_sleep);
  182. goto err_lookup_state;
  183. }
  184. /* skip setting to sleep state for LPI_TLMM GPIOs */
  185. if (!of_property_read_bool(pdev->dev.of_node, "qcom,lpi-gpios")) {
  186. /* Set pinctrl state to aud_sleep by default */
  187. ret = pinctrl_select_state(gpio_data->pinctrl,
  188. gpio_data->pinctrl_sleep);
  189. if (ret)
  190. dev_err(&pdev->dev, "%s: set cdc gpio sleep state fail: %d\n",
  191. __func__, ret);
  192. }
  193. count = of_property_count_u32_elems(pdev->dev.of_node, "qcom,tlmm-gpio");
  194. if (count <= 0)
  195. goto cdc_rst;
  196. if (!of_property_read_u32_array(pdev->dev.of_node, "qcom,tlmm-gpio",
  197. tlmm_gpio, count)) {
  198. gpio_data->wakeup_capable = true;
  199. for (i = 0; i < count; i++)
  200. gpio_data->tlmm_gpio[i] = tlmm_gpio[i];
  201. gpio_data->count = count;
  202. }
  203. cdc_rst:
  204. gpio_data->gpio = of_get_named_gpio(pdev->dev.of_node,
  205. "qcom,cdc-rst-n-gpio", 0);
  206. if (gpio_is_valid(gpio_data->gpio)) {
  207. ret = gpio_request(gpio_data->gpio, "MSM_CDC_RESET");
  208. if (ret) {
  209. dev_err(&pdev->dev, "%s: Failed to request gpio %d\n",
  210. __func__, gpio_data->gpio);
  211. goto err_lookup_state;
  212. }
  213. }
  214. dev_set_drvdata(&pdev->dev, gpio_data);
  215. return 0;
  216. err_lookup_state:
  217. devm_pinctrl_put(gpio_data->pinctrl);
  218. err_pctrl_get:
  219. devm_kfree(&pdev->dev, gpio_data);
  220. return ret;
  221. }
  222. static int msm_cdc_pinctrl_remove(struct platform_device *pdev)
  223. {
  224. struct msm_cdc_pinctrl_info *gpio_data;
  225. gpio_data = dev_get_drvdata(&pdev->dev);
  226. /* to free the requested gpio before exiting */
  227. if (gpio_data) {
  228. if (gpio_is_valid(gpio_data->gpio))
  229. gpio_free(gpio_data->gpio);
  230. if (gpio_data->pinctrl)
  231. devm_pinctrl_put(gpio_data->pinctrl);
  232. }
  233. devm_kfree(&pdev->dev, gpio_data);
  234. return 0;
  235. }
  236. static const struct of_device_id msm_cdc_pinctrl_match[] = {
  237. {.compatible = "qcom,msm-cdc-pinctrl"},
  238. {}
  239. };
  240. static struct platform_driver msm_cdc_pinctrl_driver = {
  241. .driver = {
  242. .name = "msm-cdc-pinctrl",
  243. .owner = THIS_MODULE,
  244. .of_match_table = msm_cdc_pinctrl_match,
  245. .suppress_bind_attrs = true,
  246. },
  247. .probe = msm_cdc_pinctrl_probe,
  248. .remove = msm_cdc_pinctrl_remove,
  249. };
  250. int msm_cdc_pinctrl_drv_init(void)
  251. {
  252. return platform_driver_register(&msm_cdc_pinctrl_driver);
  253. }
  254. void msm_cdc_pinctrl_drv_exit(void)
  255. {
  256. platform_driver_unregister(&msm_cdc_pinctrl_driver);
  257. }
  258. MODULE_DESCRIPTION("MSM CODEC pin control platform driver");
  259. MODULE_LICENSE("GPL v2");