mt8186-afe-gpio.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. // SPDX-License-Identifier: GPL-2.0
  2. //
  3. // mt8186-afe-gpio.c -- Mediatek 8186 afe gpio ctrl
  4. //
  5. // Copyright (c) 2022 MediaTek Inc.
  6. // Author: Jiaxin Yu <[email protected]>
  7. #include <linux/gpio.h>
  8. #include <linux/pinctrl/consumer.h>
  9. #include "mt8186-afe-common.h"
  10. #include "mt8186-afe-gpio.h"
  11. struct pinctrl *aud_pinctrl;
  12. enum mt8186_afe_gpio {
  13. MT8186_AFE_GPIO_CLK_MOSI_OFF,
  14. MT8186_AFE_GPIO_CLK_MOSI_ON,
  15. MT8186_AFE_GPIO_CLK_MISO_OFF,
  16. MT8186_AFE_GPIO_CLK_MISO_ON,
  17. MT8186_AFE_GPIO_DAT_MISO_OFF,
  18. MT8186_AFE_GPIO_DAT_MISO_ON,
  19. MT8186_AFE_GPIO_DAT_MOSI_OFF,
  20. MT8186_AFE_GPIO_DAT_MOSI_ON,
  21. MT8186_AFE_GPIO_I2S0_OFF,
  22. MT8186_AFE_GPIO_I2S0_ON,
  23. MT8186_AFE_GPIO_I2S1_OFF,
  24. MT8186_AFE_GPIO_I2S1_ON,
  25. MT8186_AFE_GPIO_I2S2_OFF,
  26. MT8186_AFE_GPIO_I2S2_ON,
  27. MT8186_AFE_GPIO_I2S3_OFF,
  28. MT8186_AFE_GPIO_I2S3_ON,
  29. MT8186_AFE_GPIO_TDM_OFF,
  30. MT8186_AFE_GPIO_TDM_ON,
  31. MT8186_AFE_GPIO_PCM_OFF,
  32. MT8186_AFE_GPIO_PCM_ON,
  33. MT8186_AFE_GPIO_GPIO_NUM
  34. };
  35. struct audio_gpio_attr {
  36. const char *name;
  37. bool gpio_prepare;
  38. struct pinctrl_state *gpioctrl;
  39. };
  40. static struct audio_gpio_attr aud_gpios[MT8186_AFE_GPIO_GPIO_NUM] = {
  41. [MT8186_AFE_GPIO_CLK_MOSI_OFF] = {"aud_clk_mosi_off", false, NULL},
  42. [MT8186_AFE_GPIO_CLK_MOSI_ON] = {"aud_clk_mosi_on", false, NULL},
  43. [MT8186_AFE_GPIO_CLK_MISO_OFF] = {"aud_clk_miso_off", false, NULL},
  44. [MT8186_AFE_GPIO_CLK_MISO_ON] = {"aud_clk_miso_on", false, NULL},
  45. [MT8186_AFE_GPIO_DAT_MISO_OFF] = {"aud_dat_miso_off", false, NULL},
  46. [MT8186_AFE_GPIO_DAT_MISO_ON] = {"aud_dat_miso_on", false, NULL},
  47. [MT8186_AFE_GPIO_DAT_MOSI_OFF] = {"aud_dat_mosi_off", false, NULL},
  48. [MT8186_AFE_GPIO_DAT_MOSI_ON] = {"aud_dat_mosi_on", false, NULL},
  49. [MT8186_AFE_GPIO_I2S0_OFF] = {"aud_gpio_i2s0_off", false, NULL},
  50. [MT8186_AFE_GPIO_I2S0_ON] = {"aud_gpio_i2s0_on", false, NULL},
  51. [MT8186_AFE_GPIO_I2S1_OFF] = {"aud_gpio_i2s1_off", false, NULL},
  52. [MT8186_AFE_GPIO_I2S1_ON] = {"aud_gpio_i2s1_on", false, NULL},
  53. [MT8186_AFE_GPIO_I2S2_OFF] = {"aud_gpio_i2s2_off", false, NULL},
  54. [MT8186_AFE_GPIO_I2S2_ON] = {"aud_gpio_i2s2_on", false, NULL},
  55. [MT8186_AFE_GPIO_I2S3_OFF] = {"aud_gpio_i2s3_off", false, NULL},
  56. [MT8186_AFE_GPIO_I2S3_ON] = {"aud_gpio_i2s3_on", false, NULL},
  57. [MT8186_AFE_GPIO_TDM_OFF] = {"aud_gpio_tdm_off", false, NULL},
  58. [MT8186_AFE_GPIO_TDM_ON] = {"aud_gpio_tdm_on", false, NULL},
  59. [MT8186_AFE_GPIO_PCM_OFF] = {"aud_gpio_pcm_off", false, NULL},
  60. [MT8186_AFE_GPIO_PCM_ON] = {"aud_gpio_pcm_on", false, NULL},
  61. };
  62. static DEFINE_MUTEX(gpio_request_mutex);
  63. int mt8186_afe_gpio_init(struct device *dev)
  64. {
  65. int i, j, ret;
  66. aud_pinctrl = devm_pinctrl_get(dev);
  67. if (IS_ERR(aud_pinctrl)) {
  68. ret = PTR_ERR(aud_pinctrl);
  69. dev_err(dev, "%s(), ret %d, cannot get aud_pinctrl!\n",
  70. __func__, ret);
  71. return ret;
  72. }
  73. for (i = 0; i < ARRAY_SIZE(aud_gpios); i++) {
  74. aud_gpios[i].gpioctrl = pinctrl_lookup_state(aud_pinctrl,
  75. aud_gpios[i].name);
  76. if (IS_ERR(aud_gpios[i].gpioctrl)) {
  77. ret = PTR_ERR(aud_gpios[i].gpioctrl);
  78. dev_info(dev, "%s(), pinctrl_lookup_state %s fail, ret %d\n",
  79. __func__, aud_gpios[i].name, ret);
  80. } else {
  81. aud_gpios[i].gpio_prepare = true;
  82. }
  83. }
  84. /* gpio status init */
  85. for (i = MT8186_DAI_ADDA; i <= MT8186_DAI_TDM_IN; i++) {
  86. for (j = 0; j <= 1; j++)
  87. mt8186_afe_gpio_request(dev, false, i, j);
  88. }
  89. return 0;
  90. }
  91. EXPORT_SYMBOL_GPL(mt8186_afe_gpio_init);
  92. static int mt8186_afe_gpio_select(struct device *dev,
  93. enum mt8186_afe_gpio type)
  94. {
  95. int ret = 0;
  96. if (type < 0 || type >= MT8186_AFE_GPIO_GPIO_NUM) {
  97. dev_err(dev, "%s(), error, invalid gpio type %d\n",
  98. __func__, type);
  99. return -EINVAL;
  100. }
  101. if (!aud_gpios[type].gpio_prepare) {
  102. dev_err(dev, "%s(), error, gpio type %d not prepared\n",
  103. __func__, type);
  104. return -EIO;
  105. }
  106. ret = pinctrl_select_state(aud_pinctrl,
  107. aud_gpios[type].gpioctrl);
  108. if (ret) {
  109. dev_err(dev, "%s(), error, can not set gpio type %d\n",
  110. __func__, type);
  111. return ret;
  112. }
  113. return 0;
  114. }
  115. static int mt8186_afe_gpio_adda_dl(struct device *dev, bool enable)
  116. {
  117. int ret;
  118. if (enable) {
  119. ret = mt8186_afe_gpio_select(dev, MT8186_AFE_GPIO_CLK_MOSI_ON);
  120. if (ret) {
  121. dev_err(dev, "%s(), MOSI CLK ON select fail!\n", __func__);
  122. return ret;
  123. }
  124. ret = mt8186_afe_gpio_select(dev, MT8186_AFE_GPIO_DAT_MOSI_ON);
  125. if (ret) {
  126. dev_err(dev, "%s(), MOSI DAT ON select fail!\n", __func__);
  127. return ret;
  128. }
  129. } else {
  130. ret = mt8186_afe_gpio_select(dev, MT8186_AFE_GPIO_DAT_MOSI_OFF);
  131. if (ret) {
  132. dev_err(dev, "%s(), MOSI DAT OFF select fail!\n", __func__);
  133. return ret;
  134. }
  135. ret = mt8186_afe_gpio_select(dev, MT8186_AFE_GPIO_CLK_MOSI_OFF);
  136. if (ret) {
  137. dev_err(dev, "%s(), MOSI CLK ON select fail!\n", __func__);
  138. return ret;
  139. }
  140. }
  141. return 0;
  142. }
  143. static int mt8186_afe_gpio_adda_ul(struct device *dev, bool enable)
  144. {
  145. int ret;
  146. if (enable) {
  147. ret = mt8186_afe_gpio_select(dev, MT8186_AFE_GPIO_CLK_MISO_ON);
  148. if (ret) {
  149. dev_err(dev, "%s(), MISO CLK ON select fail!\n", __func__);
  150. return ret;
  151. }
  152. ret = mt8186_afe_gpio_select(dev, MT8186_AFE_GPIO_DAT_MISO_ON);
  153. if (ret) {
  154. dev_err(dev, "%s(), MISO DAT ON select fail!\n", __func__);
  155. return ret;
  156. }
  157. } else {
  158. ret = mt8186_afe_gpio_select(dev, MT8186_AFE_GPIO_DAT_MISO_OFF);
  159. if (ret) {
  160. dev_err(dev, "%s(), MISO DAT OFF select fail!\n", __func__);
  161. return ret;
  162. }
  163. ret = mt8186_afe_gpio_select(dev, MT8186_AFE_GPIO_CLK_MISO_OFF);
  164. if (ret) {
  165. dev_err(dev, "%s(), MISO CLK OFF select fail!\n", __func__);
  166. return ret;
  167. }
  168. }
  169. return 0;
  170. }
  171. int mt8186_afe_gpio_request(struct device *dev, bool enable,
  172. int dai, int uplink)
  173. {
  174. enum mt8186_afe_gpio sel;
  175. int ret = -EINVAL;
  176. mutex_lock(&gpio_request_mutex);
  177. switch (dai) {
  178. case MT8186_DAI_ADDA:
  179. if (uplink)
  180. ret = mt8186_afe_gpio_adda_ul(dev, enable);
  181. else
  182. ret = mt8186_afe_gpio_adda_dl(dev, enable);
  183. goto unlock;
  184. case MT8186_DAI_I2S_0:
  185. sel = enable ? MT8186_AFE_GPIO_I2S0_ON : MT8186_AFE_GPIO_I2S0_OFF;
  186. break;
  187. case MT8186_DAI_I2S_1:
  188. sel = enable ? MT8186_AFE_GPIO_I2S1_ON : MT8186_AFE_GPIO_I2S1_OFF;
  189. break;
  190. case MT8186_DAI_I2S_2:
  191. sel = enable ? MT8186_AFE_GPIO_I2S2_ON : MT8186_AFE_GPIO_I2S2_OFF;
  192. break;
  193. case MT8186_DAI_I2S_3:
  194. sel = enable ? MT8186_AFE_GPIO_I2S3_ON : MT8186_AFE_GPIO_I2S3_OFF;
  195. break;
  196. case MT8186_DAI_TDM_IN:
  197. sel = enable ? MT8186_AFE_GPIO_TDM_ON : MT8186_AFE_GPIO_TDM_OFF;
  198. break;
  199. case MT8186_DAI_PCM:
  200. sel = enable ? MT8186_AFE_GPIO_PCM_ON : MT8186_AFE_GPIO_PCM_OFF;
  201. break;
  202. default:
  203. dev_err(dev, "%s(), invalid dai %d\n", __func__, dai);
  204. goto unlock;
  205. }
  206. ret = mt8186_afe_gpio_select(dev, sel);
  207. unlock:
  208. mutex_unlock(&gpio_request_mutex);
  209. return ret;
  210. }