Lines Matching +full:reg +full:- +full:offset

1 // SPDX-License-Identifier: GPL-2.0-only
35 * struct ws16c48_reg - device register structure
38 * @page_lock: Register page (Bits 7-6) and I/O port lock (Bits 5-0)
49 * struct ws16c48_gpio - GPIO device private data structure
56 * @reg: I/O address offset for the device registers
65 struct ws16c48_reg __iomem *reg; member
68 static int ws16c48_gpio_get_direction(struct gpio_chip *chip, unsigned offset) in ws16c48_gpio_get_direction() argument
71 const unsigned port = offset / 8; in ws16c48_gpio_get_direction()
72 const unsigned mask = BIT(offset % 8); in ws16c48_gpio_get_direction()
74 if (ws16c48gpio->io_state[port] & mask) in ws16c48_gpio_get_direction()
80 static int ws16c48_gpio_direction_input(struct gpio_chip *chip, unsigned offset) in ws16c48_gpio_direction_input() argument
83 const unsigned port = offset / 8; in ws16c48_gpio_direction_input()
84 const unsigned mask = BIT(offset % 8); in ws16c48_gpio_direction_input()
87 raw_spin_lock_irqsave(&ws16c48gpio->lock, flags); in ws16c48_gpio_direction_input()
89 ws16c48gpio->io_state[port] |= mask; in ws16c48_gpio_direction_input()
90 ws16c48gpio->out_state[port] &= ~mask; in ws16c48_gpio_direction_input()
91 iowrite8(ws16c48gpio->out_state[port], ws16c48gpio->reg->port + port); in ws16c48_gpio_direction_input()
93 raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); in ws16c48_gpio_direction_input()
99 unsigned offset, int value) in ws16c48_gpio_direction_output() argument
102 const unsigned port = offset / 8; in ws16c48_gpio_direction_output()
103 const unsigned mask = BIT(offset % 8); in ws16c48_gpio_direction_output()
106 raw_spin_lock_irqsave(&ws16c48gpio->lock, flags); in ws16c48_gpio_direction_output()
108 ws16c48gpio->io_state[port] &= ~mask; in ws16c48_gpio_direction_output()
110 ws16c48gpio->out_state[port] |= mask; in ws16c48_gpio_direction_output()
112 ws16c48gpio->out_state[port] &= ~mask; in ws16c48_gpio_direction_output()
113 iowrite8(ws16c48gpio->out_state[port], ws16c48gpio->reg->port + port); in ws16c48_gpio_direction_output()
115 raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); in ws16c48_gpio_direction_output()
120 static int ws16c48_gpio_get(struct gpio_chip *chip, unsigned offset) in ws16c48_gpio_get() argument
123 const unsigned port = offset / 8; in ws16c48_gpio_get()
124 const unsigned mask = BIT(offset % 8); in ws16c48_gpio_get()
128 raw_spin_lock_irqsave(&ws16c48gpio->lock, flags); in ws16c48_gpio_get()
131 if (!(ws16c48gpio->io_state[port] & mask)) { in ws16c48_gpio_get()
132 raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); in ws16c48_gpio_get()
133 return -EINVAL; in ws16c48_gpio_get()
136 port_state = ioread8(ws16c48gpio->reg->port + port); in ws16c48_gpio_get()
138 raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); in ws16c48_gpio_get()
147 unsigned long offset; in ws16c48_gpio_get_multiple() local
154 bitmap_zero(bits, chip->ngpio); in ws16c48_gpio_get_multiple()
156 for_each_set_clump8(offset, gpio_mask, mask, chip->ngpio) { in ws16c48_gpio_get_multiple()
157 index = offset / 8; in ws16c48_gpio_get_multiple()
158 port_addr = ws16c48gpio->reg->port + index; in ws16c48_gpio_get_multiple()
161 bitmap_set_value8(bits, port_state, offset); in ws16c48_gpio_get_multiple()
167 static void ws16c48_gpio_set(struct gpio_chip *chip, unsigned offset, int value) in ws16c48_gpio_set() argument
170 const unsigned port = offset / 8; in ws16c48_gpio_set()
171 const unsigned mask = BIT(offset % 8); in ws16c48_gpio_set()
174 raw_spin_lock_irqsave(&ws16c48gpio->lock, flags); in ws16c48_gpio_set()
177 if (ws16c48gpio->io_state[port] & mask) { in ws16c48_gpio_set()
178 raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); in ws16c48_gpio_set()
183 ws16c48gpio->out_state[port] |= mask; in ws16c48_gpio_set()
185 ws16c48gpio->out_state[port] &= ~mask; in ws16c48_gpio_set()
186 iowrite8(ws16c48gpio->out_state[port], ws16c48gpio->reg->port + port); in ws16c48_gpio_set()
188 raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); in ws16c48_gpio_set()
195 unsigned long offset; in ws16c48_gpio_set_multiple() local
202 for_each_set_clump8(offset, gpio_mask, mask, chip->ngpio) { in ws16c48_gpio_set_multiple()
203 index = offset / 8; in ws16c48_gpio_set_multiple()
204 port_addr = ws16c48gpio->reg->port + index; in ws16c48_gpio_set_multiple()
207 gpio_mask &= ~ws16c48gpio->io_state[index]; in ws16c48_gpio_set_multiple()
208 bitmask = bitmap_get_value8(bits, offset) & gpio_mask; in ws16c48_gpio_set_multiple()
210 raw_spin_lock_irqsave(&ws16c48gpio->lock, flags); in ws16c48_gpio_set_multiple()
213 ws16c48gpio->out_state[index] &= ~gpio_mask; in ws16c48_gpio_set_multiple()
214 ws16c48gpio->out_state[index] |= bitmask; in ws16c48_gpio_set_multiple()
215 iowrite8(ws16c48gpio->out_state[index], port_addr); in ws16c48_gpio_set_multiple()
217 raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); in ws16c48_gpio_set_multiple()
225 const unsigned long offset = irqd_to_hwirq(data); in ws16c48_irq_ack() local
226 const unsigned port = offset / 8; in ws16c48_irq_ack()
227 const unsigned mask = BIT(offset % 8); in ws16c48_irq_ack()
235 raw_spin_lock_irqsave(&ws16c48gpio->lock, flags); in ws16c48_irq_ack()
237 port_state = ws16c48gpio->irq_mask >> (8*port); in ws16c48_irq_ack()
240 iowrite8(0x80, &ws16c48gpio->reg->page_lock); in ws16c48_irq_ack()
243 iowrite8(port_state & ~mask, ws16c48gpio->reg->pol_enab_int_id + port); in ws16c48_irq_ack()
244 iowrite8(port_state | mask, ws16c48gpio->reg->pol_enab_int_id + port); in ws16c48_irq_ack()
247 iowrite8(0xC0, &ws16c48gpio->reg->page_lock); in ws16c48_irq_ack()
249 raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); in ws16c48_irq_ack()
256 const unsigned long offset = irqd_to_hwirq(data); in ws16c48_irq_mask() local
257 const unsigned long mask = BIT(offset); in ws16c48_irq_mask()
258 const unsigned port = offset / 8; in ws16c48_irq_mask()
266 raw_spin_lock_irqsave(&ws16c48gpio->lock, flags); in ws16c48_irq_mask()
268 ws16c48gpio->irq_mask &= ~mask; in ws16c48_irq_mask()
269 gpiochip_disable_irq(chip, offset); in ws16c48_irq_mask()
270 port_state = ws16c48gpio->irq_mask >> (8 * port); in ws16c48_irq_mask()
273 iowrite8(0x80, &ws16c48gpio->reg->page_lock); in ws16c48_irq_mask()
276 iowrite8(port_state, ws16c48gpio->reg->pol_enab_int_id + port); in ws16c48_irq_mask()
279 iowrite8(0xC0, &ws16c48gpio->reg->page_lock); in ws16c48_irq_mask()
281 raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); in ws16c48_irq_mask()
288 const unsigned long offset = irqd_to_hwirq(data); in ws16c48_irq_unmask() local
289 const unsigned long mask = BIT(offset); in ws16c48_irq_unmask()
290 const unsigned port = offset / 8; in ws16c48_irq_unmask()
298 raw_spin_lock_irqsave(&ws16c48gpio->lock, flags); in ws16c48_irq_unmask()
300 gpiochip_enable_irq(chip, offset); in ws16c48_irq_unmask()
301 ws16c48gpio->irq_mask |= mask; in ws16c48_irq_unmask()
302 port_state = ws16c48gpio->irq_mask >> (8 * port); in ws16c48_irq_unmask()
305 iowrite8(0x80, &ws16c48gpio->reg->page_lock); in ws16c48_irq_unmask()
308 iowrite8(port_state, ws16c48gpio->reg->pol_enab_int_id + port); in ws16c48_irq_unmask()
311 iowrite8(0xC0, &ws16c48gpio->reg->page_lock); in ws16c48_irq_unmask()
313 raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); in ws16c48_irq_unmask()
320 const unsigned long offset = irqd_to_hwirq(data); in ws16c48_irq_set_type() local
321 const unsigned long mask = BIT(offset); in ws16c48_irq_set_type()
322 const unsigned port = offset / 8; in ws16c48_irq_set_type()
328 return -EINVAL; in ws16c48_irq_set_type()
330 raw_spin_lock_irqsave(&ws16c48gpio->lock, flags); in ws16c48_irq_set_type()
336 ws16c48gpio->flow_mask |= mask; in ws16c48_irq_set_type()
339 ws16c48gpio->flow_mask &= ~mask; in ws16c48_irq_set_type()
342 raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); in ws16c48_irq_set_type()
343 return -EINVAL; in ws16c48_irq_set_type()
346 port_state = ws16c48gpio->flow_mask >> (8 * port); in ws16c48_irq_set_type()
349 iowrite8(0x40, &ws16c48gpio->reg->page_lock); in ws16c48_irq_set_type()
352 iowrite8(port_state, ws16c48gpio->reg->pol_enab_int_id + port); in ws16c48_irq_set_type()
355 iowrite8(0xC0, &ws16c48gpio->reg->page_lock); in ws16c48_irq_set_type()
357 raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); in ws16c48_irq_set_type()
375 struct gpio_chip *const chip = &ws16c48gpio->chip; in ws16c48_irq_handler()
376 struct ws16c48_reg __iomem *const reg = ws16c48gpio->reg; in ws16c48_irq_handler() local
382 int_pending = ioread8(&reg->int_pending) & 0x7; in ws16c48_irq_handler()
389 int_id = ioread8(reg->pol_enab_int_id + port); in ws16c48_irq_handler()
391 generic_handle_domain_irq(chip->irq.domain, in ws16c48_irq_handler()
395 int_pending = ioread8(&reg->int_pending) & 0x7; in ws16c48_irq_handler()
422 iowrite8(0x80, &ws16c48gpio->reg->page_lock); in ws16c48_irq_init_hw()
425 iowrite8(0, &ws16c48gpio->reg->pol_enab_int_id[0]); in ws16c48_irq_init_hw()
426 iowrite8(0, &ws16c48gpio->reg->pol_enab_int_id[1]); in ws16c48_irq_init_hw()
427 iowrite8(0, &ws16c48gpio->reg->pol_enab_int_id[2]); in ws16c48_irq_init_hw()
430 iowrite8(0xC0, &ws16c48gpio->reg->page_lock); in ws16c48_irq_init_hw()
444 return -ENOMEM; in ws16c48_probe()
447 dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n", in ws16c48_probe()
449 return -EBUSY; in ws16c48_probe()
452 ws16c48gpio->reg = devm_ioport_map(dev, base[id], WS16C48_EXTENT); in ws16c48_probe()
453 if (!ws16c48gpio->reg) in ws16c48_probe()
454 return -ENOMEM; in ws16c48_probe()
456 ws16c48gpio->chip.label = name; in ws16c48_probe()
457 ws16c48gpio->chip.parent = dev; in ws16c48_probe()
458 ws16c48gpio->chip.owner = THIS_MODULE; in ws16c48_probe()
459 ws16c48gpio->chip.base = -1; in ws16c48_probe()
460 ws16c48gpio->chip.ngpio = WS16C48_NGPIO; in ws16c48_probe()
461 ws16c48gpio->chip.names = ws16c48_names; in ws16c48_probe()
462 ws16c48gpio->chip.get_direction = ws16c48_gpio_get_direction; in ws16c48_probe()
463 ws16c48gpio->chip.direction_input = ws16c48_gpio_direction_input; in ws16c48_probe()
464 ws16c48gpio->chip.direction_output = ws16c48_gpio_direction_output; in ws16c48_probe()
465 ws16c48gpio->chip.get = ws16c48_gpio_get; in ws16c48_probe()
466 ws16c48gpio->chip.get_multiple = ws16c48_gpio_get_multiple; in ws16c48_probe()
467 ws16c48gpio->chip.set = ws16c48_gpio_set; in ws16c48_probe()
468 ws16c48gpio->chip.set_multiple = ws16c48_gpio_set_multiple; in ws16c48_probe()
470 girq = &ws16c48gpio->chip.irq; in ws16c48_probe()
473 girq->parent_handler = NULL; in ws16c48_probe()
474 girq->num_parents = 0; in ws16c48_probe()
475 girq->parents = NULL; in ws16c48_probe()
476 girq->default_type = IRQ_TYPE_NONE; in ws16c48_probe()
477 girq->handler = handle_edge_irq; in ws16c48_probe()
478 girq->init_hw = ws16c48_irq_init_hw; in ws16c48_probe()
480 raw_spin_lock_init(&ws16c48gpio->lock); in ws16c48_probe()
482 err = devm_gpiochip_add_data(dev, &ws16c48gpio->chip, ws16c48gpio); in ws16c48_probe()