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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/* $Id: parport_sunbpp.c,v 1.1.1.1 2004-04-15 02:29:11 phoenix Exp $
2
 * Parallel-port routines for Sun architecture
3
 *
4
 * Author: Derrick J. Brashear <shadow@dementia.org>
5
 *
6
 * based on work by:
7
 *          Phil Blundell <Philip.Blundell@pobox.com>
8
 *          Tim Waugh <tim@cyberelk.demon.co.uk>
9
 *          Jose Renau <renau@acm.org>
10
 *          David Campbell <campbell@tirian.che.curtin.edu.au>
11
 *          Grant Guenther <grant@torque.net>
12
 *          Eddie C. Dost <ecd@skynet.be>
13
 *          Stephen Williams (steve@icarus.com)
14
 *          Gus Baldauf (gbaldauf@ix.netcom.com)
15
 *          Peter Zaitcev
16
 *          Tom Dyas
17
 */
18
 
19
#include <linux/string.h>
20
#include <linux/module.h>
21
#include <linux/delay.h>
22
#include <linux/errno.h>
23
#include <linux/ioport.h>
24
#include <linux/kernel.h>
25
#include <linux/slab.h>
26
#include <linux/init.h>
27
 
28
#include <linux/parport.h>
29
 
30
#include <asm/ptrace.h>
31
#include <linux/interrupt.h>
32
 
33
#include <asm/io.h>
34
#include <asm/oplib.h>           /* OpenProm Library */
35
#include <asm/sbus.h>
36
#include <asm/dma.h>             /* BPP uses LSI 64854 for DMA */
37
#include <asm/irq.h>
38
#include <asm/sunbpp.h>
39
 
40
#undef __SUNBPP_DEBUG
41
#ifdef __SUNBPP_DEBUG
42
#define dprintk(x) printk x
43
#else
44
#define dprintk(x)
45
#endif
46
 
47
static void parport_sunbpp_interrupt(int irq, void *dev_id, struct pt_regs *regs)
48
{
49
        parport_generic_irq(irq, (struct parport *) dev_id, regs);
50
}
51
 
52
static void parport_sunbpp_disable_irq(struct parport *p)
53
{
54
        struct bpp_regs *regs = (struct bpp_regs *)p->base;
55
        u32 tmp;
56
 
57
        tmp = sbus_readl(&regs->p_csr);
58
        tmp &= ~DMA_INT_ENAB;
59
        sbus_writel(tmp, &regs->p_csr);
60
}
61
 
62
static void parport_sunbpp_enable_irq(struct parport *p)
63
{
64
        struct bpp_regs *regs = (struct bpp_regs *)p->base;
65
        u32 tmp;
66
 
67
        tmp = sbus_readl(&regs->p_csr);
68
        tmp |= DMA_INT_ENAB;
69
        sbus_writel(tmp, &regs->p_csr);
70
}
71
 
72
static void parport_sunbpp_write_data(struct parport *p, unsigned char d)
73
{
74
        struct bpp_regs *regs = (struct bpp_regs *)p->base;
75
 
76
        sbus_writeb(d, &regs->p_dr);
77
        dprintk((KERN_DEBUG "wrote 0x%x\n", d));
78
}
79
 
80
static unsigned char parport_sunbpp_read_data(struct parport *p)
81
{
82
        struct bpp_regs *regs = (struct bpp_regs *)p->base;
83
 
84
        return sbus_readb(&regs->p_dr);
85
}
86
 
87
#if 0
88
static void control_pc_to_sunbpp(struct parport *p, unsigned char status)
89
{
90
        struct bpp_regs *regs = (struct bpp_regs *)p->base;
91
        unsigned char value_tcr = sbus_readb(&regs->p_tcr);
92
        unsigned char value_or = sbus_readb(&regs->p_or);
93
 
94
        if (status & PARPORT_CONTROL_STROBE)
95
                value_tcr |= P_TCR_DS;
96
        if (status & PARPORT_CONTROL_AUTOFD)
97
                value_or |= P_OR_AFXN;
98
        if (status & PARPORT_CONTROL_INIT)
99
                value_or |= P_OR_INIT;
100
        if (status & PARPORT_CONTROL_SELECT)
101
                value_or |= P_OR_SLCT_IN;
102
 
103
        sbus_writeb(value_or, &regs->p_or);
104
        sbus_writeb(value_tcr, &regs->p_tcr);
105
}
106
#endif
107
 
108
static unsigned char status_sunbpp_to_pc(struct parport *p)
109
{
110
        struct bpp_regs *regs = (struct bpp_regs *)p->base;
111
        unsigned char bits = 0;
112
        unsigned char value_tcr = sbus_readb(&regs->p_tcr);
113
        unsigned char value_ir = sbus_readb(&regs->p_ir);
114
 
115
        if (!(value_ir & P_IR_ERR))
116
                bits |= PARPORT_STATUS_ERROR;
117
        if (!(value_ir & P_IR_SLCT))
118
                bits |= PARPORT_STATUS_SELECT;
119
        if (!(value_ir & P_IR_PE))
120
                bits |= PARPORT_STATUS_PAPEROUT;
121
        if (value_tcr & P_TCR_ACK)
122
                bits |= PARPORT_STATUS_ACK;
123
        if (!(value_tcr & P_TCR_BUSY))
124
                bits |= PARPORT_STATUS_BUSY;
125
 
126
        dprintk((KERN_DEBUG "tcr 0x%x ir 0x%x\n", regs->p_tcr, regs->p_ir));
127
        dprintk((KERN_DEBUG "read status 0x%x\n", bits));
128
        return bits;
129
}
130
 
131
static unsigned char control_sunbpp_to_pc(struct parport *p)
132
{
133
        struct bpp_regs *regs = (struct bpp_regs *)p->base;
134
        unsigned char bits = 0;
135
        unsigned char value_tcr = sbus_readb(&regs->p_tcr);
136
        unsigned char value_or = sbus_readb(&regs->p_or);
137
 
138
        if (!(value_tcr & P_TCR_DS))
139
                bits |= PARPORT_CONTROL_STROBE;
140
        if (!(value_or & P_OR_AFXN))
141
                bits |= PARPORT_CONTROL_AUTOFD;
142
        if (!(value_or & P_OR_INIT))
143
                bits |= PARPORT_CONTROL_INIT;
144
        if (value_or & P_OR_SLCT_IN)
145
                bits |= PARPORT_CONTROL_SELECT;
146
 
147
        dprintk((KERN_DEBUG "tcr 0x%x or 0x%x\n", regs->p_tcr, regs->p_or));
148
        dprintk((KERN_DEBUG "read control 0x%x\n", bits));
149
        return bits;
150
}
151
 
152
static unsigned char parport_sunbpp_read_control(struct parport *p)
153
{
154
        return control_sunbpp_to_pc(p);
155
}
156
 
157
static unsigned char parport_sunbpp_frob_control(struct parport *p,
158
                                                 unsigned char mask,
159
                                                 unsigned char val)
160
{
161
        struct bpp_regs *regs = (struct bpp_regs *)p->base;
162
        unsigned char value_tcr = sbus_readb(&regs->p_tcr);
163
        unsigned char value_or = sbus_readb(&regs->p_or);
164
 
165
        dprintk((KERN_DEBUG "frob1: tcr 0x%x or 0x%x\n", regs->p_tcr, regs->p_or));
166
        if (mask & PARPORT_CONTROL_STROBE) {
167
                if (val & PARPORT_CONTROL_STROBE) {
168
                        value_tcr &= ~P_TCR_DS;
169
                } else {
170
                        value_tcr |= P_TCR_DS;
171
                }
172
        }
173
        if (mask & PARPORT_CONTROL_AUTOFD) {
174
                if (val & PARPORT_CONTROL_AUTOFD) {
175
                        value_or &= ~P_OR_AFXN;
176
                } else {
177
                        value_or |= P_OR_AFXN;
178
                }
179
        }
180
        if (mask & PARPORT_CONTROL_INIT) {
181
                if (val & PARPORT_CONTROL_INIT) {
182
                        value_or &= ~P_OR_INIT;
183
                } else {
184
                        value_or |= P_OR_INIT;
185
                }
186
        }
187
        if (mask & PARPORT_CONTROL_SELECT) {
188
                if (val & PARPORT_CONTROL_SELECT) {
189
                        value_or |= P_OR_SLCT_IN;
190
                } else {
191
                        value_or &= ~P_OR_SLCT_IN;
192
                }
193
        }
194
 
195
        sbus_writeb(value_or, &regs->p_or);
196
        sbus_writeb(value_tcr, &regs->p_tcr);
197
        dprintk((KERN_DEBUG "frob2: tcr 0x%x or 0x%x\n", regs->p_tcr, regs->p_or));
198
        return parport_sunbpp_read_control(p);
199
}
200
 
201
static void parport_sunbpp_write_control(struct parport *p, unsigned char d)
202
{
203
        const unsigned char wm = (PARPORT_CONTROL_STROBE |
204
                                  PARPORT_CONTROL_AUTOFD |
205
                                  PARPORT_CONTROL_INIT |
206
                                  PARPORT_CONTROL_SELECT);
207
 
208
        parport_sunbpp_frob_control (p, wm, d & wm);
209
}
210
 
211
static unsigned char parport_sunbpp_read_status(struct parport *p)
212
{
213
        return status_sunbpp_to_pc(p);
214
}
215
 
216
static void parport_sunbpp_data_forward (struct parport *p)
217
{
218
        struct bpp_regs *regs = (struct bpp_regs *)p->base;
219
        unsigned char value_tcr = sbus_readb(&regs->p_tcr);
220
 
221
        dprintk((KERN_DEBUG "forward\n"));
222
        value_tcr &= ~P_TCR_DIR;
223
        sbus_writeb(value_tcr, &regs->p_tcr);
224
}
225
 
226
static void parport_sunbpp_data_reverse (struct parport *p)
227
{
228
        struct bpp_regs *regs = (struct bpp_regs *)p->base;
229
        u8 val = sbus_readb(&regs->p_tcr);
230
 
231
        dprintk((KERN_DEBUG "reverse\n"));
232
        val |= P_TCR_DIR;
233
        sbus_writeb(val, &regs->p_tcr);
234
}
235
 
236
static void parport_sunbpp_init_state(struct pardevice *dev, struct parport_state *s)
237
{
238
        s->u.pc.ctr = 0xc;
239
        s->u.pc.ecr = 0x0;
240
}
241
 
242
static void parport_sunbpp_save_state(struct parport *p, struct parport_state *s)
243
{
244
        s->u.pc.ctr = parport_sunbpp_read_control(p);
245
}
246
 
247
static void parport_sunbpp_restore_state(struct parport *p, struct parport_state *s)
248
{
249
        parport_sunbpp_write_control(p, s->u.pc.ctr);
250
}
251
 
252
static void parport_sunbpp_inc_use_count(void)
253
{
254
#ifdef MODULE
255
        MOD_INC_USE_COUNT;
256
#endif
257
}
258
 
259
static void parport_sunbpp_dec_use_count(void)
260
{
261
#ifdef MODULE
262
        MOD_DEC_USE_COUNT;
263
#endif
264
}
265
 
266
static struct parport_operations parport_sunbpp_ops =
267
{
268
        parport_sunbpp_write_data,
269
        parport_sunbpp_read_data,
270
 
271
        parport_sunbpp_write_control,
272
        parport_sunbpp_read_control,
273
        parport_sunbpp_frob_control,
274
 
275
        parport_sunbpp_read_status,
276
 
277
        parport_sunbpp_enable_irq,
278
        parport_sunbpp_disable_irq,
279
 
280
        parport_sunbpp_data_forward,
281
        parport_sunbpp_data_reverse,
282
 
283
        parport_sunbpp_init_state,
284
        parport_sunbpp_save_state,
285
        parport_sunbpp_restore_state,
286
 
287
        parport_sunbpp_inc_use_count,
288
        parport_sunbpp_dec_use_count,
289
 
290
        parport_ieee1284_epp_write_data,
291
        parport_ieee1284_epp_read_data,
292
        parport_ieee1284_epp_write_addr,
293
        parport_ieee1284_epp_read_addr,
294
 
295
        parport_ieee1284_ecp_write_data,
296
        parport_ieee1284_ecp_read_data,
297
        parport_ieee1284_ecp_write_addr,
298
 
299
        parport_ieee1284_write_compat,
300
        parport_ieee1284_read_nibble,
301
        parport_ieee1284_read_byte,
302
};
303
 
304
static int __init init_one_port(struct sbus_dev *sdev)
305
{
306
        struct parport *p;
307
        /* at least in theory there may be a "we don't dma" case */
308
        struct parport_operations *ops;
309
        unsigned long base;
310
        int irq, dma, err, size;
311
        struct bpp_regs *regs;
312
        unsigned char value_tcr;
313
 
314
        dprintk((KERN_DEBUG "init_one_port(%p): ranges, alloc_io, ", sdev));
315
        irq = sdev->irqs[0];
316
        base = sbus_ioremap(&sdev->resource[0], 0,
317
                            sdev->reg_addrs[0].reg_size,
318
                            "sunbpp");
319
        size = sdev->reg_addrs[0].reg_size;
320
        dma = PARPORT_DMA_NONE;
321
 
322
        dprintk(("alloc(ppops), "));
323
        ops = kmalloc (sizeof (struct parport_operations), GFP_KERNEL);
324
        if (!ops) {
325
                sbus_iounmap(base, size);
326
                return 0;
327
        }
328
 
329
        memcpy (ops, &parport_sunbpp_ops, sizeof (struct parport_operations));
330
 
331
        dprintk(("register_port\n"));
332
        if (!(p = parport_register_port(base, irq, dma, ops))) {
333
                kfree(ops);
334
                sbus_iounmap(base, size);
335
                return 0;
336
        }
337
 
338
        p->size = size;
339
 
340
        dprintk((KERN_DEBUG "init_one_port: request_irq(%08x:%p:%x:%s:%p) ",
341
                p->irq, parport_sunbpp_interrupt, SA_SHIRQ, p->name, p));
342
        if ((err = request_irq(p->irq, parport_sunbpp_interrupt,
343
                               SA_SHIRQ, p->name, p)) != 0) {
344
                dprintk(("ERROR %d\n", err));
345
                parport_unregister_port(p);
346
                kfree(ops);
347
                sbus_iounmap(base, size);
348
                return err;
349
        } else {
350
                dprintk(("OK\n"));
351
                parport_sunbpp_enable_irq(p);
352
        }
353
 
354
        regs = (struct bpp_regs *)p->base;
355
        dprintk((KERN_DEBUG "forward\n"));
356
        value_tcr = sbus_readb(&regs->p_tcr);
357
        value_tcr &= ~P_TCR_DIR;
358
        sbus_writeb(value_tcr, &regs->p_tcr);
359
 
360
        printk(KERN_INFO "%s: sunbpp at 0x%lx\n", p->name, p->base);
361
        parport_proc_register(p);
362
        parport_announce_port (p);
363
 
364
        return 1;
365
}
366
 
367
EXPORT_NO_SYMBOLS;
368
 
369
#ifdef MODULE
370
int init_module(void)
371
#else
372
int __init parport_sunbpp_init(void)
373
#endif
374
{
375
        struct sbus_bus *sbus;
376
        struct sbus_dev *sdev;
377
        int count = 0;
378
 
379
        for_each_sbus(sbus) {
380
                for_each_sbusdev(sdev, sbus) {
381
                        if (!strcmp(sdev->prom_name, "SUNW,bpp"))
382
                                count += init_one_port(sdev);
383
                }
384
        }
385
        return count ? 0 : -ENODEV;
386
}
387
 
388
#ifdef MODULE
389
MODULE_AUTHOR("Derrick J Brashear");
390
MODULE_DESCRIPTION("Parport Driver for Sparc bidirectional Port");
391
MODULE_SUPPORTED_DEVICE("Sparc Bidirectional Parallel Port");
392
 
393
void
394
cleanup_module(void)
395
{
396
        struct parport *p = parport_enumerate();
397
 
398
        while (p) {
399
                struct parport *next = p->next;
400
 
401
                if (1/*p->modes & PARPORT_MODE_PCSPP*/) {
402
                        struct parport_operations *ops = p->ops;
403
 
404
                        if (p->irq != PARPORT_IRQ_NONE) {
405
                                parport_sunbpp_disable_irq(p);
406
                                free_irq(p->irq, p);
407
                        }
408
                        sbus_iounmap(p->base, p->size);
409
                        parport_proc_unregister(p);
410
                        parport_unregister_port(p);
411
                        kfree (ops);
412
                }
413
                p = next;
414
        }
415
}
416
#endif

powered by: WebSVN 2.1.0

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