diff options
author | Heiko Stübner <heiko@sntech.de> | 2014-05-05 07:58:20 -0400 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2014-05-09 05:14:15 -0400 |
commit | 751a99aba47e9bd30b4fd5bf36f4e0143d3e81bb (patch) | |
tree | 95c7daf3598570c2f157a91cb6fa86f89ea7baa9 /drivers/pinctrl/pinctrl-rockchip.c | |
parent | bfc7a42a0e74f0b589a017679620d2a3edda9198 (diff) |
pinctrl: rockchip: use regmaps instead of raw mappings
This allows us to use syscons in the future.
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Tested-by: Max Schwarz <max.schwarz@online.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.c | 116 |
1 files changed, 80 insertions, 36 deletions
diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index ab71de8bc7e0..71d9c9994511 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <linux/pinctrl/pinconf-generic.h> | 37 | #include <linux/pinctrl/pinconf-generic.h> |
38 | #include <linux/irqchip/chained_irq.h> | 38 | #include <linux/irqchip/chained_irq.h> |
39 | #include <linux/clk.h> | 39 | #include <linux/clk.h> |
40 | #include <linux/regmap.h> | ||
40 | #include <dt-bindings/pinctrl/rockchip.h> | 41 | #include <dt-bindings/pinctrl/rockchip.h> |
41 | 42 | ||
42 | #include "core.h" | 43 | #include "core.h" |
@@ -86,7 +87,7 @@ enum rockchip_pin_bank_type { | |||
86 | */ | 87 | */ |
87 | struct rockchip_pin_bank { | 88 | struct rockchip_pin_bank { |
88 | void __iomem *reg_base; | 89 | void __iomem *reg_base; |
89 | void __iomem *reg_pull; | 90 | struct regmap *regmap_pull; |
90 | struct clk *clk; | 91 | struct clk *clk; |
91 | int irq; | 92 | int irq; |
92 | u32 pin_base; | 93 | u32 pin_base; |
@@ -120,8 +121,9 @@ struct rockchip_pin_ctrl { | |||
120 | char *label; | 121 | char *label; |
121 | enum rockchip_pinctrl_type type; | 122 | enum rockchip_pinctrl_type type; |
122 | int mux_offset; | 123 | int mux_offset; |
123 | void (*pull_calc_reg)(struct rockchip_pin_bank *bank, int pin_num, | 124 | void (*pull_calc_reg)(struct rockchip_pin_bank *bank, |
124 | void __iomem **reg, u8 *bit); | 125 | int pin_num, struct regmap **regmap, |
126 | int *reg, u8 *bit); | ||
125 | }; | 127 | }; |
126 | 128 | ||
127 | struct rockchip_pin_config { | 129 | struct rockchip_pin_config { |
@@ -159,9 +161,9 @@ struct rockchip_pmx_func { | |||
159 | }; | 161 | }; |
160 | 162 | ||
161 | struct rockchip_pinctrl { | 163 | struct rockchip_pinctrl { |
162 | void __iomem *reg_base; | 164 | struct regmap *regmap_base; |
163 | int reg_size; | 165 | int reg_size; |
164 | void __iomem *reg_pull; | 166 | struct regmap *regmap_pull; |
165 | struct device *dev; | 167 | struct device *dev; |
166 | struct rockchip_pin_ctrl *ctrl; | 168 | struct rockchip_pin_ctrl *ctrl; |
167 | struct pinctrl_desc pctl; | 169 | struct pinctrl_desc pctl; |
@@ -172,6 +174,12 @@ struct rockchip_pinctrl { | |||
172 | unsigned int nfunctions; | 174 | unsigned int nfunctions; |
173 | }; | 175 | }; |
174 | 176 | ||
177 | static struct regmap_config rockchip_regmap_config = { | ||
178 | .reg_bits = 32, | ||
179 | .val_bits = 32, | ||
180 | .reg_stride = 4, | ||
181 | }; | ||
182 | |||
175 | static inline struct rockchip_pin_bank *gc_to_pin_bank(struct gpio_chip *gc) | 183 | static inline struct rockchip_pin_bank *gc_to_pin_bank(struct gpio_chip *gc) |
176 | { | 184 | { |
177 | return container_of(gc, struct rockchip_pin_bank, gpio_chip); | 185 | return container_of(gc, struct rockchip_pin_bank, gpio_chip); |
@@ -333,18 +341,24 @@ static const struct pinctrl_ops rockchip_pctrl_ops = { | |||
333 | static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin) | 341 | static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin) |
334 | { | 342 | { |
335 | struct rockchip_pinctrl *info = bank->drvdata; | 343 | struct rockchip_pinctrl *info = bank->drvdata; |
336 | void __iomem *reg = info->reg_base + info->ctrl->mux_offset; | 344 | unsigned int val; |
345 | int reg, ret; | ||
337 | u8 bit; | 346 | u8 bit; |
338 | 347 | ||
339 | if (bank->bank_type == RK3188_BANK0 && pin < 16) | 348 | if (bank->bank_type == RK3188_BANK0 && pin < 16) |
340 | return RK_FUNC_GPIO; | 349 | return RK_FUNC_GPIO; |
341 | 350 | ||
342 | /* get basic quadrupel of mux registers and the correct reg inside */ | 351 | /* get basic quadrupel of mux registers and the correct reg inside */ |
352 | reg = info->ctrl->mux_offset; | ||
343 | reg += bank->bank_num * 0x10; | 353 | reg += bank->bank_num * 0x10; |
344 | reg += (pin / 8) * 4; | 354 | reg += (pin / 8) * 4; |
345 | bit = (pin % 8) * 2; | 355 | bit = (pin % 8) * 2; |
346 | 356 | ||
347 | return ((readl(reg) >> bit) & 3); | 357 | ret = regmap_read(info->regmap_base, reg, &val); |
358 | if (ret) | ||
359 | return ret; | ||
360 | |||
361 | return ((val >> bit) & 3); | ||
348 | } | 362 | } |
349 | 363 | ||
350 | /* | 364 | /* |
@@ -363,7 +377,7 @@ static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin) | |||
363 | static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) | 377 | static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) |
364 | { | 378 | { |
365 | struct rockchip_pinctrl *info = bank->drvdata; | 379 | struct rockchip_pinctrl *info = bank->drvdata; |
366 | void __iomem *reg = info->reg_base + info->ctrl->mux_offset; | 380 | int reg, ret; |
367 | unsigned long flags; | 381 | unsigned long flags; |
368 | u8 bit; | 382 | u8 bit; |
369 | u32 data; | 383 | u32 data; |
@@ -386,6 +400,7 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) | |||
386 | bank->bank_num, pin, mux); | 400 | bank->bank_num, pin, mux); |
387 | 401 | ||
388 | /* get basic quadrupel of mux registers and the correct reg inside */ | 402 | /* get basic quadrupel of mux registers and the correct reg inside */ |
403 | reg = info->ctrl->mux_offset; | ||
389 | reg += bank->bank_num * 0x10; | 404 | reg += bank->bank_num * 0x10; |
390 | reg += (pin / 8) * 4; | 405 | reg += (pin / 8) * 4; |
391 | bit = (pin % 8) * 2; | 406 | bit = (pin % 8) * 2; |
@@ -394,11 +409,11 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) | |||
394 | 409 | ||
395 | data = (3 << (bit + 16)); | 410 | data = (3 << (bit + 16)); |
396 | data |= (mux & 3) << bit; | 411 | data |= (mux & 3) << bit; |
397 | writel(data, reg); | 412 | ret = regmap_write(info->regmap_base, reg, data); |
398 | 413 | ||
399 | spin_unlock_irqrestore(&bank->slock, flags); | 414 | spin_unlock_irqrestore(&bank->slock, flags); |
400 | 415 | ||
401 | return 0; | 416 | return ret; |
402 | } | 417 | } |
403 | 418 | ||
404 | #define RK2928_PULL_OFFSET 0x118 | 419 | #define RK2928_PULL_OFFSET 0x118 |
@@ -406,11 +421,13 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) | |||
406 | #define RK2928_PULL_BANK_STRIDE 8 | 421 | #define RK2928_PULL_BANK_STRIDE 8 |
407 | 422 | ||
408 | static void rk2928_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, | 423 | static void rk2928_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, |
409 | int pin_num, void __iomem **reg, u8 *bit) | 424 | int pin_num, struct regmap **regmap, |
425 | int *reg, u8 *bit) | ||
410 | { | 426 | { |
411 | struct rockchip_pinctrl *info = bank->drvdata; | 427 | struct rockchip_pinctrl *info = bank->drvdata; |
412 | 428 | ||
413 | *reg = info->reg_base + RK2928_PULL_OFFSET; | 429 | *regmap = info->regmap_base; |
430 | *reg = RK2928_PULL_OFFSET; | ||
414 | *reg += bank->bank_num * RK2928_PULL_BANK_STRIDE; | 431 | *reg += bank->bank_num * RK2928_PULL_BANK_STRIDE; |
415 | *reg += (pin_num / RK2928_PULL_PINS_PER_REG) * 4; | 432 | *reg += (pin_num / RK2928_PULL_PINS_PER_REG) * 4; |
416 | 433 | ||
@@ -423,19 +440,23 @@ static void rk2928_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, | |||
423 | #define RK3188_PULL_BANK_STRIDE 16 | 440 | #define RK3188_PULL_BANK_STRIDE 16 |
424 | 441 | ||
425 | static void rk3188_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, | 442 | static void rk3188_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, |
426 | int pin_num, void __iomem **reg, u8 *bit) | 443 | int pin_num, struct regmap **regmap, |
444 | int *reg, u8 *bit) | ||
427 | { | 445 | { |
428 | struct rockchip_pinctrl *info = bank->drvdata; | 446 | struct rockchip_pinctrl *info = bank->drvdata; |
429 | 447 | ||
430 | /* The first 12 pins of the first bank are located elsewhere */ | 448 | /* The first 12 pins of the first bank are located elsewhere */ |
431 | if (bank->bank_type == RK3188_BANK0 && pin_num < 12) { | 449 | if (bank->bank_type == RK3188_BANK0 && pin_num < 12) { |
432 | *reg = bank->reg_pull + | 450 | *regmap = bank->regmap_pull; |
433 | ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); | 451 | *reg = 0; |
452 | *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); | ||
434 | *bit = pin_num % RK3188_PULL_PINS_PER_REG; | 453 | *bit = pin_num % RK3188_PULL_PINS_PER_REG; |
435 | *bit *= RK3188_PULL_BITS_PER_PIN; | 454 | *bit *= RK3188_PULL_BITS_PER_PIN; |
436 | } else { | 455 | } else { |
437 | *reg = info->reg_pull ? info->reg_pull | 456 | *regmap = info->regmap_pull ? info->regmap_pull |
438 | : info->reg_base + RK3188_PULL_OFFSET; | 457 | : info->regmap_base; |
458 | *reg = info->regmap_pull ? 0 : RK3188_PULL_OFFSET; | ||
459 | |||
439 | /* correct the offset, as it is the 2nd pull register */ | 460 | /* correct the offset, as it is the 2nd pull register */ |
440 | *reg -= 4; | 461 | *reg -= 4; |
441 | *reg += bank->bank_num * RK3188_PULL_BANK_STRIDE; | 462 | *reg += bank->bank_num * RK3188_PULL_BANK_STRIDE; |
@@ -455,7 +476,8 @@ static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num) | |||
455 | { | 476 | { |
456 | struct rockchip_pinctrl *info = bank->drvdata; | 477 | struct rockchip_pinctrl *info = bank->drvdata; |
457 | struct rockchip_pin_ctrl *ctrl = info->ctrl; | 478 | struct rockchip_pin_ctrl *ctrl = info->ctrl; |
458 | void __iomem *reg; | 479 | struct regmap *regmap; |
480 | int reg, ret; | ||
459 | u8 bit; | 481 | u8 bit; |
460 | u32 data; | 482 | u32 data; |
461 | 483 | ||
@@ -463,15 +485,19 @@ static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num) | |||
463 | if (ctrl->type == RK3066B) | 485 | if (ctrl->type == RK3066B) |
464 | return PIN_CONFIG_BIAS_DISABLE; | 486 | return PIN_CONFIG_BIAS_DISABLE; |
465 | 487 | ||
466 | ctrl->pull_calc_reg(bank, pin_num, ®, &bit); | 488 | ctrl->pull_calc_reg(bank, pin_num, ®map, ®, &bit); |
489 | |||
490 | ret = regmap_read(regmap, reg, &data); | ||
491 | if (ret) | ||
492 | return ret; | ||
467 | 493 | ||
468 | switch (ctrl->type) { | 494 | switch (ctrl->type) { |
469 | case RK2928: | 495 | case RK2928: |
470 | return !(readl_relaxed(reg) & BIT(bit)) | 496 | return !(data & BIT(bit)) |
471 | ? PIN_CONFIG_BIAS_PULL_PIN_DEFAULT | 497 | ? PIN_CONFIG_BIAS_PULL_PIN_DEFAULT |
472 | : PIN_CONFIG_BIAS_DISABLE; | 498 | : PIN_CONFIG_BIAS_DISABLE; |
473 | case RK3188: | 499 | case RK3188: |
474 | data = readl_relaxed(reg) >> bit; | 500 | data >>= bit; |
475 | data &= (1 << RK3188_PULL_BITS_PER_PIN) - 1; | 501 | data &= (1 << RK3188_PULL_BITS_PER_PIN) - 1; |
476 | 502 | ||
477 | switch (data) { | 503 | switch (data) { |
@@ -498,7 +524,8 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank, | |||
498 | { | 524 | { |
499 | struct rockchip_pinctrl *info = bank->drvdata; | 525 | struct rockchip_pinctrl *info = bank->drvdata; |
500 | struct rockchip_pin_ctrl *ctrl = info->ctrl; | 526 | struct rockchip_pin_ctrl *ctrl = info->ctrl; |
501 | void __iomem *reg; | 527 | struct regmap *regmap; |
528 | int reg, ret; | ||
502 | unsigned long flags; | 529 | unsigned long flags; |
503 | u8 bit; | 530 | u8 bit; |
504 | u32 data; | 531 | u32 data; |
@@ -510,7 +537,7 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank, | |||
510 | if (ctrl->type == RK3066B) | 537 | if (ctrl->type == RK3066B) |
511 | return pull ? -EINVAL : 0; | 538 | return pull ? -EINVAL : 0; |
512 | 539 | ||
513 | ctrl->pull_calc_reg(bank, pin_num, ®, &bit); | 540 | ctrl->pull_calc_reg(bank, pin_num, ®map, ®, &bit); |
514 | 541 | ||
515 | switch (ctrl->type) { | 542 | switch (ctrl->type) { |
516 | case RK2928: | 543 | case RK2928: |
@@ -519,7 +546,7 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank, | |||
519 | data = BIT(bit + 16); | 546 | data = BIT(bit + 16); |
520 | if (pull == PIN_CONFIG_BIAS_DISABLE) | 547 | if (pull == PIN_CONFIG_BIAS_DISABLE) |
521 | data |= BIT(bit); | 548 | data |= BIT(bit); |
522 | writel(data, reg); | 549 | ret = regmap_write(regmap, reg, data); |
523 | 550 | ||
524 | spin_unlock_irqrestore(&bank->slock, flags); | 551 | spin_unlock_irqrestore(&bank->slock, flags); |
525 | break; | 552 | break; |
@@ -548,7 +575,7 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank, | |||
548 | return -EINVAL; | 575 | return -EINVAL; |
549 | } | 576 | } |
550 | 577 | ||
551 | writel(data, reg); | 578 | ret = regmap_write(regmap, reg, data); |
552 | 579 | ||
553 | spin_unlock_irqrestore(&bank->slock, flags); | 580 | spin_unlock_irqrestore(&bank->slock, flags); |
554 | break; | 581 | break; |
@@ -557,7 +584,7 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank, | |||
557 | return -EINVAL; | 584 | return -EINVAL; |
558 | } | 585 | } |
559 | 586 | ||
560 | return 0; | 587 | return ret; |
561 | } | 588 | } |
562 | 589 | ||
563 | /* | 590 | /* |
@@ -1416,6 +1443,7 @@ static int rockchip_get_bank_data(struct rockchip_pin_bank *bank, | |||
1416 | struct device *dev) | 1443 | struct device *dev) |
1417 | { | 1444 | { |
1418 | struct resource res; | 1445 | struct resource res; |
1446 | void __iomem *base; | ||
1419 | 1447 | ||
1420 | if (of_address_to_resource(bank->of_node, 0, &res)) { | 1448 | if (of_address_to_resource(bank->of_node, 0, &res)) { |
1421 | dev_err(dev, "cannot find IO resource for bank\n"); | 1449 | dev_err(dev, "cannot find IO resource for bank\n"); |
@@ -1440,9 +1468,14 @@ static int rockchip_get_bank_data(struct rockchip_pin_bank *bank, | |||
1440 | return -ENOENT; | 1468 | return -ENOENT; |
1441 | } | 1469 | } |
1442 | 1470 | ||
1443 | bank->reg_pull = devm_ioremap_resource(dev, &res); | 1471 | base = devm_ioremap_resource(dev, &res); |
1444 | if (IS_ERR(bank->reg_pull)) | 1472 | if (IS_ERR(base)) |
1445 | return PTR_ERR(bank->reg_pull); | 1473 | return PTR_ERR(base); |
1474 | rockchip_regmap_config.max_register = resource_size(&res) - 4; | ||
1475 | rockchip_regmap_config.name = "rockchip,rk3188-gpio-bank0-pull"; | ||
1476 | bank->regmap_pull = devm_regmap_init_mmio(dev, base, | ||
1477 | &rockchip_regmap_config); | ||
1478 | |||
1446 | } else { | 1479 | } else { |
1447 | bank->bank_type = COMMON_BANK; | 1480 | bank->bank_type = COMMON_BANK; |
1448 | } | 1481 | } |
@@ -1507,6 +1540,7 @@ static int rockchip_pinctrl_probe(struct platform_device *pdev) | |||
1507 | struct device *dev = &pdev->dev; | 1540 | struct device *dev = &pdev->dev; |
1508 | struct rockchip_pin_ctrl *ctrl; | 1541 | struct rockchip_pin_ctrl *ctrl; |
1509 | struct resource *res; | 1542 | struct resource *res; |
1543 | void __iomem *base; | ||
1510 | int ret; | 1544 | int ret; |
1511 | 1545 | ||
1512 | if (!dev->of_node) { | 1546 | if (!dev->of_node) { |
@@ -1527,19 +1561,29 @@ static int rockchip_pinctrl_probe(struct platform_device *pdev) | |||
1527 | info->dev = dev; | 1561 | info->dev = dev; |
1528 | 1562 | ||
1529 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1563 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1530 | info->reg_base = devm_ioremap_resource(&pdev->dev, res); | 1564 | base = devm_ioremap_resource(&pdev->dev, res); |
1531 | if (IS_ERR(info->reg_base)) | 1565 | if (IS_ERR(base)) |
1532 | return PTR_ERR(info->reg_base); | 1566 | return PTR_ERR(base); |
1567 | |||
1568 | rockchip_regmap_config.max_register = resource_size(res) - 4; | ||
1569 | rockchip_regmap_config.name = "rockchip,pinctrl"; | ||
1570 | info->regmap_base = devm_regmap_init_mmio(&pdev->dev, base, | ||
1571 | &rockchip_regmap_config); | ||
1533 | 1572 | ||
1534 | /* to check for the old dt-bindings */ | 1573 | /* to check for the old dt-bindings */ |
1535 | info->reg_size = resource_size(res); | 1574 | info->reg_size = resource_size(res); |
1536 | 1575 | ||
1537 | /* Honor the old binding, with pull registers as 2nd resource */ | 1576 | /* Honor the old binding, with pull registers as 2nd resource */ |
1538 | if (ctrl->type == RK3188 && info->reg_size < 0x200) { | 1577 | if (ctrl->type == RK3188 && info->reg_size < 0x200) { |
1539 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | 1578 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); |
1540 | info->reg_pull = devm_ioremap_resource(&pdev->dev, res); | 1579 | base = devm_ioremap_resource(&pdev->dev, res); |
1541 | if (IS_ERR(info->reg_pull)) | 1580 | if (IS_ERR(base)) |
1542 | return PTR_ERR(info->reg_pull); | 1581 | return PTR_ERR(base); |
1582 | |||
1583 | rockchip_regmap_config.max_register = resource_size(res) - 4; | ||
1584 | rockchip_regmap_config.name = "rockchip,pinctrl-pull"; | ||
1585 | info->regmap_pull = devm_regmap_init_mmio(&pdev->dev, base, | ||
1586 | &rockchip_regmap_config); | ||
1543 | } | 1587 | } |
1544 | 1588 | ||
1545 | ret = rockchip_gpiolib_register(pdev, info); | 1589 | ret = rockchip_gpiolib_register(pdev, info); |