diff options
Diffstat (limited to 'drivers/pinctrl/pinctrl-rockchip.c')
-rw-r--r-- | drivers/pinctrl/pinctrl-rockchip.c | 401 |
1 files changed, 333 insertions, 68 deletions
diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index bb805d5e9ff0..5e8b2e04cd7a 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c | |||
@@ -62,11 +62,26 @@ enum rockchip_pinctrl_type { | |||
62 | RK2928, | 62 | RK2928, |
63 | RK3066B, | 63 | RK3066B, |
64 | RK3188, | 64 | RK3188, |
65 | RK3288, | ||
65 | }; | 66 | }; |
66 | 67 | ||
67 | enum rockchip_pin_bank_type { | 68 | /** |
68 | COMMON_BANK, | 69 | * Encode variants of iomux registers into a type variable |
69 | RK3188_BANK0, | 70 | */ |
71 | #define IOMUX_GPIO_ONLY BIT(0) | ||
72 | #define IOMUX_WIDTH_4BIT BIT(1) | ||
73 | #define IOMUX_SOURCE_PMU BIT(2) | ||
74 | #define IOMUX_UNROUTED BIT(3) | ||
75 | |||
76 | /** | ||
77 | * @type: iomux variant using IOMUX_* constants | ||
78 | * @offset: if initialized to -1 it will be autocalculated, by specifying | ||
79 | * an initial offset value the relevant source offset can be reset | ||
80 | * to a new value for autocalculating the following iomux registers. | ||
81 | */ | ||
82 | struct rockchip_iomux { | ||
83 | int type; | ||
84 | int offset; | ||
70 | }; | 85 | }; |
71 | 86 | ||
72 | /** | 87 | /** |
@@ -78,6 +93,7 @@ enum rockchip_pin_bank_type { | |||
78 | * @nr_pins: number of pins in this bank | 93 | * @nr_pins: number of pins in this bank |
79 | * @name: name of the bank | 94 | * @name: name of the bank |
80 | * @bank_num: number of the bank, to account for holes | 95 | * @bank_num: number of the bank, to account for holes |
96 | * @iomux: array describing the 4 iomux sources of the bank | ||
81 | * @valid: are all necessary informations present | 97 | * @valid: are all necessary informations present |
82 | * @of_node: dt node of this bank | 98 | * @of_node: dt node of this bank |
83 | * @drvdata: common pinctrl basedata | 99 | * @drvdata: common pinctrl basedata |
@@ -95,7 +111,7 @@ struct rockchip_pin_bank { | |||
95 | u8 nr_pins; | 111 | u8 nr_pins; |
96 | char *name; | 112 | char *name; |
97 | u8 bank_num; | 113 | u8 bank_num; |
98 | enum rockchip_pin_bank_type bank_type; | 114 | struct rockchip_iomux iomux[4]; |
99 | bool valid; | 115 | bool valid; |
100 | struct device_node *of_node; | 116 | struct device_node *of_node; |
101 | struct rockchip_pinctrl *drvdata; | 117 | struct rockchip_pinctrl *drvdata; |
@@ -111,6 +127,25 @@ struct rockchip_pin_bank { | |||
111 | .bank_num = id, \ | 127 | .bank_num = id, \ |
112 | .nr_pins = pins, \ | 128 | .nr_pins = pins, \ |
113 | .name = label, \ | 129 | .name = label, \ |
130 | .iomux = { \ | ||
131 | { .offset = -1 }, \ | ||
132 | { .offset = -1 }, \ | ||
133 | { .offset = -1 }, \ | ||
134 | { .offset = -1 }, \ | ||
135 | }, \ | ||
136 | } | ||
137 | |||
138 | #define PIN_BANK_IOMUX_FLAGS(id, pins, label, iom0, iom1, iom2, iom3) \ | ||
139 | { \ | ||
140 | .bank_num = id, \ | ||
141 | .nr_pins = pins, \ | ||
142 | .name = label, \ | ||
143 | .iomux = { \ | ||
144 | { .type = iom0, .offset = -1 }, \ | ||
145 | { .type = iom1, .offset = -1 }, \ | ||
146 | { .type = iom2, .offset = -1 }, \ | ||
147 | { .type = iom3, .offset = -1 }, \ | ||
148 | }, \ | ||
114 | } | 149 | } |
115 | 150 | ||
116 | /** | 151 | /** |
@@ -121,7 +156,8 @@ struct rockchip_pin_ctrl { | |||
121 | u32 nr_pins; | 156 | u32 nr_pins; |
122 | char *label; | 157 | char *label; |
123 | enum rockchip_pinctrl_type type; | 158 | enum rockchip_pinctrl_type type; |
124 | int mux_offset; | 159 | int grf_mux_offset; |
160 | int pmu_mux_offset; | ||
125 | void (*pull_calc_reg)(struct rockchip_pin_bank *bank, | 161 | void (*pull_calc_reg)(struct rockchip_pin_bank *bank, |
126 | int pin_num, struct regmap **regmap, | 162 | int pin_num, struct regmap **regmap, |
127 | int *reg, u8 *bit); | 163 | int *reg, u8 *bit); |
@@ -343,24 +379,42 @@ static const struct pinctrl_ops rockchip_pctrl_ops = { | |||
343 | static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin) | 379 | static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin) |
344 | { | 380 | { |
345 | struct rockchip_pinctrl *info = bank->drvdata; | 381 | struct rockchip_pinctrl *info = bank->drvdata; |
382 | int iomux_num = (pin / 8); | ||
383 | struct regmap *regmap; | ||
346 | unsigned int val; | 384 | unsigned int val; |
347 | int reg, ret; | 385 | int reg, ret, mask; |
348 | u8 bit; | 386 | u8 bit; |
349 | 387 | ||
350 | if (bank->bank_type == RK3188_BANK0 && pin < 16) | 388 | if (iomux_num > 3) |
389 | return -EINVAL; | ||
390 | |||
391 | if (bank->iomux[iomux_num].type & IOMUX_UNROUTED) { | ||
392 | dev_err(info->dev, "pin %d is unrouted\n", pin); | ||
393 | return -EINVAL; | ||
394 | } | ||
395 | |||
396 | if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY) | ||
351 | return RK_FUNC_GPIO; | 397 | return RK_FUNC_GPIO; |
352 | 398 | ||
399 | regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) | ||
400 | ? info->regmap_pmu : info->regmap_base; | ||
401 | |||
353 | /* get basic quadrupel of mux registers and the correct reg inside */ | 402 | /* get basic quadrupel of mux registers and the correct reg inside */ |
354 | reg = info->ctrl->mux_offset; | 403 | mask = (bank->iomux[iomux_num].type & IOMUX_WIDTH_4BIT) ? 0xf : 0x3; |
355 | reg += bank->bank_num * 0x10; | 404 | reg = bank->iomux[iomux_num].offset; |
356 | reg += (pin / 8) * 4; | 405 | if (bank->iomux[iomux_num].type & IOMUX_WIDTH_4BIT) { |
357 | bit = (pin % 8) * 2; | 406 | if ((pin % 8) >= 4) |
407 | reg += 0x4; | ||
408 | bit = (pin % 4) * 4; | ||
409 | } else { | ||
410 | bit = (pin % 8) * 2; | ||
411 | } | ||
358 | 412 | ||
359 | ret = regmap_read(info->regmap_base, reg, &val); | 413 | ret = regmap_read(regmap, reg, &val); |
360 | if (ret) | 414 | if (ret) |
361 | return ret; | 415 | return ret; |
362 | 416 | ||
363 | return ((val >> bit) & 3); | 417 | return ((val >> bit) & mask); |
364 | } | 418 | } |
365 | 419 | ||
366 | /* | 420 | /* |
@@ -379,16 +433,22 @@ static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin) | |||
379 | static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) | 433 | static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) |
380 | { | 434 | { |
381 | struct rockchip_pinctrl *info = bank->drvdata; | 435 | struct rockchip_pinctrl *info = bank->drvdata; |
382 | int reg, ret; | 436 | int iomux_num = (pin / 8); |
437 | struct regmap *regmap; | ||
438 | int reg, ret, mask; | ||
383 | unsigned long flags; | 439 | unsigned long flags; |
384 | u8 bit; | 440 | u8 bit; |
385 | u32 data; | 441 | u32 data; |
386 | 442 | ||
387 | /* | 443 | if (iomux_num > 3) |
388 | * The first 16 pins of rk3188_bank0 are always gpios and do not have | 444 | return -EINVAL; |
389 | * a mux register at all. | 445 | |
390 | */ | 446 | if (bank->iomux[iomux_num].type & IOMUX_UNROUTED) { |
391 | if (bank->bank_type == RK3188_BANK0 && pin < 16) { | 447 | dev_err(info->dev, "pin %d is unrouted\n", pin); |
448 | return -EINVAL; | ||
449 | } | ||
450 | |||
451 | if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY) { | ||
392 | if (mux != RK_FUNC_GPIO) { | 452 | if (mux != RK_FUNC_GPIO) { |
393 | dev_err(info->dev, | 453 | dev_err(info->dev, |
394 | "pin %d only supports a gpio mux\n", pin); | 454 | "pin %d only supports a gpio mux\n", pin); |
@@ -401,17 +461,25 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) | |||
401 | dev_dbg(info->dev, "setting mux of GPIO%d-%d to %d\n", | 461 | dev_dbg(info->dev, "setting mux of GPIO%d-%d to %d\n", |
402 | bank->bank_num, pin, mux); | 462 | bank->bank_num, pin, mux); |
403 | 463 | ||
464 | regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) | ||
465 | ? info->regmap_pmu : info->regmap_base; | ||
466 | |||
404 | /* get basic quadrupel of mux registers and the correct reg inside */ | 467 | /* get basic quadrupel of mux registers and the correct reg inside */ |
405 | reg = info->ctrl->mux_offset; | 468 | mask = (bank->iomux[iomux_num].type & IOMUX_WIDTH_4BIT) ? 0xf : 0x3; |
406 | reg += bank->bank_num * 0x10; | 469 | reg = bank->iomux[iomux_num].offset; |
407 | reg += (pin / 8) * 4; | 470 | if (bank->iomux[iomux_num].type & IOMUX_WIDTH_4BIT) { |
408 | bit = (pin % 8) * 2; | 471 | if ((pin % 8) >= 4) |
472 | reg += 0x4; | ||
473 | bit = (pin % 4) * 4; | ||
474 | } else { | ||
475 | bit = (pin % 8) * 2; | ||
476 | } | ||
409 | 477 | ||
410 | spin_lock_irqsave(&bank->slock, flags); | 478 | spin_lock_irqsave(&bank->slock, flags); |
411 | 479 | ||
412 | data = (3 << (bit + 16)); | 480 | data = (mask << (bit + 16)); |
413 | data |= (mux & 3) << bit; | 481 | data |= (mux & mask) << bit; |
414 | ret = regmap_write(info->regmap_base, reg, data); | 482 | ret = regmap_write(regmap, reg, data); |
415 | 483 | ||
416 | spin_unlock_irqrestore(&bank->slock, flags); | 484 | spin_unlock_irqrestore(&bank->slock, flags); |
417 | 485 | ||
@@ -449,7 +517,7 @@ static void rk3188_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, | |||
449 | struct rockchip_pinctrl *info = bank->drvdata; | 517 | struct rockchip_pinctrl *info = bank->drvdata; |
450 | 518 | ||
451 | /* The first 12 pins of the first bank are located elsewhere */ | 519 | /* The first 12 pins of the first bank are located elsewhere */ |
452 | if (bank->bank_type == RK3188_BANK0 && pin_num < 12) { | 520 | if (bank->bank_num == 0 && pin_num < 12) { |
453 | *regmap = info->regmap_pmu ? info->regmap_pmu | 521 | *regmap = info->regmap_pmu ? info->regmap_pmu |
454 | : bank->regmap_pull; | 522 | : bank->regmap_pull; |
455 | *reg = info->regmap_pmu ? RK3188_PULL_PMU_OFFSET : 0; | 523 | *reg = info->regmap_pmu ? RK3188_PULL_PMU_OFFSET : 0; |
@@ -476,6 +544,127 @@ static void rk3188_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, | |||
476 | } | 544 | } |
477 | } | 545 | } |
478 | 546 | ||
547 | #define RK3288_PULL_OFFSET 0x140 | ||
548 | static void rk3288_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, | ||
549 | int pin_num, struct regmap **regmap, | ||
550 | int *reg, u8 *bit) | ||
551 | { | ||
552 | struct rockchip_pinctrl *info = bank->drvdata; | ||
553 | |||
554 | /* The first 24 pins of the first bank are located in PMU */ | ||
555 | if (bank->bank_num == 0) { | ||
556 | *regmap = info->regmap_pmu; | ||
557 | *reg = RK3188_PULL_PMU_OFFSET; | ||
558 | |||
559 | *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); | ||
560 | *bit = pin_num % RK3188_PULL_PINS_PER_REG; | ||
561 | *bit *= RK3188_PULL_BITS_PER_PIN; | ||
562 | } else { | ||
563 | *regmap = info->regmap_base; | ||
564 | *reg = RK3288_PULL_OFFSET; | ||
565 | |||
566 | /* correct the offset, as we're starting with the 2nd bank */ | ||
567 | *reg -= 0x10; | ||
568 | *reg += bank->bank_num * RK3188_PULL_BANK_STRIDE; | ||
569 | *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); | ||
570 | |||
571 | *bit = (pin_num % RK3188_PULL_PINS_PER_REG); | ||
572 | *bit *= RK3188_PULL_BITS_PER_PIN; | ||
573 | } | ||
574 | } | ||
575 | |||
576 | #define RK3288_DRV_PMU_OFFSET 0x70 | ||
577 | #define RK3288_DRV_GRF_OFFSET 0x1c0 | ||
578 | #define RK3288_DRV_BITS_PER_PIN 2 | ||
579 | #define RK3288_DRV_PINS_PER_REG 8 | ||
580 | #define RK3288_DRV_BANK_STRIDE 16 | ||
581 | static int rk3288_drv_list[] = { 2, 4, 8, 12 }; | ||
582 | |||
583 | static void rk3288_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, | ||
584 | int pin_num, struct regmap **regmap, | ||
585 | int *reg, u8 *bit) | ||
586 | { | ||
587 | struct rockchip_pinctrl *info = bank->drvdata; | ||
588 | |||
589 | /* The first 24 pins of the first bank are located in PMU */ | ||
590 | if (bank->bank_num == 0) { | ||
591 | *regmap = info->regmap_pmu; | ||
592 | *reg = RK3288_DRV_PMU_OFFSET; | ||
593 | |||
594 | *reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4); | ||
595 | *bit = pin_num % RK3288_DRV_PINS_PER_REG; | ||
596 | *bit *= RK3288_DRV_BITS_PER_PIN; | ||
597 | } else { | ||
598 | *regmap = info->regmap_base; | ||
599 | *reg = RK3288_DRV_GRF_OFFSET; | ||
600 | |||
601 | /* correct the offset, as we're starting with the 2nd bank */ | ||
602 | *reg -= 0x10; | ||
603 | *reg += bank->bank_num * RK3288_DRV_BANK_STRIDE; | ||
604 | *reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4); | ||
605 | |||
606 | *bit = (pin_num % RK3288_DRV_PINS_PER_REG); | ||
607 | *bit *= RK3288_DRV_BITS_PER_PIN; | ||
608 | } | ||
609 | } | ||
610 | |||
611 | static int rk3288_get_drive(struct rockchip_pin_bank *bank, int pin_num) | ||
612 | { | ||
613 | struct regmap *regmap; | ||
614 | int reg, ret; | ||
615 | u32 data; | ||
616 | u8 bit; | ||
617 | |||
618 | rk3288_calc_drv_reg_and_bit(bank, pin_num, ®map, ®, &bit); | ||
619 | |||
620 | ret = regmap_read(regmap, reg, &data); | ||
621 | if (ret) | ||
622 | return ret; | ||
623 | |||
624 | data >>= bit; | ||
625 | data &= (1 << RK3288_DRV_BITS_PER_PIN) - 1; | ||
626 | |||
627 | return rk3288_drv_list[data]; | ||
628 | } | ||
629 | |||
630 | static int rk3288_set_drive(struct rockchip_pin_bank *bank, int pin_num, | ||
631 | int strength) | ||
632 | { | ||
633 | struct rockchip_pinctrl *info = bank->drvdata; | ||
634 | struct regmap *regmap; | ||
635 | unsigned long flags; | ||
636 | int reg, ret, i; | ||
637 | u32 data; | ||
638 | u8 bit; | ||
639 | |||
640 | rk3288_calc_drv_reg_and_bit(bank, pin_num, ®map, ®, &bit); | ||
641 | |||
642 | ret = -EINVAL; | ||
643 | for (i = 0; i < ARRAY_SIZE(rk3288_drv_list); i++) { | ||
644 | if (rk3288_drv_list[i] == strength) { | ||
645 | ret = i; | ||
646 | break; | ||
647 | } | ||
648 | } | ||
649 | |||
650 | if (ret < 0) { | ||
651 | dev_err(info->dev, "unsupported driver strength %d\n", | ||
652 | strength); | ||
653 | return ret; | ||
654 | } | ||
655 | |||
656 | spin_lock_irqsave(&bank->slock, flags); | ||
657 | |||
658 | /* enable the write to the equivalent lower bits */ | ||
659 | data = ((1 << RK3288_DRV_BITS_PER_PIN) - 1) << (bit + 16); | ||
660 | data |= (ret << bit); | ||
661 | |||
662 | ret = regmap_write(regmap, reg, data); | ||
663 | spin_unlock_irqrestore(&bank->slock, flags); | ||
664 | |||
665 | return ret; | ||
666 | } | ||
667 | |||
479 | static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num) | 668 | static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num) |
480 | { | 669 | { |
481 | struct rockchip_pinctrl *info = bank->drvdata; | 670 | struct rockchip_pinctrl *info = bank->drvdata; |
@@ -501,6 +690,7 @@ static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num) | |||
501 | ? PIN_CONFIG_BIAS_PULL_PIN_DEFAULT | 690 | ? PIN_CONFIG_BIAS_PULL_PIN_DEFAULT |
502 | : PIN_CONFIG_BIAS_DISABLE; | 691 | : PIN_CONFIG_BIAS_DISABLE; |
503 | case RK3188: | 692 | case RK3188: |
693 | case RK3288: | ||
504 | data >>= bit; | 694 | data >>= bit; |
505 | data &= (1 << RK3188_PULL_BITS_PER_PIN) - 1; | 695 | data &= (1 << RK3188_PULL_BITS_PER_PIN) - 1; |
506 | 696 | ||
@@ -555,6 +745,7 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank, | |||
555 | spin_unlock_irqrestore(&bank->slock, flags); | 745 | spin_unlock_irqrestore(&bank->slock, flags); |
556 | break; | 746 | break; |
557 | case RK3188: | 747 | case RK3188: |
748 | case RK3288: | ||
558 | spin_lock_irqsave(&bank->slock, flags); | 749 | spin_lock_irqsave(&bank->slock, flags); |
559 | 750 | ||
560 | /* enable the write to the equivalent lower bits */ | 751 | /* enable the write to the equivalent lower bits */ |
@@ -657,23 +848,6 @@ static int rockchip_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector, | |||
657 | return 0; | 848 | return 0; |
658 | } | 849 | } |
659 | 850 | ||
660 | static void rockchip_pmx_disable(struct pinctrl_dev *pctldev, | ||
661 | unsigned selector, unsigned group) | ||
662 | { | ||
663 | struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); | ||
664 | const unsigned int *pins = info->groups[group].pins; | ||
665 | struct rockchip_pin_bank *bank; | ||
666 | int cnt; | ||
667 | |||
668 | dev_dbg(info->dev, "disable function %s group %s\n", | ||
669 | info->functions[selector].name, info->groups[group].name); | ||
670 | |||
671 | for (cnt = 0; cnt < info->groups[group].npins; cnt++) { | ||
672 | bank = pin_to_bank(info, pins[cnt]); | ||
673 | rockchip_set_mux(bank, pins[cnt] - bank->pin_base, 0); | ||
674 | } | ||
675 | } | ||
676 | |||
677 | /* | 851 | /* |
678 | * The calls to gpio_direction_output() and gpio_direction_input() | 852 | * The calls to gpio_direction_output() and gpio_direction_input() |
679 | * leads to this function call (via the pinctrl_gpio_direction_{input|output}() | 853 | * leads to this function call (via the pinctrl_gpio_direction_{input|output}() |
@@ -716,7 +890,6 @@ static const struct pinmux_ops rockchip_pmx_ops = { | |||
716 | .get_function_name = rockchip_pmx_get_func_name, | 890 | .get_function_name = rockchip_pmx_get_func_name, |
717 | .get_function_groups = rockchip_pmx_get_groups, | 891 | .get_function_groups = rockchip_pmx_get_groups, |
718 | .enable = rockchip_pmx_enable, | 892 | .enable = rockchip_pmx_enable, |
719 | .disable = rockchip_pmx_disable, | ||
720 | .gpio_set_direction = rockchip_pmx_gpio_set_direction, | 893 | .gpio_set_direction = rockchip_pmx_gpio_set_direction, |
721 | }; | 894 | }; |
722 | 895 | ||
@@ -734,6 +907,7 @@ static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl, | |||
734 | case RK3066B: | 907 | case RK3066B: |
735 | return pull ? false : true; | 908 | return pull ? false : true; |
736 | case RK3188: | 909 | case RK3188: |
910 | case RK3288: | ||
737 | return (pull != PIN_CONFIG_BIAS_PULL_PIN_DEFAULT); | 911 | return (pull != PIN_CONFIG_BIAS_PULL_PIN_DEFAULT); |
738 | } | 912 | } |
739 | 913 | ||
@@ -788,6 +962,15 @@ static int rockchip_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, | |||
788 | if (rc) | 962 | if (rc) |
789 | return rc; | 963 | return rc; |
790 | break; | 964 | break; |
965 | case PIN_CONFIG_DRIVE_STRENGTH: | ||
966 | /* rk3288 is the first with per-pin drive-strength */ | ||
967 | if (info->ctrl->type != RK3288) | ||
968 | return -ENOTSUPP; | ||
969 | |||
970 | rc = rk3288_set_drive(bank, pin - bank->pin_base, arg); | ||
971 | if (rc < 0) | ||
972 | return rc; | ||
973 | break; | ||
791 | default: | 974 | default: |
792 | return -ENOTSUPP; | 975 | return -ENOTSUPP; |
793 | break; | 976 | break; |
@@ -837,6 +1020,17 @@ static int rockchip_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin, | |||
837 | 1020 | ||
838 | arg = rc ? 1 : 0; | 1021 | arg = rc ? 1 : 0; |
839 | break; | 1022 | break; |
1023 | case PIN_CONFIG_DRIVE_STRENGTH: | ||
1024 | /* rk3288 is the first with per-pin drive-strength */ | ||
1025 | if (info->ctrl->type != RK3288) | ||
1026 | return -ENOTSUPP; | ||
1027 | |||
1028 | rc = rk3288_get_drive(bank, pin - bank->pin_base); | ||
1029 | if (rc < 0) | ||
1030 | return rc; | ||
1031 | |||
1032 | arg = rc; | ||
1033 | break; | ||
840 | default: | 1034 | default: |
841 | return -ENOTSUPP; | 1035 | return -ENOTSUPP; |
842 | break; | 1036 | break; |
@@ -850,6 +1044,7 @@ static int rockchip_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin, | |||
850 | static const struct pinconf_ops rockchip_pinconf_ops = { | 1044 | static const struct pinconf_ops rockchip_pinconf_ops = { |
851 | .pin_config_get = rockchip_pinconf_get, | 1045 | .pin_config_get = rockchip_pinconf_get, |
852 | .pin_config_set = rockchip_pinconf_set, | 1046 | .pin_config_set = rockchip_pinconf_set, |
1047 | .is_generic = true, | ||
853 | }; | 1048 | }; |
854 | 1049 | ||
855 | static const struct of_device_id rockchip_bank_match[] = { | 1050 | static const struct of_device_id rockchip_bank_match[] = { |
@@ -1414,10 +1609,7 @@ fail: | |||
1414 | for (--i, --bank; i >= 0; --i, --bank) { | 1609 | for (--i, --bank; i >= 0; --i, --bank) { |
1415 | if (!bank->valid) | 1610 | if (!bank->valid) |
1416 | continue; | 1611 | continue; |
1417 | 1612 | gpiochip_remove(&bank->gpio_chip); | |
1418 | if (gpiochip_remove(&bank->gpio_chip)) | ||
1419 | dev_err(&pdev->dev, "gpio chip %s remove failed\n", | ||
1420 | bank->gpio_chip.label); | ||
1421 | } | 1613 | } |
1422 | return ret; | 1614 | return ret; |
1423 | } | 1615 | } |
@@ -1427,20 +1619,15 @@ static int rockchip_gpiolib_unregister(struct platform_device *pdev, | |||
1427 | { | 1619 | { |
1428 | struct rockchip_pin_ctrl *ctrl = info->ctrl; | 1620 | struct rockchip_pin_ctrl *ctrl = info->ctrl; |
1429 | struct rockchip_pin_bank *bank = ctrl->pin_banks; | 1621 | struct rockchip_pin_bank *bank = ctrl->pin_banks; |
1430 | int ret = 0; | ||
1431 | int i; | 1622 | int i; |
1432 | 1623 | ||
1433 | for (i = 0; !ret && i < ctrl->nr_banks; ++i, ++bank) { | 1624 | for (i = 0; i < ctrl->nr_banks; ++i, ++bank) { |
1434 | if (!bank->valid) | 1625 | if (!bank->valid) |
1435 | continue; | 1626 | continue; |
1436 | 1627 | gpiochip_remove(&bank->gpio_chip); | |
1437 | ret = gpiochip_remove(&bank->gpio_chip); | ||
1438 | } | 1628 | } |
1439 | 1629 | ||
1440 | if (ret) | 1630 | return 0; |
1441 | dev_err(&pdev->dev, "gpio chip remove failed\n"); | ||
1442 | |||
1443 | return ret; | ||
1444 | } | 1631 | } |
1445 | 1632 | ||
1446 | static int rockchip_get_bank_data(struct rockchip_pin_bank *bank, | 1633 | static int rockchip_get_bank_data(struct rockchip_pin_bank *bank, |
@@ -1466,8 +1653,6 @@ static int rockchip_get_bank_data(struct rockchip_pin_bank *bank, | |||
1466 | "rockchip,rk3188-gpio-bank0")) { | 1653 | "rockchip,rk3188-gpio-bank0")) { |
1467 | struct device_node *node; | 1654 | struct device_node *node; |
1468 | 1655 | ||
1469 | bank->bank_type = RK3188_BANK0; | ||
1470 | |||
1471 | node = of_parse_phandle(bank->of_node->parent, | 1656 | node = of_parse_phandle(bank->of_node->parent, |
1472 | "rockchip,pmu", 0); | 1657 | "rockchip,pmu", 0); |
1473 | if (!node) { | 1658 | if (!node) { |
@@ -1487,9 +1672,6 @@ static int rockchip_get_bank_data(struct rockchip_pin_bank *bank, | |||
1487 | base, | 1672 | base, |
1488 | &rockchip_regmap_config); | 1673 | &rockchip_regmap_config); |
1489 | } | 1674 | } |
1490 | |||
1491 | } else { | ||
1492 | bank->bank_type = COMMON_BANK; | ||
1493 | } | 1675 | } |
1494 | 1676 | ||
1495 | bank->irq = irq_of_parse_and_map(bank->of_node, 0); | 1677 | bank->irq = irq_of_parse_and_map(bank->of_node, 0); |
@@ -1513,7 +1695,7 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data( | |||
1513 | struct device_node *np; | 1695 | struct device_node *np; |
1514 | struct rockchip_pin_ctrl *ctrl; | 1696 | struct rockchip_pin_ctrl *ctrl; |
1515 | struct rockchip_pin_bank *bank; | 1697 | struct rockchip_pin_bank *bank; |
1516 | int i; | 1698 | int grf_offs, pmu_offs, i, j; |
1517 | 1699 | ||
1518 | match = of_match_node(rockchip_pinctrl_dt_match, node); | 1700 | match = of_match_node(rockchip_pinctrl_dt_match, node); |
1519 | ctrl = (struct rockchip_pin_ctrl *)match->data; | 1701 | ctrl = (struct rockchip_pin_ctrl *)match->data; |
@@ -1535,12 +1717,51 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data( | |||
1535 | } | 1717 | } |
1536 | } | 1718 | } |
1537 | 1719 | ||
1720 | grf_offs = ctrl->grf_mux_offset; | ||
1721 | pmu_offs = ctrl->pmu_mux_offset; | ||
1538 | bank = ctrl->pin_banks; | 1722 | bank = ctrl->pin_banks; |
1539 | for (i = 0; i < ctrl->nr_banks; ++i, ++bank) { | 1723 | for (i = 0; i < ctrl->nr_banks; ++i, ++bank) { |
1724 | int bank_pins = 0; | ||
1725 | |||
1540 | spin_lock_init(&bank->slock); | 1726 | spin_lock_init(&bank->slock); |
1541 | bank->drvdata = d; | 1727 | bank->drvdata = d; |
1542 | bank->pin_base = ctrl->nr_pins; | 1728 | bank->pin_base = ctrl->nr_pins; |
1543 | ctrl->nr_pins += bank->nr_pins; | 1729 | ctrl->nr_pins += bank->nr_pins; |
1730 | |||
1731 | /* calculate iomux offsets */ | ||
1732 | for (j = 0; j < 4; j++) { | ||
1733 | struct rockchip_iomux *iom = &bank->iomux[j]; | ||
1734 | int inc; | ||
1735 | |||
1736 | if (bank_pins >= bank->nr_pins) | ||
1737 | break; | ||
1738 | |||
1739 | /* preset offset value, set new start value */ | ||
1740 | if (iom->offset >= 0) { | ||
1741 | if (iom->type & IOMUX_SOURCE_PMU) | ||
1742 | pmu_offs = iom->offset; | ||
1743 | else | ||
1744 | grf_offs = iom->offset; | ||
1745 | } else { /* set current offset */ | ||
1746 | iom->offset = (iom->type & IOMUX_SOURCE_PMU) ? | ||
1747 | pmu_offs : grf_offs; | ||
1748 | } | ||
1749 | |||
1750 | dev_dbg(d->dev, "bank %d, iomux %d has offset 0x%x\n", | ||
1751 | i, j, iom->offset); | ||
1752 | |||
1753 | /* | ||
1754 | * Increase offset according to iomux width. | ||
1755 | * 4bit iomux'es are spread over two registers. | ||
1756 | */ | ||
1757 | inc = (iom->type & IOMUX_WIDTH_4BIT) ? 8 : 4; | ||
1758 | if (iom->type & IOMUX_SOURCE_PMU) | ||
1759 | pmu_offs += inc; | ||
1760 | else | ||
1761 | grf_offs += inc; | ||
1762 | |||
1763 | bank_pins += 8; | ||
1764 | } | ||
1544 | } | 1765 | } |
1545 | 1766 | ||
1546 | return ctrl; | 1767 | return ctrl; |
@@ -1644,7 +1865,7 @@ static struct rockchip_pin_ctrl rk2928_pin_ctrl = { | |||
1644 | .nr_banks = ARRAY_SIZE(rk2928_pin_banks), | 1865 | .nr_banks = ARRAY_SIZE(rk2928_pin_banks), |
1645 | .label = "RK2928-GPIO", | 1866 | .label = "RK2928-GPIO", |
1646 | .type = RK2928, | 1867 | .type = RK2928, |
1647 | .mux_offset = 0xa8, | 1868 | .grf_mux_offset = 0xa8, |
1648 | .pull_calc_reg = rk2928_calc_pull_reg_and_bit, | 1869 | .pull_calc_reg = rk2928_calc_pull_reg_and_bit, |
1649 | }; | 1870 | }; |
1650 | 1871 | ||
@@ -1662,7 +1883,7 @@ static struct rockchip_pin_ctrl rk3066a_pin_ctrl = { | |||
1662 | .nr_banks = ARRAY_SIZE(rk3066a_pin_banks), | 1883 | .nr_banks = ARRAY_SIZE(rk3066a_pin_banks), |
1663 | .label = "RK3066a-GPIO", | 1884 | .label = "RK3066a-GPIO", |
1664 | .type = RK2928, | 1885 | .type = RK2928, |
1665 | .mux_offset = 0xa8, | 1886 | .grf_mux_offset = 0xa8, |
1666 | .pull_calc_reg = rk2928_calc_pull_reg_and_bit, | 1887 | .pull_calc_reg = rk2928_calc_pull_reg_and_bit, |
1667 | }; | 1888 | }; |
1668 | 1889 | ||
@@ -1678,11 +1899,11 @@ static struct rockchip_pin_ctrl rk3066b_pin_ctrl = { | |||
1678 | .nr_banks = ARRAY_SIZE(rk3066b_pin_banks), | 1899 | .nr_banks = ARRAY_SIZE(rk3066b_pin_banks), |
1679 | .label = "RK3066b-GPIO", | 1900 | .label = "RK3066b-GPIO", |
1680 | .type = RK3066B, | 1901 | .type = RK3066B, |
1681 | .mux_offset = 0x60, | 1902 | .grf_mux_offset = 0x60, |
1682 | }; | 1903 | }; |
1683 | 1904 | ||
1684 | static struct rockchip_pin_bank rk3188_pin_banks[] = { | 1905 | static struct rockchip_pin_bank rk3188_pin_banks[] = { |
1685 | PIN_BANK(0, 32, "gpio0"), | 1906 | PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_GPIO_ONLY, 0, 0, 0), |
1686 | PIN_BANK(1, 32, "gpio1"), | 1907 | PIN_BANK(1, 32, "gpio1"), |
1687 | PIN_BANK(2, 32, "gpio2"), | 1908 | PIN_BANK(2, 32, "gpio2"), |
1688 | PIN_BANK(3, 32, "gpio3"), | 1909 | PIN_BANK(3, 32, "gpio3"), |
@@ -1693,10 +1914,52 @@ static struct rockchip_pin_ctrl rk3188_pin_ctrl = { | |||
1693 | .nr_banks = ARRAY_SIZE(rk3188_pin_banks), | 1914 | .nr_banks = ARRAY_SIZE(rk3188_pin_banks), |
1694 | .label = "RK3188-GPIO", | 1915 | .label = "RK3188-GPIO", |
1695 | .type = RK3188, | 1916 | .type = RK3188, |
1696 | .mux_offset = 0x60, | 1917 | .grf_mux_offset = 0x60, |
1697 | .pull_calc_reg = rk3188_calc_pull_reg_and_bit, | 1918 | .pull_calc_reg = rk3188_calc_pull_reg_and_bit, |
1698 | }; | 1919 | }; |
1699 | 1920 | ||
1921 | static struct rockchip_pin_bank rk3288_pin_banks[] = { | ||
1922 | PIN_BANK_IOMUX_FLAGS(0, 24, "gpio0", IOMUX_SOURCE_PMU, | ||
1923 | IOMUX_SOURCE_PMU, | ||
1924 | IOMUX_SOURCE_PMU, | ||
1925 | IOMUX_UNROUTED | ||
1926 | ), | ||
1927 | PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_UNROUTED, | ||
1928 | IOMUX_UNROUTED, | ||
1929 | IOMUX_UNROUTED, | ||
1930 | 0 | ||
1931 | ), | ||
1932 | PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 0, 0, 0, IOMUX_UNROUTED), | ||
1933 | PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", 0, 0, 0, IOMUX_WIDTH_4BIT), | ||
1934 | PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_4BIT, | ||
1935 | IOMUX_WIDTH_4BIT, | ||
1936 | 0, | ||
1937 | 0 | ||
1938 | ), | ||
1939 | PIN_BANK_IOMUX_FLAGS(5, 32, "gpio5", IOMUX_UNROUTED, | ||
1940 | 0, | ||
1941 | 0, | ||
1942 | IOMUX_UNROUTED | ||
1943 | ), | ||
1944 | PIN_BANK_IOMUX_FLAGS(6, 32, "gpio6", 0, 0, 0, IOMUX_UNROUTED), | ||
1945 | PIN_BANK_IOMUX_FLAGS(7, 32, "gpio7", 0, | ||
1946 | 0, | ||
1947 | IOMUX_WIDTH_4BIT, | ||
1948 | IOMUX_UNROUTED | ||
1949 | ), | ||
1950 | PIN_BANK(8, 16, "gpio8"), | ||
1951 | }; | ||
1952 | |||
1953 | static struct rockchip_pin_ctrl rk3288_pin_ctrl = { | ||
1954 | .pin_banks = rk3288_pin_banks, | ||
1955 | .nr_banks = ARRAY_SIZE(rk3288_pin_banks), | ||
1956 | .label = "RK3288-GPIO", | ||
1957 | .type = RK3288, | ||
1958 | .grf_mux_offset = 0x0, | ||
1959 | .pmu_mux_offset = 0x84, | ||
1960 | .pull_calc_reg = rk3288_calc_pull_reg_and_bit, | ||
1961 | }; | ||
1962 | |||
1700 | static const struct of_device_id rockchip_pinctrl_dt_match[] = { | 1963 | static const struct of_device_id rockchip_pinctrl_dt_match[] = { |
1701 | { .compatible = "rockchip,rk2928-pinctrl", | 1964 | { .compatible = "rockchip,rk2928-pinctrl", |
1702 | .data = (void *)&rk2928_pin_ctrl }, | 1965 | .data = (void *)&rk2928_pin_ctrl }, |
@@ -1706,6 +1969,8 @@ static const struct of_device_id rockchip_pinctrl_dt_match[] = { | |||
1706 | .data = (void *)&rk3066b_pin_ctrl }, | 1969 | .data = (void *)&rk3066b_pin_ctrl }, |
1707 | { .compatible = "rockchip,rk3188-pinctrl", | 1970 | { .compatible = "rockchip,rk3188-pinctrl", |
1708 | .data = (void *)&rk3188_pin_ctrl }, | 1971 | .data = (void *)&rk3188_pin_ctrl }, |
1972 | { .compatible = "rockchip,rk3288-pinctrl", | ||
1973 | .data = (void *)&rk3288_pin_ctrl }, | ||
1709 | {}, | 1974 | {}, |
1710 | }; | 1975 | }; |
1711 | MODULE_DEVICE_TABLE(of, rockchip_pinctrl_dt_match); | 1976 | MODULE_DEVICE_TABLE(of, rockchip_pinctrl_dt_match); |