Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SUNXI NFC MTD driver #134

Open
wants to merge 1 commit into
base: sunxi-3.4
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions drivers/mtd/nand/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,12 @@ config MTD_NAND_OMAP2
Support for NAND flash on Texas Instruments OMAP2, OMAP3 and OMAP4
platforms.

config MTD_NAND_SUNXI
tristate "NAND Flash device on Allwinner A10"
depends on ARCH_SUN4I
help
Support for NAND flash on Allwinner A10

config MTD_NAND_RICOH
tristate "Ricoh xD card reader"
default n
Expand Down
1 change: 1 addition & 0 deletions drivers/mtd/nand/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,6 @@ obj-$(CONFIG_MTD_NAND_MPC5121_NFC) += mpc5121_nfc.o
obj-$(CONFIG_MTD_NAND_RICOH) += r852.o
obj-$(CONFIG_MTD_NAND_JZ4740) += jz4740_nand.o
obj-$(CONFIG_MTD_NAND_GPMI_NAND) += gpmi-nand/
obj-$(CONFIG_MTD_NAND_SUNXI) += sunxi-nand/

nand-objs := nand_base.o nand_bbt.o
4 changes: 4 additions & 0 deletions drivers/mtd/nand/sunxi-nand/Kbuild
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
obj-$(CONFIG_MTD_NAND_SUNXI) += sunxi_nand.o
sunxi_nand-objs += main.o nfc.o dma.o nand_id.o nand1k.o

ccflags-y = -D__LINUX__
39 changes: 39 additions & 0 deletions drivers/mtd/nand/sunxi-nand/defs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* defs.h
*
* Copyright (C) 2013 Qiang Yu <yuq825@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 program. If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef _SUNXI_DEFS_H
#define _SUNXI_DEFS_H

#define PREFIX "[MTD][NAND][SUNXI]: "

#ifdef __LINUX__

#include <linux/kernel.h>

#define DBG_INFO(fmt, ...) printk(KERN_INFO PREFIX fmt, ##__VA_ARGS__)
#define ERR_INFO(fmt, ...) printk(KERN_ERR PREFIX fmt, ##__VA_ARGS__)

#else /* !__LINUX__ */

#define DBG_INFO(fmt, ...)
#define ERR_INFO(fmt, ...)

#endif

#endif
116 changes: 116 additions & 0 deletions drivers/mtd/nand/sunxi-nand/dma.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
/*
* dma.c
*
* Copyright (C) 2013 Qiang Yu <yuq825@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 program. If not, see <http://www.gnu.org/licenses/>.
*/

#include <mach/dma.h>
#include <linux/wait.h>
#include <linux/sched.h>
#include <asm/cacheflush.h>

#include "defs.h"

static int nanddma_completed_flag = 1;
static DECLARE_WAIT_QUEUE_HEAD(DMA_wait);

static struct sw_dma_client nand_dma_client = {
.name="NAND_DMA",
};

static void nanddma_buffdone(struct sw_dma_chan * ch, void *buf, int size, enum sw_dma_buffresult result)
{
nanddma_completed_flag = 1;
wake_up(&DMA_wait);
//DBG_INFO("buffer done. nanddma_completed_flag: %d\n", nanddma_completed_flag);
}

static int nanddma_opfn(struct sw_dma_chan * ch, enum sw_chan_op op_code)
{
if(op_code == SW_DMAOP_START)
nanddma_completed_flag = 0;

//DBG_INFO("buffer opfn: %d, nanddma_completed_flag: %d\n", (int)op_code, nanddma_completed_flag);

return 0;
}

int dma_nand_request(unsigned int dmatype)
{
int ch;

ch = sw_dma_request(DMACH_DNAND, &nand_dma_client, NULL);
if(ch < 0)
return ch;

sw_dma_set_opfn(ch, nanddma_opfn);
sw_dma_set_buffdone_fn(ch, nanddma_buffdone);

return ch;
}

int dma_nand_release(int hDma)
{
return sw_dma_free(hDma, &nand_dma_client);
}


static int dma_set(int hDMA, void *pArg)
{
sw_dma_setflags(hDMA, SW_DMAF_AUTOSTART);
return sw_dma_config(hDMA, (struct dma_hw_conf*)pArg);
}


static int dma_enqueue(int hDma, unsigned int buff_addr, size_t len)
{
static int seq=0;
__cpuc_flush_dcache_area((void *)buff_addr, len + (1 << 5) * 2 - 2);
nanddma_completed_flag = 0;
return sw_dma_enqueue(hDma, (void*)(seq++), buff_addr, len);
}

void dma_nand_config_start(int dma, int rw, unsigned int buff_addr, size_t len)
{
struct dma_hw_conf nand_hwconf = {
.xfer_type = DMAXFER_D_BWORD_S_BWORD,
.hf_irq = SW_DMA_IRQ_FULL,
.cmbk = 0x7f077f07,
};

nand_hwconf.dir = rw + 1;

if(rw == 0) {
nand_hwconf.from = 0x01C03030,
nand_hwconf.address_type = DMAADDRT_D_LN_S_IO,
nand_hwconf.drqsrc_type = DRQ_TYPE_NAND;
}
else {
nand_hwconf.to = 0x01C03030,
nand_hwconf.address_type = DMAADDRT_D_IO_S_LN,
nand_hwconf.drqdst_type = DRQ_TYPE_NAND;
}

dma_set(dma, (void*)&nand_hwconf);
dma_enqueue(dma, buff_addr, len);
}

int dma_nand_wait_finish(void)
{
wait_event(DMA_wait, nanddma_completed_flag);
return 0;
}

29 changes: 29 additions & 0 deletions drivers/mtd/nand/sunxi-nand/dma.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* dma.h
*
* Copyright (C) 2013 Qiang Yu <yuq825@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 program. If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef _SUNXI_NAND_DMA_H
#define _SUNXI_NAND_DMA_H

int dma_nand_request(unsigned int dmatype);
int dma_nand_release(int hDma);
void dma_nand_config_start(int dma, int rw, unsigned int buff_addr, size_t len);
int dma_nand_wait_finish(void);

#endif