2 * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
4 * Copyright (C) 2002-2018 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)
82 nanddrv_send_cmd(this, 0x00);
83 nanddrv_send_addr(this, page, tr->offset);
84 nanddrv_send_cmd(this, 0x30);
85 status = nanddrv_get_status(this, 1);
86 if(!nanddrv_status_pass(status))
88 nanddrv_send_cmd(this, 0x30);
90 if(this->bus_width_shift == 0) {
91 unsigned char *buffer = tr->buffer;
95 *buffer = this->read_cycle(this);
100 unsigned short *buffer = (unsigned short *)tr->buffer;
102 ncycles = tr->nbytes >> 1;
104 *buffer = this->read_cycle(this);
113 nanddrv_send_cmd(this, 0x05);
114 nanddrv_send_addr(this, -1, tr->offset);
115 nanddrv_send_cmd(this, 0xE0);
123 * Cmd: 0x80, 5-byte address, data bytes, Cmd: 0x10, wait not busy
125 int nanddrv_write_tr(struct nand_chip *this, int page,
126 struct nanddrv_transfer *tr, int n_tr)
128 unsigned char status;
134 nanddrv_send_cmd(this, 0x80);
135 nanddrv_send_addr(this, page, tr->offset);
137 if(this->bus_width_shift == 0) {
138 unsigned char *buffer = tr->buffer;
140 ncycles = tr->nbytes;
142 this->write_cycle(this, *buffer);
147 unsigned short *buffer = (unsigned short *)tr->buffer;
149 ncycles = tr->nbytes >> 1;
151 this->write_cycle(this, *buffer);
160 nanddrv_send_cmd(this, 0x85);
161 nanddrv_send_addr(this, -1, tr->offset);
164 if(this->power_check && this->power_check(this) < 0)
167 nanddrv_send_cmd(this, 0x10);
168 status = nanddrv_get_status(this, 1);
169 if(nanddrv_status_pass(status))
176 * Cmd: 0x60, 3-byte address, cmd: 0xD0. Wait not busy.
178 int nanddrv_erase(struct nand_chip *this, int block)
180 unsigned char status;
182 nanddrv_send_cmd(this, 0x60);
183 nanddrv_send_addr(this, block * this->pages_per_block, -1);
185 if(this->power_check && this->power_check(this) < 0)
188 nanddrv_send_cmd(this, 0xD0);
189 status = nanddrv_get_status(this, 1);
190 if(nanddrv_status_pass(status))