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

Subversion Repositories test_project

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

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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