TouchDisplay2でタッチが効かなくなる問題は、どうも、起動後にrebootした後はダメになる感じ。

ドライバのロードメッセージを見てみる。
正常なときはこう。
fd@pi3b:~ $ dmesg | grep Goodix
[ 10.358666] Goodix-TS 10-005d: supply VDDIO not found, using dummy regulator
[ 10.447665] Goodix-TS 10-005d: ID 911, version: 1060
[ 10.465138] input: 10-005d Goodix Capacitive TouchScreen as /devices/platform/soc/3f205000.i2c/i2c-11/i2c-10/10-005d/input/input0
rebootしたときはこれ。
fd@pi3b:~ $ dmesg | grep Goodix
[ 7.563941] Goodix-TS 10-005d: supply VDDIO not found, using dummy regulator
[ 7.627625] Goodix-TS 10-005d: Error reading 1 bytes from 0x8140: -5
[ 7.651622] Goodix-TS 10-005d: Error reading 1 bytes from 0x8140: -5
[ 7.675364] Goodix-TS 10-005d: I2C communication failure: -5
[ 7.676273] Goodix-TS 10-005d: probe with driver Goodix-TS failed with error -5
ドライバが、I2Cの先にあるタッチデバイスを探したのだけど、失敗してエラーを出している。
これは、毎回完全に電源抜いて入れ直す(コールドブートする)必要があるようだ。
この動きの違いはこれだろうな...
Touch Display 2買ってみた -1-|kinneko|pixivFANBOX
https://kinneko.fanbox.cc/posts/10708996

ウォームブートのときには、この電源が通電しっぱなしなので、DSIのマイコンがリセットされない。Goodix-TSはDSIコントローラー配下にあるので、こちらも当然リセットされない。
つまり、再起動前のI2Cの設定が残ってしまっていて、マイコン側は新規の接続を受け付けなくなっている。
Touch Display 2のタッチ部はGoodix GT911互換コントローラ(I2C接続、通常 bus 10 / address 0x5d)を使っていて、このチップは電源投入直後のリセットシーケンス(RST + INT ピン制御)を要求するそうだ。再起動時はRaspi側のGPIO/I2Cがリセットされず、Goodix側が古い状態のまま応答しなくなる。goodix_tsドライバは起動時にI2Cに応答がないと「probe failed -5」で諦めるので、その後ロードされても復帰できない。
本来は、ハード的にはDSIマイコンのコントローラーのファームでデバイスが接続したときにはリセットすべき感じかな。もしくは、dtbでリセットするか。それとも、デバイスドライバ側でリセット処理を入れるか。
もっとも、GoodixのリセットピンがRaspi側から見えるように外に出ているわけではないので、Raspi側からの制御は難しいかも。少なくともdtsを書き換えたくらいだと無理そう。
純正プロダクトなのに、なんてお粗末な設計なんだろうなぁ... しかも、採用されているGoodixはAPI互換のクローン品らしい。
調べてみると、タッチが効かなくなるという事例は純正7インチTouch Display 2の時からたくさんある感じ。対処したというメッセージもあるけど、その後もあいかわらずダメという反応も多い。
Touch-functionality of Touch Display 2 stops working after reboot - Raspberry Pi Forums
https://forums.raspberrypi.com/viewtopic.php?t=389937
waveshare品でも同じ問題がある感じ。こちらはなんでかわからないけど、解決されないままCloseしている。
RPI 5 - Goodix capacitive touchscreen not working on latest Kernel · Issue #6456 · raspberrypi/linux
https://github.com/raspberrypi/linux/issues/6456
最近改良がされているdtbの設定でも、リセットパラメータはない。
linux/arch/arm/boot/dts/overlays/README at 4421ed134f9f03351a4a26293a29f009b8fff725 · raspberrypi/linux
https://github.com/raspberrypi/linux/blob/4421ed134f9f03351a4a26293a29f009b8fff725/arch/arm/boot/dts/overlays/README#L5600-L5612

正常時はinputデバイスが見えている。
fd@pi3b:~ $ cat /proc/bus/input/devices | grep -A5 "oodix"
N: Name="10-005d Goodix Capacitive TouchScreen"
P: Phys=input/ts
S: Sysfs=/devices/platform/soc/3f205000.i2c/i2c-11/i2c-10/10-005d/input/input0
U: Uniq=
H: Handlers=kbd mouse0 event0
B: PROP=2
とりあえず、ワークアラウンドで対応してみる。
fd@pi3b:~ $ vi goodix_recover.sh
#!/usr/bin/env bash
# /usr/local/bin/goodix_recover.sh (rev2)
set -u
BUS="${BUS:-10}"
ADDR_HEX="${ADDR_HEX:-0x5d}" # 0x5d
DEV_NAME="${BUS}-005d" # 10-005d
I2C_DEV_DIR="/sys/bus/i2c/devices"
I2C_BUS_DIR="${I2C_DEV_DIR}/i2c-${BUS}"
I2C_NEW="${I2C_BUS_DIR}/new_device"
I2C_DEL="${I2C_DEV_DIR}/delete_device"
DRV_DIR="/sys/bus/i2c/drivers/goodix"
PLAT_DRV="/sys/bus/platform/drivers/i2c-bcm2835"
PLAT_DEV="$(ls -d /sys/bus/platform/devices/*i2c* 2>/dev/null | head -n1)"
log(){ echo "[goodix_recover] $*"; }
has_input(){ grep -A5 -i "Goodix Capacitive TouchScreen" /proc/bus/input/devices 2>/dev/null | grep -q "Handlers="; }
has_node(){ [[ -e "${I2C_DEV_DIR}/${DEV_NAME}" ]]; }
unbind_goodix(){
[[ -e "${DRV_DIR}/unbind" ]] || return 0
echo "${DEV_NAME}" > "${DRV_DIR}/unbind" 2>/dev/null || true
}
bind_goodix(){
[[ -e "${DRV_DIR}/bind" ]] || return 0
echo "${DEV_NAME}" > "${DRV_DIR}/bind" 2>/dev/null || true
}
delete_node(){
[[ -w "${I2C_DEL}" ]] || return 0
echo "${DEV_NAME}" > "${I2C_DEL}" 2>/dev/null || true
}
create_node(){
[[ -w "${I2C_NEW}" ]] || return 0
echo "goodix ${ADDR_HEX}" > "${I2C_NEW}" 2>/dev/null || true
}
rebind_i2c_controller(){
[[ -n "${PLAT_DEV}" && -e "${PLAT_DRV}/unbind" && -e "${PLAT_DRV}/bind" ]] || return 0
echo "$(basename "${PLAT_DEV}")" > "${PLAT_DRV}/unbind" 2>/dev/null || true
sleep 0.2
echo "$(basename "${PLAT_DEV}")" > "${PLAT_DRV}/bind" 2>/dev/null || true
sleep 0.3
}
reload_mod(){
modprobe -r goodix_ts 2>/dev/null || true
sleep 0.2
modprobe goodix_ts 2>/dev/null || true
}
main(){
if has_input; then
log "already present (input). nothing to do."
exit 0
fi
log "step1: reload mod + unbind/bind client"
reload_mod
unbind_goodix
if has_node; then delete_node; fi
create_node
bind_goodix
sleep 0.5
if has_input; then log "recovered (step1)"; exit 0; fi
log "step2: rebind I2C controller, then recreate"
rebind_i2c_controller
reload_mod
unbind_goodix
if has_node; then delete_node; fi
create_node
bind_goodix
sleep 0.8
if has_input; then log "recovered (step2)"; exit 0; fi
if command -v vcgencmd >/dev/null 2>&1; then
log "step3: display power cycle"
vcgencmd display_power 0 >/dev/null 2>&1 || true
sleep 0.3
vcgencmd display_power 1 >/dev/null 2>&1 || true
sleep 0.5
reload_mod
unbind_goodix; if has_node; then delete_node; fi
create_node; bind_goodix
sleep 0.5
if has_input; then log "recovered (step3)"; exit 0; fi
fi
log "recovery failed. cold boot may be required."
exit 1
}
main "$@"
fd@pi3b:~ $ chmod +x goodix_recover.sh
再起動して効果を確認。
fd@pi3b:~ $ sudo reboot
fd@pi3b:~ $ cat /proc/bus/input/devices | grep -A5 "oodix"
fd@pi3b:~ $ sudo ./goodix_recover.sh
[goodix_recover] step1: reload mod + unbind/bind client
[goodix_recover] recovered (step1)
実行後は、一応見えるようになっている。
fd@pi3b:~ $ cat /proc/bus/input/devices | grep -A5 "oodix"
N: Name="10-005d Goodix Capacitive TouchScreen"
P: Phys=input/ts
S: Sysfs=/devices/platform/soc/3f205000.i2c/i2c-11/i2c-10/10-005d/input/input2
U: Uniq=
H: Handlers=kbd mouse0 event2
B: PROP=2
正常時は何もしない。
fd@pi3b:~ $ sudo ./goodix_recover.sh
[goodix_recover] already present (input). nothing to do.
systemdで起動するように設定すると、起動順序のバランスが悪いので、起動中にロックしてしまう。面倒なので、rc.localで起動することにする。
fd@pi3b:~ $ vi /etc/rc.local
#!/bin/sh -e
起動をブロックしないよう遅延してバックグラウンド実行
( sleep 5; /home/fd/goodix_recover.sh >> /var/log/goodix_recover.log 2>&1 ) &
exit 0
rebootのとき。
fd@pi3b:~ $ cat /var/log/goodix_recover.log
[goodix_recover] step1: reload mod + unbind/bind client
[goodix_recover] recovered (step1)
コールドブートのとき。
fd@pi3b:~ $ cat /var/log/goodix_recover.log
[goodix_recover] already present (input). nothing to do.
ログがたまると面倒なので、あとでログはloggerに渡すように変更しておく。
fd@pi3b:~ $ sudo rm /var/log/goodix_recover.log
fd@pi3b:~ $ sudo vi /etc/rc.local
#!/bin/sh -e
起動をブロックしないよう遅延してバックグラウンド実行
(
sleep 5
/home/fd/goodix_recover.sh 2>&1 | /usr/bin/logger -t goodix_recover
) &
exit 0
再起動してみる。
fd@pi3b:~ $ sudo reboot
動作はしている。
fd@pi3b:~ $ sudo journalctl -t goodix_recover -b | cat
Oct 30 16:58:30 pi3b goodix_recover[629]: [goodix_recover] step1: reload mod + unbind/bind client
Oct 30 16:58:31 pi3b goodix_recover[629]: [goodix_recover] recovered (step1)
デバイスは見えている。
fd@pi3b:~ $ grep -A5 -i "Goodix Capacitive TouchScreen" /proc/bus/input/devices
N: Name="10-005d Goodix Capacitive TouchScreen"
P: Phys=input/ts
S: Sysfs=/devices/platform/soc/3f205000.i2c/i2c-11/i2c-10/10-005d/input/input2
U: Uniq=
H: Handlers=kbd mouse0 event2
B: PROP=2
これで解決という感じか。
100円投げ銭 https://kinneko.booth.pm/items/1963720
オリジナル投稿:
TouchDisplay2でタッチが効かなくなる件|kinneko|pixivFANBOX
https://kinneko.fanbox.cc/posts/10816996



