pinctrl: rockchip: fix pull setting error for rk3399

Change-Id: Ie52226e751510373abc75754ab756a36ae4f3aaa
Signed-off-by: David Wu <david.wu@rock-chips.com>
This commit is contained in:
David Wu 2016-03-26 22:26:16 +08:00
parent bddaa3fd0f
commit eb4089b259

View File

@ -101,6 +101,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
};
/**
* enum type of pin extra drive alignment.
*/
@ -135,6 +144,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
@ -155,6 +165,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;
@ -210,6 +221,30 @@ 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(id, pins, label, iom0, iom1, iom2, \
iom3, drv0, drv1, drv2, drv3) \
{ \
@ -274,6 +309,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 {
@ -1354,12 +1417,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;
@ -1383,22 +1461,11 @@ static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num)
case RK3366:
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;
@ -1411,7 +1478,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;
@ -1441,30 +1508,27 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank,
case RK3366:
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, "unknown 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);
@ -2941,19 +3005,23 @@ static struct rockchip_pin_ctrl rk3368_pin_ctrl = {
};
static struct rockchip_pin_bank rk3399_pin_banks[] = {
PIN_BANK_IOMUX_FLAGS_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_FLAGS_DRV_FLAGS_OFFSET(1, 32, "gpio1", IOMUX_SOURCE_PMU,
IOMUX_SOURCE_PMU,
IOMUX_SOURCE_PMU,
@ -2967,11 +3035,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,