⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 atheros_2_0_hcd.patch

📁 openmoko 使用的sdio wifi驱动源码
💻 PATCH
📖 第 1 页 / 共 4 页
字号:
+	if (req == NULL) {+		DBG_PRINT(SDDBG_TRACE, ("%s(): No current request\n", __FUNCTION__));+		goto out;+	}++	if (cmdsta & S3C2410_SDICMDSTAT_CMDTIMEOUT) {+		DBG_PRINT(SDDBG_ERROR, ("TIMEOUT\n"));+		printk("TIMEOUT\n");+		req->Status = SDIO_STATUS_BUS_RESP_TIMEOUT;+		writel(S3C2410_SDICMDSTAT_CMDTIMEOUT, context->base + S3C2410_SDICMDSTAT);+		schedule_work(&context->io_work);+	}++	if (cmdsta & S3C2410_SDICMDSTAT_CRCFAIL) {+		DBG_PRINT(SDDBG_ERROR, ("CRCFAIL 0x%x\n", cmdsta));+		printk("CRCFAIL 0x%x\n", cmdsta);+		req->Status = SDIO_STATUS_BUS_RESP_CRC_ERR;+		dump_request(context);+		writel(S3C2410_SDICMDSTAT_CRCFAIL, context->base + S3C2410_SDICMDSTAT);+		schedule_work(&context->io_work);+	}+++	if (cmdsta & S3C2410_SDICMDSTAT_CMDSENT) {+		writel(S3C2410_SDICMDSTAT_CMDSENT, context->base + S3C2410_SDICMDSTAT);++		if (context->complete == S3C24XX_HCD_NO_RESPONSE) {+			req->Status = SDIO_STATUS_SUCCESS;+			trace = 1;+			schedule_work(&context->io_work);+		}+	}++	if (cmdsta & S3C2410_SDICMDSTAT_RSPFIN ||+	    (IS_SDREQ_WRITE_DATA(req->Flags) && (fsta &  S3C2410_SDIFSTA_TFDET)) ||+	    (!IS_SDREQ_WRITE_DATA(req->Flags) && (fsta &  S3C2410_SDIFSTA_RFDET))) {++		writel(S3C2410_SDICMDSTAT_RSPFIN, context->base + S3C2410_SDICMDSTAT);++		if (context->complete == S3C24XX_HCD_RESPONSE_SHORT ||+		    context->complete == S3C24XX_HCD_RESPONSE_LONG ||+		    context->complete == S3C24XX_HCD_DATA_READ ||+		    context->complete == S3C24XX_HCD_DATA_WRITE) {+			req->Status = SDIO_STATUS_SUCCESS;+			if (trace)+				printk("IO work already scheduled, cmdsta: 0x%x\n", cmdsta);+			schedule_work(&context->io_work);+		}+	}++ out:+	if (dsta & S3C2410_SDIDSTA_RDYWAITREQ) {+		printk("S3C2410_SDIDSTA_RDYWAITREQ\n");+		//writel(S3C2410_SDIDSTA_RDYWAITREQ, context->base + S3C2410_SDIDSTA);+	}++	if (dsta & S3C2410_SDIDSTA_FIFOFAIL) {+		printk("S3C2410_SDIDSTA_FIFOFAIL\n");+		writel(S3C2410_SDIDSTA_FIFOFAIL, context->base + S3C2410_SDIDSTA);+	}++	if (dsta & S3C2410_SDIDSTA_CRCFAIL) {+		printk("S3C2410_SDIDSTA_CRCFAIL\n");+		writel(S3C2410_SDIDSTA_CRCFAIL, context->base + S3C2410_SDIDSTA);+	}++	if (dsta & S3C2410_SDIDSTA_RXCRCFAIL) {+		printk("S3C2410_SDIDSTA_RXCRCFAIL\n");+		writel(S3C2410_SDIDSTA_RXCRCFAIL, context->base + S3C2410_SDIDSTA);+	}++	if (dsta & S3C2410_SDIDSTA_DATATIMEOUT) {+		printk("S3C2410_SDIDSTA_DATATIMEOUT\n");+		writel(S3C2410_SDIDSTA_DATATIMEOUT, context->base + S3C2410_SDIDSTA);+	}++	if (dsta & S3C2410_SDIDSTA_BUSYFINISH) {+		printk("S3C2410_SDIDSTA_BUSYFINISH\n");+		writel(S3C2410_SDIDSTA_BUSYFINISH, context->base + S3C2410_SDIDSTA);+	}++	if (dsta & S3C2410_SDIDSTA_SBITERR) {+		printk("S3C2410_SDIDSTA_SBIERR\n");+		writel(S3C2410_SDIDSTA_SBITERR, context->base + S3C2410_SDIDSTA);+	}++	spin_unlock_irqrestore(&context->lock, flags);+	return IRQ_HANDLED;+}+++SDIO_STATUS s3c24xx_hcd_config(PSDHCD hcd, PSDCONFIG config)+{+	u32 con, imsk;+	SDIO_STATUS status = SDIO_STATUS_SUCCESS;+	PSDCONFIG_SDIO_INT_CTRL_DATA int_data;+	struct s3c24xx_hcd_context * context = (struct s3c24xx_hcd_context *)hcd->pContext;++	switch (GET_SDCONFIG_CMD(config)){+	case SDCONFIG_GET_WP:+		DBG_PRINT(SDDBG_TRACE, ("config GET_WP\n"));+		*((SDCONFIG_WP_VALUE *)config->pData) = 0;+		status = SDIO_STATUS_SUCCESS;+		break;+	case SDCONFIG_SEND_INIT_CLOCKS:+		DBG_PRINT(SDDBG_TRACE, ("config SEND_INIT_CLOCKS\n"));++		/* We stop/start the clock */+		con = readl(context->base + S3C2410_SDICON);++		con &= ~S3C2410_SDICON_CLOCKTYPE;+		writel(con, context->base + S3C2410_SDICON);++		mdelay(100);++		con |= S3C2410_SDICON_CLOCKTYPE;+		writel(con, context->base + S3C2410_SDICON);++		mdelay(100);++		status = SDIO_STATUS_SUCCESS;+		break;+        case SDCONFIG_SDIO_INT_CTRL:+		DBG_PRINT(SDDBG_TRACE, ("config SDIO_INT_CTRL\n"));+		int_data =  GET_SDCONFIG_CMD_DATA(PSDCONFIG_SDIO_INT_CTRL_DATA, config);++		if (int_data->SlotIRQEnable &+		    (IRQ_DETECT_1_BIT | IRQ_DETECT_4_BIT | IRQ_DETECT_MULTI_BLK) ) {+			imsk = readl(context->base + S3C2440_SDIIMSK);++			if (int_data->SlotIRQEnable) {+				printk("SDIO_INT_CTRL enable IRQ\n");+				DBG_PRINT(SDDBG_TRACE, ("SDIO_INT_CTRL enable IRQ\n"));+				context->int_sdio = 1;+				imsk |= S3C2410_SDIIMSK_SDIOIRQ;+				writel(imsk, context->base + S3C2440_SDIIMSK);+			} else {+				printk("SDIO_INT_CTRL disable IRQ\n");+				DBG_PRINT(SDDBG_TRACE, ("SDIO_INT_CTRL disable IRQ\n"));+				context->int_sdio = 0;+				imsk &= ~S3C2410_SDIIMSK_SDIOIRQ;+				writel(imsk, context->base + S3C2440_SDIIMSK);+			}+		}+		status = SDIO_STATUS_SUCCESS;+		break;+        case SDCONFIG_SDIO_REARM_INT:+		DBG_PRINT(SDDBG_TRACE, ("config SDIO_REARM_INT\n"));++		context->int_sdio = 1;+		imsk = readl(context->base + S3C2440_SDIIMSK);+		imsk |= S3C2410_SDIIMSK_SDIOIRQ;+		writel(imsk, context->base + S3C2440_SDIIMSK);++		status = SDIO_STATUS_SUCCESS;+		break;+	case SDCONFIG_FUNC_CHANGE_BUS_MODE:+        case SDCONFIG_BUS_MODE_CTRL:+		s3c24xx_hcd_set_bus_mode(context, (PSDCONFIG_BUS_MODE_DATA)(config->pData));+		DBG_PRINT(SDDBG_TRACE, ("config BUS_MODE_CTRL\n"));+		status = SDIO_STATUS_SUCCESS;+		break;+        case SDCONFIG_POWER_CTRL:+		DBG_PRINT(SDDBG_TRACE, ("config POWER_CTRL\n"));+		status = SDIO_STATUS_SUCCESS;+		break;+        case SDCONFIG_GET_HCD_DEBUG:+		DBG_PRINT(SDDBG_TRACE, ("config GET_HCD_DEBUG\n"));+		status = SDIO_STATUS_SUCCESS;+		break;+        case SDCONFIG_SET_HCD_DEBUG:+		DBG_PRINT(SDDBG_TRACE, ("config SET_HCD_DEBUG\n"));+		status = SDIO_STATUS_SUCCESS;+		break;+	default:+		/* invalid request */+		DBG_PRINT(SDDBG_ERROR, ("%s() - unsupported command: 0x%X\n",+				       __FUNCTION__, GET_SDCONFIG_CMD(config)));+		status = SDIO_STATUS_INVALID_PARAMETER;+	}++	return SDIOErrorToOSError(status);+}+++SDIO_STATUS s3c24xx_hcd_request(PSDHCD hcd)+{+	SDIO_STATUS status = SDIO_STATUS_PENDING;+	PSDREQUEST req;+	u32 cmdcon, imask;+	unsigned long flags;+	struct s3c24xx_hcd_context * context =+		(struct s3c24xx_hcd_context *)hcd->pContext;++	req = GET_CURRENT_REQUEST(hcd);+	DBG_ASSERT(req != NULL);++	if (req->Flags & SDREQ_FLAGS_DATA_SHORT_TRANSFER)+		printk("### SHORT TRANSFER ###\n");++	spin_lock_irqsave(&context->lock, flags);++	/* Clear command, data and fifo status registers */+	writel(0xFFFFFFFF, context->base + S3C2410_SDICMDSTAT);+	writel(0xFFFFFFFF, context->base + S3C2410_SDIDSTA);+	writel(0xFFFFFFFF, context->base + S3C2410_SDIFSTA);++	/* Enabling irqs */+	imask = S3C2410_SDIIMSK_READWAIT;++	cmdcon = readl(context->base + S3C2410_SDICMDCON);++        switch (GET_SDREQ_RESP_TYPE(req->Flags)) {+	case SDREQ_FLAGS_NO_RESP:+		cmdcon &= ~S3C2410_SDICMDCON_WAITRSP;+		context->complete = S3C24XX_HCD_NO_RESPONSE;+		imask |= S3C2410_SDIIMSK_CMDSENT;+                break;+	case SDREQ_FLAGS_RESP_R1:+	case SDREQ_FLAGS_RESP_R1B:+	case SDREQ_FLAGS_RESP_R3:+	case SDREQ_FLAGS_RESP_SDIO_R4:+	case SDREQ_FLAGS_RESP_SDIO_R5:+	case SDREQ_FLAGS_RESP_R6:+		cmdcon &= ~S3C2410_SDICMDCON_LONGRSP;+		cmdcon |= S3C2410_SDICMDCON_WAITRSP;+		context->complete = S3C24XX_HCD_RESPONSE_SHORT;+		imask |= S3C2410_SDIIMSK_CRCSTATUS | S3C2410_SDIIMSK_RESPONSEND+			| S3C2410_SDIIMSK_CMDTIMEOUT | S3C2410_SDIIMSK_RESPONSECRC;+                break;+	case SDREQ_FLAGS_RESP_R2:+		cmdcon |= S3C2410_SDICMDCON_LONGRSP;+		cmdcon |= S3C2410_SDICMDCON_WAITRSP;+		context->complete = S3C24XX_HCD_RESPONSE_LONG;+		imask |= S3C2410_SDIIMSK_CRCSTATUS | S3C2410_SDIIMSK_RESPONSEND+			| S3C2410_SDIIMSK_CMDTIMEOUT | S3C2410_SDIIMSK_RESPONSECRC;+                break;++	}++	/* There is a data part */+	if (IS_SDREQ_DATA_TRANS(req->Flags)) {+		u32 dcon = 0;++		if (readl(context->base + S3C2410_SDIDSTA) &+		    (S3C2410_SDIDSTA_TXDATAON | S3C2410_SDIDSTA_RXDATAON)) {+			printk("##### DATA ON: 0x%x ######\n", readl(context->base + S3C2410_SDIDSTA));+		}++		/* Setting timer */+		writel(0x7fffff, context->base + S3C2410_SDITIMER);++		/* Block size */+		writel(req->BlockLen, context->base + S3C2410_SDIBSIZE);+		/* Number of blocks */+		dcon |= (0xfff & req->BlockCount);++		if (context->bus_width == 4)+			dcon |= S3C2410_SDIDCON_WIDEBUS;++		req->DataRemaining = req->BlockCount * req->BlockLen;++		/* Set data size, and start the transfer */+		dcon |= S3C2410_SDIDCON_IRQPERIOD;+		if (!(req->DataRemaining % 4)) {+			context->data_size = 4;+			dcon |= S3C2440_SDIDCON_DS_WORD;+		} else if (!(req->DataRemaining % 2)) {+			context->data_size = 2;+			dcon |= S3C2440_SDIDCON_DS_HALFWORD;+		} else {+			context->data_size = 1;+			dcon |= S3C2440_SDIDCON_DS_BYTE;+		}++#ifdef CONFIG_SDIO_S3C24XX_DMA+		if (req->DataRemaining > 16) {+			context->dma_en = 1;+		} else+#endif+		{+			context->dma_en = 0;+			context->data_size = 1;+			dcon |= S3C2440_SDIDCON_DS_BYTE;+		}++		if (context->dma_en) {+			dcon |= S3C2410_SDIDCON_DMAEN;+			s3c24xx_hcd_prepare_dma(context);+		}++		if (IS_SDREQ_WRITE_DATA(req->Flags)) {+			/* Data write */+			DBG_PRINT(SDDBG_TRACE, ("Start data write, block count=%d, block size=%d\n",+						req->BlockCount, req->BlockLen));++			/* Data configuration: transmit after resp, block mode*/+			dcon |= S3C2410_SDIDCON_TXAFTERRESP | S3C2410_SDIDCON_BLOCKMODE;++			/* This is a write */+			dcon |= S3C2410_SDIDCON_XFER_TXSTART;++			imask |= S3C2410_SDIIMSK_TXFIFOHALF | S3C2410_SDIIMSK_TXFIFOEMPTY |+				S3C2410_SDIIMSK_FIFOFAIL | S3C2410_SDIIMSK_DATACRC |+				S3C2410_SDIIMSK_DATATIMEOUT | S3C2410_SDIIMSK_DATAFINISH;++			context->complete = S3C24XX_HCD_DATA_WRITE;+		} else {+			/* Data read */+			DBG_PRINT(SDDBG_TRACE, ("Start data read, block count=%d, block size=%d\n",+						req->BlockCount, req->BlockLen));++			/* Data configuration: receive after cmd, block mode*/+			dcon |= S3C2410_SDIDCON_RXAFTERCMD | S3C2410_SDIDCON_BLOCKMODE;++			/* This is a read */+			dcon |= S3C2410_SDIDCON_XFER_RXSTART;++			imask |= S3C2410_SDIIMSK_RXFIFOHALF | S3C2410_SDIIMSK_RXFIFOLAST |+				S3C2410_SDIIMSK_FIFOFAIL | S3C2410_SDIIMSK_DATACRC |+				S3C2410_SDIIMSK_DATATIMEOUT | S3C2410_SDIIMSK_DATAFINISH;++			context->complete = S3C24XX_HCD_DATA_READ;+		}++		dcon |= S3C2440_SDIDCON_DATSTART;++		writel(dcon, context->base + S3C2410_SDIDCON);++		cmdcon |= S3C2410_SDICMDCON_WITHDATA;++	} else {+		cmdcon &= ~S3C2410_SDICMDCON_WITHDATA;+	}++	cmdcon |= req->Command & S3C2410_SDICMDCON_INDEX;+	cmdcon |= S3C2410_SDICMDCON_SENDERHOST | S3C2410_SDICMDCON_CMDSTART;++	req->Status = SDIO_STATUS_PENDING;++	if (context->int_sdio)+		imask |= S3C2410_SDIIMSK_SDIOIRQ;+	context->int_mask = imask;+	writel(imask, context->base + S3C2440_SDIIMSK);+	writel(req->Argument, context->base + S3C2410_SDICMDARG);+	writel(cmdcon, context->base + S3C2410_SDICMDCON);++	spin_unlock_irqrestore(&context->lock, flags);++	return status;+}++static int s3c24xx_hcd_hw_init(struct s3c24xx_hcd_context * context)+{+	SDIO_STATUS status = SDIO_STATUS_SUCCESS;+	u32 con, datacon;++	/* Clock */+	context->device.clock = clk_get(NULL, "sdi");+	if (IS_ERR(context->device.clock)) {+		DBG_PRINT(SDDBG_ERROR, ("Couldn't get clock\n"));+		status = PTR_ERR(context->device.clock);+		context->device.clock = NULL;+		return status;+	}++	status = clk_enable(context->device.clock);+	if (SDIO_IS_ERROR(status)) {+		DBG_PRINT(SDDBG_ERROR, ("Couldn't get clock\n"));+		return SDIOErrorToOSError(status);+	}++	context->device.max_clock_rate = clk_get_rate(context->device.clock);+	context->device.actual_clock_rate = context->device.max_clock_rate;++	/* I/O */+	context->mem = request_mem_region(context->mem->start,+					  RESSIZE(context->mem), context->description);++	if (!context->mem) {+		DBG_PRINT(SDDBG_ERROR, ("Failed to request io memory region\n"));+		status = -ENOENT;+		goto out_disable_clock;+	}++	context->base = ioremap(context->mem->start, RESSIZE(context->mem));+	if (context->base == 0) {+		DBG_PRINT(SDDBG_ERROR, ("failed to ioremap() io memory region.\n"));+		status = -EINVAL;+		goto out_free_mem_region;+	}++	/* IRQ */+#if 0+	context->cd_irq = s3c2410_gpio_getirq(GTA02v1_GPIO_nSD_DETECT);+	s3c2410_gpio_cfgpin(GTA02v1_GPIO_nSD_DETECT, S3C2410_GPIO_IRQ);++	if (request_irq(context->cd_irq, s3c24xx_hcd_cd_irq, 0, context->description, context)) {+		DBG_PRINT(SDDBG_ERROR, ("failed to request card detect interrupt.\n"));+		status = -ENOENT;+		goto out_unmap_mem_region;+	}+#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -