SPI子系统
一、SPI子系统模型
三个组成部分:
SPI核心:连通了SPI客户驱动、SPI主控制器驱动
SPI控制器驱动:驱动芯片中的SPI控制器
SPI的FLASH(客户驱动)
二、SPI控制器驱动分析
- static int __init s3c24xx_spi_probe(struct platform_device *pdev)
- {
- struct s3c2410_spi_info *pdata;
- struct s3c24xx_spi *hw;
- struct spi_master *master;
- struct resource *res;
- int err = 0;
- master = spi_alloc_master(&pdev->dev, sizeof(struct s3c24xx_spi));
- if (master == NULL) {
- dev_err(&pdev->dev, "No memory for spi_master\n");
- err = -ENOMEM;
- goto err_nomem;
- }
- hw = spi_master_get_devdata(master);
- memset(hw, 0, sizeof(struct s3c24xx_spi));
- hw->master = spi_master_get(master);
- hw->pdata = pdata = pdev->dev.platform_data;
- hw->dev = &pdev->dev;
- if (pdata == NULL) {
- dev_err(&pdev->dev, "No platform data supplied\n");
- err = -ENOENT;
- goto err_no_pdata;
- }
- platform_set_drvdata(pdev, hw);
- init_completion(&hw->done);
- /* setup the master state. */
- master->num_chipselect = hw->pdata->num_cs;
- master->bus_num = pdata->bus_num;
- /* setup the state for the bitbang driver */
- hw->bitbang.master = hw->master;
- hw->bitbang.setup_transfer = s3c24xx_spi_setupxfer;
- hw->bitbang.chipselect = s3c24xx_spi_chipsel;
- hw->bitbang.txrx_bufs = s3c24xx_spi_txrx;
- hw->bitbang.master->setup = s3c24xx_spi_setup;
- dev_dbg(hw->dev, "bitbang at %p\n", &hw->bitbang);
- /* find and map our resources */
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (res == NULL) {
- dev_err(&pdev->dev, "Cannot get IORESOURCE_MEM\n");
- err = -ENOENT;
- goto err_no_iores;
- }
- hw->ioarea = request_mem_region(res->start, (res->end - res->start)+1,
- pdev->name); //设置硬件资源
- if (hw->ioarea == NULL) {
- dev_err(&pdev->dev, "Cannot reserve region\n");
- err = -ENXIO;
- goto err_no_iores;
- }
- hw->regs = ioremap(res->start, (res->end - res->start)+1); //获取映射地址
- if (hw->regs == NULL) {
- dev_err(&pdev->dev, "Cannot map IO\n");
- err = -ENXIO;
- goto err_no_iomap;
- }
- hw->irq = platform_get_irq(pdev, 0); //获取中断号
- if (hw->irq < 0) {
- dev_err(&pdev->dev, "No IRQ specified\n");
- err = -ENOENT;
- goto err_no_irq;
- }
- err = request_irq(hw->irq, s3c24xx_spi_irq, 0, pdev->name, hw); //注册中断
- if (err) {
- dev_err(&pdev->dev, "Cannot claim IRQ\n");
- goto err_no_irq;
- }
- hw->clk = clk_get(&pdev->dev, "spi");
- if (IS_ERR(hw->clk)) {
- dev_err(&pdev->dev, "No clock for device\n");
- err = PTR_ERR(hw->clk);
- goto err_no_clk;
- }
- /* setup any gpio we can */
- if (!pdata->set_cs) {
- if (pdata->pin_cs < 0) {
- dev_err(&pdev->dev, "No chipselect pin\n");
- goto err_register;
- }
- err = gpio_request(pdata->pin_cs, dev_name(&pdev->dev));
- if (err) {
- dev_err(&pdev->dev, "Failed to get gpio for cs\n");
- goto err_register;
- }
- hw->set_cs = s3c24xx_spi_gpiocs;
- gpio_direction_output(pdata->pin_cs, 1);
- } else
- hw->set_cs = pdata->set_cs;
- s3c24xx_spi_initialsetup(hw); //初始化部分
- /* register our spi controller */
- err = spi_bitbang_start(&hw->bitbang); //完成注册
- if (err) {
- dev_err(&pdev->dev, "Failed to register SPI master\n");
- goto err_register;
- }
- return 0;
- err_register:
- if (hw->set_cs == s3c24xx_spi_gpiocs)
- gpio_free(pdata->pin_cs);
- clk_disable(hw->clk);
- clk_put(hw->clk);
- err_no_clk:
- free_irq(hw->irq, hw);
- err_no_irq:
- iounmap(hw->regs);
- err_no_iomap:
- release_resource(hw->ioarea);
- kfree(hw->ioarea);
- err_no_iores:
- err_no_pdata:
- spi_master_put(hw->master);;
- err_nomem:
- return err;
- }
s3c24xx_spi_initialsetup:
- static void s3c24xx_spi_initialsetup(struct s3c24xx_spi *hw)
- {
- /* for the moment, permanently enable the clock */
- clk_enable(hw->clk);
- /* program defaults into the registers */
- writeb(0xff, hw->regs + S3C2410_SPPRE);
- writeb(SPPIN_DEFAULT, hw->regs + S3C2410_SPPIN);
- writeb(SPCON_DEFAULT, hw->regs + S3C2410_SPCON); //设置成中断触发方式
- if (hw->pdata) {
- if (hw->set_cs == s3c24xx_spi_gpiocs)
- gpio_direction_output(hw->pdata->pin_cs, 1);
- if (hw->pdata->gpio_setup)
- hw->pdata->gpio_setup(hw->pdata, 1);
- }
- }
中断函数s3c24xx_spi_irq:
- static irqreturn_t s3c24xx_spi_irq(int irq, void *dev)
- {
- struct s3c24xx_spi *hw = dev;
- unsigned int spsta = readb(hw->regs + S3C2410_SPSTA);
- unsigned int count = hw->count;
- if (spsta & S3C2410_SPSTA_DCOL) {
- dev_dbg(hw->dev, "data-collision\n");
- complete(&hw->done);
- goto irq_done;
- }
- if (!(spsta & S3C2410_SPSTA_READY)) {
- dev_dbg(hw->dev, "spi not ready for tx?\n");
- complete(&hw->done);
- goto irq_done;
- }
- hw->count++;
- if (hw->rx)
- hw->rx[count] = readb(hw->regs + S3C2410_SPRDAT);
- count++;
- if (count < hw->len) //判断长度来收发?
- writeb(hw_txbyte(hw, count), hw->regs + S3C2410_SPTDAT);
- else
- complete(&hw->done);
- irq_done:
- return IRQ_HANDLED;
- }
SPI子系统的更多相关文章
- spi子系统之驱动SSD1306 OLED
spi子系统之驱动SSD1306 OLED 接触Linux之前,曾以为读源码可以更快的学习软件,于是前几个博客都是一边读源码一边添加注释,甚至精读到每一行代码,实际上效果并不理想,看过之后就忘记了.主 ...
- [国嵌攻略][159][SPI子系统]
SPI 子系统架构 1.SPI core核心:用于连接SPI客户驱动和SPI主控制器驱动,并且提供了对应的注册和注销的接口. 2.SPI controller driver主控制器驱动:用来驱动SPI ...
- SPI子系统分析之二:数据结构【转】
转自:http://www.cnblogs.com/jason-lu/articles/3164901.html 内核版本:3.9.5 spi_master struct spi_master用来描述 ...
- SPI子系统分析之四:驱动模块
内核版本:3.9.5 SPI控制器层(平台相关) 上一节讲了SPI核心层的注册和匹配函数,它是平台无关的.正是在核心层抽象了SPI控制器层的相同部分然后提供了统一的API给SPI设备层来使用.我们这一 ...
- SPI子系统分析之三:驱动模块
内核版本:3.9.5 SPI核心层(平台无关) SPI子系统初始化的第一步就是将SPI总线注册进内核,并且在/sys下创建一个spi_master的类,以后注册的从设备都将挂接在该总线下. 下列函数位 ...
- SPI子系统分析之二:数据结构
内核版本:3.9.5 spi_master struct spi_master用来描述一个SPI主控制器,我们一般不需要自己编写spi控制器驱动. /*结构体master代表一个SPI接口,或者叫一个 ...
- SPI子系统分析之一:框架
内核版本:3.9.5 SPI子系统概述: 一个SPI主控制器对应一条SPI总线,当然在系统中有唯一的总线编号. SPI总线上有两类设备: 其一是主控端,通常作为SOC系统的一个子模块出现,很多嵌入式M ...
- spi 子系统
http://blog.csdn.net/ropenyuan/article/details/42269641 http://blog.chinaunix.net/uid-27406766-id-33 ...
- Linux内核中SPI/I2c子系统剖析
Linux内核中,SPI和I2C两个子系统的软件架构是一致的,且Linux内核的驱动模型都以bus,driver,device三种抽象对象为基本元素构建起来.下文的分析将主要用这三种抽象对象的创建过程 ...
随机推荐
- Sql server 2008 的完成备份和差异备份还原
当数据库数据量不大的情况下用 Sqlserver 的完全备份就完全可以了 步骤为: 1.在需要还原的数据库上右键选择如图 2.在“常规”选项中点击“源设备”选取磁盘上备份好的.bak文件后,勾上“还原 ...
- POJ 3525 Most Distant Point from the Sea (半平面交)
Description The main land of Japan called Honshu is an island surrounded by the sea. In such an isla ...
- Java总结第一期
神奇的小阳阳阳再度归来,大家一定想我了吧~哦,谢谢,谢谢,谢谢各位的掌声,thank you,thank you@ 第一章: 下面给大家简单介绍Java: Java技术可以应用在几乎所有类型和规模的设 ...
- window环境下pipd的安装
参照:https://blog.csdn.net/jin80506/article/details/83111848 如果你还是无法使用尝试查看是否自己已经将:C:\software\Python\P ...
- CF 452E. Three strings(后缀数组+并查集)
传送门 解题思路 感觉这种题都是套路之类的??首先把三个串并成一个,中间插入一些奇怪的字符,然后跑遍\(SA\).考虑按照\(height\)分组计算,就是每个\(height\)只在最高位计算一次, ...
- python基础实现tcp文件传输
准备工作,实现文件上传需要那些工具呢? socket(传输).open()(打开文件).os(读取文件信息),当然还有辅助类sys和json,下面我们开始吧 import socket,sys imp ...
- VB - sendKey
Set WshShell=WScript.CreateObject("WScript.Shell") WshShell = SendKeys string “string”:表示要 ...
- 转 Xshell ssh长时间连接不掉线设置
1.Xshell客户端设置 2.服务器设置 vi /etc/ssh/sshd_config 把ClientAliveInterval 0和ClientAliveCountMax 3前的井号去掉,并把C ...
- Npm使用遇到的问题解决
0.运行项目: 1)git clone 项目 2)项目根目录执行npm install安装依赖 3)执行npm run dev启动 1.安装cnpm: npm install -g cnpm --re ...
- 使用自编译的Emacs26.0.50build10版本,helm报错(已解决)
使用自编译的Emacs26.0.50build10版本,helm报错(已解决) */--> code {color: #FF0000} pre.src {background-color: #0 ...