1 /* SPDX-License-Identifier: GPL-2.0+ */ 2 /* 3 * Copyright 2010 eXMeritus, A Boeing Company 4 */ 5 6 #ifndef POWERPC_ASM_MPC85XX_GPIO_H_ 7 #define POWERPC_ASM_MPC85XX_GPIO_H_ 8 9 # include <asm/immap_85xx.h> 10 11 /* 12 * The following internal functions are an MPC85XX-specific GPIO API which 13 * allows setting and querying multiple GPIOs in a single operation. 14 * 15 * All of these look relatively large, but the arguments are almost always 16 * constants, so they compile down to just a few instructions and a 17 * memory-mapped IO operation or two. 18 */ 19 static inline void mpc85xx_gpio_set(unsigned int mask, 20 unsigned int dir, unsigned int val) 21 { 22 ccsr_gpio_t *gpio = (void *)(CONFIG_SYS_MPC85xx_GPIO_ADDR); 23 24 /* First mask off the unwanted parts of "dir" and "val" */ 25 dir &= mask; 26 val &= mask; 27 28 /* Now read in the values we're supposed to preserve */ 29 dir |= (in_be32(&gpio->gpdir) & ~mask); 30 val |= (in_be32(&gpio->gpdat) & ~mask); 31 32 /* 33 * Poke the new output values first, then set the direction. This 34 * helps to avoid transient data when switching from input to output 35 * and vice versa. 36 */ 37 out_be32(&gpio->gpdat, val); 38 out_be32(&gpio->gpdir, dir); 39 } 40 41 static inline void mpc85xx_gpio_set_in(unsigned int gpios) 42 { 43 mpc85xx_gpio_set(gpios, 0x00000000, 0x00000000); 44 } 45 46 static inline void mpc85xx_gpio_set_low(unsigned int gpios) 47 { 48 mpc85xx_gpio_set(gpios, 0xFFFFFFFF, 0x00000000); 49 } 50 51 static inline void mpc85xx_gpio_set_high(unsigned int gpios) 52 { 53 mpc85xx_gpio_set(gpios, 0xFFFFFFFF, 0xFFFFFFFF); 54 } 55 56 static inline unsigned int mpc85xx_gpio_get(unsigned int mask) 57 { 58 ccsr_gpio_t *gpio = (void *)(CONFIG_SYS_MPC85xx_GPIO_ADDR); 59 60 /* Read the requested values */ 61 return in_be32(&gpio->gpdat) & mask; 62 } 63 64 /* 65 * These implement the generic Linux GPIO API on top of the other functions 66 * in this header. 67 */ 68 static inline int gpio_request(unsigned gpio, const char *label) 69 { 70 /* Compatibility shim */ 71 return 0; 72 } 73 74 static inline int gpio_free(unsigned gpio) 75 { 76 /* Compatibility shim */ 77 return 0; 78 } 79 80 static inline int gpio_direction_input(unsigned gpio) 81 { 82 mpc85xx_gpio_set_in(1U << gpio); 83 return 0; 84 } 85 86 static inline int gpio_direction_output(unsigned gpio, int value) 87 { 88 if (value) 89 mpc85xx_gpio_set_high(1U << gpio); 90 else 91 mpc85xx_gpio_set_low(1U << gpio); 92 return 0; 93 } 94 95 static inline int gpio_get_value(unsigned gpio) 96 { 97 return !!mpc85xx_gpio_get(1U << gpio); 98 } 99 100 static inline int gpio_set_value(unsigned gpio, int value) 101 { 102 if (value) 103 mpc85xx_gpio_set_high(1U << gpio); 104 else 105 mpc85xx_gpio_set_low(1U << gpio); 106 return 0; 107 } 108 109 static inline int gpio_is_valid(int gpio) 110 { 111 return (gpio >= 0) && (gpio < 32); 112 } 113 114 #endif /* not POWERPC_ASM_MPC85XX_GPIO_H_ */ 115