summaryrefslogtreecommitdiff
path: root/drivers/gpio/gpio-rcar.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpio/gpio-rcar.c')
-rw-r--r--drivers/gpio/gpio-rcar.c84
1 files changed, 54 insertions, 30 deletions
diff --git a/drivers/gpio/gpio-rcar.c b/drivers/gpio/gpio-rcar.c
index d1a39938809..c1ad20177f7 100644
--- a/drivers/gpio/gpio-rcar.c
+++ b/drivers/gpio/gpio-rcar.c
@@ -18,16 +18,13 @@
#define GPIO_IOINTSEL 0x00 /* General IO/Interrupt Switching Register */
#define GPIO_INOUTSEL 0x04 /* General Input/Output Switching Register */
#define GPIO_OUTDT 0x08 /* General Output Register */
-#define GPIO_INDT 0x0c /* General Input Register */
-#define GPIO_INTDT 0x10 /* Interrupt Display Register */
-#define GPIO_INTCLR 0x14 /* Interrupt Clear Register */
-#define GPIO_INTMSK 0x18 /* Interrupt Mask Register */
-#define GPIO_MSKCLR 0x1c /* Interrupt Mask Clear Register */
-#define GPIO_POSNEG 0x20 /* Positive/Negative Logic Select Register */
-#define GPIO_EDGLEVEL 0x24 /* Edge/level Select Register */
-#define GPIO_FILONOFF 0x28 /* Chattering Prevention On/Off Register */
-#define GPIO_BOTHEDGE 0x4c /* One Edge/Both Edge Select Register */
-#define GPIO_INEN 0x50 /* General Input Enable Register */
+#define GPIO_INDT_G2 0x0c /* General Input Register */
+#define GPIO_POSNEG_G2 0x20 /* Positive/Negative Logic Select Register */
+#define GPIO_INEN_G4 0x50 /* General Input Enable Register */
+
+#define GPIO_INDT_G5 0x1c /* General Input Register */
+#define GPIO_POSNEG_G5 0x90 /* Positive/Negative Logic Select Register */
+#define GPIO_INEN_G5 0x18 /* General Input Enable Register */
#define RCAR_MAX_GPIO_PER_BANK 32
@@ -35,15 +32,22 @@
DECLARE_GLOBAL_DATA_PTR;
+struct rcar_gpio_data {
+ u32 quirks;
+ u32 indt_offset;
+ u32 posneg_offset;
+ u32 inen_offset;
+};
+
struct rcar_gpio_priv {
- void __iomem *regs;
- u32 quirks;
- int pfc_offset;
+ void __iomem *regs;
+ const struct rcar_gpio_data *data;
};
static int rcar_gpio_get_value(struct udevice *dev, unsigned offset)
{
struct rcar_gpio_priv *priv = dev_get_priv(dev);
+ const struct rcar_gpio_data *data = priv->data;
const u32 bit = BIT(offset);
/*
@@ -53,7 +57,7 @@ static int rcar_gpio_get_value(struct udevice *dev, unsigned offset)
if (readl(priv->regs + GPIO_INOUTSEL) & bit)
return !!(readl(priv->regs + GPIO_OUTDT) & bit);
else
- return !!(readl(priv->regs + GPIO_INDT) & bit);
+ return !!(readl(priv->regs + data->indt_offset) & bit);
}
static int rcar_gpio_set_value(struct udevice *dev, unsigned offset,
@@ -73,6 +77,7 @@ static void rcar_gpio_set_direction(struct udevice *dev, unsigned offset,
bool output)
{
struct rcar_gpio_priv *priv = dev_get_priv(dev);
+ const struct rcar_gpio_data *data = priv->data;
void __iomem *regs = priv->regs;
/*
@@ -82,14 +87,14 @@ static void rcar_gpio_set_direction(struct udevice *dev, unsigned offset,
*/
/* Configure postive logic in POSNEG */
- clrbits_le32(regs + GPIO_POSNEG, BIT(offset));
+ clrbits_le32(regs + data->posneg_offset, BIT(offset));
/* Select "Input Enable/Disable" in INEN */
- if (priv->quirks & RCAR_GPIO_HAS_INEN) {
+ if (data->quirks & RCAR_GPIO_HAS_INEN) {
if (output)
- clrbits_le32(regs + GPIO_INEN, BIT(offset));
+ clrbits_le32(regs + data->inen_offset, BIT(offset));
else
- setbits_le32(regs + GPIO_INEN, BIT(offset));
+ setbits_le32(regs + data->inen_offset, BIT(offset));
}
/* Select "General Input/Output Mode" in IOINTSEL */
@@ -149,12 +154,11 @@ static int rcar_gpio_probe(struct udevice *dev)
int ret;
priv->regs = dev_read_addr_ptr(dev);
- priv->quirks = dev_get_driver_data(dev);
+ priv->data = (const struct rcar_gpio_data *)dev_get_driver_data(dev);
uc_priv->bank_name = dev->name;
ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, node, "gpio-ranges",
NULL, 3, 0, &args);
- priv->pfc_offset = ret == 0 ? args.args[1] : -1;
uc_priv->gpio_count = ret == 0 ? args.args[2] : RCAR_MAX_GPIO_PER_BANK;
ret = clk_get_by_index(dev, 0, &clk);
@@ -172,17 +176,37 @@ static int rcar_gpio_probe(struct udevice *dev)
return 0;
}
+static const struct rcar_gpio_data rcar_gpio_gen2_data = {
+ .indt_offset = GPIO_INDT_G2,
+ .posneg_offset = GPIO_POSNEG_G2,
+};
+
+static const struct rcar_gpio_data rcar_gpio_gen3_data = {
+ .quirks = RCAR_GPIO_HAS_INEN,
+ .indt_offset = GPIO_INDT_G2,
+ .posneg_offset = GPIO_POSNEG_G2,
+ .inen_offset = GPIO_INEN_G4,
+};
+
+static const struct rcar_gpio_data rcar_gpio_gen5_data = {
+ .quirks = RCAR_GPIO_HAS_INEN,
+ .indt_offset = GPIO_INDT_G5,
+ .posneg_offset = GPIO_POSNEG_G5,
+ .inen_offset = GPIO_INEN_G5,
+};
+
static const struct udevice_id rcar_gpio_ids[] = {
- { .compatible = "renesas,gpio-r8a7795" },
- { .compatible = "renesas,gpio-r8a7796" },
- { .compatible = "renesas,gpio-r8a77965" },
- { .compatible = "renesas,gpio-r8a77970" },
- { .compatible = "renesas,gpio-r8a77990" },
- { .compatible = "renesas,gpio-r8a77995" },
- { .compatible = "renesas,gpio-r8a779a0", .data = RCAR_GPIO_HAS_INEN },
- { .compatible = "renesas,rcar-gen2-gpio" },
- { .compatible = "renesas,rcar-gen3-gpio" },
- { .compatible = "renesas,rcar-gen4-gpio", .data = RCAR_GPIO_HAS_INEN },
+ { .compatible = "renesas,gpio-r8a7795", .data = (ulong)&rcar_gpio_gen2_data },
+ { .compatible = "renesas,gpio-r8a7796", .data = (ulong)&rcar_gpio_gen2_data },
+ { .compatible = "renesas,gpio-r8a77965", .data = (ulong)&rcar_gpio_gen2_data },
+ { .compatible = "renesas,gpio-r8a77970", .data = (ulong)&rcar_gpio_gen2_data },
+ { .compatible = "renesas,gpio-r8a77990", .data = (ulong)&rcar_gpio_gen2_data },
+ { .compatible = "renesas,gpio-r8a77995", .data = (ulong)&rcar_gpio_gen2_data },
+ { .compatible = "renesas,gpio-r8a779a0", .data = (ulong)&rcar_gpio_gen3_data },
+ { .compatible = "renesas,rcar-gen2-gpio", .data = (ulong)&rcar_gpio_gen2_data },
+ { .compatible = "renesas,rcar-gen3-gpio", .data = (ulong)&rcar_gpio_gen2_data },
+ { .compatible = "renesas,rcar-gen4-gpio", .data = (ulong)&rcar_gpio_gen3_data },
+ { .compatible = "renesas,rcar-gen5-gpio", .data = (ulong)&rcar_gpio_gen5_data },
{ /* sentinel */ }
};