Linux kernel 有关 spi 设备树参数解析
一、最近做了一个 spi 设备驱动从板级设备驱动升级到设备树设备驱动,这其中要了解 spi 设备树代码的解析。
二、 设备树配置如下:
503 &spi0 {
504 status = "okay";
505 pinctrl-name = "default";
506 pinctrl-0 = <&spi0_pins>;
507 ti,pindir-d0-out-d1-in;
508
509 wk2124A {
510 compatible = "wk2124A"; // 匹配字符串
511 reg = <0>; // cs
512 # spi-cpha = <1>; // 配置 spi 的模式
513 # spi-tx-bus-width = <1>; // 这是是 spi-tx 的总线宽度
514 # spi-rx-bus-width = <1>;
515 spi-max-frequency = <10000000>; // spi 最大速率配置
516 };
517 };
三、代码跟踪
// drivers/spi/spi.c
2772 postcore_initcall(spi_init); // spi_init
2733 static int __init spi_init(void)
2734 {
2735 int status;
2736
2737 buf = kmalloc(SPI_BUFSIZ, GFP_KERNEL);
2738 if (!buf) {
2739 status = -ENOMEM;
2740 goto err0;
2741 }
2742
2743 status = bus_register(&spi_bus_type);
2744 if (status < 0)
2745 goto err1;
2746
2747 status = class_register(&spi_master_class);
2748 if (status < 0)
2749 goto err2;
2750
2751 if (IS_ENABLED(CONFIG_OF_DYNAMIC))
2752 WARN_ON(of_reconfig_notifier_register(&spi_of_notifier)); // 这里要注册 主机和从机
2753
2754 return 0;
2755
2756 err2:
2757 bus_unregister(&spi_bus_type);
2758 err1:
2759 kfree(buf);
2760 buf = NULL;
2761 err0:
2762 return status;
2763 }
2726 static struct notifier_block spi_of_notifier = {
2727 .notifier_call = of_spi_notify,
2728 };
2686 static int of_spi_notify(struct notifier_block *nb, unsigned long action,
2687 void *arg)
2688 {
2689 struct of_reconfig_data *rd = arg;
2690 struct spi_master *master;
2691 struct spi_device *spi;
2692
2693 switch (of_reconfig_get_state_change(action, arg)) {
2694 case OF_RECONFIG_CHANGE_ADD:
2695 master = of_find_spi_master_by_node(rd->dn->parent); // 找到主机节点
2696 if (master == NULL)
2697 return NOTIFY_OK; /* not for us */
2698
2699 spi = of_register_spi_device(master, rd->dn); // ---> 注册设备
2700 put_device(&master->dev);
// ... ...
2722
2723 return NOTIFY_OK;
2724 }
1428 #if defined(CONFIG_OF)
1429 static struct spi_device *
1430 of_register_spi_device(struct spi_master *master, struct device_node *nc)
1431 {
1432 struct spi_device *spi;
1433 int rc;
1434 u32 value;
1435
1436 /* Alloc an spi_device */
1437 spi = spi_alloc_device(master);
1438 if (!spi) {
1439 dev_err(&master->dev, "spi_device alloc error for %s\n",
1440 nc->full_name);
1441 rc = -ENOMEM;
1442 goto err_out;
1443 }
1444
1445 /* Select device driver */
1446 rc = of_modalias_node(nc, spi->modalias, // 匹配到从机
1447 sizeof(spi->modalias));
1448 if (rc < 0) {
1449 dev_err(&master->dev, "cannot find modalias for %s\n",
1450 nc->full_name);
1451 goto err_out;
1452 }
1453
1454 /* Device address */
1455 rc = of_property_read_u32(nc, "reg", &value); // 设备节点 reg 表示 cs
1456 if (rc) {
1457 dev_err(&master->dev, "%s has no valid 'reg' property (%d)\n",
1458 nc->full_name, rc);
1459 goto err_out;
1460 }
1461 spi->chip_select = value;
1462
1463 /* Mode (clock phase/polarity/etc.) */ // 选择 spi 的模式
1464 if (of_find_property(nc, "spi-cpha", NULL))
1465 spi->mode |= SPI_CPHA;
1466 if (of_find_property(nc, "spi-cpol", NULL))
1467 spi->mode |= SPI_CPOL;
1468 if (of_find_property(nc, "spi-cs-high", NULL)) // 选择 spi cs 是高有效还是低有效
1469 spi->mode |= SPI_CS_HIGH;
1470 if (of_find_property(nc, "spi-3wire", NULL))
1471 spi->mode |= SPI_3WIRE;
1472 if (of_find_property(nc, "spi-lsb-first", NULL))
1473 spi->mode |= SPI_LSB_FIRST;
1474
1475 /* Device DUAL/QUAD mode */ // 选择 单线还是双线通道
1476 if (!of_property_read_u32(nc, "spi-tx-bus-width", &value)) {
1477 switch (value) {
1478 case 1:
1479 break;
1480 case 2:
1481 spi->mode |= SPI_TX_DUAL;
1482 break;
1483 case 4:
1484 spi->mode |= SPI_TX_QUAD;
1485 break;
1486 default:
1487 dev_warn(&master->dev,
1488 "spi-tx-bus-width %d not supported\n",
1489 value);
1490 break;
1491 }
1492 }
1493
1494 if (!of_property_read_u32(nc, "spi-rx-bus-width", &value)) {
1495 switch (value) {
1496 case 1:
1497 break;
1498 case 2:
1499 spi->mode |= SPI_RX_DUAL;
1500 break;
1501 case 4:
1502 spi->mode |= SPI_RX_QUAD;
1503 break;
1504 default:
1505 dev_warn(&master->dev,
1506 "spi-rx-bus-width %d not supported\n",
1507 value);
1508 break;
1509 }
1510 }
1511
1512 /* Device speed */ // 设备速度 配置
1513 rc = of_property_read_u32(nc, "spi-max-frequency", &value);
1514 if (rc) {
1515 dev_err(&master->dev, "%s has no valid 'spi-max-frequency' property (%d)\n",
1516 nc->full_name, rc);
1517 goto err_out;
1518 }
1519 spi->max_speed_hz = value;
1520
1521 /* Store a pointer to the node in the device structure */
1522 of_node_get(nc);
1523 spi->dev.of_node = nc; // 保存设备结构体
1524
1525 /* Register the new device */
1526 rc = spi_add_device(spi);
1527 if (rc) {
1528 dev_err(&master->dev, "spi_device register error %s\n",
1529 nc->full_name);
1530 goto err_out;
1531 }
1532
1533 return spi;
1534
1535 err_out:
1536 spi_dev_put(spi);
1537 return ERR_PTR(rc);
1538 }
Linux kernel 有关 spi 设备树参数解析的更多相关文章
- linux设备驱动程序-i2c(2)-adapter和设备树的解析
linux设备驱动程序-i2c(2)-adapter和设备树的解析 (注: 基于beagle bone green开发板,linux4.14内核版本) 在本系列linux内核i2c框架的前两篇,分别讲 ...
- linux驱动之获取设备树信息
上一篇文章学习了字符设备的注册,操作过的小伙伴都知道上一篇文章中测试驱动时是通过手动创建设备节点的,现在开始学习怎么自动挂载设备节点和设备树信息的获取,这篇文章中的源码将会是我以后编写字符驱动的模板. ...
- ARM Linux 3.x的设备树(Device Tree)
http://blog.csdn.net/21cnbao/article/details/8457546 宋宝华 Barry Song <21cnbao@gmail.com> 1. ...
- ARM Linux 3.x的设备树(Device Tree)
1. ARM Device Tree起源 Linus Torvalds在2011年3月17日的ARM Linux邮件列表宣称“this whole ARM thing is a f*cking pai ...
- 【转】 ARM Linux 3.x的设备树(Device Tree)
1. ARM Device Tree起源 http://blog.csdn.net/21cnbao/article/details/8457546 Linus Torvalds在2011年3月1 ...
- 【转】ARM Linux 3.x的设备树(Device Tree)
原文网址:http://blog.csdn.net/21cnbao/article/details/8457546 1. ARM Device Tree起源 Linus Torvalds在201 ...
- ARM Linux 3.x的设备树(Device Tree)【转】
转自:http://blog.csdn.net/21cnbao/article/details/8457546 宋宝华 Barry Song <21cnbao@gmail.com> 1. ...
- imx6设备树pinctrl解析【转】
转自:http://blog.csdn.net/michaelcao1980/article/details/50730421 版权声明:本文为博主原创文章,未经博主允许不得转载. 最近在移植linu ...
- LINUX kernel笔记系列 :IO块参数 图
Linux下,I/O处理的层次可分为4层: 系统调用层,应用程序使用系统调用指定读写哪个文件,文件偏移是多少 文件系统层,写文件时将用户态中的buffer拷贝到内核态下,并由cache缓存该部分数 ...
随机推荐
- 第二篇:呈现内容_第二节:WebControl呈现
一.WebControl的呈现过程 WebControl派生自Control类,所以WebControl的呈现功能基于Control的呈现逻辑之上,但有了比较大的扩展. 首先,WebControl重写 ...
- centos 6.5 上安装使用upsource
这里应领导的要求,在服务器上装了upsource Upsource的安装和与JetBrains工具的集成 JetBrains的工具一直都是我开发和学习的好帮手,本人工作主要是iOS开发,使用的是App ...
- Java数据结构和算法(十):二叉树
一.简介 二叉树是树这种数据结构的一员,后面我们还会介绍红黑树,2-3-4树等数据结构.那么为什么要使用树?它有什么优点? 前面我们介绍数组的数据结构,我们知道对于有序数组,查找很快,并介绍可以通过二 ...
- 一种解决新版本API完全兼容老版本API的方法
原文:http://android.eoe.cn/topic/android_sdk 这节课程我们讨论如何创建一个实现类,即能对应新版本的API,又能够保持对老版本API的支持. * 寻找一个替代的解 ...
- linux c select函数使用求解释
代码非常easy,就是发送c语言发送http请求.但 i= read(sockfd, buf, BUFSIZE-1); 能够正常执行, 替换为i= Read(sockfd, buf, B ...
- amazon建立基于centos的ec2
在amazon上建立centos系统的ec2,主要就是系统要找对. 1.登录网址:amazonaws-china.com,注意这个网址是专门为在国内建立国外通用亚马逊ec2设立的,其他的是用国内的ec ...
- [na]tcpdump非常实用的抓包实例
基本语法篇 常用应用: 过滤物理口 过滤某个port/ip/mac 过滤协议 显示ip/mac/port不解析等 过滤mac tcpdump -i eth0 ether host 24:DF:6A:F ...
- 文档 - STOMP Over WebSocket
http://jmesnil.net/stomp-websocket/doc/ What is STOMP? STOMP is a simple text-orientated messaging p ...
- Android-优化UI性能(1)-降低主线程的堵塞时间
Android-优化UI性能(1)-降低主线程的堵塞时间 一 降低主线程的堵塞时间 Android已经提供了AsyncTask实现从主线程生成新的异步任务的方法. 定义并实现以下的类就可以(方法由系统 ...
- Spring Cloud Consul
1.2.0.RELEASE 该项目通过自动配置并绑定到Spring环境和其他Spring编程模型成语,为Spring Boot应用程序提供Consul集成.通过几个简单的注释,您可以快速启用和配置应用 ...