一:首先在我的平台注册platform_device,保证能让spi-gpio.c能执行到probe函数。

   1:  struct spi_gpio_platform_data {
   2:      unsigned    sck;
   3:      unsigned    mosi;
   4:      unsigned    miso;
   5:   
   6:      u16        num_chipselect;
   7:  };
   1:  //#define NCS      GPIO_PB(2)                     //定义SS所对应的GPIO接口编号  
   2:  //#define SCLK     GPIO_PB(0)                     //定义SCLK所对应的GPIO接口编号  
   3:  //#define MOSI     GPIO_PB(4)                     //定义SCLK所对应的GPIO接口编号  
   4:  //#define MISO     GPIO_PB(1)
   5:  static struct spi_gpio_platform_data jz_spi_gpio_data = {
   6:      .sck    = GPIO_PB(0),    //GPIO_SPI_SCK,
   7:      .mosi    = GPIO_PB(4),     //GPIO_SPI_MOSI,
   8:      .miso    = GPIO_PB(1),    //GPIO_SPI_MISO,
   9:      .num_chipselect = 1,
  10:  };
  11:   
  12:  struct platform_device jz_spi_gpio_device = {
  13:      .name   = "spi_gpio",
  14:      .id     = 0, 
  15:      .dev    = {
  16:          .platform_data = &jz_spi_gpio_data,
  17:      },
  18:  };

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

注册platform device

1: platform_device_register(&jz_spi_gpio_device);
 

二:注册platform_driver在spi_gpio.c里面注册platform driver

   1:  MODULE_ALIAS("platform:" DRIVER_NAME);
   2:   
   3:  static struct platform_driver spi_gpio_driver = {
   4:      .driver.name    = DRIVER_NAME,
   5:      .driver.owner    = THIS_MODULE,
   6:      .remove        = __exit_p(spi_gpio_remove),
   7:  };
   8:   
   9:  static int __init spi_gpio_init(void)
  10:  {
  11:      return platform_driver_probe(&spi_gpio_driver, spi_gpio_probe);
  12:  }
  13:  module_init(spi_gpio_init);
  14:   
  15:  static void __exit spi_gpio_exit(void)
  16:  {
  17:      platform_driver_unregister(&spi_gpio_driver);
  18:  }
  19:  module_exit(spi_gpio_exit);
  20:   
  21:   
  22:  MODULE_DESCRIPTION("SPI master driver using generic bitbanged GPIO ");
  23:  MODULE_AUTHOR("David Brownell");
  24:  MODULE_LICENSE("GPL");

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

 

三:具体算法分析

   1:  struct spi_gpio {
   2:      struct spi_bitbang          bitbang;        /* gpio 模拟spi算法相关的结构 */
   3:      struct spi_gpio_platform_data  pdata;        /* spi platform data 对应模拟spi的四个gpio编号 */
   4:      struct platform_device    *pdev;        /* 对应注册的 platform device */
   5:  };
   1:   
   2:  static int __init spi_gpio_probe(struct platform_device *pdev)
   3:  {
   4:      int                status;
   5:      struct spi_master        *master;
   6:      struct spi_gpio            *spi_gpio;
   7:      struct spi_gpio_platform_data    *pdata;
   8:      u16 master_flags = 0;
   9:   
  10:      pdata = pdev->dev.platform_data; /* 存放spi的四根gpio */
  11:  #ifdef GENERIC_BITBANG
  12:      if (!pdata || !pdata->num_chipselect)
  13:          return -ENODEV;
  14:  #endif
  15:   
  16:      /* 申请注册四个gpio */
  17:      status = spi_gpio_request(pdata, dev_name(&pdev->dev), &master_flags);
  18:      if (status < 0) {
  19:          return status;
  20:      }
  21:   
  22:      /* alloc a spi master ,master->dev->p->driver_data = &master[1]*/
  23:      master = spi_alloc_master(&pdev->dev, sizeof *spi_gpio);
  24:      if (!master) {
  25:          status = -ENOMEM;
  26:          goto gpio_free;
  27:      }
  28:      /* spi_gpio指向一块空间, 即指向mstaer[1] 
  29:         pdev->dev->p->driver_data = spi_gpio;
  30:         初始化spi_gpio
  31:      */
  32:      spi_gpio = spi_master_get_devdata(master);
  33:      platform_set_drvdata(pdev, spi_gpio); 
  34:   
  35:      spi_gpio->pdev = pdev;
  36:      if (pdata)
  37:          spi_gpio->pdata = *pdata;
  38:   
  39:      master->flags = master_flags;
  40:      master->bus_num = pdev->id;
  41:      master->num_chipselect = SPI_N_CHIPSEL;
  42:      master->setup = spi_gpio_setup; /* setup 比如cs引脚申请 */
  43:      master->cleanup = spi_gpio_cleanup;
  44:      /* spi_gpio->bitbang.master = master */
  45:      spi_gpio->bitbang.master = spi_master_get(master);
  46:      spi_gpio->bitbang.chipselect = spi_gpio_chipselect;
  47:      /* spi_gpio->bitbang.txrx_word 数组函数四个元素指针,分别指向spi四种mode算法函数 */
  48:      if ((master_flags & (SPI_MASTER_NO_TX | SPI_MASTER_NO_RX)) == 0) {
  49:          spi_gpio->bitbang.txrx_word[SPI_MODE_0] = spi_gpio_txrx_word_mode0;
  50:          spi_gpio->bitbang.txrx_word[SPI_MODE_1] = spi_gpio_txrx_word_mode1;
  51:          spi_gpio->bitbang.txrx_word[SPI_MODE_2] = spi_gpio_txrx_word_mode2;
  52:          spi_gpio->bitbang.txrx_word[SPI_MODE_3] = spi_gpio_txrx_word_mode3;
  53:      } else {
  54:          spi_gpio->bitbang.txrx_word[SPI_MODE_0] = spi_gpio_spec_txrx_word_mode0;
  55:          spi_gpio->bitbang.txrx_word[SPI_MODE_1] = spi_gpio_spec_txrx_word_mode1;
  56:          spi_gpio->bitbang.txrx_word[SPI_MODE_2] = spi_gpio_spec_txrx_word_mode2;
  57:          spi_gpio->bitbang.txrx_word[SPI_MODE_3] = spi_gpio_spec_txrx_word_mode3;
  58:      }
  59:      /* spi_gpio->bitbang.setup_transfer初始化传输的bits_per_word和speed */
  60:      spi_gpio->bitbang.setup_transfer = spi_bitbang_setup_transfer;
  61:      spi_gpio->bitbang.flags = SPI_CS_HIGH;
  62:      /* spi_gpio->bitbang相关算法接口初始化 */
  63:      status = spi_bitbang_start(&spi_gpio->bitbang);
  64:      if (status < 0) {
  65:          spi_master_put(spi_gpio->bitbang.master);
  66:  gpio_free:
  67:          if (SPI_MISO_GPIO != SPI_GPIO_NO_MISO)
  68:              gpio_free(SPI_MISO_GPIO);
  69:          if (SPI_MOSI_GPIO != SPI_GPIO_NO_MOSI)
  70:              gpio_free(SPI_MOSI_GPIO);
  71:          gpio_free(SPI_SCK_GPIO);
  72:          spi_master_put(master);
  73:      }
  74:   
  75:      return status;
  76:  }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

 

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

四:总之最终让spi_gpi0整个对象存放了整个gpio模拟spi的算法结构;而pdev->dev->p->driver_data = spi_gpio;
platform device和 platform driver两者match结果是:

root@CarRadio:/# ls /sys/bus/platform/devices/spi_gpio.0/
driver      modalias    power       spi0.0      spi_master  subsystem   uevent
root@CarRadio:/# ls /sys/bus/platform/devices/spi_gpio.0/driver/
spi_gpio.0  uevent

linux SPI驱动——gpio模拟spi驱动(三)的更多相关文章

  1. GPIO模拟SPI

    上次用gpio模拟i2c理解i2c协议.相同的,我用gpio模拟spi来理解spi协议. 我用的是4线spi,四线各自是片选.时钟.命令/数据.数据. 数据在时钟上升沿传递,数据表示的是数据还是命令由 ...

  2. am335x gpio 模拟 spi 驱动添加

    kernel 内 make menuconfig // make menuconfig Device Drivers ---> [*] SPI support ---> <*> ...

  3. gpio模拟i2c驱动

    前段时间做项目,需要gpio模拟i2c通信,最后参考了一些资料,然后编写了一个程序.现在发出来,以免以后忘记,也为一些需要的朋友提供参考.不喜勿喷哈. /* 说明:该程序是基于atmel公司的sama ...

  4. linux SPI驱动——简单的gpio模拟SPI驱动测试 (二)

    1: /* 2: * Add by xuyonghong for duotin car radio fm 3: * Copyright (C) 2016-5-24 xuyonghong@duotin. ...

  5. 使用STM32的USART的同步模式Synchronous调戏SPI【usart模拟spi理论】

    [原创出品§转载请注明出处] 出处:http://www.cnblogs.com/libra13179/p/7064321.html 什么东西?? 我们先来看我们平常看到SPI的时序图(呵呵,要是忘记 ...

  6. STM32-24位AD7799驱动之手册代码详解,支持模拟SPI和硬件SPI

    1.AD7799介绍 AD7799结构图如下所示: 其中REFIN参考电压建议为2.5V, REFIN电压低于0.1V时,则差分输入ad值就无法检测了,如下图所示: 注意: 如果REG_CONFIG的 ...

  7. LPC4370使用学习:GPIO的引脚功能使用,和12864OLED模拟I2C驱动

    一: 手中有块LPC4370的开发板,因为便宜,所以引脚引出的不多,而且只有基本的底板资源驱动代码和例程. 看着手册和例程看了老半天,写程序写了半天,结果GPIO老是驱动不起来,因为引脚配置寄存器中有 ...

  8. 软件模拟spi的注意事项

    前几天遇到了软件模拟spi的时候,读和写不一致的现象,后来仔细研究了一下,其实是时序性问题不对. spi的有四种时序,硬件实现的时候,很简单,初始化后直接调用api即可.但是软件模拟就比较麻烦. 举例 ...

  9. linux enc28j60网卡驱动移植(硬件spi和模拟spi)

    本来想移植DM9000网卡的驱动,无奈硬件出了点问题,通过杜邦线链接开发板和DM9000网卡模块,系统上电,还没加载网卡驱动就直接崩溃了,找不到原因...刚好手上有一个enc28j60的网卡模块,于是 ...

随机推荐

  1. 17.2.10 NOIP模拟赛 聪哥的工资

    聪哥的工资 (money/money.in/money.out) 时限1000ms 内存256MB 题目描述 lwher: 了体验劳苦大众的生活,聪哥在暑假参加了打零工的活动,这个活动分为n个工作日, ...

  2. [转].net创建XML文件的两种方法

    原文发布时间为:2009-08-26 -- 来源于本人的百度文章 [由搬家工具导入] 方法一:按照XML的结构一步一步的构建XML文档.    通过.Net FrameWork SDK中的命名空间&q ...

  3. javascript屏蔽脏字

    原文发布时间为:2009-04-16 -- 来源于本人的百度文章 [由搬家工具导入] <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Tran ...

  4. [LeetCode] Binary Tree Postorder Traversal dfs,深度搜索

    Given a binary tree, return the postorder traversal of its nodes' values. For example:Given binary t ...

  5. poj 3693 Maximum repetition substring 重复次数最多的连续子串

    题目链接 题意 对于任意的字符串,定义它的 重复次数 为:它最多可被划分成的完全相同的子串个数.例如:ababab 的重复次数为3,ababa 的重复次数为1. 现给定一字符串,求它的一个子串,其重复 ...

  6. python 生成式和生成器

    #!/usr/bin/env python # -*- coding:utf-8 -*- # @Time : 2017/10/17 21:46 # @Author : lijunjiang # @Fi ...

  7. hdu 5055(模拟)

    Bob and math problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...

  8. Codeforces 371A K-Periodic Array(模拟)

    题目链接 K-Periodic Array 简单题,直接模拟即可. #include <bits/stdc++.h> using namespace std; #define REP(i, ...

  9. 11G在用EXP导出时,空表不能导出

    11G中有个新特性,当表无数据时,不分配segment,以节省空间 解决方法: 1.insert一行,再rollback就产生segment了. 该方法是在在空表中插入数据,再删除,则产生segmen ...

  10. css 让两个div重叠

    做网页的时候在div里放了一个别的网页的天气插件,但是点击了会跳到广告页面的,想去网上找个禁止div点击的方法,可是发现没有,用了js的方法好像也没有成功,后来觉得还是用两个层重叠的方法来阻止点击,虽 ...