diff options
author | Russell King <rmk@dyn-67.arm.linux.org.uk> | 2008-08-07 04:55:03 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2008-08-07 04:55:03 -0400 |
commit | 4fb8af10d0fd09372d52966b76922b9e82bbc950 (patch) | |
tree | d240e4d40357583e3f3eb228dccf20122a5b31ed /drivers/mtd/devices/mtd_dataflash.c | |
parent | f44f82e8a20b98558486eb14497b2f71c78fa325 (diff) | |
parent | 64a99d2a8c3ed5c4e39f3ae1cc682aa8fd3977fc (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/sam/kbuild-fixes
Diffstat (limited to 'drivers/mtd/devices/mtd_dataflash.c')
-rw-r--r-- | drivers/mtd/devices/mtd_dataflash.c | 130 |
1 files changed, 83 insertions, 47 deletions
diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c index 54e36bfc2c3b..8bd0dea6885f 100644 --- a/drivers/mtd/devices/mtd_dataflash.c +++ b/drivers/mtd/devices/mtd_dataflash.c | |||
@@ -15,6 +15,8 @@ | |||
15 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
16 | #include <linux/device.h> | 16 | #include <linux/device.h> |
17 | #include <linux/mutex.h> | 17 | #include <linux/mutex.h> |
18 | #include <linux/err.h> | ||
19 | |||
18 | #include <linux/spi/spi.h> | 20 | #include <linux/spi/spi.h> |
19 | #include <linux/spi/flash.h> | 21 | #include <linux/spi/flash.h> |
20 | 22 | ||
@@ -487,9 +489,8 @@ add_dataflash(struct spi_device *spi, char *name, | |||
487 | device->write = dataflash_write; | 489 | device->write = dataflash_write; |
488 | device->priv = priv; | 490 | device->priv = priv; |
489 | 491 | ||
490 | dev_info(&spi->dev, "%s (%d KBytes) pagesize %d bytes, " | 492 | dev_info(&spi->dev, "%s (%d KBytes) pagesize %d bytes\n", |
491 | "erasesize %d bytes\n", name, device->size/1024, | 493 | name, DIV_ROUND_UP(device->size, 1024), pagesize); |
492 | pagesize, pagesize * 8); /* 8 pages = 1 block */ | ||
493 | dev_set_drvdata(&spi->dev, priv); | 494 | dev_set_drvdata(&spi->dev, priv); |
494 | 495 | ||
495 | if (mtd_has_partitions()) { | 496 | if (mtd_has_partitions()) { |
@@ -518,65 +519,57 @@ add_dataflash(struct spi_device *spi, char *name, | |||
518 | return add_mtd_device(device) == 1 ? -ENODEV : 0; | 519 | return add_mtd_device(device) == 1 ? -ENODEV : 0; |
519 | } | 520 | } |
520 | 521 | ||
521 | /* | ||
522 | * Detect and initialize DataFlash device: | ||
523 | * | ||
524 | * Device Density ID code #Pages PageSize Offset | ||
525 | * AT45DB011B 1Mbit (128K) xx0011xx (0x0c) 512 264 9 | ||
526 | * AT45DB021B 2Mbit (256K) xx0101xx (0x14) 1024 264 9 | ||
527 | * AT45DB041B 4Mbit (512K) xx0111xx (0x1c) 2048 264 9 | ||
528 | * AT45DB081B 8Mbit (1M) xx1001xx (0x24) 4096 264 9 | ||
529 | * AT45DB0161B 16Mbit (2M) xx1011xx (0x2c) 4096 528 10 | ||
530 | * AT45DB0321B 32Mbit (4M) xx1101xx (0x34) 8192 528 10 | ||
531 | * AT45DB0642 64Mbit (8M) xx111xxx (0x3c) 8192 1056 11 | ||
532 | * AT45DB1282 128Mbit (16M) xx0100xx (0x10) 16384 1056 11 | ||
533 | */ | ||
534 | |||
535 | struct flash_info { | 522 | struct flash_info { |
536 | char *name; | 523 | char *name; |
537 | 524 | ||
538 | /* JEDEC id zero means "no ID" (most older chips); otherwise it has | 525 | /* JEDEC id has a high byte of zero plus three data bytes: |
539 | * a high byte of zero plus three data bytes: the manufacturer id, | 526 | * the manufacturer id, then a two byte device id. |
540 | * then a two byte device id. | ||
541 | */ | 527 | */ |
542 | uint32_t jedec_id; | 528 | uint32_t jedec_id; |
543 | 529 | ||
544 | /* The size listed here is what works with OPCODE_SE, which isn't | 530 | /* The size listed here is what works with OP_ERASE_PAGE. */ |
545 | * necessarily called a "sector" by the vendor. | ||
546 | */ | ||
547 | unsigned nr_pages; | 531 | unsigned nr_pages; |
548 | uint16_t pagesize; | 532 | uint16_t pagesize; |
549 | uint16_t pageoffset; | 533 | uint16_t pageoffset; |
550 | 534 | ||
551 | uint16_t flags; | 535 | uint16_t flags; |
552 | #define SUP_POW2PS 0x02 | 536 | #define SUP_POW2PS 0x0002 /* supports 2^N byte pages */ |
553 | #define IS_POW2PS 0x01 | 537 | #define IS_POW2PS 0x0001 /* uses 2^N byte pages */ |
554 | }; | 538 | }; |
555 | 539 | ||
556 | static struct flash_info __devinitdata dataflash_data [] = { | 540 | static struct flash_info __devinitdata dataflash_data [] = { |
557 | 541 | ||
558 | { "at45db011d", 0x1f2200, 512, 264, 9, SUP_POW2PS}, | 542 | /* |
543 | * NOTE: chips with SUP_POW2PS (rev D and up) need two entries, | ||
544 | * one with IS_POW2PS and the other without. The entry with the | ||
545 | * non-2^N byte page size can't name exact chip revisions without | ||
546 | * losing backwards compatibility for cmdlinepart. | ||
547 | * | ||
548 | * These newer chips also support 128-byte security registers (with | ||
549 | * 64 bytes one-time-programmable) and software write-protection. | ||
550 | */ | ||
551 | { "AT45DB011B", 0x1f2200, 512, 264, 9, SUP_POW2PS}, | ||
559 | { "at45db011d", 0x1f2200, 512, 256, 8, SUP_POW2PS | IS_POW2PS}, | 552 | { "at45db011d", 0x1f2200, 512, 256, 8, SUP_POW2PS | IS_POW2PS}, |
560 | 553 | ||
561 | { "at45db021d", 0x1f2300, 1024, 264, 9, SUP_POW2PS}, | 554 | { "AT45DB021B", 0x1f2300, 1024, 264, 9, SUP_POW2PS}, |
562 | { "at45db021d", 0x1f2300, 1024, 256, 8, SUP_POW2PS | IS_POW2PS}, | 555 | { "at45db021d", 0x1f2300, 1024, 256, 8, SUP_POW2PS | IS_POW2PS}, |
563 | 556 | ||
564 | { "at45db041d", 0x1f2400, 2048, 264, 9, SUP_POW2PS}, | 557 | { "AT45DB041x", 0x1f2400, 2048, 264, 9, SUP_POW2PS}, |
565 | { "at45db041d", 0x1f2400, 2048, 256, 8, SUP_POW2PS | IS_POW2PS}, | 558 | { "at45db041d", 0x1f2400, 2048, 256, 8, SUP_POW2PS | IS_POW2PS}, |
566 | 559 | ||
567 | { "at45db081d", 0x1f2500, 4096, 264, 9, SUP_POW2PS}, | 560 | { "AT45DB081B", 0x1f2500, 4096, 264, 9, SUP_POW2PS}, |
568 | { "at45db081d", 0x1f2500, 4096, 256, 8, SUP_POW2PS | IS_POW2PS}, | 561 | { "at45db081d", 0x1f2500, 4096, 256, 8, SUP_POW2PS | IS_POW2PS}, |
569 | 562 | ||
570 | { "at45db161d", 0x1f2600, 4096, 528, 10, SUP_POW2PS}, | 563 | { "AT45DB161x", 0x1f2600, 4096, 528, 10, SUP_POW2PS}, |
571 | { "at45db161d", 0x1f2600, 4096, 512, 9, SUP_POW2PS | IS_POW2PS}, | 564 | { "at45db161d", 0x1f2600, 4096, 512, 9, SUP_POW2PS | IS_POW2PS}, |
572 | 565 | ||
573 | { "at45db321c", 0x1f2700, 8192, 528, 10, }, | 566 | { "AT45DB321x", 0x1f2700, 8192, 528, 10, 0}, /* rev C */ |
574 | 567 | ||
575 | { "at45db321d", 0x1f2701, 8192, 528, 10, SUP_POW2PS}, | 568 | { "AT45DB321x", 0x1f2701, 8192, 528, 10, SUP_POW2PS}, |
576 | { "at45db321d", 0x1f2701, 8192, 512, 9, SUP_POW2PS | IS_POW2PS}, | 569 | { "at45db321d", 0x1f2701, 8192, 512, 9, SUP_POW2PS | IS_POW2PS}, |
577 | 570 | ||
578 | { "at45db641d", 0x1f2800, 8192, 1056, 11, SUP_POW2PS}, | 571 | { "AT45DB642x", 0x1f2800, 8192, 1056, 11, SUP_POW2PS}, |
579 | { "at45db641d", 0x1f2800, 8192, 1024, 10, SUP_POW2PS | IS_POW2PS}, | 572 | { "at45db642d", 0x1f2800, 8192, 1024, 10, SUP_POW2PS | IS_POW2PS}, |
580 | }; | 573 | }; |
581 | 574 | ||
582 | static struct flash_info *__devinit jedec_probe(struct spi_device *spi) | 575 | static struct flash_info *__devinit jedec_probe(struct spi_device *spi) |
@@ -588,17 +581,23 @@ static struct flash_info *__devinit jedec_probe(struct spi_device *spi) | |||
588 | struct flash_info *info; | 581 | struct flash_info *info; |
589 | int status; | 582 | int status; |
590 | 583 | ||
591 | |||
592 | /* JEDEC also defines an optional "extended device information" | 584 | /* JEDEC also defines an optional "extended device information" |
593 | * string for after vendor-specific data, after the three bytes | 585 | * string for after vendor-specific data, after the three bytes |
594 | * we use here. Supporting some chips might require using it. | 586 | * we use here. Supporting some chips might require using it. |
587 | * | ||
588 | * If the vendor ID isn't Atmel's (0x1f), assume this call failed. | ||
589 | * That's not an error; only rev C and newer chips handle it, and | ||
590 | * only Atmel sells these chips. | ||
595 | */ | 591 | */ |
596 | tmp = spi_write_then_read(spi, &code, 1, id, 3); | 592 | tmp = spi_write_then_read(spi, &code, 1, id, 3); |
597 | if (tmp < 0) { | 593 | if (tmp < 0) { |
598 | DEBUG(MTD_DEBUG_LEVEL0, "%s: error %d reading JEDEC ID\n", | 594 | DEBUG(MTD_DEBUG_LEVEL0, "%s: error %d reading JEDEC ID\n", |
599 | spi->dev.bus_id, tmp); | 595 | spi->dev.bus_id, tmp); |
600 | return NULL; | 596 | return ERR_PTR(tmp); |
601 | } | 597 | } |
598 | if (id[0] != 0x1f) | ||
599 | return NULL; | ||
600 | |||
602 | jedec = id[0]; | 601 | jedec = id[0]; |
603 | jedec = jedec << 8; | 602 | jedec = jedec << 8; |
604 | jedec |= id[1]; | 603 | jedec |= id[1]; |
@@ -609,19 +608,53 @@ static struct flash_info *__devinit jedec_probe(struct spi_device *spi) | |||
609 | tmp < ARRAY_SIZE(dataflash_data); | 608 | tmp < ARRAY_SIZE(dataflash_data); |
610 | tmp++, info++) { | 609 | tmp++, info++) { |
611 | if (info->jedec_id == jedec) { | 610 | if (info->jedec_id == jedec) { |
611 | DEBUG(MTD_DEBUG_LEVEL1, "%s: OTP, sector protect%s\n", | ||
612 | dev_name(&spi->dev), | ||
613 | (info->flags & SUP_POW2PS) | ||
614 | ? ", binary pagesize" : "" | ||
615 | ); | ||
612 | if (info->flags & SUP_POW2PS) { | 616 | if (info->flags & SUP_POW2PS) { |
613 | status = dataflash_status(spi); | 617 | status = dataflash_status(spi); |
614 | if (status & 0x1) | 618 | if (status < 0) { |
615 | /* return power of 2 pagesize */ | 619 | DEBUG(MTD_DEBUG_LEVEL1, |
616 | return ++info; | 620 | "%s: status error %d\n", |
617 | else | 621 | dev_name(&spi->dev), status); |
618 | return info; | 622 | return ERR_PTR(status); |
623 | } | ||
624 | if (status & 0x1) { | ||
625 | if (info->flags & IS_POW2PS) | ||
626 | return info; | ||
627 | } else { | ||
628 | if (!(info->flags & IS_POW2PS)) | ||
629 | return info; | ||
630 | } | ||
619 | } | 631 | } |
620 | } | 632 | } |
621 | } | 633 | } |
622 | return NULL; | 634 | |
635 | /* | ||
636 | * Treat other chips as errors ... we won't know the right page | ||
637 | * size (it might be binary) even when we can tell which density | ||
638 | * class is involved (legacy chip id scheme). | ||
639 | */ | ||
640 | dev_warn(&spi->dev, "JEDEC id %06x not handled\n", jedec); | ||
641 | return ERR_PTR(-ENODEV); | ||
623 | } | 642 | } |
624 | 643 | ||
644 | /* | ||
645 | * Detect and initialize DataFlash device, using JEDEC IDs on newer chips | ||
646 | * or else the ID code embedded in the status bits: | ||
647 | * | ||
648 | * Device Density ID code #Pages PageSize Offset | ||
649 | * AT45DB011B 1Mbit (128K) xx0011xx (0x0c) 512 264 9 | ||
650 | * AT45DB021B 2Mbit (256K) xx0101xx (0x14) 1024 264 9 | ||
651 | * AT45DB041B 4Mbit (512K) xx0111xx (0x1c) 2048 264 9 | ||
652 | * AT45DB081B 8Mbit (1M) xx1001xx (0x24) 4096 264 9 | ||
653 | * AT45DB0161B 16Mbit (2M) xx1011xx (0x2c) 4096 528 10 | ||
654 | * AT45DB0321B 32Mbit (4M) xx1101xx (0x34) 8192 528 10 | ||
655 | * AT45DB0642 64Mbit (8M) xx111xxx (0x3c) 8192 1056 11 | ||
656 | * AT45DB1282 128Mbit (16M) xx0100xx (0x10) 16384 1056 11 | ||
657 | */ | ||
625 | static int __devinit dataflash_probe(struct spi_device *spi) | 658 | static int __devinit dataflash_probe(struct spi_device *spi) |
626 | { | 659 | { |
627 | int status; | 660 | int status; |
@@ -632,14 +665,17 @@ static int __devinit dataflash_probe(struct spi_device *spi) | |||
632 | * If it succeeds we know we have either a C or D part. | 665 | * If it succeeds we know we have either a C or D part. |
633 | * D will support power of 2 pagesize option. | 666 | * D will support power of 2 pagesize option. |
634 | */ | 667 | */ |
635 | |||
636 | info = jedec_probe(spi); | 668 | info = jedec_probe(spi); |
637 | 669 | if (IS_ERR(info)) | |
670 | return PTR_ERR(info); | ||
638 | if (info != NULL) | 671 | if (info != NULL) |
639 | return add_dataflash(spi, info->name, info->nr_pages, | 672 | return add_dataflash(spi, info->name, info->nr_pages, |
640 | info->pagesize, info->pageoffset); | 673 | info->pagesize, info->pageoffset); |
641 | 674 | ||
642 | 675 | /* | |
676 | * Older chips support only legacy commands, identifing | ||
677 | * capacity using bits in the status byte. | ||
678 | */ | ||
643 | status = dataflash_status(spi); | 679 | status = dataflash_status(spi); |
644 | if (status <= 0 || status == 0xff) { | 680 | if (status <= 0 || status == 0xff) { |
645 | DEBUG(MTD_DEBUG_LEVEL1, "%s: status error %d\n", | 681 | DEBUG(MTD_DEBUG_LEVEL1, "%s: status error %d\n", |
@@ -661,13 +697,13 @@ static int __devinit dataflash_probe(struct spi_device *spi) | |||
661 | status = add_dataflash(spi, "AT45DB021B", 1024, 264, 9); | 697 | status = add_dataflash(spi, "AT45DB021B", 1024, 264, 9); |
662 | break; | 698 | break; |
663 | case 0x1c: /* 0 1 1 1 x x */ | 699 | case 0x1c: /* 0 1 1 1 x x */ |
664 | status = add_dataflash(spi, "AT45DB041B", 2048, 264, 9); | 700 | status = add_dataflash(spi, "AT45DB041x", 2048, 264, 9); |
665 | break; | 701 | break; |
666 | case 0x24: /* 1 0 0 1 x x */ | 702 | case 0x24: /* 1 0 0 1 x x */ |
667 | status = add_dataflash(spi, "AT45DB081B", 4096, 264, 9); | 703 | status = add_dataflash(spi, "AT45DB081B", 4096, 264, 9); |
668 | break; | 704 | break; |
669 | case 0x2c: /* 1 0 1 1 x x */ | 705 | case 0x2c: /* 1 0 1 1 x x */ |
670 | status = add_dataflash(spi, "AT45DB161B", 4096, 528, 10); | 706 | status = add_dataflash(spi, "AT45DB161x", 4096, 528, 10); |
671 | break; | 707 | break; |
672 | case 0x34: /* 1 1 0 1 x x */ | 708 | case 0x34: /* 1 1 0 1 x x */ |
673 | status = add_dataflash(spi, "AT45DB321x", 8192, 528, 10); | 709 | status = add_dataflash(spi, "AT45DB321x", 8192, 528, 10); |