aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pinctrl')
-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[] = {