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>;
|
||||
};
|
||||
|
||||
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 {
|
||||
compatible = "simple-bus";
|
||||
#address-cells = <1>;
|
||||
|
@ -758,7 +749,6 @@
|
|||
pinctrl-0 = <&pinctrl_usdhc3>;
|
||||
pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
|
||||
pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
|
||||
mmc-pwrseq = <&wifi_pwrseq>;
|
||||
bus-width = <4>;
|
||||
enable-sdio-wakeup;
|
||||
non-removable;
|
||||
|
@ -774,7 +764,6 @@
|
|||
interrupt-parent = <&gpio4>;
|
||||
interrupts = <2 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "host-wake";
|
||||
/*resets = <&wifi_reset>;*/
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -16,10 +16,77 @@
|
|||
#include <linux/regmap.h>
|
||||
#include <asm/mach/arch.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 "hardware.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)
|
||||
{
|
||||
struct regmap *gpr;
|
||||
|
@ -33,6 +100,10 @@ static void __init imx6sl_fec_clk_init(void)
|
|||
IMX6SL_GPR1_FEC_CLOCK_MUX1_SEL_MASK, 0);
|
||||
} else
|
||||
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)
|
||||
|
|
|
@ -1028,6 +1028,8 @@ static int brcmf_sdiod_probe(struct brcmf_sdio_dev *sdiodev)
|
|||
uint max_blocks;
|
||||
int ret = 0;
|
||||
|
||||
pr_debug("brcmf_sdiod_probe (enter)\n");
|
||||
|
||||
sdiodev->num_funcs = 2;
|
||||
|
||||
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_4345),
|
||||
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4354),
|
||||
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43455),
|
||||
{ /* end: all zeroes */ }
|
||||
};
|
||||
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_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, "Class=%x\n", func->class);
|
||||
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;
|
||||
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++) {
|
||||
if (brcmf_fwname_data[i].chipid == ci->chip &&
|
||||
brcmf_fwname_data[i].revmsk & BIT(ci->chiprev))
|
||||
|
@ -697,6 +699,7 @@ static int brcmf_sdio_get_fwnames(struct brcmf_chip *ci,
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
|
||||
/* check if firmware path is provided by module parameter */
|
||||
if (brcmf_firmware_path[0] != '\0') {
|
||||
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,
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -1046,7 +1052,7 @@ brcmf_sdio_bus_sleep(struct brcmf_sdio *bus, bool sleep, bool pendok)
|
|||
end:
|
||||
/* control clocks */
|
||||
if (sleep) {
|
||||
if (!bus->sr_enabled)
|
||||
if (false && !bus->sr_enabled)
|
||||
brcmf_sdio_clkctl(bus, CLK_NONE, pendok);
|
||||
} else {
|
||||
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 workqueue_struct *wq;
|
||||
|
||||
brcmf_dbg(TRACE, "Enter\n");
|
||||
pr_debug("brcmf_sdio_probe (enter)\n");
|
||||
|
||||
/* Allocate private bus interface state */
|
||||
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,
|
||||
dev_name(&sdiodev->func[1]->dev));
|
||||
if (!wq) {
|
||||
brcmf_err("insufficient memory to create txworkqueue\n");
|
||||
pr_err("brcmf_sdio_probe: insufficient memory to create txworkqueue\n");
|
||||
goto fail;
|
||||
}
|
||||
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 */
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -4150,7 +4156,7 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
|
|||
bus, "brcmf_wdog/%s",
|
||||
dev_name(&sdiodev->func[1]->dev));
|
||||
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;
|
||||
}
|
||||
/* 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 */
|
||||
ret = brcmf_attach(bus->sdiodev->dev);
|
||||
if (ret != 0) {
|
||||
brcmf_err("brcmf_attach failed\n");
|
||||
pr_err("brcmf_sdio_probe: brcmf_attach failed\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@ -4185,7 +4191,7 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
|
|||
ALIGNMENT) + bus->head_align;
|
||||
bus->rxbuf = kmalloc(bus->rxblen, GFP_ATOMIC);
|
||||
if (!(bus->rxbuf)) {
|
||||
brcmf_err("rxbuf allocation failed\n");
|
||||
pr_err("brcmf_sdio_probe: rxbuf allocation failed\n");
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
@ -4221,7 +4227,7 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
|
|||
sdiodev->fw_name, sdiodev->nvram_name,
|
||||
brcmf_sdio_firmware_callback);
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#define SDIO_DEVICE_ID_BROADCOM_43362 0xa962
|
||||
#define SDIO_DEVICE_ID_BROADCOM_43430 0xa9a6
|
||||
#define SDIO_DEVICE_ID_BROADCOM_4345 0x4345
|
||||
#define SDIO_DEVICE_ID_BROADCOM_43455 0xa9bf
|
||||
#define SDIO_DEVICE_ID_BROADCOM_4354 0x4354
|
||||
|
||||
#define SDIO_VENDOR_ID_INTEL 0x0089
|
||||
|
|
Loading…
Reference in New Issue