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.具体过程(含具体代码):
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不支持