Lines Matching +full:data +full:- +full:mirror
1 // SPDX-License-Identifier: GPL-2.0-only
19 #include <linux/pinctrl/pinconf-generic.h>
21 #include "pinctrl-mcp23s08.h"
139 return regmap_read(mcp->regmap, reg << mcp->reg_shift, val); in mcp_read()
144 return regmap_write(mcp->regmap, reg << mcp->reg_shift, val); in mcp_write()
151 return regmap_update_bits(mcp->regmap, reg << mcp->reg_shift, in mcp_set_mask()
208 return -ENOTSUPP; in mcp_pinctrl_get_group_pins()
226 unsigned int data, status; in mcp_pinconf_get() local
231 ret = mcp_read(mcp, MCP_GPPU, &data); in mcp_pinconf_get()
234 status = (data & BIT(pin)) ? 1 : 0; in mcp_pinconf_get()
237 return -ENOTSUPP; in mcp_pinconf_get()
242 return status ? 0 : -EINVAL; in mcp_pinconf_get()
263 dev_dbg(mcp->dev, "Invalid config param %04x\n", param); in mcp_pinconf_set()
264 return -ENOTSUPP; in mcp_pinconf_set()
277 /*----------------------------------------------------------------------*/
284 mutex_lock(&mcp->lock); in mcp23s08_direction_input()
286 mutex_unlock(&mcp->lock); in mcp23s08_direction_input()
296 mutex_lock(&mcp->lock); in mcp23s08_get()
303 mcp->cached_gpio = status; in mcp23s08_get()
307 mutex_unlock(&mcp->lock); in mcp23s08_get()
321 mutex_lock(&mcp->lock); in mcp23s08_set()
323 mutex_unlock(&mcp->lock); in mcp23s08_set()
333 mutex_lock(&mcp->lock); in mcp23s08_direction_output()
338 mutex_unlock(&mcp->lock); in mcp23s08_direction_output()
342 /*----------------------------------------------------------------------*/
343 static irqreturn_t mcp23s08_irq(int irq, void *data) in mcp23s08_irq() argument
345 struct mcp23s08 *mcp = data; in mcp23s08_irq()
351 mutex_lock(&mcp->lock); in mcp23s08_irq()
373 gpio_orig = mcp->cached_gpio; in mcp23s08_irq()
374 mcp->cached_gpio = gpio; in mcp23s08_irq()
375 mutex_unlock(&mcp->lock); in mcp23s08_irq()
377 dev_dbg(mcp->chip.parent, in mcp23s08_irq()
381 for (i = 0; i < mcp->chip.ngpio; i++) { in mcp23s08_irq()
387 * not written to at the same time - only on a per-bank in mcp23s08_irq()
391 * interrupt per-bank. On the mcp23s17, there is in mcp23s08_irq()
419 (BIT(i) & mcp->irq_rise) && gpio_set) || in mcp23s08_irq()
421 (BIT(i) & mcp->irq_fall) && !gpio_set) || in mcp23s08_irq()
423 child_irq = irq_find_mapping(mcp->chip.irq.domain, i); in mcp23s08_irq()
431 mutex_unlock(&mcp->lock); in mcp23s08_irq()
435 static void mcp23s08_irq_mask(struct irq_data *data) in mcp23s08_irq_mask() argument
437 struct gpio_chip *gc = irq_data_get_irq_chip_data(data); in mcp23s08_irq_mask()
439 unsigned int pos = data->hwirq; in mcp23s08_irq_mask()
444 static void mcp23s08_irq_unmask(struct irq_data *data) in mcp23s08_irq_unmask() argument
446 struct gpio_chip *gc = irq_data_get_irq_chip_data(data); in mcp23s08_irq_unmask()
448 unsigned int pos = data->hwirq; in mcp23s08_irq_unmask()
453 static int mcp23s08_irq_set_type(struct irq_data *data, unsigned int type) in mcp23s08_irq_set_type() argument
455 struct gpio_chip *gc = irq_data_get_irq_chip_data(data); in mcp23s08_irq_set_type()
457 unsigned int pos = data->hwirq; in mcp23s08_irq_set_type()
461 mcp->irq_rise |= BIT(pos); in mcp23s08_irq_set_type()
462 mcp->irq_fall |= BIT(pos); in mcp23s08_irq_set_type()
465 mcp->irq_rise |= BIT(pos); in mcp23s08_irq_set_type()
466 mcp->irq_fall &= ~BIT(pos); in mcp23s08_irq_set_type()
469 mcp->irq_rise &= ~BIT(pos); in mcp23s08_irq_set_type()
470 mcp->irq_fall |= BIT(pos); in mcp23s08_irq_set_type()
478 return -EINVAL; in mcp23s08_irq_set_type()
483 static void mcp23s08_irq_bus_lock(struct irq_data *data) in mcp23s08_irq_bus_lock() argument
485 struct gpio_chip *gc = irq_data_get_irq_chip_data(data); in mcp23s08_irq_bus_lock()
488 mutex_lock(&mcp->lock); in mcp23s08_irq_bus_lock()
489 regcache_cache_only(mcp->regmap, true); in mcp23s08_irq_bus_lock()
492 static void mcp23s08_irq_bus_unlock(struct irq_data *data) in mcp23s08_irq_bus_unlock() argument
494 struct gpio_chip *gc = irq_data_get_irq_chip_data(data); in mcp23s08_irq_bus_unlock()
497 regcache_cache_only(mcp->regmap, false); in mcp23s08_irq_bus_unlock()
498 regcache_sync(mcp->regmap); in mcp23s08_irq_bus_unlock()
500 mutex_unlock(&mcp->lock); in mcp23s08_irq_bus_unlock()
505 struct gpio_chip *chip = &mcp->chip; in mcp23s08_irq_setup()
509 if (mcp->irq_active_high) in mcp23s08_irq_setup()
514 err = devm_request_threaded_irq(chip->parent, mcp->irq, NULL, in mcp23s08_irq_setup()
516 irqflags, dev_name(chip->parent), mcp); in mcp23s08_irq_setup()
518 dev_err(chip->parent, "unable to request IRQ#%d: %d\n", in mcp23s08_irq_setup()
519 mcp->irq, err); in mcp23s08_irq_setup()
526 /*----------------------------------------------------------------------*/
532 bool mirror = false; in mcp23s08_probe_one() local
535 mutex_init(&mcp->lock); in mcp23s08_probe_one()
537 mcp->dev = dev; in mcp23s08_probe_one()
538 mcp->addr = addr; in mcp23s08_probe_one()
540 mcp->irq_active_high = false; in mcp23s08_probe_one()
541 mcp->irq_chip.name = dev_name(dev); in mcp23s08_probe_one()
542 mcp->irq_chip.irq_mask = mcp23s08_irq_mask; in mcp23s08_probe_one()
543 mcp->irq_chip.irq_unmask = mcp23s08_irq_unmask; in mcp23s08_probe_one()
544 mcp->irq_chip.irq_set_type = mcp23s08_irq_set_type; in mcp23s08_probe_one()
545 mcp->irq_chip.irq_bus_lock = mcp23s08_irq_bus_lock; in mcp23s08_probe_one()
546 mcp->irq_chip.irq_bus_sync_unlock = mcp23s08_irq_bus_unlock; in mcp23s08_probe_one()
548 mcp->chip.direction_input = mcp23s08_direction_input; in mcp23s08_probe_one()
549 mcp->chip.get = mcp23s08_get; in mcp23s08_probe_one()
550 mcp->chip.direction_output = mcp23s08_direction_output; in mcp23s08_probe_one()
551 mcp->chip.set = mcp23s08_set; in mcp23s08_probe_one()
553 mcp->chip.of_gpio_n_cells = 2; in mcp23s08_probe_one()
554 mcp->chip.of_node = dev->of_node; in mcp23s08_probe_one()
557 mcp->chip.base = base; in mcp23s08_probe_one()
558 mcp->chip.can_sleep = true; in mcp23s08_probe_one()
559 mcp->chip.parent = dev; in mcp23s08_probe_one()
560 mcp->chip.owner = THIS_MODULE; in mcp23s08_probe_one()
562 mcp->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); in mcp23s08_probe_one()
572 mcp->irq_controller = in mcp23s08_probe_one()
573 device_property_read_bool(dev, "interrupt-controller"); in mcp23s08_probe_one()
574 if (mcp->irq && mcp->irq_controller) { in mcp23s08_probe_one()
575 mcp->irq_active_high = in mcp23s08_probe_one()
577 "microchip,irq-active-high"); in mcp23s08_probe_one()
579 mirror = device_property_read_bool(dev, "microchip,irq-mirror"); in mcp23s08_probe_one()
580 open_drain = device_property_read_bool(dev, "drive-open-drain"); in mcp23s08_probe_one()
583 if ((status & IOCON_SEQOP) || !(status & IOCON_HAEN) || mirror || in mcp23s08_probe_one()
584 mcp->irq_active_high || open_drain) { in mcp23s08_probe_one()
588 if (mcp->irq_active_high) in mcp23s08_probe_one()
593 if (mirror) in mcp23s08_probe_one()
607 if (mcp->irq && mcp->irq_controller) { in mcp23s08_probe_one()
608 struct gpio_irq_chip *girq = &mcp->chip.irq; in mcp23s08_probe_one()
610 girq->chip = &mcp->irq_chip; in mcp23s08_probe_one()
612 girq->parent_handler = NULL; in mcp23s08_probe_one()
613 girq->num_parents = 0; in mcp23s08_probe_one()
614 girq->parents = NULL; in mcp23s08_probe_one()
615 girq->default_type = IRQ_TYPE_NONE; in mcp23s08_probe_one()
616 girq->handler = handle_simple_irq; in mcp23s08_probe_one()
617 girq->threaded = true; in mcp23s08_probe_one()
620 ret = devm_gpiochip_add_data(dev, &mcp->chip, mcp); in mcp23s08_probe_one()
624 mcp->pinctrl_desc.pctlops = &mcp_pinctrl_ops; in mcp23s08_probe_one()
625 mcp->pinctrl_desc.confops = &mcp_pinconf_ops; in mcp23s08_probe_one()
626 mcp->pinctrl_desc.npins = mcp->chip.ngpio; in mcp23s08_probe_one()
627 if (mcp->pinctrl_desc.npins == 8) in mcp23s08_probe_one()
628 mcp->pinctrl_desc.pins = mcp23x08_pins; in mcp23s08_probe_one()
629 else if (mcp->pinctrl_desc.npins == 16) in mcp23s08_probe_one()
630 mcp->pinctrl_desc.pins = mcp23x17_pins; in mcp23s08_probe_one()
631 mcp->pinctrl_desc.owner = THIS_MODULE; in mcp23s08_probe_one()
633 mcp->pctldev = devm_pinctrl_register(dev, &mcp->pinctrl_desc, mcp); in mcp23s08_probe_one()
634 if (IS_ERR(mcp->pctldev)) in mcp23s08_probe_one()
635 return dev_err_probe(dev, PTR_ERR(mcp->pctldev), "can't register controller\n"); in mcp23s08_probe_one()
637 if (mcp->irq) { in mcp23s08_probe_one()