This allows the elan_i2c module to be reset when it crashes.

Typical behaviour: driver failing with a kernel message like:

elan_i2c i2c-ELAN0600:00: invalid report id data (ff)

In older kernels it was possible to just do rmmod elan_i2c; modprobe elan_i2c.

Since 4.20 the reload of the module no longer works.

KT Liao provided a fix which allows the following reset:

echo 1 > /sys/devices/pci0000:00/INT3433:00/i2c-1/i2c-ELAN0600:00/i2creset

Files:

elan_i2c_core.c
elan_i2c.h
elan_i2c_i2c.c
elan_i2c.mod.c
elan_i2c_smbus.c

Script to copy these into the kernel source and build and install the module

#! /bin/bash
set -x
VERS=`uname -r`
DEST=/usr/src/linux/drivers/input/mouse
FILES="elan_i2c.h elan_i2c.mod.c elan_i2c_core.c elan_i2c_i2c.c elan_i2c_smbus.c"
cp -p $FILES $DEST
cp /boot/System.map-$VERS /usr/src/linux/System.map
cp /lib/modules/$VERS/build/Module.symvers /usr/src/linux/
zcat /proc/config.gz > /usr/src/linux/.config
cd /usr/src/linux
make prepare
make modules_prepare
make modules SUBDIRS=drivers/input/mouse
make modules_install SUBDIRS=drivers/input/mouse

Script to watch for failure messages and reset

This can be placed at /etc/init.d/boot.local

#! /bin/bash
tail -fn0 /var/log/messages | while read line ; do
    echo "$line" | grep "ff" | grep "invalid" | grep "elan_i2c" >> /var/log/reload-elan_i2c.log
    if [ $? = 0 ];
    then
        echo 1 > /sys/devices/pci0000:00/INT3433:00/i2c-1/i2c-ELAN0600:00/i2creset
    fi
done