一、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. Sql server 2008 的完成备份和差异备份还原

    当数据库数据量不大的情况下用 Sqlserver 的完全备份就完全可以了 步骤为: 1.在需要还原的数据库上右键选择如图 2.在“常规”选项中点击“源设备”选取磁盘上备份好的.bak文件后,勾上“还原 ...

  2. 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 ...

  3. Java总结第一期

    神奇的小阳阳阳再度归来,大家一定想我了吧~哦,谢谢,谢谢,谢谢各位的掌声,thank you,thank you@ 第一章: 下面给大家简单介绍Java: Java技术可以应用在几乎所有类型和规模的设 ...

  4. window环境下pipd的安装

    参照:https://blog.csdn.net/jin80506/article/details/83111848 如果你还是无法使用尝试查看是否自己已经将:C:\software\Python\P ...

  5. CF 452E. Three strings(后缀数组+并查集)

    传送门 解题思路 感觉这种题都是套路之类的??首先把三个串并成一个,中间插入一些奇怪的字符,然后跑遍\(SA\).考虑按照\(height\)分组计算,就是每个\(height\)只在最高位计算一次, ...

  6. python基础实现tcp文件传输

    准备工作,实现文件上传需要那些工具呢? socket(传输).open()(打开文件).os(读取文件信息),当然还有辅助类sys和json,下面我们开始吧 import socket,sys imp ...

  7. VB - sendKey

    Set WshShell=WScript.CreateObject("WScript.Shell") WshShell = SendKeys string “string”:表示要 ...

  8. 转 Xshell ssh长时间连接不掉线设置

    1.Xshell客户端设置 2.服务器设置 vi /etc/ssh/sshd_config 把ClientAliveInterval 0和ClientAliveCountMax 3前的井号去掉,并把C ...

  9. Npm使用遇到的问题解决

    0.运行项目: 1)git clone 项目 2)项目根目录执行npm install安装依赖 3)执行npm run dev启动 1.安装cnpm: npm install -g cnpm --re ...

  10. 使用自编译的Emacs26.0.50build10版本,helm报错(已解决)

    使用自编译的Emacs26.0.50build10版本,helm报错(已解决) */--> code {color: #FF0000} pre.src {background-color: #0 ...