PINE64
OpenBSD: GPIO with the I2C device PCF8574(A) - Printable Version

+- PINE64 (https://forum.pine64.org)
+-- Forum: ROCK64 (https://forum.pine64.org/forumdisplay.php?fid=85)
+--- Forum: BSD on Rock64 (https://forum.pine64.org/forumdisplay.php?fid=106)
+--- Thread: OpenBSD: GPIO with the I2C device PCF8574(A) (/showthread.php?tid=6377)



OpenBSD: GPIO with the I2C device PCF8574(A) - krjdev - 08-09-2018

Currently the ROCK64 GPIO cannot used in userland. (I currently working on it.)

So I have written a driver for the good old PCF8574 from NXP.
You can find the driver on my Github page:

Additional drivers for OpenBSD

To use the PCF8574, add this to the device trees (Example):

Code:
/dts-v1/;
/include/ "rk3328-rock64.dts"

&i2c0 {
   status = "okay";

   pcf8574: gpio@20 {
       compatible = "nxp,pcf8574";
       status = "okay";
       reg = <0x20>;
       #gpio-cells = <2>;
       gpio-controller;
   };
};

Configuration of the Kernel (add the following):

Code:
pcfgpio*    at iic?
gpio*       at pcfgpio?

Compile the kernel.

dmesg output from my driver:

Code:
pcfgpio0 at iic0 addr 0x20
gpio0 at pcfgpio0: 8 pins



Use the driver with gpioctl:

Code:
$ gpioctl /dev/gpio0 0 on
Turns pin 0 to on.



Use the driver with ioctls (simple running light example):

Code:
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/gpio.h>
#include <sys/ioctl.h>

int main(int argc, char *argv[])
{
   int i, fd;
   int ret;
   struct gpio_info ginfo;
   struct gpio_pin_op gop;
   
   if (argc < 2) {
       printf("usage: gpio [DEV]\n");
       return 1;
   }

   fd = open(argv[1], O_RDWR);

   if (fd == -1) {
       printf("error: couldn't open file (%s)\n", strerror(errno));
       return 1;
   }

   ret = ioctl(fd, GPIOINFO, &ginfo);

   if (ret == -1) {
       printf("error: ioctl GPIOINFO failed (%s)\n", strerror(errno));
       close(fd);
       return 1;
   }

   printf("gpio: Number of pins: %d\n", ginfo.gpio_npins);

   while (1) {
       for (i = 0; i < ginfo.gpio_npins; i++) {
           gop.gp_pin = i;
           gop.gp_value = GPIO_PIN_HIGH;
           ret = ioctl(fd, GPIOPINWRITE, &gop);

           if (ret == -1) {
               printf("error: ioctl GPIOPINWRITE failed (%s)\n", strerror(errno));
               close(fd);
               return 1;
           }

           sleep(1);
           gop.gp_value = GPIO_PIN_LOW;
           ret = ioctl(fd, GPIOPINWRITE, &gop);

           if (ret == -1) {
               printf("error: ioctl GPIOPINWRITE failed (%s)\n", strerror(errno));
               close(fd);
               return 1;
           }
       }
   }

   close(fd);
   return 0;
}