1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Helpers for controlling modem lines via GPIO 4 * 5 * Copyright (C) 2014 Paratronic S.A. 6 */ 7 8 #include <linux/err.h> 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> 16 17 #include "serial_mctrl_gpio.h" 18 19 struct mctrl_gpios { 20 struct uart_port *port; 21 struct gpio_desc *gpio[UART_GPIO_MAX]; 22 int irq[UART_GPIO_MAX]; 23 unsigned int mctrl_prev; 24 bool mctrl_on; 25 }; 26 27 static const struct { 28 const char *name; 29 unsigned int mctrl; 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, }, 38 }; 39 40 static bool mctrl_gpio_flags_is_dir_out(unsigned int idx) 41 { 42 return mctrl_gpios_desc[idx].flags & GPIOD_FLAGS_BIT_DIR_OUT; 43 } 44 45 /** 46 * mctrl_gpio_set - set gpios according to mctrl state 47 * @gpios: gpios to set 48 * @mctrl: state to set 49 * 50 * Set the gpios according to the mctrl state. 51 */ 52 void mctrl_gpio_set(struct mctrl_gpios *gpios, unsigned int mctrl) 53 { 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; 58 59 if (gpios == NULL) 60 return; 61 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); 67 count++; 68 } 69 gpiod_set_array_value(count, desc_array, NULL, values); 70 } 71 EXPORT_SYMBOL_GPL(mctrl_gpio_set); 72 73 /** 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 78 */ 79 struct gpio_desc *mctrl_gpio_to_gpiod(struct mctrl_gpios *gpios, 80 enum mctrl_gpio_idx gidx) 81 { 82 if (gpios == NULL) 83 return NULL; 84 85 return gpios->gpio[gidx]; 86 } 87 EXPORT_SYMBOL_GPL(mctrl_gpio_to_gpiod); 88 89 /** 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) 94 * 95 * Update mctrl with the gpios values. 96 */ 97 unsigned int mctrl_gpio_get(struct mctrl_gpios *gpios, unsigned int *mctrl) 98 { 99 enum mctrl_gpio_idx i; 100 101 if (gpios == NULL) 102 return *mctrl; 103 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; 108 else 109 *mctrl &= ~mctrl_gpios_desc[i].mctrl; 110 } 111 } 112 113 return *mctrl; 114 } 115 EXPORT_SYMBOL_GPL(mctrl_gpio_get); 116 117 unsigned int 118 mctrl_gpio_get_outputs(struct mctrl_gpios *gpios, unsigned int *mctrl) 119 { 120 enum mctrl_gpio_idx i; 121 122 if (gpios == NULL) 123 return *mctrl; 124 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; 129 else 130 *mctrl &= ~mctrl_gpios_desc[i].mctrl; 131 } 132 } 133 134 return *mctrl; 135 } 136 EXPORT_SYMBOL_GPL(mctrl_gpio_get_outputs); 137 138 struct mctrl_gpios *mctrl_gpio_init_noauto(struct device *dev, unsigned int idx) 139 { 140 struct mctrl_gpios *gpios; 141 enum mctrl_gpio_idx i; 142 143 gpios = devm_kzalloc(dev, sizeof(*gpios), GFP_KERNEL); 144 if (!gpios) 145 return ERR_PTR(-ENOMEM); 146 147 for (i = 0; i < UART_GPIO_MAX; i++) { 148 char *gpio_str; 149 bool present; 150 151 /* Check if GPIO property exists and continue if not */ 152 gpio_str = kasprintf(GFP_KERNEL, "%s-gpios", 153 mctrl_gpios_desc[i].name); 154 if (!gpio_str) 155 continue; 156 157 present = device_property_present(dev, gpio_str); 158 kfree(gpio_str); 159 if (!present) 160 continue; 161 162 gpios->gpio[i] = 163 devm_gpiod_get_index_optional(dev, 164 mctrl_gpios_desc[i].name, 165 idx, 166 mctrl_gpios_desc[i].flags); 167 168 if (IS_ERR(gpios->gpio[i])) 169 return ERR_CAST(gpios->gpio[i]); 170 } 171 172 return gpios; 173 } 174 EXPORT_SYMBOL_GPL(mctrl_gpio_init_noauto); 175 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) 178 { 179 struct mctrl_gpios *gpios = context; 180 struct uart_port *port = gpios->port; 181 u32 mctrl = gpios->mctrl_prev; 182 u32 mctrl_diff; 183 unsigned long flags; 184 185 mctrl_gpio_get(gpios, &mctrl); 186 187 uart_port_lock_irqsave(port, &flags); 188 189 mctrl_diff = mctrl ^ gpios->mctrl_prev; 190 gpios->mctrl_prev = mctrl; 191 192 if (mctrl_diff & MCTRL_ANY_DELTA && port->state != NULL) { 193 if ((mctrl_diff & mctrl) & TIOCM_RI) 194 port->icount.rng++; 195 196 if ((mctrl_diff & mctrl) & TIOCM_DSR) 197 port->icount.dsr++; 198 199 if (mctrl_diff & TIOCM_CD) 200 uart_handle_dcd_change(port, mctrl & TIOCM_CD); 201 202 if (mctrl_diff & TIOCM_CTS) 203 uart_handle_cts_change(port, mctrl & TIOCM_CTS); 204 205 wake_up_interruptible(&port->state->port.delta_msr_wait); 206 } 207 208 uart_port_unlock_irqrestore(port, flags); 209 210 return IRQ_HANDLED; 211 } 212 213 /** 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 217 * 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. 223 */ 224 struct mctrl_gpios *mctrl_gpio_init(struct uart_port *port, unsigned int idx) 225 { 226 struct mctrl_gpios *gpios; 227 enum mctrl_gpio_idx i; 228 229 gpios = mctrl_gpio_init_noauto(port->dev, idx); 230 if (IS_ERR(gpios)) 231 return gpios; 232 233 gpios->port = port; 234 235 for (i = 0; i < UART_GPIO_MAX; ++i) { 236 int ret; 237 238 if (!gpios->gpio[i] || mctrl_gpio_flags_is_dir_out(i)) 239 continue; 240 241 ret = gpiod_to_irq(gpios->gpio[i]); 242 if (ret < 0) { 243 dev_err(port->dev, 244 "failed to find corresponding irq for %s (idx=%d, err=%d)\n", 245 mctrl_gpios_desc[i].name, idx, ret); 246 return ERR_PTR(ret); 247 } 248 gpios->irq[i] = ret; 249 250 /* irqs should only be enabled in .enable_ms */ 251 irq_set_status_flags(gpios->irq[i], IRQ_NOAUTOEN); 252 253 ret = devm_request_irq(port->dev, gpios->irq[i], 254 mctrl_gpio_irq_handle, 255 IRQ_TYPE_EDGE_BOTH, dev_name(port->dev), 256 gpios); 257 if (ret) { 258 /* alternatively implement polling */ 259 dev_err(port->dev, 260 "failed to request irq for %s (idx=%d, err=%d)\n", 261 mctrl_gpios_desc[i].name, idx, ret); 262 return ERR_PTR(ret); 263 } 264 } 265 266 return gpios; 267 } 268 EXPORT_SYMBOL_GPL(mctrl_gpio_init); 269 270 /** 271 * mctrl_gpio_free - explicitly free uart gpios 272 * @dev: uart port's device 273 * @gpios: gpios structure to be freed 274 * 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. 277 */ 278 void mctrl_gpio_free(struct device *dev, struct mctrl_gpios *gpios) 279 { 280 enum mctrl_gpio_idx i; 281 282 if (gpios == NULL) 283 return; 284 285 for (i = 0; i < UART_GPIO_MAX; i++) { 286 if (gpios->irq[i]) 287 devm_free_irq(gpios->port->dev, gpios->irq[i], gpios); 288 289 if (gpios->gpio[i]) 290 devm_gpiod_put(dev, gpios->gpio[i]); 291 } 292 devm_kfree(dev, gpios); 293 } 294 EXPORT_SYMBOL_GPL(mctrl_gpio_free); 295 296 /** 297 * mctrl_gpio_enable_ms - enable irqs and handling of changes to the ms lines 298 * @gpios: gpios to enable 299 */ 300 void mctrl_gpio_enable_ms(struct mctrl_gpios *gpios) 301 { 302 enum mctrl_gpio_idx i; 303 304 if (gpios == NULL) 305 return; 306 307 /* .enable_ms may be called multiple times */ 308 if (gpios->mctrl_on) 309 return; 310 311 gpios->mctrl_on = true; 312 313 /* get initial status of modem lines GPIOs */ 314 mctrl_gpio_get(gpios, &gpios->mctrl_prev); 315 316 for (i = 0; i < UART_GPIO_MAX; ++i) { 317 if (!gpios->irq[i]) 318 continue; 319 320 enable_irq(gpios->irq[i]); 321 } 322 } 323 EXPORT_SYMBOL_GPL(mctrl_gpio_enable_ms); 324 325 /** 326 * mctrl_gpio_disable_ms - disable irqs and handling of changes to the ms lines 327 * @gpios: gpios to disable 328 */ 329 void mctrl_gpio_disable_ms(struct mctrl_gpios *gpios) 330 { 331 enum mctrl_gpio_idx i; 332 333 if (gpios == NULL) 334 return; 335 336 if (!gpios->mctrl_on) 337 return; 338 339 gpios->mctrl_on = false; 340 341 for (i = 0; i < UART_GPIO_MAX; ++i) { 342 if (!gpios->irq[i]) 343 continue; 344 345 disable_irq(gpios->irq[i]); 346 } 347 } 348 EXPORT_SYMBOL_GPL(mctrl_gpio_disable_ms); 349 350 void mctrl_gpio_enable_irq_wake(struct mctrl_gpios *gpios) 351 { 352 enum mctrl_gpio_idx i; 353 354 if (!gpios) 355 return; 356 357 if (!gpios->mctrl_on) 358 return; 359 360 for (i = 0; i < UART_GPIO_MAX; ++i) { 361 if (!gpios->irq[i]) 362 continue; 363 364 enable_irq_wake(gpios->irq[i]); 365 } 366 } 367 EXPORT_SYMBOL_GPL(mctrl_gpio_enable_irq_wake); 368 369 void mctrl_gpio_disable_irq_wake(struct mctrl_gpios *gpios) 370 { 371 enum mctrl_gpio_idx i; 372 373 if (!gpios) 374 return; 375 376 if (!gpios->mctrl_on) 377 return; 378 379 for (i = 0; i < UART_GPIO_MAX; ++i) { 380 if (!gpios->irq[i]) 381 continue; 382 383 disable_irq_wake(gpios->irq[i]); 384 } 385 } 386 EXPORT_SYMBOL_GPL(mctrl_gpio_disable_irq_wake); 387 388 MODULE_DESCRIPTION("Helpers for controlling modem lines via GPIO"); 389 MODULE_LICENSE("GPL"); 390