要为SPI控制器中添加设备,以前的方法是在BSP文件中添加,这种方法过于麻烦,现在都使用设备树dts进行外设的描述.

要想让SPI控制器能够在加载驱动时添加你的设备,需要在dts中添加设备节点,如下:

MT7688的设备树在openwrt_widora-master/target/linux/ramips/dts/ 目录下面: Widora.dts

下面添加树节点到SPI驱动器节点下面:

     palmbus@10000000 {68                 spi@b00 {69                         status = "okay";70 71                         pinctrl-names = "default";72 73 74                         pinctrl-0 = <&spi_pins>, <&spi_cs1_pins>;75 76                         m25p80@0 {77                                 #address-cells = <1>;78                                 #size-cells = <1>;79                                 compatible = "w25q128";80                                 reg = <0 0>;81                                 linux,modalias = "m25p80", "w25q128";82                                 spi-max-frequency = <40000000>;83                                 m25p,chunked-io = <31>;84 85                                 partition@0 {86                                         label = "u-boot";87                                         reg = <0x0 0x30000>;88                                         read-only;89                                 };90 91                                 partition@30000 {92                                         label = "u-boot-env";93                                         reg = <0x30000 0x10000>;94                                 };95 96                                 factory: partition@40000 {97                                         label = "factory";98                                         reg = <0x40000 0x10000>;99                                         read-only;
100                                 };
101
102                                 partition@50000 {
103                                         label = "firmware";
104                                         reg = <0x50000 0x0fb0000>;
105                                 };
106                         };
107 /*
108                         spidev@1 {
109                                 #address-cells = <1>;
110                                 #size-cells = <1>;
111                                 compatible = "spidev";
112                                 reg = <1 0>;
113                                 spi-max-frequency = <40000000>;
114                         };
115 */
116                         bpeer@1 {
117                                 #address-cells = <1>;
118                                 #size-cells = <1>;
119                                 compatible = "bpeer,tft0";
120                                 reg= <1 0>;spi-max-frequency = <60000000>;
122                                 spi-cpol = <1>;
123                                 spi-cpha = <1>;
124                         };bpeer@2 {  #address-cells = <1>;   #size-cells = <1>;       compatible = "bpeer,tft0";reg= <2 0>;     spi-max-frequency = <60000000>;      spi-cpha = <1>;                                    spi-cpol = <1>;};
125                 }        

bpeer@1这个是我的设备节点, @前面名字可以根据自己的爱好随意命名,@后面的数字代表使用的是几号片选,我使用的是CS1,故为1,

.compatible.这里的属性必须与驱动中的结构体: struct of_device_id 中的成员.compatible保持一致,

reg:此处与bpeer@1保持一致,本例子设为:<1 0>

spi-max-frequency :此处设置spi使用的最高频率.

spi-cpol,spi-cpha:SPI 的工作模式在此设置,本例所用的SPI工作模式为SPI_MODE_3

我在这里加了两个设备节点因为我有两个类型相同的设备,所以公用的同一个驱动,不同之处在于它们的片选不同,一个是CS1,另一个是CS2,

这里估计就疑惑了吧,哪里来的CS2,别急,咱们这就加,

在这之前,要先了解一下设备树是如何被驱动使用的,众所周知,当控制器驱动注册到系统后,spi驱动会扫描控制器节点下面的子节点,也就是看有几个设备,

调用过程如下,首先在spi-mt7621.c的   static int mt7621_spi_probe(struct platform_device *pdev)  函数的结尾,注册了控制器驱动到系统,

472         spin_lock_irqsave(&rs->lock, flags);
473
474         device_reset(&pdev->dev);
475
476         mt7621_spi_reset(rs, 0);
477
478         return spi_register_master(master);
spi_register_master(master)函数会扫描有多少个设备

在spi/spi.c中有对此函数的定义,只关心咱们要分析的如下:

1675         list_for_each_entry(bi, &board_list, list)
1676                 spi_match_master_to_boardinfo(master, &bi->board_info);
1677         mutex_unlock(&board_lock);
1678
1679         /* Register devices from the device tree and ACPI */
1680         of_register_spi_devices(master);
1681         acpi_register_spi_devices(master);

of_register_spi_devices(master);会注册所有的设备,它会根据设备树填充一个struct spi_device 结构体代表一个设备:

 852                 /* Device address */853                 prop = of_get_property(nc, "reg", &len);854                 if (!prop || len < sizeof(*prop)) {855                         dev_err(&master->dev, "%s has no 'reg' property\n",856                                 nc->full_name);857                         spi_dev_put(spi);858                         continue;859                 }860                 spi->chip_select = be32_to_cpup(prop);861 862                 /* Mode (clock phase/polarity/etc.) */863                 if (of_find_property(nc, "spi-cpha", NULL))864                         spi->mode |= SPI_CPHA;865                 if (of_find_property(nc, "spi-cpol", NULL))866                         spi->mode |= SPI_CPOL;867                 if (of_find_property(nc, "spi-cs-high", NULL))868                         spi->mode |= SPI_CS_HIGH;869                 if (of_find_property(nc, "spi-3wire", NULL))870                         spi->mode |= SPI_3WIRE;871 872                 /* Device speed */873                 prop = of_get_property(nc, "spi-max-frequency", &len);874                 if (!prop || len < sizeof(*prop)) {875                         dev_err(&master->dev, "%s has no 'spi-max-frequency' property\n",876                                 nc->full_name);877                         spi_dev_put(spi);878                         continue;879                 }880                 spi->max_speed_hz = be32_to_cpup(prop);

设备树里面的它都会读到并且填充到struct spi_device 结构体中作为一个设备,注意第860行,它会读取reg属性字段,并填充到spi->chip_select中作为几号片选,这里就OK了

了解完这些后我们就利用一个GPIO来作为片选2来使用,

方法就是,在SPI控制器驱动的mt7621_spi_setup(struct spi_device *spi)中添加对GPIO的申请及配置,注意头文件中要包含#include<linux/gpio.h>,修改如下:

static int mt7621_spi_setup(struct spi_device *spi)
382 {
383         struct mt7621_spi *rs = spidev_to_mt7621_spi(spi);
384         int status = 0;
385         if ((spi->max_speed_hz == 0) ||
386                 (spi->max_speed_hz > (rs->sys_freq / 2)))
387                 spi->max_speed_hz = (rs->sys_freq / 2);
388
389         if (spi->max_speed_hz < (rs->sys_freq / 4097)) {
390                 dev_err(&spi->dev, "setup: requested speed is too low %d Hz\n",
391                         spi->max_speed_hz);
392                 return -EINVAL;
393         }
394 /**************************************************************
395 *       Modefiy Liuchen on here
396 ***************************************************************/
397 //      int cs = spi->cs_gpio;
398         int cs = spi->chip_select;
399         if( cs >= 2 )
400         {
401                 status = gpio_request( 42, dev_name( &spi->dev ) );
402                 dev_info( spi->master->dev.parent,"in %s,cs_gpio =%d, status =%d\n", __func__, cs, status );
403                 if( status ) return status;
404                 status = gpio_direction_output( 42, 1);
405         }
406         return status;
407 }

该函数会在static void of_register_spi_devices(struct spi_master *master)中被调用.

接下来添加GPIO作为CS来操作,修改另外一个函数 mt7621_spi_set_cs(struct spi_device *spi, int enable),此函数用来设置CS片选信号的拉低及拉高,修改如下:

102 static void mt7621_spi_set_cs(struct spi_device *spi, int enable)
103 {
104         struct mt7621_spi *rs = spidev_to_mt7621_spi(spi);
105         int cs = spi->chip_select;
106         u32 polar = 0;
107
108         mt7621_spi_reset(rs, cs);
109         if(cs == 2)
110         {
111                 //printk("enable = %d\n",enable);
112                 //gpio_set_value_cansleep( 42, enable );
113                 gpio_set_value_cansleep( 42, (spi->mode&SPI_CS_HIGH)?enable: !enable );
114         }else
115         {
116                 if (enable)
117                         polar = BIT(cs);
118                 mt7621_spi_write(rs, MT7621_SPI_POLAR, polar);
119         }
120 }

至此已经添加完毕,重新编译内核就0K了.还有一种方式是在dts中直接添加,再此忽略了哦,没时间去搞了.........

为MT7688 SPI添加N个SPI接口相关推荐

  1. 基于MT7688 原厂SDK 使用SPI控制器驱动TFT屏幕ILI9225驱动器(spi接口)

    以下是我的一个利用SPI控制器操作屏的一个操作实例 包含一个bpeer_tft.c 和一个bpeer_tft.h 这是我基于flash驱动剥离出来的spi控制器驱动 好的话,顶起来~~~~~~~~~~ ...

  2. SPI通信协议:单片机spi通信接口什么意思,spi接口干什么用的?

    讲真,以前做开发的时候最怕就是调spi和iic. 因为公司没有逻辑分析仪,调起来全凭经验,一出问题找都找不到,只能仔细看代码盲调,看是不是哪个时序有问题. 说到这里,可能刚初学的小伙伴会问:单片机sp ...

  3. java spi_Java SPI(服务提供商接口)和ServiceLoader

    java spi Java SPI (Service Provider Interface) is the mechanism to load services dynamically. We can ...

  4. 微雪树莓派PICO笔记——7. SPI(串行外设接口)

    文章目录 SPI简介 硬件连接 通讯协议详解 RP2040 SPI 主要参数 RP2040 SPI 逻辑框图 machine.SPI类函数详解 例程地址 代码示例 代码实现 SPI简介 SPI全称为串 ...

  5. 为您的高速SPI添加强大和可靠的隔离交流

    介绍 串行外设接口(SPI)是工业设备中常用于数字处理器核心和外围设备之间通信的一种协议.然而,为了安全使用,有必要对外围设备和核心进行电隔离.虽然隔离和SPI都是成熟的技术,但将两者接口并不像预期的 ...

  6. SPI协议概括、SPI总线工作的四种方式和SPI接口时序

    SPI协议概括: SPI总线是一种4线总线,因其硬件功能很强,所以与SPI有关的软件就相当简单,使中央处理器(Central Processing Unit,CPU)有更多的时间处理其他事务.正是因为 ...

  7. linux spi屏驱动程序,65 linux spi设备驱动之spi LCD屏驱动

    SPI的控制器驱动由平台设备与平台驱动来实现. 驱动后用spi_master对象来描述.在设备驱动中就可以通过函数spi_write, spi_read, spi_w8r16, spi_w8r8等函数 ...

  8. ginkgo spi 错误_开发SPI时不要犯这个错误

    ginkgo spi 错误 您的大多数代码都是私有的,内部的,专有的,并且永远不会公开. 在这种情况下,您可以放轻松–您可以重构所有错误,包括那些可能导致API更改中断的错误. 但是,如果要维护公共A ...

  9. Arduino 与 SPI 结合使用 以及SPI 深层理解

    本文主要讲解两部分内容,不做任何转发,仅个人学习记录: 一. Arduino 与 SPI 结合使用  : 二. SPI 深层理解 有价值的几个好的参考: 1. 中文版: https://blog.cs ...

最新文章

  1. SpringBoot入门(1)——创建springBoot项目
  2. hdu_4391,线段树
  3. 【暑假训练 7.10】 codevs 2492 上帝造题的七分钟2
  4. CentOS7下解决yum install mysql-server没有可用包的问题
  5. 比较=、==、===
  6. 详解Java动态代理机制
  7. 大神干货:冠军选手分享解题思路,助你轻松突围初赛
  8. ArrayList的add方法值被覆盖(android项目)
  9. Ubuntu18 mongodb 离线安装
  10. 《地球概论》(第3版)笔记 第二章 地球的宇宙环境
  11. 直线型一阶倒立摆3---控制器设计
  12. 超市进销存之openGauss数据库的应用与实践
  13. 001、【C语言编程题目】猴子吃桃问题
  14. 来钱快的3种副业,虽然不起眼,不过很赚钱‍‍‍
  15. ggplot 绘制热图
  16. CLICKHOUSE函数使用经验(arrayJoin与arrayMap函数应用场景)
  17. Excel大数据排查重复行内容方法,三步搞定!
  18. geotools 可视化,具有无状态渲染器
  19. 【离散数学期复习系列】二、一阶逻辑(谓词逻辑)
  20. 北京精雕电主轴用海德汉编码器AK ERM280/2480/TTRERM2404/vs sensorik编码器RGM2G-AE3-V3Z参数接线定义

热门文章

  1. php mcrypt aes,简单的PHP加密/解密(Mcrypt,AES)
  2. vFlash 软件升级方案
  3. python小欢喜(七)游戏编程 (2) 挡球游戏的改进:使用中文提示并添加声音效果
  4. 组织机构代码生成规则
  5. Linux桌面两大阵营 GNOME与KDE的战争
  6. 创建数据库并指定字符集
  7. 关于VS/VC工程编译不过去这件事
  8. 圣卡塔利娜海岸5K Mac高清壁纸
  9. 树和二叉树知识要点(期末必考)
  10. 窄带物联网NB-IOT