GPIO中断,调试和客制化
PA2 GPIO/Interrupt non-HLOS 覆盖 non-HLOS GPIO/Interrupt 软件驱动,GPIO是标准通用输入输出。Msm与外设之间最基本的输入/输出接口.msm提供GPIO数量,每一个GPIO能够配置通用输入/输出pin脚或者其他功能。
内部单元(hardware time,其他子系统(SMD)或者外部设备(I2c,uart)能够产生中断。
每一个子系统(APSS,MPSS)都拥有自己的中断控制器将替代他们自己的IRQs。另外,
MPM(MSM Power Manager)拥有一个简单的中断控制器支持64个wakeup IRQs。
仅仅自由MPM的IRQs能够wake up msm从deep sleep (VDD minimization or XO shutdown)
所以得GPIO能够产生生成中断,但是只有a subset GPIOs能够产生MPM中断。
当进入suspense,进入deep sleep。软件模块使用GPIO需要put GPIO进入sleep state以减少电流泄露。
Linux Pin Control Overview
MSM8916/MSM8939系列新品有122个GPIOs
GPIO pin能够配置作为输入、输出或者其他功能。当作为输入时,GPIO设置为interrupt 资源。一个GPIOs子集能够产生中断,能够将msm deep sleep唤醒。GPIO也能够配置成内部上拉和不同的驱动能力。
Pin configuration vs pin function
Pin脚配置作为一个属性可编程,提供一个信号驱动这lines。典型的配置包含驱动能力,pull value,方向等。Pin功能能够被定义作为信号驱动pins。
Pin states
Pin states Framework继承employs观点。配置和功能的状态被应用在一组引脚中。一个或多个pins的拥有者必须提供包含一组pin脚的信息。Framework允许使用中竞争,独立客户端想使用一样的pin为了不同的目的,提供不同pin脚状态信息。
Pin脚能够定义三个状态:Default,Active,Sleep。
MSM TLMM
MSM Socs拥有pinmux controller 作为Top-LEVEL Mode Multiplexer(TLMM)。
Pin types on TLMM
TLMM支持复用和配置不同类型的pins。这些types拥有不同的寄存器语义,某些情况下甚至拥有自己特殊协议pin属性。列如:不同驱动能力,pull,方向等。
通用pins ---- pins能够使用作为复用
SDC pins ----- 专门为SDHC
Pin控制软件模型
Pin脚控制软件模型不同的方向:
所有的pin配置和TLMM信息定义在Soc -specific文件中。
<soc>-pinctrl.dtsi。这文件包含pin组,同时这配置和功能应用在这。
独立的客户设备数节点参考信息节点定义在<soc>-pinctrl.dtsi。由状态pin组成。
客户端拥有许多配置节点状态,
状态信息解析通过devm_pinctrl_get().
客户端能够选择安装给定的状态使用pinctrl_lookup_state()和pinctrl_selset_state().
Example:
&soc {
tlmm_pinmux: pinctrl@1000000 {
compatible = "qcom,msm-tlmm-v4";
reg = <0x1000000 0x300000>;
interrupts = <0 208 0>;
/*General purpose pins*/
gp: gp {
qcom,pin-type-gp;
qcom,num-pins = <122>;
#qcom,pin-cells = <1>;
msm_gpio: msm_gpio {
compatible = "qcom,msm-tlmmv4-gp-intc";
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
num_irqs = <122>;
};
};
/* SDC pin type */
sdc: sdc {
Pin Control Software Model
80-NL239-47 B 11 Confidential and Proprietary – Qualcomm Technologies, Inc.
MAY CONTAIN U.S. AND INTERNATIONAL EXPORT CONTROLLED INFORMATION
qcom,pin-type-sdc;
/* 0-2 for sdc1 4-6 for sdc2 */
qcom,num-pins = <7>;
/* Order of pins */
/* SDC1: CLK -> 0, CMD -> 1, DATA -> 2 */
/* SDC2: CLK -> 4, CMD -> 5, DATA -> 6 */
#qcom,pin-cells = <1>;
};
};
软件修改:
现在使用可以分为以下三种类型:
1、pin脚驱动被控制器,列如:uart ,spi,i2c
2、软件通过bit banging使用pin脚,典型的设备连接board,列如:显示panels。
3、Pin脚作为中断资源使用, 典型的连接board,如:网卡。
Pin驱动被控制器
1、启动时配置通过pins
&soc {
tlmm_pinmux: pinctrl@1000000 {
…..
….
..
Client1_pins {
/* Uses general purpose pins */
qcom,pins = <&gp 0>, <&gp 1>;
qcom,num-grp-pins = <2>;
/* function setting as specified in board-<soc>-gpiomux.c */
qcom,pin-func = <1>;
label = “client1-bus”;
/* Active configuration of bus pins */
Client1_default: client1_default {
/* Property names as specified in
• pinctrl-bindings.txt /
drive-strength = <8>; /* 8 MA */
bias-disable; /* No PULL */
};
};
修改客户节点在device tree
Soc {
…….
…
..
Client1 {
……
…
/*Note the the default state is programmed by the kernel at the time of
kernel bootup. No driver changes are necessary since at probe time the
default state would already be programmed in TLMM */
pinctrl-states = “default”;
/* Use phandle referrence to default configuration node */
pinctrl-0 = <&Client1_default>;
};
2、 配置通用pin 在active 和sleep状态(runtime)
控制器驱动拥有active 状态pins和sleep状态,当system suspend。
Driver 必须安装正确的state。
配置pin节点包含active 和suspend状态
&soc {
tlmm_pinmux: pinctrl@1000000 {
…..
….
Client2_pins {
/* Pin group node */
/* Uses general purpose pins */
qcom,pins = <&gp 0>, <&gp 1>;
qcom,num-grp-pins = <2>;
/* function setting as specified in board-<soc>-gpiomux.c */
qcom,pin-func = <1>;
label = “client2-bus”;
/* Active configuration of bus pins */
Client2_active: client2_active {
/* Configuration node:
• Property names as specified in
• pinctrl-bindings.txt /
drive-strength = <8>; /* 8 MA */
bias-pull-up; /* PULL UP */
};
Client2_suspend: client2_suspend {
/* Configuration node:
• Property names as specified in
• pinctrl-bindings.txt /
drive-strength = <2>; /* 2 MA */
bias-disable; /* No PULL */
};
};
修改client node包含pinctrl states。删除隐形gpio参数,使用GPIO芯片节点。
Soc {
…….
…
Client2 {
……
pinctrl-states = “active”, “suspend”;
/* Use phandle referrence to active and sleep configurations to
Define the active and sleep pin states */
pinctrl-0 = <&Client2_active>;
pinctrl-1 = <&Client2_sleep>;
client2-gpio-1 = <&msmgpio 0 0>;
client2-gpio-2 = <&msmgpio 1 0>;
};
修改驱动pinctl 接口
Static int msm_client2_probe (struct platform_device *pdev) {
Struct pinctrl_state *set_state;
Struct client2_data *client2_dd;
…..
…
..
/* Try to obtain pinctrl handle */
Pdev->dev->pins->p = devm_pinctrl_get(pdev);
/* Lookup the active configuration */
set_state = pinctrl_lookup_state(pdev->dev->pins->p, “active”);
if (!set_state)
goto fail;
else
/*Actually write the active configuration to hardware */
ret = pinctrl_select_state(pdev->dev->pins->p, set_state);
/* Install sleep configuration in runtime suspend function */
Static int client2_suspend( struct platfom_device) {
/* Configure pins to sleep state state */
Struct pinctrl_state *set_state;
/* Actually write the sleep configuration to hardware */
set_state = pinctrl_lookup_state(pdev->dev->pins->p, “sleep”);
if (!set_state)
goto fail;
else
ret = pinctrl_select_state(pdev->dev->pins->p, set_state);
}
Pin组配置不同的功能(runtime)