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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * Parallel port driver for ETRAX.
3
 *
4
 * NOTE!
5
 *   Since par0 shares DMA with ser2 and par 1 shares DMA with ser3
6
 *   this should be handled if both are enabled at the same time.
7
 *   THIS IS NOT HANDLED YET!
8
 *
9
 * Copyright (c) 2001, 2002, 2003 Axis Communications AB
10
 *
11
 * Author: Fredrik Hugosson
12
 *
13
 */
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/config.h>
21
#include <linux/errno.h>
22
#include <linux/kernel.h>
23
#include <linux/major.h>
24
#include <linux/sched.h>
25
 
26
#include <linux/slab.h>
27
#include <linux/interrupt.h>
28
 
29
#include <asm/setup.h>
30
#include <asm/irq.h>
31
#include <asm/io.h>
32
 
33
#include <asm/segment.h>
34
#include <asm/system.h>
35
 
36
#include <asm/svinto.h>
37
 
38
 
39
#undef DEBUG
40
#ifdef DEBUG
41
#define DPRINTK printk
42
#else
43
static inline int DPRINTK(void *nothing, ...) {return 0;}
44
#endif
45
 
46
/*
47
 * Etrax100 DMAchannels:
48
 * Par0 out : DMA2
49
 * Par0 in  : DMA3
50
 * Par1 out : DMA4
51
 * Par1 in  : DMA5
52
 * NOTE! par0 is shared with ser2 and par1 is shared with ser3 regarding
53
 *       DMA and DMA irq
54
 */
55
 
56
//#define CONFIG_PAR0_INT 1
57
//#define CONFIG_PAR1_INT 1
58
 
59
/* Define some macros to access ETRAX 100 registers */
60
#define SETF(var, reg, field, val) var = (var & ~IO_MASK_(reg##_, field##_)) | \
61
                                          IO_FIELD_(reg##_, field##_, val)
62
#define SETS(var, reg, field, val) var = (var & ~IO_MASK_(reg##_, field##_)) | \
63
                                          IO_STATE_(reg##_, field##_, _##val)
64
 
65
struct etrax100par_struct {
66
        /* parallell port control */
67
        volatile u32 *reg_ctrl_data; /* R_PARx_CTRL_DATA */
68
        const volatile u32 *reg_status_data; /* R_PARx_STATUS_DATA */
69
        volatile u32 *reg_config; /* R_PARx_CONFIG */
70
        volatile u32 *reg_delay; /* R_PARx_DELAY */
71
 
72
        /* DMA control */
73
        int odma;
74
        unsigned long dma_irq;  /* bitnr in R_IRQ_MASK2 for dmaX_descr */
75
 
76
        volatile char *oclrintradr; /* adr to R_DMA_CHx_CLR_INTR, output */
77
        volatile u32 *ofirstadr;   /* adr to R_DMA_CHx_FIRST, output */
78
        volatile char *ocmdadr;     /* adr to R_DMA_CHx_CMD, output */
79
 
80
        volatile char *iclrintradr; /* adr to R_DMA_CHx_CLR_INTR, input */
81
        volatile u32 *ifirstadr;   /* adr to R_DMA_CHx_FIRST, input */
82
        volatile char *icmdadr;     /* adr to R_DMA_CHx_CMD, input */
83
 
84
        /* Non DMA interrupt stuff */
85
        unsigned long int_irq; /* R_VECT_MASK_RD */
86
        const volatile u32 *irq_mask_rd; /* R_IRQ_MASKX_RD */
87
        volatile u32 *irq_mask_clr; /* R_IRQ_MASKX_RD */
88
        const volatile u32 *irq_read; /* R_IRQ_READX */
89
        volatile u32 *irq_mask_set; /* R_IRQ_MASKX_SET */
90
        unsigned long irq_mask_tx;  /* bitmask in R_IRQ_ for tx (ready) int */
91
        unsigned long irq_mask_rx;  /* bitmask in R_IRQ_ for rx (data) int */
92
        unsigned long irq_mask_ecp_cmd;  /* mask in R_IRQ_ for ecp_cmd int */
93
        unsigned long irq_mask_peri;  /* bitmask in R_IRQ_ for peri int */
94
        int portnr;
95
 
96
        /* ----- end of fields initialised in port_table[] below ----- */
97
 
98
        struct parport *port;
99
 
100
        /* Shadow registers */
101
        volatile unsigned long reg_ctrl_data_shadow; /* for R_PARx_CTRL_DATA */
102
        volatile unsigned long reg_config_shadow;    /* for R_PARx_CONFIG */
103
        volatile unsigned long reg_delay_shadow;    /* for R_PARx_DELAY */
104
};
105
 
106
/* Always have the complete structs here, even if the port is not used!
107
 *  (that way we can index this by the port number)
108
 */
109
static struct etrax100par_struct port_table[] = {
110
        {
111
                R_PAR0_CTRL_DATA,
112
                R_PAR0_STATUS_DATA,
113
                R_PAR0_CONFIG,
114
                R_PAR0_DELAY,
115
                /* DMA interrupt stuff */
116
                2,
117
                1U << 4, /* uses DMA 2 and 3 */
118
                R_DMA_CH2_CLR_INTR,
119
                R_DMA_CH2_FIRST,
120
                R_DMA_CH2_CMD,
121
                R_DMA_CH3_CLR_INTR,
122
                R_DMA_CH3_FIRST,
123
                R_DMA_CH3_CMD,
124
                /* Non DMA interrupt stuff */
125
                IO_BITNR(R_VECT_MASK_RD, par0),
126
                R_IRQ_MASK0_RD,
127
                R_IRQ_MASK0_CLR,
128
                R_IRQ_READ0,
129
                R_IRQ_MASK0_SET,
130
                IO_FIELD(R_IRQ_MASK0_RD, par0_ready, 1U), /* tx (ready)*/
131
                IO_FIELD(R_IRQ_MASK0_RD, par0_data, 1U), /* rx (data)*/
132
                IO_FIELD(R_IRQ_MASK0_RD, par0_ecp_cmd, 1U), /* ecp_cmd */
133
                IO_FIELD(R_IRQ_MASK0_RD, par0_peri, 1U), /* peri */
134
 
135
        },
136
        {
137
                R_PAR1_CTRL_DATA,
138
                R_PAR1_STATUS_DATA,
139
                R_PAR1_CONFIG,
140
                R_PAR1_DELAY,
141
                /* DMA interrupt stuff */
142
                4,
143
                1U << 8, /* uses DMA 4 and 5 */
144
 
145
                R_DMA_CH4_CLR_INTR,
146
                R_DMA_CH4_FIRST,
147
                R_DMA_CH4_CMD,
148
                R_DMA_CH5_CLR_INTR,
149
                R_DMA_CH5_FIRST,
150
                R_DMA_CH5_CMD,
151
                /* Non DMA interrupt stuff */
152
                IO_BITNR(R_VECT_MASK_RD, par1),
153
                R_IRQ_MASK1_RD,
154
                R_IRQ_MASK1_CLR,
155
                R_IRQ_READ1,
156
                R_IRQ_MASK1_SET,
157
                IO_FIELD(R_IRQ_MASK1_RD, par1_ready, 1U), /* tx (ready)*/
158
                IO_FIELD(R_IRQ_MASK1_RD, par1_data, 1U), /* rx (data)*/
159
                IO_FIELD(R_IRQ_MASK1_RD, par1_ecp_cmd, 1U), /* ecp_cmd */
160
                IO_FIELD(R_IRQ_MASK1_RD, par1_peri, 1U), /* peri */
161
                1
162
        }
163
};
164
 
165
 
166
#define NR_PORTS (sizeof(port_table)/sizeof(struct etrax100par_struct))
167
 
168
static void
169
parport_etrax_write_data(struct parport *p, unsigned char value)
170
{
171
        struct etrax100par_struct *info =
172
                (struct etrax100par_struct *)p->private_data;
173
 
174
        DPRINTK("* E100 PP %d: etrax_write_data %02X\n", p->portnum, value);
175
        SETF(info->reg_ctrl_data_shadow, R_PAR0_CTRL_DATA, data, value);
176
        *info->reg_ctrl_data = info->reg_ctrl_data_shadow;
177
}
178
 
179
 
180
static unsigned char
181
parport_etrax_read_data(struct parport *p)
182
{
183
        unsigned char ret;
184
        struct etrax100par_struct *info =
185
                (struct etrax100par_struct *)p->private_data;
186
 
187
        ret = IO_EXTRACT(R_PAR0_STATUS_DATA, data, *info->reg_status_data);
188
 
189
        DPRINTK("* E100 PP %d: etrax_read_data %02X\n", p->portnum, ret);
190
        return ret;
191
}
192
 
193
 
194
static void
195
parport_etrax_write_control(struct parport *p, unsigned char control)
196
{
197
        struct etrax100par_struct *info =
198
                (struct etrax100par_struct *)p->private_data;
199
 
200
        DPRINTK("* E100 PP %d: etrax_write_control %02x\n", p->portnum, control);
201
 
202
        SETF(info->reg_ctrl_data_shadow, R_PAR0_CTRL_DATA, strb,
203
             (control & PARPORT_CONTROL_STROBE) > 0);
204
        SETF(info->reg_ctrl_data_shadow, R_PAR0_CTRL_DATA, autofd,
205
             (control & PARPORT_CONTROL_AUTOFD) > 0);
206
        SETF(info->reg_ctrl_data_shadow, R_PAR0_CTRL_DATA, init,
207
             (control & PARPORT_CONTROL_INIT) == 0);
208
        SETF(info->reg_ctrl_data_shadow, R_PAR0_CTRL_DATA, seli,
209
             (control & PARPORT_CONTROL_SELECT) > 0);
210
 
211
        *info->reg_ctrl_data = info->reg_ctrl_data_shadow;
212
}
213
 
214
 
215
static unsigned char
216
parport_etrax_read_control( struct parport *p)
217
{
218
        unsigned char ret = 0;
219
        struct etrax100par_struct *info =
220
                (struct etrax100par_struct *)p->private_data;
221
 
222
        if (IO_EXTRACT(R_PAR0_CTRL_DATA, strb, info->reg_ctrl_data_shadow))
223
                ret |= PARPORT_CONTROL_STROBE;
224
        if (IO_EXTRACT(R_PAR0_CTRL_DATA, autofd, info->reg_ctrl_data_shadow))
225
                ret |= PARPORT_CONTROL_AUTOFD;
226
        if (!IO_EXTRACT(R_PAR0_CTRL_DATA, init, info->reg_ctrl_data_shadow))
227
                ret |= PARPORT_CONTROL_INIT;
228
        if (IO_EXTRACT(R_PAR0_CTRL_DATA, seli, info->reg_ctrl_data_shadow))
229
                ret |= PARPORT_CONTROL_SELECT;
230
 
231
        DPRINTK("* E100 PP %d: etrax_read_control %02x\n", p->portnum, ret);
232
        return ret;
233
}
234
 
235
 
236
static unsigned char
237
parport_etrax_frob_control(struct parport *p, unsigned char mask,
238
                           unsigned char val)
239
{
240
        unsigned char old;
241
 
242
        DPRINTK("* E100 PP %d: frob_control mask %02x, value %02x\n",
243
                p->portnum, mask, val);
244
        old = parport_etrax_read_control(p);
245
        parport_etrax_write_control(p, (old & ~mask) ^ val);
246
        return old;
247
}
248
 
249
 
250
static unsigned char
251
parport_etrax_read_status(struct parport *p)
252
{
253
        unsigned char ret = 0;
254
        struct etrax100par_struct *info =
255
                (struct etrax100par_struct *)p->private_data;
256
 
257
        if (IO_EXTRACT(R_PAR0_STATUS_DATA, fault, *info->reg_status_data))
258
                ret |= PARPORT_STATUS_ERROR;
259
        if (IO_EXTRACT(R_PAR0_STATUS_DATA, sel, *info->reg_status_data))
260
                ret |= PARPORT_STATUS_SELECT;
261
        if (IO_EXTRACT(R_PAR0_STATUS_DATA, perr, *info->reg_status_data))
262
                ret |= PARPORT_STATUS_PAPEROUT;
263
        if (IO_EXTRACT(R_PAR0_STATUS_DATA, ack, *info->reg_status_data))
264
                ret |= PARPORT_STATUS_ACK;
265
        if (!IO_EXTRACT(R_PAR0_STATUS_DATA, busy, *info->reg_status_data))
266
                ret |= PARPORT_STATUS_BUSY;
267
 
268
        DPRINTK("* E100 PP %d: status register %04x\n",
269
                p->portnum, *info->reg_status_data);
270
        DPRINTK("* E100 PP %d: read_status %02x\n", p->portnum, ret);
271
        return ret;
272
}
273
 
274
 
275
static void
276
parport_etrax_enable_irq(struct parport *p)
277
{
278
        struct etrax100par_struct *info =
279
                (struct etrax100par_struct *)p->private_data;
280
        *info->irq_mask_set = info->irq_mask_tx;
281
        DPRINTK("* E100 PP %d: enable irq\n", p->portnum);
282
}
283
 
284
 
285
static void
286
parport_etrax_disable_irq(struct parport *p)
287
{
288
        struct etrax100par_struct *info =
289
                (struct etrax100par_struct *)p->private_data;
290
        *info->irq_mask_clr = info->irq_mask_tx;
291
        DPRINTK("* E100 PP %d: disable irq\n", p->portnum);
292
}
293
 
294
 
295
static void
296
parport_etrax_data_forward(struct parport *p)
297
{
298
        struct etrax100par_struct *info =
299
                (struct etrax100par_struct *)p->private_data;
300
 
301
        DPRINTK("* E100 PP %d: forward mode\n", p->portnum);
302
        SETS(info->reg_ctrl_data_shadow, R_PAR0_CTRL_DATA, oe, enable);
303
        *info->reg_ctrl_data = info->reg_ctrl_data_shadow;
304
}
305
 
306
 
307
static void
308
parport_etrax_data_reverse(struct parport *p)
309
{
310
        struct etrax100par_struct *info =
311
                (struct etrax100par_struct *)p->private_data;
312
 
313
        DPRINTK("* E100 PP %d: reverse mode\n", p->portnum);
314
        SETS(info->reg_ctrl_data_shadow, R_PAR0_CTRL_DATA, oe, disable);
315
        *info->reg_ctrl_data = info->reg_ctrl_data_shadow;
316
}
317
 
318
 
319
static void
320
parport_etrax_init_state(struct pardevice *dev, struct parport_state *s)
321
{
322
        DPRINTK("* E100 PP: parport_etrax_init_state\n");
323
}
324
 
325
 
326
static void
327
parport_etrax_save_state(struct parport *p, struct parport_state *s)
328
{
329
        DPRINTK("* E100 PP: parport_etrax_save_state\n");
330
}
331
 
332
 
333
static void
334
parport_etrax_restore_state(struct parport *p, struct parport_state *s)
335
{
336
        DPRINTK("* E100 PP: parport_etrax_restore_state\n");
337
}
338
 
339
 
340
static void
341
parport_etrax_inc_use_count(void)
342
{
343
        MOD_INC_USE_COUNT;
344
}
345
 
346
 
347
static void
348
parport_etrax_dec_use_count(void)
349
{
350
        MOD_DEC_USE_COUNT;
351
}
352
 
353
 
354
static struct
355
parport_operations pp_etrax_ops = {
356
        parport_etrax_write_data,
357
        parport_etrax_read_data,
358
 
359
        parport_etrax_write_control,
360
        parport_etrax_read_control,
361
        parport_etrax_frob_control,
362
 
363
        parport_etrax_read_status,
364
 
365
        parport_etrax_enable_irq,
366
        parport_etrax_disable_irq,
367
 
368
        parport_etrax_data_forward,
369
        parport_etrax_data_reverse,
370
 
371
        parport_etrax_init_state,
372
        parport_etrax_save_state,
373
        parport_etrax_restore_state,
374
 
375
        parport_etrax_inc_use_count,
376
        parport_etrax_dec_use_count,
377
 
378
        parport_ieee1284_epp_write_data,
379
        parport_ieee1284_epp_read_data,
380
        parport_ieee1284_epp_write_addr,
381
        parport_ieee1284_epp_read_addr,
382
 
383
        parport_ieee1284_ecp_write_data,
384
        parport_ieee1284_ecp_read_data,
385
        parport_ieee1284_ecp_write_addr,
386
 
387
        parport_ieee1284_write_compat,
388
        parport_ieee1284_read_nibble,
389
        parport_ieee1284_read_byte,
390
};
391
 
392
 
393
static void
394
parport_etrax_interrupt(int irq, void *dev_id, struct pt_regs *regs)
395
{
396
        struct etrax100par_struct *info = (struct etrax100par_struct *)
397
                ((struct parport *)dev_id)->private_data;
398
        DPRINTK("* E100 PP %d: Interrupt received\n",
399
                ((struct parport *)dev_id)->portnum);
400
        *info->irq_mask_clr = info->irq_mask_tx;
401
        parport_generic_irq(irq, (struct parport *)dev_id, regs);
402
}
403
 
404
/* ----------- Initialisation code --------------------------------- */
405
 
406
static void __init
407
parport_etrax_show_parallel_version(void)
408
{
409
        printk("ETRAX 100LX parallel port driver v1.0, (c) 2001-2003 Axis Communications AB\n");
410
}
411
 
412
#ifdef CONFIG_ETRAX_PAR0_DMA
413
#define PAR0_USE_DMA 1
414
#else
415
#define PAR0_USE_DMA 0
416
#endif
417
 
418
#ifdef CONFIG_ETRAX_PAR1_DMA
419
#define PAR1_USE_DMA 1
420
#else
421
#define PAR1_USE_DMA 0
422
#endif
423
 
424
static void __init
425
parport_etrax_init_registers(void)
426
{
427
        struct etrax100par_struct *info;
428
        int i;
429
 
430
        for (i = 0, info = port_table; i < 2; i++, info++) {
431
#ifndef CONFIG_ETRAX_PARALLEL_PORT0
432
                if (i == 0)
433
                        continue;
434
#endif
435
#ifndef CONFIG_ETRAX_PARALLEL_PORT1
436
                if (i == 1)
437
                        continue;
438
#endif
439
                info->reg_config_shadow =
440
                        IO_STATE(R_PAR0_CONFIG, iseli, inv)       |
441
                        IO_STATE(R_PAR0_CONFIG, iautofd, inv)     |
442
                        IO_STATE(R_PAR0_CONFIG, istrb, inv)       |
443
                        IO_STATE(R_PAR0_CONFIG, iinit, inv)       |
444
                        IO_STATE(R_PAR0_CONFIG, rle_in, disable)  |
445
                        IO_STATE(R_PAR0_CONFIG, rle_out, disable) |
446
                        IO_STATE(R_PAR0_CONFIG, enable, on)       |
447
                        IO_STATE(R_PAR0_CONFIG, force, off)       |
448
                        IO_STATE(R_PAR0_CONFIG, ign_ack, wait)    |
449
                        IO_STATE(R_PAR0_CONFIG, oe_ack, wait_oe)  |
450
                        IO_STATE(R_PAR0_CONFIG, mode, manual);
451
 
452
                if ((i == 0 && PAR0_USE_DMA) || (i == 1 && PAR1_USE_DMA))
453
                        info->reg_config_shadow |=
454
                                IO_STATE(R_PAR0_CONFIG, dma, enable);
455
                else
456
                        info->reg_config_shadow |=
457
                                IO_STATE(R_PAR0_CONFIG, dma, disable);
458
 
459
                *info->reg_config = info->reg_config_shadow;
460
 
461
                info->reg_ctrl_data_shadow =
462
                        IO_STATE(R_PAR0_CTRL_DATA, peri_int, nop)    |
463
                        IO_STATE(R_PAR0_CTRL_DATA, oe, enable)       |
464
                        IO_STATE(R_PAR0_CTRL_DATA, seli, inactive)   |
465
                        IO_STATE(R_PAR0_CTRL_DATA, autofd, inactive) |
466
                        IO_STATE(R_PAR0_CTRL_DATA, strb, inactive)   |
467
                        IO_STATE(R_PAR0_CTRL_DATA, init, inactive)   |
468
                        IO_STATE(R_PAR0_CTRL_DATA, ecp_cmd, data)    |
469
                        IO_FIELD(R_PAR0_CTRL_DATA, data, 0);
470
                *info->reg_ctrl_data = info->reg_ctrl_data_shadow;
471
 
472
                /* Clear peri int without setting shadow */
473
                *info->reg_ctrl_data = info->reg_ctrl_data_shadow |
474
                        IO_STATE(R_PAR0_CTRL_DATA, peri_int, ack);
475
 
476
                info->reg_delay_shadow =
477
                        IO_FIELD(R_PAR0_DELAY, setup, 5)  |
478
                        IO_FIELD(R_PAR0_DELAY, strobe, 5) |
479
                        IO_FIELD(R_PAR0_DELAY, hold, 5);
480
                *info->reg_delay = info->reg_delay_shadow;
481
        }
482
 
483
#ifdef CONFIG_ETRAX_PARALLEL_PORT0
484
#ifdef CONFIG_ETRAX_PAR0_DMA
485
        RESET_DMA(PAR0_TX_DMA_NBR);
486
        WAIT_DMA(PAR0_TX_DMA_NBR);
487
#ifdef CONFIG_ETRAX_SERIAL_PORT2
488
        printk(" Warning - DMA clash with ser2!\n");
489
#endif /* SERIAL_PORT2 */
490
#endif /* DMA */
491
#endif /* PORT0 */
492
 
493
#ifdef CONFIG_ETRAX_PARALLEL_PORT1
494
#ifdef CONFIG_ETRAX_PAR1_DMA
495
        RESET_DMA(PAR1_TX_DMA_NBR);
496
        WAIT_DMA(PAR1_TX_DMA_NBR);
497
#ifdef CONFIG_ETRAX_SERIAL_PORT3
498
        printk(" Warning - DMA clash with ser3!\n");
499
#endif /* SERIAL_PORT3 */
500
#endif /* DMA */
501
#endif /* PORT1 */
502
}
503
 
504
 
505
int __init
506
parport_etrax_init(void)
507
{
508
        struct parport *p;
509
        int port_exists = 0;
510
        int i;
511
        struct etrax100par_struct *info;
512
        const char *names[] = { "parallel 0 tx+rx", "parallel 1 tx+rx" };
513
 
514
        parport_etrax_show_parallel_version();
515
        parport_etrax_init_registers();
516
 
517
        for (i = 0, info = port_table; i < NR_PORTS; i++, info++) {
518
#ifndef CONFIG_ETRAX_PARALLEL_PORT0
519
                if (i == 0)
520
                        continue;
521
#endif
522
#ifndef CONFIG_ETRAX_PARALLEL_PORT1
523
                if (i == 1)
524
                        continue;
525
#endif
526
                p = parport_register_port((unsigned long)0, info->int_irq,
527
                                          PARPORT_DMA_NONE, &pp_etrax_ops);
528
                if (!p)
529
                        continue;
530
 
531
                info->port = p;
532
                p->private_data = info;
533
                /* Axis FIXME: Set mode flags. */
534
                /* p->modes = PARPORT_MODE_TRISTATE | PARPORT_MODE_SAFEININT; */
535
 
536
                if(request_irq(info->int_irq, parport_etrax_interrupt,
537
                               SA_SHIRQ, names[i], p)) {
538
                        parport_unregister_port (p);
539
                        continue;
540
                }
541
 
542
                printk(KERN_INFO "%s: ETRAX 100LX port %d using irq\n",
543
                       p->name, i);
544
                parport_proc_register(p);
545
                parport_announce_port(p);
546
                port_exists = 1;
547
        }
548
 
549
        return port_exists;
550
}
551
 
552
void __exit
553
parport_etrax_exit(void)
554
{
555
        int i;
556
        struct etrax100par_struct *info;
557
 
558
        for (i = 0, info = port_table; i < NR_PORTS; i++, info++) {
559
#ifndef CONFIG_ETRAX_PARALLEL_PORT0
560
                if (i == 0)
561
                        continue;
562
#endif
563
#ifndef CONFIG_ETRAX_PARALLEL_PORT1
564
                if (i == 1)
565
                        continue;
566
#endif
567
                if (info->int_irq != PARPORT_IRQ_NONE)
568
                        free_irq(info->int_irq, info->port);
569
                parport_proc_unregister(info->port);
570
                parport_unregister_port(info->port);
571
        }
572
}

powered by: WebSVN 2.1.0

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