1710308eeSKyle Moffett /* 2710308eeSKyle Moffett * Copyright 2010 eXMeritus, A Boeing Company 3710308eeSKyle Moffett * 41a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+ 5710308eeSKyle Moffett */ 6710308eeSKyle Moffett 7710308eeSKyle Moffett #ifndef POWERPC_ASM_MPC85XX_GPIO_H_ 8710308eeSKyle Moffett #define POWERPC_ASM_MPC85XX_GPIO_H_ 9710308eeSKyle Moffett 10710308eeSKyle Moffett # include <asm/immap_85xx.h> 11710308eeSKyle Moffett 12710308eeSKyle Moffett /* 13710308eeSKyle Moffett * The following internal functions are an MPC85XX-specific GPIO API which 14710308eeSKyle Moffett * allows setting and querying multiple GPIOs in a single operation. 15710308eeSKyle Moffett * 16710308eeSKyle Moffett * All of these look relatively large, but the arguments are almost always 17710308eeSKyle Moffett * constants, so they compile down to just a few instructions and a 18710308eeSKyle Moffett * memory-mapped IO operation or two. 19710308eeSKyle Moffett */ 20710308eeSKyle Moffett static inline void mpc85xx_gpio_set(unsigned int mask, 21710308eeSKyle Moffett unsigned int dir, unsigned int val) 22710308eeSKyle Moffett { 23f40fcfd9STang Yuantian ccsr_gpio_t *gpio = (void *)(CONFIG_SYS_MPC85xx_GPIO_ADDR); 24710308eeSKyle Moffett 25710308eeSKyle Moffett /* First mask off the unwanted parts of "dir" and "val" */ 26710308eeSKyle Moffett dir &= mask; 27710308eeSKyle Moffett val &= mask; 28710308eeSKyle Moffett 29710308eeSKyle Moffett /* Now read in the values we're supposed to preserve */ 30710308eeSKyle Moffett dir |= (in_be32(&gpio->gpdir) & ~mask); 31710308eeSKyle Moffett val |= (in_be32(&gpio->gpdat) & ~mask); 32710308eeSKyle Moffett 33710308eeSKyle Moffett /* 34710308eeSKyle Moffett * Poke the new output values first, then set the direction. This 35710308eeSKyle Moffett * helps to avoid transient data when switching from input to output 36710308eeSKyle Moffett * and vice versa. 37710308eeSKyle Moffett */ 38710308eeSKyle Moffett out_be32(&gpio->gpdat, val); 39710308eeSKyle Moffett out_be32(&gpio->gpdir, dir); 40710308eeSKyle Moffett } 41710308eeSKyle Moffett 42710308eeSKyle Moffett static inline void mpc85xx_gpio_set_in(unsigned int gpios) 43710308eeSKyle Moffett { 44710308eeSKyle Moffett mpc85xx_gpio_set(gpios, 0x00000000, 0x00000000); 45710308eeSKyle Moffett } 46710308eeSKyle Moffett 47710308eeSKyle Moffett static inline void mpc85xx_gpio_set_low(unsigned int gpios) 48710308eeSKyle Moffett { 49710308eeSKyle Moffett mpc85xx_gpio_set(gpios, 0xFFFFFFFF, 0x00000000); 50710308eeSKyle Moffett } 51710308eeSKyle Moffett 52710308eeSKyle Moffett static inline void mpc85xx_gpio_set_high(unsigned int gpios) 53710308eeSKyle Moffett { 54710308eeSKyle Moffett mpc85xx_gpio_set(gpios, 0xFFFFFFFF, 0xFFFFFFFF); 55710308eeSKyle Moffett } 56710308eeSKyle Moffett 57710308eeSKyle Moffett static inline unsigned int mpc85xx_gpio_get(unsigned int mask) 58710308eeSKyle Moffett { 59f40fcfd9STang Yuantian ccsr_gpio_t *gpio = (void *)(CONFIG_SYS_MPC85xx_GPIO_ADDR); 60710308eeSKyle Moffett 61710308eeSKyle Moffett /* Read the requested values */ 62710308eeSKyle Moffett return in_be32(&gpio->gpdat) & mask; 63710308eeSKyle Moffett } 64710308eeSKyle Moffett 65710308eeSKyle Moffett /* 66710308eeSKyle Moffett * These implement the generic Linux GPIO API on top of the other functions 67710308eeSKyle Moffett * in this header. 68710308eeSKyle Moffett */ 69710308eeSKyle Moffett static inline int gpio_request(unsigned gpio, const char *label) 70710308eeSKyle Moffett { 71710308eeSKyle Moffett /* Compatibility shim */ 72710308eeSKyle Moffett return 0; 73710308eeSKyle Moffett } 74710308eeSKyle Moffett 75*d7732faaSOleksandr G Zhadan static inline int gpio_free(unsigned gpio) 76710308eeSKyle Moffett { 77710308eeSKyle Moffett /* Compatibility shim */ 78*d7732faaSOleksandr G Zhadan return 0; 79710308eeSKyle Moffett } 80710308eeSKyle Moffett 81710308eeSKyle Moffett static inline int gpio_direction_input(unsigned gpio) 82710308eeSKyle Moffett { 83710308eeSKyle Moffett mpc85xx_gpio_set_in(1U << gpio); 84710308eeSKyle Moffett return 0; 85710308eeSKyle Moffett } 86710308eeSKyle Moffett 87710308eeSKyle Moffett static inline int gpio_direction_output(unsigned gpio, int value) 88710308eeSKyle Moffett { 89168e5bc4SChris Packham if (value) 90168e5bc4SChris Packham mpc85xx_gpio_set_high(1U << gpio); 91168e5bc4SChris Packham else 92710308eeSKyle Moffett mpc85xx_gpio_set_low(1U << gpio); 93710308eeSKyle Moffett return 0; 94710308eeSKyle Moffett } 95710308eeSKyle Moffett 96710308eeSKyle Moffett static inline int gpio_get_value(unsigned gpio) 97710308eeSKyle Moffett { 98710308eeSKyle Moffett return !!mpc85xx_gpio_get(1U << gpio); 99710308eeSKyle Moffett } 100710308eeSKyle Moffett 101*d7732faaSOleksandr G Zhadan static inline int gpio_set_value(unsigned gpio, int value) 102710308eeSKyle Moffett { 103710308eeSKyle Moffett if (value) 104710308eeSKyle Moffett mpc85xx_gpio_set_high(1U << gpio); 105710308eeSKyle Moffett else 106710308eeSKyle Moffett mpc85xx_gpio_set_low(1U << gpio); 107*d7732faaSOleksandr G Zhadan return 0; 108710308eeSKyle Moffett } 109710308eeSKyle Moffett 110710308eeSKyle Moffett static inline int gpio_is_valid(int gpio) 111710308eeSKyle Moffett { 112710308eeSKyle Moffett return (gpio >= 0) && (gpio < 32); 113710308eeSKyle Moffett } 114710308eeSKyle Moffett 115710308eeSKyle Moffett #endif /* not POWERPC_ASM_MPC85XX_GPIO_H_ */ 116