diff options
Diffstat (limited to 'drivers/pinctrl')
-rw-r--r-- | drivers/pinctrl/pinctrl-rockchip.c | 119 |
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 | ||
65 | enum rockchip_pin_bank_type { | 65 | enum 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 | */ |
85 | struct rockchip_pin_bank { | 87 | struct 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 | ||
158 | struct rockchip_pinctrl { | 161 | struct 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 | |||
390 | static 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 | |||
382 | static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num) | 416 | static 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, ®, &bit); | ||
429 | |||
393 | switch (ctrl->type) { | 430 | switch (ctrl->type) { |
394 | case RK2928: | 431 | case RK2928: |
395 | ctrl->pull_calc_reg(bank, pin_num, ®, &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, ®, &bit); | ||
476 | |||
425 | switch (ctrl->type) { | 477 | switch (ctrl->type) { |
426 | case RK2928: | 478 | case RK2928: |
427 | ctrl->pull_calc_reg(bank, pin_num, ®, &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 | ||
670 | static const struct of_device_id rockchip_bank_match[] = { | 747 | static 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 | ||
1388 | static const struct of_device_id rockchip_pinctrl_dt_match[] = { | 1493 | static const struct of_device_id rockchip_pinctrl_dt_match[] = { |