|
@@ -203,6 +203,51 @@ static void nand_select_chip(struct mtd_info *mtd, int chipnr)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * nand_write_byte - [DEFAULT] write single byte to chip
|
|
|
+ * @mtd: MTD device structure
|
|
|
+ * @byte: value to write
|
|
|
+ *
|
|
|
+ * Default function to write a byte to I/O[7:0]
|
|
|
+ */
|
|
|
+static void nand_write_byte(struct mtd_info *mtd, uint8_t byte)
|
|
|
+{
|
|
|
+ struct nand_chip *chip = mtd->priv;
|
|
|
+
|
|
|
+ chip->write_buf(mtd, &byte, 1);
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * nand_write_byte16 - [DEFAULT] write single byte to a chip with width 16
|
|
|
+ * @mtd: MTD device structure
|
|
|
+ * @byte: value to write
|
|
|
+ *
|
|
|
+ * Default function to write a byte to I/O[7:0] on a 16-bit wide chip.
|
|
|
+ */
|
|
|
+static void nand_write_byte16(struct mtd_info *mtd, uint8_t byte)
|
|
|
+{
|
|
|
+ struct nand_chip *chip = mtd->priv;
|
|
|
+ uint16_t word = byte;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * It's not entirely clear what should happen to I/O[15:8] when writing
|
|
|
+ * a byte. The ONFi spec (Revision 3.1; 2012-09-19, Section 2.16) reads:
|
|
|
+ *
|
|
|
+ * When the host supports a 16-bit bus width, only data is
|
|
|
+ * transferred at the 16-bit width. All address and command line
|
|
|
+ * transfers shall use only the lower 8-bits of the data bus. During
|
|
|
+ * command transfers, the host may place any value on the upper
|
|
|
+ * 8-bits of the data bus. During address transfers, the host shall
|
|
|
+ * set the upper 8-bits of the data bus to 00h.
|
|
|
+ *
|
|
|
+ * One user of the write_byte callback is nand_onfi_set_features. The
|
|
|
+ * four parameters are specified to be written to I/O[7:0], but this is
|
|
|
+ * neither an address nor a command transfer. Let's assume a 0 on the
|
|
|
+ * upper I/O lines is OK.
|
|
|
+ */
|
|
|
+ chip->write_buf(mtd, (uint8_t *)&word, 2);
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* nand_write_buf - [DEFAULT] write buffer to chip
|
|
|
* @mtd: MTD device structure
|
|
@@ -2769,6 +2814,7 @@ static int nand_onfi_set_features(struct mtd_info *mtd, struct nand_chip *chip,
|
|
|
int addr, uint8_t *subfeature_param)
|
|
|
{
|
|
|
int status;
|
|
|
+ int i;
|
|
|
|
|
|
if (!chip->onfi_version ||
|
|
|
!(le16_to_cpu(chip->onfi_params.opt_cmd)
|
|
@@ -2776,7 +2822,9 @@ static int nand_onfi_set_features(struct mtd_info *mtd, struct nand_chip *chip,
|
|
|
return -EINVAL;
|
|
|
|
|
|
chip->cmdfunc(mtd, NAND_CMD_SET_FEATURES, addr, -1);
|
|
|
- chip->write_buf(mtd, subfeature_param, ONFI_SUBFEATURE_PARAM_LEN);
|
|
|
+ for (i = 0; i < ONFI_SUBFEATURE_PARAM_LEN; ++i)
|
|
|
+ chip->write_byte(mtd, subfeature_param[i]);
|
|
|
+
|
|
|
status = chip->waitfunc(mtd, chip);
|
|
|
if (status & NAND_STATUS_FAIL)
|
|
|
return -EIO;
|
|
@@ -2793,6 +2841,8 @@ static int nand_onfi_set_features(struct mtd_info *mtd, struct nand_chip *chip,
|
|
|
static int nand_onfi_get_features(struct mtd_info *mtd, struct nand_chip *chip,
|
|
|
int addr, uint8_t *subfeature_param)
|
|
|
{
|
|
|
+ int i;
|
|
|
+
|
|
|
if (!chip->onfi_version ||
|
|
|
!(le16_to_cpu(chip->onfi_params.opt_cmd)
|
|
|
& ONFI_OPT_CMD_SET_GET_FEATURES))
|
|
@@ -2802,7 +2852,8 @@ static int nand_onfi_get_features(struct mtd_info *mtd, struct nand_chip *chip,
|
|
|
memset(subfeature_param, 0, ONFI_SUBFEATURE_PARAM_LEN);
|
|
|
|
|
|
chip->cmdfunc(mtd, NAND_CMD_GET_FEATURES, addr, -1);
|
|
|
- chip->read_buf(mtd, subfeature_param, ONFI_SUBFEATURE_PARAM_LEN);
|
|
|
+ for (i = 0; i < ONFI_SUBFEATURE_PARAM_LEN; ++i)
|
|
|
+ *subfeature_param++ = chip->read_byte(mtd);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -2865,6 +2916,8 @@ static void nand_set_defaults(struct nand_chip *chip, int busw)
|
|
|
chip->block_markbad = nand_default_block_markbad;
|
|
|
if (!chip->write_buf || chip->write_buf == nand_write_buf)
|
|
|
chip->write_buf = busw ? nand_write_buf16 : nand_write_buf;
|
|
|
+ if (!chip->write_byte || chip->write_byte == nand_write_byte)
|
|
|
+ chip->write_byte = busw ? nand_write_byte16 : nand_write_byte;
|
|
|
if (!chip->read_buf || chip->read_buf == nand_read_buf)
|
|
|
chip->read_buf = busw ? nand_read_buf16 : nand_read_buf;
|
|
|
if (!chip->scan_bbt)
|