From 4fad4e8636e3c488b3cebf2491ef4704fef967a9 Mon Sep 17 00:00:00 2001 From: Chaoli Zhou Date: Mon, 24 Aug 2020 19:39:49 +0800 Subject: [PATCH] qcacmn: Add wmi interfaces for GPIO configuration Add wmi interfaces for GPIO configuration. Change-Id: Ic7c23a67bab752012ded147908238faa8ecc4789 CRs-Fixed: 2753648 --- wmi/inc/wmi_unified_gpio_api.h | 49 +++++++ wmi/inc/wmi_unified_param.h | 87 +++++++++---- wmi/inc/wmi_unified_priv.h | 17 +++ wmi/src/wmi_unified_gpio_api.c | 40 ++++++ wmi/src/wmi_unified_gpio_tlv.c | 231 +++++++++++++++++++++++++++++++++ wmi/src/wmi_unified_tlv.c | 1 + 6 files changed, 400 insertions(+), 25 deletions(-) create mode 100644 wmi/inc/wmi_unified_gpio_api.h create mode 100644 wmi/src/wmi_unified_gpio_api.c create mode 100644 wmi/src/wmi_unified_gpio_tlv.c diff --git a/wmi/inc/wmi_unified_gpio_api.h b/wmi/inc/wmi_unified_gpio_api.h new file mode 100644 index 0000000000..c1d289b7f0 --- /dev/null +++ b/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_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_ */ diff --git a/wmi/inc/wmi_unified_param.h b/wmi/inc/wmi_unified_param.h index 55f9278a3e..772aec8a9c 100644 --- a/wmi/inc/wmi_unified_param.h +++ b/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 */ diff --git a/wmi/inc/wmi_unified_priv.h b/wmi/inc/wmi_unified_priv.h index 14f2ee3ffb..4198e37ba4 100644 --- a/wmi/inc/wmi_unified_priv.h +++ b/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 diff --git a/wmi/src/wmi_unified_gpio_api.c b/wmi/src/wmi_unified_gpio_api.c new file mode 100644 index 0000000000..289f9ec7f2 --- /dev/null +++ b/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 +#include + +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; +} + diff --git a/wmi/src/wmi_unified_gpio_tlv.c b/wmi/src/wmi_unified_gpio_tlv.c new file mode 100644 index 0000000000..25c49e80c5 --- /dev/null +++ b/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 +#include +#include +#include + +/** + * 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; +} + diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c index bd0025a425..ef17745393 100644 --- a/wmi/src/wmi_unified_tlv.c +++ b/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);