Merge branch 'hwmon-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jdelv...
[deliverable/linux.git] / drivers / pinctrl / pinctrl-rockchip.c
index bf032b9b4c57e06df4b43c794f484fc539b56e3d..a91026e8cd7c1ab09f6328841f2b6499362d4141 100644 (file)
@@ -98,6 +98,15 @@ enum rockchip_pin_drv_type {
        DRV_TYPE_MAX
 };
 
+/**
+ * enum type index corresponding to rockchip_pull_list arrays index.
+ */
+enum rockchip_pin_pull_type {
+       PULL_TYPE_IO_DEFAULT = 0,
+       PULL_TYPE_IO_1V8_ONLY,
+       PULL_TYPE_MAX
+};
+
 /**
  * @drv_type: drive strength variant using rockchip_perpin_drv_type
  * @offset: if initialized to -1 it will be autocalculated, by specifying
@@ -123,6 +132,7 @@ struct rockchip_drv {
  * @bank_num: number of the bank, to account for holes
  * @iomux: array describing the 4 iomux sources of the bank
  * @drv: array describing the 4 drive strength sources of the bank
+ * @pull_type: array describing the 4 pull type sources of the bank
  * @valid: are all necessary informations present
  * @of_node: dt node of this bank
  * @drvdata: common pinctrl basedata
@@ -143,6 +153,7 @@ struct rockchip_pin_bank {
        u8                              bank_num;
        struct rockchip_iomux           iomux[4];
        struct rockchip_drv             drv[4];
+       enum rockchip_pin_pull_type     pull_type[4];
        bool                            valid;
        struct device_node              *of_node;
        struct rockchip_pinctrl         *drvdata;
@@ -198,6 +209,31 @@ struct rockchip_pin_bank {
                },                                                      \
        }
 
+#define PIN_BANK_DRV_FLAGS_PULL_FLAGS(id, pins, label, drv0, drv1,     \
+                                     drv2, drv3, pull0, pull1,         \
+                                     pull2, pull3)                     \
+       {                                                               \
+               .bank_num       = id,                                   \
+               .nr_pins        = pins,                                 \
+               .name           = label,                                \
+               .iomux          = {                                     \
+                       { .offset = -1 },                               \
+                       { .offset = -1 },                               \
+                       { .offset = -1 },                               \
+                       { .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_DRV_FLAGS_OFFSET(id, pins, label, iom0, iom1,   \
                                        iom2, iom3, drv0, drv1, drv2,   \
                                        drv3, offset0, offset1,         \
@@ -220,6 +256,34 @@ struct rockchip_pin_bank {
                },                                                      \
        }
 
+#define PIN_BANK_IOMUX_FLAGS_DRV_FLAGS_OFFSET_PULL_FLAGS(id, pins,     \
+                                             label, iom0, iom1, iom2,  \
+                                             iom3, drv0, drv1, drv2,   \
+                                             drv3, offset0, offset1,   \
+                                             offset2, offset3, 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 = offset0 },        \
+                       { .drv_type = drv1, .offset = offset1 },        \
+                       { .drv_type = drv2, .offset = offset2 },        \
+                       { .drv_type = drv3, .offset = offset3 },        \
+               },                                                      \
+               .pull_type[0] = pull0,                                  \
+               .pull_type[1] = pull1,                                  \
+               .pull_type[2] = pull2,                                  \
+               .pull_type[3] = pull3,                                  \
+       }
+
 /**
  */
 struct rockchip_pin_ctrl {
@@ -1020,12 +1084,27 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
        return ret;
 }
 
+static int rockchip_pull_list[PULL_TYPE_MAX][4] = {
+       {
+               PIN_CONFIG_BIAS_DISABLE,
+               PIN_CONFIG_BIAS_PULL_UP,
+               PIN_CONFIG_BIAS_PULL_DOWN,
+               PIN_CONFIG_BIAS_BUS_HOLD
+       },
+       {
+               PIN_CONFIG_BIAS_DISABLE,
+               PIN_CONFIG_BIAS_PULL_DOWN,
+               PIN_CONFIG_BIAS_DISABLE,
+               PIN_CONFIG_BIAS_PULL_UP
+       },
+};
+
 static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num)
 {
        struct rockchip_pinctrl *info = bank->drvdata;
        struct rockchip_pin_ctrl *ctrl = info->ctrl;
        struct regmap *regmap;
-       int reg, ret;
+       int reg, ret, pull_type;
        u8 bit;
        u32 data;
 
@@ -1048,22 +1127,11 @@ static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num)
        case RK3288:
        case RK3368:
        case RK3399:
+               pull_type = bank->pull_type[pin_num / 8];
                data >>= bit;
                data &= (1 << RK3188_PULL_BITS_PER_PIN) - 1;
 
-               switch (data) {
-               case 0:
-                       return PIN_CONFIG_BIAS_DISABLE;
-               case 1:
-                       return PIN_CONFIG_BIAS_PULL_UP;
-               case 2:
-                       return PIN_CONFIG_BIAS_PULL_DOWN;
-               case 3:
-                       return PIN_CONFIG_BIAS_BUS_HOLD;
-               }
-
-               dev_err(info->dev, "unknown pull setting\n");
-               return -EIO;
+               return rockchip_pull_list[pull_type][data];
        default:
                dev_err(info->dev, "unsupported pinctrl type\n");
                return -EINVAL;
@@ -1076,7 +1144,7 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank,
        struct rockchip_pinctrl *info = bank->drvdata;
        struct rockchip_pin_ctrl *ctrl = info->ctrl;
        struct regmap *regmap;
-       int reg, ret;
+       int reg, ret, i, pull_type;
        unsigned long flags;
        u8 bit;
        u32 data, rmask;
@@ -1105,30 +1173,28 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank,
        case RK3288:
        case RK3368:
        case RK3399:
+               pull_type = bank->pull_type[pin_num / 8];
+               ret = -EINVAL;
+               for (i = 0; i < ARRAY_SIZE(rockchip_pull_list[pull_type]);
+                       i++) {
+                       if (rockchip_pull_list[pull_type][i] == pull) {
+                               ret = i;
+                               break;
+                       }
+               }
+
+               if (ret < 0) {
+                       dev_err(info->dev, "unsupported pull setting %d\n",
+                               pull);
+                       return ret;
+               }
+
                spin_lock_irqsave(&bank->slock, flags);
 
                /* enable the write to the equivalent lower bits */
                data = ((1 << RK3188_PULL_BITS_PER_PIN) - 1) << (bit + 16);
                rmask = data | (data >> 16);
-
-               switch (pull) {
-               case PIN_CONFIG_BIAS_DISABLE:
-                       break;
-               case PIN_CONFIG_BIAS_PULL_UP:
-                       data |= (1 << bit);
-                       break;
-               case PIN_CONFIG_BIAS_PULL_DOWN:
-                       data |= (2 << bit);
-                       break;
-               case PIN_CONFIG_BIAS_BUS_HOLD:
-                       data |= (3 << bit);
-                       break;
-               default:
-                       spin_unlock_irqrestore(&bank->slock, flags);
-                       dev_err(info->dev, "unsupported pull setting %d\n",
-                               pull);
-                       return -EINVAL;
-               }
+               data |= (ret << bit);
 
                ret = regmap_update_bits(regmap, reg, rmask, data);
 
@@ -1208,6 +1274,16 @@ static int rockchip_pmx_set(struct pinctrl_dev *pctldev, unsigned selector,
        return 0;
 }
 
+static int rockchip_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
+{
+       struct rockchip_pin_bank *bank = gpiochip_get_data(chip);
+       u32 data;
+
+       data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR);
+
+       return !(data & BIT(offset));
+}
+
 /*
  * The calls to gpio_direction_output() and gpio_direction_input()
  * leads to this function call (via the pinctrl_gpio_direction_{input|output}()
@@ -1636,7 +1712,7 @@ static int rockchip_pinctrl_register(struct platform_device *pdev,
        if (ret)
                return ret;
 
-       info->pctl_dev = pinctrl_register(ctrldesc, &pdev->dev, info);
+       info->pctl_dev = devm_pinctrl_register(&pdev->dev, ctrldesc, info);
        if (IS_ERR(info->pctl_dev)) {
                dev_err(&pdev->dev, "could not register pinctrl driver\n");
                return PTR_ERR(info->pctl_dev);
@@ -1741,6 +1817,7 @@ static const struct gpio_chip rockchip_gpiolib_chip = {
        .free = gpiochip_generic_free,
        .set = rockchip_gpio_set,
        .get = rockchip_gpio_get,
+       .get_direction  = rockchip_gpio_get_direction,
        .direction_input = rockchip_gpio_direction_input,
        .direction_output = rockchip_gpio_direction_output,
        .to_irq = rockchip_gpio_to_irq,
@@ -2541,19 +2618,24 @@ static struct rockchip_pin_ctrl rk3368_pin_ctrl = {
 };
 
 static struct rockchip_pin_bank rk3399_pin_banks[] = {
-       PIN_BANK_IOMUX_DRV_FLAGS_OFFSET(0, 32, "gpio0", IOMUX_SOURCE_PMU,
-                                       IOMUX_SOURCE_PMU,
-                                       IOMUX_SOURCE_PMU,
-                                       IOMUX_SOURCE_PMU,
-                                       DRV_TYPE_IO_1V8_ONLY,
-                                       DRV_TYPE_IO_1V8_ONLY,
-                                       DRV_TYPE_IO_DEFAULT,
-                                       DRV_TYPE_IO_DEFAULT,
-                                       0x0,
-                                       0x8,
-                                       -1,
-                                       -1
-                                       ),
+       PIN_BANK_IOMUX_FLAGS_DRV_FLAGS_OFFSET_PULL_FLAGS(0, 32, "gpio0",
+                                                        IOMUX_SOURCE_PMU,
+                                                        IOMUX_SOURCE_PMU,
+                                                        IOMUX_SOURCE_PMU,
+                                                        IOMUX_SOURCE_PMU,
+                                                        DRV_TYPE_IO_1V8_ONLY,
+                                                        DRV_TYPE_IO_1V8_ONLY,
+                                                        DRV_TYPE_IO_DEFAULT,
+                                                        DRV_TYPE_IO_DEFAULT,
+                                                        0x0,
+                                                        0x8,
+                                                        -1,
+                                                        -1,
+                                                        PULL_TYPE_IO_1V8_ONLY,
+                                                        PULL_TYPE_IO_1V8_ONLY,
+                                                        PULL_TYPE_IO_DEFAULT,
+                                                        PULL_TYPE_IO_DEFAULT
+                                                       ),
        PIN_BANK_IOMUX_DRV_FLAGS_OFFSET(1, 32, "gpio1", IOMUX_SOURCE_PMU,
                                        IOMUX_SOURCE_PMU,
                                        IOMUX_SOURCE_PMU,
@@ -2567,11 +2649,15 @@ static struct rockchip_pin_bank rk3399_pin_banks[] = {
                                        0x30,
                                        0x38
                                        ),
-       PIN_BANK_DRV_FLAGS(2, 32, "gpio2", DRV_TYPE_IO_1V8_OR_3V0,
-                          DRV_TYPE_IO_1V8_OR_3V0,
-                          DRV_TYPE_IO_1V8_ONLY,
-                          DRV_TYPE_IO_1V8_ONLY
-                          ),
+       PIN_BANK_DRV_FLAGS_PULL_FLAGS(2, 32, "gpio2", DRV_TYPE_IO_1V8_OR_3V0,
+                                     DRV_TYPE_IO_1V8_OR_3V0,
+                                     DRV_TYPE_IO_1V8_ONLY,
+                                     DRV_TYPE_IO_1V8_ONLY,
+                                     PULL_TYPE_IO_DEFAULT,
+                                     PULL_TYPE_IO_DEFAULT,
+                                     PULL_TYPE_IO_1V8_ONLY,
+                                     PULL_TYPE_IO_1V8_ONLY
+                                     ),
        PIN_BANK_DRV_FLAGS(3, 32, "gpio3", DRV_TYPE_IO_3V3_ONLY,
                           DRV_TYPE_IO_3V3_ONLY,
                           DRV_TYPE_IO_3V3_ONLY,
This page took 0.052209 seconds and 5 git commands to generate.