hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/gpio/gpio-ts4900.c
....@@ -1,7 +1,7 @@
11 /*
22 * Digital I/O driver for Technologic Systems I2C FPGA Core
33 *
4
- * Copyright (C) 2015 Technologic Systems
4
+ * Copyright (C) 2015, 2018 Technologic Systems
55 * Copyright (C) 2016 Savoir-Faire Linux
66 *
77 * This program is free software; you can redistribute it and/or
....@@ -44,7 +44,10 @@
4444
4545 regmap_read(priv->regmap, offset, &reg);
4646
47
- return !(reg & TS4900_GPIO_OE);
47
+ if (reg & TS4900_GPIO_OE)
48
+ return GPIO_LINE_DIRECTION_OUT;
49
+
50
+ return GPIO_LINE_DIRECTION_IN;
4851 }
4952
5053 static int ts4900_gpio_direction_input(struct gpio_chip *chip,
....@@ -52,19 +55,33 @@
5255 {
5356 struct ts4900_gpio_priv *priv = gpiochip_get_data(chip);
5457
55
- /*
56
- * This will clear the output enable bit, the other bits are
57
- * dontcare when this is cleared
58
+ /* Only clear the OE bit here, requires a RMW. Prevents potential issue
59
+ * with OE and data getting to the physical pin at different times.
5860 */
59
- return regmap_write(priv->regmap, offset, 0);
61
+ return regmap_update_bits(priv->regmap, offset, TS4900_GPIO_OE, 0);
6062 }
6163
6264 static int ts4900_gpio_direction_output(struct gpio_chip *chip,
6365 unsigned int offset, int value)
6466 {
6567 struct ts4900_gpio_priv *priv = gpiochip_get_data(chip);
68
+ unsigned int reg;
6669 int ret;
6770
71
+ /* If changing from an input to an output, we need to first set the
72
+ * proper data bit to what is requested and then set OE bit. This
73
+ * prevents a glitch that can occur on the IO line
74
+ */
75
+ regmap_read(priv->regmap, offset, &reg);
76
+ if (!(reg & TS4900_GPIO_OE)) {
77
+ if (value)
78
+ reg = TS4900_GPIO_OUT;
79
+ else
80
+ reg &= ~TS4900_GPIO_OUT;
81
+
82
+ regmap_write(priv->regmap, offset, reg);
83
+ }
84
+
6885 if (value)
6986 ret = regmap_write(priv->regmap, offset, TS4900_GPIO_OE |
7087 TS4900_GPIO_OUT);