Merge tag 'u-boot-atmel-fixes-2021.01-b' of https://gitlab.denx.de/u-boot/custodians...
[platform/kernel/u-boot.git] / drivers / pinctrl / renesas / pfc.c
index 6aa2e13..fb811a9 100644 (file)
 #include <common.h>
 #include <dm.h>
 #include <errno.h>
+#include <dm/device_compat.h>
+#include <dm/devres.h>
 #include <dm/pinctrl.h>
+#include <linux/bitops.h>
+#include <linux/bug.h>
 #include <linux/io.h>
 #include <linux/sizes.h>
 
@@ -28,7 +32,12 @@ enum sh_pfc_model {
        SH_PFC_R8A7794,
        SH_PFC_R8A7795,
        SH_PFC_R8A7796,
+       SH_PFC_R8A774A1,
+       SH_PFC_R8A774B1,
+       SH_PFC_R8A774E1,
+       SH_PFC_R8A77965,
        SH_PFC_R8A77970,
+       SH_PFC_R8A77980,
        SH_PFC_R8A77990,
        SH_PFC_R8A77995,
 };
@@ -41,10 +50,6 @@ struct sh_pfc_pinctrl {
        struct sh_pfc *pfc;
 
        struct sh_pfc_pin_config *configs;
-
-       const char *func_prop_name;
-       const char *groups_prop_name;
-       const char *pins_prop_name;
 };
 
 struct sh_pfc_pin_range {
@@ -121,7 +126,7 @@ void sh_pfc_write_raw_reg(void __iomem *mapped_reg, unsigned int reg_width,
 
 u32 sh_pfc_read(struct sh_pfc *pfc, u32 reg)
 {
-       return sh_pfc_read_raw_reg(pfc->regs + reg, 32);
+       return sh_pfc_read_raw_reg((void __iomem *)(uintptr_t)reg, 32);
 }
 
 void sh_pfc_write(struct sh_pfc *pfc, u32 reg, u32 data)
@@ -132,7 +137,7 @@ void sh_pfc_write(struct sh_pfc *pfc, u32 reg, u32 data)
        if (pfc->info->unlock_reg)
                sh_pfc_write_raw_reg(unlock_reg, 32, ~data);
 
-       sh_pfc_write_raw_reg(pfc->regs + reg, 32, data);
+       sh_pfc_write_raw_reg((void __iomem *)(uintptr_t)reg, 32, data);
 }
 
 static void sh_pfc_config_reg_helper(struct sh_pfc *pfc,
@@ -458,16 +463,17 @@ static const char *sh_pfc_pinctrl_get_function_name(struct udevice *dev,
        return priv->pfc.info->functions[selector].name;
 }
 
-int sh_pfc_config_mux_for_gpio(struct udevice *dev, unsigned pin_selector)
+static int sh_pfc_gpio_request_enable(struct udevice *dev,
+                                     unsigned pin_selector)
 {
        struct sh_pfc_pinctrl_priv *priv = dev_get_priv(dev);
        struct sh_pfc_pinctrl *pmx = &priv->pmx;
        struct sh_pfc *pfc = &priv->pfc;
        struct sh_pfc_pin_config *cfg;
        const struct sh_pfc_pin *pin = NULL;
-       int i, idx;
+       int i, ret, idx;
 
-       for (i = 1; i < pfc->info->nr_pins; i++) {
+       for (i = 0; i < pfc->info->nr_pins; i++) {
                if (priv->pfc.info->pins[i].pin != pin_selector)
                        continue;
 
@@ -484,7 +490,42 @@ int sh_pfc_config_mux_for_gpio(struct udevice *dev, unsigned pin_selector)
        if (cfg->type != PINMUX_TYPE_NONE)
                return -EBUSY;
 
-       return sh_pfc_config_mux(pfc, pin->enum_id, PINMUX_TYPE_GPIO);
+       ret = sh_pfc_config_mux(pfc, pin->enum_id, PINMUX_TYPE_GPIO);
+       if (ret)
+               return ret;
+
+       cfg->type = PINMUX_TYPE_GPIO;
+
+       return 0;
+}
+
+static int sh_pfc_gpio_disable_free(struct udevice *dev,
+                                   unsigned pin_selector)
+{
+       struct sh_pfc_pinctrl_priv *priv = dev_get_priv(dev);
+       struct sh_pfc_pinctrl *pmx = &priv->pmx;
+       struct sh_pfc *pfc = &priv->pfc;
+       struct sh_pfc_pin_config *cfg;
+       const struct sh_pfc_pin *pin = NULL;
+       int i, idx;
+
+       for (i = 0; i < pfc->info->nr_pins; i++) {
+               if (priv->pfc.info->pins[i].pin != pin_selector)
+                       continue;
+
+               pin = &priv->pfc.info->pins[i];
+               break;
+       }
+
+       if (!pin)
+               return -EINVAL;
+
+       idx = sh_pfc_get_pin_index(pfc, pin->pin);
+       cfg = &pmx->configs[idx];
+
+       cfg->type = PINMUX_TYPE_NONE;
+
+       return 0;
 }
 
 static int sh_pfc_pinctrl_pin_set(struct udevice *dev, unsigned pin_selector,
@@ -591,7 +632,7 @@ static int sh_pfc_pinconf_set_drive_strength(struct sh_pfc *pfc,
        strength = strength / step - 1;
 
        val = sh_pfc_read_raw_reg(reg, 32);
-       val &= ~GENMASK(offset + size - 1, offset);
+       val &= ~GENMASK(offset + 4 - 1, offset);
        val |= strength << offset;
 
        if (unlock_reg)
@@ -745,6 +786,9 @@ static struct pinctrl_ops sh_pfc_pinctrl_ops = {
        .pinmux_set             = sh_pfc_pinctrl_pin_set,
        .pinmux_group_set       = sh_pfc_pinctrl_group_set,
        .set_state              = pinctrl_generic_set_state,
+
+       .gpio_request_enable    = sh_pfc_gpio_request_enable,
+       .gpio_disable_free      = sh_pfc_gpio_disable_free,
 };
 
 static int sh_pfc_map_pins(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx)
@@ -772,7 +816,7 @@ static int sh_pfc_pinctrl_probe(struct udevice *dev)
        enum sh_pfc_model model = dev_get_driver_data(dev);
        fdt_addr_t base;
 
-       base = devfdt_get_addr(dev);
+       base = dev_read_addr(dev);
        if (base == FDT_ADDR_T_NONE)
                return -EINVAL;
 
@@ -808,10 +852,30 @@ static int sh_pfc_pinctrl_probe(struct udevice *dev)
        if (model == SH_PFC_R8A7796)
                priv->pfc.info = &r8a7796_pinmux_info;
 #endif
+#ifdef CONFIG_PINCTRL_PFC_R8A774A1
+       if (model == SH_PFC_R8A774A1)
+               priv->pfc.info = &r8a774a1_pinmux_info;
+#endif
+#ifdef CONFIG_PINCTRL_PFC_R8A774B1
+       if (model == SH_PFC_R8A774B1)
+               priv->pfc.info = &r8a774b1_pinmux_info;
+#endif
+#ifdef CONFIG_PINCTRL_PFC_R8A774E1
+       if (model == SH_PFC_R8A774E1)
+               priv->pfc.info = &r8a774e1_pinmux_info;
+#endif
+#ifdef CONFIG_PINCTRL_PFC_R8A77965
+       if (model == SH_PFC_R8A77965)
+               priv->pfc.info = &r8a77965_pinmux_info;
+#endif
 #ifdef CONFIG_PINCTRL_PFC_R8A77970
        if (model == SH_PFC_R8A77970)
                priv->pfc.info = &r8a77970_pinmux_info;
 #endif
+#ifdef CONFIG_PINCTRL_PFC_R8A77980
+       if (model == SH_PFC_R8A77980)
+               priv->pfc.info = &r8a77980_pinmux_info;
+#endif
 #ifdef CONFIG_PINCTRL_PFC_R8A77990
        if (model == SH_PFC_R8A77990)
                priv->pfc.info = &r8a77990_pinmux_info;
@@ -869,9 +933,30 @@ static const struct udevice_id sh_pfc_pinctrl_ids[] = {
        {
                .compatible = "renesas,pfc-r8a7796",
                .data = SH_PFC_R8A7796,
-       }, {
+       },
+#endif
+#ifdef CONFIG_PINCTRL_PFC_R8A774A1
+       {
+               .compatible = "renesas,pfc-r8a774a1",
+               .data = SH_PFC_R8A774A1,
+       },
+#endif
+#ifdef CONFIG_PINCTRL_PFC_R8A774B1
+       {
+               .compatible = "renesas,pfc-r8a774b1",
+               .data = SH_PFC_R8A774B1,
+       },
+#endif
+#ifdef CONFIG_PINCTRL_PFC_R8A774E1
+       {
+               .compatible = "renesas,pfc-r8a774e1",
+               .data = SH_PFC_R8A774E1,
+       },
+#endif
+#ifdef CONFIG_PINCTRL_PFC_R8A77965
+       {
                .compatible = "renesas,pfc-r8a77965",
-               .data = SH_PFC_R8A7796,
+               .data = SH_PFC_R8A77965,
        },
 #endif
 #ifdef CONFIG_PINCTRL_PFC_R8A77970
@@ -880,6 +965,12 @@ static const struct udevice_id sh_pfc_pinctrl_ids[] = {
                .data = SH_PFC_R8A77970,
        },
 #endif
+#ifdef CONFIG_PINCTRL_PFC_R8A77980
+       {
+               .compatible = "renesas,pfc-r8a77980",
+               .data = SH_PFC_R8A77980,
+       },
+#endif
 #ifdef CONFIG_PINCTRL_PFC_R8A77990
        {
                .compatible = "renesas,pfc-r8a77990",