Linux 2.6.38
S3C2440
在“SDIO驱动(9)Host驱动probe实现”中简单介绍了host操作card的接口mmc_host_ops一些成员函数的作用,接下来分析下各个函数的实现。
static struct mmc_host_ops s3cmci_ops = {
.request = s3cmci_request,
.set_ios = s3cmci_set_ios,
.get_ro = s3cmci_get_ro,
.get_cd = s3cmci_card_present,
.enable_sdio_irq = s3cmci_enable_sdio_irq,
};
get_cd,检测card是否存在,返回值有4种:card存在返回1,不存在返回0;如果不支持这个操作返回-ENOSYS(Function not implemented),支持但出现错误返回负的错误码。s3cmci_card_present实现:
static int s3cmci_card_present(struct mmc_host *mmc)
{
struct s3cmci_host *host = mmc_priv(mmc);
struct s3c24xx_mci_pdata *pdata = host->pdata;
int ret;
if (pdata->no_detect)
return -ENOSYS;
ret = gpio_get_value(pdata->gpio_detect) ? 0 : 1;
return ret ^ pdata->detect_invert;
}
3行的小伎俩无需赘言。在硬件连接上,gpio_detect对应的pin用于card detection,如果插入了card那么该pin的电平为0;detect_invert作为一个flag,如果该标志设置的话card
detection对应的电平反转,即1电平表示card已经插入。有了以上信息代码的意图就昭然明揭了。
get_ro,获取card的读写类型,返回值有4种:0表明这是一张read/write,1说这是一张read-only卡);后两种返回类型同get_cd函数,s3cmci_get_ro实现:
static int s3cmci_get_ro(struct mmc_host *mmc)
{
struct s3cmci_host *host = mmc_priv(mmc);
struct s3c24xx_mci_pdata *pdata = host->pdata;
int ret;
if (pdata->no_wprotect)
return 0;
ret = gpio_get_value(pdata->gpio_wprotect) ? 1 : 0;
ret ^= pdata->wprotect_invert;
return ret;
}