The board 🙂
Today I will explain you how I managed to write my own custom driver for nct5104d under Centos running on PCEngines APU board . But before we go any further wanted to share my “big wow” to the makers of the board. For anyone doing home automation , tinkering around or being just interested in engineering it is something I can completely recommend. It features amongst many cool perks things like 3 Gig ethernet ports , 16(18) GPIO ports , I2C , 2xRS232 ( one with RX,TX only ). For me its 5/5 start rating 🙂
In a place far far away…
… I have started this post some time ago since I thought it would be a great idea to have opportunity of sharing my experience as I go through the whole learning of how to write a Linux driver for nct5104d ( sitting on APU board )
Before I decided to anything crazy like that I would like to let you know that there is already a driver for the device and you can find it https://github.com/tasanakorn/linux-gpio-nct5104d . What made me thinking of writing my version was the way I would need to interoperate with the GPIOs by making some funky commands like :
echo 1 > /sys/class/gpio/gpio0/value
At that moment I knew I can make it easier for my automation purposes 🙂
Writing own driver … where to start ?
So this is good question to ask yourself here. It took me many hours of reading articles/forums but also talking with people that have been doing such things before. From a high level perspective its simple – read basics and then start small with hello world. Once you start understanding it you will have more results.
I could recommend you take a look at the following resources ( which I have found very useful for getting my head around 🙂 )
- http://linuxseekernel.blogspot.nl/search/label/platform%20driver
- https://www.codeproject.com/Tips/1080177/Linux-Platform-Device-Driver
- https://sysplay.in/blog/linux-device-drivers/2013/08/generic-hardware-access-in-linux/
- https://lwn.net/Articles/338837/
- https://lwn.net/Articles/448499/
Step by step ?
In most of my articles we would probably dive into technical details of the challenge. But in this instance I will point you to my github repository and ask to take a look. There has been a big amount of work that I have put into this and if you will have specific questions I will be here to try and answer them!
As just as interesting part – thats how my work looked like though the last 2 weeks ( from start to finish 🙂 )
Where is the code ?
The complete repository is available in my github repo https://github.com/RafPe/gpio-driver-nct5104d
So how does it work ?
Now we are talking 🙂 So using the driver is really nice. Once you go through the steps of compiling it and installing in your system you then have access to device via ioctl.
I have exposed methods for interacting with registries and with pins. However what is important here – the device automatically uses Logical device 7 which is GPIO. If you would have other needs we would most likely need to compile some logic around it.
Since not everyone is guru in creating binaries 🙂 I have created 2 apps which are respectively for management of pins or registries
Managing pins
With simple commands you can manage pins instantly
nct5104dpin [ --get|--set ] [--pin ] --val < 0|1 > --dir <out|in>
Get a pin value: nct5104dpin --pin 7
Get a pin value: nct5104dpin --get --pin 14
Set a pin value: nct5104dpin --set --pin 14 --val 1
Set a pin direction: nct5104dpin --set --pin 14 --dir out
Cool thing is that I have made it in such a way that parsing data with i.e. JQ is just straightforward.
[email protected] > nct5104dpin --pin 1 | jq [ { "pin": 1, "value": 0 } ]
Managing registries
Same apply for managing registers. I have been aiming to keep it simple and specific.
ct5104dreg [ --get|--set ] [--reg ] <HEX> --val <DECIMAL>
Get a reg value: nct5104dreg --reg 0x07
Get a reg value: nct5104dreg --get --reg 0x07
Set a reg value: nct5104dreg --set --reg 0xE0 --val 252
Here I also made sure output can easily be parsed
[email protected] > nct5104dreg --reg 0xE1 | jq [ { "registry": "0xe1", "value": 248 } ]
Adventure begins here
I hope by sharing this I will enable you or maybe someone else to do things that you have not been doing before 🙂 or at least get you interested