一:首先在我的平台注册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. 51Nod 1001 数组中和等于K的数对 And 1015 水仙花数

    1001 数组中和等于K的数对 基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题 给出一个整数K和一个无序数组A,A的元素为N个互不相同的整数,找出数组A中所有和等于K ...

  2. ubuntu 配置虚拟主机

    ubuntu下Apache虚拟主机的配置   启用站点停用站点方法   a2ensite/a2dissite 比如添加一个ecshop 的虚拟机 首先到/etc/apache2/site-availa ...

  3. PHP json_encode 转换成空对象和空数组

    对于以下对象 $foo = array( "bar1" => array(), "bar2" => array() ); 我想转换成 { " ...

  4. Educational Codeforces Round 34 C. Boxes Packing【模拟/STL-map/俄罗斯套娃】

    C. Boxes Packing time limit per test 1 second memory limit per test 256 megabytes input standard inp ...

  5. Longest Increasing Subsequence - LeetCode

    Given an unsorted array of integers, find the length of longest increasing subsequence. For example, ...

  6. QQ聊天窗口上的广告与QQ弹窗广告的完美屏蔽去除

    涉及的软件 1. QQ  (笔者的为v8.2版本) 2. Win7 3. ADSafe(3.13.308.9900正式版) 前言 QQ广告十分讨人厌,除了QQ弹窗的广告,让人十分反感外,最近发现QQ聊 ...

  7. goreplay使用

    最新版的发布公告:https://leonsbox.com/goreplay-v0-16-and-4th-anniversary-5408b1fd72e0 主要提到:中间件.报文解压.从kafka读取 ...

  8. 一入python深似海--range()、list与for

    range使用方法 使用python的人都知道range()函数非常方便,今天再用到他的时候发现了非常多曾经看到过可是忘记的细节. 这里记录一下: range(1,5)#代表从1到5(不包括5) [1 ...

  9. 2016.7.14 如何在浏览器中查看jsp文件

    参考资料: http://jingyan.baidu.com/article/ed15cb1b10f1241be36981ab.html 1.复制jsp文件地址 2.写在浏览器里 E:/lyh/tas ...

  10. 转: RPC框架 远程对象服务引擎Hprose

    http://www.cnblogs.com/chenxizhang/archive/2010/07/18/1780258.html