Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b4178de3 authored by Chaoli Zhou's avatar Chaoli Zhou Committed by Madan Koyyalamudi
Browse files

qcacmn: Add wmi interfaces for GPIO configuration

Add wmi interfaces for GPIO configuration.

Change-Id: Ic7c23a67bab752012ded147908238faa8ecc4789
CRs-Fixed: 2753648
parent 87785ff8
Loading
Loading
Loading
Loading
+49 −0
Original line number Diff line number Diff line
/*
 * Copyright (c) 2020-2021, 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_ */
+63 −26
Original line number Diff line number Diff line
/*
 * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved.
 * Copyright (c) 2016-2021 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
@@ -3516,24 +3516,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,
};

/**
@@ -3546,26 +3583,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 */
+18 −1
Original line number Diff line number Diff line
/*
 * Copyright (c) 2013-2020 The Linux Foundation. All rights reserved.
 * Copyright (c) 2013-2021 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
@@ -1334,11 +1334,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);
@@ -2656,6 +2658,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
Original line number Diff line number Diff line
/*
 * Copyright (c) 2020-2021, 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
Original line number Diff line number Diff line
/*
 * Copyright (c) 2020-2021, 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;
}
Loading