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 <ryan@bluewatersys.com> 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 int partitioned; 57 }; 58 59 struct flash_info { 60 const char *name; 61 uint16_t device_id; 62 unsigned page_size; 63 unsigned nr_pages; 64 unsigned erase_size; 65 }; 66 67 #define to_sst25l_flash(x) container_of(x, struct sst25l_flash, mtd) 68 69 static struct flash_info __initdata sst25l_flash_info[] = { 70 {"sst25lf020a", 0xbf43, 256, 1024, 4096}, 71 {"sst25lf040a", 0xbf44, 256, 2048, 4096}, 72 }; 73 74 static int sst25l_status(struct sst25l_flash *flash, int *status) 75 { 76 struct spi_message m; 77 struct spi_transfer t; 78 unsigned char cmd_resp[2]; 79 int err; 80 81 spi_message_init(&m); 82 memset(&t, 0, sizeof(struct spi_transfer)); 83 84 cmd_resp[0] = SST25L_CMD_RDSR; 85 cmd_resp[1] = 0xff; 86 t.tx_buf = cmd_resp; 87 t.rx_buf = cmd_resp; 88 t.len = sizeof(cmd_resp); 89 spi_message_add_tail(&t, &m); 90 err = spi_sync(flash->spi, &m); 91 if (err < 0) 92 return err; 93 94 *status = cmd_resp[1]; 95 return 0; 96 } 97 98 static int sst25l_write_enable(struct sst25l_flash *flash, int enable) 99 { 100 unsigned char command[2]; 101 int status, err; 102 103 command[0] = enable ? SST25L_CMD_WREN : SST25L_CMD_WRDI; 104 err = spi_write(flash->spi, command, 1); 105 if (err) 106 return err; 107 108 command[0] = SST25L_CMD_EWSR; 109 err = spi_write(flash->spi, command, 1); 110 if (err) 111 return err; 112 113 command[0] = SST25L_CMD_WRSR; 114 command[1] = enable ? 0 : SST25L_STATUS_BP0 | SST25L_STATUS_BP1; 115 err = spi_write(flash->spi, command, 2); 116 if (err) 117 return err; 118 119 if (enable) { 120 err = sst25l_status(flash, &status); 121 if (err) 122 return err; 123 if (!(status & SST25L_STATUS_WREN)) 124 return -EROFS; 125 } 126 127 return 0; 128 } 129 130 static int sst25l_wait_till_ready(struct sst25l_flash *flash) 131 { 132 unsigned long deadline; 133 int status, err; 134 135 deadline = jiffies + MAX_READY_WAIT_JIFFIES; 136 do { 137 err = sst25l_status(flash, &status); 138 if (err) 139 return err; 140 if (!(status & SST25L_STATUS_BUSY)) 141 return 0; 142 143 cond_resched(); 144 } while (!time_after_eq(jiffies, deadline)); 145 146 return -ETIMEDOUT; 147 } 148 149 static int sst25l_erase_sector(struct sst25l_flash *flash, uint32_t offset) 150 { 151 unsigned char command[4]; 152 int err; 153 154 err = sst25l_write_enable(flash, 1); 155 if (err) 156 return err; 157 158 command[0] = SST25L_CMD_SECTOR_ERASE; 159 command[1] = offset >> 16; 160 command[2] = offset >> 8; 161 command[3] = offset; 162 err = spi_write(flash->spi, command, 4); 163 if (err) 164 return err; 165 166 err = sst25l_wait_till_ready(flash); 167 if (err) 168 return err; 169 170 return sst25l_write_enable(flash, 0); 171 } 172 173 static int sst25l_erase(struct mtd_info *mtd, struct erase_info *instr) 174 { 175 struct sst25l_flash *flash = to_sst25l_flash(mtd); 176 uint32_t addr, end; 177 int err; 178 179 /* Sanity checks */ 180 if (instr->addr + instr->len > flash->mtd.size) 181 return -EINVAL; 182 183 if ((uint32_t)instr->len % mtd->erasesize) 184 return -EINVAL; 185 186 if ((uint32_t)instr->addr % mtd->erasesize) 187 return -EINVAL; 188 189 addr = instr->addr; 190 end = addr + instr->len; 191 192 mutex_lock(&flash->lock); 193 194 err = sst25l_wait_till_ready(flash); 195 if (err) { 196 mutex_unlock(&flash->lock); 197 return err; 198 } 199 200 while (addr < end) { 201 err = sst25l_erase_sector(flash, addr); 202 if (err) { 203 mutex_unlock(&flash->lock); 204 instr->state = MTD_ERASE_FAILED; 205 dev_err(&flash->spi->dev, "Erase failed\n"); 206 return err; 207 } 208 209 addr += mtd->erasesize; 210 } 211 212 mutex_unlock(&flash->lock); 213 214 instr->state = MTD_ERASE_DONE; 215 mtd_erase_callback(instr); 216 return 0; 217 } 218 219 static int sst25l_read(struct mtd_info *mtd, loff_t from, size_t len, 220 size_t *retlen, unsigned char *buf) 221 { 222 struct sst25l_flash *flash = to_sst25l_flash(mtd); 223 struct spi_transfer transfer[2]; 224 struct spi_message message; 225 unsigned char command[4]; 226 int ret; 227 228 /* Sanity checking */ 229 if (len == 0) 230 return 0; 231 232 if (from + len > flash->mtd.size) 233 return -EINVAL; 234 235 if (retlen) 236 *retlen = 0; 237 238 spi_message_init(&message); 239 memset(&transfer, 0, sizeof(transfer)); 240 241 command[0] = SST25L_CMD_READ; 242 command[1] = from >> 16; 243 command[2] = from >> 8; 244 command[3] = from; 245 246 transfer[0].tx_buf = command; 247 transfer[0].len = sizeof(command); 248 spi_message_add_tail(&transfer[0], &message); 249 250 transfer[1].rx_buf = buf; 251 transfer[1].len = len; 252 spi_message_add_tail(&transfer[1], &message); 253 254 mutex_lock(&flash->lock); 255 256 /* Wait for previous write/erase to complete */ 257 ret = sst25l_wait_till_ready(flash); 258 if (ret) { 259 mutex_unlock(&flash->lock); 260 return ret; 261 } 262 263 spi_sync(flash->spi, &message); 264 265 if (retlen && message.actual_length > sizeof(command)) 266 *retlen += message.actual_length - sizeof(command); 267 268 mutex_unlock(&flash->lock); 269 return 0; 270 } 271 272 static int sst25l_write(struct mtd_info *mtd, loff_t to, size_t len, 273 size_t *retlen, const unsigned char *buf) 274 { 275 struct sst25l_flash *flash = to_sst25l_flash(mtd); 276 int i, j, ret, bytes, copied = 0; 277 unsigned char command[5]; 278 279 /* Sanity checks */ 280 if (!len) 281 return 0; 282 283 if (to + len > flash->mtd.size) 284 return -EINVAL; 285 286 if ((uint32_t)to % mtd->writesize) 287 return -EINVAL; 288 289 mutex_lock(&flash->lock); 290 291 ret = sst25l_write_enable(flash, 1); 292 if (ret) 293 goto out; 294 295 for (i = 0; i < len; i += mtd->writesize) { 296 ret = sst25l_wait_till_ready(flash); 297 if (ret) 298 goto out; 299 300 /* Write the first byte of the page */ 301 command[0] = SST25L_CMD_AAI_PROGRAM; 302 command[1] = (to + i) >> 16; 303 command[2] = (to + i) >> 8; 304 command[3] = (to + i); 305 command[4] = buf[i]; 306 ret = spi_write(flash->spi, command, 5); 307 if (ret < 0) 308 goto out; 309 copied++; 310 311 /* 312 * Write the remaining bytes using auto address 313 * increment mode 314 */ 315 bytes = min_t(uint32_t, mtd->writesize, len - i); 316 for (j = 1; j < bytes; j++, copied++) { 317 ret = sst25l_wait_till_ready(flash); 318 if (ret) 319 goto out; 320 321 command[1] = buf[i + j]; 322 ret = spi_write(flash->spi, command, 2); 323 if (ret) 324 goto out; 325 } 326 } 327 328 out: 329 ret = sst25l_write_enable(flash, 0); 330 331 if (retlen) 332 *retlen = copied; 333 334 mutex_unlock(&flash->lock); 335 return ret; 336 } 337 338 static struct flash_info *__devinit sst25l_match_device(struct spi_device *spi) 339 { 340 struct flash_info *flash_info = NULL; 341 struct spi_message m; 342 struct spi_transfer t; 343 unsigned char cmd_resp[6]; 344 int i, err; 345 uint16_t id; 346 347 spi_message_init(&m); 348 memset(&t, 0, sizeof(struct spi_transfer)); 349 350 cmd_resp[0] = SST25L_CMD_READ_ID; 351 cmd_resp[1] = 0; 352 cmd_resp[2] = 0; 353 cmd_resp[3] = 0; 354 cmd_resp[4] = 0xff; 355 cmd_resp[5] = 0xff; 356 t.tx_buf = cmd_resp; 357 t.rx_buf = cmd_resp; 358 t.len = sizeof(cmd_resp); 359 spi_message_add_tail(&t, &m); 360 err = spi_sync(spi, &m); 361 if (err < 0) { 362 dev_err(&spi->dev, "error reading device id\n"); 363 return NULL; 364 } 365 366 id = (cmd_resp[4] << 8) | cmd_resp[5]; 367 368 for (i = 0; i < ARRAY_SIZE(sst25l_flash_info); i++) 369 if (sst25l_flash_info[i].device_id == id) 370 flash_info = &sst25l_flash_info[i]; 371 372 if (!flash_info) 373 dev_err(&spi->dev, "unknown id %.4x\n", id); 374 375 return flash_info; 376 } 377 378 static int __devinit sst25l_probe(struct spi_device *spi) 379 { 380 struct flash_info *flash_info; 381 struct sst25l_flash *flash; 382 struct flash_platform_data *data; 383 int ret, i; 384 385 flash_info = sst25l_match_device(spi); 386 if (!flash_info) 387 return -ENODEV; 388 389 flash = kzalloc(sizeof(struct sst25l_flash), GFP_KERNEL); 390 if (!flash) 391 return -ENOMEM; 392 393 flash->spi = spi; 394 mutex_init(&flash->lock); 395 dev_set_drvdata(&spi->dev, flash); 396 397 data = spi->dev.platform_data; 398 if (data && data->name) 399 flash->mtd.name = data->name; 400 else 401 flash->mtd.name = dev_name(&spi->dev); 402 403 flash->mtd.type = MTD_NORFLASH; 404 flash->mtd.flags = MTD_CAP_NORFLASH; 405 flash->mtd.erasesize = flash_info->erase_size; 406 flash->mtd.writesize = flash_info->page_size; 407 flash->mtd.size = flash_info->page_size * flash_info->nr_pages; 408 flash->mtd.erase = sst25l_erase; 409 flash->mtd.read = sst25l_read; 410 flash->mtd.write = sst25l_write; 411 412 dev_info(&spi->dev, "%s (%lld KiB)\n", flash_info->name, 413 (long long)flash->mtd.size >> 10); 414 415 DEBUG(MTD_DEBUG_LEVEL2, 416 "mtd .name = %s, .size = 0x%llx (%lldMiB) " 417 ".erasesize = 0x%.8x (%uKiB) .numeraseregions = %d\n", 418 flash->mtd.name, 419 (long long)flash->mtd.size, (long long)(flash->mtd.size >> 20), 420 flash->mtd.erasesize, flash->mtd.erasesize / 1024, 421 flash->mtd.numeraseregions); 422 423 if (mtd_has_partitions()) { 424 struct mtd_partition *parts = NULL; 425 int nr_parts = 0; 426 427 if (mtd_has_cmdlinepart()) { 428 static const char *part_probes[] = 429 {"cmdlinepart", NULL}; 430 431 nr_parts = parse_mtd_partitions(&flash->mtd, 432 part_probes, 433 &parts, 0); 434 } 435 436 if (nr_parts <= 0 && data && data->parts) { 437 parts = data->parts; 438 nr_parts = data->nr_parts; 439 } 440 441 if (nr_parts > 0) { 442 for (i = 0; i < nr_parts; i++) { 443 DEBUG(MTD_DEBUG_LEVEL2, "partitions[%d] = " 444 "{.name = %s, .offset = 0x%llx, " 445 ".size = 0x%llx (%lldKiB) }\n", 446 i, parts[i].name, 447 (long long)parts[i].offset, 448 (long long)parts[i].size, 449 (long long)(parts[i].size >> 10)); 450 } 451 452 flash->partitioned = 1; 453 return add_mtd_partitions(&flash->mtd, 454 parts, nr_parts); 455 } 456 457 } else if (data && data->nr_parts) { 458 dev_warn(&spi->dev, "ignoring %d default partitions on %s\n", 459 data->nr_parts, data->name); 460 } 461 462 ret = add_mtd_device(&flash->mtd); 463 if (ret == 1) { 464 kfree(flash); 465 dev_set_drvdata(&spi->dev, NULL); 466 return -ENODEV; 467 } 468 469 return 0; 470 } 471 472 static int __exit sst25l_remove(struct spi_device *spi) 473 { 474 struct sst25l_flash *flash = dev_get_drvdata(&spi->dev); 475 int ret; 476 477 if (mtd_has_partitions() && flash->partitioned) 478 ret = del_mtd_partitions(&flash->mtd); 479 else 480 ret = del_mtd_device(&flash->mtd); 481 if (ret == 0) 482 kfree(flash); 483 return ret; 484 } 485 486 static struct spi_driver sst25l_driver = { 487 .driver = { 488 .name = "sst25l", 489 .bus = &spi_bus_type, 490 .owner = THIS_MODULE, 491 }, 492 .probe = sst25l_probe, 493 .remove = __exit_p(sst25l_remove), 494 }; 495 496 static int __init sst25l_init(void) 497 { 498 return spi_register_driver(&sst25l_driver); 499 } 500 501 static void __exit sst25l_exit(void) 502 { 503 spi_unregister_driver(&sst25l_driver); 504 } 505 506 module_init(sst25l_init); 507 module_exit(sst25l_exit); 508 509 MODULE_DESCRIPTION("MTD SPI driver for SST25L Flash chips"); 510 MODULE_AUTHOR("Andre Renaud <andre@bluewatersys.com>, " 511 "Ryan Mallon <ryan@bluewatersys.com>"); 512 MODULE_LICENSE("GPL"); 513