Lines Matching +full:3 +full:- +full:port

1 // SPDX-License-Identifier: GPL-2.0-only
34 * struct ws16c48_gpio - GPIO device private data structure
41 * @base: base port address of the GPIO device
56 const unsigned port = offset / 8; in ws16c48_gpio_get_direction() local
59 if (ws16c48gpio->io_state[port] & mask) in ws16c48_gpio_get_direction()
68 const unsigned port = offset / 8; in ws16c48_gpio_direction_input() local
72 raw_spin_lock_irqsave(&ws16c48gpio->lock, flags); in ws16c48_gpio_direction_input()
74 ws16c48gpio->io_state[port] |= mask; in ws16c48_gpio_direction_input()
75 ws16c48gpio->out_state[port] &= ~mask; in ws16c48_gpio_direction_input()
76 outb(ws16c48gpio->out_state[port], ws16c48gpio->base + port); in ws16c48_gpio_direction_input()
78 raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); in ws16c48_gpio_direction_input()
87 const unsigned port = offset / 8; in ws16c48_gpio_direction_output() local
91 raw_spin_lock_irqsave(&ws16c48gpio->lock, flags); in ws16c48_gpio_direction_output()
93 ws16c48gpio->io_state[port] &= ~mask; in ws16c48_gpio_direction_output()
95 ws16c48gpio->out_state[port] |= mask; in ws16c48_gpio_direction_output()
97 ws16c48gpio->out_state[port] &= ~mask; in ws16c48_gpio_direction_output()
98 outb(ws16c48gpio->out_state[port], ws16c48gpio->base + port); in ws16c48_gpio_direction_output()
100 raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); in ws16c48_gpio_direction_output()
108 const unsigned port = offset / 8; in ws16c48_gpio_get() local
113 raw_spin_lock_irqsave(&ws16c48gpio->lock, flags); in ws16c48_gpio_get()
116 if (!(ws16c48gpio->io_state[port] & mask)) { in ws16c48_gpio_get()
117 raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); in ws16c48_gpio_get()
118 return -EINVAL; in ws16c48_gpio_get()
121 port_state = inb(ws16c48gpio->base + port); in ws16c48_gpio_get()
123 raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); in ws16c48_gpio_get()
138 bitmap_zero(bits, chip->ngpio); in ws16c48_gpio_get_multiple()
140 for_each_set_clump8(offset, gpio_mask, mask, chip->ngpio) { in ws16c48_gpio_get_multiple()
141 port_addr = ws16c48gpio->base + offset / 8; in ws16c48_gpio_get_multiple()
153 const unsigned port = offset / 8; in ws16c48_gpio_set() local
157 raw_spin_lock_irqsave(&ws16c48gpio->lock, flags); in ws16c48_gpio_set()
160 if (ws16c48gpio->io_state[port] & mask) { in ws16c48_gpio_set()
161 raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); in ws16c48_gpio_set()
166 ws16c48gpio->out_state[port] |= mask; in ws16c48_gpio_set()
168 ws16c48gpio->out_state[port] &= ~mask; in ws16c48_gpio_set()
169 outb(ws16c48gpio->out_state[port], ws16c48gpio->base + port); in ws16c48_gpio_set()
171 raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); in ws16c48_gpio_set()
185 for_each_set_clump8(offset, gpio_mask, mask, chip->ngpio) { in ws16c48_gpio_set_multiple()
187 port_addr = ws16c48gpio->base + index; in ws16c48_gpio_set_multiple()
190 gpio_mask &= ~ws16c48gpio->io_state[index]; in ws16c48_gpio_set_multiple()
193 raw_spin_lock_irqsave(&ws16c48gpio->lock, flags); in ws16c48_gpio_set_multiple()
196 ws16c48gpio->out_state[index] &= ~gpio_mask; in ws16c48_gpio_set_multiple()
197 ws16c48gpio->out_state[index] |= bitmask; in ws16c48_gpio_set_multiple()
198 outb(ws16c48gpio->out_state[index], port_addr); in ws16c48_gpio_set_multiple()
200 raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); in ws16c48_gpio_set_multiple()
209 const unsigned port = offset / 8; in ws16c48_irq_ack() local
214 /* only the first 3 ports support interrupts */ in ws16c48_irq_ack()
215 if (port > 2) in ws16c48_irq_ack()
218 raw_spin_lock_irqsave(&ws16c48gpio->lock, flags); in ws16c48_irq_ack()
220 port_state = ws16c48gpio->irq_mask >> (8*port); in ws16c48_irq_ack()
222 outb(0x80, ws16c48gpio->base + 7); in ws16c48_irq_ack()
223 outb(port_state & ~mask, ws16c48gpio->base + 8 + port); in ws16c48_irq_ack()
224 outb(port_state | mask, ws16c48gpio->base + 8 + port); in ws16c48_irq_ack()
225 outb(0xC0, ws16c48gpio->base + 7); in ws16c48_irq_ack()
227 raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); in ws16c48_irq_ack()
236 const unsigned port = offset / 8; in ws16c48_irq_mask() local
239 /* only the first 3 ports support interrupts */ in ws16c48_irq_mask()
240 if (port > 2) in ws16c48_irq_mask()
243 raw_spin_lock_irqsave(&ws16c48gpio->lock, flags); in ws16c48_irq_mask()
245 ws16c48gpio->irq_mask &= ~mask; in ws16c48_irq_mask()
247 outb(0x80, ws16c48gpio->base + 7); in ws16c48_irq_mask()
248 outb(ws16c48gpio->irq_mask >> (8*port), ws16c48gpio->base + 8 + port); in ws16c48_irq_mask()
249 outb(0xC0, ws16c48gpio->base + 7); in ws16c48_irq_mask()
251 raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); in ws16c48_irq_mask()
260 const unsigned port = offset / 8; in ws16c48_irq_unmask() local
263 /* only the first 3 ports support interrupts */ in ws16c48_irq_unmask()
264 if (port > 2) in ws16c48_irq_unmask()
267 raw_spin_lock_irqsave(&ws16c48gpio->lock, flags); in ws16c48_irq_unmask()
269 ws16c48gpio->irq_mask |= mask; in ws16c48_irq_unmask()
271 outb(0x80, ws16c48gpio->base + 7); in ws16c48_irq_unmask()
272 outb(ws16c48gpio->irq_mask >> (8*port), ws16c48gpio->base + 8 + port); in ws16c48_irq_unmask()
273 outb(0xC0, ws16c48gpio->base + 7); in ws16c48_irq_unmask()
275 raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); in ws16c48_irq_unmask()
284 const unsigned port = offset / 8; in ws16c48_irq_set_type() local
287 /* only the first 3 ports support interrupts */ in ws16c48_irq_set_type()
288 if (port > 2) in ws16c48_irq_set_type()
289 return -EINVAL; in ws16c48_irq_set_type()
291 raw_spin_lock_irqsave(&ws16c48gpio->lock, flags); in ws16c48_irq_set_type()
297 ws16c48gpio->flow_mask |= mask; in ws16c48_irq_set_type()
300 ws16c48gpio->flow_mask &= ~mask; in ws16c48_irq_set_type()
303 raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); in ws16c48_irq_set_type()
304 return -EINVAL; in ws16c48_irq_set_type()
307 outb(0x40, ws16c48gpio->base + 7); in ws16c48_irq_set_type()
308 outb(ws16c48gpio->flow_mask >> (8*port), ws16c48gpio->base + 8 + port); in ws16c48_irq_set_type()
309 outb(0xC0, ws16c48gpio->base + 7); in ws16c48_irq_set_type()
311 raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); in ws16c48_irq_set_type()
327 struct gpio_chip *const chip = &ws16c48gpio->chip; in ws16c48_irq_handler()
329 unsigned long port; in ws16c48_irq_handler() local
333 int_pending = inb(ws16c48gpio->base + 6) & 0x7; in ws16c48_irq_handler()
339 for_each_set_bit(port, &int_pending, 3) { in ws16c48_irq_handler()
340 int_id = inb(ws16c48gpio->base + 8 + port); in ws16c48_irq_handler()
343 chip->irq.domain, gpio + 8*port)); in ws16c48_irq_handler()
346 int_pending = inb(ws16c48gpio->base + 6) & 0x7; in ws16c48_irq_handler()
354 "Port 0 Bit 0", "Port 0 Bit 1", "Port 0 Bit 2", "Port 0 Bit 3",
355 "Port 0 Bit 4", "Port 0 Bit 5", "Port 0 Bit 6", "Port 0 Bit 7",
356 "Port 1 Bit 0", "Port 1 Bit 1", "Port 1 Bit 2", "Port 1 Bit 3",
357 "Port 1 Bit 4", "Port 1 Bit 5", "Port 1 Bit 6", "Port 1 Bit 7",
358 "Port 2 Bit 0", "Port 2 Bit 1", "Port 2 Bit 2", "Port 2 Bit 3",
359 "Port 2 Bit 4", "Port 2 Bit 5", "Port 2 Bit 6", "Port 2 Bit 7",
360 "Port 3 Bit 0", "Port 3 Bit 1", "Port 3 Bit 2", "Port 3 Bit 3",
361 "Port 3 Bit 4", "Port 3 Bit 5", "Port 3 Bit 6", "Port 3 Bit 7",
362 "Port 4 Bit 0", "Port 4 Bit 1", "Port 4 Bit 2", "Port 4 Bit 3",
363 "Port 4 Bit 4", "Port 4 Bit 5", "Port 4 Bit 6", "Port 4 Bit 7",
364 "Port 5 Bit 0", "Port 5 Bit 1", "Port 5 Bit 2", "Port 5 Bit 3",
365 "Port 5 Bit 4", "Port 5 Bit 5", "Port 5 Bit 6", "Port 5 Bit 7"
373 outb(0x80, ws16c48gpio->base + 7); in ws16c48_irq_init_hw()
374 outb(0, ws16c48gpio->base + 8); in ws16c48_irq_init_hw()
375 outb(0, ws16c48gpio->base + 9); in ws16c48_irq_init_hw()
376 outb(0, ws16c48gpio->base + 10); in ws16c48_irq_init_hw()
377 outb(0xC0, ws16c48gpio->base + 7); in ws16c48_irq_init_hw()
391 return -ENOMEM; in ws16c48_probe()
394 dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n", in ws16c48_probe()
396 return -EBUSY; in ws16c48_probe()
399 ws16c48gpio->chip.label = name; in ws16c48_probe()
400 ws16c48gpio->chip.parent = dev; in ws16c48_probe()
401 ws16c48gpio->chip.owner = THIS_MODULE; in ws16c48_probe()
402 ws16c48gpio->chip.base = -1; in ws16c48_probe()
403 ws16c48gpio->chip.ngpio = WS16C48_NGPIO; in ws16c48_probe()
404 ws16c48gpio->chip.names = ws16c48_names; in ws16c48_probe()
405 ws16c48gpio->chip.get_direction = ws16c48_gpio_get_direction; in ws16c48_probe()
406 ws16c48gpio->chip.direction_input = ws16c48_gpio_direction_input; in ws16c48_probe()
407 ws16c48gpio->chip.direction_output = ws16c48_gpio_direction_output; in ws16c48_probe()
408 ws16c48gpio->chip.get = ws16c48_gpio_get; in ws16c48_probe()
409 ws16c48gpio->chip.get_multiple = ws16c48_gpio_get_multiple; in ws16c48_probe()
410 ws16c48gpio->chip.set = ws16c48_gpio_set; in ws16c48_probe()
411 ws16c48gpio->chip.set_multiple = ws16c48_gpio_set_multiple; in ws16c48_probe()
412 ws16c48gpio->base = base[id]; in ws16c48_probe()
414 girq = &ws16c48gpio->chip.irq; in ws16c48_probe()
415 girq->chip = &ws16c48_irqchip; in ws16c48_probe()
417 girq->parent_handler = NULL; in ws16c48_probe()
418 girq->num_parents = 0; in ws16c48_probe()
419 girq->parents = NULL; in ws16c48_probe()
420 girq->default_type = IRQ_TYPE_NONE; in ws16c48_probe()
421 girq->handler = handle_edge_irq; in ws16c48_probe()
422 girq->init_hw = ws16c48_irq_init_hw; in ws16c48_probe()
424 raw_spin_lock_init(&ws16c48gpio->lock); in ws16c48_probe()
426 err = devm_gpiochip_add_data(dev, &ws16c48gpio->chip, ws16c48gpio); in ws16c48_probe()