aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl/pinctrl-rockchip.c
diff options
context:
space:
mode:
authorHeiko Stübner <heiko@sntech.de>2013-10-15 19:08:42 -0400
committerLinus Walleij <linus.walleij@linaro.org>2013-10-16 09:33:54 -0400
commit6ca5274d1d1258b0e84bc1a0d67ca160d8658e5a (patch)
tree5a26bd97f0a5b8a3a55e27288171337629a53d1c /drivers/pinctrl/pinctrl-rockchip.c
parentd1358f90e3b63530a5e0cf4ffa7560b359e9d638 (diff)
pinctrl: rockchip: add rk3188 specifics
Besides the pull registers sitting in a separate place, the rk3188 also has the peculiarity that the pull registers of the first bank are split and the first half is sitting in the register space of the pmu. Therefore this adds a special bank-type for the first bank, to handle the two register sources. Signed-off-by: Heiko Stuebner <heiko@sntech.de> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl/pinctrl-rockchip.c')
-rw-r--r--drivers/pinctrl/pinctrl-rockchip.c119
1 files changed, 112 insertions, 7 deletions
diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
index 91027dd19f89..f5e53a723152 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
@@ -64,10 +64,12 @@ enum rockchip_pinctrl_type {
64 64
65enum rockchip_pin_bank_type { 65enum rockchip_pin_bank_type {
66 COMMON_BANK, 66 COMMON_BANK,
67 RK3188_BANK0,
67}; 68};
68 69
69/** 70/**
70 * @reg_base: register base of the gpio bank 71 * @reg_base: register base of the gpio bank
72 * @reg_pull: optional separate register for additional pull settings
71 * @clk: clock of the gpio bank 73 * @clk: clock of the gpio bank
72 * @irq: interrupt of the gpio bank 74 * @irq: interrupt of the gpio bank
73 * @pin_base: first pin number 75 * @pin_base: first pin number
@@ -84,6 +86,7 @@ enum rockchip_pin_bank_type {
84 */ 86 */
85struct rockchip_pin_bank { 87struct rockchip_pin_bank {
86 void __iomem *reg_base; 88 void __iomem *reg_base;
89 void __iomem *reg_pull;
87 struct clk *clk; 90 struct clk *clk;
88 int irq; 91 int irq;
89 u32 pin_base; 92 u32 pin_base;
@@ -157,6 +160,7 @@ struct rockchip_pmx_func {
157 160
158struct rockchip_pinctrl { 161struct rockchip_pinctrl {
159 void __iomem *reg_base; 162 void __iomem *reg_base;
163 void __iomem *reg_pull;
160 struct device *dev; 164 struct device *dev;
161 struct rockchip_pin_ctrl *ctrl; 165 struct rockchip_pin_ctrl *ctrl;
162 struct pinctrl_desc pctl; 166 struct pinctrl_desc pctl;
@@ -379,25 +383,71 @@ static void rk2928_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
379 *bit = pin_num % RK2928_PULL_PINS_PER_REG; 383 *bit = pin_num % RK2928_PULL_PINS_PER_REG;
380}; 384};
381 385
386#define RK3188_PULL_BITS_PER_PIN 2
387#define RK3188_PULL_PINS_PER_REG 8
388#define RK3188_PULL_BANK_STRIDE 16
389
390static void rk3188_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
391 int pin_num, void __iomem **reg, u8 *bit)
392{
393 struct rockchip_pinctrl *info = bank->drvdata;
394
395 /* The first 12 pins of the first bank are located elsewhere */
396 if (bank->bank_type == RK3188_BANK0 && pin_num < 12) {
397 *reg = bank->reg_pull +
398 ((pin_num / RK3188_PULL_PINS_PER_REG) * 4);
399 *bit = pin_num % RK3188_PULL_PINS_PER_REG;
400 *bit *= RK3188_PULL_BITS_PER_PIN;
401 } else {
402 *reg = info->reg_pull - 4;
403 *reg += bank->bank_num * RK3188_PULL_BANK_STRIDE;
404 *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4);
405
406 /*
407 * The bits in these registers have an inverse ordering
408 * with the lowest pin being in bits 15:14 and the highest
409 * pin in bits 1:0
410 */
411 *bit = 7 - (pin_num % RK3188_PULL_PINS_PER_REG);
412 *bit *= RK3188_PULL_BITS_PER_PIN;
413 }
414}
415
382static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num) 416static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num)
383{ 417{
384 struct rockchip_pinctrl *info = bank->drvdata; 418 struct rockchip_pinctrl *info = bank->drvdata;
385 struct rockchip_pin_ctrl *ctrl = info->ctrl; 419 struct rockchip_pin_ctrl *ctrl = info->ctrl;
386 void __iomem *reg; 420 void __iomem *reg;
387 u8 bit; 421 u8 bit;
422 u32 data;
388 423
389 /* rk3066b does support any pulls */ 424 /* rk3066b does support any pulls */
390 if (ctrl->type == RK3066B) 425 if (ctrl->type == RK3066B)
391 return PIN_CONFIG_BIAS_DISABLE; 426 return PIN_CONFIG_BIAS_DISABLE;
392 427
428 ctrl->pull_calc_reg(bank, pin_num, &reg, &bit);
429
393 switch (ctrl->type) { 430 switch (ctrl->type) {
394 case RK2928: 431 case RK2928:
395 ctrl->pull_calc_reg(bank, pin_num, &reg, &bit);
396 return !(readl_relaxed(reg) & BIT(bit)) 432 return !(readl_relaxed(reg) & BIT(bit))
397 ? PIN_CONFIG_BIAS_PULL_PIN_DEFAULT 433 ? PIN_CONFIG_BIAS_PULL_PIN_DEFAULT
398 : PIN_CONFIG_BIAS_DISABLE; 434 : PIN_CONFIG_BIAS_DISABLE;
399 case RK3188: 435 case RK3188:
400 dev_err(info->dev, "pull support for rk31xx not implemented\n"); 436 data = readl_relaxed(reg) >> bit;
437 data &= (1 << RK3188_PULL_BITS_PER_PIN) - 1;
438
439 switch (data) {
440 case 0:
441 return PIN_CONFIG_BIAS_DISABLE;
442 case 1:
443 return PIN_CONFIG_BIAS_PULL_UP;
444 case 2:
445 return PIN_CONFIG_BIAS_PULL_DOWN;
446 case 3:
447 return PIN_CONFIG_BIAS_BUS_HOLD;
448 }
449
450 dev_err(info->dev, "unknown pull setting\n");
401 return -EIO; 451 return -EIO;
402 default: 452 default:
403 dev_err(info->dev, "unsupported pinctrl type\n"); 453 dev_err(info->dev, "unsupported pinctrl type\n");
@@ -422,10 +472,10 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank,
422 if (ctrl->type == RK3066B) 472 if (ctrl->type == RK3066B)
423 return pull ? -EINVAL : 0; 473 return pull ? -EINVAL : 0;
424 474
475 ctrl->pull_calc_reg(bank, pin_num, &reg, &bit);
476
425 switch (ctrl->type) { 477 switch (ctrl->type) {
426 case RK2928: 478 case RK2928:
427 ctrl->pull_calc_reg(bank, pin_num, &reg, &bit);
428
429 spin_lock_irqsave(&bank->slock, flags); 479 spin_lock_irqsave(&bank->slock, flags);
430 480
431 data = BIT(bit + 16); 481 data = BIT(bit + 16);
@@ -436,8 +486,33 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank,
436 spin_unlock_irqrestore(&bank->slock, flags); 486 spin_unlock_irqrestore(&bank->slock, flags);
437 break; 487 break;
438 case RK3188: 488 case RK3188:
439 dev_err(info->dev, "pull support for rk31xx not implemented\n"); 489 spin_lock_irqsave(&bank->slock, flags);
440 return -EIO; 490
491 /* enable the write to the equivalent lower bits */
492 data = ((1 << RK3188_PULL_BITS_PER_PIN) - 1) << (bit + 16);
493
494 switch (pull) {
495 case PIN_CONFIG_BIAS_DISABLE:
496 break;
497 case PIN_CONFIG_BIAS_PULL_UP:
498 data |= (1 << bit);
499 break;
500 case PIN_CONFIG_BIAS_PULL_DOWN:
501 data |= (2 << bit);
502 break;
503 case PIN_CONFIG_BIAS_BUS_HOLD:
504 data |= (3 << bit);
505 break;
506 default:
507 dev_err(info->dev, "unsupported pull setting %d\n",
508 pull);
509 return -EINVAL;
510 }
511
512 writel(data, reg);
513
514 spin_unlock_irqrestore(&bank->slock, flags);
515 break;
441 default: 516 default:
442 dev_err(info->dev, "unsupported pinctrl type\n"); 517 dev_err(info->dev, "unsupported pinctrl type\n");
443 return -EINVAL; 518 return -EINVAL;
@@ -608,6 +683,7 @@ static int rockchip_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
608 case PIN_CONFIG_BIAS_PULL_UP: 683 case PIN_CONFIG_BIAS_PULL_UP:
609 case PIN_CONFIG_BIAS_PULL_DOWN: 684 case PIN_CONFIG_BIAS_PULL_DOWN:
610 case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT: 685 case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
686 case PIN_CONFIG_BIAS_BUS_HOLD:
611 if (!rockchip_pinconf_pull_valid(info->ctrl, param)) 687 if (!rockchip_pinconf_pull_valid(info->ctrl, param))
612 return -ENOTSUPP; 688 return -ENOTSUPP;
613 689
@@ -646,6 +722,7 @@ static int rockchip_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
646 case PIN_CONFIG_BIAS_PULL_UP: 722 case PIN_CONFIG_BIAS_PULL_UP:
647 case PIN_CONFIG_BIAS_PULL_DOWN: 723 case PIN_CONFIG_BIAS_PULL_DOWN:
648 case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT: 724 case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
725 case PIN_CONFIG_BIAS_BUS_HOLD:
649 if (!rockchip_pinconf_pull_valid(info->ctrl, param)) 726 if (!rockchip_pinconf_pull_valid(info->ctrl, param))
650 return -ENOTSUPP; 727 return -ENOTSUPP;
651 728
@@ -669,6 +746,7 @@ static const struct pinconf_ops rockchip_pinconf_ops = {
669 746
670static const struct of_device_id rockchip_bank_match[] = { 747static const struct of_device_id rockchip_bank_match[] = {
671 { .compatible = "rockchip,gpio-bank" }, 748 { .compatible = "rockchip,gpio-bank" },
749 { .compatible = "rockchip,rk3188-gpio-bank0" },
672 {}, 750 {},
673}; 751};
674 752
@@ -1220,7 +1298,25 @@ static int rockchip_get_bank_data(struct rockchip_pin_bank *bank,
1220 if (IS_ERR(bank->reg_base)) 1298 if (IS_ERR(bank->reg_base))
1221 return PTR_ERR(bank->reg_base); 1299 return PTR_ERR(bank->reg_base);
1222 1300
1223 bank->bank_type = COMMON_BANK; 1301 /*
1302 * special case, where parts of the pull setting-registers are
1303 * part of the PMU register space
1304 */
1305 if (of_device_is_compatible(bank->of_node,
1306 "rockchip,rk3188-gpio-bank0")) {
1307 bank->bank_type = RK3188_BANK0;
1308
1309 if (of_address_to_resource(bank->of_node, 1, &res)) {
1310 dev_err(dev, "cannot find IO resource for bank\n");
1311 return -ENOENT;
1312 }
1313
1314 bank->reg_pull = devm_ioremap_resource(dev, &res);
1315 if (IS_ERR(bank->reg_pull))
1316 return PTR_ERR(bank->reg_pull);
1317 } else {
1318 bank->bank_type = COMMON_BANK;
1319 }
1224 1320
1225 bank->irq = irq_of_parse_and_map(bank->of_node, 0); 1321 bank->irq = irq_of_parse_and_map(bank->of_node, 0);
1226 1322
@@ -1306,6 +1402,14 @@ static int rockchip_pinctrl_probe(struct platform_device *pdev)
1306 if (IS_ERR(info->reg_base)) 1402 if (IS_ERR(info->reg_base))
1307 return PTR_ERR(info->reg_base); 1403 return PTR_ERR(info->reg_base);
1308 1404
1405 /* The RK3188 has its pull registers in a separate place */
1406 if (ctrl->type == RK3188) {
1407 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
1408 info->reg_pull = devm_ioremap_resource(&pdev->dev, res);
1409 if (IS_ERR(info->reg_base))
1410 return PTR_ERR(info->reg_base);
1411 }
1412
1309 ret = rockchip_gpiolib_register(pdev, info); 1413 ret = rockchip_gpiolib_register(pdev, info);
1310 if (ret) 1414 if (ret)
1311 return ret; 1415 return ret;
@@ -1383,6 +1487,7 @@ static struct rockchip_pin_ctrl rk3188_pin_ctrl = {
1383 .label = "RK3188-GPIO", 1487 .label = "RK3188-GPIO",
1384 .type = RK3188, 1488 .type = RK3188,
1385 .mux_offset = 0x68, 1489 .mux_offset = 0x68,
1490 .pull_calc_reg = rk3188_calc_pull_reg_and_bit,
1386}; 1491};
1387 1492
1388static const struct of_device_id rockchip_pinctrl_dt_match[] = { 1493static const struct of_device_id rockchip_pinctrl_dt_match[] = {