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()
211 return regmap_assign_bits(wg->regmap, reg, 1, value); in wcove_gpio_set()
225 return regmap_update_bits(wg->regmap, reg, CTLO_DRV_MASK, in wcove_gpio_set_config()
228 return regmap_update_bits(wg->regmap, reg, CTLO_DRV_MASK, in wcove_gpio_set_config()
234 return -ENOTSUPP; in wcove_gpio_set_config()
248 wg->intcnt = CTLI_INTCNT_DIS; in wcove_irq_type()
251 wg->intcnt = CTLI_INTCNT_BE; in wcove_irq_type()
254 wg->intcnt = CTLI_INTCNT_PE; in wcove_irq_type()
257 wg->intcnt = CTLI_INTCNT_NE; in wcove_irq_type()
260 return -EINVAL; in wcove_irq_type()
263 wg->update |= UPDATE_IRQ_TYPE; in wcove_irq_type()
273 mutex_lock(&wg->buslock); in wcove_bus_lock()
282 if (wg->update & UPDATE_IRQ_TYPE) in wcove_bus_sync_unlock()
284 if (wg->update & UPDATE_IRQ_MASK) in wcove_bus_sync_unlock()
286 wg->update = 0; in wcove_bus_sync_unlock()
288 mutex_unlock(&wg->buslock); in wcove_bus_sync_unlock()
302 wg->set_irq_mask = false; in wcove_irq_unmask()
303 wg->update |= UPDATE_IRQ_MASK; in wcove_irq_unmask()
315 wg->set_irq_mask = true; in wcove_irq_mask()
316 wg->update |= UPDATE_IRQ_MASK; in wcove_irq_mask()
339 if (regmap_bulk_read(wg->regmap, IRQ_STATUS_BASE, p, 2)) { in wcove_gpio_irq_handler()
340 dev_err(wg->dev, "Failed to read irq status register\n"); in wcove_gpio_irq_handler()
352 unsigned int mask, reg = to_ireg(gpio, IRQ_STATUS, &mask); in wcove_gpio_irq_handler() local
354 virq = irq_find_mapping(wg->chip.irq.domain, gpio); in wcove_gpio_irq_handler()
356 regmap_set_bits(wg->regmap, reg, mask); in wcove_gpio_irq_handler()
360 if (regmap_bulk_read(wg->regmap, IRQ_STATUS_BASE, p, 2)) { in wcove_gpio_irq_handler()
361 dev_err(wg->dev, "Failed to read irq status\n"); in wcove_gpio_irq_handler()
375 int gpio, mask, ret = 0; in wcove_gpio_dbg_show() local
378 ret += regmap_read(wg->regmap, to_reg(gpio, CTRL_OUT), &ctlo); in wcove_gpio_dbg_show()
379 ret += regmap_read(wg->regmap, to_reg(gpio, CTRL_IN), &ctli); in wcove_gpio_dbg_show()
381 dev_err(wg->dev, "Failed to read registers: CTRL out/in\n"); in wcove_gpio_dbg_show()
385 ret += regmap_read(wg->regmap, to_ireg(gpio, IRQ_MASK, &mask), &irq_mask); in wcove_gpio_dbg_show()
386 ret += regmap_read(wg->regmap, to_ireg(gpio, IRQ_STATUS, &mask), &irq_status); in wcove_gpio_dbg_show()
388 dev_err(wg->dev, "Failed to read registers: IRQ status/mask\n"); in wcove_gpio_dbg_show()
392 seq_printf(s, " gpio-%-2d %s %s %s %s ctlo=%2x,%s %s\n", in wcove_gpio_dbg_show()
398 irq_mask & mask ? "mask " : "unmask", in wcove_gpio_dbg_show()
399 irq_status & mask ? "pending" : " "); in wcove_gpio_dbg_show()
414 * shared by all sub-devices created by the mfd device, the regmap in wcove_gpio_probe()
418 pmic = dev_get_drvdata(pdev->dev.parent); in wcove_gpio_probe()
420 return -ENODEV; in wcove_gpio_probe()
426 dev = &pdev->dev; in wcove_gpio_probe()
430 return -ENOMEM; in wcove_gpio_probe()
432 wg->regmap_irq_chip = pmic->irq_chip_data; in wcove_gpio_probe()
436 mutex_init(&wg->buslock); in wcove_gpio_probe()
437 wg->chip.label = KBUILD_MODNAME; in wcove_gpio_probe()
438 wg->chip.direction_input = wcove_gpio_dir_in; in wcove_gpio_probe()
439 wg->chip.direction_output = wcove_gpio_dir_out; in wcove_gpio_probe()
440 wg->chip.get_direction = wcove_gpio_get_direction; in wcove_gpio_probe()
441 wg->chip.get = wcove_gpio_get; in wcove_gpio_probe()
442 wg->chip.set = wcove_gpio_set; in wcove_gpio_probe()
443 wg->chip.set_config = wcove_gpio_set_config; in wcove_gpio_probe()
444 wg->chip.base = -1; in wcove_gpio_probe()
445 wg->chip.ngpio = WCOVE_VGPIO_NUM; in wcove_gpio_probe()
446 wg->chip.can_sleep = true; in wcove_gpio_probe()
447 wg->chip.parent = pdev->dev.parent; in wcove_gpio_probe()
448 wg->chip.dbg_show = wcove_gpio_dbg_show; in wcove_gpio_probe()
449 wg->dev = dev; in wcove_gpio_probe()
450 wg->regmap = pmic->regmap; in wcove_gpio_probe()
452 virq = regmap_irq_get_virq(wg->regmap_irq_chip, irq); in wcove_gpio_probe()
458 girq = &wg->chip.irq; in wcove_gpio_probe()
461 girq->parent_handler = NULL; in wcove_gpio_probe()
462 girq->num_parents = 0; in wcove_gpio_probe()
463 girq->parents = NULL; in wcove_gpio_probe()
464 girq->default_type = IRQ_TYPE_NONE; in wcove_gpio_probe()
465 girq->handler = handle_simple_irq; in wcove_gpio_probe()
466 girq->threaded = true; in wcove_gpio_probe()
469 IRQF_ONESHOT, pdev->name, wg); in wcove_gpio_probe()
475 ret = devm_gpiochip_add_data(dev, &wg->chip, wg); in wcove_gpio_probe()
482 ret = regmap_clear_bits(wg->regmap, IRQ_MASK_BASE + 0, GPIO_IRQ0_MASK); in wcove_gpio_probe()
487 ret = regmap_clear_bits(wg->regmap, IRQ_MASK_BASE + 1, GPIO_IRQ1_MASK); in wcove_gpio_probe()