diff --git a/ChangeLog b/ChangeLog index 161e66d3..59bf56a6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2021-11-27 Joerg Wunsch + + Submitted by Alex Sverdlin: + patch #10031: linuxspi: Support GPIO uAPI v2 + * linuxspi.c (linuxspi_reset_mcu, linuxspi_open): Since Linux + v5.10 GPIO ABI Version 1 is optional and depends on + CONFIG_GPIO_CDEV_V1. + 2021-11-27 Joerg Wunsch Submitted by Alex Sverdlin: diff --git a/NEWS b/NEWS index e1e20885..a36bba70 100644 --- a/NEWS +++ b/NEWS @@ -121,6 +121,7 @@ Current: patch #10028: linuxspi: close() only when necessary patch #10029: linuxspi: Report GPIO_GET_LINEHANDLE_IOCTL errors patch #10030: linuxspi: Support inverted GPIO pin + patch #10031: linuxspi: Support GPIO uAPI v2 * Internals: - New avrdude.conf keyword "family_id", used to verify SIB attributes diff --git a/linuxspi.c b/linuxspi.c index da2821f2..bbaf820d 100644 --- a/linuxspi.c +++ b/linuxspi.c @@ -109,6 +109,16 @@ static int linuxspi_reset_mcu(PROGRAMMER *pgm, bool active) */ data.values[0] = active ^ !(pgm->pinno[PIN_AVR_RESET] & PIN_INVERSE); ret = ioctl(fd_linehandle, GPIOHANDLE_SET_LINE_VALUES_IOCTL, &data); +#ifdef GPIO_V2_LINE_SET_VALUES_IOCTL + if (ret == -1) { + struct gpio_v2_line_values val; + + val.mask = 1; + val.bits = active ^ !(pgm->pinno[PIN_AVR_RESET] & PIN_INVERSE); + + ret = ioctl(fd_linehandle, GPIO_V2_LINE_SET_VALUES_IOCTL, &val); + } +#endif if (ret == -1) { ret = -errno; avrdude_message(MSG_INFO, "%s error: Unable to set GPIO line %d value\n", @@ -169,6 +179,27 @@ static int linuxspi_open(PROGRAMMER *pgm, char *port) req.flags = GPIOHANDLE_REQUEST_OUTPUT; ret = ioctl(fd_gpiochip, GPIO_GET_LINEHANDLE_IOCTL, &req); + if (ret != -1) + fd_linehandle = req.fd; +#ifdef GPIO_V2_GET_LINE_IOCTL + if (ret == -1) { + struct gpio_v2_line_request reqv2; + + memset(&reqv2, 0, sizeof(reqv2)); + reqv2.offsets[0] = pgm->pinno[PIN_AVR_RESET] & ~PIN_INVERSE; + strncpy(reqv2.consumer, progname, sizeof(reqv2.consumer) - 1); + reqv2.config.flags = GPIO_V2_LINE_FLAG_OUTPUT; + reqv2.config.num_attrs = 1; + reqv2.config.attrs[0].attr.id = GPIO_V2_LINE_ATTR_ID_OUTPUT_VALUES; + reqv2.config.attrs[0].attr.values = !!(pgm->pinno[PIN_AVR_RESET] & PIN_INVERSE); + reqv2.config.attrs[0].mask = 1; + reqv2.num_lines = 1; + + ret = ioctl(fd_gpiochip, GPIO_V2_GET_LINE_IOCTL, &reqv2); + if (ret != -1) + fd_linehandle = reqv2.fd; + } +#endif if (ret == -1) { ret = -errno; avrdude_message(MSG_INFO, "%s error: Unable to get GPIO line %d\n", @@ -176,8 +207,6 @@ static int linuxspi_open(PROGRAMMER *pgm, char *port) goto close_gpiochip; } - fd_linehandle = req.fd; - ret = linuxspi_reset_mcu(pgm, true); if (ret) goto close_out;