1 /* IO interface mux allocator for ETRAX100LX.
2 * Copyright 2004, Axis Communications AB
3 * $Id: io_interface_mux.c,v 1.2 2004/12/21 12:08:38 starvik Exp $
7 /* C.f. ETRAX100LX Designer's Reference 20.9 */
9 #include <linux/kernel.h>
10 #include <linux/slab.h>
11 #include <linux/errno.h>
12 #include <linux/module.h>
13 #include <linux/init.h>
15 #include <asm/arch/svinto.h>
17 #include <asm/arch/io_interface_mux.h>
22 /* Macro to access ETRAX 100 registers */
23 #define SETS(var, reg, field, val) var = (var & ~IO_MASK_(reg##_, field##_)) | \
24 IO_STATE_(reg##_, field##_, _##val)
37 void (*notify
)(const unsigned int gpio_in_available
,
38 const unsigned int gpio_out_available
,
39 const unsigned char pa_available
,
40 const unsigned char pb_available
);
47 enum io_if_group group
;
49 enum cris_io_interface owner
;
55 enum cris_io_interface ioif
;
59 unsigned int gpio_g_in
;
60 unsigned int gpio_g_out
;
64 static struct if_group if_groups
[6] = {
91 /* The order in the array must match the order of enum
92 * cris_io_interface in io_interface_mux.h */
93 static struct interface interfaces
[] = {
94 /* Begin Non-multiplexed interfaces */
109 /* End Non-multiplexed interfaces */
113 .gpio_g_in
= 0x00000000,
114 .gpio_g_out
= 0x00000000,
120 .gpio_g_in
= 0x000000c0,
121 .gpio_g_out
= 0x000000c0,
127 .gpio_g_in
= 0xc0000000,
128 .gpio_g_out
= 0xc0000000,
132 .ioif
= if_sync_serial_1
,
133 .groups
= group_e
| group_f
, /* if_sync_serial_1 and if_sync_serial_3
134 can be used simultaneously */
135 .gpio_g_in
= 0x00000000,
136 .gpio_g_out
= 0x00000000,
140 .ioif
= if_sync_serial_3
,
141 .groups
= group_c
| group_f
,
142 .gpio_g_in
= 0xc0000000,
143 .gpio_g_out
= 0xc0000000,
147 .ioif
= if_shared_ram
,
149 .gpio_g_in
= 0x0000ff3e,
150 .gpio_g_out
= 0x0000ff38,
154 .ioif
= if_shared_ram_w
,
155 .groups
= group_a
| group_d
,
156 .gpio_g_in
= 0x00ffff3e,
157 .gpio_g_out
= 0x00ffff38,
163 .gpio_g_in
= 0x0000ff3e,
164 .gpio_g_out
= 0x0000ff3e,
170 .gpio_g_in
= 0x3eff0000,
171 .gpio_g_out
= 0x3eff0000,
176 .groups
= group_a
| group_d
,
177 .gpio_g_in
= 0x00ffff3e,
178 .gpio_g_out
= 0x00ffff3e,
183 .groups
= group_a
| group_b
| group_f
, /* if_scsi8_0 and if_scsi8_1
184 can be used simultaneously */
185 .gpio_g_in
= 0x0000ffff,
186 .gpio_g_out
= 0x0000ffff,
191 .groups
= group_c
| group_d
| group_f
, /* if_scsi8_0 and if_scsi8_1
192 can be used simultaneously */
193 .gpio_g_in
= 0xffff0000,
194 .gpio_g_out
= 0xffff0000,
199 .groups
= group_a
| group_b
| group_d
| group_f
,
200 .gpio_g_in
= 0x01ffffff,
201 .gpio_g_out
= 0x07ffffff,
206 .groups
= group_a
| group_b
| group_c
| group_d
,
207 .gpio_g_in
= 0xf9ffffff,
208 .gpio_g_out
= 0xffffffff,
213 .groups
= group_f
, /* if_csp and if_i2c can be used simultaneously */
214 .gpio_g_in
= 0x00000000,
215 .gpio_g_out
= 0x00000000,
220 .groups
= group_f
, /* if_csp and if_i2c can be used simultaneously */
221 .gpio_g_in
= 0x00000000,
222 .gpio_g_out
= 0x00000000,
227 .groups
= group_e
| group_f
,
228 .gpio_g_in
= 0x00000000,
229 .gpio_g_out
= 0x00000000,
235 .gpio_g_in
= 0x0e000000,
236 .gpio_g_out
= 0x3c000000,
241 .ioif
= if_gpio_grp_a
,
243 .gpio_g_in
= 0x0000ff3f,
244 .gpio_g_out
= 0x0000ff3f,
248 .ioif
= if_gpio_grp_b
,
250 .gpio_g_in
= 0x000000c0,
251 .gpio_g_out
= 0x000000c0,
255 .ioif
= if_gpio_grp_c
,
257 .gpio_g_in
= 0xc0000000,
258 .gpio_g_out
= 0xc0000000,
262 .ioif
= if_gpio_grp_d
,
264 .gpio_g_in
= 0x3fff0000,
265 .gpio_g_out
= 0x3fff0000,
269 .ioif
= if_gpio_grp_e
,
271 .gpio_g_in
= 0x00000000,
272 .gpio_g_out
= 0x00000000,
276 .ioif
= if_gpio_grp_f
,
278 .gpio_g_in
= 0x00000000,
279 .gpio_g_out
= 0x00000000,
285 static struct watcher
*watchers
= NULL
;
287 static unsigned int gpio_in_pins
= 0xffffffff;
288 static unsigned int gpio_out_pins
= 0xffffffff;
289 static unsigned char gpio_pb_pins
= 0xff;
290 static unsigned char gpio_pa_pins
= 0xff;
292 static enum cris_io_interface gpio_pa_owners
[8];
293 static enum cris_io_interface gpio_pb_owners
[8];
294 static enum cris_io_interface gpio_pg_owners
[32];
296 static int cris_io_interface_init(void);
298 static unsigned char clear_group_from_set(const unsigned char groups
, struct if_group
*group
)
300 return (groups
& ~group
->group
);
304 static struct if_group
*get_group(const unsigned char groups
)
307 for (i
= 0; i
< sizeof(if_groups
)/sizeof(struct if_group
); i
++) {
308 if (groups
& if_groups
[i
].group
) {
309 return &if_groups
[i
];
316 static void notify_watchers(void)
318 struct watcher
*w
= watchers
;
320 DBG(printk("io_interface_mux: notifying watchers\n"));
323 w
->notify((const unsigned int)gpio_in_pins
,
324 (const unsigned int)gpio_out_pins
,
325 (const unsigned char)gpio_pa_pins
,
326 (const unsigned char)gpio_pb_pins
);
332 int cris_request_io_interface(enum cris_io_interface ioif
, const char *device_id
)
334 int set_gen_config
= 0;
335 int set_gen_config_ii
= 0;
336 unsigned long int gens
;
337 unsigned long int gens_ii
;
338 struct if_group
*grp
;
339 unsigned char group_set
;
342 (void)cris_io_interface_init();
344 DBG(printk("cris_request_io_interface(%d, \"%s\")\n", ioif
, device_id
));
346 if ((ioif
>= if_max_interfaces
) || (ioif
< 0)) {
347 printk(KERN_CRIT
"cris_request_io_interface: Bad interface %u submitted for %s\n",
353 local_irq_save(flags
);
355 if (interfaces
[ioif
].used
) {
356 local_irq_restore(flags
);
357 printk(KERN_CRIT
"cris_io_interface: Cannot allocate interface for %s, in use by %s\n",
359 interfaces
[ioif
].owner
);
363 /* Check that all required groups are free before allocating, */
364 group_set
= interfaces
[ioif
].groups
;
365 while (NULL
!= (grp
= get_group(group_set
))) {
367 if (grp
->group
== group_f
) {
368 if ((if_sync_serial_1
== ioif
) ||
369 (if_sync_serial_3
== ioif
)) {
370 if ((grp
->owner
!= if_sync_serial_1
) &&
371 (grp
->owner
!= if_sync_serial_3
)) {
372 local_irq_restore(flags
);
375 } else if ((if_scsi8_0
== ioif
) ||
376 (if_scsi8_1
== ioif
)) {
377 if ((grp
->owner
!= if_scsi8_0
) &&
378 (grp
->owner
!= if_scsi8_1
)) {
379 local_irq_restore(flags
);
384 local_irq_restore(flags
);
388 group_set
= clear_group_from_set(group_set
, grp
);
391 /* Are the required GPIO pins available too? */
392 if (((interfaces
[ioif
].gpio_g_in
& gpio_in_pins
) != interfaces
[ioif
].gpio_g_in
) ||
393 ((interfaces
[ioif
].gpio_g_out
& gpio_out_pins
) != interfaces
[ioif
].gpio_g_out
) ||
394 ((interfaces
[ioif
].gpio_b
& gpio_pb_pins
) != interfaces
[ioif
].gpio_b
)) {
395 printk(KERN_CRIT
"cris_request_io_interface: Could not get required pins for interface %u\n",
400 /* All needed I/O pins and pin groups are free, allocate. */
401 group_set
= interfaces
[ioif
].groups
;
402 while (NULL
!= (grp
= get_group(group_set
))) {
405 group_set
= clear_group_from_set(group_set
, grp
);
408 gens
= genconfig_shadow
;
409 gens_ii
= gen_config_ii_shadow
;
414 /* Begin Non-multiplexed interfaces */
420 /* End Non-multiplexed interfaces */
422 set_gen_config_ii
= 1;
423 SETS(gens_ii
, R_GEN_CONFIG_II
, sermode1
, async
);
426 SETS(gens
, R_GEN_CONFIG
, ser2
, select
);
429 SETS(gens
, R_GEN_CONFIG
, ser3
, select
);
430 set_gen_config_ii
= 1;
431 SETS(gens_ii
, R_GEN_CONFIG_II
, sermode3
, async
);
433 case if_sync_serial_1
:
434 set_gen_config_ii
= 1;
435 SETS(gens_ii
, R_GEN_CONFIG_II
, sermode1
, sync
);
437 case if_sync_serial_3
:
438 SETS(gens
, R_GEN_CONFIG
, ser3
, select
);
439 set_gen_config_ii
= 1;
440 SETS(gens_ii
, R_GEN_CONFIG_II
, sermode3
, sync
);
443 SETS(gens
, R_GEN_CONFIG
, mio
, select
);
445 case if_shared_ram_w
:
446 SETS(gens
, R_GEN_CONFIG
, mio_w
, select
);
449 SETS(gens
, R_GEN_CONFIG
, par0
, select
);
452 SETS(gens
, R_GEN_CONFIG
, par1
, select
);
455 SETS(gens
, R_GEN_CONFIG
, par0
, select
);
456 SETS(gens
, R_GEN_CONFIG
, par_w
, select
);
459 SETS(gens
, R_GEN_CONFIG
, scsi0
, select
);
462 SETS(gens
, R_GEN_CONFIG
, scsi1
, select
);
465 SETS(gens
, R_GEN_CONFIG
, scsi0
, select
);
466 SETS(gens
, R_GEN_CONFIG
, scsi0w
, select
);
469 SETS(gens
, R_GEN_CONFIG
, ata
, select
);
477 SETS(gens
, R_GEN_CONFIG
, usb1
, select
);
480 SETS(gens
, R_GEN_CONFIG
, usb2
, select
);
483 /* GPIO groups are only accounted, don't do configuration changes. */
497 panic("cris_request_io_interface: Bad interface %u submitted for %s\n",
502 interfaces
[ioif
].used
= 1;
503 interfaces
[ioif
].owner
= (char*)device_id
;
505 if (set_gen_config
) {
507 genconfig_shadow
= gens
;
508 *R_GEN_CONFIG
= genconfig_shadow
;
509 /* Wait 12 cycles before doing any DMA command */
510 for(i
= 6; i
> 0; i
--)
513 if (set_gen_config_ii
) {
514 gen_config_ii_shadow
= gens_ii
;
515 *R_GEN_CONFIG_II
= gen_config_ii_shadow
;
518 DBG(printk("GPIO pins: available before: g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
519 gpio_in_pins
, gpio_out_pins
, gpio_pb_pins
));
520 DBG(printk("grabbing pins: g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
521 interfaces
[ioif
].gpio_g_in
,
522 interfaces
[ioif
].gpio_g_out
,
523 interfaces
[ioif
].gpio_b
));
525 gpio_in_pins
&= ~interfaces
[ioif
].gpio_g_in
;
526 gpio_out_pins
&= ~interfaces
[ioif
].gpio_g_out
;
527 gpio_pb_pins
&= ~interfaces
[ioif
].gpio_b
;
529 DBG(printk("GPIO pins: available after: g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
530 gpio_in_pins
, gpio_out_pins
, gpio_pb_pins
));
532 local_irq_restore(flags
);
540 void cris_free_io_interface(enum cris_io_interface ioif
)
542 struct if_group
*grp
;
543 unsigned char group_set
;
546 (void)cris_io_interface_init();
548 if ((ioif
>= if_max_interfaces
) || (ioif
< 0)) {
549 printk(KERN_CRIT
"cris_free_io_interface: Bad interface %u\n",
553 local_irq_save(flags
);
554 if (!interfaces
[ioif
].used
) {
555 printk(KERN_CRIT
"cris_free_io_interface: Freeing free interface %u\n",
557 local_irq_restore(flags
);
560 group_set
= interfaces
[ioif
].groups
;
561 while (NULL
!= (grp
= get_group(group_set
))) {
562 if (grp
->group
== group_f
) {
565 case if_sync_serial_1
:
566 if ((grp
->owner
== if_sync_serial_1
) &&
567 interfaces
[if_sync_serial_3
].used
) {
568 grp
->owner
= if_sync_serial_3
;
572 case if_sync_serial_3
:
573 if ((grp
->owner
== if_sync_serial_3
) &&
574 interfaces
[if_sync_serial_1
].used
) {
575 grp
->owner
= if_sync_serial_1
;
580 if ((grp
->owner
== if_scsi8_0
) &&
581 interfaces
[if_scsi8_1
].used
) {
582 grp
->owner
= if_scsi8_1
;
587 if ((grp
->owner
== if_scsi8_1
) &&
588 interfaces
[if_scsi8_0
].used
) {
589 grp
->owner
= if_scsi8_0
;
599 group_set
= clear_group_from_set(group_set
, grp
);
601 interfaces
[ioif
].used
= 0;
602 interfaces
[ioif
].owner
= NULL
;
604 DBG(printk("GPIO pins: available before: g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
605 gpio_in_pins
, gpio_out_pins
, gpio_pb_pins
));
606 DBG(printk("freeing pins: g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
607 interfaces
[ioif
].gpio_g_in
,
608 interfaces
[ioif
].gpio_g_out
,
609 interfaces
[ioif
].gpio_b
));
611 gpio_in_pins
|= interfaces
[ioif
].gpio_g_in
;
612 gpio_out_pins
|= interfaces
[ioif
].gpio_g_out
;
613 gpio_pb_pins
|= interfaces
[ioif
].gpio_b
;
615 DBG(printk("GPIO pins: available after: g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
616 gpio_in_pins
, gpio_out_pins
, gpio_pb_pins
));
618 local_irq_restore(flags
);
623 /* Create a bitmask from bit 0 (inclusive) to bit stop_bit
624 (non-inclusive). stop_bit == 0 returns 0x0 */
625 static inline unsigned int create_mask(const unsigned stop_bit
)
628 if (stop_bit
>= 32) {
631 return (1<<stop_bit
)-1;
635 /* port can be 'a', 'b' or 'g' */
636 int cris_io_interface_allocate_pins(const enum cris_io_interface ioif
,
638 const unsigned start_bit
,
639 const unsigned stop_bit
)
642 unsigned int mask
= 0;
643 unsigned int tmp_mask
;
644 unsigned long int flags
;
645 enum cris_io_interface
*owners
;
647 (void)cris_io_interface_init();
649 DBG(printk("cris_io_interface_allocate_pins: if=%d port=%c start=%u stop=%u\n",
650 ioif
, port
, start_bit
, stop_bit
));
652 if (!((start_bit
<= stop_bit
) &&
653 ((((port
== 'a') || (port
== 'b')) && (stop_bit
< 8)) ||
654 ((port
== 'g') && (stop_bit
< 32))))) {
658 mask
= create_mask(stop_bit
+ 1);
659 tmp_mask
= create_mask(start_bit
);
662 DBG(printk("cris_io_interface_allocate_pins: port=%c start=%u stop=%u mask=0x%08x\n",
663 port
, start_bit
, stop_bit
, mask
));
665 local_irq_save(flags
);
669 if ((gpio_pa_pins
& mask
) != mask
) {
670 local_irq_restore(flags
);
673 owners
= gpio_pa_owners
;
674 gpio_pa_pins
&= ~mask
;
677 if ((gpio_pb_pins
& mask
) != mask
) {
678 local_irq_restore(flags
);
681 owners
= gpio_pb_owners
;
682 gpio_pb_pins
&= ~mask
;
685 if (((gpio_in_pins
& mask
) != mask
) ||
686 ((gpio_out_pins
& mask
) != mask
)) {
687 local_irq_restore(flags
);
690 owners
= gpio_pg_owners
;
691 gpio_in_pins
&= ~mask
;
692 gpio_out_pins
&= ~mask
;
695 local_irq_restore(flags
);
699 for (i
= start_bit
; i
<= stop_bit
; i
++) {
702 local_irq_restore(flags
);
709 /* port can be 'a', 'b' or 'g' */
710 int cris_io_interface_free_pins(const enum cris_io_interface ioif
,
712 const unsigned start_bit
,
713 const unsigned stop_bit
)
716 unsigned int mask
= 0;
717 unsigned int tmp_mask
;
718 unsigned long int flags
;
719 enum cris_io_interface
*owners
;
721 (void)cris_io_interface_init();
723 if (!((start_bit
<= stop_bit
) &&
724 ((((port
== 'a') || (port
== 'b')) && (stop_bit
< 8)) ||
725 ((port
== 'g') && (stop_bit
< 32))))) {
729 mask
= create_mask(stop_bit
+ 1);
730 tmp_mask
= create_mask(start_bit
);
733 DBG(printk("cris_io_interface_free_pins: port=%c start=%u stop=%u mask=0x%08x\n",
734 port
, start_bit
, stop_bit
, mask
));
736 local_irq_save(flags
);
740 if ((~gpio_pa_pins
& mask
) != mask
) {
741 local_irq_restore(flags
);
742 printk(KERN_CRIT
"cris_io_interface_free_pins: Freeing free pins");
744 owners
= gpio_pa_owners
;
747 if ((~gpio_pb_pins
& mask
) != mask
) {
748 local_irq_restore(flags
);
749 printk(KERN_CRIT
"cris_io_interface_free_pins: Freeing free pins");
751 owners
= gpio_pb_owners
;
754 if (((~gpio_in_pins
& mask
) != mask
) ||
755 ((~gpio_out_pins
& mask
) != mask
)) {
756 local_irq_restore(flags
);
757 printk(KERN_CRIT
"cris_io_interface_free_pins: Freeing free pins");
759 owners
= gpio_pg_owners
;
762 owners
= NULL
; /* Cannot happen. Shut up, gcc! */
765 for (i
= start_bit
; i
<= stop_bit
; i
++) {
766 if (owners
[i
] != ioif
) {
767 printk(KERN_CRIT
"cris_io_interface_free_pins: Freeing unowned pins");
771 /* All was ok, change data. */
774 gpio_pa_pins
|= mask
;
777 gpio_pb_pins
|= mask
;
780 gpio_in_pins
|= mask
;
781 gpio_out_pins
|= mask
;
785 for (i
= start_bit
; i
<= stop_bit
; i
++) {
786 owners
[i
] = if_unclaimed
;
788 local_irq_restore(flags
);
795 int cris_io_interface_register_watcher(void (*notify
)(const unsigned int gpio_in_available
,
796 const unsigned int gpio_out_available
,
797 const unsigned char pa_available
,
798 const unsigned char pb_available
))
802 (void)cris_io_interface_init();
804 if (NULL
== notify
) {
807 w
= kmalloc(sizeof(*w
), GFP_KERNEL
);
815 w
->notify((const unsigned int)gpio_in_pins
,
816 (const unsigned int)gpio_out_pins
,
817 (const unsigned char)gpio_pa_pins
,
818 (const unsigned char)gpio_pb_pins
);
823 void cris_io_interface_delete_watcher(void (*notify
)(const unsigned int gpio_in_available
,
824 const unsigned int gpio_out_available
,
825 const unsigned char pa_available
,
826 const unsigned char pb_available
))
828 struct watcher
*w
= watchers
, *prev
= NULL
;
830 (void)cris_io_interface_init();
832 while ((NULL
!= w
) && (w
->notify
!= notify
)){
838 prev
->next
= w
->next
;
845 printk(KERN_WARNING
"cris_io_interface_delete_watcher: Deleting unknown watcher 0x%p\n", notify
);
849 static int cris_io_interface_init(void)
851 static int first
= 1;
859 for (i
= 0; i
<8; i
++) {
860 gpio_pa_owners
[i
] = if_unclaimed
;
861 gpio_pb_owners
[i
] = if_unclaimed
;
862 gpio_pg_owners
[i
] = if_unclaimed
;
865 gpio_pg_owners
[i
] = if_unclaimed
;
871 module_init(cris_io_interface_init
);
874 EXPORT_SYMBOL(cris_request_io_interface
);
875 EXPORT_SYMBOL(cris_free_io_interface
);
876 EXPORT_SYMBOL(cris_io_interface_allocate_pins
);
877 EXPORT_SYMBOL(cris_io_interface_free_pins
);
878 EXPORT_SYMBOL(cris_io_interface_register_watcher
);
879 EXPORT_SYMBOL(cris_io_interface_delete_watcher
);