1 /* 2 * sst25l.c 3 * 4 * Driver for SST25L SPI Flash chips 5 * 6 * Copyright © 2009 Bluewater Systems Ltd 7 * Author: Andre Renaud <andre@bluewatersys.com> 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; 59 uint16_t device_id; 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 (instr->addr + instr->len > flash->mtd.size) 179 return -EINVAL; 180 181 if ((uint32_t)instr->len % mtd->erasesize) 182 return -EINVAL; 183 184 if ((uint32_t)instr->addr % mtd->erasesize) 185 return -EINVAL; 186 187 addr = instr->addr; 188 end = addr + instr->len; 189 190 mutex_lock(&flash->lock); 191 192 err = sst25l_wait_till_ready(flash); 193 if (err) { 194 mutex_unlock(&flash->lock); 195 return err; 196 } 197 198 while (addr < end) { 199 err = sst25l_erase_sector(flash, addr); 200 if (err) { 201 mutex_unlock(&flash->lock); 202 instr->state = MTD_ERASE_FAILED; 203 dev_err(&flash->spi->dev, "Erase failed\n"); 204 return err; 205 } 206 207 addr += mtd->erasesize; 208 } 209 210 mutex_unlock(&flash->lock); 211 212 instr->state = MTD_ERASE_DONE; 213 mtd_erase_callback(instr); 214 return 0; 215 } 216 217 static int sst25l_read(struct mtd_info *mtd, loff_t from, size_t len, 218 size_t *retlen, unsigned char *buf) 219 { 220 struct sst25l_flash *flash = to_sst25l_flash(mtd); 221 struct spi_transfer transfer[2]; 222 struct spi_message message; 223 unsigned char command[4]; 224 int ret; 225 226 /* Sanity checking */ 227 if (len == 0) 228 return 0; 229 230 if (from + len > flash->mtd.size) 231 return -EINVAL; 232 233 if (retlen) 234 *retlen = 0; 235 236 spi_message_init(&message); 237 memset(&transfer, 0, sizeof(transfer)); 238 239 command[0] = SST25L_CMD_READ; 240 command[1] = from >> 16; 241 command[2] = from >> 8; 242 command[3] = from; 243 244 transfer[0].tx_buf = command; 245 transfer[0].len = sizeof(command); 246 spi_message_add_tail(&transfer[0], &message); 247 248 transfer[1].rx_buf = buf; 249 transfer[1].len = len; 250 spi_message_add_tail(&transfer[1], &message); 251 252 mutex_lock(&flash->lock); 253 254 /* Wait for previous write/erase to complete */ 255 ret = sst25l_wait_till_ready(flash); 256 if (ret) { 257 mutex_unlock(&flash->lock); 258 return ret; 259 } 260 261 spi_sync(flash->spi, &message); 262 263 if (retlen && message.actual_length > sizeof(command)) 264 *retlen += message.actual_length - sizeof(command); 265 266 mutex_unlock(&flash->lock); 267 return 0; 268 } 269 270 static int sst25l_write(struct mtd_info *mtd, loff_t to, size_t len, 271 size_t *retlen, const unsigned char *buf) 272 { 273 struct sst25l_flash *flash = to_sst25l_flash(mtd); 274 int i, j, ret, bytes, copied = 0; 275 unsigned char command[5]; 276 277 /* Sanity checks */ 278 if (!len) 279 return 0; 280 281 if (to + len > flash->mtd.size) 282 return -EINVAL; 283 284 if ((uint32_t)to % mtd->writesize) 285 return -EINVAL; 286 287 mutex_lock(&flash->lock); 288 289 ret = sst25l_write_enable(flash, 1); 290 if (ret) 291 goto out; 292 293 for (i = 0; i < len; i += mtd->writesize) { 294 ret = sst25l_wait_till_ready(flash); 295 if (ret) 296 goto out; 297 298 /* Write the first byte of the page */ 299 command[0] = SST25L_CMD_AAI_PROGRAM; 300 command[1] = (to + i) >> 16; 301 command[2] = (to + i) >> 8; 302 command[3] = (to + i); 303 command[4] = buf[i]; 304 ret = spi_write(flash->spi, command, 5); 305 if (ret < 0) 306 goto out; 307 copied++; 308 309 /* 310 * Write the remaining bytes using auto address 311 * increment mode 312 */ 313 bytes = min_t(uint32_t, mtd->writesize, len - i); 314 for (j = 1; j < bytes; j++, copied++) { 315 ret = sst25l_wait_till_ready(flash); 316 if (ret) 317 goto out; 318 319 command[1] = buf[i + j]; 320 ret = spi_write(flash->spi, command, 2); 321 if (ret) 322 goto out; 323 } 324 } 325 326 out: 327 ret = sst25l_write_enable(flash, 0); 328 329 if (retlen) 330 *retlen = copied; 331 332 mutex_unlock(&flash->lock); 333 return ret; 334 } 335 336 static struct flash_info *__devinit sst25l_match_device(struct spi_device *spi) 337 { 338 struct flash_info *flash_info = NULL; 339 struct spi_message m; 340 struct spi_transfer t; 341 unsigned char cmd_resp[6]; 342 int i, err; 343 uint16_t id; 344 345 spi_message_init(&m); 346 memset(&t, 0, sizeof(struct spi_transfer)); 347 348 cmd_resp[0] = SST25L_CMD_READ_ID; 349 cmd_resp[1] = 0; 350 cmd_resp[2] = 0; 351 cmd_resp[3] = 0; 352 cmd_resp[4] = 0xff; 353 cmd_resp[5] = 0xff; 354 t.tx_buf = cmd_resp; 355 t.rx_buf = cmd_resp; 356 t.len = sizeof(cmd_resp); 357 spi_message_add_tail(&t, &m); 358 err = spi_sync(spi, &m); 359 if (err < 0) { 360 dev_err(&spi->dev, "error reading device id\n"); 361 return NULL; 362 } 363 364 id = (cmd_resp[4] << 8) | cmd_resp[5]; 365 366 for (i = 0; i < ARRAY_SIZE(sst25l_flash_info); i++) 367 if (sst25l_flash_info[i].device_id == id) 368 flash_info = &sst25l_flash_info[i]; 369 370 if (!flash_info) 371 dev_err(&spi->dev, "unknown id %.4x\n", id); 372 373 return flash_info; 374 } 375 376 static int __devinit sst25l_probe(struct spi_device *spi) 377 { 378 struct flash_info *flash_info; 379 struct sst25l_flash *flash; 380 struct flash_platform_data *data; 381 int ret; 382 383 flash_info = sst25l_match_device(spi); 384 if (!flash_info) 385 return -ENODEV; 386 387 flash = kzalloc(sizeof(struct sst25l_flash), GFP_KERNEL); 388 if (!flash) 389 return -ENOMEM; 390 391 flash->spi = spi; 392 mutex_init(&flash->lock); 393 dev_set_drvdata(&spi->dev, flash); 394 395 data = spi->dev.platform_data; 396 if (data && data->name) 397 flash->mtd.name = data->name; 398 else 399 flash->mtd.name = dev_name(&spi->dev); 400 401 flash->mtd.type = MTD_NORFLASH; 402 flash->mtd.flags = MTD_CAP_NORFLASH; 403 flash->mtd.erasesize = flash_info->erase_size; 404 flash->mtd.writesize = flash_info->page_size; 405 flash->mtd.size = flash_info->page_size * flash_info->nr_pages; 406 flash->mtd.erase = sst25l_erase; 407 flash->mtd.read = sst25l_read; 408 flash->mtd.write = sst25l_write; 409 410 dev_info(&spi->dev, "%s (%lld KiB)\n", flash_info->name, 411 (long long)flash->mtd.size >> 10); 412 413 pr_debug("mtd .name = %s, .size = 0x%llx (%lldMiB) " 414 ".erasesize = 0x%.8x (%uKiB) .numeraseregions = %d\n", 415 flash->mtd.name, 416 (long long)flash->mtd.size, (long long)(flash->mtd.size >> 20), 417 flash->mtd.erasesize, flash->mtd.erasesize / 1024, 418 flash->mtd.numeraseregions); 419 420 421 ret = mtd_device_parse_register(&flash->mtd, NULL, 0, 422 data ? data->parts : NULL, 423 data ? data->nr_parts : 0); 424 if (ret) { 425 kfree(flash); 426 dev_set_drvdata(&spi->dev, NULL); 427 return -ENODEV; 428 } 429 430 return 0; 431 } 432 433 static int __devexit sst25l_remove(struct spi_device *spi) 434 { 435 struct sst25l_flash *flash = dev_get_drvdata(&spi->dev); 436 int ret; 437 438 ret = mtd_device_unregister(&flash->mtd); 439 if (ret == 0) 440 kfree(flash); 441 return ret; 442 } 443 444 static struct spi_driver sst25l_driver = { 445 .driver = { 446 .name = "sst25l", 447 .owner = THIS_MODULE, 448 }, 449 .probe = sst25l_probe, 450 .remove = __devexit_p(sst25l_remove), 451 }; 452 453 static int __init sst25l_init(void) 454 { 455 return spi_register_driver(&sst25l_driver); 456 } 457 458 static void __exit sst25l_exit(void) 459 { 460 spi_unregister_driver(&sst25l_driver); 461 } 462 463 module_init(sst25l_init); 464 module_exit(sst25l_exit); 465 466 MODULE_DESCRIPTION("MTD SPI driver for SST25L Flash chips"); 467 MODULE_AUTHOR("Andre Renaud <andre@bluewatersys.com>, " 468 "Ryan Mallon"); 469 MODULE_LICENSE("GPL"); 470