针对一款新的芯片,芯片厂商如何基于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. Django中的模型(操作数据库)

    目录 Django配置连接数据库 在Django中操作数据库 原生SQL语句操作数据库 ORM模型操作数据库 增删改查 后台管理 使用后台管理数据库 模型是数据唯一而且准确的信息来源.它包含您正在储存 ...

  2. CTF常见的加密和编码方法

    目录 哈希摘要算法 对称加密算法 其他加密算法 编码 哈希摘要算法 以  root 加密为例. MD4:32位的摘要算法.2add09183d0b1dc0428701df9838fba MD5:32位 ...

  3. Win64 驱动内核编程-13.回调监控模块加载

    回调监控模块加载 模块加载包括用户层模块(.DLL)和内核模块(.SYS)的加载.传统方法要监控这两者加在必须 HOOK 好几个函数,比如 NtCreateSection 和 NtLoadDriver ...

  4. Swift系列五 - 可选项

    可选项,一般也叫可选类型,它允许将值设为nil. 一.定义可选项 平时开发中,如果我们需要把一个变量置空时只需要把变量赋值一个nil即可: 上面尝试后不行,那怎么把一个变量置空呢? 答案:把变量设置可 ...

  5. python爬虫——抖音数据

    最近挺火的抖音短视频,不仅带火了一众主播,连不少做电商的也进驻其中,于是今天我来扒一扒这火的不要不要的抖音数据: 一.抓包工具获取用户ID 对于手机app数据,抓包是最直接也是最常见的手段,常用的抓包 ...

  6. QFNU 10-16 training

    7-9.小字辈 思路:建立一个类,并且类中存有其父节点,其地位,其儿子节点(因为儿子节点有很多,所以要用vector进行存储),通过-1这个祖先节点进行查找.首先找到-1这个祖先节点,并且读入其他位置 ...

  7. 【BUAA_2020_软工】个人作业

    个人项目作业博客 1. 在文章开头给出教学班级和可克隆的 Github 项目地址(例子如下).(1') 项目 内容 北航2020软工 班级博客 作业要求 具体要求 项目GitHub地址 个人项目 教学 ...

  8. Go快速入门(二)

    提示:本系列文章适合有其他语音基础并对Go有持续冲动的读者 一.package介绍 ​ Go语言的代码是通过package来组织的,package的概念和你知道的其它语言 里的libraries或者m ...

  9. linux基本命令随笔

    cd(change directory) 不跟参数,直接进入当前登录用户的家目录 . 代表当前目录 .. 代表上级目录 ls(list) -l 显示文件详细信息 -a 显示隐藏文件 -S 以文件大小排 ...

  10. gitlab同步插件gitlab-mirrors报错<已解决,未找到原因>

    今天下午在使用gitlab-mirrors同步插件时,发现一直在报错 # ~/gitlab-mirrors/add_mirror.sh --git --project-name manifests - ...