Browse Source

qcacmn: Add wmi interfaces for GPIO configuration

Add wmi interfaces for GPIO configuration.

Change-Id: Ic7c23a67bab752012ded147908238faa8ecc4789
CRs-Fixed: 2753648
Chaoli Zhou 4 năm trước cách đây
mục cha
commit
4fad4e8636

+ 49 - 0
wmi/inc/wmi_unified_gpio_api.h

@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/**
+ * DOC: Implement API's specific to gpio component.
+ */
+
+#ifndef _WMI_UNIFIED_GPIO_API_H_
+#define _WMI_UNIFIED_GPIO_API_H_
+
+#include <wmi_unified_param.h>
+
+/**
+ * wmi_unified_gpio_config_cmd_send() - WMI gpio config function
+ * @wmi_handle: handle to WMI.
+ * @param: pointer to hold gpio config param
+ *
+ * Send WMI set gpio configuration to firmware.
+ *
+ * Return QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
+ */
+QDF_STATUS wmi_unified_gpio_config_cmd_send(wmi_unified_t wmi_handle,
+					    struct gpio_config_params *param);
+
+/**
+ * wmi_unified_gpio_output_cmd_send() - WMI gpio output function
+ * @wmi_handle: handle to WMI.
+ * @param: pointer to hold gpio output param
+ *
+ * Send WMI set gpio output value to firmware.
+ *
+ * Return QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
+ */
+QDF_STATUS wmi_unified_gpio_output_cmd_send(wmi_unified_t wmi_handle,
+					    struct gpio_output_params *param);
+
+#endif /* _WMI_UNIFIED_GPIO_API_H_ */

+ 62 - 25
wmi/inc/wmi_unified_param.h

@@ -3687,24 +3687,61 @@ struct packet_power_info_params {
 };
 
 /**
- * WMI_GPIO_CONFIG_CMDID
+ * enum gpio_pull_type - GPIO PULL TYPE
+ * @WMI_HOST_GPIO_PULL_NONE: set gpio pull type to none
+ * @WMI_HOST_GPIO_PULL_UP: set gpio to pull up
+ * @WMI_HOST_GPIO_PULL_DOWN: set gpio to pull down
+ * @WMI_HOST_GPIO_PULL_MAX: invalid pull type
  */
-enum {
-	WMI_HOST_GPIO_PULL_NONE,
-	WMI_HOST_GPIO_PULL_UP,
-	WMI_HOST_GPIO_PULL_DOWN,
+enum gpio_pull_type {
+	WMI_HOST_GPIO_PULL_NONE = 0,
+	WMI_HOST_GPIO_PULL_UP = 1,
+	WMI_HOST_GPIO_PULL_DOWN = 2,
+	WMI_HOST_GPIO_PULL_MAX,
 };
 
 /**
- * WMI_GPIO_INTTYPE
+ * enum gpio_interrupt_mode - GPIO INTERRUPT MODE
+ * @WMI_HOST_GPIO_INTMODE_DISABLE: disable interrupt mode
+ * @WMI_HOST_GPIO_INTMODE_RISING_EDGE: interrupt with rising edge trigger
+ * @WMI_HOST_GPIO_INTMODE_FALLING_EDGE: interrupt with falling edge trigger
+ * @WMI_HOST_GPIO_INTMODE_BOTH_EDGE: interrupt with both edge trigger
+ * @WMI_HOST_GPIO_INTMODE_LEVEL_LOW: interrupt with gpio level low trigger
+ * @WMI_HOST_GPIO_INTMODE_LEVEL_HIGH: interrupt with gpio level high trigger
+ * @WMI_HOST_GPIO_INTMODE_MAX: invalid interrupt mode
  */
-enum {
-	WMI_HOST_GPIO_INTTYPE_DISABLE,
-	WMI_HOST_GPIO_INTTYPE_RISING_EDGE,
-	WMI_HOST_GPIO_INTTYPE_FALLING_EDGE,
-	WMI_HOST_GPIO_INTTYPE_BOTH_EDGE,
-	WMI_HOST_GPIO_INTTYPE_LEVEL_LOW,
-	WMI_HOST_GPIO_INTTYPE_LEVEL_HIGH
+enum gpio_interrupt_mode {
+	WMI_HOST_GPIO_INTMODE_DISABLE = 0,
+	WMI_HOST_GPIO_INTMODE_RISING_EDGE = 1,
+	WMI_HOST_GPIO_INTMODE_FALLING_EDGE = 2,
+	WMI_HOST_GPIO_INTMODE_BOTH_EDGE = 3,
+	WMI_HOST_GPIO_INTMODE_LEVEL_LOW = 4,
+	WMI_HOST_GPIO_INTMODE_LEVEL_HIGH = 5,
+	WMI_HOST_GPIO_INTMODE_MAX,
+};
+
+/**
+ * enum qca_gpio_direction - GPIO Direction
+ * @WLAN_GPIO_INPUT: set gpio as input mode
+ * @WLAN_GPIO_OUTPUT: set gpio as output mode
+ * @WLAN_GPIO_VALUE_MAX: invalid gpio direction
+ */
+enum gpio_direction {
+	WMI_HOST_GPIO_INPUT = 0,
+	WMI_HOST_GPIO_OUTPUT = 1,
+	WMI_HOST_GPIO_DIR_MAX,
+};
+
+/**
+ * enum qca_gpio_value - GPIO Value
+ * @WLAN_GPIO_LEVEL_LOW: set gpio output level low
+ * @WLAN_GPIO_LEVEL_HIGH: set gpio output level high
+ * @WLAN_GPIO_LEVEL_MAX: invalid gpio value
+ */
+enum gpio_value {
+	WMI_HOST_GPIO_LEVEL_LOW = 0,
+	WMI_HOST_GPIO_LEVEL_HIGH = 1,
+	WMI_HOST_GPIO_LEVEL_MAX,
 };
 
 /**
@@ -3717,26 +3754,26 @@ typedef struct {
 
 /**
  * struct gpio_config_params - GPIO config params
- * @gpio_num: GPIO number to config
- * @input: input/output
- * @pull_type: pull type
- * @intr_mode: int mode
+ * @pin_num: GPIO number to config
+ * @pin_dir: gpio direction, 1-input/0-output
+ * @pin_pull_type: pull type define in gpio_pull_type
+ * @pin_intr_mode: interrupt mode define in gpio_interrupt_mode
  */
 struct gpio_config_params {
-	uint32_t gpio_num;
-	uint32_t input;
-	uint32_t pull_type;
-	uint32_t intr_mode;
+	uint32_t pin_num;
+	enum gpio_direction pin_dir;
+	enum gpio_pull_type pin_pull_type;
+	enum gpio_interrupt_mode pin_intr_mode;
 };
 
 /**
  * struct gpio_output_params - GPIO output params
- * @gpio_num: GPIO number to configure
- * @set: set/reset
+ * @pin_num: GPIO number to configure
+ * @pinset: 1 mean gpio output high level, 0 mean gpio output low level
  */
 struct gpio_output_params {
-	uint32_t gpio_num;
-	uint32_t set;
+	uint32_t pin_num;
+	enum gpio_value pin_set;
 };
 
 /* flags bit 0: to configure wlan priority bitmap */

+ 17 - 0
wmi/inc/wmi_unified_priv.h

@@ -1455,11 +1455,13 @@ QDF_STATUS (*send_nf_dbr_dbm_info_get_cmd)(wmi_unified_t wmi_handle,
 QDF_STATUS (*send_packet_power_info_get_cmd)(wmi_unified_t wmi_handle,
 		      struct packet_power_info_params *param);
 
+#ifdef WLAN_FEATURE_GPIO_CFG
 QDF_STATUS (*send_gpio_config_cmd)(wmi_unified_t wmi_handle,
 		      struct gpio_config_params *param);
 
 QDF_STATUS (*send_gpio_output_cmd)(wmi_unified_t wmi_handle,
 		      struct gpio_output_params *param);
+#endif
 
 QDF_STATUS (*send_rtt_meas_req_test_cmd)(wmi_unified_t wmi_handle,
 		      struct rtt_meas_req_test_params *param);
@@ -2898,6 +2900,21 @@ static inline void wmi_fwol_attach_tlv(wmi_unified_t wmi_handle)
 }
 #endif
 
+/**
+ * wmi_gpio_attach_tlv() - attach gpio tlv handlers
+ * @wmi_handle: wmi handle
+ *
+ * Return: void
+ */
+#ifdef WLAN_FEATURE_GPIO_CFG
+void wmi_gpio_attach_tlv(wmi_unified_t wmi_handle);
+#else
+static inline void
+wmi_gpio_attach_tlv(struct wmi_unified *wmi_handle)
+{
+}
+#endif
+
 /**
  * wmi_align() - provides word aligned parameter
  * @param: parameter to be aligned

+ 40 - 0
wmi/src/wmi_unified_gpio_api.c

@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/**
+ * DOC: Implement API's specific to gpio component.
+ */
+
+#include <wmi_unified_priv.h>
+#include <wmi_unified_gpio_api.h>
+
+QDF_STATUS wmi_unified_gpio_config_cmd_send(wmi_unified_t wmi_handle,
+					    struct gpio_config_params *param)
+{
+	if (wmi_handle->ops->send_gpio_config_cmd)
+		return wmi_handle->ops->send_gpio_config_cmd(wmi_handle, param);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_gpio_output_cmd_send(wmi_unified_t wmi_handle,
+					    struct gpio_output_params *param)
+{
+	if (wmi_handle->ops->send_gpio_output_cmd)
+		return wmi_handle->ops->send_gpio_output_cmd(wmi_handle, param);
+
+	return QDF_STATUS_E_FAILURE;
+}
+

+ 231 - 0
wmi/src/wmi_unified_gpio_tlv.c

@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <osdep.h>
+#include <wmi.h>
+#include <wmi_unified_priv.h>
+#include <wmi_unified_gpio_api.h>
+
+/**
+ * convert_gpio_dir() - Function to convert unified gpio direction
+ * @dir: pointer to enum gpio_direction
+ *
+ * Convert the wmi unified gpio direction to FW TLV WMI gpio direction
+ *
+ * Return:
+ * 0 - Output
+ * 1 - Input
+ */
+static uint32_t
+convert_gpio_direction(enum gpio_direction dir)
+{
+	switch (dir) {
+	case WMI_HOST_GPIO_INPUT:
+		return 0;
+	case WMI_HOST_GPIO_OUTPUT:
+		return 1;
+	default:
+		return 0;
+	}
+}
+
+/**
+ * convert_gpio_pull_type() - Function to convert unified pull type
+ * @pull_type: pointer to enum gpio_pull_type
+ *
+ * Convert the wmi unified pull type to FW TLV WMI gpio pull type
+ *
+ * Return: FW TLV WMI gpio pull type
+ */
+static uint32_t
+convert_gpio_pull_type(enum gpio_pull_type pull_type)
+{
+	switch (pull_type) {
+	case WMI_HOST_GPIO_PULL_NONE:
+		return WMI_GPIO_PULL_NONE;
+	case WMI_HOST_GPIO_PULL_UP:
+		return WMI_GPIO_PULL_UP;
+	case WMI_HOST_GPIO_PULL_DOWN:
+		return WMI_GPIO_PULL_DOWN;
+	default:
+		return WMI_GPIO_PULL_NONE;
+	}
+}
+
+/**
+ * convert_gpio_interrupt_mode() - Function to convert unified interrupt mode
+ * @intr_mode: pointer to enum gpio_interrupt_mode
+ *
+ * Convert the wmi unified interrupt mode to FW TLV WMI gpio interrupt mode
+ *
+ * Return: FW TLV WMI gpio interrupt mode
+ */
+static uint32_t
+convert_gpio_interrupt_mode(enum gpio_interrupt_mode intr_mode)
+{
+	switch (intr_mode) {
+	case WMI_HOST_GPIO_INTMODE_DISABLE:
+		return WMI_GPIO_INTTYPE_DISABLE;
+	case WMI_HOST_GPIO_INTMODE_RISING_EDGE:
+		return WMI_GPIO_INTTYPE_RISING_EDGE;
+	case WMI_HOST_GPIO_INTMODE_FALLING_EDGE:
+		return WMI_GPIO_INTTYPE_FALLING_EDGE;
+	case WMI_HOST_GPIO_INTMODE_BOTH_EDGE:
+		return WMI_GPIO_INTTYPE_BOTH_EDGE;
+	case WMI_HOST_GPIO_INTMODE_LEVEL_LOW:
+		return WMI_GPIO_INTTYPE_LEVEL_LOW;
+	case WMI_HOST_GPIO_INTMODE_LEVEL_HIGH:
+		return WMI_GPIO_INTTYPE_LEVEL_HIGH;
+	default:
+		return WMI_GPIO_INTTYPE_DISABLE;
+	}
+}
+
+/**
+ * convert_gpio_output_value() - Function to convert unified gpio output value
+ * @value: pointer to enum gpio_value
+ *
+ * Convert the wmi unified gpio output value to FW TLV WMI gpio output value
+ *
+ * Return:
+ * 0 - Output low level
+ * 1 - Output high level
+ */
+static uint32_t
+convert_gpio_output_value(enum gpio_value value)
+{
+	switch (value) {
+	case WMI_HOST_GPIO_LEVEL_LOW:
+		return 0;
+	case WMI_HOST_GPIO_LEVEL_HIGH:
+		return 1;
+	default:
+		return 0;
+	}
+}
+
+/**
+ * send_gpio_config_cmd_tlv() - send gpio config to fw
+ * @wmi_handle: wmi handle
+ * @param: pointer to hold gpio config params
+ *
+ * Send gpio configuration to firmware.
+ *
+ * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
+ */
+static QDF_STATUS
+send_gpio_config_cmd_tlv(wmi_unified_t wmi_handle,
+			 struct gpio_config_params *param)
+{
+	wmi_gpio_config_cmd_fixed_param *cmd;
+	wmi_buf_t buf;
+	int32_t len;
+	QDF_STATUS ret;
+
+	len = sizeof(*cmd);
+
+	/* Sanity Checks */
+	if (param->pin_pull_type >= WMI_HOST_GPIO_PULL_MAX ||
+	    param->pin_intr_mode >= WMI_HOST_GPIO_INTMODE_MAX ||
+	    param->pin_dir >= WMI_HOST_GPIO_DIR_MAX) {
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf)
+		return QDF_STATUS_E_FAILURE;
+
+	cmd = (wmi_gpio_config_cmd_fixed_param *)wmi_buf_data(buf);
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_gpio_config_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN(
+				wmi_gpio_config_cmd_fixed_param));
+	cmd->gpio_num = param->pin_num;
+	cmd->input = convert_gpio_direction(param->pin_dir);
+	cmd->pull_type = convert_gpio_pull_type(param->pin_pull_type);
+	cmd->intr_mode = convert_gpio_interrupt_mode(param->pin_intr_mode);
+
+	WMI_LOGD("GPIO num %d, input-dir %d, pull_type %d, intr_mode %d",
+		 cmd->gpio_num, cmd->input, cmd->pull_type, cmd->intr_mode);
+	wmi_mtrace(WMI_GPIO_CONFIG_CMDID, NO_SESSION, 0);
+	ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
+				   WMI_GPIO_CONFIG_CMDID);
+
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		WMI_LOGE("Sending GPIO config cmd failed");
+		wmi_buf_free(buf);
+	}
+
+	return ret;
+}
+
+/**
+ * send_gpio_output_cmd_tlv() - send gpio output to fw
+ * @wmi_handle: wmi handle
+ * @param: pointer to hold gpio output param
+ *
+ * Send gpio output value to firmware.
+ *
+ * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
+ */
+static QDF_STATUS
+send_gpio_output_cmd_tlv(wmi_unified_t wmi_handle,
+			 struct gpio_output_params *param)
+{
+	wmi_gpio_output_cmd_fixed_param *cmd;
+	wmi_buf_t buf;
+	int32_t len;
+	QDF_STATUS ret;
+
+	len = sizeof(*cmd);
+
+	/* Sanity Checks */
+	if (param->pin_set >= WMI_HOST_GPIO_LEVEL_MAX)
+		return QDF_STATUS_E_FAILURE;
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf)
+		return QDF_STATUS_E_FAILURE;
+
+	cmd = (wmi_gpio_output_cmd_fixed_param *)wmi_buf_data(buf);
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_gpio_output_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN(
+				wmi_gpio_output_cmd_fixed_param));
+	cmd->gpio_num = param->pin_num;
+	cmd->set = convert_gpio_output_value(param->pin_set);
+
+	WMI_LOGD("GPIO num %d, set %d", cmd->gpio_num, cmd->set);
+	wmi_mtrace(WMI_GPIO_OUTPUT_CMDID, NO_SESSION, 0);
+	ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
+				   WMI_GPIO_OUTPUT_CMDID);
+
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		WMI_LOGE("Sending GPIO output cmd failed");
+		wmi_buf_free(buf);
+	}
+
+	return ret;
+}
+
+void wmi_gpio_attach_tlv(wmi_unified_t wmi_handle)
+{
+	struct wmi_ops *ops = wmi_handle->ops;
+
+	ops->send_gpio_config_cmd = send_gpio_config_cmd_tlv;
+	ops->send_gpio_output_cmd = send_gpio_output_cmd_tlv;
+}
+

+ 1 - 0
wmi/src/wmi_unified_tlv.c

@@ -15145,6 +15145,7 @@ void wmi_tlv_attach(wmi_unified_t wmi_handle)
 	wmi_vdev_attach_tlv(wmi_handle);
 	wmi_cfr_attach_tlv(wmi_handle);
 	wmi_cp_stats_attach_tlv(wmi_handle);
+	wmi_gpio_attach_tlv(wmi_handle);
 }
 qdf_export_symbol(wmi_tlv_attach);