[U-Boot] [PATCH] gpio: spear_gpio: Fix gpio_set_value() implementation
Axel Lin
axel.lin at ingics.com
Mon Jul 1 07:32:17 CEST 2013
>
> The questions raised here are valid and it forced me to re-read the
> datasheet. For your convenience, I must tell you that the device is actually
> pl061 from ARM, so the driver can also be named so.
>
> The datasheet is here
> http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0190b/I1002697.html
>
> Quoting from the datasheet
> "The GPIODATA register is the data register. In software control mode,
> values written in the GPIODATA register are transferred onto the GPOUT pins
> if the respective pins have been configured as outputs through the GPIODIR
> register.
>
> In order to write to GPIODATA, the corresponding bits in the mask, resulting
> from the address bus, PADDR[9:2], must be HIGH. Otherwise the bit values
> remain unchanged by the write.
>
> Similarly, the values read from this register are determined for each bit,
> by the mask bit derived from the address used to access the data register,
> PADDR[9:2]. Bits that are 1 in the address mask cause the corresponding bits
> in GPIODATA to be read, and bits that are 0 in the address mask cause the
> corresponding bits in GPIODATA to be read as 0, regardless of their value.
>
> A read from GPIODATA returns the last bit value written if the respective
> pins are configured as output, or it returns the value on the corresponding
> input GPIN bit when these are configured as inputs. All bits are cleared by
> a reset."
>
> After reading all this I am confused about numbering of the gpio's. I think
> the numbering should be from 1 to 8 for a device. And this would mean that
> we should write to *®s->datareg[1 << (gpio - 1)]* instead of the present
> code which is _®s->datareg[1 << (gpio + 2)]_
Hi Vipin,
Thanks for the review and providing the datasheet information.
You mentioned that this is PL061.
So... I just checked the gpio-pl061 driver in linux kernel.
It's writing to _®s->datareg[1 << (gpio + 2)]. and seems no bug
report for this.
And the gpio_get/set implementation in linux kernel has the same behavior as
this patch does:
( below is from linux/drivers/gpio/gpio-pl061.c )
static int pl061_get_value(struct gpio_chip *gc, unsigned offset)
{
struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc);
return !!readb(chip->base + (1 << (offset + 2)));
}
static void pl061_set_value(struct gpio_chip *gc, unsigned offset, int value)
{
struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc);
writeb(!!value << offset, chip->base + (1 << (offset + 2)));
}
BTW, it would be great if you have the hardware to test.
Regards,
Axel
More information about the U-Boot
mailing list