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