Lines Matching +full:spi +full:- +full:flash

1 // SPDX-License-Identifier: GPL-2.0-only
5 * Driver for SST25L SPI Flash chips
24 #include <linux/spi/spi.h>
25 #include <linux/spi/flash.h>
47 struct spi_device *spi; member
67 static int sst25l_status(struct sst25l_flash *flash, int *status) in sst25l_status() argument
83 err = spi_sync(flash->spi, &m); in sst25l_status()
91 static int sst25l_write_enable(struct sst25l_flash *flash, int enable) in sst25l_write_enable() argument
97 err = spi_write(flash->spi, command, 1); in sst25l_write_enable()
102 err = spi_write(flash->spi, command, 1); in sst25l_write_enable()
108 err = spi_write(flash->spi, command, 2); in sst25l_write_enable()
113 err = sst25l_status(flash, &status); in sst25l_write_enable()
117 return -EROFS; in sst25l_write_enable()
123 static int sst25l_wait_till_ready(struct sst25l_flash *flash) in sst25l_wait_till_ready() argument
130 err = sst25l_status(flash, &status); in sst25l_wait_till_ready()
139 return -ETIMEDOUT; in sst25l_wait_till_ready()
142 static int sst25l_erase_sector(struct sst25l_flash *flash, uint32_t offset) in sst25l_erase_sector() argument
147 err = sst25l_write_enable(flash, 1); in sst25l_erase_sector()
155 err = spi_write(flash->spi, command, 4); in sst25l_erase_sector()
159 err = sst25l_wait_till_ready(flash); in sst25l_erase_sector()
163 return sst25l_write_enable(flash, 0); in sst25l_erase_sector()
168 struct sst25l_flash *flash = to_sst25l_flash(mtd); in sst25l_erase() local
173 if ((uint32_t)instr->len % mtd->erasesize) in sst25l_erase()
174 return -EINVAL; in sst25l_erase()
176 if ((uint32_t)instr->addr % mtd->erasesize) in sst25l_erase()
177 return -EINVAL; in sst25l_erase()
179 addr = instr->addr; in sst25l_erase()
180 end = addr + instr->len; in sst25l_erase()
182 mutex_lock(&flash->lock); in sst25l_erase()
184 err = sst25l_wait_till_ready(flash); in sst25l_erase()
186 mutex_unlock(&flash->lock); in sst25l_erase()
191 err = sst25l_erase_sector(flash, addr); in sst25l_erase()
193 mutex_unlock(&flash->lock); in sst25l_erase()
194 dev_err(&flash->spi->dev, "Erase failed\n"); in sst25l_erase()
198 addr += mtd->erasesize; in sst25l_erase()
201 mutex_unlock(&flash->lock); in sst25l_erase()
209 struct sst25l_flash *flash = to_sst25l_flash(mtd); in sst25l_read() local
231 mutex_lock(&flash->lock); in sst25l_read()
234 ret = sst25l_wait_till_ready(flash); in sst25l_read()
236 mutex_unlock(&flash->lock); in sst25l_read()
240 spi_sync(flash->spi, &message); in sst25l_read()
243 *retlen += message.actual_length - sizeof(command); in sst25l_read()
245 mutex_unlock(&flash->lock); in sst25l_read()
252 struct sst25l_flash *flash = to_sst25l_flash(mtd); in sst25l_write() local
256 if ((uint32_t)to % mtd->writesize) in sst25l_write()
257 return -EINVAL; in sst25l_write()
259 mutex_lock(&flash->lock); in sst25l_write()
261 ret = sst25l_write_enable(flash, 1); in sst25l_write()
265 for (i = 0; i < len; i += mtd->writesize) { in sst25l_write()
266 ret = sst25l_wait_till_ready(flash); in sst25l_write()
276 ret = spi_write(flash->spi, command, 5); in sst25l_write()
285 bytes = min_t(uint32_t, mtd->writesize, len - i); in sst25l_write()
287 ret = sst25l_wait_till_ready(flash); in sst25l_write()
292 ret = spi_write(flash->spi, command, 2); in sst25l_write()
299 ret = sst25l_write_enable(flash, 0); in sst25l_write()
304 mutex_unlock(&flash->lock); in sst25l_write()
308 static struct flash_info *sst25l_match_device(struct spi_device *spi) in sst25l_match_device() argument
330 err = spi_sync(spi, &m); in sst25l_match_device()
332 dev_err(&spi->dev, "error reading device id\n"); in sst25l_match_device()
343 dev_err(&spi->dev, "unknown id %.4x\n", id); in sst25l_match_device()
348 static int sst25l_probe(struct spi_device *spi) in sst25l_probe() argument
351 struct sst25l_flash *flash; in sst25l_probe() local
355 flash_info = sst25l_match_device(spi); in sst25l_probe()
357 return -ENODEV; in sst25l_probe()
359 flash = devm_kzalloc(&spi->dev, sizeof(*flash), GFP_KERNEL); in sst25l_probe()
360 if (!flash) in sst25l_probe()
361 return -ENOMEM; in sst25l_probe()
363 flash->spi = spi; in sst25l_probe()
364 mutex_init(&flash->lock); in sst25l_probe()
365 spi_set_drvdata(spi, flash); in sst25l_probe()
367 data = dev_get_platdata(&spi->dev); in sst25l_probe()
368 if (data && data->name) in sst25l_probe()
369 flash->mtd.name = data->name; in sst25l_probe()
371 flash->mtd.dev.parent = &spi->dev; in sst25l_probe()
372 flash->mtd.type = MTD_NORFLASH; in sst25l_probe()
373 flash->mtd.flags = MTD_CAP_NORFLASH; in sst25l_probe()
374 flash->mtd.erasesize = flash_info->erase_size; in sst25l_probe()
375 flash->mtd.writesize = flash_info->page_size; in sst25l_probe()
376 flash->mtd.writebufsize = flash_info->page_size; in sst25l_probe()
377 flash->mtd.size = flash_info->page_size * flash_info->nr_pages; in sst25l_probe()
378 flash->mtd._erase = sst25l_erase; in sst25l_probe()
379 flash->mtd._read = sst25l_read; in sst25l_probe()
380 flash->mtd._write = sst25l_write; in sst25l_probe()
382 dev_info(&spi->dev, "%s (%lld KiB)\n", flash_info->name, in sst25l_probe()
383 (long long)flash->mtd.size >> 10); in sst25l_probe()
387 flash->mtd.name, in sst25l_probe()
388 (long long)flash->mtd.size, (long long)(flash->mtd.size >> 20), in sst25l_probe()
389 flash->mtd.erasesize, flash->mtd.erasesize / 1024, in sst25l_probe()
390 flash->mtd.numeraseregions); in sst25l_probe()
393 ret = mtd_device_register(&flash->mtd, data ? data->parts : NULL, in sst25l_probe()
394 data ? data->nr_parts : 0); in sst25l_probe()
396 return -ENODEV; in sst25l_probe()
401 static void sst25l_remove(struct spi_device *spi) in sst25l_remove() argument
403 struct sst25l_flash *flash = spi_get_drvdata(spi); in sst25l_remove() local
405 WARN_ON(mtd_device_unregister(&flash->mtd)); in sst25l_remove()
418 MODULE_DESCRIPTION("MTD SPI driver for SST25L Flash chips");