sf: winbond: Add support for W25Q256
[platform/kernel/u-boot.git] / drivers / mtd / spi / winbond.c
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
7 #include <common.h>
8 #include <malloc.h>
9 #include <spi_flash.h>
10
11 #include "spi_flash_internal.h"
12
13 struct winbond_spi_flash_params {
14         uint16_t        id;
15         uint16_t        nr_blocks;
16         const char      *name;
17 };
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                 .id                     = 0x4019,
67                 .nr_blocks              = 512,
68                 .name                   = "W25Q256",
69         },
70         {
71                 .id                     = 0x5014,
72                 .nr_blocks              = 128,
73                 .name                   = "W25Q80",
74         },
75         {
76                 .id                     = 0x6016,
77                 .nr_blocks              = 512,
78                 .name                   = "W25Q32DW",
79         },
80         {
81                 .id                     = 0x6017,
82                 .nr_blocks              = 128,
83                 .name                   = "W25Q64DW",
84         },
85 };
86
87 struct spi_flash *spi_flash_probe_winbond(struct spi_slave *spi, u8 *idcode)
88 {
89         const struct winbond_spi_flash_params *params;
90         struct spi_flash *flash;
91         unsigned int i;
92
93         for (i = 0; i < ARRAY_SIZE(winbond_spi_flash_table); i++) {
94                 params = &winbond_spi_flash_table[i];
95                 if (params->id == ((idcode[1] << 8) | idcode[2]))
96                         break;
97         }
98
99         if (i == ARRAY_SIZE(winbond_spi_flash_table)) {
100                 debug("SF: Unsupported Winbond ID %02x%02x\n",
101                                 idcode[1], idcode[2]);
102                 return NULL;
103         }
104
105         flash = spi_flash_alloc_base(spi, params->name);
106         if (!flash) {
107                 debug("SF: Failed to allocate memory\n");
108                 return NULL;
109         }
110
111         flash->page_size = 256;
112         flash->sector_size = 4096;
113         flash->size = 4096 * 16 * params->nr_blocks;
114
115         return flash;
116 }