sonnyp / linux-minibook-x

Linux for the Chuwi MiniBook X 2023 / N100
55 stars 1 forks source link

Tablet switch sensor INT33D3 #5

Open sleeply4cat opened 6 months ago

sleeply4cat commented 6 months ago

I looked into the ACPI tables and found that INT33D3 implementation is just a stub which does not really make any queries to hardware. INT33D3 relies on VGBS ACPI method that in this device just returns the keyboard lock status that controlled by LTSM method. Linux INT33D3 driver has special case that disables tablet sensor for such defective BIOS implementations, that's why the device doesn't stuck into tablet mode. I think some Windows component or driver reads some non-standard sensor and calls the LTSM method to enable/disable the keyboard and touchpad which also triggers the standard INT33D3-ish mode switching event. I tried to trace ACPI calls that Windows make but failed because of having small brain.

lschans commented 6 months ago

So did I, the sensor is there. But there is no way to get the value of it in Linux.

sleeply4cat commented 6 months ago

the sensor is there

Which one exactly?

I'm trying to debug ACPI calls now, but doing it from the laptop itself cause BSOD on every breakpoint hit, and I'm having problems with connecting kernel debugger over USB/net.

lschans commented 6 months ago

I did try a lot, with udev. Manually reading it. Even tried some stuff in CPP to make a kmod.

Eventually I came up with this and build it today.

https://github.com/sonnyp/linux-minibook-x/issues/6

It would be cool if you can test my code. I tried it on 2 minibooks both running Ubuntu. I don't k own what you run. But maybe something needs to be adapted to make it usable for more people.

sleeply4cat commented 6 months ago

You properly recognized some week spots like wrong type of chassis (10 instead of 31/32), but the situation is much worse. The INT33D3 device that you see in udev is just an imitation on UEFI side. It doesn't really produce switching events or change its state by itself. On other hand, I found ACPI methods to control keyboard and touchpad power, and probably able to write a kernel module to add switching support. But I still don't know how does Windows read the actual sensor and what type of that sensor is

lschans commented 6 months ago

If you manage to toggle the power of the keyboard, then that would lead us to a much cleaner solution.

Still if we can toggle the power, but still not detect the state of the lid, and we still still can't convince Wayland that we have a convertible, automagic won't happen.

We will end up with a gnome extension, a script or button somewhere.

I personally hope that we can come up with an easy solution, that's easy to install for most people.

sleeply4cat commented 6 months ago

Tablet switch is being controlled by the "MEMSIC dual accelerometer driver", which is registered in system via UMDF with name mxc6655Angle.

lschans commented 6 months ago

And how they control this, did you find out? Is it a physical thing, like a magnet close to the accelerometer. Or did they pull of other kind of magic?

sleeply4cat commented 6 months ago

Be patient, it's 3 am here ;D

lschans commented 6 months ago

2.15 am here 😂 I will read out all channels of the accelerometer meter while moving and opening and closing the lid tomorrow. Good night.

sleeply4cat commented 6 months ago

you can find a bit about the situation here. not sure if this especial file is related to our laptop tho

lschans commented 6 months ago

He is talking about dual sensors. And dual sensors would make sense in my head. If there is one in the lid and one in the base. You can just check for inverted values and determine if the lid is closed or in tablet mode.

On the minibook I only see 1 sensor.

sleeply4cat commented 6 months ago

No idea actually. We have no HingeAngleService in drivers, but I pretty sure that mxc6655Angle plays that role. Haven't achieved significant success in reversing for now.

lschans commented 6 months ago

I am working on a code to fake it all and am almost there. I am doing some magic by reading the accelerometer and I will merge it into my branch soon and make a complete install script. Maybe even make a deb and rpm. That way people have at least something to make it usable as a tablet.

sleeply4cat commented 6 months ago

are you working in userspace?

lschans commented 6 months ago

Checkout the link to my github, I have a systemd service in combination with a gnomeshell extension. Works pretty well on my laptop. I am testing code now to automatically do some stuff. It's not the prettiest solution but it works

sleeply4cat commented 6 months ago

Hi, I found the solution. Surprised how many times I was so close but probably blind.

Device really has two MDA6655 accelerometers located at I2C0:0x15 and I2C1:0x15. The second one is being loaded automatically by info from the ACPI table. To enable the first one, you can execute echo mxc4005 0x15 > /sys/bus/i2c/devices/i2c-0/new_device or probably add something into startup modprobes. After that, you can operate with two vectors from two iio devices to detect the lid orientation.

lschans commented 6 months ago

Yes, let me try that, and I can make the service auto detect! Then we have a complete solution. I'll try something this week.

sleeply4cat commented 6 months ago

also remember that there is acpi method that correctly performs input locking and notifies INT33D3 driver about the configuration change. It would be more clean solution than the userspace hooks.

lschans commented 6 months ago

I know, but I've been trying to find the keyboard power and the software calls for the TouchPad power. Tried everything, googled it all. The best I could come up with so far was this solution for XWayland. If you manage to find the right acpi calls I'll be happy to code them.

So far we're doing good on this. Would be so cool if we manage to pull this off the right way.

sleeply4cat commented 6 months ago

\_SB.ACMK.LTSM 0 \_SB.ACMK.LTSM 1 it may be not trivial to call them from userspace. I know only the acpi_call module, but it is obviously bad choice. probably better to make specialized module for that

lschans commented 6 months ago

Okay I2C0:0x15 and I2C1:0x15 both working, I can trigger something on the x-axis. When they are roughly the same it's in tablet mode. When they are opposites the lid is closed. I logged the values in a text file together with the lid sensor.

This seems to work and get us a lot further to automatic tablet mode. I am not going to put anything into modprobes yet. For now I want to keep it non-intrusive just so when people mess up a reboot is all they need.

lschans commented 6 months ago

Okay got some code to try in the terminal that short of does the same as the undocumented "special HingeAngleService" in the windows driver.


#!/bin/bash
echo mxc4005 0x15 > /sys/bus/i2c/devices/i2c-0/new_device

echo "sensor:modalias:acpi:/dev/iio-device0
 ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1" > /etc/udev/hwdb.d/61-sensor-local.hwdb

echo "sensor:modalias:acpi:/dev/iio-device1
 ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1" >> /etc/udev/hwdb.d/61-sensor-local.hwdb

TRESHOLD=50

function to_pos {
if ! [ "$1" -gt 0 ]; then
    echo -n $(($1*-1))
else
    echo -n $1
fi
}

function is_tablet {
if ! [ "$1" -gt "$TRESHOLD" ]; then
  echo 1
else
  echo 0
fi
}

LID=$(to_pos `cat /sys/bus/iio/devices/iio:device0/in_accel_x_raw`)
BASE=$(to_pos `cat /sys/bus/iio/devices/iio:device1/in_accel_x_raw`)
DIFF=$(to_pos $(($LID-$BASE)) )
TABLET=$(is_tablet $DIFF)

echo "Lid: $LID"
echo "Base: $BASE"
echo "Diff: $DIFF"
echo ""
echo "Is tablet $TABLET"

if you add this to a script and run it as root with 'watch' you can see it switch to tablet mode.

lschans commented 6 months ago

_SB.ACMK.LTSM 0 _SB.ACMK.LTSM 1

I see what you mean here, for now I want to keep it in userspace. It would just be nice if I found a way to control the touchpad in any way. 'Fn+Esc' is not even registered by the system in any event. Almost seems like a hardware thing happening.

kaaku3 commented 5 months ago

Hi I have a freebook and i ran the command above but the second accelerometer doesn't seem to be detected still. How would i go about finding the location if its not I2C0:0x15 and I2C1:0x15. I am quite new to linux.

sleeply4cat commented 5 months ago

As a cheap start point, you can check if there is the device with address 0x15 on the i2c-0 bus. There are at least 3 different hw revisions are being sold under the minibook n100 name, so I would not be surprised if you have another implementation or addressing

  1. sudo apt install i2c-tools
  2. sudo modprobe i2c-dev
  3. sudo i2cdetect -r -y 0 You should see output like above: Screenshot from 2024-06-23 15-05-20 Or, if the driver loaded successfully, and device is IN USE, it would be like Screenshot from 2024-06-23 15-06-35
kaaku3 commented 5 months ago

Thankyou for the advice unfortunately no luck

Screenshot from 2024-06-23 21-40-34

kaaku3 commented 5 months ago

I did find some UU's on a diffent number though Screenshot from 2024-06-23 21-48-43

kaaku3 commented 5 months ago

could it be 12? Screenshot from 2024-06-23 21-57-46

sleeply4cat commented 5 months ago

try another bus numbers. You can see them in sudo i2cdetect -l output. Also, it's probably possible to see it from the ACPI tables dumped them as described here Not sure if it's safe to post the full dump here 'cause it may contain your windows key. I'd like to see the _SB_.ACMK node from dsdt.dsl if you success in decompiling it

sleeply4cat commented 5 months ago

That's how it looks for my laptop: https://github.com/sonnyp/linux-minibook-x/assets/37955805/837b688e-ea7a-4ac1-b2af-d6034c0e29fe

sleeply4cat commented 5 months ago

I did find some UU's on a diffent number though https://private-user-images.githubusercontent.com/2504063/342065557-c0aa59b7-a650-4b1f-841d-61338a9e4ff8.png

UU on 0x15 from the bottom one is probably the first accelerometer. By the way, does it work under Windows at all?

Barely it's 0x44 on 12th bus, the address has too many differences

kaaku3 commented 5 months ago

Not easy for a beginner but i did find this

Device (ACMG) { Name (_ADR, Zero) // _ADR: Address Name (_HID, "MDA6655") // _HID: Hardware ID Name (_CID, "MDA6655") // _CID: Compatible ID Name (_DDN, "Accelerometer with Angle Calculation") // _DDN: DOS Device Name Name (_UID, One) // _UID: Unique ID Method (_CRS, 0, NotSerialized) // CRS: Current Resource Settings { Name (RBUF, ResourceTemplate () { I2cSerialBusV2 (0x0015, ControllerInitiated, 0x00061A80, AddressingMode7Bit, "\_SB.PC00.I2C2", 0x00, ResourceConsumer, , Exclusive, ) I2cSerialBusV2 (0x0015, ControllerInitiated, 0x00061A80, AddressingMode7Bit, "\_SB.PC00.I2C3", 0x00, ResourceConsumer, , Exclusive, ) }) Return (RBUF) /* _SB.PC00.I2C3.ACMG._CRS.RBUF */

kaaku3 commented 5 months ago

Screenshot from 2024-06-23 22-33-11

sleeply4cat commented 5 months ago

so you need buses 2 and 3

kaaku3 commented 5 months ago

Sorry i'm taking too much of you time, i'm very confused sudo i2cdetect -r -y 2 and sudo i2cdetect -r -y 3 is just blank

sleeply4cat commented 5 months ago

what if you without -r ?

kaaku3 commented 5 months ago

same. It does work fine on windows

kaaku3 commented 5 months ago

I am able to cd into here, does that mean one of them is 15? cd /sys/bus/i2c/devices/i2c-15/i2c-MDA6655:00

sleeply4cat commented 5 months ago

no idea honestly. Maybe on your revision windows calls some extra methods to power up these modules or something like that. Maybe your ACPI table is just incorrect. Could you post dsdt.dsl if it's safe?

kaaku3 commented 5 months ago

I dont know if its safe but sure dsdt.txt Had to change it to .txt to upload

kaaku3 commented 5 months ago

Thankyou for your help, its currently late here and i'm in over my head. I will try again tomorrow if I have the time. Thankyou again.

sleeply4cat commented 5 months ago

I'm sorry, I don't know what exactly went wrong. You have to start your own investigation if you want to make it work, 'cause I don't have access to the exact hardware.

I can give some vectors for it:

kaaku3 commented 5 months ago

Thankyou, I appreciate the advice. I will have a look at the weekend. When it comes to things like this my knowledge is very limited. I will try and I'll let you know if i find anything.

Thinking outside the box maybe a bios mod would be less work

sleeply4cat commented 5 months ago

By the way, it would be nice if you left some info to identify your laptop revision. Like the bios build dates etc.

sleeply4cat commented 5 months ago

About BIOS mods. I checked and found that laptop has BootGuard profile 4 enabled. It means that the CPU has vendor key flashed and will refuse to start if the bios checksum mismatch. Haven't check it on practice btw.

kaaku3 commented 5 months ago

PXL_20240625_133220662 MP~2

I kinda got it working it's 2c-16 but it sometimes adds as device1 sometimes device2

csp5me commented 4 months ago

guys,

Tablet switch mode will not work in linux on the minibook x nor on the freebook, as according to the wayland specs, it needs a tablet mode switch sensor, that is not available in the chuwi devices.

In windows it works, because the driver is less strict and can only rely on the accelerometer. I also don't understand why wayland is so picky, but that's life.

How can you check that it works and not work? Please check

sleeply4cat commented 4 months ago

ok you challenged me will try the naive implementation

lschans commented 4 months ago

That would be nice, specially without recompiling the kernel, just some kmod that can be loaded afterwards.

Otherwise you'll be stuck to a manually configured kernel.

sonnyp commented 4 months ago

I guess this needs to be implemented as a new SW_TABLET_MODE "backend" in libinput.