1 #include <linux/kernel.h>
2 #include <linux/module.h>
4 #include <linux/init.h>
5 #include <linux/cdev.h>
7 #include <linux/spinlock.h>
8 #include <linux/list.h>
9 #include <linux/wait.h>
10 #include <asm/uaccess.h> /* copy_*_user */
11 #include <asm/semaphore.h>
14 #include "modulbus_register.h"
17 #define DRIVER_NAME "vmodttl"
18 #define PFX DRIVER_NAME ": "
21 struct list_head list
;
33 int created
; /* flag initialize */
35 int OpenCount
; /* open count */
37 int us_pulse
; /* Time being up of the data strobe pulse */
39 spinlock_t vmodttl_spinlock
;
40 spinlock_t vmodttl_read
;
41 struct message_list
*messages
;
42 struct vmod_dev
*config
;
43 wait_queue_head_t wait
;
44 struct vmodttlconfig ioconfig
;
48 /* The One And Only Device (OAOD) */
51 /* module config tables */
52 static struct vmod_devices dt
, *dev_table
= &dt
;
54 /* The One And Only Device (OAOD) */
57 static struct vmodttl_dev
*pvmodttlDv
[VMODTTL_MAX_BOARDS
];
66 static uint16_t vmodttl_read_word(struct vmodttl_dev
*pd
, int offset
)
69 unsigned long ioaddr
= 0;
72 ioaddr
= pd
->config
->address
+ offset
;
73 if (pd
->config
->is_big_endian
)
74 val
= ioread16be((u16
*)(ioaddr
));
76 val
= ioread16((u16
*)(ioaddr
));
83 static void vmodttl_write_word(struct vmodttl_dev
*pd
, int offset
, uint16_t value
)
85 unsigned long ioaddr
= pd
->config
->address
+ offset
;
86 if(pd
->config
->is_big_endian
)
87 iowrite16be(value
, (u16
*)ioaddr
);
89 iowrite16(value
, (u16
*)ioaddr
);
94 /* Init the ports with the desired setup */
95 static void vmodttl_def_io(struct vmodttl_dev
*pd
)
99 /* It has been needed reset MCCR with 0 to avoid a missing configuration of the register DDR_A */
100 /* Do not delete this two lines! */
101 vmodttl_write_word(pd
, VMODTTL_CONTROL
, MCCR
);
102 vmodttl_write_word(pd
, VMODTTL_CONTROL
, 0);
105 /* -------------------- */
106 /* disable interrupt */
107 vmodttl_write_word(pd
, VMODTTL_CONTROL
, PCSR_A
);
108 vmodttl_write_word(pd
, VMODTTL_CONTROL
, CLEAR_IE
);
110 vmodttl_write_word(pd
, VMODTTL_CONTROL
, PCSR_A
);
111 vmodttl_write_word(pd
, VMODTTL_CONTROL
, CLEAR_IP_IUS
);
113 vmodttl_write_word(pd
, VMODTTL_CONTROL
, PMSR_A
);
114 vmodttl_write_word(pd
, VMODTTL_CONTROL
, 0x14); /* /LPM Latch on Pattern Match */
116 if((pd
->open_collector
& A_CHAN_OPEN_COLLECTOR
) == A_CHAN_OPEN_COLLECTOR
) {
117 /* open collector connection mode */
118 if(pd
->io_flag
& A_CHAN_OUT
) {
119 vmodttl_write_word(pd
, VMODTTL_CONTROL
, DDR_A
);
120 vmodttl_write_word(pd
, VMODTTL_CONTROL
, 0x00); /* output */
121 vmodttl_write_word(pd
, VMODTTL_CONTROL
, DPPR_A
);
122 vmodttl_write_word(pd
, VMODTTL_CONTROL
, 0x00);
124 vmodttl_write_word(pd
, VMODTTL_CONTROL
, DDR_A
);
125 vmodttl_write_word(pd
, VMODTTL_CONTROL
, 0xff); /* input */
126 vmodttl_write_word(pd
, VMODTTL_CONTROL
, DPPR_A
);
128 if(pd
->io_flag
& VMODTTL_O
)
129 vmodttl_write_word(pd
, VMODTTL_CONTROL
, 0xff); /* invert! */
131 vmodttl_write_word(pd
, VMODTTL_CONTROL
, 0x00);
134 /* normal TTL connection mode */
135 if(pd
->io_flag
& A_CHAN_OUT
) {
136 vmodttl_write_word(pd
, VMODTTL_CONTROL
, DDR_A
);
137 vmodttl_write_word(pd
, VMODTTL_CONTROL
, 0x00); /* output */
139 vmodttl_write_word(pd
, VMODTTL_CONTROL
, DDR_A
);
140 vmodttl_write_word(pd
, VMODTTL_CONTROL
, 0xff); /* input */
143 vmodttl_write_word(pd
, VMODTTL_CONTROL
, DPPR_A
);
144 if(pd
->io_flag
& VMODTTL_O
)
145 vmodttl_write_word(pd
, VMODTTL_CONTROL
, 0xff); /* invert! */
147 vmodttl_write_word(pd
, VMODTTL_CONTROL
, 0x00);
150 vmodttl_write_word(pd
, VMODTTL_CONTROL
, SIOCR_A
);
151 vmodttl_write_word(pd
, VMODTTL_CONTROL
, 0x00);
154 /* -------------------- */
155 /* disable interrupt */
156 vmodttl_write_word(pd
, VMODTTL_CONTROL
, PCSR_B
);
157 vmodttl_write_word(pd
, VMODTTL_CONTROL
, CLEAR_IE
);
159 vmodttl_write_word(pd
, VMODTTL_CONTROL
, PCSR_B
);
160 vmodttl_write_word(pd
, VMODTTL_CONTROL
, CLEAR_IP_IUS
);
162 vmodttl_write_word(pd
, VMODTTL_CONTROL
,PMSR_B
);
163 vmodttl_write_word(pd
, VMODTTL_CONTROL
, 0x14); /* /LPM Latch on Pattern Match */
165 if((pd
->open_collector
& B_CHAN_OPEN_COLLECTOR
) == B_CHAN_OPEN_COLLECTOR
) {
166 /* open collector connection mode */
167 if(pd
->io_flag
& B_CHAN_OUT
) {
168 vmodttl_write_word(pd
, VMODTTL_CONTROL
, DDR_B
);
169 vmodttl_write_word(pd
, VMODTTL_CONTROL
, 0x00); /* output */
170 vmodttl_write_word(pd
, VMODTTL_CONTROL
, DPPR_B
);
171 vmodttl_write_word(pd
, VMODTTL_CONTROL
, 0x00);
173 vmodttl_write_word(pd
, VMODTTL_CONTROL
, DDR_B
);
174 vmodttl_write_word(pd
, VMODTTL_CONTROL
, 0xff); /* input */
175 vmodttl_write_word(pd
, VMODTTL_CONTROL
, DPPR_B
);
176 if(pd
->io_flag
& VMODTTL_O
)
177 vmodttl_write_word(pd
, VMODTTL_CONTROL
, 0xff); /* invert! */
179 vmodttl_write_word(pd
, VMODTTL_CONTROL
, 0x00);
182 /* normal TTL connection mode */
183 if(pd
->io_flag
& B_CHAN_OUT
) {
184 vmodttl_write_word(pd
, VMODTTL_CONTROL
, DDR_B
);
185 vmodttl_write_word(pd
, VMODTTL_CONTROL
, 0x00); /* output */
187 vmodttl_write_word(pd
, VMODTTL_CONTROL
, DDR_B
);
188 vmodttl_write_word(pd
, VMODTTL_CONTROL
, 0xff); /* input */
190 vmodttl_write_word(pd
, VMODTTL_CONTROL
, DPPR_B
);
191 if(pd
->io_flag
& VMODTTL_O
)
192 vmodttl_write_word(pd
, VMODTTL_CONTROL
, 0xff); /* invert! */
194 vmodttl_write_word(pd
, VMODTTL_CONTROL
, 0x00);
197 vmodttl_write_word(pd
, VMODTTL_CONTROL
, SIOCR_B
);
198 vmodttl_write_word(pd
, VMODTTL_CONTROL
, 0x00);
200 /* port C generates data strobe (Output) */
201 if((pd
->open_collector
& C_CHAN_OPEN_COLLECTOR
) == C_CHAN_OPEN_COLLECTOR
) {
202 /* open collector connection mode */
203 vmodttl_write_word(pd
, VMODTTL_CONTROL
, DDR_C
);
204 vmodttl_write_word(pd
, VMODTTL_CONTROL
, 0x00); /* output */
205 vmodttl_write_word(pd
, VMODTTL_CONTROL
, DPPR_C
);
206 vmodttl_write_word(pd
, VMODTTL_CONTROL
, 0x00);
208 /* normal TTL connection mode */
209 vmodttl_write_word(pd
, VMODTTL_CONTROL
, DDR_C
);
210 vmodttl_write_word(pd
, VMODTTL_CONTROL
, 0x00); /* output */
212 vmodttl_write_word(pd
, VMODTTL_CONTROL
, DPPR_C
);
213 if(pd
->io_flag
& VMODTTL_O
)
214 vmodttl_write_word(pd
, VMODTTL_CONTROL
, 0x0f); /* invert! */
216 vmodttl_write_word(pd
, VMODTTL_CONTROL
, 0x00);
219 vmodttl_write_word(pd
, VMODTTL_CONTROL
, SIOCR_C
);
220 vmodttl_write_word(pd
, VMODTTL_CONTROL
, 0x00);
222 vmodttl_write_word(pd
, VMODTTL_CONTROL
, MCCR
);
223 tmp
= vmodttl_read_word(pd
, VMODTTL_CONTROL
) | PAE
| PBE
| PCE
;
224 vmodttl_write_word(pd
, VMODTTL_CONTROL
, MCCR
);
225 vmodttl_write_word(pd
, VMODTTL_CONTROL
, tmp
);
228 /* Configure the Zilog Z8536 CIO */
229 static void vmodttl_default(struct vmodttl_dev
*pd
)
235 spin_lock_irqsave(&pd
->vmodttl_spinlock
, flags
);
237 /* Prepare the Zilog Z8536 CIO to be configured */
238 dummy
= vmodttl_read_word(pd
, VMODTTL_CONTROL
);
239 vmodttl_write_word(pd
, VMODTTL_CONTROL
, MCCR
);
240 vmodttl_write_word(pd
, VMODTTL_CONTROL
, 0);
241 vmodttl_write_word(pd
, VMODTTL_CONTROL
, MICR
);
242 dummy
= vmodttl_read_word(pd
, VMODTTL_CONTROL
);
243 vmodttl_write_word(pd
, VMODTTL_CONTROL
, MICR
);
244 vmodttl_write_word(pd
, VMODTTL_CONTROL
, 0);
246 vmodttl_write_word(pd
, VMODTTL_CONTROL
, MICR
); /* reset cio */
247 vmodttl_write_word(pd
, VMODTTL_CONTROL
, RESET
);
248 vmodttl_write_word(pd
, VMODTTL_CONTROL
,0);
252 /* enable master interrupts */
253 vmodttl_write_word(pd
, VMODTTL_CONTROL
, MICR
);
254 i
= (vmodttl_read_word(pd
, VMODTTL_CONTROL
) | MIE
| NV
);
255 vmodttl_write_word(pd
, VMODTTL_CONTROL
, MICR
);
256 vmodttl_write_word(pd
, VMODTTL_CONTROL
, i
);
258 spin_unlock_irqrestore(&pd
->vmodttl_spinlock
, flags
);
259 printk(KERN_INFO PFX
"board %d initialized\n", pd
->dev
);
262 int vmodttl_open(struct inode
*inode
, struct file
*filp
)
264 unsigned int minor
= iminor(inode
);
265 struct vmodttl_dev
*pd
= (struct vmodttl_dev
*)pvmodttlDv
[minor
];
271 int vmodttl_release(struct inode
*inode
, struct file
*filp
)
273 unsigned int minor
= iminor(inode
);
274 struct vmodttl_dev
*pd
= (struct vmodttl_dev
*)pvmodttlDv
[minor
];
280 static int vmodttl_config(struct vmodttlconfig conf
, struct vmodttl_dev
*pd
)
284 spin_lock_irqsave(&pd
->vmodttl_spinlock
, flags
);
285 if((conf
.io_flag
> (A_CHAN_OUT
+ B_CHAN_OUT
+ C_CHAN_OUT
)) ||
287 spin_unlock_irqrestore(&pd
->vmodttl_spinlock
, flags
);
290 pd
->io_flag
= conf
.io_flag
;
292 /* Used to keep up the strobe pulse during us_pulse time */
293 if (conf
.us_pulse
< DEFAULT_DELAY
)
294 pd
->us_pulse
= DEFAULT_DELAY
;
296 pd
->us_pulse
= conf
.us_pulse
;
299 pd
->io_flag
|= VMODTTL_O
;
301 pd
->open_collector
= conf
.open_collector
;
303 spin_unlock_irqrestore(&pd
->vmodttl_spinlock
, flags
);
307 static int vmodttl_read_chan(struct vmodttlarg buf
, struct vmodttl_dev
*pd
)
310 int strobe_value
= 0;
312 spin_lock(&pd
->vmodttl_spinlock
);
315 case VMOD_TTL_CHANNEL_A
:
316 val
= vmodttl_read_word(pd
, VMODTTL_PORTA
);
320 case VMOD_TTL_CHANNEL_B
:
321 val
= vmodttl_read_word(pd
, VMODTTL_PORTB
);
325 case VMOD_TTL_CHANNELS_AB
:
326 val
= vmodttl_read_word(pd
, VMODTTL_PORTA
) & 0x00ff;
327 val
+= (vmodttl_read_word(pd
, VMODTTL_PORTB
) & 0x00ff) << 8;
333 /* produce the strobe on C channel (pulse) */
334 vmodttl_write_word(pd
, VMODTTL_PORTC
, strobe_value
);
335 udelay(pd
->us_pulse
);
336 vmodttl_write_word(pd
, VMODTTL_PORTC
, 0);
337 spin_unlock(&pd
->vmodttl_spinlock
);
343 static int vmodttl_write_chan(struct vmodttlarg buf
, struct vmodttl_dev
*pd
)
348 int strobe_value
= 0;
353 if(dev
< VMOD_TTL_CHANNEL_A
|| dev
> VMOD_TTL_CHANNELS_AB
)
354 return -EINVAL
; /* invalid channel */
356 spin_lock(&pd
->vmodttl_spinlock
);
358 case VMOD_TTL_CHANNEL_A
:
360 if((pd
->io_flag
& A_CHAN_OUT
) == A_CHAN_IN
){
361 spin_unlock(&pd
->vmodttl_spinlock
);
365 vmodttl_write_word(pd
, VMODTTL_PORTA
, data
);
366 vmodttl_write_word(pd
, VMODTTL_CONTROL
, MCCR
);
367 tmp
= vmodttl_read_word(pd
, VMODTTL_CONTROL
);
369 vmodttl_write_word(pd
, VMODTTL_CONTROL
, MCCR
);
370 vmodttl_write_word(pd
, VMODTTL_CONTROL
, (tmp
| PAE
));
374 case VMOD_TTL_CHANNEL_B
:
376 if((pd
->io_flag
& B_CHAN_OUT
) == B_CHAN_IN
){
377 spin_unlock(&pd
->vmodttl_spinlock
);
381 vmodttl_write_word(pd
, VMODTTL_PORTB
, data
);
382 vmodttl_write_word(pd
, VMODTTL_CONTROL
, MCCR
);
383 tmp
= vmodttl_read_word(pd
, VMODTTL_CONTROL
);
385 vmodttl_write_word(pd
, VMODTTL_CONTROL
, MCCR
);
386 vmodttl_write_word(pd
, VMODTTL_CONTROL
, (tmp
| PBE
));
390 case VMOD_TTL_CHANNELS_AB
:
392 if(((pd
->io_flag
& B_CHAN_OUT
) == B_CHAN_IN
) ||
393 (pd
->io_flag
& A_CHAN_OUT
) == A_CHAN_IN
) {
394 spin_unlock(&pd
->vmodttl_spinlock
);
398 vmodttl_write_word(pd
, VMODTTL_PORTA
, data
& 0xff);
399 vmodttl_write_word(pd
, VMODTTL_CONTROL
, MCCR
);
400 tmp
= vmodttl_read_word(pd
, VMODTTL_CONTROL
);
402 vmodttl_write_word(pd
, VMODTTL_PORTB
, (data
>> 8) & 0xff);
403 vmodttl_write_word(pd
, VMODTTL_CONTROL
, MCCR
);
404 tmp
= vmodttl_read_word(pd
, VMODTTL_CONTROL
);
406 vmodttl_write_word(pd
, VMODTTL_CONTROL
, MCCR
);
407 vmodttl_write_word(pd
, VMODTTL_CONTROL
, (tmp
| PAE
| PBE
));
414 /* produce the strobe on C channel (pulse) */
415 vmodttl_write_word(pd
, VMODTTL_PORTC
, strobe_value
);
416 udelay(pd
->us_pulse
);
417 vmodttl_write_word(pd
, VMODTTL_PORTC
, 0);
418 spin_unlock(&pd
->vmodttl_spinlock
);
422 static int vmodttl_ioctl(struct inode
*inode
, struct file
*fp
, unsigned op
, unsigned long arg
)
424 unsigned int minor
= iminor(inode
);
425 struct vmodttl_dev
*pd
= (struct vmodttl_dev
*)pvmodttlDv
[minor
];
432 struct vmodttlconfig conf
;
434 if(copy_from_user((char *)&conf
, (char *)arg
, sizeof(struct vmodttlconfig
)))
438 ret
= vmodttl_config(conf
, pd
);
443 case VMODTTL_READ_CONFIG
:
444 if(copy_to_user((char *)arg
, (char *)&pd
->ioconfig
, sizeof(struct vmodttlconfig
)))
450 /* It's the default behaviour: Bit port simple operation without interrupts */
451 /* This ioctl operation resets the channels to this mode */
455 case VMODTTL_PATTERN
:
457 struct vmodttl_pattern buf
;
459 if(copy_from_user((char *)&buf
, (char *)arg
, sizeof(struct vmodttl_pattern
)))
461 pd
->ioconfig
.bit_pattern_a
[buf
.pos
] = buf
;
464 case VMODTTL_READ_CHAN
:
466 struct vmodttlarg buf
;
469 if(copy_from_user((char *)&buf
, (char *)arg
,sizeof(struct vmodttlarg
)))
472 dev
= buf
.dev
& 0x00ff; /* Get channel */
473 if(dev
< VMOD_TTL_CHANNEL_A
|| dev
> VMOD_TTL_CHANNELS_AB
)
474 return -EINVAL
; /* invalid channel */
476 buf
.val
= vmodttl_read_chan(buf
, pd
);
477 if(copy_to_user((char *)arg
, (char *)&buf
, sizeof(struct vmodttlarg
)))
482 case VMODTTL_WRITE_CHAN
:
484 struct vmodttlarg buf
;
486 if(copy_from_user((char *)&buf
, (char *)arg
, sizeof(struct vmodttlarg
)))
489 ret
= vmodttl_write_chan(buf
, pd
);
495 printk(KERN_INFO PFX
"There is no default option");
502 struct file_operations vmodttl_fops
= {
503 .owner
= THIS_MODULE
,
505 .ioctl
= vmodttl_ioctl
,
506 .open
= vmodttl_open
,
507 .release
= vmodttl_release
510 static int register_module_isr(struct vmodttl_dev
*dev
, isrcb_t handler
)
514 char *carrier
= dev
->config
->carrier_name
;
515 int lun
= dev
->config
->carrier_lun
;
516 int slot
= dev
->config
->slot
;
518 register_isr
= modulbus_carrier_isr_entry(carrier
);
519 if (register_isr
== NULL
)
522 err
= register_isr(handler
, (void *)dev
, lun
, slot
);
529 "could not register irq handler for lun %d\n",
535 static int unregister_module_isr(struct vmodttl_dev
*dev
)
537 return register_module_isr(dev
, NULL
);
540 static int __init
vmodttl_init(void)
544 struct vmodttl_dev
*pd
;
546 printk(KERN_INFO PFX
"reading parameters\n");
548 err
= read_params(DRIVER_NAME
, dev_table
);
551 printk(KERN_INFO PFX
"initialized driver for %d (max %d) cards\n",
552 dev_table
->num_modules
, VMODTTL_MAX_BOARDS
);
554 err
= alloc_chrdev_region(&devno
, 0, VMODTTL_MAX_BOARDS
, DRIVER_NAME
);
558 printk(KERN_INFO PFX
"allocated device %d\n", MAJOR(devno
));
560 cdev_init(&cdev
, &vmodttl_fops
);
561 cdev
.owner
= THIS_MODULE
;
562 err
= cdev_add(&cdev
, devno
, VMODTTL_MAX_BOARDS
);
564 printk(KERN_ERR PFX
"Added cdev with err = %d\n", err
);
568 for(i
= 0; i
< dev_table
->num_modules
; i
++){
569 struct vmod_dev
*mod
= &dev_table
->module
[i
];
571 pd
= kzalloc(sizeof(struct vmodttl_dev
), GFP_KERNEL
);
576 pvmodttlDv
[mod
->lun
] = (void *)pd
;
578 pd
->dev
= lun_to_index(dev_table
, mod
->lun
);
580 pd
->io_flag
= 0; /* All channels are inputs by default */
581 pd
->open_collector
= 0; /* All channels are TTL by default */
583 spin_lock_init(&pd
->vmodttl_spinlock
);
584 spin_lock_init(&pd
->vmodttl_read
);
585 init_waitqueue_head(&pd
->wait
);
586 pd
->messages
= kzalloc(sizeof(struct message_list
), GFP_KERNEL
);
587 if (pd
->messages
== 0)
590 INIT_LIST_HEAD(&pd
->messages
->list
);
599 for(k
=0; k
< k
; k
++) {
600 if(pvmodttlDv
[k
] != 0) {
601 unregister_module_isr(pvmodttlDv
[k
]);
602 kfree(pvmodttlDv
[k
]);
609 unregister_chrdev_region(devno
, VMODTTL_MAX_BOARDS
);
610 fail_chrdev
: return -1;
614 static void __exit
vmodttl_exit(void)
617 struct message_list
*entry
, *next_entry
;
619 for(i
=0; i
< dev_table
->num_modules
; i
++){
620 if(pvmodttlDv
[i
] != 0){
621 list_for_each_entry_safe(entry
, next_entry
, &pvmodttlDv
[i
]->messages
->list
, list
) {
622 list_del(&entry
->list
);
625 unregister_module_isr(pvmodttlDv
[i
]);
626 kfree(pvmodttlDv
[i
]);
631 unregister_chrdev_region(devno
, VMODTTL_MAX_BOARDS
);
632 printk(KERN_INFO
"VMODTTL: exit module.\n");
635 module_init(vmodttl_init
);
636 module_exit(vmodttl_exit
);
638 MODULE_LICENSE("GPL");
639 MODULE_AUTHOR("Samuel Iglesias Gonsalvez");
640 MODULE_DESCRIPTION("VMOD-TTL device driver");
641 MODULE_VERSION("1.0");