diff options
author | Marek Vasut <marek.vasut@gmail.com> | 2010-07-27 21:32:05 -0400 |
---|---|---|
committer | Eric Miao <eric.y.miao@gmail.com> | 2010-08-05 02:32:47 -0400 |
commit | e6a8ef54774fb01f0cf7c6d3679c76a0b60fab3b (patch) | |
tree | 495af67ab5461584fa0655ba45464802464ab75c /arch/arm/mach-pxa/balloon3.c | |
parent | 02a453e4a5a7ca8c8801140f412d327686112e4e (diff) |
[ARM] pxa/balloon3: Add NAND driver
The NAND support is implemented through the gen_nand driver.
Signed-off-by: Marek Vasut <marek.vasut@gmail.com>
Diffstat (limited to 'arch/arm/mach-pxa/balloon3.c')
-rw-r--r-- | arch/arm/mach-pxa/balloon3.c | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/arch/arm/mach-pxa/balloon3.c b/arch/arm/mach-pxa/balloon3.c index 6f594bd410dd..e2eb0b79634e 100644 --- a/arch/arm/mach-pxa/balloon3.c +++ b/arch/arm/mach-pxa/balloon3.c | |||
@@ -27,6 +27,8 @@ | |||
27 | #include <linux/mtd/partitions.h> | 27 | #include <linux/mtd/partitions.h> |
28 | #include <linux/types.h> | 28 | #include <linux/types.h> |
29 | #include <linux/i2c/pcf857x.h> | 29 | #include <linux/i2c/pcf857x.h> |
30 | #include <linux/mtd/nand.h> | ||
31 | #include <linux/mtd/physmap.h> | ||
30 | 32 | ||
31 | #include <asm/setup.h> | 33 | #include <asm/setup.h> |
32 | #include <asm/mach-types.h> | 34 | #include <asm/mach-types.h> |
@@ -530,6 +532,154 @@ static inline void balloon3_i2c_init(void) {} | |||
530 | #endif | 532 | #endif |
531 | 533 | ||
532 | /****************************************************************************** | 534 | /****************************************************************************** |
535 | * NAND | ||
536 | ******************************************************************************/ | ||
537 | #if defined(CONFIG_MTD_NAND_PLATFORM)||defined(CONFIG_MTD_NAND_PLATFORM_MODULE) | ||
538 | static uint16_t balloon3_ctl = | ||
539 | BALLOON3_NAND_CONTROL_FLCE0 | BALLOON3_NAND_CONTROL_FLCE1 | | ||
540 | BALLOON3_NAND_CONTROL_FLCE2 | BALLOON3_NAND_CONTROL_FLCE3 | | ||
541 | BALLOON3_NAND_CONTROL_FLWP; | ||
542 | |||
543 | static void balloon3_nand_cmd_ctl(struct mtd_info *mtd, int cmd, unsigned int ctrl) | ||
544 | { | ||
545 | struct nand_chip *this = mtd->priv; | ||
546 | |||
547 | if (ctrl & NAND_CTRL_CHANGE) { | ||
548 | if (ctrl & NAND_CLE) | ||
549 | balloon3_ctl |= BALLOON3_NAND_CONTROL_FLCLE; | ||
550 | else | ||
551 | balloon3_ctl &= ~BALLOON3_NAND_CONTROL_FLCLE; | ||
552 | |||
553 | if (ctrl & NAND_ALE) | ||
554 | balloon3_ctl |= BALLOON3_NAND_CONTROL_FLALE; | ||
555 | else | ||
556 | balloon3_ctl &= ~BALLOON3_NAND_CONTROL_FLALE; | ||
557 | |||
558 | __raw_writel(balloon3_ctl, BALLOON3_NAND_CONTROL_REG); | ||
559 | } | ||
560 | |||
561 | if (cmd != NAND_CMD_NONE) | ||
562 | writeb(cmd, this->IO_ADDR_W); | ||
563 | } | ||
564 | |||
565 | static void balloon3_nand_select_chip(struct mtd_info *mtd, int chip) | ||
566 | { | ||
567 | if (chip < 0 || chip > 3) | ||
568 | return; | ||
569 | |||
570 | balloon3_ctl |= BALLOON3_NAND_CONTROL_FLCE0 | | ||
571 | BALLOON3_NAND_CONTROL_FLCE1 | | ||
572 | BALLOON3_NAND_CONTROL_FLCE2 | | ||
573 | BALLOON3_NAND_CONTROL_FLCE3; | ||
574 | |||
575 | /* Deassert correct nCE line */ | ||
576 | balloon3_ctl &= ~(BALLOON3_NAND_CONTROL_FLCE0 << chip); | ||
577 | |||
578 | __raw_writew(balloon3_ctl, BALLOON3_NAND_CONTROL_REG); | ||
579 | } | ||
580 | |||
581 | static int balloon3_nand_probe(struct platform_device *pdev) | ||
582 | { | ||
583 | void __iomem *temp_map; | ||
584 | uint16_t ver; | ||
585 | int ret; | ||
586 | |||
587 | __raw_writew(BALLOON3_NAND_CONTROL2_16BIT, BALLOON3_NAND_CONTROL2_REG); | ||
588 | |||
589 | ver = __raw_readw(BALLOON3_FPGA_VER); | ||
590 | if (ver > 0x0201) | ||
591 | pr_warn("The FPGA code, version 0x%04x, is newer than rel-0.3. " | ||
592 | "NAND support might be broken in this version!", ver); | ||
593 | |||
594 | /* Power up the NAND chips */ | ||
595 | ret = gpio_request(BALLOON3_GPIO_RUN_NAND, "NAND"); | ||
596 | if (ret) | ||
597 | goto err1; | ||
598 | |||
599 | ret = gpio_direction_output(BALLOON3_GPIO_RUN_NAND, 1); | ||
600 | if (ret) | ||
601 | goto err2; | ||
602 | |||
603 | gpio_set_value(BALLOON3_GPIO_RUN_NAND, 1); | ||
604 | |||
605 | /* Deassert all nCE lines and write protect line */ | ||
606 | __raw_writel(balloon3_ctl, BALLOON3_NAND_CONTROL_REG); | ||
607 | return 0; | ||
608 | |||
609 | err2: | ||
610 | gpio_free(BALLOON3_GPIO_RUN_NAND); | ||
611 | err1: | ||
612 | return ret; | ||
613 | } | ||
614 | |||
615 | static void balloon3_nand_remove(struct platform_device *pdev) | ||
616 | { | ||
617 | /* Power down the NAND chips */ | ||
618 | gpio_set_value(BALLOON3_GPIO_RUN_NAND, 0); | ||
619 | gpio_free(BALLOON3_GPIO_RUN_NAND); | ||
620 | } | ||
621 | |||
622 | static struct mtd_partition balloon3_partition_info[] = { | ||
623 | [0] = { | ||
624 | .name = "Boot", | ||
625 | .offset = 0, | ||
626 | .size = SZ_4M, | ||
627 | }, | ||
628 | [1] = { | ||
629 | .name = "RootFS", | ||
630 | .offset = MTDPART_OFS_APPEND, | ||
631 | .size = MTDPART_SIZ_FULL | ||
632 | }, | ||
633 | }; | ||
634 | |||
635 | static const char *balloon3_part_probes[] = { "cmdlinepart", NULL }; | ||
636 | |||
637 | struct platform_nand_data balloon3_nand_pdata = { | ||
638 | .chip = { | ||
639 | .nr_chips = 4, | ||
640 | .chip_offset = 0, | ||
641 | .nr_partitions = ARRAY_SIZE(balloon3_partition_info), | ||
642 | .partitions = balloon3_partition_info, | ||
643 | .chip_delay = 50, | ||
644 | .part_probe_types = balloon3_part_probes, | ||
645 | }, | ||
646 | .ctrl = { | ||
647 | .hwcontrol = 0, | ||
648 | .dev_ready = 0, | ||
649 | .select_chip = balloon3_nand_select_chip, | ||
650 | .cmd_ctrl = balloon3_nand_cmd_ctl, | ||
651 | .probe = balloon3_nand_probe, | ||
652 | .remove = balloon3_nand_remove, | ||
653 | }, | ||
654 | }; | ||
655 | |||
656 | static struct resource balloon3_nand_resource[] = { | ||
657 | [0] = { | ||
658 | .start = BALLOON3_NAND_BASE, | ||
659 | .end = BALLOON3_NAND_BASE + 0x4, | ||
660 | .flags = IORESOURCE_MEM, | ||
661 | }, | ||
662 | }; | ||
663 | |||
664 | static struct platform_device balloon3_nand = { | ||
665 | .name = "gen_nand", | ||
666 | .num_resources = ARRAY_SIZE(balloon3_nand_resource), | ||
667 | .resource = balloon3_nand_resource, | ||
668 | .id = -1, | ||
669 | .dev = { | ||
670 | .platform_data = &balloon3_nand_pdata, | ||
671 | } | ||
672 | }; | ||
673 | |||
674 | static void __init balloon3_nand_init(void) | ||
675 | { | ||
676 | platform_device_register(&balloon3_nand); | ||
677 | } | ||
678 | #else | ||
679 | static inline void balloon3_nand_init(void) {} | ||
680 | #endif | ||
681 | |||
682 | /****************************************************************************** | ||
533 | * Machine init | 683 | * Machine init |
534 | ******************************************************************************/ | 684 | ******************************************************************************/ |
535 | static void __init balloon3_init(void) | 685 | static void __init balloon3_init(void) |
@@ -547,6 +697,7 @@ static void __init balloon3_init(void) | |||
547 | balloon3_lcd_init(); | 697 | balloon3_lcd_init(); |
548 | balloon3_leds_init(); | 698 | balloon3_leds_init(); |
549 | balloon3_mmc_init(); | 699 | balloon3_mmc_init(); |
700 | balloon3_nand_init(); | ||
550 | balloon3_nor_init(); | 701 | balloon3_nor_init(); |
551 | balloon3_ts_init(); | 702 | balloon3_ts_init(); |
552 | balloon3_udc_init(); | 703 | balloon3_udc_init(); |