1 // SPDX-License-Identifier: GPL-2.0+
3 * Helpers for controlling modem lines via GPIO
5 * Copyright (C) 2014 Paratronic S.A.
9 #include <linux/device.h>
10 #include <linux/irq.h>
11 #include <linux/gpio/consumer.h>
12 #include <linux/termios.h>
13 #include <linux/serial_core.h>
14 #include <linux/module.h>
15 #include <linux/property.h>
17 #include "serial_mctrl_gpio.h"
20 struct uart_port
*port
;
21 struct gpio_desc
*gpio
[UART_GPIO_MAX
];
22 int irq
[UART_GPIO_MAX
];
23 unsigned int mctrl_prev
;
30 enum gpiod_flags flags
;
31 } mctrl_gpios_desc
[UART_GPIO_MAX
] = {
32 { "cts", TIOCM_CTS
, GPIOD_IN
, },
33 { "dsr", TIOCM_DSR
, GPIOD_IN
, },
34 { "dcd", TIOCM_CD
, GPIOD_IN
, },
35 { "rng", TIOCM_RNG
, GPIOD_IN
, },
36 { "rts", TIOCM_RTS
, GPIOD_OUT_LOW
, },
37 { "dtr", TIOCM_DTR
, GPIOD_OUT_LOW
, },
40 static bool mctrl_gpio_flags_is_dir_out(unsigned int idx
)
42 return mctrl_gpios_desc
[idx
].flags
& GPIOD_FLAGS_BIT_DIR_OUT
;
46 * mctrl_gpio_set - set gpios according to mctrl state
47 * @gpios: gpios to set
48 * @mctrl: state to set
50 * Set the gpios according to the mctrl state.
52 void mctrl_gpio_set(struct mctrl_gpios
*gpios
, unsigned int mctrl
)
54 enum mctrl_gpio_idx i
;
55 struct gpio_desc
*desc_array
[UART_GPIO_MAX
];
56 DECLARE_BITMAP(values
, UART_GPIO_MAX
);
57 unsigned int count
= 0;
62 for (i
= 0; i
< UART_GPIO_MAX
; i
++)
63 if (gpios
->gpio
[i
] && mctrl_gpio_flags_is_dir_out(i
)) {
64 desc_array
[count
] = gpios
->gpio
[i
];
65 __assign_bit(count
, values
,
66 mctrl
& mctrl_gpios_desc
[i
].mctrl
);
69 gpiod_set_array_value(count
, desc_array
, NULL
, values
);
71 EXPORT_SYMBOL_GPL(mctrl_gpio_set
);
74 * mctrl_gpio_to_gpiod - obtain gpio_desc of modem line index
75 * @gpios: gpios to look into
76 * @gidx: index of the modem line
77 * Returns: the gpio_desc structure associated to the modem line index
79 struct gpio_desc
*mctrl_gpio_to_gpiod(struct mctrl_gpios
*gpios
,
80 enum mctrl_gpio_idx gidx
)
85 return gpios
->gpio
[gidx
];
87 EXPORT_SYMBOL_GPL(mctrl_gpio_to_gpiod
);
90 * mctrl_gpio_get - update mctrl with the gpios values.
91 * @gpios: gpios to get the info from
92 * @mctrl: mctrl to set
93 * Returns: modified mctrl (the same value as in @mctrl)
95 * Update mctrl with the gpios values.
97 unsigned int mctrl_gpio_get(struct mctrl_gpios
*gpios
, unsigned int *mctrl
)
99 enum mctrl_gpio_idx i
;
104 for (i
= 0; i
< UART_GPIO_MAX
; i
++) {
105 if (gpios
->gpio
[i
] && !mctrl_gpio_flags_is_dir_out(i
)) {
106 if (gpiod_get_value(gpios
->gpio
[i
]))
107 *mctrl
|= mctrl_gpios_desc
[i
].mctrl
;
109 *mctrl
&= ~mctrl_gpios_desc
[i
].mctrl
;
115 EXPORT_SYMBOL_GPL(mctrl_gpio_get
);
118 mctrl_gpio_get_outputs(struct mctrl_gpios
*gpios
, unsigned int *mctrl
)
120 enum mctrl_gpio_idx i
;
125 for (i
= 0; i
< UART_GPIO_MAX
; i
++) {
126 if (gpios
->gpio
[i
] && mctrl_gpio_flags_is_dir_out(i
)) {
127 if (gpiod_get_value(gpios
->gpio
[i
]))
128 *mctrl
|= mctrl_gpios_desc
[i
].mctrl
;
130 *mctrl
&= ~mctrl_gpios_desc
[i
].mctrl
;
136 EXPORT_SYMBOL_GPL(mctrl_gpio_get_outputs
);
138 struct mctrl_gpios
*mctrl_gpio_init_noauto(struct device
*dev
, unsigned int idx
)
140 struct mctrl_gpios
*gpios
;
141 enum mctrl_gpio_idx i
;
143 gpios
= devm_kzalloc(dev
, sizeof(*gpios
), GFP_KERNEL
);
145 return ERR_PTR(-ENOMEM
);
147 for (i
= 0; i
< UART_GPIO_MAX
; i
++) {
151 /* Check if GPIO property exists and continue if not */
152 gpio_str
= kasprintf(GFP_KERNEL
, "%s-gpios",
153 mctrl_gpios_desc
[i
].name
);
157 present
= device_property_present(dev
, gpio_str
);
163 devm_gpiod_get_index_optional(dev
,
164 mctrl_gpios_desc
[i
].name
,
166 mctrl_gpios_desc
[i
].flags
);
168 if (IS_ERR(gpios
->gpio
[i
]))
169 return ERR_CAST(gpios
->gpio
[i
]);
174 EXPORT_SYMBOL_GPL(mctrl_gpio_init_noauto
);
176 #define MCTRL_ANY_DELTA (TIOCM_RI | TIOCM_DSR | TIOCM_CD | TIOCM_CTS)
177 static irqreturn_t
mctrl_gpio_irq_handle(int irq
, void *context
)
179 struct mctrl_gpios
*gpios
= context
;
180 struct uart_port
*port
= gpios
->port
;
181 u32 mctrl
= gpios
->mctrl_prev
;
185 mctrl_gpio_get(gpios
, &mctrl
);
187 uart_port_lock_irqsave(port
, &flags
);
189 mctrl_diff
= mctrl
^ gpios
->mctrl_prev
;
190 gpios
->mctrl_prev
= mctrl
;
192 if (mctrl_diff
& MCTRL_ANY_DELTA
&& port
->state
!= NULL
) {
193 if ((mctrl_diff
& mctrl
) & TIOCM_RI
)
196 if ((mctrl_diff
& mctrl
) & TIOCM_DSR
)
199 if (mctrl_diff
& TIOCM_CD
)
200 uart_handle_dcd_change(port
, mctrl
& TIOCM_CD
);
202 if (mctrl_diff
& TIOCM_CTS
)
203 uart_handle_cts_change(port
, mctrl
& TIOCM_CTS
);
205 wake_up_interruptible(&port
->state
->port
.delta_msr_wait
);
208 uart_port_unlock_irqrestore(port
, flags
);
214 * mctrl_gpio_init - initialize uart gpios
215 * @port: port to initialize gpios for
216 * @idx: index of the gpio in the @port's device
218 * This will get the {cts,rts,...}-gpios from device tree if they are present
219 * and request them, set direction etc, and return an allocated structure.
220 * `devm_*` functions are used, so there's no need to call mctrl_gpio_free().
221 * As this sets up the irq handling, make sure to not handle changes to the
222 * gpio input lines in your driver, too.
224 struct mctrl_gpios
*mctrl_gpio_init(struct uart_port
*port
, unsigned int idx
)
226 struct mctrl_gpios
*gpios
;
227 enum mctrl_gpio_idx i
;
229 gpios
= mctrl_gpio_init_noauto(port
->dev
, idx
);
235 for (i
= 0; i
< UART_GPIO_MAX
; ++i
) {
238 if (!gpios
->gpio
[i
] || mctrl_gpio_flags_is_dir_out(i
))
241 ret
= gpiod_to_irq(gpios
->gpio
[i
]);
244 "failed to find corresponding irq for %s (idx=%d, err=%d)\n",
245 mctrl_gpios_desc
[i
].name
, idx
, ret
);
250 /* irqs should only be enabled in .enable_ms */
251 irq_set_status_flags(gpios
->irq
[i
], IRQ_NOAUTOEN
);
253 ret
= devm_request_irq(port
->dev
, gpios
->irq
[i
],
254 mctrl_gpio_irq_handle
,
255 IRQ_TYPE_EDGE_BOTH
, dev_name(port
->dev
),
258 /* alternatively implement polling */
260 "failed to request irq for %s (idx=%d, err=%d)\n",
261 mctrl_gpios_desc
[i
].name
, idx
, ret
);
268 EXPORT_SYMBOL_GPL(mctrl_gpio_init
);
271 * mctrl_gpio_free - explicitly free uart gpios
272 * @dev: uart port's device
273 * @gpios: gpios structure to be freed
275 * This will free the requested gpios in mctrl_gpio_init(). As `devm_*`
276 * functions are used, there's generally no need to call this function.
278 void mctrl_gpio_free(struct device
*dev
, struct mctrl_gpios
*gpios
)
280 enum mctrl_gpio_idx i
;
285 for (i
= 0; i
< UART_GPIO_MAX
; i
++) {
287 devm_free_irq(gpios
->port
->dev
, gpios
->irq
[i
], gpios
);
290 devm_gpiod_put(dev
, gpios
->gpio
[i
]);
292 devm_kfree(dev
, gpios
);
294 EXPORT_SYMBOL_GPL(mctrl_gpio_free
);
297 * mctrl_gpio_enable_ms - enable irqs and handling of changes to the ms lines
298 * @gpios: gpios to enable
300 void mctrl_gpio_enable_ms(struct mctrl_gpios
*gpios
)
302 enum mctrl_gpio_idx i
;
307 /* .enable_ms may be called multiple times */
311 gpios
->mctrl_on
= true;
313 /* get initial status of modem lines GPIOs */
314 mctrl_gpio_get(gpios
, &gpios
->mctrl_prev
);
316 for (i
= 0; i
< UART_GPIO_MAX
; ++i
) {
320 enable_irq(gpios
->irq
[i
]);
323 EXPORT_SYMBOL_GPL(mctrl_gpio_enable_ms
);
326 * mctrl_gpio_disable_ms - disable irqs and handling of changes to the ms lines
327 * @gpios: gpios to disable
329 void mctrl_gpio_disable_ms(struct mctrl_gpios
*gpios
)
331 enum mctrl_gpio_idx i
;
336 if (!gpios
->mctrl_on
)
339 gpios
->mctrl_on
= false;
341 for (i
= 0; i
< UART_GPIO_MAX
; ++i
) {
345 disable_irq(gpios
->irq
[i
]);
348 EXPORT_SYMBOL_GPL(mctrl_gpio_disable_ms
);
350 void mctrl_gpio_enable_irq_wake(struct mctrl_gpios
*gpios
)
352 enum mctrl_gpio_idx i
;
357 if (!gpios
->mctrl_on
)
360 for (i
= 0; i
< UART_GPIO_MAX
; ++i
) {
364 enable_irq_wake(gpios
->irq
[i
]);
367 EXPORT_SYMBOL_GPL(mctrl_gpio_enable_irq_wake
);
369 void mctrl_gpio_disable_irq_wake(struct mctrl_gpios
*gpios
)
371 enum mctrl_gpio_idx i
;
376 if (!gpios
->mctrl_on
)
379 for (i
= 0; i
< UART_GPIO_MAX
; ++i
) {
383 disable_irq_wake(gpios
->irq
[i
]);
386 EXPORT_SYMBOL_GPL(mctrl_gpio_disable_irq_wake
);
388 MODULE_DESCRIPTION("Helpers for controlling modem lines via GPIO");
389 MODULE_LICENSE("GPL");