summaryrefslogtreecommitdiff
path: root/drivers/mtd/nand/gpmi-nfc/gpmi-nfc.h
blob: 6f14b73dd93db80921796565661cbc7bfec9c831 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
/*
 * Freescale GPMI NFC NAND Flash Driver
 *
 * Copyright (C) 2010 Freescale Semiconductor, Inc.
 * Copyright (C) 2008 Embedded Alley Solutions, Inc.
 *
 * 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 2 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, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#ifndef __DRIVERS_MTD_NAND_GPMI_NFC_H
#define __DRIVERS_MTD_NAND_GPMI_NFC_H

/* Linux header files. */

#include <linux/err.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/io.h>
#include <linux/interrupt.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/concat.h>
#include <linux/gpmi-nfc.h>
#include <asm/sizes.h>

/* Platform header files. */

#include <mach/system.h>
#include <mach/dmaengine.h>
#include <mach/device.h>
#include <mach/clock.h>

/* Driver header files. */

#include "../nand_device_info.h"

/*
 *------------------------------------------------------------------------------
 * Fundamental Macros
 *------------------------------------------------------------------------------
 */

/* Define this macro to enable detailed information messages. */

#define DETAILED_INFO

/* Define this macro to enable event reporting. */

/*#define EVENT_REPORTING*/

/*
 *------------------------------------------------------------------------------
 * Fundamental Data Structures
 *------------------------------------------------------------------------------
 */

/**
 * struct resources - The collection of resources the driver needs.
 *
 * @gpmi_regs:         A pointer to the GPMI registers.
 * @bch_regs:          A pointer to the BCH registers.
 * @bch_interrupt:     The BCH interrupt number.
 * @dma_low_channel:   The low  DMA channel.
 * @dma_high_channel:  The high DMA channel.
 * @dma_interrupt:     The DMA interrupt number.
 * @clock:             A pointer to the struct clk for the NFC's clock.
 */

struct resources {
	void          *gpmi_regs;
	void          *bch_regs;
	unsigned int  bch_interrupt;
	unsigned int  dma_low_channel;
	unsigned int  dma_high_channel;
	unsigned int  dma_interrupt;
	struct clk    *clock;
};

/**
 * struct mil - State for the MTD Interface Layer.
 *
 * @nand:                    The NAND Flash MTD data structure that represents
 *                           the NAND Flash medium.
 * @mtd:                     The MTD data structure that represents the NAND
 *                           Flash medium.
 * @oob_layout:              A structure that describes how bytes are laid out
 *                           in the OOB.
 * @general_use_mtd:         A pointer to an MTD we export for general use.
 *                           This *may* simply be a pointer to the mtd field, if
 *                           we've been instructed NOT to protect the boot
 *                           areas.
 * @partitions:              A pointer to a set of partitions applied to the
 *                           general use MTD.
 * @partition_count:         The number of partitions.
 * @ubi_partition_memory:    If not NULL, a block of memory used to create a set
 *                           of partitions that help with the problem that UBI
 *                           can't handle an MTD larger than 2GiB.
 * @current_chip:            The chip currently selected by the NAND Fash MTD
 *                           code. A negative value indicates that no chip is
 *                           selected.
 * @command_length:          The length of the command that appears in the
 *                           command buffer (see cmd_virt, below).
 * @inject_ecc_error:        Indicates the driver should inject a "fake" ECC
 *                           error into the next read operation that uses ECC.
 *                           User space programs can set this value through the
 *                           sysfs node of the same name. If this value is less
 *                           than zero, the driver will inject an uncorrectable
 *                           ECC error. If this value is greater than zero, the
 *                           driver will inject that number of correctable
 *                           errors, capped by the maximum possible number of
 *                           errors that could appear in a single read.
 * @ignore_bad_block_marks:  Indicates we are ignoring bad block marks.
 * @saved_bbt:               A saved pointer to the in-memory NAND Flash MTD bad
 *                           block table. See show_device_ignorebad() for more
 *                           details.
 * @raw_oob_mode:            Indicates the OOB is to be read/written in "raw"
 *                           mode. See mil_ecc_read_oob() for details.
 * @hooked_read_oob:         A pointer to the ecc.read_oob() function we
 *                           "hooked." See mil_ecc_read_oob() for details.
 * @hooked_write_oob:        A pointer to the ecc.write_oob() function pointer
 *                           we "hooked." See mil_ecc_read_oob() for details.
 * @marking_a_bad_block:     Indicates the caller is marking a bad block. See
 *                           mil_ecc_write_oob() for details.
 * @hooked_block_markbad:    A pointer to the block_markbad() function we
 *                           we "hooked." See mil_ecc_write_oob() for details.
 * @cmd_virt:                A pointer to a DMA-coherent buffer in which we
 *                           accumulate command bytes before we give them to the
 *                           NFC layer. See mil_cmd_ctrl() for more details.
 * @cmd_phys:                The physical address for the cmd_virt buffer.
 * @page_buffer_virt:        A pointer to a DMA-coherent buffer we use for
 *                           reading and writing pages. This buffer includes
 *                           space for both the payload data and the auxiliary
 *                           data (including status bytes, but not syndrome
 *                           bytes).
 * @page_buffer_phys:        The physical address for the page_buffer_virt
 *                           buffer.
 * @page_buffer_size:        The size of the page buffer.
 * @payload_virt:            A pointer to a location in the page buffer used
 *                           for payload bytes. The size of this buffer is
 *                           determined by struct nfc_geometry.
 * @payload_phys:            The physical address for payload_virt.
 * @payload_size:            The size of the payload area in the page buffer.
 * @auxiliary_virt:          A pointer to a location in the page buffer used
 *                           for auxiliary bytes. The size of this buffer is
 *                           determined by struct nfc_geometry.
 * @auxiliary_phys:          The physical address for auxiliary_virt.
 * @auxiliary_size:          The size of the auxiliary area in the page buffer.
 */

#define MIL_COMMAND_BUFFER_SIZE (10)

struct mil {

	/* MTD Data Structures */

	struct nand_chip       nand;
	struct mtd_info        mtd;
	struct nand_ecclayout  oob_layout;

	/* Partitioning and Boot Area Protection */

	struct mtd_info        *general_use_mtd;
	struct mtd_partition   *partitions;
	unsigned int           partition_count;
	void                   *ubi_partition_memory;

	/* General-use Variables */

	int                    current_chip;
	unsigned int           command_length;
	int                    inject_ecc_error;
	int                    ignore_bad_block_marks;
	void                   *saved_bbt;

	/* MTD Function Pointer Hooks */

	int                    raw_oob_mode;
	int                    (*hooked_read_oob)(struct mtd_info *mtd,
					loff_t from, struct mtd_oob_ops *ops);
	int                    (*hooked_write_oob)(struct mtd_info *mtd,
					loff_t to, struct mtd_oob_ops *ops);

	int                    marking_a_bad_block;
	int                    (*hooked_block_markbad)(struct mtd_info *mtd,
					loff_t ofs);

	/* DMA Buffers */

	char                   *cmd_virt;
	dma_addr_t             cmd_phys;

	void                   *page_buffer_virt;
	dma_addr_t             page_buffer_phys;
	unsigned int           page_buffer_size;

	void                   *payload_virt;
	dma_addr_t             payload_phys;

	void                   *auxiliary_virt;
	dma_addr_t             auxiliary_phys;

};

/**
 * struct physical_geometry - Physical geometry description.
 *
 * This structure describes the physical geometry of the medium.
 *
 * @chip_count:                    The number of chips in the medium.
 * @chip_size_in_bytes:            The size, in bytes, of a single chip
 *                                 (excluding the out-of-band bytes).
 * @block_size_in_bytes:           The size, in bytes, of a single block
 *                                 (excluding the out-of-band bytes).
 * @page_data_size_in_bytes:       The size, in bytes, of the data area in a
 *                                 page (excluding the out-of-band bytes).
 * @page_oob_size_in_bytes:        The size, in bytes, of the out-of-band area
 *                                 in a page.
 */

struct physical_geometry {
	unsigned int  chip_count;
	uint64_t      chip_size_in_bytes;
	unsigned int  block_size_in_bytes;
	unsigned int  page_data_size_in_bytes;
	unsigned int  page_oob_size_in_bytes;
};

/**
 * struct nfc_geometry - NFC geometry description.
 *
 * This structure describes the NFC's view of the medium geometry.
 *
 * @ecc_algorithm:            The human-readable name of the ECC algorithm
 *                            (e.g., "Reed-Solomon" or "BCH").
 * @ecc_strength:             A number that describes the strength of the ECC
 *                            algorithm.
 * @page_size_in_bytes:       The size, in bytes, of a physical page, including
 *                            both data and OOB.
 * @metadata_size_in_bytes:   The size, in bytes, of the metadata.
 * @ecc_chunk_size_in_bytes:  The size, in bytes, of a single ECC chunk. Note
 *                            the first chunk in the page includes both data and
 *                            metadata, so it's a bit larger than this value.
 * @ecc_chunk_count:          The number of ECC chunks in the page,
 * @payload_size_in_bytes:    The size, in bytes, of the payload buffer.
 * @auxiliary_size_in_bytes:  The size, in bytes, of the auxiliary buffer.
 * @auxiliary_status_offset:  The offset into the auxiliary buffer at which
 *                            the ECC status appears.
 * @block_mark_byte_offset:   The byte offset in the ECC-based page view at
 *                            which the underlying physical block mark appears.
 * @block_mark_bit_offset:    The bit offset into the ECC-based page view at
 *                            which the underlying physical block mark appears.
 */

struct nfc_geometry {
	char          *ecc_algorithm;
	unsigned int  ecc_strength;
	unsigned int  page_size_in_bytes;
	unsigned int  metadata_size_in_bytes;
	unsigned int  ecc_chunk_size_in_bytes;
	unsigned int  ecc_chunk_count;
	unsigned int  payload_size_in_bytes;
	unsigned int  auxiliary_size_in_bytes;
	unsigned int  auxiliary_status_offset;
	unsigned int  block_mark_byte_offset;
	unsigned int  block_mark_bit_offset;
};

/**
 * struct boot_rom_geometry - Boot ROM geometry description.
 *
 * This structure encapsulates decisions made by the Boot ROM Helper.
 *
 * @boot_area_count:             The number of boot areas. The first boot area
 *                               appears at the beginning of chip 0, the next
 *                               at the beginning of chip 1, etc.
 * @boot_area_size_in_bytes:     The size, in bytes, of each boot area.
 * @stride_size_in_pages:        The size of a boot block stride, in pages.
 * @search_area_stride_exponent: The logarithm to base 2 of the size of a
 *                               search area in boot block strides.
 */

struct boot_rom_geometry {
	unsigned int  boot_area_count;
	unsigned int  boot_area_size_in_bytes;
	unsigned int  stride_size_in_pages;
	unsigned int  search_area_stride_exponent;
};

/**
 * struct gpmi_nfc_data - i.MX NFC per-device data.
 *
 * Note that the "device" managed by this driver represents the NAND Flash
 * controller *and* the NAND Flash medium behind it. Thus, the per-device data
 * structure has information about the controller, the chips to which it is
 * connected, and properties of the medium as a whole.
 *
 * @dev:                 A pointer to the owning struct device.
 * @pdev:                A pointer to the owning struct platform_device.
 * @pdata:               A pointer to the device's platform data.
 * @resources:           Information about system resources used by this driver.
 * @device_info:         A structure that contains detailed information about
 *                       the NAND Flash device.
 * @physical_geometry:   A description of the medium's physical geometry.
 * @nfc:                 A pointer to a structure that represents the underlying
 *                       NFC hardware.
 * @nfc_geometry:        A description of the medium geometry as viewed by the
 *                       NFC.
 * @rom:                 A pointer to a structure that represents the underlying
 *                       Boot ROM.
 * @rom_geometry:        A description of the medium geometry as viewed by the
 *                       Boot ROM.
 * @mil:                 A collection of information used by the MTD Interface
 *                       Layer.
 */

struct gpmi_nfc_data {

	/* System Interface */
	struct device                  *dev;
	struct platform_device         *pdev;
	struct gpmi_nfc_platform_data  *pdata;

	/* Resources */
	struct resources               resources;

	/* Flash Hardware */
	struct nand_device_info        device_info;
	struct physical_geometry       physical_geometry;

	/* NFC HAL */
	struct nfc_hal                 *nfc;
	struct nfc_geometry            nfc_geometry;

	/* Boot ROM Helper */
	struct boot_rom_helper         *rom;
	struct boot_rom_geometry       rom_geometry;

	/* MTD Interface Layer */
	struct mil                     mil;

};

/**
 * struct gpmi_nfc_timing - GPMI NFC timing parameters.
 *
 * This structure contains the fundamental timing attributes for the NAND Flash
 * bus and the GPMI NFC hardware.
 *
 * @data_setup_in_ns:         The data setup time, in nanoseconds. Usually the
 *                            maximum of tDS and tWP. A negative value
 *                            indicates this characteristic isn't known.
 * @data_hold_in_ns:          The data hold time, in nanoseconds. Usually the
 *                            maximum of tDH, tWH and tREH. A negative value
 *                            indicates this characteristic isn't known.
 * @address_setup_in_ns:      The address setup time, in nanoseconds. Usually
 *                            the maximum of tCLS, tCS and tALS. A negative
 *                            value indicates this characteristic isn't known.
 * @gpmi_sample_delay_in_ns:  A GPMI-specific timing parameter. A negative value
 *                            indicates this characteristic isn't known.
 * @tREA_in_ns:               tREA, in nanoseconds, from the data sheet. A
 *                            negative value indicates this characteristic isn't
 *                            known.
 * @tRLOH_in_ns:              tRLOH, in nanoseconds, from the data sheet. A
 *                            negative value indicates this characteristic isn't
 *                            known.
 * @tRHOH_in_ns:              tRHOH, in nanoseconds, from the data sheet. A
 *                            negative value indicates this characteristic isn't
 *                            known.
 */

struct gpmi_nfc_timing {
	int8_t  data_setup_in_ns;
	int8_t  data_hold_in_ns;
	int8_t  address_setup_in_ns;
	int8_t  gpmi_sample_delay_in_ns;
	int8_t  tREA_in_ns;
	int8_t  tRLOH_in_ns;
	int8_t  tRHOH_in_ns;
};

/**
 * struct gpmi_nfc_hardware_timing - GPMI NFC hardware timing parameters.
 *
 * This structure contains timing information expressed in a form directly
 * usable by the GPMI NFC hardware.
 *
 * @data_setup_in_cycles:      The data setup time, in cycles.
 * @data_hold_in_cycles:       The data hold time, in cycles.
 * @address_setup_in_cycles:   The address setup time, in cycles.
 * @use_half_periods:          Indicates the clock is running slowly, so the
 *                             NFC DLL should use half-periods.
 * @sample_delay_factor:       The sample delay factor.
 */

struct gpmi_nfc_hardware_timing {
	uint8_t  data_setup_in_cycles;
	uint8_t  data_hold_in_cycles;
	uint8_t  address_setup_in_cycles;
	bool     use_half_periods;
	uint8_t  sample_delay_factor;
};

/**
 * struct nfc_hal - GPMI NFC HAL
 *
 * This structure embodies an abstract interface to the underlying NFC hardware.
 *
 * @version:                     The NFC hardware version.
 * @description:                 A pointer to a human-readable description of
 *                               the NFC hardware.
 * @max_chip_count:              The maximum number of chips the NFC can
 *                               possibly support (this value is a constant for
 *                               each NFC version). This may *not* be the actual
 *                               number of chips connected.
 * @max_data_setup_cycles:       The maximum number of data setup cycles that
 *                               can be expressed in the hardware.
 * @internal_data_setup_in_ns:   The time, in ns, that the NFC hardware requires
 *                               for data read internal setup. In the Reference
 *                               Manual, see the chapter "High-Speed NAND
 *                               Timing" for more details.
 * @max_sample_delay_factor:     The maximum sample delay factor that can be
 *                               expressed in the hardware.
 * @max_dll_clock_period_in_ns:  The maximum period of the GPMI clock that the
 *                               sample delay DLL hardware can possibly work
 *                               with (the DLL is unusable with longer periods).
 *                               If the full-cycle period is greater than HALF
 *                               this value, the DLL must be configured to use
 *                               half-periods.
 * @max_dll_delay_in_ns:         The maximum amount of delay, in ns, that the
 *                               DLL can implement.
 * @dma_descriptors:             A pool of DMA descriptors.
 * @isr_dma_channel:             The DMA channel with which the NFC HAL is
 *                               working. We record this here so the ISR knows
 *                               which DMA channel to acknowledge.
 * @dma_done:                    The completion structure used for DMA
 *                               interrupts.
 * @bch_done:                    The completion structure used for BCH
 *                               interrupts.
 * @timing:                      The current timing configuration.
 * @clock_frequency_in_hz:       The clock frequency, in Hz, during the current
 *                               I/O transaction. If no I/O transaction is in
 *                               progress, this is the clock frequency during
 *                               the most recent I/O transaction.
 * @hardware_timing:             The hardware timing configuration in effect
 *                               during the current I/O transaction. If no I/O
 *                               transaction is in progress, this is the
 *                               hardware timing configuration during the most
 *                               recent I/O transaction.
 * @init:                        Initializes the NFC hardware and data
 *                               structures. This function will be called after
 *                               everything has been set up for communication
 *                               with the NFC itself, but before the platform
 *                               has set up off-chip communication. Thus, this
 *                               function must not attempt to communicate with
 *                               the NAND Flash hardware.
 * @set_geometry:                Configures the NFC hardware and data structures
 *                               to match the physical NAND Flash geometry.
 * @set_geometry:                Configures the NFC hardware and data structures
 *                               to match the physical NAND Flash geometry.
 * @set_timing:                  Configures the NFC hardware and data structures
 *                               to match the given NAND Flash bus timing.
 * @get_timing:                  Returns the the clock frequency, in Hz, and
 *                               the hardware timing configuration during the
 *                               current I/O transaction. If no I/O transaction
 *                               is in progress, this is the timing state during
 *                               the most recent I/O transaction.
 * @exit:                        Shuts down the NFC hardware and data
 *                               structures. This function will be called after
 *                               the platform has shut down off-chip
 *                               communication but while communication with the
 *                               NFC itself still works.
 * @clear_bch:                   Clears a BCH interrupt (intended to be called
 *                               by a more general interrupt handler to do
 *                               device-specific clearing).
 * @is_ready:                    Returns true if the given chip is ready.
 * @begin:                       Begins an interaction with the NFC. This
 *                               function must be called before *any* of the
 *                               following functions so the NFC can prepare
 *                               itself.
 * @end:                         Ends interaction with the NFC. This function
 *                               should be called to give the NFC a chance to,
 *                               among other things, enter a lower-power state.
 * @send_command:                Sends the given buffer of command bytes.
 * @send_data:                   Sends the given buffer of data bytes.
 * @read_data:                   Reads data bytes into the given buffer.
 * @send_page:                   Sends the given given data and OOB bytes,
 *                               using the ECC engine.
 * @read_page:                   Reads a page through the ECC engine and
 *                               delivers the data and OOB bytes to the given
 *                               buffers.
 */

#define  NFC_DMA_DESCRIPTOR_COUNT  (4)

struct nfc_hal {

	/* Hardware attributes. */

	const unsigned int      version;
	const char              *description;
	const unsigned int      max_chip_count;
	const unsigned int      max_data_setup_cycles;
	const unsigned int      internal_data_setup_in_ns;
	const unsigned int      max_sample_delay_factor;
	const unsigned int      max_dll_clock_period_in_ns;
	const unsigned int      max_dll_delay_in_ns;

	/* Working variables. */

	struct mxs_dma_desc     *dma_descriptors[NFC_DMA_DESCRIPTOR_COUNT];
	int                     isr_dma_channel;
	struct completion       dma_done;
	struct completion       bch_done;
	struct gpmi_nfc_timing  timing;
	unsigned long           clock_frequency_in_hz;

	/* Configuration functions. */

	int   (*init)        (struct gpmi_nfc_data *);
	int   (*set_geometry)(struct gpmi_nfc_data *);
	int   (*set_timing)  (struct gpmi_nfc_data *,
					const struct gpmi_nfc_timing *);
	void  (*get_timing)  (struct gpmi_nfc_data *,
					unsigned long *clock_frequency_in_hz,
					struct gpmi_nfc_hardware_timing *);
	void  (*exit)        (struct gpmi_nfc_data *);

	/* Call these functions to begin and end I/O. */

	void  (*begin)       (struct gpmi_nfc_data *);
	void  (*end)         (struct gpmi_nfc_data *);

	/* Call these I/O functions only between begin() and end(). */

	void  (*clear_bch)   (struct gpmi_nfc_data *);
	int   (*is_ready)    (struct gpmi_nfc_data *, unsigned chip);
	int   (*send_command)(struct gpmi_nfc_data *, unsigned chip,
				dma_addr_t buffer, unsigned length);
	int   (*send_data)   (struct gpmi_nfc_data *, unsigned chip,
				dma_addr_t buffer, unsigned length);
	int   (*read_data)   (struct gpmi_nfc_data *, unsigned chip,
				dma_addr_t buffer, unsigned length);
	int   (*send_page)   (struct gpmi_nfc_data *, unsigned chip,
				dma_addr_t payload, dma_addr_t auxiliary);
	int   (*read_page)   (struct gpmi_nfc_data *, unsigned chip,
				dma_addr_t payload, dma_addr_t auxiliary);
};

/**
 * struct boot_rom_helper - Boot ROM Helper
 *
 * This structure embodies the interface to an object that assists the driver
 * in making decisions that relate to the Boot ROM.
 *
 * @version:                    The Boot ROM version.
 * @description:                A pointer to a human-readable description of the
 *                              Boot ROM.
 * @swap_block_mark:            Indicates that the Boot ROM will swap the block
 *                              mark with the first byte of the OOB.
 * @set_geometry:               Configures the Boot ROM geometry.
 * @check_transcription_stamp:  Checks for a transcription stamp. This pointer
 *                              is ignored if swap_block_mark is set.
 * @write_transcription_stamp:  Writes a transcription stamp. This pointer
 *                              is ignored if swap_block_mark is set.
 */

struct boot_rom_helper {
	const unsigned int  version;
	const char          *description;
	const int           swap_block_mark;
	int  (*set_geometry)             (struct gpmi_nfc_data *);
	int  (*check_transcription_stamp)(struct gpmi_nfc_data *);
	int  (*write_transcription_stamp)(struct gpmi_nfc_data *);
};

/*
 *------------------------------------------------------------------------------
 * External Symbols
 *------------------------------------------------------------------------------
 */

/* Event Reporting */

#if defined(EVENT_REPORTING)
	extern void gpmi_nfc_start_event_trace(char *description);
	extern void gpmi_nfc_add_event(char *description, int delta);
	extern void gpmi_nfc_stop_event_trace(char *description);
	extern void gpmi_nfc_dump_event_trace(void);
#else
	#define gpmi_nfc_start_event_trace(description)  do {} while (0)
	#define gpmi_nfc_add_event(description, delta)   do {} while (0)
	#define gpmi_nfc_stop_event_trace(description)   do {} while (0)
	#define gpmi_nfc_dump_event_trace()              do {} while (0)
#endif

/* NFC HAL Common Services */

extern irqreturn_t gpmi_nfc_bch_isr(int irq, void *cookie);
extern irqreturn_t gpmi_nfc_dma_isr(int irq, void *cookie);
extern int gpmi_nfc_dma_init(struct gpmi_nfc_data *this);
extern void gpmi_nfc_dma_exit(struct gpmi_nfc_data *this);
extern int gpmi_nfc_set_geometry(struct gpmi_nfc_data *this);
extern int gpmi_nfc_dma_go(struct gpmi_nfc_data *this, int  dma_channel);
extern int gpmi_nfc_compute_hardware_timing(struct gpmi_nfc_data *this,
					struct gpmi_nfc_hardware_timing *hw);

/* NFC HAL Structures */

extern struct nfc_hal  gpmi_nfc_hal_v0;
extern struct nfc_hal  gpmi_nfc_hal_v1;

/* Boot ROM Helper Common Services */

extern int gpmi_nfc_rom_helper_set_geometry(struct gpmi_nfc_data *this);

/* Boot ROM Helper Structures */

extern struct boot_rom_helper  gpmi_nfc_boot_rom_helper_v0;
extern struct boot_rom_helper  gpmi_nfc_boot_rom_helper_v1;

/* MTD Interface Layer */

extern int  gpmi_nfc_mil_init(struct gpmi_nfc_data *this);
extern void gpmi_nfc_mil_exit(struct gpmi_nfc_data *this);

#endif