hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
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
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright © 2009 - Maxim Levitsky
 * driver for Ricoh xD readers
 */
 
#include <linux/pci.h>
#include <linux/completion.h>
#include <linux/workqueue.h>
#include <linux/mtd/rawnand.h>
#include <linux/spinlock.h>
 
 
/* nand interface + ecc
   byte write/read does one cycle on nand data lines.
   dword write/read does 4 cycles
   if R852_CTL_ECC_ACCESS is set in R852_CTL, then dword read reads
   results of ecc correction, if DMA read was done before.
   If write was done two dword reads read generated ecc checksums
*/
#define    R852_DATALINE        0x00
 
/* control register */
#define R852_CTL        0x04
#define R852_CTL_COMMAND     0x01    /* send command (#CLE)*/
#define R852_CTL_DATA        0x02    /* read/write data (#ALE)*/
#define R852_CTL_ON        0x04    /* only seem to controls the hd led, */
                   /* but has to be set on start...*/
#define R852_CTL_RESET        0x08    /* unknown, set only on start once*/
#define R852_CTL_CARDENABLE    0x10    /* probably (#CE) - always set*/
#define R852_CTL_ECC_ENABLE    0x20    /* enable ecc engine */
#define R852_CTL_ECC_ACCESS    0x40    /* read/write ecc via reg #0*/
#define R852_CTL_WRITE        0x80    /* set when performing writes (#WP) */
 
/* card detection status */
#define R852_CARD_STA        0x05
 
#define R852_CARD_STA_CD    0x01    /* state of #CD line, same as 0x04 */
#define R852_CARD_STA_RO    0x02    /* card is readonly */
#define R852_CARD_STA_PRESENT    0x04    /* card is present (#CD) */
#define R852_CARD_STA_ABSENT    0x08    /* card is absent */
#define R852_CARD_STA_BUSY    0x80    /* card is busy - (#R/B) */
 
/* card detection irq status & enable*/
#define R852_CARD_IRQ_STA    0x06    /* IRQ status */
#define R852_CARD_IRQ_ENABLE    0x07    /* IRQ enable */
 
#define R852_CARD_IRQ_CD    0x01    /* fire when #CD lights, same as 0x04*/
#define R852_CARD_IRQ_REMOVE    0x04    /* detect card removal */
#define R852_CARD_IRQ_INSERT    0x08    /* detect card insert */
#define R852_CARD_IRQ_UNK1    0x10    /* unknown */
#define R852_CARD_IRQ_GENABLE    0x80    /* general enable */
#define R852_CARD_IRQ_MASK    0x1D
 
 
 
/* hardware enable */
#define R852_HW            0x08
#define R852_HW_ENABLED        0x01    /* hw enabled */
#define R852_HW_UNKNOWN        0x80
 
 
/* dma capabilities */
#define R852_DMA_CAP        0x09
#define R852_SMBIT        0x20    /* if set with bit #6 or bit #7, then */
                   /* hw is smartmedia */
#define R852_DMA1        0x40    /* if set w/bit #7, dma is supported */
#define R852_DMA2        0x80    /* if set w/bit #6, dma is supported */
 
 
/* physical DMA address - 32 bit value*/
#define R852_DMA_ADDR        0x0C
 
 
/* dma settings */
#define R852_DMA_SETTINGS    0x10
#define R852_DMA_MEMORY        0x01    /* (memory <-> internal hw buffer) */
#define R852_DMA_READ        0x02    /* 0 = write, 1 = read */
#define R852_DMA_INTERNAL    0x04    /* (internal hw buffer <-> card) */
 
/* dma IRQ status */
#define R852_DMA_IRQ_STA        0x14
 
/* dma IRQ enable */
#define R852_DMA_IRQ_ENABLE    0x18
 
#define R852_DMA_IRQ_MEMORY    0x01    /* (memory <-> internal hw buffer) */
#define R852_DMA_IRQ_ERROR    0x02    /* error did happen */
#define R852_DMA_IRQ_INTERNAL    0x04    /* (internal hw buffer <-> card) */
#define R852_DMA_IRQ_MASK    0x07    /* mask of all IRQ bits */
 
 
/* ECC syndrome format - read from reg #0 will return two copies of these for
   each half of the page.
   first byte is error byte location, and second, bit location + flags */
#define R852_ECC_ERR_BIT_MSK    0x07    /* error bit location */
#define R852_ECC_CORRECT        0x10    /* no errors - (guessed) */
#define R852_ECC_CORRECTABLE    0x20    /* correctable error exist */
#define R852_ECC_FAIL        0x40    /* non correctable error detected */
 
#define R852_DMA_LEN        512
 
#define DMA_INTERNAL    0
#define DMA_MEMORY    1
 
struct r852_device {
   struct nand_controller        controller;
   void __iomem *mmio;        /* mmio */
   struct nand_chip *chip;        /* nand chip backpointer */
   struct pci_dev *pci_dev;    /* pci backpointer */
 
   /* dma area */
   dma_addr_t phys_dma_addr;    /* bus address of buffer*/
   struct completion dma_done;    /* data transfer done */
 
   dma_addr_t phys_bounce_buffer;    /* bus address of bounce buffer */
   uint8_t *bounce_buffer;        /* virtual address of bounce buffer */
 
   int dma_dir;            /* 1 = read, 0 = write */
   int dma_stage;            /* 0 - idle, 1 - first step,
                      2 - second step */
 
   int dma_state;            /* 0 = internal, 1 = memory */
   int dma_error;            /* dma errors */
   int dma_usable;            /* is it possible to use dma */
 
   /* card status area */
   struct delayed_work card_detect_work;
   struct workqueue_struct *card_workqueue;
   int card_registered;        /* card registered with mtd */
   int card_detected;        /* card detected in slot */
   int card_unstable;        /* whenever the card is inserted,
                      is not known yet */
   int readonly;            /* card is readonly */
   int sm;                /* Is card smartmedia */
 
   /* interrupt handling */
   spinlock_t irqlock;        /* IRQ protecting lock */
   int irq;            /* irq num */
   /* misc */
   void *tmp_buffer;        /* temporary buffer */
   uint8_t ctlreg;            /* cached contents of control reg */
};
 
#define dbg(format, ...) \
   if (debug) \
       pr_debug(format "\n", ## __VA_ARGS__)
 
#define dbg_verbose(format, ...) \
   if (debug > 1) \
       pr_debug(format "\n", ## __VA_ARGS__)
 
 
#define message(format, ...) \
   pr_info(format "\n", ## __VA_ARGS__)