Commit 652b4afb authored by Jérôme Pouiller's avatar Jérôme Pouiller Committed by Greg Kroah-Hartman

staging: wfx: load firmware

A firmware is necessary to run the chip. wfx_init_device() is in charge
of loading firmware on chip and doing low level initialization.

Firmwares for WF200 are available here:

  https://github.com/SiliconLabs/wfx-firmware/

Note that firmware are encrypted. Driver checks that key used to encrypt
firmware match with key burned into chip.

Currently, "C0" key is used for production chips.
Signed-off-by: default avatarJérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20190919142527.31797-6-Jerome.Pouiller@silabs.comSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent fee695e3
...@@ -5,6 +5,7 @@ CFLAGS_debug.o = -I$(src) ...@@ -5,6 +5,7 @@ CFLAGS_debug.o = -I$(src)
wfx-y := \ wfx-y := \
hwio.o \ hwio.o \
fwio.o \
main.o \ main.o \
debug.o debug.o
wfx-$(CONFIG_SPI) += bus_spi.o wfx-$(CONFIG_SPI) += bus_spi.o
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "main.h" #include "main.h"
static const struct wfx_platform_data wfx_sdio_pdata = { static const struct wfx_platform_data wfx_sdio_pdata = {
.file_fw = "wfm_wf200",
}; };
struct wfx_sdio_priv { struct wfx_sdio_priv {
...@@ -204,8 +205,14 @@ static int wfx_sdio_probe(struct sdio_func *func, ...@@ -204,8 +205,14 @@ static int wfx_sdio_probe(struct sdio_func *func,
goto err2; goto err2;
} }
ret = wfx_probe(bus->core);
if (ret)
goto err3;
return 0; return 0;
err3:
wfx_free_common(bus->core);
err2: err2:
wfx_sdio_irq_unsubscribe(bus); wfx_sdio_irq_unsubscribe(bus);
err1: err1:
...@@ -220,6 +227,7 @@ static void wfx_sdio_remove(struct sdio_func *func) ...@@ -220,6 +227,7 @@ static void wfx_sdio_remove(struct sdio_func *func)
{ {
struct wfx_sdio_priv *bus = sdio_get_drvdata(func); struct wfx_sdio_priv *bus = sdio_get_drvdata(func);
wfx_release(bus->core);
wfx_free_common(bus->core); wfx_free_common(bus->core);
wfx_sdio_irq_unsubscribe(bus); wfx_sdio_irq_unsubscribe(bus);
sdio_claim_host(func); sdio_claim_host(func);
......
...@@ -27,6 +27,8 @@ MODULE_PARM_DESC(gpio_reset, "gpio number for reset. -1 for none."); ...@@ -27,6 +27,8 @@ MODULE_PARM_DESC(gpio_reset, "gpio number for reset. -1 for none.");
#define SET_READ 0x8000 /* usage: or operation */ #define SET_READ 0x8000 /* usage: or operation */
static const struct wfx_platform_data wfx_spi_pdata = { static const struct wfx_platform_data wfx_spi_pdata = {
.file_fw = "wfm_wf200",
.use_rising_clk = true,
}; };
struct wfx_spi_priv { struct wfx_spi_priv {
...@@ -205,6 +207,10 @@ static int wfx_spi_probe(struct spi_device *func) ...@@ -205,6 +207,10 @@ static int wfx_spi_probe(struct spi_device *func)
if (!bus->core) if (!bus->core)
return -EIO; return -EIO;
ret = wfx_probe(bus->core);
if (ret)
wfx_free_common(bus->core);
return ret; return ret;
} }
...@@ -213,6 +219,7 @@ static int wfx_spi_disconnect(struct spi_device *func) ...@@ -213,6 +219,7 @@ static int wfx_spi_disconnect(struct spi_device *func)
{ {
struct wfx_spi_priv *bus = spi_get_drvdata(func); struct wfx_spi_priv *bus = spi_get_drvdata(func);
wfx_release(bus->core);
wfx_free_common(bus->core); wfx_free_common(bus->core);
// A few IRQ will be sent during device release. Hopefully, no IRQ // A few IRQ will be sent during device release. Hopefully, no IRQ
// should happen after wdev/wvif are released. // should happen after wdev/wvif are released.
......
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Firmware loading.
*
* Copyright (c) 2017-2019, Silicon Laboratories, Inc.
* Copyright (c) 2010, ST-Ericsson
*/
#ifndef WFX_FWIO_H
#define WFX_FWIO_H
struct wfx_dev;
int wfx_init_device(struct wfx_dev *wdev);
#endif /* WFX_FWIO_H */
...@@ -20,6 +20,8 @@ ...@@ -20,6 +20,8 @@
#include "main.h" #include "main.h"
#include "wfx.h" #include "wfx.h"
#include "fwio.h"
#include "hwio.h"
#include "bus.h" #include "bus.h"
#include "wfx_version.h" #include "wfx_version.h"
...@@ -76,6 +78,24 @@ void wfx_free_common(struct wfx_dev *wdev) ...@@ -76,6 +78,24 @@ void wfx_free_common(struct wfx_dev *wdev)
{ {
} }
int wfx_probe(struct wfx_dev *wdev)
{
int err;
err = wfx_init_device(wdev);
if (err)
goto err1;
return 0;
err1:
return err;
}
void wfx_release(struct wfx_dev *wdev)
{
}
static int __init wfx_core_init(void) static int __init wfx_core_init(void)
{ {
int ret = 0; int ret = 0;
......
...@@ -18,6 +18,13 @@ ...@@ -18,6 +18,13 @@
struct wfx_dev; struct wfx_dev;
struct wfx_platform_data { struct wfx_platform_data {
/* Keyset and ".sec" extention will appended to this string */
const char *file_fw;
/*
* if true HIF D_out is sampled on the rising edge of the clock
* (intended to be used in 50Mhz SDIO)
*/
bool use_rising_clk;
}; };
struct wfx_dev *wfx_init_common(struct device *dev, struct wfx_dev *wfx_init_common(struct device *dev,
...@@ -26,6 +33,9 @@ struct wfx_dev *wfx_init_common(struct device *dev, ...@@ -26,6 +33,9 @@ struct wfx_dev *wfx_init_common(struct device *dev,
void *hwbus_priv); void *hwbus_priv);
void wfx_free_common(struct wfx_dev *wdev); void wfx_free_common(struct wfx_dev *wdev);
int wfx_probe(struct wfx_dev *wdev);
void wfx_release(struct wfx_dev *wdev);
struct gpio_desc *wfx_get_gpio(struct device *dev, int override, struct gpio_desc *wfx_get_gpio(struct device *dev, int override,
const char *label); const char *label);
......
...@@ -19,6 +19,8 @@ struct wfx_dev { ...@@ -19,6 +19,8 @@ struct wfx_dev {
struct device *dev; struct device *dev;
const struct hwbus_ops *hwbus_ops; const struct hwbus_ops *hwbus_ops;
void *hwbus_priv; void *hwbus_priv;
u8 keyset;
}; };
#endif /* WFX_H */ #endif /* WFX_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment