diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-06-25 04:21:02 +0200 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-06-25 04:21:02 +0200 |
commit | 93a4b1b9465d92e8be031b57166afa3d5611e142 (patch) | |
tree | 0ac95e35f24a754e01bdc40c56d71068eed49e4c /drivers/pinctrl/pinctrl-rockchip.c | |
parent | Merge tag 'backlight-for-linus-4.2' of git://git.kernel.org/pub/scm/linux/ker... (diff) | |
parent | pinctrl: rockchip: add support for the rk3368 (diff) | |
download | linux-93a4b1b9465d92e8be031b57166afa3d5611e142.tar.xz linux-93a4b1b9465d92e8be031b57166afa3d5611e142.zip |
Merge tag 'pinctrl-v4.2-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl
Pull pin control updates from Linus Walleij:
"Here is the bulk of pin control changes for the v4.2 series: Quite a
lot of new SoC subdrivers and two new main drivers this time, apart
from that business as usual.
Details:
Core functionality:
- Enable exclusive pin ownership: it is possible to flag a pin
controller so that GPIO and other functions cannot use a single pin
simultaneously.
New drivers:
- NXP LPC18xx System Control Unit pin controller
- Imagination Pistachio SoC pin controller
New subdrivers:
- Freescale i.MX7d SoC
- Intel Sunrisepoint-H PCH
- Renesas PFC R8A7793
- Renesas PFC R8A7794
- Mediatek MT6397, MT8127
- SiRF Atlas 7
- Allwinner A33
- Qualcomm MSM8660
- Marvell Armada 395
- Rockchip RK3368
Cleanups:
- A big cleanup of the Marvell MVEBU driver rectifying it to
correspond to reality
- Drop platform device probing from the SH PFC driver, we are now a
DT only shop for SuperH
- Drop obsolte multi-platform check for SH PFC
- Various janitorial: constification, grammar etc
Improvements:
- The AT91 GPIO portions now supports the set_multiple() feature
- Split out SPI pins on the Xilinx Zynq
- Support DTs without specific function nodes in the i.MX driver"
* tag 'pinctrl-v4.2-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: (99 commits)
pinctrl: rockchip: add support for the rk3368
pinctrl: rockchip: generalize perpin driver-strength setting
pinctrl: sh-pfc: r8a7794: add SDHI pin groups
pinctrl: sh-pfc: r8a7794: add MMCIF pin groups
pinctrl: sh-pfc: add R8A7794 PFC support
pinctrl: make pinctrl_register() return proper error code
pinctrl: mvebu: armada-39x: add support for Armada 395 variant
pinctrl: mvebu: armada-39x: add missing SATA functions
pinctrl: mvebu: armada-39x: add missing PCIe functions
pinctrl: mvebu: armada-38x: add ptp functions
pinctrl: mvebu: armada-38x: add ua1 functions
pinctrl: mvebu: armada-38x: add nand functions
pinctrl: mvebu: armada-38x: add sata functions
pinctrl: mvebu: armada-xp: add dram functions
pinctrl: mvebu: armada-xp: add nand rb function
pinctrl: mvebu: armada-xp: add spi1 function
pinctrl: mvebu: armada-39x: normalize ref clock naming
pinctrl: mvebu: armada-xp: rename spi to spi0
pinctrl: mvebu: armada-370: align spi1 clock pin naming
pinctrl: mvebu: armada-370: align VDD cpu-pd pin naming with datasheet
...
Diffstat (limited to 'drivers/pinctrl/pinctrl-rockchip.c')
-rw-r--r-- | drivers/pinctrl/pinctrl-rockchip.c | 131 |
1 files changed, 116 insertions, 15 deletions
diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index dee7d5f06c60..9affcd725776 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -63,6 +63,7 @@ enum rockchip_pinctrl_type { RK3066B, RK3188, RK3288, + RK3368, }; /** @@ -163,6 +164,9 @@ struct rockchip_pin_ctrl { void (*pull_calc_reg)(struct rockchip_pin_bank *bank, int pin_num, struct regmap **regmap, int *reg, u8 *bit); + void (*drv_calc_reg)(struct rockchip_pin_bank *bank, + int pin_num, struct regmap **regmap, + int *reg, u8 *bit); }; struct rockchip_pin_config { @@ -581,7 +585,6 @@ static void rk3288_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, #define RK3288_DRV_BITS_PER_PIN 2 #define RK3288_DRV_PINS_PER_REG 8 #define RK3288_DRV_BANK_STRIDE 16 -static int rk3288_drv_list[] = { 2, 4, 8, 12 }; static void rk3288_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, int pin_num, struct regmap **regmap, @@ -611,14 +614,81 @@ static void rk3288_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, } } -static int rk3288_get_drive(struct rockchip_pin_bank *bank, int pin_num) +#define RK3368_PULL_GRF_OFFSET 0x100 +#define RK3368_PULL_PMU_OFFSET 0x10 + +static void rk3368_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, struct regmap **regmap, + int *reg, u8 *bit) { + struct rockchip_pinctrl *info = bank->drvdata; + + /* The first 32 pins of the first bank are located in PMU */ + if (bank->bank_num == 0) { + *regmap = info->regmap_pmu; + *reg = RK3368_PULL_PMU_OFFSET; + + *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); + *bit = pin_num % RK3188_PULL_PINS_PER_REG; + *bit *= RK3188_PULL_BITS_PER_PIN; + } else { + *regmap = info->regmap_base; + *reg = RK3368_PULL_GRF_OFFSET; + + /* correct the offset, as we're starting with the 2nd bank */ + *reg -= 0x10; + *reg += bank->bank_num * RK3188_PULL_BANK_STRIDE; + *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); + + *bit = (pin_num % RK3188_PULL_PINS_PER_REG); + *bit *= RK3188_PULL_BITS_PER_PIN; + } +} + +#define RK3368_DRV_PMU_OFFSET 0x20 +#define RK3368_DRV_GRF_OFFSET 0x200 + +static void rk3368_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, struct regmap **regmap, + int *reg, u8 *bit) +{ + struct rockchip_pinctrl *info = bank->drvdata; + + /* The first 32 pins of the first bank are located in PMU */ + if (bank->bank_num == 0) { + *regmap = info->regmap_pmu; + *reg = RK3368_DRV_PMU_OFFSET; + + *reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4); + *bit = pin_num % RK3288_DRV_PINS_PER_REG; + *bit *= RK3288_DRV_BITS_PER_PIN; + } else { + *regmap = info->regmap_base; + *reg = RK3368_DRV_GRF_OFFSET; + + /* correct the offset, as we're starting with the 2nd bank */ + *reg -= 0x10; + *reg += bank->bank_num * RK3288_DRV_BANK_STRIDE; + *reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4); + + *bit = (pin_num % RK3288_DRV_PINS_PER_REG); + *bit *= RK3288_DRV_BITS_PER_PIN; + } +} + +static int rockchip_perpin_drv_list[] = { 2, 4, 8, 12 }; + +static int rockchip_get_drive_perpin(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; u32 data; u8 bit; - rk3288_calc_drv_reg_and_bit(bank, pin_num, ®map, ®, &bit); + ctrl->drv_calc_reg(bank, pin_num, ®map, ®, &bit); ret = regmap_read(regmap, reg, &data); if (ret) @@ -627,24 +697,25 @@ static int rk3288_get_drive(struct rockchip_pin_bank *bank, int pin_num) data >>= bit; data &= (1 << RK3288_DRV_BITS_PER_PIN) - 1; - return rk3288_drv_list[data]; + return rockchip_perpin_drv_list[data]; } -static int rk3288_set_drive(struct rockchip_pin_bank *bank, int pin_num, - int strength) +static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank, + int pin_num, int strength) { struct rockchip_pinctrl *info = bank->drvdata; + struct rockchip_pin_ctrl *ctrl = info->ctrl; struct regmap *regmap; unsigned long flags; int reg, ret, i; u32 data, rmask; u8 bit; - rk3288_calc_drv_reg_and_bit(bank, pin_num, ®map, ®, &bit); + ctrl->drv_calc_reg(bank, pin_num, ®map, ®, &bit); ret = -EINVAL; - for (i = 0; i < ARRAY_SIZE(rk3288_drv_list); i++) { - if (rk3288_drv_list[i] == strength) { + for (i = 0; i < ARRAY_SIZE(rockchip_perpin_drv_list); i++) { + if (rockchip_perpin_drv_list[i] == strength) { ret = i; break; } @@ -695,6 +766,7 @@ static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num) : PIN_CONFIG_BIAS_DISABLE; case RK3188: case RK3288: + case RK3368: data >>= bit; data &= (1 << RK3188_PULL_BITS_PER_PIN) - 1; @@ -750,6 +822,7 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank, break; case RK3188: case RK3288: + case RK3368: spin_lock_irqsave(&bank->slock, flags); /* enable the write to the equivalent lower bits */ @@ -927,6 +1000,7 @@ static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl, return pull ? false : true; case RK3188: case RK3288: + case RK3368: return (pull != PIN_CONFIG_BIAS_PULL_PIN_DEFAULT); } @@ -983,10 +1057,11 @@ static int rockchip_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, break; case PIN_CONFIG_DRIVE_STRENGTH: /* rk3288 is the first with per-pin drive-strength */ - if (info->ctrl->type != RK3288) + if (!info->ctrl->drv_calc_reg) return -ENOTSUPP; - rc = rk3288_set_drive(bank, pin - bank->pin_base, arg); + rc = rockchip_set_drive_perpin(bank, + pin - bank->pin_base, arg); if (rc < 0) return rc; break; @@ -1041,10 +1116,10 @@ static int rockchip_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin, break; case PIN_CONFIG_DRIVE_STRENGTH: /* rk3288 is the first with per-pin drive-strength */ - if (info->ctrl->type != RK3288) + if (!info->ctrl->drv_calc_reg) return -ENOTSUPP; - rc = rk3288_get_drive(bank, pin - bank->pin_base); + rc = rockchip_get_drive_perpin(bank, pin - bank->pin_base); if (rc < 0) return rc; @@ -1274,9 +1349,9 @@ static int rockchip_pinctrl_register(struct platform_device *pdev, return ret; info->pctl_dev = pinctrl_register(ctrldesc, &pdev->dev, info); - if (!info->pctl_dev) { + if (IS_ERR(info->pctl_dev)) { dev_err(&pdev->dev, "could not register pinctrl driver\n"); - return -EINVAL; + return PTR_ERR(info->pctl_dev); } for (bank = 0; bank < info->ctrl->nr_banks; ++bank) { @@ -2056,8 +2131,32 @@ static struct rockchip_pin_ctrl rk3288_pin_ctrl = { .grf_mux_offset = 0x0, .pmu_mux_offset = 0x84, .pull_calc_reg = rk3288_calc_pull_reg_and_bit, + .drv_calc_reg = rk3288_calc_drv_reg_and_bit, }; +static struct rockchip_pin_bank rk3368_pin_banks[] = { + PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU, + IOMUX_SOURCE_PMU, + IOMUX_SOURCE_PMU, + IOMUX_SOURCE_PMU + ), + PIN_BANK(1, 32, "gpio1"), + PIN_BANK(2, 32, "gpio2"), + PIN_BANK(3, 32, "gpio3"), +}; + +static struct rockchip_pin_ctrl rk3368_pin_ctrl = { + .pin_banks = rk3368_pin_banks, + .nr_banks = ARRAY_SIZE(rk3368_pin_banks), + .label = "RK3368-GPIO", + .type = RK3368, + .grf_mux_offset = 0x0, + .pmu_mux_offset = 0x0, + .pull_calc_reg = rk3368_calc_pull_reg_and_bit, + .drv_calc_reg = rk3368_calc_drv_reg_and_bit, +}; + + static const struct of_device_id rockchip_pinctrl_dt_match[] = { { .compatible = "rockchip,rk2928-pinctrl", .data = (void *)&rk2928_pin_ctrl }, @@ -2069,6 +2168,8 @@ static const struct of_device_id rockchip_pinctrl_dt_match[] = { .data = (void *)&rk3188_pin_ctrl }, { .compatible = "rockchip,rk3288-pinctrl", .data = (void *)&rk3288_pin_ctrl }, + { .compatible = "rockchip,rk3368-pinctrl", + .data = (void *)&rk3368_pin_ctrl }, {}, }; MODULE_DEVICE_TABLE(of, rockchip_pinctrl_dt_match); |