/** * au_write_buf - write buffer to chip * @this: NAND chip object * @buf: data buffer * @len: number of bytes to write * * write function for 8bit buswidth
*/ staticvoid au_write_buf(struct nand_chip *this, constvoid *buf, unsignedint len)
{ struct au1550nd_ctx *ctx = chip_to_au_ctx(this); const u8 *p = buf; int i;
for (i = 0; i < len; i++) {
writeb(p[i], ctx->base + MEM_STNAND_DATA);
wmb(); /* drain writebuffer */
}
}
/** * au_read_buf - read chip data into buffer * @this: NAND chip object * @buf: buffer to store date * @len: number of bytes to read * * read function for 8bit buswidth
*/ staticvoid au_read_buf(struct nand_chip *this, void *buf, unsignedint len)
{ struct au1550nd_ctx *ctx = chip_to_au_ctx(this);
u8 *p = buf; int i;
for (i = 0; i < len; i++) {
p[i] = readb(ctx->base + MEM_STNAND_DATA);
wmb(); /* drain writebuffer */
}
}
/** * au_write_buf16 - write buffer to chip * @this: NAND chip object * @buf: data buffer * @len: number of bytes to write * * write function for 16bit buswidth
*/ staticvoid au_write_buf16(struct nand_chip *this, constvoid *buf, unsignedint len)
{ struct au1550nd_ctx *ctx = chip_to_au_ctx(this); const u16 *p = buf; unsignedint i;
len >>= 1; for (i = 0; i < len; i++) {
writew(p[i], ctx->base + MEM_STNAND_DATA);
wmb(); /* drain writebuffer */
}
}
/** * au_read_buf16 - read chip data into buffer * @this: NAND chip object * @buf: buffer to store date * @len: number of bytes to read * * read function for 16bit buswidth
*/ staticvoid au_read_buf16(struct nand_chip *this, void *buf, unsignedint len)
{ struct au1550nd_ctx *ctx = chip_to_au_ctx(this); unsignedint i;
u16 *p = buf;
len >>= 1; for (i = 0; i < len; i++) {
p[i] = readw(ctx->base + MEM_STNAND_DATA);
wmb(); /* drain writebuffer */
}
}
timeout_jiffies += msecs_to_jiffies(timeout_ms) + 1; do { if (alchemy_rdsmem(AU1000_MEM_STSTAT) & 0x1) return 0;
usleep_range(10, 100);
} while (time_before(jiffies, timeout_jiffies));
return -ETIMEDOUT;
}
staticint au1550nd_exec_instr(struct nand_chip *this, conststruct nand_op_instr *instr)
{ struct au1550nd_ctx *ctx = chip_to_au_ctx(this); unsignedint i; int ret = 0;
switch (instr->type) { case NAND_OP_CMD_INSTR:
writeb(instr->ctx.cmd.opcode,
ctx->base + MEM_STNAND_CMD); /* Drain the writebuffer */
wmb(); break;
case NAND_OP_ADDR_INSTR: for (i = 0; i < instr->ctx.addr.naddrs; i++) {
writeb(instr->ctx.addr.addrs[i],
ctx->base + MEM_STNAND_ADDR); /* Drain the writebuffer */
wmb();
} break;
case NAND_OP_DATA_IN_INSTR: if ((this->options & NAND_BUSWIDTH_16) &&
!instr->ctx.data.force_8bit)
au_read_buf16(this, instr->ctx.data.buf.in,
instr->ctx.data.len); else
au_read_buf(this, instr->ctx.data.buf.in,
instr->ctx.data.len); break;
case NAND_OP_DATA_OUT_INSTR: if ((this->options & NAND_BUSWIDTH_16) &&
!instr->ctx.data.force_8bit)
au_write_buf16(this, instr->ctx.data.buf.out,
instr->ctx.data.len); else
au_write_buf(this, instr->ctx.data.buf.out,
instr->ctx.data.len); break;
case NAND_OP_WAITRDY_INSTR:
ret = au1550nd_waitrdy(this, instr->ctx.waitrdy.timeout_ms); break; default: return -EINVAL;
}
if (pd->devwidth)
this->options |= NAND_BUSWIDTH_16;
/* * This driver assumes that the default ECC engine should be TYPE_SOFT. * Set ->engine_type before registering the NAND devices in order to * provide a driver specific default value.
*/
this->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
ret = nand_scan(this, 1); if (ret) {
dev_err(&pdev->dev, "NAND scan failed with %d\n", ret); goto out3;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.