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
2, check if hardware(touch screen) is connected and mounted.
- # getevent
- 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"
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)
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)
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:
- while (!downIdBits.isEmpty())
- BitSet32 downIdBits(currentIdBits.value & ~lastIdBits.value);
- BitSet32 currentIdBits = mCurrentCookedPointerData.touchingIdBits;
- BitSet32 lastIdBits = mLastCookedPointerData.touchingIdBits;
In MultiTouchInputMapper::syncTouch:
- bool isHovering = mTouchButtonAccumulator.getToolType() != AMOTION_EVENT_TOOL_TYPE_MOUSE
- && ( mTouchButtonAccumulator.isHovering()
- || (mRawPointerAxes.pressure.valid && inSlot->getPressure() <= 0));
- outPointer.isHovering = isHovering;
- ...
- ...
- mCurrentRawPointerData.markIdBit(id, isHovering);
- bool TouchButtonAccumulator::isHovering() const {
- return mHaveBtnTouch && !mBtnTouch;
- }
- mHaveBtnTouch = device->hasKey(BTN_TOUCH);
- #ifdef FOR_TSLIB_TEST
- set_bit(BTN_TOUCH, input_dev->keybit);
- #endif
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);
- }
- if (*outHavePointerIds) {
- if (id < 0 && !mPointerIdBits.isFull()) {
- id = mPointerIdBits.markFirstUnmarkedBit();
- mPointerTrackingIdMap[id] = trackingId;
- }
- ....
- ....
- }
- if (id < 0) {
- *outHavePointerIds = false;
- ....
- }
- if (!inSlot->isInUse()) {
- continue;
- }
- // this is new added to filter invalid pointer
- if((inSlot->getX() == 0) && (inSlot->getY() == 0)) {
- continue;
- }