Lines Matching +full:off +full:- +full:chip

56  * chip: gpio framework specific chip information structure
58 * machines where mapping b/w pin and offset is not 1-to-1.
60 * machines where mapping b/w pin and offset is not 1-to-1.
69 struct gpio_chip chip; member
108 static int plgpio_direction_input(struct gpio_chip *chip, unsigned offset) in plgpio_direction_input() argument
110 struct plgpio *plgpio = gpiochip_get_data(chip); in plgpio_direction_input()
114 if (plgpio->p2o && (plgpio->p2o_regs & PTO_DIR_REG)) { in plgpio_direction_input()
115 offset = plgpio->p2o(offset); in plgpio_direction_input()
116 if (offset == -1) in plgpio_direction_input()
117 return -EINVAL; in plgpio_direction_input()
120 spin_lock_irqsave(&plgpio->lock, flags); in plgpio_direction_input()
121 plgpio_reg_set(plgpio->base, offset, plgpio->regs.dir); in plgpio_direction_input()
122 spin_unlock_irqrestore(&plgpio->lock, flags); in plgpio_direction_input()
127 static int plgpio_direction_output(struct gpio_chip *chip, unsigned offset, in plgpio_direction_output() argument
130 struct plgpio *plgpio = gpiochip_get_data(chip); in plgpio_direction_output()
135 if (plgpio->p2o && (plgpio->p2o_regs & (PTO_DIR_REG | PTO_WDATA_REG))) { in plgpio_direction_output()
136 tmp = plgpio->p2o(offset); in plgpio_direction_output()
137 if (tmp == -1) in plgpio_direction_output()
138 return -EINVAL; in plgpio_direction_output()
140 if (plgpio->p2o_regs & PTO_DIR_REG) in plgpio_direction_output()
142 if (plgpio->p2o_regs & PTO_WDATA_REG) in plgpio_direction_output()
146 spin_lock_irqsave(&plgpio->lock, flags); in plgpio_direction_output()
148 plgpio_reg_set(plgpio->base, wdata_offset, in plgpio_direction_output()
149 plgpio->regs.wdata); in plgpio_direction_output()
151 plgpio_reg_reset(plgpio->base, wdata_offset, in plgpio_direction_output()
152 plgpio->regs.wdata); in plgpio_direction_output()
154 plgpio_reg_reset(plgpio->base, dir_offset, plgpio->regs.dir); in plgpio_direction_output()
155 spin_unlock_irqrestore(&plgpio->lock, flags); in plgpio_direction_output()
160 static int plgpio_get_value(struct gpio_chip *chip, unsigned offset) in plgpio_get_value() argument
162 struct plgpio *plgpio = gpiochip_get_data(chip); in plgpio_get_value()
164 if (offset >= chip->ngpio) in plgpio_get_value()
165 return -EINVAL; in plgpio_get_value()
168 if (plgpio->p2o && (plgpio->p2o_regs & PTO_RDATA_REG)) { in plgpio_get_value()
169 offset = plgpio->p2o(offset); in plgpio_get_value()
170 if (offset == -1) in plgpio_get_value()
171 return -EINVAL; in plgpio_get_value()
174 return is_plgpio_set(plgpio->base, offset, plgpio->regs.rdata); in plgpio_get_value()
177 static void plgpio_set_value(struct gpio_chip *chip, unsigned offset, int value) in plgpio_set_value() argument
179 struct plgpio *plgpio = gpiochip_get_data(chip); in plgpio_set_value()
181 if (offset >= chip->ngpio) in plgpio_set_value()
185 if (plgpio->p2o && (plgpio->p2o_regs & PTO_WDATA_REG)) { in plgpio_set_value()
186 offset = plgpio->p2o(offset); in plgpio_set_value()
187 if (offset == -1) in plgpio_set_value()
192 plgpio_reg_set(plgpio->base, offset, plgpio->regs.wdata); in plgpio_set_value()
194 plgpio_reg_reset(plgpio->base, offset, plgpio->regs.wdata); in plgpio_set_value()
197 static int plgpio_request(struct gpio_chip *chip, unsigned offset) in plgpio_request() argument
199 struct plgpio *plgpio = gpiochip_get_data(chip); in plgpio_request()
200 int gpio = chip->base + offset; in plgpio_request()
204 if (offset >= chip->ngpio) in plgpio_request()
205 return -EINVAL; in plgpio_request()
211 if (!IS_ERR(plgpio->clk)) { in plgpio_request()
212 ret = clk_enable(plgpio->clk); in plgpio_request()
217 if (plgpio->regs.enb == -1) in plgpio_request()
223 ret = plgpio_direction_input(chip, offset); in plgpio_request()
228 if (plgpio->p2o && (plgpio->p2o_regs & PTO_ENB_REG)) { in plgpio_request()
229 offset = plgpio->p2o(offset); in plgpio_request()
230 if (offset == -1) { in plgpio_request()
231 ret = -EINVAL; in plgpio_request()
236 spin_lock_irqsave(&plgpio->lock, flags); in plgpio_request()
237 plgpio_reg_set(plgpio->base, offset, plgpio->regs.enb); in plgpio_request()
238 spin_unlock_irqrestore(&plgpio->lock, flags); in plgpio_request()
242 if (!IS_ERR(plgpio->clk)) in plgpio_request()
243 clk_disable(plgpio->clk); in plgpio_request()
249 static void plgpio_free(struct gpio_chip *chip, unsigned offset) in plgpio_free() argument
251 struct plgpio *plgpio = gpiochip_get_data(chip); in plgpio_free()
252 int gpio = chip->base + offset; in plgpio_free()
255 if (offset >= chip->ngpio) in plgpio_free()
258 if (plgpio->regs.enb == -1) in plgpio_free()
262 if (plgpio->p2o && (plgpio->p2o_regs & PTO_ENB_REG)) { in plgpio_free()
263 offset = plgpio->p2o(offset); in plgpio_free()
264 if (offset == -1) in plgpio_free()
268 spin_lock_irqsave(&plgpio->lock, flags); in plgpio_free()
269 plgpio_reg_reset(plgpio->base, offset, plgpio->regs.enb); in plgpio_free()
270 spin_unlock_irqrestore(&plgpio->lock, flags); in plgpio_free()
273 if (!IS_ERR(plgpio->clk)) in plgpio_free()
274 clk_disable(plgpio->clk); in plgpio_free()
284 int offset = d->hwirq; in plgpio_irq_disable()
288 if (plgpio->p2o && (plgpio->p2o_regs & PTO_IE_REG)) { in plgpio_irq_disable()
289 offset = plgpio->p2o(offset); in plgpio_irq_disable()
290 if (offset == -1) in plgpio_irq_disable()
294 spin_lock_irqsave(&plgpio->lock, flags); in plgpio_irq_disable()
295 plgpio_reg_set(plgpio->base, offset, plgpio->regs.ie); in plgpio_irq_disable()
296 spin_unlock_irqrestore(&plgpio->lock, flags); in plgpio_irq_disable()
303 int offset = d->hwirq; in plgpio_irq_enable()
307 if (plgpio->p2o && (plgpio->p2o_regs & PTO_IE_REG)) { in plgpio_irq_enable()
308 offset = plgpio->p2o(offset); in plgpio_irq_enable()
309 if (offset == -1) in plgpio_irq_enable()
313 spin_lock_irqsave(&plgpio->lock, flags); in plgpio_irq_enable()
314 plgpio_reg_reset(plgpio->base, offset, plgpio->regs.ie); in plgpio_irq_enable()
315 spin_unlock_irqrestore(&plgpio->lock, flags); in plgpio_irq_enable()
322 int offset = d->hwirq; in plgpio_irq_set_type()
326 if (offset >= plgpio->chip.ngpio) in plgpio_irq_set_type()
327 return -EINVAL; in plgpio_irq_set_type()
329 if (plgpio->regs.eit == -1) in plgpio_irq_set_type()
335 return -EINVAL; in plgpio_irq_set_type()
337 if (plgpio->regs.eit == -1) in plgpio_irq_set_type()
340 reg_off = REG_OFFSET(plgpio->base, plgpio->regs.eit, offset); in plgpio_irq_set_type()
367 count = plgpio->chip.ngpio; in plgpio_irq_handler()
373 pending = readl_relaxed(plgpio->base + plgpio->regs.mis + in plgpio_irq_handler()
379 writel_relaxed(~pending, plgpio->base + plgpio->regs.mis + in plgpio_irq_handler()
384 * must have only (102 - MAX_GPIO_PER_REG * 3) = 6 relevant bits in plgpio_irq_handler()
388 count = count - i * MAX_GPIO_PER_REG; in plgpio_irq_handler()
390 pending &= (1 << count) - 1; in plgpio_irq_handler()
394 if (plgpio->o2p && (plgpio->p2o_regs & PTO_MIS_REG)) { in plgpio_irq_handler()
395 pin = plgpio->o2p(offset); in plgpio_irq_handler()
396 if (pin == -1) in plgpio_irq_handler()
404 irq_find_mapping(gc->irq.domain, pin)); in plgpio_irq_handler()
415 * 28-33 are not supported, pin 95 has offset bit 95, bit 100 has offset bit 1
424 offset = -1; in spear310_p2o()
426 offset -= 2; in spear310_p2o()
428 offset = 101 - pin; in spear310_p2o()
430 offset = -1; in spear310_p2o()
438 return 101 - offset; in spear310_o2p()
440 return offset - 4; in spear310_o2p()
447 struct device_node *np = pdev->dev.of_node; in plgpio_probe_dt()
448 int ret = -EINVAL; in plgpio_probe_dt()
452 plgpio->p2o = spear310_p2o; in plgpio_probe_dt()
453 plgpio->o2p = spear310_o2p; in plgpio_probe_dt()
454 plgpio->p2o_regs = PTO_WDATA_REG | PTO_DIR_REG | PTO_IE_REG | in plgpio_probe_dt()
458 if (!of_property_read_u32(np, "st-plgpio,ngpio", &val)) { in plgpio_probe_dt()
459 plgpio->chip.ngpio = val; in plgpio_probe_dt()
461 dev_err(&pdev->dev, "DT: Invalid ngpio field\n"); in plgpio_probe_dt()
465 if (!of_property_read_u32(np, "st-plgpio,enb-reg", &val)) in plgpio_probe_dt()
466 plgpio->regs.enb = val; in plgpio_probe_dt()
468 plgpio->regs.enb = -1; in plgpio_probe_dt()
470 if (!of_property_read_u32(np, "st-plgpio,wdata-reg", &val)) { in plgpio_probe_dt()
471 plgpio->regs.wdata = val; in plgpio_probe_dt()
473 dev_err(&pdev->dev, "DT: Invalid wdata reg\n"); in plgpio_probe_dt()
477 if (!of_property_read_u32(np, "st-plgpio,dir-reg", &val)) { in plgpio_probe_dt()
478 plgpio->regs.dir = val; in plgpio_probe_dt()
480 dev_err(&pdev->dev, "DT: Invalid dir reg\n"); in plgpio_probe_dt()
484 if (!of_property_read_u32(np, "st-plgpio,ie-reg", &val)) { in plgpio_probe_dt()
485 plgpio->regs.ie = val; in plgpio_probe_dt()
487 dev_err(&pdev->dev, "DT: Invalid ie reg\n"); in plgpio_probe_dt()
491 if (!of_property_read_u32(np, "st-plgpio,rdata-reg", &val)) { in plgpio_probe_dt()
492 plgpio->regs.rdata = val; in plgpio_probe_dt()
494 dev_err(&pdev->dev, "DT: Invalid rdata reg\n"); in plgpio_probe_dt()
498 if (!of_property_read_u32(np, "st-plgpio,mis-reg", &val)) { in plgpio_probe_dt()
499 plgpio->regs.mis = val; in plgpio_probe_dt()
501 dev_err(&pdev->dev, "DT: Invalid mis reg\n"); in plgpio_probe_dt()
505 if (!of_property_read_u32(np, "st-plgpio,eit-reg", &val)) in plgpio_probe_dt()
506 plgpio->regs.eit = val; in plgpio_probe_dt()
508 plgpio->regs.eit = -1; in plgpio_probe_dt()
520 plgpio = devm_kzalloc(&pdev->dev, sizeof(*plgpio), GFP_KERNEL); in plgpio_probe()
522 return -ENOMEM; in plgpio_probe()
524 plgpio->base = devm_platform_ioremap_resource(pdev, 0); in plgpio_probe()
525 if (IS_ERR(plgpio->base)) in plgpio_probe()
526 return PTR_ERR(plgpio->base); in plgpio_probe()
530 dev_err(&pdev->dev, "DT probe failed\n"); in plgpio_probe()
534 plgpio->clk = devm_clk_get(&pdev->dev, NULL); in plgpio_probe()
535 if (IS_ERR(plgpio->clk)) in plgpio_probe()
536 dev_warn(&pdev->dev, "clk_get() failed, work without it\n"); in plgpio_probe()
539 plgpio->csave_regs = devm_kcalloc(&pdev->dev, in plgpio_probe()
540 DIV_ROUND_UP(plgpio->chip.ngpio, MAX_GPIO_PER_REG), in plgpio_probe()
541 sizeof(*plgpio->csave_regs), in plgpio_probe()
543 if (!plgpio->csave_regs) in plgpio_probe()
544 return -ENOMEM; in plgpio_probe()
548 spin_lock_init(&plgpio->lock); in plgpio_probe()
550 plgpio->chip.base = -1; in plgpio_probe()
551 plgpio->chip.request = plgpio_request; in plgpio_probe()
552 plgpio->chip.free = plgpio_free; in plgpio_probe()
553 plgpio->chip.direction_input = plgpio_direction_input; in plgpio_probe()
554 plgpio->chip.direction_output = plgpio_direction_output; in plgpio_probe()
555 plgpio->chip.get = plgpio_get_value; in plgpio_probe()
556 plgpio->chip.set = plgpio_set_value; in plgpio_probe()
557 plgpio->chip.label = dev_name(&pdev->dev); in plgpio_probe()
558 plgpio->chip.parent = &pdev->dev; in plgpio_probe()
559 plgpio->chip.owner = THIS_MODULE; in plgpio_probe()
560 plgpio->chip.of_node = pdev->dev.of_node; in plgpio_probe()
562 if (!IS_ERR(plgpio->clk)) { in plgpio_probe()
563 ret = clk_prepare(plgpio->clk); in plgpio_probe()
565 dev_err(&pdev->dev, "clk prepare failed\n"); in plgpio_probe()
574 girq = &plgpio->chip.irq; in plgpio_probe()
575 girq->chip = &plgpio_irqchip; in plgpio_probe()
576 girq->parent_handler = plgpio_irq_handler; in plgpio_probe()
577 girq->num_parents = 1; in plgpio_probe()
578 girq->parents = devm_kcalloc(&pdev->dev, 1, in plgpio_probe()
579 sizeof(*girq->parents), in plgpio_probe()
581 if (!girq->parents) in plgpio_probe()
582 return -ENOMEM; in plgpio_probe()
583 girq->parents[0] = irq; in plgpio_probe()
584 girq->default_type = IRQ_TYPE_NONE; in plgpio_probe()
585 girq->handler = handle_simple_irq; in plgpio_probe()
586 dev_info(&pdev->dev, "PLGPIO registering with IRQs\n"); in plgpio_probe()
588 dev_info(&pdev->dev, "PLGPIO registering without IRQs\n"); in plgpio_probe()
591 ret = gpiochip_add_data(&plgpio->chip, plgpio); in plgpio_probe()
593 dev_err(&pdev->dev, "unable to add gpio chip\n"); in plgpio_probe()
600 if (!IS_ERR(plgpio->clk)) in plgpio_probe()
601 clk_unprepare(plgpio->clk); in plgpio_probe()
610 int i, reg_count = DIV_ROUND_UP(plgpio->chip.ngpio, MAX_GPIO_PER_REG); in plgpio_suspend()
611 void __iomem *off; in plgpio_suspend() local
614 off = plgpio->base + i * sizeof(int *); in plgpio_suspend()
616 if (plgpio->regs.enb != -1) in plgpio_suspend()
617 plgpio->csave_regs[i].enb = in plgpio_suspend()
618 readl_relaxed(plgpio->regs.enb + off); in plgpio_suspend()
619 if (plgpio->regs.eit != -1) in plgpio_suspend()
620 plgpio->csave_regs[i].eit = in plgpio_suspend()
621 readl_relaxed(plgpio->regs.eit + off); in plgpio_suspend()
622 plgpio->csave_regs[i].wdata = readl_relaxed(plgpio->regs.wdata + in plgpio_suspend()
623 off); in plgpio_suspend()
624 plgpio->csave_regs[i].dir = readl_relaxed(plgpio->regs.dir + in plgpio_suspend()
625 off); in plgpio_suspend()
626 plgpio->csave_regs[i].ie = readl_relaxed(plgpio->regs.ie + off); in plgpio_suspend()
636 * bit values (non-plgpio bits), and retain captured value (plgpio bits).
640 _tmp = readl_relaxed(plgpio->regs.__reg + _off); \
642 plgpio->csave_regs[i].__reg = \
643 _tmp | (plgpio->csave_regs[i].__reg & _mask); \
649 int i, reg_count = DIV_ROUND_UP(plgpio->chip.ngpio, MAX_GPIO_PER_REG); in plgpio_resume()
650 void __iomem *off; in plgpio_resume() local
654 off = plgpio->base + i * sizeof(int *); in plgpio_resume()
656 if (i == reg_count - 1) { in plgpio_resume()
657 mask = (1 << (plgpio->chip.ngpio - i * in plgpio_resume()
658 MAX_GPIO_PER_REG)) - 1; in plgpio_resume()
660 if (plgpio->regs.enb != -1) in plgpio_resume()
661 plgpio_prepare_reg(enb, off, mask, tmp); in plgpio_resume()
663 if (plgpio->regs.eit != -1) in plgpio_resume()
664 plgpio_prepare_reg(eit, off, mask, tmp); in plgpio_resume()
666 plgpio_prepare_reg(wdata, off, mask, tmp); in plgpio_resume()
667 plgpio_prepare_reg(dir, off, mask, tmp); in plgpio_resume()
668 plgpio_prepare_reg(ie, off, mask, tmp); in plgpio_resume()
671 writel_relaxed(plgpio->csave_regs[i].wdata, plgpio->regs.wdata + in plgpio_resume()
672 off); in plgpio_resume()
673 writel_relaxed(plgpio->csave_regs[i].dir, plgpio->regs.dir + in plgpio_resume()
674 off); in plgpio_resume()
676 if (plgpio->regs.eit != -1) in plgpio_resume()
677 writel_relaxed(plgpio->csave_regs[i].eit, in plgpio_resume()
678 plgpio->regs.eit + off); in plgpio_resume()
680 writel_relaxed(plgpio->csave_regs[i].ie, plgpio->regs.ie + off); in plgpio_resume()
682 if (plgpio->regs.enb != -1) in plgpio_resume()
683 writel_relaxed(plgpio->csave_regs[i].enb, in plgpio_resume()
684 plgpio->regs.enb + off); in plgpio_resume()
694 { .compatible = "st,spear-plgpio" },
701 .name = "spear-plgpio",