void sd_f0_write8(struct intf_hdl *pintfhdl, u32 addr, u8 v, s32 *err) { PADAPTER padapter; struct dvobj_priv *psdiodev; PSDIO_DATA psdio; struct sdio_func *func; bool claim_needed; _func_enter_; padapter = pintfhdl->padapter; psdiodev = pintfhdl->pintf_dev; psdio = &psdiodev->intf_data; if(padapter->bSurpriseRemoved){ //DBG_871X(" %s (padapter->bSurpriseRemoved )!!!\n",__FUNCTION__); return; } func = psdio->func; claim_needed = rtw_sdio_claim_host_needed(func); if (claim_needed) sdio_claim_host(func); sdio_f0_writeb(func, v, addr, err); if (claim_needed) sdio_release_host(func); if (err && *err) DBG_871X(KERN_ERR "%s: FAIL!(%d) addr=0x%05x val=0x%02x\n", __func__, *err, addr, v); _func_exit_; }
/** * @brief This function updates card reg based on the Cmd52 value in dev structure * * @param priv A pointer to bt_private structure * @param func A pointer to store func variable * @param reg A pointer to store reg variable * @param val A pointer to store val variable * @return BT_STATUS_SUCCESS or BT_STATUS_FAILURE */ int sd_write_cmd52_val(bt_private * priv, int func, int reg, int val) { int ret = BT_STATUS_SUCCESS; struct sdio_mmc_card *card = (struct sdio_mmc_card *) priv->bt_dev.card; ENTER(); if (val >= 0) { /* Perform actual write only if val is provided */ sdio_claim_host(card->func); if (func) sdio_writeb(card->func, val, reg, &ret); else sdio_f0_writeb(card->func, val, reg, &ret); sdio_release_host(card->func); if (ret) { PRINTM(ERROR, "Cannot write value (0x%x) to func %d reg %d\n", val, func, reg); goto done; } priv->bt_dev.cmd52_val = val; } /* Save current func and reg for future read */ priv->bt_dev.cmd52_func = func; priv->bt_dev.cmd52_reg = reg; done: LEAVE(); return ret; }
static int generic_write_bytes(unsigned int uFunc, unsigned int uHwAddr, unsigned char *pData, unsigned int uLen, unsigned int bIncAddr, unsigned int bMore) { unsigned int i; int ret; PDEBUG("%s: uFunc %d uHwAddr %d pData %x uLen %d\n", __func__, uFunc, uHwAddr, (unsigned int) pData, uLen); BUG_ON(uFunc != SDIO_CTRL_FUNC && uFunc != SDIO_WLAN_FUNC); for (i = 0; i < uLen; i++) { if (uFunc == 0) sdio_f0_writeb(tiwlan_func[uFunc], *pData, uHwAddr, &ret); else sdio_writeb(tiwlan_func[uFunc], *pData, uHwAddr, &ret); if (0 != ret) { printk(KERN_ERR "%s: function %d sdio error: %d\n", __func__, uFunc, ret); return -1; } pData++; if (bIncAddr) uHwAddr++; } return 0; }
int bcmsdio_set_blk_size(int func, unsigned int blk_size) { struct sdio_func *function = func_data[BCM_SDIO_FN1]->func; int ret = 0; if (function == NULL) { BCM_DEBUG_PRINT(ERROR_LEVEL, KERN_ALERT " ***Error: %s %d ***\n", __func__, __LINE__); return -ENON_INTF_ERR; } sdio_claim_host(function); if(func != BCM_SDIO_FN0) ret = sdio_set_block_size(function, blk_size); else { BCM_SDIO_FN0_BLK_SIZE = blk_size; sdio_f0_writeb(function,BCM_SDIO_FN0_BLK_SIZE & 0xFF, 0x10, &ret); if(ret < 0) { BCM_DEBUG_PRINT(debuglevel, KERN_ALERT "failed to set the f0 block size"); } sdio_f0_writeb(function,(BCM_SDIO_FN0_BLK_SIZE >> 8) &0xFF , 0x11, &ret); if(ret < 0) { BCM_DEBUG_PRINT(debuglevel, KERN_ALERT "failed to set the f0 block size"); } } sdio_release_host(function); return ret; }
static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf, size_t len, bool fixed) { int ret; struct sdio_func *func = wl_to_func(wl); sdio_claim_host(func); if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) { sdio_f0_writeb(func, ((u8 *)buf)[0], addr, &ret); wl1271_debug(DEBUG_SDIO, "sdio write 52 addr 0x%x, byte 0x%02x", addr, ((u8 *)buf)[0]); } else { wl1271_debug(DEBUG_SDIO, "sdio write 53 addr 0x%x, %zu bytes", addr, len); wl1271_dump_ascii(DEBUG_SDIO, "data: ", buf, len); if (fixed) ret = sdio_writesb(func, addr, buf, len); else ret = sdio_memcpy_toio(func, addr, buf, len); } sdio_release_host(func); if (ret) wl1271_error("sdio write failed (%d)", ret); }
static inline int brcmf_sdioh_f0_write_byte(struct brcmf_sdio_dev *sdiodev, uint regaddr, u8 *byte) { struct sdio_func *sdfunc = sdiodev->func[0]; int err_ret; /* * Can only directly write to some F0 registers. * Handle F2 enable/disable and Abort command * as a special case. */ if (regaddr == SDIO_CCCR_IOEx) { sdfunc = sdiodev->func[2]; if (sdfunc) { sdio_claim_host(sdfunc); if (*byte & SDIO_FUNC_ENABLE_2) { /* Enable Function 2 */ err_ret = sdio_enable_func(sdfunc); if (err_ret) brcmf_dbg(ERROR, "enable F2 failed:%d\n", err_ret); } else { /* Disable Function 2 */ err_ret = sdio_disable_func(sdfunc); if (err_ret) brcmf_dbg(ERROR, "Disable F2 failed:%d\n", err_ret); } sdio_release_host(sdfunc); } } else if ((regaddr == SDIO_CCCR_ABORT) || (regaddr == SDIO_CCCR_IENx)) { sdfunc = kmemdup(sdiodev->func[0], sizeof(struct sdio_func), GFP_KERNEL); if (!sdfunc) return -ENOMEM; sdfunc->num = 0; sdio_claim_host(sdfunc); sdio_writeb(sdfunc, *byte, regaddr, &err_ret); sdio_release_host(sdfunc); kfree(sdfunc); } else if (regaddr < 0xF0) { brcmf_dbg(ERROR, "F0 Wr:0x%02x: write disallowed\n", regaddr); err_ret = -EPERM; } else { sdio_claim_host(sdfunc); sdio_f0_writeb(sdfunc, *byte, regaddr, &err_ret); sdio_release_host(sdfunc); } return err_ret; }
void sdio_io_writeb(struct esp_pub *epub, u8 value, int addr, int *res) { struct esp_sdio_ctrl *sctrl = NULL; struct sdio_func *func = NULL; sctrl = (struct esp_sdio_ctrl *)epub->sif; func = sctrl->func; if(func->num == 0) sdio_f0_writeb(func, value, addr, res); else sdio_writeb(func, value, addr, res); sif_platform_check_r1_ready(epub); }
int bcmsdio_cmd52(unsigned int data, unsigned addr, unsigned rw, unsigned func,int *perrval) { struct sdio_func *function = func_data[BCM_SDIO_FN1]->func; int ret = data; int count = 0; *perrval = 0; if (function == NULL) { BCM_DEBUG_PRINT(ERROR_LEVEL, KERN_ALERT " ** NULL FUNC PTR: x%x\n", func); return -ENON_INTF_ERR; } sdio_claim_host(function); if(func_data[BCM_SDIO_FN1]->bremoved) { ret = -ENON_INTF_ERR; BCM_DEBUG_PRINT(ERROR_LEVEL, KERN_ALERT "Error: bremoved is non zero :%d", func_data[BCM_SDIO_FN1]->bremoved); goto rel_host; } while ( count < SDIO_CMD_RETRIES ) { if (rw) { if(func != BCM_SDIO_FN0) sdio_writeb(function, data, addr,perrval); else sdio_f0_writeb(function, data, addr,perrval); } else { if(func != 0 ) ret = sdio_readb(function, addr,perrval); else ret = sdio_f0_readb(function,addr,perrval); } if(!(*perrval)) break; count++; } if(count) BCM_DEBUG_PRINT(debuglevel, "Count is higher than 0 for cmd52: %x\n", count); if(*perrval) { BCM_DEBUG_PRINT(debuglevel, "ERR IN CMD52 %d rw: %x addr: %x, count: %x\n", *perrval, rw, addr, count); } rel_host: sdio_release_host(function); return ret; }
static inline int brcmf_sdioh_f0_write_byte(struct brcmf_sdio_dev *sdiodev, uint regaddr, u8 *byte) { struct sdio_func *sdfunc = sdiodev->func[0]; int err_ret; if (regaddr == SDIO_CCCR_IOEx) { sdfunc = sdiodev->func[2]; if (sdfunc) { sdio_claim_host(sdfunc); if (*byte & SDIO_FUNC_ENABLE_2) { err_ret = sdio_enable_func(sdfunc); if (err_ret) brcmf_dbg(ERROR, "enable F2 failed:%d\n", err_ret); } else { err_ret = sdio_disable_func(sdfunc); if (err_ret) brcmf_dbg(ERROR, "Disable F2 failed:%d\n", err_ret); } sdio_release_host(sdfunc); } } else if (regaddr == SDIO_CCCR_ABORT) { sdfunc = kmemdup(sdiodev->func[0], sizeof(struct sdio_func), GFP_KERNEL); if (!sdfunc) return -ENOMEM; sdfunc->num = 0; sdio_claim_host(sdfunc); sdio_writeb(sdfunc, *byte, regaddr, &err_ret); sdio_release_host(sdfunc); kfree(sdfunc); } else if (regaddr < 0xF0) { brcmf_dbg(ERROR, "F0 Wr:0x%02x: write disallowed\n", regaddr); err_ret = -EPERM; } else { sdio_claim_host(sdfunc); sdio_f0_writeb(sdfunc, *byte, regaddr, &err_ret); sdio_release_host(sdfunc); } return err_ret; }
void sd_f0_write8(PSDIO_DATA psdio, u32 addr, u8 v, s32 *err) { struct sdio_func *func; _func_enter_; func = psdio->func; sdio_claim_host(func); sdio_f0_writeb(func, v, addr, err); sdio_release_host(func); if (err && *err) DBG_871X(KERN_ERR "%s: FAIL!(%d) addr=0x%05x val=0x%02x\n", __func__, *err, addr, v); _func_exit_; }
/** * @brief This function updates card reg based on the Cmd52 value in dev structure * * @param handle A pointer to moal_handle structure * @param func A pointer to store func variable * @param reg A pointer to store reg variable * @param val A pointer to store val variable * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE */ int woal_sdio_read_write_cmd52(moal_handle *handle, int func, int reg, int val) { int ret = MLAN_STATUS_SUCCESS; struct sdio_mmc_card *card = (struct sdio_mmc_card *)handle->card; ENTER(); /* Save current func and reg for read */ handle->cmd52_func = func; handle->cmd52_reg = reg; sdio_claim_host(card->func); if (val >= 0) { /* Perform actual write only if val is provided */ if (func) sdio_writeb(card->func, val, reg, &ret); else sdio_f0_writeb(card->func, val, reg, &ret); if (ret) { PRINTM(MERROR, "Cannot write value (0x%x) to func %d reg 0x%x\n", val, func, reg); } else { PRINTM(MMSG, "write value (0x%x) to func %d reg 0x%x\n", (u8)val, func, reg); handle->cmd52_val = val; } } else { if (func) val = sdio_readb(card->func, reg, &ret); else val = sdio_f0_readb(card->func, reg, &ret); if (ret) { PRINTM(MERROR, "Cannot read value from func %d reg 0x%x\n", func, reg); } else { PRINTM(MMSG, "read value (0x%x) from func %d reg 0x%x\n", (u8)val, func, reg); handle->cmd52_val = val; } } sdio_release_host(card->func); LEAVE(); return ret; }
/** * @brief This function reads multiple bytes from card memory * * @param handle A Pointer to the moal_handle structure * @param pmbuf Pointer to mlan_buffer structure * @param port Port * @param timeout Time out value * * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE */ mlan_status woal_read_data_sync(moal_handle *handle, mlan_buffer *pmbuf, t_u32 port, t_u32 timeout) { mlan_status ret = MLAN_STATUS_FAILURE; t_u8 *buffer = (t_u8 *)(pmbuf->pbuf + pmbuf->data_offset); t_u8 blkmode = (port & MLAN_SDIO_BYTE_MODE_MASK) ? BYTE_MODE : BLOCK_MODE; t_u32 blksz = (blkmode == BLOCK_MODE) ? MLAN_SDIO_BLOCK_SIZE : 1; t_u32 blkcnt = (blkmode == BLOCK_MODE) ? (pmbuf->data_len / MLAN_SDIO_BLOCK_SIZE) : pmbuf->data_len; t_u32 ioport = (port & MLAN_SDIO_IO_PORT_MASK); int status = 0; if (pmbuf->use_count > 1) return woal_sdio_rw_mb(handle, pmbuf, port, MFALSE); #ifdef SDIO_MMC_DEBUG handle->cmd53r = 1; #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32) sdio_claim_host(((struct sdio_mmc_card *)handle->card)->func); #endif status = sdio_readsb(((struct sdio_mmc_card *)handle->card)->func, buffer, ioport, blkcnt * blksz); if (!status) { ret = MLAN_STATUS_SUCCESS; } else { PRINTM(MERROR, "cmd53 read error=%d\n", status); #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0) /* issue abort cmd52 command through F0*/ sdio_f0_writeb(((struct sdio_mmc_card *)handle->card)->func, 0x01, SDIO_CCCR_ABORT, &status); #endif } #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32) sdio_release_host(((struct sdio_mmc_card *)handle->card)->func); #endif #ifdef SDIO_MMC_DEBUG handle->cmd53r = 2; #endif return ret; }
static int generic_write_bytes(unsigned int uFunc, unsigned int uHwAddr, unsigned char *pData, unsigned int uLen, unsigned int bIncAddr, unsigned int bMore) { unsigned int i; int ret; PDEBUG("%s: uFunc %d uHwAddr %d pData %x uLen %d\n", __func__, uFunc, uHwAddr, (unsigned int) pData, uLen); BUG_ON(uFunc != SDIO_CTRL_FUNC && uFunc != SDIO_WLAN_FUNC); for (i = 0; i < uLen; i++) { if (uFunc == 0) { if (uHwAddr < 0xF0 || uHwAddr > 0xFF) { ret = mmc_io_rw_direct(tiwlan_func[uFunc]->card, 1, uFunc, uHwAddr, *pData, NULL); if (ret != 0) printk("%s: mmc_io_rw_direct error\n", __func__); } else { sdio_f0_writeb(tiwlan_func[uFunc], *pData, uHwAddr, &ret); if (ret != 0) printk(KERN_ERR "sdio_f0_writeb: function %d sdio error: %d\n", __func__, uFunc, ret); } } else { sdio_writeb(tiwlan_func[uFunc], *pData, uHwAddr, &ret); } if (0 != ret) { printk(KERN_ERR "%s: function %d sdio error: %d\n", __func__, uFunc, ret); return -1; } pData++; if (bIncAddr) uHwAddr++; } return 0; }
static int __must_check wl12xx_sdio_raw_write(struct device *child, int addr, void *buf, size_t len, bool fixed) { int ret; struct wl12xx_sdio_glue *glue = dev_get_drvdata(child->parent); struct sdio_func *func = dev_to_sdio_func(glue->dev); sdio_claim_host(func); if (unlikely(dump)) { printk(KERN_DEBUG "wlcore_sdio: WRITE to 0x%04x\n", addr); print_hex_dump(KERN_DEBUG, "wlcore_sdio: WRITE ", DUMP_PREFIX_OFFSET, 16, 1, buf, len, false); } if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG)) { sdio_f0_writeb(func, ((u8 *)buf)[0], addr, &ret); dev_dbg(child->parent, "sdio write 52 addr 0x%x, byte 0x%02x\n", addr, ((u8 *)buf)[0]); } else { dev_dbg(child->parent, "sdio write 53 addr 0x%x, %zu bytes\n", addr, len); if (fixed) ret = sdio_writesb(func, addr, buf, len); else ret = sdio_memcpy_toio(func, addr, buf, len); } sdio_release_host(func); if (WARN_ON(ret)) dev_err(child->parent, "sdio write failed (%d)\n", ret); return ret; }
static int cw1200_request_irq(struct hwbus_priv *self) { int ret; u8 cccr; cccr = sdio_f0_readb(self->func, SDIO_CCCR_IENx, &ret); if (WARN_ON(ret)) goto err; /* Master interrupt enable ... */ cccr |= BIT(0); /* ... for our function */ cccr |= BIT(self->func->num); sdio_f0_writeb(self->func, cccr, SDIO_CCCR_IENx, &ret); if (WARN_ON(ret)) goto err; ret = enable_irq_wake(self->pdata->irq); if (WARN_ON(ret)) goto err; /* Request the IRQ */ ret = request_threaded_irq(self->pdata->irq, cw1200_gpio_hardirq, cw1200_gpio_irq, IRQF_TRIGGER_HIGH | IRQF_ONESHOT, "cw1200_wlan_irq", self); if (WARN_ON(ret)) goto err; return 0; err: return ret; }
/** * @brief This function use SG mode to read/write data into card memory * * @param handle A Pointer to the moal_handle structure * @param pmbuf_list Pointer to a linked list of mlan_buffer structure * @param port Port * @param write write flag * * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE */ mlan_status woal_sdio_rw_mb(moal_handle *handle, pmlan_buffer pmbuf_list, t_u32 port, t_u8 write) { struct scatterlist sg_list[SDIO_MP_AGGR_DEF_PKT_LIMIT_MAX]; int num_sg = pmbuf_list->use_count; int i = 0; mlan_buffer *pmbuf = NULL; struct mmc_request mmc_req; struct mmc_command mmc_cmd; struct mmc_data mmc_dat; struct sdio_func *func = ((struct sdio_mmc_card *)handle->card)->func; t_u32 ioport = (port & MLAN_SDIO_IO_PORT_MASK); t_u32 blkcnt = pmbuf_list->data_len / MLAN_SDIO_BLOCK_SIZE; int status; if (num_sg > SDIO_MP_AGGR_DEF_PKT_LIMIT_MAX) { PRINTM(MERROR, "ERROR: num_sg=%d", num_sg); return MLAN_STATUS_FAILURE; } sg_init_table(sg_list, num_sg); pmbuf = pmbuf_list->pnext; for (i = 0; i < num_sg; i++) { if (pmbuf == pmbuf_list) break; sg_set_buf(&sg_list[i], pmbuf->pbuf + pmbuf->data_offset, pmbuf->data_len); pmbuf = pmbuf->pnext; } memset(&mmc_req, 0, sizeof(struct mmc_request)); memset(&mmc_cmd, 0, sizeof(struct mmc_command)); memset(&mmc_dat, 0, sizeof(struct mmc_data)); mmc_dat.sg = sg_list; mmc_dat.sg_len = num_sg; mmc_dat.blksz = MLAN_SDIO_BLOCK_SIZE; mmc_dat.blocks = blkcnt; mmc_dat.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ; mmc_cmd.opcode = SD_IO_RW_EXTENDED; mmc_cmd.arg = write ? 1 << 31 : 0; mmc_cmd.arg |= (func->num & 0x7) << 28; mmc_cmd.arg |= 1 << 27; /* block basic */ mmc_cmd.arg |= 0; /* fix address */ mmc_cmd.arg |= (ioport & 0x1FFFF) << 9; mmc_cmd.arg |= blkcnt & 0x1FF; mmc_cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC; mmc_req.cmd = &mmc_cmd; mmc_req.data = &mmc_dat; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32) sdio_claim_host(((struct sdio_mmc_card *)handle->card)->func); #endif mmc_set_data_timeout(&mmc_dat, ((struct sdio_mmc_card *)handle->card)->func-> card); mmc_wait_for_req(((struct sdio_mmc_card *)handle->card)->func->card-> host, &mmc_req); if (mmc_cmd.error || mmc_dat.error) { PRINTM(MERROR, "CMD53 %s cmd_error = %d data_error=%d\n", write ? "write" : "read", mmc_cmd.error, mmc_dat.error); #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0) /* issue abort cmd52 command through F0*/ sdio_f0_writeb(((struct sdio_mmc_card *)handle->card)->func, 0x01, SDIO_CCCR_ABORT, &status); #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32) sdio_release_host(((struct sdio_mmc_card *)handle->card)->func); #endif return MLAN_STATUS_FAILURE; } #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32) sdio_release_host(((struct sdio_mmc_card *)handle->card)->func); #endif return MLAN_STATUS_SUCCESS; }