diff options
Diffstat (limited to 'drivers/gpio/gpio-rcar.c')
| -rw-r--r-- | drivers/gpio/gpio-rcar.c | 84 |
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 */ } }; |
