1
0
mirror of https://github.com/merbanan/airoha_ml.git synced 2025-11-10 17:46:10 +00:00
Files
airoha_ml/commit-4da4847
Benjamin Larsson 92f7959aa1 Random driver code
2024-05-05 23:53:56 +02:00

69 lines
2.0 KiB
Plaintext

From 4da48477d2fcc165b0d4e692488b65ada571c884 Mon Sep 17 00:00:00 2001
From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
Date: Fri, 23 Dec 2022 19:18:03 +0300
Subject: gpio: en7523: fix direction set/query
GPIO Control Register uses 2 bit to specify gpio pin function. This
results in 4 possible values:
0: GPIO input mode.
1: GPIO output mode.
2: Reserved
3: Reserved
It may be noted, that only low bit is used to specify pin function.
High bit is reserved and should be zero.
It was noted that some gpio have non-zero reserved bit. Current GPIO
driver does not touch reserved bit. As result it was not possible to
configure as input/output pins with non-zero reserved bit.
Fix an issue by always zero reserved bit.
diff --git a/drivers/gpio/gpio-en7523.c b/drivers/gpio/gpio-en7523.c
index be669ec17..29ab63f97 100755
--- a/drivers/gpio/gpio-en7523.c
+++ b/drivers/gpio/gpio-en7523.c
@@ -86,16 +86,15 @@ static int airoha_dir_set(struct gpio_chip *gc, unsigned int gpio,
int val, int out)
{
struct airoha_gpio_ctrl *ctrl = gc_to_ctrl(gc);
- u32 dir = ioread32(ctrl->dir[gpio / 16]);
u32 output = ioread32(ctrl->output);
- u32 mask = BIT((gpio % 16) * 2);
+ u32 dir = ioread32(ctrl->dir[gpio / 16]);
+ u32 shift = (gpio % 16) * 2;
+ dir &= ~(0x3 << shift);
+ output &= ~BIT(gpio);
if (out) {
- dir |= mask;
+ dir |= (0x1 << shift);
output |= BIT(gpio);
- } else {
- dir &= ~mask;
- output &= ~BIT(gpio);
}
iowrite32(dir, ctrl->dir[gpio / 16]);
@@ -123,9 +122,18 @@ static int airoha_get_dir(struct gpio_chip *gc, unsigned int gpio)
{
struct airoha_gpio_ctrl *ctrl = gc_to_ctrl(gc);
u32 dir = ioread32(ctrl->dir[gpio / 16]);
- u32 mask = BIT((gpio % 16) * 2);
+ u32 shift = (gpio % 16) * 2;
+
+ switch ((dir >> shift) & 0x03) {
+ case 0:
+ return GPIO_LINE_DIRECTION_IN;
+ case 1:
+ return GPIO_LINE_DIRECTION_OUT;
+ default:
+ break;
+ }
- return (dir & mask) ? GPIO_LINE_DIRECTION_OUT : GPIO_LINE_DIRECTION_IN;
+ return -EINVAL;
}
static irqreturn_t airoha_gpio_irq_handler(int irq, void *data)