一、SPI子系统模型





三个组成部分:

SPI核心:连通了SPI客户驱动、SPI主控制器驱动

SPI控制器驱动:驱动芯片中的SPI控制器

SPI的FLASH(客户驱动)



二、SPI控制器驱动分析

  1. static int __init s3c24xx_spi_probe(struct platform_device *pdev)
  2. {
  3. struct s3c2410_spi_info *pdata;
  4. struct s3c24xx_spi *hw;
  5. struct spi_master *master;
  6. struct resource *res;
  7. int err = 0;
  8. master = spi_alloc_master(&pdev->dev, sizeof(struct s3c24xx_spi));
  9. if (master == NULL) {
  10. dev_err(&pdev->dev, "No memory for spi_master\n");
  11. err = -ENOMEM;
  12. goto err_nomem;
  13. }
  14. hw = spi_master_get_devdata(master);
  15. memset(hw, 0, sizeof(struct s3c24xx_spi));
  16. hw->master = spi_master_get(master);
  17. hw->pdata = pdata = pdev->dev.platform_data;
  18. hw->dev = &pdev->dev;
  19. if (pdata == NULL) {
  20. dev_err(&pdev->dev, "No platform data supplied\n");
  21. err = -ENOENT;
  22. goto err_no_pdata;
  23. }
  24. platform_set_drvdata(pdev, hw);
  25. init_completion(&hw->done);
  26. /* setup the master state. */
  27. master->num_chipselect = hw->pdata->num_cs;
  28. master->bus_num = pdata->bus_num;
  29. /* setup the state for the bitbang driver */
  30. hw->bitbang.master = hw->master;
  31. hw->bitbang.setup_transfer = s3c24xx_spi_setupxfer;
  32. hw->bitbang.chipselect = s3c24xx_spi_chipsel;
  33. hw->bitbang.txrx_bufs = s3c24xx_spi_txrx;
  34. hw->bitbang.master->setup = s3c24xx_spi_setup;
  35. dev_dbg(hw->dev, "bitbang at %p\n", &hw->bitbang);
  36. /* find and map our resources */
  37. res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  38. if (res == NULL) {
  39. dev_err(&pdev->dev, "Cannot get IORESOURCE_MEM\n");
  40. err = -ENOENT;
  41. goto err_no_iores;
  42. }
  43. hw->ioarea = request_mem_region(res->start, (res->end - res->start)+1,
  44. pdev->name);                                                                    //设置硬件资源
  45. if (hw->ioarea == NULL) {
  46. dev_err(&pdev->dev, "Cannot reserve region\n");
  47. err = -ENXIO;
  48. goto err_no_iores;
  49. }
  50. hw->regs = ioremap(res->start, (res->end - res->start)+1);                                      //获取映射地址
  51. if (hw->regs == NULL) {
  52. dev_err(&pdev->dev, "Cannot map IO\n");
  53. err = -ENXIO;
  54. goto err_no_iomap;
  55. }
  56. hw->irq = platform_get_irq(pdev, 0);                                                            //获取中断号
  57. if (hw->irq < 0) {
  58. dev_err(&pdev->dev, "No IRQ specified\n");
  59. err = -ENOENT;
  60. goto err_no_irq;
  61. }
  62. err = request_irq(hw->irq, s3c24xx_spi_irq, 0, pdev->name, hw);                                 //注册中断
  63. if (err) {
  64. dev_err(&pdev->dev, "Cannot claim IRQ\n");
  65. goto err_no_irq;
  66. }
  67. hw->clk = clk_get(&pdev->dev, "spi");
  68. if (IS_ERR(hw->clk)) {
  69. dev_err(&pdev->dev, "No clock for device\n");
  70. err = PTR_ERR(hw->clk);
  71. goto err_no_clk;
  72. }
  73. /* setup any gpio we can */
  74. if (!pdata->set_cs) {
  75. if (pdata->pin_cs < 0) {
  76. dev_err(&pdev->dev, "No chipselect pin\n");
  77. goto err_register;
  78. }
  79. err = gpio_request(pdata->pin_cs, dev_name(&pdev->dev));
  80. if (err) {
  81. dev_err(&pdev->dev, "Failed to get gpio for cs\n");
  82. goto err_register;
  83. }
  84. hw->set_cs = s3c24xx_spi_gpiocs;
  85. gpio_direction_output(pdata->pin_cs, 1);
  86. } else
  87. hw->set_cs = pdata->set_cs;
  88. s3c24xx_spi_initialsetup(hw);                                                                    //初始化部分
  89. /* register our spi controller */
  90. err = spi_bitbang_start(&hw->bitbang);                                                           //完成注册
  91. if (err) {
  92. dev_err(&pdev->dev, "Failed to register SPI master\n");
  93. goto err_register;
  94. }
  95. return 0;
  96. err_register:
  97. if (hw->set_cs == s3c24xx_spi_gpiocs)
  98. gpio_free(pdata->pin_cs);
  99. clk_disable(hw->clk);
  100. clk_put(hw->clk);
  101. err_no_clk:
  102. free_irq(hw->irq, hw);
  103. err_no_irq:
  104. iounmap(hw->regs);
  105. err_no_iomap:
  106. release_resource(hw->ioarea);
  107. kfree(hw->ioarea);
  108. err_no_iores:
  109. err_no_pdata:
  110. spi_master_put(hw->master);;
  111. err_nomem:
  112. return err;
  113. }

s3c24xx_spi_initialsetup:

  1. static void s3c24xx_spi_initialsetup(struct s3c24xx_spi *hw)
  2. {
  3. /* for the moment, permanently enable the clock */
  4. clk_enable(hw->clk);
  5. /* program defaults into the registers */
  6. writeb(0xff, hw->regs + S3C2410_SPPRE);
  7. writeb(SPPIN_DEFAULT, hw->regs + S3C2410_SPPIN);
  8. writeb(SPCON_DEFAULT, hw->regs + S3C2410_SPCON);                                       //设置成中断触发方式
  9. if (hw->pdata) {
  10. if (hw->set_cs == s3c24xx_spi_gpiocs)
  11. gpio_direction_output(hw->pdata->pin_cs, 1);
  12. if (hw->pdata->gpio_setup)
  13. hw->pdata->gpio_setup(hw->pdata, 1);
  14. }
  15. }

中断函数s3c24xx_spi_irq:

  1. static irqreturn_t s3c24xx_spi_irq(int irq, void *dev)
  2. {
  3. struct s3c24xx_spi *hw = dev;
  4. unsigned int spsta = readb(hw->regs + S3C2410_SPSTA);
  5. unsigned int count = hw->count;
  6. if (spsta & S3C2410_SPSTA_DCOL) {
  7. dev_dbg(hw->dev, "data-collision\n");
  8. complete(&hw->done);
  9. goto irq_done;
  10. }
  11. if (!(spsta & S3C2410_SPSTA_READY)) {
  12. dev_dbg(hw->dev, "spi not ready for tx?\n");
  13. complete(&hw->done);
  14. goto irq_done;
  15. }
  16. hw->count++;
  17. if (hw->rx)
  18. hw->rx[count] = readb(hw->regs + S3C2410_SPRDAT);
  19. count++;
  20. if (count < hw->len)                                                                            //判断长度来收发?
  21. writeb(hw_txbyte(hw, count), hw->regs + S3C2410_SPTDAT);
  22. else
  23. complete(&hw->done);
  24. irq_done:
  25. return IRQ_HANDLED;
  26. }

SPI子系统的更多相关文章

  1. spi子系统之驱动SSD1306 OLED

    spi子系统之驱动SSD1306 OLED 接触Linux之前,曾以为读源码可以更快的学习软件,于是前几个博客都是一边读源码一边添加注释,甚至精读到每一行代码,实际上效果并不理想,看过之后就忘记了.主 ...

  2. [国嵌攻略][159][SPI子系统]

    SPI 子系统架构 1.SPI core核心:用于连接SPI客户驱动和SPI主控制器驱动,并且提供了对应的注册和注销的接口. 2.SPI controller driver主控制器驱动:用来驱动SPI ...

  3. SPI子系统分析之二:数据结构【转】

    转自:http://www.cnblogs.com/jason-lu/articles/3164901.html 内核版本:3.9.5 spi_master struct spi_master用来描述 ...

  4. SPI子系统分析之四:驱动模块

    内核版本:3.9.5 SPI控制器层(平台相关) 上一节讲了SPI核心层的注册和匹配函数,它是平台无关的.正是在核心层抽象了SPI控制器层的相同部分然后提供了统一的API给SPI设备层来使用.我们这一 ...

  5. SPI子系统分析之三:驱动模块

    内核版本:3.9.5 SPI核心层(平台无关) SPI子系统初始化的第一步就是将SPI总线注册进内核,并且在/sys下创建一个spi_master的类,以后注册的从设备都将挂接在该总线下. 下列函数位 ...

  6. SPI子系统分析之二:数据结构

    内核版本:3.9.5 spi_master struct spi_master用来描述一个SPI主控制器,我们一般不需要自己编写spi控制器驱动. /*结构体master代表一个SPI接口,或者叫一个 ...

  7. SPI子系统分析之一:框架

    内核版本:3.9.5 SPI子系统概述: 一个SPI主控制器对应一条SPI总线,当然在系统中有唯一的总线编号. SPI总线上有两类设备: 其一是主控端,通常作为SOC系统的一个子模块出现,很多嵌入式M ...

  8. spi 子系统

    http://blog.csdn.net/ropenyuan/article/details/42269641 http://blog.chinaunix.net/uid-27406766-id-33 ...

  9. Linux内核中SPI/I2c子系统剖析

    Linux内核中,SPI和I2C两个子系统的软件架构是一致的,且Linux内核的驱动模型都以bus,driver,device三种抽象对象为基本元素构建起来.下文的分析将主要用这三种抽象对象的创建过程 ...

随机推荐

  1. JS中数据结构之链表

    1.链表的基本介绍 数组不总是组织数据的最佳数据结构,在很多编程语言中,数组的长度是固定的,所以当数组已被数据填满时,再要加入新的元素就会非常困难.在数组中,添加和删除元素也很麻烦,因为需要将数组中的 ...

  2. 洛谷 P3806 (点分治)

    题目:https://www.luogu.org/problem/P3806 题意:一棵树,下面有q个询问,问是否有距离为k的点对 思路:牵扯到树上路径的题都是一般都是点分治,我们可以算出所有的路径长 ...

  3. Nuget-Doc:NuGet 介绍

    ylbtech-Nuget-Doc:NuGet 介绍 NuGet 是适用于 .NET 的包管理器. 它使开发人员能够创建.共享和使用有用的 .NET 库. NuGet 客户端工具可生成这些库并将其作为 ...

  4. 建站手册-浏览器信息:Mozilla 项目

    ylbtech-建站手册-浏览器信息:Mozilla 项目 1.返回顶部 1. http://www.w3school.com.cn/browsers/browsers_mozilla.asp 2. ...

  5. jmeter添加自定义扩展函数之String---base64加密

    1,打开eclipse,新建maven工程,在pom中引用jmeter核心jar包,具体请看---https://www.cnblogs.com/guanyf/p/10863033.html---,这 ...

  6. gradle 国内加速,修改镜像源

    为什么慢 由于默认情况下执行 gradle 各种命令是去国外的 gradle 官方镜像源获取需要安装的具体软件信息,所以在不使用代理.不翻墙的情况下,从国内访问国外服务器的速度相对比较慢 如何修改镜像 ...

  7. C++内存修改器开源代码

    我们玩单机游戏时,游戏难度可能过大, 或者游戏已经比较熟练,想要增加游戏的玩法,这时候可以使用修改器. 内存式游戏修改器主要对游戏内存修改 修改时有两种方式,一是定时对内存数值进行修改.实现类似锁定的 ...

  8. jQ无法设置checkbox变成选中状态

    设置以后checkbox并没有变成选中状态,用chrome调试看了一下,checkbox中确实有checked属性,针对这个问题,大家可以参考下本文 代码如下: $("input" ...

  9. 使用matplotlib画出log的图像

    以下内容是学习笔记,若有侵权,立即删除! import math import matplotlib.pyplot as plt import numpy as np if __name__ == ' ...

  10. web编程非常实用的在线工具大全---转载

    代码对比/归并: http://www.matools.com/compare 正则表达式: http://www.matools.com/regex js/css压缩: http://www.mat ...