Lines Matching +full:r9a07g044 +full:- +full:pinctrl
1 // SPDX-License-Identifier: GPL-2.0
21 #include <linux/pinctrl/consumer.h>
22 #include <linux/pinctrl/pinconf-generic.h>
23 #include <linux/pinctrl/pinconf.h>
24 #include <linux/pinctrl/pinctrl.h>
25 #include <linux/pinctrl/pinmux.h>
27 #include <dt-bindings/pinctrl/rzg2l-pinctrl.h>
33 #define DRV_NAME "pinctrl-rzg2l"
169 spin_lock_irqsave(&pctrl->lock, flags); in rzg2l_pinctrl_set_pfc_mode()
171 /* Set pin to 'Non-use (Hi-Z input protection)' */ in rzg2l_pinctrl_set_pfc_mode()
172 reg = readw(pctrl->base + PM(port)); in rzg2l_pinctrl_set_pfc_mode()
174 writew(reg, pctrl->base + PM(port)); in rzg2l_pinctrl_set_pfc_mode()
177 reg = readb(pctrl->base + PMC(port)); in rzg2l_pinctrl_set_pfc_mode()
178 writeb(reg & ~BIT(pin), pctrl->base + PMC(port)); in rzg2l_pinctrl_set_pfc_mode()
181 writel(0x0, pctrl->base + PWPR); /* B0WI=0, PFCWE=0 */ in rzg2l_pinctrl_set_pfc_mode()
182 writel(PWPR_PFCWE, pctrl->base + PWPR); /* B0WI=0, PFCWE=1 */ in rzg2l_pinctrl_set_pfc_mode()
185 reg = readl(pctrl->base + PFC(port)); in rzg2l_pinctrl_set_pfc_mode()
187 writel(reg | (func << (pin * 4)), pctrl->base + PFC(port)); in rzg2l_pinctrl_set_pfc_mode()
189 /* Set the PWPR register to be write-protected */ in rzg2l_pinctrl_set_pfc_mode()
190 writel(0x0, pctrl->base + PWPR); /* B0WI=0, PFCWE=0 */ in rzg2l_pinctrl_set_pfc_mode()
191 writel(PWPR_B0WI, pctrl->base + PWPR); /* B0WI=1, PFCWE=0 */ in rzg2l_pinctrl_set_pfc_mode()
194 reg = readb(pctrl->base + PMC(port)); in rzg2l_pinctrl_set_pfc_mode()
195 writeb(reg | BIT(pin), pctrl->base + PMC(port)); in rzg2l_pinctrl_set_pfc_mode()
197 spin_unlock_irqrestore(&pctrl->lock, flags); in rzg2l_pinctrl_set_pfc_mode()
212 return -EINVAL; in rzg2l_pinctrl_set_mux()
215 return -EINVAL; in rzg2l_pinctrl_set_mux()
217 psel_val = func->data; in rzg2l_pinctrl_set_mux()
218 pins = group->pins; in rzg2l_pinctrl_set_mux()
220 for (i = 0; i < group->num_pins; i++) { in rzg2l_pinctrl_set_mux()
221 dev_dbg(pctrl->dev, "port:%u pin: %u PSEL:%u\n", in rzg2l_pinctrl_set_mux()
242 return -ENOMEM; in rzg2l_map_add_config()
244 map->type = type; in rzg2l_map_add_config()
245 map->data.configs.group_or_pin = group_or_pin; in rzg2l_map_add_config()
246 map->data.configs.configs = cfgs; in rzg2l_map_add_config()
247 map->data.configs.num_configs = num_configs; in rzg2l_map_add_config()
277 num_pinmux = pinmux->length / sizeof(u32); in rzg2l_dt_subnode_to_map()
280 if (ret == -EINVAL) { in rzg2l_dt_subnode_to_map()
283 dev_err(pctrl->dev, "Invalid pins list in DT\n"); in rzg2l_dt_subnode_to_map()
293 dev_err(pctrl->dev, in rzg2l_dt_subnode_to_map()
295 return -EINVAL; in rzg2l_dt_subnode_to_map()
303 dev_err(pctrl->dev, "DT node must contain a config\n"); in rzg2l_dt_subnode_to_map()
304 ret = -ENODEV; in rzg2l_dt_subnode_to_map()
316 ret = -ENOMEM; in rzg2l_dt_subnode_to_map()
336 pins = devm_kcalloc(pctrl->dev, num_pinmux, sizeof(*pins), GFP_KERNEL); in rzg2l_dt_subnode_to_map()
337 psel_val = devm_kcalloc(pctrl->dev, num_pinmux, sizeof(*psel_val), in rzg2l_dt_subnode_to_map()
339 pin_fn = devm_kzalloc(pctrl->dev, sizeof(*pin_fn), GFP_KERNEL); in rzg2l_dt_subnode_to_map()
341 ret = -ENOMEM; in rzg2l_dt_subnode_to_map()
357 name = devm_kasprintf(pctrl->dev, GFP_KERNEL, "%pOFn.%pOFn", in rzg2l_dt_subnode_to_map()
360 ret = -ENOMEM; in rzg2l_dt_subnode_to_map()
364 name = np->name; in rzg2l_dt_subnode_to_map()
367 mutex_lock(&pctrl->mutex); in rzg2l_dt_subnode_to_map()
387 mutex_unlock(&pctrl->mutex); in rzg2l_dt_subnode_to_map()
394 dev_dbg(pctrl->dev, "Parsed %pOF with %d pins\n", np, num_pinmux); in rzg2l_dt_subnode_to_map()
401 mutex_unlock(&pctrl->mutex); in rzg2l_dt_subnode_to_map()
458 dev_err(pctrl->dev, "no mapping found in node %pOF\n", np); in rzg2l_dt_node_to_map()
459 ret = -EINVAL; in rzg2l_dt_node_to_map()
474 if (bit >= pincount || port >= pctrl->data->n_port_pins) in rzg2l_validate_gpio_pin()
475 return -EINVAL; in rzg2l_validate_gpio_pin()
477 data = pctrl->data->port_pin_configs[port]; in rzg2l_validate_gpio_pin()
479 return -EINVAL; in rzg2l_validate_gpio_pin()
487 void __iomem *addr = pctrl->base + offset; in rzg2l_read_pin_config()
489 /* handle _L/_H for 32-bit register read/write */ in rzg2l_read_pin_config()
491 bit -= 4; in rzg2l_read_pin_config()
501 void __iomem *addr = pctrl->base + offset; in rzg2l_rmw_pin_config()
505 /* handle _L/_H for 32-bit register read/write */ in rzg2l_rmw_pin_config()
507 bit -= 4; in rzg2l_rmw_pin_config()
511 spin_lock_irqsave(&pctrl->lock, flags); in rzg2l_rmw_pin_config()
514 spin_unlock_irqrestore(&pctrl->lock, flags); in rzg2l_rmw_pin_config()
523 const struct pinctrl_pin_desc *pin = &pctrl->desc.pins[_pin]; in rzg2l_pinctrl_pinconf_get()
524 unsigned int *pin_data = pin->drv_data; in rzg2l_pinctrl_pinconf_get()
533 return -EINVAL; in rzg2l_pinctrl_pinconf_get()
545 return -EINVAL; in rzg2l_pinctrl_pinconf_get()
551 return -EINVAL; in rzg2l_pinctrl_pinconf_get()
554 return -EINVAL; in rzg2l_pinctrl_pinconf_get()
567 return -EINVAL; in rzg2l_pinctrl_pinconf_get()
569 spin_lock_irqsave(&pctrl->lock, flags); in rzg2l_pinctrl_pinconf_get()
570 addr = pctrl->base + pwr_reg; in rzg2l_pinctrl_pinconf_get()
572 spin_unlock_irqrestore(&pctrl->lock, flags); in rzg2l_pinctrl_pinconf_get()
580 return -EINVAL; in rzg2l_pinctrl_pinconf_get()
591 return -EINVAL; in rzg2l_pinctrl_pinconf_get()
599 return -ENOTSUPP; in rzg2l_pinctrl_pinconf_get()
613 const struct pinctrl_pin_desc *pin = &pctrl->desc.pins[_pin]; in rzg2l_pinctrl_pinconf_set()
614 unsigned int *pin_data = pin->drv_data; in rzg2l_pinctrl_pinconf_set()
624 return -EINVAL; in rzg2l_pinctrl_pinconf_set()
636 return -EINVAL; in rzg2l_pinctrl_pinconf_set()
647 return -EINVAL; in rzg2l_pinctrl_pinconf_set()
658 return -EINVAL; in rzg2l_pinctrl_pinconf_set()
667 return -EINVAL; in rzg2l_pinctrl_pinconf_set()
669 addr = pctrl->base + pwr_reg; in rzg2l_pinctrl_pinconf_set()
670 spin_lock_irqsave(&pctrl->lock, flags); in rzg2l_pinctrl_pinconf_set()
672 spin_unlock_irqrestore(&pctrl->lock, flags); in rzg2l_pinctrl_pinconf_set()
681 return -EINVAL; in rzg2l_pinctrl_pinconf_set()
688 return -EINVAL; in rzg2l_pinctrl_pinconf_set()
699 return -EINVAL; in rzg2l_pinctrl_pinconf_set()
706 return -EINVAL; in rzg2l_pinctrl_pinconf_set()
713 return -EOPNOTSUPP; in rzg2l_pinctrl_pinconf_set()
762 return -EOPNOTSUPP; in rzg2l_pinctrl_pinconf_group_get()
804 ret = pinctrl_gpio_request(chip->base + offset); in rzg2l_gpio_request()
808 spin_lock_irqsave(&pctrl->lock, flags); in rzg2l_gpio_request()
811 reg8 = readb(pctrl->base + PMC(port)); in rzg2l_gpio_request()
813 writeb(reg8, pctrl->base + PMC(port)); in rzg2l_gpio_request()
815 spin_unlock_irqrestore(&pctrl->lock, flags); in rzg2l_gpio_request()
826 spin_lock_irqsave(&pctrl->lock, flags); in rzg2l_gpio_set_direction()
828 reg16 = readw(pctrl->base + PM(port)); in rzg2l_gpio_set_direction()
832 writew(reg16, pctrl->base + PM(port)); in rzg2l_gpio_set_direction()
834 spin_unlock_irqrestore(&pctrl->lock, flags); in rzg2l_gpio_set_direction()
843 if (!(readb(pctrl->base + PMC(port)) & BIT(bit))) { in rzg2l_gpio_get_direction()
846 reg16 = readw(pctrl->base + PM(port)); in rzg2l_gpio_get_direction()
876 spin_lock_irqsave(&pctrl->lock, flags); in rzg2l_gpio_set()
878 reg8 = readb(pctrl->base + P(port)); in rzg2l_gpio_set()
881 writeb(reg8 | BIT(bit), pctrl->base + P(port)); in rzg2l_gpio_set()
883 writeb(reg8 & ~BIT(bit), pctrl->base + P(port)); in rzg2l_gpio_set()
885 spin_unlock_irqrestore(&pctrl->lock, flags); in rzg2l_gpio_set()
908 reg16 = readw(pctrl->base + PM(port)); in rzg2l_gpio_get()
912 return !!(readb(pctrl->base + PIN(port)) & BIT(bit)); in rzg2l_gpio_get()
914 return !!(readb(pctrl->base + P(port)) & BIT(bit)); in rzg2l_gpio_get()
916 return -EINVAL; in rzg2l_gpio_get()
923 pinctrl_gpio_free(chip->base + offset); in rzg2l_gpio_free()
925 virq = irq_find_mapping(chip->irq.domain, offset); in rzg2l_gpio_free()
1157 if (port >= data->n_ports || in rzg2l_gpio_get_gpioint()
1158 bit >= RZG2L_GPIO_PORT_GET_PINCNT(data->port_pin_configs[port])) in rzg2l_gpio_get_gpioint()
1159 return -EINVAL; in rzg2l_gpio_get_gpioint()
1163 gpioint += RZG2L_GPIO_PORT_GET_PINCNT(data->port_pin_configs[i]); in rzg2l_gpio_get_gpioint()
1183 addr = pctrl->base + ISEL(port); in rzg2l_gpio_irq_disable()
1185 bit -= 4; in rzg2l_gpio_irq_disable()
1189 spin_lock_irqsave(&pctrl->lock, flags); in rzg2l_gpio_irq_disable()
1191 spin_unlock_irqrestore(&pctrl->lock, flags); in rzg2l_gpio_irq_disable()
1211 addr = pctrl->base + ISEL(port); in rzg2l_gpio_irq_enable()
1213 bit -= 4; in rzg2l_gpio_irq_enable()
1217 spin_lock_irqsave(&pctrl->lock, flags); in rzg2l_gpio_irq_enable()
1219 spin_unlock_irqrestore(&pctrl->lock, flags); in rzg2l_gpio_irq_enable()
1238 seq_printf(p, dev_name(gc->parent)); in rzg2l_gpio_irq_print_chip()
1242 .name = "rzg2l-gpio",
1264 gpioint = rzg2l_gpio_get_gpioint(child, pctrl->data); in rzg2l_gpio_child_to_parent_hwirq()
1268 spin_lock_irqsave(&pctrl->bitmap_lock, flags); in rzg2l_gpio_child_to_parent_hwirq()
1269 irq = bitmap_find_free_region(pctrl->tint_slot, RZG2L_TINT_MAX_INTERRUPT, get_order(1)); in rzg2l_gpio_child_to_parent_hwirq()
1270 spin_unlock_irqrestore(&pctrl->bitmap_lock, flags); in rzg2l_gpio_child_to_parent_hwirq()
1272 return -ENOSPC; in rzg2l_gpio_child_to_parent_hwirq()
1273 pctrl->hwirq[irq] = child; in rzg2l_gpio_child_to_parent_hwirq()
1287 struct irq_fwspec *fwspec = &gfwspec->fwspec; in rzg2l_gpio_populate_parent_fwspec()
1289 fwspec->fwnode = chip->irq.parent_domain->fwnode; in rzg2l_gpio_populate_parent_fwspec()
1290 fwspec->param_count = 2; in rzg2l_gpio_populate_parent_fwspec()
1291 fwspec->param[0] = parent_hwirq; in rzg2l_gpio_populate_parent_fwspec()
1292 fwspec->param[1] = parent_type; in rzg2l_gpio_populate_parent_fwspec()
1311 if (pctrl->hwirq[i] == hwirq) { in rzg2l_gpio_irq_domain_free()
1312 spin_lock_irqsave(&pctrl->bitmap_lock, flags); in rzg2l_gpio_irq_domain_free()
1313 bitmap_release_region(pctrl->tint_slot, i, get_order(1)); in rzg2l_gpio_irq_domain_free()
1314 spin_unlock_irqrestore(&pctrl->bitmap_lock, flags); in rzg2l_gpio_irq_domain_free()
1315 pctrl->hwirq[i] = 0; in rzg2l_gpio_irq_domain_free()
1328 struct gpio_chip *chip = &pctrl->gpio_chip; in rzg2l_init_irq_valid_mask()
1332 for (offset = 0; offset < chip->ngpio; offset++) { in rzg2l_init_irq_valid_mask()
1338 if (port >= pctrl->data->n_ports || in rzg2l_init_irq_valid_mask()
1339 bit >= RZG2L_GPIO_PORT_GET_PINCNT(pctrl->data->port_pin_configs[port])) in rzg2l_init_irq_valid_mask()
1346 struct device_node *np = pctrl->dev->of_node; in rzg2l_gpio_register()
1347 struct gpio_chip *chip = &pctrl->gpio_chip; in rzg2l_gpio_register()
1348 const char *name = dev_name(pctrl->dev); in rzg2l_gpio_register()
1357 return -ENXIO; in rzg2l_gpio_register()
1362 return -EPROBE_DEFER; in rzg2l_gpio_register()
1364 ret = of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3, 0, &of_args); in rzg2l_gpio_register()
1366 dev_err(pctrl->dev, "Unable to parse gpio-ranges\n"); in rzg2l_gpio_register()
1371 of_args.args[2] != pctrl->data->n_port_pins) { in rzg2l_gpio_register()
1372 dev_err(pctrl->dev, "gpio-ranges does not match selected SOC\n"); in rzg2l_gpio_register()
1373 return -EINVAL; in rzg2l_gpio_register()
1376 chip->names = pctrl->data->port_pins; in rzg2l_gpio_register()
1377 chip->request = rzg2l_gpio_request; in rzg2l_gpio_register()
1378 chip->free = rzg2l_gpio_free; in rzg2l_gpio_register()
1379 chip->get_direction = rzg2l_gpio_get_direction; in rzg2l_gpio_register()
1380 chip->direction_input = rzg2l_gpio_direction_input; in rzg2l_gpio_register()
1381 chip->direction_output = rzg2l_gpio_direction_output; in rzg2l_gpio_register()
1382 chip->get = rzg2l_gpio_get; in rzg2l_gpio_register()
1383 chip->set = rzg2l_gpio_set; in rzg2l_gpio_register()
1384 chip->label = name; in rzg2l_gpio_register()
1385 chip->parent = pctrl->dev; in rzg2l_gpio_register()
1386 chip->owner = THIS_MODULE; in rzg2l_gpio_register()
1387 chip->base = -1; in rzg2l_gpio_register()
1388 chip->ngpio = of_args.args[2]; in rzg2l_gpio_register()
1390 girq = &chip->irq; in rzg2l_gpio_register()
1392 girq->fwnode = of_node_to_fwnode(np); in rzg2l_gpio_register()
1393 girq->parent_domain = parent_domain; in rzg2l_gpio_register()
1394 girq->child_to_parent_hwirq = rzg2l_gpio_child_to_parent_hwirq; in rzg2l_gpio_register()
1395 girq->populate_parent_alloc_arg = rzg2l_gpio_populate_parent_fwspec; in rzg2l_gpio_register()
1396 girq->child_irq_domain_ops.free = rzg2l_gpio_irq_domain_free; in rzg2l_gpio_register()
1397 girq->init_valid_mask = rzg2l_init_irq_valid_mask; in rzg2l_gpio_register()
1399 pctrl->gpio_range.id = 0; in rzg2l_gpio_register()
1400 pctrl->gpio_range.pin_base = 0; in rzg2l_gpio_register()
1401 pctrl->gpio_range.base = 0; in rzg2l_gpio_register()
1402 pctrl->gpio_range.npins = chip->ngpio; in rzg2l_gpio_register()
1403 pctrl->gpio_range.name = chip->label; in rzg2l_gpio_register()
1404 pctrl->gpio_range.gc = chip; in rzg2l_gpio_register()
1405 ret = devm_gpiochip_add_data(pctrl->dev, chip, pctrl); in rzg2l_gpio_register()
1407 dev_err(pctrl->dev, "failed to add GPIO controller\n"); in rzg2l_gpio_register()
1411 dev_dbg(pctrl->dev, "Registered gpio controller\n"); in rzg2l_gpio_register()
1423 pctrl->desc.name = DRV_NAME; in rzg2l_pinctrl_register()
1424 pctrl->desc.npins = pctrl->data->n_port_pins + pctrl->data->n_dedicated_pins; in rzg2l_pinctrl_register()
1425 pctrl->desc.pctlops = &rzg2l_pinctrl_pctlops; in rzg2l_pinctrl_register()
1426 pctrl->desc.pmxops = &rzg2l_pinctrl_pmxops; in rzg2l_pinctrl_register()
1427 pctrl->desc.confops = &rzg2l_pinctrl_confops; in rzg2l_pinctrl_register()
1428 pctrl->desc.owner = THIS_MODULE; in rzg2l_pinctrl_register()
1430 pins = devm_kcalloc(pctrl->dev, pctrl->desc.npins, sizeof(*pins), GFP_KERNEL); in rzg2l_pinctrl_register()
1432 return -ENOMEM; in rzg2l_pinctrl_register()
1434 pin_data = devm_kcalloc(pctrl->dev, pctrl->desc.npins, in rzg2l_pinctrl_register()
1437 return -ENOMEM; in rzg2l_pinctrl_register()
1439 pctrl->pins = pins; in rzg2l_pinctrl_register()
1440 pctrl->desc.pins = pins; in rzg2l_pinctrl_register()
1442 for (i = 0, j = 0; i < pctrl->data->n_port_pins; i++) { in rzg2l_pinctrl_register()
1444 pins[i].name = pctrl->data->port_pins[i]; in rzg2l_pinctrl_register()
1447 pin_data[i] = pctrl->data->port_pin_configs[j]; in rzg2l_pinctrl_register()
1451 for (i = 0; i < pctrl->data->n_dedicated_pins; i++) { in rzg2l_pinctrl_register()
1452 unsigned int index = pctrl->data->n_port_pins + i; in rzg2l_pinctrl_register()
1455 pins[index].name = pctrl->data->dedicated_pins[i].name; in rzg2l_pinctrl_register()
1456 pin_data[index] = pctrl->data->dedicated_pins[i].config; in rzg2l_pinctrl_register()
1460 ret = devm_pinctrl_register_and_init(pctrl->dev, &pctrl->desc, pctrl, in rzg2l_pinctrl_register()
1461 &pctrl->pctl); in rzg2l_pinctrl_register()
1463 dev_err(pctrl->dev, "pinctrl registration failed\n"); in rzg2l_pinctrl_register()
1467 ret = pinctrl_enable(pctrl->pctl); in rzg2l_pinctrl_register()
1469 dev_err(pctrl->dev, "pinctrl enable failed\n"); in rzg2l_pinctrl_register()
1475 dev_err(pctrl->dev, "failed to add GPIO chip: %i\n", ret); in rzg2l_pinctrl_register()
1494 pctrl = devm_kzalloc(&pdev->dev, sizeof(*pctrl), GFP_KERNEL); in rzg2l_pinctrl_probe()
1496 return -ENOMEM; in rzg2l_pinctrl_probe()
1498 pctrl->dev = &pdev->dev; in rzg2l_pinctrl_probe()
1500 pctrl->data = of_device_get_match_data(&pdev->dev); in rzg2l_pinctrl_probe()
1501 if (!pctrl->data) in rzg2l_pinctrl_probe()
1502 return -EINVAL; in rzg2l_pinctrl_probe()
1504 pctrl->base = devm_platform_ioremap_resource(pdev, 0); in rzg2l_pinctrl_probe()
1505 if (IS_ERR(pctrl->base)) in rzg2l_pinctrl_probe()
1506 return PTR_ERR(pctrl->base); in rzg2l_pinctrl_probe()
1508 clk = devm_clk_get_enabled(pctrl->dev, NULL); in rzg2l_pinctrl_probe()
1510 return dev_err_probe(pctrl->dev, PTR_ERR(clk), in rzg2l_pinctrl_probe()
1513 spin_lock_init(&pctrl->lock); in rzg2l_pinctrl_probe()
1514 spin_lock_init(&pctrl->bitmap_lock); in rzg2l_pinctrl_probe()
1515 mutex_init(&pctrl->mutex); in rzg2l_pinctrl_probe()
1523 dev_info(pctrl->dev, "%s support registered\n", DRV_NAME); in rzg2l_pinctrl_probe()
1548 .compatible = "renesas,r9a07g043-pinctrl",
1552 .compatible = "renesas,r9a07g044-pinctrl",
1572 MODULE_AUTHOR("Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>");