2017-03-11 12:42:32 +00:00
|
|
|
#include <stdint.h>
|
|
|
|
#include <stdlib.h>
|
2017-06-23 16:09:56 +02:00
|
|
|
#include <string.h>
|
2017-03-11 12:42:32 +00:00
|
|
|
|
|
|
|
#include <flash.h>
|
2017-06-14 16:19:02 +02:00
|
|
|
#include <macros.h>
|
2017-03-11 12:42:32 +00:00
|
|
|
|
2017-07-27 16:53:01 +02:00
|
|
|
static int default_flash_is_val(struct flash_dev *dev, uint32_t addr, char val)
|
2017-05-19 17:16:01 +02:00
|
|
|
{
|
2017-07-27 16:53:01 +02:00
|
|
|
char data[32];
|
2017-06-14 16:19:02 +02:00
|
|
|
size_t i, nbytes, len = 1 << dev->log2_block_size;
|
2017-05-19 17:16:01 +02:00
|
|
|
|
2017-06-14 16:19:02 +02:00
|
|
|
addr <<= dev->log2_block_size;
|
2017-05-19 17:16:01 +02:00
|
|
|
|
2017-06-14 16:19:02 +02:00
|
|
|
while (len) {
|
|
|
|
nbytes = min(32, len);
|
|
|
|
|
|
|
|
if (flash_read(dev, addr, data, nbytes) == 0)
|
2017-05-19 17:16:01 +02:00
|
|
|
return 0;
|
2017-06-14 16:19:02 +02:00
|
|
|
|
|
|
|
for (i = 0; i < sizeof(data); ++i) {
|
2017-07-27 16:53:01 +02:00
|
|
|
if (data[i] != val)
|
2017-06-14 16:19:02 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
addr += nbytes;
|
|
|
|
len -= nbytes;
|
2017-05-19 17:16:01 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2017-07-27 16:53:01 +02:00
|
|
|
int default_flash_is_zero(struct flash_dev *dev, uint32_t addr)
|
|
|
|
{
|
|
|
|
return default_flash_is_val(dev, addr, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
int default_flash_is_one(struct flash_dev *dev, uint32_t addr)
|
|
|
|
{
|
|
|
|
return default_flash_is_val(dev, addr, 0xff);
|
|
|
|
}
|
|
|
|
|
2017-06-16 15:40:02 +02:00
|
|
|
size_t default_flash_copy(struct flash_dev *dev, uint32_t dst, uint32_t src,
|
|
|
|
size_t len)
|
|
|
|
{
|
|
|
|
uint8_t data[32];
|
|
|
|
size_t nbytes, ret = 0;
|
|
|
|
|
|
|
|
while (len) {
|
|
|
|
nbytes = min(sizeof data, len);
|
|
|
|
|
|
|
|
if (flash_read(dev, src, data, nbytes) == 0)
|
2017-06-23 16:55:45 +02:00
|
|
|
return ret;
|
2017-06-16 15:40:02 +02:00
|
|
|
|
|
|
|
if (flash_write(dev, dst, data, nbytes) == 0)
|
2017-06-23 16:55:45 +02:00
|
|
|
return ret;
|
2017-06-16 15:40:02 +02:00
|
|
|
|
|
|
|
dst += nbytes;
|
|
|
|
src += nbytes;
|
|
|
|
len -= nbytes;
|
|
|
|
ret += nbytes;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2017-05-19 17:26:00 +02:00
|
|
|
void flash_release(struct flash_dev *dev)
|
|
|
|
{
|
|
|
|
if (!dev)
|
|
|
|
return;
|
|
|
|
|
|
|
|
dev->ops->release(dev);
|
|
|
|
}
|
|
|
|
|
2017-04-07 19:35:51 +02:00
|
|
|
size_t flash_get_size(struct flash_dev *dev)
|
|
|
|
{
|
|
|
|
if (!dev)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
return dev->ops->get_size(dev);
|
|
|
|
}
|
|
|
|
|
2017-05-19 15:09:25 +02:00
|
|
|
size_t flash_get_capacity(struct flash_dev *dev)
|
|
|
|
{
|
|
|
|
if (!dev)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
return dev->ops->get_capacity(dev);
|
|
|
|
}
|
|
|
|
|
2017-05-19 18:20:50 +02:00
|
|
|
size_t flash_read(struct flash_dev *dev, uint32_t addr, void *data, size_t len)
|
2017-03-11 12:42:32 +00:00
|
|
|
{
|
|
|
|
if (!dev)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
return dev->ops->read(dev, addr, data, len);
|
|
|
|
}
|
|
|
|
|
2017-05-19 18:20:50 +02:00
|
|
|
size_t flash_write(struct flash_dev *dev, uint32_t addr, const void *data,
|
2017-03-11 12:42:32 +00:00
|
|
|
size_t len)
|
|
|
|
{
|
|
|
|
if (!dev)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
return dev->ops->write(dev, addr, data, len);
|
|
|
|
}
|
|
|
|
|
2017-06-23 16:09:56 +02:00
|
|
|
size_t flash_write0(struct flash_dev *dev, uint32_t addr, size_t len)
|
|
|
|
{
|
|
|
|
uint8_t data[32];
|
|
|
|
size_t nbytes, ret = 0;
|
|
|
|
|
|
|
|
memset(data, 0, 32);
|
|
|
|
|
|
|
|
while (len) {
|
|
|
|
nbytes = min(sizeof data, len);
|
|
|
|
|
|
|
|
if (flash_write(dev, addr, data, nbytes) == 0)
|
2017-06-23 16:55:45 +02:00
|
|
|
return ret;
|
2017-06-23 16:09:56 +02:00
|
|
|
|
|
|
|
addr += nbytes;
|
|
|
|
len -= nbytes;
|
|
|
|
ret += nbytes;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2017-06-16 15:42:08 +02:00
|
|
|
size_t flash_copy(struct flash_dev *dev, uint32_t dst, uint32_t src, size_t len)
|
2017-03-11 12:42:32 +00:00
|
|
|
{
|
|
|
|
if (!dev)
|
2017-06-16 15:42:08 +02:00
|
|
|
return 0;
|
2017-03-11 12:42:32 +00:00
|
|
|
|
2017-05-15 16:07:13 +02:00
|
|
|
return dev->ops->copy(dev, dst, src, len);
|
|
|
|
}
|
|
|
|
|
2017-05-19 17:16:01 +02:00
|
|
|
int flash_is_erased(struct flash_dev *dev, uint32_t addr, size_t len)
|
|
|
|
{
|
|
|
|
if (!dev)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
while (len--) {
|
|
|
|
if (!dev->ops->is_erased(dev, addr))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
++addr;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2017-05-19 17:04:45 +02:00
|
|
|
int flash_erase(struct flash_dev *dev, uint32_t addr, size_t len)
|
2017-05-15 16:07:13 +02:00
|
|
|
{
|
|
|
|
if (!dev)
|
|
|
|
return -1;
|
|
|
|
|
2017-05-19 17:04:45 +02:00
|
|
|
while (len--) {
|
|
|
|
if (dev->ops->erase(dev, addr) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
++addr;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
2017-03-11 12:42:32 +00:00
|
|
|
}
|
2017-07-24 15:05:16 +02:00
|
|
|
|
|
|
|
int flash_sync(struct flash_dev *dev)
|
|
|
|
{
|
|
|
|
if (!dev)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (!dev->ops->sync)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
return dev->ops->sync(dev);
|
|
|
|
}
|