linux mmc驱动
插曲:
因为使用的平台是telechips的tcc803x,其芯片用户手册描述寄存器都是四字节寻址的,但是在代码驱动中用的很可能是单字节寻址,咋一看,有可能有的地址在芯片手册上没有或者感觉写错了,其实不是,这个需要注意一下。
简单流程:
mmc host主控器注册完成之后,会分别生成一个底层硬件相关的主控制设备(struct)sdhci_host和通用抽象的主控制器设备(struct)mmc_host,当检测到有sd卡等mmc从设备插入时,mmc host主控制器会向sd卡等mmc从设备发起会话,sd卡等从设备作出相应的应答。mmc host主控制建立会话的机制是先通过通用抽象的(struct)mmc_host主设备的通用操作集(struct)mmc_host_ops,再由通用操作集(struct)mmc_host_ops进一步调用底层硬件相关的操作集(struct)sdhci_ops实现主从设备的通信的。
转载:linux MMC framework(2) - sdhci host driver_Hacker_Albert的博客-CSDN博客
注册mmc主控制器:
static int sdhci_tcc_probe(struct platform_device *pdev)
{const struct of_device_id *match;const struct sdhci_tcc_soc_data *soc_data;struct sdhci_host *host;struct sdhci_pltfm_host *pltfm_host;struct sdhci_tcc *tcc = NULL;match = of_match_device(sdhci_tcc_of_match_table, &pdev->dev);soc_data = match->data;host = sdhci_pltfm_init(pdev, soc_data->pdata, sizeof(*tcc));pltfm_host = sdhci_priv(host);tcc = sdhci_pltfm_priv(pltfm_host);sdhci_add_host(host);}
sdhci_tcc_of_match_table表:
static const struct of_device_id sdhci_tcc_of_match_table[] = {{ .compatible = "telechips,tcc803x-sdhci,module-only", .data = &soc_data_tcc803x},{}
};
表里的soc_data_tcc803x结构:
static const struct sdhci_tcc_soc_data soc_data_tcc803x = {.pdata = &sdhci_tcc803x_pdata,.parse_channel_configs = sdhci_tcc803x_parse_channel_configs,.set_channel_configs = sdhci_tcc803x_set_channel_configs,.set_core_clock = sdhci_tcc803x_set_core_clock,.sdhci_tcc_quirks = 0,
};
sdhci_tcc803x_pdata平台数据结构:
static const struct sdhci_pltfm_data sdhci_tcc803x_pdata = {.ops = &sdhci_tcc803x_ops,.quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN,.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN |SDHCI_QUIRK2_STOP_WITH_TC,
};
sdhci_tcc803x_ops操作集:
static const struct sdhci_ops sdhci_tcc803x_ops = {.get_max_clock = sdhci_tcc803x_clk_get_max_clock,.set_clock = sdhci_tcc_set_clock,.set_bus_width = sdhci_set_bus_width,.reset = sdhci_tcc_reset,.hw_reset = sdhci_tcc_hw_reset,.set_uhs_signaling = sdhci_set_uhs_signaling,.get_ro = sdhci_tcc_get_ro,};
sdhci_ops与主控制硬件打交道,所以是再host主控制器驱动中实现的。
重新回到probe函数,看sdhci_pltfm_init函数:
struct sdhci_host *sdhci_pltfm_init(struct platform_device *pdev,const struct sdhci_pltfm_data *pdata,size_t priv_size)
{struct sdhci_host *host;//分配一个struct sdhci_host结构空间,附带分配一个struct sdhci_pltfm_host结构空间//和一个priv_size大小的空间host = sdhci_alloc_host(&pdev->dev,sizeof(struct sdhci_pltfm_host) + priv_size);if (pdata && pdata->ops)host->ops = pdata->ops; //对应上面定义的struct sdhci_ops sdhci_tcc803x_ops变量return host;
}
sdhci_alloc_host函数:
struct sdhci_host *sdhci_alloc_host(struct device *dev,size_t priv_size)
{struct mmc_host *mmc;struct sdhci_host *host;//本来是分配struct sdci_host结构体空间的,这里先分配struct mmc_host//结构体空间,附带分配着sdhci_host结构体空间,以及sdhci_host结构体附带//的其它空间大小mmc = mmc_alloc_host(sizeof(struct sdhci_host) + priv_size, dev);host = mmc_priv(mmc);host->mmc = mmc;host->mmc_host_ops = sdhci_ops;mmc->ops = &host->mmc_host_ops;return host;
}
mmc_priv函数:
static inline void *mmc_priv(struct mmc_host *host)
{return (void *)host->private;
}
mmc_host结构体:
struct mmc_host {struct device *parent;struct device class_dev;const struct mmc_host_ops *ops;unsigned int f_min;unsigned int f_max;unsigned int f_init;......unsigned long private[0] ____cacheline_aligned;
}
回到probe函数,看sdhci_priv函数:
static inline void *sdhci_priv(struct sdhci_host *host)
{return host->private;
}
sdhci_host结构:
struct sdhci_host {/* Data set by hardware interface driver */const char *hw_name; /* Hardware bus name */const struct sdhci_ops *ops; /* Low level hw interface *//* Internal data */struct mmc_host *mmc; /* MMC structure */struct mmc_host_ops mmc_host_ops; /* MMC host ops */......unsigned long private[0] ____cacheline_aligned;
}
回到probe函数,看sdhci_add_host函数:
int sdhci_add_host(struct sdhci_host *host)
{sdhci_setup_host(host);__sdhci_add_host(host);return 0;
}
linux mmc驱动相关推荐
- Linux MMC 驱动子系统详解
Linxu MMC 驱动子系统 文章目录 Linxu MMC 驱动子系统 硬件关联 目录说明 mmc子系统的逻辑架构 设备-总线-驱动模型 一.MMC驱动抽象模型 二.SDIO驱动抽象模型 三.MMC ...
- Linux MMC驱动架构浅析
Linux MMC驱动架构浅析 MMC驱动模型 Linux内核设计了MMC子系统,用于管理MMC/SD等设备,MMC/SD存储设备是一种典型的块设备.MMC子系统的框架结构如下图所示. 块设备(MMC ...
- linux mmc驱动框架,Linux mmc framework2:基本组件之mmc
1.前言 本文主要mmc组件的主要流程,在介绍的过程中,将详细说明和mmc相关的流程,涉及到其它组件的详细流程再在相关文章中说明. 2.主要数据结构和API TODO 3. 主要流程 3.1 mmc_ ...
- (linux)MMC 卡驱动分析
最近花时间研究了一下 MMC 卡驱动程序,开始在网上找了很多关于 MMC 卡驱动的分析文章,但大都是在描述各个层,这对于初学者来讲帮助并不大,所以我就打算把自己的理解写下来,希望对大家有用.个人觉得理 ...
- Linux下驱动SD/MMC读卡器(转)
Linux下驱动SD/MMC读卡器(转)[@more@] 本文仅仅适用于笔记本自带的内置读卡器. 如果你使用的是USB接口的读卡器,那么,不用看这个了,插上之后就可以当成U盘去用了. 如果你看了这个文 ...
- linux mmc分区_【经验记录】如何给嵌入式Linux的SD/MMC卡驱动中添加多个分区
How to add multi partition for SD/MMC card in Linux Driver 之所以写这个,是因为,在这个过程中,自己明显感觉到了,做事情一定要有一定的方法,方 ...
- linux设备驱动——总线、设备、驱动
http://blog.csdn.net/wh_19910525/article/details/7398051 2.6 版本内核是如何管理总线,驱动,设备之间的关系的,关于bus_type.devi ...
- 《Linux设备驱动开发详解 A》一一2.3 接口与总线
本节书摘来华章计算机出版社<Linux设备驱动开发详解 A>一书中的第2章,第2.3节,作者:宋宝华 更多章节内容可以访问云栖社区"华章计算机"公众号查看.1 2.3 ...
- linux设备驱动——andriod平台wlan驱动
转自 :http://blog.chinaunix.net/space.php?uid=22278460&do=blog&cuid=2186191 linux设备驱动--andriod ...
最新文章
- URI URL 简介区别
- 全球首个知识增强千亿大模型鹏城-百度·文心发布
- 【洛谷4001】 [ICPC-Beijing 2006]狼抓兔子(最小割)
- tidevice.exceptions.MuxServiceError: Could not start service: com.apple.testmanagerd.lockdown.secure
- 在ASP.NET Core 2.0中使用CookieAuthentication
- confluencejira集成_Jira Service Desk使用教程之如何将Jira Cloud与Confluence集成?
- LeetCode 364. 加权嵌套序列和 II(重复叠加)
- 需求分析的初稿出来了
- 强化学习 ---baselines项目之 Atari游戏的网络结构解析
- 自动化Ansible常见命令
- 免费JS甘特图组件dhtmlxgantt
- ai中如何插入签名_如何在PDF文档中插入文本框?
- 刷题 BFS 广度优先算法 : 大胖子走迷宫 (python, java)
- VLC的windows版本下载
- Jetpack Compose 从入门到入门(六)
- 【每日早报】2019/09/03
- 爱剪辑 v3.0.0.2000
- R | 常用函数-2
- 【南航计算机系统结构】第1,2,3章作业
- 贪心算法之区间取点问题
热门文章
- Dell笔记本(预装win10)重装win7的方法
- 仿微信发朋友圈获取定位
- Linux离线安装Python第三方库Requests
- 亚马逊 kindle ebook 大合集资源多真的好吗?
- Vue实现一个长方形少一个三角形的样式(类似两个直角梯形摞在一起的样式)
- 5. 有 2*n 的一个长方形方格,用一个1*2 的骨牌铺满方格
- 移动终端软件测试基础知识,移动终端软件测试基础知识 - Mr.南柯 - 51Testing软件测试网 51Testing软件测试网-软件测试人的精神家园...
- three.js中坐标系转换以及camera的position、lookAt与up属性理解
- 推荐2022年有微信小程序毕业设计需求的70多个作品
- 联想电脑怎么录屏?这3个方法,轻松解决