1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0+ */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Helpers for controlling modem lines via GPIO
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright (C) 2014 Paratronic S.A.
6*4882a593Smuzhiyun */
7*4882a593Smuzhiyun
8*4882a593Smuzhiyun #ifndef __SERIAL_MCTRL_GPIO__
9*4882a593Smuzhiyun #define __SERIAL_MCTRL_GPIO__
10*4882a593Smuzhiyun
11*4882a593Smuzhiyun #include <linux/err.h>
12*4882a593Smuzhiyun #include <linux/device.h>
13*4882a593Smuzhiyun #include <linux/gpio/consumer.h>
14*4882a593Smuzhiyun
15*4882a593Smuzhiyun struct uart_port;
16*4882a593Smuzhiyun
17*4882a593Smuzhiyun enum mctrl_gpio_idx {
18*4882a593Smuzhiyun UART_GPIO_CTS,
19*4882a593Smuzhiyun UART_GPIO_DSR,
20*4882a593Smuzhiyun UART_GPIO_DCD,
21*4882a593Smuzhiyun UART_GPIO_RNG,
22*4882a593Smuzhiyun UART_GPIO_RI = UART_GPIO_RNG,
23*4882a593Smuzhiyun UART_GPIO_RTS,
24*4882a593Smuzhiyun UART_GPIO_DTR,
25*4882a593Smuzhiyun UART_GPIO_MAX,
26*4882a593Smuzhiyun };
27*4882a593Smuzhiyun
28*4882a593Smuzhiyun /*
29*4882a593Smuzhiyun * Opaque descriptor for modem lines controlled by GPIOs
30*4882a593Smuzhiyun */
31*4882a593Smuzhiyun struct mctrl_gpios;
32*4882a593Smuzhiyun
33*4882a593Smuzhiyun #ifdef CONFIG_GPIOLIB
34*4882a593Smuzhiyun
35*4882a593Smuzhiyun /*
36*4882a593Smuzhiyun * Set state of the modem control output lines via GPIOs.
37*4882a593Smuzhiyun */
38*4882a593Smuzhiyun void mctrl_gpio_set(struct mctrl_gpios *gpios, unsigned int mctrl);
39*4882a593Smuzhiyun
40*4882a593Smuzhiyun /*
41*4882a593Smuzhiyun * Get state of the modem control input lines from GPIOs.
42*4882a593Smuzhiyun * The mctrl flags are updated and returned.
43*4882a593Smuzhiyun */
44*4882a593Smuzhiyun unsigned int mctrl_gpio_get(struct mctrl_gpios *gpios, unsigned int *mctrl);
45*4882a593Smuzhiyun
46*4882a593Smuzhiyun /*
47*4882a593Smuzhiyun * Get state of the modem control output lines from GPIOs.
48*4882a593Smuzhiyun * The mctrl flags are updated and returned.
49*4882a593Smuzhiyun */
50*4882a593Smuzhiyun unsigned int
51*4882a593Smuzhiyun mctrl_gpio_get_outputs(struct mctrl_gpios *gpios, unsigned int *mctrl);
52*4882a593Smuzhiyun
53*4882a593Smuzhiyun /*
54*4882a593Smuzhiyun * Returns the associated struct gpio_desc to the modem line gidx
55*4882a593Smuzhiyun */
56*4882a593Smuzhiyun struct gpio_desc *mctrl_gpio_to_gpiod(struct mctrl_gpios *gpios,
57*4882a593Smuzhiyun enum mctrl_gpio_idx gidx);
58*4882a593Smuzhiyun
59*4882a593Smuzhiyun /*
60*4882a593Smuzhiyun * Request and set direction of modem control line GPIOs and set up irq
61*4882a593Smuzhiyun * handling.
62*4882a593Smuzhiyun * devm_* functions are used, so there's no need to call mctrl_gpio_free().
63*4882a593Smuzhiyun * Returns a pointer to the allocated mctrl structure if ok, -ENOMEM on
64*4882a593Smuzhiyun * allocation error.
65*4882a593Smuzhiyun */
66*4882a593Smuzhiyun struct mctrl_gpios *mctrl_gpio_init(struct uart_port *port, unsigned int idx);
67*4882a593Smuzhiyun
68*4882a593Smuzhiyun /*
69*4882a593Smuzhiyun * Request and set direction of modem control line GPIOs.
70*4882a593Smuzhiyun * devm_* functions are used, so there's no need to call mctrl_gpio_free().
71*4882a593Smuzhiyun * Returns a pointer to the allocated mctrl structure if ok, -ENOMEM on
72*4882a593Smuzhiyun * allocation error.
73*4882a593Smuzhiyun */
74*4882a593Smuzhiyun struct mctrl_gpios *mctrl_gpio_init_noauto(struct device *dev,
75*4882a593Smuzhiyun unsigned int idx);
76*4882a593Smuzhiyun
77*4882a593Smuzhiyun /*
78*4882a593Smuzhiyun * Free the mctrl_gpios structure.
79*4882a593Smuzhiyun * Normally, this function will not be called, as the GPIOs will
80*4882a593Smuzhiyun * be disposed of by the resource management code.
81*4882a593Smuzhiyun */
82*4882a593Smuzhiyun void mctrl_gpio_free(struct device *dev, struct mctrl_gpios *gpios);
83*4882a593Smuzhiyun
84*4882a593Smuzhiyun /*
85*4882a593Smuzhiyun * Enable gpio interrupts to report status line changes.
86*4882a593Smuzhiyun */
87*4882a593Smuzhiyun void mctrl_gpio_enable_ms(struct mctrl_gpios *gpios);
88*4882a593Smuzhiyun
89*4882a593Smuzhiyun /*
90*4882a593Smuzhiyun * Disable gpio interrupts to report status line changes.
91*4882a593Smuzhiyun */
92*4882a593Smuzhiyun void mctrl_gpio_disable_ms(struct mctrl_gpios *gpios);
93*4882a593Smuzhiyun
94*4882a593Smuzhiyun #else /* GPIOLIB */
95*4882a593Smuzhiyun
96*4882a593Smuzhiyun static inline
mctrl_gpio_set(struct mctrl_gpios * gpios,unsigned int mctrl)97*4882a593Smuzhiyun void mctrl_gpio_set(struct mctrl_gpios *gpios, unsigned int mctrl)
98*4882a593Smuzhiyun {
99*4882a593Smuzhiyun }
100*4882a593Smuzhiyun
101*4882a593Smuzhiyun static inline
mctrl_gpio_get(struct mctrl_gpios * gpios,unsigned int * mctrl)102*4882a593Smuzhiyun unsigned int mctrl_gpio_get(struct mctrl_gpios *gpios, unsigned int *mctrl)
103*4882a593Smuzhiyun {
104*4882a593Smuzhiyun return *mctrl;
105*4882a593Smuzhiyun }
106*4882a593Smuzhiyun
107*4882a593Smuzhiyun static inline unsigned int
mctrl_gpio_get_outputs(struct mctrl_gpios * gpios,unsigned int * mctrl)108*4882a593Smuzhiyun mctrl_gpio_get_outputs(struct mctrl_gpios *gpios, unsigned int *mctrl)
109*4882a593Smuzhiyun {
110*4882a593Smuzhiyun return *mctrl;
111*4882a593Smuzhiyun }
112*4882a593Smuzhiyun
113*4882a593Smuzhiyun static inline
mctrl_gpio_to_gpiod(struct mctrl_gpios * gpios,enum mctrl_gpio_idx gidx)114*4882a593Smuzhiyun struct gpio_desc *mctrl_gpio_to_gpiod(struct mctrl_gpios *gpios,
115*4882a593Smuzhiyun enum mctrl_gpio_idx gidx)
116*4882a593Smuzhiyun {
117*4882a593Smuzhiyun return NULL;
118*4882a593Smuzhiyun }
119*4882a593Smuzhiyun
120*4882a593Smuzhiyun static inline
mctrl_gpio_init(struct uart_port * port,unsigned int idx)121*4882a593Smuzhiyun struct mctrl_gpios *mctrl_gpio_init(struct uart_port *port, unsigned int idx)
122*4882a593Smuzhiyun {
123*4882a593Smuzhiyun return NULL;
124*4882a593Smuzhiyun }
125*4882a593Smuzhiyun
126*4882a593Smuzhiyun static inline
mctrl_gpio_init_noauto(struct device * dev,unsigned int idx)127*4882a593Smuzhiyun struct mctrl_gpios *mctrl_gpio_init_noauto(struct device *dev, unsigned int idx)
128*4882a593Smuzhiyun {
129*4882a593Smuzhiyun return NULL;
130*4882a593Smuzhiyun }
131*4882a593Smuzhiyun
132*4882a593Smuzhiyun static inline
mctrl_gpio_free(struct device * dev,struct mctrl_gpios * gpios)133*4882a593Smuzhiyun void mctrl_gpio_free(struct device *dev, struct mctrl_gpios *gpios)
134*4882a593Smuzhiyun {
135*4882a593Smuzhiyun }
136*4882a593Smuzhiyun
mctrl_gpio_enable_ms(struct mctrl_gpios * gpios)137*4882a593Smuzhiyun static inline void mctrl_gpio_enable_ms(struct mctrl_gpios *gpios)
138*4882a593Smuzhiyun {
139*4882a593Smuzhiyun }
140*4882a593Smuzhiyun
mctrl_gpio_disable_ms(struct mctrl_gpios * gpios)141*4882a593Smuzhiyun static inline void mctrl_gpio_disable_ms(struct mctrl_gpios *gpios)
142*4882a593Smuzhiyun {
143*4882a593Smuzhiyun }
144*4882a593Smuzhiyun
145*4882a593Smuzhiyun #endif /* GPIOLIB */
146*4882a593Smuzhiyun
147*4882a593Smuzhiyun #endif
148