winbond.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. /*
  2. * Copyright 2008, Network Appliance Inc.
  3. * Author: Jason McMullan <mcmullan <at> netapp.com>
  4. * Licensed under the GPL-2 or later.
  5. */
  6. #include <common.h>
  7. #include <malloc.h>
  8. #include <spi_flash.h>
  9. #include "spi_flash_internal.h"
  10. /* M25Pxx-specific commands */
  11. #define CMD_W25_SE 0x20 /* Sector (4K) Erase */
  12. #define CMD_W25_BE 0xd8 /* Block (64K) Erase */
  13. #define CMD_W25_CE 0xc7 /* Chip Erase */
  14. struct winbond_spi_flash_params {
  15. uint16_t id;
  16. uint16_t nr_blocks;
  17. const char *name;
  18. };
  19. static const struct winbond_spi_flash_params winbond_spi_flash_table[] = {
  20. {
  21. .id = 0x3013,
  22. .nr_blocks = 8,
  23. .name = "W25X40",
  24. },
  25. {
  26. .id = 0x3015,
  27. .nr_blocks = 32,
  28. .name = "W25X16",
  29. },
  30. {
  31. .id = 0x3016,
  32. .nr_blocks = 64,
  33. .name = "W25X32",
  34. },
  35. {
  36. .id = 0x3017,
  37. .nr_blocks = 128,
  38. .name = "W25X64",
  39. },
  40. {
  41. .id = 0x4014,
  42. .nr_blocks = 16,
  43. .name = "W25Q80BL",
  44. },
  45. {
  46. .id = 0x4015,
  47. .nr_blocks = 32,
  48. .name = "W25Q16",
  49. },
  50. {
  51. .id = 0x4016,
  52. .nr_blocks = 64,
  53. .name = "W25Q32",
  54. },
  55. {
  56. .id = 0x4017,
  57. .nr_blocks = 128,
  58. .name = "W25Q64",
  59. },
  60. {
  61. .id = 0x4018,
  62. .nr_blocks = 256,
  63. .name = "W25Q128",
  64. },
  65. };
  66. static int winbond_erase(struct spi_flash *flash, u32 offset, size_t len)
  67. {
  68. return spi_flash_cmd_erase(flash, CMD_W25_SE, offset, len);
  69. }
  70. struct spi_flash *spi_flash_probe_winbond(struct spi_slave *spi, u8 *idcode)
  71. {
  72. const struct winbond_spi_flash_params *params;
  73. struct spi_flash *flash;
  74. unsigned int i;
  75. for (i = 0; i < ARRAY_SIZE(winbond_spi_flash_table); i++) {
  76. params = &winbond_spi_flash_table[i];
  77. if (params->id == ((idcode[1] << 8) | idcode[2]))
  78. break;
  79. }
  80. if (i == ARRAY_SIZE(winbond_spi_flash_table)) {
  81. debug("SF: Unsupported Winbond ID %02x%02x\n",
  82. idcode[1], idcode[2]);
  83. return NULL;
  84. }
  85. flash = malloc(sizeof(*flash));
  86. if (!flash) {
  87. debug("SF: Failed to allocate memory\n");
  88. return NULL;
  89. }
  90. flash->spi = spi;
  91. flash->name = params->name;
  92. flash->write = spi_flash_cmd_write_multi;
  93. flash->erase = winbond_erase;
  94. flash->read = spi_flash_cmd_read_fast;
  95. flash->page_size = 4096;
  96. flash->sector_size = 4096;
  97. flash->size = 4096 * 16 * params->nr_blocks;
  98. return flash;
  99. }