新路程------hi35516a kernel导入spi flash

来源:互联网 发布:java 网络爬虫demo 编辑:程序博客网 时间:2024/06/07 07:59

  首先找到spi 总线驱动

hifmc100_os.c里


static int __init hifmc100_module_init(void)
{
int result = 0;


result = platform_driver_register(&hifmc100_driver_pltdrv); 这里注册了这个驱动结构体
if (result < 0)
return result;


result = platform_device_register(&hifmc100_device_pltdev);
if (result < 0) {
platform_driver_unregister(&hifmc100_driver_pltdrv);
return result;
}


return result;
}


static struct platform_driver hifmc100_driver_pltdrv = {
.driver.name = "hi_sfc",
.probe = hifmc100_driver_probe,这里有probe函数
.remove = hifmc100_driver_remove,
.shutdown = hifmc100_driver_shutdown,
#ifdef CONFIG_PM
.suspend = hifmc100_driver_suspend,
.resume = hifmc100_driver_resume,
#endif
.driver.owner = THIS_MODULE,
.driver.bus = &platform_bus_type,
};


这个probe里有result = hifmc100_spi_nor_scan(host);


int hifmc100_spi_nor_scan(struct hifmc_host *host)
{
unsigned char cs;
struct mtd_info *mtd = host->mtd;
struct hifmc_spi *spi = host->spi;


FMC_PR(BT_DBG, "\t|*-Start Scan SPI nor flash\n");


mtd->size = 0;


for (cs = 0; cs < CONFIG_SPI_NOR_MAX_CHIP_NUM; cs++)
host->spi[cs].host = host;


if (!hifmc_spi_nor_probe(mtd, spi)) {
#ifndef CONFIG_SPI_NOR_QUIET_TEST
pr_info("Can't find a valid spi nor flash chip.\n");
#endif
goto end;
}


FMC_PR(BT_DBG, "\t||-Initial mtd structure func hook\n");


#ifdef CONFIG_SPI_BLOCK_PROTECT
hifmc100_get_spi_lock_info(host);
#endif
mtd->_erase = hifmc100_reg_erase;
#ifdef HIFMC100_SPI_NOR_SUPPORT_REG_WRITE
mtd->_write = hifmc100_reg_write;
#else
mtd->_write = hifmc100_dma_write;
#endif


#ifdef HIFMC100_SPI_NOR_SUPPORT_REG_READ
mtd->_read = hifmc100_reg_read;
#else
mtd->_read = hifmc100_dma_read;
#endif


end:
FMC_PR(BT_DBG, "\t|*-Found SPI nor flash: %s on %s\n", spi->name,
mtd->name);


return 0;
}
然后到了
int hifmc_spi_nor_probe(struct mtd_info *mtd, struct hifmc_spi *spi)
{
unsigned char ids[MAX_SPI_NOR_ID_LEN], ix, len = 0;
unsigned char cs, chip_num = CONFIG_SPI_NOR_MAX_CHIP_NUM;
unsigned int total = 0;
char buffer[100];
struct spi_nor_info *spiinfo = NULL;
struct hifmc_host *host = MTD_TO_HOST(mtd);


FMC_PR(BT_DBG, "\t||*-Start probe SPI nor flash\n");


host->num_chip = 0;


for (cs = 0; chip_num && (cs < CONFIG_HIFMC_MAX_CS_NUM); cs++) {
if (hifmc_cs_user[cs]) {
FMC_PR(BT_DBG, "\t|||-CS(%d) is occupied\n", cs);
continue;
}


hifmc100_read_ids(spi, cs, ids);


/* can't find spi flash device. */
if (!(ids[0] | ids[1] | ids[2])
|| ((ids[0] & ids[1] & ids[2]) == 0xFF))
continue;


len = sprintf(buffer, "SPI Nor(cs %d) ID: %#x %#x %#x", cs,
ids[0], ids[1], ids[2]);


spiinfo = hifmc_spi_nor_serach_ids(ids);
for (ix = 3; (spiinfo) && (ix < spiinfo->id_len); ix++)
len += sprintf(buffer + len, " %#x", ids[ix]);


if (spiinfo) {
pr_info("%s\n", buffer);
#ifdef CONFIG_SPI_BLOCK_PROTECT
host->mid = ids[0];
FMC_PR(BP_DBG, "Get manufacturer ID: [%#x]\n",
host->mid);
#endif


FMC_PR(BT_DBG, "\t|||-CS-%d found SPI nor flash: %s\n",
cs, spiinfo->name);


spi->name = spiinfo->name;
spi->chipselect = cs;
spi->chipsize = spiinfo->chipsize;
spi->erasesize = spiinfo->erasesize;
spi->addrcycle = spiinfo->addrcycle;
spi->driver = spiinfo->driver;


hifmc_spi_nor_search_rw(spiinfo, spi->read,
HIFMC_SPI_NOR_SUPPORT_READ,
HIFMC_SPI_NOR_SUPPORT_MAX_DUMMY, RW_OP_READ);
FMC_PR(BT_DBG, "\t|||-Save spi->read op cmd:%#x\n",
spi->read->cmd);


hifmc_spi_nor_search_rw(spiinfo, spi->write,
HIFMC_SPI_NOR_SUPPORT_WRITE,
HIFMC_SPI_NOR_SUPPORT_MAX_DUMMY, RW_OP_WRITE);
FMC_PR(BT_DBG, "\t|||-Save spi->write op cmd:%#x\n",
spi->write->cmd);


hifmc_spi_nor_get_erase(spiinfo, spi->erase);
hifmc_map_iftype_and_clock(spi);
FMC_PR(BT_DBG, "\t|||-Save spi->erase op cmd:%#x\n",
spi->erase->cmd);
spi->driver->qe_enable(spi);


/* auto check fmc_addr_mode 3 bytes or 4 bytes */
start_up_addr_mode = GET_FMC_BOOT_MODE;


if (start_up_addr_mode == SPI_NOR_ADDR_MODE_3_BYTES) {
FMC_PR(BT_DBG, "\t|||-start up: 3-Byte mode\n");
spi->driver->entry_4addr(spi, ENABLE);
} else
FMC_PR(BT_DBG, "\t|||-start up: 4-Byte mode\n");


len = 0;
len += sprintf(buffer + len, "Block:%sB ",
ulltostr(spi->erasesize));
len += sprintf(buffer + len, "Chip:%sB ",
ulltostr(spi->chipsize));


pr_info("%sName:\"%s\"\n", buffer, spi->name);


host->num_chip++;
chip_num--;
total += spi->chipsize;
spi++;
hifmc_cs_user[cs]++;
} else
FMC_PR(BT_DBG, "\t|||-CS-%d not found SPI nor flash\n",
cs);
}
if (chip_num == CONFIG_SPI_NOR_MAX_CHIP_NUM)
return 0;


FMC_PR(BT_DBG, "\t||*-End probe SPI nor num: %d\n", host->num_chip);
return host->num_chip;
}
到了
static struct spi_nor_info *hifmc_spi_nor_serach_ids(u_char ids[8])
{
struct spi_nor_info *info = hifmc_spi_nor_info_table;
struct spi_nor_info *fit_info = NULL;


for (; info->name; info++) {
if (memcmp(info->id, ids, info->id_len))
continue;


if ((fit_info == NULL) || (fit_info->id_len < info->id_len))
fit_info = info;
}
return fit_info;
}
然后看这个table
static struct spi_nor_info hifmc_spi_nor_info_table[] = {
/* name id id_len chipsize(Bytes) erasesize */
{
"MX25L25635F", {0xc2, 0x20, 0x19}, 3, _32M, _64K, 3,这个name只要非空即可.id在spec 28页
{
&READ_STD(0, INFINITE, 50),
&READ_FAST(1, INFINITE, 104),
&READ_DUAL(1, INFINITE, 104),
&READ_DUAL_ADDR(1, INFINITE, 104),
#ifndef CONFIG_CLOSE_SPI_8PIN_4IO
&READ_QUAD(1, INFINITE, 104),
&READ_QUAD_ADDR(3, INFINITE, 104),
#endif
0
},


{
&WRITE_STD(0, 256, 104),
0
},


{
&ERASE_SECTOR_64K(0, _64K, 104),
0
},
&spi_driver_mx25l25635e,
}

在Hi3516A_SDK_V1.0.6.0/osdrv/opensource/kernel/linux-3.4.y/drivers/mtd/devices/hisfc350/hisfc350_spi_mx25l25635e.c
struct spi_nor_info {
char *name;
unsigned char id[MAX_SPI_NOR_ID_LEN];
unsigned int id_len;
unsigned long chipsize;等于256/8,看规律是这样
unsigned int erasesize;
unsigned int addrcycle;
struct spi_op *read[MAX_SPI_OP];
struct spi_op *write[MAX_SPI_OP];
struct spi_op *erase[MAX_SPI_OP];
struct spi_drv *driver;
};

原创粉丝点击