OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [parport/] [parport_amiga.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/* Low-level parallel port routines for the Amiga built-in port
2
 *
3
 * Author: Joerg Dorchain <joerg@dorchain.net>
4
 *
5
 * This is a complete rewrite of the code, but based heaviy upon the old
6
 * lp_intern. code.
7
 *
8
 * The built-in Amiga parallel port provides one port at a fixed address
9
 * with 8 bidirectional data lines (D0 - D7) and 3 bidirectional status
10
 * lines (BUSY, POUT, SEL), 1 output control line /STROBE (raised automatically
11
 * in hardware when the data register is accessed), and 1 input control line
12
 * /ACK, able to cause an interrupt, but both not directly settable by
13
 * software.
14
 */
15
 
16
#include <linux/module.h>
17
#include <linux/init.h>
18
#include <linux/parport.h>
19
#include <linux/ioport.h>
20
#include <linux/interrupt.h>
21
#include <asm/setup.h>
22
#include <asm/amigahw.h>
23
#include <asm/irq.h>
24
#include <asm/io.h>
25
#include <asm/amigaints.h>
26
 
27
#undef DEBUG
28
#ifdef DEBUG
29
#define DPRINTK printk
30
#else
31
#define DPRINTK(x...)   do { } while (0)
32
#endif
33
 
34
static struct parport *this_port = NULL;
35
 
36
static void amiga_write_data(struct parport *p, unsigned char data)
37
{
38
        DPRINTK(KERN_DEBUG "write_data %c\n",data);
39
        /* Triggers also /STROBE. This behavior cannot be changed */
40
        ciaa.prb = data;
41
        mb();
42
}
43
 
44
static unsigned char amiga_read_data(struct parport *p)
45
{
46
        /* Triggers also /STROBE. This behavior cannot be changed */
47
        return ciaa.prb;
48
}
49
 
50
#if 0
51
static unsigned char control_pc_to_amiga(unsigned char control)
52
{
53
        unsigned char ret = 0;
54
 
55
        if (control & PARPORT_CONTROL_SELECT) /* XXX: What is SELECP? */
56
                ;
57
        if (control & PARPORT_CONTROL_INIT) /* INITP */
58
                /* reset connected to cpu reset pin */;
59
        if (control & PARPORT_CONTROL_AUTOFD) /* AUTOLF */
60
                /* Not connected */;
61
        if (control & PARPORT_CONTROL_STROBE) /* Strobe */
62
                /* Handled only directly by hardware */;
63
        return ret;
64
}
65
#endif
66
 
67
static unsigned char control_amiga_to_pc(unsigned char control)
68
{
69
        return PARPORT_CONTROL_SELECT |
70
              PARPORT_CONTROL_AUTOFD | PARPORT_CONTROL_STROBE;
71
        /* fake value: interrupt enable, select in, no reset,
72
        no autolf, no strobe - seems to be closest the wiring diagram */
73
}
74
 
75
static void amiga_write_control(struct parport *p, unsigned char control)
76
{
77
        DPRINTK(KERN_DEBUG "write_control %02x\n",control);
78
        /* No implementation possible */
79
}
80
 
81
static unsigned char amiga_read_control( struct parport *p)
82
{
83
        DPRINTK(KERN_DEBUG "read_control \n");
84
        return control_amiga_to_pc(0);
85
}
86
 
87
static unsigned char amiga_frob_control( struct parport *p, unsigned char mask, unsigned char val)
88
{
89
        unsigned char old;
90
 
91
        DPRINTK(KERN_DEBUG "frob_control mask %02x, value %02x\n",mask,val);
92
        old = amiga_read_control(p);
93
        amiga_write_control(p, (old & ~mask) ^ val);
94
        return old;
95
}
96
 
97
#if 0 /* currently unused */
98
static unsigned char status_pc_to_amiga(unsigned char status)
99
{
100
        unsigned char ret = 1;
101
 
102
        if (status & PARPORT_STATUS_BUSY) /* Busy */
103
                ret &= ~1;
104
        if (status & PARPORT_STATUS_ACK) /* Ack */
105
                /* handled in hardware */;
106
        if (status & PARPORT_STATUS_PAPEROUT) /* PaperOut */
107
                ret |= 2;
108
        if (status & PARPORT_STATUS_SELECT) /* select */
109
                ret |= 4;
110
        if (status & PARPORT_STATUS_ERROR) /* error */
111
                /* not connected */;
112
        return ret;
113
}
114
#endif
115
 
116
static unsigned char status_amiga_to_pc(unsigned char status)
117
{
118
        unsigned char ret = PARPORT_STATUS_BUSY | PARPORT_STATUS_ACK | PARPORT_STATUS_ERROR;
119
 
120
        if (status & 1) /* Busy */
121
                ret &= ~PARPORT_STATUS_BUSY;
122
        if (status & 2) /* PaperOut */
123
                ret |= PARPORT_STATUS_PAPEROUT;
124
        if (status & 4) /* Selected */
125
                ret |= PARPORT_STATUS_SELECT;
126
        /* the rest is not connected or handled autonomously in hardware */
127
 
128
        return ret;
129
}
130
 
131
static unsigned char amiga_read_status(struct parport *p)
132
{
133
        unsigned char status;
134
 
135
        status = status_amiga_to_pc(ciab.pra & 7);
136
        DPRINTK(KERN_DEBUG "read_status %02x\n", status);
137
        return status;
138
}
139
 
140
static void amiga_enable_irq(struct parport *p)
141
{
142
        enable_irq(IRQ_AMIGA_CIAA_FLG);
143
}
144
 
145
static void amiga_disable_irq(struct parport *p)
146
{
147
        disable_irq(IRQ_AMIGA_CIAA_FLG);
148
}
149
 
150
static void amiga_data_forward(struct parport *p)
151
{
152
        DPRINTK(KERN_DEBUG "forward\n");
153
        ciaa.ddrb = 0xff; /* all pins output */
154
        mb();
155
}
156
 
157
static void amiga_data_reverse(struct parport *p)
158
{
159
        DPRINTK(KERN_DEBUG "reverse\n");
160
        ciaa.ddrb = 0; /* all pins input */
161
        mb();
162
}
163
 
164
static void amiga_init_state(struct pardevice *dev, struct parport_state *s)
165
{
166
        s->u.amiga.data = 0;
167
        s->u.amiga.datadir = 255;
168
        s->u.amiga.status = 0;
169
        s->u.amiga.statusdir = 0;
170
}
171
 
172
static void amiga_save_state(struct parport *p, struct parport_state *s)
173
{
174
        mb();
175
        s->u.amiga.data = ciaa.prb;
176
        s->u.amiga.datadir = ciaa.ddrb;
177
        s->u.amiga.status = ciab.pra & 7;
178
        s->u.amiga.statusdir = ciab.ddra & 7;
179
        mb();
180
}
181
 
182
static void amiga_restore_state(struct parport *p, struct parport_state *s)
183
{
184
        mb();
185
        ciaa.prb = s->u.amiga.data;
186
        ciaa.ddrb = s->u.amiga.datadir;
187
        ciab.pra |= (ciab.pra & 0xf8) | s->u.amiga.status;
188
        ciab.ddra |= (ciab.ddra & 0xf8) | s->u.amiga.statusdir;
189
        mb();
190
}
191
 
192
static struct parport_operations pp_amiga_ops = {
193
        .write_data     = amiga_write_data,
194
        .read_data      = amiga_read_data,
195
 
196
        .write_control  = amiga_write_control,
197
        .read_control   = amiga_read_control,
198
        .frob_control   = amiga_frob_control,
199
 
200
        .read_status    = amiga_read_status,
201
 
202
        .enable_irq     = amiga_enable_irq,
203
        .disable_irq    = amiga_disable_irq,
204
 
205
        .data_forward   = amiga_data_forward,
206
        .data_reverse   = amiga_data_reverse,
207
 
208
        .init_state     = amiga_init_state,
209
        .save_state     = amiga_save_state,
210
        .restore_state  = amiga_restore_state,
211
 
212
        .epp_write_data = parport_ieee1284_epp_write_data,
213
        .epp_read_data  = parport_ieee1284_epp_read_data,
214
        .epp_write_addr = parport_ieee1284_epp_write_addr,
215
        .epp_read_addr  = parport_ieee1284_epp_read_addr,
216
 
217
        .ecp_write_data = parport_ieee1284_ecp_write_data,
218
        .ecp_read_data  = parport_ieee1284_ecp_read_data,
219
        .ecp_write_addr = parport_ieee1284_ecp_write_addr,
220
 
221
        .compat_write_data      = parport_ieee1284_write_compat,
222
        .nibble_read_data       = parport_ieee1284_read_nibble,
223
        .byte_read_data         = parport_ieee1284_read_byte,
224
 
225
        .owner          = THIS_MODULE,
226
};
227
 
228
/* ----------- Initialisation code --------------------------------- */
229
 
230
static int __init parport_amiga_init(void)
231
{
232
        struct parport *p;
233
        int err;
234
 
235
        if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(AMI_PARALLEL))
236
                return -ENODEV;
237
 
238
        err = -EBUSY;
239
        if (!request_mem_region(CIAA_PHYSADDR-1+0x100, 0x100, "parallel"))
240
                goto out_mem;
241
 
242
        ciaa.ddrb = 0xff;
243
        ciab.ddra &= 0xf8;
244
        mb();
245
 
246
        p = parport_register_port((unsigned long)&ciaa.prb, IRQ_AMIGA_CIAA_FLG,
247
                                   PARPORT_DMA_NONE, &pp_amiga_ops);
248
        if (!p)
249
                goto out_port;
250
 
251
        err = request_irq(IRQ_AMIGA_CIAA_FLG, parport_irq_handler, 0, p->name, p);
252
        if (err)
253
                goto out_irq;
254
 
255
        this_port = p;
256
        printk(KERN_INFO "%s: Amiga built-in port using irq\n", p->name);
257
        /* XXX: set operating mode */
258
        parport_announce_port(p);
259
 
260
        return 0;
261
 
262
out_irq:
263
        parport_put_port(p);
264
out_port:
265
        release_mem_region(CIAA_PHYSADDR-1+0x100, 0x100);
266
out_mem:
267
        return err;
268
}
269
 
270
static void __exit parport_amiga_exit(void)
271
{
272
        parport_remove_port(this_port);
273
        if (this_port->irq != PARPORT_IRQ_NONE)
274
                free_irq(IRQ_AMIGA_CIAA_FLG, this_port);
275
        parport_put_port(this_port);
276
        release_mem_region(CIAA_PHYSADDR-1+0x100, 0x100);
277
}
278
 
279
 
280
MODULE_AUTHOR("Joerg Dorchain <joerg@dorchain.net>");
281
MODULE_DESCRIPTION("Parport Driver for Amiga builtin Port");
282
MODULE_SUPPORTED_DEVICE("Amiga builtin Parallel Port");
283
MODULE_LICENSE("GPL");
284
 
285
module_init(parport_amiga_init)
286
module_exit(parport_amiga_exit)

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.