HyperPixel 4 - Touch screen dimensions are swapped


Hi Guys,

The screen is 800x480.

The touchscreen is using 480x800

Here is the output from evtest using my fat fingers so not quite maximums:

Event: time 1532361620.610154, -------------- SYN_REPORT ------------
Event: time 1532361620.620811, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 789
Event: time 1532361620.620811, type 3 (EV_ABS), code 1 (ABS_Y), value 789
Event: time 1532361620.620811, -------------- SYN_REPORT ------------
Event: time 1532361620.642078, type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 470
Event: time 1532361620.642078, type 3 (EV_ABS), code 0 (ABS_X), value 470


Also I have just tested with rotating the display to portrait mode, changes to config.txt:


Now the X and Y touchscreen values are incorrectly swapped and still with incorrect dimensions. Also the Y axis (which should be the X axis) in inverted with 0 on the right.


See: Hyperpixel 4.0 - Multi touch?

The only fix for this at the moment that I’m aware of is to rescale the touch coordinates in software which is what I do in the Python library:

It’s a crude fix, but most of the options available for configuring the driver have no effect and the ones that do don’t have the one we need.


Thanks for the info.

I’m beginning to go off this driver :)


Hi Again,

So I built the driver and added some debug code in to see what is going on.

The issue seems to be a step lower at the firmware level of the touchscreen.

Have you guys at pimoroni written a new firmware to them or do they have the factory firmware?




They are using the factory firmware- bear in mind that they are technically 480x800 pixel resolution portrait touchscreens. (although that doesn’t explain why the touch input is so weird). X seems to have no trouble making sense of the data, though.

I haven’t delved into the inner workings at all since we chose this part for its upstreamed linux support to avoid another creaky Python input driver.

Looking at the driver source and random google search results suggests the touch IC supports configuration data in volatile RAM that might affect how it reports touch information. Is this the “firmware” you refer to?

The “official” driver seems to support uploading configs, but I’ve no idea how to generate them: https://github.com/goodix/goodix_gt9xx_public/blob/master/kernel/arch/arm/boot/dts/goodix-gt9xx-i2c.dtsi



Funny I was just looking at the official driver and wondering if I can get it going…

A near enough data sheet for the touchscreen with useful data and not in Chinese is here: http://dl.linux-sunxi.org/touchscreen/GT967%20Datasheet%20English.pdf this one is a 10 touch version, the rest seems the same.

The firmware data is copied to the volatile ram to initialise the registers on power up, currently in this firmware the axis are swapped which I think is why we are seeing the 800 instead of 480.

I have set the register that un-swaps the axis when the driver initialises but it has no effect, so I just wondered if it needed to be set at device power up from the firmware data.

One question you could help me with, have you got the GPIOs for reset and irq connected to the touchscreen or just the i2c? If so could you tell me the GPIO numbers for them please?


Good news.

I managed to write some code to upgrade the firmware and set the X2Y flag to 0.

Amazingly it works, at the hardware level the Narrow axis of the screen is now 480 and the long axis is now 800 :)

I need to test the modified firmware with the original driver, some settings in the config may need to be changed but it is looking good.

If everything works ok we can modify the original driver slightly to check the X2Y flag, if it is set the driver could update the firmware with the correct value. Then all you need to do is package up the new ko file in your installer.


Ok got it all working, including in X.

The driver requires some changes as it is not coded correctly to take notice of the firmware X2Y flag!

I will create a tidy version of the driver for you when I get a bit of time…





You can find the driver source, updated DTS and ko here: https://github.com/AndrewCapon/HyperPixel4TouchScreen/tree/master/driver

There is a new DTS flag “touchscreen-hyperpixel4” including this make the driver update the firmware on the touchscreen if needed and also changes the order of inverting and swapping in the original driver which doesn’t take account of the X2Y flag.




It should be possible to produce a DKMS package, but the best way would be to somehow submit this change upstream to the Raspberry Pi Linux repo and actually make it available in Raspbian proper- that way there are no messy side-loaded kernel modules (which don’t always work). But for the time being a DKMS package for sideloading would work. I learned the hard way with https://github.com/pimoroni/rp_usbdisplay that producing .ko files for installation doesn’t scale well.


Maybe I should change the code to remove references to Hyperpixel and instead make it more generic based around the X2Y flag. That might be more acceptable to the raspberry linux guys.

Is it easy to get changes upstream?


I think they’re relatively open to changes, but I’m not sure how easy/difficult it is for a particular kernel module. I’m also not sure if it should be submitted to raspberrypi/linux or further upstream as it were. It’s not actually something I’ve done before since generally I have to get something working ASAP and the upstreaming process is playing the long game.

Thanks for looking into this by the way- I haven’t had time to try it out myself yet, but it’s great to know that it’s at least possible to get the most out of the touchscreen.


No problem, it was interesting trying to work out why the hell the axis resolution was swapped!

Maybe the best bet is to change it to a totally “new” driver (HyperPixel4.ko) and not to alter the existing goodix driver, not sure really. I will have a think about it.

I want to see if it is possible to increase the resolution of the touchscreen as well so we can get sub-pixel resolution from it, probably not useful for X but useful for what I want to do…


Hi Again,

I have updated the driver, hyper pixel references are now removed.

The following dts params are now supported:


By default with no flags the x2y flag will be set to 0 fixing the issue with the axis resolution being wrong, if you add touchscreen-x2y into the dts it will set it to 1 as the screens are set from the factory.

You can also set the X an Y dimensions you want to use, this enables sub pixel resolution and works fine at 16 times screen resolution:

touchscreen-size-x = <7680>;
touchscreen-size-y = <12800>;

Not much use for X I guess but very useful if you want higher resolution touch input.


Updated again, adding flag:

Sets the refresh rate, range 0-15ms. This is added to the 5ms overhead of the screen giving a range 5-20ms. Default is 5 giving 10ms refresh rate. Setting this higher drastically reduces cpu load but increases lag, setting lower decreases lag and increases cpu load.


I’m happy to help package this up with dkms and get it installable by the masses, working with your fork as the basis so credit is given where credit is due. It should be straight forward enough, although dkms packages can be a hassle for beginners ( huge kernel header install required)



I think I have approved your changes, best to check though!

I am fully happy for you to move this into your repository though, no need for any credit.


I don’t mind it being separate, although I may link to our fork just so I know what state it’s in. For the time being I’ll continue using the existing “goodix” display driver as the default for HyperPixel users since it wont require the install of dmks and kernel headers, but this is a great alternative if people need a little more flexibility.

Works a treat in all orientations with my python-multitouch UI/touch toolkit.


Good news that it is working for you as well :)

Did you try out touchscreen-refresh-rate to limit the cpu hit?