Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * sst25l.c
0004  *
0005  * Driver for SST25L SPI Flash chips
0006  *
0007  * Copyright © 2009 Bluewater Systems Ltd
0008  * Author: Andre Renaud <andre@bluewatersys.com>
0009  * Author: Ryan Mallon
0010  *
0011  * Based on m25p80.c
0012  */
0013 
0014 #include <linux/module.h>
0015 #include <linux/device.h>
0016 #include <linux/mutex.h>
0017 #include <linux/interrupt.h>
0018 #include <linux/slab.h>
0019 #include <linux/sched.h>
0020 
0021 #include <linux/mtd/mtd.h>
0022 #include <linux/mtd/partitions.h>
0023 
0024 #include <linux/spi/spi.h>
0025 #include <linux/spi/flash.h>
0026 
0027 /* Erases can take up to 3 seconds! */
0028 #define MAX_READY_WAIT_JIFFIES  msecs_to_jiffies(3000)
0029 
0030 #define SST25L_CMD_WRSR     0x01    /* Write status register */
0031 #define SST25L_CMD_WRDI     0x04    /* Write disable */
0032 #define SST25L_CMD_RDSR     0x05    /* Read status register */
0033 #define SST25L_CMD_WREN     0x06    /* Write enable */
0034 #define SST25L_CMD_READ     0x03    /* High speed read */
0035 
0036 #define SST25L_CMD_EWSR     0x50    /* Enable write status register */
0037 #define SST25L_CMD_SECTOR_ERASE 0x20    /* Erase sector */
0038 #define SST25L_CMD_READ_ID  0x90    /* Read device ID */
0039 #define SST25L_CMD_AAI_PROGRAM  0xaf    /* Auto address increment */
0040 
0041 #define SST25L_STATUS_BUSY  (1 << 0)    /* Chip is busy */
0042 #define SST25L_STATUS_WREN  (1 << 1)    /* Write enabled */
0043 #define SST25L_STATUS_BP0   (1 << 2)    /* Block protection 0 */
0044 #define SST25L_STATUS_BP1   (1 << 3)    /* Block protection 1 */
0045 
0046 struct sst25l_flash {
0047     struct spi_device   *spi;
0048     struct mutex        lock;
0049     struct mtd_info     mtd;
0050 };
0051 
0052 struct flash_info {
0053     const char      *name;
0054     uint16_t        device_id;
0055     unsigned        page_size;
0056     unsigned        nr_pages;
0057     unsigned        erase_size;
0058 };
0059 
0060 #define to_sst25l_flash(x) container_of(x, struct sst25l_flash, mtd)
0061 
0062 static struct flash_info sst25l_flash_info[] = {
0063     {"sst25lf020a", 0xbf43, 256, 1024, 4096},
0064     {"sst25lf040a", 0xbf44, 256, 2048, 4096},
0065 };
0066 
0067 static int sst25l_status(struct sst25l_flash *flash, int *status)
0068 {
0069     struct spi_message m;
0070     struct spi_transfer t;
0071     unsigned char cmd_resp[2];
0072     int err;
0073 
0074     spi_message_init(&m);
0075     memset(&t, 0, sizeof(struct spi_transfer));
0076 
0077     cmd_resp[0] = SST25L_CMD_RDSR;
0078     cmd_resp[1] = 0xff;
0079     t.tx_buf = cmd_resp;
0080     t.rx_buf = cmd_resp;
0081     t.len = sizeof(cmd_resp);
0082     spi_message_add_tail(&t, &m);
0083     err = spi_sync(flash->spi, &m);
0084     if (err < 0)
0085         return err;
0086 
0087     *status = cmd_resp[1];
0088     return 0;
0089 }
0090 
0091 static int sst25l_write_enable(struct sst25l_flash *flash, int enable)
0092 {
0093     unsigned char command[2];
0094     int status, err;
0095 
0096     command[0] = enable ? SST25L_CMD_WREN : SST25L_CMD_WRDI;
0097     err = spi_write(flash->spi, command, 1);
0098     if (err)
0099         return err;
0100 
0101     command[0] = SST25L_CMD_EWSR;
0102     err = spi_write(flash->spi, command, 1);
0103     if (err)
0104         return err;
0105 
0106     command[0] = SST25L_CMD_WRSR;
0107     command[1] = enable ? 0 : SST25L_STATUS_BP0 | SST25L_STATUS_BP1;
0108     err = spi_write(flash->spi, command, 2);
0109     if (err)
0110         return err;
0111 
0112     if (enable) {
0113         err = sst25l_status(flash, &status);
0114         if (err)
0115             return err;
0116         if (!(status & SST25L_STATUS_WREN))
0117             return -EROFS;
0118     }
0119 
0120     return 0;
0121 }
0122 
0123 static int sst25l_wait_till_ready(struct sst25l_flash *flash)
0124 {
0125     unsigned long deadline;
0126     int status, err;
0127 
0128     deadline = jiffies + MAX_READY_WAIT_JIFFIES;
0129     do {
0130         err = sst25l_status(flash, &status);
0131         if (err)
0132             return err;
0133         if (!(status & SST25L_STATUS_BUSY))
0134             return 0;
0135 
0136         cond_resched();
0137     } while (!time_after_eq(jiffies, deadline));
0138 
0139     return -ETIMEDOUT;
0140 }
0141 
0142 static int sst25l_erase_sector(struct sst25l_flash *flash, uint32_t offset)
0143 {
0144     unsigned char command[4];
0145     int err;
0146 
0147     err = sst25l_write_enable(flash, 1);
0148     if (err)
0149         return err;
0150 
0151     command[0] = SST25L_CMD_SECTOR_ERASE;
0152     command[1] = offset >> 16;
0153     command[2] = offset >> 8;
0154     command[3] = offset;
0155     err = spi_write(flash->spi, command, 4);
0156     if (err)
0157         return err;
0158 
0159     err = sst25l_wait_till_ready(flash);
0160     if (err)
0161         return err;
0162 
0163     return sst25l_write_enable(flash, 0);
0164 }
0165 
0166 static int sst25l_erase(struct mtd_info *mtd, struct erase_info *instr)
0167 {
0168     struct sst25l_flash *flash = to_sst25l_flash(mtd);
0169     uint32_t addr, end;
0170     int err;
0171 
0172     /* Sanity checks */
0173     if ((uint32_t)instr->len % mtd->erasesize)
0174         return -EINVAL;
0175 
0176     if ((uint32_t)instr->addr % mtd->erasesize)
0177         return -EINVAL;
0178 
0179     addr = instr->addr;
0180     end = addr + instr->len;
0181 
0182     mutex_lock(&flash->lock);
0183 
0184     err = sst25l_wait_till_ready(flash);
0185     if (err) {
0186         mutex_unlock(&flash->lock);
0187         return err;
0188     }
0189 
0190     while (addr < end) {
0191         err = sst25l_erase_sector(flash, addr);
0192         if (err) {
0193             mutex_unlock(&flash->lock);
0194             dev_err(&flash->spi->dev, "Erase failed\n");
0195             return err;
0196         }
0197 
0198         addr += mtd->erasesize;
0199     }
0200 
0201     mutex_unlock(&flash->lock);
0202 
0203     return 0;
0204 }
0205 
0206 static int sst25l_read(struct mtd_info *mtd, loff_t from, size_t len,
0207                size_t *retlen, unsigned char *buf)
0208 {
0209     struct sst25l_flash *flash = to_sst25l_flash(mtd);
0210     struct spi_transfer transfer[2];
0211     struct spi_message message;
0212     unsigned char command[4];
0213     int ret;
0214 
0215     spi_message_init(&message);
0216     memset(&transfer, 0, sizeof(transfer));
0217 
0218     command[0] = SST25L_CMD_READ;
0219     command[1] = from >> 16;
0220     command[2] = from >> 8;
0221     command[3] = from;
0222 
0223     transfer[0].tx_buf = command;
0224     transfer[0].len = sizeof(command);
0225     spi_message_add_tail(&transfer[0], &message);
0226 
0227     transfer[1].rx_buf = buf;
0228     transfer[1].len = len;
0229     spi_message_add_tail(&transfer[1], &message);
0230 
0231     mutex_lock(&flash->lock);
0232 
0233     /* Wait for previous write/erase to complete */
0234     ret = sst25l_wait_till_ready(flash);
0235     if (ret) {
0236         mutex_unlock(&flash->lock);
0237         return ret;
0238     }
0239 
0240     spi_sync(flash->spi, &message);
0241 
0242     if (retlen && message.actual_length > sizeof(command))
0243         *retlen += message.actual_length - sizeof(command);
0244 
0245     mutex_unlock(&flash->lock);
0246     return 0;
0247 }
0248 
0249 static int sst25l_write(struct mtd_info *mtd, loff_t to, size_t len,
0250             size_t *retlen, const unsigned char *buf)
0251 {
0252     struct sst25l_flash *flash = to_sst25l_flash(mtd);
0253     int i, j, ret, bytes, copied = 0;
0254     unsigned char command[5];
0255 
0256     if ((uint32_t)to % mtd->writesize)
0257         return -EINVAL;
0258 
0259     mutex_lock(&flash->lock);
0260 
0261     ret = sst25l_write_enable(flash, 1);
0262     if (ret)
0263         goto out;
0264 
0265     for (i = 0; i < len; i += mtd->writesize) {
0266         ret = sst25l_wait_till_ready(flash);
0267         if (ret)
0268             goto out;
0269 
0270         /* Write the first byte of the page */
0271         command[0] = SST25L_CMD_AAI_PROGRAM;
0272         command[1] = (to + i) >> 16;
0273         command[2] = (to + i) >> 8;
0274         command[3] = (to + i);
0275         command[4] = buf[i];
0276         ret = spi_write(flash->spi, command, 5);
0277         if (ret < 0)
0278             goto out;
0279         copied++;
0280 
0281         /*
0282          * Write the remaining bytes using auto address
0283          * increment mode
0284          */
0285         bytes = min_t(uint32_t, mtd->writesize, len - i);
0286         for (j = 1; j < bytes; j++, copied++) {
0287             ret = sst25l_wait_till_ready(flash);
0288             if (ret)
0289                 goto out;
0290 
0291             command[1] = buf[i + j];
0292             ret = spi_write(flash->spi, command, 2);
0293             if (ret)
0294                 goto out;
0295         }
0296     }
0297 
0298 out:
0299     ret = sst25l_write_enable(flash, 0);
0300 
0301     if (retlen)
0302         *retlen = copied;
0303 
0304     mutex_unlock(&flash->lock);
0305     return ret;
0306 }
0307 
0308 static struct flash_info *sst25l_match_device(struct spi_device *spi)
0309 {
0310     struct flash_info *flash_info = NULL;
0311     struct spi_message m;
0312     struct spi_transfer t;
0313     unsigned char cmd_resp[6];
0314     int i, err;
0315     uint16_t id;
0316 
0317     spi_message_init(&m);
0318     memset(&t, 0, sizeof(struct spi_transfer));
0319 
0320     cmd_resp[0] = SST25L_CMD_READ_ID;
0321     cmd_resp[1] = 0;
0322     cmd_resp[2] = 0;
0323     cmd_resp[3] = 0;
0324     cmd_resp[4] = 0xff;
0325     cmd_resp[5] = 0xff;
0326     t.tx_buf = cmd_resp;
0327     t.rx_buf = cmd_resp;
0328     t.len = sizeof(cmd_resp);
0329     spi_message_add_tail(&t, &m);
0330     err = spi_sync(spi, &m);
0331     if (err < 0) {
0332         dev_err(&spi->dev, "error reading device id\n");
0333         return NULL;
0334     }
0335 
0336     id = (cmd_resp[4] << 8) | cmd_resp[5];
0337 
0338     for (i = 0; i < ARRAY_SIZE(sst25l_flash_info); i++)
0339         if (sst25l_flash_info[i].device_id == id)
0340             flash_info = &sst25l_flash_info[i];
0341 
0342     if (!flash_info)
0343         dev_err(&spi->dev, "unknown id %.4x\n", id);
0344 
0345     return flash_info;
0346 }
0347 
0348 static int sst25l_probe(struct spi_device *spi)
0349 {
0350     struct flash_info *flash_info;
0351     struct sst25l_flash *flash;
0352     struct flash_platform_data *data;
0353     int ret;
0354 
0355     flash_info = sst25l_match_device(spi);
0356     if (!flash_info)
0357         return -ENODEV;
0358 
0359     flash = devm_kzalloc(&spi->dev, sizeof(*flash), GFP_KERNEL);
0360     if (!flash)
0361         return -ENOMEM;
0362 
0363     flash->spi = spi;
0364     mutex_init(&flash->lock);
0365     spi_set_drvdata(spi, flash);
0366 
0367     data = dev_get_platdata(&spi->dev);
0368     if (data && data->name)
0369         flash->mtd.name = data->name;
0370 
0371     flash->mtd.dev.parent   = &spi->dev;
0372     flash->mtd.type     = MTD_NORFLASH;
0373     flash->mtd.flags    = MTD_CAP_NORFLASH;
0374     flash->mtd.erasesize    = flash_info->erase_size;
0375     flash->mtd.writesize    = flash_info->page_size;
0376     flash->mtd.writebufsize = flash_info->page_size;
0377     flash->mtd.size     = flash_info->page_size * flash_info->nr_pages;
0378     flash->mtd._erase   = sst25l_erase;
0379     flash->mtd._read        = sst25l_read;
0380     flash->mtd._write   = sst25l_write;
0381 
0382     dev_info(&spi->dev, "%s (%lld KiB)\n", flash_info->name,
0383          (long long)flash->mtd.size >> 10);
0384 
0385     pr_debug("mtd .name = %s, .size = 0x%llx (%lldMiB) "
0386           ".erasesize = 0x%.8x (%uKiB) .numeraseregions = %d\n",
0387           flash->mtd.name,
0388           (long long)flash->mtd.size, (long long)(flash->mtd.size >> 20),
0389           flash->mtd.erasesize, flash->mtd.erasesize / 1024,
0390           flash->mtd.numeraseregions);
0391 
0392 
0393     ret = mtd_device_register(&flash->mtd, data ? data->parts : NULL,
0394                   data ? data->nr_parts : 0);
0395     if (ret)
0396         return -ENODEV;
0397 
0398     return 0;
0399 }
0400 
0401 static void sst25l_remove(struct spi_device *spi)
0402 {
0403     struct sst25l_flash *flash = spi_get_drvdata(spi);
0404 
0405     WARN_ON(mtd_device_unregister(&flash->mtd));
0406 }
0407 
0408 static struct spi_driver sst25l_driver = {
0409     .driver = {
0410         .name   = "sst25l",
0411     },
0412     .probe      = sst25l_probe,
0413     .remove     = sst25l_remove,
0414 };
0415 
0416 module_spi_driver(sst25l_driver);
0417 
0418 MODULE_DESCRIPTION("MTD SPI driver for SST25L Flash chips");
0419 MODULE_AUTHOR("Andre Renaud <andre@bluewatersys.com>, "
0420           "Ryan Mallon");
0421 MODULE_LICENSE("GPL");