Dell Venue 10 Pro 5055 Screen Rotation in Gnome

I recently fished a Dell Venue 10 Pro out of a pile of old computers at work that were heading to recycling. It's a pretty underwhelming computer but I thought it might be fun to tinker with a linux tablet in anticipation of the PineTab being released sometime next year.

I threw Fedora 31 on it as a first attempt, partly because I like Fedora and mostly because I had a USB drive with the installer already handy. I realize this might not be the best distro for this underpowered tablet but I just wanted to check it out. It installed fine with one exception, the screen is rotated 90 degrees clockwise in gnome. It worked fine under LXDE though. I poked around looking for a simple screen rotation setting in gnome but didn't find anything. Google kept pointing me down the road of iio-sensor-proxy and something about an ACCEL_MOUNT_MATRIX which I sort of glossed over because it seemed overly complex for a simple screen rotation. Surely there is just a simple "rotate 90 degrees" setting somewhere, right?

Eventually I gave up on a simple solution and started to read through the accelerometer matrix stuff. It turns out it's not that complicated. There is a file containing information about how the accelerometer in any given device is mounted so the OS knows which readings on each axis, x, y, and z correspond to the physical world. This is recorded in a matrix of three rows and three columns. It's been 30 years since I learned linear algebra and everything I once knew about matrix math is long forgotten so I couldn't really figure out how the matrix itself works, I just got my settings through trial and error. You can read the details of the matrix documented in the kernel but it didn't really help me much.

If you look at the sensor file it contains instructions for adding your own custom entry. Essentially you just need to figure out your device modalias:

cat /sys/`udevadm info -q path -n /dev/iio:device0`/../modalias

For the Dell Venue it returned acpi:INVN6500: Then you can get your device DMI string:

cat /sys/class/dmi/id/modalias

which returns:

dmi:bvnDellInc.:bvrA07:bd12/30/2015:svnDellInc.:pnVenue10Pro5055:pvrA07:rvnDellInc.:rn0T2H9X:rvrA00:cvnDellInc.:ct8:cvrNotSpecified:

Then create the file /etc/udev/hwdb.d/61-sensor-local.hwdb with the contents below. NOTE: Whitepace matters, you need to start the ACCEL_MOUNT_MATRIX line with a blank space

sensor:modalias:acpi:INVN6500*:dmi:*xvnDell*:pnVenue10Pro5055*   ACCEL_MOUNT_MATRIX=0, -1, 0;1, 0, 0;0, 0, 1

You can see I simplified the DMI string above with asterisks rather than specify every detail. On your own system it probably doesn't matter, in fact you can skip the full DMI string entirely and just do something very simple like this:

sensor:modalias:acpi:INVN6500*:dmi*

This will match anything using the INVN6500 sensor which is fine because your machine only has one sensor, but I tried to format my string to match the style of other strings in the main systemd sensor file because I wanted to also submit a pull request to include this in the official project.

Now you just need to update your hardware database:

sudo systemd-hwdb update

If you get an error, you probably ignored the note above about whitespace. If you didn't get an error you can validate your setting worked by running the commands below. Or you can just reboot and see what happens.

sudo udevadm trigger
sudo udevadm info -export-db | grep ACCEL

I submitted a pull request to add the Dell Venue 10 Pro 5055 info to systemd so at some point in the future this will "just work" but If you are following this guide and have a different device for which you are trying to figure out the matrix, I can tell you what I figured out in my trial and error. The default matrix is the "identity matrix" which means the hardware and sensor are perfectly aligned by default. The identity matrix is:

1 0 0
0 1 0
0 0 1

The following matrix gave me the correct default orientation when docked to the keyboard but it would not rotate at all.

0 1 0
0 1 0
0 0 1

So, I think you should not have two ones in the same row or column which makes sense because I believe they represent which sensor is pointing up in a given orientation. This next matrix worked for two orientations but was flipped 180 degrees for the other two:

0 1 0
1 0 0
0 0 1

So finally flipping the first one to a negative one corrected the 180 degree issue:

0 -1 0
1 0 0
0 0 1

And so that is ultimately the value I used for the "ACCEL_MOUNT_MATRIX=0, -1, 0;1, 0, 0;0, 0, 1" setting.

UPDATE: My pull request was accepted to systemd. As minor as it is, I'm weirdly excited that my first real pull request was accepted to a project as important as systemd.