一、TP调试思路
TP外设属于比较常见且简单的外设,今天以ti,tsc2046这款为例简述下TP外设的调试。
调试思路
1、配置设备树----驱动调试的device部分
2、TP驱动编译及驱动匹配—driver部分
3、整机调试
二、配置设备树
对于ti,tsc2046设备树的配置,我们可以参考内核Documentation/devicetree/bindings/input/ads7846.txt
内核文档还是讲的比较详细,包括必选参数、可选参数以及各个参数的含义都有说明,包括示例我们都可以参考。
Device tree bindings for TI's ADS7843, ADS7845, ADS7846, ADS7873, TSC2046
SPI driven touch screen controllers.
The node for this driver must be a child node of a SPI controller, hence
all mandatory properties described in
Documentation/devicetree/bindings/spi/spi-bus.txt
must be specified.
Additional required properties:
compatible Must be one of the following, depending on the
model:
"ti,tsc2046"
"ti,ads7843"
"ti,ads7845"
"ti,ads7846"
"ti,ads7873"
interrupt-parent
interrupts An interrupt node describing the IRQ line the chip's
!PENIRQ pin is connected to.
vcc-supply A regulator node for the supply voltage.
Optional properties:
ti,vref-delay-usecs vref supply delay in usecs, 0 for
external vref (u16).
ti,vref-mv The VREF voltage, in millivolts (u16).
Set to 0 to use internal references
(ADS7846).
ti,keep-vref-on set to keep vref on for differential
measurements as well
ti,swap-xy swap x and y axis
ti,settle-delay-usec Settling time of the analog signals;
a function of Vcc and the capacitance
on the X/Y drivers. If set to non-zero,
two samples are taken with settle_delay
us apart, and the second one is used.
~150 uSec with 0.01uF caps (u16).
ti,penirq-recheck-delay-usecs If set to non-zero, after samples are
taken this delay is applied and penirq
is rechecked, to help avoid false
events. This value is affected by the
material used to build the touch layer
(u16).
ti,x-plate-ohms Resistance of the X-plate,
in Ohms (u16).
ti,y-plate-ohms Resistance of the Y-plate,
in Ohms (u16).
ti,x-min Minimum value on the X axis (u16).
ti,y-min Minimum value on the Y axis (u16).
ti,x-max Maximum value on the X axis (u16).
ti,y-max Minimum value on the Y axis (u16).
ti,pressure-min Minimum reported pressure value
(threshold) - u16.
ti,pressure-max Maximum reported pressure value (u16).
ti,debounce-max Max number of additional readings per
sample (u16).
ti,debounce-tol Tolerance used for filtering (u16).
ti,debounce-rep Additional consecutive good readings
required after the first two (u16).
ti,pendown-gpio-debounce Platform specific debounce time for the
pendown-gpio (u32).
pendown-gpio GPIO handle describing the pin the !PENIRQ
line is connected to.
wakeup-source use any event on touchscreen as wakeup event.
(Legacy property support: "linux,wakeup")
Example for a TSC2046 chip connected to an McSPI controller of an OMAP SoC::
spi_controller {
tsc2046@0 {
reg = <0>; /* CS0 */
compatible = "ti,tsc2046";
interrupt-parent = <&gpio1>;
interrupts = <8 0>; /* BOOT6 / GPIO 8 */
spi-max-frequency = <1000000>;
pendown-gpio = <&gpio1 8 0>;
vcc-supply = <®_vcc3>;
ti,x-min = /bits/ 16 <0>;
ti,x-max = /bits/ 16 <8000>;
ti,y-min = /bits/ 16 <0>;
ti,y-max = /bits/ 16 <4800>;
ti,x-plate-ohms = /bits/ 16 <40>;
ti,pressure-max = /bits/ 16 <255>;
wakeup-source;
};
};
这里需要注意的是,这是一款SPI总线的TP,所以TP对应设备树节点必选在SPI设备树spi_controller目录下。
下图是我自己在高通平台一款芯片下加的设备树,其中spi_1: spi@78b5000为SPI设备树节点,真正属于TP的设备树添加为tsc2046@0,如下图:
spi_1: spi@78b5000 {
compatible = "qcom,spi-qup";
#address-cells = <1>;
#size-cells = <0>;
reg-names = "spi_physical", "spi_bam_physical";
reg = <0x78b5000 0x600>,
<0x7884000 0x2b000>;
interrupt-names = "spi_irq", "spi_bam_irq";
interrupts = <0 95 0>, <0 238 0>;
spi-max-frequency = <19200000>;
pinctrl-names = "spi_default", "spi_sleep";
pinctrl-0 = <&spi1_default &spi1_cs0_active>;
pinctrl-1 = <&spi1_sleep &spi1_cs0_sleep>;
clocks = <&clock_gcc clk_gcc_blsp1_ahb_clk>,
<&clock_gcc clk_gcc_blsp1_qup1_spi_apps_clk>;
clock-names = "iface_clk", "core_clk";
qcom,infinite-mode = <0>;
qcom,use-bam;
qcom,use-pinctrl;
qcom,ver-reg-exists;
qcom,bam-consumer-pipe-index = <12>;
qcom,bam-producer-pipe-index = <13>;
qcom,master-id = <86>;
tsc2046@0 {
reg = <0>; /* CS0 */
compatible = "ti,tsc2046";
interrupt-parent = <&tlmm_pinmux>;
interrupts = <29 0x2>; /* GPIO 29 */
spi-max-frequency = <2000000>;
pendown-gpio = <&tlmm_pinmux 29 0x02>;
//vcc-supply = <®_vcc3>;
ti,x-min = /bits/ 16 <0>;
ti,x-max = /bits/ 16 <8000>;
ti,y-min = /bits/ 16 <0>;
ti,y-max = /bits/ 16 <4800>;
ti,x-plate-ohms = /bits/ 16 <40>;
ti,pressure-max = /bits/ 16 <255>;
wakeup-source;
};
};
三、TP驱动编译及驱动匹配
我们使用的TP驱动为内核原生驱动drivers/input/touchscreen/ads7846.c。
关于驱动编译的问题我们需要从ads7846.c所在目录一层一层往上去分析Makefile文件,保证ads7846.c参与到编译中来,我们注意到需要打开3个宏才可以,如下图:
同级Makefile
obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o
上一层Makefile
obj-$(CONFIG_INPUT) += input-core.o
obj-$(CONFIG_INPUT_TOUCHSCREEN) += touchscreen/
最终配置文件需要添加
CONFIG_INPUT=y
CONFIG_TOUCHSCREEN_ADS7846=y
CONFIG_INPUT_TOUCHSCREEN=y
不同平台内核宏配置文件位置不一样,但是编译之后顶层会生成.config文件,我们可以查看对应的宏是否为y,另外可以看编译目录有没有ads7846.o文件生成,这些都是一些辅助判断技巧。
另外关于驱动匹配问题我们可以看到驱动文件of_device_id与设备树都函数compatible = “ti,tsc2046”,所以理论上只要平台SPI没有问题(SPI是基础),TP驱动就会正常匹配,即便TP硬件不存在,也会走到probe函数入口,另外我们也可以在驱动文件probe函数中添加打印以辅助判断或者阅读代码,通过驱动文件所建立的节点以及对应打印进行判断。
四、整机调试
经过上面几步,如果一帆风顺的话可以看到/dev/input下面会产生新的event节点,使用手指点击TP,然后查看有数值变化,如下图。我们点击TP发现event可以正常上报且有变化产生,证明驱动整体是ok。
驱动文件我们使用原生的,很多参数可能需要根据实际TP厂商进行调整及优化,另外刚才也说了一帆风顺的时候可以看到event上报且变化,正常情况下驱动调试大概率是不可能一步到位的,我们需要排查的重点有以下几点:
1、TP硬件是否ok
2、平台的SPI总线是否ok,平台同SPI总线下是否有其他设备,使用示波器配合spi测试程序验证总线是否有CLK,总之就是确保总线是ok的
3、TP与平台之前的连接是否ok,一般TP软排线多一些,可以测试调试点证明硬件连接是OK的
4、点击TP时中断是否正常,驱动文件中断函数可以添加调试打印,确认中断配置正常,以及可以正常收到中断
5、软件层面节点是否出来,驱动probe是否已经完整的处理完
6、有节点但是没有上报或者上报不对,说明驱动匹配基本没有问题,大概率还是1~5的问题,继续重点排查。