针对一款新的芯片,芯片厂商如何基于Linux编写对应的 SPI controller 驱动?

我们先看看 Linux SPI 的整体框架:

可以看到,最底层是硬件层,对应芯片内部 SPI controller 和 挂在 SPI 总线上的外部设备;中间层是内核层,对应 SPI 驱动;最顶层是用户空间的应用程序。

位于内核层的 SPI 驱动,Linux kernel 抽象出了 spi core,屏蔽掉各厂商 spi controller 的差异,对上为 spi device driver 提供统一接口,对下为各芯片厂商实现 spi controller driver 接入spi core 提供统一接口。

为了用户空间应用程序能直接操作 spi,kernel 除了抽象出 spi core,还实现了 spidev 程序。spidev 主要有两部分构成:虚拟的 spi 设备驱动 + 字符设备,前者利用 spi core 提供的接口操作 spi,后者提供 read/write/ioctl 接口给用户空间。

与 spidev 同一层的 specific spi device driver,指的是各个 spi 外设在内核空间实现的驱动程序,也是利用 spi core 提供的接口操作 spi。也就是说,如果要在用户空间驱动 spi 外设,那可以使用 spidev 提供的接口;如果是在内核空间驱动 spi 外设,那就无需用到 spidev,直接在内核空间编写驱动即可。

作为芯片厂商,如果芯片内置了 spi controller,那么就需要实现 spi contorller driver。结合某芯片平台示例,编写 spi controller driver 的主要步骤如下:

1、定义 platform device 和 platform driver,并注册到 platform。

2、定义 spi_controller(又称 spi_master) 并注册到 spi core。下图代码经过精简。如红色箭头所示,1是分配一个 spi_controller(spi_master) 实例,2是定义 controller 的一些属性和函数操作,3是注册到 spi core 中。

3、实现 spi_controller 的 ops (operations)。

最关键的 operations 有两个,如上图中红色箭头2所示,set_cs 函数和 transfer_one 函数。set_cs 是操作 spi cs 脚;transfer_one 是操作 spi controller 完成一次 spi transfer。什么是 spi transfer?spi transfer 和 spi message 是 spi core 定义的概念,spi transfer 简单地说就是一次spi读或者写的操作,而一个 spi message 可由一个或者多个 spi transfer 组成。spi transfer 不控制 spi cs脚,而 spi message 控制 spi cs 脚。

下图是set_cs的实现,可以看到有操作芯片 spi controller 的 IO_CONTROL 寄存器的 CS 位。

下图是transfer_one的实现。红色箭头处,就是调用实际 spi 传输的函数,而且区分了DMA和非DMA两种情况。这两个函数的具体实现,与该芯片平台 spi controller 的设计紧密相关,相关操作逻辑和寄存器定义需要查阅芯片Spec。


作者:bigfish99

博客:https://www.cnblogs.com/bigfish0506/

公众号:大鱼嵌入式

Linux芯片驱动之SPI Controller的更多相关文章

  1. [转]Linux芯片级移植与底层驱动(基于3.7.4内核)

      1.   SoC Linux底层驱动的组成和现状 为了让Linux在一个全新的ARM SoC上运行,需要提供大量的底层支撑,如定时器节拍.中断控制器.SMP启动.CPU hotplug以及底层的G ...

  2. Linux驱动:SPI驱动编写要点

    题外话:面对成功和失败,一个人有没有“冠军之心”,直接影响他的表现. 几周前剖析了Linux SPI 驱动框架,算是明白个所以然,对于这么一个庞大的框架,并不是每一行代码都要自己去敲,因为前人已经把这 ...

  3. 基于335X平台Linux交换芯片驱动开发

    基于335X平台Linux交换芯片驱动开发   一.软硬件平台资料 1.开发板:创龙AM3359核心板,网口采用RMII形式. 2.Kernel版本:4.4.12,采用FDT 3.交换芯片MARVEL ...

  4. 《linux设备驱动开发详解》笔记——15 linux i2c驱动

    结合实际代码和书中描述,可能跟书上有一定出入.本文后续芯片相关代码参考ZYNQ. 15.1 总体结构 如下图,i2c驱动分为如下几个重要模块 核心层core,完成i2c总线.设备.驱动模型,对用户提供 ...

  5. Linux设备驱动模型之I2C总线

    一.I2C子系统总体架构 1.三大组成部分 (1)I2C核心(i2c-core):I2C核心提供了I2C总线驱动(适配器)和设备驱动的注册.注销方法,提供了与具体硬件无关的I2C读写函数. (2)I2 ...

  6. linux设备驱动归纳总结(六):2.分享中断号【转】

    本文转载自:http://blog.chinaunix.net/uid-25014876-id-90837.html xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ...

  7. linux nandflash驱动之MTD层

    MTD,Memory Technology Device即内存技术设备,在Linux内核中,引入MTD层为NOR FLASH和NAND FLASH设备提供统一接口.MTD将文件系统与底层FLASH存储 ...

  8. 《Linux设备驱动开发具体解释(第3版)》进展同步更新

    本博实时更新<Linux设备驱动开发具体解释(第3版)>的最新进展. 2015.2.26 差点儿完毕初稿. 本书已经rebase到开发中的Linux 4.0内核,案例多数基于多核CORTE ...

  9. linux 设备驱动概述

    linux 设备驱动概述 目前,Linux软件工程师大致可分为两个层次: (1)Linux应用软件工程师(Application Software Engineer):       主要利用C库函数和 ...

随机推荐

  1. 寻找OEP

    1.使用ESP定律 OD载入后,F8一次,在寄存器窗口的ESP的内容上(如0012FFA4)右键:"在数据窗口中跟随",到内存数据窗口,将内存数据窗口以HEX数据形式显示,在刚才的 ...

  2. Day009 二维数组

    多维数组 多维数组是数组的嵌套(数组的元素是数组,数组的数组元素的元素是数组...),比如二维数组就是一个特殊的一维数组,其每一个元素都是一个一维数组. 二维数组 int a[][]=new int ...

  3. springmvcdemo

      项目点击属性  2.3  转换成2.5    已经变成一个网站项目了     报错消失 pom.xml <project xmlns="http://maven.apache.or ...

  4. 【转】浅谈自动特征构造工具Featuretools

    转自https://www.cnblogs.com/dogecheng/p/12659605.html 简介 特征工程在机器学习中具有重要意义,但是通过手动创造特征是一个缓慢且艰巨的过程.Python ...

  5. 10个 解放双手的 IDEA 插件,这些代码都不用写(第二弹)

    本文案例收录在 https://github.com/chengxy-nds/Springboot-Notebook 大家好,我是小富~ 鸽了很久没发文,不写文章的日子真的好惬意,每天也不用愁着写点什 ...

  6. java面试一日一题:java中垃圾回收算法有哪些

    问题:请讲下在java中有哪些垃圾回收算法 分析:该问题主要考察对java中垃圾回收的算法以及使用场景 回答要点: 主要从以下几点去考虑, 1.GC回收算法有哪些 2.每种算法的使用场景 3.基于垃圾 ...

  7. python爬虫——《瓜子网》的广州二手车市场信息

    由于多线程爬取数据比单线程的效率要高,尤其对于爬取数据量大的情况,效果更好,所以这次采用多线程进行爬取.具体代码和流程如下: import math import re from concurrent ...

  8. sscanf的应用

    1.提取字符串 2.提取指定长度的字符串 3.提取指定字符为止的字符串 4.取仅包含指定字符集的字符串 5.取到指定字符集为止的字符串 #include <stdio.h> int mai ...

  9. CRM系统有哪几种常见类型?

    随着市场的快速变化,客户开始变得越来越重要,因此CRM客户管理系统开始逐渐被企业所认可.从CRM系统进入中国市场到现在十余年的发展中,越来越多的CRM厂商开始出现.为了满足不同行业.不同类型的企业的需 ...

  10. 《Ray Tracing in One Weekend》阅读笔记 - 9、Metal(金属)

    如果我们希望不同的物体使用不同的材料,则需要进行设计决策.我们可以使用具有许多参数的通用材料,而将不同的材料类型仅将其中一些参数归零.这不是一个坏方法.或者我们可以有一个抽象的材料类来封装行为.我是后 ...