aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl/pinctrl-rockchip.c
diff options
context:
space:
mode:
authorHeiko Stübner <heiko@sntech.de>2014-05-05 07:58:20 -0400
committerLinus Walleij <linus.walleij@linaro.org>2014-05-09 05:14:15 -0400
commit751a99aba47e9bd30b4fd5bf36f4e0143d3e81bb (patch)
tree95c7daf3598570c2f157a91cb6fa86f89ea7baa9 /drivers/pinctrl/pinctrl-rockchip.c
parentbfc7a42a0e74f0b589a017679620d2a3edda9198 (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.c116
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 */
87struct rockchip_pin_bank { 88struct 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
127struct rockchip_pin_config { 129struct rockchip_pin_config {
@@ -159,9 +161,9 @@ struct rockchip_pmx_func {
159}; 161};
160 162
161struct rockchip_pinctrl { 163struct 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
177static struct regmap_config rockchip_regmap_config = {
178 .reg_bits = 32,
179 .val_bits = 32,
180 .reg_stride = 4,
181};
182
175static inline struct rockchip_pin_bank *gc_to_pin_bank(struct gpio_chip *gc) 183static 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 = {
333static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin) 341static 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)
363static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) 377static 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
408static void rk2928_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 423static 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
425static void rk3188_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 442static 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, &reg, &bit); 488 ctrl->pull_calc_reg(bank, pin_num, &regmap, &reg, &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, &reg, &bit); 540 ctrl->pull_calc_reg(bank, pin_num, &regmap, &reg, &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);