Linux kernel 有关 spi 设备树参数解析

Posted 陈富林

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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);
    
    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);
    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.) */
    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))
    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 SPI通过设备树文件添加设备

设备树学习:内核对设备树的处理

linux kernel下指定要编译的设备树 设备树与内核一起编译

linux SPI 驱动

__Kernel专栏文章导航与优秀笔记整理(2021.08.14更新)

SPI:Linux驱动模型