Add support for AP6256 wifi module
- Add sdio chip ID 43455 - Replace formerly used devicetree based wifi module power cycling via SDIO host interface driver with brcmf platform driver power eventsap6256_fix_initial_attempt_before_cleanup
parent
7f82abb869
commit
fd8872af5d
|
@ -22,15 +22,6 @@
|
||||||
reg = <0x80000000 0x20000000>;
|
reg = <0x80000000 0x20000000>;
|
||||||
};
|
};
|
||||||
|
|
||||||
wifi_pwrseq: wifi_pwrseq {
|
|
||||||
compatible = "mmc-pwrseq-simple";
|
|
||||||
reset-gpios = <&gpio3 30 GPIO_ACTIVE_LOW>,
|
|
||||||
<&gpio4 0 GPIO_ACTIVE_LOW>;
|
|
||||||
clocks = <&clks IMX6SL_CLK_OSC>;
|
|
||||||
clock-names = "ext_clock";
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
regulators {
|
regulators {
|
||||||
compatible = "simple-bus";
|
compatible = "simple-bus";
|
||||||
#address-cells = <1>;
|
#address-cells = <1>;
|
||||||
|
@ -758,7 +749,6 @@
|
||||||
pinctrl-0 = <&pinctrl_usdhc3>;
|
pinctrl-0 = <&pinctrl_usdhc3>;
|
||||||
pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
|
pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
|
||||||
pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
|
pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
|
||||||
mmc-pwrseq = <&wifi_pwrseq>;
|
|
||||||
bus-width = <4>;
|
bus-width = <4>;
|
||||||
enable-sdio-wakeup;
|
enable-sdio-wakeup;
|
||||||
non-removable;
|
non-removable;
|
||||||
|
@ -774,7 +764,6 @@
|
||||||
interrupt-parent = <&gpio4>;
|
interrupt-parent = <&gpio4>;
|
||||||
interrupts = <2 IRQ_TYPE_LEVEL_HIGH>;
|
interrupts = <2 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
interrupt-names = "host-wake";
|
interrupt-names = "host-wake";
|
||||||
/*resets = <&wifi_reset>;*/
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -16,10 +16,77 @@
|
||||||
#include <linux/regmap.h>
|
#include <linux/regmap.h>
|
||||||
#include <asm/mach/arch.h>
|
#include <asm/mach/arch.h>
|
||||||
#include <asm/mach/map.h>
|
#include <asm/mach/map.h>
|
||||||
|
#include <linux/gpio.h>
|
||||||
|
#include <config/brcmfmac.h>
|
||||||
|
#include <linux/delay.h>
|
||||||
|
#include <linux/platform_data/brcmfmac-sdio.h>
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include "hardware.h"
|
||||||
#include "cpuidle.h"
|
#include "cpuidle.h"
|
||||||
|
|
||||||
|
#define WL_PWR_ON IMX_GPIO_NR(3, 30)
|
||||||
|
#define WL_REG_ON IMX_GPIO_NR(4, 0)
|
||||||
|
|
||||||
|
static bool init_wifi_gpio(void)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
pr_debug("init_wifi_gpio: enter\n");
|
||||||
|
|
||||||
|
pr_debug("init_wifi_gpio: Requesting GPIO_3_30 (PWR_ON) ..\n");
|
||||||
|
err = gpio_request_one(WL_PWR_ON, GPIOF_OUT_INIT_LOW, "wl_pwr_on");
|
||||||
|
if (err) {
|
||||||
|
pr_err("Failed to request power GPIO for wifi: %d\n", err);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
pr_debug("init_wifi_gpio: OK !\n");
|
||||||
|
|
||||||
|
pr_debug("init_wifi_gpio: Requesting GPIO4_0 (REG_ON) ..\n");
|
||||||
|
err = gpio_request_one(WL_REG_ON, GPIOF_OUT_INIT_LOW, "wl_reg_on");
|
||||||
|
if (err) {
|
||||||
|
pr_err("Failed to request regulator GPIO for wifi: %d\n", err);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
pr_debug("init_wifi_gpio: OK !!\n");
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void brcmfmac_power_on(void)
|
||||||
|
{
|
||||||
|
pr_debug("brcmfmac_power_on: enter\n");
|
||||||
|
gpio_set_value(WL_PWR_ON, 1);
|
||||||
|
gpio_set_value(WL_REG_ON, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void brcmfmac_power_off(void)
|
||||||
|
{
|
||||||
|
pr_debug("brcmfmac_power_off: enter\n");
|
||||||
|
gpio_set_value(WL_PWR_ON, 0);
|
||||||
|
gpio_set_value(WL_REG_ON, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void brcmfmac_reset(void)
|
||||||
|
{
|
||||||
|
pr_debug("brcmfmac_reset: enter\n");
|
||||||
|
brcmfmac_power_off();
|
||||||
|
msleep(5);
|
||||||
|
brcmfmac_power_on();
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct brcmfmac_sdio_platform_data brcmfmac_sdio_pdata = {
|
||||||
|
.power_on = brcmfmac_power_on,
|
||||||
|
.power_off = brcmfmac_power_off,
|
||||||
|
.reset = brcmfmac_reset
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device brcmfmac_device = {
|
||||||
|
.name = BRCMFMAC_SDIO_PDATA_NAME,
|
||||||
|
.id = PLATFORM_DEVID_NONE,
|
||||||
|
.dev.platform_data = &brcmfmac_sdio_pdata
|
||||||
|
};
|
||||||
|
|
||||||
static void __init imx6sl_fec_clk_init(void)
|
static void __init imx6sl_fec_clk_init(void)
|
||||||
{
|
{
|
||||||
struct regmap *gpr;
|
struct regmap *gpr;
|
||||||
|
@ -33,6 +100,10 @@ static void __init imx6sl_fec_clk_init(void)
|
||||||
IMX6SL_GPR1_FEC_CLOCK_MUX1_SEL_MASK, 0);
|
IMX6SL_GPR1_FEC_CLOCK_MUX1_SEL_MASK, 0);
|
||||||
} else
|
} else
|
||||||
pr_err("failed to find fsl,imx6sl-iomux-gpr regmap\n");
|
pr_err("failed to find fsl,imx6sl-iomux-gpr regmap\n");
|
||||||
|
|
||||||
|
if (init_wifi_gpio()) {
|
||||||
|
platform_device_register(&brcmfmac_device);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void imx6sl_fec_init(void)
|
static inline void imx6sl_fec_init(void)
|
||||||
|
|
|
@ -1028,6 +1028,8 @@ static int brcmf_sdiod_probe(struct brcmf_sdio_dev *sdiodev)
|
||||||
uint max_blocks;
|
uint max_blocks;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
pr_debug("brcmf_sdiod_probe (enter)\n");
|
||||||
|
|
||||||
sdiodev->num_funcs = 2;
|
sdiodev->num_funcs = 2;
|
||||||
|
|
||||||
sdio_claim_host(sdiodev->func[1]);
|
sdio_claim_host(sdiodev->func[1]);
|
||||||
|
@ -1111,6 +1113,7 @@ static const struct sdio_device_id brcmf_sdmmc_ids[] = {
|
||||||
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43430),
|
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43430),
|
||||||
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4345),
|
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4345),
|
||||||
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4354),
|
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4354),
|
||||||
|
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43455),
|
||||||
{ /* end: all zeroes */ }
|
{ /* end: all zeroes */ }
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids);
|
MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids);
|
||||||
|
@ -1125,7 +1128,8 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func,
|
||||||
struct brcmf_sdio_dev *sdiodev;
|
struct brcmf_sdio_dev *sdiodev;
|
||||||
struct brcmf_bus *bus_if;
|
struct brcmf_bus *bus_if;
|
||||||
|
|
||||||
printk("brcmf_ops_sdio_probe\n");
|
pr_debug("brcmf_ops_sdio_probe (enter)\n");
|
||||||
|
|
||||||
brcmf_dbg(SDIO, "Enter\n");
|
brcmf_dbg(SDIO, "Enter\n");
|
||||||
brcmf_dbg(SDIO, "Class=%x\n", func->class);
|
brcmf_dbg(SDIO, "Class=%x\n", func->class);
|
||||||
brcmf_dbg(SDIO, "sdio vendor ID: 0x%04x\n", func->vendor);
|
brcmf_dbg(SDIO, "sdio vendor ID: 0x%04x\n", func->vendor);
|
||||||
|
|
|
@ -686,6 +686,8 @@ static int brcmf_sdio_get_fwnames(struct brcmf_chip *ci,
|
||||||
int i;
|
int i;
|
||||||
char end;
|
char end;
|
||||||
|
|
||||||
|
printk("brcmf_sdio_get_fwnames: chip id:%lx/%ld, revision:%d\n", ci->chip, ci->chip, ci->chiprev);
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(brcmf_fwname_data); i++) {
|
for (i = 0; i < ARRAY_SIZE(brcmf_fwname_data); i++) {
|
||||||
if (brcmf_fwname_data[i].chipid == ci->chip &&
|
if (brcmf_fwname_data[i].chipid == ci->chip &&
|
||||||
brcmf_fwname_data[i].revmsk & BIT(ci->chiprev))
|
brcmf_fwname_data[i].revmsk & BIT(ci->chiprev))
|
||||||
|
@ -697,6 +699,7 @@ static int brcmf_sdio_get_fwnames(struct brcmf_chip *ci,
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* check if firmware path is provided by module parameter */
|
/* check if firmware path is provided by module parameter */
|
||||||
if (brcmf_firmware_path[0] != '\0') {
|
if (brcmf_firmware_path[0] != '\0') {
|
||||||
strlcpy(sdiodev->fw_name, brcmf_firmware_path,
|
strlcpy(sdiodev->fw_name, brcmf_firmware_path,
|
||||||
|
@ -717,6 +720,9 @@ static int brcmf_sdio_get_fwnames(struct brcmf_chip *ci,
|
||||||
strlcat(sdiodev->nvram_name, brcmf_fwname_data[i].nv,
|
strlcat(sdiodev->nvram_name, brcmf_fwname_data[i].nv,
|
||||||
sizeof(sdiodev->nvram_name));
|
sizeof(sdiodev->nvram_name));
|
||||||
|
|
||||||
|
pr_debug("brcmf_sdio_get_fwnames: fw_name = %s\n", sdiodev->fw_name);
|
||||||
|
pr_debug("brcmf_sdio_get_fwnames: nvram_name = %s\n", sdiodev->nvram_name);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1046,7 +1052,7 @@ brcmf_sdio_bus_sleep(struct brcmf_sdio *bus, bool sleep, bool pendok)
|
||||||
end:
|
end:
|
||||||
/* control clocks */
|
/* control clocks */
|
||||||
if (sleep) {
|
if (sleep) {
|
||||||
if (!bus->sr_enabled)
|
if (false && !bus->sr_enabled)
|
||||||
brcmf_sdio_clkctl(bus, CLK_NONE, pendok);
|
brcmf_sdio_clkctl(bus, CLK_NONE, pendok);
|
||||||
} else {
|
} else {
|
||||||
brcmf_sdio_clkctl(bus, CLK_AVAIL, pendok);
|
brcmf_sdio_clkctl(bus, CLK_AVAIL, pendok);
|
||||||
|
@ -4090,7 +4096,7 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
|
||||||
struct brcmf_sdio *bus;
|
struct brcmf_sdio *bus;
|
||||||
struct workqueue_struct *wq;
|
struct workqueue_struct *wq;
|
||||||
|
|
||||||
brcmf_dbg(TRACE, "Enter\n");
|
pr_debug("brcmf_sdio_probe (enter)\n");
|
||||||
|
|
||||||
/* Allocate private bus interface state */
|
/* Allocate private bus interface state */
|
||||||
bus = kzalloc(sizeof(struct brcmf_sdio), GFP_ATOMIC);
|
bus = kzalloc(sizeof(struct brcmf_sdio), GFP_ATOMIC);
|
||||||
|
@ -4121,7 +4127,7 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
|
||||||
wq = alloc_ordered_workqueue("brcmf_wq/%s", WQ_MEM_RECLAIM,
|
wq = alloc_ordered_workqueue("brcmf_wq/%s", WQ_MEM_RECLAIM,
|
||||||
dev_name(&sdiodev->func[1]->dev));
|
dev_name(&sdiodev->func[1]->dev));
|
||||||
if (!wq) {
|
if (!wq) {
|
||||||
brcmf_err("insufficient memory to create txworkqueue\n");
|
pr_err("brcmf_sdio_probe: insufficient memory to create txworkqueue\n");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
brcmf_sdiod_freezer_count(sdiodev);
|
brcmf_sdiod_freezer_count(sdiodev);
|
||||||
|
@ -4130,7 +4136,7 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
|
||||||
|
|
||||||
/* attempt to attach to the dongle */
|
/* attempt to attach to the dongle */
|
||||||
if (!(brcmf_sdio_probe_attach(bus))) {
|
if (!(brcmf_sdio_probe_attach(bus))) {
|
||||||
brcmf_err("brcmf_sdio_probe_attach failed\n");
|
pr_err("brcmf_sdio_probe: brcmf_sdio_probe_attach failed\n");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4150,7 +4156,7 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
|
||||||
bus, "brcmf_wdog/%s",
|
bus, "brcmf_wdog/%s",
|
||||||
dev_name(&sdiodev->func[1]->dev));
|
dev_name(&sdiodev->func[1]->dev));
|
||||||
if (IS_ERR(bus->watchdog_tsk)) {
|
if (IS_ERR(bus->watchdog_tsk)) {
|
||||||
pr_warn("brcmf_watchdog thread failed to start\n");
|
pr_err("brcmf_sdio_probe: brcmf_watchdog thread failed to start\n");
|
||||||
bus->watchdog_tsk = NULL;
|
bus->watchdog_tsk = NULL;
|
||||||
}
|
}
|
||||||
/* Initialize DPC thread */
|
/* Initialize DPC thread */
|
||||||
|
@ -4169,7 +4175,7 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
|
||||||
/* Attach to the common layer, reserve hdr space */
|
/* Attach to the common layer, reserve hdr space */
|
||||||
ret = brcmf_attach(bus->sdiodev->dev);
|
ret = brcmf_attach(bus->sdiodev->dev);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
brcmf_err("brcmf_attach failed\n");
|
pr_err("brcmf_sdio_probe: brcmf_attach failed\n");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4185,7 +4191,7 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
|
||||||
ALIGNMENT) + bus->head_align;
|
ALIGNMENT) + bus->head_align;
|
||||||
bus->rxbuf = kmalloc(bus->rxblen, GFP_ATOMIC);
|
bus->rxbuf = kmalloc(bus->rxblen, GFP_ATOMIC);
|
||||||
if (!(bus->rxbuf)) {
|
if (!(bus->rxbuf)) {
|
||||||
brcmf_err("rxbuf allocation failed\n");
|
pr_err("brcmf_sdio_probe: rxbuf allocation failed\n");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4221,7 +4227,7 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
|
||||||
sdiodev->fw_name, sdiodev->nvram_name,
|
sdiodev->fw_name, sdiodev->nvram_name,
|
||||||
brcmf_sdio_firmware_callback);
|
brcmf_sdio_firmware_callback);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
brcmf_err("async firmware request failed: %d\n", ret);
|
pr_err("brcmf_sdio_probe: async firmware request failed: %d\n", ret);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#define SDIO_DEVICE_ID_BROADCOM_43362 0xa962
|
#define SDIO_DEVICE_ID_BROADCOM_43362 0xa962
|
||||||
#define SDIO_DEVICE_ID_BROADCOM_43430 0xa9a6
|
#define SDIO_DEVICE_ID_BROADCOM_43430 0xa9a6
|
||||||
#define SDIO_DEVICE_ID_BROADCOM_4345 0x4345
|
#define SDIO_DEVICE_ID_BROADCOM_4345 0x4345
|
||||||
|
#define SDIO_DEVICE_ID_BROADCOM_43455 0xa9bf
|
||||||
#define SDIO_DEVICE_ID_BROADCOM_4354 0x4354
|
#define SDIO_DEVICE_ID_BROADCOM_4354 0x4354
|
||||||
|
|
||||||
#define SDIO_VENDOR_ID_INTEL 0x0089
|
#define SDIO_VENDOR_ID_INTEL 0x0089
|
||||||
|
|
Loading…
Reference in New Issue