1606f7047SAlbert ARIBAUD \(3ADEV\) /* 2606f7047SAlbert ARIBAUD \(3ADEV\) * LPC32xxGPIO driver 3606f7047SAlbert ARIBAUD \(3ADEV\) * 4606f7047SAlbert ARIBAUD \(3ADEV\) * (C) Copyright 2014 DENX Software Engineering GmbH 5606f7047SAlbert ARIBAUD \(3ADEV\) * Written-by: Albert ARIBAUD <albert.aribaud@3adev.fr> 6606f7047SAlbert ARIBAUD \(3ADEV\) * 7606f7047SAlbert ARIBAUD \(3ADEV\) * SPDX-License-Identifier: GPL-2.0+ 8606f7047SAlbert ARIBAUD \(3ADEV\) */ 9606f7047SAlbert ARIBAUD \(3ADEV\) 10*4af0d7e8SSimon Glass #include <common.h> 11606f7047SAlbert ARIBAUD \(3ADEV\) #include <asm/io.h> 12606f7047SAlbert ARIBAUD \(3ADEV\) #include <asm/arch-lpc32xx/cpu.h> 13606f7047SAlbert ARIBAUD \(3ADEV\) #include <asm/arch-lpc32xx/gpio.h> 14606f7047SAlbert ARIBAUD \(3ADEV\) #include <asm-generic/gpio.h> 15606f7047SAlbert ARIBAUD \(3ADEV\) #include <dm.h> 16606f7047SAlbert ARIBAUD \(3ADEV\) 17606f7047SAlbert ARIBAUD \(3ADEV\) /** 18606f7047SAlbert ARIBAUD \(3ADEV\) * LPC32xx GPIOs work in banks but are non-homogeneous: 19606f7047SAlbert ARIBAUD \(3ADEV\) * - each bank holds a different number of GPIOs 20606f7047SAlbert ARIBAUD \(3ADEV\) * - some GPIOs are input/ouput, some input only, some output only; 21606f7047SAlbert ARIBAUD \(3ADEV\) * - some GPIOs have different meanings as an input and as an output; 22606f7047SAlbert ARIBAUD \(3ADEV\) * - some GPIOs are controlled on a given port and bit index, but 23606f7047SAlbert ARIBAUD \(3ADEV\) * read on another one. 24606f7047SAlbert ARIBAUD \(3ADEV\) * 25606f7047SAlbert ARIBAUD \(3ADEV\) * In order to keep this code simple, GPIOS are considered here as 2689983478SSylvain Lemieux * homogeneous and linear, from 0 to 159. 27606f7047SAlbert ARIBAUD \(3ADEV\) * 28606f7047SAlbert ARIBAUD \(3ADEV\) * ** WARNING #1 ** 29606f7047SAlbert ARIBAUD \(3ADEV\) * 30606f7047SAlbert ARIBAUD \(3ADEV\) * Client code is responsible for properly using valid GPIO numbers, 31606f7047SAlbert ARIBAUD \(3ADEV\) * including cases where a single physical GPIO has differing numbers 32606f7047SAlbert ARIBAUD \(3ADEV\) * for setting its direction, reading it and/or writing to it. 33606f7047SAlbert ARIBAUD \(3ADEV\) * 34606f7047SAlbert ARIBAUD \(3ADEV\) * ** WARNING #2 ** 35606f7047SAlbert ARIBAUD \(3ADEV\) * 36606f7047SAlbert ARIBAUD \(3ADEV\) * Please read NOTE in description of lpc32xx_gpio_get_function(). 37606f7047SAlbert ARIBAUD \(3ADEV\) */ 38606f7047SAlbert ARIBAUD \(3ADEV\) 3989983478SSylvain Lemieux #define LPC32XX_GPIOS 160 40606f7047SAlbert ARIBAUD \(3ADEV\) 411f9e5e22SAxel Lin struct lpc32xx_gpio_priv { 42606f7047SAlbert ARIBAUD \(3ADEV\) struct gpio_regs *regs; 43606f7047SAlbert ARIBAUD \(3ADEV\) /* GPIO FUNCTION: SEE WARNING #2 */ 44606f7047SAlbert ARIBAUD \(3ADEV\) signed char function[LPC32XX_GPIOS]; 45606f7047SAlbert ARIBAUD \(3ADEV\) }; 46606f7047SAlbert ARIBAUD \(3ADEV\) 47606f7047SAlbert ARIBAUD \(3ADEV\) /** 48606f7047SAlbert ARIBAUD \(3ADEV\) * We have 4 GPIO ports of 32 bits each 4989983478SSylvain Lemieux * 5089983478SSylvain Lemieux * Port mapping offset (32 bits each): 5189983478SSylvain Lemieux * - Port 0: 0 5289983478SSylvain Lemieux * - Port 1: 32 5389983478SSylvain Lemieux * - Port 2: 64 5489983478SSylvain Lemieux * - Port 3: GPO / GPIO (output): 96 5589983478SSylvain Lemieux * - Port 3: GPI: 128 56606f7047SAlbert ARIBAUD \(3ADEV\) */ 57606f7047SAlbert ARIBAUD \(3ADEV\) 5889983478SSylvain Lemieux #define MAX_GPIO 160 59606f7047SAlbert ARIBAUD \(3ADEV\) 6089983478SSylvain Lemieux #define GPIO_TO_PORT(gpio) ((gpio / 32) & 7) 61606f7047SAlbert ARIBAUD \(3ADEV\) #define GPIO_TO_RANK(gpio) (gpio % 32) 62606f7047SAlbert ARIBAUD \(3ADEV\) #define GPIO_TO_MASK(gpio) (1 << (gpio % 32)) 63606f7047SAlbert ARIBAUD \(3ADEV\) 64606f7047SAlbert ARIBAUD \(3ADEV\) /** 65606f7047SAlbert ARIBAUD \(3ADEV\) * Configure a GPIO number 'offset' as input 66606f7047SAlbert ARIBAUD \(3ADEV\) */ 67606f7047SAlbert ARIBAUD \(3ADEV\) 68606f7047SAlbert ARIBAUD \(3ADEV\) static int lpc32xx_gpio_direction_input(struct udevice *dev, unsigned offset) 69606f7047SAlbert ARIBAUD \(3ADEV\) { 70606f7047SAlbert ARIBAUD \(3ADEV\) int port, mask; 711f9e5e22SAxel Lin struct lpc32xx_gpio_priv *gpio_priv = dev_get_priv(dev); 721f9e5e22SAxel Lin struct gpio_regs *regs = gpio_priv->regs; 73606f7047SAlbert ARIBAUD \(3ADEV\) 74606f7047SAlbert ARIBAUD \(3ADEV\) port = GPIO_TO_PORT(offset); 75606f7047SAlbert ARIBAUD \(3ADEV\) mask = GPIO_TO_MASK(offset); 76606f7047SAlbert ARIBAUD \(3ADEV\) 77606f7047SAlbert ARIBAUD \(3ADEV\) switch (port) { 78606f7047SAlbert ARIBAUD \(3ADEV\) case 0: 79606f7047SAlbert ARIBAUD \(3ADEV\) writel(mask, ®s->p0_dir_clr); 80606f7047SAlbert ARIBAUD \(3ADEV\) break; 81606f7047SAlbert ARIBAUD \(3ADEV\) case 1: 82606f7047SAlbert ARIBAUD \(3ADEV\) writel(mask, ®s->p1_dir_clr); 83606f7047SAlbert ARIBAUD \(3ADEV\) break; 84606f7047SAlbert ARIBAUD \(3ADEV\) case 2: 85606f7047SAlbert ARIBAUD \(3ADEV\) /* ports 2 and 3 share a common direction */ 86606f7047SAlbert ARIBAUD \(3ADEV\) writel(mask, ®s->p2_p3_dir_clr); 87606f7047SAlbert ARIBAUD \(3ADEV\) break; 8889983478SSylvain Lemieux case 3: 8989983478SSylvain Lemieux /* Setup direction only for GPIO_xx. */ 9089983478SSylvain Lemieux if ((mask >= 25) && (mask <= 30)) 9189983478SSylvain Lemieux writel(mask, ®s->p2_p3_dir_clr); 9289983478SSylvain Lemieux break; 9389983478SSylvain Lemieux case 4: 9489983478SSylvain Lemieux /* GPI_xx; nothing to do. */ 9589983478SSylvain Lemieux break; 96606f7047SAlbert ARIBAUD \(3ADEV\) default: 97606f7047SAlbert ARIBAUD \(3ADEV\) return -1; 98606f7047SAlbert ARIBAUD \(3ADEV\) } 99606f7047SAlbert ARIBAUD \(3ADEV\) 100606f7047SAlbert ARIBAUD \(3ADEV\) /* GPIO FUNCTION: SEE WARNING #2 */ 1011f9e5e22SAxel Lin gpio_priv->function[offset] = GPIOF_INPUT; 102606f7047SAlbert ARIBAUD \(3ADEV\) 103606f7047SAlbert ARIBAUD \(3ADEV\) return 0; 104606f7047SAlbert ARIBAUD \(3ADEV\) } 105606f7047SAlbert ARIBAUD \(3ADEV\) 106606f7047SAlbert ARIBAUD \(3ADEV\) /** 107606f7047SAlbert ARIBAUD \(3ADEV\) * Get the value of a GPIO 108606f7047SAlbert ARIBAUD \(3ADEV\) */ 109606f7047SAlbert ARIBAUD \(3ADEV\) 110606f7047SAlbert ARIBAUD \(3ADEV\) static int lpc32xx_gpio_get_value(struct udevice *dev, unsigned offset) 111606f7047SAlbert ARIBAUD \(3ADEV\) { 112606f7047SAlbert ARIBAUD \(3ADEV\) int port, rank, mask, value; 1131f9e5e22SAxel Lin struct lpc32xx_gpio_priv *gpio_priv = dev_get_priv(dev); 1141f9e5e22SAxel Lin struct gpio_regs *regs = gpio_priv->regs; 115606f7047SAlbert ARIBAUD \(3ADEV\) 116606f7047SAlbert ARIBAUD \(3ADEV\) port = GPIO_TO_PORT(offset); 117606f7047SAlbert ARIBAUD \(3ADEV\) 118606f7047SAlbert ARIBAUD \(3ADEV\) switch (port) { 119606f7047SAlbert ARIBAUD \(3ADEV\) case 0: 120606f7047SAlbert ARIBAUD \(3ADEV\) value = readl(®s->p0_inp_state); 121606f7047SAlbert ARIBAUD \(3ADEV\) break; 122606f7047SAlbert ARIBAUD \(3ADEV\) case 1: 123606f7047SAlbert ARIBAUD \(3ADEV\) value = readl(®s->p1_inp_state); 124606f7047SAlbert ARIBAUD \(3ADEV\) break; 125606f7047SAlbert ARIBAUD \(3ADEV\) case 2: 126606f7047SAlbert ARIBAUD \(3ADEV\) value = readl(®s->p2_inp_state); 127606f7047SAlbert ARIBAUD \(3ADEV\) break; 128606f7047SAlbert ARIBAUD \(3ADEV\) case 3: 12989983478SSylvain Lemieux /* Read GPO_xx and GPIO_xx (as output) using p3_outp_state. */ 13089983478SSylvain Lemieux value = readl(®s->p3_outp_state); 13189983478SSylvain Lemieux break; 13289983478SSylvain Lemieux case 4: 13389983478SSylvain Lemieux /* Read GPI_xx and GPIO_xx (as input) using p3_inp_state. */ 134606f7047SAlbert ARIBAUD \(3ADEV\) value = readl(®s->p3_inp_state); 135606f7047SAlbert ARIBAUD \(3ADEV\) break; 136606f7047SAlbert ARIBAUD \(3ADEV\) default: 137606f7047SAlbert ARIBAUD \(3ADEV\) return -1; 138606f7047SAlbert ARIBAUD \(3ADEV\) } 139606f7047SAlbert ARIBAUD \(3ADEV\) 140606f7047SAlbert ARIBAUD \(3ADEV\) rank = GPIO_TO_RANK(offset); 141606f7047SAlbert ARIBAUD \(3ADEV\) mask = GPIO_TO_MASK(offset); 142606f7047SAlbert ARIBAUD \(3ADEV\) 143606f7047SAlbert ARIBAUD \(3ADEV\) return (value & mask) >> rank; 144606f7047SAlbert ARIBAUD \(3ADEV\) } 145606f7047SAlbert ARIBAUD \(3ADEV\) 146606f7047SAlbert ARIBAUD \(3ADEV\) /** 147606f7047SAlbert ARIBAUD \(3ADEV\) * Set a GPIO 148606f7047SAlbert ARIBAUD \(3ADEV\) */ 149606f7047SAlbert ARIBAUD \(3ADEV\) 150606f7047SAlbert ARIBAUD \(3ADEV\) static int gpio_set(struct udevice *dev, unsigned gpio) 151606f7047SAlbert ARIBAUD \(3ADEV\) { 152606f7047SAlbert ARIBAUD \(3ADEV\) int port, mask; 1531f9e5e22SAxel Lin struct lpc32xx_gpio_priv *gpio_priv = dev_get_priv(dev); 1541f9e5e22SAxel Lin struct gpio_regs *regs = gpio_priv->regs; 155606f7047SAlbert ARIBAUD \(3ADEV\) 156606f7047SAlbert ARIBAUD \(3ADEV\) port = GPIO_TO_PORT(gpio); 157606f7047SAlbert ARIBAUD \(3ADEV\) mask = GPIO_TO_MASK(gpio); 158606f7047SAlbert ARIBAUD \(3ADEV\) 159606f7047SAlbert ARIBAUD \(3ADEV\) switch (port) { 160606f7047SAlbert ARIBAUD \(3ADEV\) case 0: 161606f7047SAlbert ARIBAUD \(3ADEV\) writel(mask, ®s->p0_outp_set); 162606f7047SAlbert ARIBAUD \(3ADEV\) break; 163606f7047SAlbert ARIBAUD \(3ADEV\) case 1: 164606f7047SAlbert ARIBAUD \(3ADEV\) writel(mask, ®s->p1_outp_set); 165606f7047SAlbert ARIBAUD \(3ADEV\) break; 166606f7047SAlbert ARIBAUD \(3ADEV\) case 2: 167606f7047SAlbert ARIBAUD \(3ADEV\) writel(mask, ®s->p2_outp_set); 168606f7047SAlbert ARIBAUD \(3ADEV\) break; 169606f7047SAlbert ARIBAUD \(3ADEV\) case 3: 170606f7047SAlbert ARIBAUD \(3ADEV\) writel(mask, ®s->p3_outp_set); 171606f7047SAlbert ARIBAUD \(3ADEV\) break; 17289983478SSylvain Lemieux case 4: 17389983478SSylvain Lemieux /* GPI_xx; invalid. */ 174606f7047SAlbert ARIBAUD \(3ADEV\) default: 175606f7047SAlbert ARIBAUD \(3ADEV\) return -1; 176606f7047SAlbert ARIBAUD \(3ADEV\) } 177606f7047SAlbert ARIBAUD \(3ADEV\) return 0; 178606f7047SAlbert ARIBAUD \(3ADEV\) } 179606f7047SAlbert ARIBAUD \(3ADEV\) 180606f7047SAlbert ARIBAUD \(3ADEV\) /** 181606f7047SAlbert ARIBAUD \(3ADEV\) * Clear a GPIO 182606f7047SAlbert ARIBAUD \(3ADEV\) */ 183606f7047SAlbert ARIBAUD \(3ADEV\) 184606f7047SAlbert ARIBAUD \(3ADEV\) static int gpio_clr(struct udevice *dev, unsigned gpio) 185606f7047SAlbert ARIBAUD \(3ADEV\) { 186606f7047SAlbert ARIBAUD \(3ADEV\) int port, mask; 1871f9e5e22SAxel Lin struct lpc32xx_gpio_priv *gpio_priv = dev_get_priv(dev); 1881f9e5e22SAxel Lin struct gpio_regs *regs = gpio_priv->regs; 189606f7047SAlbert ARIBAUD \(3ADEV\) 190606f7047SAlbert ARIBAUD \(3ADEV\) port = GPIO_TO_PORT(gpio); 191606f7047SAlbert ARIBAUD \(3ADEV\) mask = GPIO_TO_MASK(gpio); 192606f7047SAlbert ARIBAUD \(3ADEV\) 193606f7047SAlbert ARIBAUD \(3ADEV\) switch (port) { 194606f7047SAlbert ARIBAUD \(3ADEV\) case 0: 195606f7047SAlbert ARIBAUD \(3ADEV\) writel(mask, ®s->p0_outp_clr); 196606f7047SAlbert ARIBAUD \(3ADEV\) break; 197606f7047SAlbert ARIBAUD \(3ADEV\) case 1: 198606f7047SAlbert ARIBAUD \(3ADEV\) writel(mask, ®s->p1_outp_clr); 199606f7047SAlbert ARIBAUD \(3ADEV\) break; 200606f7047SAlbert ARIBAUD \(3ADEV\) case 2: 201606f7047SAlbert ARIBAUD \(3ADEV\) writel(mask, ®s->p2_outp_clr); 202606f7047SAlbert ARIBAUD \(3ADEV\) break; 203606f7047SAlbert ARIBAUD \(3ADEV\) case 3: 204606f7047SAlbert ARIBAUD \(3ADEV\) writel(mask, ®s->p3_outp_clr); 205606f7047SAlbert ARIBAUD \(3ADEV\) break; 20689983478SSylvain Lemieux case 4: 20789983478SSylvain Lemieux /* GPI_xx; invalid. */ 208606f7047SAlbert ARIBAUD \(3ADEV\) default: 209606f7047SAlbert ARIBAUD \(3ADEV\) return -1; 210606f7047SAlbert ARIBAUD \(3ADEV\) } 211606f7047SAlbert ARIBAUD \(3ADEV\) return 0; 212606f7047SAlbert ARIBAUD \(3ADEV\) } 213606f7047SAlbert ARIBAUD \(3ADEV\) 214606f7047SAlbert ARIBAUD \(3ADEV\) /** 215606f7047SAlbert ARIBAUD \(3ADEV\) * Set the value of a GPIO 216606f7047SAlbert ARIBAUD \(3ADEV\) */ 217606f7047SAlbert ARIBAUD \(3ADEV\) 218606f7047SAlbert ARIBAUD \(3ADEV\) static int lpc32xx_gpio_set_value(struct udevice *dev, unsigned offset, 219606f7047SAlbert ARIBAUD \(3ADEV\) int value) 220606f7047SAlbert ARIBAUD \(3ADEV\) { 221606f7047SAlbert ARIBAUD \(3ADEV\) if (value) 222606f7047SAlbert ARIBAUD \(3ADEV\) return gpio_set(dev, offset); 223606f7047SAlbert ARIBAUD \(3ADEV\) else 224606f7047SAlbert ARIBAUD \(3ADEV\) return gpio_clr(dev, offset); 225606f7047SAlbert ARIBAUD \(3ADEV\) } 226606f7047SAlbert ARIBAUD \(3ADEV\) 227606f7047SAlbert ARIBAUD \(3ADEV\) /** 228606f7047SAlbert ARIBAUD \(3ADEV\) * Configure a GPIO number 'offset' as output with given initial value. 229606f7047SAlbert ARIBAUD \(3ADEV\) */ 230606f7047SAlbert ARIBAUD \(3ADEV\) 231606f7047SAlbert ARIBAUD \(3ADEV\) static int lpc32xx_gpio_direction_output(struct udevice *dev, unsigned offset, 232606f7047SAlbert ARIBAUD \(3ADEV\) int value) 233606f7047SAlbert ARIBAUD \(3ADEV\) { 234606f7047SAlbert ARIBAUD \(3ADEV\) int port, mask; 2351f9e5e22SAxel Lin struct lpc32xx_gpio_priv *gpio_priv = dev_get_priv(dev); 2361f9e5e22SAxel Lin struct gpio_regs *regs = gpio_priv->regs; 237606f7047SAlbert ARIBAUD \(3ADEV\) 238606f7047SAlbert ARIBAUD \(3ADEV\) port = GPIO_TO_PORT(offset); 239606f7047SAlbert ARIBAUD \(3ADEV\) mask = GPIO_TO_MASK(offset); 240606f7047SAlbert ARIBAUD \(3ADEV\) 241606f7047SAlbert ARIBAUD \(3ADEV\) switch (port) { 242606f7047SAlbert ARIBAUD \(3ADEV\) case 0: 243606f7047SAlbert ARIBAUD \(3ADEV\) writel(mask, ®s->p0_dir_set); 244606f7047SAlbert ARIBAUD \(3ADEV\) break; 245606f7047SAlbert ARIBAUD \(3ADEV\) case 1: 246606f7047SAlbert ARIBAUD \(3ADEV\) writel(mask, ®s->p1_dir_set); 247606f7047SAlbert ARIBAUD \(3ADEV\) break; 248606f7047SAlbert ARIBAUD \(3ADEV\) case 2: 249606f7047SAlbert ARIBAUD \(3ADEV\) /* ports 2 and 3 share a common direction */ 250606f7047SAlbert ARIBAUD \(3ADEV\) writel(mask, ®s->p2_p3_dir_set); 251606f7047SAlbert ARIBAUD \(3ADEV\) break; 25289983478SSylvain Lemieux case 3: 25389983478SSylvain Lemieux /* Setup direction only for GPIO_xx. */ 25489983478SSylvain Lemieux if ((mask >= 25) && (mask <= 30)) 25589983478SSylvain Lemieux writel(mask, ®s->p2_p3_dir_set); 25689983478SSylvain Lemieux break; 25789983478SSylvain Lemieux case 4: 25889983478SSylvain Lemieux /* GPI_xx; invalid. */ 259606f7047SAlbert ARIBAUD \(3ADEV\) default: 260606f7047SAlbert ARIBAUD \(3ADEV\) return -1; 261606f7047SAlbert ARIBAUD \(3ADEV\) } 262606f7047SAlbert ARIBAUD \(3ADEV\) 263606f7047SAlbert ARIBAUD \(3ADEV\) /* GPIO FUNCTION: SEE WARNING #2 */ 2641f9e5e22SAxel Lin gpio_priv->function[offset] = GPIOF_OUTPUT; 265606f7047SAlbert ARIBAUD \(3ADEV\) 266606f7047SAlbert ARIBAUD \(3ADEV\) return lpc32xx_gpio_set_value(dev, offset, value); 267606f7047SAlbert ARIBAUD \(3ADEV\) } 268606f7047SAlbert ARIBAUD \(3ADEV\) 269606f7047SAlbert ARIBAUD \(3ADEV\) /** 270606f7047SAlbert ARIBAUD \(3ADEV\) * GPIO functions are supposed to be computed from their current 271606f7047SAlbert ARIBAUD \(3ADEV\) * configuration, but that's way too complicated in LPC32XX. A simpler 272606f7047SAlbert ARIBAUD \(3ADEV\) * approach is used, where the GPIO functions are cached in an array. 273606f7047SAlbert ARIBAUD \(3ADEV\) * When the GPIO is in use, its function is either "input" or "output" 274606f7047SAlbert ARIBAUD \(3ADEV\) * depending on its direction, otherwise its function is "unknown". 275606f7047SAlbert ARIBAUD \(3ADEV\) * 276606f7047SAlbert ARIBAUD \(3ADEV\) * ** NOTE ** 277606f7047SAlbert ARIBAUD \(3ADEV\) * 278606f7047SAlbert ARIBAUD \(3ADEV\) * THIS APPROACH WAS CHOSEN DU TO THE COMPLEX NATURE OF THE LPC32XX 279606f7047SAlbert ARIBAUD \(3ADEV\) * GPIOS; DO NOT TAKE THIS AS AN EXAMPLE FOR NEW CODE. 280606f7047SAlbert ARIBAUD \(3ADEV\) */ 281606f7047SAlbert ARIBAUD \(3ADEV\) 282606f7047SAlbert ARIBAUD \(3ADEV\) static int lpc32xx_gpio_get_function(struct udevice *dev, unsigned offset) 283606f7047SAlbert ARIBAUD \(3ADEV\) { 2841f9e5e22SAxel Lin struct lpc32xx_gpio_priv *gpio_priv = dev_get_priv(dev); 2851f9e5e22SAxel Lin return gpio_priv->function[offset]; 286606f7047SAlbert ARIBAUD \(3ADEV\) } 287606f7047SAlbert ARIBAUD \(3ADEV\) 288606f7047SAlbert ARIBAUD \(3ADEV\) static const struct dm_gpio_ops gpio_lpc32xx_ops = { 289606f7047SAlbert ARIBAUD \(3ADEV\) .direction_input = lpc32xx_gpio_direction_input, 290606f7047SAlbert ARIBAUD \(3ADEV\) .direction_output = lpc32xx_gpio_direction_output, 291606f7047SAlbert ARIBAUD \(3ADEV\) .get_value = lpc32xx_gpio_get_value, 292606f7047SAlbert ARIBAUD \(3ADEV\) .set_value = lpc32xx_gpio_set_value, 293606f7047SAlbert ARIBAUD \(3ADEV\) .get_function = lpc32xx_gpio_get_function, 294606f7047SAlbert ARIBAUD \(3ADEV\) }; 295606f7047SAlbert ARIBAUD \(3ADEV\) 296606f7047SAlbert ARIBAUD \(3ADEV\) static int lpc32xx_gpio_probe(struct udevice *dev) 297606f7047SAlbert ARIBAUD \(3ADEV\) { 2981f9e5e22SAxel Lin struct lpc32xx_gpio_priv *gpio_priv = dev_get_priv(dev); 299606f7047SAlbert ARIBAUD \(3ADEV\) struct gpio_dev_priv *uc_priv = dev->uclass_priv; 300606f7047SAlbert ARIBAUD \(3ADEV\) 301e160f7d4SSimon Glass if (dev_of_offset(dev) == -1) { 302606f7047SAlbert ARIBAUD \(3ADEV\) /* Tell the uclass how many GPIOs we have */ 303606f7047SAlbert ARIBAUD \(3ADEV\) uc_priv->gpio_count = LPC32XX_GPIOS; 304606f7047SAlbert ARIBAUD \(3ADEV\) } 305606f7047SAlbert ARIBAUD \(3ADEV\) 306606f7047SAlbert ARIBAUD \(3ADEV\) /* set base address for GPIO registers */ 3071f9e5e22SAxel Lin gpio_priv->regs = (struct gpio_regs *)GPIO_BASE; 308606f7047SAlbert ARIBAUD \(3ADEV\) 309606f7047SAlbert ARIBAUD \(3ADEV\) /* all GPIO functions are unknown until requested */ 310606f7047SAlbert ARIBAUD \(3ADEV\) /* GPIO FUNCTION: SEE WARNING #2 */ 3111f9e5e22SAxel Lin memset(gpio_priv->function, GPIOF_UNKNOWN, sizeof(gpio_priv->function)); 312606f7047SAlbert ARIBAUD \(3ADEV\) 313606f7047SAlbert ARIBAUD \(3ADEV\) return 0; 314606f7047SAlbert ARIBAUD \(3ADEV\) } 315606f7047SAlbert ARIBAUD \(3ADEV\) 316606f7047SAlbert ARIBAUD \(3ADEV\) U_BOOT_DRIVER(gpio_lpc32xx) = { 317606f7047SAlbert ARIBAUD \(3ADEV\) .name = "gpio_lpc32xx", 318606f7047SAlbert ARIBAUD \(3ADEV\) .id = UCLASS_GPIO, 319606f7047SAlbert ARIBAUD \(3ADEV\) .ops = &gpio_lpc32xx_ops, 320606f7047SAlbert ARIBAUD \(3ADEV\) .probe = lpc32xx_gpio_probe, 3211f9e5e22SAxel Lin .priv_auto_alloc_size = sizeof(struct lpc32xx_gpio_priv), 322606f7047SAlbert ARIBAUD \(3ADEV\) }; 323