145051539SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2bfa9a2ebSMichael Ellerman /*
3bfa9a2ebSMichael Ellerman * PPC4xx gpio driver
4bfa9a2ebSMichael Ellerman *
5bfa9a2ebSMichael Ellerman * Copyright (c) 2008 Harris Corporation
6bfa9a2ebSMichael Ellerman * Copyright (c) 2008 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
7bfa9a2ebSMichael Ellerman * Copyright (c) MontaVista Software, Inc. 2008.
8bfa9a2ebSMichael Ellerman *
9bfa9a2ebSMichael Ellerman * Author: Steve Falco <sfalco@harris.com>
10bfa9a2ebSMichael Ellerman */
11bfa9a2ebSMichael Ellerman
12bfa9a2ebSMichael Ellerman #include <linux/kernel.h>
13bfa9a2ebSMichael Ellerman #include <linux/init.h>
14bfa9a2ebSMichael Ellerman #include <linux/spinlock.h>
15bfa9a2ebSMichael Ellerman #include <linux/io.h>
16bfa9a2ebSMichael Ellerman #include <linux/of.h>
17*a99cc668SArnd Bergmann #include <linux/gpio/legacy-of-mm-gpiochip.h>
18bfa9a2ebSMichael Ellerman #include <linux/gpio/driver.h>
19bfa9a2ebSMichael Ellerman #include <linux/types.h>
20bfa9a2ebSMichael Ellerman #include <linux/slab.h>
21bfa9a2ebSMichael Ellerman
22bfa9a2ebSMichael Ellerman #define GPIO_MASK(gpio) (0x80000000 >> (gpio))
23bfa9a2ebSMichael Ellerman #define GPIO_MASK2(gpio) (0xc0000000 >> ((gpio) * 2))
24bfa9a2ebSMichael Ellerman
25bfa9a2ebSMichael Ellerman /* Physical GPIO register layout */
26bfa9a2ebSMichael Ellerman struct ppc4xx_gpio {
27bfa9a2ebSMichael Ellerman __be32 or;
28bfa9a2ebSMichael Ellerman __be32 tcr;
29bfa9a2ebSMichael Ellerman __be32 osrl;
30bfa9a2ebSMichael Ellerman __be32 osrh;
31bfa9a2ebSMichael Ellerman __be32 tsrl;
32bfa9a2ebSMichael Ellerman __be32 tsrh;
33bfa9a2ebSMichael Ellerman __be32 odr;
34bfa9a2ebSMichael Ellerman __be32 ir;
35bfa9a2ebSMichael Ellerman __be32 rr1;
36bfa9a2ebSMichael Ellerman __be32 rr2;
37bfa9a2ebSMichael Ellerman __be32 rr3;
38bfa9a2ebSMichael Ellerman __be32 reserved1;
39bfa9a2ebSMichael Ellerman __be32 isr1l;
40bfa9a2ebSMichael Ellerman __be32 isr1h;
41bfa9a2ebSMichael Ellerman __be32 isr2l;
42bfa9a2ebSMichael Ellerman __be32 isr2h;
43bfa9a2ebSMichael Ellerman __be32 isr3l;
44bfa9a2ebSMichael Ellerman __be32 isr3h;
45bfa9a2ebSMichael Ellerman };
46bfa9a2ebSMichael Ellerman
47bfa9a2ebSMichael Ellerman struct ppc4xx_gpio_chip {
48bfa9a2ebSMichael Ellerman struct of_mm_gpio_chip mm_gc;
49bfa9a2ebSMichael Ellerman spinlock_t lock;
50bfa9a2ebSMichael Ellerman };
51bfa9a2ebSMichael Ellerman
52bfa9a2ebSMichael Ellerman /*
53bfa9a2ebSMichael Ellerman * GPIO LIB API implementation for GPIOs
54bfa9a2ebSMichael Ellerman *
55bfa9a2ebSMichael Ellerman * There are a maximum of 32 gpios in each gpio controller.
56bfa9a2ebSMichael Ellerman */
57bfa9a2ebSMichael Ellerman
ppc4xx_gpio_get(struct gpio_chip * gc,unsigned int gpio)58bfa9a2ebSMichael Ellerman static int ppc4xx_gpio_get(struct gpio_chip *gc, unsigned int gpio)
59bfa9a2ebSMichael Ellerman {
60bfa9a2ebSMichael Ellerman struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
61bfa9a2ebSMichael Ellerman struct ppc4xx_gpio __iomem *regs = mm_gc->regs;
62bfa9a2ebSMichael Ellerman
63bfa9a2ebSMichael Ellerman return !!(in_be32(®s->ir) & GPIO_MASK(gpio));
64bfa9a2ebSMichael Ellerman }
65bfa9a2ebSMichael Ellerman
66bfa9a2ebSMichael Ellerman static inline void
__ppc4xx_gpio_set(struct gpio_chip * gc,unsigned int gpio,int val)67bfa9a2ebSMichael Ellerman __ppc4xx_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
68bfa9a2ebSMichael Ellerman {
69bfa9a2ebSMichael Ellerman struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
70bfa9a2ebSMichael Ellerman struct ppc4xx_gpio __iomem *regs = mm_gc->regs;
71bfa9a2ebSMichael Ellerman
72bfa9a2ebSMichael Ellerman if (val)
73bfa9a2ebSMichael Ellerman setbits32(®s->or, GPIO_MASK(gpio));
74bfa9a2ebSMichael Ellerman else
75bfa9a2ebSMichael Ellerman clrbits32(®s->or, GPIO_MASK(gpio));
76bfa9a2ebSMichael Ellerman }
77bfa9a2ebSMichael Ellerman
78bfa9a2ebSMichael Ellerman static void
ppc4xx_gpio_set(struct gpio_chip * gc,unsigned int gpio,int val)79bfa9a2ebSMichael Ellerman ppc4xx_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
80bfa9a2ebSMichael Ellerman {
81bfa9a2ebSMichael Ellerman struct ppc4xx_gpio_chip *chip = gpiochip_get_data(gc);
82bfa9a2ebSMichael Ellerman unsigned long flags;
83bfa9a2ebSMichael Ellerman
84bfa9a2ebSMichael Ellerman spin_lock_irqsave(&chip->lock, flags);
85bfa9a2ebSMichael Ellerman
86bfa9a2ebSMichael Ellerman __ppc4xx_gpio_set(gc, gpio, val);
87bfa9a2ebSMichael Ellerman
88bfa9a2ebSMichael Ellerman spin_unlock_irqrestore(&chip->lock, flags);
89bfa9a2ebSMichael Ellerman
90bfa9a2ebSMichael Ellerman pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
91bfa9a2ebSMichael Ellerman }
92bfa9a2ebSMichael Ellerman
ppc4xx_gpio_dir_in(struct gpio_chip * gc,unsigned int gpio)93bfa9a2ebSMichael Ellerman static int ppc4xx_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
94bfa9a2ebSMichael Ellerman {
95bfa9a2ebSMichael Ellerman struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
96bfa9a2ebSMichael Ellerman struct ppc4xx_gpio_chip *chip = gpiochip_get_data(gc);
97bfa9a2ebSMichael Ellerman struct ppc4xx_gpio __iomem *regs = mm_gc->regs;
98bfa9a2ebSMichael Ellerman unsigned long flags;
99bfa9a2ebSMichael Ellerman
100bfa9a2ebSMichael Ellerman spin_lock_irqsave(&chip->lock, flags);
101bfa9a2ebSMichael Ellerman
102bfa9a2ebSMichael Ellerman /* Disable open-drain function */
103bfa9a2ebSMichael Ellerman clrbits32(®s->odr, GPIO_MASK(gpio));
104bfa9a2ebSMichael Ellerman
105bfa9a2ebSMichael Ellerman /* Float the pin */
106bfa9a2ebSMichael Ellerman clrbits32(®s->tcr, GPIO_MASK(gpio));
107bfa9a2ebSMichael Ellerman
108bfa9a2ebSMichael Ellerman /* Bits 0-15 use TSRL/OSRL, bits 16-31 use TSRH/OSRH */
109bfa9a2ebSMichael Ellerman if (gpio < 16) {
110bfa9a2ebSMichael Ellerman clrbits32(®s->osrl, GPIO_MASK2(gpio));
111bfa9a2ebSMichael Ellerman clrbits32(®s->tsrl, GPIO_MASK2(gpio));
112bfa9a2ebSMichael Ellerman } else {
113bfa9a2ebSMichael Ellerman clrbits32(®s->osrh, GPIO_MASK2(gpio));
114bfa9a2ebSMichael Ellerman clrbits32(®s->tsrh, GPIO_MASK2(gpio));
115bfa9a2ebSMichael Ellerman }
116bfa9a2ebSMichael Ellerman
117bfa9a2ebSMichael Ellerman spin_unlock_irqrestore(&chip->lock, flags);
118bfa9a2ebSMichael Ellerman
119bfa9a2ebSMichael Ellerman return 0;
120bfa9a2ebSMichael Ellerman }
121bfa9a2ebSMichael Ellerman
122bfa9a2ebSMichael Ellerman static int
ppc4xx_gpio_dir_out(struct gpio_chip * gc,unsigned int gpio,int val)123bfa9a2ebSMichael Ellerman ppc4xx_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
124bfa9a2ebSMichael Ellerman {
125bfa9a2ebSMichael Ellerman struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
126bfa9a2ebSMichael Ellerman struct ppc4xx_gpio_chip *chip = gpiochip_get_data(gc);
127bfa9a2ebSMichael Ellerman struct ppc4xx_gpio __iomem *regs = mm_gc->regs;
128bfa9a2ebSMichael Ellerman unsigned long flags;
129bfa9a2ebSMichael Ellerman
130bfa9a2ebSMichael Ellerman spin_lock_irqsave(&chip->lock, flags);
131bfa9a2ebSMichael Ellerman
132bfa9a2ebSMichael Ellerman /* First set initial value */
133bfa9a2ebSMichael Ellerman __ppc4xx_gpio_set(gc, gpio, val);
134bfa9a2ebSMichael Ellerman
135bfa9a2ebSMichael Ellerman /* Disable open-drain function */
136bfa9a2ebSMichael Ellerman clrbits32(®s->odr, GPIO_MASK(gpio));
137bfa9a2ebSMichael Ellerman
138bfa9a2ebSMichael Ellerman /* Drive the pin */
139bfa9a2ebSMichael Ellerman setbits32(®s->tcr, GPIO_MASK(gpio));
140bfa9a2ebSMichael Ellerman
141bfa9a2ebSMichael Ellerman /* Bits 0-15 use TSRL, bits 16-31 use TSRH */
142bfa9a2ebSMichael Ellerman if (gpio < 16) {
143bfa9a2ebSMichael Ellerman clrbits32(®s->osrl, GPIO_MASK2(gpio));
144bfa9a2ebSMichael Ellerman clrbits32(®s->tsrl, GPIO_MASK2(gpio));
145bfa9a2ebSMichael Ellerman } else {
146bfa9a2ebSMichael Ellerman clrbits32(®s->osrh, GPIO_MASK2(gpio));
147bfa9a2ebSMichael Ellerman clrbits32(®s->tsrh, GPIO_MASK2(gpio));
148bfa9a2ebSMichael Ellerman }
149bfa9a2ebSMichael Ellerman
150bfa9a2ebSMichael Ellerman spin_unlock_irqrestore(&chip->lock, flags);
151bfa9a2ebSMichael Ellerman
152bfa9a2ebSMichael Ellerman pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
153bfa9a2ebSMichael Ellerman
154bfa9a2ebSMichael Ellerman return 0;
155bfa9a2ebSMichael Ellerman }
156bfa9a2ebSMichael Ellerman
ppc4xx_add_gpiochips(void)157bfa9a2ebSMichael Ellerman static int __init ppc4xx_add_gpiochips(void)
158bfa9a2ebSMichael Ellerman {
159bfa9a2ebSMichael Ellerman struct device_node *np;
160bfa9a2ebSMichael Ellerman
161bfa9a2ebSMichael Ellerman for_each_compatible_node(np, NULL, "ibm,ppc4xx-gpio") {
162bfa9a2ebSMichael Ellerman int ret;
163bfa9a2ebSMichael Ellerman struct ppc4xx_gpio_chip *ppc4xx_gc;
164bfa9a2ebSMichael Ellerman struct of_mm_gpio_chip *mm_gc;
165bfa9a2ebSMichael Ellerman struct gpio_chip *gc;
166bfa9a2ebSMichael Ellerman
167bfa9a2ebSMichael Ellerman ppc4xx_gc = kzalloc(sizeof(*ppc4xx_gc), GFP_KERNEL);
168bfa9a2ebSMichael Ellerman if (!ppc4xx_gc) {
169bfa9a2ebSMichael Ellerman ret = -ENOMEM;
170bfa9a2ebSMichael Ellerman goto err;
171bfa9a2ebSMichael Ellerman }
172bfa9a2ebSMichael Ellerman
173bfa9a2ebSMichael Ellerman spin_lock_init(&ppc4xx_gc->lock);
174bfa9a2ebSMichael Ellerman
175bfa9a2ebSMichael Ellerman mm_gc = &ppc4xx_gc->mm_gc;
176bfa9a2ebSMichael Ellerman gc = &mm_gc->gc;
177bfa9a2ebSMichael Ellerman
178bfa9a2ebSMichael Ellerman gc->ngpio = 32;
179bfa9a2ebSMichael Ellerman gc->direction_input = ppc4xx_gpio_dir_in;
180bfa9a2ebSMichael Ellerman gc->direction_output = ppc4xx_gpio_dir_out;
181bfa9a2ebSMichael Ellerman gc->get = ppc4xx_gpio_get;
182bfa9a2ebSMichael Ellerman gc->set = ppc4xx_gpio_set;
183bfa9a2ebSMichael Ellerman
184bfa9a2ebSMichael Ellerman ret = of_mm_gpiochip_add_data(np, mm_gc, ppc4xx_gc);
185bfa9a2ebSMichael Ellerman if (ret)
186bfa9a2ebSMichael Ellerman goto err;
187bfa9a2ebSMichael Ellerman continue;
188bfa9a2ebSMichael Ellerman err:
189b7c670d6SRob Herring pr_err("%pOF: registration failed with status %d\n", np, ret);
190bfa9a2ebSMichael Ellerman kfree(ppc4xx_gc);
191bfa9a2ebSMichael Ellerman /* try others anyway */
192bfa9a2ebSMichael Ellerman }
193bfa9a2ebSMichael Ellerman return 0;
194bfa9a2ebSMichael Ellerman }
195bfa9a2ebSMichael Ellerman arch_initcall(ppc4xx_add_gpiochips);
196