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