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缓存该部分数 ...
随机推荐
- session的取代者:Json Web Tokens----在客户端存储登陆状态
https://auth0.com/blog/2014/01/07/angularjs-authentication-with-cookies-vs-token/
- SharePoint 2013 How to Backup Site Collection Automatically With a PowerShell Script
In this post I will introduce a way how to run a script for backing up SharePoint data which could b ...
- asp.net与C# path.GetFullPath 获取上级目录
string path = new directoryinfo("../").fullname;//当前应用程序路径的上级目录 获取当前目录可以使用appdomain.curren ...
- Android Developers:保存文件
Android使用一个和其它平台基于硬盘文件系统相似的文件系统.这个课程描述了如何和在Android文件系统使用File APIs读和写文件. 一个File对象适用于读或者写从头到尾没用中断的大型数据 ...
- Android studio的一些常用快捷键
Alt+回车 导入包,自动修正 Ctrl+N 查找类 Ctrl+Shift+N 查找文件 Ctrl+Alt+L 格式化代码 Ctrl+Alt+O 优化导入的类和包 Alt+Insert 生成代码(如g ...
- debian linux 下设置开机自启动
懒得写了,一张图简单明了.其实很简单,一开始没有加上nohup有点问题.现在问题已解决.
- 两种屏幕HUD区域限制的做法(矩形,弧形)
HUD区域限制算是比较常用到的功能,方形的HUD区域限制多见于小地图,弧形或者椭圆多见于屏幕范围约束. 我没有研究倒角矩形做法,而是将椭圆和矩形进行插值得到一个弧度比较高的形状: 当插值为0时限制范围 ...
- CentOS7静态IP设置
[root@localhost network-scripts]# pwd /etc/sysconfig/network-scripts [root@localhost network-scripts ...
- Android4.4r1(KitKat)源码下载地址
未经验证 http://blog.csdn.net/gaojinshan/article/details/14228737 百度云盘保存了大量android源码,没有经过验证,并不能保证能够正常编译, ...
- FlexPaper:使用flash在线展示pdf
WFTools工具包中的PDF2SWF工具可用来将PDF格式文件转换成SWF格式.使用下面的命令可以将pdf文件转换为单页swf文件. pdf2swf pdfPath –o swfPath –T ...