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)"