1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2015-2018 Pengutronix, Uwe Kleine-König <kernel@pengutronix.de>
6 #include <linux/module.h>
7 #include <linux/siox.h>
8 #include <linux/gpio/driver.h>
11 struct gpio_siox_ddata
{
12 struct gpio_chip gchip
;
17 raw_spinlock_t irqlock
;
24 * Note that this callback only sets the value that is clocked out in the next
27 static int gpio_siox_set_data(struct siox_device
*sdevice
, u8 status
, u8 buf
[])
29 struct gpio_siox_ddata
*ddata
= dev_get_drvdata(&sdevice
->dev
);
31 mutex_lock(&ddata
->lock
);
32 buf
[0] = ddata
->setdata
[0];
33 mutex_unlock(&ddata
->lock
);
38 static int gpio_siox_get_data(struct siox_device
*sdevice
, const u8 buf
[])
40 struct gpio_siox_ddata
*ddata
= dev_get_drvdata(&sdevice
->dev
);
44 mutex_lock(&ddata
->lock
);
46 raw_spin_lock_irq(&ddata
->irqlock
);
48 for (offset
= 0; offset
< 12; ++offset
) {
49 unsigned int bitpos
= 11 - offset
;
50 unsigned int gpiolevel
= buf
[bitpos
/ 8] & (1 << bitpos
% 8);
51 unsigned int prev_level
=
52 ddata
->getdata
[bitpos
/ 8] & (1 << (bitpos
% 8));
53 u32 irq_type
= ddata
->irq_type
[offset
];
56 if ((irq_type
& IRQ_TYPE_LEVEL_HIGH
) ||
57 ((irq_type
& IRQ_TYPE_EDGE_RISING
) && !prev_level
))
58 ddata
->irq_status
|= 1 << offset
;
60 if ((irq_type
& IRQ_TYPE_LEVEL_LOW
) ||
61 ((irq_type
& IRQ_TYPE_EDGE_FALLING
) && prev_level
))
62 ddata
->irq_status
|= 1 << offset
;
66 trigger
= ddata
->irq_status
& ddata
->irq_enable
;
68 raw_spin_unlock_irq(&ddata
->irqlock
);
70 ddata
->getdata
[0] = buf
[0];
71 ddata
->getdata
[1] = buf
[1];
72 ddata
->getdata
[2] = buf
[2];
74 mutex_unlock(&ddata
->lock
);
76 for (offset
= 0; offset
< 12; ++offset
) {
77 if (trigger
& (1 << offset
)) {
78 struct irq_domain
*irqdomain
= ddata
->gchip
.irq
.domain
;
79 unsigned int irq
= irq_find_mapping(irqdomain
, offset
);
82 * Conceptually handle_nested_irq should call the flow
83 * handler of the irq chip. But it doesn't, so we have
84 * to clean the irq_status here.
86 raw_spin_lock_irq(&ddata
->irqlock
);
87 ddata
->irq_status
&= ~(1 << offset
);
88 raw_spin_unlock_irq(&ddata
->irqlock
);
90 handle_nested_irq(irq
);
97 static void gpio_siox_irq_ack(struct irq_data
*d
)
99 struct gpio_chip
*gc
= irq_data_get_irq_chip_data(d
);
100 struct gpio_siox_ddata
*ddata
= gpiochip_get_data(gc
);
102 raw_spin_lock(&ddata
->irqlock
);
103 ddata
->irq_status
&= ~(1 << d
->hwirq
);
104 raw_spin_unlock(&ddata
->irqlock
);
107 static void gpio_siox_irq_mask(struct irq_data
*d
)
109 struct gpio_chip
*gc
= irq_data_get_irq_chip_data(d
);
110 struct gpio_siox_ddata
*ddata
= gpiochip_get_data(gc
);
112 raw_spin_lock(&ddata
->irqlock
);
113 ddata
->irq_enable
&= ~(1 << d
->hwirq
);
114 raw_spin_unlock(&ddata
->irqlock
);
115 gpiochip_disable_irq(gc
, irqd_to_hwirq(d
));
118 static void gpio_siox_irq_unmask(struct irq_data
*d
)
120 struct gpio_chip
*gc
= irq_data_get_irq_chip_data(d
);
121 struct gpio_siox_ddata
*ddata
= gpiochip_get_data(gc
);
123 gpiochip_enable_irq(gc
, irqd_to_hwirq(d
));
124 raw_spin_lock(&ddata
->irqlock
);
125 ddata
->irq_enable
|= 1 << d
->hwirq
;
126 raw_spin_unlock(&ddata
->irqlock
);
129 static int gpio_siox_irq_set_type(struct irq_data
*d
, u32 type
)
131 struct gpio_chip
*gc
= irq_data_get_irq_chip_data(d
);
132 struct gpio_siox_ddata
*ddata
= gpiochip_get_data(gc
);
134 raw_spin_lock(&ddata
->irqlock
);
135 ddata
->irq_type
[d
->hwirq
] = type
;
136 raw_spin_unlock(&ddata
->irqlock
);
141 static int gpio_siox_get(struct gpio_chip
*chip
, unsigned int offset
)
143 struct gpio_siox_ddata
*ddata
= gpiochip_get_data(chip
);
146 mutex_lock(&ddata
->lock
);
149 unsigned int bitpos
= 19 - offset
;
151 ret
= ddata
->setdata
[0] & (1 << bitpos
);
153 unsigned int bitpos
= 11 - offset
;
155 ret
= ddata
->getdata
[bitpos
/ 8] & (1 << (bitpos
% 8));
158 mutex_unlock(&ddata
->lock
);
163 static void gpio_siox_set(struct gpio_chip
*chip
,
164 unsigned int offset
, int value
)
166 struct gpio_siox_ddata
*ddata
= gpiochip_get_data(chip
);
167 u8 mask
= 1 << (19 - offset
);
169 mutex_lock(&ddata
->lock
);
172 ddata
->setdata
[0] |= mask
;
174 ddata
->setdata
[0] &= ~mask
;
176 mutex_unlock(&ddata
->lock
);
179 static int gpio_siox_direction_input(struct gpio_chip
*chip
,
188 static int gpio_siox_direction_output(struct gpio_chip
*chip
,
189 unsigned int offset
, int value
)
194 gpio_siox_set(chip
, offset
, value
);
198 static int gpio_siox_get_direction(struct gpio_chip
*chip
, unsigned int offset
)
201 return GPIO_LINE_DIRECTION_IN
;
203 return GPIO_LINE_DIRECTION_OUT
;
206 static const struct irq_chip gpio_siox_irq_chip
= {
208 .irq_ack
= gpio_siox_irq_ack
,
209 .irq_mask
= gpio_siox_irq_mask
,
210 .irq_unmask
= gpio_siox_irq_unmask
,
211 .irq_set_type
= gpio_siox_irq_set_type
,
212 .flags
= IRQCHIP_IMMUTABLE
,
213 GPIOCHIP_IRQ_RESOURCE_HELPERS
,
216 static int gpio_siox_probe(struct siox_device
*sdevice
)
218 struct gpio_siox_ddata
*ddata
;
219 struct gpio_irq_chip
*girq
;
220 struct device
*dev
= &sdevice
->dev
;
221 struct gpio_chip
*gc
;
224 ddata
= devm_kzalloc(dev
, sizeof(*ddata
), GFP_KERNEL
);
228 dev_set_drvdata(dev
, ddata
);
230 mutex_init(&ddata
->lock
);
231 raw_spin_lock_init(&ddata
->irqlock
);
237 gc
->owner
= THIS_MODULE
;
238 gc
->get
= gpio_siox_get
;
239 gc
->set
= gpio_siox_set
;
240 gc
->direction_input
= gpio_siox_direction_input
;
241 gc
->direction_output
= gpio_siox_direction_output
;
242 gc
->get_direction
= gpio_siox_get_direction
;
246 gpio_irq_chip_set_chip(girq
, &gpio_siox_irq_chip
);
247 girq
->default_type
= IRQ_TYPE_NONE
;
248 girq
->handler
= handle_level_irq
;
249 girq
->threaded
= true;
251 ret
= devm_gpiochip_add_data(dev
, gc
, ddata
);
253 dev_err(dev
, "Failed to register gpio chip (%d)\n", ret
);
258 static struct siox_driver gpio_siox_driver
= {
259 .probe
= gpio_siox_probe
,
260 .set_data
= gpio_siox_set_data
,
261 .get_data
= gpio_siox_get_data
,
266 module_siox_driver(gpio_siox_driver
);
268 MODULE_AUTHOR("Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>");
269 MODULE_DESCRIPTION("SIOX gpio driver");
270 MODULE_LICENSE("GPL v2");