1 /* IO interface mux allocator for ETRAX100LX.
2 * Copyright 2004-2007, Axis Communications AB
6 /* C.f. ETRAX100LX Designer's Reference chapter 19.9 */
8 #include <linux/kernel.h>
9 #include <linux/slab.h>
10 #include <linux/errno.h>
11 #include <linux/module.h>
12 #include <linux/init.h>
14 #include <arch/svinto.h>
16 #include <arch/io_interface_mux.h>
17 #include <arch/system.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;
48 /* name - the name of the group 'A' to 'F' */
50 /* used - a bit mask of all pins in the group in the order listed
51 * in the tables in 19.9.1 to 19.9.6. Note that no
52 * distinction is made between in, out and in/out pins. */
59 enum cris_io_interface ioif;
60 /* name - the name of the interface */
62 /* groups - OR'ed together io_if_group flags describing what pin groups
63 * the interface uses pins in. */
65 /* used - set when the interface is allocated. */
68 /* group_a through group_f - bit masks describing what pins in the
69 * pin groups the interface uses. */
77 /* gpio_g_in, gpio_g_out, gpio_b - bit masks telling what pins in the
78 * GPIO ports the interface uses. This could be reconstucted using
79 * the group_X masks and a table of what pins the GPIO ports use,
80 * but that would be messy. */
81 unsigned int gpio_g_in;
82 unsigned int gpio_g_out;
86 static struct if_group if_groups[6] = {
119 /* The order in the array must match the order of enum
120 * cris_io_interface in io_interface_mux.h */
121 static struct interface interfaces[] = {
122 /* Begin Non-multiplexed interfaces */
155 /* End Non-multiplexed interfaces */
168 .gpio_g_in = 0x00000000,
169 .gpio_g_out = 0x00000000,
184 .gpio_g_in = 0x000000c0,
185 .gpio_g_out = 0x000000c0,
200 .gpio_g_in = 0xc0000000,
201 .gpio_g_out = 0xc0000000,
205 .ioif = if_sync_serial_1,
206 .name = "sync_serial_1",
207 .groups = group_e | group_f,
216 .gpio_g_in = 0x00000000,
217 .gpio_g_out = 0x00000000,
221 .ioif = if_sync_serial_3,
222 .name = "sync_serial_3",
223 .groups = group_c | group_f,
232 .gpio_g_in = 0xc0000000,
233 .gpio_g_out = 0xc0000000,
237 .ioif = if_shared_ram,
238 .name = "shared_ram",
248 .gpio_g_in = 0x0000ff3e,
249 .gpio_g_out = 0x0000ff38,
253 .ioif = if_shared_ram_w,
254 .name = "shared_ram_w",
255 .groups = group_a | group_d,
264 .gpio_g_in = 0x00ffff3e,
265 .gpio_g_out = 0x00ffff38,
280 .gpio_g_in = 0x0000ff3e,
281 .gpio_g_out = 0x0000ff3e,
296 .gpio_g_in = 0x3eff0000,
297 .gpio_g_out = 0x3eff0000,
303 .groups = group_a | group_d,
312 .gpio_g_in = 0x00ffff3e,
313 .gpio_g_out = 0x00ffff3e,
319 .groups = group_a | group_b | group_f,
328 .gpio_g_in = 0x0000ffff,
329 .gpio_g_out = 0x0000ffff,
335 .groups = group_c | group_d | group_f,
344 .gpio_g_in = 0xffff0000,
345 .gpio_g_out = 0xffff0000,
351 .groups = group_a | group_b | group_d | group_f,
360 .gpio_g_in = 0x01ffffff,
361 .gpio_g_out = 0x07ffffff,
367 .groups = group_a | group_b | group_c | group_d,
376 .gpio_g_in = 0xf9ffffff,
377 .gpio_g_out = 0xffffffff,
392 .gpio_g_in = 0x00000000,
393 .gpio_g_out = 0x00000000,
408 .gpio_g_in = 0x00000000,
409 .gpio_g_out = 0x00000000,
415 .groups = group_e | group_f,
424 .gpio_g_in = 0x00000000,
425 .gpio_g_out = 0x00000000,
440 .gpio_g_in = 0x3e000000,
441 .gpio_g_out = 0x0c000000,
446 .ioif = if_gpio_grp_a,
457 .gpio_g_in = 0x0000ff3f,
458 .gpio_g_out = 0x0000ff3f,
462 .ioif = if_gpio_grp_b,
473 .gpio_g_in = 0x000000c0,
474 .gpio_g_out = 0x000000c0,
478 .ioif = if_gpio_grp_c,
489 .gpio_g_in = 0xc0000000,
490 .gpio_g_out = 0xc0000000,
494 .ioif = if_gpio_grp_d,
505 .gpio_g_in = 0x3fff0000,
506 .gpio_g_out = 0x3fff0000,
510 .ioif = if_gpio_grp_e,
521 .gpio_g_in = 0x00000000,
522 .gpio_g_out = 0x00000000,
526 .ioif = if_gpio_grp_f,
537 .gpio_g_in = 0x00000000,
538 .gpio_g_out = 0x00000000,
544 static struct watcher *watchers = NULL;
546 /* The pins that are free to use in the GPIO ports. */
547 static unsigned int gpio_in_pins = 0xffffffff;
548 static unsigned int gpio_out_pins = 0xffffffff;
549 static unsigned char gpio_pb_pins = 0xff;
550 static unsigned char gpio_pa_pins = 0xff;
552 /* Identifiers for the owners of the GPIO pins. */
553 static enum cris_io_interface gpio_pa_owners[8];
554 static enum cris_io_interface gpio_pb_owners[8];
555 static enum cris_io_interface gpio_pg_owners[32];
557 static int cris_io_interface_init(void);
559 static unsigned char clear_group_from_set(const unsigned char groups, struct if_group *group)
561 return (groups & ~group->group);
565 static struct if_group *get_group(const unsigned char groups)
568 for (i = 0; i < ARRAY_SIZE(if_groups); i++) {
569 if (groups & if_groups[i].group) {
570 return &if_groups[i];
577 static void notify_watchers(void)
579 struct watcher *w = watchers;
581 DBG(printk("io_interface_mux: notifying watchers\n"));
584 w->notify((const unsigned int)gpio_in_pins,
585 (const unsigned int)gpio_out_pins,
586 (const unsigned char)gpio_pa_pins,
587 (const unsigned char)gpio_pb_pins);
593 int cris_request_io_interface(enum cris_io_interface ioif, const char *device_id)
595 int set_gen_config = 0;
596 int set_gen_config_ii = 0;
597 unsigned long int gens;
598 unsigned long int gens_ii;
599 struct if_group *grp;
600 unsigned char group_set;
604 (void)cris_io_interface_init();
606 DBG(printk("cris_request_io_interface(%d, \"%s\")\n", ioif, device_id));
608 if ((ioif >= if_max_interfaces) || (ioif < 0)) {
609 printk(KERN_CRIT "cris_request_io_interface: Bad interface "
610 "%u submitted for %s\n",
616 local_irq_save(flags);
618 if (interfaces[ioif].used) {
619 printk(KERN_CRIT "cris_io_interface: Cannot allocate interface "
620 "%s for %s, in use by %s\n",
621 interfaces[ioif].name,
623 interfaces[ioif].owner);
628 /* Check that all required pins in the used groups are free
629 * before allocating. */
630 group_set = interfaces[ioif].groups;
631 while (NULL != (grp = get_group(group_set))) {
632 unsigned int if_group_use = 0;
634 switch (grp->group) {
636 if_group_use = interfaces[ioif].group_a;
639 if_group_use = interfaces[ioif].group_b;
642 if_group_use = interfaces[ioif].group_c;
645 if_group_use = interfaces[ioif].group_d;
648 if_group_use = interfaces[ioif].group_e;
651 if_group_use = interfaces[ioif].group_f;
657 if (if_group_use & grp->used) {
658 printk(KERN_INFO "cris_request_io_interface: group "
659 "%s needed by %s not available\n",
660 grp->name, interfaces[ioif].name);
665 group_set = clear_group_from_set(group_set, grp);
668 /* Are the required GPIO pins available too? */
669 if (((interfaces[ioif].gpio_g_in & gpio_in_pins) !=
670 interfaces[ioif].gpio_g_in) ||
671 ((interfaces[ioif].gpio_g_out & gpio_out_pins) !=
672 interfaces[ioif].gpio_g_out) ||
673 ((interfaces[ioif].gpio_b & gpio_pb_pins) !=
674 interfaces[ioif].gpio_b)) {
675 printk(KERN_CRIT "cris_request_io_interface: Could not get "
676 "required pins for interface %u\n", ioif);
681 /* Check which registers need to be reconfigured. */
682 gens = genconfig_shadow;
683 gens_ii = gen_config_ii_shadow;
688 /* Begin Non-multiplexed interfaces */
694 /* End Non-multiplexed interfaces */
696 set_gen_config_ii = 1;
697 SETS(gens_ii, R_GEN_CONFIG_II, sermode1, async);
700 SETS(gens, R_GEN_CONFIG, ser2, select);
703 SETS(gens, R_GEN_CONFIG, ser3, select);
704 set_gen_config_ii = 1;
705 SETS(gens_ii, R_GEN_CONFIG_II, sermode3, async);
707 case if_sync_serial_1:
708 set_gen_config_ii = 1;
709 SETS(gens_ii, R_GEN_CONFIG_II, sermode1, sync);
711 case if_sync_serial_3:
712 SETS(gens, R_GEN_CONFIG, ser3, select);
713 set_gen_config_ii = 1;
714 SETS(gens_ii, R_GEN_CONFIG_II, sermode3, sync);
717 SETS(gens, R_GEN_CONFIG, mio, select);
719 case if_shared_ram_w:
720 SETS(gens, R_GEN_CONFIG, mio_w, select);
723 SETS(gens, R_GEN_CONFIG, par0, select);
726 SETS(gens, R_GEN_CONFIG, par1, select);
729 SETS(gens, R_GEN_CONFIG, par0, select);
730 SETS(gens, R_GEN_CONFIG, par_w, select);
733 SETS(gens, R_GEN_CONFIG, scsi0, select);
736 SETS(gens, R_GEN_CONFIG, scsi1, select);
739 SETS(gens, R_GEN_CONFIG, scsi0, select);
740 SETS(gens, R_GEN_CONFIG, scsi0w, select);
743 SETS(gens, R_GEN_CONFIG, ata, select);
751 SETS(gens, R_GEN_CONFIG, usb1, select);
754 SETS(gens, R_GEN_CONFIG, usb2, select);
757 /* GPIO groups are only accounted, don't do configuration changes. */
771 printk(KERN_INFO "cris_request_io_interface: Bad interface "
772 "%u submitted for %s\n",
778 /* All needed I/O pins and pin groups are free, allocate. */
779 group_set = interfaces[ioif].groups;
780 while (NULL != (grp = get_group(group_set))) {
781 unsigned int if_group_use = 0;
783 switch (grp->group) {
785 if_group_use = interfaces[ioif].group_a;
788 if_group_use = interfaces[ioif].group_b;
791 if_group_use = interfaces[ioif].group_c;
794 if_group_use = interfaces[ioif].group_d;
797 if_group_use = interfaces[ioif].group_e;
800 if_group_use = interfaces[ioif].group_f;
805 grp->used |= if_group_use;
807 group_set = clear_group_from_set(group_set, grp);
810 interfaces[ioif].used = 1;
811 interfaces[ioif].owner = (char*)device_id;
813 if (set_gen_config) {
815 genconfig_shadow = gens;
816 *R_GEN_CONFIG = genconfig_shadow;
817 /* Wait 12 cycles before doing any DMA command */
818 for(i = 6; i > 0; i--)
821 if (set_gen_config_ii) {
822 gen_config_ii_shadow = gens_ii;
823 *R_GEN_CONFIG_II = gen_config_ii_shadow;
826 DBG(printk(KERN_DEBUG "GPIO pins: available before: "
827 "g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
828 gpio_in_pins, gpio_out_pins, gpio_pb_pins));
829 DBG(printk(KERN_DEBUG
830 "grabbing pins: g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
831 interfaces[ioif].gpio_g_in,
832 interfaces[ioif].gpio_g_out,
833 interfaces[ioif].gpio_b));
835 gpio_in_pins &= ~interfaces[ioif].gpio_g_in;
836 gpio_out_pins &= ~interfaces[ioif].gpio_g_out;
837 gpio_pb_pins &= ~interfaces[ioif].gpio_b;
839 DBG(printk(KERN_DEBUG "GPIO pins: available after: "
840 "g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
841 gpio_in_pins, gpio_out_pins, gpio_pb_pins));
844 local_irq_restore(flags);
851 void cris_free_io_interface(enum cris_io_interface ioif)
853 struct if_group *grp;
854 unsigned char group_set;
857 (void)cris_io_interface_init();
859 if ((ioif >= if_max_interfaces) || (ioif < 0)) {
860 printk(KERN_CRIT "cris_free_io_interface: Bad interface %u\n",
864 local_irq_save(flags);
865 if (!interfaces[ioif].used) {
866 printk(KERN_CRIT "cris_free_io_interface: Freeing free interface %u\n",
868 local_irq_restore(flags);
871 group_set = interfaces[ioif].groups;
872 while (NULL != (grp = get_group(group_set))) {
873 unsigned int if_group_use = 0;
875 switch (grp->group) {
877 if_group_use = interfaces[ioif].group_a;
880 if_group_use = interfaces[ioif].group_b;
883 if_group_use = interfaces[ioif].group_c;
886 if_group_use = interfaces[ioif].group_d;
889 if_group_use = interfaces[ioif].group_e;
892 if_group_use = interfaces[ioif].group_f;
898 if ((grp->used & if_group_use) != if_group_use)
900 grp->used = grp->used & ~if_group_use;
902 group_set = clear_group_from_set(group_set, grp);
904 interfaces[ioif].used = 0;
905 interfaces[ioif].owner = NULL;
907 DBG(printk("GPIO pins: available before: g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
908 gpio_in_pins, gpio_out_pins, gpio_pb_pins));
909 DBG(printk("freeing pins: g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
910 interfaces[ioif].gpio_g_in,
911 interfaces[ioif].gpio_g_out,
912 interfaces[ioif].gpio_b));
914 gpio_in_pins |= interfaces[ioif].gpio_g_in;
915 gpio_out_pins |= interfaces[ioif].gpio_g_out;
916 gpio_pb_pins |= interfaces[ioif].gpio_b;
918 DBG(printk("GPIO pins: available after: g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
919 gpio_in_pins, gpio_out_pins, gpio_pb_pins));
921 local_irq_restore(flags);
926 /* Create a bitmask from bit 0 (inclusive) to bit stop_bit
927 (non-inclusive). stop_bit == 0 returns 0x0 */
928 static inline unsigned int create_mask(const unsigned stop_bit)
931 if (stop_bit >= 32) {
934 return (1<<stop_bit)-1;
938 /* port can be 'a', 'b' or 'g' */
939 int cris_io_interface_allocate_pins(const enum cris_io_interface ioif,
941 const unsigned start_bit,
942 const unsigned stop_bit)
945 unsigned int mask = 0;
946 unsigned int tmp_mask;
947 unsigned long int flags;
948 enum cris_io_interface *owners;
950 (void)cris_io_interface_init();
952 DBG(printk("cris_io_interface_allocate_pins: if=%d port=%c start=%u stop=%u\n",
953 ioif, port, start_bit, stop_bit));
955 if (!((start_bit <= stop_bit) &&
956 ((((port == 'a') || (port == 'b')) && (stop_bit < 8)) ||
957 ((port == 'g') && (stop_bit < 32))))) {
961 mask = create_mask(stop_bit + 1);
962 tmp_mask = create_mask(start_bit);
965 DBG(printk("cris_io_interface_allocate_pins: port=%c start=%u stop=%u mask=0x%08x\n",
966 port, start_bit, stop_bit, mask));
968 local_irq_save(flags);
972 if ((gpio_pa_pins & mask) != mask) {
973 local_irq_restore(flags);
976 owners = gpio_pa_owners;
977 gpio_pa_pins &= ~mask;
980 if ((gpio_pb_pins & mask) != mask) {
981 local_irq_restore(flags);
984 owners = gpio_pb_owners;
985 gpio_pb_pins &= ~mask;
988 if (((gpio_in_pins & mask) != mask) ||
989 ((gpio_out_pins & mask) != mask)) {
990 local_irq_restore(flags);
993 owners = gpio_pg_owners;
994 gpio_in_pins &= ~mask;
995 gpio_out_pins &= ~mask;
998 local_irq_restore(flags);
1002 for (i = start_bit; i <= stop_bit; i++) {
1005 local_irq_restore(flags);
1012 /* port can be 'a', 'b' or 'g' */
1013 int cris_io_interface_free_pins(const enum cris_io_interface ioif,
1015 const unsigned start_bit,
1016 const unsigned stop_bit)
1019 unsigned int mask = 0;
1020 unsigned int tmp_mask;
1021 unsigned long int flags;
1022 enum cris_io_interface *owners;
1024 (void)cris_io_interface_init();
1026 if (!((start_bit <= stop_bit) &&
1027 ((((port == 'a') || (port == 'b')) && (stop_bit < 8)) ||
1028 ((port == 'g') && (stop_bit < 32))))) {
1032 mask = create_mask(stop_bit + 1);
1033 tmp_mask = create_mask(start_bit);
1036 DBG(printk("cris_io_interface_free_pins: port=%c start=%u stop=%u mask=0x%08x\n",
1037 port, start_bit, stop_bit, mask));
1039 local_irq_save(flags);
1043 if ((~gpio_pa_pins & mask) != mask) {
1044 local_irq_restore(flags);
1045 printk(KERN_CRIT "cris_io_interface_free_pins: Freeing free pins");
1047 owners = gpio_pa_owners;
1050 if ((~gpio_pb_pins & mask) != mask) {
1051 local_irq_restore(flags);
1052 printk(KERN_CRIT "cris_io_interface_free_pins: Freeing free pins");
1054 owners = gpio_pb_owners;
1057 if (((~gpio_in_pins & mask) != mask) ||
1058 ((~gpio_out_pins & mask) != mask)) {
1059 local_irq_restore(flags);
1060 printk(KERN_CRIT "cris_io_interface_free_pins: Freeing free pins");
1062 owners = gpio_pg_owners;
1065 owners = NULL; /* Cannot happen. Shut up, gcc! */
1068 for (i = start_bit; i <= stop_bit; i++) {
1069 if (owners[i] != ioif) {
1070 printk(KERN_CRIT "cris_io_interface_free_pins: Freeing unowned pins");
1074 /* All was ok, change data. */
1077 gpio_pa_pins |= mask;
1080 gpio_pb_pins |= mask;
1083 gpio_in_pins |= mask;
1084 gpio_out_pins |= mask;
1088 for (i = start_bit; i <= stop_bit; i++) {
1089 owners[i] = if_unclaimed;
1091 local_irq_restore(flags);
1098 int cris_io_interface_register_watcher(void (*notify)(const unsigned int gpio_in_available,
1099 const unsigned int gpio_out_available,
1100 const unsigned char pa_available,
1101 const unsigned char pb_available))
1105 (void)cris_io_interface_init();
1107 if (NULL == notify) {
1110 w = kmalloc(sizeof(*w), GFP_KERNEL);
1118 w->notify((const unsigned int)gpio_in_pins,
1119 (const unsigned int)gpio_out_pins,
1120 (const unsigned char)gpio_pa_pins,
1121 (const unsigned char)gpio_pb_pins);
1126 void cris_io_interface_delete_watcher(void (*notify)(const unsigned int gpio_in_available,
1127 const unsigned int gpio_out_available,
1128 const unsigned char pa_available,
1129 const unsigned char pb_available))
1131 struct watcher *w = watchers, *prev = NULL;
1133 (void)cris_io_interface_init();
1135 while ((NULL != w) && (w->notify != notify)){
1141 prev->next = w->next;
1148 printk(KERN_WARNING "cris_io_interface_delete_watcher: Deleting unknown watcher 0x%p\n", notify);
1152 static int cris_io_interface_init(void)
1154 static int first = 1;
1162 for (i = 0; i<8; i++) {
1163 gpio_pa_owners[i] = if_unclaimed;
1164 gpio_pb_owners[i] = if_unclaimed;
1165 gpio_pg_owners[i] = if_unclaimed;
1168 gpio_pg_owners[i] = if_unclaimed;
1174 module_init(cris_io_interface_init);
1177 EXPORT_SYMBOL(cris_request_io_interface);
1178 EXPORT_SYMBOL(cris_free_io_interface);
1179 EXPORT_SYMBOL(cris_io_interface_allocate_pins);
1180 EXPORT_SYMBOL(cris_io_interface_free_pins);
1181 EXPORT_SYMBOL(cris_io_interface_register_watcher);
1182 EXPORT_SYMBOL(cris_io_interface_delete_watcher);