^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Raspberry Pi 3 expander GPIO driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Uses the firmware mailbox service to communicate with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * GPIO expander on the VPU.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (C) 2017 Raspberry Pi Trading Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/gpio/driver.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <soc/bcm2835/raspberrypi-firmware.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #define MODULE_NAME "raspberrypi-exp-gpio"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define NUM_GPIO 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define RPI_EXP_GPIO_BASE 128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define RPI_EXP_GPIO_DIR_IN 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define RPI_EXP_GPIO_DIR_OUT 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) struct rpi_exp_gpio {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) struct gpio_chip gc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) struct rpi_firmware *fw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) /* VC4 firmware mailbox interface data structures */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) struct gpio_set_config {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) u32 gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) u32 direction;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) u32 polarity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) u32 term_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) u32 term_pull_up;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) u32 state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) struct gpio_get_config {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) u32 gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) u32 direction;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) u32 polarity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) u32 term_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) u32 term_pull_up;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) struct gpio_get_set_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) u32 gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) u32 state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) static int rpi_exp_gpio_get_polarity(struct gpio_chip *gc, unsigned int off)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) struct rpi_exp_gpio *gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) struct gpio_get_config get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) gpio = gpiochip_get_data(gc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) get.gpio = off + RPI_EXP_GPIO_BASE; /* GPIO to update */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_GET_GPIO_CONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) &get, sizeof(get));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) if (ret || get.gpio != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) dev_err(gc->parent, "Failed to get GPIO %u config (%d %x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) off, ret, get.gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) return ret ? ret : -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) return get.polarity;
^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) static int rpi_exp_gpio_dir_in(struct gpio_chip *gc, unsigned int off)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) struct rpi_exp_gpio *gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) struct gpio_set_config set_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) gpio = gpiochip_get_data(gc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) set_in.gpio = off + RPI_EXP_GPIO_BASE; /* GPIO to update */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) set_in.direction = RPI_EXP_GPIO_DIR_IN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) set_in.term_en = 0; /* termination disabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) set_in.term_pull_up = 0; /* n/a as termination disabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) set_in.state = 0; /* n/a as configured as an input */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) ret = rpi_exp_gpio_get_polarity(gc, off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) set_in.polarity = ret; /* Retain existing setting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_SET_GPIO_CONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) &set_in, sizeof(set_in));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) if (ret || set_in.gpio != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) dev_err(gc->parent, "Failed to set GPIO %u to input (%d %x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) off, ret, set_in.gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) return ret ? ret : -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) static int rpi_exp_gpio_dir_out(struct gpio_chip *gc, unsigned int off, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) struct rpi_exp_gpio *gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) struct gpio_set_config set_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) gpio = gpiochip_get_data(gc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) set_out.gpio = off + RPI_EXP_GPIO_BASE; /* GPIO to update */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) set_out.direction = RPI_EXP_GPIO_DIR_OUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) set_out.term_en = 0; /* n/a as an output */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) set_out.term_pull_up = 0; /* n/a as termination disabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) set_out.state = val; /* Output state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) ret = rpi_exp_gpio_get_polarity(gc, off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) set_out.polarity = ret; /* Retain existing setting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_SET_GPIO_CONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) &set_out, sizeof(set_out));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) if (ret || set_out.gpio != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) dev_err(gc->parent, "Failed to set GPIO %u to output (%d %x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) off, ret, set_out.gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) return ret ? ret : -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) static int rpi_exp_gpio_get_direction(struct gpio_chip *gc, unsigned int off)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) struct rpi_exp_gpio *gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) struct gpio_get_config get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) gpio = gpiochip_get_data(gc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) get.gpio = off + RPI_EXP_GPIO_BASE; /* GPIO to update */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_GET_GPIO_CONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) &get, sizeof(get));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) if (ret || get.gpio != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) dev_err(gc->parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) "Failed to get GPIO %u config (%d %x)\n", off, ret,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) get.gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) return ret ? ret : -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) if (get.direction)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) return GPIO_LINE_DIRECTION_OUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) return GPIO_LINE_DIRECTION_IN;
^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 int rpi_exp_gpio_get(struct gpio_chip *gc, unsigned int off)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) struct rpi_exp_gpio *gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) struct gpio_get_set_state get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) gpio = gpiochip_get_data(gc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) get.gpio = off + RPI_EXP_GPIO_BASE; /* GPIO to update */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) get.state = 0; /* storage for returned value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_GET_GPIO_STATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) &get, sizeof(get));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) if (ret || get.gpio != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) dev_err(gc->parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) "Failed to get GPIO %u state (%d %x)\n", off, ret,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) get.gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) return ret ? ret : -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) return !!get.state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) static void rpi_exp_gpio_set(struct gpio_chip *gc, unsigned int off, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) struct rpi_exp_gpio *gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) struct gpio_get_set_state set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) gpio = gpiochip_get_data(gc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) set.gpio = off + RPI_EXP_GPIO_BASE; /* GPIO to update */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) set.state = val; /* Output state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_SET_GPIO_STATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) &set, sizeof(set));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) if (ret || set.gpio != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) dev_err(gc->parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) "Failed to set GPIO %u state (%d %x)\n", off, ret,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) set.gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) static int rpi_exp_gpio_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) struct device_node *np = dev->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) struct device_node *fw_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) struct rpi_firmware *fw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) struct rpi_exp_gpio *rpi_gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) fw_node = of_get_parent(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) if (!fw_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) dev_err(dev, "Missing firmware node\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) fw = rpi_firmware_get(fw_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) of_node_put(fw_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) if (!fw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) return -EPROBE_DEFER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) rpi_gpio = devm_kzalloc(dev, sizeof(*rpi_gpio), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) if (!rpi_gpio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) rpi_gpio->fw = fw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) rpi_gpio->gc.parent = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) rpi_gpio->gc.label = MODULE_NAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) rpi_gpio->gc.owner = THIS_MODULE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) rpi_gpio->gc.of_node = np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) rpi_gpio->gc.base = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) rpi_gpio->gc.ngpio = NUM_GPIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) rpi_gpio->gc.direction_input = rpi_exp_gpio_dir_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) rpi_gpio->gc.direction_output = rpi_exp_gpio_dir_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) rpi_gpio->gc.get_direction = rpi_exp_gpio_get_direction;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) rpi_gpio->gc.get = rpi_exp_gpio_get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) rpi_gpio->gc.set = rpi_exp_gpio_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) rpi_gpio->gc.can_sleep = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) return devm_gpiochip_add_data(dev, &rpi_gpio->gc, rpi_gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) static const struct of_device_id rpi_exp_gpio_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) { .compatible = "raspberrypi,firmware-gpio" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) MODULE_DEVICE_TABLE(of, rpi_exp_gpio_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) static struct platform_driver rpi_exp_gpio_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) .name = MODULE_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) .of_match_table = of_match_ptr(rpi_exp_gpio_ids),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) .probe = rpi_exp_gpio_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) module_platform_driver(rpi_exp_gpio_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) MODULE_AUTHOR("Dave Stevenson <dave.stevenson@raspberrypi.org>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) MODULE_DESCRIPTION("Raspberry Pi 3 expander GPIO driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) MODULE_ALIAS("platform:rpi-exp-gpio");