Lines Matching +full:3 +full:- +full:line
1 // SPDX-License-Identifier: GPL-2.0
3 * Digital I/O driver for Technologic Systems TS-5500
5 * Copyright (c) 2012 Savoir-faire Linux Inc.
10 * In that sense, the support is not limited to the TS-5500 blocks.
13 * TS-5500:
14 * Documentation: https://docs.embeddedts.com/TS-5500
17 * TS-5600:
18 * Documentation: https://docs.embeddedts.com/TS-5600
19 * Blocks: LCD port (identical to TS-5500 LCD).
99 TS5500_DIO_IN_OUT(vaddr, vbitfrom + 3, caddr, cbit)
102 * TS-5500 DIO1 block
108 * 0x7b 1 0x7a 0 x x DIO1_1 3 1
110 * 0x7b 3 0x7a 0 x x DIO1_3 7 3
118 * 0x7c 3 0x7a 5 x x DIO1_11 10 11
131 * TS-5500 DIO2 block
137 * 0x7e 1 0x7d 0 x x DIO2_1 3 1
139 * 0x7e 3 0x7d 0 x x DIO2_3 7 3
147 * 0x7f 3 0x7d 5 x x DIO2_11 10 11
158 * TS-5500 LCD port used as DIO block
159 * TS-5600 LCD port is identical
167 * 0x72 3 0x7d 2 x x LCD_3 9 3
168 * 0x72 4 0x7d 3 x x LCD_4 12 4
169 * 0x72 5 0x7d 3 x x LCD_5 11 5
170 * 0x72 6 0x7d 3 x x LCD_6 14 6
171 * 0x72 7 0x7d 3 x x LCD_7 13 7
174 * 0x73 7 x 1 LCD_RS 3 10
178 TS5500_DIO_GROUP(0x72, 4, 0x7d, 3),
201 const struct ts5500_dio line = priv->pinout[offset]; in ts5500_gpio_input() local
204 if (line.no_input) in ts5500_gpio_input()
205 return -ENXIO; in ts5500_gpio_input()
207 if (line.no_output) in ts5500_gpio_input()
210 spin_lock_irqsave(&priv->lock, flags); in ts5500_gpio_input()
211 ts5500_clear_mask(line.control_mask, line.control_addr); in ts5500_gpio_input()
212 spin_unlock_irqrestore(&priv->lock, flags); in ts5500_gpio_input()
220 const struct ts5500_dio line = priv->pinout[offset]; in ts5500_gpio_get() local
222 return !!(inb(line.value_addr) & line.value_mask); in ts5500_gpio_get()
228 const struct ts5500_dio line = priv->pinout[offset]; in ts5500_gpio_output() local
231 if (line.no_output) in ts5500_gpio_output()
232 return -ENXIO; in ts5500_gpio_output()
234 spin_lock_irqsave(&priv->lock, flags); in ts5500_gpio_output()
235 if (!line.no_input) in ts5500_gpio_output()
236 ts5500_set_mask(line.control_mask, line.control_addr); in ts5500_gpio_output()
239 ts5500_set_mask(line.value_mask, line.value_addr); in ts5500_gpio_output()
241 ts5500_clear_mask(line.value_mask, line.value_addr); in ts5500_gpio_output()
242 spin_unlock_irqrestore(&priv->lock, flags); in ts5500_gpio_output()
250 const struct ts5500_dio line = priv->pinout[offset]; in ts5500_gpio_set() local
253 spin_lock_irqsave(&priv->lock, flags); in ts5500_gpio_set()
255 ts5500_set_mask(line.value_mask, line.value_addr); in ts5500_gpio_set()
257 ts5500_clear_mask(line.value_mask, line.value_addr); in ts5500_gpio_set()
258 spin_unlock_irqrestore(&priv->lock, flags); in ts5500_gpio_set()
264 const struct ts5500_dio *block = priv->pinout; in ts5500_gpio_to_irq()
265 const struct ts5500_dio line = block[offset]; in ts5500_gpio_to_irq() local
268 if (line.irq) in ts5500_gpio_to_irq()
269 return line.irq; in ts5500_gpio_to_irq()
271 /* As this pin is input-only, we may strap it to another in/out pin */ in ts5500_gpio_to_irq()
272 if (priv->strap) in ts5500_gpio_to_irq()
273 return priv->hwirq; in ts5500_gpio_to_irq()
275 return -ENXIO; in ts5500_gpio_to_irq()
283 spin_lock_irqsave(&priv->lock, flags); in ts5500_enable_irq()
284 if (priv->hwirq == 7) in ts5500_enable_irq()
286 else if (priv->hwirq == 6) in ts5500_enable_irq()
288 else if (priv->hwirq == 1) in ts5500_enable_irq()
291 ret = -EINVAL; in ts5500_enable_irq()
292 spin_unlock_irqrestore(&priv->lock, flags); in ts5500_enable_irq()
301 spin_lock_irqsave(&priv->lock, flags); in ts5500_disable_irq()
302 if (priv->hwirq == 7) in ts5500_disable_irq()
304 else if (priv->hwirq == 6) in ts5500_disable_irq()
306 else if (priv->hwirq == 1) in ts5500_disable_irq()
309 dev_err(priv->gpio_chip.parent, "invalid hwirq %d\n", in ts5500_disable_irq()
310 priv->hwirq); in ts5500_disable_irq()
311 spin_unlock_irqrestore(&priv->lock, flags); in ts5500_disable_irq()
316 enum ts5500_blocks block = platform_get_device_id(pdev)->driver_data; in ts5500_dio_probe()
317 struct device *dev = &pdev->dev; in ts5500_dio_probe()
329 return -ENOMEM; in ts5500_dio_probe()
332 priv->hwirq = ret; in ts5500_dio_probe()
333 spin_lock_init(&priv->lock); in ts5500_dio_probe()
335 priv->gpio_chip.owner = THIS_MODULE; in ts5500_dio_probe()
336 priv->gpio_chip.label = name; in ts5500_dio_probe()
337 priv->gpio_chip.parent = dev; in ts5500_dio_probe()
338 priv->gpio_chip.direction_input = ts5500_gpio_input; in ts5500_dio_probe()
339 priv->gpio_chip.direction_output = ts5500_gpio_output; in ts5500_dio_probe()
340 priv->gpio_chip.get = ts5500_gpio_get; in ts5500_dio_probe()
341 priv->gpio_chip.set = ts5500_gpio_set; in ts5500_dio_probe()
342 priv->gpio_chip.to_irq = ts5500_gpio_to_irq; in ts5500_dio_probe()
343 priv->gpio_chip.base = -1; in ts5500_dio_probe()
347 priv->pinout = ts5500_dio1; in ts5500_dio_probe()
348 priv->gpio_chip.ngpio = ARRAY_SIZE(ts5500_dio1); in ts5500_dio_probe()
350 if (!devm_request_region(dev, 0x7a, 3, name)) { in ts5500_dio_probe()
352 return -EBUSY; in ts5500_dio_probe()
356 priv->pinout = ts5500_dio2; in ts5500_dio_probe()
357 priv->gpio_chip.ngpio = ARRAY_SIZE(ts5500_dio2); in ts5500_dio_probe()
361 return -EBUSY; in ts5500_dio_probe()
369 return -EBUSY; in ts5500_dio_probe()
376 priv->pinout = ts5500_lcd; in ts5500_dio_probe()
377 priv->gpio_chip.ngpio = ARRAY_SIZE(ts5500_lcd); in ts5500_dio_probe()
381 return -EBUSY; in ts5500_dio_probe()
387 return -EBUSY; in ts5500_dio_probe()
394 spin_lock_irqsave(&priv->lock, flags); in ts5500_dio_probe()
396 spin_unlock_irqrestore(&priv->lock, flags); in ts5500_dio_probe()
400 ret = devm_gpiochip_add_data(dev, &priv->gpio_chip, priv); in ts5500_dio_probe()
408 dev_err(dev, "invalid interrupt %d\n", priv->hwirq); in ts5500_dio_probe()
423 { "ts5500-dio1", TS5500_DIO1 },
424 { "ts5500-dio2", TS5500_DIO2 },
425 { "ts5500-dio-lcd", TS5500_LCD },
426 { "ts5600-dio-lcd", TS5600_LCD },
433 .name = "ts5500-dio",
443 MODULE_AUTHOR("Savoir-faire Linux Inc. <kernel@savoirfairelinux.com>");
444 MODULE_DESCRIPTION("Technologic Systems TS-5500 Digital I/O driver");