153 lines
3.5 KiB
C
153 lines
3.5 KiB
C
#include <stdio.h>
|
|
#include <errno.h>
|
|
#include <fcntl.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/ioctl.h>
|
|
#include <sys/types.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <limits.h>
|
|
#include "pm_flash.h"
|
|
|
|
struct flash_opt *get_nand_opt(void);
|
|
struct flash_opt *get_emmc_opt(void);
|
|
struct flash_opt *get_spi_opt(void);
|
|
|
|
static xmedia_flash_type get_flashtype_by_bootargs(const xmedia_char *bootargs)
|
|
{
|
|
xmedia_s32 i;
|
|
xmedia_flash_type flash_type = PM_FLASH_TYPE_MAX;
|
|
xmedia_char type_str[PM_FLASH_TYPE_MAX][16] = {"sfc:", "nand:", "mmcblk0:"};
|
|
|
|
for (i = 0; i < PM_FLASH_TYPE_MAX; i++) {
|
|
if (strstr((xmedia_char *)bootargs, type_str[i]) != NULL)
|
|
break;
|
|
}
|
|
|
|
flash_type = (xmedia_flash_type)i;
|
|
|
|
return flash_type;
|
|
}
|
|
|
|
static xmedia_flash_type get_flashtype(void)
|
|
{
|
|
xmedia_char bootargs[512];
|
|
FILE *pf;
|
|
|
|
pf = fopen("/proc/cmdline", "r");
|
|
if (pf == XMEDIA_NULL) {
|
|
PM_USR_TRACE(MODULE_DBG_ERR, "Failed to open '/proc/cmdline'.\n");
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
if (XMEDIA_NULL == fgets((xmedia_char *)bootargs, 512, pf)) {
|
|
PM_USR_TRACE(MODULE_DBG_ERR, "Failed to fgets string.\n");
|
|
fclose(pf);
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
fclose(pf);
|
|
|
|
return get_flashtype_by_bootargs(bootargs);
|
|
}
|
|
|
|
struct flash_part_dev *alloc_flash_part(void)
|
|
{
|
|
struct flash_part_dev *part_dev = (struct flash_part_dev *)malloc(sizeof(struct flash_part_dev));
|
|
|
|
if (part_dev == XMEDIA_NULL)
|
|
return XMEDIA_NULL;
|
|
|
|
memset(part_dev, 0, sizeof(struct flash_part_dev));
|
|
|
|
part_dev->flash.flash_type = get_flashtype();
|
|
|
|
if (part_dev->flash.flash_type == PM_FLASH_TYPE_SPI)
|
|
part_dev->part_opt = get_spi_opt();
|
|
else if (part_dev->flash.flash_type == PM_FLASH_TYPE_NAND)
|
|
part_dev->part_opt = get_nand_opt();
|
|
else if (part_dev->flash.flash_type == PM_FLASH_TYPE_EMMC)
|
|
part_dev->part_opt = get_emmc_opt();
|
|
else {
|
|
free(part_dev);
|
|
return XMEDIA_NULL;
|
|
}
|
|
|
|
part_dev->part.flash_type = part_dev->flash.flash_type;
|
|
return part_dev;
|
|
}
|
|
|
|
void free_flash_part(struct flash_part_dev *part_dev)
|
|
{
|
|
free(part_dev);
|
|
}
|
|
|
|
xmedia_s32 flash_open(struct flash_part_dev *part_dev, xmedia_u32 flag)
|
|
{
|
|
if (part_dev->part_opt->open)
|
|
part_dev->part_fd = part_dev->part_opt->open(part_dev, flag);
|
|
|
|
if (part_dev->part_fd == -1)
|
|
return -1;
|
|
else
|
|
return XMEDIA_SUCCESS;
|
|
}
|
|
|
|
xmedia_s32 flash_close(struct flash_part_dev *part_dev)
|
|
{
|
|
if (part_dev->part_opt->close)
|
|
return part_dev->part_opt->close(part_dev);
|
|
|
|
return -1;
|
|
}
|
|
|
|
xmedia_s32 flash_get_info(struct flash_part_dev *part_dev)
|
|
{
|
|
xmedia_s32 ret = XMEDIA_FAILURE;
|
|
|
|
if (part_dev->part_opt->get_info)
|
|
ret = part_dev->part_opt->get_info(part_dev);
|
|
|
|
return ret;
|
|
}
|
|
|
|
xmedia_s32 flash_read(struct flash_part_dev *part_dev, xmedia_u32 addr, xmedia_u32 size, xmedia_char *buf)
|
|
{
|
|
xmedia_s32 ret = XMEDIA_FAILURE;
|
|
|
|
if (part_dev->part_opt->read)
|
|
ret = part_dev->part_opt->read(part_dev, addr, size, buf);
|
|
|
|
return ret;
|
|
}
|
|
|
|
xmedia_s32 flash_write(struct flash_part_dev *part_dev, xmedia_u32 addr, xmedia_u32 size, xmedia_char *buf)
|
|
{
|
|
xmedia_s32 ret = XMEDIA_FAILURE;
|
|
|
|
if (part_dev->part_opt->write)
|
|
ret = part_dev->part_opt->write(part_dev, addr, size, buf);
|
|
|
|
return ret;
|
|
}
|
|
|
|
xmedia_s32 flash_erase(struct flash_part_dev *part_dev, xmedia_u32 addr, xmedia_u32 size)
|
|
{
|
|
xmedia_s32 ret = XMEDIA_FAILURE;
|
|
|
|
if (part_dev->part_opt->erase)
|
|
ret = part_dev->part_opt->erase(part_dev, addr, size);
|
|
|
|
return ret;
|
|
}
|
|
|
|
xmedia_s32 flash_init(struct flash_part_dev *part_dev)
|
|
{
|
|
xmedia_s32 ret = XMEDIA_FAILURE;
|
|
|
|
if (part_dev->part_opt->init)
|
|
ret = part_dev->part_opt->init(part_dev);
|
|
|
|
return ret;
|
|
} |