Lines Matching +full:4 +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).
91 * Input/Output DIO lines are programmed in groups of 4. Their values are
92 * available through 4 consecutive bits in a value port, whereas the direction
93 * of these 4 lines is driven by only 1 bit in a control port.
102 * TS-5500 DIO1 block
111 * 0x7b 4 0x7a 1 x x DIO1_4 9 4
115 * 0x7c 0 0x7a 5 x x DIO1_8 4 8
119 * 0x7c 4 x DIO1_12 12 12
124 TS5500_DIO_GROUP(0x7b, 4, 0x7a, 1),
126 TS5500_DIO_IN(0x7c, 4),
131 * TS-5500 DIO2 block
140 * 0x7e 4 0x7d 1 x x DIO2_4 9 4
144 * 0x7f 0 0x7d 5 x x DIO2_8 4 8
148 * 0x7f 4 x 6 DIO2_13 14 12
152 TS5500_DIO_GROUP(0x7e, 4, 0x7d, 1),
154 TS5500_DIO_IN_IRQ(0x7f, 4, 6),
158 * TS-5500 LCD port used as DIO block
159 * TS-5600 LCD port is identical
168 * 0x72 4 0x7d 3 x x LCD_4 12 4
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()
266 const struct ts5500_dio *block = priv->pinout; in ts5500_gpio_to_irq()
267 const struct ts5500_dio line = block[offset]; in ts5500_gpio_to_irq() local
270 if (line.irq) in ts5500_gpio_to_irq()
271 return line.irq; in ts5500_gpio_to_irq()
273 /* As this pin is input-only, we may strap it to another in/out pin */ in ts5500_gpio_to_irq()
274 if (priv->strap) in ts5500_gpio_to_irq()
275 return priv->hwirq; in ts5500_gpio_to_irq()
277 return -ENXIO; in ts5500_gpio_to_irq()
285 spin_lock_irqsave(&priv->lock, flags); in ts5500_enable_irq()
286 if (priv->hwirq == 7) in ts5500_enable_irq()
288 else if (priv->hwirq == 6) in ts5500_enable_irq()
290 else if (priv->hwirq == 1) in ts5500_enable_irq()
293 ret = -EINVAL; in ts5500_enable_irq()
294 spin_unlock_irqrestore(&priv->lock, flags); in ts5500_enable_irq()
303 spin_lock_irqsave(&priv->lock, flags); in ts5500_disable_irq()
304 if (priv->hwirq == 7) in ts5500_disable_irq()
306 else if (priv->hwirq == 6) in ts5500_disable_irq()
308 else if (priv->hwirq == 1) in ts5500_disable_irq()
311 dev_err(priv->gpio_chip.parent, "invalid hwirq %d\n", in ts5500_disable_irq()
312 priv->hwirq); in ts5500_disable_irq()
313 spin_unlock_irqrestore(&priv->lock, flags); in ts5500_disable_irq()
318 enum ts5500_blocks block = platform_get_device_id(pdev)->driver_data; in ts5500_dio_probe()
319 struct device *dev = &pdev->dev; in ts5500_dio_probe()
331 return -ENOMEM; in ts5500_dio_probe()
334 priv->hwirq = ret; in ts5500_dio_probe()
335 spin_lock_init(&priv->lock); in ts5500_dio_probe()
337 priv->gpio_chip.owner = THIS_MODULE; in ts5500_dio_probe()
338 priv->gpio_chip.label = name; in ts5500_dio_probe()
339 priv->gpio_chip.parent = dev; in ts5500_dio_probe()
340 priv->gpio_chip.direction_input = ts5500_gpio_input; in ts5500_dio_probe()
341 priv->gpio_chip.direction_output = ts5500_gpio_output; in ts5500_dio_probe()
342 priv->gpio_chip.get = ts5500_gpio_get; in ts5500_dio_probe()
343 priv->gpio_chip.set = ts5500_gpio_set; in ts5500_dio_probe()
344 priv->gpio_chip.to_irq = ts5500_gpio_to_irq; in ts5500_dio_probe()
345 priv->gpio_chip.base = -1; in ts5500_dio_probe()
349 priv->pinout = ts5500_dio1; in ts5500_dio_probe()
350 priv->gpio_chip.ngpio = ARRAY_SIZE(ts5500_dio1); in ts5500_dio_probe()
354 return -EBUSY; in ts5500_dio_probe()
358 priv->pinout = ts5500_dio2; in ts5500_dio_probe()
359 priv->gpio_chip.ngpio = ARRAY_SIZE(ts5500_dio2); in ts5500_dio_probe()
363 return -EBUSY; in ts5500_dio_probe()
371 return -EBUSY; in ts5500_dio_probe()
378 priv->pinout = ts5500_lcd; in ts5500_dio_probe()
379 priv->gpio_chip.ngpio = ARRAY_SIZE(ts5500_lcd); in ts5500_dio_probe()
383 return -EBUSY; in ts5500_dio_probe()
389 return -EBUSY; in ts5500_dio_probe()
396 spin_lock_irqsave(&priv->lock, flags); in ts5500_dio_probe()
397 ts5500_clear_mask(BIT(4), 0x7d); in ts5500_dio_probe()
398 spin_unlock_irqrestore(&priv->lock, flags); in ts5500_dio_probe()
402 ret = devm_gpiochip_add_data(dev, &priv->gpio_chip, priv); in ts5500_dio_probe()
410 dev_err(dev, "invalid interrupt %d\n", priv->hwirq); in ts5500_dio_probe()
425 { "ts5500-dio1", TS5500_DIO1 },
426 { "ts5500-dio2", TS5500_DIO2 },
427 { "ts5500-dio-lcd", TS5500_LCD },
428 { "ts5600-dio-lcd", TS5600_LCD },
435 .name = "ts5500-dio",
445 MODULE_AUTHOR("Savoir-faire Linux Inc. <kernel@savoirfairelinux.com>");
446 MODULE_DESCRIPTION("Technologic Systems TS-5500 Digital I/O driver");