📄 sdio_ops.c
字号:
/* * linux/drivers/mmc/core/sdio_ops.c * * Copyright 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 as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. */#include <linux/module.h>#include <linux/types.h>#include <asm/scatterlist.h>#include <linux/scatterlist.h>#include <linux/mmc/host.h>#include <linux/mmc/card.h>#include <linux/mmc/sdio.h>#include <linux/mmc/mmc.h>#include <linux/mmc/core.h>#include "core.h"#include "sdio_ops.h"#define SDIO_FUNCREG_MASK 0x1F8FF#define SDIO_FUNCSIZE_REG1 0x10#define SDIO_FUNCSIZE_REG2 0x11#define SDIO_FUNC_MASK 0x00700static int sdio_func_blksize[8] = {0,0,0,0,0,0,0,0};int read_cia,sdioresp;extern struct mmc_card *sdiocard;int io_send_op_cond(struct mmc_host *host, u32 ocr, u32 * rocr){ struct mmc_command cmd; int i, err = 0; cmd.opcode = IO_SEND_OP_COND; cmd.arg = ocr; cmd.flags = MMC_RSP_R4; mmc_delay(10); for (i = 100; i; i--) { err = mmc_wait_for_cmd(host, &cmd, 0); if (err != MMC_ERR_NONE) break; if (cmd.resp[0] & MMC_CARD_BUSY || ocr == 0) break; mmc_delay(1); err = MMC_ERR_TIMEOUT; mmc_delay(10); } if (rocr) *rocr = cmd.resp[0]; return err;}int io_select_card(struct mmc_host *host){ struct mmc_command cmd; int err = 0; cmd.opcode = MMC_SELECT_CARD; cmd.arg = sdiocard->rca; cmd.flags = MMC_RSP_R1; err = mmc_wait_for_cmd(host, &cmd,0); return err;}/* * Read/Write one byte of data from an SDIO card register * of the given function on the resp line. */int io_rw_direct(int rwFlag,int funcNum,int rawFlag, unsigned long regAddr,int value) { struct mmc_command cmd; int err = 0,trans_err = 1, func_num = 0; if (!sdiocard) return trans_err; if (sdioresp) return trans_err; pr_debug("SDIO CMD IO_RW_DIRECT: rwflag %d function %d Write verify %d" "regaddr %ld value %d\n", rwFlag, funcNum, rawFlag, regAddr, value); cmd.opcode = IO_RW_DIRECT; if(funcNum==0 && rwFlag==1) { if((regAddr & SDIO_FUNCREG_MASK) == 0x10){ func_num= ((regAddr & SDIO_FUNC_MASK)>>8); sdio_func_blksize[func_num]=sdio_func_blksize[func_num] & 0xFF00; sdio_func_blksize[func_num]=sdio_func_blksize[func_num] | value; } else if((regAddr & SDIO_FUNCREG_MASK) == 0x11){ func_num= ((regAddr & SDIO_FUNC_MASK)>>8); sdio_func_blksize[func_num]=sdio_func_blksize[func_num] & 0x00FF; sdio_func_blksize[func_num]=sdio_func_blksize[func_num] | (value<< 8); } } if(rwFlag) cmd.arg = ((rwFlag<<31) | (funcNum << 28) | (rawFlag<<27) | (regAddr << 9) | value); else cmd.arg = ((rwFlag<<31) | (funcNum << 28) | (rawFlag<<27) | (regAddr << 9)); cmd.flags = MMC_RSP_R5; if (read_cia == 0) mmc_claim_host(sdiocard->host); if (sdiocard->host->ios.clock == 0){ printk(KERN_ERR"CMD52 when the host is suspended\n"); mmc_release_host(sdiocard->host); return trans_err; } err = mmc_wait_for_cmd(sdiocard->host, &cmd,0); if (read_cia == 0) mmc_release_host(sdiocard->host); if (err!= MMC_ERR_NONE) return err; if (rwFlag) return err; else return cmd.resp[0] & 0xFF;}EXPORT_SYMBOL(io_rw_direct);/* * Read/Write bytec number of bytes from SDIO card registers * of a given function on the data lines. */int io_rw_extended(struct mmc_request *mrq,int rwFlag,int funcNum,int blkMode, int opcode, unsigned long regAddr, int bytec) { struct mmc_command cmd; struct scatterlist sg; int err = 0,trans_err = 1, bufsize = 0; pr_debug("SDIO CMD IO_RW_EXTENDED: rwflag %d function %d blkmode %d" "opcode %d regaddr %ld count %d blksize %d\n", rwFlag, funcNum, blkMode, opcode, regAddr, bytec, sdio_func_blksize[funcNum]); if (!sdiocard) return trans_err; if(blkMode) bufsize=bytec*sdio_func_blksize[funcNum]; else bufsize=bytec; if(bytec == 0x0200) bytec = 0; else bytec = bytec & 0x1FF; mrq->cmd = &cmd; cmd.opcode = IO_RW_EXTENDED; cmd.arg = ((rwFlag<<31) | (funcNum << 28) | (blkMode<<27) | (opcode << 26) | (regAddr << 9) | bytec); cmd.flags = MMC_RSP_R5; mmc_claim_host(sdiocard->host); if (sdiocard->host->ios.clock == 0){ printk(KERN_ERR"CMD53 when the host is suspended\n"); mmc_release_host(sdiocard->host); return trans_err; } mrq->data->sg = &sg; mrq->data->sg_len = 1; sg_init_one(&sg,(u8*)mrq->data->sdio_buffer_virt, bufsize); err = mmc_wait_for_req(sdiocard->host, mrq); mmc_release_host(sdiocard->host); return err;}EXPORT_SYMBOL(io_rw_extended);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -