Commit 1e0d9823 authored by Daniel Krueger's avatar Daniel Krueger Committed by Linus Walleij

gpio-sch: set output level after configuration of direction

According to the datasheet, writing to the level register has no effect
when GPIO is programmed as input. Actually the the level register is
read-only when configured as input. Thus presetting the output level
before switching to output is _NOT_ possible. Any writes are lost!
Hence we set the level after configuring the GPIO as output.
But we cannot prevent a short low pulse if direction is set to high and
an external  pull-up is connected.
Signed-off-by: default avatarDaniel Krueger <daniel.krueger@systec-electronic.com>
Signed-off-by: default avatarAlexander Stein <alexander.stein@systec-electronic.com>
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
parent 9ea8d810
...@@ -97,8 +97,6 @@ static int sch_gpio_core_direction_out(struct gpio_chip *gc, ...@@ -97,8 +97,6 @@ static int sch_gpio_core_direction_out(struct gpio_chip *gc,
u8 curr_dirs; u8 curr_dirs;
unsigned short offset, bit; unsigned short offset, bit;
sch_gpio_core_set(gc, gpio_num, val);
spin_lock(&gpio_lock); spin_lock(&gpio_lock);
offset = CGIO + gpio_num / 8; offset = CGIO + gpio_num / 8;
...@@ -109,6 +107,17 @@ static int sch_gpio_core_direction_out(struct gpio_chip *gc, ...@@ -109,6 +107,17 @@ static int sch_gpio_core_direction_out(struct gpio_chip *gc,
outb(curr_dirs & ~(1 << bit), gpio_ba + offset); outb(curr_dirs & ~(1 << bit), gpio_ba + offset);
spin_unlock(&gpio_lock); spin_unlock(&gpio_lock);
/*
* according to the datasheet, writing to the level register has no
* effect when GPIO is programmed as input.
* Actually the the level register is read-only when configured as input.
* Thus presetting the output level before switching to output is _NOT_ possible.
* Hence we set the level after configuring the GPIO as output.
* But we cannot prevent a short low pulse if direction is set to high
* and an external pull-up is connected.
*/
sch_gpio_core_set(gc, gpio_num, val);
return 0; return 0;
} }
...@@ -178,8 +187,6 @@ static int sch_gpio_resume_direction_out(struct gpio_chip *gc, ...@@ -178,8 +187,6 @@ static int sch_gpio_resume_direction_out(struct gpio_chip *gc,
u8 curr_dirs; u8 curr_dirs;
unsigned short offset, bit; unsigned short offset, bit;
sch_gpio_resume_set(gc, gpio_num, val);
offset = RGIO + gpio_num / 8; offset = RGIO + gpio_num / 8;
bit = gpio_num % 8; bit = gpio_num % 8;
...@@ -190,6 +197,17 @@ static int sch_gpio_resume_direction_out(struct gpio_chip *gc, ...@@ -190,6 +197,17 @@ static int sch_gpio_resume_direction_out(struct gpio_chip *gc,
outb(curr_dirs & ~(1 << bit), gpio_ba + offset); outb(curr_dirs & ~(1 << bit), gpio_ba + offset);
spin_unlock(&gpio_lock); spin_unlock(&gpio_lock);
/*
* according to the datasheet, writing to the level register has no
* effect when GPIO is programmed as input.
* Actually the the level register is read-only when configured as input.
* Thus presetting the output level before switching to output is _NOT_ possible.
* Hence we set the level after configuring the GPIO as output.
* But we cannot prevent a short low pulse if direction is set to high
* and an external pull-up is connected.
*/
sch_gpio_resume_set(gc, gpio_num, val);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment