Merge with git://www.denx.de/git/u-boot.git#testing-USB
[oweals/u-boot.git] / drivers / nand / nand_ecc.c
index dc9db4b4802f4dbcebbd478957010c99c17fc560..f33be9655d36150cefadc990f88a8b4b6cf8f077 100644 (file)
  * under the terms of the GNU General Public License as published by the
  * Free Software Foundation; either version 2 or (at your option) any
  * later version.
- * 
+ *
  * This file is distributed in the hope that it will be useful, but WITHOUT
  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License along
  * with this file; if not, write to the Free Software Foundation, Inc.,
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- * 
+ *
  * As a special exception, if other files instantiate templates or use
  * macros or inline functions from these files, or you compile these
  * files and link them with other works to produce a work based on these
  * covered by the GNU General Public License. However the source code for
  * these files must still be made available in accordance with section (3)
  * of the GNU General Public License.
- * 
+ *
  * This exception does not invalidate any other reasons why a work based on
  * this file might be covered by the GNU General Public License.
  */
 
 #include <common.h>
 
-#if (CONFIG_COMMANDS & CFG_CMD_NAND)
+#if (CONFIG_COMMANDS & CFG_CMD_NAND) && !defined(CFG_NAND_LEGACY)
 
+#include<linux/mtd/mtd.h>
 /*
  * Pre-calculated 256-way 1 byte column parity
  */
@@ -66,7 +67,7 @@ static const u_char nand_ecc_precalc_table[] = {
  * nand_trans_result - [GENERIC] create non-inverted ECC
  * @reg2:      line parity reg 2
  * @reg3:      line parity reg 3
- * @ecc_code:  ecc 
+ * @ecc_code:  ecc
  *
  * Creates non-inverted ECC code from line parity
  */
@@ -74,11 +75,11 @@ static void nand_trans_result(u_char reg2, u_char reg3,
        u_char *ecc_code)
 {
        u_char a, b, i, tmp1, tmp2;
-       
+
        /* Initialize variables */
        a = b = 0x80;
        tmp1 = tmp2 = 0;
-       
+
        /* Calculate first ECC byte */
        for (i = 0; i < 4; i++) {
                if (reg3 & a)           /* LP15,13,11,9 --> ecc_code[0] */
@@ -89,7 +90,7 @@ static void nand_trans_result(u_char reg2, u_char reg3,
                b >>= 1;
                a >>= 1;
        }
-       
+
        /* Calculate second ECC byte */
        b = 0x80;
        for (i = 0; i < 4; i++) {
@@ -101,7 +102,7 @@ static void nand_trans_result(u_char reg2, u_char reg3,
                b >>= 1;
                a >>= 1;
        }
-       
+
        /* Store two of the ECC bytes */
        ecc_code[0] = tmp1;
        ecc_code[1] = tmp2;
@@ -117,28 +118,28 @@ int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code
 {
        u_char idx, reg1, reg2, reg3;
        int j;
-       
+
        /* Initialize variables */
        reg1 = reg2 = reg3 = 0;
        ecc_code[0] = ecc_code[1] = ecc_code[2] = 0;
-       
-       /* Build up column parity */ 
+
+       /* Build up column parity */
        for(j = 0; j < 256; j++) {
-               
+
                /* Get CP0 - CP5 from table */
                idx = nand_ecc_precalc_table[dat[j]];
                reg1 ^= (idx & 0x3f);
-               
+
                /* All bit XOR = 1 ? */
                if (idx & 0x40) {
                        reg3 ^= (u_char) j;
                        reg2 ^= ~((u_char) j);
                }
        }
-       
+
        /* Create non-inverted ECC code from line parity */
        nand_trans_result(reg2, reg3, ecc_code);
-       
+
        /* Calculate final ECC code */
        ecc_code[0] = ~ecc_code[0];
        ecc_code[1] = ~ecc_code[1];
@@ -158,12 +159,12 @@ int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code
 int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc)
 {
        u_char a, b, c, d1, d2, d3, add, bit, i;
-       
-       /* Do error detection */ 
+
+       /* Do error detection */
        d1 = calc_ecc[0] ^ read_ecc[0];
        d2 = calc_ecc[1] ^ read_ecc[1];
        d3 = calc_ecc[2] ^ read_ecc[2];
-       
+
        if ((d1 | d2 | d3) == 0) {
                /* No errors */
                return 0;
@@ -172,7 +173,7 @@ int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_cha
                a = (d1 ^ (d1 >> 1)) & 0x55;
                b = (d2 ^ (d2 >> 1)) & 0x55;
                c = (d3 ^ (d3 >> 1)) & 0x54;
-               
+
                /* Found and will correct single bit error in the data */
                if ((a == 0x55) && (b == 0x55) && (c == 0x54)) {
                        c = 0x80;
@@ -205,8 +206,7 @@ int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_cha
                        a ^= (b << bit);
                        dat[add] = a;
                        return 1;
-               }
-               else {
+               } else {
                        i = 0;
                        while (d1) {
                                if (d1 & 0x01)
@@ -236,7 +236,7 @@ int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_cha
                        }
                }
        }
-       
+
        /* Should never happen */
        return -1;
 }