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 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 *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 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 = devm_kzalloc(&spi->dev, sizeof(*flash), GFP_KERNEL); 368 if (!flash) 369 return -ENOMEM; 370 371 flash->spi = spi; 372 mutex_init(&flash->lock); 373 spi_set_drvdata(spi, flash); 374 375 data = dev_get_platdata(&spi->dev); 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 return -ENODEV; 407 408 return 0; 409 } 410 411 static int sst25l_remove(struct spi_device *spi) 412 { 413 struct sst25l_flash *flash = spi_get_drvdata(spi); 414 415 return mtd_device_unregister(&flash->mtd); 416 } 417 418 static struct spi_driver sst25l_driver = { 419 .driver = { 420 .name = "sst25l", 421 .owner = THIS_MODULE, 422 }, 423 .probe = sst25l_probe, 424 .remove = sst25l_remove, 425 }; 426 427 module_spi_driver(sst25l_driver); 428 429 MODULE_DESCRIPTION("MTD SPI driver for SST25L Flash chips"); 430 MODULE_AUTHOR("Andre Renaud <andre@bluewatersys.com>, " 431 "Ryan Mallon"); 432 MODULE_LICENSE("GPL"); 433