Jump to content
Ulysse31

PS2 Protocol in General and Cypress VoodooPS2 kext story

7 posts in this topic

Recommended Posts

Hello to all,
 
I'm opening this new topic in order to make some documentation about the cypress trackpad kext I made and about the cypress PS2 protocol itself.
This will help people understand my code and also help them if they want to customize it or just understand it a little bit more.

It might also help other devs that would like to implement other trackpads ^^, i really think that any C/C++ coder that have an unsupported trackpad can nowadays create a driver for it "easily" (of course some hard work and research to do, but doable ^^' ), i never coded a kext and never coded on PS2 protocol before this first one.

Will try to update this topic each time something revelant comes to my mind.

 

here is some good links to know how "standard" protocol works :

 

http://www.computer-engineering.org/ps2mouse/

http://www.win.tue.nl/~aeb/linux/kbd/scancodes-13.html
 

 

Cypress Protocol Part:
First lets speak about the cypress protocol: searching on the net, reading linux driver source code and asking some infos to cypress gave me some knowledge on how protocol works :

- like any other PS2 mouse, the cypress one uses standard values for configuring rates/resolution/data mode.

- the only difference to set the trackpad from "standard" protocol to "cypress" packet reporting seems only to rely on the firmware asking. sending the right byte to ask the firmware and then reading the bytes like in linux allowed to "activate" the cypress mode packet reporting.

- so firstly, i re-implemented the same functions present in linux source code for init. (well almost the same, some implicit configuration is done by some linux syscalls).
- once configured properly : init sequence similar to linux one (ask the trackpad its firmware, set rate and res. this can be seen on the function setTouchpadModeByte on my sourcecode), I just send one byte to set data reporting on (0xF4: meaning that from that moment, the mouse will automatically send packets for each events happening on the pad).
 
From there, trackpad will flood the host system with the following :
- each packet is composed of 5 or 8 bytes, depending on the header byte (first one)
- on the contrary of other trackpads (like ALPS or Synaptics), THERE IS NO ACCURATE way (no way to be 100% sure) to determine if a byte is a header byte or not : there is no bit sequence to determine that a byte is header or a byte squence separator between packets to tell that new packet is coming
- The only way to deal with this is to count correctly each received bytes. and try to "validate" a possible header byte by checking consistency (example: if tap bit is on, left or right bit should be on, etc ...)
- And in case of invalid header byte,  empty actual buffer and ask trackpad a resend of last packet (send 0xFE).
- the parsing of the packet content was also given by re-implementing the cypress linux source code.

- for now, have found 2 scenarios in that the trackpad sends 8 bytes packet instead of 5 : on init, and when two fingers are on the trackpad (sending 2 distinct coordinates).

- for 1/3/4/5 fingers, it only sends 5 bytes : specifying on the header the number of fingers but followed only with one finger coordinate.

- so, for a single move on the pad, the trackpad, floods the host with packets containing coordinates.

- once finger/s leave the pad, 500 null bytes (if none is lost) is sent to the host. (don't ask me why)

 

Source code implementation part:

So why have i based my code on VoodooPS2Controller, and more exactly on rehabman's one ?

Because it is a already existing kext that uses and implements ApplePS2Controller (which allows PS2 init/send/receive), and also because it is clean and easy to add new hardware implementation : just added 2 new files at beginning (VoodooPS2CypressTouchPad.cpp and VoodooPS2CypressTouchPad.h) with new class and object instanciation base on the already present classes.

Then implemented cypress init/protocol handling on it.

One thing I have done to manage correctly mouse movement is storing infos about "frames" : each finger move on the trackpad is considered as a packet frame, I store the timer when the frame begins and count packets, if fingers leave pad i clear the counters, if a change on the number of fingers appears (new fingers/removed fingers) I consider it as a new frame.

 

For now that is the only infos that comes to my mind, if somes are working on a PS2 driver, or have questions regarding my code, don't hesitate, ask it here, i will answer and update this post if revelant.

 

Hope that it would help other PS2 devs beginners.

 

 

--

Ulysse31

Share this post


Link to post
Share on other sites
Advertisement

Hi,

I know I am digging up an old thread, but I am currently trying to port the focaltech protocol from linux to VoodooPS2 and have a few questions.

I understand that I have to create a IOHIPointing class which will contain much of the linux protocol. However, I cannot figure out what to do with all the pmouse->private calls from the linux methods.

Could someone who already work on such a port explain me how to replace them ?

Share this post


Link to post
Share on other sites

Hi,

 

From what i remember (and briefly checked on cypress linux source 5 min ago ^^) the "pmouse->private" is a kernel pointer where the driver should store its data.

To explain it differently, it is used by the linux driver to keep a pointer to where it "stores" its stuff to have its "data between calls" (at least its this way that ->private is used in cypress linux driver).

You should keep in mind that linux kernel and drivers are written in C, on the other hand, osx kernel and drivers are written in C++, under osx you should just use your private data on your class to store whatever infos you want/need.

 

Hope that I've been helpful ^^.

If you have questions, go ahead.

 

 

Cheers,

 

 

--

Ulysse31

Share this post


Link to post
Share on other sites

Thanks !

I knew it would not be that easy to port this driver, but comparing this :

static int cypress_ps2_sendbyte(struct psmouse *psmouse, int value)
{
	struct ps2dev *ps2dev = &psmouse->ps2dev;

	if (ps2_sendbyte(ps2dev, value & 0xff, CYTP_CMD_TIMEOUT) < 0) {
		psmouse_dbg(psmouse,
				"sending command 0x%02x failed, resp 0x%02x\n",
				value & 0xff, ps2dev->nak);
		if (ps2dev->nak == CYTP_PS2_RETRY)
			return CYTP_PS2_RETRY;
		else
			return CYTP_PS2_ERROR;
	}

#ifdef CYTP_DEBUG_VERBOSE
	psmouse_dbg(psmouse, "sending command 0x%02x succeeded, resp 0xfa\n",
			value & 0xff);
#endif

	return 0;
}

to that :

 

UInt8 ApplePS2CypressTouchPad::cypressSendByte(UInt8 cmd)
{
  TPS2Request<1> request;


  request.commands[0].command  = kPS2C_SendMouseCommandAndCompareAck;
  request.commands[0].inOrOut  = cmd & 0xFF;  // & 0xFF is useless but here to hint/guess from where it comes from ^^'


  request.commandsCount = 1;
  assert(request.commandsCount <= countof(request.commands));
  _device->submitRequestAndBlock(&request);


  if (request.commandsCount != 1)
    {
      DEBUG_LOG("CYPRESS: cypressSendByte: RETRY\n");
      return (CYTP_PS2_RETRY);
    }
  return (0);
}

 

make me realize I have a lot to learn...

 

Anyway, I will go step by step until this work.

Share this post


Link to post
Share on other sites

Thanks !

 

I knew it would not be that easy to port this driver, but comparing this :

static int cypress_ps2_sendbyte(struct psmouse *psmouse, int value)
{
	struct ps2dev *ps2dev = &psmouse->ps2dev;

	if (ps2_sendbyte(ps2dev, value & 0xff, CYTP_CMD_TIMEOUT) < 0) {
		psmouse_dbg(psmouse,
				"sending command 0x%02x failed, resp 0x%02x\n",
				value & 0xff, ps2dev->nak);
		if (ps2dev->nak == CYTP_PS2_RETRY)
			return CYTP_PS2_RETRY;
		else
			return CYTP_PS2_ERROR;
	}

#ifdef CYTP_DEBUG_VERBOSE
	psmouse_dbg(psmouse, "sending command 0x%02x succeeded, resp 0xfa\n",
			value & 0xff);
#endif

	return 0;
}

to that :

 

UInt8 ApplePS2CypressTouchPad::cypressSendByte(UInt8 cmd)
{
  TPS2Request<1> request;


  request.commands[0].command  = kPS2C_SendMouseCommandAndCompareAck;
  request.commands[0].inOrOut  = cmd & 0xFF;  // & 0xFF is useless but here to hint/guess from where it comes from ^^'


  request.commandsCount = 1;
  assert(request.commandsCount <= countof(request.commands));
  _device->submitRequestAndBlock(&request);


  if (request.commandsCount != 1)
    {
      DEBUG_LOG("CYPRESS: cypressSendByte: RETRY\n");
      return (CYTP_PS2_RETRY);
    }
  return (0);
}

 

make me realize I have a lot to learn...

 

Anyway, I will go step by step until this work.

 

 

Keep in mind that porting a driver is never copy/paste code ^^

Just go step by step as you said.

here some global steps :

1 - read the linux code, do not start from beginning of file but from first call, and follow the calling process. will help understand what it does and how it communicates with the ps2 device.

2 - read a basic osx ps2 driver code, try to find similarities and understand how you make similar actions you've noticed in linux under osx ps2 code.

3 - then here you can start coding/hacking some code ^^.

 

 

Cheers.

Share this post


Link to post
Share on other sites

Thanks !

 

I knew it would not be that easy to port this driver, but comparing this :

static int cypress_ps2_sendbyte(struct psmouse *psmouse, int value)
{
	struct ps2dev *ps2dev = &psmouse->ps2dev;

	if (ps2_sendbyte(ps2dev, value & 0xff, CYTP_CMD_TIMEOUT) < 0) {
		psmouse_dbg(psmouse,
				"sending command 0x%02x failed, resp 0x%02x\n",
				value & 0xff, ps2dev->nak);
		if (ps2dev->nak == CYTP_PS2_RETRY)
			return CYTP_PS2_RETRY;
		else
			return CYTP_PS2_ERROR;
	}

#ifdef CYTP_DEBUG_VERBOSE
	psmouse_dbg(psmouse, "sending command 0x%02x succeeded, resp 0xfa\n",
			value & 0xff);
#endif

	return 0;
}

to that :

 

UInt8 ApplePS2CypressTouchPad::cypressSendByte(UInt8 cmd)
{
  TPS2Request<1> request;


  request.commands[0].command  = kPS2C_SendMouseCommandAndCompareAck;
  request.commands[0].inOrOut  = cmd & 0xFF;  // & 0xFF is useless but here to hint/guess from where it comes from ^^'


  request.commandsCount = 1;
  assert(request.commandsCount <= countof(request.commands));
  _device->submitRequestAndBlock(&request);


  if (request.commandsCount != 1)
    {
      DEBUG_LOG("CYPRESS: cypressSendByte: RETRY\n");
      return (CYTP_PS2_RETRY);
    }
  return (0);
}

 

make me realize I have a lot to learn...

 

Anyway, I will go step by step until this work.

 

Hello procrastination, have you had any luck with porting the protocol for Focaltech touchpads?

 

I was just thinking of getting to it myself, so maybe you can give me some insight into which problems you encountered?

Thanks

Share this post


Link to post
Share on other sites

Well, to tell you the truth I haven't had much time to spend on this since then. The only thing I could tell you is to compare both voodoops2controller .h files and linux input ps2 files to identify corresponding ps2 codes... I will get back to this as soon as possible, but I cannot promise anything right now.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By M3G4DR01D
      Hello everyone, I have an Asus gl502vmk (i7 kabylake + GTX 1060 6 gb) laptop and I tried all the patches/kexts to get the brightness with fn keys/touchpad (I2C ELAN 1200 works with VooDoo I2C kext v1.0 but no gestures/preference pane)/Keyboard backlight to work but no success so far, any help would be appreciated, thanks in advance.
      [EDIT] (10/04/2018)
      Battery status now works, thanks to @RehabMan turned out to be incorrect SMBIOS (used iMac instead of Mbp) lol, but it drains crazy fast (~1.5 - 2 hours while on standby (all apps quited!), on windows 10 it lasts 4 - 5 hours, and on linux it lasts 6 ~ 7 hours!)
      And with VoodooI2C v2.0.1 + VoodooI2CHID kext and patched DSDT, the touchpad is now detected in the sys pref pane but still no input.
      Sound works with VoodooHDA v2.9.1, but the only issue is that the jack sense isn't working (the output device doesn't auto switch to headphone when connected)
       
      [EDIT 2] (11/04/2018)
      The system brightness now works thanks to @onejay09 but I have no brightness slider, and there are 4 extra brightness levels (brightness stops increasing after 12 levels)  and the brightness keys are not mapped correctly, plus the brightness decreases when I plug in the ac adapter, then increases if I unplug it???, the brightness level isn't also saved after reboot.
      battery still drains crazy fast (~1.5 - 2 hours, even with brightness at 50%, so apparently it is a power management issue).
      and I also have shutdowns while in sleep mode (I tried darkwake=10 and darkwake-0 and darkwake=no)
       
      P.S. I have uploaded my new report files, thanks!
       
      Latest report files (11/04/2018): https://www95.zippyshare.com/v/AMOpP0AY/file.html
    • By Atasher
      Hey guys,
       
      I am fairly new to the scene and recently successfuly installed El Capitan 10.11 on the Asus K501UX
       
      The specs are: Core i7-6500u, 8GB RAM, GTX 950M (DISABLED), HD520
       
      Everything seems to be in good working order thanks to Ludwig Bartholomew for guiding me and helping me through the process.
       
      But, I keep recieving a Kernel Panic everytime I have the VoodooI2C kext installed for the trackpad to function. If I remove it everything works fine except for the trackpad which is the issue.
       
      Note: I also removed all of the LPSS kext files from the S/L/E to no avail.
       
      Any help would be greatly appreciated.
       
      Thanks in advance.

    • By jonny789
      I have Acer Aspire E5-572G [having Core i5-4210M and NVIDIA Geforce 940M 2GB ] and installed Sierra 10.12.2.
      I have got intelgraphics , brightness ,audio (ALC 283) and wifi (atheros ar956x) working by following guides on this site.
       
      But, Trackpad is not working, only keyboard is working after I have installed VoodooPS2Controller.kext . (I think trackpad is synaptics as I install synaptics driver on windows. )
      webcam is not working too ( when I open FaceTime , it shows no camera found)
      I have installed Nvidia web drivers but I think card is not being detected.
      Battery is draining very fast.
       
      Plz guide me how to resolve above issues and what else do I need to do (applying patches or other tweaks etc) to get a fully working Mac.
       
      Thanks.
    • By PumpkenPie
      Hello
       
      Recently I have installed macOS Sierra on my HP dv6-2105ea. It is well optimised and everything except for the:
       
      >Wi-fi
      Broadcom Wireless LAN
      >Sound
      IDT High Definition Audio CODEC
      >Trackpad / Keyboard
      Synaptics
       
      Laptop drivers:
      http://support.hp.com/gb-en/drivers/selfservice/hp-pavilion-dv6-2100-entertainment-notebook-pc-series/4041735/model/4105236
      More info about laptop
      http://www.insanelymac.com/forum/topic/316902-stuck-on-system-uptime-in-nanoseconds-booting-to-installation/?p=2301138&do=findComment&comment=2301138
    • By shoopy
      The only kext being injected in Clover is FakeSMC.kext yet somehow VoodooPS2Controller.kext is running when I boot with clover and kexts from S/L/E are being disabled. For instance, my battery and hardware sensors kexts are disabled when I load from Clover but work when booting from Chameleon. I have checked every folder, there are no Voodoo kexts, is there a driver or something injecting Voodoo kexts in Clover, the only changes I've made is in the config file?
       
      When I boot with Chameleon all of my kexts from S/L/E are working fine and VoodooPS2Controller doesn't load (as it should).
       
      Can anyone help me figure out what's wrong? I have an Asus UX303LN and these are my specs along with my config file.
       
      i5 4210u 1TB HDD Intel HD 4400 nVidia 840m [disabled in Clover] FocalTech Touchpad config.zip
×