Lines Matching +full:rcar +full:- +full:gen2 +full:- +full:gpio
1 // SPDX-License-Identifier: GPL-2.0
3 * Renesas R-Car GPIO Support
10 #include <linux/gpio/driver.h>
66 return ioread32(p->base + offs); in gpio_rcar_read()
72 iowrite32(value, p->base + offs); in gpio_rcar_write()
112 /* follow steps in the GPIO documentation for in gpio_rcar_config_interrupt_input_mode()
113 * "Setting Edge-Sensitive Interrupt Input Mode" and in gpio_rcar_config_interrupt_input_mode()
114 * "Setting Level-Sensitive Interrupt Input Mode" in gpio_rcar_config_interrupt_input_mode()
117 spin_lock_irqsave(&p->lock, flags); in gpio_rcar_config_interrupt_input_mode()
126 if (p->has_both_edge_trigger) in gpio_rcar_config_interrupt_input_mode()
136 spin_unlock_irqrestore(&p->lock, flags); in gpio_rcar_config_interrupt_input_mode()
145 dev_dbg(p->dev, "sense irq = %d, type = %d\n", hwirq, type); in gpio_rcar_irq_set_type()
165 if (!p->has_both_edge_trigger) in gpio_rcar_irq_set_type()
166 return -EINVAL; in gpio_rcar_irq_set_type()
171 return -EINVAL; in gpio_rcar_irq_set_type()
182 if (p->irq_parent) { in gpio_rcar_irq_set_wake()
183 error = irq_set_irq_wake(p->irq_parent, on); in gpio_rcar_irq_set_wake()
185 dev_dbg(p->dev, "irq %u doesn't support irq_set_wake\n", in gpio_rcar_irq_set_wake()
186 p->irq_parent); in gpio_rcar_irq_set_wake()
187 p->irq_parent = 0; in gpio_rcar_irq_set_wake()
192 atomic_inc(&p->wakeup_path); in gpio_rcar_irq_set_wake()
194 atomic_dec(&p->wakeup_path); in gpio_rcar_irq_set_wake()
209 generic_handle_irq(irq_find_mapping(p->gpio_chip.irq.domain, in gpio_rcar_irq_handler()
218 unsigned int gpio, in gpio_rcar_config_general_input_output_mode() argument
224 /* follow steps in the GPIO documentation for in gpio_rcar_config_general_input_output_mode()
229 spin_lock_irqsave(&p->lock, flags); in gpio_rcar_config_general_input_output_mode()
232 gpio_rcar_modify_bit(p, POSNEG, gpio, false); in gpio_rcar_config_general_input_output_mode()
235 gpio_rcar_modify_bit(p, IOINTSEL, gpio, false); in gpio_rcar_config_general_input_output_mode()
238 gpio_rcar_modify_bit(p, INOUTSEL, gpio, output); in gpio_rcar_config_general_input_output_mode()
241 if (p->has_outdtsel && output) in gpio_rcar_config_general_input_output_mode()
242 gpio_rcar_modify_bit(p, OUTDTSEL, gpio, false); in gpio_rcar_config_general_input_output_mode()
244 spin_unlock_irqrestore(&p->lock, flags); in gpio_rcar_config_general_input_output_mode()
252 error = pm_runtime_get_sync(p->dev); in gpio_rcar_request()
254 pm_runtime_put(p->dev); in gpio_rcar_request()
258 error = pinctrl_gpio_request(chip->base + offset); in gpio_rcar_request()
260 pm_runtime_put(p->dev); in gpio_rcar_request()
269 pinctrl_gpio_free(chip->base + offset); in gpio_rcar_free()
272 * Set the GPIO as an input to ensure that the next GPIO request won't in gpio_rcar_free()
273 * drive the GPIO pin as an output. in gpio_rcar_free()
277 pm_runtime_put(p->dev); in gpio_rcar_free()
313 spin_lock_irqsave(&p->lock, flags); in gpio_rcar_set()
315 spin_unlock_irqrestore(&p->lock, flags); in gpio_rcar_set()
325 bankmask = mask[0] & GENMASK(chip->ngpio - 1, 0); in gpio_rcar_set_multiple()
326 if (chip->valid_mask) in gpio_rcar_set_multiple()
327 bankmask &= chip->valid_mask[0]; in gpio_rcar_set_multiple()
332 spin_lock_irqsave(&p->lock, flags); in gpio_rcar_set_multiple()
337 spin_unlock_irqrestore(&p->lock, flags); in gpio_rcar_set_multiple()
343 /* write GPIO value to output before selecting output mode of pin */ in gpio_rcar_direction_output()
366 .compatible = "renesas,gpio-r8a7743",
367 /* RZ/G1 GPIO is identical to R-Car Gen2. */
370 .compatible = "renesas,gpio-r8a7790",
373 .compatible = "renesas,gpio-r8a7791",
376 .compatible = "renesas,gpio-r8a7792",
379 .compatible = "renesas,gpio-r8a7793",
382 .compatible = "renesas,gpio-r8a7794",
385 .compatible = "renesas,gpio-r8a7795",
386 /* Gen3 GPIO is identical to Gen2. */
389 .compatible = "renesas,gpio-r8a7796",
390 /* Gen3 GPIO is identical to Gen2. */
393 .compatible = "renesas,rcar-gen1-gpio",
396 .compatible = "renesas,rcar-gen2-gpio",
399 .compatible = "renesas,rcar-gen3-gpio",
400 /* Gen3 GPIO is identical to Gen2. */
403 .compatible = "renesas,gpio-rcar",
414 struct device_node *np = p->dev->of_node; in gpio_rcar_parse_dt()
419 info = of_device_get_match_data(p->dev); in gpio_rcar_parse_dt()
420 p->has_outdtsel = info->has_outdtsel; in gpio_rcar_parse_dt()
421 p->has_both_edge_trigger = info->has_both_edge_trigger; in gpio_rcar_parse_dt()
423 ret = of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3, 0, &args); in gpio_rcar_parse_dt()
427 dev_warn(p->dev, "Invalid number of gpio lines %u, using %u\n", in gpio_rcar_parse_dt()
442 struct device *dev = &pdev->dev; in gpio_rcar_probe()
449 return -ENOMEM; in gpio_rcar_probe()
451 p->dev = dev; in gpio_rcar_probe()
452 spin_lock_init(&p->lock); in gpio_rcar_probe()
466 ret = -EINVAL; in gpio_rcar_probe()
470 p->base = devm_platform_ioremap_resource(pdev, 0); in gpio_rcar_probe()
471 if (IS_ERR(p->base)) { in gpio_rcar_probe()
472 ret = PTR_ERR(p->base); in gpio_rcar_probe()
476 gpio_chip = &p->gpio_chip; in gpio_rcar_probe()
477 gpio_chip->request = gpio_rcar_request; in gpio_rcar_probe()
478 gpio_chip->free = gpio_rcar_free; in gpio_rcar_probe()
479 gpio_chip->get_direction = gpio_rcar_get_direction; in gpio_rcar_probe()
480 gpio_chip->direction_input = gpio_rcar_direction_input; in gpio_rcar_probe()
481 gpio_chip->get = gpio_rcar_get; in gpio_rcar_probe()
482 gpio_chip->direction_output = gpio_rcar_direction_output; in gpio_rcar_probe()
483 gpio_chip->set = gpio_rcar_set; in gpio_rcar_probe()
484 gpio_chip->set_multiple = gpio_rcar_set_multiple; in gpio_rcar_probe()
485 gpio_chip->label = name; in gpio_rcar_probe()
486 gpio_chip->parent = dev; in gpio_rcar_probe()
487 gpio_chip->owner = THIS_MODULE; in gpio_rcar_probe()
488 gpio_chip->base = -1; in gpio_rcar_probe()
489 gpio_chip->ngpio = npins; in gpio_rcar_probe()
491 irq_chip = &p->irq_chip; in gpio_rcar_probe()
492 irq_chip->name = "gpio-rcar"; in gpio_rcar_probe()
493 irq_chip->parent_device = dev; in gpio_rcar_probe()
494 irq_chip->irq_mask = gpio_rcar_irq_disable; in gpio_rcar_probe()
495 irq_chip->irq_unmask = gpio_rcar_irq_enable; in gpio_rcar_probe()
496 irq_chip->irq_set_type = gpio_rcar_irq_set_type; in gpio_rcar_probe()
497 irq_chip->irq_set_wake = gpio_rcar_irq_set_wake; in gpio_rcar_probe()
498 irq_chip->flags = IRQCHIP_SET_TYPE_MASKED | IRQCHIP_MASK_ON_SUSPEND; in gpio_rcar_probe()
500 girq = &gpio_chip->irq; in gpio_rcar_probe()
501 girq->chip = irq_chip; in gpio_rcar_probe()
503 girq->parent_handler = NULL; in gpio_rcar_probe()
504 girq->num_parents = 0; in gpio_rcar_probe()
505 girq->parents = NULL; in gpio_rcar_probe()
506 girq->default_type = IRQ_TYPE_NONE; in gpio_rcar_probe()
507 girq->handler = handle_level_irq; in gpio_rcar_probe()
511 dev_err(dev, "failed to add GPIO controller\n"); in gpio_rcar_probe()
515 p->irq_parent = irq->start; in gpio_rcar_probe()
516 if (devm_request_irq(dev, irq->start, gpio_rcar_irq_handler, in gpio_rcar_probe()
519 ret = -ENOENT; in gpio_rcar_probe()
538 gpiochip_remove(&p->gpio_chip); in gpio_rcar_remove()
540 pm_runtime_disable(&pdev->dev); in gpio_rcar_remove()
549 p->bank_info.iointsel = gpio_rcar_read(p, IOINTSEL); in gpio_rcar_suspend()
550 p->bank_info.inoutsel = gpio_rcar_read(p, INOUTSEL); in gpio_rcar_suspend()
551 p->bank_info.outdt = gpio_rcar_read(p, OUTDT); in gpio_rcar_suspend()
552 p->bank_info.intmsk = gpio_rcar_read(p, INTMSK); in gpio_rcar_suspend()
553 p->bank_info.posneg = gpio_rcar_read(p, POSNEG); in gpio_rcar_suspend()
554 p->bank_info.edglevel = gpio_rcar_read(p, EDGLEVEL); in gpio_rcar_suspend()
555 if (p->has_both_edge_trigger) in gpio_rcar_suspend()
556 p->bank_info.bothedge = gpio_rcar_read(p, BOTHEDGE); in gpio_rcar_suspend()
558 if (atomic_read(&p->wakeup_path)) in gpio_rcar_suspend()
570 for (offset = 0; offset < p->gpio_chip.ngpio; offset++) { in gpio_rcar_resume()
571 if (!gpiochip_line_is_valid(&p->gpio_chip, offset)) in gpio_rcar_resume()
576 if (!(p->bank_info.iointsel & mask)) { in gpio_rcar_resume()
577 if (p->bank_info.inoutsel & mask) in gpio_rcar_resume()
579 &p->gpio_chip, offset, in gpio_rcar_resume()
580 !!(p->bank_info.outdt & mask)); in gpio_rcar_resume()
582 gpio_rcar_direction_input(&p->gpio_chip, in gpio_rcar_resume()
589 !(p->bank_info.posneg & mask), in gpio_rcar_resume()
590 !(p->bank_info.edglevel & mask), in gpio_rcar_resume()
591 !!(p->bank_info.bothedge & mask)); in gpio_rcar_resume()
593 if (p->bank_info.intmsk & mask) in gpio_rcar_resume()
617 MODULE_DESCRIPTION("Renesas R-Car GPIO Driver");