pinctrl: rockchip: Add 32bit writing function for rk3288 gpio0 pinctrl
authorDavid Wu <david.wu@rock-chips.com>
Tue, 12 Feb 2019 11:51:51 +0000 (19:51 +0800)
committerPhilipp Tomsich <philipp.tomsich@theobroma-systems.com>
Fri, 29 Mar 2019 08:24:44 +0000 (09:24 +0100)
There are no higher 16 writing corresponding bits for pmu_gpio0's
iomux/drive/pull at rk3288, need to read the value from register
firstly. Add the flag to distinguish it from normal registers.

Signed-off-by: David Wu <david.wu@rock-chips.com>
drivers/pinctrl/rockchip/pinctrl-rk3288.c
drivers/pinctrl/rockchip/pinctrl-rockchip-core.c
drivers/pinctrl/rockchip/pinctrl-rockchip.h

index 60585f3208590903a05c05f85ce1ace63455fe5e..8b6ce11a63b5b5df293bc38b961b98e18ac99559 100644 (file)
@@ -92,10 +92,19 @@ static void rk3288_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
 }
 
 static struct rockchip_pin_bank rk3288_pin_banks[] = {
-       PIN_BANK_IOMUX_FLAGS(0, 24, "gpio0", IOMUX_SOURCE_PMU,
-                                            IOMUX_SOURCE_PMU,
-                                            IOMUX_SOURCE_PMU,
-                                            IOMUX_UNROUTED
+       PIN_BANK_IOMUX_DRV_PULL_FLAGS(0, 24, "gpio0",
+                                     IOMUX_SOURCE_PMU | IOMUX_WRITABLE_32BIT,
+                                     IOMUX_SOURCE_PMU | IOMUX_WRITABLE_32BIT,
+                                     IOMUX_SOURCE_PMU | IOMUX_WRITABLE_32BIT,
+                                     IOMUX_UNROUTED,
+                                     DRV_TYPE_WRITABLE_32BIT,
+                                     DRV_TYPE_WRITABLE_32BIT,
+                                     DRV_TYPE_WRITABLE_32BIT,
+                                     0,
+                                     PULL_TYPE_WRITABLE_32BIT,
+                                     PULL_TYPE_WRITABLE_32BIT,
+                                     PULL_TYPE_WRITABLE_32BIT,
+                                     0
                            ),
        PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_UNROUTED,
                                             IOMUX_UNROUTED,
index b84b0790641b346ca269de04782712fe6d9c84db..ce935656f064ce8c6001d04b454effaaccd13b52 100644 (file)
@@ -228,7 +228,13 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
                }
        }
 
-       data = (mask << (bit + 16));
+       if (mux_type & IOMUX_WRITABLE_32BIT) {
+               regmap_read(regmap, reg, &data);
+               data &= ~(mask << bit);
+       } else {
+               data = (mask << (bit + 16));
+       }
+
        data |= (mux & mask) << bit;
        ret = regmap_write(regmap, reg, data);
 
@@ -252,7 +258,8 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
        int reg, ret, i;
        u32 data, rmask_bits, temp;
        u8 bit;
-       int drv_type = bank->drv[pin_num / 8].drv_type;
+       /* Where need to clean the special mask for rockchip_perpin_drv_list */
+       int drv_type = bank->drv[pin_num / 8].drv_type & (~DRV_TYPE_IO_MASK);
 
        debug("setting drive of GPIO%d-%d to %d\n", bank->bank_num,
              pin_num, strength);
@@ -324,10 +331,15 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
                return -EINVAL;
        }
 
-       /* enable the write to the equivalent lower bits */
-       data = ((1 << rmask_bits) - 1) << (bit + 16);
-       data |= (ret << bit);
+       if (bank->drv[pin_num / 8].drv_type & DRV_TYPE_WRITABLE_32BIT) {
+               regmap_read(regmap, reg, &data);
+               data &= ~(((1 << rmask_bits) - 1) << bit);
+       } else {
+               /* enable the write to the equivalent lower bits */
+               data = ((1 << rmask_bits) - 1) << (bit + 16);
+       }
 
+       data |= (ret << bit);
        ret = regmap_write(regmap, reg, data);
        return ret;
 }
@@ -375,7 +387,11 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank,
        case RK3288:
        case RK3368:
        case RK3399:
-               pull_type = bank->pull_type[pin_num / 8];
+               /*
+                * Where need to clean the special mask for
+                * rockchip_pull_list.
+                */
+               pull_type = bank->pull_type[pin_num / 8] & (~PULL_TYPE_IO_MASK);
                ret = -EINVAL;
                for (i = 0; i < ARRAY_SIZE(rockchip_pull_list[pull_type]);
                        i++) {
@@ -390,10 +406,15 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank,
                        return ret;
                }
 
-               /* enable the write to the equivalent lower bits */
-               data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16);
-               data |= (ret << bit);
+               if (bank->pull_type[pin_num / 8] & PULL_TYPE_WRITABLE_32BIT) {
+                       regmap_read(regmap, reg, &data);
+                       data &= ~(((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << bit);
+               } else {
+                       /* enable the write to the equivalent lower bits */
+                       data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16);
+               }
 
+               data |= (ret << bit);
                ret = regmap_write(regmap, reg, data);
                break;
        default:
index bc809630c1919abd7b63c90fe2db2440fa27bcb8..5a6849c9964506daae529e4eabf5cc4656f15abd 100644 (file)
@@ -26,6 +26,7 @@ enum rockchip_pinctrl_type {
 #define IOMUX_SOURCE_PMU       BIT(2)
 #define IOMUX_UNROUTED         BIT(3)
 #define IOMUX_WIDTH_3BIT       BIT(4)
+#define IOMUX_WRITABLE_32BIT   BIT(5)
 
 /**
  * Defined some common pins constants
@@ -49,6 +50,9 @@ struct rockchip_iomux {
        int                             offset;
 };
 
+#define DRV_TYPE_IO_MASK               GENMASK(31, 16)
+#define DRV_TYPE_WRITABLE_32BIT                BIT(31)
+
 /**
  * enum type index corresponding to rockchip_perpin_drv_list arrays index.
  */
@@ -61,6 +65,9 @@ enum rockchip_pin_drv_type {
        DRV_TYPE_MAX
 };
 
+#define PULL_TYPE_IO_MASK              GENMASK(31, 16)
+#define PULL_TYPE_WRITABLE_32BIT       BIT(31)
+
 /**
  * enum type index corresponding to rockchip_pull_list arrays index.
  */
@@ -200,6 +207,32 @@ struct rockchip_pin_bank {
                },                                                      \
        }
 
+#define PIN_BANK_IOMUX_DRV_PULL_FLAGS(id, pins, label, iom0, iom1,     \
+                                     iom2, iom3, drv0, drv1, drv2,     \
+                                     drv3, pull0, pull1, pull2,        \
+                                     pull3)                            \
+       {                                                               \
+               .bank_num       = id,                                   \
+               .nr_pins        = pins,                                 \
+               .name           = label,                                \
+               .iomux          = {                                     \
+                       { .type = iom0, .offset = -1 },                 \
+                       { .type = iom1, .offset = -1 },                 \
+                       { .type = iom2, .offset = -1 },                 \
+                       { .type = iom3, .offset = -1 },                 \
+               },                                                      \
+               .drv            = {                                     \
+                       { .drv_type = drv0, .offset = -1 },             \
+                       { .drv_type = drv1, .offset = -1 },             \
+                       { .drv_type = drv2, .offset = -1 },             \
+                       { .drv_type = drv3, .offset = -1 },             \
+               },                                                      \
+               .pull_type[0] = pull0,                                  \
+               .pull_type[1] = pull1,                                  \
+               .pull_type[2] = pull2,                                  \
+               .pull_type[3] = pull3,                                  \
+       }
+
 #define PIN_BANK_IOMUX_FLAGS_DRV_FLAGS_OFFSET_PULL_FLAGS(id, pins,     \
                                              label, iom0, iom1, iom2,  \
                                              iom3, drv0, drv1, drv2,   \