Merge branch 'parisc-5.2-4' of git://git.kernel.org/pub/scm/linux/kernel/git/deller...
[sfrench/cifs-2.6.git] / drivers / mtd / devices / sst25l.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * sst25l.c
4  *
5  * Driver for SST25L SPI Flash chips
6  *
7  * Copyright © 2009 Bluewater Systems Ltd
8  * Author: Andre Renaud <andre@bluewatersys.com>
9  * Author: Ryan Mallon
10  *
11  * Based on m25p80.c
12  */
13
14 #include <linux/module.h>
15 #include <linux/device.h>
16 #include <linux/mutex.h>
17 #include <linux/interrupt.h>
18 #include <linux/slab.h>
19 #include <linux/sched.h>
20
21 #include <linux/mtd/mtd.h>
22 #include <linux/mtd/partitions.h>
23
24 #include <linux/spi/spi.h>
25 #include <linux/spi/flash.h>
26
27 /* Erases can take up to 3 seconds! */
28 #define MAX_READY_WAIT_JIFFIES  msecs_to_jiffies(3000)
29
30 #define SST25L_CMD_WRSR         0x01    /* Write status register */
31 #define SST25L_CMD_WRDI         0x04    /* Write disable */
32 #define SST25L_CMD_RDSR         0x05    /* Read status register */
33 #define SST25L_CMD_WREN         0x06    /* Write enable */
34 #define SST25L_CMD_READ         0x03    /* High speed read */
35
36 #define SST25L_CMD_EWSR         0x50    /* Enable write status register */
37 #define SST25L_CMD_SECTOR_ERASE 0x20    /* Erase sector */
38 #define SST25L_CMD_READ_ID      0x90    /* Read device ID */
39 #define SST25L_CMD_AAI_PROGRAM  0xaf    /* Auto address increment */
40
41 #define SST25L_STATUS_BUSY      (1 << 0)        /* Chip is busy */
42 #define SST25L_STATUS_WREN      (1 << 1)        /* Write enabled */
43 #define SST25L_STATUS_BP0       (1 << 2)        /* Block protection 0 */
44 #define SST25L_STATUS_BP1       (1 << 3)        /* Block protection 1 */
45
46 struct sst25l_flash {
47         struct spi_device       *spi;
48         struct mutex            lock;
49         struct mtd_info         mtd;
50 };
51
52 struct flash_info {
53         const char              *name;
54         uint16_t                device_id;
55         unsigned                page_size;
56         unsigned                nr_pages;
57         unsigned                erase_size;
58 };
59
60 #define to_sst25l_flash(x) container_of(x, struct sst25l_flash, mtd)
61
62 static struct flash_info sst25l_flash_info[] = {
63         {"sst25lf020a", 0xbf43, 256, 1024, 4096},
64         {"sst25lf040a", 0xbf44, 256, 2048, 4096},
65 };
66
67 static int sst25l_status(struct sst25l_flash *flash, int *status)
68 {
69         struct spi_message m;
70         struct spi_transfer t;
71         unsigned char cmd_resp[2];
72         int err;
73
74         spi_message_init(&m);
75         memset(&t, 0, sizeof(struct spi_transfer));
76
77         cmd_resp[0] = SST25L_CMD_RDSR;
78         cmd_resp[1] = 0xff;
79         t.tx_buf = cmd_resp;
80         t.rx_buf = cmd_resp;
81         t.len = sizeof(cmd_resp);
82         spi_message_add_tail(&t, &m);
83         err = spi_sync(flash->spi, &m);
84         if (err < 0)
85                 return err;
86
87         *status = cmd_resp[1];
88         return 0;
89 }
90
91 static int sst25l_write_enable(struct sst25l_flash *flash, int enable)
92 {
93         unsigned char command[2];
94         int status, err;
95
96         command[0] = enable ? SST25L_CMD_WREN : SST25L_CMD_WRDI;
97         err = spi_write(flash->spi, command, 1);
98         if (err)
99                 return err;
100
101         command[0] = SST25L_CMD_EWSR;
102         err = spi_write(flash->spi, command, 1);
103         if (err)
104                 return err;
105
106         command[0] = SST25L_CMD_WRSR;
107         command[1] = enable ? 0 : SST25L_STATUS_BP0 | SST25L_STATUS_BP1;
108         err = spi_write(flash->spi, command, 2);
109         if (err)
110                 return err;
111
112         if (enable) {
113                 err = sst25l_status(flash, &status);
114                 if (err)
115                         return err;
116                 if (!(status & SST25L_STATUS_WREN))
117                         return -EROFS;
118         }
119
120         return 0;
121 }
122
123 static int sst25l_wait_till_ready(struct sst25l_flash *flash)
124 {
125         unsigned long deadline;
126         int status, err;
127
128         deadline = jiffies + MAX_READY_WAIT_JIFFIES;
129         do {
130                 err = sst25l_status(flash, &status);
131                 if (err)
132                         return err;
133                 if (!(status & SST25L_STATUS_BUSY))
134                         return 0;
135
136                 cond_resched();
137         } while (!time_after_eq(jiffies, deadline));
138
139         return -ETIMEDOUT;
140 }
141
142 static int sst25l_erase_sector(struct sst25l_flash *flash, uint32_t offset)
143 {
144         unsigned char command[4];
145         int err;
146
147         err = sst25l_write_enable(flash, 1);
148         if (err)
149                 return err;
150
151         command[0] = SST25L_CMD_SECTOR_ERASE;
152         command[1] = offset >> 16;
153         command[2] = offset >> 8;
154         command[3] = offset;
155         err = spi_write(flash->spi, command, 4);
156         if (err)
157                 return err;
158
159         err = sst25l_wait_till_ready(flash);
160         if (err)
161                 return err;
162
163         return sst25l_write_enable(flash, 0);
164 }
165
166 static int sst25l_erase(struct mtd_info *mtd, struct erase_info *instr)
167 {
168         struct sst25l_flash *flash = to_sst25l_flash(mtd);
169         uint32_t addr, end;
170         int err;
171
172         /* Sanity checks */
173         if ((uint32_t)instr->len % mtd->erasesize)
174                 return -EINVAL;
175
176         if ((uint32_t)instr->addr % mtd->erasesize)
177                 return -EINVAL;
178
179         addr = instr->addr;
180         end = addr + instr->len;
181
182         mutex_lock(&flash->lock);
183
184         err = sst25l_wait_till_ready(flash);
185         if (err) {
186                 mutex_unlock(&flash->lock);
187                 return err;
188         }
189
190         while (addr < end) {
191                 err = sst25l_erase_sector(flash, addr);
192                 if (err) {
193                         mutex_unlock(&flash->lock);
194                         dev_err(&flash->spi->dev, "Erase failed\n");
195                         return err;
196                 }
197
198                 addr += mtd->erasesize;
199         }
200
201         mutex_unlock(&flash->lock);
202
203         return 0;
204 }
205
206 static int sst25l_read(struct mtd_info *mtd, loff_t from, size_t len,
207                        size_t *retlen, unsigned char *buf)
208 {
209         struct sst25l_flash *flash = to_sst25l_flash(mtd);
210         struct spi_transfer transfer[2];
211         struct spi_message message;
212         unsigned char command[4];
213         int ret;
214
215         spi_message_init(&message);
216         memset(&transfer, 0, sizeof(transfer));
217
218         command[0] = SST25L_CMD_READ;
219         command[1] = from >> 16;
220         command[2] = from >> 8;
221         command[3] = from;
222
223         transfer[0].tx_buf = command;
224         transfer[0].len = sizeof(command);
225         spi_message_add_tail(&transfer[0], &message);
226
227         transfer[1].rx_buf = buf;
228         transfer[1].len = len;
229         spi_message_add_tail(&transfer[1], &message);
230
231         mutex_lock(&flash->lock);
232
233         /* Wait for previous write/erase to complete */
234         ret = sst25l_wait_till_ready(flash);
235         if (ret) {
236                 mutex_unlock(&flash->lock);
237                 return ret;
238         }
239
240         spi_sync(flash->spi, &message);
241
242         if (retlen && message.actual_length > sizeof(command))
243                 *retlen += message.actual_length - sizeof(command);
244
245         mutex_unlock(&flash->lock);
246         return 0;
247 }
248
249 static int sst25l_write(struct mtd_info *mtd, loff_t to, size_t len,
250                         size_t *retlen, const unsigned char *buf)
251 {
252         struct sst25l_flash *flash = to_sst25l_flash(mtd);
253         int i, j, ret, bytes, copied = 0;
254         unsigned char command[5];
255
256         if ((uint32_t)to % mtd->writesize)
257                 return -EINVAL;
258
259         mutex_lock(&flash->lock);
260
261         ret = sst25l_write_enable(flash, 1);
262         if (ret)
263                 goto out;
264
265         for (i = 0; i < len; i += mtd->writesize) {
266                 ret = sst25l_wait_till_ready(flash);
267                 if (ret)
268                         goto out;
269
270                 /* Write the first byte of the page */
271                 command[0] = SST25L_CMD_AAI_PROGRAM;
272                 command[1] = (to + i) >> 16;
273                 command[2] = (to + i) >> 8;
274                 command[3] = (to + i);
275                 command[4] = buf[i];
276                 ret = spi_write(flash->spi, command, 5);
277                 if (ret < 0)
278                         goto out;
279                 copied++;
280
281                 /*
282                  * Write the remaining bytes using auto address
283                  * increment mode
284                  */
285                 bytes = min_t(uint32_t, mtd->writesize, len - i);
286                 for (j = 1; j < bytes; j++, copied++) {
287                         ret = sst25l_wait_till_ready(flash);
288                         if (ret)
289                                 goto out;
290
291                         command[1] = buf[i + j];
292                         ret = spi_write(flash->spi, command, 2);
293                         if (ret)
294                                 goto out;
295                 }
296         }
297
298 out:
299         ret = sst25l_write_enable(flash, 0);
300
301         if (retlen)
302                 *retlen = copied;
303
304         mutex_unlock(&flash->lock);
305         return ret;
306 }
307
308 static struct flash_info *sst25l_match_device(struct spi_device *spi)
309 {
310         struct flash_info *flash_info = NULL;
311         struct spi_message m;
312         struct spi_transfer t;
313         unsigned char cmd_resp[6];
314         int i, err;
315         uint16_t id;
316
317         spi_message_init(&m);
318         memset(&t, 0, sizeof(struct spi_transfer));
319
320         cmd_resp[0] = SST25L_CMD_READ_ID;
321         cmd_resp[1] = 0;
322         cmd_resp[2] = 0;
323         cmd_resp[3] = 0;
324         cmd_resp[4] = 0xff;
325         cmd_resp[5] = 0xff;
326         t.tx_buf = cmd_resp;
327         t.rx_buf = cmd_resp;
328         t.len = sizeof(cmd_resp);
329         spi_message_add_tail(&t, &m);
330         err = spi_sync(spi, &m);
331         if (err < 0) {
332                 dev_err(&spi->dev, "error reading device id\n");
333                 return NULL;
334         }
335
336         id = (cmd_resp[4] << 8) | cmd_resp[5];
337
338         for (i = 0; i < ARRAY_SIZE(sst25l_flash_info); i++)
339                 if (sst25l_flash_info[i].device_id == id)
340                         flash_info = &sst25l_flash_info[i];
341
342         if (!flash_info)
343                 dev_err(&spi->dev, "unknown id %.4x\n", id);
344
345         return flash_info;
346 }
347
348 static int sst25l_probe(struct spi_device *spi)
349 {
350         struct flash_info *flash_info;
351         struct sst25l_flash *flash;
352         struct flash_platform_data *data;
353         int ret;
354
355         flash_info = sst25l_match_device(spi);
356         if (!flash_info)
357                 return -ENODEV;
358
359         flash = devm_kzalloc(&spi->dev, sizeof(*flash), GFP_KERNEL);
360         if (!flash)
361                 return -ENOMEM;
362
363         flash->spi = spi;
364         mutex_init(&flash->lock);
365         spi_set_drvdata(spi, flash);
366
367         data = dev_get_platdata(&spi->dev);
368         if (data && data->name)
369                 flash->mtd.name = data->name;
370
371         flash->mtd.dev.parent   = &spi->dev;
372         flash->mtd.type         = MTD_NORFLASH;
373         flash->mtd.flags        = MTD_CAP_NORFLASH;
374         flash->mtd.erasesize    = flash_info->erase_size;
375         flash->mtd.writesize    = flash_info->page_size;
376         flash->mtd.writebufsize = flash_info->page_size;
377         flash->mtd.size         = flash_info->page_size * flash_info->nr_pages;
378         flash->mtd._erase       = sst25l_erase;
379         flash->mtd._read                = sst25l_read;
380         flash->mtd._write       = sst25l_write;
381
382         dev_info(&spi->dev, "%s (%lld KiB)\n", flash_info->name,
383                  (long long)flash->mtd.size >> 10);
384
385         pr_debug("mtd .name = %s, .size = 0x%llx (%lldMiB) "
386               ".erasesize = 0x%.8x (%uKiB) .numeraseregions = %d\n",
387               flash->mtd.name,
388               (long long)flash->mtd.size, (long long)(flash->mtd.size >> 20),
389               flash->mtd.erasesize, flash->mtd.erasesize / 1024,
390               flash->mtd.numeraseregions);
391
392
393         ret = mtd_device_register(&flash->mtd, data ? data->parts : NULL,
394                                   data ? data->nr_parts : 0);
395         if (ret)
396                 return -ENODEV;
397
398         return 0;
399 }
400
401 static int sst25l_remove(struct spi_device *spi)
402 {
403         struct sst25l_flash *flash = spi_get_drvdata(spi);
404
405         return mtd_device_unregister(&flash->mtd);
406 }
407
408 static struct spi_driver sst25l_driver = {
409         .driver = {
410                 .name   = "sst25l",
411         },
412         .probe          = sst25l_probe,
413         .remove         = sst25l_remove,
414 };
415
416 module_spi_driver(sst25l_driver);
417
418 MODULE_DESCRIPTION("MTD SPI driver for SST25L Flash chips");
419 MODULE_AUTHOR("Andre Renaud <andre@bluewatersys.com>, "
420               "Ryan Mallon");
421 MODULE_LICENSE("GPL");