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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [parport/] [parport_amiga.c] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

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