static int nand_erase_block(uffs_Device *dev, u32 block)
{
	u8 val = 0;
	struct my_nand_chip *chip = (struct my_nand_chip *) dev->attr->_private;

	CHIP_CLR_NCS(chip);

	CHIP_SET_CLE(chip);
	WRITE_COMMAND(chip, NAND_CMD_ERASE1);
	CHIP_CLR_CLE(chip);
	CHIP_SET_ALE(chip);
	WRITE_ERASE_ADDR(chip, blcok);
	CHIP_CLR_ALE(chip);
	CHIP_SET_CLE(chip);
	WRITE_COMMAND(chip, NAND_CMD_ERASE2);
	WRITE_COMMAND(chip, NAND_CMD_STATUS);
	CHIP_CLR_CLE(chip);
	CHIP_READY(chip);
	READ_DATA(chip, &val, 1);

	CHIP_SET_NCS(chip);

	val = val; // just for eliminating warning

	return PARSE_STATUS(val);
}
예제 #2
0
static int nand_read_page(uffs_Device *dev, u32 block, u32 page, u8 *data, int data_len, u8 *ecc,
						u8 *spare, int spare_len)
{
	u8 val = 0;
	int ret = UFFS_FLASH_NO_ERR;
	struct my_nand_chip *chip = (struct my_nand_chip *) dev->attr->_private;

	CHIP_CLR_NCS(chip);
	if (data && data_len > 0) {
		CHIP_SET_CLE(chip);
		WRITE_COMMAND(chip, NAND_CMD_READ0);
		CHIP_CLR_CLE(chip);
		CHIP_SET_ALE(chip);
		WRITE_DATA_ADDR(chip, block, page, 0);
		CHIP_CLR_ALE(chip);
		READ_DATA(chip, data, data_len);

		// for now, we return all 0xFF to pass UFFS mount, you should remove this at your driver
		memset(data, 0xFF, data_len);
	}

	if (spare && spare_len > 0) {
		CHIP_SET_CLE(chip);
		WRITE_COMMAND(chip, NAND_CMD_READOOB);
		CHIP_CLR_CLE(chip);
		CHIP_SET_ALE(chip);
		WRITE_DATA_ADDR(chip, block, page, dev->attr->page_data_size);
		CHIP_CLR_ALE(chip);
		READ_DATA(chip, spare, spare_len);

		// for now, we return all 0xFF to pass UFFS mount, you should remove this at your driver
		memset(spare, 0xFF, spare_len);
	}

	if (data == NULL && spare == NULL) {
		// read bad block mark
		CHIP_SET_CLE(chip);
		WRITE_COMMAND(chip, NAND_CMD_READOOB);
		CHIP_CLR_CLE(chip);
		CHIP_SET_ALE(chip);
		WRITE_DATA_ADDR(chip, block, page, dev->attr->page_data_size + attr->block_status_offs);
		CHIP_CLR_ALE(chip);
		READ_DATA(chip, &val, 1);
		ret = (val == 0xFF ? UFFS_FLASH_NO_ERR : UFFS_FLASH_BAD_BLK);

		// for now, we return UFFS_FLASH_NO_ERR to pass UFFS mount, you should remove this at your driver
		ret = UFFS_FLASH_NO_ERR;
	}

	CHIP_SET_NCS(chip);

	return ret;
}
예제 #3
0
static int nand_write_page(uffs_Device *dev, u32 block, u32 page,
							const u8 *data, int data_len, const u8 *spare, int spare_len)
{
	u8 val = 0;
	int ret = UFFS_FLASH_NO_ERR;
	UBOOL fall_through = FALSE;
	struct my_nand_chip *chip = (struct my_nand_chip *) dev->attr->_private;

	CHIP_CLR_NCS(chip);

	if (data && data_len > 0) {
		CHIP_SET_CLE(chip);
		WRITE_COMMAND(chip, NAND_CMD_READ0);
		WRITE_COMMAND(chip, NAND_CMD_SEQIN);
		CHIP_CLR_CLE(chip);
		CHIP_SET_ALE(chip);
		WRITE_DATA_ADDR(chip, block, page, 0);
		CHIP_CLR_ALE(chip);
		CHIP_BUSY(chip);
		WRITE_DATA(chip, data, data_len);
		if (data_len == dev->attr->page_data_size)
			fall_through = U_TRUE;
		else {
			CHIP_SET_CLE(chip);
			WRITE_COMMAND(chip, NAND_CMD_PAGEPROG);
			WRITE_COMMAND(chip, NAND_CMD_STATUS);
			CHIP_CLR_CLE(chip);
			CHIP_READY(chip);
			READ_DATA(chip, &val, 1);
			ret = PARSE_STATUS(val);
		}
	}

	if (ret != UFFS_FLASH_NO_ERR)
		goto ext;

	if (spare && spare_len > 0) {
		if (!fall_through) {
			CHIP_SET_CLE(chip);
			WRITE_COMMAND(chip, NAND_CMD_READOOB);
			WRITE_COMMAND(chip, NAND_CMD_SEQIN);
			CHIP_CLR_CLE(chip);
			CHIP_SET_ALE(chip);
			WRITE_DATA_ADDR(chip, block, page, dev->attr->page_data_size);
			CHIP_CLR_ALE(chip);
			CHIP_BUSY(chip);
		}
		WRITE_DATA(chip, spare, spare_len);
		CHIP_SET_CLE(chip);
		WRITE_COMMAND(chip, NAND_CMD_PAGEPROG);
		WRITE_COMMAND(chip, NAND_CMD_STATUS);
		CHIP_CLR_CLE(chip);
		CHIP_READY(chip);
		READ_DATA(chip, &val, 1);
		ret = PARSE_STATUS(val);
	}

	if (data == NULL && spare == NULL) {
		// mark bad block
		CHIP_SET_CLE(chip);
		WRITE_COMMAND(chip, NAND_CMD_READOOB);
		WRITE_COMMAND(chip, NAND_CMD_SEQIN);
		CHIP_CLR_CLE(chip);
		CHIP_SET_ALE(chip);
		WRITE_DATA_ADDR(chip, block, page, dev->attr->page_data_size + attr->block_status_offs);
		CHIP_CLR_ALE(chip);
		CHIP_BUSY(chip);
		val = 0;
		WRITE_DATA(chip, &val, 1);
		CHIP_SET_CLE(chip);
		WRITE_COMMAND(chip, NAND_CMD_PAGEPROG);
		WRITE_COMMAND(chip, NAND_CMD_STATUS);
		CHIP_CLR_CLE(chip);
		CHIP_READY(chip);
		READ_DATA(chip, &val, 1);
		ret = PARSE_STATUS(val);
	}

ext:
	CHIP_SET_NCS(chip);

	return ret;
}