Lines Matching +full:lock +full:- +full:status

1 // SPDX-License-Identifier: GPL-2.0-only
20 #include <linux/pinctrl/pinconf-generic.h>
22 #include "pinctrl-mcp23s08.h"
89 .disable_locking = true, /* mcp->lock protects the regmap */
136 .disable_locking = true, /* mcp->lock protects the regmap */
142 return regmap_read(mcp->regmap, reg << mcp->reg_shift, val); in mcp_read()
147 return regmap_write(mcp->regmap, reg << mcp->reg_shift, val); in mcp_write()
153 return regmap_update_bits(mcp->regmap, reg << mcp->reg_shift, in mcp_update_bits()
210 return -ENOTSUPP; in mcp_pinctrl_get_group_pins()
228 unsigned int data, status; in mcp_pinconf_get() local
233 mutex_lock(&mcp->lock); in mcp_pinconf_get()
235 mutex_unlock(&mcp->lock); in mcp_pinconf_get()
238 status = (data & BIT(pin)) ? 1 : 0; in mcp_pinconf_get()
241 return -ENOTSUPP; in mcp_pinconf_get()
246 return status ? 0 : -EINVAL; in mcp_pinconf_get()
264 mutex_lock(&mcp->lock); in mcp_pinconf_set()
266 mutex_unlock(&mcp->lock); in mcp_pinconf_set()
269 dev_dbg(mcp->dev, "Invalid config param %04x\n", param); in mcp_pinconf_set()
270 return -ENOTSUPP; in mcp_pinconf_set()
283 /*----------------------------------------------------------------------*/
288 int status; in mcp23s08_direction_input() local
290 mutex_lock(&mcp->lock); in mcp23s08_direction_input()
291 status = mcp_set_bit(mcp, MCP_IODIR, offset, true); in mcp23s08_direction_input()
292 mutex_unlock(&mcp->lock); in mcp23s08_direction_input()
294 return status; in mcp23s08_direction_input()
300 int status, ret; in mcp23s08_get() local
302 mutex_lock(&mcp->lock); in mcp23s08_get()
305 ret = mcp_read(mcp, MCP_GPIO, &status); in mcp23s08_get()
307 status = 0; in mcp23s08_get()
309 mcp->cached_gpio = status; in mcp23s08_get()
310 status = !!(status & (1 << offset)); in mcp23s08_get()
313 mutex_unlock(&mcp->lock); in mcp23s08_get()
314 return status; in mcp23s08_get()
321 unsigned int status; in mcp23s08_get_multiple() local
324 mutex_lock(&mcp->lock); in mcp23s08_get_multiple()
327 ret = mcp_read(mcp, MCP_GPIO, &status); in mcp23s08_get_multiple()
329 status = 0; in mcp23s08_get_multiple()
331 mcp->cached_gpio = status; in mcp23s08_get_multiple()
332 *bits = status; in mcp23s08_get_multiple()
335 mutex_unlock(&mcp->lock); in mcp23s08_get_multiple()
350 mutex_lock(&mcp->lock); in mcp23s08_set()
352 mutex_unlock(&mcp->lock); in mcp23s08_set()
363 mutex_lock(&mcp->lock); in mcp23s08_set_multiple()
365 mutex_unlock(&mcp->lock); in mcp23s08_set_multiple()
375 int status; in mcp23s08_direction_output() local
377 mutex_lock(&mcp->lock); in mcp23s08_direction_output()
378 status = __mcp23s08_set(mcp, mask, value); in mcp23s08_direction_output()
379 if (status == 0) { in mcp23s08_direction_output()
380 status = mcp_update_bits(mcp, MCP_IODIR, mask, 0); in mcp23s08_direction_output()
382 mutex_unlock(&mcp->lock); in mcp23s08_direction_output()
383 return status; in mcp23s08_direction_output()
386 /*----------------------------------------------------------------------*/
397 mutex_lock(&mcp->lock); in mcp23s08_irq()
429 gpio_orig = mcp->cached_gpio; in mcp23s08_irq()
430 mcp->cached_gpio = gpio; in mcp23s08_irq()
431 mutex_unlock(&mcp->lock); in mcp23s08_irq()
433 dev_dbg(mcp->chip.parent, in mcp23s08_irq()
438 for_each_set_bit(i, &enabled_interrupts, mcp->chip.ngpio) { in mcp23s08_irq()
446 * not written to at the same time - only on a per-bank in mcp23s08_irq()
450 * interrupt per-bank. On the mcp23s17, there is in mcp23s08_irq()
478 (BIT(i) & mcp->irq_rise) && gpio_set) || in mcp23s08_irq()
480 (BIT(i) & mcp->irq_fall) && !gpio_set) || in mcp23s08_irq()
482 child_irq = irq_find_mapping(mcp->chip.irq.domain, i); in mcp23s08_irq()
488 mutex_lock(&mcp->lock); in mcp23s08_irq()
497 dev_err(mcp->chip.parent, "can't unmask GPINTEN\n"); in mcp23s08_irq()
499 mutex_unlock(&mcp->lock); in mcp23s08_irq()
531 mcp->irq_rise |= BIT(pos); in mcp23s08_irq_set_type()
532 mcp->irq_fall |= BIT(pos); in mcp23s08_irq_set_type()
535 mcp->irq_rise |= BIT(pos); in mcp23s08_irq_set_type()
536 mcp->irq_fall &= ~BIT(pos); in mcp23s08_irq_set_type()
539 mcp->irq_rise &= ~BIT(pos); in mcp23s08_irq_set_type()
540 mcp->irq_fall |= BIT(pos); in mcp23s08_irq_set_type()
548 return -EINVAL; in mcp23s08_irq_set_type()
558 mutex_lock(&mcp->lock); in mcp23s08_irq_bus_lock()
559 regcache_cache_only(mcp->regmap, true); in mcp23s08_irq_bus_lock()
567 regcache_cache_only(mcp->regmap, false); in mcp23s08_irq_bus_unlock()
568 regcache_sync(mcp->regmap); in mcp23s08_irq_bus_unlock()
570 mutex_unlock(&mcp->lock); in mcp23s08_irq_bus_unlock()
575 struct gpio_chip *chip = &mcp->chip; in mcp23s08_irq_setup()
579 if (mcp->irq_active_high) in mcp23s08_irq_setup()
584 err = devm_request_threaded_irq(chip->parent, mcp->irq, NULL, in mcp23s08_irq_setup()
586 irqflags, dev_name(chip->parent), mcp); in mcp23s08_irq_setup()
588 dev_err(chip->parent, "unable to request IRQ#%d: %d\n", in mcp23s08_irq_setup()
589 mcp->irq, err); in mcp23s08_irq_setup()
601 seq_puts(p, dev_name(mcp->dev)); in mcp23s08_irq_print_chip()
615 /*----------------------------------------------------------------------*/
620 int status, ret; in mcp23s08_probe_one() local
624 mutex_init(&mcp->lock); in mcp23s08_probe_one()
626 mcp->dev = dev; in mcp23s08_probe_one()
627 mcp->addr = addr; in mcp23s08_probe_one()
629 mcp->irq_active_high = false; in mcp23s08_probe_one()
631 mcp->chip.direction_input = mcp23s08_direction_input; in mcp23s08_probe_one()
632 mcp->chip.get = mcp23s08_get; in mcp23s08_probe_one()
633 mcp->chip.get_multiple = mcp23s08_get_multiple; in mcp23s08_probe_one()
634 mcp->chip.direction_output = mcp23s08_direction_output; in mcp23s08_probe_one()
635 mcp->chip.set = mcp23s08_set; in mcp23s08_probe_one()
636 mcp->chip.set_multiple = mcp23s08_set_multiple; in mcp23s08_probe_one()
638 mcp->chip.base = base; in mcp23s08_probe_one()
639 mcp->chip.can_sleep = true; in mcp23s08_probe_one()
640 mcp->chip.parent = dev; in mcp23s08_probe_one()
641 mcp->chip.owner = THIS_MODULE; in mcp23s08_probe_one()
643 mcp->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); in mcp23s08_probe_one()
646 * Reset the chip - we don't really know what state it's in, so reset in mcp23s08_probe_one()
649 ret = mcp_write(mcp, MCP_IODIR, mcp->chip.ngpio == 16 ? 0xFFFF : 0xFF); in mcp23s08_probe_one()
657 ret = mcp_read(mcp, MCP_IOCON, &status); in mcp23s08_probe_one()
661 mcp->irq_controller = in mcp23s08_probe_one()
662 device_property_read_bool(dev, "interrupt-controller"); in mcp23s08_probe_one()
663 if (mcp->irq && mcp->irq_controller) { in mcp23s08_probe_one()
664 mcp->irq_active_high = in mcp23s08_probe_one()
666 "microchip,irq-active-high"); in mcp23s08_probe_one()
668 mirror = device_property_read_bool(dev, "microchip,irq-mirror"); in mcp23s08_probe_one()
669 open_drain = device_property_read_bool(dev, "drive-open-drain"); in mcp23s08_probe_one()
672 if ((status & IOCON_SEQOP) || !(status & IOCON_HAEN) || mirror || in mcp23s08_probe_one()
673 mcp->irq_active_high || open_drain) { in mcp23s08_probe_one()
675 status &= ~(IOCON_SEQOP | (IOCON_SEQOP << 8)); in mcp23s08_probe_one()
676 status |= IOCON_HAEN | (IOCON_HAEN << 8); in mcp23s08_probe_one()
677 if (mcp->irq_active_high) in mcp23s08_probe_one()
678 status |= IOCON_INTPOL | (IOCON_INTPOL << 8); in mcp23s08_probe_one()
680 status &= ~(IOCON_INTPOL | (IOCON_INTPOL << 8)); in mcp23s08_probe_one()
683 status |= IOCON_MIRROR | (IOCON_MIRROR << 8); in mcp23s08_probe_one()
686 status |= IOCON_ODR | (IOCON_ODR << 8); in mcp23s08_probe_one()
689 status |= IOCON_INTCC | (IOCON_INTCC << 8); in mcp23s08_probe_one()
691 ret = mcp_write(mcp, MCP_IOCON, status); in mcp23s08_probe_one()
696 if (mcp->irq && mcp->irq_controller) { in mcp23s08_probe_one()
697 struct gpio_irq_chip *girq = &mcp->chip.irq; in mcp23s08_probe_one()
701 girq->parent_handler = NULL; in mcp23s08_probe_one()
702 girq->num_parents = 0; in mcp23s08_probe_one()
703 girq->parents = NULL; in mcp23s08_probe_one()
704 girq->default_type = IRQ_TYPE_NONE; in mcp23s08_probe_one()
705 girq->handler = handle_simple_irq; in mcp23s08_probe_one()
706 girq->threaded = true; in mcp23s08_probe_one()
709 ret = devm_gpiochip_add_data(dev, &mcp->chip, mcp); in mcp23s08_probe_one()
713 mcp->pinctrl_desc.pctlops = &mcp_pinctrl_ops; in mcp23s08_probe_one()
714 mcp->pinctrl_desc.confops = &mcp_pinconf_ops; in mcp23s08_probe_one()
715 mcp->pinctrl_desc.npins = mcp->chip.ngpio; in mcp23s08_probe_one()
716 if (mcp->pinctrl_desc.npins == 8) in mcp23s08_probe_one()
717 mcp->pinctrl_desc.pins = mcp23x08_pins; in mcp23s08_probe_one()
718 else if (mcp->pinctrl_desc.npins == 16) in mcp23s08_probe_one()
719 mcp->pinctrl_desc.pins = mcp23x17_pins; in mcp23s08_probe_one()
720 mcp->pinctrl_desc.owner = THIS_MODULE; in mcp23s08_probe_one()
722 mcp->pctldev = devm_pinctrl_register(dev, &mcp->pinctrl_desc, mcp); in mcp23s08_probe_one()
723 if (IS_ERR(mcp->pctldev)) in mcp23s08_probe_one()
724 return dev_err_probe(dev, PTR_ERR(mcp->pctldev), "can't register controller\n"); in mcp23s08_probe_one()
726 if (mcp->irq) { in mcp23s08_probe_one()