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