wmi_unified_gpio_tlv.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. /*
  2. * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
  3. *
  4. * Permission to use, copy, modify, and/or distribute this software for any
  5. * purpose with or without fee is hereby granted, provided that the above
  6. * copyright notice and this permission notice appear in all copies.
  7. *
  8. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  9. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  11. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  13. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  14. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15. */
  16. #include <osdep.h>
  17. #include <wmi.h>
  18. #include <wmi_unified_priv.h>
  19. #include <wmi_unified_gpio_api.h>
  20. /**
  21. * convert_gpio_dir() - Function to convert unified gpio direction
  22. * @dir: pointer to enum gpio_direction
  23. *
  24. * Convert the wmi unified gpio direction to FW TLV WMI gpio direction
  25. *
  26. * Return:
  27. * 0 - Output
  28. * 1 - Input
  29. */
  30. static uint32_t
  31. convert_gpio_direction(enum gpio_direction dir)
  32. {
  33. switch (dir) {
  34. case WMI_HOST_GPIO_INPUT:
  35. return WMI_FW_GPIO_INPUT;
  36. case WMI_HOST_GPIO_OUTPUT:
  37. return WMI_FW_GPIO_OUTPUT;
  38. default:
  39. return WMI_FW_GPIO_OUTPUT;
  40. }
  41. }
  42. /**
  43. * convert_gpio_pull_type() - Function to convert unified pull type
  44. * @pull_type: pointer to enum gpio_pull_type
  45. *
  46. * Convert the wmi unified pull type to FW TLV WMI gpio pull type
  47. *
  48. * Return: FW TLV WMI gpio pull type
  49. */
  50. static uint32_t
  51. convert_gpio_pull_type(enum gpio_pull_type pull_type)
  52. {
  53. switch (pull_type) {
  54. case WMI_HOST_GPIO_PULL_NONE:
  55. return WMI_GPIO_PULL_NONE;
  56. case WMI_HOST_GPIO_PULL_UP:
  57. return WMI_GPIO_PULL_UP;
  58. case WMI_HOST_GPIO_PULL_DOWN:
  59. return WMI_GPIO_PULL_DOWN;
  60. default:
  61. return WMI_GPIO_PULL_NONE;
  62. }
  63. }
  64. /**
  65. * convert_gpio_interrupt_mode() - Function to convert unified interrupt mode
  66. * @intr_mode: pointer to enum gpio_interrupt_mode
  67. *
  68. * Convert the wmi unified interrupt mode to FW TLV WMI gpio interrupt mode
  69. *
  70. * Return: FW TLV WMI gpio interrupt mode
  71. */
  72. static uint32_t
  73. convert_gpio_interrupt_mode(enum gpio_interrupt_mode intr_mode)
  74. {
  75. switch (intr_mode) {
  76. case WMI_HOST_GPIO_INTMODE_DISABLE:
  77. return WMI_GPIO_INTTYPE_DISABLE;
  78. case WMI_HOST_GPIO_INTMODE_RISING_EDGE:
  79. return WMI_GPIO_INTTYPE_RISING_EDGE;
  80. case WMI_HOST_GPIO_INTMODE_FALLING_EDGE:
  81. return WMI_GPIO_INTTYPE_FALLING_EDGE;
  82. case WMI_HOST_GPIO_INTMODE_BOTH_EDGE:
  83. return WMI_GPIO_INTTYPE_BOTH_EDGE;
  84. case WMI_HOST_GPIO_INTMODE_LEVEL_LOW:
  85. return WMI_GPIO_INTTYPE_LEVEL_LOW;
  86. case WMI_HOST_GPIO_INTMODE_LEVEL_HIGH:
  87. return WMI_GPIO_INTTYPE_LEVEL_HIGH;
  88. default:
  89. return WMI_GPIO_INTTYPE_DISABLE;
  90. }
  91. }
  92. /**
  93. * convert_gpio_output_value() - Function to convert unified gpio output value
  94. * @value: pointer to enum gpio_value
  95. *
  96. * Convert the wmi unified gpio output value to FW TLV WMI gpio output value
  97. *
  98. * Return:
  99. * 0 - Output low level
  100. * 1 - Output high level
  101. */
  102. static uint32_t
  103. convert_gpio_output_value(enum gpio_value value)
  104. {
  105. switch (value) {
  106. case WMI_HOST_GPIO_LEVEL_LOW:
  107. return 0;
  108. case WMI_HOST_GPIO_LEVEL_HIGH:
  109. return 1;
  110. default:
  111. return 0;
  112. }
  113. }
  114. /**
  115. * send_gpio_config_cmd_tlv() - send gpio config to fw
  116. * @wmi_handle: wmi handle
  117. * @param: pointer to hold gpio config params
  118. *
  119. * Send gpio configuration to firmware.
  120. *
  121. * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
  122. */
  123. static QDF_STATUS
  124. send_gpio_config_cmd_tlv(wmi_unified_t wmi_handle,
  125. struct gpio_config_params *param)
  126. {
  127. wmi_gpio_config_cmd_fixed_param *cmd;
  128. wmi_buf_t buf;
  129. int32_t len;
  130. QDF_STATUS ret;
  131. len = sizeof(*cmd);
  132. /* Sanity Checks */
  133. if (param->pin_pull_type >= WMI_HOST_GPIO_PULL_MAX ||
  134. param->pin_intr_mode >= WMI_HOST_GPIO_INTMODE_MAX ||
  135. param->pin_dir >= WMI_HOST_GPIO_DIR_MAX) {
  136. return QDF_STATUS_E_FAILURE;
  137. }
  138. buf = wmi_buf_alloc(wmi_handle, len);
  139. if (!buf)
  140. return QDF_STATUS_E_FAILURE;
  141. cmd = (wmi_gpio_config_cmd_fixed_param *)wmi_buf_data(buf);
  142. WMITLV_SET_HDR(&cmd->tlv_header,
  143. WMITLV_TAG_STRUC_wmi_gpio_config_cmd_fixed_param,
  144. WMITLV_GET_STRUCT_TLVLEN(
  145. wmi_gpio_config_cmd_fixed_param));
  146. cmd->gpio_num = param->pin_num;
  147. cmd->input = convert_gpio_direction(param->pin_dir);
  148. cmd->pull_type = convert_gpio_pull_type(param->pin_pull_type);
  149. cmd->intr_mode = convert_gpio_interrupt_mode(param->pin_intr_mode);
  150. cmd->mux_config_val = param->mux_config_val;
  151. cmd->drive = param->drive;
  152. cmd->init_enable = param->init_enable;
  153. wmi_debug("GPIO num %d, input-dir %d, pull_type %d, intr_mode %d"
  154. " mux_config_val %d drive %d init_enable %d",
  155. cmd->gpio_num, cmd->input, cmd->pull_type, cmd->intr_mode,
  156. cmd->mux_config_val, cmd->drive, cmd->init_enable);
  157. wmi_mtrace(WMI_GPIO_CONFIG_CMDID, NO_SESSION, 0);
  158. ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
  159. WMI_GPIO_CONFIG_CMDID);
  160. if (QDF_IS_STATUS_ERROR(ret)) {
  161. wmi_err("Sending GPIO config cmd failed");
  162. wmi_buf_free(buf);
  163. }
  164. return ret;
  165. }
  166. /**
  167. * send_gpio_output_cmd_tlv() - send gpio output to fw
  168. * @wmi_handle: wmi handle
  169. * @param: pointer to hold gpio output param
  170. *
  171. * Send gpio output value to firmware.
  172. *
  173. * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
  174. */
  175. static QDF_STATUS
  176. send_gpio_output_cmd_tlv(wmi_unified_t wmi_handle,
  177. struct gpio_output_params *param)
  178. {
  179. wmi_gpio_output_cmd_fixed_param *cmd;
  180. wmi_buf_t buf;
  181. int32_t len;
  182. QDF_STATUS ret;
  183. len = sizeof(*cmd);
  184. /* Sanity Checks */
  185. if (param->pin_set >= WMI_HOST_GPIO_LEVEL_MAX)
  186. return QDF_STATUS_E_FAILURE;
  187. buf = wmi_buf_alloc(wmi_handle, len);
  188. if (!buf)
  189. return QDF_STATUS_E_FAILURE;
  190. cmd = (wmi_gpio_output_cmd_fixed_param *)wmi_buf_data(buf);
  191. WMITLV_SET_HDR(&cmd->tlv_header,
  192. WMITLV_TAG_STRUC_wmi_gpio_output_cmd_fixed_param,
  193. WMITLV_GET_STRUCT_TLVLEN(
  194. wmi_gpio_output_cmd_fixed_param));
  195. cmd->gpio_num = param->pin_num;
  196. cmd->set = convert_gpio_output_value(param->pin_set);
  197. wmi_debug("GPIO num %d, set %d", cmd->gpio_num, cmd->set);
  198. wmi_mtrace(WMI_GPIO_OUTPUT_CMDID, NO_SESSION, 0);
  199. ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
  200. WMI_GPIO_OUTPUT_CMDID);
  201. if (QDF_IS_STATUS_ERROR(ret)) {
  202. wmi_err("Sending GPIO output cmd failed");
  203. wmi_buf_free(buf);
  204. }
  205. return ret;
  206. }
  207. void wmi_gpio_attach_tlv(wmi_unified_t wmi_handle)
  208. {
  209. struct wmi_ops *ops = wmi_handle->ops;
  210. ops->send_gpio_config_cmd = send_gpio_config_cmd_tlv;
  211. ops->send_gpio_output_cmd = send_gpio_output_cmd_tlv;
  212. }