1 /* 2 * Copyright 2010 eXMeritus, A Boeing Company 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License as 6 * published by the Free Software Foundation; either version 2 of 7 * the License, or (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 17 * MA 02111-1307 USA 18 */ 19 20 #ifndef POWERPC_ASM_MPC85XX_GPIO_H_ 21 #define POWERPC_ASM_MPC85XX_GPIO_H_ 22 23 # include <asm/immap_85xx.h> 24 25 /* 26 * The following internal functions are an MPC85XX-specific GPIO API which 27 * allows setting and querying multiple GPIOs in a single operation. 28 * 29 * All of these look relatively large, but the arguments are almost always 30 * constants, so they compile down to just a few instructions and a 31 * memory-mapped IO operation or two. 32 */ 33 static inline void mpc85xx_gpio_set(unsigned int mask, 34 unsigned int dir, unsigned int val) 35 { 36 ccsr_gpio_t *gpio = (void *)(CONFIG_SYS_MPC85xx_GPIO_ADDR + 0xc00); 37 38 /* First mask off the unwanted parts of "dir" and "val" */ 39 dir &= mask; 40 val &= mask; 41 42 /* Now read in the values we're supposed to preserve */ 43 dir |= (in_be32(&gpio->gpdir) & ~mask); 44 val |= (in_be32(&gpio->gpdat) & ~mask); 45 46 /* 47 * Poke the new output values first, then set the direction. This 48 * helps to avoid transient data when switching from input to output 49 * and vice versa. 50 */ 51 out_be32(&gpio->gpdat, val); 52 out_be32(&gpio->gpdir, dir); 53 } 54 55 static inline void mpc85xx_gpio_set_in(unsigned int gpios) 56 { 57 mpc85xx_gpio_set(gpios, 0x00000000, 0x00000000); 58 } 59 60 static inline void mpc85xx_gpio_set_low(unsigned int gpios) 61 { 62 mpc85xx_gpio_set(gpios, 0xFFFFFFFF, 0x00000000); 63 } 64 65 static inline void mpc85xx_gpio_set_high(unsigned int gpios) 66 { 67 mpc85xx_gpio_set(gpios, 0xFFFFFFFF, 0xFFFFFFFF); 68 } 69 70 static inline unsigned int mpc85xx_gpio_get(unsigned int mask) 71 { 72 ccsr_gpio_t *gpio = (void *)(CONFIG_SYS_MPC85xx_GPIO_ADDR + 0xc00); 73 74 /* Read the requested values */ 75 return in_be32(&gpio->gpdat) & mask; 76 } 77 78 /* 79 * These implement the generic Linux GPIO API on top of the other functions 80 * in this header. 81 */ 82 static inline int gpio_request(unsigned gpio, const char *label) 83 { 84 /* Compatibility shim */ 85 return 0; 86 } 87 88 static inline void gpio_free(unsigned gpio) 89 { 90 /* Compatibility shim */ 91 } 92 93 static inline int gpio_direction_input(unsigned gpio) 94 { 95 mpc85xx_gpio_set_in(1U << gpio); 96 return 0; 97 } 98 99 static inline int gpio_direction_output(unsigned gpio, int value) 100 { 101 if (value) 102 mpc85xx_gpio_set_high(1U << gpio); 103 else 104 mpc85xx_gpio_set_low(1U << gpio); 105 return 0; 106 } 107 108 static inline int gpio_get_value(unsigned gpio) 109 { 110 return !!mpc85xx_gpio_get(1U << gpio); 111 } 112 113 static inline void gpio_set_value(unsigned gpio, int value) 114 { 115 if (value) 116 mpc85xx_gpio_set_high(1U << gpio); 117 else 118 mpc85xx_gpio_set_low(1U << gpio); 119 } 120 121 static inline int gpio_is_valid(int gpio) 122 { 123 return (gpio >= 0) && (gpio < 32); 124 } 125 126 #endif /* not POWERPC_ASM_MPC85XX_GPIO_H_ */ 127