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缓存该部分数 ...
随机推荐
- HDU 2602 Bone Collector 0/1背包
题目链接:pid=2602">HDU 2602 Bone Collector Bone Collector Time Limit: 2000/1000 MS (Java/Others) ...
- 图床神器:七牛云 + Mpic + FScapture
概述 最近在搞Markdown的东西,遇到了一个很棘手的问题,即图片的显示:通用的图片,可以直接网上搜索,但有时候需要自己截一些图或者对下载的图片进行修改,在本地存储完全没有问题,但Markdown写 ...
- Python把同一个对象循环赋值给另外一个变量
Python把同一个对象循环赋值给另外一个变量,修改一个对象,其他对象也修改了 >>> row=['_'] * 3 >>> board = [] >>& ...
- js判断是否IE浏览器
//ie? if (!!window.ActiveXObject || "ActiveXObject" in window){ //是 alert(1); }else{ //不是 ...
- Viola-Jones人脸检測
OpenCV中有一个基于树的技术:Haar分类器,它建立了boost筛选式级联. 它能够识别出人脸和其它刚性物体. 对于检測"基本刚性"的物体(脸,汽车,自行车,人体等)这类识别任 ...
- MAME模拟器使用简单教程
平时比较喜欢玩小时候的街机游戏,一开始用Winkawas,后来改用MAME,原因无他,mame是开源软件,更新更稳定可靠,但是它也有几个问题,记录一下. 1.MAME官网:www.mamedev.or ...
- 一种3D空间的柱状多边形检测实现
最近无意中拓展出这个东西,基于之前写的2D多边形检测: http://www.cnblogs.com/hont/p/6105997.html 而判断两条线相交的方法替换成了我后来写的差乘判断: htt ...
- 开发集成工具MyEclipse中Outline的问题
序言 不懂的多查,越查就越显得自己的无知,越发现大神的存在,可能相对于我来说是大神,在他那个高度,就觉得自己很菜,这些都正常,最值得敬佩的是,比你厉害的人,还比你更努力,那自己还有什么理由不努力呢,如 ...
- 各个框架下的aop
http://www.cnblogs.com/neverc/p/5241466.html
- ubuntu java 环境配置
下载oracle java sudo add-apt-repository ppa:webupd8team/java -y sudo apt-get update sudo apt-get insta ...