aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl/pinctrl-rockchip.c
diff options
context:
space:
mode:
authorHeiko Stübner <heiko@sntech.de>2013-10-15 19:07:20 -0400
committerLinus Walleij <linus.walleij@linaro.org>2013-10-16 09:33:52 -0400
commita282926d658209ed1acee51a1ccc897ac169fb41 (patch)
tree6b3427284d79b04f8be6a0b700205931577a1437 /drivers/pinctrl/pinctrl-rockchip.c
parent6d0a4ed2b90a12e1403d3e7d9d8c2cc7fdc301b5 (diff)
pinctrl: rockchip: separate different sub-types more
Further investigation of the different Rockchip SoCs showed that the differences especially in the pull settings are quite deep. As further patches will show, the register layout for the pulls of the rk3188 is quite strange. Also it is to assume, that later Rockchip SoCs may introduce even more quirks in this regard, making it hard to support all of those using the current generic pull_* variables. Therefore move the driver to hold the type of controller in an enum and do the handling according to it in the necessary places. Also instead of calculating the register in the get and set pull functions move it to a type-specific callback. Signed-off-by: Heiko Stuebner <heiko@sntech.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.c105
1 files changed, 57 insertions, 48 deletions
diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
index e0718b7c4abc..df155f9b2432 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
@@ -56,6 +56,12 @@
56#define GPIO_EXT_PORT 0x50 56#define GPIO_EXT_PORT 0x50
57#define GPIO_LS_SYNC 0x60 57#define GPIO_LS_SYNC 0x60
58 58
59enum rockchip_pinctrl_type {
60 RK2928,
61 RK3066B,
62 RK3188,
63};
64
59/** 65/**
60 * @reg_base: register base of the gpio bank 66 * @reg_base: register base of the gpio bank
61 * @clk: clock of the gpio bank 67 * @clk: clock of the gpio bank
@@ -98,18 +104,16 @@ struct rockchip_pin_bank {
98 } 104 }
99 105
100/** 106/**
101 * @pull_auto: some SoCs don't allow pulls to be specified as up or down, but
102 * instead decide this automatically based on the pad-type.
103 */ 107 */
104struct rockchip_pin_ctrl { 108struct rockchip_pin_ctrl {
105 struct rockchip_pin_bank *pin_banks; 109 struct rockchip_pin_bank *pin_banks;
106 u32 nr_banks; 110 u32 nr_banks;
107 u32 nr_pins; 111 u32 nr_pins;
108 char *label; 112 char *label;
113 enum rockchip_pinctrl_type type;
109 int mux_offset; 114 int mux_offset;
110 int pull_offset; 115 void (*pull_calc_reg)(struct rockchip_pin_bank *bank, int pin_num,
111 bool pull_auto; 116 void __iomem **reg, u8 *bit);
112 int pull_bank_stride;
113}; 117};
114 118
115struct rockchip_pin_config { 119struct rockchip_pin_config {
@@ -354,6 +358,22 @@ static void rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
354 spin_unlock_irqrestore(&bank->slock, flags); 358 spin_unlock_irqrestore(&bank->slock, flags);
355} 359}
356 360
361#define RK2928_PULL_OFFSET 0x118
362#define RK2928_PULL_PINS_PER_REG 16
363#define RK2928_PULL_BANK_STRIDE 8
364
365static void rk2928_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
366 int pin_num, void __iomem **reg, u8 *bit)
367{
368 struct rockchip_pinctrl *info = bank->drvdata;
369
370 *reg = info->reg_base + RK2928_PULL_OFFSET;
371 *reg += bank->bank_num * RK2928_PULL_BANK_STRIDE;
372 *reg += (pin_num / RK2928_PULL_PINS_PER_REG) * 4;
373
374 *bit = pin_num % RK2928_PULL_PINS_PER_REG;
375};
376
357static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num) 377static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num)
358{ 378{
359 struct rockchip_pinctrl *info = bank->drvdata; 379 struct rockchip_pinctrl *info = bank->drvdata;
@@ -362,23 +382,22 @@ static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num)
362 u8 bit; 382 u8 bit;
363 383
364 /* rk3066b does support any pulls */ 384 /* rk3066b does support any pulls */
365 if (!ctrl->pull_offset) 385 if (ctrl->type == RK3066B)
366 return PIN_CONFIG_BIAS_DISABLE; 386 return PIN_CONFIG_BIAS_DISABLE;
367 387
368 reg = info->reg_base + ctrl->pull_offset; 388 switch (ctrl->type) {
369 389 case RK2928:
370 if (ctrl->pull_auto) { 390 ctrl->pull_calc_reg(bank, pin_num, &reg, &bit);
371 reg += bank->bank_num * ctrl->pull_bank_stride;
372 reg += (pin_num / 16) * 4;
373 bit = pin_num % 16;
374
375 return !(readl_relaxed(reg) & BIT(bit)) 391 return !(readl_relaxed(reg) & BIT(bit))
376 ? PIN_CONFIG_BIAS_PULL_PIN_DEFAULT 392 ? PIN_CONFIG_BIAS_PULL_PIN_DEFAULT
377 : PIN_CONFIG_BIAS_DISABLE; 393 : PIN_CONFIG_BIAS_DISABLE;
378 } else { 394 case RK3188:
379 dev_err(info->dev, "pull support for rk31xx not implemented\n"); 395 dev_err(info->dev, "pull support for rk31xx not implemented\n");
380 return -EIO; 396 return -EIO;
381 } 397 default:
398 dev_err(info->dev, "unsupported pinctrl type\n");
399 return -EINVAL;
400 };
382} 401}
383 402
384static int rockchip_set_pull(struct rockchip_pin_bank *bank, 403static int rockchip_set_pull(struct rockchip_pin_bank *bank,
@@ -395,21 +414,18 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank,
395 bank->bank_num, pin_num, pull); 414 bank->bank_num, pin_num, pull);
396 415
397 /* rk3066b does support any pulls */ 416 /* rk3066b does support any pulls */
398 if (!ctrl->pull_offset) 417 if (ctrl->type == RK3066B)
399 return pull ? -EINVAL : 0; 418 return pull ? -EINVAL : 0;
400 419
401 reg = info->reg_base + ctrl->pull_offset; 420 switch (ctrl->type) {
402 421 case RK2928:
403 if (ctrl->pull_auto) {
404 if (pull != PIN_CONFIG_BIAS_PULL_PIN_DEFAULT && 422 if (pull != PIN_CONFIG_BIAS_PULL_PIN_DEFAULT &&
405 pull != PIN_CONFIG_BIAS_DISABLE) { 423 pull != PIN_CONFIG_BIAS_DISABLE) {
406 dev_err(info->dev, "only PIN_DEFAULT and DISABLE allowed\n"); 424 dev_err(info->dev, "only PIN_DEFAULT and DISABLE allowed\n");
407 return -EINVAL; 425 return -EINVAL;
408 } 426 }
409 427
410 reg += bank->bank_num * ctrl->pull_bank_stride; 428 ctrl->pull_calc_reg(bank, pin_num, &reg, &bit);
411 reg += (pin_num / 16) * 4;
412 bit = pin_num % 16;
413 429
414 spin_lock_irqsave(&bank->slock, flags); 430 spin_lock_irqsave(&bank->slock, flags);
415 431
@@ -419,14 +435,13 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank,
419 writel(data, reg); 435 writel(data, reg);
420 436
421 spin_unlock_irqrestore(&bank->slock, flags); 437 spin_unlock_irqrestore(&bank->slock, flags);
422 } else { 438 break;
423 if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT) { 439 case RK3188:
424 dev_err(info->dev, "pull direction (up/down) needs to be specified\n");
425 return -EINVAL;
426 }
427
428 dev_err(info->dev, "pull support for rk31xx not implemented\n"); 440 dev_err(info->dev, "pull support for rk31xx not implemented\n");
429 return -EIO; 441 return -EIO;
442 default:
443 dev_err(info->dev, "unsupported pinctrl type\n");
444 return -EINVAL;
430 } 445 }
431 446
432 return 0; 447 return 0;
@@ -556,20 +571,17 @@ static const struct pinmux_ops rockchip_pmx_ops = {
556static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl, 571static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl,
557 enum pin_config_param pull) 572 enum pin_config_param pull)
558{ 573{
559 /* rk3066b does support any pulls */ 574 switch (ctrl->type) {
560 if (!ctrl->pull_offset) 575 case RK2928:
576 return (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT ||
577 pull == PIN_CONFIG_BIAS_DISABLE);
578 case RK3066B:
561 return pull ? false : true; 579 return pull ? false : true;
562 580 case RK3188:
563 if (ctrl->pull_auto) { 581 return (pull != PIN_CONFIG_BIAS_PULL_PIN_DEFAULT);
564 if (pull != PIN_CONFIG_BIAS_PULL_PIN_DEFAULT &&
565 pull != PIN_CONFIG_BIAS_DISABLE)
566 return false;
567 } else {
568 if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT)
569 return false;
570 } 582 }
571 583
572 return true; 584 return false;
573} 585}
574 586
575/* set the pin config settings for a specified pin */ 587/* set the pin config settings for a specified pin */
@@ -1315,10 +1327,9 @@ static struct rockchip_pin_ctrl rk2928_pin_ctrl = {
1315 .pin_banks = rk2928_pin_banks, 1327 .pin_banks = rk2928_pin_banks,
1316 .nr_banks = ARRAY_SIZE(rk2928_pin_banks), 1328 .nr_banks = ARRAY_SIZE(rk2928_pin_banks),
1317 .label = "RK2928-GPIO", 1329 .label = "RK2928-GPIO",
1330 .type = RK2928,
1318 .mux_offset = 0xa8, 1331 .mux_offset = 0xa8,
1319 .pull_offset = 0x118, 1332 .pull_calc_reg = rk2928_calc_pull_reg_and_bit,
1320 .pull_auto = 1,
1321 .pull_bank_stride = 8,
1322}; 1333};
1323 1334
1324static struct rockchip_pin_bank rk3066a_pin_banks[] = { 1335static struct rockchip_pin_bank rk3066a_pin_banks[] = {
@@ -1334,10 +1345,9 @@ static struct rockchip_pin_ctrl rk3066a_pin_ctrl = {
1334 .pin_banks = rk3066a_pin_banks, 1345 .pin_banks = rk3066a_pin_banks,
1335 .nr_banks = ARRAY_SIZE(rk3066a_pin_banks), 1346 .nr_banks = ARRAY_SIZE(rk3066a_pin_banks),
1336 .label = "RK3066a-GPIO", 1347 .label = "RK3066a-GPIO",
1348 .type = RK2928,
1337 .mux_offset = 0xa8, 1349 .mux_offset = 0xa8,
1338 .pull_offset = 0x118, 1350 .pull_calc_reg = rk2928_calc_pull_reg_and_bit,
1339 .pull_auto = 1,
1340 .pull_bank_stride = 8,
1341}; 1351};
1342 1352
1343static struct rockchip_pin_bank rk3066b_pin_banks[] = { 1353static struct rockchip_pin_bank rk3066b_pin_banks[] = {
@@ -1351,8 +1361,8 @@ static struct rockchip_pin_ctrl rk3066b_pin_ctrl = {
1351 .pin_banks = rk3066b_pin_banks, 1361 .pin_banks = rk3066b_pin_banks,
1352 .nr_banks = ARRAY_SIZE(rk3066b_pin_banks), 1362 .nr_banks = ARRAY_SIZE(rk3066b_pin_banks),
1353 .label = "RK3066b-GPIO", 1363 .label = "RK3066b-GPIO",
1364 .type = RK3066B,
1354 .mux_offset = 0x60, 1365 .mux_offset = 0x60,
1355 .pull_offset = -EINVAL,
1356}; 1366};
1357 1367
1358static struct rockchip_pin_bank rk3188_pin_banks[] = { 1368static struct rockchip_pin_bank rk3188_pin_banks[] = {
@@ -1366,9 +1376,8 @@ static struct rockchip_pin_ctrl rk3188_pin_ctrl = {
1366 .pin_banks = rk3188_pin_banks, 1376 .pin_banks = rk3188_pin_banks,
1367 .nr_banks = ARRAY_SIZE(rk3188_pin_banks), 1377 .nr_banks = ARRAY_SIZE(rk3188_pin_banks),
1368 .label = "RK3188-GPIO", 1378 .label = "RK3188-GPIO",
1379 .type = RK3188,
1369 .mux_offset = 0x68, 1380 .mux_offset = 0x68,
1370 .pull_offset = 0x164,
1371 .pull_bank_stride = 16,
1372}; 1381};
1373 1382
1374static const struct of_device_id rockchip_pinctrl_dt_match[] = { 1383static const struct of_device_id rockchip_pinctrl_dt_match[] = {