Linuxkernel有关spi设备树参数解析

更新时间:2023-06-15 01:17:02 阅读: 评论:0

Linuxkernel有关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;
bodhi2746
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    ca 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;
ninja什么意思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;
renli1434    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_lect = value;
1462
1463    /* Mode (clock pha/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        ca 1:
1479            break;
西安环球雅思
1480        ca 2:
1481            spi->mode |= SPI_TX_DUAL;
1482            break;
1483        ca 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        ca 1:
1497            break;
1498        ca 2:
1499            spi->mode |= SPI_RX_DUAL;
1500            break;
1501        ca 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",
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);
roadtrip
1517        goto err_out;
1518    }
1519    spi->max_speed_hz = value;
1520
1521    /* Store a pointer to the node in the device structure */
majeste1522    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 }

本文发布于:2023-06-15 01:17:02,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/90/145393.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

上一篇:regsvr32
标签:设备   驱动   配置   通道   字符串   总线   西安   文章
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图