/* Customer function to control hw specific wlan gpios */ void dhd_customer_gpio_wlan_ctrl(int onoff) { switch (onoff) { case WLAN_RESET_OFF: WL_TRACE(("%s: call customer specific GPIO to insert WLAN RESET\n", __FUNCTION__)); #ifdef CONFIG_MACH_SAMSUNG_P3 nvidia_wlan_poweroff (POWER_OFF, 2); #elif defined(SYSLSI_SPECIFIC) wlan_setup_power(POWER_OFF, 2); #endif WL_ERROR(("=========== WLAN placed in RESET ========\n")); break; case WLAN_RESET_ON: WL_TRACE(("%s: callc customer specific GPIO to remove WLAN RESET\n", __FUNCTION__)); #ifdef CONFIG_MACH_SAMSUNG_P3 nvidia_wlan_poweron (POWER_ON,2); #elif defined(SYSLSI_SPECIFIC) wlan_setup_power(POWER_ON, 2); #endif WL_ERROR(("=========== WLAN going back to live ========\n")); break; case WLAN_POWER_OFF: WL_TRACE(("%s: call customer specific GPIO to turn off WL_REG_ON\n", __FUNCTION__)); #ifdef CONFIG_MACH_SAMSUNG_P3 nvidia_wlan_poweroff (POWER_OFF, 1); #elif defined(SYSLSI_SPECIFIC) wlan_setup_power(POWER_OFF, 1); #elif defined(CONFIG_MACH_N1) n1_device_wifi_power (0); #elif defined(CONFIG_MACH_GODIN) godin_wifi_power(0); #endif break; case WLAN_POWER_ON: WL_TRACE(("%s: call customer specific GPIO to turn on WL_REG_ON\n", __FUNCTION__)); #ifdef CONFIG_MACH_SAMSUNG_P3 nvidia_wlan_poweron (POWER_ON, 1); #elif defined(SYSLSI_SPECIFIC) wlan_setup_power(POWER_ON, 1); #elif defined(CONFIG_MACH_N1) n1_device_wifi_power (1); #elif defined(CONFIG_MACH_GODIN) godin_wifi_power(1); OSL_DELAY(150); u8500_sdio_detect_card(); OSL_DELAY(2000); #endif /* Lets customer power to get stable */ /* OSL_DELAY(200); */ break; } }
/* Advance clock(s) */ static void adm_adclk(adm_info_t *adm, int clocks) { int i; for (i = 0; i < clocks; i ++) { /* Clock high */ si_gpioout(adm->sih, adm->eesk, adm->eesk, GPIO_DRV_PRIORITY); OSL_DELAY(EECK_EDGE_TIME); /* Clock low */ si_gpioout(adm->sih, adm->eesk, 0, GPIO_DRV_PRIORITY); OSL_DELAY(EECK_EDGE_TIME); } }
static bool pcie2_mdiosetblock(pcicore_info_t *pi, uint blk) { sbpcieregs_t *pcieregs = pi->regs.pcieregs; uint mdiodata, mdioctrl, i = 0; uint pcie_serdes_spinwait = 200; mdioctrl = MDIOCTL2_DIVISOR_VAL | (0x1F << MDIOCTL2_REGADDR_SHF); W_REG(pi->osh, &pcieregs->u.pcie2.mdiocontrol, mdioctrl); mdiodata = (blk << MDIODATA2_DEVADDR_SHF) | MDIODATA2_DONE; W_REG(pi->osh, &pcieregs->u.pcie2.mdiowrdata, mdiodata); PR28829_DELAY(); /* retry till the transaction is complete */ while (i < pcie_serdes_spinwait) { if (!(R_REG(pi->osh, &(pcieregs->u.pcie2.mdiowrdata)) & MDIODATA2_DONE)) { break; } OSL_DELAY(1000); i++; } if (i >= pcie_serdes_spinwait) { PCI_ERROR(("pcie_mdiosetblock: timed out\n")); return FALSE; } return TRUE; }
static bool pcie_mdiosetblock(pcicore_info_t *pi, uint blk) { sbpcieregs_t *pcieregs = pi->regs.pcieregs; uint mdiodata, i = 0; uint pcie_serdes_spinwait = 200; mdiodata = MDIODATA_START | MDIODATA_WRITE | (MDIODATA_DEV_ADDR << MDIODATA_DEVADDR_SHF) | \ (MDIODATA_BLK_ADDR << MDIODATA_REGADDR_SHF) | MDIODATA_TA | (blk << 4); W_REG(pi->osh, &pcieregs->mdiodata, mdiodata); PR28829_DELAY(); /* retry till the transaction is complete */ while (i < pcie_serdes_spinwait) { if (R_REG(pi->osh, &(pcieregs->mdiocontrol)) & MDIOCTL_ACCESS_DONE) { break; } OSL_DELAY(1000); i++; } if (i >= pcie_serdes_spinwait) { PCI_ERROR(("pcie_mdiosetblock: timed out\n")); return FALSE; } return TRUE; }
/* Disable outputs to the chip */ static void adm_disout(adm_info_t *adm, uint32 pins) { /* Disable GPIO outputs */ si_gpioouten(adm->sih, pins, 0, GPIO_DRV_PRIORITY); OSL_DELAY(EECK_EDGE_TIME); }
void dma_txreset(dma_info_t *di) { uint32 status; DMA_TRACE(("%s: dma_txreset\n", di->name)); /* address PR8249/PR7577 issue */ /* suspend tx DMA first */ W_REG(&di->regs->xmtcontrol, XC_SE); SPINWAIT((status = (R_REG(&di->regs->xmtstatus) & XS_XS_MASK)) != XS_XS_DISABLED && status != XS_XS_IDLE && status != XS_XS_STOPPED, 10000); /* PR2414 WAR: DMA engines are not disabled until transfer finishes */ W_REG(&di->regs->xmtcontrol, 0); SPINWAIT((status = (R_REG(&di->regs->xmtstatus) & XS_XS_MASK)) != XS_XS_DISABLED, 10000); if (status != XS_XS_DISABLED) { DMA_ERROR(("%s: dma_txreset: dma cannot be stopped\n", di->name)); } /* wait for the last transaction to complete */ OSL_DELAY(300); }
static void reset_release_wait(void) { int gpio; uint32 gpiomask; int i=0; if ((gpio = nvram_resetgpio_init ((void *)sih)) < 0) return; /* Reset button is active low */ gpiomask = (uint32)1 << gpio; while (1) { if ((i%100000) < 30000) { LEDON(); } else { LEDOFF(); } i++; if (i==0xffffff) { i = 0; } if (si_gpioin(sih) & gpiomask) { OSL_DELAY(RESET_DEBOUNCE_TIME); if (si_gpioin(sih) & gpiomask) break; } } }
/* Customer function to control hw specific wlan gpios */ void dhd_customer_gpio_wlan_ctrl(int onoff) { switch (onoff) { case WLAN_RESET_OFF: WL_TRACE(("%s: call customer specific GPIO to insert WLAN RESET\n", __FUNCTION__)); #ifdef FIH_HW bcm4330_wifi_suspend(); //FIH-ADD+ #endif #ifdef CUSTOMER_HW bcm_wlan_power_off(2); #endif /* CUSTOMER_HW */ #ifdef CUSTOMER_HW2 wifi_set_power(0, 0); #endif //WL_ERROR(("=========== WLAN placed in RESET ========\n")); break; case WLAN_RESET_ON: WL_TRACE(("%s: callc customer specific GPIO to remove WLAN RESET\n", __FUNCTION__)); #ifdef FIH_HW bcm4330_wifi_resume(); //FIH-ADD+ #endif #ifdef CUSTOMER_HW bcm_wlan_power_on(2); #endif /* CUSTOMER_HW */ #ifdef CUSTOMER_HW2 wifi_set_power(1, 0); #endif //WL_ERROR(("=========== WLAN going back to live ========\n")); break; case WLAN_POWER_OFF: WL_TRACE(("%s: call customer specific GPIO to turn off WL_REG_ON\n", __FUNCTION__)); #ifdef FIH_HW wifi_power(0); //FIH-ADD+ #endif #ifdef CUSTOMER_HW bcm_wlan_power_off(1); #endif /* CUSTOMER_HW */ break; case WLAN_POWER_ON: WL_TRACE(("%s: call customer specific GPIO to turn on WL_REG_ON\n", __FUNCTION__)); #ifdef FIH_HW wifi_power(1); //FIH-ADD+ #endif #ifdef CUSTOMER_HW bcm_wlan_power_on(1); /* Lets customer power to get stable */ OSL_DELAY(200); #endif /* CUSTOMER_HW */ break; } }
void bcm_mdelay(uint ms) { uint i; for (i = 0; i < ms; i++) { OSL_DELAY(1000); } }
/* Enable outputs with specified value to the chip */ static void adm_enout(adm_info_t *adm, uint32 pins, uint val) { /* Prepare GPIO output value */ si_gpioout(adm->sih, pins, val, GPIO_DRV_PRIORITY); /* Enable GPIO outputs */ si_gpioouten(adm->sih, pins, pins, GPIO_DRV_PRIORITY); OSL_DELAY(EECK_EDGE_TIME); }
static int pciegen1_mdioop(pcicore_info_t *pi, uint physmedia, uint regaddr, bool write, uint *val) { sbpcieregs_t *pcieregs = pi->regs.pcieregs; uint mdiodata; uint i = 0; uint pcie_serdes_spinwait = 10; if (!PCIE_GEN1(pi->sih)) ASSERT(0); /* enable mdio access to SERDES */ W_REG(pi->osh, (&pcieregs->u.pcie1.mdiocontrol), MDIOCTL_PREAM_EN | MDIOCTL_DIVISOR_VAL); if (pi->sih->buscorerev >= 10) { /* new serdes is slower in rw, using two layers of reg address mapping */ if (!pcie_mdiosetblock(pi, physmedia)) return 1; mdiodata = (MDIODATA_DEV_ADDR << MDIODATA_DEVADDR_SHF) | (regaddr << MDIODATA_REGADDR_SHF); pcie_serdes_spinwait *= 20; } else { mdiodata = (physmedia << MDIODATA_DEVADDR_SHF_OLD) | (regaddr << MDIODATA_REGADDR_SHF_OLD); } if (!write) mdiodata |= (MDIODATA_START | MDIODATA_READ | MDIODATA_TA); else mdiodata |= (MDIODATA_START | MDIODATA_WRITE | MDIODATA_TA | *val); W_REG(pi->osh, &pcieregs->u.pcie1.mdiodata, mdiodata); PR28829_DELAY(); /* retry till the transaction is complete */ while (i < pcie_serdes_spinwait) { if (R_REG(pi->osh, &(pcieregs->u.pcie1.mdiocontrol)) & MDIOCTL_ACCESS_DONE) { if (!write) { PR28829_DELAY(); *val = (R_REG(pi->osh, &(pcieregs->u.pcie1.mdiodata)) & MDIODATA_MASK); } /* Disable mdio access to SERDES */ W_REG(pi->osh, (&pcieregs->u.pcie1.mdiocontrol), 0); return 0; } OSL_DELAY(1000); i++; } PCI_ERROR(("pcie_mdioop: timed out op: %d\n", write)); /* Disable mdio access to SERDES */ W_REG(pi->osh, (&pcieregs->u.pcie1.mdiocontrol), 0); return 1; }
/* Customer function to control hw specific wlan gpios */ void dhd_customer_gpio_wlan_ctrl(int onoff) { switch (onoff) { case WLAN_RESET_OFF: WL_TRACE(("%s: call customer specific GPIO to insert WLAN RESET\n", __FUNCTION__)); #if defined(CONFIG_LGE_BCM432X_PATCH) gpio_set_value(CONFIG_BCM4329_GPIO_WL_RESET, 0); #endif #ifdef CUSTOMER_HW bcm_wlan_power_off(2); #endif /* CUSTOMER_HW */ #ifdef CUSTOMER_HW2 wifi_set_power(0, 0); #endif WL_ERROR(("=========== WLAN placed in RESET ========\n")); break; case WLAN_RESET_ON: WL_TRACE(("%s: callc customer specific GPIO to remove WLAN RESET\n", __FUNCTION__)); #if defined(CONFIG_LGE_BCM432X_PATCH) gpio_set_value(CONFIG_BCM4329_GPIO_WL_RESET, 1); mdelay(150); //mingi #endif #ifdef CUSTOMER_HW bcm_wlan_power_on(2); #endif /* CUSTOMER_HW */ #ifdef CUSTOMER_HW2 wifi_set_power(1, 0); #endif WL_ERROR(("=========== WLAN going back to live ========\n")); break; case WLAN_POWER_OFF: WL_TRACE(("%s: call customer specific GPIO to turn off WL_REG_ON\n", __FUNCTION__)); #ifdef CUSTOMER_HW bcm_wlan_power_off(1); #endif /* CUSTOMER_HW */ break; case WLAN_POWER_ON: WL_TRACE(("%s: call customer specific GPIO to turn on WL_REG_ON\n", __FUNCTION__)); #ifdef CUSTOMER_HW bcm_wlan_power_on(1); #endif /* CUSTOMER_HW */ /* Lets customer power to get stable */ OSL_DELAY(500); break; } }
/* Write a bit stream to the chip */ static void adm_write(adm_info_t *adm, int cs, uint8 *buf, uint bits) { uint i, len = (bits + 7) / 8; uint8 mask; /* CS high/low */ if (cs) si_gpioout(adm->sih, adm->eecs, adm->eecs, GPIO_DRV_PRIORITY); else si_gpioout(adm->sih, adm->eecs, 0, GPIO_DRV_PRIORITY); OSL_DELAY(EECK_EDGE_TIME); /* Byte assemble from MSB to LSB */ for (i = 0; i < len; i++) { /* Bit bang from MSB to LSB */ for (mask = 0x80; mask && bits > 0; mask >>= 1, bits --) { /* Clock low */ si_gpioout(adm->sih, adm->eesk, 0, GPIO_DRV_PRIORITY); OSL_DELAY(EECK_EDGE_TIME); /* Output on rising edge */ if (mask & buf[i]) si_gpioout(adm->sih, adm->eedi, adm->eedi, GPIO_DRV_PRIORITY); else si_gpioout(adm->sih, adm->eedi, 0, GPIO_DRV_PRIORITY); OSL_DELAY(EEDI_SETUP_TIME); /* Clock high */ si_gpioout(adm->sih, adm->eesk, adm->eesk, GPIO_DRV_PRIORITY); OSL_DELAY(EECK_EDGE_TIME); } } /* Clock low */ si_gpioout(adm->sih, adm->eesk, 0, GPIO_DRV_PRIORITY); OSL_DELAY(EECK_EDGE_TIME); /* CS low */ if (cs) si_gpioout(adm->sih, adm->eecs, 0, GPIO_DRV_PRIORITY); }
/* Customer function to control hw specific wlan gpios */ void dhd_customer_gpio_wlan_ctrl(int onoff) { switch (onoff) { case WLAN_RESET_OFF: WL_TRACE(("%s: call customer specific GPIO to insert WLAN RESET\n", __FUNCTION__)); #if defined (CUSTOMER_HW_SAMSUNG) wlan_setup_power(POWER_OFF, 2); #elif defined(CUSTOMER_HW) bcm_wlan_power_off(2); #elif defined(CUSTOMER_HW2) wifi_set_power(0, 0); #endif WL_ERROR(("=========== WLAN placed in RESET ========\n")); break; case WLAN_RESET_ON: WL_TRACE(("%s: callc customer specific GPIO to remove WLAN RESET\n", __FUNCTION__)); #if defined(CUSTOMER_HW_SAMSUNG) wlan_setup_power(POWER_ON, 2); #elif defined(CUSTOMER_HW) bcm_wlan_power_on(2); #elif defined(CUSTOMER_HW2) wifi_set_power(1, 0); #endif WL_ERROR(("=========== WLAN going back to live ========\n")); break; case WLAN_POWER_OFF: WL_TRACE(("%s: call customer specific GPIO to turn off WL_REG_ON\n", __FUNCTION__)); #if defined(CUSTOMER_HW_SAMSUNG) wlan_setup_power(POWER_OFF, 1); #elif defined(CUSTOMER_HW) bcm_wlan_power_off(1); #endif /* CUSTOMER_HW || CUSTOMER_HW_SAMSUNG */ break; case WLAN_POWER_ON: WL_TRACE(("%s: call customer specific GPIO to turn on WL_REG_ON\n", __FUNCTION__)); #if defined(CUSTOMER_HW_SAMSUNG) wlan_setup_power(POWER_ON, 1); #elif defined(CUSTOMER_HW) bcm_wlan_power_on(1); /* Lets customer power to get stable */ OSL_DELAY(50); #endif /* CUSTOMER_HW || CUSTOMER_HW_SAMSUNG */ break; } }
/* Customer function to control hw specific wlan gpios */ void dhd_customer_gpio_wlan_ctrl(int onoff) { switch (onoff) { case WLAN_RESET_OFF: WL_TRACE(("%s: call customer specific GPIO to insert WLAN RESET\n", __FUNCTION__)); #ifdef CUSTOMER_HW bcm_wlan_power_off(2); #endif /* CUSTOMER_HW */ #ifdef CUSTOMER_HW2 wifi_set_power(0, 0); #endif WL_ERROR(("=========== WLAN placed in RESET ========\n")); break; case WLAN_RESET_ON: WL_TRACE(("%s: callc customer specific GPIO to remove WLAN RESET\n", __FUNCTION__)); #ifdef CUSTOMER_HW bcm_wlan_power_on(2); #endif /* CUSTOMER_HW */ #ifdef CUSTOMER_HW2 wifi_set_power(1, 0); #endif WL_ERROR(("=========== WLAN going back to live ========\n")); break; case WLAN_POWER_OFF: WL_TRACE(("%s: call customer specific GPIO to turn off WL_REG_ON\n", __FUNCTION__)); #ifdef CUSTOMER_HW bcm_wlan_power_off(1); #endif /* CUSTOMER_HW */ remove_proc_entry("q_wlan", NULL); q_wlan_flag = 0; break; case WLAN_POWER_ON: WL_TRACE(("%s: call customer specific GPIO to turn on WL_REG_ON\n", __FUNCTION__)); entry = create_proc_read_entry("q_wlan", 0, NULL, q_proc_call, NULL); if (!entry) printk("cl: unable to create proc file.\n"); #ifdef CUSTOMER_HW bcm_wlan_power_on(1); #endif /* Lets customer power to get stable */ OSL_DELAY(50); break; } }
void pcie_watchdog_reset(osl_t *osh, si_t *sih, sbpcieregs_t *sbpcieregs) { uint32 val, i, lsc; uint16 cfg_offset[] = {PCIECFGREG_STATUS_CMD, PCIECFGREG_PM_CSR, PCIECFGREG_MSI_CAP, PCIECFGREG_MSI_ADDR_L, PCIECFGREG_MSI_ADDR_H, PCIECFGREG_MSI_DATA, PCIECFGREG_LINK_STATUS_CTRL2, PCIECFGREG_RBAR_CTRL, PCIECFGREG_PML1_SUB_CTRL1, PCIECFGREG_REG_BAR2_CONFIG, PCIECFGREG_REG_BAR3_CONFIG}; uint32 origidx = si_coreidx(sih); /* Disable/restore ASPM Control to protect the watchdog reset */ W_REG(osh, &sbpcieregs->configaddr, PCIECFGREG_LINK_STATUS_CTRL); lsc = R_REG(osh, &sbpcieregs->configdata); val = lsc & (~PCIE_ASPM_ENAB); W_REG(osh, &sbpcieregs->configdata, val); si_setcore(sih, PCIE2_CORE_ID, 0); si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, watchdog), ~0, 4); OSL_DELAY(100000); #ifdef BCMQT OSL_DELAY(200000); #endif /* BCMQT */ W_REG(osh, &sbpcieregs->configaddr, PCIECFGREG_LINK_STATUS_CTRL); W_REG(osh, &sbpcieregs->configdata, lsc); /* Write configuration registers back to the shadow registers * cause shadow registers are cleared out after watchdog reset. */ for (i = 0; i < ARRAYSIZE(cfg_offset); i++) { W_REG(osh, &sbpcieregs->configaddr, cfg_offset[i]); val = R_REG(osh, &sbpcieregs->configdata); W_REG(osh, &sbpcieregs->configdata, val); } si_setcoreidx(sih, origidx); }
static int flash_poll(unsigned long off, uint16 data) { unsigned long addr; int cnt = FLASH_TRIES; uint16 st; ASSERT(flashutl_desc != NULL); if (flashutl_desc->type == AMD || flashutl_desc->type == SST) { /* AMD style poll checkes the address being written */ addr = FLASH_ADDR(off); while ((st = flash_readword(addr)) != data && cnt != 0) { OSL_DELAY(10); cnt--; } if (cnt == 0) { DPRINT(("%s: timeout, off %lx, read 0x%x, expected 0x%x\n", __FUNCTION__, off, st, data)); return -1; } } else { /* INTEL style poll is at second word of the block being written */ addr = FLASH_ADDR(block(off, BLOCK_BASE)+sizeof(uint16)); while (((st = flash_readword(addr)) & DONE) == 0 && cnt != 0) { OSL_DELAY(10); cnt--; } if (cnt == 0) { DPRINT(("%s: timeout, error status = 0x%x\n", __FUNCTION__, st)); return -1; } } return 0; }
static void chipphyreset(struct bcm4xxx *ch, uint phyaddr) { ASSERT(phyaddr < MAXEPHY); if (phyaddr == EPHY_NOREG) return; chipphywr(ch, phyaddr, 0, CTL_RESET); OSL_DELAY(100); if (chipphyrd(ch, phyaddr, 0) & CTL_RESET) { ET_ERROR(("et%d: chipphyreset: reset not complete\n", ch->etc->unit)); } chipphyinit(ch, phyaddr); }
void dhd_customer_gpio_wlan_ctrl(int onoff) { switch (onoff) { case WLAN_RESET_OFF: WL_TRACE(("%s: call customer specific GPIO to insert WLAN RESET\n", __FUNCTION__)); #ifdef CUSTOMER_HW bcm_wlan_power_off(2); #endif #ifdef CUSTOMER_HW2 wifi_set_power(0, 0); #endif WL_ERROR(("=========== WLAN placed in RESET ========\n")); break; case WLAN_RESET_ON: WL_TRACE(("%s: callc customer specific GPIO to remove WLAN RESET\n", __FUNCTION__)); #ifdef CUSTOMER_HW bcm_wlan_power_on(2); #endif #ifdef CUSTOMER_HW2 wifi_set_power(1, 0); #endif WL_ERROR(("=========== WLAN going back to live ========\n")); break; case WLAN_POWER_OFF: WL_TRACE(("%s: call customer specific GPIO to turn off WL_REG_ON\n", __FUNCTION__)); #ifdef CUSTOMER_HW bcm_wlan_power_off(1); #endif break; case WLAN_POWER_ON: WL_TRACE(("%s: call customer specific GPIO to turn on WL_REG_ON\n", __FUNCTION__)); #ifdef CUSTOMER_HW bcm_wlan_power_on(1); OSL_DELAY(200); #endif break; } }
/* Customer function to control hw specific wlan gpios */ void dhd_customer_gpio_wlan_ctrl(int onoff) { switch (onoff) { case WLAN_RESET_OFF: WL_TRACE(("%s: call customer specific GPIO to insert WLAN RESET\n", __FUNCTION__)); #ifdef CUSTOMER_HW bcm_wlan_power_off(2); #endif /* CUSTOMER_HW */ #if defined(CUSTOMER_HW2) || defined(CUSTOMER_HW4) wifi_set_power(0, WIFI_TURNOFF_DELAY); #endif WL_ERROR(("=========== WLAN placed in RESET ========\n")); break; case WLAN_RESET_ON: WL_TRACE(("%s: callc customer specific GPIO to remove WLAN RESET\n", __FUNCTION__)); #ifdef CUSTOMER_HW bcm_wlan_power_on(2); #endif /* CUSTOMER_HW */ #if defined(CUSTOMER_HW2) || defined(CUSTOMER_HW4) wifi_set_power(1, WIFI_TURNON_DELAY); #endif WL_ERROR(("=========== WLAN going back to live ========\n")); break; case WLAN_POWER_OFF: WL_TRACE(("%s: call customer specific GPIO to turn off WL_REG_ON\n", __FUNCTION__)); #ifdef CUSTOMER_HW bcm_wlan_power_off(1); #endif /* CUSTOMER_HW */ break; case WLAN_POWER_ON: WL_TRACE(("%s: call customer specific GPIO to turn on WL_REG_ON\n", __FUNCTION__)); #ifdef CUSTOMER_HW bcm_wlan_power_on(1); /* Lets customer power to get stable */ OSL_DELAY(200); #endif /* CUSTOMER_HW */ break; } }
static bool si_buscore_prep(si_info_t *sii, uint bustype, uint devid, void *sdh) { /* need to set memseg flag for CF card first before any sb registers access */ if (BUSTYPE(bustype) == PCMCIA_BUS) sii->memseg = TRUE; if (BUSTYPE(bustype) == SDIO_BUS) { int err; uint8 clkset; /* Try forcing SDIO core to do ALPAvail request only */ clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ; bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err); if (!err) { uint8 clkval; /* If register supported, wait for ALPAvail and then force ALP */ clkval = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, NULL); if ((clkval & ~SBSDIO_AVBITS) == clkset) { SPINWAIT(((clkval = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, NULL)), !SBSDIO_ALPAV(clkval)), PMU_MAX_TRANSITION_DLY); if (!SBSDIO_ALPAV(clkval)) { SI_ERROR(("timeout on ALPAV wait, clkval 0x%02x\n", clkval)); return FALSE; } clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP; bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err); OSL_DELAY(65); } } #ifndef MMC_SDIO_FORCE_PULLUP /* Also, disable the extra SDIO pull-ups */ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SDIOPULLUP, 0, NULL); #endif } return TRUE; }
/* Customer function to control hw specific wlan gpios */ void dhd_customer_gpio_wlan_ctrl(int onoff) { switch (onoff) { case WLAN_RESET_OFF: WL_TRACE(("%s: call customer specific GPIO to insert WLAN RESET_OFF\n", __FUNCTION__)); #ifdef CUSTOMER_HW gpio_set_value(WL_RST_N, 0); #endif /* CUSTOMER_HW */ WL_ERROR(("=========== WLAN placed in RESET ========\n")); break; case WLAN_RESET_ON: WL_TRACE(("%s: callc customer specific GPIO to remove WLAN RESET_ON\n", __FUNCTION__)); #ifdef CUSTOMER_HW gpio_set_value(WL_RST_N, 1); #endif /* CUSTOMER_HW */ WL_ERROR(("=========== WLAN going back to live ========\n")); break; case WLAN_POWER_OFF: WL_TRACE(("%s: call customer specific GPIO to turn off WL_REG_OFF\n", __FUNCTION__)); #ifdef CUSTOMER_HW gpio_set_value(WL_RST_N, 0); #endif /* CUSTOMER_HW */ break; case WLAN_POWER_ON: WL_TRACE(("%s: call customer specific GPIO to turn on WL_REG_ON\n", __FUNCTION__)); #ifdef CUSTOMER_HW gpio_set_value(WL_RST_N, 1); #endif /* CUSTOMER_HW */ break; } /* Lets customer power to get stable */ OSL_DELAY(200); }
static int pciegen2_mdioop(pcicore_info_t *pi, uint physmedia, uint regaddr, bool write, uint *val, bool slave_bypass) { sbpcieregs_t *pcieregs = pi->regs.pcieregs; uint pcie_serdes_spinwait = 200, i = 0, mdio_ctrl; uint32 *reg32; if (!PCIE_GEN2(pi->sih)) ASSERT(0); pcie2_mdiosetblock(pi, physmedia); /* enable mdio access to SERDES */ mdio_ctrl = MDIOCTL2_DIVISOR_VAL; mdio_ctrl |= (regaddr << MDIOCTL2_REGADDR_SHF); if (slave_bypass) mdio_ctrl |= MDIOCTL2_SLAVE_BYPASS; if (!write) mdio_ctrl |= MDIOCTL2_READ; W_REG(pi->osh, (&pcieregs->u.pcie2.mdiocontrol), mdio_ctrl); if (write) { reg32 = (uint32 *)&(pcieregs->u.pcie2.mdiowrdata); W_REG(pi->osh, reg32, *val | MDIODATA2_DONE); } else reg32 = (uint32 *)&(pcieregs->u.pcie2.mdiorddata); /* retry till the transaction is complete */ while (i < pcie_serdes_spinwait) { if (!(R_REG(pi->osh, reg32) & MDIODATA2_DONE)) { if (!write) *val = (R_REG(pi->osh, reg32) & MDIODATA2_MASK); return 0; } OSL_DELAY(1000); i++; } return 0; }
static void reset_release_wait(void) { int gpio; uint32 gpiomask; if ((gpio = nvram_resetgpio_init ((void *)sih)) < 0) return; /* Reset button is active low */ gpiomask = (uint32)1 << gpio; while (1) { if (si_gpioin(sih) & gpiomask) { OSL_DELAY(RESET_DEBOUNCE_TIME); if (si_gpioin(sih) & gpiomask) break; } } }
int BCMINITFN(nvram_reset)(void *si) { int gpio; uint msec; si_t * sih = (si_t *)si; if ((gpio = nvram_resetgpio_init((void *)sih)) < 0) return FALSE; /* GPIO reset is asserted low */ for (msec = 0; msec < 5000; msec++) { if (si_gpioin(sih) & ((uint32) 1 << gpio)) return FALSE; OSL_DELAY(1000); } nvram_do_reset = TRUE; return TRUE; }
static bool nvram_reset(void *sbh) { chipcregs_t *cc; char *value; uint32 watchdog = 0, gpio; uint idx, msec; idx = sb_coreidx(sbh); /* Check if we were soft reset */ if ((cc = sb_setcore(sbh, SB_CC, 0))) { watchdog = R_REG(&cc->intstatus) & 0x80000000; sb_setcoreidx(sbh, idx); } if (watchdog) return FALSE; value = nvram_get("reset_gpio"); if (!value) return FALSE; gpio = (uint32) bcm_atoi(value); if (gpio > 7) return FALSE; /* Setup GPIO input */ sb_gpioouten(sbh, (1 << gpio), 0); /* GPIO reset is asserted low */ for (msec = 0; msec < 5000; msec++) { if (sb_gpioin(sbh) & (1 << gpio)) return FALSE; OSL_DELAY(1000); } return TRUE; }
int sflash_write(si_t *sih, chipcregs_t *cc, uint offset, uint length, const uchar *buffer) { struct sflash *sfl; uint off = offset, len = length; const uint8 *buf = buffer; uint8 data; int ret = 0, ntry = 0; bool is4712b0; uint32 page, byte, mask; osl_t *osh; ASSERT(sih); osh = si_osh(sih); if (!len) return 0; sfl = &sflash; if ((off + len) > sfl->size) return -22; switch (sfl->type) { case SFLASH_ST: is4712b0 = (CHIPID(sih->chip) == BCM4712_CHIP_ID) && (CHIPREV(sih->chiprev) == 3); /* Enable writes */ retry: sflash_cmd(osh, cc, SFLASH_ST_WREN); off = offset; len = length; buf = buffer; ntry++; if (is4712b0) { mask = 1 << 14; W_REG(osh, &cc->flashaddress, off); data = GET_BYTE(buf); buf++; W_REG(osh, &cc->flashdata, data); /* Set chip select */ OR_REG(osh, &cc->gpioout, mask); /* Issue a page program with the first byte */ sflash_cmd(osh, cc, SFLASH_ST_PP); ret = 1; off++; len--; while (len > 0) { if ((off & 255) == 0) { /* Page boundary, drop cs and return */ AND_REG(osh, &cc->gpioout, ~mask); OSL_DELAY(1); if (!sflash_poll(sih, cc, off)) { /* Flash rejected command */ if (ntry <= ST_RETRIES) goto retry; else return -11; } return ret; } else { /* Write single byte */ data = GET_BYTE(buf); buf++; sflash_cmd(osh, cc, data); } ret++; off++; len--; } /* All done, drop cs */ AND_REG(osh, &cc->gpioout, ~mask); OSL_DELAY(1); if (!sflash_poll(sih, cc, off)) { /* Flash rejected command */ if (ntry <= ST_RETRIES) goto retry; else return -12; } } else if (sih->ccrev >= 20) { W_REG(osh, &cc->flashaddress, off); data = GET_BYTE(buf); buf++; W_REG(osh, &cc->flashdata, data); /* Issue a page program with CSA bit set */ sflash_cmd(osh, cc, SFLASH_ST_CSA | SFLASH_ST_PP); ret = 1; off++; len--; while (len > 0) { if ((off & 255) == 0) { /* Page boundary, poll droping cs and return */ W_REG(NULL, &cc->flashcontrol, 0); OSL_DELAY(1); if (sflash_poll(sih, cc, off) == 0) { /* Flash rejected command */ SFL_MSG(("sflash: pp rejected, ntry: %d," " off: %d/%d, len: %d/%d, ret:" "%d\n", ntry, off, offset, len, length, ret)); if (ntry <= ST_RETRIES) goto retry; else return -11; } return ret; } else { /* Write single byte */ data = GET_BYTE(buf); buf++; sflash_cmd(osh, cc, SFLASH_ST_CSA | data); } ret++; off++; len--; } /* All done, drop cs & poll */ W_REG(NULL, &cc->flashcontrol, 0); OSL_DELAY(1); if (sflash_poll(sih, cc, off) == 0) { /* Flash rejected command */ SFL_MSG(("sflash: pp rejected, ntry: %d, off: %d/%d," " len: %d/%d, ret: %d\n", ntry, off, offset, len, length, ret)); if (ntry <= ST_RETRIES) goto retry; else return -12; } } else { ret = 1; W_REG(osh, &cc->flashaddress, off); data = GET_BYTE(buf); buf++; W_REG(osh, &cc->flashdata, data); /* Page program */ sflash_cmd(osh, cc, SFLASH_ST_PP); } break; case SFLASH_AT: mask = sfl->blocksize - 1; page = (off & ~mask) << 1; byte = off & mask; /* Read main memory page into buffer 1 */ if (byte || (len < sfl->blocksize)) { W_REG(osh, &cc->flashaddress, page); sflash_cmd(osh, cc, SFLASH_AT_BUF1_LOAD); /* 250 us for AT45DB321B */ SPINWAIT(sflash_poll(sih, cc, off), 1000); ASSERT(!sflash_poll(sih, cc, off)); } /* Write into buffer 1 */ for (ret = 0; (ret < (int)len) && (byte < sfl->blocksize); ret++) { W_REG(osh, &cc->flashaddress, byte++); W_REG(osh, &cc->flashdata, *buf++); sflash_cmd(osh, cc, SFLASH_AT_BUF1_WRITE); } /* Write buffer 1 into main memory page */ W_REG(osh, &cc->flashaddress, page); sflash_cmd(osh, cc, SFLASH_AT_BUF1_PROGRAM); break; } return ret; }
void osl_delay(uint usec) { OSL_DELAY(usec); }
/* Customer function to control hw specific wlan gpios */ void dhd_customer_gpio_wlan_ctrl(int onoff) { switch (onoff) { case WLAN_RESET_OFF: WL_TRACE(("%s: call customer specific GPIO to insert WLAN RESET\n", __FUNCTION__)); #ifdef CUSTOMER_HW bcm_wlan_power_off(2); #endif /* CUSTOMER_HW */ #if defined(CUSTOMER_HW2) wifi_set_power(0, WIFI_TURNOFF_DELAY); #endif #ifdef CUSTOMER_HW_AMLOGIC //extern_wifi_set_enable(0); #endif /* CUSTOMER_HW_AMLOGIC */ WL_ERROR(("=========== WLAN placed in RESET ========\n")); break; case WLAN_RESET_ON: WL_TRACE(("%s: call customer specific GPIO to remove WLAN RESET\n", __FUNCTION__)); #ifdef CUSTOMER_HW bcm_wlan_power_on(2); OSL_DELAY(200); #endif /* CUSTOMER_HW */ #if defined(CUSTOMER_HW2) wifi_set_power(1, 200); #endif #ifdef CUSTOMER_HW_AMLOGIC extern_wifi_set_enable(0); mdelay(200); extern_wifi_set_enable(1); mdelay(200); sdio_reinit(); #endif /* CUSTOMER_HW_AMLOGIC */ mdelay(100); WL_ERROR(("=========== WLAN going back to live ========\n")); break; case WLAN_POWER_OFF: WL_TRACE(("%s: call customer specific GPIO to turn off WL_REG_ON\n", __FUNCTION__)); #ifdef CUSTOMER_HW bcm_wlan_power_off(1); #endif /* CUSTOMER_HW */ #ifdef CUSTOMER_HW_AMLOGIC extern_wifi_set_enable(0); #endif /* CUSTOMER_HW_AMLOGIC */ WL_ERROR(("=========== WLAN placed in POWER OFF ========\n")); break; case WLAN_POWER_ON: WL_TRACE(("%s: call customer specific GPIO to turn on WL_REG_ON\n", __FUNCTION__)); #ifdef CUSTOMER_HW bcm_wlan_power_on(1); #endif /* CUSTOMER_HW */ #ifdef CUSTOMER_HW_AMLOGIC extern_wifi_set_enable(0); mdelay(200); extern_wifi_set_enable(1); mdelay(200); sdio_reinit(); #endif /* CUSTOMER_HW_AMLOGIC */ /* Lets customer power to get stable */ OSL_DELAY(200); WL_ERROR(("=========== WLAN placed in POWER ON ========\n")); break; } }
/* Customer function to control hw specific wlan gpios */ void dhd_customer_gpio_wlan_ctrl(int onoff) { #if defined CONFIG_MMC_SUNXI_POWER_CONTROL unsigned int mod_sel = mmc_pm_get_mod_type(); if (mod_sel != 6) { printk("Config Error: not for huawei mw269x sdio wifi module\n"); } #endif switch (onoff) { case WLAN_RESET_OFF: WL_TRACE(("%s: call customer specific GPIO to insert WLAN RESET\n", __FUNCTION__)); #if defined CONFIG_MMC_SUNXI_POWER_CONTROL mmc_pm_gpio_ctrl("hw_mw269x_wl_enb", 0); #endif #ifdef CUSTOMER_HW bcm_wlan_power_off(2); #endif /* CUSTOMER_HW */ #ifdef CUSTOMER_HW2 wifi_set_power(0, 0); #endif WL_ERROR(("=========== WLAN placed in RESET ========\n")); break; case WLAN_RESET_ON: WL_TRACE(("%s: callc customer specific GPIO to remove WLAN RESET\n", __FUNCTION__)); #if defined CONFIG_MMC_SUNXI_POWER_CONTROL mmc_pm_gpio_ctrl("hw_mw269x_wl_enb", 1); #endif #ifdef CUSTOMER_HW bcm_wlan_power_on(2); #endif /* CUSTOMER_HW */ #ifdef CUSTOMER_HW2 wifi_set_power(1, 0); #endif WL_ERROR(("=========== WLAN going back to live ========\n")); OSL_DELAY(10000); break; case WLAN_POWER_OFF: WL_TRACE(("%s: call customer specific GPIO to turn off WL_REG_ON\n", __FUNCTION__)); #if defined CONFIG_MMC_SUNXI_POWER_CONTROL mmc_pm_gpio_ctrl("hw_mw269x_wl_enb", 0); sunximmc_rescan_card(SDIOID, 0); #endif #ifdef CUSTOMER_HW bcm_wlan_power_off(1); #endif /* CUSTOMER_HW */ break; case WLAN_POWER_ON: WL_TRACE(("%s: call customer specific GPIO to turn on WL_REG_ON\n", __FUNCTION__)); #if defined CONFIG_MMC_SUNXI_POWER_CONTROL mmc_pm_gpio_ctrl("hw_mw269x_wl_enb", 1); #endif #ifdef CUSTOMER_HW bcm_wlan_power_on(1); #endif /* CUSTOMER_HW */ /* Lets customer power to get stable */ OSL_DELAY(200); #if defined CONFIG_MMC_SUNXI_POWER_CONTROL sunximmc_rescan_card(SDIOID, 1); #endif /* CUSTOMER_HW */ break; } }