Lines Matching +full:firmware +full:- +full:gpio
1 // SPDX-License-Identifier: GPL-2.0+
3 * Raspberry Pi 3 expander GPIO driver
5 * Uses the firmware mailbox service to communicate with the
6 * GPIO expander on the VPU.
12 #include <linux/gpio/driver.h>
15 #include <soc/bcm2835/raspberrypi-firmware.h>
17 #define MODULE_NAME "raspberrypi-exp-gpio"
30 /* VC4 firmware mailbox interface data structures */
33 u32 gpio; member
42 u32 gpio; member
50 u32 gpio; member
56 struct rpi_exp_gpio *gpio; in rpi_exp_gpio_get_polarity() local
60 gpio = gpiochip_get_data(gc); in rpi_exp_gpio_get_polarity()
62 get.gpio = off + RPI_EXP_GPIO_BASE; /* GPIO to update */ in rpi_exp_gpio_get_polarity()
64 ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_GET_GPIO_CONFIG, in rpi_exp_gpio_get_polarity()
66 if (ret || get.gpio != 0) { in rpi_exp_gpio_get_polarity()
67 dev_err(gc->parent, "Failed to get GPIO %u config (%d %x)\n", in rpi_exp_gpio_get_polarity()
68 off, ret, get.gpio); in rpi_exp_gpio_get_polarity()
69 return ret ? ret : -EIO; in rpi_exp_gpio_get_polarity()
76 struct rpi_exp_gpio *gpio; in rpi_exp_gpio_dir_in() local
80 gpio = gpiochip_get_data(gc); in rpi_exp_gpio_dir_in()
82 set_in.gpio = off + RPI_EXP_GPIO_BASE; /* GPIO to update */ in rpi_exp_gpio_dir_in()
93 ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_SET_GPIO_CONFIG, in rpi_exp_gpio_dir_in()
95 if (ret || set_in.gpio != 0) { in rpi_exp_gpio_dir_in()
96 dev_err(gc->parent, "Failed to set GPIO %u to input (%d %x)\n", in rpi_exp_gpio_dir_in()
97 off, ret, set_in.gpio); in rpi_exp_gpio_dir_in()
98 return ret ? ret : -EIO; in rpi_exp_gpio_dir_in()
105 struct rpi_exp_gpio *gpio; in rpi_exp_gpio_dir_out() local
109 gpio = gpiochip_get_data(gc); in rpi_exp_gpio_dir_out()
111 set_out.gpio = off + RPI_EXP_GPIO_BASE; /* GPIO to update */ in rpi_exp_gpio_dir_out()
122 ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_SET_GPIO_CONFIG, in rpi_exp_gpio_dir_out()
124 if (ret || set_out.gpio != 0) { in rpi_exp_gpio_dir_out()
125 dev_err(gc->parent, "Failed to set GPIO %u to output (%d %x)\n", in rpi_exp_gpio_dir_out()
126 off, ret, set_out.gpio); in rpi_exp_gpio_dir_out()
127 return ret ? ret : -EIO; in rpi_exp_gpio_dir_out()
134 struct rpi_exp_gpio *gpio; in rpi_exp_gpio_get_direction() local
138 gpio = gpiochip_get_data(gc); in rpi_exp_gpio_get_direction()
140 get.gpio = off + RPI_EXP_GPIO_BASE; /* GPIO to update */ in rpi_exp_gpio_get_direction()
142 ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_GET_GPIO_CONFIG, in rpi_exp_gpio_get_direction()
144 if (ret || get.gpio != 0) { in rpi_exp_gpio_get_direction()
145 dev_err(gc->parent, in rpi_exp_gpio_get_direction()
146 "Failed to get GPIO %u config (%d %x)\n", off, ret, in rpi_exp_gpio_get_direction()
147 get.gpio); in rpi_exp_gpio_get_direction()
148 return ret ? ret : -EIO; in rpi_exp_gpio_get_direction()
158 struct rpi_exp_gpio *gpio; in rpi_exp_gpio_get() local
162 gpio = gpiochip_get_data(gc); in rpi_exp_gpio_get()
164 get.gpio = off + RPI_EXP_GPIO_BASE; /* GPIO to update */ in rpi_exp_gpio_get()
167 ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_GET_GPIO_STATE, in rpi_exp_gpio_get()
169 if (ret || get.gpio != 0) { in rpi_exp_gpio_get()
170 dev_err(gc->parent, in rpi_exp_gpio_get()
171 "Failed to get GPIO %u state (%d %x)\n", off, ret, in rpi_exp_gpio_get()
172 get.gpio); in rpi_exp_gpio_get()
173 return ret ? ret : -EIO; in rpi_exp_gpio_get()
180 struct rpi_exp_gpio *gpio; in rpi_exp_gpio_set() local
184 gpio = gpiochip_get_data(gc); in rpi_exp_gpio_set()
186 set.gpio = off + RPI_EXP_GPIO_BASE; /* GPIO to update */ in rpi_exp_gpio_set()
189 ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_SET_GPIO_STATE, in rpi_exp_gpio_set()
191 if (ret || set.gpio != 0) in rpi_exp_gpio_set()
192 dev_err(gc->parent, in rpi_exp_gpio_set()
193 "Failed to set GPIO %u state (%d %x)\n", off, ret, in rpi_exp_gpio_set()
194 set.gpio); in rpi_exp_gpio_set()
199 struct device *dev = &pdev->dev; in rpi_exp_gpio_probe()
200 struct device_node *np = dev->of_node; in rpi_exp_gpio_probe()
207 dev_err(dev, "Missing firmware node\n"); in rpi_exp_gpio_probe()
208 return -ENOENT; in rpi_exp_gpio_probe()
211 fw = devm_rpi_firmware_get(&pdev->dev, fw_node); in rpi_exp_gpio_probe()
214 return -EPROBE_DEFER; in rpi_exp_gpio_probe()
218 return -ENOMEM; in rpi_exp_gpio_probe()
220 rpi_gpio->fw = fw; in rpi_exp_gpio_probe()
221 rpi_gpio->gc.parent = dev; in rpi_exp_gpio_probe()
222 rpi_gpio->gc.label = MODULE_NAME; in rpi_exp_gpio_probe()
223 rpi_gpio->gc.owner = THIS_MODULE; in rpi_exp_gpio_probe()
224 rpi_gpio->gc.base = -1; in rpi_exp_gpio_probe()
225 rpi_gpio->gc.ngpio = NUM_GPIO; in rpi_exp_gpio_probe()
227 rpi_gpio->gc.direction_input = rpi_exp_gpio_dir_in; in rpi_exp_gpio_probe()
228 rpi_gpio->gc.direction_output = rpi_exp_gpio_dir_out; in rpi_exp_gpio_probe()
229 rpi_gpio->gc.get_direction = rpi_exp_gpio_get_direction; in rpi_exp_gpio_probe()
230 rpi_gpio->gc.get = rpi_exp_gpio_get; in rpi_exp_gpio_probe()
231 rpi_gpio->gc.set = rpi_exp_gpio_set; in rpi_exp_gpio_probe()
232 rpi_gpio->gc.can_sleep = true; in rpi_exp_gpio_probe()
234 return devm_gpiochip_add_data(dev, &rpi_gpio->gc, rpi_gpio); in rpi_exp_gpio_probe()
238 { .compatible = "raspberrypi,firmware-gpio" },
254 MODULE_DESCRIPTION("Raspberry Pi 3 expander GPIO driver");
255 MODULE_ALIAS("platform:rpi-exp-gpio");