Re: [PATCH v2] pinctrl: rockchip: add support for the rk3399
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
- Subject: Re: [PATCH v2] pinctrl: rockchip: add support for the rk3399
- From: "David.Wu" <wdc@xxxxxxxxxxxxxx>
- Date: Fri, 29 Jan 2016 19:35:23 +0800
- In-reply-to: <7536813.E6m4KCLL9V@diego>
- User-agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Thunderbird/38.5.0
Hi Heiko,
在 2016/1/29 0:56, Heiko Stübner 写道:
Hi David,
Am Donnerstag, 7. Januar 2016, 15:41:38 schrieb David Wu:
From: David Wu <david.wu@xxxxxxxxxxxxxx>
The pinctrl of rk3399 is much different from other's,
especially the 3bits of drive strength.
Signed-off-by: David Wu <david.wu@xxxxxxxxxxxxxx>
---
change from v1:
- need spin_unlock_irqrestore for set drive default case
.../bindings/pinctrl/rockchip,pinctrl.txt | 1 +
drivers/pinctrl/pinctrl-rockchip.c | 339
++++++++++++++++++++- 2 files changed, 326 insertions(+), 14 deletions(-)
diff --git a/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.txt
b/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.txt index
391ef4b..3bb9456 100644
--- a/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.txt
+++ b/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.txt
@@ -22,6 +22,7 @@ Required properties for iomux controller:
- compatible: one of "rockchip,rk2928-pinctrl",
"rockchip,rk3066a-pinctrl" "rockchip,rk3066b-pinctrl",
"rockchip,rk3188-pinctrl"
"rockchip,rk3288-pinctrl", "rockchip,rk3368-pinctrl"
+ "rockchip,rk3399-pinctrl"
- rockchip,grf: phandle referencing a syscon providing the
"general register files"
diff --git a/drivers/pinctrl/pinctrl-rockchip.c
b/drivers/pinctrl/pinctrl-rockchip.c index a065112..9d61c6e 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
[...]
@@ -685,19 +821,60 @@ static int rockchip_get_drive_perpin(struct
rockchip_pin_bank *bank, struct rockchip_pin_ctrl *ctrl = info->ctrl;
struct regmap *regmap;
int reg, ret;
- u32 data;
+ u32 data, temp, rmask_bits;
u8 bit;
+ int drv_type = bank->drv[pin_num / 8].drv_type;
ctrl->drv_calc_reg(bank, pin_num, ®map, ®, &bit);
+ switch (drv_type) {
+ case DRV_TYPE_IO_1V8_3V0_AUTO:
+ case DRV_TYPE_IO_3V3_ONLY:
+ if (RK3399_DRV_3BITS_PER_PIN + bit >= 16) {
According to the doc excerpts, wouldn't the big special handling only be
necessary for for gpio3b5 alone (+ other banks) ... i.e. the one setting being
split over both registers?
yes, only the pin5 setting of 3bits width bank is split over two registers.
If so I think doing something like the following might be easier to
understand? Same of course for the set-counterpart. [Beware if I missed up the
indices somewhere :-)
yeap.
Seemed it is clearer to view by using following code.
I will have a try, thanks.
rmask_bits = RK3399_DRV_3BITS_PER_PIN;
switch(bit) {
case 0 ... 12:
/* regular case, nothing to do */
break;
case 15:
/* drive-strength offset is special, as it is spread over 2 registers */
ret = regmap_read(regmap, reg, &data);
if (ret)
return ret;
ret = regmap_read(regmap, reg + 0x4, &temp);
if (ret)
return ret;
/*
* the bit data[15] contains bit 0 of the value
* while temp[1:0] containts bits 2 and 1
*/
data >>= 15;
temp &= 0x3;
temp <<= 1;
data |= temp;
return rockchip_perpin_drv_list[drv_type][data];
case 18 ... 21:
/* setting fully enclosed in the second register */
rmask_bits = RK3399_DRV_3BITS_PER_PIN;
reg += 4;
bit -= 18;
}
+ /* need to read regs twice */
+ ret = regmap_read(regmap, reg, &temp);
+ if (ret)
+ return ret;
+
+ temp >>= bit;
+ rmask_bits = 16 - bit;
+ temp &= (1 << rmask_bits) - 1;
+
+ reg = reg + 0x4;
+ ret = regmap_read(regmap, reg, &data);
+ if (ret)
+ return ret;
+
+ rmask_bits = RK3399_DRV_3BITS_PER_PIN
+ + bit - 16;
+ data &= (1 << rmask_bits) - 1;
+ data <<= 16 - bit;
+ data |= temp;
+
+ return rockchip_perpin_drv_list[drv_type][data];
+ }
+
+ rmask_bits = RK3399_DRV_3BITS_PER_PIN;
+ break;
+ case DRV_TYPE_IO_DEFAULT:
+ case DRV_TYPE_IO_1V8_OR_3V0:
+ case DRV_TYPE_IO_1V8_ONLY:
+ rmask_bits = RK3288_DRV_BITS_PER_PIN;
+ break;
+ default:
+ dev_err(info->dev, "unsupported pinctrl drive type: %d\n",
+ drv_type);
+ return -EINVAL;
+ }
+
ret = regmap_read(regmap, reg, &data);
if (ret)
return ret;
data >>= bit;
- data &= (1 << RK3288_DRV_BITS_PER_PIN) - 1;
+ data &= (1 << rmask_bits) - 1;
- return rockchip_perpin_drv_list[data];
+ return rockchip_perpin_drv_list[drv_type][data];
}
static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
[...]
@@ -729,8 +913,45 @@ static int rockchip_set_drive_perpin(struct
rockchip_pin_bank *bank,
spin_lock_irqsave(&bank->slock, flags);
+ switch (drv_type) {
+ case DRV_TYPE_IO_1V8_3V0_AUTO:
+ case DRV_TYPE_IO_3V3_ONLY:
+ if (RK3399_DRV_3BITS_PER_PIN + bit >= 16) {
+ /* need to write regs twice */
+ rmask_bits = 16 - bit;
+ /* enable the write to the equivalent lower bits */
+ data = ((1 << rmask_bits) - 1) << (bit + 16);
+ rmask = data | (data >> 16);
+ ret &= (1 << rmask_bits) - 1;
+ data |= (ret << bit);
+
+ ret = regmap_update_bits(regmap, reg, rmask, data);
+ if (ret)
+ return ret;
+
+ ret = i >> rmask_bits;
+ rmask_bits = RK3399_DRV_3BITS_PER_PIN + bit - 16;
+ reg = reg + 0x4;
+ bit = 0;
Apart from a change similar to the above, should the setting maybe also
directly return and not depend on the final write?
okay, i will do the simialr change to the above.
+ } else {
+ rmask_bits = RK3399_DRV_3BITS_PER_PIN;
+ }
+ break;
+ case DRV_TYPE_IO_DEFAULT:
+ case DRV_TYPE_IO_1V8_OR_3V0:
+ case DRV_TYPE_IO_1V8_ONLY:
+ rmask_bits = RK3288_DRV_BITS_PER_PIN;
+ break;
+ default:
+ spin_unlock_irqrestore(&bank->slock, flags);
+ dev_err(info->dev, "unsupported pinctrl drive type: %d\n",
+ drv_type);
+ return -EINVAL;
+
+ }
+
/* enable the write to the equivalent lower bits */
- data = ((1 << RK3288_DRV_BITS_PER_PIN) - 1) << (bit + 16);
+ data = ((1 << rmask_bits) - 1) << (bit + 16);
rmask = data | (data >> 16);
data |= (ret << bit);
[...]
@@ -2208,6 +2461,62 @@ static struct rockchip_pin_ctrl rk3368_pin_ctrl = {
.drv_calc_reg = rk3368_calc_drv_reg_and_bit,
};
+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,
+ 0,
+ 0,
DRV_TYPE_IO_DEFAULT instead of 0 please.
--
To unsubscribe from this list: send the line "unsubscribe linux-gpio" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
[Index of Archives]
[Linux SPI]
[Linux Kernel]
[Linux ARM (vger)]
[Linux ARM MSM]
[Linux Omap]
[Linux Arm]
[Linux Tegra]
[Fedora ARM]
[Linux for Samsung SOC]
[eCos]
[Linux Fastboot]
[Gcc Help]
[Git]
[DCCP]
[IETF Announce]
[Security]
[Linux MIPS]
[Yosemite Campsites]
|