blob: 1b332f0b193000c32097f07d861ee1f2c16976da [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001/* SPDX-License-Identifier: GPL-2.0+ */
Kyle Moffett3761b972011-10-19 14:58:15 -04002/*
3 * Copyright 2010 eXMeritus, A Boeing Company
Kyle Moffett3761b972011-10-19 14:58:15 -04004 */
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 */
19static inline void mpc85xx_gpio_set(unsigned int mask,
20 unsigned int dir, unsigned int val)
21{
Tang Yuantian0c61d5d2013-10-17 10:47:33 +080022 ccsr_gpio_t *gpio = (void *)(CONFIG_SYS_MPC85xx_GPIO_ADDR);
Kyle Moffett3761b972011-10-19 14:58:15 -040023
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
41static inline void mpc85xx_gpio_set_in(unsigned int gpios)
42{
43 mpc85xx_gpio_set(gpios, 0x00000000, 0x00000000);
44}
45
46static inline void mpc85xx_gpio_set_low(unsigned int gpios)
47{
48 mpc85xx_gpio_set(gpios, 0xFFFFFFFF, 0x00000000);
49}
50
51static inline void mpc85xx_gpio_set_high(unsigned int gpios)
52{
53 mpc85xx_gpio_set(gpios, 0xFFFFFFFF, 0xFFFFFFFF);
54}
55
56static inline unsigned int mpc85xx_gpio_get(unsigned int mask)
57{
Tang Yuantian0c61d5d2013-10-17 10:47:33 +080058 ccsr_gpio_t *gpio = (void *)(CONFIG_SYS_MPC85xx_GPIO_ADDR);
Kyle Moffett3761b972011-10-19 14:58:15 -040059
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 */
68static inline int gpio_request(unsigned gpio, const char *label)
69{
70 /* Compatibility shim */
71 return 0;
72}
73
Oleksandr G Zhadan2d24af12015-04-28 13:59:50 -040074static inline int gpio_free(unsigned gpio)
Kyle Moffett3761b972011-10-19 14:58:15 -040075{
76 /* Compatibility shim */
Oleksandr G Zhadan2d24af12015-04-28 13:59:50 -040077 return 0;
Kyle Moffett3761b972011-10-19 14:58:15 -040078}
79
80static inline int gpio_direction_input(unsigned gpio)
81{
82 mpc85xx_gpio_set_in(1U << gpio);
83 return 0;
84}
85
86static inline int gpio_direction_output(unsigned gpio, int value)
87{
Chris Packham09f4c2c2012-09-06 17:28:35 +000088 if (value)
89 mpc85xx_gpio_set_high(1U << gpio);
90 else
91 mpc85xx_gpio_set_low(1U << gpio);
Kyle Moffett3761b972011-10-19 14:58:15 -040092 return 0;
93}
94
95static inline int gpio_get_value(unsigned gpio)
96{
97 return !!mpc85xx_gpio_get(1U << gpio);
98}
99
Oleksandr G Zhadan2d24af12015-04-28 13:59:50 -0400100static inline int gpio_set_value(unsigned gpio, int value)
Kyle Moffett3761b972011-10-19 14:58:15 -0400101{
102 if (value)
103 mpc85xx_gpio_set_high(1U << gpio);
104 else
105 mpc85xx_gpio_set_low(1U << gpio);
Oleksandr G Zhadan2d24af12015-04-28 13:59:50 -0400106 return 0;
Kyle Moffett3761b972011-10-19 14:58:15 -0400107}
108
109static inline int gpio_is_valid(int gpio)
110{
111 return (gpio >= 0) && (gpio < 32);
112}
113
114#endif /* not POWERPC_ASM_MPC85XX_GPIO_H_ */