bcm53xx: allow device tree to override SPI flash partition layout
[openwrt.git] / target / linux / bcm53xx / files / drivers / mtd / spi-nor / bcm53xxspiflash.c
1 #include <linux/module.h>
2 #include <linux/delay.h>
3 #include <linux/spi/spi.h>
4 #include <linux/mtd/spi-nor.h>
5 #include <linux/mtd/mtd.h>
6 #include <linux/mtd/cfi.h>
7 #include <linux/mtd/partitions.h>
8
9 static const char * const probes[] = { "ofpart", "bcm47xxpart", NULL };
10
11 struct bcm53xxsf {
12         struct spi_device *spi;
13         struct mtd_info mtd;
14         struct spi_nor nor;
15 };
16
17 /**************************************************
18  * spi-nor API
19  **************************************************/
20
21 static int bcm53xxspiflash_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf,
22                                    int len)
23 {
24         struct bcm53xxsf *b53sf = nor->priv;
25
26         return spi_write_then_read(b53sf->spi, &opcode, 1, buf, len);
27 }
28
29 static int bcm53xxspiflash_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf,
30                                      int len, int write_enable)
31 {
32         struct bcm53xxsf *b53sf = nor->priv;
33         u8 *cmd = kzalloc(len + 1, GFP_KERNEL);
34         int err;
35
36         if (!cmd)
37                 return -ENOMEM;
38
39         cmd[0] = opcode;
40         memcpy(&cmd[1], buf, len);
41         err = spi_write(b53sf->spi, cmd, len + 1);
42
43         kfree(cmd);
44
45         return err;
46 }
47
48 static int bcm53xxspiflash_read(struct spi_nor *nor, loff_t from, size_t len,
49                                 size_t *retlen, u_char *buf)
50 {
51         struct bcm53xxsf *b53sf = nor->priv;
52         struct spi_message m;
53         struct spi_transfer t[2] = { { 0 }, { 0 } };
54         unsigned char cmd[5];
55         int cmd_len = 0;
56         int err;
57
58         spi_message_init(&m);
59
60         cmd[cmd_len++] = SPINOR_OP_READ;
61         if (b53sf->mtd.size > 0x1000000)
62                 cmd[cmd_len++] = (from & 0xFF000000) >> 24;
63         cmd[cmd_len++] = (from & 0x00FF0000) >> 16;
64         cmd[cmd_len++] = (from & 0x0000FF00) >> 8;
65         cmd[cmd_len++] = (from & 0x000000FF) >> 0;
66
67         t[0].tx_buf = cmd;
68         t[0].len = cmd_len;
69         spi_message_add_tail(&t[0], &m);
70
71         t[1].rx_buf = buf;
72         t[1].len = len;
73         spi_message_add_tail(&t[1], &m);
74
75         err = spi_sync(b53sf->spi, &m);
76         if (err)
77                 return err;
78
79         if (retlen && m.actual_length > cmd_len)
80                 *retlen = m.actual_length - cmd_len;
81
82         return 0;
83 }
84
85 static void bcm53xxspiflash_write(struct spi_nor *nor, loff_t to, size_t len,
86                                   size_t *retlen, const u_char *buf)
87 {
88         struct bcm53xxsf *b53sf = nor->priv;
89         struct spi_message m;
90         struct spi_transfer t = { 0 };
91         u8 *cmd = kzalloc(len + 5, GFP_KERNEL);
92         int cmd_len = 0;
93         int err;
94
95         if (!cmd)
96                 return;
97
98         spi_message_init(&m);
99
100         cmd[cmd_len++] = nor->program_opcode;
101         if (b53sf->mtd.size > 0x1000000)
102                 cmd[cmd_len++] = (to & 0xFF000000) >> 24;
103         cmd[cmd_len++] = (to & 0x00FF0000) >> 16;
104         cmd[cmd_len++] = (to & 0x0000FF00) >> 8;
105         cmd[cmd_len++] = (to & 0x000000FF) >> 0;
106         memcpy(&cmd[cmd_len], buf, len);
107
108         t.tx_buf = cmd;
109         t.len = cmd_len + len;
110         spi_message_add_tail(&t, &m);
111
112         err = spi_sync(b53sf->spi, &m);
113         if (err)
114                 goto out;
115
116         if (retlen && m.actual_length > cmd_len)
117                 *retlen += m.actual_length - cmd_len;
118
119 out:
120         kfree(cmd);
121 }
122
123 static int bcm53xxspiflash_erase(struct spi_nor *nor, loff_t offs)
124 {
125         struct bcm53xxsf *b53sf = nor->priv;
126         unsigned char cmd[5];
127         int i;
128
129         i = 0;
130         cmd[i++] = nor->erase_opcode;
131         if (b53sf->mtd.size > 0x1000000)
132                 cmd[i++] = (offs & 0xFF000000) >> 24;
133         cmd[i++] = ((offs & 0x00FF0000) >> 16);
134         cmd[i++] = ((offs & 0x0000FF00) >> 8);
135         cmd[i++] = ((offs & 0x000000FF) >> 0);
136
137         return spi_write(b53sf->spi, cmd, i);
138 }
139
140 static const char *bcm53xxspiflash_chip_name(struct spi_nor *nor)
141 {
142         struct bcm53xxsf *b53sf = nor->priv;
143         struct device *dev = &b53sf->spi->dev;
144         unsigned char cmd[4];
145         unsigned char resp[2];
146         int err;
147
148         /* SST and Winbond/NexFlash specific command */
149         cmd[0] = 0x90; /* Read Manufacturer / Device ID */
150         cmd[1] = 0;
151         cmd[2] = 0;
152         cmd[3] = 0;
153         err = spi_write_then_read(b53sf->spi, cmd, 4, resp, 2);
154         if (err < 0) {
155                 dev_err(dev, "error reading SPI flash id\n");
156                 return ERR_PTR(-EBUSY);
157         }
158         switch (resp[0]) {
159         case 0xef: /* Winbond/NexFlash */
160                 switch (resp[1]) {
161                 case 0x17:
162                         return "w25q128";
163                 }
164                 dev_err(dev, "Unknown Winbond/NexFlash flash: %02X %02X\n",
165                         resp[0], resp[1]);
166                 return NULL;
167         }
168
169         /* TODO: Try more ID commands */
170
171         return NULL;
172 }
173
174 /**************************************************
175  * SPI driver
176  **************************************************/
177
178 static int bcm53xxspiflash_probe(struct spi_device *spi)
179 {
180         struct mtd_part_parser_data parser_data = {};
181         struct bcm53xxsf *b53sf;
182         struct spi_nor *nor;
183         int err;
184
185         b53sf = devm_kzalloc(&spi->dev, sizeof(*b53sf), GFP_KERNEL);
186         if (!b53sf)
187                 return -ENOMEM;
188         spi_set_drvdata(spi, b53sf);
189
190         nor = &b53sf->nor;
191         b53sf->spi = spi;
192         b53sf->mtd.priv = &b53sf->nor;
193
194         nor->mtd = &b53sf->mtd;
195         nor->dev = &spi->dev;
196         nor->read_reg = bcm53xxspiflash_read_reg;
197         nor->write_reg = bcm53xxspiflash_write_reg;
198         nor->read = bcm53xxspiflash_read;
199         nor->write = bcm53xxspiflash_write;
200         nor->erase = bcm53xxspiflash_erase;
201         nor->priv = b53sf;
202
203         err = spi_nor_scan(&b53sf->nor, bcm53xxspiflash_chip_name(nor),
204                            SPI_NOR_NORMAL);
205         if (err)
206                 return err;
207
208         parser_data.of_node = spi->master->dev.parent->of_node;
209         err = mtd_device_parse_register(&b53sf->mtd, probes, &parser_data,
210                                         NULL, 0);
211         if (err)
212                 return err;
213
214         return 0;
215 }
216
217 static int bcm53xxspiflash_remove(struct spi_device *spi)
218 {
219         return 0;
220 }
221
222 static struct spi_driver bcm53xxspiflash_driver = {
223         .driver = {
224                 .name   = "bcm53xxspiflash",
225                 .owner  = THIS_MODULE,
226         },
227         .probe          = bcm53xxspiflash_probe,
228         .remove         = bcm53xxspiflash_remove,
229 };
230
231 module_spi_driver(bcm53xxspiflash_driver);