pinctrl: rockchip: separate different sub-types more
authorHeiko Stübner <heiko@sntech.de>
Tue, 15 Oct 2013 23:07:20 +0000 (01:07 +0200)
committerLinus Walleij <linus.walleij@linaro.org>
Wed, 16 Oct 2013 13:33:52 +0000 (15:33 +0200)
Further investigation of the different Rockchip SoCs showed that
the differences especially in the pull settings are quite deep.
As further patches will show, the register layout for the pulls of
the rk3188 is quite strange. Also it is to assume, that later
Rockchip SoCs may introduce even more quirks in this regard, making
it hard to support all of those using the current generic pull_*
variables.

Therefore move the driver to hold the type of controller in an enum
and do the handling according to it in the necessary places. Also
instead of calculating the register in the get and set pull functions
move it to a type-specific callback.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
drivers/pinctrl/pinctrl-rockchip.c

index e0718b7c4abc347ff359bfa526060e663a6a811b..df155f9b24322236690e11e14fc5cf350d93d363 100644 (file)
 #define GPIO_EXT_PORT          0x50
 #define GPIO_LS_SYNC           0x60
 
+enum rockchip_pinctrl_type {
+       RK2928,
+       RK3066B,
+       RK3188,
+};
+
 /**
  * @reg_base: register base of the gpio bank
  * @clk: clock of the gpio bank
@@ -98,18 +104,16 @@ struct rockchip_pin_bank {
        }
 
 /**
- * @pull_auto: some SoCs don't allow pulls to be specified as up or down, but
- *            instead decide this automatically based on the pad-type.
  */
 struct rockchip_pin_ctrl {
        struct rockchip_pin_bank        *pin_banks;
        u32                             nr_banks;
        u32                             nr_pins;
        char                            *label;
+       enum rockchip_pinctrl_type      type;
        int                             mux_offset;
-       int                             pull_offset;
-       bool                            pull_auto;
-       int                             pull_bank_stride;
+       void    (*pull_calc_reg)(struct rockchip_pin_bank *bank, int pin_num,
+                                void __iomem **reg, u8 *bit);
 };
 
 struct rockchip_pin_config {
@@ -354,6 +358,22 @@ static void rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
        spin_unlock_irqrestore(&bank->slock, flags);
 }
 
+#define RK2928_PULL_OFFSET             0x118
+#define RK2928_PULL_PINS_PER_REG       16
+#define RK2928_PULL_BANK_STRIDE                8
+
+static void rk2928_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
+                                   int pin_num, void __iomem **reg, u8 *bit)
+{
+       struct rockchip_pinctrl *info = bank->drvdata;
+
+       *reg = info->reg_base + RK2928_PULL_OFFSET;
+       *reg += bank->bank_num * RK2928_PULL_BANK_STRIDE;
+       *reg += (pin_num / RK2928_PULL_PINS_PER_REG) * 4;
+
+       *bit = pin_num % RK2928_PULL_PINS_PER_REG;
+};
+
 static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num)
 {
        struct rockchip_pinctrl *info = bank->drvdata;
@@ -362,23 +382,22 @@ static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num)
        u8 bit;
 
        /* rk3066b does support any pulls */
-       if (!ctrl->pull_offset)
+       if (ctrl->type == RK3066B)
                return PIN_CONFIG_BIAS_DISABLE;
 
-       reg = info->reg_base + ctrl->pull_offset;
-
-       if (ctrl->pull_auto) {
-               reg += bank->bank_num * ctrl->pull_bank_stride;
-               reg += (pin_num / 16) * 4;
-               bit = pin_num % 16;
-
+       switch (ctrl->type) {
+       case RK2928:
+               ctrl->pull_calc_reg(bank, pin_num, &reg, &bit);
                return !(readl_relaxed(reg) & BIT(bit))
                                ? PIN_CONFIG_BIAS_PULL_PIN_DEFAULT
                                : PIN_CONFIG_BIAS_DISABLE;
-       } else {
+       case RK3188:
                dev_err(info->dev, "pull support for rk31xx not implemented\n");
                return -EIO;
-       }
+       default:
+               dev_err(info->dev, "unsupported pinctrl type\n");
+               return -EINVAL;
+       };
 }
 
 static int rockchip_set_pull(struct rockchip_pin_bank *bank,
@@ -395,21 +414,18 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank,
                 bank->bank_num, pin_num, pull);
 
        /* rk3066b does support any pulls */
-       if (!ctrl->pull_offset)
+       if (ctrl->type == RK3066B)
                return pull ? -EINVAL : 0;
 
-       reg = info->reg_base + ctrl->pull_offset;
-
-       if (ctrl->pull_auto) {
+       switch (ctrl->type) {
+       case RK2928:
                if (pull != PIN_CONFIG_BIAS_PULL_PIN_DEFAULT &&
                                        pull != PIN_CONFIG_BIAS_DISABLE) {
                        dev_err(info->dev, "only PIN_DEFAULT and DISABLE allowed\n");
                        return -EINVAL;
                }
 
-               reg += bank->bank_num * ctrl->pull_bank_stride;
-               reg += (pin_num / 16) * 4;
-               bit = pin_num % 16;
+               ctrl->pull_calc_reg(bank, pin_num, &reg, &bit);
 
                spin_lock_irqsave(&bank->slock, flags);
 
@@ -419,14 +435,13 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank,
                writel(data, reg);
 
                spin_unlock_irqrestore(&bank->slock, flags);
-       } else {
-               if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT) {
-                       dev_err(info->dev, "pull direction (up/down) needs to be specified\n");
-                       return -EINVAL;
-               }
-
+               break;
+       case RK3188:
                dev_err(info->dev, "pull support for rk31xx not implemented\n");
                return -EIO;
+       default:
+               dev_err(info->dev, "unsupported pinctrl type\n");
+               return -EINVAL;
        }
 
        return 0;
@@ -556,20 +571,17 @@ static const struct pinmux_ops rockchip_pmx_ops = {
 static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl,
                                        enum pin_config_param pull)
 {
-       /* rk3066b does support any pulls */
-       if (!ctrl->pull_offset)
+       switch (ctrl->type) {
+       case RK2928:
+               return (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT ||
+                                       pull == PIN_CONFIG_BIAS_DISABLE);
+       case RK3066B:
                return pull ? false : true;
-
-       if (ctrl->pull_auto) {
-               if (pull != PIN_CONFIG_BIAS_PULL_PIN_DEFAULT &&
-                                       pull != PIN_CONFIG_BIAS_DISABLE)
-                       return false;
-       } else {
-               if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT)
-                       return false;
+       case RK3188:
+               return (pull != PIN_CONFIG_BIAS_PULL_PIN_DEFAULT);
        }
 
-       return true;
+       return false;
 }
 
 /* set the pin config settings for a specified pin */
@@ -1315,10 +1327,9 @@ static struct rockchip_pin_ctrl rk2928_pin_ctrl = {
                .pin_banks              = rk2928_pin_banks,
                .nr_banks               = ARRAY_SIZE(rk2928_pin_banks),
                .label                  = "RK2928-GPIO",
+               .type                   = RK2928,
                .mux_offset             = 0xa8,
-               .pull_offset            = 0x118,
-               .pull_auto              = 1,
-               .pull_bank_stride       = 8,
+               .pull_calc_reg          = rk2928_calc_pull_reg_and_bit,
 };
 
 static struct rockchip_pin_bank rk3066a_pin_banks[] = {
@@ -1334,10 +1345,9 @@ static struct rockchip_pin_ctrl rk3066a_pin_ctrl = {
                .pin_banks              = rk3066a_pin_banks,
                .nr_banks               = ARRAY_SIZE(rk3066a_pin_banks),
                .label                  = "RK3066a-GPIO",
+               .type                   = RK2928,
                .mux_offset             = 0xa8,
-               .pull_offset            = 0x118,
-               .pull_auto              = 1,
-               .pull_bank_stride       = 8,
+               .pull_calc_reg          = rk2928_calc_pull_reg_and_bit,
 };
 
 static struct rockchip_pin_bank rk3066b_pin_banks[] = {
@@ -1351,8 +1361,8 @@ static struct rockchip_pin_ctrl rk3066b_pin_ctrl = {
                .pin_banks      = rk3066b_pin_banks,
                .nr_banks       = ARRAY_SIZE(rk3066b_pin_banks),
                .label          = "RK3066b-GPIO",
+               .type           = RK3066B,
                .mux_offset     = 0x60,
-               .pull_offset    = -EINVAL,
 };
 
 static struct rockchip_pin_bank rk3188_pin_banks[] = {
@@ -1366,9 +1376,8 @@ static struct rockchip_pin_ctrl rk3188_pin_ctrl = {
                .pin_banks              = rk3188_pin_banks,
                .nr_banks               = ARRAY_SIZE(rk3188_pin_banks),
                .label                  = "RK3188-GPIO",
+               .type                   = RK3188,
                .mux_offset             = 0x68,
-               .pull_offset            = 0x164,
-               .pull_bank_stride       = 16,
 };
 
 static const struct of_device_id rockchip_pinctrl_dt_match[] = {