qcacmn: Add GPIO configuration OSIF code
Add OSIF APIs for GPIO config Change-Id: I091c3b21a7dd12dfee5aa5f05d3d1d0557d16792
This commit is contained in:
57
os_if/linux/gpio/inc/wlan_cfg80211_gpio.h
Normal file
57
os_if/linux/gpio/inc/wlan_cfg80211_gpio.h
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* 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: wlan_cfg80211_gpio.h
|
||||||
|
*
|
||||||
|
* This Header file provide declaration for cfg80211 command handler API
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __WLAN_CFG80211_GPIO_CFG_H__
|
||||||
|
#define __WLAN_CFG80211_GPIO_CFG_H__
|
||||||
|
|
||||||
|
#include <wlan_objmgr_cmn.h>
|
||||||
|
#include <qdf_types.h>
|
||||||
|
#include <net/cfg80211.h>
|
||||||
|
#include <qca_vendor.h>
|
||||||
|
|
||||||
|
#ifdef WLAN_FEATURE_GPIO_CFG
|
||||||
|
|
||||||
|
extern const struct nla_policy
|
||||||
|
wlan_cfg80211_gpio_config_policy
|
||||||
|
[QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_MAX + 1];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* wlan_cfg80211_start_gpio_config() - set GPIO config
|
||||||
|
* @psoc: pointer to psoc common object
|
||||||
|
* @data: Pointer to the data to be passed via vendor interface
|
||||||
|
* @data_len: Length of the data to be passed
|
||||||
|
*
|
||||||
|
* Return: Return the Success or Failure code
|
||||||
|
*/
|
||||||
|
int wlan_cfg80211_start_gpio_config(struct wiphy *wiphy,
|
||||||
|
struct wlan_objmgr_psoc *psoc,
|
||||||
|
const void *data, int data_len);
|
||||||
|
#else
|
||||||
|
static inline
|
||||||
|
int wlan_cfg80211_start_gpio_config(struct wiphy *wiphy,
|
||||||
|
struct wlan_objmgr_psoc *psoc,
|
||||||
|
const void *data, int data_len)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* WLAN_FEATURE_GPIO_CFG */
|
||||||
|
#endif /* __WLAN_CFG80211_GPIO_CFG_H__ */
|
301
os_if/linux/gpio/src/wlan_cfg80211_gpio.c
Normal file
301
os_if/linux/gpio/src/wlan_cfg80211_gpio.c
Normal file
@@ -0,0 +1,301 @@
|
|||||||
|
/*
|
||||||
|
* 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: defines driver functions interfacing with linux kernel
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <qdf_list.h>
|
||||||
|
#include <qdf_status.h>
|
||||||
|
#include <linux/wireless.h>
|
||||||
|
#include <linux/netdevice.h>
|
||||||
|
#include <wlan_cfg80211.h>
|
||||||
|
#include <wlan_osif_priv.h>
|
||||||
|
#include <wlan_gpio_ucfg_api.h>
|
||||||
|
#include <wlan_cfg80211_gpio.h>
|
||||||
|
#include "qdf_module.h"
|
||||||
|
|
||||||
|
const struct nla_policy
|
||||||
|
wlan_cfg80211_gpio_config_policy[QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_MAX + 1] = {
|
||||||
|
[QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND] = {
|
||||||
|
.type = NLA_U32,
|
||||||
|
.len = sizeof(uint32_t) },
|
||||||
|
[QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_PINNUM] = {
|
||||||
|
.type = NLA_U32,
|
||||||
|
.len = sizeof(uint32_t) },
|
||||||
|
[QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_VALUE] = {
|
||||||
|
.type = NLA_U32,
|
||||||
|
.len = sizeof(uint32_t) },
|
||||||
|
[QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_PULL_TYPE] = {
|
||||||
|
.type = NLA_U32,
|
||||||
|
.len = sizeof(uint32_t) },
|
||||||
|
[QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTR_MODE] = {
|
||||||
|
.type = NLA_U32,
|
||||||
|
.len = sizeof(uint32_t) },
|
||||||
|
[QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_DIR] = {
|
||||||
|
.type = NLA_U32,
|
||||||
|
.len = sizeof(uint32_t) },
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* convert_vendor_gpio_direction() - Function to convert vendor gpio direction
|
||||||
|
* @dir: pointer to enum qca_gpio_direction
|
||||||
|
*
|
||||||
|
* Convert the vendor gpio direction to wmi unified gpio direction
|
||||||
|
*
|
||||||
|
* Return: wmi unified gpio direction
|
||||||
|
*/
|
||||||
|
static enum gpio_direction
|
||||||
|
convert_vendor_gpio_direction(enum qca_gpio_direction dir)
|
||||||
|
{
|
||||||
|
switch (dir) {
|
||||||
|
case QCA_WLAN_GPIO_INPUT:
|
||||||
|
return WMI_HOST_GPIO_INPUT;
|
||||||
|
case QCA_WLAN_GPIO_OUTPUT:
|
||||||
|
return WMI_HOST_GPIO_OUTPUT;
|
||||||
|
default:
|
||||||
|
return WMI_HOST_GPIO_INPUT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* convert_vendor_gpio_pull_type() - Function to convert vendor pull type
|
||||||
|
* @pull_type: pointer to enum qca_gpio_pull_type
|
||||||
|
*
|
||||||
|
* Convert the vendor pull type to wmi unified pull type
|
||||||
|
*
|
||||||
|
* Return: wmi unified gpio pull type
|
||||||
|
*/
|
||||||
|
static enum gpio_pull_type
|
||||||
|
convert_vendor_gpio_pull_type(enum qca_gpio_pull_type pull_type)
|
||||||
|
{
|
||||||
|
switch (pull_type) {
|
||||||
|
case QCA_WLAN_GPIO_PULL_NONE:
|
||||||
|
return WMI_HOST_GPIO_PULL_NONE;
|
||||||
|
case QCA_WLAN_GPIO_PULL_UP:
|
||||||
|
return WMI_HOST_GPIO_PULL_UP;
|
||||||
|
case QCA_WLAN_GPIO_PULL_DOWN:
|
||||||
|
return WMI_HOST_GPIO_PULL_DOWN;
|
||||||
|
default:
|
||||||
|
return WMI_HOST_GPIO_PULL_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* convert_vendor_gpio_interrupt_mode() - Function to convert
|
||||||
|
* vendor interrupt mode
|
||||||
|
* @intr_mode: pointer to enum qca_gpio_interrupt_mode
|
||||||
|
*
|
||||||
|
* Convert the vendor interrupt mode to wmi unified interrupt mode
|
||||||
|
*
|
||||||
|
* Return: wmi unified gpio interrupt mode
|
||||||
|
*/
|
||||||
|
static enum gpio_interrupt_mode
|
||||||
|
convert_vendor_gpio_interrupt_mode(enum qca_gpio_interrupt_mode intr_mode)
|
||||||
|
{
|
||||||
|
switch (intr_mode) {
|
||||||
|
case QCA_WLAN_GPIO_INTMODE_DISABLE:
|
||||||
|
return WMI_HOST_GPIO_INTMODE_DISABLE;
|
||||||
|
case QCA_WLAN_GPIO_INTMODE_RISING_EDGE:
|
||||||
|
return WMI_HOST_GPIO_INTMODE_RISING_EDGE;
|
||||||
|
case QCA_WLAN_GPIO_INTMODE_FALLING_EDGE:
|
||||||
|
return WMI_HOST_GPIO_INTMODE_FALLING_EDGE;
|
||||||
|
case QCA_WLAN_GPIO_INTMODE_BOTH_EDGE:
|
||||||
|
return WMI_HOST_GPIO_INTMODE_BOTH_EDGE;
|
||||||
|
case QCA_WLAN_GPIO_INTMODE_LEVEL_LOW:
|
||||||
|
return WMI_HOST_GPIO_INTMODE_LEVEL_LOW;
|
||||||
|
case QCA_WLAN_GPIO_INTMODE_LEVEL_HIGH:
|
||||||
|
return WMI_HOST_GPIO_INTMODE_LEVEL_HIGH;
|
||||||
|
default:
|
||||||
|
return WMI_HOST_GPIO_INTMODE_DISABLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* convert_vendor_gpio_output_value() - Function to convert vendor
|
||||||
|
* gpio output value
|
||||||
|
* @value: pointer to enum qca_gpio_value
|
||||||
|
*
|
||||||
|
* Convert the vendor gpio value to wmi unified gpio output value
|
||||||
|
*
|
||||||
|
* Return: wmi unified gpio output value
|
||||||
|
*/
|
||||||
|
static enum gpio_value
|
||||||
|
convert_vendor_gpio_output_value(enum qca_gpio_value value)
|
||||||
|
{
|
||||||
|
switch (value) {
|
||||||
|
case QCA_WLAN_GPIO_LEVEL_LOW:
|
||||||
|
return WMI_HOST_GPIO_LEVEL_LOW;
|
||||||
|
case QCA_WLAN_GPIO_LEVEL_HIGH:
|
||||||
|
return WMI_HOST_GPIO_LEVEL_HIGH;
|
||||||
|
default:
|
||||||
|
return WMI_HOST_GPIO_LEVEL_LOW;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* wlan_set_gpio_config() - set the gpio configuration info
|
||||||
|
* @psoc: the pointer of wlan_objmgr_psoc
|
||||||
|
* @attr: list of attributes
|
||||||
|
*
|
||||||
|
* Return: 0 on success; errno on failure
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
wlan_set_gpio_config(struct wlan_objmgr_psoc *psoc,
|
||||||
|
struct nlattr **attr)
|
||||||
|
{
|
||||||
|
struct gpio_config_params cfg_param;
|
||||||
|
struct nlattr *gpio_attr;
|
||||||
|
enum qca_gpio_direction pin_dir;
|
||||||
|
enum qca_gpio_pull_type pull_type;
|
||||||
|
enum qca_gpio_interrupt_mode intr_mode;
|
||||||
|
QDF_STATUS status;
|
||||||
|
|
||||||
|
gpio_attr = attr[QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_PINNUM];
|
||||||
|
if (!gpio_attr) {
|
||||||
|
osif_err("attr gpio number failed");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
cfg_param.pin_num = nla_get_u32(gpio_attr);
|
||||||
|
|
||||||
|
gpio_attr = attr[QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_DIR];
|
||||||
|
if (!gpio_attr) {
|
||||||
|
osif_err("attr gpio dir failed");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
pin_dir = nla_get_u32(gpio_attr);
|
||||||
|
if (pin_dir >= QCA_WLAN_GPIO_DIR_MAX) {
|
||||||
|
osif_err("attr gpio direction invalid");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
cfg_param.pin_dir = convert_vendor_gpio_direction(pin_dir);
|
||||||
|
|
||||||
|
gpio_attr = attr[QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_PULL_TYPE];
|
||||||
|
if (!gpio_attr) {
|
||||||
|
osif_err("attr gpio pull failed");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
pull_type = nla_get_u32(gpio_attr);
|
||||||
|
if (pull_type >= QCA_WLAN_GPIO_PULL_MAX) {
|
||||||
|
osif_err("attr gpio pull type invalid");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
cfg_param.pin_pull_type = convert_vendor_gpio_pull_type(pull_type);
|
||||||
|
|
||||||
|
gpio_attr = attr[QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTR_MODE];
|
||||||
|
if (!gpio_attr) {
|
||||||
|
osif_err("attr gpio interrupt mode failed");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
intr_mode = nla_get_u32(gpio_attr);
|
||||||
|
if (intr_mode >= QCA_WLAN_GPIO_INTMODE_MAX) {
|
||||||
|
osif_err("attr gpio interrupt mode invalid");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
cfg_param.pin_intr_mode = convert_vendor_gpio_interrupt_mode(intr_mode);
|
||||||
|
|
||||||
|
status = ucfg_set_gpio_config(psoc, &cfg_param);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* wlan_set_gpio_output() - set the gpio output info
|
||||||
|
* @psoc: the pointer of wlan_objmgr_psoc
|
||||||
|
* @attr: list of attributes
|
||||||
|
*
|
||||||
|
* Return: 0 on success; errno on failure
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
wlan_set_gpio_output(struct wlan_objmgr_psoc *psoc,
|
||||||
|
struct nlattr **attr)
|
||||||
|
{
|
||||||
|
struct gpio_output_params out_param;
|
||||||
|
struct nlattr *gpio_attr;
|
||||||
|
enum qca_gpio_value pin_set;
|
||||||
|
QDF_STATUS status;
|
||||||
|
|
||||||
|
gpio_attr = attr[QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_PINNUM];
|
||||||
|
if (!gpio_attr) {
|
||||||
|
osif_err("attr gpio number failed");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
out_param.pin_num = nla_get_u32(gpio_attr);
|
||||||
|
|
||||||
|
gpio_attr = attr[QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_VALUE];
|
||||||
|
if (!gpio_attr) {
|
||||||
|
osif_err("attr gpio value failed");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
pin_set = nla_get_u32(gpio_attr);
|
||||||
|
if (pin_set >= QCA_WLAN_GPIO_LEVEL_MAX) {
|
||||||
|
osif_err("attr gpio level invalid");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
out_param.pin_set = convert_vendor_gpio_output_value(pin_set);
|
||||||
|
|
||||||
|
status = ucfg_set_gpio_output(psoc, &out_param);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* wlan_cfg80211_start_gpio_config - Set the gpio configuration
|
||||||
|
* @wiphy: pointer to wiphy
|
||||||
|
* @psoc: the pointer of wlan_objmgr_psoc
|
||||||
|
* @data: pointer to data
|
||||||
|
* @data_len: data length
|
||||||
|
*
|
||||||
|
* __wlan_cfg80211_set_gpio_config will forward the GPIO setting to FW by
|
||||||
|
* WMI_GPIO_CONFIG/OUTPUT_CMDID
|
||||||
|
*
|
||||||
|
* Return: 0 on success; errno on failure
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
wlan_cfg80211_start_gpio_config(struct wiphy *wiphy,
|
||||||
|
struct wlan_objmgr_psoc *psoc,
|
||||||
|
const void *data,
|
||||||
|
int data_len)
|
||||||
|
{
|
||||||
|
uint32_t command;
|
||||||
|
struct nlattr *attr[QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_MAX + 1];
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (wlan_cfg80211_nla_parse(attr, QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_MAX,
|
||||||
|
data, data_len,
|
||||||
|
wlan_cfg80211_gpio_config_policy)) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attr[QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND]) {
|
||||||
|
command = nla_get_u32(
|
||||||
|
attr[QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND]);
|
||||||
|
|
||||||
|
if (command == QCA_WLAN_VENDOR_GPIO_CONFIG) {
|
||||||
|
ret = wlan_set_gpio_config(psoc, attr);
|
||||||
|
} else if (command == QCA_WLAN_VENDOR_GPIO_OUTPUT) {
|
||||||
|
ret = wlan_set_gpio_output(psoc, attr);
|
||||||
|
} else {
|
||||||
|
osif_err("Invalid command");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
osif_err("Invalid command");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
qdf_export_symbol(wlan_cfg80211_start_gpio_config);
|
||||||
|
|
Reference in New Issue
Block a user