|
@@ -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);
|
|
|
|
|
@@ -2552,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,
|
|
@@ -2578,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,
|