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