1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * gpio-reg: single register individually fixed-direction GPIOs |
4 | * |
5 | * Copyright (C) 2016 Russell King |
6 | */ |
7 | #include <linux/bits.h> |
8 | #include <linux/container_of.h> |
9 | #include <linux/device.h> |
10 | #include <linux/err.h> |
11 | #include <linux/errno.h> |
12 | #include <linux/io.h> |
13 | #include <linux/irqdomain.h> |
14 | #include <linux/slab.h> |
15 | #include <linux/spinlock.h> |
16 | #include <linux/types.h> |
17 | |
18 | #include <linux/gpio/driver.h> |
19 | #include <linux/gpio/gpio-reg.h> |
20 | |
21 | struct gpio_reg { |
22 | struct gpio_chip gc; |
23 | spinlock_t lock; |
24 | u32 direction; |
25 | u32 out; |
26 | void __iomem *reg; |
27 | struct irq_domain *irqdomain; |
28 | const int *irqs; |
29 | }; |
30 | |
31 | #define to_gpio_reg(x) container_of(x, struct gpio_reg, gc) |
32 | |
33 | static int gpio_reg_get_direction(struct gpio_chip *gc, unsigned offset) |
34 | { |
35 | struct gpio_reg *r = to_gpio_reg(gc); |
36 | |
37 | return r->direction & BIT(offset) ? GPIO_LINE_DIRECTION_IN : |
38 | GPIO_LINE_DIRECTION_OUT; |
39 | } |
40 | |
41 | static int gpio_reg_direction_output(struct gpio_chip *gc, unsigned offset, |
42 | int value) |
43 | { |
44 | struct gpio_reg *r = to_gpio_reg(gc); |
45 | |
46 | if (r->direction & BIT(offset)) |
47 | return -ENOTSUPP; |
48 | |
49 | gc->set(gc, offset, value); |
50 | return 0; |
51 | } |
52 | |
53 | static int gpio_reg_direction_input(struct gpio_chip *gc, unsigned offset) |
54 | { |
55 | struct gpio_reg *r = to_gpio_reg(gc); |
56 | |
57 | return r->direction & BIT(offset) ? 0 : -ENOTSUPP; |
58 | } |
59 | |
60 | static void gpio_reg_set(struct gpio_chip *gc, unsigned offset, int value) |
61 | { |
62 | struct gpio_reg *r = to_gpio_reg(gc); |
63 | unsigned long flags; |
64 | u32 val, mask = BIT(offset); |
65 | |
66 | spin_lock_irqsave(&r->lock, flags); |
67 | val = r->out; |
68 | if (value) |
69 | val |= mask; |
70 | else |
71 | val &= ~mask; |
72 | r->out = val; |
73 | writel_relaxed(val, r->reg); |
74 | spin_unlock_irqrestore(lock: &r->lock, flags); |
75 | } |
76 | |
77 | static int gpio_reg_get(struct gpio_chip *gc, unsigned offset) |
78 | { |
79 | struct gpio_reg *r = to_gpio_reg(gc); |
80 | u32 val, mask = BIT(offset); |
81 | |
82 | if (r->direction & mask) { |
83 | /* |
84 | * double-read the value, some registers latch after the |
85 | * first read. |
86 | */ |
87 | readl_relaxed(r->reg); |
88 | val = readl_relaxed(r->reg); |
89 | } else { |
90 | val = r->out; |
91 | } |
92 | return !!(val & mask); |
93 | } |
94 | |
95 | static void gpio_reg_set_multiple(struct gpio_chip *gc, unsigned long *mask, |
96 | unsigned long *bits) |
97 | { |
98 | struct gpio_reg *r = to_gpio_reg(gc); |
99 | unsigned long flags; |
100 | |
101 | spin_lock_irqsave(&r->lock, flags); |
102 | r->out = (r->out & ~*mask) | (*bits & *mask); |
103 | writel_relaxed(r->out, r->reg); |
104 | spin_unlock_irqrestore(lock: &r->lock, flags); |
105 | } |
106 | |
107 | static int gpio_reg_to_irq(struct gpio_chip *gc, unsigned offset) |
108 | { |
109 | struct gpio_reg *r = to_gpio_reg(gc); |
110 | int irq = r->irqs[offset]; |
111 | |
112 | if (irq >= 0 && r->irqdomain) |
113 | irq = irq_find_mapping(domain: r->irqdomain, hwirq: irq); |
114 | |
115 | return irq; |
116 | } |
117 | |
118 | /** |
119 | * gpio_reg_init - add a fixed in/out register as gpio |
120 | * @dev: optional struct device associated with this register |
121 | * @base: start gpio number, or -1 to allocate |
122 | * @num: number of GPIOs, maximum 32 |
123 | * @label: GPIO chip label |
124 | * @direction: bitmask of fixed direction, one per GPIO signal, 1 = in |
125 | * @def_out: initial GPIO output value |
126 | * @names: array of %num strings describing each GPIO signal or %NULL |
127 | * @irqdom: irq domain or %NULL |
128 | * @irqs: array of %num ints describing the interrupt mapping for each |
129 | * GPIO signal, or %NULL. If @irqdom is %NULL, then this |
130 | * describes the Linux interrupt number, otherwise it describes |
131 | * the hardware interrupt number in the specified irq domain. |
132 | * |
133 | * Add a single-register GPIO device containing up to 32 GPIO signals, |
134 | * where each GPIO has a fixed input or output configuration. Only |
135 | * input GPIOs are assumed to be readable from the register, and only |
136 | * then after a double-read. Output values are assumed not to be |
137 | * readable. |
138 | */ |
139 | struct gpio_chip *gpio_reg_init(struct device *dev, void __iomem *reg, |
140 | int base, int num, const char *label, u32 direction, u32 def_out, |
141 | const char *const *names, struct irq_domain *irqdom, const int *irqs) |
142 | { |
143 | struct gpio_reg *r; |
144 | int ret; |
145 | |
146 | if (dev) |
147 | r = devm_kzalloc(dev, size: sizeof(*r), GFP_KERNEL); |
148 | else |
149 | r = kzalloc(size: sizeof(*r), GFP_KERNEL); |
150 | |
151 | if (!r) |
152 | return ERR_PTR(error: -ENOMEM); |
153 | |
154 | spin_lock_init(&r->lock); |
155 | |
156 | r->gc.label = label; |
157 | r->gc.get_direction = gpio_reg_get_direction; |
158 | r->gc.direction_input = gpio_reg_direction_input; |
159 | r->gc.direction_output = gpio_reg_direction_output; |
160 | r->gc.set = gpio_reg_set; |
161 | r->gc.get = gpio_reg_get; |
162 | r->gc.set_multiple = gpio_reg_set_multiple; |
163 | if (irqs) |
164 | r->gc.to_irq = gpio_reg_to_irq; |
165 | r->gc.base = base; |
166 | r->gc.ngpio = num; |
167 | r->gc.names = names; |
168 | r->direction = direction; |
169 | r->out = def_out; |
170 | r->reg = reg; |
171 | r->irqs = irqs; |
172 | |
173 | if (dev) |
174 | ret = devm_gpiochip_add_data(dev, &r->gc, r); |
175 | else |
176 | ret = gpiochip_add_data(&r->gc, r); |
177 | |
178 | return ret ? ERR_PTR(error: ret) : &r->gc; |
179 | } |
180 | |
181 | int gpio_reg_resume(struct gpio_chip *gc) |
182 | { |
183 | struct gpio_reg *r = to_gpio_reg(gc); |
184 | unsigned long flags; |
185 | |
186 | spin_lock_irqsave(&r->lock, flags); |
187 | writel_relaxed(r->out, r->reg); |
188 | spin_unlock_irqrestore(lock: &r->lock, flags); |
189 | |
190 | return 0; |
191 | } |
192 | |