pin control & dts详解,含实际代码

dts位于

linux/arch/arm/boot/dts


1.接口(此部分摘自http://www.wowotech.net/gpio_subsystem/pin-control-subsystem.html)

(1)devm_pinctrl_get和pinctrl_get。devm_pinctrl_get是Resource managed版本的pinctrl_get,核心还是pinctrl_get函数。这两个接口都是获取设备(设备模型中的struct device)的pin control state holder(struct pinctrl)。pin control state holder不是静态定义的,一般在第一次调用该函数的时候会动态创建。

(2)devm_pinctrl_put和pinctrl_put。是(1)接口中的逆函数。devm_pinctrl_get和pinctrl_get获取句柄的时候申请了很多资源,在devm_pinctrl_put和pinctrl_put可以释放。需要注意的是多次调用get函数不会重复分配资源,只会reference count加一,在put中referrenct count减一,当count==0的时候才释放该device的pin control state holder持有的所有资源。

(3)pinctrl_lookup_state。根据state name在pin control state holder找到对应的pin control state。具体的state是各个device自己定义的,不过pin control subsystem自己定义了一些标准的pin control state,定义在pinctrl-state.h文件中:

(4)pinctrl_select_state。设定一个具体的pin control state接口。


2.具体过程(含具体代码):

2.1 driver-->


                spi->dev.of_node=of_find_compatible_node(NULL, NULL, "mediatek,mt6735-finger");





2.2 dtsi-->(相当于dts的头文件)

                finger: finger {
                               compatible = "mediatek,mt6735-finger";
                };
2.3 dts-->

                    &finger {
                        pinctrl-names = "fp_default", "finger_rst_high", "finger_rst_low","eint_as_int", "eint_in_low", "eint_in_float", "miso_pull_up",
                         "miso_pull_disable","finger_power_low","finger_power_high","finger_mode_as_cs","finger_mode_as_ck","finger_mode_as_mi","finger_mode_as_mo";
                        pinctrl-0 = <&fp_default>;
                        pinctrl-1 = <&fp_rst_high>;
                        pinctrl-2 = <&fp_rst_low>;
                        pinctrl-3 = <&fp_eint_as_int>;
                        pinctrl-4 = <&fp_eint_in_low>;
                        pinctrl-5 = <&fp_eint_in_float>;
                        pinctrl-6 = <&fp_miso_pull_up>;
                        pinctrl-7 = <&fp_miso_pull_disable>;
                        pinctrl-8 = <&fp_power_low>;
                        pinctrl-9 = <&fp_power_high>;
                        pinctrl-10 = <&fp_as_cs_mode>;
                        pinctrl-11 = <&fp_as_ck_mode>;
                        pinctrl-12 = <&fp_as_mi_mode>;
                        pinctrl-13 = <&fp_as_mo_mode>;
                        status = "okay";
                    };

                    &pio {
                        fp_default: default {
                        };

                        fp_rst_high: fp_rst_high {
                            pins_cmd_dat {
                                pins = ;
                                slew-rate = <1>;
                                output-high;
                            };
                        };
                        fp_rst_low: fp_rst_low {
                            pins_cmd_dat {
                                pins = ;
                                slew-rate = <1>;
                                output-low;
                            };
                        };

                        fp_eint_as_int: fp_eint_as_int {
                            pins_cmd_dat {
                                pins = ;
                                slew-rate = <0>;
                                bias-disable;
                            };
                        };
                        fp_eint_in_low: fp_eint_in_low {
                            pins_cmd_dat {
                                pins = ;
                                slew-rate = <0>;
                                bias-pull-down = <00>;
                            };
                        };
                        fp_eint_in_float: fp_eint_in_float {
                            pins_cmd_dat {
                                pins = ;
                                slew-rate = <0>;
                                bias-disable;
                            };
                        };

                        fp_miso_pull_up: fp_miso_pull_up {
                            pins_cmd_dat {
                                pins = ;
                                slew-rate = <0>;
                                bias-pull-up = <00>;
                            };
                        };
                        fp_miso_pull_disable: fp_miso_pull_disable {
                            pins_cmd_dat {
                                pins = ;
                                bias-disable;
                            };
                        };
                        
                        fp_power_low: fp_power_low {
                            pins_cmd_dat {
                                pins = ;
                                slew-rate = <1>;
                                output-low;
                            };
                        };    
                        fp_power_high: fp_power_high {
                            pins_cmd_dat {
                                pins = ;
                                slew-rate = <1>;
                                output-high;
                            };
                        };
                        
                        fp_as_cs_mode: fp_as_cs_mode {
                            pins_cmd_dat {
                                pins = ;
                                slew-rate = <0>;
                                bias-pull-up = <00>;
                            };
                        };
                        fp_as_ck_mode: fp_as_ck_mode {
                            pins_cmd_dat {
                                pins = ;
                                slew-rate = <0>;
                                bias-pull-down = <00>;
                            };
                        };

                        fp_as_mi_mode: fp_as_mi_mode {
                            pins_cmd_dat {
                                pins = ;
                                slew-rate = <0>;
                                bias-pull-up = <00>;
                            };
                        };
                        fp_as_mo_mode: fp_as_mo_mode {
                            pins_cmd_dat {
                                pins = ;
                                slew-rate = <0>;
                                bias-pull-up = <00>;
                            };
                        };
                        
                    };


2.4 driver-->

            fp->pinctrl1 = devm_pinctrl_get(&spi->dev);//调用devm_pinctrl_get获取该device对应的 pin control state holder句柄。
            if (IS_ERR(fp->pinctrl1)) {
                err = PTR_ERR(fp->pinctrl1);
                dev_err(&spi->dev, "fwq Cannot find fp pinctrl1!\n");
                return err;
            }



2.5 driver-->对应的pin control对应上面2.3的dts中的引脚设置

                pdev->pins_default = pinctrl_lookup_state(pdev->pinctrl1, "fp_default");
                if (IS_ERR(pdev->pins_default)) {
                    ret = PTR_ERR(pdev->pins_default);
                    printk("fwq Cannot find nasri_fingerprint pinctrl default %d!\n", ret);
                }

                    pdev->fp_rst_high = pinctrl_lookup_state(pdev->pinctrl1, "finger_rst_high");
                    if (IS_ERR(pdev->fp_rst_high)) {
                        ret = PTR_ERR(pdev->fp_rst_high);
                        dev_err(&pdev->spi->dev, "fwq Cannot find fp pinctrl finger_rst_high!\n");
                        return ret;
                    }
                    pdev->fp_rst_low = pinctrl_lookup_state(pdev->pinctrl1, "finger_rst_low");
                    if (IS_ERR(pdev->fp_rst_low)) {
                        ret = PTR_ERR(pdev->fp_rst_low);
                        dev_err(&pdev->spi->dev, "fwq Cannot find fp pinctrl finger_rst_low!\n");
                        return ret;
                    }
                    pdev->eint_as_int = pinctrl_lookup_state(pdev->pinctrl1, "eint_as_int");
                    if (IS_ERR(pdev->eint_as_int)) {
                        ret = PTR_ERR(pdev->eint_as_int);
                        dev_err(&pdev->spi->dev, "fwq Cannot find fp pinctrl eint_as_int!\n");
                        return ret;
                    }
                    pdev->eint_in_low = pinctrl_lookup_state(pdev->pinctrl1, "eint_in_low");
                    if (IS_ERR(pdev->eint_in_low)) {
                        ret = PTR_ERR(pdev->eint_in_low);
                        dev_err(&pdev->spi->dev, "fwq Cannot find fp pinctrl eint_output_low!\n");
                        return ret;
                    }
                    pdev->eint_in_float = pinctrl_lookup_state(pdev->pinctrl1, "eint_in_float");
                    if (IS_ERR(pdev->eint_in_float)) {
                        ret = PTR_ERR(pdev->eint_in_float);
                        dev_err(&pdev->spi->dev, "fwq Cannot find fp pinctrl eint_output_high!\n");
                        return ret;
                    }

                pdev->power_low = pinctrl_lookup_state(pdev->pinctrl1, "finger_power_low");
                if (IS_ERR(pdev->power_low)) {
                    ret = PTR_ERR(pdev->power_low);
                    printk("fwq Cannot find nasri_fingerprint pinctrl finger_power_low!\n");
                    return ret;
                }
                pdev->power_high = pinctrl_lookup_state(pdev->pinctrl1, "finger_power_high");
                if (IS_ERR(pdev->power_high)) {
                    ret = PTR_ERR(pdev->power_high);
                    printk("fwq Cannot find nasri_fingerprint pinctrl finger_power_high!\n");
                    return ret;
                }    
                    pinctrl_select_state(pdev->pinctrl1, pdev->power_high);
                    return ret;
                    printk("[FP] mt_fp_pinctrl----------\n");


2.6 irq-->

                efsa120s_gpio_as_int();
                printk("ints[0] = %d, ints[1] = %d!!\n", ints[0], ints[1]);
                
                fp->irq = irq_of_parse_and_map( node, 0);//产生中断号

            ret = request_irq(fp->irq, elan_fp_irq_handler,
                IRQF_TRIGGER_NONE, "elan_fp", NULL);


2.7 debounce-->

                of_property_read_u32_array( node, "debounce", ints, ARRAY_SIZE(ints));//在返回的节点中查找是否有debounce这个属性,此属性用于中断信号防抖
                //gpio_request(ints[0], "fingerprint-irq");
                pinctrl_select_state(fp->pinctrl1, fp->eint_in_float);
                gpio_set_debounce(ints[0], ints[1]);//设置中断防抖,v550不支持


你可能感兴趣的:(driver)