Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
arch
cris
arch-v32
drivers
mach-a3
nandflash.c
Go to the documentation of this file.
1
/*
2
* arch/cris/arch-v32/drivers/nandflash.c
3
*
4
* Copyright (c) 2007
5
*
6
* Derived from drivers/mtd/nand/spia.c
7
* Copyright (C) 2000 Steven J. Hill (
[email protected]
)
8
*
9
* This program is free software; you can redistribute it and/or modify
10
* it under the terms of the GNU General Public License version 2 as
11
* published by the Free Software Foundation.
12
*
13
*/
14
15
#include <linux/slab.h>
16
#include <
linux/init.h
>
17
#include <linux/module.h>
18
#include <
linux/mtd/mtd.h
>
19
#include <
linux/mtd/nand.h
>
20
#include <
linux/mtd/partitions.h
>
21
#include <arch/memmap.h>
22
#include <hwregs/reg_map.h>
23
#include <
hwregs/reg_rdwr.h
>
24
#include <
hwregs/pio_defs.h
>
25
#include <pinmux.h>
26
#include <asm/io.h>
27
28
#define MANUAL_ALE_CLE_CONTROL 1
29
30
#define regf_ALE a0
31
#define regf_CLE a1
32
#define regf_NCE ce0_n
33
34
#define CLE_BIT 10
35
#define ALE_BIT 11
36
#define CE_BIT 12
37
38
struct
mtd_info_wrapper
{
39
struct
mtd_info
info
;
40
struct
nand_chip
chip
;
41
};
42
43
/* Bitmask for control pins */
44
#define PIN_BITMASK ((1 << CE_BIT) | (1 << CLE_BIT) | (1 << ALE_BIT))
45
46
static
struct
mtd_info
*crisv32_mtd;
47
/*
48
* hardware specific access to control-lines
49
*/
50
static
void
crisv32_hwcontrol(
struct
mtd_info
*mtd,
int
cmd
,
51
unsigned
int
ctrl
)
52
{
53
unsigned
long
flags
;
54
reg_pio_rw_dout
dout
;
55
struct
nand_chip
*
this
= mtd->
priv
;
56
57
local_irq_save
(flags);
58
59
/* control bits change */
60
if
(ctrl &
NAND_CTRL_CHANGE
) {
61
dout =
REG_RD
(
pio
,
regi_pio
, rw_dout);
62
dout.regf_NCE = (ctrl &
NAND_NCE
) ? 0 : 1;
63
64
#if !MANUAL_ALE_CLE_CONTROL
65
if
(ctrl &
NAND_ALE
) {
66
/* A0 = ALE high */
67
this->
IO_ADDR_W
= (
void
__iomem
*)
REG_ADDR
(
pio
,
68
regi_pio
, rw_io_access1);
69
}
else
if
(ctrl &
NAND_CLE
) {
70
/* A1 = CLE high */
71
this->
IO_ADDR_W
= (
void
__iomem
*)
REG_ADDR
(
pio
,
72
regi_pio
, rw_io_access2);
73
}
else
{
74
/* A1 = CLE and A0 = ALE low */
75
this->
IO_ADDR_W
= (
void
__iomem
*)
REG_ADDR
(
pio
,
76
regi_pio
, rw_io_access0);
77
}
78
#else
79
80
dout.regf_CLE = (ctrl &
NAND_CLE
) ? 1 : 0;
81
dout.regf_ALE = (ctrl &
NAND_ALE
) ? 1 : 0;
82
#endif
83
REG_WR
(
pio
,
regi_pio
, rw_dout, dout);
84
}
85
86
/* command to chip */
87
if
(cmd !=
NAND_CMD_NONE
)
88
writeb
(cmd, this->
IO_ADDR_W
);
89
90
local_irq_restore
(flags);
91
}
92
93
/*
94
* read device ready pin
95
*/
96
static
int
crisv32_device_ready(
struct
mtd_info
*mtd)
97
{
98
reg_pio_r_din
din =
REG_RD
(
pio
,
regi_pio
, r_din);
99
return
din.
rdy
;
100
}
101
102
/*
103
* Main initialization routine
104
*/
105
struct
mtd_info
*
__init
crisv32_nand_flash_probe
(
void
)
106
{
107
void
__iomem
*read_cs;
108
void
__iomem
*write_cs;
109
110
struct
mtd_info_wrapper
*wrapper;
111
struct
nand_chip
*
this
;
112
int
err
= 0;
113
114
reg_pio_rw_man_ctrl
man_ctrl = {
115
.regf_NCE =
regk_pio_yes
,
116
#if MANUAL_ALE_CLE_CONTROL
117
.regf_ALE =
regk_pio_yes
,
118
.regf_CLE =
regk_pio_yes
119
#endif
120
};
121
reg_pio_rw_oe
oe = {
122
.regf_NCE =
regk_pio_yes
,
123
#if MANUAL_ALE_CLE_CONTROL
124
.regf_ALE =
regk_pio_yes
,
125
.regf_CLE =
regk_pio_yes
126
#endif
127
};
128
reg_pio_rw_dout
dout
= { .regf_NCE = 1 };
129
130
/* Allocate pio pins to pio */
131
crisv32_pinmux_alloc_fixed
(
pinmux_pio
);
132
/* Set up CE, ALE, CLE (ce0_n, a0, a1) for manual control and output */
133
REG_WR
(
pio
,
regi_pio
, rw_man_ctrl, man_ctrl);
134
REG_WR
(
pio
,
regi_pio
, rw_dout, dout);
135
REG_WR
(
pio
,
regi_pio
, rw_oe, oe);
136
137
/* Allocate memory for MTD device structure and private data */
138
wrapper = kzalloc(
sizeof
(
struct
mtd_info_wrapper
),
GFP_KERNEL
);
139
if
(!wrapper) {
140
printk
(
KERN_ERR
"Unable to allocate CRISv32 NAND MTD "
141
"device structure.\n"
);
142
err = -
ENOMEM
;
143
return
NULL
;
144
}
145
146
read_cs = write_cs = (
void
__iomem
*)
REG_ADDR
(
pio
,
regi_pio
,
147
rw_io_access0);
148
149
/* Get pointer to private data */
150
this
= &wrapper->
chip
;
151
crisv32_mtd = &wrapper->
info
;
152
153
/* Link the private data with the MTD structure */
154
crisv32_mtd->
priv
=
this
;
155
156
/* Set address of NAND IO lines */
157
this->
IO_ADDR_R
= read_cs;
158
this->
IO_ADDR_W
= write_cs;
159
this->
cmd_ctrl
= crisv32_hwcontrol;
160
this->
dev_ready
= crisv32_device_ready;
161
/* 20 us command delay time */
162
this->
chip_delay
= 20;
163
this->
ecc
.mode =
NAND_ECC_SOFT
;
164
165
/* Enable the following for a flash based bad block table */
166
/* this->bbt_options = NAND_BBT_USE_FLASH; */
167
168
/* Scan to find existence of the device */
169
if
(
nand_scan
(crisv32_mtd, 1)) {
170
err = -
ENXIO
;
171
goto
out_mtd;
172
}
173
174
return
crisv32_mtd;
175
176
out_mtd:
177
kfree
(wrapper);
178
return
NULL
;
179
}
180
Generated on Thu Jan 10 2013 13:05:16 for Linux Kernel by
1.8.2