diff options
-rw-r--r-- | drivers/pinctrl/pinctrl-rockchip.c | 105 |
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 | ||
59 | enum 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 | */ |
104 | struct rockchip_pin_ctrl { | 108 | struct 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 | ||
115 | struct rockchip_pin_config { | 119 | struct 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 | |||
365 | static 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 | |||
357 | static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num) | 377 | static 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, ®, &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 | ||
384 | static int rockchip_set_pull(struct rockchip_pin_bank *bank, | 403 | static 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, ®, &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 = { | |||
556 | static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl, | 571 | static 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 | ||
1324 | static struct rockchip_pin_bank rk3066a_pin_banks[] = { | 1335 | static 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 | ||
1343 | static struct rockchip_pin_bank rk3066b_pin_banks[] = { | 1353 | static 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 | ||
1358 | static struct rockchip_pin_bank rk3188_pin_banks[] = { | 1368 | static 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 | ||
1374 | static const struct of_device_id rockchip_pinctrl_dt_match[] = { | 1383 | static const struct of_device_id rockchip_pinctrl_dt_match[] = { |