Skip to content

About

Loads the Egis EV620 vision sensor on the Acer Swift 14 AI (SF14-51) through the Intel ISH, so ambient light and presence work on Linux

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

ev620-sensor-loader

CI

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.

Supported hardware

  • 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

Files you must provide

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.

Install

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-ev620 to /usr/local/sbin and ev620-load to /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-ev620 for your files
  • creates /etc/default/ish-ev620 with 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

./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.

Service behaviour

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.

Check that it works

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.

Troubleshooting

  • modprobe ish_ev620 failed: the module is missing for this kernel or not signed. Check dkms status and modinfo -F signer ish_ev620. With Secure Boot, mokutil --list-enrolled must show the DKMS key.
  • no firmware in /var/lib/ish-ev620: see Files you must provide.
  • load failed: run sudo ish-ev620 load again. 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 binding ish-hid fails.
  • 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.

How it works

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:

  1. stop iio-sensor-proxy
  2. unbind ish-hid from the ISH HID client
  3. load ish_ev620 and bind it to the client
  4. run ev620-load load --fw-dir /var/lib/ish-ev620
  5. unbind and unload ish_ev620, bind ish-hid again
  6. wait for the HID sensors to come back, start iio-sensor-proxy again

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.

The module only accepts the loader's commands

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.

What is in this repository

  • 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-hid must 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 status reads 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-run prints every request without opening the device.
    • -v dumps 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.

The load sequence

  1. Read the IC version (register 0x2003c). It must be 0x0620.
  2. 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 --force is given.
  3. Write the interface and clock registers: 0x20000, 0x20002, 0x20200, 0x20204, 0x141c0. Each write is read back.
  4. Read the sensor type.
  5. Reset (0xff), wait 100 ms.
  6. Start the upload (0x19).
  7. Send the firmware, then the weights, in 255 byte data packets (0xfe).
  8. 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.
  9. Jump to RAM code (0x1a).
  10. 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.

Development

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.

License

GPL-2.0, see COPYING.

About

Loads the Egis EV620 vision sensor on the Acer Swift 14 AI (SF14-51) through the Intel ISH, so ambient light and presence work on Linux

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages