ev620-sensor-loader loads the Egis EV620 vision sensor on the Acer Swift 14 AI (SF14-51) through the Intel Integrated Sensor Hub (ISH). Once loaded, the ambient light sensor and the presence sensor work on Linux.
This project is not affiliated with, endorsed by or supported by Acer, Egis or Intel. All names belong to their owners.
Status: experimental. Use at your own risk.
- Acer Swift 14 AI, SF14-51 (Intel ISH with an Egis EV620).
Other laptops with an EV620 behind the ISH may work, but nobody has tested one. The loader stops if the chip does not report IC version 0x0620.
Tested on the SF14-51 with Ubuntu 26.04 and kernel 7.0, Secure Boot on:
- the loader reads IC version 0x0620
- a full load takes about 3 to 5 seconds, with a CRC check of both files
- the light sensor reads 0 to 65 lux (range seen so far), presence reads 0 or 1, attention 0 or 100
- it works after a cold boot and after suspend
- DKMS builds the module and signs it with the MOK key
The sensor has no flash memory. It needs a firmware file and a weights file at every power on. These files are NOT included, and this project will never ship them. They must come from you: either a model you built yourself, or files you are entitled to use on your own hardware.
The loader does not check where the files come from. It only checks what the protocol needs:
| File | Size | Content |
|---|---|---|
| firmware | 14336 bytes (0x3800) | raw binary, as it should land in sensor RAM |
| weights | 90100 bytes (0x15ff4) | raw binary, sent right after the firmware |
Both are plain binary files, no header. The sensor receives them as one stream with no addresses, so the sizes must be exact.
The sensor reports a type (0 or 1). Different types may need a different
firmware. The service looks in /var/lib/ish-ev620, owned by root:
/var/lib/ish-ev620/ev620-firmware-type0.bin
/var/lib/ish-ev620/ev620-weights-type0.bin
and the type1 pair too if you have it. ev620-weights.bin is used when
there is no weights file for the detected type. If the folder has no
firmware file, the service logs a line and exits without touching anything.
You need the kernel headers, dkms and a C compiler:
sudo apt install dkms build-essential linux-headers-$(uname -r)
Then, as a normal user, from this folder:
./install.sh
The script asks for your password and:
- copies the module source to
/usr/src/ish-ev620-<version>and installs it with DKMS, so it is built again for every new kernel - installs
ish-ev620to/usr/local/sbinandev620-loadto/usr/local/libexec/ish-ev620 - installs and enables the systemd units (see Service behaviour)
- installs a udev hwdb file for the presence sensor
- creates
/var/lib/ish-ev620for your files - creates
/etc/default/ish-ev620with the settings, if it is missing
You can run it again after a git pull. It replaces the old install.
With Secure Boot on, DKMS on Ubuntu signs the module with the key in
/var/lib/shim-signed/mok/. That key must be enrolled with mokutil once.
If DKMS made a new key during the install, it tells you how to enroll it.
Reboot and accept it in the blue MOK screen.
Then put your files in /var/lib/ish-ev620 and run:
sudo systemctl start ish-ev620-load.service
./uninstall.sh
It stops and removes the units, the DKMS module, the tools, the settings and
the hwdb file. Your files in /var/lib/ish-ev620 stay. Delete them yourself
if you want.
Boot: ish-ev620-load.service runs once at boot. It waits up to 90 seconds
for the ISH sensor hub to show up, then loads the sensor.
Suspend and hibernate: the sensor keeps its firmware over a normal suspend.
This was tested: after s2idle it still runs its RAM code, and light and
presence work right away. So nothing runs after suspend.
ish-ev620-resume.service only runs after hibernate, hybrid sleep and
suspend-then-hibernate, where the machine is powered off. It waits 3 seconds
and then does the same as the boot service.
Periodic check: the Windows driver reads the sensor every 60 seconds and
reloads it if it fell back to its boot ROM. That is not possible here
without side effects: reading anything from the EV620 means unbinding
ish-hid, and all ISH sensors would vanish every minute. So
ish-ev620-check.timer runs a low-impact check every 5 minutes that only
reads what Linux already shows:
- If the HID sensor hub was enumerated again since the last run (its name,
like
001F:8087:0AC2.0006, gets a new number), the ISH was probably reset. Then it runs a real load right away. - If the screen is on (lid open, internal panel on) and both the light sensor and the presence sensor read exactly 0 for 6 checks in a row (30 minutes), it runs a real load. Both read 0 when the EV620 is not loaded. This happens at most once every 2 hours.
The trade off: a sensor that falls back to its boot ROM without an ISH reset
can stay dead for 30 minutes or more. And in a dark room with nobody in front
of the screen you get a needless load, which means a few seconds without
sensors, at most every 2 hours. The numbers are in /etc/default/ish-ev620.
To turn the check off:
sudo systemctl disable --now ish-ev620-check.timer
The same works for the other two units.
Presence: the ISH prox device reports 1 when someone looks at the screen.
iio-sensor-proxy wants a PROXIMITY_NEAR_LEVEL udev property to use it.
udev/61-ish-ev620.hwdb sets it to 1, only on the SF14-51. On other models
edit the dmi: match. GNOME does not use the proximity value today. The
file mainly removes a warning and lets monitor-sensor show it.
journalctl -u ish-ev620-load.service -b
journalctl -u ish-ev620-resume.service -u ish-ev620-check.service -b
ish-ev620 status
The load log should end with EV620 loaded (or already running) and
ISH sensors are back. In ish-ev620 status, in_illuminance_raw of the
als device should change with the light, and in_proximity0_raw should be
1 while you sit in front of the screen. monitor-sensor shows what GNOME
sees.
modprobe ish_ev620 failed: the module is missing for this kernel or not signed. Checkdkms statusandmodinfo -F signer ish_ev620. With Secure Boot,mokutil --list-enrolledmust show the DKMS key.no firmware in /var/lib/ish-ev620: see Files you must provide.load failed: runsudo ish-ev620 loadagain. If it keeps failing, shut the laptop down fully (not a reboot) and try again. A full power off puts the sensor back in its boot ROM.- Sensors missing after a run:
sudo modprobe -r intel_ishtp_hid && sudo modprobe intel_ishtp_hid, or reboot. The script tries this itself if bindingish-hidfails. - GNOME automatic brightness stops following the light: this can happen
after the backlight was changed by something other than GNOME. Turn
automatic brightness off and on again in the settings. If that does not
help, run
sudo systemctl restart iio-sensor-proxy. - Keep the brightness slider below 100%. At 100% GNOME has no room to adjust and automatic brightness may seem to do nothing.
- To load by hand:
sudo ish-ev620 load. To force a new upload even if the sensor runs:sudo ish-ev620 load --force.
The EV620 has no flash memory. At power on it runs a small boot ROM and waits. The host must upload the firmware and the weights into its RAM, ask the sensor for a CRC of what it received, and tell it to jump to the new code. From then on the sensor runs its own firmware and reports through the ISH like the other sensors.
The sensor is not directly visible to Linux. It sits behind the ISH. The
host talks to it through the ISH HID client, using the HOSTIF raw_request
message (command 0x07). Each request carries the EV620 logical unit id
(LUID) and a small EV620 command: register read, register write, reset,
start upload, data packet, get CRC, jump. The ISH firmware forwards the
command to the sensor and sends back the answer.
The in-tree ish-hid driver owns the ISH HID client while the sensors are
in use, so the loader has to borrow it. Each load does this:
- stop
iio-sensor-proxy - unbind
ish-hidfrom the ISH HID client - load
ish_ev620and bind it to the client - run
ev620-load load --fw-dir /var/lib/ish-ev620 - unbind and unload
ish_ev620, bindish-hidagain - wait for the HID sensors to come back, start
iio-sensor-proxyagain
Steps 5 and 6 always run, also on errors or when the service is stopped.
During those few seconds the ISH sensors (light, presence and the others)
are gone. If the sensor already runs its RAM code, ev620-load sees it and
does nothing.
Restarting iio-sensor-proxy matters: without it GNOME may keep showing
old values until you toggle automatic brightness.
ish_ev620 is not a generic pass-through. It checks every message against
a fixed list and rejects the rest with EPERM. It accepts the HOSTIF device
enumeration, and raw_request messages to the EV620 LUID that match one of
the steps in the load sequence below exactly: the same registers, lengths
and written values. Upload data packets are only accepted after an upload
start (0x19) in the same open() of /dev/ish_ev620, and stop being
accepted after the CRC read, the jump or a reset. There is no option to turn
this off.
ish_ev620.c: a small kernel module. It is an ISHTP client for the ISH HID client and creates/dev/ish_ev620. A write sends one HOSTIF message and waits for its answer, a read returns that answer. It does not bind by itself:ish-hidmust be unbound first, because only one client can talk to the ISH HID client at a time.ev620-load.c: the user space loader. It does all the EV620 logic.ev620-load statusreads the IC version, the RAM version (0 means "still in boot ROM") and the sensor type.ev620-load load ...runs the full upload sequence.--dry-runprints every request without opening the device.-vdumps every request and answer in hex.
ish-ev620: the script the systemd units run (load,check,status).systemd/: the units.udev/: the hwdb file.install.sh,uninstall.sh,ish-ev620.default(settings).dev/: test scripts for development, see below.
- Read the IC version (register 0x2003c). It must be 0x0620.
- Read the RAM version (0x14003). If it is not 0 the sensor already runs
RAM code. The loader reads 0x14400 as a liveness check and stops, unless
--forceis given. - Write the interface and clock registers: 0x20000, 0x20002, 0x20200, 0x20204, 0x141c0. Each write is read back.
- Read the sensor type.
- Reset (0xff), wait 100 ms.
- Start the upload (0x19).
- Send the firmware, then the weights, in 255 byte data packets (0xfe).
- Read the CRCs (0x1b) and compare. The loader computes a CRC-16 (polynomial 0x8005, init 0, not reflected) over each file. A mismatch stops the sequence before the jump.
- Jump to RAM code (0x1a).
- Write 2 to 0x14353 (up to 20 tries, 100 ms apart), then 2 to 0x14314.
If any step fails, the loader waits 5 seconds and starts again from step 1,
up to --retries times (default 3). A failed upload leaves the sensor in
its boot ROM. A new attempt starts with a reset, so it does not depend on
what was left behind.
You can also give the files by hand:
ev620-load load --firmware fw.bin --weights weights.bin --type 0
ev620-load load --fw-dir /var/lib/ish-ev620
With --type N the loader stops before uploading anything if the sensor
reports another type.
make
This builds the module and ev620-load in place, as a normal user. With
Secure Boot on, sign the module after every build:
sudo /usr/src/linux-headers-$(uname -r)/scripts/sign-file sha256 \
/var/lib/shim-signed/mok/MOK.priv /var/lib/shim-signed/mok/MOK.der ish_ev620.ko
The scripts in dev/ use this local build, not the DKMS one:
sudo dev/test-status.sh # status only, read only
sudo dev/test-load.sh /var/lib/ish-ev620 # upload, then watch the sensors
They unbind ish-hid, load the module, run one command, then always bind
ish-hid again, also on errors or Ctrl-C. They keep a log under
~/.cache/ish-ev620/ of the user who ran sudo (set EV620_LOGDIR to change
it). Stop the installed services first if you test by hand
(sudo systemctl stop ish-ev620-check.timer).
If the ISH sensors do not come back after a test, run
sudo modprobe -r intel_ishtp_hid && sudo modprobe intel_ishtp_hid, or
reboot.
See CONTRIBUTING.md before sending changes.
GPL-2.0, see COPYING.