1 // SPDX-License-Identifier: GPL-2.0
5 * Copyright (C) 2022 Sascha Hauer <s.hauer@pengutronix.de>
7 * This driver implements a GPIO (or better GPO as there is no input)
8 * multiplexer based on latches like this:
10 * CLK0 ----------------------. ,--------.
11 * CLK1 -------------------. `--------|> #0 |
13 * OUT0 ----------------+--|-----------|D0 Q0|-----|<
14 * OUT1 --------------+-|--|-----------|D1 Q1|-----|<
15 * OUT2 ------------+-|-|--|-----------|D2 Q2|-----|<
16 * OUT3 ----------+-|-|-|--|-----------|D3 Q3|-----|<
17 * OUT4 --------+-|-|-|-|--|-----------|D4 Q4|-----|<
18 * OUT5 ------+-|-|-|-|-|--|-----------|D5 Q5|-----|<
19 * OUT6 ----+-|-|-|-|-|-|--|-----------|D6 Q6|-----|<
20 * OUT7 --+-|-|-|-|-|-|-|--|-----------|D7 Q7|-----|<
21 * | | | | | | | | | `--------'
23 * | | | | | | | | | ,--------.
24 * | | | | | | | | `-----------|> #1 |
26 * | | | | | | | `--------------|D0 Q0|-----|<
27 * | | | | | | `----------------|D1 Q1|-----|<
28 * | | | | | `------------------|D2 Q2|-----|<
29 * | | | | `--------------------|D3 Q3|-----|<
30 * | | | `----------------------|D4 Q4|-----|<
31 * | | `------------------------|D5 Q5|-----|<
32 * | `--------------------------|D6 Q6|-----|<
33 * `----------------------------|D7 Q7|-----|<
36 * The above is just an example. The actual number of number of latches and
37 * the number of inputs per latch is derived from the number of GPIOs given
38 * in the corresponding device tree properties.
41 #include <linux/err.h>
42 #include <linux/gpio/consumer.h>
43 #include <linux/gpio/driver.h>
44 #include <linux/module.h>
45 #include <linux/mod_devicetable.h>
46 #include <linux/platform_device.h>
47 #include <linux/delay.h>
51 struct gpio_latch_priv
{
53 struct gpio_descs
*clk_gpios
;
54 struct gpio_descs
*latched_gpios
;
56 unsigned int setup_duration_ns
;
57 unsigned int clock_duration_ns
;
58 unsigned long *shadow
;
60 * Depending on whether any of the underlying GPIOs may sleep we either
61 * use a mutex or a spinlock to protect our shadow map.
64 struct mutex mutex
; /* protects @shadow */
65 spinlock_t spinlock
; /* protects @shadow */
69 static int gpio_latch_get_direction(struct gpio_chip
*gc
, unsigned int offset
)
71 return GPIO_LINE_DIRECTION_OUT
;
74 static void gpio_latch_set_unlocked(struct gpio_latch_priv
*priv
,
75 void (*set
)(struct gpio_desc
*desc
, int value
),
76 unsigned int offset
, bool val
)
78 int latch
= offset
/ priv
->n_latched_gpios
;
81 assign_bit(offset
, priv
->shadow
, val
);
83 for (i
= 0; i
< priv
->n_latched_gpios
; i
++)
84 set(priv
->latched_gpios
->desc
[i
],
85 test_bit(latch
* priv
->n_latched_gpios
+ i
, priv
->shadow
));
87 ndelay(priv
->setup_duration_ns
);
88 set(priv
->clk_gpios
->desc
[latch
], 1);
89 ndelay(priv
->clock_duration_ns
);
90 set(priv
->clk_gpios
->desc
[latch
], 0);
93 static void gpio_latch_set(struct gpio_chip
*gc
, unsigned int offset
, int val
)
95 struct gpio_latch_priv
*priv
= gpiochip_get_data(gc
);
98 spin_lock_irqsave(&priv
->spinlock
, flags
);
100 gpio_latch_set_unlocked(priv
, gpiod_set_value
, offset
, val
);
102 spin_unlock_irqrestore(&priv
->spinlock
, flags
);
105 static void gpio_latch_set_can_sleep(struct gpio_chip
*gc
, unsigned int offset
, int val
)
107 struct gpio_latch_priv
*priv
= gpiochip_get_data(gc
);
109 mutex_lock(&priv
->mutex
);
111 gpio_latch_set_unlocked(priv
, gpiod_set_value_cansleep
, offset
, val
);
113 mutex_unlock(&priv
->mutex
);
116 static bool gpio_latch_can_sleep(struct gpio_latch_priv
*priv
, unsigned int n_latches
)
120 for (i
= 0; i
< n_latches
; i
++)
121 if (gpiod_cansleep(priv
->clk_gpios
->desc
[i
]))
124 for (i
= 0; i
< priv
->n_latched_gpios
; i
++)
125 if (gpiod_cansleep(priv
->latched_gpios
->desc
[i
]))
132 * Some value which is still acceptable to delay in atomic context.
133 * If we need to go higher we might have to switch to usleep_range(),
134 * but that cannot ne used in atomic context and the driver would have
135 * to be adjusted to support that.
137 #define DURATION_NS_MAX 5000
139 static int gpio_latch_probe(struct platform_device
*pdev
)
141 struct gpio_latch_priv
*priv
;
142 unsigned int n_latches
;
143 struct device_node
*np
= pdev
->dev
.of_node
;
145 priv
= devm_kzalloc(&pdev
->dev
, sizeof(*priv
), GFP_KERNEL
);
149 priv
->clk_gpios
= devm_gpiod_get_array(&pdev
->dev
, "clk", GPIOD_OUT_LOW
);
150 if (IS_ERR(priv
->clk_gpios
))
151 return PTR_ERR(priv
->clk_gpios
);
153 priv
->latched_gpios
= devm_gpiod_get_array(&pdev
->dev
, "latched", GPIOD_OUT_LOW
);
154 if (IS_ERR(priv
->latched_gpios
))
155 return PTR_ERR(priv
->latched_gpios
);
157 n_latches
= priv
->clk_gpios
->ndescs
;
158 priv
->n_latched_gpios
= priv
->latched_gpios
->ndescs
;
160 priv
->shadow
= devm_bitmap_zalloc(&pdev
->dev
, n_latches
* priv
->n_latched_gpios
,
165 if (gpio_latch_can_sleep(priv
, n_latches
)) {
166 priv
->gc
.can_sleep
= true;
167 priv
->gc
.set
= gpio_latch_set_can_sleep
;
168 mutex_init(&priv
->mutex
);
170 priv
->gc
.can_sleep
= false;
171 priv
->gc
.set
= gpio_latch_set
;
172 spin_lock_init(&priv
->spinlock
);
175 of_property_read_u32(np
, "setup-duration-ns", &priv
->setup_duration_ns
);
176 if (priv
->setup_duration_ns
> DURATION_NS_MAX
) {
177 dev_warn(&pdev
->dev
, "setup-duration-ns too high, limit to %d\n",
179 priv
->setup_duration_ns
= DURATION_NS_MAX
;
182 of_property_read_u32(np
, "clock-duration-ns", &priv
->clock_duration_ns
);
183 if (priv
->clock_duration_ns
> DURATION_NS_MAX
) {
184 dev_warn(&pdev
->dev
, "clock-duration-ns too high, limit to %d\n",
186 priv
->clock_duration_ns
= DURATION_NS_MAX
;
189 priv
->gc
.get_direction
= gpio_latch_get_direction
;
190 priv
->gc
.ngpio
= n_latches
* priv
->n_latched_gpios
;
191 priv
->gc
.owner
= THIS_MODULE
;
193 priv
->gc
.parent
= &pdev
->dev
;
195 platform_set_drvdata(pdev
, priv
);
197 return devm_gpiochip_add_data(&pdev
->dev
, &priv
->gc
, priv
);
200 static const struct of_device_id gpio_latch_ids
[] = {
202 .compatible
= "gpio-latch",
206 MODULE_DEVICE_TABLE(of
, gpio_latch_ids
);
208 static struct platform_driver gpio_latch_driver
= {
210 .name
= "gpio-latch",
211 .of_match_table
= gpio_latch_ids
,
213 .probe
= gpio_latch_probe
,
215 module_platform_driver(gpio_latch_driver
);
217 MODULE_LICENSE("GPL v2");
218 MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
219 MODULE_DESCRIPTION("GPIO latch driver");