]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/mtd/spi/winbond.c
sf: inline data constants
[karo-tx-uboot.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 /* M25Pxx-specific commands */
14 #define CMD_W25_SE              0x20    /* Sector (4K) Erase */
15 #define CMD_W25_BE              0xd8    /* Block (64K) Erase */
16 #define CMD_W25_CE              0xc7    /* Chip Erase */
17
18 struct winbond_spi_flash_params {
19         uint16_t        id;
20         uint16_t        nr_blocks;
21         const char      *name;
22 };
23
24 static const struct winbond_spi_flash_params winbond_spi_flash_table[] = {
25         {
26                 .id                     = 0x3013,
27                 .nr_blocks              = 8,
28                 .name                   = "W25X40",
29         },
30         {
31                 .id                     = 0x3015,
32                 .nr_blocks              = 32,
33                 .name                   = "W25X16",
34         },
35         {
36                 .id                     = 0x3016,
37                 .nr_blocks              = 64,
38                 .name                   = "W25X32",
39         },
40         {
41                 .id                     = 0x3017,
42                 .nr_blocks              = 128,
43                 .name                   = "W25X64",
44         },
45         {
46                 .id                     = 0x4014,
47                 .nr_blocks              = 16,
48                 .name                   = "W25Q80BL",
49         },
50         {
51                 .id                     = 0x4015,
52                 .nr_blocks              = 32,
53                 .name                   = "W25Q16",
54         },
55         {
56                 .id                     = 0x4016,
57                 .nr_blocks              = 64,
58                 .name                   = "W25Q32",
59         },
60         {
61                 .id                     = 0x4017,
62                 .nr_blocks              = 128,
63                 .name                   = "W25Q64",
64         },
65         {
66                 .id                     = 0x4018,
67                 .nr_blocks              = 256,
68                 .name                   = "W25Q128",
69         },
70 };
71
72 static int winbond_erase(struct spi_flash *flash, u32 offset, size_t len)
73 {
74         return spi_flash_cmd_erase(flash, CMD_W25_SE, offset, len);
75 }
76
77 struct spi_flash *spi_flash_probe_winbond(struct spi_slave *spi, u8 *idcode)
78 {
79         const struct winbond_spi_flash_params *params;
80         struct spi_flash *flash;
81         unsigned int i;
82
83         for (i = 0; i < ARRAY_SIZE(winbond_spi_flash_table); i++) {
84                 params = &winbond_spi_flash_table[i];
85                 if (params->id == ((idcode[1] << 8) | idcode[2]))
86                         break;
87         }
88
89         if (i == ARRAY_SIZE(winbond_spi_flash_table)) {
90                 debug("SF: Unsupported Winbond ID %02x%02x\n",
91                                 idcode[1], idcode[2]);
92                 return NULL;
93         }
94
95         flash = malloc(sizeof(*flash));
96         if (!flash) {
97                 debug("SF: Failed to allocate memory\n");
98                 return NULL;
99         }
100
101         flash->spi = spi;
102         flash->name = params->name;
103
104         flash->write = spi_flash_cmd_write_multi;
105         flash->erase = winbond_erase;
106         flash->read = spi_flash_cmd_read_fast;
107         flash->page_size = 4096;
108         flash->sector_size = 4096;
109         flash->size = 4096 * 16 * params->nr_blocks;
110
111         return flash;
112 }