ese_reset.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. /******************************************************************************
  2. *
  3. * Copyright 2023 NXP
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  18. *
  19. ******************************************************************************/
  20. #include <linux/kernel.h>
  21. #include <linux/module.h>
  22. #include <linux/jiffies.h>
  23. #include "common_ese.h"
  24. #include "ese_reset.h"
  25. static reset_timer_t sResetTimer;
  26. /*!
  27. * \ingroup spi_driver
  28. * \brief Function getting invoked after eSE reset guard time
  29. * \n expiry
  30. * \param[in] struct timer_list *
  31. */
  32. static void gpio_reset_guard_timer_callback(struct timer_list *t)
  33. {
  34. struct reset_timer *sResetTimer = from_timer(sResetTimer, t, timer);
  35. NFC_LOG_INFO("%s: entry\n", __func__);
  36. sResetTimer->in_progress = false;
  37. NFC_LOG_INFO("%s: exit with in_progress set to false\n", __func__);
  38. }
  39. /*!
  40. * \ingroup spi_driver
  41. * \brief Initialising mutex
  42. */
  43. void ese_reset_init(void)
  44. {
  45. mutex_init(&sResetTimer.reset_mutex);
  46. timer_setup(&sResetTimer.timer, gpio_reset_guard_timer_callback, 0);
  47. }
  48. /*!
  49. * \ingroup spi_driver
  50. * \brief Deinitialising mutex
  51. */
  52. void ese_reset_deinit(void)
  53. {
  54. mutex_destroy(&sResetTimer.reset_mutex);
  55. del_timer(&sResetTimer.timer);
  56. }
  57. /*!
  58. * \ingroup spi_driver
  59. * \brief Setting the timer on
  60. * \return long 0 for inactive timer 1 for active timer
  61. */
  62. static long start_gpio_reset_guard_timer(void)
  63. {
  64. long ret;
  65. NFC_LOG_INFO("%s: entry\n", __func__);
  66. ret = mod_timer(&sResetTimer.timer,
  67. jiffies + msecs_to_jiffies(ESE_GPIO_RST_GUARD_TIME_MS));
  68. if (!ret)
  69. sResetTimer.in_progress = true;
  70. else
  71. NFC_LOG_ERR("%s: Error in mod_timer, returned:'%ld'\n", __func__, ret);
  72. NFC_LOG_INFO("%s: exit\n", __func__);
  73. return ret;
  74. }
  75. /*!
  76. * \ingroup spi_driver
  77. * \brief Reset the gpio by toggling low and high state
  78. * \param struct p61_dev
  79. */
  80. int perform_ese_gpio_reset(int rst_gpio)
  81. {
  82. int ret = 0;
  83. if (gpio_is_valid(rst_gpio)) {
  84. NFC_LOG_INFO("%s: entry\n", __func__);
  85. mutex_lock(&sResetTimer.reset_mutex);
  86. if (sResetTimer.in_progress) {
  87. NFC_LOG_ERR("%s: gpio reset already in progress\n", __func__);
  88. ret = -EBUSY;
  89. mutex_unlock(&sResetTimer.reset_mutex);
  90. return ret;
  91. }
  92. NFC_LOG_INFO("%s: entering gpio ese reset case\n", __func__);
  93. ret = start_gpio_reset_guard_timer();
  94. if (ret) {
  95. mutex_unlock(&sResetTimer.reset_mutex);
  96. NFC_LOG_ERR("%s: error in mod_timer\n", __func__);
  97. ret = -EINVAL;
  98. return ret;
  99. }
  100. NFC_LOG_INFO(" eSE Domain Reset");
  101. gpio_set_value(rst_gpio, 0);
  102. usleep_range(ESE_GPIO_RESET_WAIT_TIME_USEC,
  103. ESE_GPIO_RESET_WAIT_TIME_USEC + 100);
  104. gpio_set_value(rst_gpio, 1);
  105. NFC_LOG_INFO("%s: exit\n", __func__);
  106. mutex_unlock(&sResetTimer.reset_mutex);
  107. } else {
  108. NFC_LOG_ERR("%s not entering GPIO Reset, gpio value invalid : %x\n",
  109. __func__, rst_gpio);
  110. return -EPERM;
  111. }
  112. return ret;
  113. }
  114. /*!
  115. * \ingroup spi_driver
  116. * \brief setup ese reset gpio pin as an output pin
  117. * \param struct p61_spi_platform_data *
  118. * \return Return 0 in case of success, else an error code
  119. */
  120. int ese_reset_gpio_setup(struct p61_spi_platform_data *platform_data)
  121. {
  122. int ret = -1;
  123. if (gpio_is_valid(platform_data->rst_gpio)) {
  124. ret = gpio_request(platform_data->rst_gpio, "p61 reset");
  125. if (ret < 0) {
  126. NFC_LOG_ERR("reset gpio 0x%x request failed\n", platform_data->rst_gpio);
  127. return ret;
  128. }
  129. /* reset gpio is set to default high */
  130. ret = gpio_direction_output(platform_data->rst_gpio, 1);
  131. if (ret < 0) {
  132. NFC_LOG_ERR("Failed to set the direction of reset gpio=0x%x\n",
  133. platform_data->rst_gpio);
  134. goto fail_gpio;
  135. }
  136. NFC_LOG_INFO("Exit : %s\n", __func__);
  137. } else {
  138. NFC_LOG_INFO("%s, gpio value invalid : %x\n", __func__,
  139. platform_data->rst_gpio);
  140. }
  141. return ret;
  142. fail_gpio:
  143. if (gpio_is_valid(platform_data->rst_gpio))
  144. gpio_free(platform_data->rst_gpio);
  145. return ret;
  146. }