diff options
| author | Guennadi Liakhovetski <g.liakhovetski@gmx.de> | 2012-06-28 06:29:46 -0400 |
|---|---|---|
| committer | Paul Mundt <lethal@linux-sh.org> | 2012-06-28 10:16:56 -0400 |
| commit | d4c191dfb9190880644c1542a21c9deda5c76151 (patch) | |
| tree | aba4eca60a0a7f516b9a82ecaa94b81ba46c2eab /arch | |
| parent | 67ef578699ff42aa772d797bffae1f9e25c254c5 (diff) | |
sh: ecovec: switch MMC power control to regulators
Power on the CN11 and CN12 SD/MMC slots on ecovec is controlled by GPIOs,
which makes it possible to use the fixed voltage regulator driver to switch
card power on and off.
Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch')
| -rw-r--r-- | arch/sh/boards/mach-ecovec24/setup.c | 117 |
1 files changed, 100 insertions, 17 deletions
diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c index 4158d70c0dea..a06c5c8a14a8 100644 --- a/arch/sh/boards/mach-ecovec24/setup.c +++ b/arch/sh/boards/mach-ecovec24/setup.c | |||
| @@ -19,6 +19,8 @@ | |||
| 19 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
| 20 | #include <linux/io.h> | 20 | #include <linux/io.h> |
| 21 | #include <linux/delay.h> | 21 | #include <linux/delay.h> |
| 22 | #include <linux/regulator/fixed.h> | ||
| 23 | #include <linux/regulator/machine.h> | ||
| 22 | #include <linux/usb/r8a66597.h> | 24 | #include <linux/usb/r8a66597.h> |
| 23 | #include <linux/usb/renesas_usbhs.h> | 25 | #include <linux/usb/renesas_usbhs.h> |
| 24 | #include <linux/i2c.h> | 26 | #include <linux/i2c.h> |
| @@ -518,10 +520,86 @@ static struct i2c_board_info ts_i2c_clients = { | |||
| 518 | .irq = IRQ0, | 520 | .irq = IRQ0, |
| 519 | }; | 521 | }; |
| 520 | 522 | ||
| 523 | static struct regulator_consumer_supply cn12_power_consumers[] = | ||
| 524 | { | ||
| 525 | REGULATOR_SUPPLY("vmmc", "sh_mmcif.0"), | ||
| 526 | REGULATOR_SUPPLY("vqmmc", "sh_mmcif.0"), | ||
| 527 | REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.1"), | ||
| 528 | REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.1"), | ||
| 529 | }; | ||
| 530 | |||
| 531 | static struct regulator_init_data cn12_power_init_data = { | ||
| 532 | .constraints = { | ||
| 533 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | ||
| 534 | }, | ||
| 535 | .num_consumer_supplies = ARRAY_SIZE(cn12_power_consumers), | ||
| 536 | .consumer_supplies = cn12_power_consumers, | ||
| 537 | }; | ||
| 538 | |||
| 539 | static struct fixed_voltage_config cn12_power_info = { | ||
| 540 | .supply_name = "CN12 SD/MMC Vdd", | ||
| 541 | .microvolts = 3300000, | ||
| 542 | .gpio = GPIO_PTB7, | ||
| 543 | .enable_high = 1, | ||
| 544 | .init_data = &cn12_power_init_data, | ||
| 545 | }; | ||
| 546 | |||
| 547 | static struct platform_device cn12_power = { | ||
| 548 | .name = "reg-fixed-voltage", | ||
| 549 | .id = 0, | ||
| 550 | .dev = { | ||
| 551 | .platform_data = &cn12_power_info, | ||
| 552 | }, | ||
| 553 | }; | ||
| 554 | |||
| 521 | #if defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE) | 555 | #if defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE) |
| 522 | /* SDHI0 */ | 556 | /* SDHI0 */ |
| 557 | static struct regulator_consumer_supply sdhi0_power_consumers[] = | ||
| 558 | { | ||
| 559 | REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"), | ||
| 560 | REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.0"), | ||
| 561 | }; | ||
| 562 | |||
| 563 | static struct regulator_init_data sdhi0_power_init_data = { | ||
| 564 | .constraints = { | ||
| 565 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | ||
| 566 | }, | ||
| 567 | .num_consumer_supplies = ARRAY_SIZE(sdhi0_power_consumers), | ||
| 568 | .consumer_supplies = sdhi0_power_consumers, | ||
| 569 | }; | ||
| 570 | |||
| 571 | static struct fixed_voltage_config sdhi0_power_info = { | ||
| 572 | .supply_name = "CN11 SD/MMC Vdd", | ||
| 573 | .microvolts = 3300000, | ||
| 574 | .gpio = GPIO_PTB6, | ||
| 575 | .enable_high = 1, | ||
| 576 | .init_data = &sdhi0_power_init_data, | ||
| 577 | }; | ||
| 578 | |||
| 579 | static struct platform_device sdhi0_power = { | ||
| 580 | .name = "reg-fixed-voltage", | ||
| 581 | .id = 1, | ||
| 582 | .dev = { | ||
| 583 | .platform_data = &sdhi0_power_info, | ||
| 584 | }, | ||
| 585 | }; | ||
| 586 | |||
| 523 | static void sdhi0_set_pwr(struct platform_device *pdev, int state) | 587 | static void sdhi0_set_pwr(struct platform_device *pdev, int state) |
| 524 | { | 588 | { |
| 589 | static int power_gpio = -EINVAL; | ||
| 590 | |||
| 591 | if (power_gpio < 0) { | ||
| 592 | int ret = gpio_request(GPIO_PTB6, NULL); | ||
| 593 | if (!ret) { | ||
| 594 | power_gpio = GPIO_PTB6; | ||
| 595 | gpio_direction_output(power_gpio, 0); | ||
| 596 | } | ||
| 597 | } | ||
| 598 | |||
| 599 | /* | ||
| 600 | * Toggle the GPIO regardless, whether we managed to grab it above or | ||
| 601 | * the fixed regulator driver did. | ||
| 602 | */ | ||
| 525 | gpio_set_value(GPIO_PTB6, state); | 603 | gpio_set_value(GPIO_PTB6, state); |
| 526 | } | 604 | } |
| 527 | 605 | ||
| @@ -562,13 +640,27 @@ static struct platform_device sdhi0_device = { | |||
| 562 | }, | 640 | }, |
| 563 | }; | 641 | }; |
| 564 | 642 | ||
| 565 | #if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE) | 643 | static void cn12_set_pwr(struct platform_device *pdev, int state) |
| 566 | /* SDHI1 */ | ||
| 567 | static void sdhi1_set_pwr(struct platform_device *pdev, int state) | ||
| 568 | { | 644 | { |
| 645 | static int power_gpio = -EINVAL; | ||
| 646 | |||
| 647 | if (power_gpio < 0) { | ||
| 648 | int ret = gpio_request(GPIO_PTB7, NULL); | ||
| 649 | if (!ret) { | ||
| 650 | power_gpio = GPIO_PTB7; | ||
| 651 | gpio_direction_output(power_gpio, 0); | ||
| 652 | } | ||
| 653 | } | ||
| 654 | |||
| 655 | /* | ||
| 656 | * Toggle the GPIO regardless, whether we managed to grab it above or | ||
| 657 | * the fixed regulator driver did. | ||
| 658 | */ | ||
| 569 | gpio_set_value(GPIO_PTB7, state); | 659 | gpio_set_value(GPIO_PTB7, state); |
| 570 | } | 660 | } |
| 571 | 661 | ||
| 662 | #if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE) | ||
| 663 | /* SDHI1 */ | ||
| 572 | static int sdhi1_get_cd(struct platform_device *pdev) | 664 | static int sdhi1_get_cd(struct platform_device *pdev) |
| 573 | { | 665 | { |
| 574 | return !gpio_get_value(GPIO_PTW7); | 666 | return !gpio_get_value(GPIO_PTW7); |
| @@ -579,7 +671,7 @@ static struct sh_mobile_sdhi_info sdhi1_info = { | |||
| 579 | .dma_slave_rx = SHDMA_SLAVE_SDHI1_RX, | 671 | .dma_slave_rx = SHDMA_SLAVE_SDHI1_RX, |
| 580 | .tmio_caps = MMC_CAP_SDIO_IRQ | MMC_CAP_POWER_OFF_CARD | | 672 | .tmio_caps = MMC_CAP_SDIO_IRQ | MMC_CAP_POWER_OFF_CARD | |
| 581 | MMC_CAP_NEEDS_POLL, | 673 | MMC_CAP_NEEDS_POLL, |
| 582 | .set_pwr = sdhi1_set_pwr, | 674 | .set_pwr = cn12_set_pwr, |
| 583 | .get_cd = sdhi1_get_cd, | 675 | .get_cd = sdhi1_get_cd, |
| 584 | }; | 676 | }; |
| 585 | 677 | ||
| @@ -899,14 +991,9 @@ static struct platform_device vou_device = { | |||
| 899 | 991 | ||
| 900 | #if defined(CONFIG_MMC_SH_MMCIF) || defined(CONFIG_MMC_SH_MMCIF_MODULE) | 992 | #if defined(CONFIG_MMC_SH_MMCIF) || defined(CONFIG_MMC_SH_MMCIF_MODULE) |
| 901 | /* SH_MMCIF */ | 993 | /* SH_MMCIF */ |
| 902 | static void mmcif_set_pwr(struct platform_device *pdev, int state) | ||
| 903 | { | ||
| 904 | gpio_set_value(GPIO_PTB7, state); | ||
| 905 | } | ||
| 906 | |||
| 907 | static void mmcif_down_pwr(struct platform_device *pdev) | 994 | static void mmcif_down_pwr(struct platform_device *pdev) |
| 908 | { | 995 | { |
| 909 | gpio_set_value(GPIO_PTB7, 0); | 996 | cn12_set_pwr(pdev, 0); |
| 910 | } | 997 | } |
| 911 | 998 | ||
| 912 | static struct resource sh_mmcif_resources[] = { | 999 | static struct resource sh_mmcif_resources[] = { |
| @@ -929,7 +1016,7 @@ static struct resource sh_mmcif_resources[] = { | |||
| 929 | }; | 1016 | }; |
| 930 | 1017 | ||
| 931 | static struct sh_mmcif_plat_data sh_mmcif_plat = { | 1018 | static struct sh_mmcif_plat_data sh_mmcif_plat = { |
| 932 | .set_pwr = mmcif_set_pwr, | 1019 | .set_pwr = cn12_set_pwr, |
| 933 | .down_pwr = mmcif_down_pwr, | 1020 | .down_pwr = mmcif_down_pwr, |
| 934 | .sup_pclk = 0, /* SH7724: Max Pclk/2 */ | 1021 | .sup_pclk = 0, /* SH7724: Max Pclk/2 */ |
| 935 | .caps = MMC_CAP_4_BIT_DATA | | 1022 | .caps = MMC_CAP_4_BIT_DATA | |
| @@ -960,7 +1047,9 @@ static struct platform_device *ecovec_devices[] __initdata = { | |||
| 960 | &ceu0_device, | 1047 | &ceu0_device, |
| 961 | &ceu1_device, | 1048 | &ceu1_device, |
| 962 | &keysc_device, | 1049 | &keysc_device, |
| 1050 | &cn12_power, | ||
| 963 | #if defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE) | 1051 | #if defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE) |
| 1052 | &sdhi0_power, | ||
| 964 | &sdhi0_device, | 1053 | &sdhi0_device, |
| 965 | #if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE) | 1054 | #if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE) |
| 966 | &sdhi1_device, | 1055 | &sdhi1_device, |
| @@ -1258,8 +1347,6 @@ static int __init arch_setup(void) | |||
| 1258 | gpio_request(GPIO_FN_SDHI0D2, NULL); | 1347 | gpio_request(GPIO_FN_SDHI0D2, NULL); |
| 1259 | gpio_request(GPIO_FN_SDHI0D1, NULL); | 1348 | gpio_request(GPIO_FN_SDHI0D1, NULL); |
| 1260 | gpio_request(GPIO_FN_SDHI0D0, NULL); | 1349 | gpio_request(GPIO_FN_SDHI0D0, NULL); |
| 1261 | gpio_request(GPIO_PTB6, NULL); | ||
| 1262 | gpio_direction_output(GPIO_PTB6, 0); | ||
| 1263 | #else | 1350 | #else |
| 1264 | /* enable MSIOF0 on CN11 (needs DS2.4 set to OFF) */ | 1351 | /* enable MSIOF0 on CN11 (needs DS2.4 set to OFF) */ |
| 1265 | gpio_request(GPIO_FN_MSIOF0_TXD, NULL); | 1352 | gpio_request(GPIO_FN_MSIOF0_TXD, NULL); |
| @@ -1288,8 +1375,6 @@ static int __init arch_setup(void) | |||
| 1288 | gpio_request(GPIO_FN_MMC_D0, NULL); | 1375 | gpio_request(GPIO_FN_MMC_D0, NULL); |
| 1289 | gpio_request(GPIO_FN_MMC_CLK, NULL); | 1376 | gpio_request(GPIO_FN_MMC_CLK, NULL); |
| 1290 | gpio_request(GPIO_FN_MMC_CMD, NULL); | 1377 | gpio_request(GPIO_FN_MMC_CMD, NULL); |
| 1291 | gpio_request(GPIO_PTB7, NULL); | ||
| 1292 | gpio_direction_output(GPIO_PTB7, 0); | ||
| 1293 | 1378 | ||
| 1294 | cn12_enabled = true; | 1379 | cn12_enabled = true; |
| 1295 | #elif defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE) | 1380 | #elif defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE) |
| @@ -1301,8 +1386,6 @@ static int __init arch_setup(void) | |||
| 1301 | gpio_request(GPIO_FN_SDHI1D2, NULL); | 1386 | gpio_request(GPIO_FN_SDHI1D2, NULL); |
| 1302 | gpio_request(GPIO_FN_SDHI1D1, NULL); | 1387 | gpio_request(GPIO_FN_SDHI1D1, NULL); |
| 1303 | gpio_request(GPIO_FN_SDHI1D0, NULL); | 1388 | gpio_request(GPIO_FN_SDHI1D0, NULL); |
| 1304 | gpio_request(GPIO_PTB7, NULL); | ||
| 1305 | gpio_direction_output(GPIO_PTB7, 0); | ||
| 1306 | 1389 | ||
| 1307 | /* Card-detect, used on CN12 with SDHI1 */ | 1390 | /* Card-detect, used on CN12 with SDHI1 */ |
| 1308 | gpio_request(GPIO_PTW7, NULL); | 1391 | gpio_request(GPIO_PTW7, NULL); |
