mirror of
https://github.com/torvalds/linux.git
synced 2024-11-30 16:11:38 +00:00
staging: wfx: add infrastructure for new driver
Instantiate build infrastructure WFx driver. This driver provides support for Wifi chipset Silicon Labs WF200 and further: https://www.silabs.com/documents/public/data-sheets/wf200-datasheet.pdf This chip support SPI and SDIO bus. SDIO interface has two particularities: 1. Some parameters may be useful for end user (I will talk about gpio_wakeup later). 2. The SDIO VID and PID of WF200 are 0000:0001 which are too much generic to rely on. So, current code checks VID/PID and looks for a node in DT (since WF200 targets embedded platforms, I don't think it is a problem to rely on DT). DT can also be used to define to parameters for driver. Currently, if no node is found, a warning is emitted, but it could be changed in error. Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com> Link: https://lore.kernel.org/r/20190919142527.31797-2-Jerome.Pouiller@silabs.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
d98bb9c2fe
commit
a7a91ca5a2
@ -14802,6 +14802,11 @@ S: Maintained
|
||||
F: drivers/input/touchscreen/silead.c
|
||||
F: drivers/platform/x86/touchscreen_dmi.c
|
||||
|
||||
SILICON LABS WIRELESS DRIVERS (for WFxxx series)
|
||||
M: Jérôme Pouiller <jerome.pouiller@silabs.com>
|
||||
S: Supported
|
||||
F: drivers/staging/wfx/
|
||||
|
||||
SILICON MOTION SM712 FRAME BUFFER DRIVER
|
||||
M: Sudip Mukherjee <sudipm.mukherjee@gmail.com>
|
||||
M: Teddy Wang <teddy.wang@siliconmotion.com>
|
||||
|
@ -125,4 +125,6 @@ source "drivers/staging/exfat/Kconfig"
|
||||
|
||||
source "drivers/staging/qlge/Kconfig"
|
||||
|
||||
source "drivers/staging/wfx/Kconfig"
|
||||
|
||||
endif # STAGING
|
||||
|
@ -53,3 +53,4 @@ obj-$(CONFIG_UWB) += uwb/
|
||||
obj-$(CONFIG_USB_WUSB) += wusbcore/
|
||||
obj-$(CONFIG_EXFAT_FS) += exfat/
|
||||
obj-$(CONFIG_QLGE) += qlge/
|
||||
obj-$(CONFIG_WFX) += wfx/
|
||||
|
@ -0,0 +1,97 @@
|
||||
The WFxxx chip series can be connected via SPI or via SDIO.
|
||||
|
||||
SPI
|
||||
---
|
||||
|
||||
You have to declare the WFxxx chip in your device tree.
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be "silabs,wfx-spi"
|
||||
- reg: Chip select address of device
|
||||
- spi-max-frequency: Maximum SPI clocking speed of device in Hz
|
||||
- interrupts-extended: Should contain interrupt line (interrupt-parent +
|
||||
interrupt can also been used). Trigger should be `IRQ_TYPE_EDGE_RISING`.
|
||||
|
||||
Optional properties:
|
||||
- reset-gpios: phandle of gpio that will be used to reset chip during probe.
|
||||
Without this property, you may encounter issues with warm boot.
|
||||
|
||||
Please consult Documentation/devicetree/bindings/spi/spi-bus.txt for optional
|
||||
SPI connection related properties,
|
||||
|
||||
Example:
|
||||
|
||||
&spi1 {
|
||||
wfx {
|
||||
compatible = "silabs,wfx-spi";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&wfx_irq &wfx_gpios>;
|
||||
interrupts-extended = <&gpio 16 IRQ_TYPE_EDGE_RISING>;
|
||||
wakeup-gpios = <&gpio 12 GPIO_ACTIVE_HIGH>;
|
||||
reset-gpios = <&gpio 13 GPIO_ACTIVE_HIGH>;
|
||||
reg = <0>;
|
||||
spi-max-frequency = <42000000>;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
SDIO
|
||||
----
|
||||
|
||||
The driver is able to detect a WFxxx chip on SDIO bus by matching its Vendor ID
|
||||
and Product ID. However, driver will only provide limited features in this
|
||||
case. Thus declaring WFxxx chip in device tree is strongly recommended (and may
|
||||
become mandatory in the future).
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be "silabs,wfx-sdio"
|
||||
- reg: Should be 1
|
||||
|
||||
In addition, it is recommended to declare a mmc-pwrseq on SDIO host above WFx.
|
||||
Without it, you may encounter issues with warm boot. mmc-pwrseq should be
|
||||
compatible with mmc-pwrseq-simple. Please consult
|
||||
Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt for more
|
||||
information.
|
||||
|
||||
Example:
|
||||
|
||||
/ {
|
||||
wfx_pwrseq: wfx_pwrseq {
|
||||
compatible = "mmc-pwrseq-simple";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&wfx_reset>;
|
||||
reset-gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
};
|
||||
|
||||
&mmc1 {
|
||||
mmc-pwrseq = <&wfx_pwrseq>;
|
||||
#address-size = <1>;
|
||||
#size = <0>;
|
||||
|
||||
mmc@1 {
|
||||
compatible = "silabs,wfx-sdio";
|
||||
reg = <1>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&wfx_wakeup>;
|
||||
wakeup-gpios = <&gpio 12 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
};
|
||||
|
||||
Note that #address-size and #size shoud already be defined in node mmc1, but it
|
||||
is rarely the case.
|
||||
|
||||
Common properties
|
||||
-----------------
|
||||
|
||||
Some properties are recognized either by SPI and SDIO versions:
|
||||
- wakeup-gpios: phandle of gpio that will be used to wake-up chip. Without
|
||||
this property, driver will disable most of power saving features.
|
||||
- config-file: Use an alternative file as PDS. Default is `wf200.pds`. Only
|
||||
necessary for development/debug purpose.
|
||||
- slk_key: String representing hexdecimal value of secure link key to use.
|
||||
Must contains 64 hexadecimal digits. Not supported in current version.
|
||||
|
||||
WFx driver also supports `mac-address` and `local-mac-address` as described in
|
||||
Documentation/devicetree/binding/net/ethernet.txt
|
||||
|
7
drivers/staging/wfx/Kconfig
Normal file
7
drivers/staging/wfx/Kconfig
Normal file
@ -0,0 +1,7 @@
|
||||
config WFX
|
||||
tristate "Silicon Labs wireless chips WF200 and further"
|
||||
depends on MAC80211
|
||||
depends on (SPI || MMC)
|
||||
help
|
||||
This is a driver for Silicons Labs WFxxx series (WF200 and further)
|
||||
chipsets. This chip can be found on SPI or SDIO buses.
|
8
drivers/staging/wfx/Makefile
Normal file
8
drivers/staging/wfx/Makefile
Normal file
@ -0,0 +1,8 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
wfx-y := \
|
||||
main.o
|
||||
wfx-$(CONFIG_SPI) += bus_spi.o
|
||||
wfx-$(subst m,y,$(CONFIG_MMC)) += bus_sdio.o
|
||||
|
||||
obj-$(CONFIG_WFX) += wfx.o
|
20
drivers/staging/wfx/TODO
Normal file
20
drivers/staging/wfx/TODO
Normal file
@ -0,0 +1,20 @@
|
||||
This is a list of things that need to be done to get this driver out of the
|
||||
staging directory.
|
||||
|
||||
- wfx_version.h is still there in order to ensure synchronization with github.
|
||||
It can be dropped as soon as development is entirely in kernel
|
||||
|
||||
- I have to take a decision about secure link support. I can:
|
||||
- drop completely
|
||||
- keep it in an external patch (my preferred option)
|
||||
- replace call to mbedtls with kernel crypto API (necessitate a
|
||||
bunch of work)
|
||||
- pull mbedtls in kernel (non-realistic)
|
||||
|
||||
- mac80211 interface does not (yet) have expected quality to be placed
|
||||
outside of staging:
|
||||
- Some processings are redundant with mac80211 ones
|
||||
- Many members from wfx_dev/wfx_vif can be retrieved from mac80211
|
||||
structures
|
||||
- Some functions are too complex
|
||||
- ...
|
17
drivers/staging/wfx/bus.h
Normal file
17
drivers/staging/wfx/bus.h
Normal file
@ -0,0 +1,17 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Common bus abstraction layer.
|
||||
*
|
||||
* Copyright (c) 2017-2018, Silicon Laboratories, Inc.
|
||||
* Copyright (c) 2010, ST-Ericsson
|
||||
*/
|
||||
#ifndef WFX_BUS_H
|
||||
#define WFX_BUS_H
|
||||
|
||||
#include <linux/mmc/sdio_func.h>
|
||||
#include <linux/spi/spi.h>
|
||||
|
||||
extern struct sdio_driver wfx_sdio_driver;
|
||||
extern struct spi_driver wfx_spi_driver;
|
||||
|
||||
#endif
|
70
drivers/staging/wfx/bus_sdio.c
Normal file
70
drivers/staging/wfx/bus_sdio.c
Normal file
@ -0,0 +1,70 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* SDIO interface.
|
||||
*
|
||||
* Copyright (c) 2017-2019, Silicon Laboratories, Inc.
|
||||
* Copyright (c) 2010, ST-Ericsson
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/mmc/sdio_func.h>
|
||||
#include <linux/mmc/card.h>
|
||||
#include <linux/of_irq.h>
|
||||
|
||||
#include "bus.h"
|
||||
|
||||
static const struct of_device_id wfx_sdio_of_match[];
|
||||
static int wfx_sdio_probe(struct sdio_func *func,
|
||||
const struct sdio_device_id *id)
|
||||
{
|
||||
struct device_node *np = func->dev.of_node;
|
||||
|
||||
if (func->num != 1) {
|
||||
dev_err(&func->dev, "SDIO function number is %d while it should always be 1 (unsupported chip?)\n", func->num);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (np) {
|
||||
if (!of_match_node(wfx_sdio_of_match, np)) {
|
||||
dev_warn(&func->dev, "no compatible device found in DT\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
} else {
|
||||
dev_warn(&func->dev, "device is not declared in DT, features will be limited\n");
|
||||
// FIXME: ignore VID/PID and only rely on device tree
|
||||
// return -ENODEV;
|
||||
}
|
||||
return -EIO; // FIXME: not yet supported
|
||||
}
|
||||
|
||||
static void wfx_sdio_remove(struct sdio_func *func)
|
||||
{
|
||||
}
|
||||
|
||||
#define SDIO_VENDOR_ID_SILABS 0x0000
|
||||
#define SDIO_DEVICE_ID_SILABS_WF200 0x1000
|
||||
static const struct sdio_device_id wfx_sdio_ids[] = {
|
||||
{ SDIO_DEVICE(SDIO_VENDOR_ID_SILABS, SDIO_DEVICE_ID_SILABS_WF200) },
|
||||
// FIXME: ignore VID/PID and only rely on device tree
|
||||
// { SDIO_DEVICE(SDIO_ANY_ID, SDIO_ANY_ID) },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(sdio, wfx_sdio_ids);
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id wfx_sdio_of_match[] = {
|
||||
{ .compatible = "silabs,wfx-sdio" },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, wfx_sdio_of_match);
|
||||
#endif
|
||||
|
||||
struct sdio_driver wfx_sdio_driver = {
|
||||
.name = "wfx-sdio",
|
||||
.id_table = wfx_sdio_ids,
|
||||
.probe = wfx_sdio_probe,
|
||||
.remove = wfx_sdio_remove,
|
||||
.drv = {
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = of_match_ptr(wfx_sdio_of_match),
|
||||
}
|
||||
};
|
53
drivers/staging/wfx/bus_spi.c
Normal file
53
drivers/staging/wfx/bus_spi.c
Normal file
@ -0,0 +1,53 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* SPI interface.
|
||||
*
|
||||
* Copyright (c) 2017-2019, Silicon Laboratories, Inc.
|
||||
* Copyright (c) 2011, Sagrad Inc.
|
||||
* Copyright (c) 2010, ST-Ericsson
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
#include "bus.h"
|
||||
|
||||
static int wfx_spi_probe(struct spi_device *func)
|
||||
{
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* Disconnect Function to be called by SPI stack when device is disconnected */
|
||||
static int wfx_spi_disconnect(struct spi_device *func)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* For dynamic driver binding, kernel does not use OF to match driver. It only
|
||||
* use modalias and modalias is a copy of 'compatible' DT node with vendor
|
||||
* stripped.
|
||||
*/
|
||||
static const struct spi_device_id wfx_spi_id[] = {
|
||||
{ "wfx-spi", 0 },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(spi, wfx_spi_id);
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id wfx_spi_of_match[] = {
|
||||
{ .compatible = "silabs,wfx-spi" },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, wfx_spi_of_match);
|
||||
#endif
|
||||
|
||||
struct spi_driver wfx_spi_driver = {
|
||||
.driver = {
|
||||
.name = "wfx-spi",
|
||||
.of_match_table = of_match_ptr(wfx_spi_of_match),
|
||||
},
|
||||
.id_table = wfx_spi_id,
|
||||
.probe = wfx_spi_probe,
|
||||
.remove = wfx_spi_disconnect,
|
||||
};
|
47
drivers/staging/wfx/main.c
Normal file
47
drivers/staging/wfx/main.c
Normal file
@ -0,0 +1,47 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Device probe and register.
|
||||
*
|
||||
* Copyright (c) 2017-2019, Silicon Laboratories, Inc.
|
||||
* Copyright (c) 2010, ST-Ericsson
|
||||
* Copyright (c) 2008, Johannes Berg <johannes@sipsolutions.net>
|
||||
* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
|
||||
* Copyright (c) 2007-2009, Christian Lamparter <chunkeey@web.de>
|
||||
* Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net>
|
||||
* Copyright (c) 2004-2006 Jean-Baptiste Note <jbnote@gmail.com>, et al.
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/mmc/sdio_func.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/etherdevice.h>
|
||||
|
||||
#include "bus.h"
|
||||
#include "wfx_version.h"
|
||||
|
||||
MODULE_DESCRIPTION("Silicon Labs 802.11 Wireless LAN driver for WFx");
|
||||
MODULE_AUTHOR("Jérôme Pouiller <jerome.pouiller@silabs.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_VERSION(WFX_LABEL);
|
||||
|
||||
static int __init wfx_core_init(void)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
pr_info("wfx: Silicon Labs " WFX_LABEL "\n");
|
||||
|
||||
if (IS_ENABLED(CONFIG_SPI))
|
||||
ret = spi_register_driver(&wfx_spi_driver);
|
||||
if (IS_ENABLED(CONFIG_MMC) && !ret)
|
||||
ret = sdio_register_driver(&wfx_sdio_driver);
|
||||
return ret;
|
||||
}
|
||||
module_init(wfx_core_init);
|
||||
|
||||
static void __exit wfx_core_exit(void)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_MMC))
|
||||
sdio_unregister_driver(&wfx_sdio_driver);
|
||||
if (IS_ENABLED(CONFIG_SPI))
|
||||
spi_unregister_driver(&wfx_spi_driver);
|
||||
}
|
||||
module_exit(wfx_core_exit);
|
3
drivers/staging/wfx/wfx_version.h
Normal file
3
drivers/staging/wfx/wfx_version.h
Normal file
@ -0,0 +1,3 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT! */
|
||||
#define WFX_LABEL "2.3.1"
|
Loading…
Reference in New Issue
Block a user