|
@@ -165,49 +165,16 @@
|
|
|
|
|
|
#define NFC_MAX_CS 7
|
|
|
|
|
|
-/*
|
|
|
- * Ready/Busy detection type: describes the Ready/Busy detection modes
|
|
|
- *
|
|
|
- * @RB_NONE: no external detection available, rely on STATUS command
|
|
|
- * and software timeouts
|
|
|
- * @RB_NATIVE: use sunxi NAND controller Ready/Busy support. The Ready/Busy
|
|
|
- * pin of the NAND flash chip must be connected to one of the
|
|
|
- * native NAND R/B pins (those which can be muxed to the NAND
|
|
|
- * Controller)
|
|
|
- * @RB_GPIO: use a simple GPIO to handle Ready/Busy status. The Ready/Busy
|
|
|
- * pin of the NAND flash chip must be connected to a GPIO capable
|
|
|
- * pin.
|
|
|
- */
|
|
|
-enum sunxi_nand_rb_type {
|
|
|
- RB_NONE,
|
|
|
- RB_NATIVE,
|
|
|
- RB_GPIO,
|
|
|
-};
|
|
|
-
|
|
|
-/*
|
|
|
- * Ready/Busy structure: stores information related to Ready/Busy detection
|
|
|
- *
|
|
|
- * @type: the Ready/Busy detection mode
|
|
|
- * @info: information related to the R/B detection mode. Either a gpio
|
|
|
- * id or a native R/B id (those supported by the NAND controller).
|
|
|
- */
|
|
|
-struct sunxi_nand_rb {
|
|
|
- enum sunxi_nand_rb_type type;
|
|
|
- union {
|
|
|
- int gpio;
|
|
|
- int nativeid;
|
|
|
- } info;
|
|
|
-};
|
|
|
-
|
|
|
/*
|
|
|
* Chip Select structure: stores information related to NAND Chip Select
|
|
|
*
|
|
|
* @cs: the NAND CS id used to communicate with a NAND Chip
|
|
|
- * @rb: the Ready/Busy description
|
|
|
+ * @rb: the Ready/Busy pin ID. -1 means no R/B pin connected to the
|
|
|
+ * NFC
|
|
|
*/
|
|
|
struct sunxi_nand_chip_sel {
|
|
|
u8 cs;
|
|
|
- struct sunxi_nand_rb rb;
|
|
|
+ s8 rb;
|
|
|
};
|
|
|
|
|
|
/*
|
|
@@ -440,30 +407,19 @@ static int sunxi_nfc_dev_ready(struct mtd_info *mtd)
|
|
|
struct nand_chip *nand = mtd_to_nand(mtd);
|
|
|
struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
|
|
|
struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
|
|
|
- struct sunxi_nand_rb *rb;
|
|
|
- int ret;
|
|
|
+ u32 mask;
|
|
|
|
|
|
if (sunxi_nand->selected < 0)
|
|
|
return 0;
|
|
|
|
|
|
- rb = &sunxi_nand->sels[sunxi_nand->selected].rb;
|
|
|
-
|
|
|
- switch (rb->type) {
|
|
|
- case RB_NATIVE:
|
|
|
- ret = !!(readl(nfc->regs + NFC_REG_ST) &
|
|
|
- NFC_RB_STATE(rb->info.nativeid));
|
|
|
- break;
|
|
|
- case RB_GPIO:
|
|
|
- ret = gpio_get_value(rb->info.gpio);
|
|
|
- break;
|
|
|
- case RB_NONE:
|
|
|
- default:
|
|
|
- ret = 0;
|
|
|
+ if (sunxi_nand->sels[sunxi_nand->selected].rb < 0) {
|
|
|
dev_err(nfc->dev, "cannot check R/B NAND status!\n");
|
|
|
- break;
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
- return ret;
|
|
|
+ mask = NFC_RB_STATE(sunxi_nand->sels[sunxi_nand->selected].rb);
|
|
|
+
|
|
|
+ return !!(readl(nfc->regs + NFC_REG_ST) & mask);
|
|
|
}
|
|
|
|
|
|
static void sunxi_nfc_select_chip(struct mtd_info *mtd, int chip)
|
|
@@ -488,12 +444,11 @@ static void sunxi_nfc_select_chip(struct mtd_info *mtd, int chip)
|
|
|
|
|
|
ctl |= NFC_CE_SEL(sel->cs) | NFC_EN |
|
|
|
NFC_PAGE_SHIFT(nand->page_shift);
|
|
|
- if (sel->rb.type == RB_NONE) {
|
|
|
+ if (sel->rb < 0) {
|
|
|
nand->dev_ready = NULL;
|
|
|
} else {
|
|
|
nand->dev_ready = sunxi_nfc_dev_ready;
|
|
|
- if (sel->rb.type == RB_NATIVE)
|
|
|
- ctl |= NFC_RB_SEL(sel->rb.info.nativeid);
|
|
|
+ ctl |= NFC_RB_SEL(sel->rb);
|
|
|
}
|
|
|
|
|
|
writel(mtd->writesize, nfc->regs + NFC_REG_SPARE_AREA);
|
|
@@ -1946,26 +1901,10 @@ static int sunxi_nand_chip_init(struct device *dev, struct sunxi_nfc *nfc,
|
|
|
chip->sels[i].cs = tmp;
|
|
|
|
|
|
if (!of_property_read_u32_index(np, "allwinner,rb", i, &tmp) &&
|
|
|
- tmp < 2) {
|
|
|
- chip->sels[i].rb.type = RB_NATIVE;
|
|
|
- chip->sels[i].rb.info.nativeid = tmp;
|
|
|
- } else {
|
|
|
- ret = of_get_named_gpio(np, "rb-gpios", i);
|
|
|
- if (ret >= 0) {
|
|
|
- tmp = ret;
|
|
|
- chip->sels[i].rb.type = RB_GPIO;
|
|
|
- chip->sels[i].rb.info.gpio = tmp;
|
|
|
- ret = devm_gpio_request(dev, tmp, "nand-rb");
|
|
|
- if (ret)
|
|
|
- return ret;
|
|
|
-
|
|
|
- ret = gpio_direction_input(tmp);
|
|
|
- if (ret)
|
|
|
- return ret;
|
|
|
- } else {
|
|
|
- chip->sels[i].rb.type = RB_NONE;
|
|
|
- }
|
|
|
- }
|
|
|
+ tmp < 2)
|
|
|
+ chip->sels[i].rb = tmp;
|
|
|
+ else
|
|
|
+ chip->sels[i].rb = -1;
|
|
|
}
|
|
|
|
|
|
nand = &chip->nand;
|