programmer: Add bitbanging programmer driver for Linux libgpiod

With this driver, any single board computer, old smartphone, etc. with
a few spare GPIOs can be used for flashrom.

Tested by reading of a 2048 kB flash chip on a Qualcomm MSM8916 SoC
@800 MHz, ran the following command:

time flashrom -p linux_gpiod:gpiochip=0,cs=18,sck=19,mosi=13,miso=56 -r test.bin

This command uses /dev/gpiochip0 with the specified GPIO numbers for the
SPI lines. All arguments are mandatory.

Output:
[...]
Found GigaDevice flash chip "GD25LQ16" (2048 kB, SPI) on linux_gpiod.
[...]
real    1m 33.96s

Change-Id: Icad3eb7764f28feaea51bda3a7893da724c86d06
Signed-off-by: Steve Markgraf <steve@steve-m.de>
Signed-off-by: Nico Huber <nico.h@gmx.de>
Reviewed-on: https://review.coreboot.org/c/flashrom-stable/+/73290
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
diff --git a/Makefile b/Makefile
index bcf795b..5db5e03 100644
--- a/Makefile
+++ b/Makefile
@@ -104,6 +104,7 @@
 DEPENDS_ON_BITBANG_SPI := \
 	CONFIG_DEVELOPERBOX_SPI \
 	CONFIG_INTERNAL_X86 \
+	CONFIG_LINUX_GPIOD \
 	CONFIG_NICINTEL_SPI \
 	CONFIG_OGP_SPI \
 	CONFIG_PONY_SPI \
@@ -177,6 +178,9 @@
 DEPENDS_ON_LINUX_I2C := \
 	CONFIG_MSTARDDC_SPI \
 
+DEPENDS_ON_LIBGPIOD := \
+	CONFIG_LINUX_GPIOD \
+
 ifeq ($(CONFIG_ENABLE_LIBUSB1_PROGRAMMERS), no)
 $(call disable_all,$(DEPENDS_ON_LIBUSB1))
 endif
@@ -231,6 +235,10 @@
 CONFIG_LIBPCI_CFLAGS       := $(call dependency_cflags, libpci)
 CONFIG_LIBPCI_LDFLAGS      := $(call dependency_ldflags, libpci)
 
+CONFIG_LIBGPIOD_VERSION      := $(call dependency_version, libgpiod)
+CONFIG_LIBGPIOD_CFLAGS       := $(call dependency_cflags, libgpiod)
+CONFIG_LIBGPIOD_LDFLAGS      := $(call dependency_ldflags, libgpiod)
+
 # Determine the destination OS, architecture and endian
 # IMPORTANT: The following lines must be placed before TARGET_OS, ARCH or ENDIAN
 # is ever used (of course), but should come after any lines setting CC because
@@ -245,6 +253,7 @@
 HAS_LIBJAYLINK      := $(call find_dependency, libjaylink)
 HAS_LIBUSB1         := $(call find_dependency, libusb-1.0)
 HAS_LIBPCI          := $(call find_dependency, libpci)
+HAS_LIBGPIOD        := $(call find_dependency, libgpiod)
 
 HAS_PCI_OLD_GET_DEV := $(call c_compile_test, Makefile.d/pci_old_get_dev_test.c, $(CONFIG_LIBPCI_CFLAGS))
 HAS_FT232H          := $(call c_compile_test, Makefile.d/ft232h_test.c, $(CONFIG_LIBFTDI1_CFLAGS))
@@ -351,6 +360,10 @@
 $(call mark_unsupported,$(DEPENDS_ON_LIBUSB1))
 endif
 
+ifeq ($(HAS_LIBGPIOD), no)
+$(call mark_unsupported,$(DEPENDS_ON_LIBGPIOD))
+endif
+
 ifeq ($(HAS_SERIAL), no)
 $(call mark_unsupported, $(DEPENDS_ON_SERIAL))
 endif
@@ -497,9 +510,10 @@
 # Always enable Marvell SATA controllers for now.
 CONFIG_SATAMV ?= yes
 
-# Enable Linux spidev and MTD interfaces by default. We disable them on non-Linux targets.
+# Enable Linux spidev, MTD and gpiod interfaces by default. We disable them on non-Linux targets.
 CONFIG_LINUX_MTD ?= yes
 CONFIG_LINUX_SPI ?= yes
+CONFIG_LINUX_GPIOD ?= yes
 
 # Always enable ITE IT8212F PATA controllers for now.
 CONFIG_IT8212 ?= yes
@@ -731,6 +745,11 @@
 PROGRAMMER_OBJS += linux_spi.o
 endif
 
+ifeq ($(CONFIG_LINUX_GPIOD), yes)
+FEATURE_FLAGS += -D'CONFIG_LINUX_GPIOD=1'
+PROGRAMMER_OBJS += linux_gpio_spi.o
+endif
+
 ifeq ($(CONFIG_MSTARDDC_SPI), yes)
 FEATURE_FLAGS += -D'CONFIG_MSTARDDC_SPI=1'
 PROGRAMMER_OBJS += mstarddc_spi.o
@@ -839,6 +858,12 @@
 endif
 endif
 
+USE_LIBGPIOD := $(if $(call filter_deps,$(DEPENDS_ON_LIBGPIOD)),yes,no)
+ifeq ($(USE_LIBGPIOD), yes)
+override CFLAGS  += $(CONFIG_LIBGPIOD_CFLAGS)
+override LDFLAGS += $(CONFIG_LIBGPIOD_LDFLAGS)
+endif
+
 USE_LIB_NI845X := $(if $(call filter_deps,$(DEPENDS_ON_LIB_NI845X)),yes,no)
 ifeq ($(USE_LIB_NI845X), yes)
 override CFLAGS += $(CONFIG_LIB_NI845X_CFLAGS)
@@ -917,6 +942,11 @@
 		echo "  CFLAGS: $(CONFIG_LIBFTDI1_CFLAGS)";	\
 		echo "  LDFLAGS: $(CONFIG_LIBFTDI1_LDFLAGS)";	\
 	fi
+	@echo Dependency libgpiod found: $(HAS_LIBGPIOD) $(CONFIG_LIBGPIOD_VERSION)
+	@if [ $(HAS_LIBGPIOD) = yes ]; then			\
+		echo "  CFLAGS: $(CONFIG_LIBGPIOD_CFLAGS)";	\
+		echo "  LDFLAGS: $(CONFIG_LIBGPIOD_LDFLAGS)";	\
+	fi
 	@echo "Checking for header \"mtd/mtd-user.h\": $(HAS_LINUX_MTD)"
 	@echo "Checking for header \"linux/spi/spidev.h\": $(HAS_LINUX_SPI)"
 	@echo "Checking for header \"linux/i2c-dev.h\": $(HAS_LINUX_I2C)"