^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * GPIO controller in LSI ZEVIO SoCs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Author: Fabian Vogt <fabian@ritter-vogt.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/of_gpio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/gpio/driver.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * Memory layout:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * This chip has four gpio sections, each controls 8 GPIOs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * Bit 0 in section 0 is GPIO 0, bit 2 in section 1 is GPIO 10.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * Disclaimer: Reverse engineered!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * For more information refer to:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * http://hackspire.unsads.com/wiki/index.php/Memory-mapped_I/O_ports#90000000_-_General_Purpose_I.2FO_.28GPIO.29
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * 0x00-0x3F: Section 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * +0x00: Masked interrupt status (read-only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * +0x04: R: Interrupt status W: Reset interrupt status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * +0x08: R: Interrupt mask W: Mask interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * +0x0C: W: Unmask interrupt (write-only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * +0x10: Direction: I/O=1/0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * +0x14: Output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * +0x18: Input (read-only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * +0x20: R: Level interrupt W: Set as level interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * 0x40-0x7F: Section 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * 0x80-0xBF: Section 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * 0xC0-0xFF: Section 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define ZEVIO_GPIO_SECTION_SIZE 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) /* Offsets to various registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define ZEVIO_GPIO_INT_MASKED_STATUS 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define ZEVIO_GPIO_INT_STATUS 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define ZEVIO_GPIO_INT_UNMASK 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define ZEVIO_GPIO_INT_MASK 0x0C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define ZEVIO_GPIO_DIRECTION 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define ZEVIO_GPIO_OUTPUT 0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define ZEVIO_GPIO_INPUT 0x18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define ZEVIO_GPIO_INT_STICKY 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) /* Bit number of GPIO in its section */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define ZEVIO_GPIO_BIT(gpio) (gpio&7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) struct zevio_gpio {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) struct of_mm_gpio_chip chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) static inline u32 zevio_gpio_port_get(struct zevio_gpio *c, unsigned pin,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) unsigned port_offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) unsigned section_offset = ((pin >> 3) & 3)*ZEVIO_GPIO_SECTION_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) return readl(IOMEM(c->chip.regs + section_offset + port_offset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) static inline void zevio_gpio_port_set(struct zevio_gpio *c, unsigned pin,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) unsigned port_offset, u32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) unsigned section_offset = ((pin >> 3) & 3)*ZEVIO_GPIO_SECTION_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) writel(val, IOMEM(c->chip.regs + section_offset + port_offset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) /* Functions for struct gpio_chip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) static int zevio_gpio_get(struct gpio_chip *chip, unsigned pin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) struct zevio_gpio *controller = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) u32 val, dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) spin_lock(&controller->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) dir = zevio_gpio_port_get(controller, pin, ZEVIO_GPIO_DIRECTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) if (dir & BIT(ZEVIO_GPIO_BIT(pin)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) val = zevio_gpio_port_get(controller, pin, ZEVIO_GPIO_INPUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) val = zevio_gpio_port_get(controller, pin, ZEVIO_GPIO_OUTPUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) spin_unlock(&controller->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) return (val >> ZEVIO_GPIO_BIT(pin)) & 0x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) static void zevio_gpio_set(struct gpio_chip *chip, unsigned pin, int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) struct zevio_gpio *controller = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) spin_lock(&controller->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) val = zevio_gpio_port_get(controller, pin, ZEVIO_GPIO_OUTPUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) if (value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) val |= BIT(ZEVIO_GPIO_BIT(pin));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) val &= ~BIT(ZEVIO_GPIO_BIT(pin));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) zevio_gpio_port_set(controller, pin, ZEVIO_GPIO_OUTPUT, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) spin_unlock(&controller->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static int zevio_gpio_direction_input(struct gpio_chip *chip, unsigned pin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) struct zevio_gpio *controller = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) spin_lock(&controller->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) val = zevio_gpio_port_get(controller, pin, ZEVIO_GPIO_DIRECTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) val |= BIT(ZEVIO_GPIO_BIT(pin));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) zevio_gpio_port_set(controller, pin, ZEVIO_GPIO_DIRECTION, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) spin_unlock(&controller->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) static int zevio_gpio_direction_output(struct gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) unsigned pin, int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) struct zevio_gpio *controller = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) spin_lock(&controller->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) val = zevio_gpio_port_get(controller, pin, ZEVIO_GPIO_OUTPUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) if (value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) val |= BIT(ZEVIO_GPIO_BIT(pin));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) val &= ~BIT(ZEVIO_GPIO_BIT(pin));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) zevio_gpio_port_set(controller, pin, ZEVIO_GPIO_OUTPUT, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) val = zevio_gpio_port_get(controller, pin, ZEVIO_GPIO_DIRECTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) val &= ~BIT(ZEVIO_GPIO_BIT(pin));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) zevio_gpio_port_set(controller, pin, ZEVIO_GPIO_DIRECTION, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) spin_unlock(&controller->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) static int zevio_gpio_to_irq(struct gpio_chip *chip, unsigned pin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) * TODO: Implement IRQs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) * Not implemented yet due to weird lockups
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) static const struct gpio_chip zevio_gpio_chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) .direction_input = zevio_gpio_direction_input,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) .direction_output = zevio_gpio_direction_output,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) .set = zevio_gpio_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) .get = zevio_gpio_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) .to_irq = zevio_gpio_to_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) .base = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) .ngpio = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) .of_gpio_n_cells = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) /* Initialization */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) static int zevio_gpio_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) struct zevio_gpio *controller;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) int status, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) controller = devm_kzalloc(&pdev->dev, sizeof(*controller), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) if (!controller)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) platform_set_drvdata(pdev, controller);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) /* Copy our reference */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) controller->chip.gc = zevio_gpio_chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) controller->chip.gc.parent = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) status = of_mm_gpiochip_add_data(pdev->dev.of_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) &(controller->chip),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) controller);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) dev_err(&pdev->dev, "failed to add gpiochip: %d\n", status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) spin_lock_init(&controller->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) /* Disable interrupts, they only cause errors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) for (i = 0; i < controller->chip.gc.ngpio; i += 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) zevio_gpio_port_set(controller, i, ZEVIO_GPIO_INT_MASK, 0xFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) dev_dbg(controller->chip.gc.parent, "ZEVIO GPIO controller set up!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) static const struct of_device_id zevio_gpio_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) { .compatible = "lsi,zevio-gpio", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) static struct platform_driver zevio_gpio_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) .name = "gpio-zevio",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) .of_match_table = zevio_gpio_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) .suppress_bind_attrs = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) .probe = zevio_gpio_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) builtin_platform_driver(zevio_gpio_driver);