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

📄 atheros_2_0_hcd.patch

📁 openmoko 使用的sdio wifi驱动源码
💻 PATCH
📖 第 1 页 / 共 4 页
字号:
Index: linux-2.6.24/drivers/sdio/hcd/Kconfig===================================================================--- /dev/null+++ linux-2.6.24/drivers/sdio/hcd/Kconfig@@ -0,0 +1,14 @@+config SDIO_S3C24XX+	tristate "Samsung s3c24xx host controller"+	depends on PLAT_S3C24XX && SDIO+	default m+	help+	  good luck.++config SDIO_S3C24XX_DMA+	bool "Samsung s3c24xx host controller DMA I/O"+	depends on SDIO_S3C24XX+	default n+	help+	  good luck.+Index: linux-2.6.24/drivers/sdio/hcd/Makefile===================================================================--- /dev/null+++ linux-2.6.24/drivers/sdio/hcd/Makefile@@ -0,0 +1 @@+obj-$(CONFIG_PLAT_S3C24XX)	 	+= s3c24xx/Index: linux-2.6.24/drivers/sdio/hcd/s3c24xx/Makefile===================================================================--- /dev/null+++ linux-2.6.24/drivers/sdio/hcd/s3c24xx/Makefile@@ -0,0 +1,2 @@+obj-$(CONFIG_PLAT_S3C24XX) += sdio_s3c24xx_hcd.o+sdio_s3c24xx_hcd-objs := s3c24xx_hcd.oIndex: linux-2.6.24/drivers/sdio/hcd/s3c24xx/s3c24xx_hcd.c===================================================================--- /dev/null+++ linux-2.6.24/drivers/sdio/hcd/s3c24xx/s3c24xx_hcd.c@@ -0,0 +1,1502 @@+/*+ * s3c24xx_hcd.c - Samsung S3C MCI driver, Atheros SDIO API compatible.+ *+ * Copyright (C) 2007 by OpenMoko, Inc.+ * Written by Samuel Ortiz <sameo@openedhand.com>+ * All Rights Reserved+ *+ * This program is free software; you can redistribute it and/or modify+ * it under the terms of the GNU General Public License as published by+ * the Free Software Foundation; either version 2 of the License, or+ * (at your option) any later version.+ *+ * This program is distributed in the hope that it will be useful,+ * but WITHOUT ANY WARRANTY; without even the implied warranty of+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the+ * GNU General Public License for more details.+ *+ * You should have received a copy of the GNU General Public License along+ * with this program; if not, write to the Free Software Foundation, Inc.,+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.+ */++#include <linux/kernel.h>+#include <linux/interrupt.h>+#include <linux/list.h>+#include <linux/dma-mapping.h>+#include <linux/errno.h>+#include <linux/platform_device.h>+#include <linux/device.h>+#include <linux/clk.h>+#include <linux/fs.h>+#include <linux/ioport.h>+#include <linux/workqueue.h>+#include <linux/completion.h>+#include <linux/delay.h>+#include <linux/seq_file.h>+#include <linux/debugfs.h>++#include <linux/sdio/ctsystem.h>+#include <linux/sdio/sdio_busdriver.h>+#include <linux/sdio/sdio_lib.h>++#include <asm/io.h>+#include <asm/irq.h>+#include <asm/uaccess.h>+#include <asm/dma.h>+#include <asm/dma-mapping.h>++#include <asm/arch/regs-sdi.h>+#include <asm/arch/regs-gpio.h>+#include <asm/arch/mci.h>+#include <asm/arch/gta02.h>++#include "s3c24xx_hcd.h"++#define DESCRIPTION "S3c24xx SDIO host controller"+#define AUTHOR "Samuel Ortiz <sameo@openedhand.com>"++#define RESSIZE(ressource) (((ressource)->end - (ressource)->start)+1)++static struct s3c2410_dma_client s3c24xx_hcd_dma_client = {+	.name		= "s3c24xx_hcd",+};++extern struct platform_device s3c_device_sdi;++static void dump_request(struct s3c24xx_hcd_context * context)+{+    if (context->hcd.pCurrentRequest != NULL) {+        DBG_PRINT(SDDBG_ERROR, ("Current Request Command:%d, ARG:0x%8.8X flags: 0x%04x\n",+				context->hcd.pCurrentRequest->Command, context->hcd.pCurrentRequest->Argument,+				context->hcd.pCurrentRequest->Flags));+        if (IS_SDREQ_DATA_TRANS(context->hcd.pCurrentRequest->Flags)) {+            DBG_PRINT(SDDBG_ERROR, ("Data %s, Blocks: %d, BlockLen:%d Remaining: %d \n",+                      IS_SDREQ_WRITE_DATA(context->hcd.pCurrentRequest->Flags) ? "WRITE":"READ",+                      context->hcd.pCurrentRequest->BlockCount,+                      context->hcd.pCurrentRequest->BlockLen,+                      context->hcd.pCurrentRequest->DataRemaining));+        }+    }+}++static void s3c24xx_dump_regs(struct s3c24xx_hcd_context * context)+{+	u32 con, pre, cmdarg, cmdcon, cmdsta, r0, r1, r2, r3, timer, bsize;+	u32 datcon, datcnt, datsta, fsta, imask;++	con 	= readl(context->base + S3C2410_SDICON);+	pre 	= readl(context->base + S3C2410_SDIPRE);+	cmdarg 	= readl(context->base + S3C2410_SDICMDARG);+	cmdcon 	= readl(context->base + S3C2410_SDICMDCON);+	cmdsta 	= readl(context->base + S3C2410_SDICMDSTAT);+	r0 	= readl(context->base + S3C2410_SDIRSP0);+	r1 	= readl(context->base + S3C2410_SDIRSP1);+	r2 	= readl(context->base + S3C2410_SDIRSP2);+	r3 	= readl(context->base + S3C2410_SDIRSP3);+	timer 	= readl(context->base + S3C2410_SDITIMER);+	bsize 	= readl(context->base + S3C2410_SDIBSIZE);+	datcon 	= readl(context->base + S3C2410_SDIDCON);+	datcnt 	= readl(context->base + S3C2410_SDIDCNT);+	datsta 	= readl(context->base + S3C2410_SDIDSTA);+	fsta 	= readl(context->base + S3C2410_SDIFSTA);+	imask   = readl(context->base + S3C2440_SDIIMSK);++	printk("SDICON:    0x%08x\n", con);+	printk("SDIPRE:    0x%08x\n", pre);+	printk("SDICmdArg: 0x%08x\n", cmdarg);+	printk("SDICmdCon: 0x%08x\n", cmdcon);+	printk("SDICmdSta: 0x%08x\n", cmdsta);+	printk("SDIRSP0:   0x%08x\n", r0);+	printk("SDIRSP1:   0x%08x\n", r1);+	printk("SDIRSP2:   0x%08x\n", r2);+	printk("SDIRSP3:   0x%08x\n", r3);+	printk("SDIDTimer: 0x%08x\n", timer);+	printk("SDIBSize:  0x%08x\n", bsize);+	printk("SDIDatCon: 0x%08x\n", datcon);+	printk("SDIDatCnt: 0x%08x\n", datcnt);+	printk("SDIDatSta: 0x%08x\n", datsta);+	printk("SDIFSta:   0x%08x\n", fsta);+	printk("SDIIntMsk: 0x%08x\n", imask);+}++static inline void s3c24xx_hcd_clear_imask(struct s3c24xx_hcd_context * context)+{+	if (context->int_sdio) {+		writel(S3C2410_SDIIMSK_SDIOIRQ | S3C2410_SDIIMSK_READWAIT,+		       context->base + S3C2440_SDIIMSK);+	}  else {+		writel(0, context->base + S3C2440_SDIIMSK);+	}+}++static inline void s3c24xx_hcd_set_imask(struct s3c24xx_hcd_context * context)+{+	writel(context->int_mask, context->base + S3C2440_SDIIMSK);+}+++static inline void s3c24xx_hcd_clear_dsta(struct s3c24xx_hcd_context * context)+{+	u32 dsta;++	dsta = readl(context->base + S3C2410_SDIDSTA);+	writel(dsta, context->base + S3C2410_SDIDSTA);+}++static inline void s3c24xx_hcd_clear_csta(struct s3c24xx_hcd_context * context)+{+	u32 csta, csta_clear = 0;++	csta = readl(context->base + S3C2410_SDICMDSTAT);++	if (csta & S3C2410_SDICMDSTAT_CRCFAIL)+		csta_clear |= S3C2410_SDICMDSTAT_CRCFAIL;+	if (csta & S3C2410_SDICMDSTAT_CMDSENT)+		csta_clear |= S3C2410_SDICMDSTAT_CMDSENT;+	if (csta & S3C2410_SDICMDSTAT_CMDTIMEOUT)+		csta_clear |= S3C2410_SDICMDSTAT_CMDTIMEOUT;+	if (csta & S3C2410_SDICMDSTAT_RSPFIN)+		csta_clear |= S3C2410_SDICMDSTAT_RSPFIN;++	writel(csta_clear, context->base + S3C2410_SDICMDSTAT);+}++static inline void s3c24xx_hcd_clear_sta(struct s3c24xx_hcd_context * context)+{+	u32 csta, dsta, csta_clear = 0, dsta_clear = 0;++	csta = readl(context->base + S3C2410_SDICMDSTAT);+	dsta = readl(context->base + S3C2410_SDIDSTA);++	if (csta & S3C2410_SDICMDSTAT_CRCFAIL)+		csta_clear |= S3C2410_SDICMDSTAT_CRCFAIL;+	if (csta & S3C2410_SDICMDSTAT_CMDSENT)+		csta_clear |= S3C2410_SDICMDSTAT_CMDSENT;+	if (csta & S3C2410_SDICMDSTAT_CMDTIMEOUT)+		csta_clear |= S3C2410_SDICMDSTAT_CMDTIMEOUT;+	if (csta & S3C2410_SDICMDSTAT_RSPFIN)+		csta_clear |= S3C2410_SDICMDSTAT_RSPFIN;+++	if (dsta & S3C2410_SDIDSTA_RDYWAITREQ)+		dsta_clear |= S3C2410_SDIDSTA_RDYWAITREQ;+	if (dsta & S3C2410_SDIDSTA_SDIOIRQDETECT)+		dsta_clear |= S3C2410_SDIDSTA_SDIOIRQDETECT;+	if (dsta & S3C2410_SDIDSTA_FIFOFAIL)+		dsta_clear |= S3C2410_SDIDSTA_FIFOFAIL;+	if (dsta & S3C2410_SDIDSTA_CRCFAIL)+		dsta_clear |= S3C2410_SDIDSTA_CRCFAIL;+	if (dsta & S3C2410_SDIDSTA_RXCRCFAIL)+		dsta_clear |= S3C2410_SDIDSTA_RXCRCFAIL;+	if (dsta & S3C2410_SDIDSTA_DATATIMEOUT)+		dsta_clear |= S3C2410_SDIDSTA_DATATIMEOUT;+	if (dsta & S3C2410_SDIDSTA_XFERFINISH)+		dsta_clear |= S3C2410_SDIDSTA_XFERFINISH;+	if (dsta & S3C2410_SDIDSTA_BUSYFINISH)+		dsta_clear |= S3C2410_SDIDSTA_BUSYFINISH;+	if (dsta & S3C2410_SDIDSTA_SBITERR)+		dsta_clear |= S3C2410_SDIDSTA_SBITERR;++	writel(csta_clear, context->base + S3C2410_SDICMDSTAT);+	writel(dsta_clear, context->base + S3C2410_SDIDSTA);+}++static inline void s3c24xx_hcd_fifo_reset(struct s3c24xx_hcd_context * context)+{+	u32 fsta;++	fsta = readl(context->base + S3C2410_SDIFSTA);+	fsta |= S3C2440_SDIFSTA_FIFORESET;+	writel(fsta, context->base + S3C2410_SDIFSTA);+}++#if 0+static void s3c24xx_hcd_reset(struct s3c24xx_hcd_context * context)+{+	u32 con, counter;+	unsigned long flags;++	spin_lock_irqsave(&context->lock, flags);++	con = readl(context->base + S3C2410_SDICON);++	con |= S3C2440_SDICON_SDRESET;++	writel(con, context->base + S3C2410_SDICON);++	counter = 1000;+	while(counter) {+		con = readl(context->base + S3C2410_SDICON);+		if (!(con & S3C2440_SDICON_SDRESET))+			break;+		counter--;+		mdelay(1);+	}++	spin_unlock_irqrestore(&context->lock, flags);+}+#endif++static SDIO_STATUS s3c24xx_hcd_clock_enable(struct s3c24xx_hcd_context * context,+					    unsigned int clock_rate,+					    unsigned char enable)+{+	SDIO_STATUS status = SDIO_STATUS_SUCCESS;+	unsigned long flags;+	u32 con;++	spin_lock_irqsave(&context->lock, flags);++	con = readl(context->base + S3C2410_SDICON);++	if (enable && clock_rate) {+		con |= S3C2410_SDICON_CLOCKTYPE;+	} else {+		con &= ~S3C2410_SDICON_CLOCKTYPE;+	}++	if (clock_rate) {+		int prescaler;++		for (prescaler = 0; prescaler < 0xff; prescaler++) {+			context->device.actual_clock_rate =+				context->device.max_clock_rate / (prescaler + 1);++			if (context->device.actual_clock_rate <= clock_rate &&+			    context->device.actual_clock_rate <= context->hcd.MaxClockRate)+				break;+		}++		if (prescaler == 0xff)+			DBG_PRINT(SDDBG_ERROR , ("Using lowest clock rate\n"));++		writel(prescaler, context->base + S3C2410_SDIPRE);+	}++	writel(con, context->base + S3C2410_SDICON);++	spin_unlock_irqrestore(&context->lock, flags);++	return SDIOErrorToOSError(status);+}++static void s3c24xx_hcd_set_bus_mode(struct s3c24xx_hcd_context *context,+				     PSDCONFIG_BUS_MODE_DATA pMode)+{+	u32 datacon;+	unsigned long flags;++	DBG_PRINT(SDDBG_TRACE , ("SetBusMode\n"));++	spin_lock_irqsave(&context->lock, flags);+	datacon = readl(context->base + S3C2410_SDIDCON);++	switch (SDCONFIG_GET_BUSWIDTH(pMode->BusModeFlags)) {+        case SDCONFIG_BUS_WIDTH_1_BIT:+		context->bus_width = 1;+		datacon &= S3C2410_SDIDCON_WIDEBUS;+		break;+        case SDCONFIG_BUS_WIDTH_4_BIT:+		context->bus_width = 4;+		datacon |= S3C2410_SDIDCON_WIDEBUS;+		break;+        default:+		DBG_PRINT(SDDBG_TRACE , ("Unknown bus width: %d\n", SDCONFIG_GET_BUSWIDTH(pMode->BusModeFlags)));+		break;+	}++	writel(datacon, context->base + S3C2410_SDIDCON);+	spin_unlock_irqrestore(&context->lock, flags);++	/* Set clock rate and enable clock */+	s3c24xx_hcd_clock_enable(context, pMode->ClockRate, 1);+	pMode->ActualClockRate = context->device.actual_clock_rate;++ 	DBG_PRINT(SDDBG_TRACE , ("BUS mode: %d bits wide, actual clock rate: %d kHz (requested %d kHz)\n",+				 context->bus_width, pMode->ActualClockRate / 1000, pMode->ClockRate / 1000));+}+++static void s3c24xx_hcd_dma_complete(struct s3c24xx_hcd_context * context)+{+	u32 dsta, counter, i;+	PSDREQUEST req;+	SDIO_STATUS status = SDIO_STATUS_ERROR;++	req = GET_CURRENT_REQUEST(&context->hcd);+	if (req == NULL) {+		DBG_PRINT(SDDBG_ERROR, ("%s(): No current request\n", __FUNCTION__));+		return;+	}++	if (context->complete == S3C24XX_HCD_DATA_READ) {+		/* DMA READ completion */+		if (context->latest_xfer_size != req->DataRemaining) {+			DBG_PRINT(SDDBG_ERROR, ("Unexpected read xfer size: %d <-> %d\n",+						context->latest_xfer_size, req->DataRemaining));+			status = SDIO_STATUS_BUS_WRITE_ERROR;+		}++		counter = 0;+		dsta = readl(context->base + S3C2410_SDIDSTA);+		while (!(dsta & S3C2410_SDIDSTA_XFERFINISH)) {+			if (counter > 500) {+				printk("read xfer timed out\n");+				s3c24xx_dump_regs(context);+				memcpy(req->pDataBuffer, context->io_buffer,+				       req->BlockCount * req->BlockLen);+				printk("Transfer: %dx%d\n", req->BlockCount, req->BlockLen);+				for (i = 0; i < req->DataRemaining; i++)+					printk("0x%x ", *(((char *)context->io_buffer) + i));+				printk("\n");+				status = SDIO_STATUS_BUS_READ_TIMEOUT;+				goto out;+			}+			dsta = readl(context->base + S3C2410_SDIDSTA);+			counter++;+			mdelay(1);+		};++		dma_sync_single(NULL, context->io_buffer_dma,+				req->BlockCount * req->BlockLen, DMA_BIDIRECTIONAL);++		writel(S3C2410_SDIDSTA_XFERFINISH, context->base + S3C2410_SDIDSTA);++		memcpy(req->pDataBuffer, context->io_buffer,

⌨️ 快捷键说明

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