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