一、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. 「NOI2017」蔬菜 解题报告

    「NOI2017」蔬菜 首先考虑流 可以从 \(s\) 流入表示得到蔬菜,流出到 \(t\) 表示卖出蔬菜,给每个蔬菜拆点,并给它它每天应得的蔬菜. 但是我们没办法直接给,注意到如果把变质看成得到并可 ...

  2. [CSP-S模拟测试]:Walk(BFS+建边)

    题目描述 在比特镇一共有$n$个街区,编号依次为$1$到$n$,它们之间通过若干条单向道路连接. 比特镇的交通系统极具特色,除了$m$条单向道路之外,每个街区还有一个编码${val}_i$,不同街区可 ...

  3. [CSP-S模拟测试]:密码(AC自动机+DP)

    题目传送门(内部题19) 输入格式 第一行两个正整数$n,k$,代表秘钥个数和要求.接下来两个正整数$x$和$y$,意义如题所述.接下来$n$行,每行一个正整数,意义如题所述. 输出格式 一个正整数, ...

  4. sublime常用基础插件合集

    插件介绍 Package Control 功能:安装包管理简介:sublime插件控制台,提供添加.删除.禁用.查找插件等功能使用方法:快捷键 Ctrl+Shift+P,输入 install 选中In ...

  5. 2018-2019-2 实验三 敏捷开发与XP实践

    实验内容 1.XP基础 2.XP核心实践 3.相关工具 实验要求 1.没有Linux基础的同学建议先学习<Linux基础入门(新版)><Vim编辑器> 课程 2.完成实验.撰写 ...

  6. 建站手册-网站构建:万维网联盟(World Wide Web Consortium)

    ylbtech-建站手册-网站构建:万维网联盟(World Wide Web Consortium) 1.返回顶部 1. http://www.w3school.com.cn/site/site_w3 ...

  7. git配置密钥(私钥、ssh、公钥)

    参照: https://blog.csdn.net/weixin_42063071/article/details/80999690 经常帮人配置git的私钥,来总结一下简单的流程真心希望对大家有所帮 ...

  8. mybatis 学习视频总结记录

    学习mybaits简单增删改查例子记录 此整理是学习视频后的视频内容整理,后半段还没有整理 网易云课堂 SSM高级整合视频 地址 : http://study.163.com/course/cours ...

  9. automate sap遇上的一些问题

    1. get column name of SAPGuiTable columnCount = SAPGuiSession("Session").SAPGuiWindow(&quo ...

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

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