2 * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
4 * Copyright (C) 2010-2011 Aleph One Ltd.
6 * Created by Charles Manning <charles@aleph1.co.uk>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
15 #include "nand_chip.h"
17 int nanddrv_initialise(void)
22 static void nanddrv_send_addr(struct nand_chip *this, int page, int offset)
24 this->set_ale(this,1);
26 this->write_cycle(this, offset & 0xff);
27 this->write_cycle(this, (offset>>8) & 0x0f);
31 this->write_cycle(this, page & 0xff);
32 this->write_cycle(this, (page>>8) & 0xff);
33 this->write_cycle(this, (page>>16) & 0xff);
35 this->set_ale(this,0);
38 static void nanddrv_send_cmd(struct nand_chip *this, unsigned char cmd)
40 this->set_cle(this, 1);
41 this->write_cycle(this, cmd);
42 this->set_cle(this, 0);
46 static inline int nanddrv_status_pass(unsigned char status)
48 /* If bit 0 is zero then pass, if 1 then fail */
49 return (status & (1 << 0)) == 0;
52 static inline int nanddrv_status_busy(unsigned char status)
54 /* If bit 6 is zero then busy, if 1 then ready */
55 return (status & (1 << 6)) == 0;
58 static unsigned char nanddrv_get_status(struct nand_chip *this,
63 nanddrv_send_cmd(this, 0x70);
64 status = this->read_cycle(this) & 0xff;
67 while (nanddrv_status_busy(status)) {
68 status = this->read_cycle(this) & 0xff;
73 int nanddrv_read_tr(struct nand_chip *this, int page,
74 struct nanddrv_transfer *tr, int n_tr)
78 unsigned char *buffer;
83 nanddrv_send_cmd(this, 0x00);
84 nanddrv_send_addr(this, page, tr->offset);
85 nanddrv_send_cmd(this, 0x30);
86 status = nanddrv_get_status(this, 1);
87 if(!nanddrv_status_pass(status))
89 nanddrv_send_cmd(this, 0x30);
91 if(this->bus_width_shift == 0) {
92 unsigned char *buffer = tr->buffer;
96 *buffer = this->read_cycle(this);
101 unsigned short *buffer = tr->buffer;
103 ncycles = tr->nbytes >> 1;
105 *buffer = this->read_cycle(this);
114 nanddrv_send_cmd(this, 0x05);
115 nanddrv_send_addr(this, -1, tr->offset);
116 nanddrv_send_cmd(this, 0xE0);
124 * Cmd: 0x80, 5-byte address, data bytes, Cmd: 0x10, wait not busy
126 int nanddrv_write_tr(struct nand_chip *this, int page,
127 struct nanddrv_transfer *tr, int n_tr)
129 unsigned char status;
135 nanddrv_send_cmd(this, 0x80);
136 nanddrv_send_addr(this, page, tr->offset);
138 if(this->bus_width_shift == 0) {
139 unsigned char *buffer = tr->buffer;
141 ncycles = tr->nbytes;
143 this->write_cycle(this, *buffer);
148 unsigned short *buffer = tr->buffer;
150 ncycles = tr->nbytes >> 1;
152 this->write_cycle(this, *buffer);
161 nanddrv_send_cmd(this, 0x85);
162 nanddrv_send_addr(this, -1, tr->offset);
165 if(this->power_check && this->power_check(this) < 0)
168 nanddrv_send_cmd(this, 0x10);
169 status = nanddrv_get_status(this, 1);
170 if(nanddrv_status_pass(status))
177 * Cmd: 0x60, 3-byte address, cmd: 0xD0. Wait not busy.
179 int nanddrv_erase(struct nand_chip *this, int block)
181 unsigned char status;
183 nanddrv_send_cmd(this, 0x60);
184 nanddrv_send_addr(this, block * this->pages_per_block, -1);
186 if(this->power_check && this->power_check(this) < 0)
189 nanddrv_send_cmd(this, 0xD0);
190 status = nanddrv_get_status(this, 1);
191 if(nanddrv_status_pass(status))