Lines Matching +full:gpio1 +full:- +full:cfg
1 // SPDX-License-Identifier: GPL-2.0
12 #include <linux/pinctrl/pinconf-generic.h>
61 * struct keembay_mux_desc - Mux properties of each GPIO pin
83 * struct keembay_gpio_irq - Config of each GPIO Interrupt sources
84 * @source: Interrupt source number (0 - 7)
99 * struct keembay_pinctrl - Intel Keembay pinctrl structure
131 * struct keembay_pin_soc - Pin control config data based on SoC
148 KEEMBAY_PIN_DESC(1, "GPIO1",
890 unsigned int val = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_MODE, pin); in keembay_gpio_invert()
899 keembay_write_reg(val, kpc->base1 + KEEMBAY_GPIO_MODE, pin); in keembay_gpio_invert()
904 unsigned int val = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_MODE, pin); in keembay_gpio_restore_default()
907 keembay_write_reg(val, kpc->base1 + KEEMBAY_GPIO_MODE, pin); in keembay_gpio_restore_default()
916 if (pin >= kpc->npins) in keembay_request_gpio()
917 return -EINVAL; in keembay_request_gpio()
919 val = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_MODE, pin); in keembay_request_gpio()
924 return -EBUSY; in keembay_request_gpio()
941 return -EINVAL; in keembay_set_mux()
945 return -EINVAL; in keembay_set_mux()
948 pin = *grp->grp.pins; in keembay_set_mux()
949 pin_mode = *(u8 *)(func->data); in keembay_set_mux()
951 val = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_MODE, pin); in keembay_set_mux()
953 keembay_write_reg(val, kpc->base1 + KEEMBAY_GPIO_MODE, pin); in keembay_set_mux()
960 unsigned int val = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_MODE, pin); in keembay_pinconf_get_pull()
968 unsigned int val = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_MODE, pin); in keembay_pinconf_set_pull()
971 keembay_write_reg(val, kpc->base1 + KEEMBAY_GPIO_MODE, pin); in keembay_pinconf_set_pull()
978 unsigned int val = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_MODE, pin); in keembay_pinconf_get_drive()
990 unsigned int val = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_MODE, pin); in keembay_pinconf_set_drive()
995 keembay_write_reg(val, kpc->base1 + KEEMBAY_GPIO_MODE, pin); in keembay_pinconf_set_drive()
1002 unsigned int val = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_MODE, pin); in keembay_pinconf_get_slew_rate()
1010 unsigned int val = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_MODE, pin); in keembay_pinconf_set_slew_rate()
1017 keembay_write_reg(val, kpc->base1 + KEEMBAY_GPIO_MODE, pin); in keembay_pinconf_set_slew_rate()
1024 unsigned int val = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_MODE, pin); in keembay_pinconf_get_schmitt()
1032 unsigned int val = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_MODE, pin); in keembay_pinconf_set_schmitt()
1039 keembay_write_reg(val, kpc->base1 + KEEMBAY_GPIO_MODE, pin); in keembay_pinconf_set_schmitt()
1045 unsigned long *cfg) in keembay_pinconf_get() argument
1048 unsigned int param = pinconf_to_config_param(*cfg); in keembay_pinconf_get()
1051 if (pin >= kpc->npins) in keembay_pinconf_get()
1052 return -EINVAL; in keembay_pinconf_get()
1057 return -EINVAL; in keembay_pinconf_get()
1062 return -EINVAL; in keembay_pinconf_get()
1067 return -EINVAL; in keembay_pinconf_get()
1072 return -EINVAL; in keembay_pinconf_get()
1077 return -EINVAL; in keembay_pinconf_get()
1082 *cfg = pinconf_to_config_packed(param, val); in keembay_pinconf_get()
1087 *cfg = pinconf_to_config_packed(param, val); in keembay_pinconf_get()
1091 return -ENOTSUPP; in keembay_pinconf_get()
1098 unsigned long *cfg, unsigned int num_configs) in keembay_pinconf_set() argument
1105 if (pin >= kpc->npins) in keembay_pinconf_set()
1106 return -EINVAL; in keembay_pinconf_set()
1109 param = pinconf_to_config_param(cfg[i]); in keembay_pinconf_set()
1110 arg = pinconf_to_config_argument(cfg[i]); in keembay_pinconf_set()
1142 return -ENOTSUPP; in keembay_pinconf_set()
1173 .name = "keembay-pinmux",
1185 val = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_MODE, pin); in keembay_gpio_get()
1188 return keembay_read_pin(kpc->base0 + offset, pin); in keembay_gpio_get()
1196 reg_val = keembay_read_gpio_reg(kpc->base0 + KEEMBAY_GPIO_DATA_OUT, pin); in keembay_gpio_set()
1199 kpc->base0 + KEEMBAY_GPIO_DATA_HIGH, pin); in keembay_gpio_set()
1202 kpc->base0 + KEEMBAY_GPIO_DATA_LOW, pin); in keembay_gpio_set()
1208 unsigned int val = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_MODE, pin); in keembay_gpio_get_direction()
1218 val = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_MODE, pin); in keembay_gpio_set_direction_in()
1220 keembay_write_reg(val, kpc->base1 + KEEMBAY_GPIO_MODE, pin); in keembay_gpio_set_direction_in()
1231 val = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_MODE, pin); in keembay_gpio_set_direction_out()
1233 keembay_write_reg(val, kpc->base1 + KEEMBAY_GPIO_MODE, pin); in keembay_gpio_set_direction_out()
1250 if (kmb_irq == gc->irq.parents[src]) in keembay_gpio_irq_handler()
1261 reg = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_INT_CFG, src); in keembay_gpio_irq_handler()
1270 val = keembay_read_pin(kpc->base0 + KEEMBAY_GPIO_DATA_IN, pin); in keembay_gpio_irq_handler()
1271 kmb_irq = irq_linear_revmap(gc->irq.domain, pin); in keembay_gpio_irq_handler()
1286 struct keembay_gpio_irq *irq = &kpc->irq[src]; in keembay_gpio_clear_irq()
1294 val = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_INT_CFG, src); in keembay_gpio_clear_irq()
1297 keembay_write_reg(val, kpc->base1 + KEEMBAY_GPIO_INT_CFG, src); in keembay_gpio_clear_irq()
1299 irq->num_share--; in keembay_gpio_clear_irq()
1300 irq->pins[pos / KEEMBAY_GPIO_NUM_IRQ] = 0; in keembay_gpio_clear_irq()
1305 if (irq->trigger == IRQ_TYPE_LEVEL_HIGH) in keembay_gpio_clear_irq()
1306 kpc->max_gpios_level_type++; in keembay_gpio_clear_irq()
1307 else if (irq->trigger == IRQ_TYPE_EDGE_RISING) in keembay_gpio_clear_irq()
1308 kpc->max_gpios_edge_type++; in keembay_gpio_clear_irq()
1313 unsigned long val = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_INT_CFG, src); in keembay_find_free_slot()
1328 if (kpc->irq[src].trigger != type) in keembay_find_free_src()
1331 if (!keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_INT_CFG, src) || in keembay_find_free_src()
1332 kpc->irq[src].num_share < KEEMBAY_GPIO_MAX_PER_IRQ) in keembay_find_free_src()
1336 return -EBUSY; in keembay_find_free_src()
1343 struct keembay_gpio_irq *irq = &kpc->irq[src]; in keembay_gpio_set_irq()
1346 raw_spin_lock_irqsave(&kpc->lock, flags); in keembay_gpio_set_irq()
1347 reg = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_INT_CFG, src); in keembay_gpio_set_irq()
1349 keembay_write_reg(reg, kpc->base1 + KEEMBAY_GPIO_INT_CFG, src); in keembay_gpio_set_irq()
1350 raw_spin_unlock_irqrestore(&kpc->lock, flags); in keembay_gpio_set_irq()
1352 if (irq->trigger == IRQ_TYPE_LEVEL_HIGH) in keembay_gpio_set_irq()
1353 kpc->max_gpios_level_type--; in keembay_gpio_set_irq()
1354 else if (irq->trigger == IRQ_TYPE_EDGE_RISING) in keembay_gpio_set_irq()
1355 kpc->max_gpios_edge_type--; in keembay_gpio_set_irq()
1357 irq->source = src; in keembay_gpio_set_irq()
1358 irq->pins[slot] = pin; in keembay_gpio_set_irq()
1359 irq->num_share++; in keembay_gpio_set_irq()
1388 * is used for handling interrupts which do not come in short-time and in keembay_gpio_irq_ack()
1405 reg = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_INT_CFG, src); in keembay_gpio_irq_disable()
1421 if (!kpc->max_gpios_edge_type && (type & IRQ_TYPE_EDGE_BOTH)) in keembay_gpio_irq_set_type()
1424 if (!kpc->max_gpios_level_type && (type & IRQ_TYPE_LEVEL_MASK)) in keembay_gpio_irq_set_type()
1432 return -EINVAL; in keembay_gpio_irq_set_type()
1442 ret = gpiochip_add_pin_range(chip, dev_name(kpc->dev), 0, 0, chip->ngpio); in keembay_gpio_add_pin_ranges()
1444 dev_err_probe(kpc->dev, ret, "failed to add GPIO pin range\n"); in keembay_gpio_add_pin_ranges()
1449 .name = "keembay-gpio",
1460 struct gpio_chip *gc = &kpc->chip; in keembay_gpiochip_probe()
1464 girq = &kpc->chip.irq; in keembay_gpiochip_probe()
1465 girq->chip = &keembay_gpio_irqchip; in keembay_gpiochip_probe()
1466 girq->parent_handler = keembay_gpio_irq_handler; in keembay_gpiochip_probe()
1467 girq->num_parents = KEEMBAY_GPIO_NUM_IRQ; in keembay_gpiochip_probe()
1468 girq->parents = devm_kcalloc(kpc->dev, girq->num_parents, in keembay_gpiochip_probe()
1469 sizeof(*girq->parents), GFP_KERNEL); in keembay_gpiochip_probe()
1471 if (!girq->parents) in keembay_gpiochip_probe()
1472 return -ENOMEM; in keembay_gpiochip_probe()
1475 gc->label = dev_name(kpc->dev); in keembay_gpiochip_probe()
1476 gc->parent = kpc->dev; in keembay_gpiochip_probe()
1477 gc->request = gpiochip_generic_request; in keembay_gpiochip_probe()
1478 gc->free = gpiochip_generic_free; in keembay_gpiochip_probe()
1479 gc->get_direction = keembay_gpio_get_direction; in keembay_gpiochip_probe()
1480 gc->direction_input = keembay_gpio_set_direction_in; in keembay_gpiochip_probe()
1481 gc->direction_output = keembay_gpio_set_direction_out; in keembay_gpiochip_probe()
1482 gc->get = keembay_gpio_get; in keembay_gpiochip_probe()
1483 gc->set = keembay_gpio_set; in keembay_gpiochip_probe()
1484 gc->set_config = gpiochip_generic_config; in keembay_gpiochip_probe()
1485 gc->base = -1; in keembay_gpiochip_probe()
1486 gc->ngpio = kpc->npins; in keembay_gpiochip_probe()
1487 gc->add_pin_ranges = keembay_gpio_add_pin_ranges; in keembay_gpiochip_probe()
1490 struct keembay_gpio_irq *kmb_irq = &kpc->irq[i]; in keembay_gpiochip_probe()
1497 girq->parents[i] = irq; in keembay_gpiochip_probe()
1498 kmb_irq->line = girq->parents[i]; in keembay_gpiochip_probe()
1499 kmb_irq->source = i; in keembay_gpiochip_probe()
1500 kmb_irq->trigger = irq_get_trigger_type(girq->parents[i]); in keembay_gpiochip_probe()
1501 kmb_irq->num_share = 0; in keembay_gpiochip_probe()
1503 if (kmb_irq->trigger == IRQ_TYPE_LEVEL_HIGH) in keembay_gpiochip_probe()
1509 kpc->max_gpios_level_type = level_line * KEEMBAY_GPIO_MAX_PER_IRQ; in keembay_gpiochip_probe()
1510 kpc->max_gpios_edge_type = edge_line * KEEMBAY_GPIO_MAX_PER_IRQ; in keembay_gpiochip_probe()
1512 girq->default_type = IRQ_TYPE_NONE; in keembay_gpiochip_probe()
1513 girq->handler = handle_bad_irq; in keembay_gpiochip_probe()
1515 return devm_gpiochip_add_data(kpc->dev, gc, kpc); in keembay_gpiochip_probe()
1523 kpc->ngroups = kpc->npins; in keembay_build_groups()
1524 grp = devm_kcalloc(kpc->dev, kpc->ngroups, sizeof(*grp), GFP_KERNEL); in keembay_build_groups()
1526 return -ENOMEM; in keembay_build_groups()
1529 for (i = 0; i < kpc->ngroups; i++) { in keembay_build_groups()
1533 kmb_grp->name = pdesc->name; in keembay_build_groups()
1534 kmb_grp->pins = (int *)&pdesc->number; in keembay_build_groups()
1535 pinctrl_generic_add_group(kpc->pctrl, kmb_grp->name, in keembay_build_groups()
1536 kmb_grp->pins, 1, NULL); in keembay_build_groups()
1547 ret = of_property_read_u32(dev->of_node, "ngpios", &kpc->npins); in keembay_pinctrl_reg()
1550 keembay_pinctrl_desc.npins = kpc->npins; in keembay_pinctrl_reg()
1552 kpc->pctrl = devm_pinctrl_register(kpc->dev, &keembay_pinctrl_desc, kpc); in keembay_pinctrl_reg()
1554 return PTR_ERR_OR_ZERO(kpc->pctrl); in keembay_pinctrl_reg()
1563 for (i = 0; i < kpc->nfuncs; i++) { in keembay_add_functions()
1569 group_names = devm_kcalloc(kpc->dev, func->func.ngroups, in keembay_add_functions()
1572 return -ENOMEM; in keembay_add_functions()
1574 for (j = 0; j < kpc->npins; j++) { in keembay_add_functions()
1578 for (mux = pdesc->drv_data; mux->name; mux++) { in keembay_add_functions()
1579 if (!strcmp(mux->name, func->func.name)) in keembay_add_functions()
1580 group_names[grp_idx++] = pdesc->name; in keembay_add_functions()
1584 func->func.groups = group_names; in keembay_add_functions()
1588 for (i = 0; i < kpc->nfuncs; i++) { in keembay_add_functions()
1589 pinmux_generic_add_function(kpc->pctrl, in keembay_add_functions()
1608 kpc->nfuncs = 0; in keembay_build_functions()
1609 keembay_funcs = kcalloc(kpc->npins * 8, sizeof(*keembay_funcs), GFP_KERNEL); in keembay_build_functions()
1611 return -ENOMEM; in keembay_build_functions()
1614 for (i = 0; i < kpc->npins; i++) { in keembay_build_functions()
1618 for (mux = pdesc->drv_data; mux->name; mux++) { in keembay_build_functions()
1622 for (fdesc = keembay_funcs; fdesc->func.name; fdesc++) { in keembay_build_functions()
1623 if (!strcmp(mux->name, fdesc->func.name)) { in keembay_build_functions()
1624 fdesc->func.ngroups++; in keembay_build_functions()
1630 if (!fdesc->func.name) { in keembay_build_functions()
1631 fdesc->func.name = mux->name; in keembay_build_functions()
1632 fdesc->func.ngroups = 1; in keembay_build_functions()
1633 fdesc->data = &mux->mode; in keembay_build_functions()
1634 kpc->nfuncs++; in keembay_build_functions()
1640 new_funcs = krealloc(keembay_funcs, kpc->nfuncs * sizeof(*new_funcs), GFP_KERNEL); in keembay_build_functions()
1643 return -ENOMEM; in keembay_build_functions()
1654 { .compatible = "intel,keembay-pinctrl", .data = &keembay_data },
1661 struct device *dev = &pdev->dev; in keembay_pinctrl_probe()
1667 return -ENOMEM; in keembay_pinctrl_probe()
1669 kpc->dev = dev; in keembay_pinctrl_probe()
1670 kpc->soc = device_get_match_data(dev); in keembay_pinctrl_probe()
1672 kpc->base0 = devm_platform_ioremap_resource(pdev, 0); in keembay_pinctrl_probe()
1673 if (IS_ERR(kpc->base0)) in keembay_pinctrl_probe()
1674 return PTR_ERR(kpc->base0); in keembay_pinctrl_probe()
1676 kpc->base1 = devm_platform_ioremap_resource(pdev, 1); in keembay_pinctrl_probe()
1677 if (IS_ERR(kpc->base1)) in keembay_pinctrl_probe()
1678 return PTR_ERR(kpc->base1); in keembay_pinctrl_probe()
1680 raw_spin_lock_init(&kpc->lock); in keembay_pinctrl_probe()
1706 .name = "keembay-pinctrl",