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 + 0xc00); 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 + 0xc00); 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 void gpio_free(unsigned gpio) 76 { 77 /* Compatibility shim */ 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 void 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 } 107 108 static inline int gpio_is_valid(int gpio) 109 { 110 return (gpio >= 0) && (gpio < 32); 111 } 112 113 #endif /* not POWERPC_ASM_MPC85XX_GPIO_H_ */ 114