+// SPDX-License-Identifier: GPL-2.0+
/*
* LPC32xxGPIO driver
*
* (C) Copyright 2014 DENX Software Engineering GmbH
* Written-by: Albert ARIBAUD <albert.aribaud@3adev.fr>
- *
- * SPDX-License-Identifier: GPL-2.0+
*/
+#include <common.h>
#include <asm/io.h>
#include <asm/arch-lpc32xx/cpu.h>
#include <asm/arch-lpc32xx/gpio.h>
* read on another one.
*
* In order to keep this code simple, GPIOS are considered here as
- * homogeneous and linear, from 0 to 127.
+ * homogeneous and linear, from 0 to 159.
*
* ** WARNING #1 **
*
* Please read NOTE in description of lpc32xx_gpio_get_function().
*/
-#define LPC32XX_GPIOS 128
+#define LPC32XX_GPIOS 160
struct lpc32xx_gpio_priv {
struct gpio_regs *regs;
/**
* We have 4 GPIO ports of 32 bits each
+ *
+ * Port mapping offset (32 bits each):
+ * - Port 0: 0
+ * - Port 1: 32
+ * - Port 2: 64
+ * - Port 3: GPO / GPIO (output): 96
+ * - Port 3: GPI: 128
*/
-#define MAX_GPIO 128
+#define MAX_GPIO 160
-#define GPIO_TO_PORT(gpio) ((gpio / 32) & 3)
+#define GPIO_TO_PORT(gpio) ((gpio / 32) & 7)
#define GPIO_TO_RANK(gpio) (gpio % 32)
#define GPIO_TO_MASK(gpio) (1 << (gpio % 32))
break;
case 2:
/* ports 2 and 3 share a common direction */
- case 3:
writel(mask, ®s->p2_p3_dir_clr);
break;
+ case 3:
+ /* Setup direction only for GPIO_xx. */
+ if ((mask >= 25) && (mask <= 30))
+ writel(mask, ®s->p2_p3_dir_clr);
+ break;
+ case 4:
+ /* GPI_xx; nothing to do. */
+ break;
default:
return -1;
}
value = readl(®s->p2_inp_state);
break;
case 3:
+ /* Read GPO_xx and GPIO_xx (as output) using p3_outp_state. */
+ value = readl(®s->p3_outp_state);
+ break;
+ case 4:
+ /* Read GPI_xx and GPIO_xx (as input) using p3_inp_state. */
value = readl(®s->p3_inp_state);
break;
default:
case 3:
writel(mask, ®s->p3_outp_set);
break;
+ case 4:
+ /* GPI_xx; invalid. */
default:
return -1;
}
case 3:
writel(mask, ®s->p3_outp_clr);
break;
+ case 4:
+ /* GPI_xx; invalid. */
default:
return -1;
}
break;
case 2:
/* ports 2 and 3 share a common direction */
- case 3:
writel(mask, ®s->p2_p3_dir_set);
break;
+ case 3:
+ /* Setup direction only for GPIO_xx. */
+ if ((mask >= 25) && (mask <= 30))
+ writel(mask, ®s->p2_p3_dir_set);
+ break;
+ case 4:
+ /* GPI_xx; invalid. */
default:
return -1;
}
struct lpc32xx_gpio_priv *gpio_priv = dev_get_priv(dev);
struct gpio_dev_priv *uc_priv = dev->uclass_priv;
- if (dev->of_offset == -1) {
+ if (dev_of_offset(dev) == -1) {
/* Tell the uclass how many GPIOs we have */
uc_priv->gpio_count = LPC32XX_GPIOS;
}