1/* 2 * Copyright 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> 3 * 4 * OF helpers for mtd. 5 * 6 * This file is released under the GPLv2 7 * 8 */ 9#include <linux/kernel.h> 10#include <linux/of_mtd.h> 11#include <linux/mtd/nand.h> 12#include <linux/export.h> 13 14/** 15 * It maps 'enum nand_ecc_modes_t' found in include/linux/mtd/nand.h 16 * into the device tree binding of 'nand-ecc', so that MTD 17 * device driver can get nand ecc from device tree. 18 */ 19static const char *nand_ecc_modes[] = { 20 [NAND_ECC_NONE] = "none", 21 [NAND_ECC_SOFT] = "soft", 22 [NAND_ECC_HW] = "hw", 23 [NAND_ECC_HW_SYNDROME] = "hw_syndrome", 24 [NAND_ECC_HW_OOB_FIRST] = "hw_oob_first", 25 [NAND_ECC_SOFT_BCH] = "soft_bch", 26}; 27 28/** 29 * of_get_nand_ecc_mode - Get nand ecc mode for given device_node 30 * @np: Pointer to the given device_node 31 * 32 * The function gets ecc mode string from property 'nand-ecc-mode', 33 * and return its index in nand_ecc_modes table, or errno in error case. 34 */ 35int of_get_nand_ecc_mode(struct device_node *np) 36{ 37 const char *pm; 38 int err, i; 39 40 err = of_property_read_string(np, "nand-ecc-mode", &pm); 41 if (err < 0) 42 return err; 43 44 for (i = 0; i < ARRAY_SIZE(nand_ecc_modes); i++) 45 if (!strcasecmp(pm, nand_ecc_modes[i])) 46 return i; 47 48 return -ENODEV; 49} 50EXPORT_SYMBOL_GPL(of_get_nand_ecc_mode); 51 52/** 53 * of_get_nand_ecc_step_size - Get ECC step size associated to 54 * the required ECC strength (see below). 55 * @np: Pointer to the given device_node 56 * 57 * return the ECC step size, or errno in error case. 58 */ 59int of_get_nand_ecc_step_size(struct device_node *np) 60{ 61 int ret; 62 u32 val; 63 64 ret = of_property_read_u32(np, "nand-ecc-step-size", &val); 65 return ret ? ret : val; 66} 67EXPORT_SYMBOL_GPL(of_get_nand_ecc_step_size); 68 69/** 70 * of_get_nand_ecc_strength - Get required ECC strength over the 71 * correspnding step size as defined by 'nand-ecc-size' 72 * @np: Pointer to the given device_node 73 * 74 * return the ECC strength, or errno in error case. 75 */ 76int of_get_nand_ecc_strength(struct device_node *np) 77{ 78 int ret; 79 u32 val; 80 81 ret = of_property_read_u32(np, "nand-ecc-strength", &val); 82 return ret ? ret : val; 83} 84EXPORT_SYMBOL_GPL(of_get_nand_ecc_strength); 85 86/** 87 * of_get_nand_bus_width - Get nand bus witdh for given device_node 88 * @np: Pointer to the given device_node 89 * 90 * return bus width option, or errno in error case. 91 */ 92int of_get_nand_bus_width(struct device_node *np) 93{ 94 u32 val; 95 96 if (of_property_read_u32(np, "nand-bus-width", &val)) 97 return 8; 98 99 switch(val) { 100 case 8: 101 case 16: 102 return val; 103 default: 104 return -EIO; 105 } 106} 107EXPORT_SYMBOL_GPL(of_get_nand_bus_width); 108 109/** 110 * of_get_nand_on_flash_bbt - Get nand on flash bbt for given device_node 111 * @np: Pointer to the given device_node 112 * 113 * return true if present false other wise 114 */ 115bool of_get_nand_on_flash_bbt(struct device_node *np) 116{ 117 return of_property_read_bool(np, "nand-on-flash-bbt"); 118} 119EXPORT_SYMBOL_GPL(of_get_nand_on_flash_bbt); 120