Lines Matching +full:spi +full:- +full:flash
1 // SPDX-License-Identifier: GPL-2.0
3 * Driver for Microchip 48L640 64 Kb SPI Serial EERAM
23 #include <linux/spi/flash.h>
24 #include <linux/spi/spi.h>
33 struct spi_device *spi; member
60 static int mchp48l640_mkcmd(struct mchp48l640_flash *flash, u8 cmd, loff_t addr, char *buf) in mchp48l640_mkcmd() argument
69 static int mchp48l640_read_status(struct mchp48l640_flash *flash, int *status) in mchp48l640_read_status() argument
76 mutex_lock(&flash->lock); in mchp48l640_read_status()
77 ret = spi_write_then_read(flash->spi, &cmd[0], 1, &cmd[1], 1); in mchp48l640_read_status()
78 mutex_unlock(&flash->lock); in mchp48l640_read_status()
81 dev_dbg(&flash->spi->dev, "read status ret: %d status: %x", ret, *status); in mchp48l640_read_status()
86 static int mchp48l640_waitforbit(struct mchp48l640_flash *flash, int bit, bool set) in mchp48l640_waitforbit() argument
93 ret = mchp48l640_read_status(flash, &status); in mchp48l640_waitforbit()
94 dev_dbg(&flash->spi->dev, "read status ret: %d bit: %x %sset status: %x", in mchp48l640_waitforbit()
110 dev_err(&flash->spi->dev, "Timeout waiting for bit %x %s set in status register.", in mchp48l640_waitforbit()
112 return -ETIMEDOUT; in mchp48l640_waitforbit()
115 static int mchp48l640_write_prepare(struct mchp48l640_flash *flash, bool enable) in mchp48l640_write_prepare() argument
125 mutex_lock(&flash->lock); in mchp48l640_write_prepare()
126 ret = spi_write(flash->spi, cmd, 1); in mchp48l640_write_prepare()
127 mutex_unlock(&flash->lock); in mchp48l640_write_prepare()
130 dev_err(&flash->spi->dev, "write %sable failed ret: %d", in mchp48l640_write_prepare()
133 dev_dbg(&flash->spi->dev, "write %sable success ret: %d", in mchp48l640_write_prepare()
136 return mchp48l640_waitforbit(flash, MCHP48L640_STATUS_WEL, true); in mchp48l640_write_prepare()
141 static int mchp48l640_set_mode(struct mchp48l640_flash *flash) in mchp48l640_set_mode() argument
146 ret = mchp48l640_write_prepare(flash, true); in mchp48l640_set_mode()
153 mutex_lock(&flash->lock); in mchp48l640_set_mode()
154 ret = spi_write(flash->spi, cmd, 2); in mchp48l640_set_mode()
155 mutex_unlock(&flash->lock); in mchp48l640_set_mode()
157 dev_err(&flash->spi->dev, "Could not set continuous mode ret: %d", ret); in mchp48l640_set_mode()
159 return mchp48l640_waitforbit(flash, MCHP48L640_STATUS_PRO, true); in mchp48l640_set_mode()
162 static int mchp48l640_wait_rdy(struct mchp48l640_flash *flash) in mchp48l640_wait_rdy() argument
164 return mchp48l640_waitforbit(flash, MCHP48L640_STATUS_RDY, false); in mchp48l640_wait_rdy()
170 struct mchp48l640_flash *flash = to_mchp48l640_flash(mtd); in mchp48l640_write_page() local
177 return -ENOMEM; in mchp48l640_write_page()
179 ret = mchp48l640_wait_rdy(flash); in mchp48l640_write_page()
183 ret = mchp48l640_write_prepare(flash, true); in mchp48l640_write_page()
187 mutex_lock(&flash->lock); in mchp48l640_write_page()
188 cmdlen = mchp48l640_mkcmd(flash, MCHP48L640_CMD_WRITE, to, cmd); in mchp48l640_write_page()
190 ret = spi_write(flash->spi, cmd, cmdlen + len); in mchp48l640_write_page()
191 mutex_unlock(&flash->lock); in mchp48l640_write_page()
197 ret = mchp48l640_waitforbit(flash, MCHP48L640_STATUS_WEL, false); in mchp48l640_write_page()
205 dev_err(&flash->spi->dev, "write fail with: %d", ret); in mchp48l640_write_page()
212 struct mchp48l640_flash *flash = to_mchp48l640_flash(mtd); in mchp48l640_write() local
217 size_t page_sz = flash->caps->page_size; in mchp48l640_write()
224 ws = min((len - wlen), page_sz); in mchp48l640_write()
238 struct mchp48l640_flash *flash = to_mchp48l640_flash(mtd); in mchp48l640_read_page() local
245 return -ENOMEM; in mchp48l640_read_page()
247 ret = mchp48l640_wait_rdy(flash); in mchp48l640_read_page()
251 mutex_lock(&flash->lock); in mchp48l640_read_page()
252 cmdlen = mchp48l640_mkcmd(flash, MCHP48L640_CMD_READ, from, cmd); in mchp48l640_read_page()
253 ret = spi_write_then_read(flash->spi, cmd, cmdlen, buf, len); in mchp48l640_read_page()
254 mutex_unlock(&flash->lock); in mchp48l640_read_page()
263 dev_err(&flash->spi->dev, "read fail with: %d", ret); in mchp48l640_read_page()
270 struct mchp48l640_flash *flash = to_mchp48l640_flash(mtd); in mchp48l640_read() local
275 size_t page_sz = flash->caps->page_size; in mchp48l640_read()
282 ws = min((len - wlen), page_sz); in mchp48l640_read()
298 static int mchp48l640_probe(struct spi_device *spi) in mchp48l640_probe() argument
300 struct mchp48l640_flash *flash; in mchp48l640_probe() local
305 flash = devm_kzalloc(&spi->dev, sizeof(*flash), GFP_KERNEL); in mchp48l640_probe()
306 if (!flash) in mchp48l640_probe()
307 return -ENOMEM; in mchp48l640_probe()
309 flash->spi = spi; in mchp48l640_probe()
310 mutex_init(&flash->lock); in mchp48l640_probe()
311 spi_set_drvdata(spi, flash); in mchp48l640_probe()
313 err = mchp48l640_read_status(flash, &status); in mchp48l640_probe()
317 err = mchp48l640_set_mode(flash); in mchp48l640_probe()
321 data = dev_get_platdata(&spi->dev); in mchp48l640_probe()
323 flash->caps = of_device_get_match_data(&spi->dev); in mchp48l640_probe()
324 if (!flash->caps) in mchp48l640_probe()
325 flash->caps = &mchp48l640_caps; in mchp48l640_probe()
327 mtd_set_of_node(&flash->mtd, spi->dev.of_node); in mchp48l640_probe()
328 flash->mtd.dev.parent = &spi->dev; in mchp48l640_probe()
329 flash->mtd.type = MTD_RAM; in mchp48l640_probe()
330 flash->mtd.flags = MTD_CAP_RAM; in mchp48l640_probe()
331 flash->mtd.writesize = flash->caps->page_size; in mchp48l640_probe()
332 flash->mtd.size = flash->caps->size; in mchp48l640_probe()
333 flash->mtd._read = mchp48l640_read; in mchp48l640_probe()
334 flash->mtd._write = mchp48l640_write; in mchp48l640_probe()
336 err = mtd_device_register(&flash->mtd, data ? data->parts : NULL, in mchp48l640_probe()
337 data ? data->nr_parts : 0); in mchp48l640_probe()
344 static void mchp48l640_remove(struct spi_device *spi) in mchp48l640_remove() argument
346 struct mchp48l640_flash *flash = spi_get_drvdata(spi); in mchp48l640_remove() local
348 WARN_ON(mtd_device_unregister(&flash->mtd)); in mchp48l640_remove()
367 MODULE_DEVICE_TABLE(spi, mchp48l640_spi_ids);
381 MODULE_DESCRIPTION("MTD SPI driver for Microchip 48l640 EERAM chips");
384 MODULE_ALIAS("spi:mchp48l640");