Lines Matching +full:sync +full:- +full:update +full:- +full:mask

1 // SPDX-License-Identifier: GPL-2.0
5 * This driver is written based on gpio-crystalcove.c
22 * Bank 0: Pin 0 - 6
23 * Bank 1: Pin 7 - 10
24 * Bank 2: Pin 11 - 12
32 /* GPIO output control registers (one per pin): 0x4e44 - 0x4e50 */
34 /* GPIO input control registers (one per pin): 0x4e51 - 0x4e5d */
39 * Group 0: Bank 0 pins (Pin 0 - 6)
40 * Group 1: Bank 1 and Bank 2 pins (Pin 7 - 12)
41 * Each group has two registers (one bit per pin): status and mask.
82 * struct wcove_gpio - Whiskey Cove GPIO controller
83 * @buslock: for bus lock/sync and unlock.
88 * @update: pending IRQ setting update, to be written to the chip upon unlock.
90 * @set_irq_mask: true if the IRQ mask needs to be set, false to clear.
98 int update; member
108 return -ENOTSUPP; in to_reg()
113 static inline int to_ireg(int gpio, enum ctrl_register type, unsigned int *mask) in to_ireg() argument
119 *mask = BIT(gpio); in to_ireg()
122 *mask = BIT(gpio - GROUP0_NR_IRQS); in to_ireg()
130 unsigned int mask, reg = to_ireg(gpio, IRQ_MASK, &mask); in wcove_update_irq_mask() local
132 if (wg->set_irq_mask) in wcove_update_irq_mask()
133 regmap_set_bits(wg->regmap, reg, mask); in wcove_update_irq_mask()
135 regmap_clear_bits(wg->regmap, reg, mask); in wcove_update_irq_mask()
142 regmap_update_bits(wg->regmap, reg, CTLI_INTCNT_BE, wg->intcnt); in wcove_update_irq_ctrl()
153 return regmap_write(wg->regmap, reg, CTLO_INPUT_SET); in wcove_gpio_dir_in()
165 return regmap_write(wg->regmap, reg, CTLO_OUTPUT_SET | value); in wcove_gpio_dir_out()
177 ret = regmap_read(wg->regmap, reg, &val); in wcove_gpio_get_direction()
196 ret = regmap_read(wg->regmap, reg, &val); in wcove_gpio_get()
212 regmap_set_bits(wg->regmap, reg, 1); in wcove_gpio_set()
214 regmap_clear_bits(wg->regmap, reg, 1); in wcove_gpio_set()
228 return regmap_update_bits(wg->regmap, reg, CTLO_DRV_MASK, in wcove_gpio_set_config()
231 return regmap_update_bits(wg->regmap, reg, CTLO_DRV_MASK, in wcove_gpio_set_config()
237 return -ENOTSUPP; in wcove_gpio_set_config()
251 wg->intcnt = CTLI_INTCNT_DIS; in wcove_irq_type()
254 wg->intcnt = CTLI_INTCNT_BE; in wcove_irq_type()
257 wg->intcnt = CTLI_INTCNT_PE; in wcove_irq_type()
260 wg->intcnt = CTLI_INTCNT_NE; in wcove_irq_type()
263 return -EINVAL; in wcove_irq_type()
266 wg->update |= UPDATE_IRQ_TYPE; in wcove_irq_type()
276 mutex_lock(&wg->buslock); in wcove_bus_lock()
285 if (wg->update & UPDATE_IRQ_TYPE) in wcove_bus_sync_unlock()
287 if (wg->update & UPDATE_IRQ_MASK) in wcove_bus_sync_unlock()
289 wg->update = 0; in wcove_bus_sync_unlock()
291 mutex_unlock(&wg->buslock); in wcove_bus_sync_unlock()
305 wg->set_irq_mask = false; in wcove_irq_unmask()
306 wg->update |= UPDATE_IRQ_MASK; in wcove_irq_unmask()
318 wg->set_irq_mask = true; in wcove_irq_mask()
319 wg->update |= UPDATE_IRQ_MASK; in wcove_irq_mask()
342 if (regmap_bulk_read(wg->regmap, IRQ_STATUS_BASE, p, 2)) { in wcove_gpio_irq_handler()
343 dev_err(wg->dev, "Failed to read irq status register\n"); in wcove_gpio_irq_handler()
355 unsigned int mask, reg = to_ireg(gpio, IRQ_STATUS, &mask); in wcove_gpio_irq_handler() local
357 virq = irq_find_mapping(wg->chip.irq.domain, gpio); in wcove_gpio_irq_handler()
359 regmap_set_bits(wg->regmap, reg, mask); in wcove_gpio_irq_handler()
363 if (regmap_bulk_read(wg->regmap, IRQ_STATUS_BASE, p, 2)) { in wcove_gpio_irq_handler()
364 dev_err(wg->dev, "Failed to read irq status\n"); in wcove_gpio_irq_handler()
378 int gpio, mask, ret = 0; in wcove_gpio_dbg_show() local
381 ret += regmap_read(wg->regmap, to_reg(gpio, CTRL_OUT), &ctlo); in wcove_gpio_dbg_show()
382 ret += regmap_read(wg->regmap, to_reg(gpio, CTRL_IN), &ctli); in wcove_gpio_dbg_show()
384 dev_err(wg->dev, "Failed to read registers: CTRL out/in\n"); in wcove_gpio_dbg_show()
388 ret += regmap_read(wg->regmap, to_ireg(gpio, IRQ_MASK, &mask), &irq_mask); in wcove_gpio_dbg_show()
389 ret += regmap_read(wg->regmap, to_ireg(gpio, IRQ_STATUS, &mask), &irq_status); in wcove_gpio_dbg_show()
391 dev_err(wg->dev, "Failed to read registers: IRQ status/mask\n"); in wcove_gpio_dbg_show()
395 seq_printf(s, " gpio-%-2d %s %s %s %s ctlo=%2x,%s %s\n", in wcove_gpio_dbg_show()
401 irq_mask & mask ? "mask " : "unmask", in wcove_gpio_dbg_show()
402 irq_status & mask ? "pending" : " "); in wcove_gpio_dbg_show()
417 * shared by all sub-devices created by the mfd device, the regmap in wcove_gpio_probe()
421 pmic = dev_get_drvdata(pdev->dev.parent); in wcove_gpio_probe()
423 return -ENODEV; in wcove_gpio_probe()
429 dev = &pdev->dev; in wcove_gpio_probe()
433 return -ENOMEM; in wcove_gpio_probe()
435 wg->regmap_irq_chip = pmic->irq_chip_data; in wcove_gpio_probe()
439 mutex_init(&wg->buslock); in wcove_gpio_probe()
440 wg->chip.label = KBUILD_MODNAME; in wcove_gpio_probe()
441 wg->chip.direction_input = wcove_gpio_dir_in; in wcove_gpio_probe()
442 wg->chip.direction_output = wcove_gpio_dir_out; in wcove_gpio_probe()
443 wg->chip.get_direction = wcove_gpio_get_direction; in wcove_gpio_probe()
444 wg->chip.get = wcove_gpio_get; in wcove_gpio_probe()
445 wg->chip.set = wcove_gpio_set; in wcove_gpio_probe()
446 wg->chip.set_config = wcove_gpio_set_config; in wcove_gpio_probe()
447 wg->chip.base = -1; in wcove_gpio_probe()
448 wg->chip.ngpio = WCOVE_VGPIO_NUM; in wcove_gpio_probe()
449 wg->chip.can_sleep = true; in wcove_gpio_probe()
450 wg->chip.parent = pdev->dev.parent; in wcove_gpio_probe()
451 wg->chip.dbg_show = wcove_gpio_dbg_show; in wcove_gpio_probe()
452 wg->dev = dev; in wcove_gpio_probe()
453 wg->regmap = pmic->regmap; in wcove_gpio_probe()
455 virq = regmap_irq_get_virq(wg->regmap_irq_chip, irq); in wcove_gpio_probe()
461 girq = &wg->chip.irq; in wcove_gpio_probe()
464 girq->parent_handler = NULL; in wcove_gpio_probe()
465 girq->num_parents = 0; in wcove_gpio_probe()
466 girq->parents = NULL; in wcove_gpio_probe()
467 girq->default_type = IRQ_TYPE_NONE; in wcove_gpio_probe()
468 girq->handler = handle_simple_irq; in wcove_gpio_probe()
469 girq->threaded = true; in wcove_gpio_probe()
472 IRQF_ONESHOT, pdev->name, wg); in wcove_gpio_probe()
478 ret = devm_gpiochip_add_data(dev, &wg->chip, wg); in wcove_gpio_probe()
485 ret = regmap_clear_bits(wg->regmap, IRQ_MASK_BASE + 0, GPIO_IRQ0_MASK); in wcove_gpio_probe()
490 ret = regmap_clear_bits(wg->regmap, IRQ_MASK_BASE + 1, GPIO_IRQ1_MASK); in wcove_gpio_probe()