Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Asus Expertbook B9400CEA #2

Closed
DupiDachs opened this issue Mar 22, 2021 · 21 comments
Closed

Asus Expertbook B9400CEA #2

DupiDachs opened this issue Mar 22, 2021 · 21 comments

Comments

@DupiDachs
Copy link

First of all: Thanks a lot for all the work you have put into this!

I am currently trying to get your prototype running on an ASUS Expertbook B9400. This device has a somewhat different sensor, but is also based on SPI ELAN device.

  • ../../../devices/pci0000:00/0000:00:1e.2/pxa2xx-spi.4/spi_master/spi0/spi-ELAN70A1:00/
  • hidraw0 -> ../../devices/pci0000:00/0000:00:15.1/i2c_designware.1/i2c-2/i2c-ASUE140A:00/0018:04F3:3134.0001/hidraw/hidraw0/

Hence, I set up 04F3:3134 as VID:PID and the ACPI ID ELAN70A1. Then I built the prototype and ran it:

sudo ./prototype udev
Prototype starting...
Compiled with HKEY values : TP_VID 4f3; TP_PID 3134; ACPI_ID ELAN70A1
Got SPI entry /sys/devices/pci0000:00/0000:00:1e.2/pxa2xx-spi.4/spi_master/spi0/spi-ELAN70A1:00/spidev/spidev0.0
Found ACPI id!
Got HID entry /sys/devices/pci0000:00/0000:00:15.1/i2c_designware.1/i2c-2/i2c-ASUE140A:00/0018:04F3:3134.0001/hidraw/hidraw0
Found TP ID!
Got SPI = /dev/spidev0.0 and HID = /dev/hidraw0, opening.
Beginning initialization
SPIStatus = 0x01
Result of ioctl for reset 5
SPIStatus after reset = 0x01

  • Register 00 = 00
  • Register 01 = 00
  • Register 02 = 4f
  • Register 03 = 00
  • Register 04 = 4f
  • Register 05 = a0
  • Register 06 = 00
  • Register 07 = 00
  • Register 08 = 00
  • Register 09 = 04
  • Register 0a = 73
  • Register 0b = 01
  • Register 0c = 08
  • Register 0d = 00
  • Register 0e = 00
  • Register 0f = 13
  • Register 10 = 38
  • Register 11 = 01
  • Register 12 = 00
  • Register 13 = 00
  • Register 14 = 00
  • Register 15 = 04
  • Register 16 = 00
  • Register 17 = 64
  • Register 18 = 01
  • Register 19 = f4
  • Register 1a = 00
  • Register 1b = 00
  • Register 1c = 00
  • Register 1d = 00
  • Register 1e = 00
  • Register 1f = 00
  • Register 20 = 00
  • Register 21 = 00
  • Register 22 = 04
  • Register 23 = 00
  • Register 24 = 00
  • Register 25 = 00
  • Register 26 = 00
  • Register 27 = 00
  • Register 28 = 00
  • Register 29 = 02
  • Register 2a = 07
  • Register 2b = e0
  • Register 2c = 00
  • Register 2d = 00
  • Register 2e = d0
  • Register 2f = 40
  • Register 30 = 01
  • Register 31 = 38
  • Register 32 = 00
  • Register 33 = 00
  • Register 34 = 00
  • Register 35 = 1f
  • Register 36 = ff
  • Register 37 = 00
  • Register 38 = 00
  • Register 39 = 00
  • Register 3a = 00
  • Register 3b = 24
  • Register 3c = ff
  • Register 3d = ff
  • Register 3e = ff
  • Register 3f = f8
    Reading raw dimensions
    Got 80x80 sensor
    After hardcoded lookup: (80 x 80) Version = 39
    Speicherzugriffsfehler

Speicherzugriffsfehler is German for memory access error.
Any ideas on how I might get this working? Maybe I need to somehow follow what you have done in Windows for your ELAN reader chasing logs. Is there any help on how to get me started?

@DupiDachs
Copy link
Author

OK. Already got a step further and simply hardcoded sensIcVersion = 1; to the code.

It is now running and returns somehow sensible values:

  • Without the finger on, I end up at New mean image == 8350.
  • With finger, I end up at New mean image == 14728.

So I guess there is still something off with the register that sets the gain. I'll take a look ...

@mincrmatt12
Copy link
Owner

OK so I opened up the build of the driver for your laptop and it seems to be a newer sensor than what the version I originally reversed supported, and I think it's using a different calibration sequence. I'm still reading through it but I might have some new initialization/calibration stuff pushed soon.

I would ask for windows driver logs but the new drivers don't use OutputDebugString so you can't use something simple like sysinternals debugview to view them, and I'm not sure how to view UMDF 2 TraceMessage outputs. In theory you can do it with windbg, like how msdn explains it here but I don't have any experience with that, although if you manage to get anything going that route (something containing logs with "FpDeviceInitialize" in them) they'd be useful for understanding the driver.

@DupiDachs
Copy link
Author

DupiDachs commented Mar 24, 2021

Thanks for the hint. I'll give that link of yours a try once I have some time again - possibly this weekend. :)

One more info: Ignoring the calibration procedure and allowing a far higher mean_value lets me proceed with taking an image. At least the process runs reliable here. I then ran the python script to get an visual output, changing the size from 96x96 to 80x80 (as indicated by my sensor) in the script.
Output is pretty useless, but reproducable. :D

bla

@mincrmatt12
Copy link
Owner

You might think it's useless but that confirms my basic understanding of the capture image code for this sensor is correct. Specifically unlike the other sensors which you request line-by-line, for this one it seems you have to request the entire image at once. Since the current code doesn't know that, it's requesting the entire image for each line and so you get 80 first lines (plus a bunch of junk since you also apparently have to filter 0xffs from the bytestream)

mincrmatt12 added a commit that referenced this issue Mar 25, 2021
@mincrmatt12
Copy link
Owner

mincrmatt12 commented Mar 25, 2021

Alright in theory you should be able to use the new code to capture an image.

@DupiDachs
Copy link
Author

DupiDachs commented Mar 26, 2021

Thanks for the input!
I did a git pull just now, rebuilt the prototype and ran another test. I found a couple of things:
image

  • SensorDataTableEntry is 1 item longer than SensorNameTable (so it seems one sensor name is missing)
  • The reader I am using has a size of 80x80 -> 0x50
    Adjusting the size makes the program enter the sensIcVersion==2 specific code (CaptureRawImageHV). I then get the following output instead of a successful reading:
    image

I'll try later to take a closer look. Thanks again for your efforts!

@mincrmatt12
Copy link
Owner

mincrmatt12 commented Mar 26, 2021

I should have fixed the missing sensor name in 33e5c9a, but hmm that is interesting. When you hardcoded it did you also have it use the HV version of the calibration code too? What kind of output did it end up giving you?

@DupiDachs
Copy link
Author

Yes. It also enters CalibrateHV. Just checked that with a simple printf in there.
image

Another thing I have found. Linux lists TP_PID = 0x3134; When I am in Windows, I found the following HKLM regedit:
// These values come from HKLM\System\CurrentControlSet\Control\ElanFP\OtherSetting\TP_VID,TP_PID
// available PIDs: 22FE, 3028, 304D, 3059, 306F, 30B1, 30B2, 3104
You also find 3104 in there, which is the ID for which you have set up an assert. I am not using this PID, but is it actually the right one? On linux, I do not see it.

@mincrmatt12
Copy link
Owner

The PID that the touchpad is reporting shows up in the path in /sys, and based on what you showed earlier you have it set correctly. Plus, the driver refers to that mode (the reason that I've specifically asserted against that specific touchpad) as "x571_special_parameter", which I assume means the X571 which is not what you have.

Based on those results though CaptureImage doesn't seem to actually be getting new (or even any valid) data at all.

@DupiDachs
Copy link
Author

  • Based on those results though CaptureImage doesn't seem to actually be getting new (or even any valid) data at all.
    Exactly. Now I am trying to directly output "hardcoded_unclean_rx_buf" to somehow see what it actually contains before you do your processing magic.

@mincrmatt12
Copy link
Owner

I just re-read the CaptureImage method in the windows driver and it seems like I was missing a "wait for ready" bit thing; I just pushed code that does wait for it so maybe now it will actually have some valid data?

@DupiDachs
Copy link
Author

That did not do it unfortunately. :/ I'll keep looking. :)

@mincrmatt12
Copy link
Owner

Anything noticeably different in the output?

@DupiDachs
Copy link
Author

DupiDachs commented Mar 26, 2021

Interestingly, the "waiting for image" part never gets printed...
Did not see any difference. From time to time, I get now "EMPTY" instead of "UNKNOWN", but I guess that is just passing a different threshold by accident.
image

@mincrmatt12
Copy link
Owner

mincrmatt12 commented Mar 26, 2021

Maybe I'm hitting the upper limit on the size of an SPI transfer, some googling says they can only be at most 4096 bytes long by default and I'm doing what the windows driver does which is one huge 16k transfer.

I just pushed some slightly suspicious code that tries to chunk up big transfers into 2048byte segments.

@DupiDachs
Copy link
Author

DupiDachs commented Mar 26, 2021

image
I put this printf statement there and it never gets printed. Nevermind the for loop, played a bit there as well...

Trying your push now...

@mincrmatt12
Copy link
Owner

Actually I just checked the spidev code directly and that push wouldn't bypass the limit (it's applied to the entire ioctl) so I made another one that just uses multiple reads. Based on the fact that it's never seeing any data it probably was never actually doing any transferring and the "image" was just junk on the stack.

@DupiDachs
Copy link
Author

Crap. Gotta continue tomorrow - no more time. From what I tried just now it simply proceeds and writes out an image, but it its all zeros.
I'll be back...

@DupiDachs
Copy link
Author

DupiDachs commented Mar 26, 2021

OK! So, I do not know why the sequential read process in blocks of 0x300 fails, but I managed to get a successful reading by going back to the previous code and setting the kernel parameter spidev.bufsiz=65536! I might reduce that to a value that is actually required...
I then get a very clean reading of my finger :)
image
Thanks again for your great work! And btw: Also the calibration is now working.

@mincrmatt12
Copy link
Owner

Cool! I guess the sensor doesn't like it if you deselect it while receiving the image partway through. At some point (bit busy rn) I'll start work on adding the new routines to the libfprint driver.

@DupiDachs
Copy link
Author

Just wanted to let you know that with your latest push, I could remove my manual tweaks and have it run successfully without them. I will continue taking a look at your fprint branch...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants