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

📄 sdio.c

📁 omap3 linux 2.6 用nocc去除了冗余代码
💻 C
字号:
/* *  linux/drivers/mmc/core/sdio.c * *  Copyright (C) 2007 Texas Instruments, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */#include <linux/err.h>#include <linux/mmc/host.h>#include <linux/mmc/card.h>#include <linux/mmc/sdio.h>#include "core.h"#include "sysfs.h"#include "sdio_ops.h"#include "mmc_ops.h"extern int read_cia,sdioresp;struct mmc_card *sdiocard;/* * Allocate a new SDIO card, and assign a RCA. */static struct mmc_card *sdio_alloc_card(struct mmc_host *host, int io_rca){	struct mmc_card *card;	card = kmalloc(sizeof(struct mmc_card), GFP_KERNEL);	if (!card)		return ERR_PTR(-ENOMEM);	mmc_init_card(card, host);	card->rca = io_rca;	card->raw_cid[0]=io_rca;	card->raw_cid[1]=io_rca;	card->raw_cid[2]=io_rca;	card->raw_cid[3]=io_rca;	return card;}/* * Card detection callback from host. */static void sdio_detect(struct mmc_host *host){	int err;	BUG_ON(!host);	BUG_ON(!host->card);	mmc_claim_host(host);	/*	 * Just check if our card has been removed.	 */	err = io_select_card(host);	mmc_release_host(host);	if (err != MMC_ERR_NONE) {		mmc_remove_card(host->card);		host->card = NULL;		mmc_claim_host(host);		mmc_detach_bus(host);		mmc_release_host(host);	}}/* * Host is being removed. Free up the current card. */static void sdio_remove(struct mmc_host *host){	BUG_ON(!host);	BUG_ON(!host->card);	mmc_remove_card(host->card);	host->card = NULL;}static const struct mmc_bus_ops sdio_ops = {	.remove = sdio_remove,	.detect = sdio_detect,	.suspend = NULL,	.resume = NULL,};/* * Read the CCCR register contents of an I/O card. */static void io_read_cia(struct mmc_host *host){	int sdio_rev,io_cardtype,io_buswidth,io_cardcap;		read_cia = 1;	sdioresp = io_select_card(host);	host->ios.bus_width = MMC_BUS_WIDTH_1;	if (sdioresp == 0) {		if (host->caps & MMC_CAP_4_BIT_DATA ||			host->caps & MMC_CAP_8_BIT_DATA) {			io_cardcap = io_rw_direct(SDIO_READ, SDIO_FUNCTION_0, 0,					CCCR_CARD_CAPACITY, 0x0);			if (io_cardcap & (1<<6)) {				host->ios.clock = host->f_min;				host->ops->set_ios(host, &host->ios);				if (io_cardcap & (1<<7)) {					io_buswidth = io_rw_direct(SDIO_READ,						SDIO_FUNCTION_0, 0,						CCCR_BUS_INTF_CONTROL, 0x0);					io_buswidth |= 0x2;					io_rw_direct(SDIO_WRITE,SDIO_FUNCTION_0,						0, CCCR_BUS_INTF_CONTROL,						io_buswidth);					host->ios.bus_width = MMC_BUS_WIDTH_4;				}			} else {				host->ios.clock = 25000000;				host->ios.bus_width = MMC_BUS_WIDTH_4;				host->ops->set_ios(host, &host->ios);				io_buswidth = io_rw_direct(SDIO_READ,						SDIO_FUNCTION_0, 0,						CCCR_BUS_INTF_CONTROL, 0x0);				io_buswidth |= 0x2;				io_rw_direct(SDIO_WRITE,SDIO_FUNCTION_0, 0,						CCCR_BUS_INTF_CONTROL,						io_buswidth);			}		}		sdio_rev = io_rw_direct(SDIO_READ,SDIO_FUNCTION_0, 0,			CCCR_SDIO_REVISION, 0x0);	/*	 * Enable all the functions in the card.	 */	io_rw_direct(SDIO_WRITE, SDIO_FUNCTION_0, 0, CCCR_IO_ENABLE,0xFF);	io_rw_direct(SDIO_WRITE, SDIO_FUNCTION_0, 0, CCCR_FUNCTION_SELECT,		io_rw_direct(SDIO_READ, SDIO_FUNCTION_0, 0,			CCCR_FUNCTION_SELECT, 0x0) | 0x1);	io_cardtype = io_rw_direct(SDIO_READ, SDIO_FUNCTION_1, 0, FBR1, 0x0);	if (io_cardtype == 0x0)		printk(KERN_INFO"Non SDIO standard interface detected\n");	else if (io_cardtype == 0x1)		printk(KERN_INFO"SDIO UART interface detected\n");	else if (io_cardtype == 0x2)		printk(KERN_INFO"SDIO thin bluetooth interface detected\n");	else if (io_cardtype == 0x3)		printk(KERN_INFO"SDIO complete bluetooth interface detected\n");	else if (io_cardtype == 0x4)		printk(KERN_INFO"SDIO GPS standard interface detected\n");	else if (io_cardtype == 0x5)		printk(KERN_INFO"SDIO Camera standard interface detected\n");	else if (io_cardtype == 0x6)		printk(KERN_INFO"SDIO PHS Radio standard interface detected\n");	else if (io_cardtype == 0x7)		printk(KERN_INFO"SDIO WLAN interface detected\n");	if (sdio_rev == 0x00)		printk(KERN_INFO"SDIO revision 1.00\n");	}	read_cia = 0;}static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,	struct mmc_card *oldcard){	struct mmc_command cmd;	int err;	u32 cid[4], io_rca;	BUG_ON(!host);	BUG_ON(!host->claimed);	/*	 * Since we're changing the OCR value, we seem to	 * need to tell some cards to go back to the idle	 * state.  We wait 1ms to give cards time to	 * respond.	 */	mmc_go_idle(host);	err = io_send_op_cond(host, ocr, NULL);	if (err != MMC_ERR_NONE)		goto err;	while(1) {		/* 		 * Read the rca of an SDIO card.                 */		cmd.opcode = SDIO_SEND_RELATIVE_ADDR;		cmd.arg = 0x0;		cmd.flags = MMC_RSP_R6;		err = mmc_wait_for_cmd(host, &cmd,0);		if (err == MMC_ERR_NONE){			io_rca = cmd.resp[0] & 0xFFFF0000;			cid[0]=io_rca;			cid[1]=io_rca;			cid[2]=io_rca;			cid[3]=io_rca;			break;		}	}	if (oldcard) {		if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0)			goto err;		sdiocard = oldcard;	} else {		/*		 * Allocate card structure.		 */		sdiocard = sdio_alloc_card(host, io_rca);		if (IS_ERR(sdiocard))			goto err;		sdiocard->type = MMC_TYPE_SDIO;		host->mode = MMC_MODE_SDIO;		memcpy(sdiocard->raw_cid, cid, sizeof(sdiocard->raw_cid));	}	/*	 * Fetch CIA from card.	 */	io_read_cia(host);	if (!oldcard)		host->card = sdiocard;	return MMC_ERR_NONE;err:	return MMC_ERR_FAILED;}int mmc_attach_sdio(struct mmc_host *host, u32 ocr){	int err;	BUG_ON(!host);	BUG_ON(!host->claimed);	mmc_attach_bus(host, &sdio_ops);	/*	 * Sanity check the voltages that the card claims to	 * support.	 */	if (ocr & 0x7F) {		printk(KERN_WARNING "%s: card claims to support voltages "		       "below the defined range. These will be ignored.\n",		       mmc_hostname(host));		ocr &= ~0x7F;	}	host->ocr = mmc_select_voltage(host, ocr);	/*	 * Can we support the voltage of the card?	 */	if (!host->ocr)		goto err;	/*	 * Detect and init the card.	 */	err = mmc_sd_init_card(host, host->ocr, NULL);	if (err != MMC_ERR_NONE)		goto err;	mmc_release_host(host);	err = mmc_register_card(host->card);	if (err)		goto reclaim_host;	return 0;reclaim_host:	mmc_claim_host(host);	mmc_remove_card(host->card);	host->card = NULL;err:	mmc_detach_bus(host);	mmc_release_host(host);	return 0;}

⌨️ 快捷键说明

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