zoukankan      html  css  js  c++  java
  • spidev 驱动 probe 获取 dts 节点参数

    • 一、 尝试在 spi 驱动里边读取 设备树里面 节点的信息

        //  dts  里面的参数配置
        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>;
        512         name = "chenfulin";
        513         // spi-cpha = <1>;
        514         // spi-tx-bus-width = <1>;
        515         // spi-rx-bus-width = <1>;
        516         spi-max-frequency = <10000000>;
        517     };
        518 };
    
    • 二、 代码跟踪

        //  drivers/spi/spi.c
        1428 #if defined(CONFIG_OF)
        1429 static struct spi_device *
        1430 of_register_spi_device(struct spi_master *master, struct device_node *nc)·
        1431 {
                // ... 
        1454     /* Device address */
        1455     rc = of_property_read_u32(nc, "reg", &value);           // 看他是怎么找到 reg 的值的
        1456     if (rc) {
        1457         dev_err(&master->dev, "%s has no valid 'reg' property (%d)
    ",
        1458             nc->full_name, rc);
        1459         goto err_out;
        1460     }  
    
        //  include/linux/of.h 
         857 static inline int of_property_read_u32(const struct device_node *np,
         858                        const char *propname,
         859                        u32 *out_value)
         860 {
         861     return of_property_read_u32_array(np, propname, out_value, 1);        // 从函数可以看出,找的是一个 u32的值
         862 }
    
        // drivers/of/base.c 
        1252 int of_property_read_u32_array(const struct device_node *np,
        1253                    const char *propname, u32 *out_values,
        1254                    size_t sz)
        1255 {
        1256     const __be32 *val = of_find_property_value_of_size(np, propname,            // 然后函数又封了一层
        1257                         (sz * sizeof(*out_values)));
        1258
        1259     if (IS_ERR(val))
        1260         return PTR_ERR(val);
        1261
        1262     while (sz--)
        1263         *out_values++ = be32_to_cpup(val++);
        1264     return 0;
        1265 }
        1266 EXPORT_SYMBOL_GPL(of_property_read_u32_array);
    
        1125 static void *of_find_property_value_of_size(const struct device_node *np,
        1126             const char *propname, u32 len)
        1127 {
        1128     struct property *prop = of_find_property(np, propname, NULL);               // 这里就是找到节点的函数,这个 property 的链表就是设备树节点
        1129
        q1130     if (!prop)
        1131         return ERR_PTR(-EINVAL);
        1132     if (!prop->value)
        1133         return ERR_PTR(-ENODATA);
        1134     if (len > prop->length)
        1135         return ERR_PTR(-EOVERFLOW);
        1136
        1137     return prop->value;
        1138 }
    
         232 struct property *of_find_property(const struct device_node *np,
         233                   const char *name,
         234                   int *lenp)
         235 {
         236     struct property *pp;
         237     unsigned long flags;
         238
         239     raw_spin_lock_irqsave(&devtree_lock, flags);
         240     pp = __of_find_property(np, name, lenp);            //  加一个自旋锁 保证安全,然后继续匹配
         241     raw_spin_unlock_irqrestore(&devtree_lock, flags);
         242
         243     return pp;
         244 }
         245 EXPORT_SYMBOL(of_find_property);
    
         213 static struct property *__of_find_property(const struct device_node *np,
         214                        const char *name, int *lenp)
         215 {
         216     struct property *pp;
         217
         218     if (!np)
         219         return NULL;
         220
         221     for (pp = np->properties; pp; pp = pp->next) {
         222         if (of_prop_cmp(pp->name, name) == 0) {             // 如果找到了就直接返回 pp节点。
         223             if (lenp)
         224                 *lenp = pp->length;
         225             break;
         226         }
         227     }
         228
         229     return pp;
         230 }
    
        include/linux/of.h
        227 #define of_prop_cmp(s1, s2)     strcmp((s1), (s2))
    
    • 三、 关联起来的过程如下

        // driver/spi/spi.c
        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;
                // ... ..
        1521     /* Store a pointer to the node in the device structure */
        1522     of_node_get(nc);
        1523     spi->dev.of_node = nc;
                // ... ... 这里直接把设备节点挂在了 spi-dev.of_node 下面,  上面的 np 就是节点
                //  struct property *pp == pp = np->properties    np 是一个链表。
        1538 } 
    
    • 四、在 spi drrver 里面找出相关参数

        //  probe 函数里面
        1521 #if 1
        1522     printk("wk2124A debug speed : %d
    ", spi->max_speed_hz);
        1523
        1524     for (pp = spi->dev.of_node->properties; pp; pp = pp->next)
        1525     {
        1526         printk("%s   
    ", pp->name);
        1527         if (strcmp(pp->name, "name") == 0)
        1528             printk("name : %s
    ", (char *)pp->value);
        1529     }
        1530     printk("
    ");
        1531 #endif
    
  • 相关阅读:
    吃货联盟订餐系统
    第一章课后习题
    hostapd阅读(openwrt)-1
    通过C语言获取MAC地址(转)
    OpenWrt 编译分割
    ubuntu 12.04无盘工作站
    WEB前端性能优化-如何提高页面加载速度
    HTML6
    easyui 根据值查找匹配
    收藏的网站
  • 原文地址:https://www.cnblogs.com/chenfulin5/p/8473642.html
Copyright © 2011-2022 走看看