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