st_ll.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. /*
  2. * Shared Transport driver
  3. * HCI-LL module responsible for TI proprietary HCI_LL protocol
  4. * Copyright (C) 2009-2010 Texas Instruments
  5. * Author: Pavan Savoy <pavan_savoy@ti.com>
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License version 2 as
  9. * published by the Free Software Foundation.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19. *
  20. */
  21. #define pr_fmt(fmt) "(stll) :" fmt
  22. #include <linux/skbuff.h>
  23. #include <linux/module.h>
  24. #include <linux/platform_device.h>
  25. #include <linux/ti_wilink_st.h>
  26. /**********************************************************************/
  27. /* internal functions */
  28. static void send_ll_cmd(struct st_data_s *st_data,
  29. unsigned char cmd)
  30. {
  31. pr_debug("%s: writing %x", __func__, cmd);
  32. st_int_write(st_data, &cmd, 1);
  33. return;
  34. }
  35. static void ll_device_want_to_sleep(struct st_data_s *st_data)
  36. {
  37. struct kim_data_s *kim_data;
  38. struct ti_st_plat_data *pdata;
  39. pr_debug("%s", __func__);
  40. /* sanity check */
  41. if (st_data->ll_state != ST_LL_AWAKE)
  42. pr_err("ERR hcill: ST_LL_GO_TO_SLEEP_IND"
  43. "in state %ld", st_data->ll_state);
  44. send_ll_cmd(st_data, LL_SLEEP_ACK);
  45. /* update state */
  46. st_data->ll_state = ST_LL_ASLEEP;
  47. /* communicate to platform about chip asleep */
  48. kim_data = st_data->kim_data;
  49. pdata = kim_data->kim_pdev->dev.platform_data;
  50. if (pdata->chip_asleep)
  51. pdata->chip_asleep(NULL);
  52. }
  53. static void ll_device_want_to_wakeup(struct st_data_s *st_data)
  54. {
  55. struct kim_data_s *kim_data;
  56. struct ti_st_plat_data *pdata;
  57. /* diff actions in diff states */
  58. switch (st_data->ll_state) {
  59. case ST_LL_ASLEEP:
  60. send_ll_cmd(st_data, LL_WAKE_UP_ACK); /* send wake_ack */
  61. break;
  62. case ST_LL_ASLEEP_TO_AWAKE:
  63. /* duplicate wake_ind */
  64. pr_err("duplicate wake_ind while waiting for Wake ack");
  65. break;
  66. case ST_LL_AWAKE:
  67. /* duplicate wake_ind */
  68. pr_err("duplicate wake_ind already AWAKE");
  69. break;
  70. case ST_LL_AWAKE_TO_ASLEEP:
  71. /* duplicate wake_ind */
  72. pr_err("duplicate wake_ind");
  73. break;
  74. }
  75. /* update state */
  76. st_data->ll_state = ST_LL_AWAKE;
  77. /* communicate to platform about chip wakeup */
  78. kim_data = st_data->kim_data;
  79. pdata = kim_data->kim_pdev->dev.platform_data;
  80. if (pdata->chip_awake)
  81. pdata->chip_awake(NULL);
  82. }
  83. /**********************************************************************/
  84. /* functions invoked by ST Core */
  85. /* called when ST Core wants to
  86. * enable ST LL */
  87. void st_ll_enable(struct st_data_s *ll)
  88. {
  89. ll->ll_state = ST_LL_AWAKE;
  90. }
  91. /* called when ST Core /local module wants to
  92. * disable ST LL */
  93. void st_ll_disable(struct st_data_s *ll)
  94. {
  95. ll->ll_state = ST_LL_INVALID;
  96. }
  97. /* called when ST Core wants to update the state */
  98. void st_ll_wakeup(struct st_data_s *ll)
  99. {
  100. if (likely(ll->ll_state != ST_LL_AWAKE)) {
  101. send_ll_cmd(ll, LL_WAKE_UP_IND); /* WAKE_IND */
  102. ll->ll_state = ST_LL_ASLEEP_TO_AWAKE;
  103. } else {
  104. /* don't send the duplicate wake_indication */
  105. pr_err(" Chip already AWAKE ");
  106. }
  107. }
  108. /* called when ST Core wants the state */
  109. unsigned long st_ll_getstate(struct st_data_s *ll)
  110. {
  111. pr_debug(" returning state %ld", ll->ll_state);
  112. return ll->ll_state;
  113. }
  114. /* called from ST Core, when a PM related packet arrives */
  115. unsigned long st_ll_sleep_state(struct st_data_s *st_data,
  116. unsigned char cmd)
  117. {
  118. switch (cmd) {
  119. case LL_SLEEP_IND: /* sleep ind */
  120. pr_debug("sleep indication recvd");
  121. ll_device_want_to_sleep(st_data);
  122. break;
  123. case LL_SLEEP_ACK: /* sleep ack */
  124. pr_err("sleep ack rcvd: host shouldn't");
  125. break;
  126. case LL_WAKE_UP_IND: /* wake ind */
  127. pr_debug("wake indication recvd");
  128. ll_device_want_to_wakeup(st_data);
  129. break;
  130. case LL_WAKE_UP_ACK: /* wake ack */
  131. pr_debug("wake ack rcvd");
  132. st_data->ll_state = ST_LL_AWAKE;
  133. break;
  134. default:
  135. pr_err(" unknown input/state ");
  136. return -EINVAL;
  137. }
  138. return 0;
  139. }
  140. /* Called from ST CORE to initialize ST LL */
  141. long st_ll_init(struct st_data_s *ll)
  142. {
  143. /* set state to invalid */
  144. ll->ll_state = ST_LL_INVALID;
  145. return 0;
  146. }
  147. /* Called from ST CORE to de-initialize ST LL */
  148. long st_ll_deinit(struct st_data_s *ll)
  149. {
  150. return 0;
  151. }