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 }
Read The Fucking Source Code