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
21 * Bank 0: Pin 0 - 6
22 * Bank 1: Pin 7 - 10
23 * Bank 2: Pin 11 - 12
31 /* GPIO output control registers (one per pin): 0x4e44 - 0x4e50 */
33 /* GPIO input control registers (one per pin): 0x4e51 - 0x4e5d */
38 * Group 0: Bank 0 pins (Pin 0 - 6)
39 * Group 1: Bank 1 and Bank 2 pins (Pin 7 - 12)
40 * Each group has two registers (one bit per pin): status and mask.
81 * struct wcove_gpio - Whiskey Cove GPIO controller
82 * @buslock: for bus lock/sync and unlock.
87 * @update: pending IRQ setting update, to be written to the chip upon unlock.
89 * @set_irq_mask: true if the IRQ mask needs to be set, false to clear.
97 int update; member
107 return -ENOTSUPP; in to_reg()
112 static inline int to_ireg(int gpio, enum ctrl_register type, unsigned int *mask) in to_ireg() argument
118 *mask = BIT(gpio); in to_ireg()
121 *mask = BIT(gpio - GROUP0_NR_IRQS); in to_ireg()
129 unsigned int mask, reg = to_ireg(gpio, IRQ_MASK, &mask); in wcove_update_irq_mask() local
131 if (wg->set_irq_mask) in wcove_update_irq_mask()
132 regmap_set_bits(wg->regmap, reg, mask); in wcove_update_irq_mask()
134 regmap_clear_bits(wg->regmap, reg, mask); in wcove_update_irq_mask()
141 regmap_update_bits(wg->regmap, reg, CTLI_INTCNT_BE, wg->intcnt); in wcove_update_irq_ctrl()
152 return regmap_write(wg->regmap, reg, CTLO_INPUT_SET); in wcove_gpio_dir_in()
164 return regmap_write(wg->regmap, reg, CTLO_OUTPUT_SET | value); in wcove_gpio_dir_out()
176 ret = regmap_read(wg->regmap, reg, &val); in wcove_gpio_get_direction()
195 ret = regmap_read(wg->regmap, reg, &val); in wcove_gpio_get()
211 regmap_set_bits(wg->regmap, reg, 1); in wcove_gpio_set()
213 regmap_clear_bits(wg->regmap, reg, 1); in wcove_gpio_set()
227 return regmap_update_bits(wg->regmap, reg, CTLO_DRV_MASK, in wcove_gpio_set_config()
230 return regmap_update_bits(wg->regmap, reg, CTLO_DRV_MASK, in wcove_gpio_set_config()
236 return -ENOTSUPP; in wcove_gpio_set_config()
250 wg->intcnt = CTLI_INTCNT_DIS; in wcove_irq_type()
253 wg->intcnt = CTLI_INTCNT_BE; in wcove_irq_type()
256 wg->intcnt = CTLI_INTCNT_PE; in wcove_irq_type()
259 wg->intcnt = CTLI_INTCNT_NE; in wcove_irq_type()
262 return -EINVAL; in wcove_irq_type()
265 wg->update |= UPDATE_IRQ_TYPE; in wcove_irq_type()
275 mutex_lock(&wg->buslock); in wcove_bus_lock()
284 if (wg->update & UPDATE_IRQ_TYPE) in wcove_bus_sync_unlock()
286 if (wg->update & UPDATE_IRQ_MASK) in wcove_bus_sync_unlock()
288 wg->update = 0; in wcove_bus_sync_unlock()
290 mutex_unlock(&wg->buslock); in wcove_bus_sync_unlock()
304 wg->set_irq_mask = false; in wcove_irq_unmask()
305 wg->update |= UPDATE_IRQ_MASK; in wcove_irq_unmask()
317 wg->set_irq_mask = true; in wcove_irq_mask()
318 wg->update |= UPDATE_IRQ_MASK; in wcove_irq_mask()
341 if (regmap_bulk_read(wg->regmap, IRQ_STATUS_BASE, p, 2)) { in wcove_gpio_irq_handler()
342 dev_err(wg->dev, "Failed to read irq status register\n"); in wcove_gpio_irq_handler()
354 unsigned int mask, reg = to_ireg(gpio, IRQ_STATUS, &mask); in wcove_gpio_irq_handler() local
356 virq = irq_find_mapping(wg->chip.irq.domain, gpio); in wcove_gpio_irq_handler()
358 regmap_set_bits(wg->regmap, reg, mask); in wcove_gpio_irq_handler()
362 if (regmap_bulk_read(wg->regmap, IRQ_STATUS_BASE, p, 2)) { in wcove_gpio_irq_handler()
363 dev_err(wg->dev, "Failed to read irq status\n"); in wcove_gpio_irq_handler()
377 int gpio, mask, ret = 0; in wcove_gpio_dbg_show() local
380 ret += regmap_read(wg->regmap, to_reg(gpio, CTRL_OUT), &ctlo); in wcove_gpio_dbg_show()
381 ret += regmap_read(wg->regmap, to_reg(gpio, CTRL_IN), &ctli); in wcove_gpio_dbg_show()
383 dev_err(wg->dev, "Failed to read registers: CTRL out/in\n"); in wcove_gpio_dbg_show()
387 ret += regmap_read(wg->regmap, to_ireg(gpio, IRQ_MASK, &mask), &irq_mask); in wcove_gpio_dbg_show()
388 ret += regmap_read(wg->regmap, to_ireg(gpio, IRQ_STATUS, &mask), &irq_status); in wcove_gpio_dbg_show()
390 dev_err(wg->dev, "Failed to read registers: IRQ status/mask\n"); in wcove_gpio_dbg_show()
394 seq_printf(s, " gpio-%-2d %s %s %s %s ctlo=%2x,%s %s\n", in wcove_gpio_dbg_show()
400 irq_mask & mask ? "mask " : "unmask", in wcove_gpio_dbg_show()
401 irq_status & mask ? "pending" : " "); in wcove_gpio_dbg_show()
416 * shared by all sub-devices created by the mfd device, the regmap in wcove_gpio_probe()
420 pmic = dev_get_drvdata(pdev->dev.parent); in wcove_gpio_probe()
422 return -ENODEV; in wcove_gpio_probe()
428 dev = &pdev->dev; in wcove_gpio_probe()
432 return -ENOMEM; in wcove_gpio_probe()
434 wg->regmap_irq_chip = pmic->irq_chip_data; in wcove_gpio_probe()
438 mutex_init(&wg->buslock); in wcove_gpio_probe()
439 wg->chip.label = KBUILD_MODNAME; in wcove_gpio_probe()
440 wg->chip.direction_input = wcove_gpio_dir_in; in wcove_gpio_probe()
441 wg->chip.direction_output = wcove_gpio_dir_out; in wcove_gpio_probe()
442 wg->chip.get_direction = wcove_gpio_get_direction; in wcove_gpio_probe()
443 wg->chip.get = wcove_gpio_get; in wcove_gpio_probe()
444 wg->chip.set = wcove_gpio_set; in wcove_gpio_probe()
445 wg->chip.set_config = wcove_gpio_set_config; in wcove_gpio_probe()
446 wg->chip.base = -1; in wcove_gpio_probe()
447 wg->chip.ngpio = WCOVE_VGPIO_NUM; in wcove_gpio_probe()
448 wg->chip.can_sleep = true; in wcove_gpio_probe()
449 wg->chip.parent = pdev->dev.parent; in wcove_gpio_probe()
450 wg->chip.dbg_show = wcove_gpio_dbg_show; in wcove_gpio_probe()
451 wg->dev = dev; in wcove_gpio_probe()
452 wg->regmap = pmic->regmap; in wcove_gpio_probe()
454 virq = regmap_irq_get_virq(wg->regmap_irq_chip, irq); in wcove_gpio_probe()
460 girq = &wg->chip.irq; in wcove_gpio_probe()
463 girq->parent_handler = NULL; in wcove_gpio_probe()
464 girq->num_parents = 0; in wcove_gpio_probe()
465 girq->parents = NULL; in wcove_gpio_probe()
466 girq->default_type = IRQ_TYPE_NONE; in wcove_gpio_probe()
467 girq->handler = handle_simple_irq; in wcove_gpio_probe()
468 girq->threaded = true; in wcove_gpio_probe()
471 IRQF_ONESHOT, pdev->name, wg); in wcove_gpio_probe()
477 ret = devm_gpiochip_add_data(dev, &wg->chip, wg); in wcove_gpio_probe()
484 ret = regmap_clear_bits(wg->regmap, IRQ_MASK_BASE + 0, GPIO_IRQ0_MASK); in wcove_gpio_probe()
489 ret = regmap_clear_bits(wg->regmap, IRQ_MASK_BASE + 1, GPIO_IRQ1_MASK); in wcove_gpio_probe()