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

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [parport/] [parport_gsc.c] - Blame information for rev 67

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

Line No. Rev Author Line
1 62 marcus.erl
/*
2
 *      Low-level parallel-support for PC-style hardware integrated in the
3
 *      LASI-Controller (on GSC-Bus) for HP-PARISC Workstations
4
 *
5
 *      This program is free software; you can redistribute it and/or modify
6
 *      it under the terms of the GNU General Public License as published by
7
 *      the Free Software Foundation; either version 2 of the License, or
8
 *      (at your option) any later version.
9
 *
10
 *      (C) 1999-2001 by Helge Deller <deller@gmx.de>
11
 *
12
 *
13
 * based on parport_pc.c by
14
 *          Grant Guenther <grant@torque.net>
15
 *          Phil Blundell <philb@gnu.org>
16
 *          Tim Waugh <tim@cyberelk.demon.co.uk>
17
 *          Jose Renau <renau@acm.org>
18
 *          David Campbell
19
 *          Andrea Arcangeli
20
 */
21
 
22
#undef DEBUG    /* undef for production */
23
 
24
#include <linux/module.h>
25
#include <linux/init.h>
26
#include <linux/delay.h>
27
#include <linux/errno.h>
28
#include <linux/interrupt.h>
29
#include <linux/ioport.h>
30
#include <linux/kernel.h>
31
#include <linux/slab.h>
32
#include <linux/pci.h>
33
#include <linux/sysctl.h>
34
 
35
#include <asm/io.h>
36
#include <asm/dma.h>
37
#include <asm/uaccess.h>
38
#include <asm/superio.h>
39
 
40
#include <linux/parport.h>
41
#include <asm/pdc.h>
42
#include <asm/parisc-device.h>
43
#include <asm/hardware.h>
44
#include "parport_gsc.h"
45
 
46
 
47
MODULE_AUTHOR("Helge Deller <deller@gmx.de>");
48
MODULE_DESCRIPTION("HP-PARISC PC-style parallel port driver");
49
MODULE_SUPPORTED_DEVICE("integrated PC-style parallel port");
50
MODULE_LICENSE("GPL");
51
 
52
 
53
/*
54
 * Clear TIMEOUT BIT in EPP MODE
55
 *
56
 * This is also used in SPP detection.
57
 */
58
static int clear_epp_timeout(struct parport *pb)
59
{
60
        unsigned char r;
61
 
62
        if (!(parport_gsc_read_status(pb) & 0x01))
63
                return 1;
64
 
65
        /* To clear timeout some chips require double read */
66
        parport_gsc_read_status(pb);
67
        r = parport_gsc_read_status(pb);
68
        parport_writeb (r | 0x01, STATUS (pb)); /* Some reset by writing 1 */
69
        parport_writeb (r & 0xfe, STATUS (pb)); /* Others by writing 0 */
70
        r = parport_gsc_read_status(pb);
71
 
72
        return !(r & 0x01);
73
}
74
 
75
/*
76
 * Access functions.
77
 *
78
 * Most of these aren't static because they may be used by the
79
 * parport_xxx_yyy macros.  extern __inline__ versions of several
80
 * of these are in parport_gsc.h.
81
 */
82
 
83
void parport_gsc_init_state(struct pardevice *dev, struct parport_state *s)
84
{
85
        s->u.pc.ctr = 0xc | (dev->irq_func ? 0x10 : 0x0);
86
}
87
 
88
void parport_gsc_save_state(struct parport *p, struct parport_state *s)
89
{
90
        s->u.pc.ctr = parport_readb (CONTROL (p));
91
}
92
 
93
void parport_gsc_restore_state(struct parport *p, struct parport_state *s)
94
{
95
        parport_writeb (s->u.pc.ctr, CONTROL (p));
96
}
97
 
98
struct parport_operations parport_gsc_ops =
99
{
100
        .write_data     = parport_gsc_write_data,
101
        .read_data      = parport_gsc_read_data,
102
 
103
        .write_control  = parport_gsc_write_control,
104
        .read_control   = parport_gsc_read_control,
105
        .frob_control   = parport_gsc_frob_control,
106
 
107
        .read_status    = parport_gsc_read_status,
108
 
109
        .enable_irq     = parport_gsc_enable_irq,
110
        .disable_irq    = parport_gsc_disable_irq,
111
 
112
        .data_forward   = parport_gsc_data_forward,
113
        .data_reverse   = parport_gsc_data_reverse,
114
 
115
        .init_state     = parport_gsc_init_state,
116
        .save_state     = parport_gsc_save_state,
117
        .restore_state  = parport_gsc_restore_state,
118
 
119
        .epp_write_data = parport_ieee1284_epp_write_data,
120
        .epp_read_data  = parport_ieee1284_epp_read_data,
121
        .epp_write_addr = parport_ieee1284_epp_write_addr,
122
        .epp_read_addr  = parport_ieee1284_epp_read_addr,
123
 
124
        .ecp_write_data = parport_ieee1284_ecp_write_data,
125
        .ecp_read_data  = parport_ieee1284_ecp_read_data,
126
        .ecp_write_addr = parport_ieee1284_ecp_write_addr,
127
 
128
        .compat_write_data      = parport_ieee1284_write_compat,
129
        .nibble_read_data       = parport_ieee1284_read_nibble,
130
        .byte_read_data         = parport_ieee1284_read_byte,
131
 
132
        .owner          = THIS_MODULE,
133
};
134
 
135
/* --- Mode detection ------------------------------------- */
136
 
137
/*
138
 * Checks for port existence, all ports support SPP MODE
139
 */
140
static int __devinit parport_SPP_supported(struct parport *pb)
141
{
142
        unsigned char r, w;
143
 
144
        /*
145
         * first clear an eventually pending EPP timeout
146
         * I (sailer@ife.ee.ethz.ch) have an SMSC chipset
147
         * that does not even respond to SPP cycles if an EPP
148
         * timeout is pending
149
         */
150
        clear_epp_timeout(pb);
151
 
152
        /* Do a simple read-write test to make sure the port exists. */
153
        w = 0xc;
154
        parport_writeb (w, CONTROL (pb));
155
 
156
        /* Is there a control register that we can read from?  Some
157
         * ports don't allow reads, so read_control just returns a
158
         * software copy. Some ports _do_ allow reads, so bypass the
159
         * software copy here.  In addition, some bits aren't
160
         * writable. */
161
        r = parport_readb (CONTROL (pb));
162
        if ((r & 0xf) == w) {
163
                w = 0xe;
164
                parport_writeb (w, CONTROL (pb));
165
                r = parport_readb (CONTROL (pb));
166
                parport_writeb (0xc, CONTROL (pb));
167
                if ((r & 0xf) == w)
168
                        return PARPORT_MODE_PCSPP;
169
        }
170
 
171
        /* Try the data register.  The data lines aren't tri-stated at
172
         * this stage, so we expect back what we wrote. */
173
        w = 0xaa;
174
        parport_gsc_write_data (pb, w);
175
        r = parport_gsc_read_data (pb);
176
        if (r == w) {
177
                w = 0x55;
178
                parport_gsc_write_data (pb, w);
179
                r = parport_gsc_read_data (pb);
180
                if (r == w)
181
                        return PARPORT_MODE_PCSPP;
182
        }
183
 
184
        return 0;
185
}
186
 
187
/* Detect PS/2 support.
188
 *
189
 * Bit 5 (0x20) sets the PS/2 data direction; setting this high
190
 * allows us to read data from the data lines.  In theory we would get back
191
 * 0xff but any peripheral attached to the port may drag some or all of the
192
 * lines down to zero.  So if we get back anything that isn't the contents
193
 * of the data register we deem PS/2 support to be present.
194
 *
195
 * Some SPP ports have "half PS/2" ability - you can't turn off the line
196
 * drivers, but an external peripheral with sufficiently beefy drivers of
197
 * its own can overpower them and assert its own levels onto the bus, from
198
 * where they can then be read back as normal.  Ports with this property
199
 * and the right type of device attached are likely to fail the SPP test,
200
 * (as they will appear to have stuck bits) and so the fact that they might
201
 * be misdetected here is rather academic.
202
 */
203
 
204
static int __devinit parport_PS2_supported(struct parport *pb)
205
{
206
        int ok = 0;
207
 
208
        clear_epp_timeout(pb);
209
 
210
        /* try to tri-state the buffer */
211
        parport_gsc_data_reverse (pb);
212
 
213
        parport_gsc_write_data(pb, 0x55);
214
        if (parport_gsc_read_data(pb) != 0x55) ok++;
215
 
216
        parport_gsc_write_data(pb, 0xaa);
217
        if (parport_gsc_read_data(pb) != 0xaa) ok++;
218
 
219
        /* cancel input mode */
220
        parport_gsc_data_forward (pb);
221
 
222
        if (ok) {
223
                pb->modes |= PARPORT_MODE_TRISTATE;
224
        } else {
225
                struct parport_gsc_private *priv = pb->private_data;
226
                priv->ctr_writable &= ~0x20;
227
        }
228
 
229
        return ok;
230
}
231
 
232
 
233
/* --- Initialisation code -------------------------------- */
234
 
235
struct parport *__devinit parport_gsc_probe_port (unsigned long base,
236
                                                 unsigned long base_hi,
237
                                                 int irq, int dma,
238
                                                 struct pci_dev *dev)
239
{
240
        struct parport_gsc_private *priv;
241
        struct parport_operations *ops;
242
        struct parport tmp;
243
        struct parport *p = &tmp;
244
 
245
        priv = kzalloc (sizeof (struct parport_gsc_private), GFP_KERNEL);
246
        if (!priv) {
247
                printk (KERN_DEBUG "parport (0x%lx): no memory!\n", base);
248
                return NULL;
249
        }
250
        ops = kmalloc (sizeof (struct parport_operations), GFP_KERNEL);
251
        if (!ops) {
252
                printk (KERN_DEBUG "parport (0x%lx): no memory for ops!\n",
253
                        base);
254
                kfree (priv);
255
                return NULL;
256
        }
257
        memcpy (ops, &parport_gsc_ops, sizeof (struct parport_operations));
258
        priv->ctr = 0xc;
259
        priv->ctr_writable = 0xff;
260
        priv->dma_buf = 0;
261
        priv->dma_handle = 0;
262
        priv->dev = dev;
263
        p->base = base;
264
        p->base_hi = base_hi;
265
        p->irq = irq;
266
        p->dma = dma;
267
        p->modes = PARPORT_MODE_PCSPP | PARPORT_MODE_SAFEININT;
268
        p->ops = ops;
269
        p->private_data = priv;
270
        p->physport = p;
271
        if (!parport_SPP_supported (p)) {
272
                /* No port. */
273
                kfree (priv);
274
                return NULL;
275
        }
276
        parport_PS2_supported (p);
277
 
278
        if (!(p = parport_register_port(base, PARPORT_IRQ_NONE,
279
                                        PARPORT_DMA_NONE, ops))) {
280
                kfree (priv);
281
                kfree (ops);
282
                return NULL;
283
        }
284
 
285
        p->base_hi = base_hi;
286
        p->modes = tmp.modes;
287
        p->size = (p->modes & PARPORT_MODE_EPP)?8:3;
288
        p->private_data = priv;
289
 
290
        printk(KERN_INFO "%s: PC-style at 0x%lx", p->name, p->base);
291
        p->irq = irq;
292
        if (p->irq == PARPORT_IRQ_AUTO) {
293
                p->irq = PARPORT_IRQ_NONE;
294
        }
295
        if (p->irq != PARPORT_IRQ_NONE) {
296
                printk(", irq %d", p->irq);
297
 
298
                if (p->dma == PARPORT_DMA_AUTO) {
299
                        p->dma = PARPORT_DMA_NONE;
300
                }
301
        }
302
        if (p->dma == PARPORT_DMA_AUTO) /* To use DMA, giving the irq
303
                                           is mandatory (see above) */
304
                p->dma = PARPORT_DMA_NONE;
305
 
306
        printk(" [");
307
#define printmode(x) {if(p->modes&PARPORT_MODE_##x){printk("%s%s",f?",":"",#x);f++;}}
308
        {
309
                int f = 0;
310
                printmode(PCSPP);
311
                printmode(TRISTATE);
312
                printmode(COMPAT)
313
                printmode(EPP);
314
//              printmode(ECP);
315
//              printmode(DMA);
316
        }
317
#undef printmode
318
        printk("]\n");
319
 
320
        if (p->irq != PARPORT_IRQ_NONE) {
321
                if (request_irq (p->irq, parport_irq_handler,
322
                                 0, p->name, p)) {
323
                        printk (KERN_WARNING "%s: irq %d in use, "
324
                                "resorting to polled operation\n",
325
                                p->name, p->irq);
326
                        p->irq = PARPORT_IRQ_NONE;
327
                        p->dma = PARPORT_DMA_NONE;
328
                }
329
        }
330
 
331
        /* Done probing.  Now put the port into a sensible start-up state. */
332
 
333
        parport_gsc_write_data(p, 0);
334
        parport_gsc_data_forward (p);
335
 
336
        /* Now that we've told the sharing engine about the port, and
337
           found out its characteristics, let the high-level drivers
338
           know about it. */
339
        parport_announce_port (p);
340
 
341
        return p;
342
}
343
 
344
 
345
#define PARPORT_GSC_OFFSET 0x800
346
 
347
static int __devinitdata parport_count;
348
 
349
static int __devinit parport_init_chip(struct parisc_device *dev)
350
{
351
        struct parport *p;
352
        unsigned long port;
353
 
354
        if (!dev->irq) {
355
                printk(KERN_WARNING "IRQ not found for parallel device at 0x%lx\n",
356
                        dev->hpa.start);
357
                return -ENODEV;
358
        }
359
 
360
        port = dev->hpa.start + PARPORT_GSC_OFFSET;
361
 
362
        /* some older machines with ASP-chip don't support
363
         * the enhanced parport modes.
364
         */
365
        if (boot_cpu_data.cpu_type > pcxt && !pdc_add_valid(port+4)) {
366
 
367
                /* Initialize bidirectional-mode (0x10) & data-tranfer-mode #1 (0x20) */
368
                printk("%s: initialize bidirectional-mode.\n", __FUNCTION__);
369
                parport_writeb ( (0x10 + 0x20), port + 4);
370
 
371
        } else {
372
                printk("%s: enhanced parport-modes not supported.\n", __FUNCTION__);
373
        }
374
 
375
        p = parport_gsc_probe_port(port, 0, dev->irq,
376
                        /* PARPORT_IRQ_NONE */ PARPORT_DMA_NONE, NULL);
377
        if (p)
378
                parport_count++;
379
        dev->dev.driver_data = p;
380
 
381
        return 0;
382
}
383
 
384
static int __devexit parport_remove_chip(struct parisc_device *dev)
385
{
386
        struct parport *p = dev->dev.driver_data;
387
        if (p) {
388
                struct parport_gsc_private *priv = p->private_data;
389
                struct parport_operations *ops = p->ops;
390
                parport_remove_port(p);
391
                if (p->dma != PARPORT_DMA_NONE)
392
                        free_dma(p->dma);
393
                if (p->irq != PARPORT_IRQ_NONE)
394
                        free_irq(p->irq, p);
395
                if (priv->dma_buf)
396
                        pci_free_consistent(priv->dev, PAGE_SIZE,
397
                                            priv->dma_buf,
398
                                            priv->dma_handle);
399
                kfree (p->private_data);
400
                parport_put_port(p);
401
                kfree (ops); /* hope no-one cached it */
402
        }
403
        return 0;
404
}
405
 
406
static struct parisc_device_id parport_tbl[] = {
407
        { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x74 },
408
        { 0, }
409
};
410
 
411
MODULE_DEVICE_TABLE(parisc, parport_tbl);
412
 
413
static struct parisc_driver parport_driver = {
414
        .name           = "Parallel",
415
        .id_table       = parport_tbl,
416
        .probe          = parport_init_chip,
417
        .remove         = __devexit_p(parport_remove_chip),
418
};
419
 
420
int __devinit parport_gsc_init(void)
421
{
422
        return register_parisc_driver(&parport_driver);
423
}
424
 
425
static void __devexit parport_gsc_exit(void)
426
{
427
        unregister_parisc_driver(&parport_driver);
428
}
429
 
430
module_init(parport_gsc_init);
431
module_exit(parport_gsc_exit);

powered by: WebSVN 2.1.0

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