Assumed that you Linux kernel & Android system can start successfully, and adb can work. Below context just list what I do when I debug touch screen feature in A10 pro of Allwinner.
1, At first, check if you driver module is loaded or not in you adb shell or by minicom in serial port.
# lsmod
if not, please check your init.rc or insert manually(driver ko file
usually in path /system/vendor/modules/, depending on makefile of your
devices)
2, check if hardware(touch screen) is connected and mounted.
# getevent
show info below:
add device 1: /dev/input/event3 name: "bma250" could not get driver version for /dev/input/js0, Invalid argument add device 2: /dev/input/event2 name: "ft5x_ts" add device 3: /dev/input/event0 name: "sun4i-keyboard" could not get driver version for /dev/input/mice, Not a typewriter add device 4: /dev/input/event1 name: "axp20-supplyer"
Fortunately I have not hardware problem, it mount as device /dev/input/event2 successfully. If failed, please check step 1, then make sure if you hardware is not broken and power supply correct. This
part debug is a little complicated because it is relative with your
Linux kernel driver code. Let's instruct touch screen driver simply.
At first, it defines a ctp(configurable touch panel) relative
operations, read some hardware configure from special file(defined by
manufactory or yourself), initial and wakeup to detect touch panel.
Then defines some aw_i2c_ts_fops(struct file_operations), at least
implement open, unlocked_ioctl and release function here. It implemented
by comunication with i2c modules and usually this part is mature
enough, just copy from Internet. At last a struct i2c_driver
should be add to i2c drivers(by function i2c_add_driver), here, probe,
the most important function should be implemented. In probe, register
some input event for device, allocate a input device struct and register
it, and initial a irq for handle input request in bottom half. When Irq coming, it read data from i2c and post to android frame work, that all the process in short. I will instruct input kernel driver details in some other post later.
3, Check raw events from kernel when you click your touch panel.
You can get event by command getevent and compare with log in
EventHub(framework/base/services/input/EventHub.cpp, InputReader get raw
events in a thread by invoking EventHub::getEvents). As a click event, raw events should be(just list some important parameters): Down Events group:
(EV_ABS, ABS_MT_TRACKING_ID, touchId)
(EV_ABS, ABS_MT_TOUCH_MAJOR, pressValue)
(EV_ABS, ABS_MT_POSITION_X, x)
(EV_ABS, ABS_MT_POSITION_Y, y)
(EV_ABS, ABS_MT_WIDTH_MAJOR, 1)
(EV_SYN, SYN_MT_REPORT, 0)
(EV_SYN, SYN_REPORT, 0)
touchId is from 0 to increase, max is 16, to identify your touch pointer; pressValue is a nonzero value.
You can refer to android document:
http://source.android.com/tech/input/touch-devices.html. You can add or
remove some optional events yourself in your kernel driver. Upper
raw events group will be send to input reader several times until you
move your finger up from touch panel. then raw event should be: Up Events group:
(EV_ABS, ABS_MT_TOUCH_MAJOR, releaseValue)
(EV_SYN, SYN_REPORT, 0)
releaseValue usually is 0.
If you event is very different, please check you kernel driver code of
irq handle part. In my case, raw events is all right. so I have to
continue to check android input dispatch process.
4, Generate various action in InputReader and dispatch them in InputDispatch.
When first down events group is captured by input reader, it should be
dispatch as event AMOTION_EVENT_ACTION_DOWN at
TouchInputMapper::dispatchTouches. In my case it is defined as a
AMOTION_EVENT_ACTION_HOVER_ENTER, it is wrong! So I investigate why it
is regarded as a hover event:
I check mCurrentCookedPointerData.touchingIdBits, it is 0 all the time, but mCurrentCookedPointerData.hoveringIdBits change; Obviously process is using hoveringIdBits to respond some events rather than using touchingIdBits. Why? In MultiTouchInputMapper::syncTouch:
I track and find that isHovering is always true, THAT'S THE REASON. Let's check how mTouchButtonAccumulator.isHovering works:
bool TouchButtonAccumulator::isHovering() const {
return mHaveBtnTouch && !mBtnTouch;
}
while:
mHaveBtnTouch = device->hasKey(BTN_TOUCH);
LOL, seems root cause is found. As a muti-touch screen, this event
should not be register, but for a single touch screen this must be
register. Check kernel driver if BTN_TOUCH event is register in probe
function :
#ifdef FOR_TSLIB_TEST
set_bit(BTN_TOUCH, input_dev->keybit);
#endif
undefine it and AMOTION_EVENT_ACTION_DOWN is generated.
5, Trouble is continuing...
When up event group is capture, My broad does not generate
AMOTION_EVENT_ACTION_UP, it continue with AMOTION_EVENT_ACTION_MOVE.
WTF. Look the logcat log, in TouchInputMapper::sync:
syncTouch(when, &havePointerIds);
#if DEBUG_RAW_EVENTS
if (!havePointerIds) {
ALOGD("syncTouch: pointerCount %d -> %d, no pointer ids",
mLastRawPointerData.pointerCount,
mCurrentRawPointerData.pointerCount);
}
havePointerIds
return a false here, and log show "syncTouch: pointerCount 1 -> 1".
and 1 -> 0. Check MultiTouchInputMapper::syncTouch again:
if (*outHavePointerIds) {
if (id < 0 && !mPointerIdBits.isFull()) {
id = mPointerIdBits.markFirstUnmarkedBit();
mPointerTrackingIdMap[id] = trackingId;
}
....
....
}
if (id < 0) {
*outHavePointerIds = false;
....
}
mPointerIdBits is always full and id can not get a positive value. Add codes in this function to drop some invalid pointer: